@happyvertical/sql 0.105.12 → 0.106.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +88 -0
- package/dist/aggregate-expression.d.ts +100 -0
- package/dist/aggregate-expression.d.ts.map +1 -0
- package/dist/aggregate.d.ts +23 -0
- package/dist/aggregate.d.ts.map +1 -1
- package/dist/chunks/{duckdb-D4x661Ux.js → duckdb-EvsYk7GK.js} +2 -2
- package/dist/chunks/{duckdb-D4x661Ux.js.map → duckdb-EvsYk7GK.js.map} +1 -1
- package/dist/chunks/{query-DubG7aF0.js → query-B6ATOWzc.js} +246 -39
- package/dist/chunks/{query-DubG7aF0.js.map → query-B6ATOWzc.js.map} +1 -1
- package/dist/chunks/{sqlite-DZkc-EBc.js → sqlite-DxgBiHFg.js} +3 -3
- package/dist/chunks/{sqlite-DZkc-EBc.js.map → sqlite-DxgBiHFg.js.map} +1 -1
- package/dist/chunks/{sqlite-native-79oQLrDp.js → sqlite-native-ytHS5F4a.js} +2 -2
- package/dist/chunks/{sqlite-native-79oQLrDp.js.map → sqlite-native-ytHS5F4a.js.map} +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -3
- package/dist/index.js.map +1 -1
- package/dist/query.js +1 -1
- package/package.json +2 -2
|
@@ -1,6 +1,119 @@
|
|
|
1
1
|
import { a as raw, i as parseConditionKey, n as buildWhere, s as unwrapRawKey } from "./schema-manager-tfASrb_b.js";
|
|
2
2
|
import { DatabaseError } from "@happyvertical/utils";
|
|
3
|
+
//#region src/aggregate-expression.ts
|
|
4
|
+
var MAX_DEPTH = 24;
|
|
5
|
+
/** Node budget for a whole spec (every select item, join, filter and predicate together). */
|
|
6
|
+
var MAX_NODES = 1024;
|
|
7
|
+
var ARITHMETIC = {
|
|
8
|
+
add: "+",
|
|
9
|
+
sub: "-",
|
|
10
|
+
mul: "*",
|
|
11
|
+
div: "/"
|
|
12
|
+
};
|
|
13
|
+
var COMPARISON = {
|
|
14
|
+
eq: "=",
|
|
15
|
+
ne: "<>",
|
|
16
|
+
lt: "<",
|
|
17
|
+
lte: "<=",
|
|
18
|
+
gt: ">",
|
|
19
|
+
gte: ">="
|
|
20
|
+
};
|
|
21
|
+
function isRecord(value) {
|
|
22
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
23
|
+
}
|
|
24
|
+
function literal(value, state) {
|
|
25
|
+
const { ctx } = state;
|
|
26
|
+
if (value === null) return "NULL";
|
|
27
|
+
if (typeof value === "boolean") return value ? "TRUE" : "FALSE";
|
|
28
|
+
if (typeof value === "number") {
|
|
29
|
+
if (!Number.isFinite(value)) throw new Error("Aggregate expression numbers must be finite");
|
|
30
|
+
return String(value);
|
|
31
|
+
}
|
|
32
|
+
if (value instanceof Date) {
|
|
33
|
+
if (Number.isNaN(value.getTime())) throw new Error("Aggregate expression dates must be valid");
|
|
34
|
+
const placeholder = `$${ctx.nextIndex++}`;
|
|
35
|
+
ctx.values.push(value.toISOString());
|
|
36
|
+
if (ctx.adapterType === "duckdb" || ctx.adapterType === "json") return `CAST(${placeholder} AS TIMESTAMP)`;
|
|
37
|
+
if (ctx.adapterType === "postgres") return `CAST(${placeholder} AS TIMESTAMPTZ)`;
|
|
38
|
+
return placeholder;
|
|
39
|
+
}
|
|
40
|
+
if (typeof value === "string") {
|
|
41
|
+
const placeholder = `$${ctx.nextIndex++}`;
|
|
42
|
+
ctx.values.push(value);
|
|
43
|
+
return placeholder;
|
|
44
|
+
}
|
|
45
|
+
throw new Error("Aggregate expression literal must be a string, number, boolean, Date or null");
|
|
46
|
+
}
|
|
47
|
+
function secondsBetween(adapterType, later, earlier) {
|
|
48
|
+
if (adapterType === "postgres") return `CAST(EXTRACT(EPOCH FROM (${later} - ${earlier})) AS DOUBLE PRECISION)`;
|
|
49
|
+
if (adapterType === "duckdb" || adapterType === "json") return `epoch(${later}) - epoch(${earlier})`;
|
|
50
|
+
return `((julianday(${later}) - julianday(${earlier})) * 86400.0)`;
|
|
51
|
+
}
|
|
52
|
+
function renderOperand(node, state, depth) {
|
|
53
|
+
if (depth > MAX_DEPTH) throw new Error(`Aggregate expression is nested deeper than ${MAX_DEPTH}`);
|
|
54
|
+
state.ctx.nodeCount = (state.ctx.nodeCount ?? 0) + 1;
|
|
55
|
+
if (state.ctx.nodeCount > MAX_NODES) throw new Error(`Aggregate expression has more than ${MAX_NODES} nodes`);
|
|
56
|
+
if (!isRecord(node)) throw new Error("Aggregate expression node must be an object");
|
|
57
|
+
const { ctx } = state;
|
|
58
|
+
if ("col" in node) {
|
|
59
|
+
const column = ctx.identifier(node.col);
|
|
60
|
+
ctx.onColumn?.(column);
|
|
61
|
+
return column;
|
|
62
|
+
}
|
|
63
|
+
if ("value" in node) return literal(node.value, state);
|
|
64
|
+
const op = node.op;
|
|
65
|
+
const child = (value) => renderOperand(value, state, depth + 1);
|
|
66
|
+
if (typeof op === "string" && Object.hasOwn(ARITHMETIC, op)) {
|
|
67
|
+
const arithmetic = op;
|
|
68
|
+
const left = child(node.left);
|
|
69
|
+
const right = child(node.right);
|
|
70
|
+
if (arithmetic === "div") {
|
|
71
|
+
const quotient = `((${left} * 1.0) / NULLIF(${right}, 0))`;
|
|
72
|
+
if (ctx.adapterType === "postgres") return `CAST(${quotient} AS DOUBLE PRECISION)`;
|
|
73
|
+
if (ctx.adapterType === "duckdb" || ctx.adapterType === "json") return `CAST(${quotient} AS DOUBLE)`;
|
|
74
|
+
return quotient;
|
|
75
|
+
}
|
|
76
|
+
return `(${left} ${ARITHMETIC[arithmetic]} ${right})`;
|
|
77
|
+
}
|
|
78
|
+
if (op === "secondsBetween") return secondsBetween(ctx.adapterType, child(node.later), child(node.earlier));
|
|
79
|
+
if (typeof op === "string" && Object.hasOwn(COMPARISON, op)) {
|
|
80
|
+
const comparison = op;
|
|
81
|
+
const against = (side) => isRecord(side) && "value" in side && side.value === null;
|
|
82
|
+
if ((comparison === "eq" || comparison === "ne") && against(node.right)) return `(${child(node.left)} IS ${comparison === "eq" ? "NULL" : "NOT NULL"})`;
|
|
83
|
+
if ((comparison === "eq" || comparison === "ne") && against(node.left)) return `(${child(node.right)} IS ${comparison === "eq" ? "NULL" : "NOT NULL"})`;
|
|
84
|
+
return `(${child(node.left)} ${COMPARISON[comparison]} ${child(node.right)})`;
|
|
85
|
+
}
|
|
86
|
+
if (op === "and" || op === "or") {
|
|
87
|
+
const operands = node.operands;
|
|
88
|
+
if (!Array.isArray(operands) || operands.length === 0) throw new Error(`Aggregate expression ${op} requires at least one operand`);
|
|
89
|
+
return `(${operands.map(child).join(op === "and" ? " AND " : " OR ")})`;
|
|
90
|
+
}
|
|
91
|
+
if (op === "not") return `(NOT ${child(node.operand)})`;
|
|
92
|
+
if (op === "isNull" || op === "isNotNull") return `(${child(node.operand)} IS ${op === "isNull" ? "NULL" : "NOT NULL"})`;
|
|
93
|
+
if (op === "coalesce") {
|
|
94
|
+
const operands = node.operands;
|
|
95
|
+
if (!Array.isArray(operands) || operands.length === 0) throw new Error("Aggregate expression coalesce requires at least one operand");
|
|
96
|
+
return `COALESCE(${operands.map(child).join(", ")})`;
|
|
97
|
+
}
|
|
98
|
+
throw new Error(`Unsupported aggregate expression operator: ${String(op)}`);
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Render an expression node to SQL, binding its string and date literals into
|
|
102
|
+
* `ctx` as numbered parameters. Throws on any unknown operator, unsafe
|
|
103
|
+
* identifier, non-finite number, or an expression too large to be legitimate.
|
|
104
|
+
*/
|
|
105
|
+
function renderAggregateExpression(node, ctx) {
|
|
106
|
+
return renderOperand(node, { ctx }, 0);
|
|
107
|
+
}
|
|
108
|
+
//#endregion
|
|
3
109
|
//#region src/aggregate.ts
|
|
110
|
+
var EXPRESSION_AGGREGATES = /* @__PURE__ */ new Set([
|
|
111
|
+
"count",
|
|
112
|
+
"sum",
|
|
113
|
+
"avg",
|
|
114
|
+
"min",
|
|
115
|
+
"max"
|
|
116
|
+
]);
|
|
4
117
|
var VALID_DIRECTIONS = /* @__PURE__ */ new Set(["ASC", "DESC"]);
|
|
5
118
|
var VALID_BUCKET_UNITS = /* @__PURE__ */ new Set([
|
|
6
119
|
"minute",
|
|
@@ -36,32 +149,66 @@ function bucketExpr(adapterType, unit, column) {
|
|
|
36
149
|
case "year": return `strftime('%Y-01-01 00:00:00', ${col})`;
|
|
37
150
|
}
|
|
38
151
|
}
|
|
39
|
-
function
|
|
152
|
+
function checkColumn(state, column) {
|
|
153
|
+
const { scope } = state;
|
|
154
|
+
if (scope && column.includes(".")) {
|
|
155
|
+
const parts = column.split(".");
|
|
156
|
+
if (parts.length !== 2 || !scope.has(parts[0])) throw new Error(`Aggregate column ${column} must be qualified by the from table or a join alias`);
|
|
157
|
+
}
|
|
158
|
+
return column;
|
|
159
|
+
}
|
|
160
|
+
function validateColumn(state, column) {
|
|
161
|
+
return checkColumn(state, validateSqlIdentifier(column));
|
|
162
|
+
}
|
|
163
|
+
function renderExpression(state, node) {
|
|
164
|
+
return renderAggregateExpression(node, state.ctx);
|
|
165
|
+
}
|
|
166
|
+
function aggregateExpression(expr, state) {
|
|
40
167
|
const normalizedFn = String(expr.fn).toLowerCase();
|
|
41
168
|
const fn = validateSqlIdentifier(String(expr.fn)).toUpperCase();
|
|
42
|
-
if (
|
|
169
|
+
if (expr.column !== void 0 && expr.expr !== void 0) throw new Error(`Aggregate ${expr.fn} takes a column or an expr, not both`);
|
|
170
|
+
if ((expr.expr !== void 0 || expr.filter !== void 0) && !EXPRESSION_AGGREGATES.has(normalizedFn)) throw new Error(`Aggregate ${expr.fn} cannot take an expr or filter; use count, sum, avg, min or max`);
|
|
171
|
+
const hasArgument = Boolean(expr.column) || expr.expr !== void 0;
|
|
172
|
+
const filter = expr.filter !== void 0 ? renderExpression(state, expr.filter) : void 0;
|
|
173
|
+
if (normalizedFn === "count" && !hasArgument) {
|
|
43
174
|
if (expr.distinct) throw new Error(`Aggregate ${expr.fn} with distinct requires a column`);
|
|
44
|
-
return "COUNT(*)";
|
|
175
|
+
return filter ? `COUNT(CASE WHEN ${filter} THEN 1 END)` : "COUNT(*)";
|
|
45
176
|
}
|
|
46
|
-
if (!
|
|
47
|
-
const
|
|
48
|
-
return `${fn}(${expr.distinct ? "DISTINCT " : ""}${
|
|
177
|
+
if (!hasArgument) throw new Error(`Aggregate ${expr.fn} requires a column`);
|
|
178
|
+
const argument = expr.expr !== void 0 ? renderExpression(state, expr.expr) : validateColumn(state, expr.column);
|
|
179
|
+
return `${fn}(${expr.distinct ? "DISTINCT " : ""}${filter ? `CASE WHEN ${filter} THEN ${argument} END` : argument})`;
|
|
49
180
|
}
|
|
50
|
-
function selectExpression(expr, adapterType) {
|
|
51
|
-
if (
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
181
|
+
function selectExpression(expr, adapterType, state) {
|
|
182
|
+
if ([
|
|
183
|
+
"fn" in expr,
|
|
184
|
+
"expr" in expr && !("fn" in expr),
|
|
185
|
+
"bucket" in expr
|
|
186
|
+
].filter(Boolean).length > 1) throw new Error("Aggregate select item mixes fn, bucket and expr");
|
|
187
|
+
if ("fn" in expr) return {
|
|
188
|
+
expression: aggregateExpression(expr, state),
|
|
189
|
+
alias: validateSqlIdentifier(expr.as),
|
|
190
|
+
groupingCandidate: false,
|
|
191
|
+
computed: false
|
|
55
192
|
};
|
|
56
|
-
if ("
|
|
57
|
-
expression:
|
|
193
|
+
if ("expr" in expr) return {
|
|
194
|
+
expression: renderExpression(state, expr.expr),
|
|
58
195
|
alias: validateSqlIdentifier(expr.as),
|
|
59
|
-
groupingCandidate: true
|
|
196
|
+
groupingCandidate: true,
|
|
197
|
+
computed: true
|
|
198
|
+
};
|
|
199
|
+
if ("column" in expr && !("bucket" in expr)) return {
|
|
200
|
+
expression: validateColumn(state, expr.column),
|
|
201
|
+
alias: validateSqlIdentifier(expr.as ?? expr.column.split(".").pop() ?? expr.column),
|
|
202
|
+
groupingCandidate: true,
|
|
203
|
+
computed: false
|
|
60
204
|
};
|
|
205
|
+
const column = validateColumn(state, expr.column);
|
|
206
|
+
const bucket = expr.bucket;
|
|
61
207
|
return {
|
|
62
|
-
expression:
|
|
208
|
+
expression: bucketExpr(adapterType, bucket, column),
|
|
63
209
|
alias: validateSqlIdentifier(expr.as),
|
|
64
|
-
groupingCandidate:
|
|
210
|
+
groupingCandidate: true,
|
|
211
|
+
computed: false
|
|
65
212
|
};
|
|
66
213
|
}
|
|
67
214
|
function expandHavingKey(key, expressionByAlias) {
|
|
@@ -85,61 +232,121 @@ function buildHaving(having, expressionByAlias, startIndex, adapterType) {
|
|
|
85
232
|
values: built.values
|
|
86
233
|
};
|
|
87
234
|
}
|
|
88
|
-
function buildOrderBy(orderBy) {
|
|
235
|
+
function buildOrderBy(orderBy, state, aliases) {
|
|
89
236
|
if (!orderBy) return "";
|
|
90
237
|
return `ORDER BY ${(Array.isArray(orderBy) ? orderBy : [orderBy]).map((item) => {
|
|
91
238
|
const [field, direction = "ASC"] = item.trim().split(/\s+/);
|
|
92
239
|
const normalizedDirection = direction.toUpperCase();
|
|
93
240
|
if (!VALID_DIRECTIONS.has(normalizedDirection)) throw new Error(`Invalid aggregate order direction: ${direction}`);
|
|
94
|
-
return `${validateSqlIdentifier(field)} ${normalizedDirection}`;
|
|
241
|
+
return `${aliases.has(field) ? validateSqlIdentifier(field) : validateColumn(state, field)} ${normalizedDirection}`;
|
|
95
242
|
}).join(", ")}`;
|
|
96
243
|
}
|
|
244
|
+
var VALID_JOIN_TYPES = /* @__PURE__ */ new Set(["inner", "left"]);
|
|
245
|
+
var JOIN_ALIAS = /^[A-Za-z_][A-Za-z0-9_]*$/;
|
|
246
|
+
function buildScope(fromAlias, joins, from) {
|
|
247
|
+
if (joins.length === 0 && fromAlias === void 0) return void 0;
|
|
248
|
+
const scope = /* @__PURE__ */ new Set();
|
|
249
|
+
const claim = (name, what) => {
|
|
250
|
+
if (typeof name !== "string" || !JOIN_ALIAS.test(name)) throw new Error(`Invalid aggregate ${what}: ${name}`);
|
|
251
|
+
if (scope.has(name)) throw new Error(`Duplicate aggregate table name or alias: ${name}`);
|
|
252
|
+
scope.add(name);
|
|
253
|
+
};
|
|
254
|
+
if (fromAlias !== void 0) claim(fromAlias, "from alias");
|
|
255
|
+
else {
|
|
256
|
+
if (from.includes(".")) throw new Error("AggregateSpec.fromAlias is required when joining a schema-qualified from table");
|
|
257
|
+
claim(from, "from table");
|
|
258
|
+
}
|
|
259
|
+
for (const join of joins) claim(join.alias, "join alias");
|
|
260
|
+
return scope;
|
|
261
|
+
}
|
|
262
|
+
function joinSql(state, joins) {
|
|
263
|
+
return joins.map((join) => {
|
|
264
|
+
const type = join.type ?? "inner";
|
|
265
|
+
if (!VALID_JOIN_TYPES.has(type)) throw new Error(`Invalid aggregate join type: ${type}`);
|
|
266
|
+
if (join.on === void 0) throw new Error(`Aggregate join ${join.alias} requires an on condition`);
|
|
267
|
+
const table = validateSqlIdentifier(join.table);
|
|
268
|
+
const alias = join.alias;
|
|
269
|
+
if (typeof alias !== "string" || !JOIN_ALIAS.test(alias)) throw new Error(`Invalid aggregate join alias: ${String(alias)}`);
|
|
270
|
+
const on = renderExpression(state, join.on);
|
|
271
|
+
return `${type === "left" ? "LEFT" : "INNER"} JOIN ${table} AS ${alias} ON ${on}`;
|
|
272
|
+
});
|
|
273
|
+
}
|
|
97
274
|
function buildAggregate(spec, startIndex = 1, adapterType) {
|
|
98
275
|
const from = validateSqlIdentifier(spec.from);
|
|
99
276
|
if (spec.select.length === 0) throw new Error("AggregateSpec.select must contain at least one expression");
|
|
277
|
+
if (spec.joins !== void 0 && !Array.isArray(spec.joins)) throw new Error("AggregateSpec.joins must be an array");
|
|
278
|
+
const values = [];
|
|
279
|
+
const ctx = {
|
|
280
|
+
adapterType,
|
|
281
|
+
nextIndex: startIndex,
|
|
282
|
+
values,
|
|
283
|
+
identifier: validateSqlIdentifier
|
|
284
|
+
};
|
|
285
|
+
const fromAlias = spec.fromAlias;
|
|
286
|
+
const joins = (spec.joins ?? []).map((join) => ({
|
|
287
|
+
table: join.table,
|
|
288
|
+
alias: join.alias,
|
|
289
|
+
type: join.type,
|
|
290
|
+
on: join.on
|
|
291
|
+
}));
|
|
292
|
+
const state = {
|
|
293
|
+
ctx,
|
|
294
|
+
scope: buildScope(fromAlias, joins, from)
|
|
295
|
+
};
|
|
296
|
+
ctx.onColumn = (column) => {
|
|
297
|
+
checkColumn(state, column);
|
|
298
|
+
};
|
|
100
299
|
const expressionByAlias = /* @__PURE__ */ new Map();
|
|
300
|
+
const ordinalByAlias = /* @__PURE__ */ new Map();
|
|
101
301
|
const groupingAliases = [];
|
|
102
|
-
const selectSql = spec.select.map((expr) => {
|
|
103
|
-
const selected = selectExpression(expr, adapterType);
|
|
302
|
+
const selectSql = spec.select.map((expr, position) => {
|
|
303
|
+
const selected = selectExpression(expr, adapterType, state);
|
|
304
|
+
if (expressionByAlias.has(selected.alias)) throw new Error(`Duplicate aggregate select alias: ${selected.alias}`);
|
|
104
305
|
expressionByAlias.set(selected.alias, selected.expression);
|
|
306
|
+
if (selected.computed) ordinalByAlias.set(selected.alias, position + 1);
|
|
105
307
|
if (selected.groupingCandidate) groupingAliases.push(selected.alias);
|
|
106
308
|
return `${selected.expression} AS ${selected.alias}`;
|
|
107
309
|
});
|
|
108
|
-
const
|
|
310
|
+
const joinParts = joinSql(state, joins);
|
|
311
|
+
const where = spec.where ? buildWhere(spec.where, ctx.nextIndex, adapterType) : {
|
|
109
312
|
sql: "",
|
|
110
313
|
values: []
|
|
111
314
|
};
|
|
112
|
-
|
|
315
|
+
values.push(...where.values);
|
|
316
|
+
ctx.nextIndex += where.values.length;
|
|
317
|
+
let whereSql = where.sql;
|
|
318
|
+
if (spec.whereExpr !== void 0) {
|
|
319
|
+
const predicate = renderExpression(state, spec.whereExpr);
|
|
320
|
+
whereSql = whereSql ? `WHERE (${whereSql.replace(/^WHERE /, "")}) AND ${predicate}` : `WHERE ${predicate}`;
|
|
321
|
+
}
|
|
113
322
|
const groupByItems = spec.groupBy ?? groupingAliases;
|
|
114
|
-
const groupBySql = groupByItems.length > 0 ? `GROUP BY ${groupByItems.map((item) => expressionByAlias.has(item) ? expressionByAlias.get(item) :
|
|
115
|
-
const having = buildHaving(spec.having, expressionByAlias,
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
const
|
|
323
|
+
const groupBySql = groupByItems.length > 0 ? `GROUP BY ${groupByItems.map((item) => ordinalByAlias.has(item) ? String(ordinalByAlias.get(item)) : expressionByAlias.has(item) ? expressionByAlias.get(item) : validateColumn(state, item)).join(", ")}` : "";
|
|
324
|
+
const having = buildHaving(spec.having, expressionByAlias, ctx.nextIndex, adapterType);
|
|
325
|
+
values.push(...having.values);
|
|
326
|
+
ctx.nextIndex += having.values.length;
|
|
327
|
+
const orderBySql = buildOrderBy(spec.orderBy, state, new Set(expressionByAlias.keys()));
|
|
119
328
|
const pagingSql = [];
|
|
120
329
|
if (spec.limit !== void 0) {
|
|
121
|
-
pagingSql.push(`LIMIT ${placeholder(
|
|
122
|
-
|
|
330
|
+
pagingSql.push(`LIMIT ${placeholder(ctx.nextIndex++)}`);
|
|
331
|
+
values.push(spec.limit);
|
|
123
332
|
} else if (spec.offset !== void 0 && normalizeAdapter(adapterType) === "sqlite") pagingSql.push("LIMIT -1");
|
|
124
333
|
if (spec.offset !== void 0) {
|
|
125
|
-
pagingSql.push(`OFFSET ${placeholder(
|
|
126
|
-
|
|
334
|
+
pagingSql.push(`OFFSET ${placeholder(ctx.nextIndex++)}`);
|
|
335
|
+
values.push(spec.offset);
|
|
127
336
|
}
|
|
337
|
+
const fromSql = spec.fromAlias !== void 0 ? `${from} AS ${fromAlias}` : from;
|
|
128
338
|
return {
|
|
129
339
|
sql: [
|
|
130
340
|
`SELECT ${selectSql.join(", ")}`,
|
|
131
|
-
`FROM ${
|
|
132
|
-
|
|
341
|
+
`FROM ${fromSql}`,
|
|
342
|
+
...joinParts,
|
|
343
|
+
whereSql,
|
|
133
344
|
groupBySql,
|
|
134
345
|
having.sql,
|
|
135
346
|
orderBySql,
|
|
136
347
|
pagingSql.join(" ")
|
|
137
348
|
].filter(Boolean).join(" "),
|
|
138
|
-
values
|
|
139
|
-
...where.values,
|
|
140
|
-
...having.values,
|
|
141
|
-
...pagingValues
|
|
142
|
-
]
|
|
349
|
+
values
|
|
143
350
|
};
|
|
144
351
|
}
|
|
145
352
|
//#endregion
|
|
@@ -350,4 +557,4 @@ async function syncSchema(options) {
|
|
|
350
557
|
//#endregion
|
|
351
558
|
export { NestedTransactionError as a, bucketExpr as c, validateColumnName as i, buildAggregate as l, syncSchema as n, resolveSchemas as o, tableExists as r, convertUniqueIndexesToInlineConstraints as s, escapeSqlValue as t };
|
|
352
559
|
|
|
353
|
-
//# sourceMappingURL=query-
|
|
560
|
+
//# sourceMappingURL=query-B6ATOWzc.js.map
|