effect-qb 0.13.0 → 0.15.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 (146) hide show
  1. package/README.md +6 -1431
  2. package/dist/mysql.js +61945 -3611
  3. package/dist/postgres/metadata.js +2818 -0
  4. package/dist/postgres.js +9942 -5591
  5. package/package.json +21 -10
  6. package/src/internal/aggregation-validation.ts +3 -3
  7. package/src/internal/case-analysis.d.ts +18 -0
  8. package/src/internal/case-analysis.ts +4 -4
  9. package/src/internal/coercion/analysis.d.ts +7 -0
  10. package/src/internal/{coercion-analysis.ts → coercion/analysis.ts} +3 -3
  11. package/src/internal/coercion/errors.d.ts +17 -0
  12. package/src/internal/{coercion-errors.ts → coercion/errors.ts} +1 -1
  13. package/src/internal/coercion/kind.d.ts +4 -0
  14. package/src/internal/{coercion-kind.ts → coercion/kind.ts} +2 -2
  15. package/src/internal/{coercion-normalize.ts → coercion/normalize.ts} +1 -1
  16. package/src/internal/coercion/rules.d.ts +6 -0
  17. package/src/internal/{coercion-rules.ts → coercion/rules.ts} +2 -2
  18. package/src/internal/column-state.d.ts +190 -0
  19. package/src/internal/column-state.ts +119 -56
  20. package/src/internal/column.ts +387 -149
  21. package/src/internal/datatypes/define.d.ts +17 -0
  22. package/src/internal/datatypes/define.ts +18 -34
  23. package/src/internal/datatypes/lookup.d.ts +44 -0
  24. package/src/internal/datatypes/lookup.ts +61 -152
  25. package/src/internal/datatypes/shape.d.ts +16 -0
  26. package/src/internal/datatypes/shape.ts +1 -1
  27. package/src/internal/derived-table.d.ts +4 -0
  28. package/src/internal/derived-table.ts +21 -16
  29. package/src/internal/dsl-mutation-runtime.ts +378 -0
  30. package/src/internal/dsl-plan-runtime.ts +387 -0
  31. package/src/internal/dsl-query-runtime.ts +160 -0
  32. package/src/internal/dsl-transaction-ddl-runtime.ts +263 -0
  33. package/src/internal/executor.ts +173 -38
  34. package/src/internal/expression-ast.ts +19 -5
  35. package/src/internal/grouping-key.d.ts +3 -0
  36. package/src/internal/grouping-key.ts +1 -1
  37. package/src/internal/implication-runtime.d.ts +15 -0
  38. package/src/internal/implication-runtime.ts +171 -0
  39. package/src/internal/json/ast.d.ts +30 -0
  40. package/src/internal/json/ast.ts +1 -1
  41. package/src/internal/json/errors.d.ts +8 -0
  42. package/src/internal/json/path.d.ts +75 -0
  43. package/src/internal/json/path.ts +1 -1
  44. package/src/internal/json/types.d.ts +62 -0
  45. package/src/internal/predicate/analysis.d.ts +20 -0
  46. package/src/internal/{predicate-analysis.ts → predicate/analysis.ts} +13 -3
  47. package/src/internal/predicate/atom.d.ts +28 -0
  48. package/src/internal/{predicate-branches.ts → predicate/branches.ts} +2 -2
  49. package/src/internal/predicate/context.d.ts +67 -0
  50. package/src/internal/{predicate-context.ts → predicate/context.ts} +111 -32
  51. package/src/internal/predicate/formula.d.ts +35 -0
  52. package/src/internal/{predicate-formula.ts → predicate/formula.ts} +32 -20
  53. package/src/internal/predicate/key.d.ts +11 -0
  54. package/src/internal/{predicate-key.ts → predicate/key.ts} +2 -2
  55. package/src/internal/{predicate-nnf.ts → predicate/nnf.ts} +2 -2
  56. package/src/internal/predicate/normalize.d.ts +53 -0
  57. package/src/internal/predicate/normalize.ts +273 -0
  58. package/src/internal/predicate/runtime.d.ts +31 -0
  59. package/src/internal/predicate/runtime.ts +679 -0
  60. package/src/internal/projection-alias.d.ts +13 -0
  61. package/src/internal/projections.d.ts +31 -0
  62. package/src/internal/projections.ts +1 -1
  63. package/src/internal/query-ast.d.ts +217 -0
  64. package/src/internal/query-ast.ts +1 -1
  65. package/src/internal/query-requirements.d.ts +20 -0
  66. package/src/internal/query.d.ts +775 -0
  67. package/src/internal/query.ts +767 -275
  68. package/src/internal/renderer.ts +7 -21
  69. package/src/internal/row-set.d.ts +53 -0
  70. package/src/internal/{plan.ts → row-set.ts} +23 -11
  71. package/src/internal/{runtime-normalize.ts → runtime/normalize.ts} +9 -31
  72. package/src/internal/{runtime-schema.ts → runtime/schema.ts} +84 -55
  73. package/src/internal/runtime/value.d.ts +22 -0
  74. package/src/internal/{runtime-value.ts → runtime/value.ts} +2 -2
  75. package/src/internal/scalar.d.ts +107 -0
  76. package/src/internal/scalar.ts +191 -0
  77. package/src/internal/schema-derivation.d.ts +105 -0
  78. package/src/internal/schema-derivation.ts +93 -21
  79. package/src/internal/schema-expression.d.ts +18 -0
  80. package/src/internal/schema-expression.ts +75 -0
  81. package/src/internal/table-options.d.ts +94 -0
  82. package/src/internal/table-options.ts +94 -8
  83. package/src/internal/table.d.ts +173 -0
  84. package/src/internal/table.ts +135 -54
  85. package/src/mysql/column.ts +95 -18
  86. package/src/mysql/datatypes/index.ts +58 -3
  87. package/src/mysql/errors/generated.ts +57336 -0
  88. package/src/mysql/errors/index.ts +1 -0
  89. package/src/mysql/errors/normalize.ts +55 -53
  90. package/src/mysql/errors/types.ts +74 -0
  91. package/src/mysql/executor.ts +69 -7
  92. package/src/mysql/function/aggregate.ts +1 -5
  93. package/src/mysql/function/core.ts +1 -3
  94. package/src/mysql/function/index.ts +1 -1
  95. package/src/mysql/function/string.ts +1 -5
  96. package/src/mysql/function/temporal.ts +12 -15
  97. package/src/mysql/function/window.ts +1 -6
  98. package/src/{internal/mysql-dialect.ts → mysql/internal/dialect.ts} +1 -1
  99. package/src/mysql/internal/dsl.ts +6115 -0
  100. package/src/{internal/mysql-renderer.ts → mysql/internal/renderer.ts} +6 -6
  101. package/src/mysql/internal/sql-expression-renderer.ts +1455 -0
  102. package/src/mysql/json.ts +2 -0
  103. package/src/mysql/query.ts +111 -86
  104. package/src/mysql/renderer.ts +1 -1
  105. package/src/mysql/table.ts +1 -1
  106. package/src/mysql.ts +6 -4
  107. package/src/postgres/cast.ts +30 -0
  108. package/src/postgres/column.ts +178 -20
  109. package/src/postgres/datatypes/index.d.ts +515 -0
  110. package/src/postgres/datatypes/index.ts +49 -5
  111. package/src/postgres/datatypes/spec.d.ts +412 -0
  112. package/src/postgres/errors/generated.ts +2636 -0
  113. package/src/postgres/errors/index.ts +1 -0
  114. package/src/postgres/errors/normalize.ts +47 -62
  115. package/src/postgres/errors/types.ts +92 -34
  116. package/src/postgres/executor.ts +37 -5
  117. package/src/postgres/function/aggregate.ts +1 -5
  118. package/src/postgres/function/core.ts +20 -2
  119. package/src/postgres/function/index.ts +1 -1
  120. package/src/postgres/function/string.ts +1 -5
  121. package/src/postgres/function/temporal.ts +12 -15
  122. package/src/postgres/function/window.ts +1 -6
  123. package/src/{internal/postgres-dialect.ts → postgres/internal/dialect.ts} +1 -1
  124. package/src/{internal/query-factory.ts → postgres/internal/dsl.ts} +1568 -2120
  125. package/src/{internal/postgres-renderer.ts → postgres/internal/renderer.ts} +6 -6
  126. package/src/postgres/internal/schema-ddl.ts +108 -0
  127. package/src/postgres/internal/schema-model.ts +150 -0
  128. package/src/{internal → postgres/internal}/sql-expression-renderer.ts +112 -46
  129. package/src/postgres/json.ts +493 -0
  130. package/src/postgres/metadata.ts +31 -0
  131. package/src/postgres/query.ts +113 -86
  132. package/src/postgres/renderer.ts +3 -13
  133. package/src/postgres/schema-expression.ts +17 -0
  134. package/src/postgres/schema-management.ts +204 -0
  135. package/src/postgres/schema.ts +35 -0
  136. package/src/postgres/table.ts +316 -42
  137. package/src/postgres/type.ts +31 -0
  138. package/src/postgres.ts +20 -4
  139. package/CHANGELOG.md +0 -134
  140. package/src/internal/expression.ts +0 -327
  141. package/src/internal/predicate-normalize.ts +0 -202
  142. package/src/mysql/function/json.ts +0 -4
  143. package/src/mysql/private/query.ts +0 -13
  144. package/src/postgres/function/json.ts +0 -4
  145. package/src/postgres/private/query.ts +0 -13
  146. /package/src/internal/{predicate-atom.ts → predicate/atom.ts} +0 -0
@@ -0,0 +1,2818 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __export = (target, all) => {
3
+ for (var name in all)
4
+ __defProp(target, name, {
5
+ get: all[name],
6
+ enumerable: true,
7
+ configurable: true,
8
+ set: (newValue) => all[name] = () => newValue
9
+ });
10
+ };
11
+
12
+ // src/postgres/metadata.ts
13
+ var exports_metadata = {};
14
+ __export(exports_metadata, {
15
+ toTableModel: () => toTableModel,
16
+ toEnumModel: () => toEnumModel,
17
+ tableKey: () => tableKey,
18
+ renderDdlExpressionSql: () => renderDdlExpressionSql,
19
+ normalizeDdlExpressionSql: () => normalizeDdlExpressionSql,
20
+ isTableDefinition: () => isTableDefinition,
21
+ isEnumDefinition: () => isEnumDefinition,
22
+ fromDiscoveredValues: () => fromDiscoveredValues,
23
+ enumKey: () => enumKey,
24
+ EnumTypeId: () => EnumTypeId
25
+ });
26
+
27
+ // src/internal/table.ts
28
+ import { pipeArguments as pipeArguments2 } from "effect/Pipeable";
29
+
30
+ // src/internal/row-set.ts
31
+ var exports_row_set = {};
32
+ __export(exports_row_set, {
33
+ TypeId: () => TypeId
34
+ });
35
+ var TypeId = Symbol.for("effect-qb/Plan");
36
+
37
+ // src/internal/column-state.ts
38
+ import { pipeArguments } from "effect/Pipeable";
39
+ import * as Schema from "effect/Schema";
40
+
41
+ // src/internal/scalar.ts
42
+ var exports_scalar = {};
43
+ __export(exports_scalar, {
44
+ TypeId: () => TypeId2
45
+ });
46
+ var TypeId2 = Symbol.for("effect-qb/Expression");
47
+
48
+ // src/internal/expression-ast.ts
49
+ var TypeId3 = Symbol.for("effect-qb/ExpressionAst");
50
+
51
+ // src/internal/column-state.ts
52
+ var ColumnTypeId = Symbol.for("effect-qb/Column");
53
+ var BoundColumnTypeId = Symbol.for("effect-qb/BoundColumn");
54
+ var ColumnProto = {
55
+ pipe() {
56
+ return pipeArguments(this, arguments);
57
+ }
58
+ };
59
+ var attachPipe = (value) => {
60
+ Object.defineProperty(value, "pipe", {
61
+ configurable: true,
62
+ writable: true,
63
+ value: function() {
64
+ return pipeArguments(value, arguments);
65
+ }
66
+ });
67
+ return value;
68
+ };
69
+ var makeColumnDefinition = (schema, metadata) => {
70
+ const column = attachPipe(Object.create(ColumnProto));
71
+ column.schema = schema;
72
+ column.metadata = metadata;
73
+ column[TypeId2] = {
74
+ runtime: undefined,
75
+ dbType: metadata.dbType,
76
+ runtimeSchema: schema,
77
+ nullability: metadata.nullable ? "maybe" : "never",
78
+ dialect: metadata.dbType.dialect,
79
+ kind: "scalar",
80
+ dependencies: {}
81
+ };
82
+ column[ColumnTypeId] = {
83
+ select: undefined,
84
+ insert: undefined,
85
+ update: undefined,
86
+ dbType: metadata.dbType,
87
+ nullable: metadata.nullable,
88
+ hasDefault: metadata.hasDefault,
89
+ generated: metadata.generated,
90
+ primaryKey: metadata.primaryKey,
91
+ unique: metadata.unique,
92
+ references: metadata.references,
93
+ defaultValue: metadata.defaultValue,
94
+ generatedValue: metadata.generatedValue,
95
+ ddlType: metadata.ddlType,
96
+ identity: metadata.identity,
97
+ enum: metadata.enum
98
+ };
99
+ return column;
100
+ };
101
+ var remapColumnDefinition = (column, options = {}) => {
102
+ const schema = options.schema ?? column.schema;
103
+ const metadata = options.metadata ?? column.metadata;
104
+ const next = attachPipe(Object.create(ColumnProto));
105
+ next.schema = schema;
106
+ next.metadata = metadata;
107
+ next[TypeId2] = {
108
+ ...column[TypeId2],
109
+ runtime: undefined,
110
+ dbType: metadata.dbType,
111
+ runtimeSchema: schema,
112
+ nullability: metadata.nullable ? "maybe" : "never",
113
+ dialect: metadata.dbType.dialect
114
+ };
115
+ next[ColumnTypeId] = {
116
+ ...column[ColumnTypeId],
117
+ select: undefined,
118
+ insert: undefined,
119
+ update: undefined,
120
+ dbType: metadata.dbType,
121
+ nullable: metadata.nullable,
122
+ hasDefault: metadata.hasDefault,
123
+ generated: metadata.generated,
124
+ primaryKey: metadata.primaryKey,
125
+ unique: metadata.unique,
126
+ references: metadata.references,
127
+ defaultValue: metadata.defaultValue,
128
+ generatedValue: metadata.generatedValue,
129
+ ddlType: metadata.ddlType,
130
+ identity: metadata.identity,
131
+ enum: metadata.enum
132
+ };
133
+ if (TypeId3 in column) {
134
+ next[TypeId3] = column[TypeId3];
135
+ }
136
+ if (BoundColumnTypeId in column) {
137
+ next[BoundColumnTypeId] = column[BoundColumnTypeId];
138
+ }
139
+ return next;
140
+ };
141
+ var bindColumn = (tableName, columnName, column, baseTableName, schemaName) => {
142
+ const brandName = `${tableName}.${columnName}`;
143
+ const schema = column.metadata.brand === true ? Schema.brand(brandName)(column.schema) : column.schema;
144
+ const bound = attachPipe(Object.create(ColumnProto));
145
+ bound.schema = schema;
146
+ bound.metadata = column.metadata;
147
+ bound[TypeId2] = {
148
+ runtime: undefined,
149
+ dbType: column.metadata.dbType,
150
+ runtimeSchema: schema,
151
+ nullability: column.metadata.nullable ? "maybe" : "never",
152
+ dialect: column.metadata.dbType.dialect,
153
+ kind: "scalar",
154
+ dependencies: {
155
+ [tableName]: true
156
+ }
157
+ };
158
+ bound[TypeId3] = {
159
+ kind: "column",
160
+ tableName,
161
+ columnName
162
+ };
163
+ bound[ColumnTypeId] = column[ColumnTypeId];
164
+ bound[BoundColumnTypeId] = {
165
+ tableName,
166
+ columnName,
167
+ baseTableName,
168
+ schemaName
169
+ };
170
+ return bound;
171
+ };
172
+
173
+ // src/internal/table-options.ts
174
+ var normalizeColumnList = (columns) => {
175
+ const normalized = Array.isArray(columns) ? [...columns] : [columns];
176
+ if (normalized.length === 0) {
177
+ throw new Error("Table options require at least one column");
178
+ }
179
+ return normalized;
180
+ };
181
+ var collectInlineOptions = (fields) => {
182
+ const options = [];
183
+ for (const [columnName, column] of Object.entries(fields)) {
184
+ if (column.metadata.primaryKey) {
185
+ options.push({
186
+ kind: "primaryKey",
187
+ columns: [columnName]
188
+ });
189
+ }
190
+ if (column.metadata.unique && !column.metadata.primaryKey) {
191
+ options.push({
192
+ kind: "unique",
193
+ columns: [columnName],
194
+ name: column.metadata.uniqueConstraint?.name,
195
+ nullsNotDistinct: column.metadata.uniqueConstraint?.nullsNotDistinct,
196
+ deferrable: column.metadata.uniqueConstraint?.deferrable,
197
+ initiallyDeferred: column.metadata.uniqueConstraint?.initiallyDeferred
198
+ });
199
+ }
200
+ if (column.metadata.references) {
201
+ const local = [columnName];
202
+ options.push({
203
+ kind: "foreignKey",
204
+ columns: local,
205
+ references: () => {
206
+ const targetColumn = column.metadata.references.target();
207
+ const bound = targetColumn[BoundColumnTypeId];
208
+ return {
209
+ tableName: bound.baseTableName,
210
+ schemaName: bound.schemaName,
211
+ columns: [bound.columnName]
212
+ };
213
+ },
214
+ name: column.metadata.references.name,
215
+ onUpdate: column.metadata.references.onUpdate,
216
+ onDelete: column.metadata.references.onDelete,
217
+ deferrable: column.metadata.references.deferrable,
218
+ initiallyDeferred: column.metadata.references.initiallyDeferred
219
+ });
220
+ }
221
+ if (column.metadata.index) {
222
+ options.push({
223
+ kind: "index",
224
+ keys: [{
225
+ kind: "column",
226
+ column: columnName,
227
+ order: column.metadata.index.order,
228
+ nulls: column.metadata.index.nulls,
229
+ operatorClass: column.metadata.index.operatorClass,
230
+ collation: column.metadata.index.collation
231
+ }],
232
+ name: column.metadata.index.name,
233
+ method: column.metadata.index.method,
234
+ include: column.metadata.index.include,
235
+ predicate: column.metadata.index.predicate
236
+ });
237
+ }
238
+ }
239
+ return options;
240
+ };
241
+ var resolvePrimaryKeyColumns = (fields, declaredOptions) => {
242
+ const inline = Object.entries(fields).filter(([, column]) => column.metadata.primaryKey).map(([key]) => key);
243
+ const explicit = declaredOptions.filter((option) => option.kind === "primaryKey").map((option) => option.columns);
244
+ if (explicit.length > 1) {
245
+ throw new Error("Only one primary key declaration is allowed");
246
+ }
247
+ if (explicit.length === 0) {
248
+ return inline;
249
+ }
250
+ const tablePrimaryKey = [...explicit[0]];
251
+ if (inline.length > 0) {
252
+ const same = inline.length === tablePrimaryKey.length && inline.every((column) => tablePrimaryKey.includes(column));
253
+ if (!same) {
254
+ throw new Error("Inline primary keys conflict with table-level primary key declaration");
255
+ }
256
+ }
257
+ return tablePrimaryKey;
258
+ };
259
+ var validateOptions = (tableName, fields, options) => {
260
+ const knownColumns = new Set(Object.keys(fields));
261
+ for (const option of options) {
262
+ switch (option.kind) {
263
+ case "index":
264
+ case "primaryKey":
265
+ case "unique":
266
+ case "foreignKey": {
267
+ const columns = option.kind === "index" ? option.columns ?? [] : option.columns;
268
+ if (columns.length === 0 && option.kind !== "index") {
269
+ throw new Error(`Option '${option.kind}' on table '${tableName}' requires at least one column`);
270
+ }
271
+ for (const column of columns) {
272
+ if (!knownColumns.has(column)) {
273
+ throw new Error(`Unknown column '${column}' on table '${tableName}'`);
274
+ }
275
+ }
276
+ if (option.kind === "foreignKey") {
277
+ const reference = option.references();
278
+ if (reference.columns.length !== columns.length) {
279
+ throw new Error(`Foreign key on table '${tableName}' must reference the same number of columns`);
280
+ }
281
+ if (reference.knownColumns) {
282
+ const referenced = new Set(reference.knownColumns);
283
+ for (const column of reference.columns) {
284
+ if (!referenced.has(column)) {
285
+ throw new Error(`Unknown referenced column '${column}' on table '${reference.tableName}'`);
286
+ }
287
+ }
288
+ }
289
+ }
290
+ if (option.kind === "index") {
291
+ for (const column of option.include ?? []) {
292
+ if (!knownColumns.has(column)) {
293
+ throw new Error(`Unknown included column '${column}' on table '${tableName}'`);
294
+ }
295
+ }
296
+ for (const key of option.keys ?? []) {
297
+ if (key.kind === "column" && !knownColumns.has(key.column)) {
298
+ throw new Error(`Unknown index key column '${key.column}' on table '${tableName}'`);
299
+ }
300
+ }
301
+ if (option.columns === undefined && (option.keys === undefined || option.keys.length === 0)) {
302
+ throw new Error(`Index on table '${tableName}' requires at least one column or key`);
303
+ }
304
+ }
305
+ break;
306
+ }
307
+ case "check": {
308
+ break;
309
+ }
310
+ }
311
+ }
312
+ for (const column of resolvePrimaryKeyColumns(fields, options)) {
313
+ if (fields[column].metadata.nullable) {
314
+ throw new Error(`Primary key column '${String(column)}' cannot be nullable`);
315
+ }
316
+ }
317
+ };
318
+
319
+ // src/internal/schema-derivation.ts
320
+ import * as VariantSchema from "@effect/experimental/VariantSchema";
321
+ import * as Schema2 from "effect/Schema";
322
+ var TableSchema = VariantSchema.make({
323
+ variants: ["select", "insert", "update"],
324
+ defaultVariant: "select"
325
+ });
326
+ var maybeBrandSchema = (column, tableName, columnName) => column.metadata.brand === true ? Schema2.brand(`${tableName}.${columnName}`)(column.schema) : column.schema;
327
+ var selectSchema = (column, tableName, columnName) => column.metadata.nullable ? Schema2.NullOr(maybeBrandSchema(column, tableName, columnName)) : maybeBrandSchema(column, tableName, columnName);
328
+ var insertSchema = (column, tableName, columnName) => {
329
+ if (column.metadata.generated) {
330
+ return;
331
+ }
332
+ const base = column.metadata.nullable ? Schema2.NullOr(maybeBrandSchema(column, tableName, columnName)) : maybeBrandSchema(column, tableName, columnName);
333
+ return column.metadata.nullable || column.metadata.hasDefault ? Schema2.optional(base) : base;
334
+ };
335
+ var updateSchema = (column, tableName, columnName, isPrimaryKey) => {
336
+ if (column.metadata.generated || isPrimaryKey) {
337
+ return;
338
+ }
339
+ const base = column.metadata.nullable ? Schema2.NullOr(maybeBrandSchema(column, tableName, columnName)) : maybeBrandSchema(column, tableName, columnName);
340
+ return Schema2.optional(base);
341
+ };
342
+ var deriveSchemas = (tableName, fields, primaryKeyColumns) => {
343
+ const primaryKeySet = new Set(primaryKeyColumns);
344
+ const variants = {};
345
+ for (const [key, column] of Object.entries(fields)) {
346
+ const config = {
347
+ select: selectSchema(column, tableName, key),
348
+ insert: undefined,
349
+ update: undefined
350
+ };
351
+ const insert = insertSchema(column, tableName, key);
352
+ const update = updateSchema(column, tableName, key, primaryKeySet.has(key));
353
+ if (insert !== undefined) {
354
+ config.insert = insert;
355
+ } else {
356
+ delete config.insert;
357
+ }
358
+ if (update !== undefined) {
359
+ config.update = update;
360
+ } else {
361
+ delete config.update;
362
+ }
363
+ variants[key] = TableSchema.Field(config);
364
+ }
365
+ const struct = TableSchema.Struct(variants);
366
+ return {
367
+ select: TableSchema.extract(struct, "select"),
368
+ insert: TableSchema.extract(struct, "insert"),
369
+ update: TableSchema.extract(struct, "update")
370
+ };
371
+ };
372
+
373
+ // src/internal/table.ts
374
+ var TypeId4 = Symbol.for("effect-qb/Table");
375
+ var OptionsSymbol = Symbol.for("effect-qb/Table/normalizedOptions");
376
+ var options = Symbol.for("effect-qb/Table/declaredOptions");
377
+ var CacheSymbol = Symbol.for("effect-qb/Table/cache");
378
+ var DeclaredOptionsSymbol = Symbol.for("effect-qb/Table/factoryDeclaredOptions");
379
+ var TableProto = {
380
+ pipe() {
381
+ return pipeArguments2(this, arguments);
382
+ }
383
+ };
384
+ var attachPipe2 = (value) => {
385
+ Object.defineProperty(value, "pipe", {
386
+ configurable: true,
387
+ writable: true,
388
+ value: function() {
389
+ return pipeArguments2(value, arguments);
390
+ }
391
+ });
392
+ return value;
393
+ };
394
+ var buildArtifacts = (name, fields, declaredOptions, schemaName) => {
395
+ const normalizedOptions = [...collectInlineOptions(fields), ...declaredOptions];
396
+ validateFieldDialects(name, fields);
397
+ validateOptions(name, fields, declaredOptions);
398
+ const primaryKey = resolvePrimaryKeyColumns(fields, declaredOptions);
399
+ const columns = Object.fromEntries(Object.entries(fields).map(([key, column]) => [key, bindColumn(name, key, column, name, schemaName)]));
400
+ const schemas = deriveSchemas(name, fields, primaryKey);
401
+ return {
402
+ columns,
403
+ schemas,
404
+ normalizedOptions,
405
+ primaryKey
406
+ };
407
+ };
408
+ var makeTable = (name, fields, declaredOptions, baseName = name, kind = "schema", schemaName, schemaMode = "default") => {
409
+ const resolvedSchemaName = schemaMode === "explicit" ? schemaName : "public";
410
+ const artifacts = buildArtifacts(name, fields, declaredOptions, resolvedSchemaName);
411
+ const dialect = resolveFieldDialect(fields);
412
+ const table = attachPipe2(Object.create(TableProto));
413
+ table.name = name;
414
+ table.columns = artifacts.columns;
415
+ table.schemas = artifacts.schemas;
416
+ table[TypeId4] = {
417
+ name,
418
+ baseName,
419
+ schemaName: resolvedSchemaName,
420
+ fields,
421
+ primaryKey: artifacts.primaryKey,
422
+ kind
423
+ };
424
+ table[TypeId] = {
425
+ selection: artifacts.columns,
426
+ required: undefined,
427
+ available: {
428
+ [name]: {
429
+ name,
430
+ mode: "required",
431
+ baseName
432
+ }
433
+ },
434
+ dialect
435
+ };
436
+ table[OptionsSymbol] = artifacts.normalizedOptions;
437
+ table[DeclaredOptionsSymbol] = declaredOptions;
438
+ for (const [key, value] of Object.entries(artifacts.columns)) {
439
+ Object.defineProperty(table, key, {
440
+ enumerable: true,
441
+ value
442
+ });
443
+ }
444
+ return table;
445
+ };
446
+ var extractDeclaredOptions = (declaredOptions) => declaredOptions?.map((option) => option.option) ?? [];
447
+ var applyDeclaredOptions = (table, declaredOptions) => {
448
+ if (declaredOptions === undefined || declaredOptions.length === 0) {
449
+ return table;
450
+ }
451
+ return declaredOptions.reduce((current, option) => option(current), table);
452
+ };
453
+ var validateClassOptions = (declaredOptions) => {
454
+ for (const option of declaredOptions) {
455
+ if (option.kind === "primaryKey") {
456
+ throw new Error("Table.Class does not support table-level primary keys; declare primary keys inline on columns");
457
+ }
458
+ }
459
+ };
460
+ var resolveFieldDialect = (fields) => {
461
+ const dialects = [...new Set(Object.values(fields).map((field) => field.metadata.dbType.dialect))];
462
+ if (dialects.length === 0) {
463
+ throw new Error("Cannot infer table dialect from an empty field set");
464
+ }
465
+ if (dialects.length > 1) {
466
+ throw new Error(`Mixed table dialects are not supported: ${dialects.join(", ")}`);
467
+ }
468
+ return dialects[0];
469
+ };
470
+ var validateFieldDialects = (tableName, fields) => {
471
+ try {
472
+ resolveFieldDialect(fields);
473
+ } catch (error) {
474
+ throw new Error(`Invalid dialects for table '${tableName}': ${error.message}`);
475
+ }
476
+ };
477
+ var ensureClassArtifacts = (self) => {
478
+ const cached = self[CacheSymbol];
479
+ if (cached) {
480
+ return cached;
481
+ }
482
+ const state = self[TypeId4];
483
+ const classOptions = self[options];
484
+ validateClassOptions(extractDeclaredOptions(classOptions));
485
+ const table = applyDeclaredOptions(makeTable(state.name, state.fields, [], state.name, "schema", state.schemaName, state.schemaName === undefined || state.schemaName === "public" ? "default" : "explicit"), classOptions);
486
+ const artifacts = {
487
+ columns: table.columns,
488
+ schemas: table.schemas,
489
+ normalizedOptions: table[OptionsSymbol],
490
+ primaryKey: table[TypeId4].primaryKey
491
+ };
492
+ Object.defineProperty(self, CacheSymbol, {
493
+ configurable: true,
494
+ value: artifacts
495
+ });
496
+ return artifacts;
497
+ };
498
+ var appendOption = (table, option) => {
499
+ const state = table[TypeId4];
500
+ if (state.kind !== "schema") {
501
+ throw new Error("Table options can only be applied to schema tables, not aliased query sources");
502
+ }
503
+ return makeTable(state.name, state.fields, [...table[DeclaredOptionsSymbol], option], state.baseName, state.kind, state.schemaName, "explicit");
504
+ };
505
+ var makeOption = (option) => {
506
+ const builder = (table) => appendOption(table, option);
507
+ builder.option = option;
508
+ return builder;
509
+ };
510
+ var option = (spec) => makeOption(spec);
511
+ function make2(name, fields, schemaName) {
512
+ const resolvedSchemaName = arguments.length >= 3 ? schemaName : "public";
513
+ return makeTable(name, fields, [], name, "schema", resolvedSchemaName, arguments.length >= 3 ? "explicit" : "default");
514
+ }
515
+ var schema = (schemaName) => ({
516
+ schemaName,
517
+ table: (name, fields, ...options2) => applyDeclaredOptions(makeTable(name, fields, [], name, "schema", schemaName, "explicit"), options2)
518
+ });
519
+ var alias = (table, aliasName) => {
520
+ const state = table[TypeId4];
521
+ const columns = Object.fromEntries(Object.entries(state.fields).map(([key, column]) => [key, bindColumn(aliasName, key, column, state.baseName, state.schemaName)]));
522
+ const aliased = attachPipe2(Object.create(TableProto));
523
+ aliased.name = aliasName;
524
+ aliased.columns = columns;
525
+ aliased.schemas = deriveSchemas(aliasName, state.fields, state.primaryKey);
526
+ aliased[TypeId4] = {
527
+ name: aliasName,
528
+ baseName: state.baseName,
529
+ schemaName: state.schemaName,
530
+ fields: state.fields,
531
+ primaryKey: state.primaryKey,
532
+ kind: "alias"
533
+ };
534
+ aliased[TypeId] = {
535
+ selection: columns,
536
+ required: undefined,
537
+ available: {
538
+ [aliasName]: {
539
+ name: aliasName,
540
+ mode: "required",
541
+ baseName: state.baseName
542
+ }
543
+ },
544
+ dialect: table[TypeId].dialect
545
+ };
546
+ aliased[OptionsSymbol] = table[OptionsSymbol];
547
+ aliased[DeclaredOptionsSymbol] = table[DeclaredOptionsSymbol];
548
+ for (const [key, value] of Object.entries(columns)) {
549
+ Object.defineProperty(aliased, key, {
550
+ enumerable: true,
551
+ value
552
+ });
553
+ }
554
+ return aliased;
555
+ };
556
+ function Class(name, schemaName) {
557
+ const resolvedSchemaName = arguments.length >= 2 ? schemaName : "public";
558
+ return (fields) => {
559
+
560
+ class TableClassBase {
561
+ static tableName = name;
562
+ static get columns() {
563
+ return ensureClassArtifacts(this).columns;
564
+ }
565
+ static get schemas() {
566
+ return ensureClassArtifacts(this).schemas;
567
+ }
568
+ static get [TypeId4]() {
569
+ const declaredOptions = extractDeclaredOptions(this[options]);
570
+ validateClassOptions(declaredOptions);
571
+ return {
572
+ name,
573
+ baseName: name,
574
+ schemaName: resolvedSchemaName,
575
+ fields,
576
+ primaryKey: resolvePrimaryKeyColumns(fields, collectInlineOptions(fields)),
577
+ kind: "schema"
578
+ };
579
+ }
580
+ static get [TypeId]() {
581
+ const artifacts = ensureClassArtifacts(this);
582
+ return {
583
+ selection: artifacts.columns,
584
+ required: undefined,
585
+ available: {
586
+ [name]: {
587
+ name,
588
+ mode: "required",
589
+ baseName: name
590
+ }
591
+ },
592
+ dialect: resolveFieldDialect(fields)
593
+ };
594
+ }
595
+ static get [OptionsSymbol]() {
596
+ return ensureClassArtifacts(this).normalizedOptions;
597
+ }
598
+ static pipe() {
599
+ return pipeArguments2(this, arguments);
600
+ }
601
+ }
602
+ for (const key of Object.keys(fields)) {
603
+ Object.defineProperty(TableClassBase, key, {
604
+ enumerable: true,
605
+ configurable: true,
606
+ get() {
607
+ return ensureClassArtifacts(this).columns[key];
608
+ }
609
+ });
610
+ }
611
+ return TableClassBase;
612
+ };
613
+ }
614
+ var primaryKey = (columns) => makeOption({
615
+ kind: "primaryKey",
616
+ columns: normalizeColumnList(columns)
617
+ });
618
+ var unique = (columns) => makeOption({
619
+ kind: "unique",
620
+ columns: normalizeColumnList(columns)
621
+ });
622
+ var index = (columns) => makeOption({
623
+ kind: "index",
624
+ columns: normalizeColumnList(columns)
625
+ });
626
+ var foreignKey = (columns, target, referencedColumns) => makeOption({
627
+ kind: "foreignKey",
628
+ columns: normalizeColumnList(columns),
629
+ references: () => ({
630
+ tableName: target()[TypeId4].baseName,
631
+ schemaName: target()[TypeId4].schemaName,
632
+ columns: normalizeColumnList(referencedColumns),
633
+ knownColumns: Object.keys(target()[TypeId4].fields)
634
+ })
635
+ });
636
+ var check = (name, predicate) => makeOption({
637
+ kind: "check",
638
+ name,
639
+ predicate
640
+ });
641
+
642
+ // src/internal/schema-expression.ts
643
+ import { parse, toSql } from "pgsql-ast-parser";
644
+ import { pipeArguments as pipeArguments3 } from "effect/Pipeable";
645
+ var TypeId5 = Symbol.for("effect-qb/SchemaExpression");
646
+ var SchemaExpressionProto = {
647
+ pipe() {
648
+ return pipeArguments3(this, arguments);
649
+ }
650
+ };
651
+ var attachPipe3 = (value) => {
652
+ Object.defineProperty(value, "pipe", {
653
+ configurable: true,
654
+ writable: true,
655
+ value: function() {
656
+ return pipeArguments3(value, arguments);
657
+ }
658
+ });
659
+ return value;
660
+ };
661
+ var isSchemaExpression = (value) => typeof value === "object" && value !== null && (TypeId5 in value);
662
+ var fromAst = (ast) => {
663
+ const expression = attachPipe3(Object.create(SchemaExpressionProto));
664
+ expression[TypeId5] = {
665
+ ast
666
+ };
667
+ return expression;
668
+ };
669
+ var fromSql = (sql) => {
670
+ const expression = attachPipe3(Object.create(SchemaExpressionProto));
671
+ expression[TypeId5] = {
672
+ sql: sql.trim()
673
+ };
674
+ return expression;
675
+ };
676
+ var parseExpression = (sql) => fromAst(parse(sql, "expr"));
677
+ var toAst = (expression) => {
678
+ const ast = expression[TypeId5].ast;
679
+ if (ast !== undefined) {
680
+ return ast;
681
+ }
682
+ return parse(render(expression), "expr");
683
+ };
684
+ var render = (expression) => expression[TypeId5].sql ?? toSql.expr(toAst(expression));
685
+ var normalize = (expression) => (() => {
686
+ const sql = render(expression);
687
+ try {
688
+ return parseExpression(sql);
689
+ } catch {
690
+ return fromSql(sql);
691
+ }
692
+ })();
693
+
694
+ // src/internal/query.ts
695
+ import { pipeArguments as pipeArguments4 } from "effect/Pipeable";
696
+
697
+ // src/internal/query-ast.ts
698
+ var TypeId6 = Symbol.for("effect-qb/QueryAst");
699
+
700
+ // src/internal/predicate/runtime.ts
701
+ var trueFormula = () => ({ kind: "true" });
702
+ var falseFormula = () => ({ kind: "false" });
703
+ var atomFormula = (atom) => ({ kind: "atom", atom });
704
+ var allFormula = (items) => normalizeFormula({ kind: "all", items });
705
+ var anyFormula = (items) => normalizeFormula({ kind: "any", items });
706
+ var notFormula = (item) => normalizeFormula({ kind: "not", item });
707
+ var andFormula = (left, right) => allFormula([left, right]);
708
+ var unknownTag = (tag) => atomFormula({ kind: "unknown", tag });
709
+ var emptyContext = () => ({
710
+ nonNullKeys: new Set,
711
+ nullKeys: new Set,
712
+ eqLiterals: new Map,
713
+ neqLiterals: new Map,
714
+ sourceNames: new Set,
715
+ contradiction: false,
716
+ unknown: false
717
+ });
718
+ var cloneContext = (context) => ({
719
+ nonNullKeys: new Set(context.nonNullKeys),
720
+ nullKeys: new Set(context.nullKeys),
721
+ eqLiterals: new Map(context.eqLiterals),
722
+ neqLiterals: new Map(Array.from(context.neqLiterals.entries(), ([key, values]) => [key, new Set(values)])),
723
+ sourceNames: new Set(context.sourceNames),
724
+ contradiction: context.contradiction,
725
+ unknown: context.unknown
726
+ });
727
+ var freezeContext = (context) => context;
728
+ var sourceNameOfKey = (key) => key.split(".", 1)[0] ?? key;
729
+ var addSourceName = (context, key) => {
730
+ context.sourceNames.add(sourceNameOfKey(key));
731
+ };
732
+ var addNonNull = (context, key) => {
733
+ addSourceName(context, key);
734
+ if (context.nullKeys.has(key)) {
735
+ context.contradiction = true;
736
+ }
737
+ context.nonNullKeys.add(key);
738
+ };
739
+ var addNull = (context, key) => {
740
+ addSourceName(context, key);
741
+ if (context.nonNullKeys.has(key)) {
742
+ context.contradiction = true;
743
+ }
744
+ context.nullKeys.add(key);
745
+ };
746
+ var addEqLiteral = (context, key, value) => {
747
+ addNonNull(context, key);
748
+ const existing = context.eqLiterals.get(key);
749
+ if (existing !== undefined && existing !== value) {
750
+ context.contradiction = true;
751
+ }
752
+ const neqValues = context.neqLiterals.get(key);
753
+ if (neqValues?.has(value)) {
754
+ context.contradiction = true;
755
+ }
756
+ context.eqLiterals.set(key, value);
757
+ };
758
+ var addNeqLiteral = (context, key, value) => {
759
+ addNonNull(context, key);
760
+ if (context.eqLiterals.get(key) === value) {
761
+ context.contradiction = true;
762
+ }
763
+ const values = context.neqLiterals.get(key) ?? new Set;
764
+ values.add(value);
765
+ context.neqLiterals.set(key, values);
766
+ };
767
+ var applyEqColumn = (context, left, right) => {
768
+ const leftValue = context.eqLiterals.get(left);
769
+ const rightValue = context.eqLiterals.get(right);
770
+ if (leftValue === undefined && rightValue === undefined) {
771
+ addNonNull(context, left);
772
+ addNonNull(context, right);
773
+ return;
774
+ }
775
+ if (leftValue === undefined && rightValue !== undefined) {
776
+ addNonNull(context, left);
777
+ addEqLiteral(context, left, rightValue);
778
+ return;
779
+ }
780
+ if (leftValue !== undefined && rightValue === undefined) {
781
+ addNonNull(context, right);
782
+ addEqLiteral(context, right, leftValue);
783
+ return;
784
+ }
785
+ if (leftValue === rightValue) {
786
+ addEqLiteral(context, left, leftValue);
787
+ addEqLiteral(context, right, rightValue);
788
+ return;
789
+ }
790
+ context.contradiction = true;
791
+ };
792
+ var applyAtom = (context, atom) => {
793
+ switch (atom.kind) {
794
+ case "is-null":
795
+ addNull(context, atom.key);
796
+ return;
797
+ case "is-not-null":
798
+ addNonNull(context, atom.key);
799
+ return;
800
+ case "eq-literal":
801
+ addEqLiteral(context, atom.key, atom.value);
802
+ return;
803
+ case "neq-literal":
804
+ addNeqLiteral(context, atom.key, atom.value);
805
+ return;
806
+ case "eq-column":
807
+ applyEqColumn(context, atom.left, atom.right);
808
+ return;
809
+ case "unknown":
810
+ context.unknown = true;
811
+ return;
812
+ }
813
+ };
814
+ var applyNegativeAtom = (context, atom) => {
815
+ switch (atom.kind) {
816
+ case "is-null":
817
+ addNonNull(context, atom.key);
818
+ return;
819
+ case "is-not-null":
820
+ addNull(context, atom.key);
821
+ return;
822
+ case "eq-literal":
823
+ addNeqLiteral(context, atom.key, atom.value);
824
+ return;
825
+ case "neq-literal":
826
+ addEqLiteral(context, atom.key, atom.value);
827
+ return;
828
+ case "eq-column":
829
+ addNonNull(context, atom.left);
830
+ addNonNull(context, atom.right);
831
+ return;
832
+ case "unknown":
833
+ context.unknown = true;
834
+ return;
835
+ }
836
+ };
837
+ var intersectEqLiterals = (left, right) => {
838
+ const result = new Map;
839
+ for (const [key, value] of left) {
840
+ if (right.get(key) === value) {
841
+ result.set(key, value);
842
+ }
843
+ }
844
+ return result;
845
+ };
846
+ var intersectNeqLiterals = (left, right) => {
847
+ const result = new Map;
848
+ for (const [key, leftValues] of left) {
849
+ const rightValues = right.get(key);
850
+ if (rightValues === undefined) {
851
+ continue;
852
+ }
853
+ const next = new Set(Array.from(leftValues).filter((value) => rightValues.has(value)));
854
+ if (next.size > 0) {
855
+ result.set(key, next);
856
+ }
857
+ }
858
+ return result;
859
+ };
860
+ var intersectContexts = (left, right) => {
861
+ if (left.contradiction) {
862
+ return cloneContext(right);
863
+ }
864
+ if (right.contradiction) {
865
+ return cloneContext(left);
866
+ }
867
+ return {
868
+ nonNullKeys: new Set(Array.from(left.nonNullKeys).filter((key) => right.nonNullKeys.has(key))),
869
+ nullKeys: new Set(Array.from(left.nullKeys).filter((key) => right.nullKeys.has(key))),
870
+ eqLiterals: intersectEqLiterals(left.eqLiterals, right.eqLiterals),
871
+ neqLiterals: intersectNeqLiterals(left.neqLiterals, right.neqLiterals),
872
+ sourceNames: new Set(Array.from(left.sourceNames).filter((name) => right.sourceNames.has(name))),
873
+ contradiction: false,
874
+ unknown: left.unknown || right.unknown
875
+ };
876
+ };
877
+ var analyzeBranchSet = (context, items, polarity) => {
878
+ let current;
879
+ for (const item of items) {
880
+ const branch = analyzeStack(cloneContext(context), [{ formula: item, polarity }]);
881
+ if (branch.contradiction) {
882
+ continue;
883
+ }
884
+ current = current === undefined ? branch : intersectContexts(current, branch);
885
+ }
886
+ if (current === undefined) {
887
+ const next = cloneContext(context);
888
+ next.contradiction = true;
889
+ return next;
890
+ }
891
+ return current;
892
+ };
893
+ var analyzeStack = (context, stack) => {
894
+ const queue = [...stack];
895
+ while (queue.length > 0 && !context.contradiction) {
896
+ const frame = queue.shift();
897
+ switch (frame.formula.kind) {
898
+ case "true":
899
+ if (frame.polarity === "negative") {
900
+ context.contradiction = true;
901
+ }
902
+ break;
903
+ case "false":
904
+ if (frame.polarity === "positive") {
905
+ context.contradiction = true;
906
+ }
907
+ break;
908
+ case "atom":
909
+ if (frame.polarity === "positive") {
910
+ applyAtom(context, frame.formula.atom);
911
+ } else {
912
+ applyNegativeAtom(context, frame.formula.atom);
913
+ }
914
+ break;
915
+ case "not":
916
+ queue.unshift({
917
+ formula: frame.formula.item,
918
+ polarity: frame.polarity === "positive" ? "negative" : "positive"
919
+ });
920
+ break;
921
+ case "all":
922
+ if (frame.polarity === "positive") {
923
+ queue.unshift(...frame.formula.items.map((formula) => ({ formula, polarity: "positive" })));
924
+ } else {
925
+ context = analyzeBranchSet(context, frame.formula.items, "negative");
926
+ }
927
+ break;
928
+ case "any":
929
+ if (frame.polarity === "positive") {
930
+ context = analyzeBranchSet(context, frame.formula.items, "positive");
931
+ } else {
932
+ queue.unshift(...frame.formula.items.map((formula) => ({ formula, polarity: "negative" })));
933
+ }
934
+ break;
935
+ }
936
+ }
937
+ return context;
938
+ };
939
+ var analyzeFormula = (formula) => freezeContext(analyzeStack(emptyContext(), [{ formula, polarity: "positive" }]));
940
+ var astOf = (value) => value[TypeId3];
941
+ var columnKeyOfExpression = (value) => {
942
+ const ast = astOf(value);
943
+ return ast.kind === "column" ? `${ast.tableName}.${ast.columnName}` : undefined;
944
+ };
945
+ var valueKeyOfLiteral = (value) => {
946
+ if (typeof value === "string") {
947
+ return `string:${value}`;
948
+ }
949
+ if (typeof value === "number") {
950
+ return `number:${value}`;
951
+ }
952
+ if (typeof value === "boolean") {
953
+ return `boolean:${value}`;
954
+ }
955
+ if (value === null) {
956
+ return "null";
957
+ }
958
+ if (value instanceof Date) {
959
+ return `date:${value.toISOString()}`;
960
+ }
961
+ return "unknown";
962
+ };
963
+ var nonNullFactsOfExpression = (value) => {
964
+ const key = columnKeyOfExpression(value);
965
+ return key === undefined ? undefined : atomFormula({ kind: "is-not-null", key });
966
+ };
967
+ var combineFacts = (left, right) => {
968
+ if (left === undefined) {
969
+ return right ?? trueFormula();
970
+ }
971
+ if (right === undefined) {
972
+ return left;
973
+ }
974
+ return andFormula(left, right);
975
+ };
976
+ var formulaOfEq = (left, right) => {
977
+ const leftKey = columnKeyOfExpression(left);
978
+ const rightKey = columnKeyOfExpression(right);
979
+ const leftAst = astOf(left);
980
+ const rightAst = astOf(right);
981
+ const leftLiteral = leftAst.kind === "literal" ? leftAst.value : undefined;
982
+ const rightLiteral = rightAst.kind === "literal" ? rightAst.value : undefined;
983
+ if (leftKey === undefined && rightKey === undefined) {
984
+ if (leftAst.kind !== "literal" || rightAst.kind !== "literal") {
985
+ return unknownTag("eq:unsupported");
986
+ }
987
+ if (leftLiteral === null || rightLiteral === null) {
988
+ return falseFormula();
989
+ }
990
+ return Object.is(leftLiteral, rightLiteral) ? trueFormula() : falseFormula();
991
+ }
992
+ if (leftKey === undefined) {
993
+ if (leftAst.kind !== "literal") {
994
+ return unknownTag("eq:unsupported");
995
+ }
996
+ if (leftLiteral === null) {
997
+ return falseFormula();
998
+ }
999
+ return atomFormula({
1000
+ kind: "eq-literal",
1001
+ key: rightKey,
1002
+ value: valueKeyOfLiteral(leftLiteral)
1003
+ });
1004
+ }
1005
+ if (rightKey === undefined) {
1006
+ if (rightAst.kind !== "literal") {
1007
+ return unknownTag("eq:unsupported");
1008
+ }
1009
+ if (rightLiteral === null) {
1010
+ return falseFormula();
1011
+ }
1012
+ return atomFormula({
1013
+ kind: "eq-literal",
1014
+ key: leftKey,
1015
+ value: valueKeyOfLiteral(rightLiteral)
1016
+ });
1017
+ }
1018
+ return atomFormula({
1019
+ kind: "eq-column",
1020
+ left: leftKey,
1021
+ right: rightKey
1022
+ });
1023
+ };
1024
+ var formulaOfNeq = (left, right) => {
1025
+ const leftKey = columnKeyOfExpression(left);
1026
+ const rightKey = columnKeyOfExpression(right);
1027
+ const leftAst = astOf(left);
1028
+ const rightAst = astOf(right);
1029
+ const leftLiteral = leftAst.kind === "literal" ? leftAst.value : undefined;
1030
+ const rightLiteral = rightAst.kind === "literal" ? rightAst.value : undefined;
1031
+ if (leftKey === undefined && rightKey === undefined) {
1032
+ if (leftAst.kind !== "literal" || rightAst.kind !== "literal") {
1033
+ return unknownTag("neq:unsupported");
1034
+ }
1035
+ if (leftLiteral === null || rightLiteral === null) {
1036
+ return falseFormula();
1037
+ }
1038
+ return Object.is(leftLiteral, rightLiteral) ? falseFormula() : trueFormula();
1039
+ }
1040
+ if (leftKey === undefined) {
1041
+ if (leftAst.kind !== "literal") {
1042
+ return unknownTag("neq:unsupported");
1043
+ }
1044
+ if (leftLiteral === null) {
1045
+ return falseFormula();
1046
+ }
1047
+ return atomFormula({
1048
+ kind: "neq-literal",
1049
+ key: rightKey,
1050
+ value: valueKeyOfLiteral(leftLiteral)
1051
+ });
1052
+ }
1053
+ if (rightKey === undefined) {
1054
+ if (rightAst.kind !== "literal") {
1055
+ return unknownTag("neq:unsupported");
1056
+ }
1057
+ if (rightLiteral === null) {
1058
+ return falseFormula();
1059
+ }
1060
+ return atomFormula({
1061
+ kind: "neq-literal",
1062
+ key: leftKey,
1063
+ value: valueKeyOfLiteral(rightLiteral)
1064
+ });
1065
+ }
1066
+ return combineFacts(nonNullFactsOfExpression(left), nonNullFactsOfExpression(right));
1067
+ };
1068
+ var formulaOfIsNotDistinctFrom = (left, right) => {
1069
+ const leftKey = columnKeyOfExpression(left);
1070
+ const rightKey = columnKeyOfExpression(right);
1071
+ const leftAst = astOf(left);
1072
+ const rightAst = astOf(right);
1073
+ const leftLiteral = leftAst.kind === "literal" ? leftAst.value : undefined;
1074
+ const rightLiteral = rightAst.kind === "literal" ? rightAst.value : undefined;
1075
+ if (leftAst.kind === "literal" && rightAst.kind === "literal") {
1076
+ return Object.is(leftLiteral, rightLiteral) ? trueFormula() : falseFormula();
1077
+ }
1078
+ if (leftAst.kind === "literal" && leftLiteral === null && rightKey !== undefined) {
1079
+ return atomFormula({ kind: "is-null", key: rightKey });
1080
+ }
1081
+ if (rightAst.kind === "literal" && rightLiteral === null && leftKey !== undefined) {
1082
+ return atomFormula({ kind: "is-null", key: leftKey });
1083
+ }
1084
+ if (leftAst.kind === "literal" && rightKey !== undefined) {
1085
+ return atomFormula({
1086
+ kind: "eq-literal",
1087
+ key: rightKey,
1088
+ value: valueKeyOfLiteral(leftLiteral)
1089
+ });
1090
+ }
1091
+ if (rightAst.kind === "literal" && leftKey !== undefined) {
1092
+ return atomFormula({
1093
+ kind: "eq-literal",
1094
+ key: leftKey,
1095
+ value: valueKeyOfLiteral(rightLiteral)
1096
+ });
1097
+ }
1098
+ return unknownTag("isNotDistinctFrom:unsupported");
1099
+ };
1100
+ var normalizeFormula = (formula) => {
1101
+ switch (formula.kind) {
1102
+ case "all": {
1103
+ const items = [];
1104
+ for (const item of formula.items) {
1105
+ const normalized = normalizeFormula(item);
1106
+ if (normalized.kind === "true") {
1107
+ continue;
1108
+ }
1109
+ if (normalized.kind === "false") {
1110
+ return falseFormula();
1111
+ }
1112
+ if (normalized.kind === "all") {
1113
+ items.push(...normalized.items);
1114
+ } else {
1115
+ items.push(normalized);
1116
+ }
1117
+ }
1118
+ if (items.length === 0) {
1119
+ return trueFormula();
1120
+ }
1121
+ if (items.length === 1) {
1122
+ return items[0];
1123
+ }
1124
+ return { kind: "all", items };
1125
+ }
1126
+ case "any": {
1127
+ const items = [];
1128
+ for (const item of formula.items) {
1129
+ const normalized = normalizeFormula(item);
1130
+ if (normalized.kind === "false") {
1131
+ continue;
1132
+ }
1133
+ if (normalized.kind === "true") {
1134
+ return trueFormula();
1135
+ }
1136
+ if (normalized.kind === "any") {
1137
+ items.push(...normalized.items);
1138
+ } else {
1139
+ items.push(normalized);
1140
+ }
1141
+ }
1142
+ if (items.length === 0) {
1143
+ return falseFormula();
1144
+ }
1145
+ if (items.length === 1) {
1146
+ return items[0];
1147
+ }
1148
+ return { kind: "any", items };
1149
+ }
1150
+ case "not": {
1151
+ const item = normalizeFormula(formula.item);
1152
+ if (item.kind === "true") {
1153
+ return falseFormula();
1154
+ }
1155
+ if (item.kind === "false") {
1156
+ return trueFormula();
1157
+ }
1158
+ return { kind: "not", item };
1159
+ }
1160
+ default:
1161
+ return formula;
1162
+ }
1163
+ };
1164
+ var formulaOfExpression = (value) => {
1165
+ const ast = astOf(value);
1166
+ switch (ast.kind) {
1167
+ case "literal":
1168
+ if (ast.value === true) {
1169
+ return trueFormula();
1170
+ }
1171
+ if (ast.value === false) {
1172
+ return falseFormula();
1173
+ }
1174
+ return unknownTag("literal:non-boolean");
1175
+ case "isNull": {
1176
+ const key = columnKeyOfExpression(ast.value);
1177
+ return key === undefined ? unknownTag("isNull:unsupported") : atomFormula({ kind: "is-null", key });
1178
+ }
1179
+ case "isNotNull": {
1180
+ const key = columnKeyOfExpression(ast.value);
1181
+ return key === undefined ? unknownTag("isNotNull:unsupported") : atomFormula({ kind: "is-not-null", key });
1182
+ }
1183
+ case "not":
1184
+ return notFormula(formulaOfExpression(ast.value));
1185
+ case "eq":
1186
+ return formulaOfEq(ast.left, ast.right);
1187
+ case "neq":
1188
+ return formulaOfNeq(ast.left, ast.right);
1189
+ case "isNotDistinctFrom":
1190
+ return formulaOfIsNotDistinctFrom(ast.left, ast.right);
1191
+ case "isDistinctFrom":
1192
+ return notFormula(formulaOfIsNotDistinctFrom(ast.left, ast.right));
1193
+ case "and":
1194
+ return allFormula(ast.values.map((value2) => formulaOfExpression(value2)));
1195
+ case "or":
1196
+ return anyFormula(ast.values.map((value2) => formulaOfExpression(value2)));
1197
+ case "in": {
1198
+ const [left, ...rest] = ast.values;
1199
+ return left === undefined ? falseFormula() : anyFormula(rest.map((value2) => formulaOfEq(left, value2)));
1200
+ }
1201
+ case "notIn": {
1202
+ const [left, ...rest] = ast.values;
1203
+ return left === undefined ? trueFormula() : combineFacts(nonNullFactsOfExpression(left), allFormula(rest.map((value2) => formulaOfNeq(left, value2))));
1204
+ }
1205
+ case "between":
1206
+ return combineFacts(ast.values.reduce((current, entry) => combineFacts(current, nonNullFactsOfExpression(entry)), undefined), unknownTag("variadic:between"));
1207
+ case "lt":
1208
+ case "lte":
1209
+ case "gt":
1210
+ case "gte":
1211
+ case "like":
1212
+ case "ilike":
1213
+ case "contains":
1214
+ case "containedBy":
1215
+ case "overlaps":
1216
+ return combineFacts(nonNullFactsOfExpression(ast.left), nonNullFactsOfExpression(ast.right));
1217
+ default:
1218
+ return unknownTag(`expr:${ast.kind}`);
1219
+ }
1220
+ };
1221
+ var assumeFormulaTrue = (assumptions, formula) => assumptions.kind === "true" ? formula : andFormula(assumptions, formula);
1222
+ var assumeFormulaFalse = (assumptions, formula) => assumptions.kind === "true" ? notFormula(formula) : andFormula(assumptions, notFormula(formula));
1223
+ var contradictsFormula = (assumptions, formula) => analyzeFormula(andFormula(assumptions, formula)).contradiction;
1224
+ var impliesFormula = (assumptions, formula) => analyzeFormula(andFormula(assumptions, notFormula(formula))).contradiction;
1225
+ var guaranteedNonNullKeys = (assumptions) => analyzeFormula(assumptions).nonNullKeys;
1226
+ var guaranteedNullKeys = (assumptions) => analyzeFormula(assumptions).nullKeys;
1227
+ var guaranteedSourceNames = (assumptions) => analyzeFormula(assumptions).sourceNames;
1228
+
1229
+ // src/internal/query-requirements.ts
1230
+ var read_query_capabilities = ["read"];
1231
+ var union_query_capabilities = (...values) => [...new Set(values.flatMap((value) => value))];
1232
+
1233
+ // src/internal/query.ts
1234
+ var ExpressionProto = {
1235
+ pipe() {
1236
+ return pipeArguments4(this, arguments);
1237
+ }
1238
+ };
1239
+ var PlanProto = {
1240
+ pipe() {
1241
+ return pipeArguments4(this, arguments);
1242
+ }
1243
+ };
1244
+ var QueryTypeId = Symbol.for("effect-qb/Query/internal");
1245
+ var mergeDependencies = (left, right = undefined) => ({
1246
+ ...left ?? {},
1247
+ ...right ?? {}
1248
+ });
1249
+ var mergeAggregationRuntime = (left, right = "scalar") => left === "window" || right === "window" ? "window" : left === "aggregate" || right === "aggregate" ? "aggregate" : "scalar";
1250
+ var mergeAggregationManyRuntime = (values) => values.reduce((current, value) => mergeAggregationRuntime(current, value[TypeId2].kind), "scalar");
1251
+ var mergeNullabilityRuntime = (left, right = "never") => left === "always" || right === "always" ? "always" : left === "maybe" || right === "maybe" ? "maybe" : "never";
1252
+ var mergeNullabilityManyRuntime = (values) => values.reduce((current, value) => mergeNullabilityRuntime(current, value[TypeId2].nullability), "never");
1253
+ var mergeManyDependencies = (values) => values.reduce((current, value) => mergeDependencies(current, value[TypeId2].dependencies), {});
1254
+ var makeExpression = (state, ast) => {
1255
+ const expression = Object.create(ExpressionProto);
1256
+ Object.defineProperty(expression, "pipe", {
1257
+ configurable: true,
1258
+ writable: true,
1259
+ value: function() {
1260
+ return pipeArguments4(expression, arguments);
1261
+ }
1262
+ });
1263
+ expression[TypeId2] = {
1264
+ runtime: state.runtime,
1265
+ dbType: state.dbType,
1266
+ runtimeSchema: state.runtimeSchema,
1267
+ nullability: state.nullability,
1268
+ dialect: state.dialect,
1269
+ kind: state.kind ?? "scalar",
1270
+ dependencies: state.dependencies ?? {}
1271
+ };
1272
+ expression[TypeId3] = ast;
1273
+ return expression;
1274
+ };
1275
+ var makePlan = (state, ast, _assumptions, _capabilities, _statement, _target, _insertState) => {
1276
+ const plan = Object.create(PlanProto);
1277
+ Object.defineProperty(plan, "pipe", {
1278
+ configurable: true,
1279
+ writable: true,
1280
+ value: function() {
1281
+ return pipeArguments4(plan, arguments);
1282
+ }
1283
+ });
1284
+ plan[TypeId] = state;
1285
+ plan[TypeId6] = ast;
1286
+ plan[QueryTypeId] = {
1287
+ required: undefined,
1288
+ availableNames: undefined,
1289
+ grouped: undefined,
1290
+ assumptions: _assumptions ?? trueFormula(),
1291
+ capabilities: undefined,
1292
+ statement: _statement ?? "select",
1293
+ target: _target ?? undefined,
1294
+ insertSource: _insertState ?? "ready"
1295
+ };
1296
+ return plan;
1297
+ };
1298
+ var getAst = (plan) => plan[TypeId6];
1299
+ var getQueryState = (plan) => plan[QueryTypeId];
1300
+ var extractRequiredRuntime = (selection) => {
1301
+ const required = new Set;
1302
+ const visit = (value) => {
1303
+ if (TypeId2 in value) {
1304
+ for (const tableName of Object.keys(value[TypeId2].dependencies)) {
1305
+ required.add(tableName);
1306
+ }
1307
+ return;
1308
+ }
1309
+ for (const nested of Object.values(value)) {
1310
+ visit(nested);
1311
+ }
1312
+ };
1313
+ visit(selection);
1314
+ return [...required];
1315
+ };
1316
+ var extractSingleSelectedExpressionRuntime = (selection) => {
1317
+ const keys = Object.keys(selection);
1318
+ if (keys.length !== 1) {
1319
+ throw new Error("scalar subqueries must select exactly one top-level expression");
1320
+ }
1321
+ const record = selection;
1322
+ const value = record[keys[0]];
1323
+ if (value === null || typeof value !== "object" || !(TypeId2 in value)) {
1324
+ throw new Error("scalar subqueries must select a scalar expression");
1325
+ }
1326
+ return value;
1327
+ };
1328
+ var currentRequiredList = (required) => Array.isArray(required) ? [...required] : required === undefined ? [] : [required];
1329
+
1330
+ // src/internal/json/path.ts
1331
+ var SegmentTypeId = Symbol.for("effect-qb/JsonPathSegment");
1332
+ var TypeId7 = Symbol.for("effect-qb/JsonPath");
1333
+ var makeSegment = (segment) => segment;
1334
+ var key = (value) => makeSegment({
1335
+ [SegmentTypeId]: {
1336
+ kind: "key"
1337
+ },
1338
+ kind: "key",
1339
+ key: value
1340
+ });
1341
+ var index2 = (value) => makeSegment({
1342
+ [SegmentTypeId]: {
1343
+ kind: "index"
1344
+ },
1345
+ kind: "index",
1346
+ index: value
1347
+ });
1348
+ var wildcard = () => makeSegment({
1349
+ [SegmentTypeId]: {
1350
+ kind: "wildcard"
1351
+ },
1352
+ kind: "wildcard"
1353
+ });
1354
+ var slice = (start, end) => makeSegment({
1355
+ [SegmentTypeId]: {
1356
+ kind: "slice"
1357
+ },
1358
+ kind: "slice",
1359
+ start,
1360
+ end
1361
+ });
1362
+ var descend = () => makeSegment({
1363
+ [SegmentTypeId]: {
1364
+ kind: "descend"
1365
+ },
1366
+ kind: "descend"
1367
+ });
1368
+ var path = (...segments) => ({
1369
+ [TypeId7]: {
1370
+ segments
1371
+ },
1372
+ segments
1373
+ });
1374
+
1375
+ // src/internal/projection-alias.ts
1376
+ var TypeId8 = Symbol.for("effect-qb/ProjectionAlias");
1377
+
1378
+ // src/internal/projections.ts
1379
+ var aliasFromPath = (path2) => path2.join("__");
1380
+ var isExpression = (value) => typeof value === "object" && value !== null && (TypeId2 in value);
1381
+ var projectionAliasOf = (expression) => (TypeId8 in expression) ? expression[TypeId8].alias : undefined;
1382
+ var pathKeyOf = (path2) => JSON.stringify(path2);
1383
+ var formatProjectionPath = (path2) => path2.join(".");
1384
+ var isPrefixPath = (left, right) => left.length < right.length && left.every((segment, index3) => segment === right[index3]);
1385
+ var flattenSelection = (selection, path2 = []) => {
1386
+ const fields = [];
1387
+ for (const [key2, value] of Object.entries(selection)) {
1388
+ const nextPath = [...path2, key2];
1389
+ if (isExpression(value)) {
1390
+ fields.push({
1391
+ path: nextPath,
1392
+ expression: value,
1393
+ alias: projectionAliasOf(value) ?? aliasFromPath(nextPath)
1394
+ });
1395
+ continue;
1396
+ }
1397
+ fields.push(...flattenSelection(value, nextPath));
1398
+ }
1399
+ return fields;
1400
+ };
1401
+ var validateProjections = (projections) => {
1402
+ const seen = new Set;
1403
+ const pathKeys = new Set;
1404
+ for (const projection of projections) {
1405
+ if (seen.has(projection.alias)) {
1406
+ throw new Error(`Duplicate projection alias: ${projection.alias}`);
1407
+ }
1408
+ seen.add(projection.alias);
1409
+ const pathKey = pathKeyOf(projection.path);
1410
+ if (pathKeys.has(pathKey)) {
1411
+ throw new Error(`Duplicate projection path: ${formatProjectionPath(projection.path)}`);
1412
+ }
1413
+ pathKeys.add(pathKey);
1414
+ }
1415
+ for (let index3 = 0;index3 < projections.length; index3++) {
1416
+ const current = projections[index3];
1417
+ for (let compareIndex = index3 + 1;compareIndex < projections.length; compareIndex++) {
1418
+ const other = projections[compareIndex];
1419
+ if (isPrefixPath(current.path, other.path) || isPrefixPath(other.path, current.path)) {
1420
+ throw new Error(`Conflicting projection paths: ${formatProjectionPath(current.path)} conflicts with ${formatProjectionPath(other.path)}`);
1421
+ }
1422
+ }
1423
+ }
1424
+ };
1425
+
1426
+ // src/internal/grouping-key.ts
1427
+ var literalGroupingKey = (value) => {
1428
+ if (value instanceof Date) {
1429
+ return `date:${value.toISOString()}`;
1430
+ }
1431
+ if (value === null) {
1432
+ return "null";
1433
+ }
1434
+ switch (typeof value) {
1435
+ case "string":
1436
+ return `string:${JSON.stringify(value)}`;
1437
+ case "number":
1438
+ return `number:${value}`;
1439
+ case "boolean":
1440
+ return `boolean:${value}`;
1441
+ default:
1442
+ return `literal:${JSON.stringify(value)}`;
1443
+ }
1444
+ };
1445
+ var groupingKeyOfExpression = (expression) => {
1446
+ const ast = expression[TypeId3];
1447
+ switch (ast.kind) {
1448
+ case "column":
1449
+ return `column:${ast.tableName}.${ast.columnName}`;
1450
+ case "literal":
1451
+ return `literal:${literalGroupingKey(ast.value)}`;
1452
+ case "cast":
1453
+ return `cast(${groupingKeyOfExpression(ast.value)} as ${ast.target.dialect}:${ast.target.kind})`;
1454
+ case "isNull":
1455
+ case "isNotNull":
1456
+ case "not":
1457
+ case "upper":
1458
+ case "lower":
1459
+ case "count":
1460
+ case "max":
1461
+ case "min":
1462
+ return `${ast.kind}(${groupingKeyOfExpression(ast.value)})`;
1463
+ case "eq":
1464
+ case "neq":
1465
+ case "lt":
1466
+ case "lte":
1467
+ case "gt":
1468
+ case "gte":
1469
+ case "like":
1470
+ case "ilike":
1471
+ case "isDistinctFrom":
1472
+ case "isNotDistinctFrom":
1473
+ return `${ast.kind}(${groupingKeyOfExpression(ast.left)},${groupingKeyOfExpression(ast.right)})`;
1474
+ case "and":
1475
+ case "or":
1476
+ case "coalesce":
1477
+ case "concat":
1478
+ case "in":
1479
+ case "notIn":
1480
+ case "between":
1481
+ return `${ast.kind}(${ast.values.map(groupingKeyOfExpression).join(",")})`;
1482
+ case "case":
1483
+ return `case(${ast.branches.map((branch) => `when:${groupingKeyOfExpression(branch.when)}=>${groupingKeyOfExpression(branch.then)}`).join("|")};else:${groupingKeyOfExpression(ast.else)})`;
1484
+ default:
1485
+ throw new Error("Unsupported expression for grouping key generation");
1486
+ }
1487
+ };
1488
+ var dedupeGroupedExpressions = (values) => {
1489
+ const seen = new Set;
1490
+ return values.filter((value) => {
1491
+ const key2 = groupingKeyOfExpression(value);
1492
+ if (seen.has(key2)) {
1493
+ return false;
1494
+ }
1495
+ seen.add(key2);
1496
+ return true;
1497
+ });
1498
+ };
1499
+
1500
+ // src/internal/aggregation-validation.ts
1501
+ var isExpression2 = (value) => typeof value === "object" && value !== null && (TypeId2 in value);
1502
+ var selectionHasAggregate = (selection) => {
1503
+ if (isExpression2(selection)) {
1504
+ return selection[TypeId2].kind === "aggregate";
1505
+ }
1506
+ return Object.values(selection).some((value) => selectionHasAggregate(value));
1507
+ };
1508
+ var isGroupedSelectionValid = (selection, groupedExpressions) => {
1509
+ if (isExpression2(selection)) {
1510
+ const aggregation = selection[TypeId2].kind;
1511
+ if (aggregation === "aggregate") {
1512
+ return true;
1513
+ }
1514
+ if (aggregation === "window") {
1515
+ return false;
1516
+ }
1517
+ if (Object.keys(selection[TypeId2].dependencies).length === 0) {
1518
+ return true;
1519
+ }
1520
+ return groupedExpressions.has(groupingKeyOfExpression(selection));
1521
+ }
1522
+ return Object.values(selection).every((value) => isGroupedSelectionValid(value, groupedExpressions));
1523
+ };
1524
+ var validateAggregationSelection = (selection, grouped) => {
1525
+ const groupedExpressions = new Set(grouped.map(groupingKeyOfExpression));
1526
+ const hasAggregate = selectionHasAggregate(selection);
1527
+ const isValid = hasAggregate || grouped.length > 0 ? isGroupedSelectionValid(selection, groupedExpressions) : true;
1528
+ if (!isValid) {
1529
+ throw new Error("Invalid grouped selection: scalar expressions must be covered by groupBy(...) when aggregates are present");
1530
+ }
1531
+ };
1532
+
1533
+ // src/postgres/internal/sql-expression-renderer.ts
1534
+ var renderDbType = (dialect, dbType) => {
1535
+ if (dialect.name === "mysql" && dbType.dialect === "mysql" && dbType.kind === "uuid") {
1536
+ return "char(36)";
1537
+ }
1538
+ return dbType.kind;
1539
+ };
1540
+ var renderCastType = (dialect, dbType) => {
1541
+ if (dialect.name !== "mysql") {
1542
+ return dbType.kind;
1543
+ }
1544
+ switch (dbType.kind) {
1545
+ case "text":
1546
+ return "char";
1547
+ case "uuid":
1548
+ return "char(36)";
1549
+ case "numeric":
1550
+ return "decimal";
1551
+ case "timestamp":
1552
+ return "datetime";
1553
+ case "bool":
1554
+ case "boolean":
1555
+ return "boolean";
1556
+ case "json":
1557
+ return "json";
1558
+ default:
1559
+ return dbType.kind;
1560
+ }
1561
+ };
1562
+ var renderDdlExpression = (expression, state, dialect) => isSchemaExpression(expression) ? render(expression) : renderExpression(expression, state, dialect);
1563
+ var renderColumnDefinition = (dialect, state, columnName, column) => {
1564
+ const clauses = [
1565
+ dialect.quoteIdentifier(columnName),
1566
+ column.metadata.ddlType ?? renderDbType(dialect, column.metadata.dbType)
1567
+ ];
1568
+ if (column.metadata.identity) {
1569
+ clauses.push(`generated ${column.metadata.identity.generation === "byDefault" ? "by default" : "always"} as identity`);
1570
+ } else if (column.metadata.generatedValue) {
1571
+ clauses.push(`generated always as (${renderDdlExpression(column.metadata.generatedValue, state, dialect)}) stored`);
1572
+ } else if (column.metadata.defaultValue) {
1573
+ clauses.push(`default ${renderDdlExpression(column.metadata.defaultValue, state, dialect)}`);
1574
+ }
1575
+ if (!column.metadata.nullable) {
1576
+ clauses.push("not null");
1577
+ }
1578
+ return clauses.join(" ");
1579
+ };
1580
+ var renderCreateTableSql = (targetSource, state, dialect, ifNotExists) => {
1581
+ const table = targetSource.source;
1582
+ const fields = table[TypeId4].fields;
1583
+ const definitions = Object.entries(fields).map(([columnName, column]) => renderColumnDefinition(dialect, state, columnName, column));
1584
+ for (const option2 of table[OptionsSymbol]) {
1585
+ switch (option2.kind) {
1586
+ case "primaryKey":
1587
+ 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" : ""}` : ""}`);
1588
+ break;
1589
+ case "unique":
1590
+ 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" : ""}` : ""}`);
1591
+ break;
1592
+ case "foreignKey": {
1593
+ const reference = option2.references();
1594
+ 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" : ""}` : ""}`);
1595
+ break;
1596
+ }
1597
+ case "check":
1598
+ definitions.push(`constraint ${dialect.quoteIdentifier(option2.name)} check (${renderDdlExpression(option2.predicate, state, dialect)})${option2.noInherit ? " no inherit" : ""}`);
1599
+ break;
1600
+ case "index":
1601
+ break;
1602
+ }
1603
+ }
1604
+ return `create table${ifNotExists ? " if not exists" : ""} ${renderSourceReference(targetSource.source, targetSource.tableName, targetSource.baseTableName, state, dialect)} (${definitions.join(", ")})`;
1605
+ };
1606
+ var renderCreateIndexSql = (targetSource, ddl, state, dialect) => {
1607
+ const maybeIfNotExists = dialect.name === "postgres" && ddl.ifNotExists ? " if not exists" : "";
1608
+ 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(", ")})`;
1609
+ };
1610
+ 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)}`;
1611
+ var isExpression3 = (value) => value !== null && typeof value === "object" && (TypeId2 in value);
1612
+ var isJsonDbType = (dbType) => dbType.kind === "jsonb" || dbType.kind === "json" || ("variant" in dbType) && dbType.variant === "json";
1613
+ var isJsonExpression = (value) => isExpression3(value) && isJsonDbType(value[TypeId2].dbType);
1614
+ var unsupportedJsonFeature = (dialect, feature) => {
1615
+ const error = new Error(`Unsupported JSON feature for ${dialect.name}: ${feature}`);
1616
+ Object.assign(error, {
1617
+ tag: `@${dialect.name}/unsupported/json-feature`,
1618
+ dialect: dialect.name,
1619
+ feature
1620
+ });
1621
+ throw error;
1622
+ };
1623
+ var extractJsonBase = (node) => node.value ?? node.base ?? node.input ?? node.left ?? node.target;
1624
+ var isJsonPathValue = (value) => value !== null && typeof value === "object" && (TypeId7 in value);
1625
+ var extractJsonPathSegments = (node) => {
1626
+ const path2 = node.path ?? node.segments ?? node.keys;
1627
+ if (isJsonPathValue(path2)) {
1628
+ return path2.segments;
1629
+ }
1630
+ if (Array.isArray(path2)) {
1631
+ return path2;
1632
+ }
1633
+ if ("key" in node) {
1634
+ return [key(String(node.key))];
1635
+ }
1636
+ if ("segment" in node) {
1637
+ const segment = node.segment;
1638
+ if (typeof segment === "string") {
1639
+ return [key(segment)];
1640
+ }
1641
+ if (typeof segment === "number") {
1642
+ return [index2(segment)];
1643
+ }
1644
+ if (segment !== null && typeof segment === "object" && SegmentTypeId in segment) {
1645
+ return [segment];
1646
+ }
1647
+ return [];
1648
+ }
1649
+ if ("right" in node && isJsonPathValue(node.right)) {
1650
+ return node.right.segments;
1651
+ }
1652
+ return [];
1653
+ };
1654
+ var extractJsonValue = (node) => node.newValue ?? node.insert ?? node.right;
1655
+ var renderJsonPathSegment = (segment) => {
1656
+ if (typeof segment === "string") {
1657
+ return /^[A-Za-z_][A-Za-z0-9_]*$/.test(segment) ? `.${segment}` : `."${segment.replace(/\\/g, "\\\\").replace(/"/g, "\\\"")}"`;
1658
+ }
1659
+ if (typeof segment === "number") {
1660
+ return `[${segment}]`;
1661
+ }
1662
+ switch (segment.kind) {
1663
+ case "key":
1664
+ return /^[A-Za-z_][A-Za-z0-9_]*$/.test(segment.key) ? `.${segment.key}` : `."${segment.key.replace(/\\/g, "\\\\").replace(/"/g, "\\\"")}"`;
1665
+ case "index":
1666
+ return `[${segment.index}]`;
1667
+ case "wildcard":
1668
+ return "[*]";
1669
+ case "slice":
1670
+ return `[${segment.start ?? 0} to ${segment.end ?? "last"}]`;
1671
+ case "descend":
1672
+ return ".**";
1673
+ default:
1674
+ throw new Error("Unsupported JSON path segment");
1675
+ }
1676
+ };
1677
+ var renderJsonPathStringLiteral = (segments) => {
1678
+ let path2 = "$";
1679
+ for (const segment of segments) {
1680
+ path2 += renderJsonPathSegment(segment);
1681
+ }
1682
+ return path2;
1683
+ };
1684
+ var renderMySqlJsonPath = (segments, state, dialect) => dialect.renderLiteral(renderJsonPathStringLiteral(segments), state);
1685
+ var renderPostgresJsonPathArray = (segments, state, dialect) => `array[${segments.map((segment) => {
1686
+ if (typeof segment === "string") {
1687
+ return dialect.renderLiteral(segment, state);
1688
+ }
1689
+ if (typeof segment === "number") {
1690
+ return dialect.renderLiteral(String(segment), state);
1691
+ }
1692
+ switch (segment.kind) {
1693
+ case "key":
1694
+ return dialect.renderLiteral(segment.key, state);
1695
+ case "index":
1696
+ return dialect.renderLiteral(String(segment.index), state);
1697
+ default:
1698
+ throw new Error("Postgres JSON traversal requires exact key/index segments");
1699
+ }
1700
+ }).join(", ")}]`;
1701
+ var renderPostgresTextLiteral = (value, state, dialect) => `cast(${dialect.renderLiteral(value, state)} as text)`;
1702
+ var renderPostgresJsonAccessStep = (segment, textMode, state, dialect) => {
1703
+ switch (segment.kind) {
1704
+ case "key":
1705
+ return `${textMode ? "->>" : "->"} ${dialect.renderLiteral(segment.key, state)}`;
1706
+ case "index":
1707
+ return `${textMode ? "->>" : "->"} ${dialect.renderLiteral(String(segment.index), state)}`;
1708
+ default:
1709
+ throw new Error("Postgres exact JSON access requires key/index segments");
1710
+ }
1711
+ };
1712
+ var renderPostgresJsonValue = (value, state, dialect) => {
1713
+ if (!isExpression3(value)) {
1714
+ throw new Error("Expected a JSON expression");
1715
+ }
1716
+ const rendered = renderExpression(value, state, dialect);
1717
+ return value[TypeId2].dbType.kind === "jsonb" ? rendered : `cast(${rendered} as jsonb)`;
1718
+ };
1719
+ var renderPostgresJsonKind = (value) => value[TypeId2].dbType.kind === "jsonb" ? "jsonb" : "json";
1720
+ var renderJsonOpaquePath = (value, state, dialect) => {
1721
+ if (isJsonPathValue(value)) {
1722
+ return dialect.renderLiteral(renderJsonPathStringLiteral(value.segments), state);
1723
+ }
1724
+ if (typeof value === "string") {
1725
+ return dialect.renderLiteral(value, state);
1726
+ }
1727
+ if (isExpression3(value)) {
1728
+ return renderExpression(value, state, dialect);
1729
+ }
1730
+ throw new Error("Unsupported SQL/JSON path input");
1731
+ };
1732
+ var renderFunctionCall = (name, args, state, dialect) => {
1733
+ if (name === "array") {
1734
+ return `ARRAY[${args.map((arg) => renderExpression(arg, state, dialect)).join(", ")}]`;
1735
+ }
1736
+ if (name === "extract" && args.length === 2) {
1737
+ const field = args[0];
1738
+ const source = args[1];
1739
+ if (field === undefined) {
1740
+ throw new Error("Unsupported SQL extract expression");
1741
+ }
1742
+ if (source === undefined) {
1743
+ throw new Error("Unsupported SQL extract expression");
1744
+ }
1745
+ const fieldRuntime = isExpression3(field) && field[TypeId2].dbType.kind === "text" && typeof field[TypeId2].runtime === "string" ? field[TypeId2].runtime : undefined;
1746
+ const renderedField = fieldRuntime ?? renderExpression(field, state, dialect);
1747
+ return `extract(${renderedField} from ${renderExpression(source, state, dialect)})`;
1748
+ }
1749
+ const renderedArgs = args.map((arg) => renderExpression(arg, state, dialect)).join(", ");
1750
+ if (args.length === 0) {
1751
+ switch (name) {
1752
+ case "current_date":
1753
+ case "current_time":
1754
+ case "current_timestamp":
1755
+ case "localtime":
1756
+ case "localtimestamp":
1757
+ return name;
1758
+ default:
1759
+ return `${name}()`;
1760
+ }
1761
+ }
1762
+ return `${name}(${renderedArgs})`;
1763
+ };
1764
+ var renderJsonExpression = (expression, ast, state, dialect) => {
1765
+ const kind = typeof ast.kind === "string" ? ast.kind : undefined;
1766
+ if (!kind) {
1767
+ return;
1768
+ }
1769
+ const base = extractJsonBase(ast);
1770
+ const segments = extractJsonPathSegments(ast);
1771
+ const exact = segments.every((segment) => segment.kind === "key" || segment.kind === "index");
1772
+ const postgresExpressionKind = dialect.name === "postgres" && isJsonExpression(expression) ? renderPostgresJsonKind(expression) : undefined;
1773
+ const postgresBaseKind = dialect.name === "postgres" && isJsonExpression(base) ? renderPostgresJsonKind(base) : undefined;
1774
+ switch (kind) {
1775
+ case "jsonGet":
1776
+ case "jsonPath":
1777
+ case "jsonAccess":
1778
+ case "jsonTraverse":
1779
+ case "jsonGetText":
1780
+ case "jsonPathText":
1781
+ case "jsonAccessText":
1782
+ case "jsonTraverseText": {
1783
+ if (!isExpression3(base) || segments.length === 0) {
1784
+ return;
1785
+ }
1786
+ const baseSql = renderExpression(base, state, dialect);
1787
+ const textMode = kind.endsWith("Text") || ast.text === true || ast.asText === true;
1788
+ if (dialect.name === "postgres") {
1789
+ if (exact) {
1790
+ return segments.length === 1 ? `(${baseSql} ${renderPostgresJsonAccessStep(segments[0], textMode, state, dialect)})` : `(${baseSql} ${textMode ? "#>>" : "#>"} ${renderPostgresJsonPathArray(segments, state, dialect)})`;
1791
+ }
1792
+ const jsonPathLiteral = dialect.renderLiteral(renderJsonPathStringLiteral(segments), state);
1793
+ const queried = `jsonb_path_query_first(${renderPostgresJsonValue(base, state, dialect)}, ${jsonPathLiteral})`;
1794
+ return textMode ? `(${queried} #>> '{}')` : queried;
1795
+ }
1796
+ if (dialect.name === "mysql") {
1797
+ const extracted = `json_extract(${baseSql}, ${renderMySqlJsonPath(segments, state, dialect)})`;
1798
+ return textMode ? `json_unquote(${extracted})` : extracted;
1799
+ }
1800
+ return;
1801
+ }
1802
+ case "jsonHasKey":
1803
+ case "jsonKeyExists":
1804
+ case "jsonHasAnyKeys":
1805
+ case "jsonHasAllKeys": {
1806
+ if (!isExpression3(base)) {
1807
+ return;
1808
+ }
1809
+ const baseSql = dialect.name === "postgres" ? renderPostgresJsonValue(base, state, dialect) : renderExpression(base, state, dialect);
1810
+ const keys = segments;
1811
+ if (keys.length === 0) {
1812
+ return;
1813
+ }
1814
+ if (dialect.name === "postgres") {
1815
+ if (kind === "jsonHasAnyKeys") {
1816
+ return `(${baseSql} ?| array[${keys.map((key2) => renderPostgresTextLiteral(String(key2), state, dialect)).join(", ")}])`;
1817
+ }
1818
+ if (kind === "jsonHasAllKeys") {
1819
+ return `(${baseSql} ?& array[${keys.map((key2) => renderPostgresTextLiteral(String(key2), state, dialect)).join(", ")}])`;
1820
+ }
1821
+ return `(${baseSql} ? ${renderPostgresTextLiteral(String(keys[0]), state, dialect)})`;
1822
+ }
1823
+ if (dialect.name === "mysql") {
1824
+ const mode = kind === "jsonHasAllKeys" ? "all" : "one";
1825
+ const paths = keys.map((segment) => renderMySqlJsonPath([segment], state, dialect)).join(", ");
1826
+ return `json_contains_path(${baseSql}, ${dialect.renderLiteral(mode, state)}, ${paths})`;
1827
+ }
1828
+ return;
1829
+ }
1830
+ case "jsonConcat":
1831
+ case "jsonMerge": {
1832
+ if (!isExpression3(ast.left) || !isExpression3(ast.right)) {
1833
+ return;
1834
+ }
1835
+ if (dialect.name === "postgres") {
1836
+ return `(${renderPostgresJsonValue(ast.left, state, dialect)} || ${renderPostgresJsonValue(ast.right, state, dialect)})`;
1837
+ }
1838
+ if (dialect.name === "mysql") {
1839
+ return `json_merge_preserve(${renderExpression(ast.left, state, dialect)}, ${renderExpression(ast.right, state, dialect)})`;
1840
+ }
1841
+ return;
1842
+ }
1843
+ case "jsonBuildObject": {
1844
+ const entries = Array.isArray(ast.entries) ? ast.entries : [];
1845
+ const renderedEntries = entries.flatMap((entry) => [
1846
+ dialect.renderLiteral(entry.key, state),
1847
+ renderExpression(entry.value, state, dialect)
1848
+ ]);
1849
+ if (dialect.name === "postgres") {
1850
+ return `${postgresExpressionKind === "jsonb" ? "jsonb" : "json"}_build_object(${renderedEntries.join(", ")})`;
1851
+ }
1852
+ if (dialect.name === "mysql") {
1853
+ return `json_object(${renderedEntries.join(", ")})`;
1854
+ }
1855
+ return;
1856
+ }
1857
+ case "jsonBuildArray": {
1858
+ const values = Array.isArray(ast.values) ? ast.values : [];
1859
+ const renderedValues = values.map((value) => renderExpression(value, state, dialect)).join(", ");
1860
+ if (dialect.name === "postgres") {
1861
+ return `${postgresExpressionKind === "jsonb" ? "jsonb" : "json"}_build_array(${renderedValues})`;
1862
+ }
1863
+ if (dialect.name === "mysql") {
1864
+ return `json_array(${renderedValues})`;
1865
+ }
1866
+ return;
1867
+ }
1868
+ case "jsonToJson":
1869
+ if (!isExpression3(base)) {
1870
+ return;
1871
+ }
1872
+ if (dialect.name === "postgres") {
1873
+ return `to_json(${renderExpression(base, state, dialect)})`;
1874
+ }
1875
+ if (dialect.name === "mysql") {
1876
+ return `cast(${renderExpression(base, state, dialect)} as json)`;
1877
+ }
1878
+ return;
1879
+ case "jsonToJsonb":
1880
+ if (!isExpression3(base)) {
1881
+ return;
1882
+ }
1883
+ if (dialect.name === "postgres") {
1884
+ return `to_jsonb(${renderExpression(base, state, dialect)})`;
1885
+ }
1886
+ if (dialect.name === "mysql") {
1887
+ return `cast(${renderExpression(base, state, dialect)} as json)`;
1888
+ }
1889
+ return;
1890
+ case "jsonTypeOf":
1891
+ if (!isExpression3(base)) {
1892
+ return;
1893
+ }
1894
+ if (dialect.name === "postgres") {
1895
+ const baseSql = renderExpression(base, state, dialect);
1896
+ return `${postgresBaseKind === "jsonb" ? "jsonb" : "json"}_typeof(${baseSql})`;
1897
+ }
1898
+ if (dialect.name === "mysql") {
1899
+ return `json_type(${renderExpression(base, state, dialect)})`;
1900
+ }
1901
+ return;
1902
+ case "jsonLength":
1903
+ if (!isExpression3(base)) {
1904
+ return;
1905
+ }
1906
+ if (dialect.name === "postgres") {
1907
+ const baseSql = renderExpression(base, state, dialect);
1908
+ const typeOf = `${postgresBaseKind === "jsonb" ? "jsonb" : "json"}_typeof`;
1909
+ const arrayLength = `${postgresBaseKind === "jsonb" ? "jsonb" : "json"}_array_length`;
1910
+ const objectKeys = `${postgresBaseKind === "jsonb" ? "jsonb" : "json"}_object_keys`;
1911
+ return `(case when ${typeOf}(${baseSql}) = 'array' then ${arrayLength}(${baseSql}) when ${typeOf}(${baseSql}) = 'object' then (select count(*)::int from ${objectKeys}(${baseSql})) else null end)`;
1912
+ }
1913
+ if (dialect.name === "mysql") {
1914
+ return `json_length(${renderExpression(base, state, dialect)})`;
1915
+ }
1916
+ return;
1917
+ case "jsonKeys":
1918
+ if (!isExpression3(base)) {
1919
+ return;
1920
+ }
1921
+ if (dialect.name === "postgres") {
1922
+ const baseSql = renderExpression(base, state, dialect);
1923
+ const typeOf = `${postgresBaseKind === "jsonb" ? "jsonb" : "json"}_typeof`;
1924
+ const objectKeys = `${postgresBaseKind === "jsonb" ? "jsonb" : "json"}_object_keys`;
1925
+ return `(case when ${typeOf}(${baseSql}) = 'object' then array(select ${objectKeys}(${baseSql})) else null end)`;
1926
+ }
1927
+ if (dialect.name === "mysql") {
1928
+ return `json_keys(${renderExpression(base, state, dialect)})`;
1929
+ }
1930
+ return;
1931
+ case "jsonStripNulls":
1932
+ if (!isExpression3(base)) {
1933
+ return;
1934
+ }
1935
+ if (dialect.name === "postgres") {
1936
+ return `${postgresBaseKind === "jsonb" ? "jsonb" : "json"}_strip_nulls(${renderExpression(base, state, dialect)})`;
1937
+ }
1938
+ unsupportedJsonFeature(dialect, "jsonStripNulls");
1939
+ return;
1940
+ case "jsonDelete":
1941
+ case "jsonDeletePath":
1942
+ case "jsonRemove": {
1943
+ if (!isExpression3(base) || segments.length === 0) {
1944
+ return;
1945
+ }
1946
+ if (dialect.name === "postgres") {
1947
+ const baseSql = renderPostgresJsonValue(base, state, dialect);
1948
+ if (segments.length === 1 && (segments[0].kind === "key" || segments[0].kind === "index")) {
1949
+ const segment = segments[0];
1950
+ return `(${baseSql} - ${segment.kind === "key" ? dialect.renderLiteral(segment.key, state) : dialect.renderLiteral(String(segment.index), state)})`;
1951
+ }
1952
+ return `(${baseSql} #- ${renderPostgresJsonPathArray(segments, state, dialect)})`;
1953
+ }
1954
+ if (dialect.name === "mysql") {
1955
+ return `json_remove(${renderExpression(base, state, dialect)}, ${segments.map((segment) => renderMySqlJsonPath([segment], state, dialect)).join(", ")})`;
1956
+ }
1957
+ return;
1958
+ }
1959
+ case "jsonSet":
1960
+ case "jsonInsert": {
1961
+ if (!isExpression3(base) || segments.length === 0) {
1962
+ return;
1963
+ }
1964
+ const nextValue = extractJsonValue(ast);
1965
+ if (!isExpression3(nextValue)) {
1966
+ return;
1967
+ }
1968
+ const createMissing = ast.createMissing === true;
1969
+ const insertAfter = ast.insertAfter === true;
1970
+ if (dialect.name === "postgres") {
1971
+ const functionName = kind === "jsonInsert" ? "jsonb_insert" : "jsonb_set";
1972
+ const extra = kind === "jsonInsert" ? `, ${insertAfter ? "true" : "false"}` : `, ${createMissing ? "true" : "false"}`;
1973
+ return `${functionName}(${renderPostgresJsonValue(base, state, dialect)}, ${renderPostgresJsonPathArray(segments, state, dialect)}, ${renderPostgresJsonValue(nextValue, state, dialect)}${extra})`;
1974
+ }
1975
+ if (dialect.name === "mysql") {
1976
+ const functionName = kind === "jsonInsert" ? "json_insert" : "json_set";
1977
+ return `${functionName}(${renderExpression(base, state, dialect)}, ${renderMySqlJsonPath(segments, state, dialect)}, ${renderExpression(nextValue, state, dialect)})`;
1978
+ }
1979
+ return;
1980
+ }
1981
+ case "jsonPathExists": {
1982
+ if (!isExpression3(base)) {
1983
+ return;
1984
+ }
1985
+ const path2 = ast.path ?? ast.query ?? ast.right;
1986
+ if (path2 === undefined) {
1987
+ return;
1988
+ }
1989
+ if (dialect.name === "postgres") {
1990
+ return `(${renderPostgresJsonValue(base, state, dialect)} @? ${renderJsonOpaquePath(path2, state, dialect)})`;
1991
+ }
1992
+ if (dialect.name === "mysql") {
1993
+ return `json_contains_path(${renderExpression(base, state, dialect)}, ${dialect.renderLiteral("one", state)}, ${renderJsonOpaquePath(path2, state, dialect)})`;
1994
+ }
1995
+ return;
1996
+ }
1997
+ case "jsonPathMatch": {
1998
+ if (!isExpression3(base)) {
1999
+ return;
2000
+ }
2001
+ const path2 = ast.path ?? ast.query ?? ast.right;
2002
+ if (path2 === undefined) {
2003
+ return;
2004
+ }
2005
+ if (dialect.name === "postgres") {
2006
+ return `(${renderPostgresJsonValue(base, state, dialect)} @@ ${renderJsonOpaquePath(path2, state, dialect)})`;
2007
+ }
2008
+ unsupportedJsonFeature(dialect, "jsonPathMatch");
2009
+ }
2010
+ }
2011
+ return;
2012
+ };
2013
+ var selectionProjections = (selection) => flattenSelection(selection).map(({ path: path2, alias: alias2 }) => ({
2014
+ path: path2,
2015
+ alias: alias2
2016
+ }));
2017
+ var renderMutationAssignment = (entry, state, dialect) => {
2018
+ const column = entry.tableName && dialect.name === "mysql" ? `${dialect.quoteIdentifier(entry.tableName)}.${dialect.quoteIdentifier(entry.columnName)}` : dialect.quoteIdentifier(entry.columnName);
2019
+ return `${column} = ${renderExpression(entry.value, state, dialect)}`;
2020
+ };
2021
+ var renderJoinSourcesForMutation = (joins, state, dialect) => joins.map((join) => renderSourceReference(join.source, join.tableName, join.baseTableName, state, dialect)).join(", ");
2022
+ var renderFromSources = (sources, state, dialect) => sources.map((source) => renderSourceReference(source.source, source.tableName, source.baseTableName, state, dialect)).join(", ");
2023
+ var renderJoinPredicatesForMutation = (joins, state, dialect) => joins.flatMap((join) => join.kind === "cross" || !join.on ? [] : [renderExpression(join.on, state, dialect)]);
2024
+ var renderDeleteTargets = (targets, dialect) => targets.map((target) => dialect.quoteIdentifier(target.tableName)).join(", ");
2025
+ var renderMysqlMutationLock = (lock, statement) => {
2026
+ if (!lock) {
2027
+ return "";
2028
+ }
2029
+ switch (lock.mode) {
2030
+ case "lowPriority":
2031
+ return " low_priority";
2032
+ case "ignore":
2033
+ return " ignore";
2034
+ case "quick":
2035
+ return statement === "delete" ? " quick" : "";
2036
+ default:
2037
+ return "";
2038
+ }
2039
+ };
2040
+ var renderTransactionClause = (clause, dialect) => {
2041
+ switch (clause.kind) {
2042
+ case "transaction": {
2043
+ const modes = [];
2044
+ if (clause.isolationLevel) {
2045
+ modes.push(`isolation level ${clause.isolationLevel}`);
2046
+ }
2047
+ if (clause.readOnly === true) {
2048
+ modes.push("read only");
2049
+ }
2050
+ return modes.length > 0 ? `start transaction ${modes.join(", ")}` : "start transaction";
2051
+ }
2052
+ case "commit":
2053
+ return "commit";
2054
+ case "rollback":
2055
+ return "rollback";
2056
+ case "savepoint":
2057
+ return `savepoint ${dialect.quoteIdentifier(clause.name)}`;
2058
+ case "rollbackTo":
2059
+ return `rollback to savepoint ${dialect.quoteIdentifier(clause.name)}`;
2060
+ case "releaseSavepoint":
2061
+ return `release savepoint ${dialect.quoteIdentifier(clause.name)}`;
2062
+ }
2063
+ return "";
2064
+ };
2065
+ var renderSelectionList = (selection, state, dialect, validateAggregation) => {
2066
+ if (validateAggregation) {
2067
+ validateAggregationSelection(selection, []);
2068
+ }
2069
+ const flattened = flattenSelection(selection);
2070
+ const projections = selectionProjections(selection);
2071
+ const sql = flattened.map(({ expression, alias: alias2 }) => `${renderExpression(expression, state, dialect)} as ${dialect.quoteIdentifier(alias2)}`).join(", ");
2072
+ return {
2073
+ sql,
2074
+ projections
2075
+ };
2076
+ };
2077
+ var renderQueryAst = (ast, state, dialect) => {
2078
+ let sql = "";
2079
+ let projections = [];
2080
+ switch (ast.kind) {
2081
+ case "select": {
2082
+ validateAggregationSelection(ast.select, ast.groupBy);
2083
+ const rendered = renderSelectionList(ast.select, state, dialect, false);
2084
+ projections = rendered.projections;
2085
+ const clauses = [
2086
+ 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}`
2087
+ ];
2088
+ if (ast.from) {
2089
+ clauses.push(`from ${renderSourceReference(ast.from.source, ast.from.tableName, ast.from.baseTableName, state, dialect)}`);
2090
+ }
2091
+ for (const join of ast.joins) {
2092
+ const source = renderSourceReference(join.source, join.tableName, join.baseTableName, state, dialect);
2093
+ clauses.push(join.kind === "cross" ? `cross join ${source}` : `${join.kind} join ${source} on ${renderExpression(join.on, state, dialect)}`);
2094
+ }
2095
+ if (ast.where.length > 0) {
2096
+ clauses.push(`where ${ast.where.map((entry) => renderExpression(entry.predicate, state, dialect)).join(" and ")}`);
2097
+ }
2098
+ if (ast.groupBy.length > 0) {
2099
+ clauses.push(`group by ${ast.groupBy.map((value) => renderExpression(value, state, dialect)).join(", ")}`);
2100
+ }
2101
+ if (ast.having.length > 0) {
2102
+ clauses.push(`having ${ast.having.map((entry) => renderExpression(entry.predicate, state, dialect)).join(" and ")}`);
2103
+ }
2104
+ if (ast.orderBy.length > 0) {
2105
+ clauses.push(`order by ${ast.orderBy.map((entry) => `${renderExpression(entry.value, state, dialect)} ${entry.direction}`).join(", ")}`);
2106
+ }
2107
+ if (ast.limit) {
2108
+ clauses.push(`limit ${renderExpression(ast.limit, state, dialect)}`);
2109
+ }
2110
+ if (ast.offset) {
2111
+ clauses.push(`offset ${renderExpression(ast.offset, state, dialect)}`);
2112
+ }
2113
+ if (ast.lock) {
2114
+ clauses.push(`${ast.lock.mode === "update" ? "for update" : "for share"}${ast.lock.nowait ? " nowait" : ""}${ast.lock.skipLocked ? " skip locked" : ""}`);
2115
+ }
2116
+ sql = clauses.join(" ");
2117
+ break;
2118
+ }
2119
+ case "set": {
2120
+ const setAst = ast;
2121
+ const base = renderQueryAst(getAst(setAst.setBase), state, dialect);
2122
+ projections = selectionProjections(setAst.select);
2123
+ sql = [
2124
+ `(${base.sql})`,
2125
+ ...(setAst.setOperations ?? []).map((entry) => {
2126
+ const rendered = renderQueryAst(getAst(entry.query), state, dialect);
2127
+ return `${entry.kind}${entry.all ? " all" : ""} (${rendered.sql})`;
2128
+ })
2129
+ ].join(" ");
2130
+ break;
2131
+ }
2132
+ case "insert": {
2133
+ const insertAst = ast;
2134
+ const targetSource = insertAst.into;
2135
+ const target = renderSourceReference(targetSource.source, targetSource.tableName, targetSource.baseTableName, state, dialect);
2136
+ sql = `insert into ${target}`;
2137
+ if (insertAst.insertSource?.kind === "values") {
2138
+ const columns = insertAst.insertSource.columns.map((column) => dialect.quoteIdentifier(column)).join(", ");
2139
+ const rows = insertAst.insertSource.rows.map((row) => `(${row.values.map((entry) => renderExpression(entry.value, state, dialect)).join(", ")})`).join(", ");
2140
+ sql += ` (${columns}) values ${rows}`;
2141
+ } else if (insertAst.insertSource?.kind === "query") {
2142
+ const columns = insertAst.insertSource.columns.map((column) => dialect.quoteIdentifier(column)).join(", ");
2143
+ const renderedQuery = renderQueryAst(getAst(insertAst.insertSource.query), state, dialect);
2144
+ sql += ` (${columns}) ${renderedQuery.sql}`;
2145
+ } else if (insertAst.insertSource?.kind === "unnest") {
2146
+ const unnestSource = insertAst.insertSource;
2147
+ const columns = unnestSource.columns.map((column) => dialect.quoteIdentifier(column)).join(", ");
2148
+ if (dialect.name === "postgres") {
2149
+ const table = targetSource.source;
2150
+ const fields = table[TypeId4].fields;
2151
+ const rendered = unnestSource.values.map((entry) => `cast(${dialect.renderLiteral(entry.values, state)} as ${renderCastType(dialect, fields[entry.columnName].metadata.dbType)}[])`).join(", ");
2152
+ sql += ` (${columns}) select * from unnest(${rendered})`;
2153
+ } else {
2154
+ const rowCount = unnestSource.values[0]?.values.length ?? 0;
2155
+ const rows = Array.from({ length: rowCount }, (_, index3) => `(${unnestSource.values.map((entry) => dialect.renderLiteral(entry.values[index3], state)).join(", ")})`).join(", ");
2156
+ sql += ` (${columns}) values ${rows}`;
2157
+ }
2158
+ } else {
2159
+ const columns = (insertAst.values ?? []).map((entry) => dialect.quoteIdentifier(entry.columnName)).join(", ");
2160
+ const values = (insertAst.values ?? []).map((entry) => renderExpression(entry.value, state, dialect)).join(", ");
2161
+ if ((insertAst.values ?? []).length > 0) {
2162
+ sql += ` (${columns}) values (${values})`;
2163
+ } else {
2164
+ sql += " default values";
2165
+ }
2166
+ }
2167
+ if (insertAst.conflict) {
2168
+ const updateValues = (insertAst.conflict.values ?? []).map((entry) => `${dialect.quoteIdentifier(entry.columnName)} = ${renderExpression(entry.value, state, dialect)}`).join(", ");
2169
+ if (dialect.name === "postgres") {
2170
+ 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";
2171
+ sql += targetSql;
2172
+ sql += insertAst.conflict.action === "doNothing" ? " do nothing" : ` do update set ${updateValues}${insertAst.conflict.where ? ` where ${renderExpression(insertAst.conflict.where, state, dialect)}` : ""}`;
2173
+ } else if (insertAst.conflict.action === "doNothing") {
2174
+ sql = sql.replace(/^insert/, "insert ignore");
2175
+ } else {
2176
+ sql += ` on duplicate key update ${updateValues}`;
2177
+ }
2178
+ }
2179
+ const returning = renderSelectionList(insertAst.select, state, dialect, false);
2180
+ projections = returning.projections;
2181
+ if (returning.sql.length > 0) {
2182
+ sql += ` returning ${returning.sql}`;
2183
+ }
2184
+ break;
2185
+ }
2186
+ case "update": {
2187
+ const updateAst = ast;
2188
+ const targetSource = updateAst.target;
2189
+ const target = renderSourceReference(targetSource.source, targetSource.tableName, targetSource.baseTableName, state, dialect);
2190
+ const targets = updateAst.targets ?? [targetSource];
2191
+ const fromSources = updateAst.fromSources ?? [];
2192
+ const assignments = updateAst.set.map((entry) => renderMutationAssignment(entry, state, dialect)).join(", ");
2193
+ if (dialect.name === "mysql") {
2194
+ const modifiers = renderMysqlMutationLock(updateAst.lock, "update");
2195
+ const extraSources = renderFromSources(fromSources, state, dialect);
2196
+ 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(" ");
2197
+ const targetList = [
2198
+ ...targets.map((entry) => renderSourceReference(entry.source, entry.tableName, entry.baseTableName, state, dialect)),
2199
+ ...extraSources.length > 0 ? [extraSources] : []
2200
+ ].join(", ");
2201
+ sql = `update${modifiers} ${targetList}${joinSources.length > 0 ? ` ${joinSources}` : ""} set ${assignments}`;
2202
+ } else {
2203
+ sql = `update ${target} set ${assignments}`;
2204
+ const mutationSources = [
2205
+ ...fromSources.length > 0 ? [renderFromSources(fromSources, state, dialect)] : [],
2206
+ ...updateAst.joins.length > 0 ? [renderJoinSourcesForMutation(updateAst.joins, state, dialect)] : []
2207
+ ].filter((part) => part.length > 0);
2208
+ if (mutationSources.length > 0) {
2209
+ sql += ` from ${mutationSources.join(", ")}`;
2210
+ }
2211
+ }
2212
+ const whereParts = [
2213
+ ...dialect.name === "postgres" ? renderJoinPredicatesForMutation(updateAst.joins, state, dialect) : [],
2214
+ ...updateAst.where.map((entry) => renderExpression(entry.predicate, state, dialect))
2215
+ ];
2216
+ if (whereParts.length > 0) {
2217
+ sql += ` where ${whereParts.join(" and ")}`;
2218
+ }
2219
+ if (dialect.name === "mysql" && updateAst.orderBy.length > 0) {
2220
+ sql += ` order by ${updateAst.orderBy.map((entry) => `${renderExpression(entry.value, state, dialect)} ${entry.direction}`).join(", ")}`;
2221
+ }
2222
+ if (dialect.name === "mysql" && updateAst.limit) {
2223
+ sql += ` limit ${renderExpression(updateAst.limit, state, dialect)}`;
2224
+ }
2225
+ const returning = renderSelectionList(updateAst.select, state, dialect, false);
2226
+ projections = returning.projections;
2227
+ if (returning.sql.length > 0) {
2228
+ sql += ` returning ${returning.sql}`;
2229
+ }
2230
+ break;
2231
+ }
2232
+ case "delete": {
2233
+ const deleteAst = ast;
2234
+ const targetSource = deleteAst.target;
2235
+ const target = renderSourceReference(targetSource.source, targetSource.tableName, targetSource.baseTableName, state, dialect);
2236
+ const targets = deleteAst.targets ?? [targetSource];
2237
+ if (dialect.name === "mysql") {
2238
+ const modifiers = renderMysqlMutationLock(deleteAst.lock, "delete");
2239
+ const hasJoinedSources = deleteAst.joins.length > 0 || targets.length > 1;
2240
+ const targetList = renderDeleteTargets(targets, dialect);
2241
+ const fromSources = targets.map((entry) => renderSourceReference(entry.source, entry.tableName, entry.baseTableName, state, dialect)).join(", ");
2242
+ 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(" ");
2243
+ sql = hasJoinedSources ? `delete${modifiers} ${targetList} from ${fromSources}${joinSources.length > 0 ? ` ${joinSources}` : ""}` : `delete${modifiers} from ${fromSources}`;
2244
+ } else {
2245
+ sql = `delete from ${target}`;
2246
+ if (deleteAst.joins.length > 0) {
2247
+ sql += ` using ${renderJoinSourcesForMutation(deleteAst.joins, state, dialect)}`;
2248
+ }
2249
+ }
2250
+ const whereParts = [
2251
+ ...dialect.name === "postgres" ? renderJoinPredicatesForMutation(deleteAst.joins, state, dialect) : [],
2252
+ ...deleteAst.where.map((entry) => renderExpression(entry.predicate, state, dialect))
2253
+ ];
2254
+ if (whereParts.length > 0) {
2255
+ sql += ` where ${whereParts.join(" and ")}`;
2256
+ }
2257
+ if (dialect.name === "mysql" && deleteAst.orderBy.length > 0) {
2258
+ sql += ` order by ${deleteAst.orderBy.map((entry) => `${renderExpression(entry.value, state, dialect)} ${entry.direction}`).join(", ")}`;
2259
+ }
2260
+ if (dialect.name === "mysql" && deleteAst.limit) {
2261
+ sql += ` limit ${renderExpression(deleteAst.limit, state, dialect)}`;
2262
+ }
2263
+ const returning = renderSelectionList(deleteAst.select, state, dialect, false);
2264
+ projections = returning.projections;
2265
+ if (returning.sql.length > 0) {
2266
+ sql += ` returning ${returning.sql}`;
2267
+ }
2268
+ break;
2269
+ }
2270
+ case "truncate": {
2271
+ const truncateAst = ast;
2272
+ const targetSource = truncateAst.target;
2273
+ sql = `truncate table ${renderSourceReference(targetSource.source, targetSource.tableName, targetSource.baseTableName, state, dialect)}`;
2274
+ if (truncateAst.truncate?.restartIdentity) {
2275
+ sql += " restart identity";
2276
+ }
2277
+ if (truncateAst.truncate?.cascade) {
2278
+ sql += " cascade";
2279
+ }
2280
+ break;
2281
+ }
2282
+ case "merge": {
2283
+ if (dialect.name !== "postgres") {
2284
+ throw new Error(`Unsupported merge statement for ${dialect.name}`);
2285
+ }
2286
+ const mergeAst = ast;
2287
+ const targetSource = mergeAst.target;
2288
+ const usingSource = mergeAst.using;
2289
+ const merge = mergeAst.merge;
2290
+ 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)}`;
2291
+ if (merge.whenMatched) {
2292
+ sql += " when matched";
2293
+ if (merge.whenMatched.predicate) {
2294
+ sql += ` and ${renderExpression(merge.whenMatched.predicate, state, dialect)}`;
2295
+ }
2296
+ if (merge.whenMatched.kind === "delete") {
2297
+ sql += " then delete";
2298
+ } else {
2299
+ sql += ` then update set ${merge.whenMatched.values.map((entry) => `${dialect.quoteIdentifier(entry.columnName)} = ${renderExpression(entry.value, state, dialect)}`).join(", ")}`;
2300
+ }
2301
+ }
2302
+ if (merge.whenNotMatched) {
2303
+ sql += " when not matched";
2304
+ if (merge.whenNotMatched.predicate) {
2305
+ sql += ` and ${renderExpression(merge.whenNotMatched.predicate, state, dialect)}`;
2306
+ }
2307
+ 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(", ")})`;
2308
+ }
2309
+ break;
2310
+ }
2311
+ case "transaction":
2312
+ case "commit":
2313
+ case "rollback":
2314
+ case "savepoint":
2315
+ case "rollbackTo":
2316
+ case "releaseSavepoint": {
2317
+ sql = renderTransactionClause(ast.transaction, dialect);
2318
+ break;
2319
+ }
2320
+ case "createTable": {
2321
+ const createTableAst = ast;
2322
+ sql = renderCreateTableSql(createTableAst.target, state, dialect, createTableAst.ddl?.kind === "createTable" && createTableAst.ddl.ifNotExists);
2323
+ break;
2324
+ }
2325
+ case "dropTable": {
2326
+ const dropTableAst = ast;
2327
+ const ifExists = dropTableAst.ddl?.kind === "dropTable" && dropTableAst.ddl.ifExists;
2328
+ sql = `drop table${ifExists ? " if exists" : ""} ${renderSourceReference(dropTableAst.target.source, dropTableAst.target.tableName, dropTableAst.target.baseTableName, state, dialect)}`;
2329
+ break;
2330
+ }
2331
+ case "createIndex": {
2332
+ const createIndexAst = ast;
2333
+ sql = renderCreateIndexSql(createIndexAst.target, createIndexAst.ddl, state, dialect);
2334
+ break;
2335
+ }
2336
+ case "dropIndex": {
2337
+ const dropIndexAst = ast;
2338
+ sql = renderDropIndexSql(dropIndexAst.target, dropIndexAst.ddl, state, dialect);
2339
+ break;
2340
+ }
2341
+ }
2342
+ if (state.ctes.length === 0) {
2343
+ return {
2344
+ sql,
2345
+ projections
2346
+ };
2347
+ }
2348
+ return {
2349
+ sql: `with${state.ctes.some((entry) => entry.recursive) ? " recursive" : ""} ${state.ctes.map((entry) => `${dialect.quoteIdentifier(entry.name)} as (${entry.sql})`).join(", ")} ${sql}`,
2350
+ projections
2351
+ };
2352
+ };
2353
+ var renderSourceReference = (source, tableName, baseTableName, state, dialect) => {
2354
+ const renderSelectRows = (rows, columnNames) => {
2355
+ const renderedRows = rows.map((row) => `select ${columnNames.map((columnName) => `${renderExpression(row[columnName], state, dialect)} as ${dialect.quoteIdentifier(columnName)}`).join(", ")}`);
2356
+ return `(${renderedRows.join(" union all ")}) as ${dialect.quoteIdentifier(tableName)}(${columnNames.map((columnName) => dialect.quoteIdentifier(columnName)).join(", ")})`;
2357
+ };
2358
+ const renderUnnestRows = (arrays, columnNames) => {
2359
+ const rowCount = arrays[columnNames[0]].length;
2360
+ const rows = Array.from({ length: rowCount }, (_, index3) => Object.fromEntries(columnNames.map((columnName) => [columnName, arrays[columnName][index3]])));
2361
+ return renderSelectRows(rows, columnNames);
2362
+ };
2363
+ if (typeof source === "object" && source !== null && "kind" in source && source.kind === "cte") {
2364
+ const cte = source;
2365
+ if (!state.cteNames.has(cte.name)) {
2366
+ state.cteNames.add(cte.name);
2367
+ const rendered = renderQueryAst(getAst(cte.plan), state, dialect);
2368
+ state.ctes.push({
2369
+ name: cte.name,
2370
+ sql: rendered.sql,
2371
+ recursive: cte.recursive
2372
+ });
2373
+ }
2374
+ return dialect.quoteIdentifier(cte.name);
2375
+ }
2376
+ if (typeof source === "object" && source !== null && "kind" in source && source.kind === "derived") {
2377
+ const derived = source;
2378
+ if (!state.cteNames.has(derived.name)) {}
2379
+ return `(${renderQueryAst(getAst(derived.plan), state, dialect).sql}) as ${dialect.quoteIdentifier(derived.name)}`;
2380
+ }
2381
+ if (typeof source === "object" && source !== null && "kind" in source && source.kind === "lateral") {
2382
+ const lateral = source;
2383
+ return `lateral (${renderQueryAst(getAst(lateral.plan), state, dialect).sql}) as ${dialect.quoteIdentifier(lateral.name)}`;
2384
+ }
2385
+ if (typeof source === "object" && source !== null && source.kind === "values") {
2386
+ const values = source;
2387
+ return renderSelectRows(values.rows, Object.keys(values.columns));
2388
+ }
2389
+ if (typeof source === "object" && source !== null && source.kind === "unnest") {
2390
+ const unnest = source;
2391
+ return renderUnnestRows(unnest.arrays, Object.keys(unnest.columns));
2392
+ }
2393
+ if (typeof source === "object" && source !== null && source.kind === "tableFunction") {
2394
+ const tableFunction = source;
2395
+ if (dialect.name !== "postgres") {
2396
+ throw new Error("Unsupported table function source for SQL rendering");
2397
+ }
2398
+ const columnNames = Object.keys(tableFunction.columns);
2399
+ return `${tableFunction.functionName}(${tableFunction.args.map((arg) => renderExpression(arg, state, dialect)).join(", ")}) as ${dialect.quoteIdentifier(tableFunction.name)}(${columnNames.map((columnName) => dialect.quoteIdentifier(columnName)).join(", ")})`;
2400
+ }
2401
+ const schemaName = typeof source === "object" && source !== null && TypeId4 in source ? source[TypeId4].schemaName : undefined;
2402
+ return dialect.renderTableReference(tableName, baseTableName, schemaName);
2403
+ };
2404
+ var renderExpression = (expression, state, dialect) => {
2405
+ const rawAst = expression[TypeId3];
2406
+ const jsonSql = renderJsonExpression(expression, rawAst, state, dialect);
2407
+ if (jsonSql !== undefined) {
2408
+ return jsonSql;
2409
+ }
2410
+ const ast = rawAst;
2411
+ const renderComparisonOperator = (operator) => operator === "eq" ? "=" : operator === "neq" ? "<>" : operator === "lt" ? "<" : operator === "lte" ? "<=" : operator === "gt" ? ">" : ">=";
2412
+ switch (ast.kind) {
2413
+ case "column":
2414
+ return ast.tableName.length === 0 ? dialect.quoteIdentifier(ast.columnName) : `${dialect.quoteIdentifier(ast.tableName)}.${dialect.quoteIdentifier(ast.columnName)}`;
2415
+ case "literal":
2416
+ return dialect.renderLiteral(ast.value, state);
2417
+ case "excluded":
2418
+ return dialect.name === "mysql" ? `values(${dialect.quoteIdentifier(ast.columnName)})` : `excluded.${dialect.quoteIdentifier(ast.columnName)}`;
2419
+ case "cast":
2420
+ return `cast(${renderExpression(ast.value, state, dialect)} as ${renderCastType(dialect, ast.target)})`;
2421
+ case "collate":
2422
+ return `(${renderExpression(ast.value, state, dialect)} collate ${ast.collation.map((segment) => dialect.quoteIdentifier(segment)).join(".")})`;
2423
+ case "function":
2424
+ return renderFunctionCall(ast.name, Array.isArray(ast.args) ? ast.args : [], state, dialect);
2425
+ case "eq":
2426
+ return `(${renderExpression(ast.left, state, dialect)} = ${renderExpression(ast.right, state, dialect)})`;
2427
+ case "neq":
2428
+ return `(${renderExpression(ast.left, state, dialect)} <> ${renderExpression(ast.right, state, dialect)})`;
2429
+ case "lt":
2430
+ return `(${renderExpression(ast.left, state, dialect)} < ${renderExpression(ast.right, state, dialect)})`;
2431
+ case "lte":
2432
+ return `(${renderExpression(ast.left, state, dialect)} <= ${renderExpression(ast.right, state, dialect)})`;
2433
+ case "gt":
2434
+ return `(${renderExpression(ast.left, state, dialect)} > ${renderExpression(ast.right, state, dialect)})`;
2435
+ case "gte":
2436
+ return `(${renderExpression(ast.left, state, dialect)} >= ${renderExpression(ast.right, state, dialect)})`;
2437
+ case "like":
2438
+ return `(${renderExpression(ast.left, state, dialect)} like ${renderExpression(ast.right, state, dialect)})`;
2439
+ case "ilike":
2440
+ 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)}))`;
2441
+ case "regexMatch":
2442
+ 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)})`;
2443
+ case "regexIMatch":
2444
+ 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)})`;
2445
+ case "regexNotMatch":
2446
+ 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)})`;
2447
+ case "regexNotIMatch":
2448
+ 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)})`;
2449
+ case "isDistinctFrom":
2450
+ 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)})`;
2451
+ case "isNotDistinctFrom":
2452
+ 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)})`;
2453
+ case "contains":
2454
+ if (dialect.name === "postgres") {
2455
+ const left = isJsonExpression(ast.left) ? renderPostgresJsonValue(ast.left, state, dialect) : renderExpression(ast.left, state, dialect);
2456
+ const right = isJsonExpression(ast.right) ? renderPostgresJsonValue(ast.right, state, dialect) : renderExpression(ast.right, state, dialect);
2457
+ return `(${left} @> ${right})`;
2458
+ }
2459
+ if (dialect.name === "mysql" && isJsonExpression(ast.left) && isJsonExpression(ast.right)) {
2460
+ return `json_contains(${renderExpression(ast.left, state, dialect)}, ${renderExpression(ast.right, state, dialect)})`;
2461
+ }
2462
+ throw new Error("Unsupported container operator for SQL rendering");
2463
+ case "containedBy":
2464
+ if (dialect.name === "postgres") {
2465
+ const left = isJsonExpression(ast.left) ? renderPostgresJsonValue(ast.left, state, dialect) : renderExpression(ast.left, state, dialect);
2466
+ const right = isJsonExpression(ast.right) ? renderPostgresJsonValue(ast.right, state, dialect) : renderExpression(ast.right, state, dialect);
2467
+ return `(${left} <@ ${right})`;
2468
+ }
2469
+ if (dialect.name === "mysql" && isJsonExpression(ast.left) && isJsonExpression(ast.right)) {
2470
+ return `json_contains(${renderExpression(ast.right, state, dialect)}, ${renderExpression(ast.left, state, dialect)})`;
2471
+ }
2472
+ throw new Error("Unsupported container operator for SQL rendering");
2473
+ case "overlaps":
2474
+ if (dialect.name === "postgres") {
2475
+ const left = isJsonExpression(ast.left) ? renderPostgresJsonValue(ast.left, state, dialect) : renderExpression(ast.left, state, dialect);
2476
+ const right = isJsonExpression(ast.right) ? renderPostgresJsonValue(ast.right, state, dialect) : renderExpression(ast.right, state, dialect);
2477
+ return `(${left} && ${right})`;
2478
+ }
2479
+ if (dialect.name === "mysql" && isJsonExpression(ast.left) && isJsonExpression(ast.right)) {
2480
+ return `json_overlaps(${renderExpression(ast.left, state, dialect)}, ${renderExpression(ast.right, state, dialect)})`;
2481
+ }
2482
+ throw new Error("Unsupported container operator for SQL rendering");
2483
+ case "isNull":
2484
+ return `(${renderExpression(ast.value, state, dialect)} is null)`;
2485
+ case "isNotNull":
2486
+ return `(${renderExpression(ast.value, state, dialect)} is not null)`;
2487
+ case "not":
2488
+ return `(not ${renderExpression(ast.value, state, dialect)})`;
2489
+ case "upper":
2490
+ return `upper(${renderExpression(ast.value, state, dialect)})`;
2491
+ case "lower":
2492
+ return `lower(${renderExpression(ast.value, state, dialect)})`;
2493
+ case "count":
2494
+ return `count(${renderExpression(ast.value, state, dialect)})`;
2495
+ case "max":
2496
+ return `max(${renderExpression(ast.value, state, dialect)})`;
2497
+ case "min":
2498
+ return `min(${renderExpression(ast.value, state, dialect)})`;
2499
+ case "and":
2500
+ return `(${ast.values.map((value) => renderExpression(value, state, dialect)).join(" and ")})`;
2501
+ case "or":
2502
+ return `(${ast.values.map((value) => renderExpression(value, state, dialect)).join(" or ")})`;
2503
+ case "coalesce":
2504
+ return `coalesce(${ast.values.map((value) => renderExpression(value, state, dialect)).join(", ")})`;
2505
+ case "in":
2506
+ return `(${renderExpression(ast.values[0], state, dialect)} in (${ast.values.slice(1).map((value) => renderExpression(value, state, dialect)).join(", ")}))`;
2507
+ case "notIn":
2508
+ return `(${renderExpression(ast.values[0], state, dialect)} not in (${ast.values.slice(1).map((value) => renderExpression(value, state, dialect)).join(", ")}))`;
2509
+ case "between":
2510
+ return `(${renderExpression(ast.values[0], state, dialect)} between ${renderExpression(ast.values[1], state, dialect)} and ${renderExpression(ast.values[2], state, dialect)})`;
2511
+ case "concat":
2512
+ return dialect.renderConcat(ast.values.map((value) => renderExpression(value, state, dialect)));
2513
+ case "case":
2514
+ 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`;
2515
+ case "exists":
2516
+ return `exists (${renderQueryAst(getAst(ast.plan), state, dialect).sql})`;
2517
+ case "scalarSubquery":
2518
+ return `(${renderQueryAst(getAst(ast.plan), state, dialect).sql})`;
2519
+ case "inSubquery":
2520
+ return `(${renderExpression(ast.left, state, dialect)} in (${renderQueryAst(getAst(ast.plan), state, dialect).sql}))`;
2521
+ case "comparisonAny":
2522
+ return `(${renderExpression(ast.left, state, dialect)} ${renderComparisonOperator(ast.operator)} any (${renderQueryAst(getAst(ast.plan), state, dialect).sql}))`;
2523
+ case "comparisonAll":
2524
+ return `(${renderExpression(ast.left, state, dialect)} ${renderComparisonOperator(ast.operator)} all (${renderQueryAst(getAst(ast.plan), state, dialect).sql}))`;
2525
+ case "window": {
2526
+ if (!Array.isArray(ast.partitionBy) || !Array.isArray(ast.orderBy) || typeof ast.function !== "string") {
2527
+ break;
2528
+ }
2529
+ const clauses = [];
2530
+ if (ast.partitionBy.length > 0) {
2531
+ clauses.push(`partition by ${ast.partitionBy.map((value) => renderExpression(value, state, dialect)).join(", ")}`);
2532
+ }
2533
+ if (ast.orderBy.length > 0) {
2534
+ clauses.push(`order by ${ast.orderBy.map((entry) => `${renderExpression(entry.value, state, dialect)} ${entry.direction}`).join(", ")}`);
2535
+ }
2536
+ const specification = clauses.join(" ");
2537
+ switch (ast.function) {
2538
+ case "rowNumber":
2539
+ return `row_number() over (${specification})`;
2540
+ case "rank":
2541
+ return `rank() over (${specification})`;
2542
+ case "denseRank":
2543
+ return `dense_rank() over (${specification})`;
2544
+ case "over":
2545
+ return `${renderExpression(ast.value, state, dialect)} over (${specification})`;
2546
+ }
2547
+ break;
2548
+ }
2549
+ }
2550
+ throw new Error("Unsupported expression for SQL rendering");
2551
+ };
2552
+
2553
+ // src/postgres/internal/schema-ddl.ts
2554
+ import { parse as parse2, toSql as toSql2 } from "pgsql-ast-parser";
2555
+
2556
+ // src/postgres/internal/dialect.ts
2557
+ var quoteIdentifier = (value) => `"${value.replaceAll('"', '""')}"`;
2558
+ var renderLiteral = (value, state) => {
2559
+ if (value === null) {
2560
+ return "null";
2561
+ }
2562
+ if (typeof value === "boolean") {
2563
+ return value ? "true" : "false";
2564
+ }
2565
+ state.params.push(value);
2566
+ return `$${state.params.length}`;
2567
+ };
2568
+ var postgresDialect = {
2569
+ name: "postgres",
2570
+ quoteIdentifier,
2571
+ renderLiteral,
2572
+ renderTableReference(tableName, baseTableName, schemaName) {
2573
+ const renderedBase = schemaName ? `${quoteIdentifier(schemaName)}.${quoteIdentifier(baseTableName)}` : quoteIdentifier(baseTableName);
2574
+ return tableName === baseTableName ? renderedBase : `${renderedBase} as ${quoteIdentifier(tableName)}`;
2575
+ },
2576
+ renderConcat(values) {
2577
+ return `(${values.join(" || ")})`;
2578
+ }
2579
+ };
2580
+
2581
+ // src/postgres/internal/schema-ddl.ts
2582
+ var escapeString = (value) => `'${value.replaceAll("'", "''")}'`;
2583
+ var inlineLiteralDialect = {
2584
+ ...postgresDialect,
2585
+ renderLiteral(value) {
2586
+ if (value === null) {
2587
+ return "null";
2588
+ }
2589
+ if (typeof value === "boolean") {
2590
+ return value ? "true" : "false";
2591
+ }
2592
+ if (typeof value === "number" || typeof value === "bigint") {
2593
+ return String(value);
2594
+ }
2595
+ if (value instanceof Date) {
2596
+ return escapeString(value.toISOString());
2597
+ }
2598
+ return escapeString(String(value));
2599
+ }
2600
+ };
2601
+ var renderDdlExpressionSql = (expression) => isSchemaExpression(expression) ? render(expression) : renderExpression(expression, {
2602
+ params: [],
2603
+ ctes: [],
2604
+ cteNames: new Set
2605
+ }, inlineLiteralDialect);
2606
+ var stripRedundantOuterParens = (value) => {
2607
+ let current = value.trim();
2608
+ while (current.startsWith("(") && current.endsWith(")")) {
2609
+ let depth = 0;
2610
+ let wrapsWholeExpression = true;
2611
+ let inSingleQuote = false;
2612
+ let inDoubleQuote = false;
2613
+ for (let index3 = 0;index3 < current.length; index3++) {
2614
+ const char = current[index3];
2615
+ const previous = index3 > 0 ? current[index3 - 1] : undefined;
2616
+ if (char === "'" && !inDoubleQuote && previous !== "\\") {
2617
+ inSingleQuote = !inSingleQuote;
2618
+ continue;
2619
+ }
2620
+ if (char === '"' && !inSingleQuote && previous !== "\\") {
2621
+ inDoubleQuote = !inDoubleQuote;
2622
+ continue;
2623
+ }
2624
+ if (inSingleQuote || inDoubleQuote) {
2625
+ continue;
2626
+ }
2627
+ if (char === "(") {
2628
+ depth += 1;
2629
+ } else if (char === ")") {
2630
+ depth -= 1;
2631
+ if (depth === 0 && index3 < current.length - 1) {
2632
+ wrapsWholeExpression = false;
2633
+ break;
2634
+ }
2635
+ }
2636
+ }
2637
+ if (!wrapsWholeExpression) {
2638
+ break;
2639
+ }
2640
+ current = current.slice(1, -1).trim();
2641
+ }
2642
+ return current;
2643
+ };
2644
+ 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()}`));
2645
+ var normalizeDdlExpressionSql = (expression) => {
2646
+ const rendered = renderDdlExpressionSql(expression);
2647
+ try {
2648
+ return canonicalizeDdlExpressionSql(toSql2.expr(parse2(rendered, "expr")));
2649
+ } catch {
2650
+ return canonicalizeDdlExpressionSql(rendered);
2651
+ }
2652
+ };
2653
+
2654
+ // src/postgres/schema-management.ts
2655
+ import * as Schema3 from "effect/Schema";
2656
+ import { pipeArguments as pipeArguments5 } from "effect/Pipeable";
2657
+ var EnumTypeId = Symbol.for("effect-qb/SchemaManagement/Enum");
2658
+ var SequenceTypeId = Symbol.for("effect-qb/SchemaManagement/Sequence");
2659
+ var EnumProto = {
2660
+ pipe() {
2661
+ return pipeArguments5(this, arguments);
2662
+ },
2663
+ qualifiedName() {
2664
+ return this.schemaName === undefined || this.schemaName === "public" ? this.name : `${this.schemaName}.${this.name}`;
2665
+ },
2666
+ type() {
2667
+ return {
2668
+ dialect: "postgres",
2669
+ kind: this.qualifiedName(),
2670
+ variant: "enum"
2671
+ };
2672
+ },
2673
+ column() {
2674
+ const values = this.values.map((value) => Schema3.Literal(value));
2675
+ return makeColumnDefinition(values.length === 1 ? values[0] : Schema3.Union(...values), {
2676
+ dbType: this.type(),
2677
+ nullable: false,
2678
+ hasDefault: false,
2679
+ generated: false,
2680
+ primaryKey: false,
2681
+ unique: false,
2682
+ references: undefined,
2683
+ ddlType: this.qualifiedName(),
2684
+ identity: undefined,
2685
+ enum: {
2686
+ name: this.name,
2687
+ schemaName: this.schemaName,
2688
+ values: this.values
2689
+ }
2690
+ });
2691
+ }
2692
+ };
2693
+ var SequenceProto = {
2694
+ pipe() {
2695
+ return pipeArguments5(this, arguments);
2696
+ },
2697
+ qualifiedName() {
2698
+ return this.schemaName === undefined || this.schemaName === "public" ? this.name : `${this.schemaName}.${this.name}`;
2699
+ }
2700
+ };
2701
+ function enumType(name, values, schemaName) {
2702
+ const definition = Object.create(EnumProto);
2703
+ definition.name = name;
2704
+ definition.values = values;
2705
+ definition.schemaName = schemaName;
2706
+ definition[EnumTypeId] = {
2707
+ kind: "enum",
2708
+ name,
2709
+ values,
2710
+ schemaName
2711
+ };
2712
+ return definition;
2713
+ }
2714
+ function sequence(name, schemaName) {
2715
+ const definition = Object.create(SequenceProto);
2716
+ definition.name = name;
2717
+ definition.schemaName = schemaName;
2718
+ definition[SequenceTypeId] = {
2719
+ kind: "sequence",
2720
+ name,
2721
+ schemaName
2722
+ };
2723
+ return definition;
2724
+ }
2725
+ var isSequenceDefinition = (value) => typeof value === "object" && value !== null && (SequenceTypeId in value);
2726
+
2727
+ // src/postgres/internal/schema-model.ts
2728
+ var isTableDefinition = (value) => value !== null && (typeof value === "object" || typeof value === "function") && (TypeId4 in value);
2729
+ var isEnumDefinition = (value) => typeof value === "object" && value !== null && (EnumTypeId in value);
2730
+ var toTableModel = (table) => {
2731
+ const state = table[TypeId4];
2732
+ const fields = state.fields;
2733
+ const columns = Object.entries(fields).map(([name, column]) => {
2734
+ const metadata = column.metadata;
2735
+ const enumDefinition = metadata.enum;
2736
+ const ddlType = metadata.ddlType ?? metadata.dbType.kind;
2737
+ return {
2738
+ name,
2739
+ ddlType,
2740
+ dbTypeKind: enumDefinition?.name ?? column.metadata.dbType.kind,
2741
+ typeKind: enumDefinition === undefined ? undefined : "e",
2742
+ typeSchema: enumDefinition?.schemaName,
2743
+ nullable: column.metadata.nullable,
2744
+ hasDefault: column.metadata.hasDefault,
2745
+ generated: column.metadata.generated,
2746
+ defaultSql: column.metadata.defaultValue === undefined ? undefined : normalizeDdlExpressionSql(column.metadata.defaultValue),
2747
+ generatedSql: column.metadata.generatedValue === undefined ? undefined : normalizeDdlExpressionSql(column.metadata.generatedValue),
2748
+ identity: column.metadata.identity,
2749
+ column
2750
+ };
2751
+ });
2752
+ return {
2753
+ kind: "table",
2754
+ schemaName: state.schemaName,
2755
+ name: state.baseName,
2756
+ columns,
2757
+ options: table[OptionsSymbol],
2758
+ table
2759
+ };
2760
+ };
2761
+ var toEnumModel = (definition) => ({
2762
+ kind: "enum",
2763
+ schemaName: definition.schemaName,
2764
+ name: definition.name,
2765
+ values: [...definition.values]
2766
+ });
2767
+ var enumModelsOfTable = (table) => {
2768
+ const state = table[TypeId4];
2769
+ const fields = state.fields;
2770
+ return Object.values(fields).flatMap((column) => column.metadata.enum === undefined ? [] : [
2771
+ {
2772
+ kind: "enum",
2773
+ schemaName: column.metadata.enum.schemaName,
2774
+ name: column.metadata.enum.name,
2775
+ values: [...column.metadata.enum.values]
2776
+ }
2777
+ ]);
2778
+ };
2779
+ var fromDiscoveredValues = (values) => {
2780
+ const tables = values.filter(isTableDefinition).map(toTableModel);
2781
+ const enums = new Map;
2782
+ for (const value of values) {
2783
+ if (isEnumDefinition(value)) {
2784
+ enums.set(enumKey(value.schemaName, value.name), toEnumModel(value));
2785
+ } else if (isTableDefinition(value)) {
2786
+ for (const enumModel of enumModelsOfTable(value)) {
2787
+ const key2 = enumKey(enumModel.schemaName, enumModel.name);
2788
+ const existing = enums.get(key2);
2789
+ if (existing === undefined) {
2790
+ enums.set(key2, enumModel);
2791
+ continue;
2792
+ }
2793
+ if (JSON.stringify(existing.values) !== JSON.stringify(enumModel.values)) {
2794
+ throw new Error(`Conflicting enum definitions discovered for '${key2}'`);
2795
+ }
2796
+ }
2797
+ }
2798
+ }
2799
+ return {
2800
+ dialect: "postgres",
2801
+ enums: [...enums.values()],
2802
+ tables
2803
+ };
2804
+ };
2805
+ var tableKey = (schemaName, name) => `${schemaName ?? "public"}.${name}`;
2806
+ var enumKey = (schemaName, name) => `${schemaName ?? "public"}.${name}`;
2807
+ export {
2808
+ toTableModel,
2809
+ toEnumModel,
2810
+ tableKey,
2811
+ renderDdlExpressionSql,
2812
+ normalizeDdlExpressionSql,
2813
+ isTableDefinition,
2814
+ isEnumDefinition,
2815
+ fromDiscoveredValues,
2816
+ enumKey,
2817
+ EnumTypeId
2818
+ };