Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
(${sqlExpression} ${comparison} ${sqlCursors[i] || sql.null})
OR\
(\
${sqlExpression} = ${sqlCursors[i] || sql.null}\
AND\
${sqlOldFilter}\
)\
)`;
}
// Check the cursor prefixes apply
// TODO:v5: we should be able to do this in JS-land rather than SQL-land
sqlFilter = sql.fragment`(((${sql.join(
getPgCursorPrefix(),
", "
)}) = (${sql.join(
rawPrefixes.map(val => sql.value(val)),
", "
)})) AND (${sqlFilter}))`;
queryBuilder.whereBound(sqlFilter, isAfter);
} else if (
cursorValue[0] === "natural" &&
typeof cursorValue[1] === "number" &&
isSafeInteger(cursorValue[1]) &&
cursorValue[1] >= 0
) {
// $FlowFixMe: we know this is a number
const cursorValue1: number = cursorValue[1];
if (isAfter) {
queryBuilder.offset(() => cursorValue1);
} else {
queryBuilder.limit(() => {
*
* If you have a way to improve this, I'd love to see a PR - but please
* make sure that the integration tests pass with your solution first as
* there are a log of potential pitfalls!
*/
const selectionField = isPgClassLike
? /*
* This `when foo is null then null` check might *seem* redundant, but it
* is not - e.g. the compound type `(,,,,,,,)::my_type` and
* `null::my_type` differ; however the former also returns true to `foo
* is null`. We use this check to coalesce both into the canonical `null`
* representation to make it easier to deal with below.
*/
sql.query`(case when ${sqlResultSourceAlias} is null then null else ${sqlResultSourceAlias} end)`
: outputArgNames != null // It's a record
? sql.query`array[${sql.join(
outputArgNames.map(
(outputArgName, idx) =>
sql.query`${sqlResultSourceAlias}.${sql.identifier(
// According to https://www.postgresql.org/docs/10/static/sql-createfunction.html,
// "If you omit the name for an output argument, the system will choose a default column name."
// In PG 9.x and 10, the column names appear to be assigned with a `column` prefix.
outputArgName !== "" ? outputArgName : `column${idx + 1}`
)}::text`
),
" ,"
)}]`
: sql.query`(${sqlResultSourceAlias}.${sqlResultSourceAlias})::${sqlTypeIdentifier}`;
const result = await performQuery(
pgClient,
sql.query`with ${sqlResultSourceAlias} as (${sqlMutationQuery}) select (${selectionField})::text from ${sqlResultSourceAlias}`
const chunkToJson = (fieldsChunk: [SQL, string][]) =>
sql.fragment`jsonb_build_object(${sql.join(
fieldsChunk.map(
([expr, alias]) =>
sql.fragment`${sql.literal(alias)}::text, ${expr}`
),
", "
)})`;
return sql.fragment`(${sql.join(
fieldsChunks.map(chunkToJson),
" || "
)})::json`;
} else {
// PG9.4 will have issues with more than 100 parameters (50 keys)
return sql.fragment`json_build_object(${sql.join(
fields.map(
([expr, alias]) => sql.fragment`${sql.literal(alias)}::text, ${expr}`
),
", "
)})`;
}
}
fields: Array<
[SQL, string /* used to be RawAlias, but cannot work with symbols! */]
>
) {
if (this.supportsJSONB && fields.length > 50) {
const fieldsChunks = chunk(fields, 50);
const chunkToJson = (fieldsChunk: [SQL, string][]) =>
sql.fragment`jsonb_build_object(${sql.join(
fieldsChunk.map(
([expr, alias]) =>
sql.fragment`${sql.literal(alias)}::text, ${expr}`
),
", "
)})`;
return sql.fragment`(${sql.join(
fieldsChunks.map(chunkToJson),
" || "
)})::json`;
} else {
// PG9.4 will have issues with more than 100 parameters (50 keys)
return sql.fragment`json_build_object(${sql.join(
fields.map(
([expr, alias]) => sql.fragment`${sql.literal(alias)}::text, ${expr}`
),
", "
)})`;
}
}
sql.query`(${sqlValuesAlias}.output_value_list)[${sql.literal(
idx + 1
)}]::${sql.identifier(
outputArgTypes[idx].namespaceName,
outputArgTypes[idx].name
)} as ${sql.identifier(
// According to https://www.postgresql.org/docs/10/static/sql-createfunction.html,
// "If you omit the name for an output argument, the system will choose a default column name."
// In PG 9.x and 10, the column names appear to be assigned with a `column` prefix.
outputArgName !== "" ? outputArgName : `column${idx + 1}`
)}`
),
", "
)}
from (values ${sql.join(
values.map(value => sql.query`(${sql.value(value)}::text[])`),
", "
)}) as ${sqlValuesAlias}(output_value_list)`
: sql.query`\
select str::${sqlTypeIdentifier} as ${sqlResultSourceAlias}
from unnest((${sql.value(values)})::text[]) str`;
const { rows: filteredValuesResults } =
values.length > 0
? await performQuery(
pgClient,
sql.query`with ${sqlResultSourceAlias} as (${convertFieldBack}) ${sqlResultQuery}`
)
: { rows: [] };
const finalRows = rawValues.map(rawValue =>
/*
* We can't simply return 'null' here because this is expected to have
(): SQL => {
const orderBy = queryBuilder
.getOrderByExpressionsAndDirections()
.map(([expr]) => expr);
if (queryBuilder.isOrderUnique() && orderBy.length > 0) {
return sql.fragment`json_build_array(${sql.join(
[
...getPgCursorPrefix(),
sql.fragment`json_build_array(${sql.join(orderBy, ", ")})`,
],
", "
)})`;
} else {
return sql.fragment`json_build_array(${sql.join(
getPgCursorPrefix(),
", "
)}, ${
/*
* NOTE[useAsterisk/row_number]: If we have useAsterisk then the
* query with limit offset is in a subquery, so our row_number()
* call doesn't know about it. Here we add the offset back in
* again. See matching NOTE in QueryBuilder.js.
*/
options.useAsterisk
? sql.fragment`${sql.literal(
queryBuilder.getFinalOffset() || 0
)} + `
: sql.fragment``
}(row_number() over (partition by 1)))`;
}
selectIdentifiers(table: PgClass) {
if (this.selectedIdentifiers) return;
const primaryKey = table.primaryKeyConstraint;
if (!primaryKey) return;
const primaryKeys = primaryKey.keyAttributes;
this.select(
sql.fragment`json_build_array(${sql.join(
primaryKeys.map(key =>
escapeLarge(
sql.fragment`${this.getTableAlias()}.${sql.identifier(key.name)}`,
key.type
)
),
", "
)})`,
"__identifiers"
);
this.selectedIdentifiers = true;
}
selectCursor(exprGen: SQLGen) {
addNullCase,
addNotDistinctFromNullCase,
})} as object`
: this.buildSelectFields();
let fragment = sql.fragment`\
select ${useAsterisk ? sql.fragment`${this.getTableAlias()}.*` : fields}
${(this.compiledData.from &&
sql.fragment`from ${this.compiledData.from[0]} as ${this.getTableAlias()}`) ||
sql.blank}
${(this.compiledData.join.length && sql.join(this.compiledData.join, " ")) ||
sql.blank}
where ${this.buildWhereClause(true, true, options)}
${
this.compiledData.orderBy.length
? sql.fragment`order by ${sql.join(
this.compiledData.orderBy.map(
([expr, ascending, nullsFirst]) =>
sql.fragment`${expr} ${
Number(ascending) ^ Number(flip)
? sql.fragment`ASC`
: sql.fragment`DESC`
}${
nullsFirst === true
? sql.fragment` NULLS FIRST`
: nullsFirst === false
? sql.fragment` NULLS LAST`
: sql.blank
}`
),
","
*
* So don't "simplify" the line below! We're probably checking if the
* result of a function call returning a compound type was indeed null.
*/
...(addNotDistinctFromNullCase
? [sql.fragment`(${this.getTableAlias()} is distinct from null)`]
: addNullCase
? [sql.fragment`not (${this.getTableAlias()} is null)`]
: []),
...this.compiledData.where,
...(includeLowerBound ? [this.buildWhereBoundClause(true)] : []),
...(includeUpperBound ? [this.buildWhereBoundClause(false)] : []),
];
return clauses.length
? sql.fragment`(${sql.join(clauses, ") and (")})`
: sql.fragment`1 = 1`;
}
build(