-
Notifications
You must be signed in to change notification settings - Fork 155
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat (client): client-side support for int8 #665
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,7 +9,12 @@ type ForeignKey = { | |
|
||
type ColumnName = string | ||
type SQLiteType = string | ||
type ColumnTypes = Record<ColumnName, SQLiteType> | ||
type PgType = string | ||
type ColumnType = { | ||
sqliteType: SQLiteType | ||
pgType: PgType | ||
} | ||
type ColumnTypes = Record<ColumnName, ColumnType> | ||
|
||
export type Table = { | ||
tableName: string | ||
|
@@ -220,6 +225,7 @@ export function generateTriggers(tables: Tables): Statement[] { | |
* Joins the column names and values into a string of pairs of the form `'col1', val1, 'col2', val2, ...` | ||
* that can be used to build a JSON object in a SQLite `json_object` function call. | ||
* Values of type REAL are cast to text to avoid a bug in SQLite's `json_object` function (see below). | ||
* Similarly, values of type INT8 (i.e. BigInts) are cast to text because JSON does not support BigInts. | ||
* | ||
* NOTE: There is a bug with SQLite's `json_object` function up to version 3.41.2 | ||
* that causes it to return an invalid JSON object if some value is +Infinity or -Infinity. | ||
|
@@ -268,7 +274,10 @@ function joinColsForJSON( | |
// casts the value to TEXT if it is of type REAL | ||
// to work around the bug in SQLite's `json_object` function | ||
const castIfNeeded = (col: string, targettedCol: string) => { | ||
if (colTypes[col] === 'REAL') { | ||
const tpes = colTypes[col] | ||
const sqliteType = tpes.sqliteType | ||
const pgType = tpes.pgType | ||
if (sqliteType === 'REAL' || pgType === 'INT8' || pgType === 'BIGINT') { | ||
return `cast(${targettedCol} as TEXT)` | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Seeing this for the first time now, it's surprising we're not using a disciplined approach for interpolating fargments into SQL strings. I know it's out of scope for this PR but I wanted to hear your opinion on it: shouldn't we audit all table column references that are interpolated into strings like this and replace them with a centralized function that can quote all identifiers uniformly? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We could indeed change all places were we quote explicitly by calling a |
||
} else { | ||
return targettedCol | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This string should be returned from a function if it's used in multiple places like this. If, say, we add quoting for these field identifiers later, it'll be easier to make the change once and not worry about missing some occurrences that will be left unquoted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You want to introduce a local
getField()
function that returns the field?something like:
I don't really see the value of adding this now as we merely use the field without any changes.
I do see the value once we do more than just using the field name, e.g. add quoting, but now it is literally the identity function.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was only referring to the act of interpolating a variable into a string which is then passsed as SQL for execution by SQLite. Depending on the context, this can lead to SQL injection attacks or merely client-side fatal errors.
What I'm saying is that we should properly quote all identifiers and values when interpolating them into strings of SQL. It doesn't take much effort for a particular field name to break our client and as a consequence the app that depends on it. Here's a quick example:
Perhaps the value in the
field
variable is already quoted? In that case, disregard this comment.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indeed, the arguments we pass to the function are already quoted, e.g.: