effect-qb 0.16.0 → 0.19.0
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 +4 -0
- package/dist/index.js +8065 -0
- package/dist/mysql.js +4036 -2418
- package/dist/postgres/metadata.js +2536 -625
- package/dist/postgres.js +8248 -7857
- package/dist/sqlite.js +8854 -0
- package/dist/standard.js +8019 -0
- package/package.json +15 -3
- package/src/casing.ts +71 -0
- package/src/index.ts +2 -0
- package/src/internal/casing.ts +89 -0
- package/src/internal/column-state.ts +11 -6
- package/src/internal/column.ts +44 -7
- package/src/internal/datatypes/define.ts +2 -1
- package/src/internal/datatypes/enrich.ts +23 -0
- package/src/internal/datatypes/lookup.ts +14 -7
- package/src/internal/derived-table.ts +7 -13
- package/src/internal/dialect-renderers/mysql.ts +2046 -0
- package/src/{postgres/internal/sql-expression-renderer.ts → internal/dialect-renderers/postgres.ts} +867 -283
- package/src/{mysql/internal/sql-expression-renderer.ts → internal/dialect-renderers/sqlite.ts} +834 -358
- package/src/internal/dialect.ts +37 -0
- package/src/internal/dsl-mutation-runtime.ts +29 -10
- package/src/internal/dsl-plan-runtime.ts +41 -24
- package/src/internal/dsl-query-runtime.ts +11 -31
- package/src/internal/dsl-transaction-ddl-runtime.ts +61 -15
- package/src/internal/executor.ts +57 -15
- package/src/internal/expression-ast.ts +3 -2
- package/src/internal/grouping-key.ts +216 -9
- package/src/internal/implication-runtime.ts +3 -2
- package/src/internal/json/types.ts +155 -40
- package/src/internal/predicate/context.ts +14 -1
- package/src/internal/predicate/key.ts +19 -2
- package/src/internal/predicate/runtime.ts +30 -3
- package/src/internal/query.d.ts +38 -11
- package/src/internal/query.ts +315 -54
- package/src/internal/renderer.ts +51 -6
- package/src/internal/runtime/driver-value-mapping.ts +58 -0
- package/src/internal/runtime/normalize.ts +74 -43
- package/src/internal/runtime/schema.ts +5 -3
- package/src/internal/runtime/value.ts +153 -30
- package/src/internal/scalar.ts +6 -1
- package/src/internal/schema-derivation.d.ts +12 -61
- package/src/internal/schema-derivation.ts +90 -38
- package/src/internal/schema-expression.ts +2 -2
- package/src/internal/sql-expression-renderer.ts +19 -0
- package/src/internal/standard-dsl.ts +6885 -0
- package/src/internal/table-options.ts +229 -62
- package/src/internal/table.d.ts +33 -32
- package/src/internal/table.ts +469 -160
- package/src/mysql/column-extension.ts +3 -0
- package/src/mysql/column.ts +27 -12
- package/src/mysql/datatypes/index.ts +24 -2
- package/src/mysql/errors/catalog.ts +5 -5
- package/src/mysql/errors/normalize.ts +2 -2
- package/src/mysql/executor.ts +7 -5
- package/src/mysql/internal/dialect.ts +9 -4
- package/src/mysql/internal/dsl.ts +906 -324
- package/src/mysql/internal/renderer.ts +7 -2
- package/src/mysql/json.ts +37 -0
- package/src/mysql/query-extension.ts +16 -0
- package/src/mysql/query.ts +9 -2
- package/src/mysql/renderer.ts +31 -4
- package/src/mysql.ts +4 -12
- package/src/postgres/column-extension.ts +28 -0
- package/src/postgres/column.ts +9 -13
- package/src/postgres/datatypes/index.d.ts +2 -1
- package/src/postgres/datatypes/index.ts +3 -2
- package/src/postgres/errors/normalize.ts +2 -2
- package/src/postgres/executor.ts +55 -10
- package/src/postgres/function/core.ts +20 -4
- package/src/postgres/function/index.ts +1 -17
- package/src/postgres/internal/dialect.ts +9 -4
- package/src/postgres/internal/dsl.ts +850 -359
- package/src/postgres/internal/renderer.ts +7 -2
- package/src/postgres/internal/schema-ddl.ts +22 -9
- package/src/postgres/internal/schema-model.ts +244 -10
- package/src/postgres/json.ts +100 -24
- package/src/postgres/jsonb.ts +38 -0
- package/src/postgres/query-extension.ts +2 -0
- package/src/postgres/query.ts +9 -2
- package/src/postgres/renderer.ts +31 -4
- package/src/postgres/schema-management.ts +108 -16
- package/src/postgres/schema.ts +98 -15
- package/src/postgres/table.ts +203 -398
- package/src/postgres/type.ts +8 -7
- package/src/postgres.ts +9 -11
- package/src/sqlite/column-extension.ts +3 -0
- package/src/sqlite/column.ts +127 -0
- package/src/sqlite/datatypes/index.ts +80 -0
- package/src/sqlite/datatypes/spec.ts +98 -0
- package/src/sqlite/errors/catalog.ts +103 -0
- package/src/sqlite/errors/fields.ts +19 -0
- package/src/sqlite/errors/index.ts +19 -0
- package/src/sqlite/errors/normalize.ts +229 -0
- package/src/sqlite/errors/requirements.ts +71 -0
- package/src/sqlite/errors/types.ts +29 -0
- package/src/sqlite/executor.ts +229 -0
- package/src/sqlite/function/aggregate.ts +2 -0
- package/src/sqlite/function/core.ts +2 -0
- package/src/sqlite/function/index.ts +19 -0
- package/src/sqlite/function/string.ts +2 -0
- package/src/sqlite/function/temporal.ts +100 -0
- package/src/sqlite/function/window.ts +2 -0
- package/src/sqlite/internal/dialect.ts +42 -0
- package/src/sqlite/internal/dsl.ts +6979 -0
- package/src/sqlite/internal/renderer.ts +51 -0
- package/src/sqlite/json.ts +39 -0
- package/src/sqlite/query-extension.ts +2 -0
- package/src/sqlite/query.ts +196 -0
- package/src/sqlite/renderer.ts +51 -0
- package/src/sqlite.ts +14 -0
- package/src/standard/column.ts +163 -0
- package/src/standard/datatypes/index.ts +83 -0
- package/src/standard/datatypes/spec.ts +98 -0
- package/src/standard/dialect.ts +40 -0
- package/src/standard/function/aggregate.ts +2 -0
- package/src/standard/function/core.ts +2 -0
- package/src/standard/function/index.ts +18 -0
- package/src/standard/function/string.ts +2 -0
- package/src/standard/function/temporal.ts +78 -0
- package/src/standard/function/window.ts +2 -0
- package/src/standard/internal/renderer.ts +45 -0
- package/src/standard/query.ts +152 -0
- package/src/standard/renderer.ts +21 -0
- package/src/standard/table.ts +147 -0
- package/src/standard.ts +18 -0
- package/src/internal/aggregation-validation.ts +0 -57
- package/src/mysql/table.ts +0 -157
|
@@ -25,7 +25,7 @@ __export(exports_metadata, {
|
|
|
25
25
|
});
|
|
26
26
|
|
|
27
27
|
// src/internal/table.ts
|
|
28
|
-
import { pipeArguments as
|
|
28
|
+
import { pipeArguments as pipeArguments3 } from "effect/Pipeable";
|
|
29
29
|
|
|
30
30
|
// src/internal/row-set.ts
|
|
31
31
|
var exports_row_set = {};
|
|
@@ -142,7 +142,7 @@ var remapColumnDefinition = (column, options = {}) => {
|
|
|
142
142
|
}
|
|
143
143
|
return next;
|
|
144
144
|
};
|
|
145
|
-
var bindColumn = (tableName, columnName, column, baseTableName, schemaName) => {
|
|
145
|
+
var bindColumn = (tableName, columnName, column, baseTableName, schemaName, casing) => {
|
|
146
146
|
const brandName = `${tableName}.${columnName}`;
|
|
147
147
|
const schema = column.metadata.brand === true ? Schema.brand(brandName)(column.schema) : column.schema;
|
|
148
148
|
const bound = attachPipe(Object.create(ColumnProto));
|
|
@@ -170,18 +170,86 @@ var bindColumn = (tableName, columnName, column, baseTableName, schemaName) => {
|
|
|
170
170
|
tableName,
|
|
171
171
|
columnName,
|
|
172
172
|
baseTableName,
|
|
173
|
-
schemaName
|
|
173
|
+
schemaName,
|
|
174
|
+
casing
|
|
174
175
|
};
|
|
175
176
|
return bound;
|
|
176
177
|
};
|
|
177
178
|
|
|
179
|
+
// src/internal/schema-expression.ts
|
|
180
|
+
import { parse, toSql } from "pgsql-ast-parser";
|
|
181
|
+
import { pipeArguments as pipeArguments2 } from "effect/Pipeable";
|
|
182
|
+
var TypeId4 = Symbol.for("effect-qb/SchemaExpression");
|
|
183
|
+
var SchemaExpressionProto = {
|
|
184
|
+
pipe() {
|
|
185
|
+
return pipeArguments2(this, arguments);
|
|
186
|
+
}
|
|
187
|
+
};
|
|
188
|
+
var attachPipe2 = (value) => {
|
|
189
|
+
Object.defineProperty(value, "pipe", {
|
|
190
|
+
configurable: true,
|
|
191
|
+
writable: true,
|
|
192
|
+
value: function() {
|
|
193
|
+
return pipeArguments2(value, arguments);
|
|
194
|
+
}
|
|
195
|
+
});
|
|
196
|
+
return value;
|
|
197
|
+
};
|
|
198
|
+
var isSchemaExpression = (value) => typeof value === "object" && value !== null && (TypeId4 in value);
|
|
199
|
+
var fromAst = (ast) => {
|
|
200
|
+
const expression = attachPipe2(Object.create(SchemaExpressionProto));
|
|
201
|
+
expression[TypeId4] = {
|
|
202
|
+
ast
|
|
203
|
+
};
|
|
204
|
+
return expression;
|
|
205
|
+
};
|
|
206
|
+
var fromSql = (sql) => {
|
|
207
|
+
const expression = attachPipe2(Object.create(SchemaExpressionProto));
|
|
208
|
+
expression[TypeId4] = {
|
|
209
|
+
sql: sql.trim()
|
|
210
|
+
};
|
|
211
|
+
return expression;
|
|
212
|
+
};
|
|
213
|
+
var parseExpression = (sql) => fromAst(parse(sql, "expr"));
|
|
214
|
+
var toAst = (expression) => {
|
|
215
|
+
const ast = expression[TypeId4].ast;
|
|
216
|
+
if (ast !== undefined) {
|
|
217
|
+
return ast;
|
|
218
|
+
}
|
|
219
|
+
return parse(render(expression), "expr");
|
|
220
|
+
};
|
|
221
|
+
var render = (expression) => expression[TypeId4].sql ?? toSql.expr(toAst(expression));
|
|
222
|
+
var normalize = (expression) => (() => {
|
|
223
|
+
const sql = render(expression);
|
|
224
|
+
try {
|
|
225
|
+
return parseExpression(sql);
|
|
226
|
+
} catch {
|
|
227
|
+
return fromSql(sql);
|
|
228
|
+
}
|
|
229
|
+
})();
|
|
230
|
+
|
|
178
231
|
// src/internal/table-options.ts
|
|
232
|
+
var referentialActionError = "Foreign key action must be noAction, restrict, cascade, setNull, or setDefault";
|
|
233
|
+
var renderReferentialAction = (action) => {
|
|
234
|
+
switch (action) {
|
|
235
|
+
case "noAction":
|
|
236
|
+
return "no action";
|
|
237
|
+
case "restrict":
|
|
238
|
+
return "restrict";
|
|
239
|
+
case "cascade":
|
|
240
|
+
return "cascade";
|
|
241
|
+
case "setNull":
|
|
242
|
+
return "set null";
|
|
243
|
+
case "setDefault":
|
|
244
|
+
return "set default";
|
|
245
|
+
}
|
|
246
|
+
throw new Error(referentialActionError);
|
|
247
|
+
};
|
|
179
248
|
var normalizeColumnList = (columns) => {
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
throw new Error("Table options require at least one column");
|
|
249
|
+
if (typeof columns === "string") {
|
|
250
|
+
return [columns];
|
|
183
251
|
}
|
|
184
|
-
return
|
|
252
|
+
return [columns[0], ...columns.slice(1)];
|
|
185
253
|
};
|
|
186
254
|
var collectInlineOptions = (fields) => {
|
|
187
255
|
const options = [];
|
|
@@ -213,6 +281,7 @@ var collectInlineOptions = (fields) => {
|
|
|
213
281
|
return {
|
|
214
282
|
tableName: bound.baseTableName,
|
|
215
283
|
schemaName: bound.schemaName,
|
|
284
|
+
casing: bound.casing,
|
|
216
285
|
columns: [bound.columnName]
|
|
217
286
|
};
|
|
218
287
|
},
|
|
@@ -245,89 +314,50 @@ var collectInlineOptions = (fields) => {
|
|
|
245
314
|
};
|
|
246
315
|
var resolvePrimaryKeyColumns = (fields, declaredOptions) => {
|
|
247
316
|
const inline = Object.entries(fields).filter(([, column]) => column.metadata.primaryKey).map(([key]) => key);
|
|
248
|
-
const explicit = declaredOptions.
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
317
|
+
const explicit = declaredOptions.flatMap((option) => {
|
|
318
|
+
if (typeof option !== "object" || option === null || !("kind" in option) || option.kind !== "primaryKey") {
|
|
319
|
+
return [];
|
|
320
|
+
}
|
|
321
|
+
return Array.isArray(option.columns) ? [option.columns] : [];
|
|
322
|
+
});
|
|
252
323
|
if (explicit.length === 0) {
|
|
253
324
|
return inline;
|
|
254
325
|
}
|
|
255
326
|
const tablePrimaryKey = [...explicit[0]];
|
|
256
|
-
if (inline.length > 0) {
|
|
257
|
-
const same = inline.length === tablePrimaryKey.length && inline.every((column) => tablePrimaryKey.includes(column));
|
|
258
|
-
if (!same) {
|
|
259
|
-
throw new Error("Inline primary keys conflict with table-level primary key declaration");
|
|
260
|
-
}
|
|
261
|
-
}
|
|
262
327
|
return tablePrimaryKey;
|
|
263
328
|
};
|
|
264
329
|
var validateOptions = (tableName, fields, options) => {
|
|
265
|
-
const
|
|
266
|
-
for (const option of
|
|
330
|
+
const tableOptions = Array.isArray(options) ? options : [options];
|
|
331
|
+
for (const option of tableOptions) {
|
|
332
|
+
if (typeof option !== "object" || option === null || !("kind" in option)) {
|
|
333
|
+
continue;
|
|
334
|
+
}
|
|
267
335
|
switch (option.kind) {
|
|
268
336
|
case "index":
|
|
269
337
|
case "primaryKey":
|
|
270
338
|
case "unique":
|
|
271
339
|
case "foreignKey": {
|
|
272
|
-
const columns = option.kind === "index" ? option.columns ?? [] : option.columns;
|
|
273
|
-
if (columns.length === 0 && option.kind !== "index") {
|
|
274
|
-
throw new Error(`Option '${option.kind}' on table '${tableName}' requires at least one column`);
|
|
275
|
-
}
|
|
276
|
-
for (const column of columns) {
|
|
277
|
-
if (!knownColumns.has(column)) {
|
|
278
|
-
throw new Error(`Unknown column '${column}' on table '${tableName}'`);
|
|
279
|
-
}
|
|
280
|
-
}
|
|
281
|
-
if (option.kind === "foreignKey") {
|
|
282
|
-
const reference = option.references();
|
|
283
|
-
if (reference.columns.length !== columns.length) {
|
|
284
|
-
throw new Error(`Foreign key on table '${tableName}' must reference the same number of columns`);
|
|
285
|
-
}
|
|
286
|
-
if (reference.knownColumns) {
|
|
287
|
-
const referenced = new Set(reference.knownColumns);
|
|
288
|
-
for (const column of reference.columns) {
|
|
289
|
-
if (!referenced.has(column)) {
|
|
290
|
-
throw new Error(`Unknown referenced column '${column}' on table '${reference.tableName}'`);
|
|
291
|
-
}
|
|
292
|
-
}
|
|
293
|
-
}
|
|
294
|
-
}
|
|
295
340
|
if (option.kind === "index") {
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
}
|
|
301
|
-
for (const key of option.keys ?? []) {
|
|
302
|
-
if (key.kind === "column" && !knownColumns.has(key.column)) {
|
|
303
|
-
throw new Error(`Unknown index key column '${key.column}' on table '${tableName}'`);
|
|
341
|
+
const keys = Array.isArray(option.keys) ? option.keys : [];
|
|
342
|
+
for (const key of keys) {
|
|
343
|
+
if (typeof key !== "object" || key === null || !("kind" in key)) {
|
|
344
|
+
continue;
|
|
304
345
|
}
|
|
305
346
|
}
|
|
306
|
-
if (option.columns === undefined && (option.keys === undefined || option.keys.length === 0)) {
|
|
307
|
-
throw new Error(`Index on table '${tableName}' requires at least one column or key`);
|
|
308
|
-
}
|
|
309
347
|
}
|
|
310
348
|
break;
|
|
311
349
|
}
|
|
312
350
|
case "check": {
|
|
313
351
|
break;
|
|
314
352
|
}
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
for (const column of resolvePrimaryKeyColumns(fields, options)) {
|
|
318
|
-
if (fields[column].metadata.nullable) {
|
|
319
|
-
throw new Error(`Primary key column '${String(column)}' cannot be nullable`);
|
|
353
|
+
default:
|
|
354
|
+
break;
|
|
320
355
|
}
|
|
321
356
|
}
|
|
322
357
|
};
|
|
323
358
|
|
|
324
359
|
// src/internal/schema-derivation.ts
|
|
325
|
-
import * as VariantSchema from "@effect/experimental/VariantSchema";
|
|
326
360
|
import * as Schema2 from "effect/Schema";
|
|
327
|
-
var TableSchema = VariantSchema.make({
|
|
328
|
-
variants: ["select", "insert", "update"],
|
|
329
|
-
defaultVariant: "select"
|
|
330
|
-
});
|
|
331
361
|
var maybeBrandSchema = (column, tableName, columnName) => column.metadata.brand === true ? Schema2.brand(`${tableName}.${columnName}`)(column.schema) : column.schema;
|
|
332
362
|
var selectSchema = (column, tableName, columnName) => column.metadata.nullable ? Schema2.NullOr(maybeBrandSchema(column, tableName, columnName)) : maybeBrandSchema(column, tableName, columnName);
|
|
333
363
|
var insertSchema = (column, tableName, columnName) => {
|
|
@@ -344,87 +374,196 @@ var updateSchema = (column, tableName, columnName, isPrimaryKey) => {
|
|
|
344
374
|
const base = column.metadata.nullable ? Schema2.NullOr(maybeBrandSchema(column, tableName, columnName)) : maybeBrandSchema(column, tableName, columnName);
|
|
345
375
|
return Schema2.optional(base);
|
|
346
376
|
};
|
|
347
|
-
var
|
|
377
|
+
var fieldSchemaForVariant = (variant, column, tableName, columnName, primaryKeySet) => {
|
|
378
|
+
switch (variant) {
|
|
379
|
+
case "select":
|
|
380
|
+
return selectSchema(column, tableName, columnName);
|
|
381
|
+
case "insert":
|
|
382
|
+
return insertSchema(column, tableName, columnName);
|
|
383
|
+
case "update":
|
|
384
|
+
return updateSchema(column, tableName, columnName, primaryKeySet.has(columnName));
|
|
385
|
+
}
|
|
386
|
+
};
|
|
387
|
+
var deriveSchema = (variant, tableName, fields, primaryKeyColumns) => {
|
|
348
388
|
const primaryKeySet = new Set(primaryKeyColumns);
|
|
349
|
-
const
|
|
389
|
+
const structFields = {};
|
|
350
390
|
for (const [key, column] of Object.entries(fields)) {
|
|
351
|
-
const
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
update: undefined
|
|
355
|
-
};
|
|
356
|
-
const insert = insertSchema(column, tableName, key);
|
|
357
|
-
const update = updateSchema(column, tableName, key, primaryKeySet.has(key));
|
|
358
|
-
if (insert !== undefined) {
|
|
359
|
-
config.insert = insert;
|
|
360
|
-
} else {
|
|
361
|
-
delete config.insert;
|
|
391
|
+
const schema = fieldSchemaForVariant(variant, column, tableName, key, primaryKeySet);
|
|
392
|
+
if (schema !== undefined) {
|
|
393
|
+
structFields[key] = schema;
|
|
362
394
|
}
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
395
|
+
}
|
|
396
|
+
return Schema2.Struct(structFields);
|
|
397
|
+
};
|
|
398
|
+
var deriveSelectSchema = (tableName, fields, primaryKeyColumns) => deriveSchema("select", tableName, fields, primaryKeyColumns);
|
|
399
|
+
var deriveInsertSchema = (tableName, fields, primaryKeyColumns) => deriveSchema("insert", tableName, fields, primaryKeyColumns);
|
|
400
|
+
var deriveUpdateSchema = (tableName, fields, primaryKeyColumns) => deriveSchema("update", tableName, fields, primaryKeyColumns);
|
|
401
|
+
|
|
402
|
+
// src/internal/casing.ts
|
|
403
|
+
var TypeId5 = Symbol.for("effect-qb/Casing");
|
|
404
|
+
var merge = (base, override) => {
|
|
405
|
+
if (base === undefined) {
|
|
406
|
+
return override;
|
|
407
|
+
}
|
|
408
|
+
if (override === undefined) {
|
|
409
|
+
return base;
|
|
410
|
+
}
|
|
411
|
+
return { ...base, ...override };
|
|
412
|
+
};
|
|
413
|
+
var words = (name) => name.replace(/([a-z0-9])([A-Z])/g, "$1 $2").replace(/([A-Z]+)([A-Z][a-z])/g, "$1 $2").split(/[^A-Za-z0-9]+/).filter((part) => part.length > 0);
|
|
414
|
+
var capitalize = (value) => value.length === 0 ? value : `${value[0].toUpperCase()}${value.slice(1)}`;
|
|
415
|
+
var lowerWords = (name) => words(name).map((part) => part.toLowerCase());
|
|
416
|
+
var applyNamedStyle = (style, name) => {
|
|
417
|
+
switch (style) {
|
|
418
|
+
case "preserve":
|
|
419
|
+
return name;
|
|
420
|
+
case "snake_case":
|
|
421
|
+
return lowerWords(name).join("_");
|
|
422
|
+
case "camelCase": {
|
|
423
|
+
const parts = lowerWords(name);
|
|
424
|
+
const [head, ...tail] = parts;
|
|
425
|
+
return head === undefined ? "" : `${head}${tail.map(capitalize).join("")}`;
|
|
367
426
|
}
|
|
368
|
-
|
|
427
|
+
case "PascalCase":
|
|
428
|
+
return lowerWords(name).map(capitalize).join("");
|
|
429
|
+
case "kebab-case":
|
|
430
|
+
return lowerWords(name).join("-");
|
|
431
|
+
case "SCREAMING_SNAKE_CASE":
|
|
432
|
+
return lowerWords(name).join("_").toUpperCase();
|
|
369
433
|
}
|
|
370
|
-
const struct = TableSchema.Struct(variants);
|
|
371
|
-
return {
|
|
372
|
-
select: TableSchema.extract(struct, "select"),
|
|
373
|
-
insert: TableSchema.extract(struct, "insert"),
|
|
374
|
-
update: TableSchema.extract(struct, "update")
|
|
375
|
-
};
|
|
376
434
|
};
|
|
435
|
+
var apply = (style, name) => {
|
|
436
|
+
if (style === undefined) {
|
|
437
|
+
return name;
|
|
438
|
+
}
|
|
439
|
+
return typeof style === "function" ? style(name) : applyNamedStyle(style, name);
|
|
440
|
+
};
|
|
441
|
+
var applyCategory = (options, category, name) => apply(options?.[category], name);
|
|
377
442
|
|
|
378
443
|
// src/internal/table.ts
|
|
379
|
-
var
|
|
444
|
+
var TypeId6 = Symbol.for("effect-qb/Table");
|
|
380
445
|
var OptionsSymbol = Symbol.for("effect-qb/Table/normalizedOptions");
|
|
381
446
|
var options = Symbol.for("effect-qb/Table/declaredOptions");
|
|
382
447
|
var CacheSymbol = Symbol.for("effect-qb/Table/cache");
|
|
448
|
+
var SchemaCacheSymbol = Symbol.for("effect-qb/Table/schemaCache");
|
|
383
449
|
var DeclaredOptionsSymbol = Symbol.for("effect-qb/Table/factoryDeclaredOptions");
|
|
384
450
|
var TableProto = {
|
|
385
451
|
pipe() {
|
|
386
|
-
return
|
|
452
|
+
return pipeArguments3(this, arguments);
|
|
387
453
|
}
|
|
388
454
|
};
|
|
389
|
-
var
|
|
455
|
+
var attachPipe3 = (value) => {
|
|
390
456
|
Object.defineProperty(value, "pipe", {
|
|
391
457
|
configurable: true,
|
|
392
458
|
writable: true,
|
|
393
459
|
value: function() {
|
|
394
|
-
return
|
|
460
|
+
return pipeArguments3(value, arguments);
|
|
395
461
|
}
|
|
396
462
|
});
|
|
397
463
|
return value;
|
|
398
464
|
};
|
|
399
|
-
var buildArtifacts = (name, fields, declaredOptions, schemaName) => {
|
|
465
|
+
var buildArtifacts = (name, fields, declaredOptions, schemaName, casing) => {
|
|
400
466
|
const normalizedOptions = [...collectInlineOptions(fields), ...declaredOptions];
|
|
401
467
|
validateFieldDialects(name, fields);
|
|
402
468
|
validateOptions(name, fields, declaredOptions);
|
|
403
469
|
const primaryKey = resolvePrimaryKeyColumns(fields, declaredOptions);
|
|
404
|
-
const columns = Object.fromEntries(Object.entries(fields).map(([key, column]) => [key, bindColumn(name, key, column, name, schemaName)]));
|
|
405
|
-
const schemas = deriveSchemas(name, fields, primaryKey);
|
|
470
|
+
const columns = Object.fromEntries(Object.entries(fields).map(([key, column]) => [key, bindColumn(name, key, column, name, schemaName, casing)]));
|
|
406
471
|
return {
|
|
407
472
|
columns,
|
|
408
|
-
schemas,
|
|
409
473
|
normalizedOptions,
|
|
410
474
|
primaryKey
|
|
411
475
|
};
|
|
412
476
|
};
|
|
413
|
-
var
|
|
477
|
+
var getSchemaCache = (table) => {
|
|
478
|
+
const target = table;
|
|
479
|
+
if (target[SchemaCacheSymbol] !== undefined) {
|
|
480
|
+
return target[SchemaCacheSymbol];
|
|
481
|
+
}
|
|
482
|
+
const cache = {};
|
|
483
|
+
Object.defineProperty(table, SchemaCacheSymbol, {
|
|
484
|
+
configurable: true,
|
|
485
|
+
value: cache
|
|
486
|
+
});
|
|
487
|
+
return cache;
|
|
488
|
+
};
|
|
489
|
+
var deriveTableSchema = (table, variant) => {
|
|
490
|
+
const state = table[TypeId6];
|
|
491
|
+
switch (variant) {
|
|
492
|
+
case "select":
|
|
493
|
+
return deriveSelectSchema(state.name, state.fields, state.primaryKey);
|
|
494
|
+
case "insert":
|
|
495
|
+
return deriveInsertSchema(state.name, state.fields, state.primaryKey);
|
|
496
|
+
case "update":
|
|
497
|
+
return deriveUpdateSchema(state.name, state.fields, state.primaryKey);
|
|
498
|
+
}
|
|
499
|
+
};
|
|
500
|
+
var schemaFor = (table, variant) => {
|
|
501
|
+
const cache = getSchemaCache(table);
|
|
502
|
+
const cached = cache[variant];
|
|
503
|
+
if (cached !== undefined) {
|
|
504
|
+
return cached;
|
|
505
|
+
}
|
|
506
|
+
const schema = deriveTableSchema(table, variant);
|
|
507
|
+
cache[variant] = schema;
|
|
508
|
+
return schema;
|
|
509
|
+
};
|
|
510
|
+
function selectSchema2(table) {
|
|
511
|
+
return schemaFor(table, "select");
|
|
512
|
+
}
|
|
513
|
+
function insertSchema2(table) {
|
|
514
|
+
return schemaFor(table, "insert");
|
|
515
|
+
}
|
|
516
|
+
function updateSchema2(table) {
|
|
517
|
+
return schemaFor(table, "update");
|
|
518
|
+
}
|
|
519
|
+
var schemasFor = (table) => {
|
|
520
|
+
const cache = getSchemaCache(table);
|
|
521
|
+
if (cache.schemas !== undefined) {
|
|
522
|
+
return cache.schemas;
|
|
523
|
+
}
|
|
524
|
+
const schemas = {};
|
|
525
|
+
Object.defineProperties(schemas, {
|
|
526
|
+
select: {
|
|
527
|
+
enumerable: true,
|
|
528
|
+
get: () => selectSchema2(table)
|
|
529
|
+
},
|
|
530
|
+
insert: {
|
|
531
|
+
enumerable: true,
|
|
532
|
+
get: () => insertSchema2(table)
|
|
533
|
+
},
|
|
534
|
+
update: {
|
|
535
|
+
enumerable: true,
|
|
536
|
+
get: () => updateSchema2(table)
|
|
537
|
+
}
|
|
538
|
+
});
|
|
539
|
+
cache.schemas = schemas;
|
|
540
|
+
return schemas;
|
|
541
|
+
};
|
|
542
|
+
var defineSchemasGetter = (table) => {
|
|
543
|
+
Object.defineProperty(table, "schemas", {
|
|
544
|
+
configurable: true,
|
|
545
|
+
enumerable: true,
|
|
546
|
+
get() {
|
|
547
|
+
return schemasFor(table);
|
|
548
|
+
}
|
|
549
|
+
});
|
|
550
|
+
};
|
|
551
|
+
var makeTable = (name, fields, declaredOptions, baseName = name, kind = "schema", schemaName, schemaMode = "default", casing) => {
|
|
414
552
|
const resolvedSchemaName = schemaMode === "explicit" ? schemaName : "public";
|
|
415
|
-
const artifacts = buildArtifacts(name, fields, declaredOptions, resolvedSchemaName);
|
|
553
|
+
const artifacts = buildArtifacts(name, fields, declaredOptions, resolvedSchemaName, casing);
|
|
416
554
|
const dialect = resolveFieldDialect(fields);
|
|
417
|
-
const table =
|
|
555
|
+
const table = attachPipe3(Object.create(TableProto));
|
|
418
556
|
table.name = name;
|
|
419
557
|
table.columns = artifacts.columns;
|
|
420
|
-
table
|
|
421
|
-
table[
|
|
558
|
+
defineSchemasGetter(table);
|
|
559
|
+
table[TypeId6] = {
|
|
422
560
|
name,
|
|
423
561
|
baseName,
|
|
424
562
|
schemaName: resolvedSchemaName,
|
|
425
563
|
fields,
|
|
426
564
|
primaryKey: artifacts.primaryKey,
|
|
427
|
-
kind
|
|
565
|
+
kind,
|
|
566
|
+
casing
|
|
428
567
|
};
|
|
429
568
|
table[TypeId] = {
|
|
430
569
|
selection: artifacts.columns,
|
|
@@ -455,22 +594,17 @@ var applyDeclaredOptions = (table, declaredOptions) => {
|
|
|
455
594
|
}
|
|
456
595
|
return declaredOptions.reduce((current, option) => option(current), table);
|
|
457
596
|
};
|
|
458
|
-
var validateClassOptions = (declaredOptions) => {
|
|
459
|
-
for (const option of declaredOptions) {
|
|
460
|
-
if (option.kind === "primaryKey") {
|
|
461
|
-
throw new Error("Table.Class does not support table-level primary keys; declare primary keys inline on columns");
|
|
462
|
-
}
|
|
463
|
-
}
|
|
464
|
-
};
|
|
465
597
|
var resolveFieldDialect = (fields) => {
|
|
466
598
|
const dialects = [...new Set(Object.values(fields).map((field) => field.metadata.dbType.dialect))];
|
|
467
599
|
if (dialects.length === 0) {
|
|
468
600
|
throw new Error("Cannot infer table dialect from an empty field set");
|
|
469
601
|
}
|
|
470
|
-
|
|
602
|
+
const concreteDialects = dialects.filter((dialect) => dialect !== "standard");
|
|
603
|
+
const uniqueConcreteDialects = [...new Set(concreteDialects)];
|
|
604
|
+
if (uniqueConcreteDialects.length > 1) {
|
|
471
605
|
throw new Error(`Mixed table dialects are not supported: ${dialects.join(", ")}`);
|
|
472
606
|
}
|
|
473
|
-
return
|
|
607
|
+
return uniqueConcreteDialects[0] ?? "standard";
|
|
474
608
|
};
|
|
475
609
|
var validateFieldDialects = (tableName, fields) => {
|
|
476
610
|
try {
|
|
@@ -484,15 +618,13 @@ var ensureClassArtifacts = (self) => {
|
|
|
484
618
|
if (cached) {
|
|
485
619
|
return cached;
|
|
486
620
|
}
|
|
487
|
-
const state = self[
|
|
621
|
+
const state = self[TypeId6];
|
|
488
622
|
const classOptions = self[options];
|
|
489
|
-
|
|
490
|
-
const table = applyDeclaredOptions(makeTable(state.name, state.fields, [], state.name, "schema", state.schemaName, state.schemaName === undefined || state.schemaName === "public" ? "default" : "explicit"), classOptions);
|
|
623
|
+
const table = applyDeclaredOptions(makeTable(state.name, state.fields, [], state.name, "schema", state.schemaName, state.schemaName === undefined || state.schemaName === "public" ? "default" : "explicit", state.casing), classOptions);
|
|
491
624
|
const artifacts = {
|
|
492
625
|
columns: table.columns,
|
|
493
|
-
schemas: table.schemas,
|
|
494
626
|
normalizedOptions: table[OptionsSymbol],
|
|
495
|
-
primaryKey: table[
|
|
627
|
+
primaryKey: table[TypeId6].primaryKey
|
|
496
628
|
};
|
|
497
629
|
Object.defineProperty(self, CacheSymbol, {
|
|
498
630
|
configurable: true,
|
|
@@ -501,40 +633,40 @@ var ensureClassArtifacts = (self) => {
|
|
|
501
633
|
return artifacts;
|
|
502
634
|
};
|
|
503
635
|
var appendOption = (table, option) => {
|
|
504
|
-
const state = table[
|
|
505
|
-
|
|
506
|
-
throw new Error("Table options can only be applied to schema tables, not aliased query sources");
|
|
507
|
-
}
|
|
508
|
-
return makeTable(state.name, state.fields, [...table[DeclaredOptionsSymbol], option], state.baseName, state.kind, state.schemaName, "explicit");
|
|
636
|
+
const state = table[TypeId6];
|
|
637
|
+
return makeTable(state.name, state.fields, [...table[DeclaredOptionsSymbol], option], state.baseName, state.kind, state.schemaName, "explicit", state.casing);
|
|
509
638
|
};
|
|
510
639
|
var makeOption = (option) => {
|
|
511
|
-
|
|
512
|
-
builder.option = option;
|
|
513
|
-
return builder;
|
|
640
|
+
return attachPipe3(Object.assign((table, ..._validation) => appendOption(table, option), { option }));
|
|
514
641
|
};
|
|
515
642
|
var option = (spec) => makeOption(spec);
|
|
516
|
-
function
|
|
643
|
+
function make(name, fields, schemaName) {
|
|
517
644
|
const resolvedSchemaName = arguments.length >= 3 ? schemaName : "public";
|
|
518
645
|
return makeTable(name, fields, [], name, "schema", resolvedSchemaName, arguments.length >= 3 ? "explicit" : "default");
|
|
519
646
|
}
|
|
520
|
-
var
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
}
|
|
647
|
+
var withCasing = (table, casing) => {
|
|
648
|
+
const state = table[TypeId6];
|
|
649
|
+
return makeTable(state.name, state.fields, table[DeclaredOptionsSymbol], state.baseName, state.kind, state.schemaName, "explicit", merge(state.casing, casing));
|
|
650
|
+
};
|
|
651
|
+
var withSchema = (table, schemaName, schemaCasing) => {
|
|
652
|
+
const state = table[TypeId6];
|
|
653
|
+
return makeTable(state.name, state.fields, table[DeclaredOptionsSymbol], state.baseName, state.kind, schemaName, "explicit", merge(schemaCasing, state.casing));
|
|
654
|
+
};
|
|
524
655
|
var alias = (table, aliasName) => {
|
|
525
|
-
const state = table[
|
|
526
|
-
const columns = Object.fromEntries(Object.entries(state.fields).map(([key, column]) => [key, bindColumn(aliasName, key, column, state.baseName, state.schemaName)]));
|
|
527
|
-
const aliased =
|
|
656
|
+
const state = table[TypeId6];
|
|
657
|
+
const columns = Object.fromEntries(Object.entries(state.fields).map(([key, column]) => [key, bindColumn(aliasName, key, column, state.baseName, state.schemaName, state.casing)]));
|
|
658
|
+
const aliased = attachPipe3(Object.create(TableProto));
|
|
528
659
|
aliased.name = aliasName;
|
|
529
660
|
aliased.columns = columns;
|
|
530
|
-
aliased
|
|
531
|
-
aliased[
|
|
661
|
+
defineSchemasGetter(aliased);
|
|
662
|
+
aliased[TypeId6] = {
|
|
532
663
|
name: aliasName,
|
|
533
664
|
baseName: state.baseName,
|
|
534
665
|
schemaName: state.schemaName,
|
|
535
666
|
fields: state.fields,
|
|
536
667
|
primaryKey: state.primaryKey,
|
|
537
|
-
kind: "alias"
|
|
668
|
+
kind: "alias",
|
|
669
|
+
casing: state.casing
|
|
538
670
|
};
|
|
539
671
|
aliased[TypeId] = {
|
|
540
672
|
selection: columns,
|
|
@@ -568,11 +700,10 @@ function Class(name, schemaName) {
|
|
|
568
700
|
return ensureClassArtifacts(this).columns;
|
|
569
701
|
}
|
|
570
702
|
static get schemas() {
|
|
571
|
-
return
|
|
703
|
+
return schemasFor(this);
|
|
572
704
|
}
|
|
573
|
-
static get [
|
|
705
|
+
static get [TypeId6]() {
|
|
574
706
|
const declaredOptions = extractDeclaredOptions(this[options]);
|
|
575
|
-
validateClassOptions(declaredOptions);
|
|
576
707
|
return {
|
|
577
708
|
name,
|
|
578
709
|
baseName: name,
|
|
@@ -601,7 +732,7 @@ function Class(name, schemaName) {
|
|
|
601
732
|
return ensureClassArtifacts(this).normalizedOptions;
|
|
602
733
|
}
|
|
603
734
|
static pipe() {
|
|
604
|
-
return
|
|
735
|
+
return pipeArguments3(this, arguments);
|
|
605
736
|
}
|
|
606
737
|
}
|
|
607
738
|
for (const key of Object.keys(fields)) {
|
|
@@ -632,10 +763,11 @@ var foreignKey = (columns, target, referencedColumns) => makeOption({
|
|
|
632
763
|
kind: "foreignKey",
|
|
633
764
|
columns: normalizeColumnList(columns),
|
|
634
765
|
references: () => ({
|
|
635
|
-
tableName: target()[
|
|
636
|
-
schemaName: target()[
|
|
766
|
+
tableName: target()[TypeId6].baseName,
|
|
767
|
+
schemaName: target()[TypeId6].schemaName,
|
|
768
|
+
casing: target()[TypeId6].casing,
|
|
637
769
|
columns: normalizeColumnList(referencedColumns),
|
|
638
|
-
knownColumns: Object.keys(target()[
|
|
770
|
+
knownColumns: Object.keys(target()[TypeId6].fields).map((key) => key)
|
|
639
771
|
})
|
|
640
772
|
});
|
|
641
773
|
var check = (name, predicate) => makeOption({
|
|
@@ -644,63 +776,34 @@ var check = (name, predicate) => makeOption({
|
|
|
644
776
|
predicate
|
|
645
777
|
});
|
|
646
778
|
|
|
647
|
-
// src/internal/
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
var TypeId5 = Symbol.for("effect-qb/SchemaExpression");
|
|
651
|
-
var SchemaExpressionProto = {
|
|
652
|
-
pipe() {
|
|
653
|
-
return pipeArguments3(this, arguments);
|
|
654
|
-
}
|
|
655
|
-
};
|
|
656
|
-
var attachPipe3 = (value) => {
|
|
657
|
-
Object.defineProperty(value, "pipe", {
|
|
658
|
-
configurable: true,
|
|
659
|
-
writable: true,
|
|
660
|
-
value: function() {
|
|
661
|
-
return pipeArguments3(value, arguments);
|
|
662
|
-
}
|
|
663
|
-
});
|
|
664
|
-
return value;
|
|
779
|
+
// src/internal/sql-expression-renderer.ts
|
|
780
|
+
var renderQueryAst = (ast, state, dialect) => {
|
|
781
|
+
return dialect.renderQueryAst(ast, state, dialect);
|
|
665
782
|
};
|
|
666
|
-
var
|
|
667
|
-
|
|
668
|
-
const expression = attachPipe3(Object.create(SchemaExpressionProto));
|
|
669
|
-
expression[TypeId5] = {
|
|
670
|
-
ast
|
|
671
|
-
};
|
|
672
|
-
return expression;
|
|
783
|
+
var renderExpression = (expression, state, dialect) => {
|
|
784
|
+
return dialect.renderExpression(expression, state, dialect);
|
|
673
785
|
};
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
786
|
+
|
|
787
|
+
// src/postgres/internal/schema-ddl.ts
|
|
788
|
+
import { parse as parse2, toSql as toSql2 } from "pgsql-ast-parser";
|
|
789
|
+
|
|
790
|
+
// src/internal/dialect.ts
|
|
791
|
+
var quoteDoubleQuotedIdentifier = (value) => {
|
|
792
|
+
return `"${value.replaceAll('"', '""')}"`;
|
|
680
793
|
};
|
|
681
|
-
var
|
|
682
|
-
|
|
683
|
-
const ast = expression[TypeId5].ast;
|
|
684
|
-
if (ast !== undefined) {
|
|
685
|
-
return ast;
|
|
686
|
-
}
|
|
687
|
-
return parse(render(expression), "expr");
|
|
794
|
+
var quoteBacktickIdentifier = (value) => {
|
|
795
|
+
return `\`${value.replaceAll("`", "``")}\``;
|
|
688
796
|
};
|
|
689
|
-
var
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
return parseExpression(sql);
|
|
694
|
-
} catch {
|
|
695
|
-
return fromSql(sql);
|
|
696
|
-
}
|
|
697
|
-
})();
|
|
797
|
+
var renderDbTypeName = (value) => value;
|
|
798
|
+
|
|
799
|
+
// src/internal/dialect-renderers/postgres.ts
|
|
800
|
+
import * as Schema5 from "effect/Schema";
|
|
698
801
|
|
|
699
802
|
// src/internal/query.ts
|
|
700
803
|
import { pipeArguments as pipeArguments4 } from "effect/Pipeable";
|
|
701
804
|
|
|
702
805
|
// src/internal/query-ast.ts
|
|
703
|
-
var
|
|
806
|
+
var TypeId7 = Symbol.for("effect-qb/QueryAst");
|
|
704
807
|
|
|
705
808
|
// src/internal/predicate/runtime.ts
|
|
706
809
|
var trueFormula = () => ({ kind: "true" });
|
|
@@ -732,7 +835,18 @@ var cloneContext = (context) => ({
|
|
|
732
835
|
unknown: context.unknown
|
|
733
836
|
});
|
|
734
837
|
var freezeContext = (context) => context;
|
|
735
|
-
var
|
|
838
|
+
var columnPredicateKey = (tableName, columnName) => JSON.stringify([tableName, columnName]);
|
|
839
|
+
var columnPredicateKeyParts = (key) => {
|
|
840
|
+
const jsonSeparator = key.indexOf("#json:");
|
|
841
|
+
const columnKey = jsonSeparator === -1 ? key : key.slice(0, jsonSeparator);
|
|
842
|
+
try {
|
|
843
|
+
const parsed = JSON.parse(columnKey);
|
|
844
|
+
return Array.isArray(parsed) && parsed.length === 2 && typeof parsed[0] === "string" && typeof parsed[1] === "string" ? [parsed[0], parsed[1]] : undefined;
|
|
845
|
+
} catch {
|
|
846
|
+
return;
|
|
847
|
+
}
|
|
848
|
+
};
|
|
849
|
+
var sourceNameOfKey = (key) => columnPredicateKeyParts(key)?.[0] ?? key.split(".", 1)[0] ?? key;
|
|
736
850
|
var addSourceName = (context, key) => {
|
|
737
851
|
context.sourceNames.add(sourceNameOfKey(key));
|
|
738
852
|
};
|
|
@@ -982,9 +1096,10 @@ var analyzeFormula = (formula) => freezeContext(analyzeStack(emptyContext(), [{
|
|
|
982
1096
|
var astOf = (value) => value[TypeId3];
|
|
983
1097
|
var columnKeyOfExpression = (value) => {
|
|
984
1098
|
const ast = astOf(value);
|
|
985
|
-
return ast.kind === "column" ?
|
|
1099
|
+
return ast.kind === "column" ? columnPredicateKey(ast.tableName, ast.columnName) : undefined;
|
|
986
1100
|
};
|
|
987
1101
|
var sameDbType = (left, right) => left.dialect === right.dialect && left.kind === right.kind;
|
|
1102
|
+
var escapeJsonPathPredicateKeySegment = (value) => value.replaceAll("\\", "\\\\").replaceAll(".", "\\.");
|
|
988
1103
|
var jsonPathPredicateKeyOfExpression = (value) => {
|
|
989
1104
|
const ast = astOf(value);
|
|
990
1105
|
switch (ast.kind) {
|
|
@@ -1008,7 +1123,7 @@ var jsonPathPredicateKeyOfExpression = (value) => {
|
|
|
1008
1123
|
return;
|
|
1009
1124
|
}
|
|
1010
1125
|
const baseKey = columnKeyOfExpression(jsonAst.base);
|
|
1011
|
-
return baseKey === undefined ? undefined : `${baseKey}#json:${path.join(".")}`;
|
|
1126
|
+
return baseKey === undefined ? undefined : `${baseKey}#json:${path.map(escapeJsonPathPredicateKeySegment).join(".")}`;
|
|
1012
1127
|
}
|
|
1013
1128
|
default:
|
|
1014
1129
|
return;
|
|
@@ -1037,6 +1152,9 @@ var valueKeyOfLiteral = (value) => {
|
|
|
1037
1152
|
return "null";
|
|
1038
1153
|
}
|
|
1039
1154
|
if (value instanceof Date) {
|
|
1155
|
+
if (Number.isNaN(value.getTime())) {
|
|
1156
|
+
throw new Error("Expected a valid Date value");
|
|
1157
|
+
}
|
|
1040
1158
|
return `date:${value.toISOString()}`;
|
|
1041
1159
|
}
|
|
1042
1160
|
return "unknown";
|
|
@@ -1372,7 +1490,7 @@ var makePlan = (state, ast, _assumptions, _capabilities, _statement, _target, _i
|
|
|
1372
1490
|
}
|
|
1373
1491
|
});
|
|
1374
1492
|
plan[TypeId] = state;
|
|
1375
|
-
plan[
|
|
1493
|
+
plan[TypeId7] = ast;
|
|
1376
1494
|
plan[QueryTypeId] = {
|
|
1377
1495
|
required: undefined,
|
|
1378
1496
|
availableNames: undefined,
|
|
@@ -1386,7 +1504,7 @@ var makePlan = (state, ast, _assumptions, _capabilities, _statement, _target, _i
|
|
|
1386
1504
|
};
|
|
1387
1505
|
return plan;
|
|
1388
1506
|
};
|
|
1389
|
-
var getAst = (plan) => plan[
|
|
1507
|
+
var getAst = (plan) => plan[TypeId7];
|
|
1390
1508
|
var getQueryState = (plan) => plan[QueryTypeId];
|
|
1391
1509
|
var extractRequiredRuntime = (selection) => {
|
|
1392
1510
|
const required = new Set;
|
|
@@ -1405,22 +1523,14 @@ var extractRequiredRuntime = (selection) => {
|
|
|
1405
1523
|
return [...required];
|
|
1406
1524
|
};
|
|
1407
1525
|
var extractSingleSelectedExpressionRuntime = (selection) => {
|
|
1408
|
-
const keys = Object.keys(selection);
|
|
1409
|
-
if (keys.length !== 1) {
|
|
1410
|
-
throw new Error("scalar subqueries must select exactly one top-level expression");
|
|
1411
|
-
}
|
|
1412
1526
|
const record = selection;
|
|
1413
|
-
|
|
1414
|
-
if (value === null || typeof value !== "object" || !(TypeId2 in value)) {
|
|
1415
|
-
throw new Error("scalar subqueries must select a scalar expression");
|
|
1416
|
-
}
|
|
1417
|
-
return value;
|
|
1527
|
+
return record[Object.keys(record)[0]];
|
|
1418
1528
|
};
|
|
1419
1529
|
var currentRequiredList = (required) => Array.isArray(required) ? [...required] : required === undefined ? [] : [required];
|
|
1420
1530
|
|
|
1421
1531
|
// src/internal/json/path.ts
|
|
1422
1532
|
var SegmentTypeId = Symbol.for("effect-qb/JsonPathSegment");
|
|
1423
|
-
var
|
|
1533
|
+
var TypeId8 = Symbol.for("effect-qb/JsonPath");
|
|
1424
1534
|
var makeSegment = (segment) => segment;
|
|
1425
1535
|
var key = (value) => makeSegment({
|
|
1426
1536
|
[SegmentTypeId]: {
|
|
@@ -1457,87 +1567,1002 @@ var descend = () => makeSegment({
|
|
|
1457
1567
|
kind: "descend"
|
|
1458
1568
|
});
|
|
1459
1569
|
var path = (...segments) => ({
|
|
1460
|
-
[
|
|
1570
|
+
[TypeId8]: {
|
|
1461
1571
|
segments
|
|
1462
1572
|
},
|
|
1463
1573
|
segments
|
|
1464
1574
|
});
|
|
1465
1575
|
|
|
1466
|
-
// src/internal/
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
const
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
}
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1576
|
+
// src/internal/dsl-plan-runtime.ts
|
|
1577
|
+
var renderSelectLockMode = (mode) => mode === "update" ? "for update" : "for share";
|
|
1578
|
+
var renderMysqlMutationLockMode = (mode, _statement) => {
|
|
1579
|
+
if (mode === "lowPriority") {
|
|
1580
|
+
return " low_priority";
|
|
1581
|
+
}
|
|
1582
|
+
return mode === "ignore" ? " ignore" : " quick";
|
|
1583
|
+
};
|
|
1584
|
+
var makeDslPlanRuntime = (ctx) => {
|
|
1585
|
+
const sourceRequiredList = (source) => typeof source === "object" && source !== null && ("required" in source) ? ctx.currentRequiredList(source.required) : [];
|
|
1586
|
+
const buildSetOperation = (kind, all, left, right) => {
|
|
1587
|
+
const leftState = left[TypeId];
|
|
1588
|
+
const leftAst = ctx.getAst(left);
|
|
1589
|
+
const basePlan = leftAst.kind === "set" ? leftAst.setBase ?? left : left;
|
|
1590
|
+
const leftOperations = leftAst.kind === "set" ? [...leftAst.setOperations ?? []] : [];
|
|
1591
|
+
return ctx.makePlan({
|
|
1592
|
+
selection: leftState.selection,
|
|
1593
|
+
required: undefined,
|
|
1594
|
+
available: {},
|
|
1595
|
+
dialect: leftState.dialect ?? right[TypeId].dialect
|
|
1596
|
+
}, {
|
|
1597
|
+
kind: "set",
|
|
1598
|
+
select: leftState.selection,
|
|
1599
|
+
where: [],
|
|
1600
|
+
having: [],
|
|
1601
|
+
joins: [],
|
|
1602
|
+
groupBy: [],
|
|
1603
|
+
orderBy: [],
|
|
1604
|
+
setBase: basePlan,
|
|
1605
|
+
setOperations: [
|
|
1606
|
+
...leftOperations,
|
|
1607
|
+
{
|
|
1608
|
+
kind,
|
|
1609
|
+
all,
|
|
1610
|
+
query: right
|
|
1611
|
+
}
|
|
1612
|
+
]
|
|
1613
|
+
}, undefined, undefined, "set");
|
|
1614
|
+
};
|
|
1615
|
+
const where = (predicate) => (plan) => {
|
|
1616
|
+
const current = plan[TypeId];
|
|
1617
|
+
const currentAst = ctx.getAst(plan);
|
|
1618
|
+
const currentQuery = ctx.getQueryState(plan);
|
|
1619
|
+
const predicateExpression = ctx.toDialectExpression(predicate);
|
|
1620
|
+
const predicateRequired = ctx.extractRequiredFromDialectInputRuntime(predicate);
|
|
1621
|
+
return ctx.makePlan({
|
|
1622
|
+
selection: current.selection,
|
|
1623
|
+
required: [...ctx.currentRequiredList(current.required), ...predicateRequired].filter((name, index3, values) => !(name in current.available) && values.indexOf(name) === index3),
|
|
1624
|
+
available: current.available,
|
|
1625
|
+
dialect: current.dialect ?? predicateExpression[TypeId2].dialect
|
|
1626
|
+
}, {
|
|
1627
|
+
...currentAst,
|
|
1628
|
+
where: [...currentAst.where, {
|
|
1629
|
+
kind: "where",
|
|
1630
|
+
predicate: predicateExpression
|
|
1631
|
+
}]
|
|
1632
|
+
}, ctx.assumeFormulaTrue(currentQuery.assumptions, ctx.formulaOfExpressionRuntime(predicateExpression)), currentQuery.capabilities, currentQuery.statement);
|
|
1633
|
+
};
|
|
1634
|
+
const from = (source) => (plan) => {
|
|
1635
|
+
const current = plan[TypeId];
|
|
1636
|
+
const currentAst = ctx.getAst(plan);
|
|
1637
|
+
const currentQuery = ctx.getQueryState(plan);
|
|
1638
|
+
if (currentQuery.statement === "insert") {
|
|
1639
|
+
return ctx.attachInsertSource(plan, source);
|
|
1517
1640
|
}
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
const
|
|
1521
|
-
|
|
1522
|
-
|
|
1641
|
+
const sourceLike = source;
|
|
1642
|
+
const { sourceName, sourceBaseName } = ctx.sourceDetails(sourceLike);
|
|
1643
|
+
const presenceWitnesses = ctx.presenceWitnessesOfSourceLike(sourceLike);
|
|
1644
|
+
const sourceRequired = sourceRequiredList(sourceLike);
|
|
1645
|
+
if (currentQuery.statement === "select") {
|
|
1646
|
+
const nextAvailable = {
|
|
1647
|
+
[sourceName]: {
|
|
1648
|
+
name: sourceName,
|
|
1649
|
+
mode: "required",
|
|
1650
|
+
baseName: sourceBaseName,
|
|
1651
|
+
_presentFormula: ctx.trueFormula(),
|
|
1652
|
+
_presenceWitnesses: presenceWitnesses
|
|
1653
|
+
}
|
|
1654
|
+
};
|
|
1655
|
+
return ctx.makePlan({
|
|
1656
|
+
selection: current.selection,
|
|
1657
|
+
required: [...ctx.currentRequiredList(current.required), ...sourceRequired].filter((name, index3, values) => !(name in nextAvailable) && values.indexOf(name) === index3),
|
|
1658
|
+
available: nextAvailable,
|
|
1659
|
+
dialect: current.dialect
|
|
1660
|
+
}, {
|
|
1661
|
+
...currentAst,
|
|
1662
|
+
from: {
|
|
1663
|
+
kind: "from",
|
|
1664
|
+
tableName: sourceName,
|
|
1665
|
+
baseTableName: sourceBaseName,
|
|
1666
|
+
source: sourceLike
|
|
1667
|
+
}
|
|
1668
|
+
}, currentQuery.assumptions, currentQuery.capabilities, currentQuery.statement);
|
|
1523
1669
|
}
|
|
1524
|
-
if (
|
|
1525
|
-
|
|
1670
|
+
if (currentQuery.statement === "update") {
|
|
1671
|
+
const nextAvailable = {
|
|
1672
|
+
...current.available,
|
|
1673
|
+
[sourceName]: {
|
|
1674
|
+
name: sourceName,
|
|
1675
|
+
mode: "required",
|
|
1676
|
+
baseName: sourceBaseName,
|
|
1677
|
+
_presentFormula: ctx.trueFormula(),
|
|
1678
|
+
_presenceWitnesses: presenceWitnesses
|
|
1679
|
+
}
|
|
1680
|
+
};
|
|
1681
|
+
return ctx.makePlan({
|
|
1682
|
+
selection: current.selection,
|
|
1683
|
+
required: [...ctx.currentRequiredList(current.required), ...sourceRequired].filter((name, index3, values) => !(name in nextAvailable) && values.indexOf(name) === index3),
|
|
1684
|
+
available: nextAvailable,
|
|
1685
|
+
dialect: current.dialect
|
|
1686
|
+
}, {
|
|
1687
|
+
...currentAst,
|
|
1688
|
+
fromSources: [
|
|
1689
|
+
...currentAst.fromSources ?? [],
|
|
1690
|
+
{
|
|
1691
|
+
kind: "from",
|
|
1692
|
+
tableName: sourceName,
|
|
1693
|
+
baseTableName: sourceBaseName,
|
|
1694
|
+
source: sourceLike
|
|
1695
|
+
}
|
|
1696
|
+
]
|
|
1697
|
+
}, currentQuery.assumptions, currentQuery.capabilities, currentQuery.statement);
|
|
1526
1698
|
}
|
|
1527
|
-
|
|
1528
|
-
|
|
1699
|
+
return plan;
|
|
1700
|
+
};
|
|
1701
|
+
const having = (predicate) => (plan) => {
|
|
1702
|
+
const current = plan[TypeId];
|
|
1703
|
+
const currentAst = ctx.getAst(plan);
|
|
1704
|
+
const currentQuery = ctx.getQueryState(plan);
|
|
1705
|
+
const predicateExpression = ctx.toDialectExpression(predicate);
|
|
1706
|
+
const predicateRequired = ctx.extractRequiredFromDialectInputRuntime(predicate);
|
|
1707
|
+
return ctx.makePlan({
|
|
1708
|
+
selection: current.selection,
|
|
1709
|
+
required: [...ctx.currentRequiredList(current.required), ...predicateRequired].filter((name, index3, values) => !(name in current.available) && values.indexOf(name) === index3),
|
|
1710
|
+
available: current.available,
|
|
1711
|
+
dialect: current.dialect ?? predicateExpression[TypeId2].dialect
|
|
1712
|
+
}, {
|
|
1713
|
+
...currentAst,
|
|
1714
|
+
having: [...currentAst.having, {
|
|
1715
|
+
kind: "having",
|
|
1716
|
+
predicate: predicateExpression
|
|
1717
|
+
}]
|
|
1718
|
+
}, ctx.assumeFormulaTrue(currentQuery.assumptions, ctx.formulaOfExpressionRuntime(predicateExpression)), currentQuery.capabilities, currentQuery.statement);
|
|
1719
|
+
};
|
|
1720
|
+
const crossJoin = (table) => (plan) => {
|
|
1721
|
+
const current = plan[TypeId];
|
|
1722
|
+
const currentAst = ctx.getAst(plan);
|
|
1723
|
+
const currentQuery = ctx.getQueryState(plan);
|
|
1724
|
+
const { sourceName, sourceBaseName } = ctx.sourceDetails(table);
|
|
1725
|
+
const presenceWitnesses = ctx.presenceWitnessesOfSourceLike(table);
|
|
1726
|
+
const sourceRequired = sourceRequiredList(table);
|
|
1727
|
+
const nextAvailable = {
|
|
1728
|
+
...current.available,
|
|
1729
|
+
[sourceName]: {
|
|
1730
|
+
name: sourceName,
|
|
1731
|
+
mode: "required",
|
|
1732
|
+
baseName: sourceBaseName,
|
|
1733
|
+
_presentFormula: ctx.trueFormula(),
|
|
1734
|
+
_presenceWitnesses: presenceWitnesses
|
|
1735
|
+
}
|
|
1736
|
+
};
|
|
1737
|
+
return ctx.makePlan({
|
|
1738
|
+
selection: current.selection,
|
|
1739
|
+
required: [...ctx.currentRequiredList(current.required), ...sourceRequired].filter((name, index3, values) => !(name in nextAvailable) && values.indexOf(name) === index3),
|
|
1740
|
+
available: nextAvailable,
|
|
1741
|
+
dialect: current.dialect ?? table[TypeId]?.dialect ?? table.dialect
|
|
1742
|
+
}, {
|
|
1743
|
+
...currentAst,
|
|
1744
|
+
joins: [...currentAst.joins, {
|
|
1745
|
+
kind: "cross",
|
|
1746
|
+
tableName: sourceName,
|
|
1747
|
+
baseTableName: sourceBaseName,
|
|
1748
|
+
source: table
|
|
1749
|
+
}]
|
|
1750
|
+
}, currentQuery.assumptions, currentQuery.capabilities, currentQuery.statement);
|
|
1751
|
+
};
|
|
1752
|
+
const join = (kind, table, on) => (plan) => {
|
|
1753
|
+
const current = plan[TypeId];
|
|
1754
|
+
const currentAst = ctx.getAst(plan);
|
|
1755
|
+
const currentQuery = ctx.getQueryState(plan);
|
|
1756
|
+
const onExpression = ctx.toDialectExpression(on);
|
|
1757
|
+
const onFormula = ctx.formulaOfExpressionRuntime(onExpression);
|
|
1758
|
+
const { sourceName, sourceBaseName } = ctx.sourceDetails(table);
|
|
1759
|
+
const presenceWitnesses = ctx.presenceWitnessesOfSourceLike(table);
|
|
1760
|
+
const sourceRequired = sourceRequiredList(table);
|
|
1761
|
+
const baseAvailable = kind === "right" || kind === "full" ? Object.fromEntries(Object.entries(current.available).map(([name, source]) => [name, {
|
|
1762
|
+
name: source.name,
|
|
1763
|
+
mode: "optional",
|
|
1764
|
+
baseName: source.baseName,
|
|
1765
|
+
_presentFormula: source._presentFormula,
|
|
1766
|
+
_presenceWitnesses: source._presenceWitnesses
|
|
1767
|
+
}])) : current.available;
|
|
1768
|
+
const nextAvailable = {
|
|
1769
|
+
...baseAvailable,
|
|
1770
|
+
[sourceName]: {
|
|
1771
|
+
name: sourceName,
|
|
1772
|
+
mode: kind === "left" || kind === "full" ? "optional" : "required",
|
|
1773
|
+
baseName: sourceBaseName,
|
|
1774
|
+
_presentFormula: kind === "inner" || kind === "left" ? onFormula : ctx.trueFormula(),
|
|
1775
|
+
_presenceWitnesses: presenceWitnesses
|
|
1776
|
+
}
|
|
1777
|
+
};
|
|
1778
|
+
return ctx.makePlan({
|
|
1779
|
+
selection: current.selection,
|
|
1780
|
+
required: [...ctx.currentRequiredList(current.required), ...sourceRequired, ...ctx.extractRequiredFromDialectInputRuntime(on)].filter((name, index3, values) => !(name in nextAvailable) && values.indexOf(name) === index3),
|
|
1781
|
+
available: nextAvailable,
|
|
1782
|
+
dialect: current.dialect ?? table.dialect ?? onExpression[TypeId2].dialect
|
|
1783
|
+
}, {
|
|
1784
|
+
...currentAst,
|
|
1785
|
+
joins: [...currentAst.joins, {
|
|
1786
|
+
kind,
|
|
1787
|
+
tableName: sourceName,
|
|
1788
|
+
baseTableName: sourceBaseName,
|
|
1789
|
+
source: table,
|
|
1790
|
+
on: onExpression
|
|
1791
|
+
}]
|
|
1792
|
+
}, kind === "inner" ? ctx.assumeFormulaTrue(currentQuery.assumptions, onFormula) : currentQuery.assumptions, currentQuery.capabilities, currentQuery.statement);
|
|
1793
|
+
};
|
|
1794
|
+
const orderBy = (value, direction = "asc") => (plan) => {
|
|
1795
|
+
const current = plan[TypeId];
|
|
1796
|
+
const currentAst = ctx.getAst(plan);
|
|
1797
|
+
const currentQuery = ctx.getQueryState(plan);
|
|
1798
|
+
const expression = ctx.toDialectExpression(value);
|
|
1799
|
+
const required = ctx.extractRequiredFromDialectInputRuntime(value);
|
|
1800
|
+
return ctx.makePlan({
|
|
1801
|
+
selection: current.selection,
|
|
1802
|
+
required: [...ctx.currentRequiredList(current.required), ...required].filter((name, index3, values) => !(name in current.available) && values.indexOf(name) === index3),
|
|
1803
|
+
available: current.available,
|
|
1804
|
+
dialect: current.dialect ?? expression[TypeId2].dialect
|
|
1805
|
+
}, {
|
|
1806
|
+
...currentAst,
|
|
1807
|
+
orderBy: [...currentAst.orderBy, {
|
|
1808
|
+
kind: "orderBy",
|
|
1809
|
+
value: expression,
|
|
1810
|
+
direction
|
|
1811
|
+
}]
|
|
1812
|
+
}, currentQuery.assumptions, currentQuery.capabilities, currentQuery.statement);
|
|
1813
|
+
};
|
|
1814
|
+
const lock = (mode, options2 = {}) => (plan) => {
|
|
1815
|
+
const current = plan[TypeId];
|
|
1816
|
+
const currentAst = ctx.getAst(plan);
|
|
1817
|
+
const currentQuery = ctx.getQueryState(plan);
|
|
1818
|
+
return ctx.makePlan({
|
|
1819
|
+
selection: current.selection,
|
|
1820
|
+
required: current.required,
|
|
1821
|
+
available: current.available,
|
|
1822
|
+
dialect: current.dialect
|
|
1823
|
+
}, {
|
|
1824
|
+
...currentAst,
|
|
1825
|
+
lock: {
|
|
1826
|
+
kind: "lock",
|
|
1827
|
+
mode,
|
|
1828
|
+
nowait: options2.nowait ?? false,
|
|
1829
|
+
skipLocked: options2.skipLocked ?? false
|
|
1830
|
+
}
|
|
1831
|
+
}, currentQuery.assumptions, currentQuery.capabilities, currentQuery.statement);
|
|
1832
|
+
};
|
|
1833
|
+
const distinct = () => (plan) => {
|
|
1834
|
+
const current = plan[TypeId];
|
|
1835
|
+
const currentAst = ctx.getAst(plan);
|
|
1836
|
+
const currentQuery = ctx.getQueryState(plan);
|
|
1837
|
+
return ctx.makePlan({
|
|
1838
|
+
selection: current.selection,
|
|
1839
|
+
required: current.required,
|
|
1840
|
+
available: current.available,
|
|
1841
|
+
dialect: current.dialect
|
|
1842
|
+
}, {
|
|
1843
|
+
...currentAst,
|
|
1844
|
+
distinct: true
|
|
1845
|
+
}, currentQuery.assumptions, currentQuery.capabilities, currentQuery.statement);
|
|
1846
|
+
};
|
|
1847
|
+
const limit = (value) => (plan) => {
|
|
1848
|
+
const current = plan[TypeId];
|
|
1849
|
+
const currentAst = ctx.getAst(plan);
|
|
1850
|
+
const currentQuery = ctx.getQueryState(plan);
|
|
1851
|
+
const expression = ctx.toDialectNumericExpression(value);
|
|
1852
|
+
const required = ctx.extractRequiredFromDialectNumericInputRuntime(value);
|
|
1853
|
+
return ctx.makePlan({
|
|
1854
|
+
selection: current.selection,
|
|
1855
|
+
required: [...ctx.currentRequiredList(current.required), ...required].filter((name, index3, values) => !(name in current.available) && values.indexOf(name) === index3),
|
|
1856
|
+
available: current.available,
|
|
1857
|
+
dialect: current.dialect ?? expression[TypeId2].dialect
|
|
1858
|
+
}, {
|
|
1859
|
+
...currentAst,
|
|
1860
|
+
limit: expression
|
|
1861
|
+
}, currentQuery.assumptions, currentQuery.capabilities, currentQuery.statement);
|
|
1862
|
+
};
|
|
1863
|
+
const offset = (value) => (plan) => {
|
|
1864
|
+
const current = plan[TypeId];
|
|
1865
|
+
const currentAst = ctx.getAst(plan);
|
|
1866
|
+
const currentQuery = ctx.getQueryState(plan);
|
|
1867
|
+
const expression = ctx.toDialectNumericExpression(value);
|
|
1868
|
+
const required = ctx.extractRequiredFromDialectNumericInputRuntime(value);
|
|
1869
|
+
return ctx.makePlan({
|
|
1870
|
+
selection: current.selection,
|
|
1871
|
+
required: [...ctx.currentRequiredList(current.required), ...required].filter((name, index3, values) => !(name in current.available) && values.indexOf(name) === index3),
|
|
1872
|
+
available: current.available,
|
|
1873
|
+
dialect: current.dialect ?? expression[TypeId2].dialect
|
|
1874
|
+
}, {
|
|
1875
|
+
...currentAst,
|
|
1876
|
+
offset: expression
|
|
1877
|
+
}, currentQuery.assumptions, currentQuery.capabilities, currentQuery.statement);
|
|
1878
|
+
};
|
|
1879
|
+
return {
|
|
1880
|
+
buildSetOperation,
|
|
1881
|
+
where,
|
|
1882
|
+
from,
|
|
1883
|
+
having,
|
|
1884
|
+
crossJoin,
|
|
1885
|
+
join,
|
|
1886
|
+
orderBy,
|
|
1887
|
+
lock,
|
|
1888
|
+
distinct,
|
|
1889
|
+
limit,
|
|
1890
|
+
offset
|
|
1891
|
+
};
|
|
1529
1892
|
};
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1893
|
+
|
|
1894
|
+
// src/internal/dsl-transaction-ddl-runtime.ts
|
|
1895
|
+
var renderTransactionIsolationLevel = (isolationLevel) => {
|
|
1896
|
+
if (isolationLevel === undefined) {
|
|
1897
|
+
return "";
|
|
1533
1898
|
}
|
|
1534
|
-
|
|
1535
|
-
|
|
1899
|
+
return `isolation level ${isolationLevel}`;
|
|
1900
|
+
};
|
|
1901
|
+
var expectDdlClauseKind = (ddl, _kind) => ddl;
|
|
1902
|
+
var expectTruncateClause = (truncate) => truncate;
|
|
1903
|
+
var normalizeStatementFlag = (value) => value ?? false;
|
|
1904
|
+
var normalizeStatementIdentifier = (_apiName, _identifierName, value) => value;
|
|
1905
|
+
var makeDslTransactionDdlRuntime = (ctx) => {
|
|
1906
|
+
const transaction = (options2 = {}) => {
|
|
1907
|
+
return ctx.makePlan({
|
|
1908
|
+
selection: {},
|
|
1909
|
+
required: [],
|
|
1910
|
+
available: {},
|
|
1911
|
+
dialect: ctx.profile.dialect
|
|
1912
|
+
}, {
|
|
1913
|
+
kind: "transaction",
|
|
1914
|
+
select: {},
|
|
1915
|
+
transaction: {
|
|
1916
|
+
kind: "transaction",
|
|
1917
|
+
isolationLevel: options2.isolationLevel,
|
|
1918
|
+
readOnly: options2.readOnly
|
|
1919
|
+
},
|
|
1920
|
+
where: [],
|
|
1921
|
+
having: [],
|
|
1922
|
+
joins: [],
|
|
1923
|
+
groupBy: [],
|
|
1924
|
+
orderBy: []
|
|
1925
|
+
}, undefined, "transaction", "transaction");
|
|
1926
|
+
};
|
|
1927
|
+
const commit = () => ctx.makePlan({
|
|
1928
|
+
selection: {},
|
|
1929
|
+
required: [],
|
|
1930
|
+
available: {},
|
|
1931
|
+
dialect: ctx.profile.dialect
|
|
1932
|
+
}, {
|
|
1933
|
+
kind: "commit",
|
|
1934
|
+
select: {},
|
|
1935
|
+
transaction: {
|
|
1936
|
+
kind: "commit"
|
|
1937
|
+
},
|
|
1938
|
+
where: [],
|
|
1939
|
+
having: [],
|
|
1940
|
+
joins: [],
|
|
1941
|
+
groupBy: [],
|
|
1942
|
+
orderBy: []
|
|
1943
|
+
}, undefined, "transaction", "commit");
|
|
1944
|
+
const rollback = () => ctx.makePlan({
|
|
1945
|
+
selection: {},
|
|
1946
|
+
required: [],
|
|
1947
|
+
available: {},
|
|
1948
|
+
dialect: ctx.profile.dialect
|
|
1949
|
+
}, {
|
|
1950
|
+
kind: "rollback",
|
|
1951
|
+
select: {},
|
|
1952
|
+
transaction: {
|
|
1953
|
+
kind: "rollback"
|
|
1954
|
+
},
|
|
1955
|
+
where: [],
|
|
1956
|
+
having: [],
|
|
1957
|
+
joins: [],
|
|
1958
|
+
groupBy: [],
|
|
1959
|
+
orderBy: []
|
|
1960
|
+
}, undefined, "transaction", "rollback");
|
|
1961
|
+
const savepoint = (name) => {
|
|
1962
|
+
return ctx.makePlan({
|
|
1963
|
+
selection: {},
|
|
1964
|
+
required: [],
|
|
1965
|
+
available: {},
|
|
1966
|
+
dialect: ctx.profile.dialect
|
|
1967
|
+
}, {
|
|
1968
|
+
kind: "savepoint",
|
|
1969
|
+
select: {},
|
|
1970
|
+
transaction: {
|
|
1971
|
+
kind: "savepoint",
|
|
1972
|
+
name
|
|
1973
|
+
},
|
|
1974
|
+
where: [],
|
|
1975
|
+
having: [],
|
|
1976
|
+
joins: [],
|
|
1977
|
+
groupBy: [],
|
|
1978
|
+
orderBy: []
|
|
1979
|
+
}, undefined, "transaction", "savepoint");
|
|
1980
|
+
};
|
|
1981
|
+
const rollbackTo = (name) => {
|
|
1982
|
+
return ctx.makePlan({
|
|
1983
|
+
selection: {},
|
|
1984
|
+
required: [],
|
|
1985
|
+
available: {},
|
|
1986
|
+
dialect: ctx.profile.dialect
|
|
1987
|
+
}, {
|
|
1988
|
+
kind: "rollbackTo",
|
|
1989
|
+
select: {},
|
|
1990
|
+
transaction: {
|
|
1991
|
+
kind: "rollbackTo",
|
|
1992
|
+
name
|
|
1993
|
+
},
|
|
1994
|
+
where: [],
|
|
1995
|
+
having: [],
|
|
1996
|
+
joins: [],
|
|
1997
|
+
groupBy: [],
|
|
1998
|
+
orderBy: []
|
|
1999
|
+
}, undefined, "transaction", "rollbackTo");
|
|
2000
|
+
};
|
|
2001
|
+
const releaseSavepoint = (name) => {
|
|
2002
|
+
return ctx.makePlan({
|
|
2003
|
+
selection: {},
|
|
2004
|
+
required: [],
|
|
2005
|
+
available: {},
|
|
2006
|
+
dialect: ctx.profile.dialect
|
|
2007
|
+
}, {
|
|
2008
|
+
kind: "releaseSavepoint",
|
|
2009
|
+
select: {},
|
|
2010
|
+
transaction: {
|
|
2011
|
+
kind: "releaseSavepoint",
|
|
2012
|
+
name
|
|
2013
|
+
},
|
|
2014
|
+
where: [],
|
|
2015
|
+
having: [],
|
|
2016
|
+
joins: [],
|
|
2017
|
+
groupBy: [],
|
|
2018
|
+
orderBy: []
|
|
2019
|
+
}, undefined, "transaction", "releaseSavepoint");
|
|
2020
|
+
};
|
|
2021
|
+
const createTable = (target, options2 = {}) => {
|
|
2022
|
+
const ifNotExists = normalizeStatementFlag(options2.ifNotExists);
|
|
2023
|
+
const { sourceName, sourceBaseName } = ctx.targetSourceDetails(target);
|
|
2024
|
+
return ctx.makePlan({
|
|
2025
|
+
selection: {},
|
|
2026
|
+
required: [],
|
|
2027
|
+
available: {},
|
|
2028
|
+
dialect: target[TypeId].dialect
|
|
2029
|
+
}, {
|
|
2030
|
+
kind: "createTable",
|
|
2031
|
+
select: {},
|
|
2032
|
+
target: {
|
|
2033
|
+
kind: "from",
|
|
2034
|
+
tableName: sourceName,
|
|
2035
|
+
baseTableName: sourceBaseName,
|
|
2036
|
+
source: target
|
|
2037
|
+
},
|
|
2038
|
+
ddl: {
|
|
2039
|
+
kind: "createTable",
|
|
2040
|
+
ifNotExists
|
|
2041
|
+
},
|
|
2042
|
+
where: [],
|
|
2043
|
+
having: [],
|
|
2044
|
+
joins: [],
|
|
2045
|
+
groupBy: [],
|
|
2046
|
+
orderBy: []
|
|
2047
|
+
}, undefined, "ddl", "createTable");
|
|
2048
|
+
};
|
|
2049
|
+
const dropTable = (target, options2 = {}) => {
|
|
2050
|
+
const ifExists = normalizeStatementFlag(options2.ifExists);
|
|
2051
|
+
const { sourceName, sourceBaseName } = ctx.targetSourceDetails(target);
|
|
2052
|
+
return ctx.makePlan({
|
|
2053
|
+
selection: {},
|
|
2054
|
+
required: [],
|
|
2055
|
+
available: {},
|
|
2056
|
+
dialect: target[TypeId].dialect
|
|
2057
|
+
}, {
|
|
2058
|
+
kind: "dropTable",
|
|
2059
|
+
select: {},
|
|
2060
|
+
target: {
|
|
2061
|
+
kind: "from",
|
|
2062
|
+
tableName: sourceName,
|
|
2063
|
+
baseTableName: sourceBaseName,
|
|
2064
|
+
source: target
|
|
2065
|
+
},
|
|
2066
|
+
ddl: {
|
|
2067
|
+
kind: "dropTable",
|
|
2068
|
+
ifExists
|
|
2069
|
+
},
|
|
2070
|
+
where: [],
|
|
2071
|
+
having: [],
|
|
2072
|
+
joins: [],
|
|
2073
|
+
groupBy: [],
|
|
2074
|
+
orderBy: []
|
|
2075
|
+
}, undefined, "ddl", "dropTable");
|
|
2076
|
+
};
|
|
2077
|
+
const createIndex = (target, columns, options2 = {}) => {
|
|
2078
|
+
const normalizedColumns = ctx.normalizeColumnList(columns);
|
|
2079
|
+
const unique2 = normalizeStatementFlag(options2.unique);
|
|
2080
|
+
const ifNotExists = normalizeStatementFlag(options2.ifNotExists);
|
|
2081
|
+
const name = options2.name;
|
|
2082
|
+
const { sourceName, sourceBaseName } = ctx.targetSourceDetails(target);
|
|
2083
|
+
return ctx.makePlan({
|
|
2084
|
+
selection: {},
|
|
2085
|
+
required: [],
|
|
2086
|
+
available: {},
|
|
2087
|
+
dialect: target[TypeId].dialect
|
|
2088
|
+
}, {
|
|
2089
|
+
kind: "createIndex",
|
|
2090
|
+
select: {},
|
|
2091
|
+
target: {
|
|
2092
|
+
kind: "from",
|
|
2093
|
+
tableName: sourceName,
|
|
2094
|
+
baseTableName: sourceBaseName,
|
|
2095
|
+
source: target
|
|
2096
|
+
},
|
|
2097
|
+
ddl: {
|
|
2098
|
+
kind: "createIndex",
|
|
2099
|
+
name: name ?? ctx.defaultIndexName(sourceBaseName, normalizedColumns, unique2),
|
|
2100
|
+
columns: normalizedColumns,
|
|
2101
|
+
unique: unique2,
|
|
2102
|
+
ifNotExists
|
|
2103
|
+
},
|
|
2104
|
+
where: [],
|
|
2105
|
+
having: [],
|
|
2106
|
+
joins: [],
|
|
2107
|
+
groupBy: [],
|
|
2108
|
+
orderBy: []
|
|
2109
|
+
}, undefined, "ddl", "createIndex");
|
|
2110
|
+
};
|
|
2111
|
+
const dropIndex = (target, columns, options2 = {}) => {
|
|
2112
|
+
const normalizedColumns = ctx.normalizeColumnList(columns);
|
|
2113
|
+
const ifExists = normalizeStatementFlag(options2.ifExists);
|
|
2114
|
+
const name = options2.name;
|
|
2115
|
+
const { sourceName, sourceBaseName } = ctx.targetSourceDetails(target);
|
|
2116
|
+
return ctx.makePlan({
|
|
2117
|
+
selection: {},
|
|
2118
|
+
required: [],
|
|
2119
|
+
available: {},
|
|
2120
|
+
dialect: target[TypeId].dialect
|
|
2121
|
+
}, {
|
|
2122
|
+
kind: "dropIndex",
|
|
2123
|
+
select: {},
|
|
2124
|
+
target: {
|
|
2125
|
+
kind: "from",
|
|
2126
|
+
tableName: sourceName,
|
|
2127
|
+
baseTableName: sourceBaseName,
|
|
2128
|
+
source: target
|
|
2129
|
+
},
|
|
2130
|
+
ddl: {
|
|
2131
|
+
kind: "dropIndex",
|
|
2132
|
+
name: name ?? ctx.defaultIndexName(sourceBaseName, normalizedColumns, false),
|
|
2133
|
+
ifExists
|
|
2134
|
+
},
|
|
2135
|
+
where: [],
|
|
2136
|
+
having: [],
|
|
2137
|
+
joins: [],
|
|
2138
|
+
groupBy: [],
|
|
2139
|
+
orderBy: []
|
|
2140
|
+
}, undefined, "ddl", "dropIndex");
|
|
2141
|
+
};
|
|
2142
|
+
return {
|
|
2143
|
+
transaction,
|
|
2144
|
+
commit,
|
|
2145
|
+
rollback,
|
|
2146
|
+
savepoint,
|
|
2147
|
+
rollbackTo,
|
|
2148
|
+
releaseSavepoint,
|
|
2149
|
+
createTable,
|
|
2150
|
+
dropTable,
|
|
2151
|
+
createIndex,
|
|
2152
|
+
dropIndex
|
|
2153
|
+
};
|
|
2154
|
+
};
|
|
2155
|
+
|
|
2156
|
+
// src/internal/dsl-mutation-runtime.ts
|
|
2157
|
+
var expectConflictClause = (conflict) => conflict;
|
|
2158
|
+
var makeDslMutationRuntime = (ctx) => {
|
|
2159
|
+
const insert = (target, values) => {
|
|
2160
|
+
const { sourceName, sourceBaseName } = ctx.targetSourceDetails(target);
|
|
2161
|
+
const assignments = values === undefined ? [] : ctx.buildMutationAssignments(target, values);
|
|
2162
|
+
const required = assignments.flatMap((entry) => Object.keys(entry.value[TypeId2].dependencies));
|
|
2163
|
+
const insertState = values === undefined ? "missing" : "ready";
|
|
2164
|
+
return ctx.makePlan({
|
|
2165
|
+
selection: {},
|
|
2166
|
+
required: required.filter((name, index3, list) => name !== sourceName && list.indexOf(name) === index3),
|
|
2167
|
+
available: {
|
|
2168
|
+
[sourceName]: {
|
|
2169
|
+
name: sourceName,
|
|
2170
|
+
mode: "required",
|
|
2171
|
+
baseName: sourceBaseName
|
|
2172
|
+
}
|
|
2173
|
+
},
|
|
2174
|
+
dialect: target[TypeId].dialect
|
|
2175
|
+
}, {
|
|
2176
|
+
kind: "insert",
|
|
2177
|
+
select: {},
|
|
2178
|
+
into: {
|
|
2179
|
+
kind: "from",
|
|
2180
|
+
tableName: sourceName,
|
|
2181
|
+
baseTableName: sourceBaseName,
|
|
2182
|
+
source: target
|
|
2183
|
+
},
|
|
2184
|
+
values: assignments,
|
|
2185
|
+
conflict: undefined,
|
|
2186
|
+
where: [],
|
|
2187
|
+
having: [],
|
|
2188
|
+
joins: [],
|
|
2189
|
+
groupBy: [],
|
|
2190
|
+
orderBy: []
|
|
2191
|
+
}, undefined, "write", "insert", target, insertState);
|
|
2192
|
+
};
|
|
2193
|
+
const attachInsertSource = (plan, source) => {
|
|
2194
|
+
const current = plan[TypeId];
|
|
2195
|
+
const currentAst = ctx.getAst(plan);
|
|
2196
|
+
const currentQuery = ctx.getQueryState(plan);
|
|
2197
|
+
const target = currentQuery.target;
|
|
2198
|
+
const sourceName = currentAst.into.tableName;
|
|
2199
|
+
if (typeof source === "object" && source !== null && "kind" in source && source.kind === "values") {
|
|
2200
|
+
const normalized = ctx.buildInsertValuesRows(target, source.rows);
|
|
2201
|
+
return ctx.makePlan({
|
|
2202
|
+
selection: current.selection,
|
|
2203
|
+
required: normalized.required.filter((name) => name !== sourceName),
|
|
2204
|
+
available: current.available,
|
|
2205
|
+
dialect: current.dialect
|
|
2206
|
+
}, {
|
|
2207
|
+
...currentAst,
|
|
2208
|
+
values: [],
|
|
2209
|
+
insertSource: {
|
|
2210
|
+
kind: "values",
|
|
2211
|
+
columns: normalized.columns,
|
|
2212
|
+
rows: normalized.rows
|
|
2213
|
+
}
|
|
2214
|
+
}, currentQuery.assumptions, currentQuery.capabilities, currentQuery.statement, currentQuery.target, "ready");
|
|
2215
|
+
}
|
|
2216
|
+
if (typeof source === "object" && source !== null && "kind" in source && source.kind === "unnest") {
|
|
2217
|
+
const normalized = ctx.normalizeInsertUnnestValues(target, source.values);
|
|
2218
|
+
return ctx.makePlan({
|
|
2219
|
+
selection: current.selection,
|
|
2220
|
+
required: [],
|
|
2221
|
+
available: current.available,
|
|
2222
|
+
dialect: current.dialect
|
|
2223
|
+
}, {
|
|
2224
|
+
...currentAst,
|
|
2225
|
+
values: [],
|
|
2226
|
+
insertSource: {
|
|
2227
|
+
kind: "unnest",
|
|
2228
|
+
columns: normalized.columns,
|
|
2229
|
+
values: normalized.values
|
|
2230
|
+
}
|
|
2231
|
+
}, currentQuery.assumptions, currentQuery.capabilities, currentQuery.statement, currentQuery.target, "ready");
|
|
2232
|
+
}
|
|
2233
|
+
const sourcePlan = source;
|
|
2234
|
+
const selection = sourcePlan[TypeId].selection;
|
|
2235
|
+
const columns = ctx.normalizeInsertSelectColumns(selection);
|
|
2236
|
+
return ctx.makePlan({
|
|
2237
|
+
selection: current.selection,
|
|
2238
|
+
required: ctx.currentRequiredList(sourcePlan[TypeId].required),
|
|
2239
|
+
available: current.available,
|
|
2240
|
+
dialect: current.dialect
|
|
2241
|
+
}, {
|
|
2242
|
+
...currentAst,
|
|
2243
|
+
values: [],
|
|
2244
|
+
insertSource: {
|
|
2245
|
+
kind: "query",
|
|
2246
|
+
columns,
|
|
2247
|
+
query: sourcePlan
|
|
2248
|
+
}
|
|
2249
|
+
}, currentQuery.assumptions, currentQuery.capabilities, currentQuery.statement, currentQuery.target, "ready");
|
|
2250
|
+
};
|
|
2251
|
+
const onConflict = (target, options2 = {}) => (plan) => {
|
|
2252
|
+
const current = plan[TypeId];
|
|
2253
|
+
const currentAst = ctx.getAst(plan);
|
|
2254
|
+
const currentQuery = ctx.getQueryState(plan);
|
|
2255
|
+
const insertTarget = currentAst.into.source;
|
|
2256
|
+
const conflictTarget = expectConflictClause({
|
|
2257
|
+
kind: "conflict",
|
|
2258
|
+
action: "doNothing",
|
|
2259
|
+
target: ctx.buildConflictTarget(insertTarget, target)
|
|
2260
|
+
}).target;
|
|
2261
|
+
const updateAssignments = options2.update ? ctx.buildMutationAssignments(insertTarget, options2.update) : [];
|
|
2262
|
+
const updateWhere = options2.where === undefined ? undefined : ctx.toDialectExpression(options2.where);
|
|
2263
|
+
const targetWhere = conflictTarget.kind === "columns" ? conflictTarget.where : undefined;
|
|
2264
|
+
const required = [
|
|
2265
|
+
...ctx.currentRequiredList(current.required),
|
|
2266
|
+
...updateAssignments.flatMap((entry) => Object.keys(entry.value[TypeId2].dependencies)),
|
|
2267
|
+
...updateWhere ? Object.keys(updateWhere[TypeId2].dependencies) : [],
|
|
2268
|
+
...targetWhere ? Object.keys(targetWhere[TypeId2].dependencies) : []
|
|
2269
|
+
].filter((name, index3, list) => !(name in current.available) && list.indexOf(name) === index3);
|
|
2270
|
+
return ctx.makePlan({
|
|
2271
|
+
selection: current.selection,
|
|
2272
|
+
required,
|
|
2273
|
+
available: current.available,
|
|
2274
|
+
dialect: current.dialect
|
|
2275
|
+
}, {
|
|
2276
|
+
...currentAst,
|
|
2277
|
+
conflict: {
|
|
2278
|
+
kind: "conflict",
|
|
2279
|
+
target: conflictTarget,
|
|
2280
|
+
action: updateAssignments.length === 0 ? "doNothing" : "doUpdate",
|
|
2281
|
+
values: updateAssignments.length === 0 ? undefined : updateAssignments,
|
|
2282
|
+
where: updateWhere
|
|
2283
|
+
}
|
|
2284
|
+
}, currentQuery.assumptions, currentQuery.capabilities, currentQuery.statement, currentQuery.target, currentQuery.insertSource);
|
|
2285
|
+
};
|
|
2286
|
+
const update = (target, values) => {
|
|
2287
|
+
const targets = ctx.mutationTargetClauses(target);
|
|
2288
|
+
const primaryTarget = targets[0];
|
|
2289
|
+
const assignments = ctx.buildMutationAssignments(target, values);
|
|
2290
|
+
const targetNames = new Set(targets.map((entry) => entry.tableName));
|
|
2291
|
+
const required = assignments.flatMap((entry) => Object.keys(entry.value[TypeId2].dependencies)).filter((name, index3, list) => !targetNames.has(name) && list.indexOf(name) === index3);
|
|
2292
|
+
return ctx.makePlan({
|
|
2293
|
+
selection: {},
|
|
2294
|
+
required,
|
|
2295
|
+
available: ctx.mutationAvailableSources(target),
|
|
2296
|
+
dialect: primaryTarget.source[TypeId].dialect
|
|
2297
|
+
}, {
|
|
2298
|
+
kind: "update",
|
|
2299
|
+
select: {},
|
|
2300
|
+
target: primaryTarget,
|
|
2301
|
+
targets,
|
|
2302
|
+
set: assignments,
|
|
2303
|
+
where: [],
|
|
2304
|
+
having: [],
|
|
2305
|
+
joins: [],
|
|
2306
|
+
groupBy: [],
|
|
2307
|
+
orderBy: []
|
|
2308
|
+
}, undefined, "write", "update");
|
|
2309
|
+
};
|
|
2310
|
+
const upsert = (target, values, conflictColumns, updateValues) => {
|
|
2311
|
+
const { sourceName, sourceBaseName } = ctx.targetSourceDetails(target);
|
|
2312
|
+
const assignments = ctx.buildMutationAssignments(target, values);
|
|
2313
|
+
const updateAssignments = updateValues ? ctx.buildMutationAssignments(target, updateValues) : [];
|
|
2314
|
+
const required = [
|
|
2315
|
+
...assignments.flatMap((entry) => Object.keys(entry.value[TypeId2].dependencies)),
|
|
2316
|
+
...updateAssignments.flatMap((entry) => Object.keys(entry.value[TypeId2].dependencies))
|
|
2317
|
+
];
|
|
2318
|
+
return ctx.makePlan({
|
|
2319
|
+
selection: {},
|
|
2320
|
+
required: required.filter((name, index3, list) => name !== sourceName && list.indexOf(name) === index3),
|
|
2321
|
+
available: {
|
|
2322
|
+
[sourceName]: {
|
|
2323
|
+
name: sourceName,
|
|
2324
|
+
mode: "required",
|
|
2325
|
+
baseName: sourceBaseName
|
|
2326
|
+
}
|
|
2327
|
+
},
|
|
2328
|
+
dialect: target[TypeId].dialect
|
|
2329
|
+
}, {
|
|
2330
|
+
kind: "insert",
|
|
2331
|
+
select: {},
|
|
2332
|
+
into: {
|
|
2333
|
+
kind: "from",
|
|
2334
|
+
tableName: sourceName,
|
|
2335
|
+
baseTableName: sourceBaseName,
|
|
2336
|
+
source: target
|
|
2337
|
+
},
|
|
2338
|
+
values: assignments,
|
|
2339
|
+
conflict: {
|
|
2340
|
+
kind: "conflict",
|
|
2341
|
+
target: {
|
|
2342
|
+
kind: "columns",
|
|
2343
|
+
columns: ctx.normalizeConflictColumns(target, conflictColumns)
|
|
2344
|
+
},
|
|
2345
|
+
action: updateAssignments.length > 0 ? "doUpdate" : "doNothing",
|
|
2346
|
+
values: updateAssignments.length > 0 ? updateAssignments : undefined
|
|
2347
|
+
},
|
|
2348
|
+
where: [],
|
|
2349
|
+
having: [],
|
|
2350
|
+
joins: [],
|
|
2351
|
+
groupBy: [],
|
|
2352
|
+
orderBy: []
|
|
2353
|
+
}, undefined, "write", "insert", target, "ready");
|
|
2354
|
+
};
|
|
2355
|
+
const delete_ = (target) => {
|
|
2356
|
+
const targets = ctx.mutationTargetClauses(target);
|
|
2357
|
+
const primaryTarget = targets[0];
|
|
2358
|
+
return ctx.makePlan({
|
|
2359
|
+
selection: {},
|
|
2360
|
+
required: [],
|
|
2361
|
+
available: ctx.mutationAvailableSources(target),
|
|
2362
|
+
dialect: primaryTarget.source[TypeId].dialect
|
|
2363
|
+
}, {
|
|
2364
|
+
kind: "delete",
|
|
2365
|
+
select: {},
|
|
2366
|
+
target: primaryTarget,
|
|
2367
|
+
targets,
|
|
2368
|
+
where: [],
|
|
2369
|
+
having: [],
|
|
2370
|
+
joins: [],
|
|
2371
|
+
groupBy: [],
|
|
2372
|
+
orderBy: []
|
|
2373
|
+
}, undefined, "write", "delete");
|
|
2374
|
+
};
|
|
2375
|
+
const truncate = (target, options2 = {}) => {
|
|
2376
|
+
const restartIdentity = normalizeStatementFlag(options2.restartIdentity);
|
|
2377
|
+
const cascade = normalizeStatementFlag(options2.cascade);
|
|
2378
|
+
const { sourceName, sourceBaseName } = ctx.targetSourceDetails(target);
|
|
2379
|
+
return ctx.makePlan({
|
|
2380
|
+
selection: {},
|
|
2381
|
+
required: [],
|
|
2382
|
+
available: {},
|
|
2383
|
+
dialect: target[TypeId].dialect
|
|
2384
|
+
}, {
|
|
2385
|
+
kind: "truncate",
|
|
2386
|
+
select: {},
|
|
2387
|
+
target: {
|
|
2388
|
+
kind: "from",
|
|
2389
|
+
tableName: sourceName,
|
|
2390
|
+
baseTableName: sourceBaseName,
|
|
2391
|
+
source: target
|
|
2392
|
+
},
|
|
2393
|
+
truncate: {
|
|
2394
|
+
kind: "truncate",
|
|
2395
|
+
restartIdentity,
|
|
2396
|
+
cascade
|
|
2397
|
+
},
|
|
2398
|
+
where: [],
|
|
2399
|
+
having: [],
|
|
2400
|
+
joins: [],
|
|
2401
|
+
groupBy: [],
|
|
2402
|
+
orderBy: []
|
|
2403
|
+
}, undefined, "write", "truncate");
|
|
2404
|
+
};
|
|
2405
|
+
const merge2 = (target, source, on, options2 = {}) => {
|
|
2406
|
+
const { sourceName: targetName, sourceBaseName: targetBaseName } = ctx.targetSourceDetails(target);
|
|
2407
|
+
const { sourceName: usingName, sourceBaseName: usingBaseName } = ctx.sourceDetails(source);
|
|
2408
|
+
const onExpression = ctx.toDialectExpression(on);
|
|
2409
|
+
const matched = options2.whenMatched;
|
|
2410
|
+
const notMatched = options2.whenNotMatched;
|
|
2411
|
+
const matchedPredicate = matched?.predicate ? ctx.toDialectExpression(matched.predicate) : undefined;
|
|
2412
|
+
const matchedAssignments = matched && "update" in matched && matched.update ? ctx.buildMutationAssignments(target, matched.update) : [];
|
|
2413
|
+
const notMatchedPredicate = notMatched?.predicate ? ctx.toDialectExpression(notMatched.predicate) : undefined;
|
|
2414
|
+
const notMatchedAssignments = notMatched ? ctx.buildMutationAssignments(target, notMatched.values) : [];
|
|
2415
|
+
const required = [
|
|
2416
|
+
...Object.keys(onExpression[TypeId2].dependencies),
|
|
2417
|
+
...matchedAssignments.flatMap((entry) => Object.keys(entry.value[TypeId2].dependencies)),
|
|
2418
|
+
...notMatchedAssignments.flatMap((entry) => Object.keys(entry.value[TypeId2].dependencies)),
|
|
2419
|
+
...matchedPredicate ? Object.keys(matchedPredicate[TypeId2].dependencies) : [],
|
|
2420
|
+
...notMatchedPredicate ? Object.keys(notMatchedPredicate[TypeId2].dependencies) : []
|
|
2421
|
+
].filter((name, index3, values) => name !== targetName && name !== usingName && values.indexOf(name) === index3);
|
|
2422
|
+
return ctx.makePlan({
|
|
2423
|
+
selection: {},
|
|
2424
|
+
required,
|
|
2425
|
+
available: {
|
|
2426
|
+
[targetName]: {
|
|
2427
|
+
name: targetName,
|
|
2428
|
+
mode: "required",
|
|
2429
|
+
baseName: targetBaseName
|
|
2430
|
+
},
|
|
2431
|
+
[usingName]: {
|
|
2432
|
+
name: usingName,
|
|
2433
|
+
mode: "required",
|
|
2434
|
+
baseName: usingBaseName
|
|
2435
|
+
}
|
|
2436
|
+
},
|
|
2437
|
+
dialect: target[TypeId].dialect
|
|
2438
|
+
}, {
|
|
2439
|
+
kind: "merge",
|
|
2440
|
+
select: {},
|
|
2441
|
+
target: {
|
|
2442
|
+
kind: "from",
|
|
2443
|
+
tableName: targetName,
|
|
2444
|
+
baseTableName: targetBaseName,
|
|
2445
|
+
source: target
|
|
2446
|
+
},
|
|
2447
|
+
using: {
|
|
2448
|
+
kind: "from",
|
|
2449
|
+
tableName: usingName,
|
|
2450
|
+
baseTableName: usingBaseName,
|
|
2451
|
+
source
|
|
2452
|
+
},
|
|
2453
|
+
merge: {
|
|
2454
|
+
kind: "merge",
|
|
2455
|
+
on: onExpression,
|
|
2456
|
+
whenMatched: matched ? "delete" in matched && matched.delete ? {
|
|
2457
|
+
kind: "delete",
|
|
2458
|
+
predicate: matchedPredicate
|
|
2459
|
+
} : {
|
|
2460
|
+
kind: "update",
|
|
2461
|
+
values: matchedAssignments,
|
|
2462
|
+
predicate: matchedPredicate
|
|
2463
|
+
} : undefined,
|
|
2464
|
+
whenNotMatched: notMatched ? {
|
|
2465
|
+
kind: "insert",
|
|
2466
|
+
values: notMatchedAssignments,
|
|
2467
|
+
predicate: notMatchedPredicate
|
|
2468
|
+
} : undefined
|
|
2469
|
+
},
|
|
2470
|
+
where: [],
|
|
2471
|
+
having: [],
|
|
2472
|
+
joins: [],
|
|
2473
|
+
groupBy: [],
|
|
2474
|
+
orderBy: []
|
|
2475
|
+
}, undefined, "write", "merge");
|
|
2476
|
+
};
|
|
2477
|
+
return {
|
|
2478
|
+
insert,
|
|
2479
|
+
attachInsertSource,
|
|
2480
|
+
onConflict,
|
|
2481
|
+
update,
|
|
2482
|
+
upsert,
|
|
2483
|
+
delete_,
|
|
2484
|
+
truncate,
|
|
2485
|
+
merge: merge2
|
|
2486
|
+
};
|
|
2487
|
+
};
|
|
2488
|
+
|
|
2489
|
+
// src/internal/runtime/driver-value-mapping.ts
|
|
2490
|
+
import * as Schema4 from "effect/Schema";
|
|
2491
|
+
|
|
2492
|
+
// src/internal/runtime/value.ts
|
|
2493
|
+
import * as Schema3 from "effect/Schema";
|
|
2494
|
+
var brandString = (pattern2, brand4) => Schema3.String.pipe(Schema3.pattern(pattern2), Schema3.brand(brand4));
|
|
2495
|
+
var localDatePattern = /^(\d{4})-(\d{2})-(\d{2})$/;
|
|
2496
|
+
var isValidLocalDateString = (value) => {
|
|
2497
|
+
const match = localDatePattern.exec(value);
|
|
2498
|
+
if (match === null) {
|
|
2499
|
+
return false;
|
|
2500
|
+
}
|
|
2501
|
+
const year = Number(match[1]);
|
|
2502
|
+
const month = Number(match[2]);
|
|
2503
|
+
const day = Number(match[3]);
|
|
2504
|
+
const parsed = new Date(Date.UTC(year, month - 1, day));
|
|
2505
|
+
parsed.setUTCFullYear(year);
|
|
2506
|
+
return parsed.getUTCFullYear() === year && parsed.getUTCMonth() === month - 1 && parsed.getUTCDate() === day;
|
|
2507
|
+
};
|
|
2508
|
+
var localTimePattern = /^(\d{2}):(\d{2}):(\d{2})(?:\.\d+)?$/;
|
|
2509
|
+
var isValidLocalTimeString = (value) => {
|
|
2510
|
+
const match = localTimePattern.exec(value);
|
|
2511
|
+
if (match === null) {
|
|
2512
|
+
return false;
|
|
1536
2513
|
}
|
|
1537
|
-
|
|
1538
|
-
|
|
2514
|
+
const hour = Number(match[1]);
|
|
2515
|
+
const minute = Number(match[2]);
|
|
2516
|
+
const second = Number(match[3]);
|
|
2517
|
+
return hour >= 0 && hour <= 23 && minute >= 0 && minute <= 59 && second >= 0 && second <= 59;
|
|
2518
|
+
};
|
|
2519
|
+
var offsetPattern = /^(?:Z|[+-](\d{2}):(\d{2}))$/;
|
|
2520
|
+
var isValidOffset = (value) => {
|
|
2521
|
+
const match = offsetPattern.exec(value);
|
|
2522
|
+
if (match === null) {
|
|
2523
|
+
return false;
|
|
2524
|
+
}
|
|
2525
|
+
if (value === "Z") {
|
|
2526
|
+
return true;
|
|
2527
|
+
}
|
|
2528
|
+
const hour = Number(match[1]);
|
|
2529
|
+
const minute = Number(match[2]);
|
|
2530
|
+
return hour >= 0 && hour <= 23 && minute >= 0 && minute <= 59;
|
|
2531
|
+
};
|
|
2532
|
+
var offsetTimePattern = /^(\d{2}:\d{2}:\d{2}(?:\.\d+)?)(Z|[+-]\d{2}:\d{2})$/;
|
|
2533
|
+
var isValidOffsetTimeString = (value) => {
|
|
2534
|
+
const match = offsetTimePattern.exec(value);
|
|
2535
|
+
return match !== null && isValidLocalTimeString(match[1]) && isValidOffset(match[2]);
|
|
2536
|
+
};
|
|
2537
|
+
var localDateTimePattern = /^(\d{4}-\d{2}-\d{2})T(\d{2}:\d{2}:\d{2}(?:\.\d+)?)$/;
|
|
2538
|
+
var isValidLocalDateTimeString = (value) => {
|
|
2539
|
+
const match = localDateTimePattern.exec(value);
|
|
2540
|
+
return match !== null && isValidLocalDateString(match[1]) && isValidLocalTimeString(match[2]);
|
|
2541
|
+
};
|
|
2542
|
+
var instantPattern = /^(\d{4}-\d{2}-\d{2})T(\d{2}:\d{2}:\d{2}(?:\.\d+)?)(Z|[+-]\d{2}:\d{2})$/;
|
|
2543
|
+
var isValidInstantString = (value) => {
|
|
2544
|
+
const match = instantPattern.exec(value);
|
|
2545
|
+
return match !== null && isValidLocalDateString(match[1]) && isValidLocalTimeString(match[2]) && isValidOffset(match[3]);
|
|
2546
|
+
};
|
|
2547
|
+
var LocalDateStringSchema = Schema3.String.pipe(Schema3.pattern(localDatePattern), Schema3.filter(isValidLocalDateString), Schema3.brand("LocalDateString"));
|
|
2548
|
+
var LocalTimeStringSchema = Schema3.String.pipe(Schema3.pattern(localTimePattern), Schema3.filter(isValidLocalTimeString), Schema3.brand("LocalTimeString"));
|
|
2549
|
+
var OffsetTimeStringSchema = Schema3.String.pipe(Schema3.pattern(offsetTimePattern), Schema3.filter(isValidOffsetTimeString), Schema3.brand("OffsetTimeString"));
|
|
2550
|
+
var LocalDateTimeStringSchema = Schema3.String.pipe(Schema3.pattern(localDateTimePattern), Schema3.filter(isValidLocalDateTimeString), Schema3.brand("LocalDateTimeString"));
|
|
2551
|
+
var InstantStringSchema = Schema3.String.pipe(Schema3.pattern(instantPattern), Schema3.filter(isValidInstantString), Schema3.brand("InstantString"));
|
|
2552
|
+
var YearStringSchema = brandString(/^\d{4}$/, "YearString");
|
|
2553
|
+
var canonicalizeBigIntString = (input) => {
|
|
2554
|
+
const trimmed = input.trim();
|
|
2555
|
+
if (!/^-?\d+$/.test(trimmed)) {
|
|
2556
|
+
throw new Error("Expected an integer-like bigint value");
|
|
2557
|
+
}
|
|
2558
|
+
return BigInt(trimmed).toString();
|
|
2559
|
+
};
|
|
2560
|
+
var isCanonicalBigIntString = (value) => {
|
|
2561
|
+
try {
|
|
2562
|
+
return canonicalizeBigIntString(value) === value;
|
|
2563
|
+
} catch {
|
|
2564
|
+
return false;
|
|
1539
2565
|
}
|
|
1540
|
-
throw new Error("Expected an integer-like bigint value");
|
|
1541
2566
|
};
|
|
1542
2567
|
var canonicalizeDecimalString = (input) => {
|
|
1543
2568
|
const trimmed = input.trim();
|
|
@@ -1549,10 +2574,116 @@ var canonicalizeDecimalString = (input) => {
|
|
|
1549
2574
|
const integer = match[2].replace(/^0+(?=\d)/, "") || "0";
|
|
1550
2575
|
const fraction = (match[3] ?? "").replace(/0+$/, "");
|
|
1551
2576
|
if (fraction.length === 0) {
|
|
2577
|
+
if (integer === "0") {
|
|
2578
|
+
return "0";
|
|
2579
|
+
}
|
|
1552
2580
|
return `${sign}${integer}`;
|
|
1553
2581
|
}
|
|
1554
2582
|
return `${sign}${integer}.${fraction}`;
|
|
1555
2583
|
};
|
|
2584
|
+
var isCanonicalDecimalString = (value) => {
|
|
2585
|
+
try {
|
|
2586
|
+
return canonicalizeDecimalString(value) === value;
|
|
2587
|
+
} catch {
|
|
2588
|
+
return false;
|
|
2589
|
+
}
|
|
2590
|
+
};
|
|
2591
|
+
var BigIntStringSchema = Schema3.String.pipe(Schema3.filter(isCanonicalBigIntString), Schema3.brand("BigIntString"));
|
|
2592
|
+
var DecimalStringSchema = Schema3.String.pipe(Schema3.filter(isCanonicalDecimalString), Schema3.brand("DecimalString"));
|
|
2593
|
+
var JsonValueSchema = Schema3.suspend(() => Schema3.Union(Schema3.String, Schema3.Number.pipe(Schema3.finite()), Schema3.Boolean, Schema3.Null, Schema3.Array(JsonValueSchema), Schema3.Record({
|
|
2594
|
+
key: Schema3.String,
|
|
2595
|
+
value: JsonValueSchema
|
|
2596
|
+
})));
|
|
2597
|
+
var JsonPrimitiveSchema = Schema3.Union(Schema3.String, Schema3.Number.pipe(Schema3.finite()), Schema3.Boolean, Schema3.Null);
|
|
2598
|
+
|
|
2599
|
+
// src/internal/runtime/normalize.ts
|
|
2600
|
+
var isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
2601
|
+
var isPlainRecord = (value) => {
|
|
2602
|
+
if (!isRecord(value)) {
|
|
2603
|
+
return false;
|
|
2604
|
+
}
|
|
2605
|
+
const prototype = Object.getPrototypeOf(value);
|
|
2606
|
+
return prototype === Object.prototype || prototype === null;
|
|
2607
|
+
};
|
|
2608
|
+
var pad = (value, width = 2) => value.toString().padStart(width, "0");
|
|
2609
|
+
var validDate = (value) => {
|
|
2610
|
+
if (Number.isNaN(value.getTime())) {
|
|
2611
|
+
throw new Error("Expected a valid Date value");
|
|
2612
|
+
}
|
|
2613
|
+
return value;
|
|
2614
|
+
};
|
|
2615
|
+
var formatLocalDate = (value) => `${pad(value.getUTCFullYear(), 4)}-${pad(value.getUTCMonth() + 1)}-${pad(value.getUTCDate())}`;
|
|
2616
|
+
var formatLocalTime = (value) => {
|
|
2617
|
+
const milliseconds = value.getUTCMilliseconds();
|
|
2618
|
+
const base = `${pad(value.getUTCHours())}:${pad(value.getUTCMinutes())}:${pad(value.getUTCSeconds())}`;
|
|
2619
|
+
return milliseconds === 0 ? base : `${base}.${pad(milliseconds, 3)}`;
|
|
2620
|
+
};
|
|
2621
|
+
var formatLocalDateTime = (value) => {
|
|
2622
|
+
const milliseconds = value.getUTCMilliseconds();
|
|
2623
|
+
const base = `${formatLocalDate(value)}T${pad(value.getUTCHours())}:${pad(value.getUTCMinutes())}:${pad(value.getUTCSeconds())}`;
|
|
2624
|
+
return milliseconds === 0 ? base : `${base}.${pad(milliseconds, 3)}`;
|
|
2625
|
+
};
|
|
2626
|
+
var runtimeTagOfBaseDbType = (dbType) => {
|
|
2627
|
+
return dbType.runtime;
|
|
2628
|
+
};
|
|
2629
|
+
var expectString = (value, label) => {
|
|
2630
|
+
if (typeof value === "string") {
|
|
2631
|
+
return value;
|
|
2632
|
+
}
|
|
2633
|
+
throw new Error(`Expected ${label} as string`);
|
|
2634
|
+
};
|
|
2635
|
+
var finiteNumberStringPattern = /^[+-]?(?:(?:\d+\.?\d*)|(?:\.\d+))(?:[eE][+-]?\d+)?$/;
|
|
2636
|
+
var normalizeNumber = (value) => {
|
|
2637
|
+
if (typeof value === "number" && Number.isFinite(value)) {
|
|
2638
|
+
return value;
|
|
2639
|
+
}
|
|
2640
|
+
if (typeof value === "string") {
|
|
2641
|
+
const trimmed = value.trim();
|
|
2642
|
+
const parsed = finiteNumberStringPattern.test(trimmed) ? Number(trimmed) : Number.NaN;
|
|
2643
|
+
if (Number.isFinite(parsed)) {
|
|
2644
|
+
return parsed;
|
|
2645
|
+
}
|
|
2646
|
+
}
|
|
2647
|
+
if (typeof value === "bigint" && Number.isSafeInteger(Number(value))) {
|
|
2648
|
+
return Number(value);
|
|
2649
|
+
}
|
|
2650
|
+
throw new Error("Expected a finite numeric value");
|
|
2651
|
+
};
|
|
2652
|
+
var normalizeBoolean = (value) => {
|
|
2653
|
+
if (typeof value === "boolean") {
|
|
2654
|
+
return value;
|
|
2655
|
+
}
|
|
2656
|
+
if (typeof value === "number") {
|
|
2657
|
+
if (value === 1) {
|
|
2658
|
+
return true;
|
|
2659
|
+
}
|
|
2660
|
+
if (value === 0) {
|
|
2661
|
+
return false;
|
|
2662
|
+
}
|
|
2663
|
+
}
|
|
2664
|
+
if (typeof value === "string") {
|
|
2665
|
+
const normalized = value.trim().toLowerCase();
|
|
2666
|
+
if (normalized === "true" || normalized === "t" || normalized === "1") {
|
|
2667
|
+
return true;
|
|
2668
|
+
}
|
|
2669
|
+
if (normalized === "false" || normalized === "f" || normalized === "0") {
|
|
2670
|
+
return false;
|
|
2671
|
+
}
|
|
2672
|
+
}
|
|
2673
|
+
throw new Error("Expected a boolean-like value");
|
|
2674
|
+
};
|
|
2675
|
+
var normalizeBigIntString = (value) => {
|
|
2676
|
+
if (typeof value === "bigint") {
|
|
2677
|
+
return value.toString();
|
|
2678
|
+
}
|
|
2679
|
+
if (typeof value === "number" && Number.isSafeInteger(value)) {
|
|
2680
|
+
return BigInt(value).toString();
|
|
2681
|
+
}
|
|
2682
|
+
if (typeof value === "string") {
|
|
2683
|
+
return canonicalizeBigIntString(value);
|
|
2684
|
+
}
|
|
2685
|
+
throw new Error("Expected an integer-like bigint value");
|
|
2686
|
+
};
|
|
1556
2687
|
var normalizeDecimalString = (value) => {
|
|
1557
2688
|
if (typeof value === "string") {
|
|
1558
2689
|
return canonicalizeDecimalString(value);
|
|
@@ -1568,48 +2699,53 @@ var normalizeDecimalString = (value) => {
|
|
|
1568
2699
|
};
|
|
1569
2700
|
var normalizeLocalDate = (value) => {
|
|
1570
2701
|
if (value instanceof Date) {
|
|
1571
|
-
return formatLocalDate(value);
|
|
2702
|
+
return formatLocalDate(validDate(value));
|
|
1572
2703
|
}
|
|
1573
2704
|
const raw = expectString(value, "local date").trim();
|
|
1574
|
-
if (
|
|
2705
|
+
if (isValidLocalDateString(raw)) {
|
|
1575
2706
|
return raw;
|
|
1576
2707
|
}
|
|
1577
|
-
const
|
|
1578
|
-
if (
|
|
1579
|
-
|
|
2708
|
+
const canonicalInstant = raw.replace(" ", "T").replace(/z$/, "Z");
|
|
2709
|
+
if (isValidInstantString(canonicalInstant)) {
|
|
2710
|
+
const parsed = new Date(canonicalInstant);
|
|
2711
|
+
if (!Number.isNaN(parsed.getTime())) {
|
|
2712
|
+
return formatLocalDate(parsed);
|
|
2713
|
+
}
|
|
1580
2714
|
}
|
|
1581
2715
|
throw new Error("Expected a local-date value");
|
|
1582
2716
|
};
|
|
1583
2717
|
var normalizeLocalTime = (value) => {
|
|
1584
2718
|
if (value instanceof Date) {
|
|
1585
|
-
return formatLocalTime(value);
|
|
2719
|
+
return formatLocalTime(validDate(value));
|
|
1586
2720
|
}
|
|
1587
2721
|
const raw = expectString(value, "local time").trim();
|
|
1588
|
-
if (
|
|
2722
|
+
if (isValidLocalTimeString(raw)) {
|
|
1589
2723
|
return raw;
|
|
1590
2724
|
}
|
|
1591
2725
|
throw new Error("Expected a local-time value");
|
|
1592
2726
|
};
|
|
1593
2727
|
var normalizeOffsetTime = (value) => {
|
|
1594
2728
|
if (value instanceof Date) {
|
|
1595
|
-
return `${formatLocalTime(value)}Z`;
|
|
2729
|
+
return `${formatLocalTime(validDate(value))}Z`;
|
|
1596
2730
|
}
|
|
1597
2731
|
const raw = expectString(value, "offset time").trim();
|
|
1598
|
-
if (
|
|
2732
|
+
if (isValidOffsetTimeString(raw)) {
|
|
1599
2733
|
return raw;
|
|
1600
2734
|
}
|
|
1601
2735
|
throw new Error("Expected an offset-time value");
|
|
1602
2736
|
};
|
|
1603
2737
|
var normalizeLocalDateTime = (value) => {
|
|
1604
2738
|
if (value instanceof Date) {
|
|
1605
|
-
return formatLocalDateTime(value);
|
|
2739
|
+
return formatLocalDateTime(validDate(value));
|
|
1606
2740
|
}
|
|
1607
2741
|
const raw = expectString(value, "local datetime").trim();
|
|
1608
|
-
|
|
1609
|
-
|
|
2742
|
+
const canonicalLocalDateTime = raw.replace(" ", "T");
|
|
2743
|
+
if (isValidLocalDateTimeString(canonicalLocalDateTime)) {
|
|
2744
|
+
return canonicalLocalDateTime;
|
|
1610
2745
|
}
|
|
1611
|
-
|
|
1612
|
-
|
|
2746
|
+
const canonicalInstant = raw.replace(" ", "T").replace(/z$/, "Z");
|
|
2747
|
+
if (isValidInstantString(canonicalInstant)) {
|
|
2748
|
+
const parsed = new Date(canonicalInstant);
|
|
1613
2749
|
if (!Number.isNaN(parsed.getTime())) {
|
|
1614
2750
|
return formatLocalDateTime(parsed);
|
|
1615
2751
|
}
|
|
@@ -1618,13 +2754,17 @@ var normalizeLocalDateTime = (value) => {
|
|
|
1618
2754
|
};
|
|
1619
2755
|
var normalizeInstant = (value) => {
|
|
1620
2756
|
if (value instanceof Date) {
|
|
1621
|
-
return value.toISOString();
|
|
2757
|
+
return validDate(value).toISOString();
|
|
1622
2758
|
}
|
|
1623
2759
|
const raw = expectString(value, "instant").trim();
|
|
1624
2760
|
if (!/[zZ]|[+-]\d{2}:\d{2}$/.test(raw)) {
|
|
1625
2761
|
throw new Error("Instant values require a timezone offset");
|
|
1626
2762
|
}
|
|
1627
|
-
const
|
|
2763
|
+
const canonicalInstant = raw.replace(" ", "T").replace(/z$/, "Z");
|
|
2764
|
+
if (!isValidInstantString(canonicalInstant)) {
|
|
2765
|
+
throw new Error("Expected an ISO instant value");
|
|
2766
|
+
}
|
|
2767
|
+
const parsed = new Date(canonicalInstant);
|
|
1628
2768
|
if (Number.isNaN(parsed.getTime())) {
|
|
1629
2769
|
throw new Error("Expected an ISO instant value");
|
|
1630
2770
|
}
|
|
@@ -1656,25 +2796,33 @@ var isJsonValue = (value) => {
|
|
|
1656
2796
|
}
|
|
1657
2797
|
switch (typeof value) {
|
|
1658
2798
|
case "string":
|
|
1659
|
-
case "number":
|
|
1660
2799
|
case "boolean":
|
|
1661
2800
|
return true;
|
|
2801
|
+
case "number":
|
|
2802
|
+
return Number.isFinite(value);
|
|
1662
2803
|
case "object":
|
|
1663
2804
|
if (Array.isArray(value)) {
|
|
1664
2805
|
return value.every(isJsonValue);
|
|
1665
2806
|
}
|
|
1666
|
-
return
|
|
2807
|
+
return isPlainRecord(value) && Object.values(value).every(isJsonValue);
|
|
1667
2808
|
default:
|
|
1668
2809
|
return false;
|
|
1669
2810
|
}
|
|
1670
2811
|
};
|
|
1671
2812
|
var normalizeJson = (value) => {
|
|
1672
2813
|
if (typeof value === "string") {
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
|
|
2814
|
+
try {
|
|
2815
|
+
const parsed = JSON.parse(value);
|
|
2816
|
+
if (isJsonValue(parsed)) {
|
|
2817
|
+
return parsed;
|
|
2818
|
+
}
|
|
2819
|
+
throw new Error("Parsed JSON value is not a valid JSON runtime");
|
|
2820
|
+
} catch (error) {
|
|
2821
|
+
if (error instanceof SyntaxError) {
|
|
2822
|
+
return value;
|
|
2823
|
+
}
|
|
2824
|
+
throw error;
|
|
1676
2825
|
}
|
|
1677
|
-
throw new Error("Parsed JSON value is not a valid JSON runtime");
|
|
1678
2826
|
}
|
|
1679
2827
|
if (isJsonValue(value)) {
|
|
1680
2828
|
return value;
|
|
@@ -1809,22 +2957,61 @@ var findMapping = (context, key2) => {
|
|
|
1809
2957
|
}
|
|
1810
2958
|
return;
|
|
1811
2959
|
};
|
|
1812
|
-
var
|
|
1813
|
-
if (
|
|
2960
|
+
var isJsonDbType = (dbType) => {
|
|
2961
|
+
if (dbType === undefined) {
|
|
2962
|
+
return false;
|
|
2963
|
+
}
|
|
2964
|
+
if ("base" in dbType) {
|
|
2965
|
+
return isJsonDbType(dbType.base);
|
|
2966
|
+
}
|
|
2967
|
+
if (!("variant" in dbType)) {
|
|
2968
|
+
return false;
|
|
2969
|
+
}
|
|
2970
|
+
const variant = dbType.variant;
|
|
2971
|
+
return variant === "json" || variant === "jsonb";
|
|
2972
|
+
};
|
|
2973
|
+
var schemaAccepts = (schema, value) => schema !== undefined && Schema4.is(schema)(value);
|
|
2974
|
+
var encodeWithSchema = (schema, value) => {
|
|
2975
|
+
if (schema === undefined) {
|
|
1814
2976
|
return { value, encoded: false };
|
|
1815
2977
|
}
|
|
1816
|
-
if (!
|
|
2978
|
+
if (!Schema4.is(schema)(value)) {
|
|
1817
2979
|
return { value, encoded: false };
|
|
1818
2980
|
}
|
|
1819
2981
|
return {
|
|
1820
|
-
value:
|
|
2982
|
+
value: Schema4.encodeUnknownSync(schema)(value),
|
|
1821
2983
|
encoded: true
|
|
1822
2984
|
};
|
|
1823
2985
|
};
|
|
2986
|
+
var normalizeJsonDriverString = (value, context) => {
|
|
2987
|
+
if (!isJsonDbType(context.dbType) || context.runtimeSchema === undefined) {
|
|
2988
|
+
return;
|
|
2989
|
+
}
|
|
2990
|
+
try {
|
|
2991
|
+
const parsed = JSON.parse(value);
|
|
2992
|
+
if (value.trimStart().startsWith('"') && schemaAccepts(context.runtimeSchema, parsed)) {
|
|
2993
|
+
return parsed;
|
|
2994
|
+
}
|
|
2995
|
+
if (schemaAccepts(context.runtimeSchema, value) && !schemaAccepts(context.runtimeSchema, parsed)) {
|
|
2996
|
+
return value;
|
|
2997
|
+
}
|
|
2998
|
+
} catch (error) {
|
|
2999
|
+
if (error instanceof SyntaxError && schemaAccepts(context.runtimeSchema, value)) {
|
|
3000
|
+
return value;
|
|
3001
|
+
}
|
|
3002
|
+
if (!(error instanceof SyntaxError)) {
|
|
3003
|
+
throw error;
|
|
3004
|
+
}
|
|
3005
|
+
}
|
|
3006
|
+
return;
|
|
3007
|
+
};
|
|
1824
3008
|
var toDriverValue = (value, context) => {
|
|
1825
3009
|
if (value === null) {
|
|
1826
3010
|
return null;
|
|
1827
3011
|
}
|
|
3012
|
+
if (value instanceof Date && Number.isNaN(value.getTime())) {
|
|
3013
|
+
throw new Error("Expected a valid Date value");
|
|
3014
|
+
}
|
|
1828
3015
|
const dbType = context.dbType;
|
|
1829
3016
|
const encoded = encodeWithSchema(context.runtimeSchema, value);
|
|
1830
3017
|
let current = encoded.value;
|
|
@@ -1832,6 +3019,9 @@ var toDriverValue = (value, context) => {
|
|
|
1832
3019
|
if (custom !== undefined && dbType !== undefined) {
|
|
1833
3020
|
return custom(current, dbType);
|
|
1834
3021
|
}
|
|
3022
|
+
if (encoded.encoded && typeof current === "string" && isJsonDbType(dbType)) {
|
|
3023
|
+
return current;
|
|
3024
|
+
}
|
|
1835
3025
|
return dbType === undefined || !encoded.encoded ? current : normalizeDbValue(dbType, current);
|
|
1836
3026
|
};
|
|
1837
3027
|
var fromDriverValue = (value, context) => {
|
|
@@ -1843,6 +3033,12 @@ var fromDriverValue = (value, context) => {
|
|
|
1843
3033
|
if (custom !== undefined && dbType !== undefined) {
|
|
1844
3034
|
return custom(value, dbType);
|
|
1845
3035
|
}
|
|
3036
|
+
if (typeof value === "string") {
|
|
3037
|
+
const normalizedJsonString = normalizeJsonDriverString(value, context);
|
|
3038
|
+
if (normalizedJsonString !== undefined) {
|
|
3039
|
+
return normalizedJsonString;
|
|
3040
|
+
}
|
|
3041
|
+
}
|
|
1846
3042
|
return dbType === undefined ? value : normalizeDbValue(dbType, value);
|
|
1847
3043
|
};
|
|
1848
3044
|
var textCast = (sql) => `(${sql})::text`;
|
|
@@ -1879,12 +3075,12 @@ var renderJsonSelectSql = (sql, context) => {
|
|
|
1879
3075
|
};
|
|
1880
3076
|
|
|
1881
3077
|
// src/internal/projection-alias.ts
|
|
1882
|
-
var
|
|
3078
|
+
var TypeId9 = Symbol.for("effect-qb/ProjectionAlias");
|
|
1883
3079
|
|
|
1884
3080
|
// src/internal/projections.ts
|
|
1885
3081
|
var aliasFromPath = (path2) => path2.join("__");
|
|
1886
3082
|
var isExpression = (value) => typeof value === "object" && value !== null && (TypeId2 in value);
|
|
1887
|
-
var projectionAliasOf = (expression) => (
|
|
3083
|
+
var projectionAliasOf = (expression) => (TypeId9 in expression) ? expression[TypeId9].alias : undefined;
|
|
1888
3084
|
var pathKeyOf = (path2) => JSON.stringify(path2);
|
|
1889
3085
|
var formatProjectionPath = (path2) => path2.join(".");
|
|
1890
3086
|
var isPrefixPath = (left, right) => left.length < right.length && left.every((segment, index3) => segment === right[index3]);
|
|
@@ -1930,9 +3126,23 @@ var validateProjections = (projections) => {
|
|
|
1930
3126
|
};
|
|
1931
3127
|
|
|
1932
3128
|
// src/internal/grouping-key.ts
|
|
3129
|
+
var subqueryPlanIds = new WeakMap;
|
|
3130
|
+
var nextSubqueryPlanId = 0;
|
|
3131
|
+
var subqueryPlanGroupingKey = (plan) => {
|
|
3132
|
+
if (plan === null || typeof plan !== "object") {
|
|
3133
|
+
return "unknown";
|
|
3134
|
+
}
|
|
3135
|
+
const existing = subqueryPlanIds.get(plan);
|
|
3136
|
+
if (existing !== undefined) {
|
|
3137
|
+
return existing;
|
|
3138
|
+
}
|
|
3139
|
+
const next = `${nextSubqueryPlanId++}`;
|
|
3140
|
+
subqueryPlanIds.set(plan, next);
|
|
3141
|
+
return next;
|
|
3142
|
+
};
|
|
1933
3143
|
var literalGroupingKey = (value) => {
|
|
1934
3144
|
if (value instanceof Date) {
|
|
1935
|
-
return `date:${value.toISOString()}`;
|
|
3145
|
+
return Number.isNaN(value.getTime()) ? "date:invalid" : `date:${value.toISOString()}`;
|
|
1936
3146
|
}
|
|
1937
3147
|
if (value === null) {
|
|
1938
3148
|
return "null";
|
|
@@ -1948,15 +3158,99 @@ var literalGroupingKey = (value) => {
|
|
|
1948
3158
|
return `literal:${JSON.stringify(value)}`;
|
|
1949
3159
|
}
|
|
1950
3160
|
};
|
|
3161
|
+
var isExpression2 = (value) => value !== null && typeof value === "object" && (TypeId2 in value);
|
|
3162
|
+
var expressionGroupingKey = (value) => isExpression2(value) ? groupingKeyOfExpression(value) : "missing";
|
|
3163
|
+
var requiredExpressionGroupingKey = (_functionName, value) => groupingKeyOfExpression(value);
|
|
3164
|
+
var requiredBinaryExpressionGroupingKey = (_functionName, left, right) => `${groupingKeyOfExpression(left)},${groupingKeyOfExpression(right)}`;
|
|
3165
|
+
var functionCallArgsGroupingKey = (args) => args.map(groupingKeyOfExpression).join(",");
|
|
3166
|
+
var variadicGroupingKey = (_functionName, values) => values.map(groupingKeyOfExpression).join(",");
|
|
3167
|
+
var castTargetGroupingKey = (target) => {
|
|
3168
|
+
const typed = target;
|
|
3169
|
+
return `${typed?.dialect}:${typed?.kind}`;
|
|
3170
|
+
};
|
|
3171
|
+
var escapeGroupingText = (value) => value.replace(/\\/g, "\\\\").replace(/,/g, "\\,").replace(/\|/g, "\\|").replace(/=/g, "\\=").replace(/>/g, "\\>");
|
|
3172
|
+
var functionCallNameGroupingKey = (name) => escapeGroupingText(name);
|
|
3173
|
+
var quantifiedComparisonGroupingName = (kind) => kind === "comparisonAny" ? "compareAny" : "compareAll";
|
|
3174
|
+
var caseGroupingKey = (branches, fallback) => {
|
|
3175
|
+
const typedBranches = branches;
|
|
3176
|
+
return `case(${typedBranches.map((branch) => `when:${groupingKeyOfExpression(branch.when)}=>${groupingKeyOfExpression(branch.then)}`).join("|")};else:${groupingKeyOfExpression(fallback)})`;
|
|
3177
|
+
};
|
|
3178
|
+
var collationGroupingKey = (collation) => {
|
|
3179
|
+
if (Array.isArray(collation)) {
|
|
3180
|
+
return collation.map((part) => escapeGroupingText(String(part))).join(",");
|
|
3181
|
+
}
|
|
3182
|
+
return escapeGroupingText(String(collation));
|
|
3183
|
+
};
|
|
3184
|
+
var jsonSegmentGroupingKey = (segment) => {
|
|
3185
|
+
if (segment !== null && typeof segment === "object" && "kind" in segment) {
|
|
3186
|
+
switch (segment.kind) {
|
|
3187
|
+
case "key":
|
|
3188
|
+
return `key:${escapeGroupingText(segment.key)}`;
|
|
3189
|
+
case "index":
|
|
3190
|
+
return `index:${segment.index}`;
|
|
3191
|
+
case "wildcard":
|
|
3192
|
+
return "wildcard";
|
|
3193
|
+
case "slice": {
|
|
3194
|
+
const slice2 = segment;
|
|
3195
|
+
return `slice:${slice2.start ?? ""}:${slice2.end ?? ""}`;
|
|
3196
|
+
}
|
|
3197
|
+
case "descend":
|
|
3198
|
+
return "descend";
|
|
3199
|
+
}
|
|
3200
|
+
}
|
|
3201
|
+
if (typeof segment === "string") {
|
|
3202
|
+
return `key:${escapeGroupingText(segment)}`;
|
|
3203
|
+
}
|
|
3204
|
+
if (typeof segment === "number") {
|
|
3205
|
+
return `index:${segment}`;
|
|
3206
|
+
}
|
|
3207
|
+
return "unknown";
|
|
3208
|
+
};
|
|
3209
|
+
var jsonPathGroupingKey = (segments) => {
|
|
3210
|
+
if (segments === undefined) {
|
|
3211
|
+
return "";
|
|
3212
|
+
}
|
|
3213
|
+
if (!Array.isArray(segments)) {
|
|
3214
|
+
return "unknown";
|
|
3215
|
+
}
|
|
3216
|
+
return segments.map(jsonSegmentGroupingKey).join(",");
|
|
3217
|
+
};
|
|
3218
|
+
var isJsonPath = (value) => value !== null && typeof value === "object" && (TypeId8 in value);
|
|
3219
|
+
var jsonOpaquePathGroupingKey = (value) => {
|
|
3220
|
+
if (isJsonPath(value)) {
|
|
3221
|
+
return `jsonpath:${jsonPathGroupingKey(value.segments)}`;
|
|
3222
|
+
}
|
|
3223
|
+
if (typeof value === "string") {
|
|
3224
|
+
return `jsonpath:${escapeGroupingText(value)}`;
|
|
3225
|
+
}
|
|
3226
|
+
if (isExpression2(value)) {
|
|
3227
|
+
return `jsonpath:${groupingKeyOfExpression(value)}`;
|
|
3228
|
+
}
|
|
3229
|
+
return "jsonpath:unknown";
|
|
3230
|
+
};
|
|
3231
|
+
var jsonKeysGroupingKey = (keys) => {
|
|
3232
|
+
if (!Array.isArray(keys) || keys.length === 0) {
|
|
3233
|
+
return "";
|
|
3234
|
+
}
|
|
3235
|
+
return keys.map((key2) => escapeGroupingText(String(key2))).join(",");
|
|
3236
|
+
};
|
|
3237
|
+
var jsonBuildObjectGroupingKey = (entries) => {
|
|
3238
|
+
return entries.map((entry) => `${escapeGroupingText(entry.key)}=>${groupingKeyOfExpression(entry.value)}`).join("|");
|
|
3239
|
+
};
|
|
3240
|
+
var jsonBuildArrayGroupingKey = (values) => values.map(groupingKeyOfExpression).join(",");
|
|
1951
3241
|
var groupingKeyOfExpression = (expression) => {
|
|
1952
3242
|
const ast = expression[TypeId3];
|
|
1953
3243
|
switch (ast.kind) {
|
|
1954
3244
|
case "column":
|
|
1955
|
-
return `column:${ast.tableName
|
|
3245
|
+
return `column:${columnPredicateKey(ast.tableName, ast.columnName)}`;
|
|
1956
3246
|
case "literal":
|
|
1957
3247
|
return `literal:${literalGroupingKey(ast.value)}`;
|
|
1958
3248
|
case "cast":
|
|
1959
|
-
return `cast(${
|
|
3249
|
+
return `cast(${requiredExpressionGroupingKey("cast", ast.value)} as ${castTargetGroupingKey(ast.target)})`;
|
|
3250
|
+
case "collate":
|
|
3251
|
+
return `collate(${requiredExpressionGroupingKey("collate", ast.value)},${collationGroupingKey(ast.collation)})`;
|
|
3252
|
+
case "function":
|
|
3253
|
+
return `function(${functionCallNameGroupingKey(ast.name)},${functionCallArgsGroupingKey(ast.args)})`;
|
|
1960
3254
|
case "isNull":
|
|
1961
3255
|
case "isNotNull":
|
|
1962
3256
|
case "not":
|
|
@@ -1965,7 +3259,7 @@ var groupingKeyOfExpression = (expression) => {
|
|
|
1965
3259
|
case "count":
|
|
1966
3260
|
case "max":
|
|
1967
3261
|
case "min":
|
|
1968
|
-
return `${ast.kind}(${
|
|
3262
|
+
return `${ast.kind}(${requiredExpressionGroupingKey(ast.kind, ast.value)})`;
|
|
1969
3263
|
case "eq":
|
|
1970
3264
|
case "neq":
|
|
1971
3265
|
case "lt":
|
|
@@ -1974,9 +3268,16 @@ var groupingKeyOfExpression = (expression) => {
|
|
|
1974
3268
|
case "gte":
|
|
1975
3269
|
case "like":
|
|
1976
3270
|
case "ilike":
|
|
3271
|
+
case "regexMatch":
|
|
3272
|
+
case "regexIMatch":
|
|
3273
|
+
case "regexNotMatch":
|
|
3274
|
+
case "regexNotIMatch":
|
|
1977
3275
|
case "isDistinctFrom":
|
|
1978
3276
|
case "isNotDistinctFrom":
|
|
1979
|
-
|
|
3277
|
+
case "contains":
|
|
3278
|
+
case "containedBy":
|
|
3279
|
+
case "overlaps":
|
|
3280
|
+
return `${ast.kind}(${requiredBinaryExpressionGroupingKey(ast.kind, ast.left, ast.right)})`;
|
|
1980
3281
|
case "and":
|
|
1981
3282
|
case "or":
|
|
1982
3283
|
case "coalesce":
|
|
@@ -1984,11 +3285,59 @@ var groupingKeyOfExpression = (expression) => {
|
|
|
1984
3285
|
case "in":
|
|
1985
3286
|
case "notIn":
|
|
1986
3287
|
case "between":
|
|
1987
|
-
return `${ast.kind}(${ast.values
|
|
3288
|
+
return `${ast.kind}(${variadicGroupingKey(ast.kind, ast.values)})`;
|
|
1988
3289
|
case "case":
|
|
1989
|
-
return
|
|
3290
|
+
return caseGroupingKey(ast.branches, ast.else);
|
|
3291
|
+
case "exists":
|
|
3292
|
+
return `exists(${subqueryPlanGroupingKey(ast.plan)})`;
|
|
3293
|
+
case "scalarSubquery":
|
|
3294
|
+
return `scalarSubquery(${subqueryPlanGroupingKey(ast.plan)})`;
|
|
3295
|
+
case "inSubquery":
|
|
3296
|
+
return `inSubquery(${requiredExpressionGroupingKey("inSubquery", ast.left)},${subqueryPlanGroupingKey(ast.plan)})`;
|
|
3297
|
+
case "comparisonAny":
|
|
3298
|
+
case "comparisonAll":
|
|
3299
|
+
return `${ast.kind}(${ast.operator},${requiredExpressionGroupingKey(quantifiedComparisonGroupingName(ast.kind), ast.left)},${subqueryPlanGroupingKey(ast.plan)})`;
|
|
3300
|
+
case "jsonGet":
|
|
3301
|
+
case "jsonPath":
|
|
3302
|
+
case "jsonAccess":
|
|
3303
|
+
case "jsonTraverse":
|
|
3304
|
+
case "jsonGetText":
|
|
3305
|
+
case "jsonPathText":
|
|
3306
|
+
case "jsonAccessText":
|
|
3307
|
+
case "jsonTraverseText":
|
|
3308
|
+
return `json(${ast.kind},${expressionGroupingKey(ast.base)},${jsonPathGroupingKey(ast.segments)})`;
|
|
3309
|
+
case "jsonHasKey":
|
|
3310
|
+
case "jsonKeyExists":
|
|
3311
|
+
case "jsonHasAnyKeys":
|
|
3312
|
+
case "jsonHasAllKeys":
|
|
3313
|
+
return `json(${ast.kind},${expressionGroupingKey(ast.base)},${jsonKeysGroupingKey(ast.keys)})`;
|
|
3314
|
+
case "jsonConcat":
|
|
3315
|
+
case "jsonMerge":
|
|
3316
|
+
return `json(${ast.kind},${expressionGroupingKey(ast.left)},${expressionGroupingKey(ast.right)},)`;
|
|
3317
|
+
case "jsonDelete":
|
|
3318
|
+
case "jsonDeletePath":
|
|
3319
|
+
case "jsonRemove":
|
|
3320
|
+
return `json(${ast.kind},${expressionGroupingKey(ast.base)},${expressionGroupingKey(undefined)},${jsonPathGroupingKey(ast.segments)})`;
|
|
3321
|
+
case "jsonSet":
|
|
3322
|
+
return `json(${ast.kind},${expressionGroupingKey(ast.base)},${expressionGroupingKey(ast.newValue)},${jsonPathGroupingKey(ast.segments)})`;
|
|
3323
|
+
case "jsonInsert":
|
|
3324
|
+
return `json(${ast.kind},${expressionGroupingKey(ast.base)},${expressionGroupingKey(ast.insert)},${jsonPathGroupingKey(ast.segments)})`;
|
|
3325
|
+
case "jsonPathExists":
|
|
3326
|
+
case "jsonPathMatch":
|
|
3327
|
+
return `json(${ast.kind},${expressionGroupingKey(ast.base)},${jsonOpaquePathGroupingKey(ast.query)})`;
|
|
3328
|
+
case "jsonBuildObject":
|
|
3329
|
+
return `json(${ast.kind},${jsonBuildObjectGroupingKey(ast.entries)})`;
|
|
3330
|
+
case "jsonBuildArray":
|
|
3331
|
+
return `json(${ast.kind},${jsonBuildArrayGroupingKey(ast.values)})`;
|
|
3332
|
+
case "jsonToJson":
|
|
3333
|
+
case "jsonToJsonb":
|
|
3334
|
+
case "jsonTypeOf":
|
|
3335
|
+
case "jsonLength":
|
|
3336
|
+
case "jsonKeys":
|
|
3337
|
+
case "jsonStripNulls":
|
|
3338
|
+
return `json(${ast.kind},${expressionGroupingKey(ast.value)})`;
|
|
1990
3339
|
default:
|
|
1991
|
-
|
|
3340
|
+
return `unknown:${typeof ast === "object" && ast !== null && "kind" in ast ? String(ast.kind) : "ast"}`;
|
|
1992
3341
|
}
|
|
1993
3342
|
};
|
|
1994
3343
|
var dedupeGroupedExpressions = (values) => {
|
|
@@ -2003,51 +3352,20 @@ var dedupeGroupedExpressions = (values) => {
|
|
|
2003
3352
|
});
|
|
2004
3353
|
};
|
|
2005
3354
|
|
|
2006
|
-
// src/internal/
|
|
2007
|
-
var isExpression2 = (value) => typeof value === "object" && value !== null && (TypeId2 in value);
|
|
2008
|
-
var selectionHasAggregate = (selection) => {
|
|
2009
|
-
if (isExpression2(selection)) {
|
|
2010
|
-
return selection[TypeId2].kind === "aggregate";
|
|
2011
|
-
}
|
|
2012
|
-
return Object.values(selection).some((value) => selectionHasAggregate(value));
|
|
2013
|
-
};
|
|
2014
|
-
var isGroupedSelectionValid = (selection, groupedExpressions) => {
|
|
2015
|
-
if (isExpression2(selection)) {
|
|
2016
|
-
const aggregation = selection[TypeId2].kind;
|
|
2017
|
-
if (aggregation === "aggregate") {
|
|
2018
|
-
return true;
|
|
2019
|
-
}
|
|
2020
|
-
if (aggregation === "window") {
|
|
2021
|
-
return false;
|
|
2022
|
-
}
|
|
2023
|
-
if (Object.keys(selection[TypeId2].dependencies).length === 0) {
|
|
2024
|
-
return true;
|
|
2025
|
-
}
|
|
2026
|
-
return groupedExpressions.has(groupingKeyOfExpression(selection));
|
|
2027
|
-
}
|
|
2028
|
-
return Object.values(selection).every((value) => isGroupedSelectionValid(value, groupedExpressions));
|
|
2029
|
-
};
|
|
2030
|
-
var validateAggregationSelection = (selection, grouped) => {
|
|
2031
|
-
const groupedExpressions = new Set(grouped.map(groupingKeyOfExpression));
|
|
2032
|
-
const hasAggregate = selectionHasAggregate(selection);
|
|
2033
|
-
const isValid = hasAggregate || grouped.length > 0 ? isGroupedSelectionValid(selection, groupedExpressions) : true;
|
|
2034
|
-
if (!isValid) {
|
|
2035
|
-
throw new Error("Invalid grouped selection: scalar expressions must be covered by groupBy(...) when aggregates are present");
|
|
2036
|
-
}
|
|
2037
|
-
};
|
|
2038
|
-
|
|
2039
|
-
// src/postgres/internal/sql-expression-renderer.ts
|
|
3355
|
+
// src/internal/dialect-renderers/postgres.ts
|
|
2040
3356
|
var renderDbType = (dialect, dbType) => {
|
|
2041
|
-
if (dialect.name === "
|
|
2042
|
-
return "
|
|
3357
|
+
if (dialect.name === "postgres" && dbType.kind === "blob") {
|
|
3358
|
+
return "bytea";
|
|
2043
3359
|
}
|
|
2044
|
-
return dbType.kind;
|
|
3360
|
+
return renderDbTypeName(dbType.kind);
|
|
2045
3361
|
};
|
|
3362
|
+
var isArrayDbType = (dbType) => ("element" in dbType);
|
|
2046
3363
|
var renderCastType = (dialect, dbType) => {
|
|
3364
|
+
const kind = dbType?.kind;
|
|
2047
3365
|
if (dialect.name !== "mysql") {
|
|
2048
|
-
return
|
|
3366
|
+
return renderDbTypeName(kind);
|
|
2049
3367
|
}
|
|
2050
|
-
switch (
|
|
3368
|
+
switch (kind) {
|
|
2051
3369
|
case "text":
|
|
2052
3370
|
return "char";
|
|
2053
3371
|
case "uuid":
|
|
@@ -2062,21 +3380,145 @@ var renderCastType = (dialect, dbType) => {
|
|
|
2062
3380
|
case "json":
|
|
2063
3381
|
return "json";
|
|
2064
3382
|
default:
|
|
2065
|
-
return
|
|
3383
|
+
return renderDbTypeName(kind);
|
|
3384
|
+
}
|
|
3385
|
+
};
|
|
3386
|
+
var casingForTable = (table, state) => merge(state.casing, table[TypeId6].casing);
|
|
3387
|
+
var casedTableName = (table, state) => {
|
|
3388
|
+
const tableState = table[TypeId6];
|
|
3389
|
+
return applyCategory(casingForTable(table, state), "tables", tableState.baseName);
|
|
3390
|
+
};
|
|
3391
|
+
var casedSchemaName = (table, state) => {
|
|
3392
|
+
const schemaName = table[TypeId6].schemaName;
|
|
3393
|
+
return schemaName === undefined ? undefined : applyCategory(casingForTable(table, state), "schemas", schemaName);
|
|
3394
|
+
};
|
|
3395
|
+
var casedColumnName = (columnName, state, tableName) => {
|
|
3396
|
+
if (tableName !== undefined) {
|
|
3397
|
+
const mapped = state.sourceNames?.get(tableName)?.columns.get(columnName);
|
|
3398
|
+
if (mapped !== undefined) {
|
|
3399
|
+
return mapped;
|
|
3400
|
+
}
|
|
3401
|
+
}
|
|
3402
|
+
return applyCategory(state.casing, "columns", columnName);
|
|
3403
|
+
};
|
|
3404
|
+
var casedTableReferenceName = (tableName, state) => state.sourceNames?.get(tableName)?.tableName ?? applyCategory(state.casing, "tables", tableName);
|
|
3405
|
+
var quoteColumn = (columnName, state, dialect, tableName) => dialect.quoteIdentifier(casedColumnName(columnName, state, tableName));
|
|
3406
|
+
var stateWithTableCasing = (state, source) => typeof source === "object" && source !== null && (TypeId6 in source) ? { ...state, casing: casingForTable(source, state) } : state;
|
|
3407
|
+
var referenceCasing = (reference, state) => merge(state.casing, reference.casing);
|
|
3408
|
+
var renderReferenceTable = (reference, state, dialect) => {
|
|
3409
|
+
const casing = referenceCasing(reference, state);
|
|
3410
|
+
const tableName = applyCategory(casing, "tables", reference.tableName);
|
|
3411
|
+
const schemaName = reference.schemaName === undefined ? undefined : applyCategory(casing, "schemas", reference.schemaName);
|
|
3412
|
+
return dialect.renderTableReference(tableName, tableName, schemaName);
|
|
3413
|
+
};
|
|
3414
|
+
var quoteReferenceColumn = (columnName, reference, state, dialect) => dialect.quoteIdentifier(applyCategory(referenceCasing(reference, state), "columns", columnName));
|
|
3415
|
+
var registerSourceReference = (source, tableName, state) => {
|
|
3416
|
+
if (typeof source !== "object" || source === null) {
|
|
3417
|
+
return;
|
|
3418
|
+
}
|
|
3419
|
+
if (TypeId6 in source) {
|
|
3420
|
+
const table = source;
|
|
3421
|
+
const tableState = table[TypeId6];
|
|
3422
|
+
const casing = casingForTable(table, state);
|
|
3423
|
+
const renderedTableName = tableState.kind === "alias" ? tableName : applyCategory(casing, "tables", tableState.baseName);
|
|
3424
|
+
const columns = new Map(Object.keys(tableState.fields).map((columnName) => [
|
|
3425
|
+
columnName,
|
|
3426
|
+
applyCategory(casing, "columns", columnName)
|
|
3427
|
+
]));
|
|
3428
|
+
state.sourceNames?.set(tableName, {
|
|
3429
|
+
tableName: renderedTableName,
|
|
3430
|
+
columns
|
|
3431
|
+
});
|
|
3432
|
+
return;
|
|
3433
|
+
}
|
|
3434
|
+
if ("columns" in source && typeof source.columns === "object" && source.columns !== null) {
|
|
3435
|
+
state.sourceNames?.set(tableName, {
|
|
3436
|
+
tableName,
|
|
3437
|
+
columns: new Map(Object.keys(source.columns).map((columnName) => [columnName, columnName]))
|
|
3438
|
+
});
|
|
3439
|
+
}
|
|
3440
|
+
};
|
|
3441
|
+
var registerQuerySources = (ast, state) => {
|
|
3442
|
+
if (ast.from !== undefined) {
|
|
3443
|
+
registerSourceReference(ast.from.source, ast.from.tableName, state);
|
|
3444
|
+
}
|
|
3445
|
+
for (const source of ast.fromSources ?? []) {
|
|
3446
|
+
registerSourceReference(source.source, source.tableName, state);
|
|
3447
|
+
}
|
|
3448
|
+
for (const join of ast.joins) {
|
|
3449
|
+
registerSourceReference(join.source, join.tableName, state);
|
|
3450
|
+
}
|
|
3451
|
+
if (ast.into !== undefined) {
|
|
3452
|
+
registerSourceReference(ast.into.source, ast.into.tableName, state);
|
|
3453
|
+
}
|
|
3454
|
+
if (ast.target !== undefined) {
|
|
3455
|
+
registerSourceReference(ast.target.source, ast.target.tableName, state);
|
|
3456
|
+
}
|
|
3457
|
+
for (const target of ast.targets ?? []) {
|
|
3458
|
+
registerSourceReference(target.source, target.tableName, state);
|
|
3459
|
+
}
|
|
3460
|
+
if (ast.using !== undefined) {
|
|
3461
|
+
registerSourceReference(ast.using.source, ast.using.tableName, state);
|
|
2066
3462
|
}
|
|
2067
3463
|
};
|
|
2068
|
-
var
|
|
2069
|
-
var
|
|
3464
|
+
var renderPostgresDdlString = (value) => `'${value.replaceAll("'", "''")}'`;
|
|
3465
|
+
var renderPostgresDdlBytes = (value) => `decode('${Array.from(value, (byte) => byte.toString(16).padStart(2, "0")).join("")}', 'hex')`;
|
|
3466
|
+
var renderPostgresDdlLiteral = (value, state, context = {}) => {
|
|
3467
|
+
const driverValue = toDriverValue(value, {
|
|
3468
|
+
dialect: "postgres",
|
|
3469
|
+
valueMappings: state.valueMappings,
|
|
3470
|
+
...context
|
|
3471
|
+
});
|
|
3472
|
+
if (driverValue === null) {
|
|
3473
|
+
return "null";
|
|
3474
|
+
}
|
|
3475
|
+
switch (typeof driverValue) {
|
|
3476
|
+
case "boolean":
|
|
3477
|
+
return driverValue ? "true" : "false";
|
|
3478
|
+
case "number":
|
|
3479
|
+
if (!Number.isFinite(driverValue)) {
|
|
3480
|
+
throw new Error("Expected a finite numeric value");
|
|
3481
|
+
}
|
|
3482
|
+
return String(driverValue);
|
|
3483
|
+
case "bigint":
|
|
3484
|
+
return driverValue.toString();
|
|
3485
|
+
case "string":
|
|
3486
|
+
return renderPostgresDdlString(driverValue);
|
|
3487
|
+
case "object":
|
|
3488
|
+
if (driverValue instanceof Uint8Array) {
|
|
3489
|
+
return renderPostgresDdlBytes(driverValue);
|
|
3490
|
+
}
|
|
3491
|
+
break;
|
|
3492
|
+
}
|
|
3493
|
+
throw new Error("Unsupported postgres DDL literal value");
|
|
3494
|
+
};
|
|
3495
|
+
var renderDdlExpression = (expression, state, dialect) => {
|
|
3496
|
+
if (isSchemaExpression(expression)) {
|
|
3497
|
+
return render(expression);
|
|
3498
|
+
}
|
|
3499
|
+
return renderExpression2(expression, state, {
|
|
3500
|
+
...dialect,
|
|
3501
|
+
renderLiteral: renderPostgresDdlLiteral
|
|
3502
|
+
});
|
|
3503
|
+
};
|
|
3504
|
+
var renderColumnDefinition = (dialect, state, columnName, column, tableName, casing) => {
|
|
3505
|
+
const expressionState = { ...state, casing, rowLocalColumns: true };
|
|
3506
|
+
if (dialect.name !== "postgres" && isArrayDbType(column.metadata.dbType)) {
|
|
3507
|
+
throw new Error(`Unsupported ${dialect.name} array column options`);
|
|
3508
|
+
}
|
|
2070
3509
|
const clauses = [
|
|
2071
|
-
|
|
2072
|
-
column.metadata.ddlType
|
|
3510
|
+
quoteColumn(columnName, state, dialect, tableName),
|
|
3511
|
+
column.metadata.ddlType === undefined ? renderDbType(dialect, column.metadata.dbType) : renderDbTypeName(column.metadata.ddlType)
|
|
2073
3512
|
];
|
|
2074
3513
|
if (column.metadata.identity) {
|
|
3514
|
+
if (dialect.name !== "postgres") {
|
|
3515
|
+
throw new Error(`Unsupported ${dialect.name} identity column options`);
|
|
3516
|
+
}
|
|
2075
3517
|
clauses.push(`generated ${column.metadata.identity.generation === "byDefault" ? "by default" : "always"} as identity`);
|
|
2076
3518
|
} else if (column.metadata.generatedValue) {
|
|
2077
|
-
clauses.push(`generated always as (${renderDdlExpression(column.metadata.generatedValue,
|
|
3519
|
+
clauses.push(`generated always as (${renderDdlExpression(column.metadata.generatedValue, expressionState, dialect)}) stored`);
|
|
2078
3520
|
} else if (column.metadata.defaultValue) {
|
|
2079
|
-
clauses.push(`default ${renderDdlExpression(column.metadata.defaultValue,
|
|
3521
|
+
clauses.push(`default ${renderDdlExpression(column.metadata.defaultValue, expressionState, dialect)}`);
|
|
2080
3522
|
}
|
|
2081
3523
|
if (!column.metadata.nullable) {
|
|
2082
3524
|
clauses.push("not null");
|
|
@@ -2084,39 +3526,135 @@ var renderColumnDefinition = (dialect, state, columnName, column) => {
|
|
|
2084
3526
|
return clauses.join(" ");
|
|
2085
3527
|
};
|
|
2086
3528
|
var renderCreateTableSql = (targetSource, state, dialect, ifNotExists) => {
|
|
3529
|
+
const normalizedIfNotExists = normalizeStatementFlag(ifNotExists);
|
|
3530
|
+
if (dialect.name !== "postgres" && normalizedIfNotExists) {
|
|
3531
|
+
throw new Error(`Unsupported ${dialect.name} create table options`);
|
|
3532
|
+
}
|
|
2087
3533
|
const table = targetSource.source;
|
|
2088
|
-
const
|
|
2089
|
-
const
|
|
2090
|
-
|
|
3534
|
+
const tableCasing = casingForTable(table, state);
|
|
3535
|
+
const fields = table[TypeId6].fields;
|
|
3536
|
+
const definitions = Object.entries(fields).map(([columnName, column]) => renderColumnDefinition(dialect, state, columnName, column, targetSource.tableName, tableCasing));
|
|
3537
|
+
const options2 = table[OptionsSymbol];
|
|
3538
|
+
const tableOptions = Array.isArray(options2) ? options2 : [options2];
|
|
3539
|
+
validateOptions(table[TypeId6].name, fields, tableOptions);
|
|
3540
|
+
for (const option2 of tableOptions) {
|
|
3541
|
+
if (typeof option2 !== "object" || option2 === null || !("kind" in option2)) {
|
|
3542
|
+
continue;
|
|
3543
|
+
}
|
|
2091
3544
|
switch (option2.kind) {
|
|
2092
3545
|
case "primaryKey":
|
|
2093
|
-
|
|
3546
|
+
if (dialect.name !== "postgres" && (option2.deferrable || option2.initiallyDeferred)) {
|
|
3547
|
+
throw new Error(`Unsupported ${dialect.name} primary key constraint options`);
|
|
3548
|
+
}
|
|
3549
|
+
definitions.push(`${option2.name ? `constraint ${dialect.quoteIdentifier(applyCategory(tableCasing, "constraints", option2.name))} ` : ""}primary key (${option2.columns.map((column) => quoteColumn(column, state, dialect, targetSource.tableName)).join(", ")})${option2.deferrable ? ` deferrable${option2.initiallyDeferred ? " initially deferred" : ""}` : ""}`);
|
|
2094
3550
|
break;
|
|
2095
3551
|
case "unique":
|
|
2096
|
-
|
|
3552
|
+
if (dialect.name !== "postgres" && (option2.nullsNotDistinct || option2.deferrable || option2.initiallyDeferred)) {
|
|
3553
|
+
throw new Error(`Unsupported ${dialect.name} unique constraint options`);
|
|
3554
|
+
}
|
|
3555
|
+
definitions.push(`${option2.name ? `constraint ${dialect.quoteIdentifier(applyCategory(tableCasing, "constraints", option2.name))} ` : ""}unique${option2.nullsNotDistinct ? " nulls not distinct" : ""} (${option2.columns.map((column) => quoteColumn(column, state, dialect, targetSource.tableName)).join(", ")})${option2.deferrable ? ` deferrable${option2.initiallyDeferred ? " initially deferred" : ""}` : ""}`);
|
|
2097
3556
|
break;
|
|
2098
3557
|
case "foreignKey": {
|
|
2099
|
-
|
|
2100
|
-
|
|
3558
|
+
if (dialect.name !== "postgres" && (option2.deferrable || option2.initiallyDeferred)) {
|
|
3559
|
+
throw new Error(`Unsupported ${dialect.name} foreign key constraint options`);
|
|
3560
|
+
}
|
|
3561
|
+
const reference = typeof option2.references === "function" ? option2.references() : option2.references;
|
|
3562
|
+
definitions.push(`${option2.name ? `constraint ${dialect.quoteIdentifier(applyCategory(tableCasing, "constraints", option2.name))} ` : ""}foreign key (${option2.columns.map((column) => quoteColumn(column, state, dialect, targetSource.tableName)).join(", ")}) references ${renderReferenceTable(reference, state, dialect)} (${reference.columns.map((column) => quoteReferenceColumn(column, reference, state, dialect)).join(", ")})${option2.onDelete !== undefined ? ` on delete ${renderReferentialAction(option2.onDelete)}` : ""}${option2.onUpdate !== undefined ? ` on update ${renderReferentialAction(option2.onUpdate)}` : ""}${option2.deferrable ? ` deferrable${option2.initiallyDeferred ? " initially deferred" : ""}` : ""}`);
|
|
2101
3563
|
break;
|
|
2102
3564
|
}
|
|
2103
3565
|
case "check":
|
|
2104
|
-
|
|
3566
|
+
if (dialect.name !== "postgres" && option2.noInherit) {
|
|
3567
|
+
throw new Error(`Unsupported ${dialect.name} check constraint options`);
|
|
3568
|
+
}
|
|
3569
|
+
definitions.push(`constraint ${dialect.quoteIdentifier(applyCategory(tableCasing, "constraints", option2.name))} check (${renderDdlExpression(option2.predicate, { ...state, casing: tableCasing, rowLocalColumns: true }, dialect)})${option2.noInherit ? " no inherit" : ""}`);
|
|
2105
3570
|
break;
|
|
2106
3571
|
case "index":
|
|
2107
3572
|
break;
|
|
3573
|
+
default:
|
|
3574
|
+
throw new Error("Unsupported table option kind");
|
|
2108
3575
|
}
|
|
2109
3576
|
}
|
|
2110
|
-
return `create table${
|
|
3577
|
+
return `create table${normalizedIfNotExists ? " if not exists" : ""} ${renderSourceReference(targetSource.source, targetSource.tableName, targetSource.baseTableName, state, dialect)} (${definitions.join(", ")})`;
|
|
2111
3578
|
};
|
|
2112
3579
|
var renderCreateIndexSql = (targetSource, ddl, state, dialect) => {
|
|
2113
|
-
const
|
|
2114
|
-
|
|
3580
|
+
const unique2 = normalizeStatementFlag(ddl.unique);
|
|
3581
|
+
const ifNotExists = normalizeStatementFlag(ddl.ifNotExists);
|
|
3582
|
+
const name = normalizeStatementIdentifier("createIndex", "option 'name'", ddl.name);
|
|
3583
|
+
if (dialect.name !== "postgres" && ifNotExists) {
|
|
3584
|
+
throw new Error(`Unsupported ${dialect.name} create index options`);
|
|
3585
|
+
}
|
|
3586
|
+
const maybeIfNotExists = dialect.name === "postgres" && ifNotExists ? " if not exists" : "";
|
|
3587
|
+
const table = targetSource.source;
|
|
3588
|
+
const tableCasing = casingForTable(table, state);
|
|
3589
|
+
return `create${unique2 ? " unique" : ""} index${maybeIfNotExists} ${dialect.quoteIdentifier(applyCategory(tableCasing, "indexes", name))} on ${renderSourceReference(targetSource.source, targetSource.tableName, targetSource.baseTableName, state, dialect)} (${ddl.columns.map((column) => quoteColumn(column, state, dialect, targetSource.tableName)).join(", ")})`;
|
|
3590
|
+
};
|
|
3591
|
+
var renderDropIndexSql = (targetSource, ddl, state, dialect) => {
|
|
3592
|
+
const ifExists = normalizeStatementFlag(ddl.ifExists);
|
|
3593
|
+
const name = normalizeStatementIdentifier("dropIndex", "option 'name'", ddl.name);
|
|
3594
|
+
if (dialect.name !== "postgres" && ifExists) {
|
|
3595
|
+
throw new Error(`Unsupported ${dialect.name} drop index options`);
|
|
3596
|
+
}
|
|
3597
|
+
if (dialect.name === "postgres") {
|
|
3598
|
+
const table2 = typeof targetSource.source === "object" && targetSource.source !== null && TypeId6 in targetSource.source ? targetSource.source : undefined;
|
|
3599
|
+
const schemaName = table2?.[TypeId6].schemaName;
|
|
3600
|
+
const tableCasing2 = table2 === undefined ? state.casing : casingForTable(table2, state);
|
|
3601
|
+
const renderedSchemaName = table2 === undefined ? schemaName : casedSchemaName(table2, state);
|
|
3602
|
+
const renderedIndexName = applyCategory(tableCasing2, "indexes", name);
|
|
3603
|
+
const indexName = schemaName === undefined || schemaName === "public" ? dialect.quoteIdentifier(renderedIndexName) : `${dialect.quoteIdentifier(renderedSchemaName ?? schemaName)}.${dialect.quoteIdentifier(renderedIndexName)}`;
|
|
3604
|
+
return `drop index${ifExists ? " if exists" : ""} ${indexName}`;
|
|
3605
|
+
}
|
|
3606
|
+
const table = targetSource.source;
|
|
3607
|
+
const tableCasing = casingForTable(table, state);
|
|
3608
|
+
return `drop index ${dialect.quoteIdentifier(applyCategory(tableCasing, "indexes", name))} on ${renderSourceReference(targetSource.source, targetSource.tableName, targetSource.baseTableName, state, dialect)}`;
|
|
2115
3609
|
};
|
|
2116
|
-
var renderDropIndexSql = (targetSource, ddl, state, dialect) => dialect.name === "postgres" ? `drop index${ddl.ifExists ? " if exists" : ""} ${dialect.quoteIdentifier(ddl.name)}` : `drop index ${dialect.quoteIdentifier(ddl.name)} on ${renderSourceReference(targetSource.source, targetSource.tableName, targetSource.baseTableName, state, dialect)}`;
|
|
2117
3610
|
var isExpression3 = (value) => value !== null && typeof value === "object" && (TypeId2 in value);
|
|
2118
|
-
var
|
|
2119
|
-
|
|
3611
|
+
var isJsonDbType2 = (dbType) => {
|
|
3612
|
+
if (dbType.kind === "jsonb" || dbType.kind === "json") {
|
|
3613
|
+
return true;
|
|
3614
|
+
}
|
|
3615
|
+
if (!("variant" in dbType)) {
|
|
3616
|
+
return false;
|
|
3617
|
+
}
|
|
3618
|
+
const variant = dbType.variant;
|
|
3619
|
+
return variant === "json" || variant === "jsonb";
|
|
3620
|
+
};
|
|
3621
|
+
var isJsonExpression = (value) => isExpression3(value) && isJsonDbType2(value[TypeId2].dbType);
|
|
3622
|
+
var expectValueExpression = (_functionName, value) => value;
|
|
3623
|
+
var expectBinaryExpressions = (_functionName, left, right) => [left, right];
|
|
3624
|
+
var renderBinaryExpression = (functionName, operator, left, right, state, dialect) => {
|
|
3625
|
+
const [leftExpression, rightExpression] = expectBinaryExpressions(functionName, left, right);
|
|
3626
|
+
return `(${renderExpression2(leftExpression, state, dialect)} ${operator} ${renderExpression2(rightExpression, state, dialect)})`;
|
|
3627
|
+
};
|
|
3628
|
+
var postgresRangeSubtypeByKind = {
|
|
3629
|
+
int4range: "int4",
|
|
3630
|
+
int8range: "int8",
|
|
3631
|
+
numrange: "numeric",
|
|
3632
|
+
tsrange: "timestamp",
|
|
3633
|
+
tstzrange: "timestamptz",
|
|
3634
|
+
daterange: "date",
|
|
3635
|
+
int4multirange: "int4",
|
|
3636
|
+
int8multirange: "int8",
|
|
3637
|
+
nummultirange: "numeric",
|
|
3638
|
+
tsmultirange: "timestamp",
|
|
3639
|
+
tstzmultirange: "timestamptz",
|
|
3640
|
+
datemultirange: "date"
|
|
3641
|
+
};
|
|
3642
|
+
var postgresRangeSubtypeKey = (dbType) => {
|
|
3643
|
+
if ("base" in dbType) {
|
|
3644
|
+
return postgresRangeSubtypeKey(dbType.base);
|
|
3645
|
+
}
|
|
3646
|
+
if ("subtype" in dbType) {
|
|
3647
|
+
return postgresRangeSubtypeKey(dbType.subtype) ?? dbType.subtype.kind;
|
|
3648
|
+
}
|
|
3649
|
+
return postgresRangeSubtypeByKind[dbType.kind];
|
|
3650
|
+
};
|
|
3651
|
+
var assertCompatiblePostgresRangeOperands = (left, right) => {
|
|
3652
|
+
const leftKey = postgresRangeSubtypeKey(left[TypeId2].dbType);
|
|
3653
|
+
const rightKey = postgresRangeSubtypeKey(right[TypeId2].dbType);
|
|
3654
|
+
if (leftKey !== undefined && rightKey !== undefined && leftKey !== rightKey) {
|
|
3655
|
+
throw new Error("Incompatible postgres range operands");
|
|
3656
|
+
}
|
|
3657
|
+
};
|
|
2120
3658
|
var unsupportedJsonFeature = (dialect, feature) => {
|
|
2121
3659
|
const error = new Error(`Unsupported JSON feature for ${dialect.name}: ${feature}`);
|
|
2122
3660
|
Object.assign(error, {
|
|
@@ -2127,14 +3665,53 @@ var unsupportedJsonFeature = (dialect, feature) => {
|
|
|
2127
3665
|
throw error;
|
|
2128
3666
|
};
|
|
2129
3667
|
var extractJsonBase = (node) => node.value ?? node.base ?? node.input ?? node.left ?? node.target;
|
|
2130
|
-
var isJsonPathValue = (value) => value !== null && typeof value === "object" && (
|
|
3668
|
+
var isJsonPathValue = (value) => value !== null && typeof value === "object" && (TypeId8 in value);
|
|
3669
|
+
var isOptionalJsonPathNumber = (value) => value === undefined || typeof value === "number" && Number.isFinite(value);
|
|
3670
|
+
var isJsonPathSegment = (segment) => {
|
|
3671
|
+
if (typeof segment === "string") {
|
|
3672
|
+
return true;
|
|
3673
|
+
}
|
|
3674
|
+
if (typeof segment === "number") {
|
|
3675
|
+
return Number.isFinite(segment);
|
|
3676
|
+
}
|
|
3677
|
+
if (segment === null || typeof segment !== "object" || !("kind" in segment)) {
|
|
3678
|
+
return false;
|
|
3679
|
+
}
|
|
3680
|
+
switch (segment.kind) {
|
|
3681
|
+
case "key":
|
|
3682
|
+
return typeof segment.key === "string";
|
|
3683
|
+
case "index": {
|
|
3684
|
+
const index3 = segment.index;
|
|
3685
|
+
return typeof index3 === "number" && Number.isFinite(index3);
|
|
3686
|
+
}
|
|
3687
|
+
case "wildcard":
|
|
3688
|
+
case "descend":
|
|
3689
|
+
return true;
|
|
3690
|
+
case "slice":
|
|
3691
|
+
return isOptionalJsonPathNumber(segment.start) && isOptionalJsonPathNumber(segment.end);
|
|
3692
|
+
default:
|
|
3693
|
+
return false;
|
|
3694
|
+
}
|
|
3695
|
+
};
|
|
3696
|
+
var validateJsonPathSegments = (segments) => {
|
|
3697
|
+
if (!Array.isArray(segments)) {
|
|
3698
|
+
throw new Error("JSON path expressions require a segment array");
|
|
3699
|
+
}
|
|
3700
|
+
if (segments.some((segment) => !isJsonPathSegment(segment))) {
|
|
3701
|
+
throw new Error("JSON path segments require string, number, or path segment objects");
|
|
3702
|
+
}
|
|
3703
|
+
return segments;
|
|
3704
|
+
};
|
|
2131
3705
|
var extractJsonPathSegments = (node) => {
|
|
2132
3706
|
const path2 = node.path ?? node.segments ?? node.keys;
|
|
2133
3707
|
if (isJsonPathValue(path2)) {
|
|
2134
|
-
return path2.segments;
|
|
3708
|
+
return validateJsonPathSegments(path2.segments);
|
|
2135
3709
|
}
|
|
2136
3710
|
if (Array.isArray(path2)) {
|
|
2137
|
-
return path2;
|
|
3711
|
+
return validateJsonPathSegments(path2);
|
|
3712
|
+
}
|
|
3713
|
+
if (node.segments !== undefined) {
|
|
3714
|
+
return validateJsonPathSegments(node.segments);
|
|
2138
3715
|
}
|
|
2139
3716
|
if ("key" in node) {
|
|
2140
3717
|
return [key(String(node.key))];
|
|
@@ -2153,21 +3730,23 @@ var extractJsonPathSegments = (node) => {
|
|
|
2153
3730
|
return [];
|
|
2154
3731
|
}
|
|
2155
3732
|
if ("right" in node && isJsonPathValue(node.right)) {
|
|
2156
|
-
return node.right.segments;
|
|
3733
|
+
return validateJsonPathSegments(node.right.segments);
|
|
2157
3734
|
}
|
|
2158
3735
|
return [];
|
|
2159
3736
|
};
|
|
3737
|
+
var extractJsonKeys = (node, segments) => Array.isArray(node.keys) ? node.keys : segments.map((segment) => typeof segment === "object" && segment !== null && segment.kind === "key" ? segment.key : segment);
|
|
2160
3738
|
var extractJsonValue = (node) => node.newValue ?? node.insert ?? node.right;
|
|
2161
3739
|
var renderJsonPathSegment = (segment) => {
|
|
3740
|
+
const renderKey = (value) => /^[A-Za-z_][A-Za-z0-9_]*$/.test(value) ? `.${value}` : `.${JSON.stringify(value)}`;
|
|
2162
3741
|
if (typeof segment === "string") {
|
|
2163
|
-
return
|
|
3742
|
+
return renderKey(segment);
|
|
2164
3743
|
}
|
|
2165
3744
|
if (typeof segment === "number") {
|
|
2166
3745
|
return `[${segment}]`;
|
|
2167
3746
|
}
|
|
2168
3747
|
switch (segment.kind) {
|
|
2169
3748
|
case "key":
|
|
2170
|
-
return
|
|
3749
|
+
return renderKey(segment.key);
|
|
2171
3750
|
case "index":
|
|
2172
3751
|
return `[${segment.index}]`;
|
|
2173
3752
|
case "wildcard":
|
|
@@ -2210,7 +3789,7 @@ var renderPostgresJsonAccessStep = (segment, textMode, state, dialect) => {
|
|
|
2210
3789
|
case "key":
|
|
2211
3790
|
return `${textMode ? "->>" : "->"} ${dialect.renderLiteral(segment.key, state)}`;
|
|
2212
3791
|
case "index":
|
|
2213
|
-
return `${textMode ? "->>" : "->"} ${dialect.renderLiteral(
|
|
3792
|
+
return `${textMode ? "->>" : "->"} ${dialect.renderLiteral(segment.index, state)}`;
|
|
2214
3793
|
default:
|
|
2215
3794
|
throw new Error("Postgres exact JSON access requires key/index segments");
|
|
2216
3795
|
}
|
|
@@ -2219,7 +3798,7 @@ var renderPostgresJsonValue = (value, state, dialect) => {
|
|
|
2219
3798
|
if (!isExpression3(value)) {
|
|
2220
3799
|
throw new Error("Expected a JSON expression");
|
|
2221
3800
|
}
|
|
2222
|
-
const rendered =
|
|
3801
|
+
const rendered = renderExpression2(value, state, dialect);
|
|
2223
3802
|
const ast = value[TypeId3];
|
|
2224
3803
|
if (ast.kind === "literal") {
|
|
2225
3804
|
return `cast(${rendered} as jsonb)`;
|
|
@@ -2233,58 +3812,74 @@ var expressionDriverContext = (expression, state, dialect) => ({
|
|
|
2233
3812
|
runtimeSchema: expression[TypeId2].runtimeSchema,
|
|
2234
3813
|
driverValueMapping: expression[TypeId2].driverValueMapping
|
|
2235
3814
|
});
|
|
2236
|
-
var renderJsonInputExpression = (expression, state, dialect) => renderJsonSelectSql(
|
|
2237
|
-
var encodeArrayValues = (values, column, state, dialect) => values.map((value) =>
|
|
2238
|
-
|
|
2239
|
-
|
|
2240
|
-
|
|
2241
|
-
|
|
2242
|
-
|
|
2243
|
-
|
|
3815
|
+
var renderJsonInputExpression = (expression, state, dialect) => renderJsonSelectSql(renderExpression2(expression, state, dialect), expressionDriverContext(expression, state, dialect));
|
|
3816
|
+
var encodeArrayValues = (values, column, state, dialect) => values.map((value) => {
|
|
3817
|
+
if (value === null && column.metadata.nullable) {
|
|
3818
|
+
return null;
|
|
3819
|
+
}
|
|
3820
|
+
const runtimeSchemaAccepts = column.schema !== undefined && Schema5.is(column.schema)(value);
|
|
3821
|
+
const normalizedValue = runtimeSchemaAccepts ? value : normalizeDbValue(column.metadata.dbType, value);
|
|
3822
|
+
const encodedValue = column.schema === undefined || runtimeSchemaAccepts ? normalizedValue : Schema5.decodeUnknownSync(column.schema)(normalizedValue);
|
|
3823
|
+
return toDriverValue(encodedValue, {
|
|
3824
|
+
dialect: dialect.name,
|
|
3825
|
+
valueMappings: state.valueMappings,
|
|
3826
|
+
dbType: column.metadata.dbType,
|
|
3827
|
+
runtimeSchema: column.schema,
|
|
3828
|
+
driverValueMapping: column.metadata.driverValueMapping
|
|
3829
|
+
});
|
|
3830
|
+
});
|
|
2244
3831
|
var renderPostgresJsonKind = (value) => value[TypeId2].dbType.kind === "jsonb" ? "jsonb" : "json";
|
|
2245
3832
|
var renderJsonOpaquePath = (value, state, dialect) => {
|
|
2246
3833
|
if (isJsonPathValue(value)) {
|
|
2247
3834
|
return dialect.renderLiteral(renderJsonPathStringLiteral(value.segments), state);
|
|
2248
3835
|
}
|
|
2249
3836
|
if (typeof value === "string") {
|
|
3837
|
+
if (value.trim().length === 0) {
|
|
3838
|
+
throw new Error("SQL/JSON path input must be a non-empty string");
|
|
3839
|
+
}
|
|
2250
3840
|
return dialect.renderLiteral(value, state);
|
|
2251
3841
|
}
|
|
2252
3842
|
if (isExpression3(value)) {
|
|
2253
|
-
|
|
3843
|
+
const ast = value[TypeId3];
|
|
3844
|
+
if (ast.kind === "literal" && typeof ast.value === "string" && ast.value.trim().length === 0) {
|
|
3845
|
+
throw new Error("SQL/JSON path input must be a non-empty string");
|
|
3846
|
+
}
|
|
3847
|
+
return renderExpression2(value, state, dialect);
|
|
2254
3848
|
}
|
|
2255
3849
|
throw new Error("Unsupported SQL/JSON path input");
|
|
2256
3850
|
};
|
|
3851
|
+
var renderFunctionName = (name) => {
|
|
3852
|
+
return name;
|
|
3853
|
+
};
|
|
3854
|
+
var renderExtractField = (field) => {
|
|
3855
|
+
const ast = field[TypeId3];
|
|
3856
|
+
return ast.value;
|
|
3857
|
+
};
|
|
2257
3858
|
var renderFunctionCall = (name, args, state, dialect) => {
|
|
2258
|
-
|
|
2259
|
-
|
|
2260
|
-
|
|
2261
|
-
|
|
2262
|
-
|
|
2263
|
-
|
|
2264
|
-
|
|
2265
|
-
|
|
2266
|
-
}
|
|
2267
|
-
|
|
2268
|
-
|
|
2269
|
-
|
|
2270
|
-
|
|
2271
|
-
const renderedField = fieldRuntime ?? renderExpression(field, state, dialect);
|
|
2272
|
-
return `extract(${renderedField} from ${renderExpression(source, state, dialect)})`;
|
|
2273
|
-
}
|
|
2274
|
-
const renderedArgs = args.map((arg) => renderExpression(arg, state, dialect)).join(", ");
|
|
2275
|
-
if (args.length === 0) {
|
|
2276
|
-
switch (name) {
|
|
3859
|
+
const functionName = renderFunctionName(name);
|
|
3860
|
+
const functionArgs = args;
|
|
3861
|
+
if (functionName === "array") {
|
|
3862
|
+
return `ARRAY[${functionArgs.map((arg) => renderExpression2(arg, state, dialect)).join(", ")}]`;
|
|
3863
|
+
}
|
|
3864
|
+
if (functionName === "extract") {
|
|
3865
|
+
const field = functionArgs[0];
|
|
3866
|
+
const source = functionArgs[1];
|
|
3867
|
+
return `extract(${renderExtractField(field)} from ${renderExpression2(source, state, dialect)})`;
|
|
3868
|
+
}
|
|
3869
|
+
const renderedArgs = functionArgs.map((arg) => renderExpression2(arg, state, dialect)).join(", ");
|
|
3870
|
+
if (functionArgs.length === 0) {
|
|
3871
|
+
switch (functionName) {
|
|
2277
3872
|
case "current_date":
|
|
2278
3873
|
case "current_time":
|
|
2279
3874
|
case "current_timestamp":
|
|
2280
3875
|
case "localtime":
|
|
2281
3876
|
case "localtimestamp":
|
|
2282
|
-
return
|
|
3877
|
+
return functionName;
|
|
2283
3878
|
default:
|
|
2284
|
-
return `${
|
|
3879
|
+
return `${functionName}()`;
|
|
2285
3880
|
}
|
|
2286
3881
|
}
|
|
2287
|
-
return `${
|
|
3882
|
+
return `${functionName}(${renderedArgs})`;
|
|
2288
3883
|
};
|
|
2289
3884
|
var renderJsonExpression = (expression, ast, state, dialect) => {
|
|
2290
3885
|
const kind = typeof ast.kind === "string" ? ast.kind : undefined;
|
|
@@ -2308,7 +3903,7 @@ var renderJsonExpression = (expression, ast, state, dialect) => {
|
|
|
2308
3903
|
if (!isExpression3(base) || segments.length === 0) {
|
|
2309
3904
|
return;
|
|
2310
3905
|
}
|
|
2311
|
-
const baseSql =
|
|
3906
|
+
const baseSql = renderExpression2(base, state, dialect);
|
|
2312
3907
|
const textMode = kind.endsWith("Text") || ast.text === true || ast.asText === true;
|
|
2313
3908
|
if (dialect.name === "postgres") {
|
|
2314
3909
|
if (exact) {
|
|
@@ -2331,23 +3926,27 @@ var renderJsonExpression = (expression, ast, state, dialect) => {
|
|
|
2331
3926
|
if (!isExpression3(base)) {
|
|
2332
3927
|
return;
|
|
2333
3928
|
}
|
|
2334
|
-
const baseSql = dialect.name === "postgres" ? renderPostgresJsonValue(base, state, dialect) :
|
|
2335
|
-
const keys = segments;
|
|
3929
|
+
const baseSql = dialect.name === "postgres" ? renderPostgresJsonValue(base, state, dialect) : renderExpression2(base, state, dialect);
|
|
3930
|
+
const keys = extractJsonKeys(ast, segments);
|
|
2336
3931
|
if (keys.length === 0) {
|
|
2337
3932
|
return;
|
|
2338
3933
|
}
|
|
3934
|
+
if (keys.some((key2) => typeof key2 !== "string" || key2.length === 0)) {
|
|
3935
|
+
throw new Error("json key predicates require string keys");
|
|
3936
|
+
}
|
|
3937
|
+
const keyNames = keys;
|
|
2339
3938
|
if (dialect.name === "postgres") {
|
|
2340
3939
|
if (kind === "jsonHasAnyKeys") {
|
|
2341
|
-
return `(${baseSql} ?| array[${
|
|
3940
|
+
return `(${baseSql} ?| array[${keyNames.map((key2) => renderPostgresTextLiteral(key2, state, dialect)).join(", ")}])`;
|
|
2342
3941
|
}
|
|
2343
3942
|
if (kind === "jsonHasAllKeys") {
|
|
2344
|
-
return `(${baseSql} ?& array[${
|
|
3943
|
+
return `(${baseSql} ?& array[${keyNames.map((key2) => renderPostgresTextLiteral(key2, state, dialect)).join(", ")}])`;
|
|
2345
3944
|
}
|
|
2346
|
-
return `(${baseSql} ? ${renderPostgresTextLiteral(
|
|
3945
|
+
return `(${baseSql} ? ${renderPostgresTextLiteral(keyNames[0], state, dialect)})`;
|
|
2347
3946
|
}
|
|
2348
3947
|
if (dialect.name === "mysql") {
|
|
2349
3948
|
const mode = kind === "jsonHasAllKeys" ? "all" : "one";
|
|
2350
|
-
const paths =
|
|
3949
|
+
const paths = keyNames.map((segment) => renderMySqlJsonPath([segment], state, dialect)).join(", ");
|
|
2351
3950
|
return `json_contains_path(${baseSql}, ${dialect.renderLiteral(mode, state)}, ${paths})`;
|
|
2352
3951
|
}
|
|
2353
3952
|
return;
|
|
@@ -2361,12 +3960,12 @@ var renderJsonExpression = (expression, ast, state, dialect) => {
|
|
|
2361
3960
|
return `(${renderPostgresJsonValue(ast.left, state, dialect)} || ${renderPostgresJsonValue(ast.right, state, dialect)})`;
|
|
2362
3961
|
}
|
|
2363
3962
|
if (dialect.name === "mysql") {
|
|
2364
|
-
return `json_merge_preserve(${
|
|
3963
|
+
return `json_merge_preserve(${renderExpression2(ast.left, state, dialect)}, ${renderExpression2(ast.right, state, dialect)})`;
|
|
2365
3964
|
}
|
|
2366
3965
|
return;
|
|
2367
3966
|
}
|
|
2368
3967
|
case "jsonBuildObject": {
|
|
2369
|
-
const entries =
|
|
3968
|
+
const entries = ast.entries;
|
|
2370
3969
|
const renderedEntries = entries.flatMap((entry) => [
|
|
2371
3970
|
dialect.renderLiteral(entry.key, state),
|
|
2372
3971
|
renderJsonInputExpression(entry.value, state, dialect)
|
|
@@ -2380,7 +3979,7 @@ var renderJsonExpression = (expression, ast, state, dialect) => {
|
|
|
2380
3979
|
return;
|
|
2381
3980
|
}
|
|
2382
3981
|
case "jsonBuildArray": {
|
|
2383
|
-
const values =
|
|
3982
|
+
const values = ast.values;
|
|
2384
3983
|
const renderedValues = values.map((value) => renderJsonInputExpression(value, state, dialect)).join(", ");
|
|
2385
3984
|
if (dialect.name === "postgres") {
|
|
2386
3985
|
return `${postgresExpressionKind === "jsonb" ? "jsonb" : "json"}_build_array(${renderedValues})`;
|
|
@@ -2398,7 +3997,7 @@ var renderJsonExpression = (expression, ast, state, dialect) => {
|
|
|
2398
3997
|
return `to_json(${renderJsonInputExpression(base, state, dialect)})`;
|
|
2399
3998
|
}
|
|
2400
3999
|
if (dialect.name === "mysql") {
|
|
2401
|
-
return `cast(${
|
|
4000
|
+
return `cast(${renderExpression2(base, state, dialect)} as json)`;
|
|
2402
4001
|
}
|
|
2403
4002
|
return;
|
|
2404
4003
|
case "jsonToJsonb":
|
|
@@ -2409,7 +4008,7 @@ var renderJsonExpression = (expression, ast, state, dialect) => {
|
|
|
2409
4008
|
return `to_jsonb(${renderJsonInputExpression(base, state, dialect)})`;
|
|
2410
4009
|
}
|
|
2411
4010
|
if (dialect.name === "mysql") {
|
|
2412
|
-
return `cast(${
|
|
4011
|
+
return `cast(${renderExpression2(base, state, dialect)} as json)`;
|
|
2413
4012
|
}
|
|
2414
4013
|
return;
|
|
2415
4014
|
case "jsonTypeOf":
|
|
@@ -2417,11 +4016,11 @@ var renderJsonExpression = (expression, ast, state, dialect) => {
|
|
|
2417
4016
|
return;
|
|
2418
4017
|
}
|
|
2419
4018
|
if (dialect.name === "postgres") {
|
|
2420
|
-
const baseSql =
|
|
4019
|
+
const baseSql = renderExpression2(base, state, dialect);
|
|
2421
4020
|
return `${postgresBaseKind === "jsonb" ? "jsonb" : "json"}_typeof(${baseSql})`;
|
|
2422
4021
|
}
|
|
2423
4022
|
if (dialect.name === "mysql") {
|
|
2424
|
-
return `json_type(${
|
|
4023
|
+
return `json_type(${renderExpression2(base, state, dialect)})`;
|
|
2425
4024
|
}
|
|
2426
4025
|
return;
|
|
2427
4026
|
case "jsonLength":
|
|
@@ -2429,14 +4028,14 @@ var renderJsonExpression = (expression, ast, state, dialect) => {
|
|
|
2429
4028
|
return;
|
|
2430
4029
|
}
|
|
2431
4030
|
if (dialect.name === "postgres") {
|
|
2432
|
-
const baseSql =
|
|
4031
|
+
const baseSql = renderExpression2(base, state, dialect);
|
|
2433
4032
|
const typeOf = `${postgresBaseKind === "jsonb" ? "jsonb" : "json"}_typeof`;
|
|
2434
4033
|
const arrayLength = `${postgresBaseKind === "jsonb" ? "jsonb" : "json"}_array_length`;
|
|
2435
4034
|
const objectKeys = `${postgresBaseKind === "jsonb" ? "jsonb" : "json"}_object_keys`;
|
|
2436
4035
|
return `(case when ${typeOf}(${baseSql}) = 'array' then ${arrayLength}(${baseSql}) when ${typeOf}(${baseSql}) = 'object' then (select count(*)::int from ${objectKeys}(${baseSql})) else null end)`;
|
|
2437
4036
|
}
|
|
2438
4037
|
if (dialect.name === "mysql") {
|
|
2439
|
-
return `json_length(${
|
|
4038
|
+
return `json_length(${renderExpression2(base, state, dialect)})`;
|
|
2440
4039
|
}
|
|
2441
4040
|
return;
|
|
2442
4041
|
case "jsonKeys":
|
|
@@ -2444,13 +4043,13 @@ var renderJsonExpression = (expression, ast, state, dialect) => {
|
|
|
2444
4043
|
return;
|
|
2445
4044
|
}
|
|
2446
4045
|
if (dialect.name === "postgres") {
|
|
2447
|
-
const baseSql =
|
|
4046
|
+
const baseSql = renderExpression2(base, state, dialect);
|
|
2448
4047
|
const typeOf = `${postgresBaseKind === "jsonb" ? "jsonb" : "json"}_typeof`;
|
|
2449
4048
|
const objectKeys = `${postgresBaseKind === "jsonb" ? "jsonb" : "json"}_object_keys`;
|
|
2450
|
-
return `(case when ${typeOf}(${baseSql}) = 'object' then array(select ${objectKeys}(${baseSql})) else null end)`;
|
|
4049
|
+
return `(case when ${typeOf}(${baseSql}) = 'object' then to_json(array(select ${objectKeys}(${baseSql}))) else null end)`;
|
|
2451
4050
|
}
|
|
2452
4051
|
if (dialect.name === "mysql") {
|
|
2453
|
-
return `json_keys(${
|
|
4052
|
+
return `json_keys(${renderExpression2(base, state, dialect)})`;
|
|
2454
4053
|
}
|
|
2455
4054
|
return;
|
|
2456
4055
|
case "jsonStripNulls":
|
|
@@ -2458,7 +4057,7 @@ var renderJsonExpression = (expression, ast, state, dialect) => {
|
|
|
2458
4057
|
return;
|
|
2459
4058
|
}
|
|
2460
4059
|
if (dialect.name === "postgres") {
|
|
2461
|
-
return `${postgresBaseKind === "jsonb" ? "jsonb" : "json"}_strip_nulls(${
|
|
4060
|
+
return `${postgresBaseKind === "jsonb" ? "jsonb" : "json"}_strip_nulls(${renderExpression2(base, state, dialect)})`;
|
|
2462
4061
|
}
|
|
2463
4062
|
unsupportedJsonFeature(dialect, "jsonStripNulls");
|
|
2464
4063
|
return;
|
|
@@ -2472,12 +4071,12 @@ var renderJsonExpression = (expression, ast, state, dialect) => {
|
|
|
2472
4071
|
const baseSql = renderPostgresJsonValue(base, state, dialect);
|
|
2473
4072
|
if (segments.length === 1 && (segments[0].kind === "key" || segments[0].kind === "index")) {
|
|
2474
4073
|
const segment = segments[0];
|
|
2475
|
-
return `(${baseSql} - ${segment.kind === "key" ? dialect.renderLiteral(segment.key, state) : dialect.renderLiteral(
|
|
4074
|
+
return `(${baseSql} - ${segment.kind === "key" ? dialect.renderLiteral(segment.key, state) : dialect.renderLiteral(segment.index, state)})`;
|
|
2476
4075
|
}
|
|
2477
4076
|
return `(${baseSql} #- ${renderPostgresJsonPathArray(segments, state, dialect)})`;
|
|
2478
4077
|
}
|
|
2479
4078
|
if (dialect.name === "mysql") {
|
|
2480
|
-
return `json_remove(${
|
|
4079
|
+
return `json_remove(${renderExpression2(base, state, dialect)}, ${segments.map((segment) => renderMySqlJsonPath([segment], state, dialect)).join(", ")})`;
|
|
2481
4080
|
}
|
|
2482
4081
|
return;
|
|
2483
4082
|
}
|
|
@@ -2499,7 +4098,7 @@ var renderJsonExpression = (expression, ast, state, dialect) => {
|
|
|
2499
4098
|
}
|
|
2500
4099
|
if (dialect.name === "mysql") {
|
|
2501
4100
|
const functionName = kind === "jsonInsert" ? "json_insert" : "json_set";
|
|
2502
|
-
return `${functionName}(${
|
|
4101
|
+
return `${functionName}(${renderExpression2(base, state, dialect)}, ${renderMySqlJsonPath(segments, state, dialect)}, ${renderExpression2(nextValue, state, dialect)})`;
|
|
2503
4102
|
}
|
|
2504
4103
|
return;
|
|
2505
4104
|
}
|
|
@@ -2515,7 +4114,7 @@ var renderJsonExpression = (expression, ast, state, dialect) => {
|
|
|
2515
4114
|
return `(${renderPostgresJsonValue(base, state, dialect)} @? ${renderJsonOpaquePath(path2, state, dialect)})`;
|
|
2516
4115
|
}
|
|
2517
4116
|
if (dialect.name === "mysql") {
|
|
2518
|
-
return `json_contains_path(${
|
|
4117
|
+
return `json_contains_path(${renderExpression2(base, state, dialect)}, ${dialect.renderLiteral("one", state)}, ${renderJsonOpaquePath(path2, state, dialect)})`;
|
|
2519
4118
|
}
|
|
2520
4119
|
return;
|
|
2521
4120
|
}
|
|
@@ -2539,13 +4138,13 @@ var selectionProjections = (selection) => flattenSelection(selection).map(({ pat
|
|
|
2539
4138
|
path: path2,
|
|
2540
4139
|
alias: alias2
|
|
2541
4140
|
}));
|
|
2542
|
-
var renderMutationAssignment = (entry, state, dialect) => {
|
|
2543
|
-
const column = entry.tableName && dialect.name === "mysql" ? `${dialect.quoteIdentifier(entry.tableName)}.${
|
|
2544
|
-
return `${column} = ${
|
|
4141
|
+
var renderMutationAssignment = (entry, state, dialect, targetTableName) => {
|
|
4142
|
+
const column = entry.tableName && dialect.name === "mysql" ? `${dialect.quoteIdentifier(casedTableReferenceName(entry.tableName, state))}.${quoteColumn(entry.columnName, state, dialect, entry.tableName)}` : quoteColumn(entry.columnName, state, dialect, targetTableName);
|
|
4143
|
+
return `${column} = ${renderExpression2(entry.value, state, dialect)}`;
|
|
2545
4144
|
};
|
|
2546
4145
|
var renderJoinSourcesForMutation = (joins, state, dialect) => joins.map((join) => renderSourceReference(join.source, join.tableName, join.baseTableName, state, dialect)).join(", ");
|
|
2547
4146
|
var renderFromSources = (sources, state, dialect) => sources.map((source) => renderSourceReference(source.source, source.tableName, source.baseTableName, state, dialect)).join(", ");
|
|
2548
|
-
var renderJoinPredicatesForMutation = (joins, state, dialect) => joins.flatMap((join) => join.kind === "cross" || !join.on ? [] : [
|
|
4147
|
+
var renderJoinPredicatesForMutation = (joins, state, dialect) => joins.flatMap((join) => join.kind === "cross" || !join.on ? [] : [renderExpression2(join.on, state, dialect)]);
|
|
2549
4148
|
var renderDeleteTargets = (targets, dialect) => targets.map((target) => dialect.quoteIdentifier(target.tableName)).join(", ");
|
|
2550
4149
|
var renderMysqlMutationLock = (lock, statement) => {
|
|
2551
4150
|
if (!lock) {
|
|
@@ -2566,10 +4165,11 @@ var renderTransactionClause = (clause, dialect) => {
|
|
|
2566
4165
|
switch (clause.kind) {
|
|
2567
4166
|
case "transaction": {
|
|
2568
4167
|
const modes = [];
|
|
2569
|
-
|
|
2570
|
-
|
|
4168
|
+
const isolationLevel = renderTransactionIsolationLevel(clause.isolationLevel);
|
|
4169
|
+
if (isolationLevel) {
|
|
4170
|
+
modes.push(isolationLevel);
|
|
2571
4171
|
}
|
|
2572
|
-
if (clause.readOnly
|
|
4172
|
+
if (normalizeStatementFlag(clause.readOnly)) {
|
|
2573
4173
|
modes.push("read only");
|
|
2574
4174
|
}
|
|
2575
4175
|
return modes.length > 0 ? `start transaction ${modes.join(", ")}` : "start transaction";
|
|
@@ -2579,76 +4179,115 @@ var renderTransactionClause = (clause, dialect) => {
|
|
|
2579
4179
|
case "rollback":
|
|
2580
4180
|
return "rollback";
|
|
2581
4181
|
case "savepoint":
|
|
2582
|
-
return `savepoint ${dialect.quoteIdentifier(clause.name)}`;
|
|
4182
|
+
return `savepoint ${dialect.quoteIdentifier(normalizeStatementIdentifier("savepoint", "name", clause.name))}`;
|
|
2583
4183
|
case "rollbackTo":
|
|
2584
|
-
return `rollback to savepoint ${dialect.quoteIdentifier(clause.name)}`;
|
|
4184
|
+
return `rollback to savepoint ${dialect.quoteIdentifier(normalizeStatementIdentifier("rollbackTo", "name", clause.name))}`;
|
|
2585
4185
|
case "releaseSavepoint":
|
|
2586
|
-
return `release savepoint ${dialect.quoteIdentifier(clause.name)}`;
|
|
4186
|
+
return `release savepoint ${dialect.quoteIdentifier(normalizeStatementIdentifier("releaseSavepoint", "name", clause.name))}`;
|
|
2587
4187
|
}
|
|
2588
|
-
return "";
|
|
4188
|
+
return "start transaction";
|
|
2589
4189
|
};
|
|
2590
|
-
var renderSelectionList = (selection, state, dialect
|
|
2591
|
-
if (validateAggregation) {
|
|
2592
|
-
validateAggregationSelection(selection, []);
|
|
2593
|
-
}
|
|
4190
|
+
var renderSelectionList = (selection, state, dialect) => {
|
|
2594
4191
|
const flattened = flattenSelection(selection);
|
|
2595
4192
|
const projections = selectionProjections(selection);
|
|
2596
|
-
const sql = flattened.map(({ expression, alias: alias2 }) => `${renderSelectSql(
|
|
4193
|
+
const sql = flattened.map(({ expression, alias: alias2 }) => `${renderSelectSql(renderExpression2(expression, state, dialect), expressionDriverContext(expression, state, dialect))} as ${dialect.quoteIdentifier(alias2)}`).join(", ");
|
|
2597
4194
|
return {
|
|
2598
4195
|
sql,
|
|
2599
4196
|
projections
|
|
2600
4197
|
};
|
|
2601
4198
|
};
|
|
2602
|
-
var
|
|
4199
|
+
var nestedRenderState = (state) => ({
|
|
4200
|
+
params: state.params,
|
|
4201
|
+
valueMappings: state.valueMappings,
|
|
4202
|
+
casing: state.casing,
|
|
4203
|
+
ctes: [],
|
|
4204
|
+
cteNames: new Set(state.cteNames),
|
|
4205
|
+
cteSources: new Map(state.cteSources),
|
|
4206
|
+
sourceNames: new Map(state.sourceNames)
|
|
4207
|
+
});
|
|
4208
|
+
var assertSupportedMutationReturning = (dialect, selection) => {
|
|
4209
|
+
if (dialect.name === "standard" && Object.keys(selection).length > 0) {
|
|
4210
|
+
throw new Error("Unsupported standard returning");
|
|
4211
|
+
}
|
|
4212
|
+
};
|
|
4213
|
+
var validateDistinctOnOrdering = (distinctOn, orderBy) => {
|
|
4214
|
+
if (distinctOn === undefined || distinctOn.length === 0 || orderBy.length === 0) {
|
|
4215
|
+
return;
|
|
4216
|
+
}
|
|
4217
|
+
const remainingDistinctKeys = new Set(distinctOn.map(groupingKeyOfExpression));
|
|
4218
|
+
for (const order of orderBy) {
|
|
4219
|
+
const key2 = groupingKeyOfExpression(order.value);
|
|
4220
|
+
if (remainingDistinctKeys.has(key2)) {
|
|
4221
|
+
remainingDistinctKeys.delete(key2);
|
|
4222
|
+
continue;
|
|
4223
|
+
}
|
|
4224
|
+
if (remainingDistinctKeys.size > 0) {
|
|
4225
|
+
throw new Error("distinctOn(...) expressions must match the leftmost orderBy(...) expressions");
|
|
4226
|
+
}
|
|
4227
|
+
return;
|
|
4228
|
+
}
|
|
4229
|
+
};
|
|
4230
|
+
var renderQueryAst2 = (ast, state, dialect, options2 = {}) => {
|
|
4231
|
+
registerQuerySources(ast, state);
|
|
2603
4232
|
let sql = "";
|
|
2604
4233
|
let projections = [];
|
|
2605
4234
|
switch (ast.kind) {
|
|
2606
4235
|
case "select": {
|
|
2607
|
-
|
|
2608
|
-
const rendered = renderSelectionList(ast.select, state, dialect
|
|
4236
|
+
validateDistinctOnOrdering(ast.distinctOn, ast.orderBy);
|
|
4237
|
+
const rendered = renderSelectionList(ast.select, state, dialect);
|
|
2609
4238
|
projections = rendered.projections;
|
|
4239
|
+
const selectList = rendered.sql.length > 0 ? ` ${rendered.sql}` : "";
|
|
2610
4240
|
const clauses = [
|
|
2611
|
-
ast.distinctOn && ast.distinctOn.length > 0 ? `select distinct on (${ast.distinctOn.map((value) =>
|
|
4241
|
+
ast.distinctOn && ast.distinctOn.length > 0 ? `select distinct on (${ast.distinctOn.map((value) => renderExpression2(value, state, dialect)).join(", ")})${selectList}` : `select${ast.distinct ? " distinct" : ""}${selectList}`
|
|
2612
4242
|
];
|
|
2613
4243
|
if (ast.from) {
|
|
2614
4244
|
clauses.push(`from ${renderSourceReference(ast.from.source, ast.from.tableName, ast.from.baseTableName, state, dialect)}`);
|
|
2615
4245
|
}
|
|
2616
4246
|
for (const join of ast.joins) {
|
|
4247
|
+
if (dialect.name === "standard" && join.kind === "full") {
|
|
4248
|
+
throw new Error("Unsupported standard full join");
|
|
4249
|
+
}
|
|
2617
4250
|
const source = renderSourceReference(join.source, join.tableName, join.baseTableName, state, dialect);
|
|
2618
|
-
clauses.push(join.kind === "cross" ? `cross join ${source}` : `${join.kind} join ${source} on ${
|
|
4251
|
+
clauses.push(join.kind === "cross" ? `cross join ${source}` : `${join.kind} join ${source} on ${renderExpression2(join.on, state, dialect)}`);
|
|
2619
4252
|
}
|
|
2620
4253
|
if (ast.where.length > 0) {
|
|
2621
|
-
clauses.push(`where ${ast.where.map((entry) =>
|
|
4254
|
+
clauses.push(`where ${ast.where.map((entry) => renderExpression2(entry.predicate, state, dialect)).join(" and ")}`);
|
|
2622
4255
|
}
|
|
2623
4256
|
if (ast.groupBy.length > 0) {
|
|
2624
|
-
clauses.push(`group by ${ast.groupBy.map((value) =>
|
|
4257
|
+
clauses.push(`group by ${ast.groupBy.map((value) => renderExpression2(value, state, dialect)).join(", ")}`);
|
|
2625
4258
|
}
|
|
2626
4259
|
if (ast.having.length > 0) {
|
|
2627
|
-
clauses.push(`having ${ast.having.map((entry) =>
|
|
4260
|
+
clauses.push(`having ${ast.having.map((entry) => renderExpression2(entry.predicate, state, dialect)).join(" and ")}`);
|
|
2628
4261
|
}
|
|
2629
4262
|
if (ast.orderBy.length > 0) {
|
|
2630
|
-
clauses.push(`order by ${ast.orderBy.map((entry) => `${
|
|
4263
|
+
clauses.push(`order by ${ast.orderBy.map((entry) => `${renderExpression2(entry.value, state, dialect)} ${entry.direction}`).join(", ")}`);
|
|
2631
4264
|
}
|
|
2632
4265
|
if (ast.limit) {
|
|
2633
|
-
clauses.push(`limit ${
|
|
4266
|
+
clauses.push(`limit ${renderExpression2(ast.limit, state, dialect)}`);
|
|
2634
4267
|
}
|
|
2635
4268
|
if (ast.offset) {
|
|
2636
|
-
clauses.push(`offset ${
|
|
4269
|
+
clauses.push(`offset ${renderExpression2(ast.offset, state, dialect)}`);
|
|
2637
4270
|
}
|
|
2638
4271
|
if (ast.lock) {
|
|
2639
|
-
|
|
4272
|
+
if (dialect.name === "standard") {
|
|
4273
|
+
throw new Error("Unsupported standard row locking");
|
|
4274
|
+
}
|
|
4275
|
+
clauses.push(`${renderSelectLockMode(ast.lock.mode)}${ast.lock.nowait ? " nowait" : ""}${ast.lock.skipLocked ? " skip locked" : ""}`);
|
|
2640
4276
|
}
|
|
2641
4277
|
sql = clauses.join(" ");
|
|
2642
4278
|
break;
|
|
2643
4279
|
}
|
|
2644
4280
|
case "set": {
|
|
2645
4281
|
const setAst = ast;
|
|
2646
|
-
const base =
|
|
4282
|
+
const base = renderQueryAst2(getAst(setAst.setBase), state, dialect);
|
|
2647
4283
|
projections = selectionProjections(setAst.select);
|
|
2648
4284
|
sql = [
|
|
2649
4285
|
`(${base.sql})`,
|
|
2650
4286
|
...(setAst.setOperations ?? []).map((entry) => {
|
|
2651
|
-
const rendered =
|
|
4287
|
+
const rendered = renderQueryAst2(getAst(entry.query), state, dialect);
|
|
4288
|
+
if (dialect.name === "standard" && entry.all && entry.kind !== "union") {
|
|
4289
|
+
throw new Error("Unsupported standard set operator all variant");
|
|
4290
|
+
}
|
|
2652
4291
|
return `${entry.kind}${entry.all ? " all" : ""} (${rendered.sql})`;
|
|
2653
4292
|
})
|
|
2654
4293
|
].join(" ");
|
|
@@ -2658,50 +4297,58 @@ var renderQueryAst = (ast, state, dialect) => {
|
|
|
2658
4297
|
const insertAst = ast;
|
|
2659
4298
|
const targetSource = insertAst.into;
|
|
2660
4299
|
const target = renderSourceReference(targetSource.source, targetSource.tableName, targetSource.baseTableName, state, dialect);
|
|
4300
|
+
const targetCasingState = stateWithTableCasing(state, targetSource.source);
|
|
4301
|
+
const insertSource = insertAst.insertSource;
|
|
4302
|
+
const conflict = expectConflictClause(insertAst.conflict);
|
|
2661
4303
|
sql = `insert into ${target}`;
|
|
2662
|
-
if (
|
|
2663
|
-
const columns =
|
|
2664
|
-
const rows =
|
|
4304
|
+
if (insertSource?.kind === "values") {
|
|
4305
|
+
const columns = insertSource.columns.map((column) => quoteColumn(column, state, dialect, targetSource.tableName)).join(", ");
|
|
4306
|
+
const rows = insertSource.rows.map((row) => `(${row.values.map((entry) => renderExpression2(entry.value, targetCasingState, dialect)).join(", ")})`).join(", ");
|
|
2665
4307
|
sql += ` (${columns}) values ${rows}`;
|
|
2666
|
-
} else if (
|
|
2667
|
-
const columns =
|
|
2668
|
-
const renderedQuery =
|
|
4308
|
+
} else if (insertSource?.kind === "query") {
|
|
4309
|
+
const columns = insertSource.columns.map((column) => quoteColumn(column, state, dialect, targetSource.tableName)).join(", ");
|
|
4310
|
+
const renderedQuery = renderQueryAst2(getAst(insertSource.query), state, dialect);
|
|
2669
4311
|
sql += ` (${columns}) ${renderedQuery.sql}`;
|
|
2670
|
-
} else if (
|
|
2671
|
-
const
|
|
2672
|
-
const columns = unnestSource.columns.map((column) => dialect.quoteIdentifier(column)).join(", ");
|
|
4312
|
+
} else if (insertSource?.kind === "unnest") {
|
|
4313
|
+
const columns = insertSource.columns.map((column) => quoteColumn(column, state, dialect, targetSource.tableName)).join(", ");
|
|
2673
4314
|
if (dialect.name === "postgres") {
|
|
2674
4315
|
const table = targetSource.source;
|
|
2675
|
-
const fields = table[
|
|
2676
|
-
const rendered =
|
|
4316
|
+
const fields = table[TypeId6].fields;
|
|
4317
|
+
const rendered = insertSource.values.map((entry) => `cast(${dialect.renderLiteral(encodeArrayValues(entry.values, fields[entry.columnName], state, dialect), state)} as ${renderCastType(dialect, fields[entry.columnName].metadata.dbType)}[])`).join(", ");
|
|
2677
4318
|
sql += ` (${columns}) select * from unnest(${rendered})`;
|
|
2678
4319
|
} else {
|
|
2679
|
-
const rowCount =
|
|
2680
|
-
const rows = Array.from({ length: rowCount }, (_, index3) => `(${
|
|
4320
|
+
const rowCount = insertSource.values[0]?.values.length ?? 0;
|
|
4321
|
+
const rows = Array.from({ length: rowCount }, (_, index3) => `(${insertSource.values.map((entry) => dialect.renderLiteral(entry.values[index3], state, targetSource.source[TypeId6].fields[entry.columnName][TypeId2])).join(", ")})`).join(", ");
|
|
2681
4322
|
sql += ` (${columns}) values ${rows}`;
|
|
2682
4323
|
}
|
|
2683
4324
|
} else {
|
|
2684
|
-
const
|
|
2685
|
-
const
|
|
2686
|
-
|
|
4325
|
+
const insertValues = insertAst.values ?? [];
|
|
4326
|
+
const columns = insertValues.map((entry) => quoteColumn(entry.columnName, state, dialect, targetSource.tableName)).join(", ");
|
|
4327
|
+
const values = insertValues.map((entry) => renderExpression2(entry.value, targetCasingState, dialect)).join(", ");
|
|
4328
|
+
if (insertValues.length > 0) {
|
|
2687
4329
|
sql += ` (${columns}) values (${values})`;
|
|
2688
4330
|
} else {
|
|
2689
4331
|
sql += " default values";
|
|
2690
4332
|
}
|
|
2691
4333
|
}
|
|
2692
|
-
if (
|
|
2693
|
-
|
|
4334
|
+
if (conflict) {
|
|
4335
|
+
if (dialect.name === "standard") {
|
|
4336
|
+
throw new Error("Unsupported standard insert conflict");
|
|
4337
|
+
}
|
|
4338
|
+
const conflictValueState = { ...targetCasingState, allowExcluded: true };
|
|
4339
|
+
const updateValues = (conflict.values ?? []).map((entry) => `${quoteColumn(entry.columnName, state, dialect, targetSource.tableName)} = ${renderExpression2(entry.value, conflictValueState, dialect)}`).join(", ");
|
|
2694
4340
|
if (dialect.name === "postgres") {
|
|
2695
|
-
const targetSql =
|
|
4341
|
+
const targetSql = conflict.target?.kind === "constraint" ? ` on conflict on constraint ${dialect.quoteIdentifier(applyCategory(targetCasingState.casing, "constraints", conflict.target.name))}` : conflict.target?.kind === "columns" ? ` on conflict (${conflict.target.columns.map((column) => quoteColumn(column, state, dialect, targetSource.tableName)).join(", ")})${conflict.target.where ? ` where ${renderExpression2(conflict.target.where, targetCasingState, dialect)}` : ""}` : " on conflict";
|
|
2696
4342
|
sql += targetSql;
|
|
2697
|
-
sql +=
|
|
2698
|
-
} else if (
|
|
4343
|
+
sql += conflict.action === "doNothing" ? " do nothing" : ` do update set ${updateValues}${conflict.where ? ` where ${renderExpression2(conflict.where, conflictValueState, dialect)}` : ""}`;
|
|
4344
|
+
} else if (conflict.action === "doNothing") {
|
|
2699
4345
|
sql = sql.replace(/^insert/, "insert ignore");
|
|
2700
4346
|
} else {
|
|
2701
4347
|
sql += ` on duplicate key update ${updateValues}`;
|
|
2702
4348
|
}
|
|
2703
4349
|
}
|
|
2704
|
-
|
|
4350
|
+
assertSupportedMutationReturning(dialect, insertAst.select);
|
|
4351
|
+
const returning = renderSelectionList(insertAst.select, state, dialect);
|
|
2705
4352
|
projections = returning.projections;
|
|
2706
4353
|
if (returning.sql.length > 0) {
|
|
2707
4354
|
sql += ` returning ${returning.sql}`;
|
|
@@ -2714,11 +4361,14 @@ var renderQueryAst = (ast, state, dialect) => {
|
|
|
2714
4361
|
const target = renderSourceReference(targetSource.source, targetSource.tableName, targetSource.baseTableName, state, dialect);
|
|
2715
4362
|
const targets = updateAst.targets ?? [targetSource];
|
|
2716
4363
|
const fromSources = updateAst.fromSources ?? [];
|
|
2717
|
-
|
|
4364
|
+
if (dialect.name === "standard" && (targets.length > 1 || fromSources.length > 0 || updateAst.joins.length > 0)) {
|
|
4365
|
+
throw new Error("Unsupported standard joined mutation");
|
|
4366
|
+
}
|
|
4367
|
+
const assignments = updateAst.set.map((entry) => renderMutationAssignment(entry, state, dialect, targetSource.tableName)).join(", ");
|
|
2718
4368
|
if (dialect.name === "mysql") {
|
|
2719
4369
|
const modifiers = renderMysqlMutationLock(updateAst.lock, "update");
|
|
2720
4370
|
const extraSources = renderFromSources(fromSources, state, dialect);
|
|
2721
|
-
const joinSources = updateAst.joins.map((join) => join.kind === "cross" ? `cross join ${renderSourceReference(join.source, join.tableName, join.baseTableName, state, dialect)}` : `${join.kind} join ${renderSourceReference(join.source, join.tableName, join.baseTableName, state, dialect)} on ${
|
|
4371
|
+
const joinSources = updateAst.joins.map((join) => join.kind === "cross" ? `cross join ${renderSourceReference(join.source, join.tableName, join.baseTableName, state, dialect)}` : `${join.kind} join ${renderSourceReference(join.source, join.tableName, join.baseTableName, state, dialect)} on ${renderExpression2(join.on, state, dialect)}`).join(" ");
|
|
2722
4372
|
const targetList = [
|
|
2723
4373
|
...targets.map((entry) => renderSourceReference(entry.source, entry.tableName, entry.baseTableName, state, dialect)),
|
|
2724
4374
|
...extraSources.length > 0 ? [extraSources] : []
|
|
@@ -2736,18 +4386,19 @@ var renderQueryAst = (ast, state, dialect) => {
|
|
|
2736
4386
|
}
|
|
2737
4387
|
const whereParts = [
|
|
2738
4388
|
...dialect.name === "postgres" ? renderJoinPredicatesForMutation(updateAst.joins, state, dialect) : [],
|
|
2739
|
-
...updateAst.where.map((entry) =>
|
|
4389
|
+
...updateAst.where.map((entry) => renderExpression2(entry.predicate, state, dialect))
|
|
2740
4390
|
];
|
|
2741
4391
|
if (whereParts.length > 0) {
|
|
2742
4392
|
sql += ` where ${whereParts.join(" and ")}`;
|
|
2743
4393
|
}
|
|
2744
4394
|
if (dialect.name === "mysql" && updateAst.orderBy.length > 0) {
|
|
2745
|
-
sql += ` order by ${updateAst.orderBy.map((entry) => `${
|
|
4395
|
+
sql += ` order by ${updateAst.orderBy.map((entry) => `${renderExpression2(entry.value, state, dialect)} ${entry.direction}`).join(", ")}`;
|
|
2746
4396
|
}
|
|
2747
4397
|
if (dialect.name === "mysql" && updateAst.limit) {
|
|
2748
|
-
sql += ` limit ${
|
|
4398
|
+
sql += ` limit ${renderExpression2(updateAst.limit, state, dialect)}`;
|
|
2749
4399
|
}
|
|
2750
|
-
|
|
4400
|
+
assertSupportedMutationReturning(dialect, updateAst.select);
|
|
4401
|
+
const returning = renderSelectionList(updateAst.select, state, dialect);
|
|
2751
4402
|
projections = returning.projections;
|
|
2752
4403
|
if (returning.sql.length > 0) {
|
|
2753
4404
|
sql += ` returning ${returning.sql}`;
|
|
@@ -2759,12 +4410,15 @@ var renderQueryAst = (ast, state, dialect) => {
|
|
|
2759
4410
|
const targetSource = deleteAst.target;
|
|
2760
4411
|
const target = renderSourceReference(targetSource.source, targetSource.tableName, targetSource.baseTableName, state, dialect);
|
|
2761
4412
|
const targets = deleteAst.targets ?? [targetSource];
|
|
4413
|
+
if (dialect.name === "standard" && (targets.length > 1 || deleteAst.joins.length > 0)) {
|
|
4414
|
+
throw new Error("Unsupported standard joined mutation");
|
|
4415
|
+
}
|
|
2762
4416
|
if (dialect.name === "mysql") {
|
|
2763
4417
|
const modifiers = renderMysqlMutationLock(deleteAst.lock, "delete");
|
|
2764
4418
|
const hasJoinedSources = deleteAst.joins.length > 0 || targets.length > 1;
|
|
2765
4419
|
const targetList = renderDeleteTargets(targets, dialect);
|
|
2766
4420
|
const fromSources = targets.map((entry) => renderSourceReference(entry.source, entry.tableName, entry.baseTableName, state, dialect)).join(", ");
|
|
2767
|
-
const joinSources = deleteAst.joins.map((join) => join.kind === "cross" ? `cross join ${renderSourceReference(join.source, join.tableName, join.baseTableName, state, dialect)}` : `${join.kind} join ${renderSourceReference(join.source, join.tableName, join.baseTableName, state, dialect)} on ${
|
|
4421
|
+
const joinSources = deleteAst.joins.map((join) => join.kind === "cross" ? `cross join ${renderSourceReference(join.source, join.tableName, join.baseTableName, state, dialect)}` : `${join.kind} join ${renderSourceReference(join.source, join.tableName, join.baseTableName, state, dialect)} on ${renderExpression2(join.on, state, dialect)}`).join(" ");
|
|
2768
4422
|
sql = hasJoinedSources ? `delete${modifiers} ${targetList} from ${fromSources}${joinSources.length > 0 ? ` ${joinSources}` : ""}` : `delete${modifiers} from ${fromSources}`;
|
|
2769
4423
|
} else {
|
|
2770
4424
|
sql = `delete from ${target}`;
|
|
@@ -2774,18 +4428,19 @@ var renderQueryAst = (ast, state, dialect) => {
|
|
|
2774
4428
|
}
|
|
2775
4429
|
const whereParts = [
|
|
2776
4430
|
...dialect.name === "postgres" ? renderJoinPredicatesForMutation(deleteAst.joins, state, dialect) : [],
|
|
2777
|
-
...deleteAst.where.map((entry) =>
|
|
4431
|
+
...deleteAst.where.map((entry) => renderExpression2(entry.predicate, state, dialect))
|
|
2778
4432
|
];
|
|
2779
4433
|
if (whereParts.length > 0) {
|
|
2780
4434
|
sql += ` where ${whereParts.join(" and ")}`;
|
|
2781
4435
|
}
|
|
2782
4436
|
if (dialect.name === "mysql" && deleteAst.orderBy.length > 0) {
|
|
2783
|
-
sql += ` order by ${deleteAst.orderBy.map((entry) => `${
|
|
4437
|
+
sql += ` order by ${deleteAst.orderBy.map((entry) => `${renderExpression2(entry.value, state, dialect)} ${entry.direction}`).join(", ")}`;
|
|
2784
4438
|
}
|
|
2785
4439
|
if (dialect.name === "mysql" && deleteAst.limit) {
|
|
2786
|
-
sql += ` limit ${
|
|
4440
|
+
sql += ` limit ${renderExpression2(deleteAst.limit, state, dialect)}`;
|
|
2787
4441
|
}
|
|
2788
|
-
|
|
4442
|
+
assertSupportedMutationReturning(dialect, deleteAst.select);
|
|
4443
|
+
const returning = renderSelectionList(deleteAst.select, state, dialect);
|
|
2789
4444
|
projections = returning.projections;
|
|
2790
4445
|
if (returning.sql.length > 0) {
|
|
2791
4446
|
sql += ` returning ${returning.sql}`;
|
|
@@ -2794,12 +4449,18 @@ var renderQueryAst = (ast, state, dialect) => {
|
|
|
2794
4449
|
}
|
|
2795
4450
|
case "truncate": {
|
|
2796
4451
|
const truncateAst = ast;
|
|
4452
|
+
if (dialect.name === "standard") {
|
|
4453
|
+
throw new Error("Unsupported standard truncate statement");
|
|
4454
|
+
}
|
|
4455
|
+
const truncate = expectTruncateClause(truncateAst.truncate);
|
|
2797
4456
|
const targetSource = truncateAst.target;
|
|
4457
|
+
const restartIdentity = truncate.restartIdentity;
|
|
4458
|
+
const cascade = truncate.cascade;
|
|
2798
4459
|
sql = `truncate table ${renderSourceReference(targetSource.source, targetSource.tableName, targetSource.baseTableName, state, dialect)}`;
|
|
2799
|
-
if (
|
|
4460
|
+
if (restartIdentity) {
|
|
2800
4461
|
sql += " restart identity";
|
|
2801
4462
|
}
|
|
2802
|
-
if (
|
|
4463
|
+
if (cascade) {
|
|
2803
4464
|
sql += " cascade";
|
|
2804
4465
|
}
|
|
2805
4466
|
break;
|
|
@@ -2811,25 +4472,27 @@ var renderQueryAst = (ast, state, dialect) => {
|
|
|
2811
4472
|
const mergeAst = ast;
|
|
2812
4473
|
const targetSource = mergeAst.target;
|
|
2813
4474
|
const usingSource = mergeAst.using;
|
|
2814
|
-
const
|
|
2815
|
-
sql = `merge into ${renderSourceReference(targetSource.source, targetSource.tableName, targetSource.baseTableName, state, dialect)} using ${renderSourceReference(usingSource.source, usingSource.tableName, usingSource.baseTableName, state, dialect)} on ${
|
|
2816
|
-
if (
|
|
4475
|
+
const merge2 = mergeAst.merge;
|
|
4476
|
+
sql = `merge into ${renderSourceReference(targetSource.source, targetSource.tableName, targetSource.baseTableName, state, dialect)} using ${renderSourceReference(usingSource.source, usingSource.tableName, usingSource.baseTableName, state, dialect)} on ${renderExpression2(merge2.on, state, dialect)}`;
|
|
4477
|
+
if (merge2.whenMatched) {
|
|
4478
|
+
const matchedKind = merge2.whenMatched.kind === "delete" ? "delete" : "update";
|
|
2817
4479
|
sql += " when matched";
|
|
2818
|
-
if (
|
|
2819
|
-
sql += ` and ${
|
|
4480
|
+
if (merge2.whenMatched.predicate) {
|
|
4481
|
+
sql += ` and ${renderExpression2(merge2.whenMatched.predicate, state, dialect)}`;
|
|
2820
4482
|
}
|
|
2821
|
-
if (
|
|
4483
|
+
if (matchedKind === "delete") {
|
|
2822
4484
|
sql += " then delete";
|
|
2823
4485
|
} else {
|
|
2824
|
-
|
|
4486
|
+
const matchedUpdate = merge2.whenMatched;
|
|
4487
|
+
sql += ` then update set ${matchedUpdate.values.map((entry) => `${quoteColumn(entry.columnName, state, dialect, targetSource.tableName)} = ${renderExpression2(entry.value, state, dialect)}`).join(", ")}`;
|
|
2825
4488
|
}
|
|
2826
4489
|
}
|
|
2827
|
-
if (
|
|
4490
|
+
if (merge2.whenNotMatched) {
|
|
2828
4491
|
sql += " when not matched";
|
|
2829
|
-
if (
|
|
2830
|
-
sql += ` and ${
|
|
4492
|
+
if (merge2.whenNotMatched.predicate) {
|
|
4493
|
+
sql += ` and ${renderExpression2(merge2.whenNotMatched.predicate, state, dialect)}`;
|
|
2831
4494
|
}
|
|
2832
|
-
sql += ` then insert (${
|
|
4495
|
+
sql += ` then insert (${merge2.whenNotMatched.values.map((entry) => quoteColumn(entry.columnName, state, dialect, targetSource.tableName)).join(", ")}) values (${merge2.whenNotMatched.values.map((entry) => renderExpression2(entry.value, state, dialect)).join(", ")})`;
|
|
2833
4496
|
}
|
|
2834
4497
|
break;
|
|
2835
4498
|
}
|
|
@@ -2844,27 +4507,38 @@ var renderQueryAst = (ast, state, dialect) => {
|
|
|
2844
4507
|
}
|
|
2845
4508
|
case "createTable": {
|
|
2846
4509
|
const createTableAst = ast;
|
|
2847
|
-
|
|
4510
|
+
const ddl = expectDdlClauseKind(createTableAst.ddl, "createTable");
|
|
4511
|
+
sql = renderCreateTableSql(createTableAst.target, state, dialect, ddl.ifNotExists);
|
|
2848
4512
|
break;
|
|
2849
4513
|
}
|
|
2850
4514
|
case "dropTable": {
|
|
2851
4515
|
const dropTableAst = ast;
|
|
2852
|
-
const
|
|
4516
|
+
const ddl = expectDdlClauseKind(dropTableAst.ddl, "dropTable");
|
|
4517
|
+
const ifExists = normalizeStatementFlag(ddl.ifExists);
|
|
4518
|
+
if (dialect.name !== "postgres" && ifExists) {
|
|
4519
|
+
throw new Error(`Unsupported ${dialect.name} drop table options`);
|
|
4520
|
+
}
|
|
2853
4521
|
sql = `drop table${ifExists ? " if exists" : ""} ${renderSourceReference(dropTableAst.target.source, dropTableAst.target.tableName, dropTableAst.target.baseTableName, state, dialect)}`;
|
|
2854
4522
|
break;
|
|
2855
4523
|
}
|
|
2856
4524
|
case "createIndex": {
|
|
2857
4525
|
const createIndexAst = ast;
|
|
2858
|
-
sql = renderCreateIndexSql(createIndexAst.target, createIndexAst.ddl, state, dialect);
|
|
4526
|
+
sql = renderCreateIndexSql(createIndexAst.target, expectDdlClauseKind(createIndexAst.ddl, "createIndex"), state, dialect);
|
|
2859
4527
|
break;
|
|
2860
4528
|
}
|
|
2861
4529
|
case "dropIndex": {
|
|
2862
4530
|
const dropIndexAst = ast;
|
|
2863
|
-
sql = renderDropIndexSql(dropIndexAst.target, dropIndexAst.ddl, state, dialect);
|
|
4531
|
+
sql = renderDropIndexSql(dropIndexAst.target, expectDdlClauseKind(dropIndexAst.ddl, "dropIndex"), state, dialect);
|
|
4532
|
+
break;
|
|
4533
|
+
}
|
|
4534
|
+
default: {
|
|
4535
|
+
if (ast.transaction !== undefined) {
|
|
4536
|
+
sql = renderTransactionClause(ast.transaction, dialect);
|
|
4537
|
+
}
|
|
2864
4538
|
break;
|
|
2865
4539
|
}
|
|
2866
4540
|
}
|
|
2867
|
-
if (state.ctes.length === 0) {
|
|
4541
|
+
if (state.ctes.length === 0 || options2.emitCtes === false) {
|
|
2868
4542
|
return {
|
|
2869
4543
|
sql,
|
|
2870
4544
|
projections
|
|
@@ -2877,7 +4551,7 @@ var renderQueryAst = (ast, state, dialect) => {
|
|
|
2877
4551
|
};
|
|
2878
4552
|
var renderSourceReference = (source, tableName, baseTableName, state, dialect) => {
|
|
2879
4553
|
const renderSelectRows = (rows, columnNames) => {
|
|
2880
|
-
const renderedRows = rows.map((row) => `select ${columnNames.map((columnName) => `${
|
|
4554
|
+
const renderedRows = rows.map((row) => `select ${columnNames.map((columnName) => `${renderExpression2(row[columnName], state, dialect)} as ${dialect.quoteIdentifier(columnName)}`).join(", ")}`);
|
|
2881
4555
|
return `(${renderedRows.join(" union all ")}) as ${dialect.quoteIdentifier(tableName)}(${columnNames.map((columnName) => dialect.quoteIdentifier(columnName)).join(", ")})`;
|
|
2882
4556
|
};
|
|
2883
4557
|
const renderUnnestRows = (arrays, columnNames) => {
|
|
@@ -2887,9 +4561,14 @@ var renderSourceReference = (source, tableName, baseTableName, state, dialect) =
|
|
|
2887
4561
|
};
|
|
2888
4562
|
if (typeof source === "object" && source !== null && "kind" in source && source.kind === "cte") {
|
|
2889
4563
|
const cte = source;
|
|
4564
|
+
const registeredCteSource = state.cteSources.get(cte.name);
|
|
4565
|
+
if (registeredCteSource !== undefined && registeredCteSource !== cte.plan) {
|
|
4566
|
+
throw new Error(`common table expression name is already registered with a different plan: ${cte.name}`);
|
|
4567
|
+
}
|
|
2890
4568
|
if (!state.cteNames.has(cte.name)) {
|
|
2891
4569
|
state.cteNames.add(cte.name);
|
|
2892
|
-
|
|
4570
|
+
state.cteSources.set(cte.name, cte.plan);
|
|
4571
|
+
const rendered = renderQueryAst2(getAst(cte.plan), state, dialect, { emitCtes: false });
|
|
2893
4572
|
state.ctes.push({
|
|
2894
4573
|
name: cte.name,
|
|
2895
4574
|
sql: rendered.sql,
|
|
@@ -2901,11 +4580,14 @@ var renderSourceReference = (source, tableName, baseTableName, state, dialect) =
|
|
|
2901
4580
|
if (typeof source === "object" && source !== null && "kind" in source && source.kind === "derived") {
|
|
2902
4581
|
const derived = source;
|
|
2903
4582
|
if (!state.cteNames.has(derived.name)) {}
|
|
2904
|
-
return `(${
|
|
4583
|
+
return `(${renderQueryAst2(getAst(derived.plan), nestedRenderState(state), dialect).sql}) as ${dialect.quoteIdentifier(derived.name)}`;
|
|
2905
4584
|
}
|
|
2906
4585
|
if (typeof source === "object" && source !== null && "kind" in source && source.kind === "lateral") {
|
|
2907
4586
|
const lateral = source;
|
|
2908
|
-
|
|
4587
|
+
if (dialect.name === "standard") {
|
|
4588
|
+
throw new Error("Unsupported standard lateral source");
|
|
4589
|
+
}
|
|
4590
|
+
return `lateral (${renderQueryAst2(getAst(lateral.plan), nestedRenderState(state), dialect).sql}) as ${dialect.quoteIdentifier(lateral.name)}`;
|
|
2909
4591
|
}
|
|
2910
4592
|
if (typeof source === "object" && source !== null && source.kind === "values") {
|
|
2911
4593
|
const values = source;
|
|
@@ -2920,143 +4602,219 @@ var renderSourceReference = (source, tableName, baseTableName, state, dialect) =
|
|
|
2920
4602
|
if (dialect.name !== "postgres") {
|
|
2921
4603
|
throw new Error("Unsupported table function source for SQL rendering");
|
|
2922
4604
|
}
|
|
4605
|
+
const functionName = renderFunctionName(tableFunction.functionName);
|
|
2923
4606
|
const columnNames = Object.keys(tableFunction.columns);
|
|
2924
|
-
return `${
|
|
4607
|
+
return `${functionName}(${tableFunction.args.map((arg) => renderExpression2(arg, state, dialect)).join(", ")}) as ${dialect.quoteIdentifier(tableFunction.name)}(${columnNames.map((columnName) => dialect.quoteIdentifier(columnName)).join(", ")})`;
|
|
4608
|
+
}
|
|
4609
|
+
const schemaName = typeof source === "object" && source !== null && TypeId6 in source ? casedSchemaName(source, state) : undefined;
|
|
4610
|
+
if (typeof source === "object" && source !== null && TypeId6 in source) {
|
|
4611
|
+
const table = source;
|
|
4612
|
+
const renderedBaseName = casedTableName(table, state);
|
|
4613
|
+
const renderedTableName = table[TypeId6].kind === "alias" ? tableName : renderedBaseName;
|
|
4614
|
+
return dialect.renderTableReference(renderedTableName, renderedBaseName, schemaName);
|
|
2925
4615
|
}
|
|
2926
|
-
|
|
2927
|
-
return dialect.renderTableReference(tableName, baseTableName, schemaName);
|
|
4616
|
+
return dialect.renderTableReference(applyCategory(state.casing, "tables", tableName), applyCategory(state.casing, "tables", baseTableName), schemaName);
|
|
2928
4617
|
};
|
|
2929
|
-
var
|
|
4618
|
+
var renderSubqueryExpressionPlan = (plan, state, dialect) => {
|
|
4619
|
+
const statement = getQueryState(plan).statement;
|
|
4620
|
+
if (statement !== "select" && statement !== "set") {
|
|
4621
|
+
throw new Error("subquery expressions only accept select-like query plans");
|
|
4622
|
+
}
|
|
4623
|
+
return renderQueryAst2(getAst(plan), state, dialect).sql;
|
|
4624
|
+
};
|
|
4625
|
+
var renderExpression2 = (expression, state, dialect) => {
|
|
2930
4626
|
const rawAst = expression[TypeId3];
|
|
2931
4627
|
const jsonSql = renderJsonExpression(expression, rawAst, state, dialect);
|
|
2932
4628
|
if (jsonSql !== undefined) {
|
|
2933
4629
|
return jsonSql;
|
|
2934
4630
|
}
|
|
2935
4631
|
const ast = rawAst;
|
|
2936
|
-
const renderComparisonOperator = (operator) =>
|
|
4632
|
+
const renderComparisonOperator = (operator) => ({
|
|
4633
|
+
eq: "=",
|
|
4634
|
+
neq: "<>",
|
|
4635
|
+
lt: "<",
|
|
4636
|
+
lte: "<=",
|
|
4637
|
+
gt: ">",
|
|
4638
|
+
gte: ">="
|
|
4639
|
+
})[operator];
|
|
4640
|
+
const renderCollation = (collation) => {
|
|
4641
|
+
return collation.map((segment) => dialect.quoteIdentifier(segment)).join(".");
|
|
4642
|
+
};
|
|
2937
4643
|
switch (ast.kind) {
|
|
2938
4644
|
case "column":
|
|
2939
|
-
return ast.tableName.length === 0 ?
|
|
4645
|
+
return state.rowLocalColumns || ast.tableName.length === 0 ? quoteColumn(ast.columnName, state, dialect, ast.tableName) : `${dialect.quoteIdentifier(casedTableReferenceName(ast.tableName, state))}.${quoteColumn(ast.columnName, state, dialect, ast.tableName)}`;
|
|
2940
4646
|
case "literal":
|
|
4647
|
+
if (typeof ast.value === "number" && !Number.isFinite(ast.value)) {
|
|
4648
|
+
throw new Error("Expected a finite numeric value");
|
|
4649
|
+
}
|
|
2941
4650
|
return dialect.renderLiteral(ast.value, state, expression[TypeId2]);
|
|
2942
4651
|
case "excluded":
|
|
2943
|
-
|
|
4652
|
+
if (state.allowExcluded !== true) {
|
|
4653
|
+
throw new Error("excluded(...) is only supported inside insert conflict handlers");
|
|
4654
|
+
}
|
|
4655
|
+
return dialect.name === "mysql" ? `values(${quoteColumn(ast.columnName, state, dialect)})` : `excluded.${quoteColumn(ast.columnName, state, dialect)}`;
|
|
2944
4656
|
case "cast":
|
|
2945
|
-
return `cast(${
|
|
4657
|
+
return `cast(${renderExpression2(expectValueExpression("cast", ast.value), state, dialect)} as ${renderCastType(dialect, ast.target)})`;
|
|
2946
4658
|
case "collate":
|
|
2947
|
-
return `(${
|
|
4659
|
+
return `(${renderExpression2(expectValueExpression("collate", ast.value), state, dialect)} collate ${renderCollation(ast.collation)})`;
|
|
2948
4660
|
case "function":
|
|
2949
|
-
return renderFunctionCall(ast.name,
|
|
4661
|
+
return renderFunctionCall(ast.name, ast.args, state, dialect);
|
|
2950
4662
|
case "eq":
|
|
2951
|
-
return
|
|
4663
|
+
return renderBinaryExpression("eq", "=", ast.left, ast.right, state, dialect);
|
|
2952
4664
|
case "neq":
|
|
2953
|
-
return
|
|
4665
|
+
return renderBinaryExpression("neq", "<>", ast.left, ast.right, state, dialect);
|
|
2954
4666
|
case "lt":
|
|
2955
|
-
return
|
|
4667
|
+
return renderBinaryExpression("lt", "<", ast.left, ast.right, state, dialect);
|
|
2956
4668
|
case "lte":
|
|
2957
|
-
return
|
|
4669
|
+
return renderBinaryExpression("lte", "<=", ast.left, ast.right, state, dialect);
|
|
2958
4670
|
case "gt":
|
|
2959
|
-
return
|
|
4671
|
+
return renderBinaryExpression("gt", ">", ast.left, ast.right, state, dialect);
|
|
2960
4672
|
case "gte":
|
|
2961
|
-
return
|
|
4673
|
+
return renderBinaryExpression("gte", ">=", ast.left, ast.right, state, dialect);
|
|
2962
4674
|
case "like":
|
|
2963
|
-
return
|
|
2964
|
-
case "ilike":
|
|
2965
|
-
|
|
2966
|
-
|
|
2967
|
-
|
|
2968
|
-
case "
|
|
2969
|
-
|
|
2970
|
-
|
|
2971
|
-
|
|
2972
|
-
|
|
2973
|
-
return dialect.name === "postgres" ? `(${
|
|
2974
|
-
|
|
2975
|
-
|
|
2976
|
-
|
|
2977
|
-
|
|
2978
|
-
|
|
4675
|
+
return renderBinaryExpression("like", "like", ast.left, ast.right, state, dialect);
|
|
4676
|
+
case "ilike": {
|
|
4677
|
+
const [left, right] = expectBinaryExpressions("ilike", ast.left, ast.right);
|
|
4678
|
+
return dialect.name === "postgres" ? `(${renderExpression2(left, state, dialect)} ilike ${renderExpression2(right, state, dialect)})` : `(lower(${renderExpression2(left, state, dialect)}) like lower(${renderExpression2(right, state, dialect)}))`;
|
|
4679
|
+
}
|
|
4680
|
+
case "regexMatch": {
|
|
4681
|
+
const [left, right] = expectBinaryExpressions("regexMatch", ast.left, ast.right);
|
|
4682
|
+
if (dialect.name === "standard") {
|
|
4683
|
+
throw new Error("Unsupported standard regular-expression predicates");
|
|
4684
|
+
}
|
|
4685
|
+
return dialect.name === "postgres" ? `(${renderExpression2(left, state, dialect)} ~ ${renderExpression2(right, state, dialect)})` : `(${renderExpression2(left, state, dialect)} regexp ${renderExpression2(right, state, dialect)})`;
|
|
4686
|
+
}
|
|
4687
|
+
case "regexIMatch": {
|
|
4688
|
+
const [left, right] = expectBinaryExpressions("regexIMatch", ast.left, ast.right);
|
|
4689
|
+
if (dialect.name === "standard") {
|
|
4690
|
+
throw new Error("Unsupported standard regular-expression predicates");
|
|
4691
|
+
}
|
|
4692
|
+
return dialect.name === "postgres" ? `(${renderExpression2(left, state, dialect)} ~* ${renderExpression2(right, state, dialect)})` : `(${renderExpression2(left, state, dialect)} regexp ${renderExpression2(right, state, dialect)})`;
|
|
4693
|
+
}
|
|
4694
|
+
case "regexNotMatch": {
|
|
4695
|
+
const [left, right] = expectBinaryExpressions("regexNotMatch", ast.left, ast.right);
|
|
4696
|
+
if (dialect.name === "standard") {
|
|
4697
|
+
throw new Error("Unsupported standard regular-expression predicates");
|
|
4698
|
+
}
|
|
4699
|
+
return dialect.name === "postgres" ? `(${renderExpression2(left, state, dialect)} !~ ${renderExpression2(right, state, dialect)})` : `(${renderExpression2(left, state, dialect)} not regexp ${renderExpression2(right, state, dialect)})`;
|
|
4700
|
+
}
|
|
4701
|
+
case "regexNotIMatch": {
|
|
4702
|
+
const [left, right] = expectBinaryExpressions("regexNotIMatch", ast.left, ast.right);
|
|
4703
|
+
if (dialect.name === "standard") {
|
|
4704
|
+
throw new Error("Unsupported standard regular-expression predicates");
|
|
4705
|
+
}
|
|
4706
|
+
return dialect.name === "postgres" ? `(${renderExpression2(left, state, dialect)} !~* ${renderExpression2(right, state, dialect)})` : `(${renderExpression2(left, state, dialect)} not regexp ${renderExpression2(right, state, dialect)})`;
|
|
4707
|
+
}
|
|
4708
|
+
case "isDistinctFrom": {
|
|
4709
|
+
const [left, right] = expectBinaryExpressions("isDistinctFrom", ast.left, ast.right);
|
|
4710
|
+
return dialect.name === "mysql" ? `(not (${renderExpression2(left, state, dialect)} <=> ${renderExpression2(right, state, dialect)}))` : `(${renderExpression2(left, state, dialect)} is distinct from ${renderExpression2(right, state, dialect)})`;
|
|
4711
|
+
}
|
|
4712
|
+
case "isNotDistinctFrom": {
|
|
4713
|
+
const [left, right] = expectBinaryExpressions("isNotDistinctFrom", ast.left, ast.right);
|
|
4714
|
+
return dialect.name === "mysql" ? `(${renderExpression2(left, state, dialect)} <=> ${renderExpression2(right, state, dialect)})` : `(${renderExpression2(left, state, dialect)} is not distinct from ${renderExpression2(right, state, dialect)})`;
|
|
4715
|
+
}
|
|
4716
|
+
case "contains": {
|
|
4717
|
+
const [leftExpression, rightExpression] = expectBinaryExpressions("contains", ast.left, ast.right);
|
|
2979
4718
|
if (dialect.name === "postgres") {
|
|
2980
|
-
|
|
2981
|
-
const
|
|
4719
|
+
assertCompatiblePostgresRangeOperands(leftExpression, rightExpression);
|
|
4720
|
+
const left = isJsonExpression(leftExpression) ? renderPostgresJsonValue(leftExpression, state, dialect) : renderExpression2(leftExpression, state, dialect);
|
|
4721
|
+
const right = isJsonExpression(rightExpression) ? renderPostgresJsonValue(rightExpression, state, dialect) : renderExpression2(rightExpression, state, dialect);
|
|
2982
4722
|
return `(${left} @> ${right})`;
|
|
2983
4723
|
}
|
|
2984
|
-
if (dialect.name === "mysql" && isJsonExpression(
|
|
2985
|
-
return `json_contains(${
|
|
4724
|
+
if (dialect.name === "mysql" && isJsonExpression(leftExpression) && isJsonExpression(rightExpression)) {
|
|
4725
|
+
return `json_contains(${renderExpression2(leftExpression, state, dialect)}, ${renderExpression2(rightExpression, state, dialect)})`;
|
|
2986
4726
|
}
|
|
2987
4727
|
throw new Error("Unsupported container operator for SQL rendering");
|
|
2988
|
-
|
|
4728
|
+
}
|
|
4729
|
+
case "containedBy": {
|
|
4730
|
+
const [leftExpression, rightExpression] = expectBinaryExpressions("containedBy", ast.left, ast.right);
|
|
2989
4731
|
if (dialect.name === "postgres") {
|
|
2990
|
-
|
|
2991
|
-
const
|
|
4732
|
+
assertCompatiblePostgresRangeOperands(leftExpression, rightExpression);
|
|
4733
|
+
const left = isJsonExpression(leftExpression) ? renderPostgresJsonValue(leftExpression, state, dialect) : renderExpression2(leftExpression, state, dialect);
|
|
4734
|
+
const right = isJsonExpression(rightExpression) ? renderPostgresJsonValue(rightExpression, state, dialect) : renderExpression2(rightExpression, state, dialect);
|
|
2992
4735
|
return `(${left} <@ ${right})`;
|
|
2993
4736
|
}
|
|
2994
|
-
if (dialect.name === "mysql" && isJsonExpression(
|
|
2995
|
-
return `json_contains(${
|
|
4737
|
+
if (dialect.name === "mysql" && isJsonExpression(leftExpression) && isJsonExpression(rightExpression)) {
|
|
4738
|
+
return `json_contains(${renderExpression2(rightExpression, state, dialect)}, ${renderExpression2(leftExpression, state, dialect)})`;
|
|
2996
4739
|
}
|
|
2997
4740
|
throw new Error("Unsupported container operator for SQL rendering");
|
|
2998
|
-
|
|
4741
|
+
}
|
|
4742
|
+
case "overlaps": {
|
|
4743
|
+
const [leftExpression, rightExpression] = expectBinaryExpressions("overlaps", ast.left, ast.right);
|
|
2999
4744
|
if (dialect.name === "postgres") {
|
|
3000
|
-
|
|
3001
|
-
const
|
|
4745
|
+
assertCompatiblePostgresRangeOperands(leftExpression, rightExpression);
|
|
4746
|
+
const left = isJsonExpression(leftExpression) ? renderPostgresJsonValue(leftExpression, state, dialect) : renderExpression2(leftExpression, state, dialect);
|
|
4747
|
+
const right = isJsonExpression(rightExpression) ? renderPostgresJsonValue(rightExpression, state, dialect) : renderExpression2(rightExpression, state, dialect);
|
|
3002
4748
|
return `(${left} && ${right})`;
|
|
3003
4749
|
}
|
|
3004
|
-
if (dialect.name === "mysql" && isJsonExpression(
|
|
3005
|
-
return `json_overlaps(${
|
|
4750
|
+
if (dialect.name === "mysql" && isJsonExpression(leftExpression) && isJsonExpression(rightExpression)) {
|
|
4751
|
+
return `json_overlaps(${renderExpression2(leftExpression, state, dialect)}, ${renderExpression2(rightExpression, state, dialect)})`;
|
|
3006
4752
|
}
|
|
3007
4753
|
throw new Error("Unsupported container operator for SQL rendering");
|
|
4754
|
+
}
|
|
3008
4755
|
case "isNull":
|
|
3009
|
-
return `(${
|
|
4756
|
+
return `(${renderExpression2(expectValueExpression("isNull", ast.value), state, dialect)} is null)`;
|
|
3010
4757
|
case "isNotNull":
|
|
3011
|
-
return `(${
|
|
4758
|
+
return `(${renderExpression2(expectValueExpression("isNotNull", ast.value), state, dialect)} is not null)`;
|
|
3012
4759
|
case "not":
|
|
3013
|
-
return `(not ${
|
|
4760
|
+
return `(not ${renderExpression2(expectValueExpression("not", ast.value), state, dialect)})`;
|
|
3014
4761
|
case "upper":
|
|
3015
|
-
return `upper(${
|
|
4762
|
+
return `upper(${renderExpression2(expectValueExpression("upper", ast.value), state, dialect)})`;
|
|
3016
4763
|
case "lower":
|
|
3017
|
-
return `lower(${
|
|
4764
|
+
return `lower(${renderExpression2(expectValueExpression("lower", ast.value), state, dialect)})`;
|
|
3018
4765
|
case "count":
|
|
3019
|
-
return `count(${
|
|
4766
|
+
return `count(${renderExpression2(expectValueExpression("count", ast.value), state, dialect)})`;
|
|
3020
4767
|
case "max":
|
|
3021
|
-
return `max(${
|
|
4768
|
+
return `max(${renderExpression2(expectValueExpression("max", ast.value), state, dialect)})`;
|
|
3022
4769
|
case "min":
|
|
3023
|
-
return `min(${
|
|
4770
|
+
return `min(${renderExpression2(expectValueExpression("min", ast.value), state, dialect)})`;
|
|
3024
4771
|
case "and":
|
|
3025
|
-
return `(${ast.values.map((value) =>
|
|
4772
|
+
return `(${ast.values.map((value) => renderExpression2(value, state, dialect)).join(" and ")})`;
|
|
3026
4773
|
case "or":
|
|
3027
|
-
return `(${ast.values.map((value) =>
|
|
4774
|
+
return `(${ast.values.map((value) => renderExpression2(value, state, dialect)).join(" or ")})`;
|
|
3028
4775
|
case "coalesce":
|
|
3029
|
-
return `coalesce(${ast.values.map((value) =>
|
|
4776
|
+
return `coalesce(${ast.values.map((value) => renderExpression2(value, state, dialect)).join(", ")})`;
|
|
3030
4777
|
case "in":
|
|
3031
|
-
return `(${
|
|
4778
|
+
return `(${renderExpression2(ast.values[0], state, dialect)} in (${ast.values.slice(1).map((value) => renderExpression2(value, state, dialect)).join(", ")}))`;
|
|
3032
4779
|
case "notIn":
|
|
3033
|
-
return `(${
|
|
4780
|
+
return `(${renderExpression2(ast.values[0], state, dialect)} not in (${ast.values.slice(1).map((value) => renderExpression2(value, state, dialect)).join(", ")}))`;
|
|
3034
4781
|
case "between":
|
|
3035
|
-
return `(${
|
|
4782
|
+
return `(${renderExpression2(ast.values[0], state, dialect)} between ${renderExpression2(ast.values[1], state, dialect)} and ${renderExpression2(ast.values[2], state, dialect)})`;
|
|
3036
4783
|
case "concat":
|
|
3037
|
-
return dialect.renderConcat(ast.values.map((value) =>
|
|
4784
|
+
return dialect.renderConcat(ast.values.map((value) => renderExpression2(value, state, dialect)));
|
|
3038
4785
|
case "case":
|
|
3039
|
-
return `case ${ast.branches.map((branch) => `when ${
|
|
4786
|
+
return `case ${ast.branches.map((branch) => `when ${renderExpression2(branch.when, state, dialect)} then ${renderExpression2(branch.then, state, dialect)}`).join(" ")} else ${renderExpression2(ast.else, state, dialect)} end`;
|
|
3040
4787
|
case "exists":
|
|
3041
|
-
return `exists (${
|
|
4788
|
+
return `exists (${renderSubqueryExpressionPlan(ast.plan, state, dialect)})`;
|
|
3042
4789
|
case "scalarSubquery":
|
|
3043
|
-
return `(${
|
|
4790
|
+
return `(${renderSubqueryExpressionPlan(ast.plan, state, dialect)})`;
|
|
3044
4791
|
case "inSubquery":
|
|
3045
|
-
return `(${
|
|
3046
|
-
case "comparisonAny":
|
|
3047
|
-
|
|
3048
|
-
|
|
3049
|
-
|
|
3050
|
-
|
|
3051
|
-
|
|
3052
|
-
|
|
4792
|
+
return `(${renderExpression2(expectValueExpression("inSubquery", ast.left), state, dialect)} in (${renderSubqueryExpressionPlan(ast.plan, state, dialect)}))`;
|
|
4793
|
+
case "comparisonAny": {
|
|
4794
|
+
const left = expectValueExpression("compareAny", ast.left);
|
|
4795
|
+
const operator = renderComparisonOperator(ast.operator);
|
|
4796
|
+
if (dialect.name === "standard") {
|
|
4797
|
+
throw new Error("Unsupported standard quantified comparison");
|
|
4798
|
+
}
|
|
4799
|
+
return `(${renderExpression2(left, state, dialect)} ${operator} any (${renderSubqueryExpressionPlan(ast.plan, state, dialect)}))`;
|
|
4800
|
+
}
|
|
4801
|
+
case "comparisonAll": {
|
|
4802
|
+
const left = expectValueExpression("compareAll", ast.left);
|
|
4803
|
+
const operator = renderComparisonOperator(ast.operator);
|
|
4804
|
+
if (dialect.name === "standard") {
|
|
4805
|
+
throw new Error("Unsupported standard quantified comparison");
|
|
3053
4806
|
}
|
|
4807
|
+
return `(${renderExpression2(left, state, dialect)} ${operator} all (${renderSubqueryExpressionPlan(ast.plan, state, dialect)}))`;
|
|
4808
|
+
}
|
|
4809
|
+
case "window": {
|
|
4810
|
+
const partitionBy = ast.partitionBy;
|
|
4811
|
+
const orderBy = ast.orderBy;
|
|
3054
4812
|
const clauses = [];
|
|
3055
|
-
if (
|
|
3056
|
-
clauses.push(`partition by ${
|
|
4813
|
+
if (partitionBy.length > 0) {
|
|
4814
|
+
clauses.push(`partition by ${partitionBy.map((value) => renderExpression2(value, state, dialect)).join(", ")}`);
|
|
3057
4815
|
}
|
|
3058
|
-
if (
|
|
3059
|
-
clauses.push(`order by ${
|
|
4816
|
+
if (orderBy.length > 0) {
|
|
4817
|
+
clauses.push(`order by ${orderBy.map((entry) => `${renderExpression2(entry.value, state, dialect)} ${entry.direction}`).join(", ")}`);
|
|
3060
4818
|
}
|
|
3061
4819
|
const specification = clauses.join(" ");
|
|
3062
4820
|
switch (ast.function) {
|
|
@@ -3067,7 +4825,7 @@ var renderExpression = (expression, state, dialect) => {
|
|
|
3067
4825
|
case "denseRank":
|
|
3068
4826
|
return `dense_rank() over (${specification})`;
|
|
3069
4827
|
case "over":
|
|
3070
|
-
return `${
|
|
4828
|
+
return `${renderExpression2(ast.value, state, dialect)} over (${specification})`;
|
|
3071
4829
|
}
|
|
3072
4830
|
break;
|
|
3073
4831
|
}
|
|
@@ -3075,12 +4833,41 @@ var renderExpression = (expression, state, dialect) => {
|
|
|
3075
4833
|
throw new Error("Unsupported expression for SQL rendering");
|
|
3076
4834
|
};
|
|
3077
4835
|
|
|
3078
|
-
// src/
|
|
3079
|
-
|
|
4836
|
+
// src/standard/dialect.ts
|
|
4837
|
+
var quoteIdentifier = quoteDoubleQuotedIdentifier;
|
|
4838
|
+
var renderLiteral = (value, state, context = {}) => {
|
|
4839
|
+
const driverValue = toDriverValue(value, {
|
|
4840
|
+
dialect: "standard",
|
|
4841
|
+
valueMappings: state.valueMappings,
|
|
4842
|
+
...context
|
|
4843
|
+
});
|
|
4844
|
+
if (driverValue === null) {
|
|
4845
|
+
return "null";
|
|
4846
|
+
}
|
|
4847
|
+
if (typeof driverValue === "boolean") {
|
|
4848
|
+
return driverValue ? "true" : "false";
|
|
4849
|
+
}
|
|
4850
|
+
state.params.push(driverValue);
|
|
4851
|
+
return "?";
|
|
4852
|
+
};
|
|
4853
|
+
var standardDialect = {
|
|
4854
|
+
name: "standard",
|
|
4855
|
+
quoteIdentifier,
|
|
4856
|
+
renderLiteral,
|
|
4857
|
+
renderTableReference(tableName, baseTableName, schemaName) {
|
|
4858
|
+
const renderedBase = schemaName && schemaName !== "public" ? `${quoteIdentifier(schemaName)}.${quoteIdentifier(baseTableName)}` : quoteIdentifier(baseTableName);
|
|
4859
|
+
return tableName === baseTableName ? renderedBase : `${renderedBase} as ${quoteIdentifier(tableName)}`;
|
|
4860
|
+
},
|
|
4861
|
+
renderConcat(values) {
|
|
4862
|
+
return `(${values.join(" || ")})`;
|
|
4863
|
+
},
|
|
4864
|
+
renderQueryAst: renderQueryAst2,
|
|
4865
|
+
renderExpression: renderExpression2
|
|
4866
|
+
};
|
|
3080
4867
|
|
|
3081
4868
|
// src/postgres/internal/dialect.ts
|
|
3082
|
-
var
|
|
3083
|
-
var
|
|
4869
|
+
var quoteIdentifier2 = quoteDoubleQuotedIdentifier;
|
|
4870
|
+
var renderLiteral2 = (value, state, context = {}) => {
|
|
3084
4871
|
const driverValue = toDriverValue(value, {
|
|
3085
4872
|
dialect: "postgres",
|
|
3086
4873
|
valueMappings: state.valueMappings,
|
|
@@ -3096,16 +4883,19 @@ var renderLiteral = (value, state, context = {}) => {
|
|
|
3096
4883
|
return `$${state.params.length}`;
|
|
3097
4884
|
};
|
|
3098
4885
|
var postgresDialect = {
|
|
4886
|
+
...standardDialect,
|
|
3099
4887
|
name: "postgres",
|
|
3100
|
-
quoteIdentifier,
|
|
3101
|
-
renderLiteral,
|
|
4888
|
+
quoteIdentifier: quoteIdentifier2,
|
|
4889
|
+
renderLiteral: renderLiteral2,
|
|
3102
4890
|
renderTableReference(tableName, baseTableName, schemaName) {
|
|
3103
|
-
const renderedBase = schemaName ? `${
|
|
3104
|
-
return tableName === baseTableName ? renderedBase : `${renderedBase} as ${
|
|
4891
|
+
const renderedBase = schemaName && schemaName !== "public" ? `${quoteIdentifier2(schemaName)}.${quoteIdentifier2(baseTableName)}` : quoteIdentifier2(baseTableName);
|
|
4892
|
+
return tableName === baseTableName ? renderedBase : `${renderedBase} as ${quoteIdentifier2(tableName)}`;
|
|
3105
4893
|
},
|
|
3106
4894
|
renderConcat(values) {
|
|
3107
4895
|
return `(${values.join(" || ")})`;
|
|
3108
|
-
}
|
|
4896
|
+
},
|
|
4897
|
+
renderQueryAst: renderQueryAst2,
|
|
4898
|
+
renderExpression: renderExpression2
|
|
3109
4899
|
};
|
|
3110
4900
|
|
|
3111
4901
|
// src/postgres/internal/schema-ddl.ts
|
|
@@ -3123,16 +4913,22 @@ var inlineLiteralDialect = {
|
|
|
3123
4913
|
return String(value);
|
|
3124
4914
|
}
|
|
3125
4915
|
if (value instanceof Date) {
|
|
4916
|
+
if (Number.isNaN(value.getTime())) {
|
|
4917
|
+
throw new Error("Expected a valid Date value");
|
|
4918
|
+
}
|
|
3126
4919
|
return escapeString(value.toISOString());
|
|
3127
4920
|
}
|
|
3128
4921
|
return escapeString(String(value));
|
|
3129
4922
|
}
|
|
3130
4923
|
};
|
|
3131
|
-
var
|
|
4924
|
+
var makeExpressionState = (state = {}) => ({
|
|
4925
|
+
...state,
|
|
3132
4926
|
params: [],
|
|
3133
4927
|
ctes: [],
|
|
3134
|
-
cteNames: new Set
|
|
3135
|
-
|
|
4928
|
+
cteNames: new Set,
|
|
4929
|
+
cteSources: new Map
|
|
4930
|
+
});
|
|
4931
|
+
var renderDdlExpressionSql = (expression, state) => isSchemaExpression(expression) ? render(expression) : renderExpression(expression, makeExpressionState(state), inlineLiteralDialect);
|
|
3136
4932
|
var stripRedundantOuterParens = (value) => {
|
|
3137
4933
|
let current = value.trim();
|
|
3138
4934
|
while (current.startsWith("(") && current.endsWith(")")) {
|
|
@@ -3172,8 +4968,8 @@ var stripRedundantOuterParens = (value) => {
|
|
|
3172
4968
|
return current;
|
|
3173
4969
|
};
|
|
3174
4970
|
var canonicalizeDdlExpressionSql = (value) => stripRedundantOuterParens(value.trim().replace(/\s+/g, " ").replace(/"[^"]+"\./g, "").replace(/"([A-Za-z_][A-Za-z0-9_]*)"/g, "$1").replace(/\bCOLLATE\b/g, "collate").replace(/cast\(((?:'(?:[^']|'')*'|"[^"]+"|[a-zA-Z_][a-zA-Z0-9_]*|\([^()]+\))) as ([^)]+)\)/gi, (_, expression, target) => `${expression}::${target.trim()}`));
|
|
3175
|
-
var normalizeDdlExpressionSql = (expression) => {
|
|
3176
|
-
const rendered = renderDdlExpressionSql(expression);
|
|
4971
|
+
var normalizeDdlExpressionSql = (expression, state) => {
|
|
4972
|
+
const rendered = renderDdlExpressionSql(expression, state);
|
|
3177
4973
|
try {
|
|
3178
4974
|
return canonicalizeDdlExpressionSql(toSql2.expr(parse2(rendered, "expr")));
|
|
3179
4975
|
} catch {
|
|
@@ -3182,10 +4978,14 @@ var normalizeDdlExpressionSql = (expression) => {
|
|
|
3182
4978
|
};
|
|
3183
4979
|
|
|
3184
4980
|
// src/postgres/schema-management.ts
|
|
3185
|
-
import * as
|
|
4981
|
+
import * as Schema6 from "effect/Schema";
|
|
3186
4982
|
import { pipeArguments as pipeArguments5 } from "effect/Pipeable";
|
|
3187
4983
|
var EnumTypeId = Symbol.for("effect-qb/SchemaManagement/Enum");
|
|
3188
4984
|
var SequenceTypeId = Symbol.for("effect-qb/SchemaManagement/Sequence");
|
|
4985
|
+
var safeUnquotedIdentifier = /^[a-z_][a-z0-9_$]*$/;
|
|
4986
|
+
var quoteIdentifier3 = (value) => `"${value.replaceAll('"', '""')}"`;
|
|
4987
|
+
var renderIdentifier = (value) => safeUnquotedIdentifier.test(value) ? value : quoteIdentifier3(value);
|
|
4988
|
+
var renderQualifiedTypeName = (name, schemaName) => schemaName === undefined || schemaName === "public" ? renderIdentifier(name) : `${renderIdentifier(schemaName)}.${renderIdentifier(name)}`;
|
|
3189
4989
|
var EnumProto = {
|
|
3190
4990
|
pipe() {
|
|
3191
4991
|
return pipeArguments5(this, arguments);
|
|
@@ -3196,13 +4996,17 @@ var EnumProto = {
|
|
|
3196
4996
|
type() {
|
|
3197
4997
|
return {
|
|
3198
4998
|
dialect: "postgres",
|
|
3199
|
-
kind: this.
|
|
4999
|
+
kind: renderQualifiedTypeName(this.name, this.schemaName),
|
|
3200
5000
|
variant: "enum"
|
|
3201
5001
|
};
|
|
3202
5002
|
},
|
|
3203
5003
|
column() {
|
|
3204
|
-
const
|
|
3205
|
-
|
|
5004
|
+
const [first, ...rest] = this.values;
|
|
5005
|
+
const values = [
|
|
5006
|
+
Schema6.Literal(first),
|
|
5007
|
+
...rest.map((value) => Schema6.Literal(value))
|
|
5008
|
+
];
|
|
5009
|
+
return makeColumnDefinition(values.length === 1 ? values[0] : Schema6.Union(...values), {
|
|
3206
5010
|
dbType: this.type(),
|
|
3207
5011
|
nullable: false,
|
|
3208
5012
|
hasDefault: false,
|
|
@@ -3210,7 +5014,7 @@ var EnumProto = {
|
|
|
3210
5014
|
primaryKey: false,
|
|
3211
5015
|
unique: false,
|
|
3212
5016
|
references: undefined,
|
|
3213
|
-
ddlType: this.
|
|
5017
|
+
ddlType: renderQualifiedTypeName(this.name, this.schemaName),
|
|
3214
5018
|
identity: undefined,
|
|
3215
5019
|
enum: {
|
|
3216
5020
|
name: this.name,
|
|
@@ -3255,17 +5059,123 @@ function sequence(name, schemaName) {
|
|
|
3255
5059
|
var isSequenceDefinition = (value) => typeof value === "object" && value !== null && (SequenceTypeId in value);
|
|
3256
5060
|
|
|
3257
5061
|
// src/postgres/internal/schema-model.ts
|
|
3258
|
-
var isTableDefinition = (value) => value !== null && (typeof value === "object" || typeof value === "function") && (
|
|
5062
|
+
var isTableDefinition = (value) => value !== null && (typeof value === "object" || typeof value === "function") && (TypeId6 in value);
|
|
3259
5063
|
var isEnumDefinition = (value) => typeof value === "object" && value !== null && (EnumTypeId in value);
|
|
5064
|
+
var applyCasing = (casing, category, name) => applyCategory(casing, category, name);
|
|
5065
|
+
var mapColumnList = (columns, casing) => !Array.isArray(columns) ? columns : columns.length === 0 ? columns : [
|
|
5066
|
+
mapCasedValue(columns[0], casing, "columns"),
|
|
5067
|
+
...columns.slice(1).map((column) => mapCasedValue(column, casing, "columns"))
|
|
5068
|
+
];
|
|
5069
|
+
var expressionStateForTable = (state, tableName, columns, casing) => ({
|
|
5070
|
+
casing,
|
|
5071
|
+
rowLocalColumns: true,
|
|
5072
|
+
sourceNames: new Map([
|
|
5073
|
+
[state.name, { tableName, columns }],
|
|
5074
|
+
[state.baseName, { tableName, columns }]
|
|
5075
|
+
])
|
|
5076
|
+
});
|
|
5077
|
+
var mapDdlExpression = (expression, state) => fromSql(normalizeDdlExpressionSql(expression, state));
|
|
5078
|
+
function mapOptionName(name, casing, category) {
|
|
5079
|
+
return typeof name === "string" ? applyCasing(casing, category, name) : name;
|
|
5080
|
+
}
|
|
5081
|
+
function mapCasedValue(value, casing, category) {
|
|
5082
|
+
return typeof value === "string" ? applyCasing(casing, category, value) : value;
|
|
5083
|
+
}
|
|
5084
|
+
var isDdlExpressionLike = (value) => typeof value === "object" && value !== null && ((TypeId2 in value) || (TypeId4 in value));
|
|
5085
|
+
function mapIndexKey(key2, casing, expressionState) {
|
|
5086
|
+
if (typeof key2 !== "object" || key2 === null || !("kind" in key2)) {
|
|
5087
|
+
return key2;
|
|
5088
|
+
}
|
|
5089
|
+
const kind = key2.kind;
|
|
5090
|
+
if (kind === "column") {
|
|
5091
|
+
const column = key2.column;
|
|
5092
|
+
return typeof column === "string" ? {
|
|
5093
|
+
...key2,
|
|
5094
|
+
column: applyCasing(casing, "columns", column)
|
|
5095
|
+
} : key2;
|
|
5096
|
+
}
|
|
5097
|
+
if (kind === "expression") {
|
|
5098
|
+
const expression = key2.expression;
|
|
5099
|
+
return isDdlExpressionLike(expression) ? {
|
|
5100
|
+
...key2,
|
|
5101
|
+
expression: mapDdlExpression(expression, expressionState)
|
|
5102
|
+
} : key2;
|
|
5103
|
+
}
|
|
5104
|
+
return key2;
|
|
5105
|
+
}
|
|
5106
|
+
var mapOption = (option2, casing, expressionState) => {
|
|
5107
|
+
switch (option2.kind) {
|
|
5108
|
+
case "index":
|
|
5109
|
+
return {
|
|
5110
|
+
...option2,
|
|
5111
|
+
columns: option2.columns === undefined ? undefined : mapColumnList(option2.columns, casing),
|
|
5112
|
+
name: option2.name === undefined ? undefined : mapOptionName(option2.name, casing, "indexes"),
|
|
5113
|
+
include: option2.include === undefined ? undefined : Array.isArray(option2.include) ? option2.include.map((column) => mapCasedValue(column, casing, "columns")) : option2.include,
|
|
5114
|
+
predicate: option2.predicate === undefined ? undefined : isDdlExpressionLike(option2.predicate) ? mapDdlExpression(option2.predicate, expressionState) : option2.predicate,
|
|
5115
|
+
keys: option2.keys === undefined ? undefined : Array.isArray(option2.keys) ? option2.keys.length === 0 ? option2.keys : [
|
|
5116
|
+
mapIndexKey(option2.keys[0], casing, expressionState),
|
|
5117
|
+
...option2.keys.slice(1).map((key2) => mapIndexKey(key2, casing, expressionState))
|
|
5118
|
+
] : option2.keys
|
|
5119
|
+
};
|
|
5120
|
+
case "primaryKey":
|
|
5121
|
+
return {
|
|
5122
|
+
...option2,
|
|
5123
|
+
columns: mapColumnList(option2.columns, casing),
|
|
5124
|
+
name: option2.name === undefined ? undefined : mapOptionName(option2.name, casing, "constraints")
|
|
5125
|
+
};
|
|
5126
|
+
case "unique":
|
|
5127
|
+
return {
|
|
5128
|
+
...option2,
|
|
5129
|
+
columns: mapColumnList(option2.columns, casing),
|
|
5130
|
+
name: option2.name === undefined ? undefined : mapOptionName(option2.name, casing, "constraints")
|
|
5131
|
+
};
|
|
5132
|
+
case "foreignKey":
|
|
5133
|
+
return {
|
|
5134
|
+
...option2,
|
|
5135
|
+
columns: mapColumnList(option2.columns, casing),
|
|
5136
|
+
name: option2.name === undefined ? undefined : mapOptionName(option2.name, casing, "constraints"),
|
|
5137
|
+
references: () => {
|
|
5138
|
+
const reference = typeof option2.references === "function" ? option2.references() : option2.references;
|
|
5139
|
+
if (typeof reference !== "object" || reference === null) {
|
|
5140
|
+
return reference;
|
|
5141
|
+
}
|
|
5142
|
+
const referenceCasing2 = reference.casing;
|
|
5143
|
+
return {
|
|
5144
|
+
...reference,
|
|
5145
|
+
tableName: mapCasedValue(reference.tableName, referenceCasing2, "tables"),
|
|
5146
|
+
schemaName: reference.schemaName === undefined ? undefined : mapCasedValue(reference.schemaName, referenceCasing2, "schemas"),
|
|
5147
|
+
columns: mapColumnList(reference.columns, referenceCasing2),
|
|
5148
|
+
knownColumns: reference.knownColumns === undefined ? undefined : Array.isArray(reference.knownColumns) ? reference.knownColumns.map((column) => mapCasedValue(column, referenceCasing2, "columns")) : reference.knownColumns
|
|
5149
|
+
};
|
|
5150
|
+
}
|
|
5151
|
+
};
|
|
5152
|
+
case "check":
|
|
5153
|
+
return {
|
|
5154
|
+
...option2,
|
|
5155
|
+
name: mapOptionName(option2.name, casing, "constraints"),
|
|
5156
|
+
predicate: isDdlExpressionLike(option2.predicate) ? mapDdlExpression(option2.predicate, expressionState) : option2.predicate
|
|
5157
|
+
};
|
|
5158
|
+
default:
|
|
5159
|
+
return option2;
|
|
5160
|
+
}
|
|
5161
|
+
};
|
|
3260
5162
|
var toTableModel = (table) => {
|
|
3261
|
-
const state = table[
|
|
5163
|
+
const state = table[TypeId6];
|
|
5164
|
+
const casing = state.casing;
|
|
5165
|
+
const tableName = applyCasing(casing, "tables", state.baseName);
|
|
5166
|
+
const schemaName = state.schemaName === undefined ? undefined : applyCasing(casing, "schemas", state.schemaName);
|
|
3262
5167
|
const fields = state.fields;
|
|
5168
|
+
const options2 = table[OptionsSymbol];
|
|
5169
|
+
const normalizedOptions = Array.isArray(options2) ? options2 : [options2];
|
|
5170
|
+
validateOptions(state.name, fields, normalizedOptions);
|
|
5171
|
+
const columnNames = new Map(Object.keys(fields).map((name) => [name, applyCasing(casing, "columns", name)]));
|
|
5172
|
+
const expressionState = expressionStateForTable(state, tableName, columnNames, casing);
|
|
3263
5173
|
const columns = Object.entries(fields).map(([name, column]) => {
|
|
3264
5174
|
const metadata = column.metadata;
|
|
3265
5175
|
const enumDefinition = metadata.enum;
|
|
3266
5176
|
const ddlType = metadata.ddlType ?? metadata.dbType.kind;
|
|
3267
5177
|
return {
|
|
3268
|
-
name,
|
|
5178
|
+
name: columnNames.get(name) ?? name,
|
|
3269
5179
|
ddlType,
|
|
3270
5180
|
dbTypeKind: enumDefinition?.name ?? column.metadata.dbType.kind,
|
|
3271
5181
|
typeKind: enumDefinition === undefined ? undefined : "e",
|
|
@@ -3273,18 +5183,18 @@ var toTableModel = (table) => {
|
|
|
3273
5183
|
nullable: column.metadata.nullable,
|
|
3274
5184
|
hasDefault: column.metadata.hasDefault,
|
|
3275
5185
|
generated: column.metadata.generated,
|
|
3276
|
-
defaultSql: column.metadata.defaultValue === undefined ? undefined : normalizeDdlExpressionSql(column.metadata.defaultValue),
|
|
3277
|
-
generatedSql: column.metadata.generatedValue === undefined ? undefined : normalizeDdlExpressionSql(column.metadata.generatedValue),
|
|
5186
|
+
defaultSql: column.metadata.defaultValue === undefined ? undefined : normalizeDdlExpressionSql(column.metadata.defaultValue, expressionState),
|
|
5187
|
+
generatedSql: column.metadata.generatedValue === undefined ? undefined : normalizeDdlExpressionSql(column.metadata.generatedValue, expressionState),
|
|
3278
5188
|
identity: column.metadata.identity,
|
|
3279
5189
|
column
|
|
3280
5190
|
};
|
|
3281
5191
|
});
|
|
3282
5192
|
return {
|
|
3283
5193
|
kind: "table",
|
|
3284
|
-
schemaName
|
|
3285
|
-
name:
|
|
5194
|
+
schemaName,
|
|
5195
|
+
name: tableName,
|
|
3286
5196
|
columns,
|
|
3287
|
-
options:
|
|
5197
|
+
options: normalizedOptions.map((option2) => typeof option2 === "object" && option2 !== null && ("kind" in option2) ? mapOption(option2, casing, expressionState) : option2),
|
|
3288
5198
|
table
|
|
3289
5199
|
};
|
|
3290
5200
|
};
|
|
@@ -3295,7 +5205,7 @@ var toEnumModel = (definition) => ({
|
|
|
3295
5205
|
values: [...definition.values]
|
|
3296
5206
|
});
|
|
3297
5207
|
var enumModelsOfTable = (table) => {
|
|
3298
|
-
const state = table[
|
|
5208
|
+
const state = table[TypeId6];
|
|
3299
5209
|
const fields = state.fields;
|
|
3300
5210
|
return Object.values(fields).flatMap((column) => column.metadata.enum === undefined ? [] : [
|
|
3301
5211
|
{
|
|
@@ -3311,17 +5221,17 @@ var fromDiscoveredValues = (values) => {
|
|
|
3311
5221
|
const enums = new Map;
|
|
3312
5222
|
for (const value of values) {
|
|
3313
5223
|
if (isEnumDefinition(value)) {
|
|
3314
|
-
enums.set(
|
|
5224
|
+
enums.set(modelIdentityKey(value.schemaName, value.name), toEnumModel(value));
|
|
3315
5225
|
} else if (isTableDefinition(value)) {
|
|
3316
5226
|
for (const enumModel of enumModelsOfTable(value)) {
|
|
3317
|
-
const key2 =
|
|
5227
|
+
const key2 = modelIdentityKey(enumModel.schemaName, enumModel.name);
|
|
3318
5228
|
const existing = enums.get(key2);
|
|
3319
5229
|
if (existing === undefined) {
|
|
3320
5230
|
enums.set(key2, enumModel);
|
|
3321
5231
|
continue;
|
|
3322
5232
|
}
|
|
3323
5233
|
if (JSON.stringify(existing.values) !== JSON.stringify(enumModel.values)) {
|
|
3324
|
-
throw new Error(`Conflicting enum definitions discovered for '${
|
|
5234
|
+
throw new Error(`Conflicting enum definitions discovered for '${enumKey(enumModel.schemaName, enumModel.name)}'`);
|
|
3325
5235
|
}
|
|
3326
5236
|
}
|
|
3327
5237
|
}
|
|
@@ -3334,6 +5244,7 @@ var fromDiscoveredValues = (values) => {
|
|
|
3334
5244
|
};
|
|
3335
5245
|
var tableKey = (schemaName, name) => `${schemaName ?? "public"}.${name}`;
|
|
3336
5246
|
var enumKey = (schemaName, name) => `${schemaName ?? "public"}.${name}`;
|
|
5247
|
+
var modelIdentityKey = (schemaName, name) => JSON.stringify([schemaName ?? "public", name]);
|
|
3337
5248
|
export {
|
|
3338
5249
|
toTableModel,
|
|
3339
5250
|
toEnumModel,
|