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.
Files changed (128) hide show
  1. package/README.md +4 -0
  2. package/dist/index.js +8065 -0
  3. package/dist/mysql.js +4036 -2418
  4. package/dist/postgres/metadata.js +2536 -625
  5. package/dist/postgres.js +8248 -7857
  6. package/dist/sqlite.js +8854 -0
  7. package/dist/standard.js +8019 -0
  8. package/package.json +15 -3
  9. package/src/casing.ts +71 -0
  10. package/src/index.ts +2 -0
  11. package/src/internal/casing.ts +89 -0
  12. package/src/internal/column-state.ts +11 -6
  13. package/src/internal/column.ts +44 -7
  14. package/src/internal/datatypes/define.ts +2 -1
  15. package/src/internal/datatypes/enrich.ts +23 -0
  16. package/src/internal/datatypes/lookup.ts +14 -7
  17. package/src/internal/derived-table.ts +7 -13
  18. package/src/internal/dialect-renderers/mysql.ts +2046 -0
  19. package/src/{postgres/internal/sql-expression-renderer.ts → internal/dialect-renderers/postgres.ts} +867 -283
  20. package/src/{mysql/internal/sql-expression-renderer.ts → internal/dialect-renderers/sqlite.ts} +834 -358
  21. package/src/internal/dialect.ts +37 -0
  22. package/src/internal/dsl-mutation-runtime.ts +29 -10
  23. package/src/internal/dsl-plan-runtime.ts +41 -24
  24. package/src/internal/dsl-query-runtime.ts +11 -31
  25. package/src/internal/dsl-transaction-ddl-runtime.ts +61 -15
  26. package/src/internal/executor.ts +57 -15
  27. package/src/internal/expression-ast.ts +3 -2
  28. package/src/internal/grouping-key.ts +216 -9
  29. package/src/internal/implication-runtime.ts +3 -2
  30. package/src/internal/json/types.ts +155 -40
  31. package/src/internal/predicate/context.ts +14 -1
  32. package/src/internal/predicate/key.ts +19 -2
  33. package/src/internal/predicate/runtime.ts +30 -3
  34. package/src/internal/query.d.ts +38 -11
  35. package/src/internal/query.ts +315 -54
  36. package/src/internal/renderer.ts +51 -6
  37. package/src/internal/runtime/driver-value-mapping.ts +58 -0
  38. package/src/internal/runtime/normalize.ts +74 -43
  39. package/src/internal/runtime/schema.ts +5 -3
  40. package/src/internal/runtime/value.ts +153 -30
  41. package/src/internal/scalar.ts +6 -1
  42. package/src/internal/schema-derivation.d.ts +12 -61
  43. package/src/internal/schema-derivation.ts +90 -38
  44. package/src/internal/schema-expression.ts +2 -2
  45. package/src/internal/sql-expression-renderer.ts +19 -0
  46. package/src/internal/standard-dsl.ts +6885 -0
  47. package/src/internal/table-options.ts +229 -62
  48. package/src/internal/table.d.ts +33 -32
  49. package/src/internal/table.ts +469 -160
  50. package/src/mysql/column-extension.ts +3 -0
  51. package/src/mysql/column.ts +27 -12
  52. package/src/mysql/datatypes/index.ts +24 -2
  53. package/src/mysql/errors/catalog.ts +5 -5
  54. package/src/mysql/errors/normalize.ts +2 -2
  55. package/src/mysql/executor.ts +7 -5
  56. package/src/mysql/internal/dialect.ts +9 -4
  57. package/src/mysql/internal/dsl.ts +906 -324
  58. package/src/mysql/internal/renderer.ts +7 -2
  59. package/src/mysql/json.ts +37 -0
  60. package/src/mysql/query-extension.ts +16 -0
  61. package/src/mysql/query.ts +9 -2
  62. package/src/mysql/renderer.ts +31 -4
  63. package/src/mysql.ts +4 -12
  64. package/src/postgres/column-extension.ts +28 -0
  65. package/src/postgres/column.ts +9 -13
  66. package/src/postgres/datatypes/index.d.ts +2 -1
  67. package/src/postgres/datatypes/index.ts +3 -2
  68. package/src/postgres/errors/normalize.ts +2 -2
  69. package/src/postgres/executor.ts +55 -10
  70. package/src/postgres/function/core.ts +20 -4
  71. package/src/postgres/function/index.ts +1 -17
  72. package/src/postgres/internal/dialect.ts +9 -4
  73. package/src/postgres/internal/dsl.ts +850 -359
  74. package/src/postgres/internal/renderer.ts +7 -2
  75. package/src/postgres/internal/schema-ddl.ts +22 -9
  76. package/src/postgres/internal/schema-model.ts +244 -10
  77. package/src/postgres/json.ts +100 -24
  78. package/src/postgres/jsonb.ts +38 -0
  79. package/src/postgres/query-extension.ts +2 -0
  80. package/src/postgres/query.ts +9 -2
  81. package/src/postgres/renderer.ts +31 -4
  82. package/src/postgres/schema-management.ts +108 -16
  83. package/src/postgres/schema.ts +98 -15
  84. package/src/postgres/table.ts +203 -398
  85. package/src/postgres/type.ts +8 -7
  86. package/src/postgres.ts +9 -11
  87. package/src/sqlite/column-extension.ts +3 -0
  88. package/src/sqlite/column.ts +127 -0
  89. package/src/sqlite/datatypes/index.ts +80 -0
  90. package/src/sqlite/datatypes/spec.ts +98 -0
  91. package/src/sqlite/errors/catalog.ts +103 -0
  92. package/src/sqlite/errors/fields.ts +19 -0
  93. package/src/sqlite/errors/index.ts +19 -0
  94. package/src/sqlite/errors/normalize.ts +229 -0
  95. package/src/sqlite/errors/requirements.ts +71 -0
  96. package/src/sqlite/errors/types.ts +29 -0
  97. package/src/sqlite/executor.ts +229 -0
  98. package/src/sqlite/function/aggregate.ts +2 -0
  99. package/src/sqlite/function/core.ts +2 -0
  100. package/src/sqlite/function/index.ts +19 -0
  101. package/src/sqlite/function/string.ts +2 -0
  102. package/src/sqlite/function/temporal.ts +100 -0
  103. package/src/sqlite/function/window.ts +2 -0
  104. package/src/sqlite/internal/dialect.ts +42 -0
  105. package/src/sqlite/internal/dsl.ts +6979 -0
  106. package/src/sqlite/internal/renderer.ts +51 -0
  107. package/src/sqlite/json.ts +39 -0
  108. package/src/sqlite/query-extension.ts +2 -0
  109. package/src/sqlite/query.ts +196 -0
  110. package/src/sqlite/renderer.ts +51 -0
  111. package/src/sqlite.ts +14 -0
  112. package/src/standard/column.ts +163 -0
  113. package/src/standard/datatypes/index.ts +83 -0
  114. package/src/standard/datatypes/spec.ts +98 -0
  115. package/src/standard/dialect.ts +40 -0
  116. package/src/standard/function/aggregate.ts +2 -0
  117. package/src/standard/function/core.ts +2 -0
  118. package/src/standard/function/index.ts +18 -0
  119. package/src/standard/function/string.ts +2 -0
  120. package/src/standard/function/temporal.ts +78 -0
  121. package/src/standard/function/window.ts +2 -0
  122. package/src/standard/internal/renderer.ts +45 -0
  123. package/src/standard/query.ts +152 -0
  124. package/src/standard/renderer.ts +21 -0
  125. package/src/standard/table.ts +147 -0
  126. package/src/standard.ts +18 -0
  127. package/src/internal/aggregation-validation.ts +0 -57
  128. 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 pipeArguments2 } from "effect/Pipeable";
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
- const normalized = Array.isArray(columns) ? [...columns] : [columns];
181
- if (normalized.length === 0) {
182
- throw new Error("Table options require at least one column");
249
+ if (typeof columns === "string") {
250
+ return [columns];
183
251
  }
184
- return normalized;
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.filter((option) => option.kind === "primaryKey").map((option) => option.columns);
249
- if (explicit.length > 1) {
250
- throw new Error("Only one primary key declaration is allowed");
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 knownColumns = new Set(Object.keys(fields));
266
- for (const option of options) {
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
- for (const column of option.include ?? []) {
297
- if (!knownColumns.has(column)) {
298
- throw new Error(`Unknown included column '${column}' on table '${tableName}'`);
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 deriveSchemas = (tableName, fields, primaryKeyColumns) => {
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 variants = {};
389
+ const structFields = {};
350
390
  for (const [key, column] of Object.entries(fields)) {
351
- const config = {
352
- select: selectSchema(column, tableName, key),
353
- insert: undefined,
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
- if (update !== undefined) {
364
- config.update = update;
365
- } else {
366
- delete config.update;
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
- variants[key] = TableSchema.Field(config);
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 TypeId4 = Symbol.for("effect-qb/Table");
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 pipeArguments2(this, arguments);
452
+ return pipeArguments3(this, arguments);
387
453
  }
388
454
  };
389
- var attachPipe2 = (value) => {
455
+ var attachPipe3 = (value) => {
390
456
  Object.defineProperty(value, "pipe", {
391
457
  configurable: true,
392
458
  writable: true,
393
459
  value: function() {
394
- return pipeArguments2(value, arguments);
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 makeTable = (name, fields, declaredOptions, baseName = name, kind = "schema", schemaName, schemaMode = "default") => {
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 = attachPipe2(Object.create(TableProto));
555
+ const table = attachPipe3(Object.create(TableProto));
418
556
  table.name = name;
419
557
  table.columns = artifacts.columns;
420
- table.schemas = artifacts.schemas;
421
- table[TypeId4] = {
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
- if (dialects.length > 1) {
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 dialects[0];
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[TypeId4];
621
+ const state = self[TypeId6];
488
622
  const classOptions = self[options];
489
- validateClassOptions(extractDeclaredOptions(classOptions));
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[TypeId4].primaryKey
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[TypeId4];
505
- if (state.kind !== "schema") {
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
- const builder = (table) => appendOption(table, option);
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 make2(name, fields, schemaName) {
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 schema = (schemaName) => ({
521
- schemaName,
522
- table: (name, fields, ...options2) => applyDeclaredOptions(makeTable(name, fields, [], name, "schema", schemaName, "explicit"), options2)
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[TypeId4];
526
- const columns = Object.fromEntries(Object.entries(state.fields).map(([key, column]) => [key, bindColumn(aliasName, key, column, state.baseName, state.schemaName)]));
527
- const aliased = attachPipe2(Object.create(TableProto));
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.schemas = deriveSchemas(aliasName, state.fields, state.primaryKey);
531
- aliased[TypeId4] = {
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 ensureClassArtifacts(this).schemas;
703
+ return schemasFor(this);
572
704
  }
573
- static get [TypeId4]() {
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 pipeArguments2(this, arguments);
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()[TypeId4].baseName,
636
- schemaName: target()[TypeId4].schemaName,
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()[TypeId4].fields)
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/schema-expression.ts
648
- import { parse, toSql } from "pgsql-ast-parser";
649
- import { pipeArguments as pipeArguments3 } from "effect/Pipeable";
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 isSchemaExpression = (value) => typeof value === "object" && value !== null && (TypeId5 in value);
667
- var fromAst = (ast) => {
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
- var fromSql = (sql) => {
675
- const expression = attachPipe3(Object.create(SchemaExpressionProto));
676
- expression[TypeId5] = {
677
- sql: sql.trim()
678
- };
679
- return expression;
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 parseExpression = (sql) => fromAst(parse(sql, "expr"));
682
- var toAst = (expression) => {
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 render = (expression) => expression[TypeId5].sql ?? toSql.expr(toAst(expression));
690
- var normalize = (expression) => (() => {
691
- const sql = render(expression);
692
- try {
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 TypeId6 = Symbol.for("effect-qb/QueryAst");
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 sourceNameOfKey = (key) => key.split(".", 1)[0] ?? key;
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" ? `${ast.tableName}.${ast.columnName}` : undefined;
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[TypeId6] = ast;
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[TypeId6];
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
- const value = record[keys[0]];
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 TypeId7 = Symbol.for("effect-qb/JsonPath");
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
- [TypeId7]: {
1570
+ [TypeId8]: {
1461
1571
  segments
1462
1572
  },
1463
1573
  segments
1464
1574
  });
1465
1575
 
1466
- // src/internal/runtime/driver-value-mapping.ts
1467
- import * as Schema3 from "effect/Schema";
1468
-
1469
- // src/internal/runtime/normalize.ts
1470
- var isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
1471
- var pad = (value, width = 2) => value.toString().padStart(width, "0");
1472
- var formatLocalDate = (value) => `${value.getUTCFullYear()}-${pad(value.getUTCMonth() + 1)}-${pad(value.getUTCDate())}`;
1473
- var formatLocalTime = (value) => {
1474
- const milliseconds = value.getUTCMilliseconds();
1475
- const base = `${pad(value.getUTCHours())}:${pad(value.getUTCMinutes())}:${pad(value.getUTCSeconds())}`;
1476
- return milliseconds === 0 ? base : `${base}.${pad(milliseconds, 3)}`;
1477
- };
1478
- var formatLocalDateTime = (value) => {
1479
- const milliseconds = value.getUTCMilliseconds();
1480
- const base = `${formatLocalDate(value)}T${pad(value.getUTCHours())}:${pad(value.getUTCMinutes())}:${pad(value.getUTCSeconds())}`;
1481
- return milliseconds === 0 ? base : `${base}.${pad(milliseconds, 3)}`;
1482
- };
1483
- var runtimeTagOfBaseDbType = (dbType) => {
1484
- return dbType.runtime;
1485
- };
1486
- var expectString = (value, label) => {
1487
- if (typeof value === "string") {
1488
- return value;
1489
- }
1490
- throw new Error(`Expected ${label} as string`);
1491
- };
1492
- var normalizeNumber = (value) => {
1493
- if (typeof value === "number" && Number.isFinite(value)) {
1494
- return value;
1495
- }
1496
- if (typeof value === "string" && value.trim() !== "") {
1497
- const parsed = Number(value);
1498
- if (Number.isFinite(parsed)) {
1499
- return parsed;
1500
- }
1501
- }
1502
- if (typeof value === "bigint" && Number.isSafeInteger(Number(value))) {
1503
- return Number(value);
1504
- }
1505
- throw new Error("Expected a finite numeric value");
1506
- };
1507
- var normalizeBoolean = (value) => {
1508
- if (typeof value === "boolean") {
1509
- return value;
1510
- }
1511
- if (typeof value === "number") {
1512
- if (value === 1) {
1513
- return true;
1514
- }
1515
- if (value === 0) {
1516
- return false;
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
- if (typeof value === "string") {
1520
- const normalized = value.trim().toLowerCase();
1521
- if (normalized === "true" || normalized === "t" || normalized === "1") {
1522
- return true;
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 (normalized === "false" || normalized === "f" || normalized === "0") {
1525
- return false;
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
- throw new Error("Expected a boolean-like value");
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
- var normalizeBigIntString = (value) => {
1531
- if (typeof value === "bigint") {
1532
- return value.toString();
1893
+
1894
+ // src/internal/dsl-transaction-ddl-runtime.ts
1895
+ var renderTransactionIsolationLevel = (isolationLevel) => {
1896
+ if (isolationLevel === undefined) {
1897
+ return "";
1533
1898
  }
1534
- if (typeof value === "number" && Number.isSafeInteger(value)) {
1535
- return BigInt(value).toString();
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
- if (typeof value === "string" && /^-?\d+$/.test(value.trim())) {
1538
- return BigInt(value.trim()).toString();
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 (/^\d{4}-\d{2}-\d{2}$/.test(raw)) {
2705
+ if (isValidLocalDateString(raw)) {
1575
2706
  return raw;
1576
2707
  }
1577
- const parsed = new Date(raw);
1578
- if (!Number.isNaN(parsed.getTime())) {
1579
- return formatLocalDate(parsed);
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 (/^\d{2}:\d{2}:\d{2}(?:\.\d+)?$/.test(raw)) {
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 (/^\d{2}:\d{2}:\d{2}(?:\.\d+)?(?:Z|[+-]\d{2}:\d{2})$/.test(raw)) {
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
- if (/^\d{4}-\d{2}-\d{2}[ T]\d{2}:\d{2}:\d{2}(?:\.\d+)?$/.test(raw)) {
1609
- return raw.replace(" ", "T");
2742
+ const canonicalLocalDateTime = raw.replace(" ", "T");
2743
+ if (isValidLocalDateTimeString(canonicalLocalDateTime)) {
2744
+ return canonicalLocalDateTime;
1610
2745
  }
1611
- if (/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d+)?(?:Z|[+-]\d{2}:\d{2})$/.test(raw)) {
1612
- const parsed = new Date(raw);
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 parsed = new Date(raw);
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 isRecord(value) && Object.values(value).every(isJsonValue);
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
- const parsed = JSON.parse(value);
1674
- if (isJsonValue(parsed)) {
1675
- return parsed;
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 encodeWithSchema = (schema2, value) => {
1813
- if (schema2 === undefined) {
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 (!Schema3.is(schema2)(value)) {
2978
+ if (!Schema4.is(schema)(value)) {
1817
2979
  return { value, encoded: false };
1818
2980
  }
1819
2981
  return {
1820
- value: Schema3.encodeUnknownSync(schema2)(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 TypeId8 = Symbol.for("effect-qb/ProjectionAlias");
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) => (TypeId8 in expression) ? expression[TypeId8].alias : undefined;
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}.${ast.columnName}`;
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(${groupingKeyOfExpression(ast.value)} as ${ast.target.dialect}:${ast.target.kind})`;
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}(${groupingKeyOfExpression(ast.value)})`;
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
- return `${ast.kind}(${groupingKeyOfExpression(ast.left)},${groupingKeyOfExpression(ast.right)})`;
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.map(groupingKeyOfExpression).join(",")})`;
3288
+ return `${ast.kind}(${variadicGroupingKey(ast.kind, ast.values)})`;
1988
3289
  case "case":
1989
- return `case(${ast.branches.map((branch) => `when:${groupingKeyOfExpression(branch.when)}=>${groupingKeyOfExpression(branch.then)}`).join("|")};else:${groupingKeyOfExpression(ast.else)})`;
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
- throw new Error("Unsupported expression for grouping key generation");
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/aggregation-validation.ts
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 === "mysql" && dbType.dialect === "mysql" && dbType.kind === "uuid") {
2042
- return "char(36)";
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 dbType.kind;
3366
+ return renderDbTypeName(kind);
2049
3367
  }
2050
- switch (dbType.kind) {
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 dbType.kind;
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 renderDdlExpression = (expression, state, dialect) => isSchemaExpression(expression) ? render(expression) : renderExpression(expression, state, dialect);
2069
- var renderColumnDefinition = (dialect, state, columnName, column) => {
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
- dialect.quoteIdentifier(columnName),
2072
- column.metadata.ddlType ?? renderDbType(dialect, column.metadata.dbType)
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, state, dialect)}) stored`);
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, state, dialect)}`);
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 fields = table[TypeId4].fields;
2089
- const definitions = Object.entries(fields).map(([columnName, column]) => renderColumnDefinition(dialect, state, columnName, column));
2090
- for (const option2 of table[OptionsSymbol]) {
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
- definitions.push(`${option2.name ? `constraint ${dialect.quoteIdentifier(option2.name)} ` : ""}primary key (${option2.columns.map((column) => dialect.quoteIdentifier(column)).join(", ")})${option2.deferrable ? ` deferrable${option2.initiallyDeferred ? " initially deferred" : ""}` : ""}`);
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
- definitions.push(`${option2.name ? `constraint ${dialect.quoteIdentifier(option2.name)} ` : ""}unique${option2.nullsNotDistinct ? " nulls not distinct" : ""} (${option2.columns.map((column) => dialect.quoteIdentifier(column)).join(", ")})${option2.deferrable ? ` deferrable${option2.initiallyDeferred ? " initially deferred" : ""}` : ""}`);
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
- const reference = option2.references();
2100
- definitions.push(`${option2.name ? `constraint ${dialect.quoteIdentifier(option2.name)} ` : ""}foreign key (${option2.columns.map((column) => dialect.quoteIdentifier(column)).join(", ")}) references ${dialect.renderTableReference(reference.tableName, reference.tableName, reference.schemaName)} (${reference.columns.map((column) => dialect.quoteIdentifier(column)).join(", ")})${option2.onDelete ? ` on delete ${option2.onDelete.replace(/[A-Z]/g, (value) => ` ${value.toLowerCase()}`).trim()}` : ""}${option2.onUpdate ? ` on update ${option2.onUpdate.replace(/[A-Z]/g, (value) => ` ${value.toLowerCase()}`).trim()}` : ""}${option2.deferrable ? ` deferrable${option2.initiallyDeferred ? " initially deferred" : ""}` : ""}`);
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
- definitions.push(`constraint ${dialect.quoteIdentifier(option2.name)} check (${renderDdlExpression(option2.predicate, state, dialect)})${option2.noInherit ? " no inherit" : ""}`);
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${ifNotExists ? " if not exists" : ""} ${renderSourceReference(targetSource.source, targetSource.tableName, targetSource.baseTableName, state, dialect)} (${definitions.join(", ")})`;
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 maybeIfNotExists = dialect.name === "postgres" && ddl.ifNotExists ? " if not exists" : "";
2114
- return `create${ddl.unique ? " unique" : ""} index${maybeIfNotExists} ${dialect.quoteIdentifier(ddl.name)} on ${renderSourceReference(targetSource.source, targetSource.tableName, targetSource.baseTableName, state, dialect)} (${ddl.columns.map((column) => dialect.quoteIdentifier(column)).join(", ")})`;
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 isJsonDbType = (dbType) => dbType.kind === "jsonb" || dbType.kind === "json" || ("variant" in dbType) && dbType.variant === "json";
2119
- var isJsonExpression = (value) => isExpression3(value) && isJsonDbType(value[TypeId2].dbType);
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" && (TypeId7 in value);
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 /^[A-Za-z_][A-Za-z0-9_]*$/.test(segment) ? `.${segment}` : `."${segment.replace(/\\/g, "\\\\").replace(/"/g, "\\\"")}"`;
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 /^[A-Za-z_][A-Za-z0-9_]*$/.test(segment.key) ? `.${segment.key}` : `."${segment.key.replace(/\\/g, "\\\\").replace(/"/g, "\\\"")}"`;
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(String(segment.index), state)}`;
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 = renderExpression(value, state, dialect);
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(renderExpression(expression, state, dialect), expressionDriverContext(expression, state, dialect));
2237
- var encodeArrayValues = (values, column, state, dialect) => values.map((value) => toDriverValue(value, {
2238
- dialect: dialect.name,
2239
- valueMappings: state.valueMappings,
2240
- dbType: column.metadata.dbType,
2241
- runtimeSchema: column.schema,
2242
- driverValueMapping: column.metadata.driverValueMapping
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
- return renderExpression(value, state, dialect);
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
- if (name === "array") {
2259
- return `ARRAY[${args.map((arg) => renderExpression(arg, state, dialect)).join(", ")}]`;
2260
- }
2261
- if (name === "extract" && args.length === 2) {
2262
- const field = args[0];
2263
- const source = args[1];
2264
- if (field === undefined) {
2265
- throw new Error("Unsupported SQL extract expression");
2266
- }
2267
- if (source === undefined) {
2268
- throw new Error("Unsupported SQL extract expression");
2269
- }
2270
- const fieldRuntime = isExpression3(field) && field[TypeId2].dbType.kind === "text" && typeof field[TypeId2].runtime === "string" ? field[TypeId2].runtime : undefined;
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 name;
3877
+ return functionName;
2283
3878
  default:
2284
- return `${name}()`;
3879
+ return `${functionName}()`;
2285
3880
  }
2286
3881
  }
2287
- return `${name}(${renderedArgs})`;
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 = renderExpression(base, state, dialect);
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) : renderExpression(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[${keys.map((key2) => renderPostgresTextLiteral(String(key2), state, dialect)).join(", ")}])`;
3940
+ return `(${baseSql} ?| array[${keyNames.map((key2) => renderPostgresTextLiteral(key2, state, dialect)).join(", ")}])`;
2342
3941
  }
2343
3942
  if (kind === "jsonHasAllKeys") {
2344
- return `(${baseSql} ?& array[${keys.map((key2) => renderPostgresTextLiteral(String(key2), state, dialect)).join(", ")}])`;
3943
+ return `(${baseSql} ?& array[${keyNames.map((key2) => renderPostgresTextLiteral(key2, state, dialect)).join(", ")}])`;
2345
3944
  }
2346
- return `(${baseSql} ? ${renderPostgresTextLiteral(String(keys[0]), state, dialect)})`;
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 = keys.map((segment) => renderMySqlJsonPath([segment], state, dialect)).join(", ");
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(${renderExpression(ast.left, state, dialect)}, ${renderExpression(ast.right, state, dialect)})`;
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 = Array.isArray(ast.entries) ? ast.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 = Array.isArray(ast.values) ? ast.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(${renderExpression(base, state, dialect)} as json)`;
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(${renderExpression(base, state, dialect)} as json)`;
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 = renderExpression(base, state, dialect);
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(${renderExpression(base, state, dialect)})`;
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 = renderExpression(base, state, dialect);
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(${renderExpression(base, state, dialect)})`;
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 = renderExpression(base, state, dialect);
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(${renderExpression(base, state, dialect)})`;
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(${renderExpression(base, state, dialect)})`;
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(String(segment.index), state)})`;
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(${renderExpression(base, state, dialect)}, ${segments.map((segment) => renderMySqlJsonPath([segment], state, dialect)).join(", ")})`;
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}(${renderExpression(base, state, dialect)}, ${renderMySqlJsonPath(segments, state, dialect)}, ${renderExpression(nextValue, state, dialect)})`;
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(${renderExpression(base, state, dialect)}, ${dialect.renderLiteral("one", state)}, ${renderJsonOpaquePath(path2, state, dialect)})`;
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)}.${dialect.quoteIdentifier(entry.columnName)}` : dialect.quoteIdentifier(entry.columnName);
2544
- return `${column} = ${renderExpression(entry.value, state, dialect)}`;
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 ? [] : [renderExpression(join.on, state, dialect)]);
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
- if (clause.isolationLevel) {
2570
- modes.push(`isolation level ${clause.isolationLevel}`);
4168
+ const isolationLevel = renderTransactionIsolationLevel(clause.isolationLevel);
4169
+ if (isolationLevel) {
4170
+ modes.push(isolationLevel);
2571
4171
  }
2572
- if (clause.readOnly === true) {
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, validateAggregation) => {
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(renderExpression(expression, state, dialect), expressionDriverContext(expression, state, dialect))} as ${dialect.quoteIdentifier(alias2)}`).join(", ");
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 renderQueryAst = (ast, state, dialect) => {
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
- validateAggregationSelection(ast.select, ast.groupBy);
2608
- const rendered = renderSelectionList(ast.select, state, dialect, false);
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) => renderExpression(value, state, dialect)).join(", ")}) ${rendered.sql}` : `select${ast.distinct ? " distinct" : ""} ${rendered.sql}`
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 ${renderExpression(join.on, state, dialect)}`);
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) => renderExpression(entry.predicate, state, dialect)).join(" and ")}`);
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) => renderExpression(value, state, dialect)).join(", ")}`);
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) => renderExpression(entry.predicate, state, dialect)).join(" and ")}`);
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) => `${renderExpression(entry.value, state, dialect)} ${entry.direction}`).join(", ")}`);
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 ${renderExpression(ast.limit, state, dialect)}`);
4266
+ clauses.push(`limit ${renderExpression2(ast.limit, state, dialect)}`);
2634
4267
  }
2635
4268
  if (ast.offset) {
2636
- clauses.push(`offset ${renderExpression(ast.offset, state, dialect)}`);
4269
+ clauses.push(`offset ${renderExpression2(ast.offset, state, dialect)}`);
2637
4270
  }
2638
4271
  if (ast.lock) {
2639
- clauses.push(`${ast.lock.mode === "update" ? "for update" : "for share"}${ast.lock.nowait ? " nowait" : ""}${ast.lock.skipLocked ? " skip locked" : ""}`);
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 = renderQueryAst(getAst(setAst.setBase), state, dialect);
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 = renderQueryAst(getAst(entry.query), state, dialect);
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 (insertAst.insertSource?.kind === "values") {
2663
- const columns = insertAst.insertSource.columns.map((column) => dialect.quoteIdentifier(column)).join(", ");
2664
- const rows = insertAst.insertSource.rows.map((row) => `(${row.values.map((entry) => renderExpression(entry.value, state, dialect)).join(", ")})`).join(", ");
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 (insertAst.insertSource?.kind === "query") {
2667
- const columns = insertAst.insertSource.columns.map((column) => dialect.quoteIdentifier(column)).join(", ");
2668
- const renderedQuery = renderQueryAst(getAst(insertAst.insertSource.query), state, dialect);
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 (insertAst.insertSource?.kind === "unnest") {
2671
- const unnestSource = insertAst.insertSource;
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[TypeId4].fields;
2676
- const rendered = unnestSource.values.map((entry) => `cast(${dialect.renderLiteral(encodeArrayValues(entry.values, fields[entry.columnName], state, dialect), state)} as ${renderCastType(dialect, fields[entry.columnName].metadata.dbType)}[])`).join(", ");
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 = unnestSource.values[0]?.values.length ?? 0;
2680
- const rows = Array.from({ length: rowCount }, (_, index3) => `(${unnestSource.values.map((entry) => dialect.renderLiteral(entry.values[index3], state, targetSource.source[TypeId4].fields[entry.columnName][TypeId2])).join(", ")})`).join(", ");
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 columns = (insertAst.values ?? []).map((entry) => dialect.quoteIdentifier(entry.columnName)).join(", ");
2685
- const values = (insertAst.values ?? []).map((entry) => renderExpression(entry.value, state, dialect)).join(", ");
2686
- if ((insertAst.values ?? []).length > 0) {
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 (insertAst.conflict) {
2693
- const updateValues = (insertAst.conflict.values ?? []).map((entry) => `${dialect.quoteIdentifier(entry.columnName)} = ${renderExpression(entry.value, state, dialect)}`).join(", ");
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 = insertAst.conflict.target?.kind === "constraint" ? ` on conflict on constraint ${dialect.quoteIdentifier(insertAst.conflict.target.name)}` : insertAst.conflict.target?.kind === "columns" ? ` on conflict (${insertAst.conflict.target.columns.map((column) => dialect.quoteIdentifier(column)).join(", ")})${insertAst.conflict.target.where ? ` where ${renderExpression(insertAst.conflict.target.where, state, dialect)}` : ""}` : " on conflict";
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 += insertAst.conflict.action === "doNothing" ? " do nothing" : ` do update set ${updateValues}${insertAst.conflict.where ? ` where ${renderExpression(insertAst.conflict.where, state, dialect)}` : ""}`;
2698
- } else if (insertAst.conflict.action === "doNothing") {
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
- const returning = renderSelectionList(insertAst.select, state, dialect, false);
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
- const assignments = updateAst.set.map((entry) => renderMutationAssignment(entry, state, dialect)).join(", ");
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 ${renderExpression(join.on, state, dialect)}`).join(" ");
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) => renderExpression(entry.predicate, state, dialect))
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) => `${renderExpression(entry.value, state, dialect)} ${entry.direction}`).join(", ")}`;
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 ${renderExpression(updateAst.limit, state, dialect)}`;
4398
+ sql += ` limit ${renderExpression2(updateAst.limit, state, dialect)}`;
2749
4399
  }
2750
- const returning = renderSelectionList(updateAst.select, state, dialect, false);
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 ${renderExpression(join.on, state, dialect)}`).join(" ");
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) => renderExpression(entry.predicate, state, dialect))
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) => `${renderExpression(entry.value, state, dialect)} ${entry.direction}`).join(", ")}`;
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 ${renderExpression(deleteAst.limit, state, dialect)}`;
4440
+ sql += ` limit ${renderExpression2(deleteAst.limit, state, dialect)}`;
2787
4441
  }
2788
- const returning = renderSelectionList(deleteAst.select, state, dialect, false);
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 (truncateAst.truncate?.restartIdentity) {
4460
+ if (restartIdentity) {
2800
4461
  sql += " restart identity";
2801
4462
  }
2802
- if (truncateAst.truncate?.cascade) {
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 merge = mergeAst.merge;
2815
- sql = `merge into ${renderSourceReference(targetSource.source, targetSource.tableName, targetSource.baseTableName, state, dialect)} using ${renderSourceReference(usingSource.source, usingSource.tableName, usingSource.baseTableName, state, dialect)} on ${renderExpression(merge.on, state, dialect)}`;
2816
- if (merge.whenMatched) {
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 (merge.whenMatched.predicate) {
2819
- sql += ` and ${renderExpression(merge.whenMatched.predicate, state, dialect)}`;
4480
+ if (merge2.whenMatched.predicate) {
4481
+ sql += ` and ${renderExpression2(merge2.whenMatched.predicate, state, dialect)}`;
2820
4482
  }
2821
- if (merge.whenMatched.kind === "delete") {
4483
+ if (matchedKind === "delete") {
2822
4484
  sql += " then delete";
2823
4485
  } else {
2824
- sql += ` then update set ${merge.whenMatched.values.map((entry) => `${dialect.quoteIdentifier(entry.columnName)} = ${renderExpression(entry.value, state, dialect)}`).join(", ")}`;
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 (merge.whenNotMatched) {
4490
+ if (merge2.whenNotMatched) {
2828
4491
  sql += " when not matched";
2829
- if (merge.whenNotMatched.predicate) {
2830
- sql += ` and ${renderExpression(merge.whenNotMatched.predicate, state, dialect)}`;
4492
+ if (merge2.whenNotMatched.predicate) {
4493
+ sql += ` and ${renderExpression2(merge2.whenNotMatched.predicate, state, dialect)}`;
2831
4494
  }
2832
- sql += ` then insert (${merge.whenNotMatched.values.map((entry) => dialect.quoteIdentifier(entry.columnName)).join(", ")}) values (${merge.whenNotMatched.values.map((entry) => renderExpression(entry.value, state, dialect)).join(", ")})`;
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
- sql = renderCreateTableSql(createTableAst.target, state, dialect, createTableAst.ddl?.kind === "createTable" && createTableAst.ddl.ifNotExists);
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 ifExists = dropTableAst.ddl?.kind === "dropTable" && dropTableAst.ddl.ifExists;
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) => `${renderExpression(row[columnName], state, dialect)} as ${dialect.quoteIdentifier(columnName)}`).join(", ")}`);
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
- const rendered = renderQueryAst(getAst(cte.plan), state, dialect);
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 `(${renderQueryAst(getAst(derived.plan), state, dialect).sql}) as ${dialect.quoteIdentifier(derived.name)}`;
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
- return `lateral (${renderQueryAst(getAst(lateral.plan), state, dialect).sql}) as ${dialect.quoteIdentifier(lateral.name)}`;
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 `${tableFunction.functionName}(${tableFunction.args.map((arg) => renderExpression(arg, state, dialect)).join(", ")}) as ${dialect.quoteIdentifier(tableFunction.name)}(${columnNames.map((columnName) => dialect.quoteIdentifier(columnName)).join(", ")})`;
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
- const schemaName = typeof source === "object" && source !== null && TypeId4 in source ? source[TypeId4].schemaName : undefined;
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 renderExpression = (expression, state, dialect) => {
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) => operator === "eq" ? "=" : operator === "neq" ? "<>" : operator === "lt" ? "<" : operator === "lte" ? "<=" : operator === "gt" ? ">" : ">=";
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 ? dialect.quoteIdentifier(ast.columnName) : `${dialect.quoteIdentifier(ast.tableName)}.${dialect.quoteIdentifier(ast.columnName)}`;
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
- return dialect.name === "mysql" ? `values(${dialect.quoteIdentifier(ast.columnName)})` : `excluded.${dialect.quoteIdentifier(ast.columnName)}`;
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(${renderExpression(ast.value, state, dialect)} as ${renderCastType(dialect, ast.target)})`;
4657
+ return `cast(${renderExpression2(expectValueExpression("cast", ast.value), state, dialect)} as ${renderCastType(dialect, ast.target)})`;
2946
4658
  case "collate":
2947
- return `(${renderExpression(ast.value, state, dialect)} collate ${ast.collation.map((segment) => dialect.quoteIdentifier(segment)).join(".")})`;
4659
+ return `(${renderExpression2(expectValueExpression("collate", ast.value), state, dialect)} collate ${renderCollation(ast.collation)})`;
2948
4660
  case "function":
2949
- return renderFunctionCall(ast.name, Array.isArray(ast.args) ? ast.args : [], state, dialect);
4661
+ return renderFunctionCall(ast.name, ast.args, state, dialect);
2950
4662
  case "eq":
2951
- return `(${renderExpression(ast.left, state, dialect)} = ${renderExpression(ast.right, state, dialect)})`;
4663
+ return renderBinaryExpression("eq", "=", ast.left, ast.right, state, dialect);
2952
4664
  case "neq":
2953
- return `(${renderExpression(ast.left, state, dialect)} <> ${renderExpression(ast.right, state, dialect)})`;
4665
+ return renderBinaryExpression("neq", "<>", ast.left, ast.right, state, dialect);
2954
4666
  case "lt":
2955
- return `(${renderExpression(ast.left, state, dialect)} < ${renderExpression(ast.right, state, dialect)})`;
4667
+ return renderBinaryExpression("lt", "<", ast.left, ast.right, state, dialect);
2956
4668
  case "lte":
2957
- return `(${renderExpression(ast.left, state, dialect)} <= ${renderExpression(ast.right, state, dialect)})`;
4669
+ return renderBinaryExpression("lte", "<=", ast.left, ast.right, state, dialect);
2958
4670
  case "gt":
2959
- return `(${renderExpression(ast.left, state, dialect)} > ${renderExpression(ast.right, state, dialect)})`;
4671
+ return renderBinaryExpression("gt", ">", ast.left, ast.right, state, dialect);
2960
4672
  case "gte":
2961
- return `(${renderExpression(ast.left, state, dialect)} >= ${renderExpression(ast.right, state, dialect)})`;
4673
+ return renderBinaryExpression("gte", ">=", ast.left, ast.right, state, dialect);
2962
4674
  case "like":
2963
- return `(${renderExpression(ast.left, state, dialect)} like ${renderExpression(ast.right, state, dialect)})`;
2964
- case "ilike":
2965
- return dialect.name === "postgres" ? `(${renderExpression(ast.left, state, dialect)} ilike ${renderExpression(ast.right, state, dialect)})` : `(lower(${renderExpression(ast.left, state, dialect)}) like lower(${renderExpression(ast.right, state, dialect)}))`;
2966
- case "regexMatch":
2967
- return dialect.name === "postgres" ? `(${renderExpression(ast.left, state, dialect)} ~ ${renderExpression(ast.right, state, dialect)})` : `(${renderExpression(ast.left, state, dialect)} regexp ${renderExpression(ast.right, state, dialect)})`;
2968
- case "regexIMatch":
2969
- return dialect.name === "postgres" ? `(${renderExpression(ast.left, state, dialect)} ~* ${renderExpression(ast.right, state, dialect)})` : `(${renderExpression(ast.left, state, dialect)} regexp ${renderExpression(ast.right, state, dialect)})`;
2970
- case "regexNotMatch":
2971
- return dialect.name === "postgres" ? `(${renderExpression(ast.left, state, dialect)} !~ ${renderExpression(ast.right, state, dialect)})` : `(${renderExpression(ast.left, state, dialect)} not regexp ${renderExpression(ast.right, state, dialect)})`;
2972
- case "regexNotIMatch":
2973
- return dialect.name === "postgres" ? `(${renderExpression(ast.left, state, dialect)} !~* ${renderExpression(ast.right, state, dialect)})` : `(${renderExpression(ast.left, state, dialect)} not regexp ${renderExpression(ast.right, state, dialect)})`;
2974
- case "isDistinctFrom":
2975
- return dialect.name === "mysql" ? `(not (${renderExpression(ast.left, state, dialect)} <=> ${renderExpression(ast.right, state, dialect)}))` : `(${renderExpression(ast.left, state, dialect)} is distinct from ${renderExpression(ast.right, state, dialect)})`;
2976
- case "isNotDistinctFrom":
2977
- return dialect.name === "mysql" ? `(${renderExpression(ast.left, state, dialect)} <=> ${renderExpression(ast.right, state, dialect)})` : `(${renderExpression(ast.left, state, dialect)} is not distinct from ${renderExpression(ast.right, state, dialect)})`;
2978
- case "contains":
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
- const left = isJsonExpression(ast.left) ? renderPostgresJsonValue(ast.left, state, dialect) : renderExpression(ast.left, state, dialect);
2981
- const right = isJsonExpression(ast.right) ? renderPostgresJsonValue(ast.right, state, dialect) : renderExpression(ast.right, state, dialect);
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(ast.left) && isJsonExpression(ast.right)) {
2985
- return `json_contains(${renderExpression(ast.left, state, dialect)}, ${renderExpression(ast.right, state, dialect)})`;
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
- case "containedBy":
4728
+ }
4729
+ case "containedBy": {
4730
+ const [leftExpression, rightExpression] = expectBinaryExpressions("containedBy", ast.left, ast.right);
2989
4731
  if (dialect.name === "postgres") {
2990
- const left = isJsonExpression(ast.left) ? renderPostgresJsonValue(ast.left, state, dialect) : renderExpression(ast.left, state, dialect);
2991
- const right = isJsonExpression(ast.right) ? renderPostgresJsonValue(ast.right, state, dialect) : renderExpression(ast.right, state, dialect);
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(ast.left) && isJsonExpression(ast.right)) {
2995
- return `json_contains(${renderExpression(ast.right, state, dialect)}, ${renderExpression(ast.left, state, dialect)})`;
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
- case "overlaps":
4741
+ }
4742
+ case "overlaps": {
4743
+ const [leftExpression, rightExpression] = expectBinaryExpressions("overlaps", ast.left, ast.right);
2999
4744
  if (dialect.name === "postgres") {
3000
- const left = isJsonExpression(ast.left) ? renderPostgresJsonValue(ast.left, state, dialect) : renderExpression(ast.left, state, dialect);
3001
- const right = isJsonExpression(ast.right) ? renderPostgresJsonValue(ast.right, state, dialect) : renderExpression(ast.right, state, dialect);
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(ast.left) && isJsonExpression(ast.right)) {
3005
- return `json_overlaps(${renderExpression(ast.left, state, dialect)}, ${renderExpression(ast.right, state, dialect)})`;
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 `(${renderExpression(ast.value, state, dialect)} is null)`;
4756
+ return `(${renderExpression2(expectValueExpression("isNull", ast.value), state, dialect)} is null)`;
3010
4757
  case "isNotNull":
3011
- return `(${renderExpression(ast.value, state, dialect)} is not null)`;
4758
+ return `(${renderExpression2(expectValueExpression("isNotNull", ast.value), state, dialect)} is not null)`;
3012
4759
  case "not":
3013
- return `(not ${renderExpression(ast.value, state, dialect)})`;
4760
+ return `(not ${renderExpression2(expectValueExpression("not", ast.value), state, dialect)})`;
3014
4761
  case "upper":
3015
- return `upper(${renderExpression(ast.value, state, dialect)})`;
4762
+ return `upper(${renderExpression2(expectValueExpression("upper", ast.value), state, dialect)})`;
3016
4763
  case "lower":
3017
- return `lower(${renderExpression(ast.value, state, dialect)})`;
4764
+ return `lower(${renderExpression2(expectValueExpression("lower", ast.value), state, dialect)})`;
3018
4765
  case "count":
3019
- return `count(${renderExpression(ast.value, state, dialect)})`;
4766
+ return `count(${renderExpression2(expectValueExpression("count", ast.value), state, dialect)})`;
3020
4767
  case "max":
3021
- return `max(${renderExpression(ast.value, state, dialect)})`;
4768
+ return `max(${renderExpression2(expectValueExpression("max", ast.value), state, dialect)})`;
3022
4769
  case "min":
3023
- return `min(${renderExpression(ast.value, state, dialect)})`;
4770
+ return `min(${renderExpression2(expectValueExpression("min", ast.value), state, dialect)})`;
3024
4771
  case "and":
3025
- return `(${ast.values.map((value) => renderExpression(value, state, dialect)).join(" and ")})`;
4772
+ return `(${ast.values.map((value) => renderExpression2(value, state, dialect)).join(" and ")})`;
3026
4773
  case "or":
3027
- return `(${ast.values.map((value) => renderExpression(value, state, dialect)).join(" or ")})`;
4774
+ return `(${ast.values.map((value) => renderExpression2(value, state, dialect)).join(" or ")})`;
3028
4775
  case "coalesce":
3029
- return `coalesce(${ast.values.map((value) => renderExpression(value, state, dialect)).join(", ")})`;
4776
+ return `coalesce(${ast.values.map((value) => renderExpression2(value, state, dialect)).join(", ")})`;
3030
4777
  case "in":
3031
- return `(${renderExpression(ast.values[0], state, dialect)} in (${ast.values.slice(1).map((value) => renderExpression(value, state, dialect)).join(", ")}))`;
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 `(${renderExpression(ast.values[0], state, dialect)} not in (${ast.values.slice(1).map((value) => renderExpression(value, state, dialect)).join(", ")}))`;
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 `(${renderExpression(ast.values[0], state, dialect)} between ${renderExpression(ast.values[1], state, dialect)} and ${renderExpression(ast.values[2], state, dialect)})`;
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) => renderExpression(value, state, dialect)));
4784
+ return dialect.renderConcat(ast.values.map((value) => renderExpression2(value, state, dialect)));
3038
4785
  case "case":
3039
- return `case ${ast.branches.map((branch) => `when ${renderExpression(branch.when, state, dialect)} then ${renderExpression(branch.then, state, dialect)}`).join(" ")} else ${renderExpression(ast.else, state, dialect)} end`;
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 (${renderQueryAst(getAst(ast.plan), state, dialect).sql})`;
4788
+ return `exists (${renderSubqueryExpressionPlan(ast.plan, state, dialect)})`;
3042
4789
  case "scalarSubquery":
3043
- return `(${renderQueryAst(getAst(ast.plan), state, dialect).sql})`;
4790
+ return `(${renderSubqueryExpressionPlan(ast.plan, state, dialect)})`;
3044
4791
  case "inSubquery":
3045
- return `(${renderExpression(ast.left, state, dialect)} in (${renderQueryAst(getAst(ast.plan), state, dialect).sql}))`;
3046
- case "comparisonAny":
3047
- return `(${renderExpression(ast.left, state, dialect)} ${renderComparisonOperator(ast.operator)} any (${renderQueryAst(getAst(ast.plan), state, dialect).sql}))`;
3048
- case "comparisonAll":
3049
- return `(${renderExpression(ast.left, state, dialect)} ${renderComparisonOperator(ast.operator)} all (${renderQueryAst(getAst(ast.plan), state, dialect).sql}))`;
3050
- case "window": {
3051
- if (!Array.isArray(ast.partitionBy) || !Array.isArray(ast.orderBy) || typeof ast.function !== "string") {
3052
- break;
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 (ast.partitionBy.length > 0) {
3056
- clauses.push(`partition by ${ast.partitionBy.map((value) => renderExpression(value, state, dialect)).join(", ")}`);
4813
+ if (partitionBy.length > 0) {
4814
+ clauses.push(`partition by ${partitionBy.map((value) => renderExpression2(value, state, dialect)).join(", ")}`);
3057
4815
  }
3058
- if (ast.orderBy.length > 0) {
3059
- clauses.push(`order by ${ast.orderBy.map((entry) => `${renderExpression(entry.value, state, dialect)} ${entry.direction}`).join(", ")}`);
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 `${renderExpression(ast.value, state, dialect)} over (${specification})`;
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/postgres/internal/schema-ddl.ts
3079
- import { parse as parse2, toSql as toSql2 } from "pgsql-ast-parser";
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 quoteIdentifier = (value) => `"${value.replaceAll('"', '""')}"`;
3083
- var renderLiteral = (value, state, context = {}) => {
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 ? `${quoteIdentifier(schemaName)}.${quoteIdentifier(baseTableName)}` : quoteIdentifier(baseTableName);
3104
- return tableName === baseTableName ? renderedBase : `${renderedBase} as ${quoteIdentifier(tableName)}`;
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 renderDdlExpressionSql = (expression) => isSchemaExpression(expression) ? render(expression) : renderExpression(expression, {
4924
+ var makeExpressionState = (state = {}) => ({
4925
+ ...state,
3132
4926
  params: [],
3133
4927
  ctes: [],
3134
- cteNames: new Set
3135
- }, inlineLiteralDialect);
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 Schema4 from "effect/Schema";
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.qualifiedName(),
4999
+ kind: renderQualifiedTypeName(this.name, this.schemaName),
3200
5000
  variant: "enum"
3201
5001
  };
3202
5002
  },
3203
5003
  column() {
3204
- const values = this.values.map((value) => Schema4.Literal(value));
3205
- return makeColumnDefinition(values.length === 1 ? values[0] : Schema4.Union(...values), {
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.qualifiedName(),
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") && (TypeId4 in value);
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[TypeId4];
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: state.schemaName,
3285
- name: state.baseName,
5194
+ schemaName,
5195
+ name: tableName,
3286
5196
  columns,
3287
- options: table[OptionsSymbol],
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[TypeId4];
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(enumKey(value.schemaName, value.name), toEnumModel(value));
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 = enumKey(enumModel.schemaName, enumModel.name);
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 '${key2}'`);
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,