effect-qb 0.14.0 → 0.16.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/dist/mysql.js +61555 -4252
  2. package/dist/postgres/metadata.js +728 -104
  3. package/dist/postgres.js +6906 -4023
  4. package/package.json +15 -2
  5. package/src/internal/aggregation-validation.ts +3 -3
  6. package/src/internal/case-analysis.d.ts +18 -0
  7. package/src/internal/case-analysis.ts +4 -4
  8. package/src/internal/coercion/analysis.d.ts +7 -0
  9. package/src/internal/{coercion-analysis.ts → coercion/analysis.ts} +3 -3
  10. package/src/internal/coercion/errors.d.ts +17 -0
  11. package/src/internal/{coercion-errors.ts → coercion/errors.ts} +1 -1
  12. package/src/internal/coercion/kind.d.ts +4 -0
  13. package/src/internal/{coercion-kind.ts → coercion/kind.ts} +2 -2
  14. package/src/internal/{coercion-normalize.ts → coercion/normalize.ts} +1 -1
  15. package/src/internal/coercion/rules.d.ts +6 -0
  16. package/src/internal/{coercion-rules.ts → coercion/rules.ts} +2 -2
  17. package/src/internal/column-state.d.ts +190 -0
  18. package/src/internal/column-state.ts +43 -47
  19. package/src/internal/column.ts +43 -305
  20. package/src/internal/datatypes/define.d.ts +17 -0
  21. package/src/internal/datatypes/define.ts +18 -4
  22. package/src/internal/datatypes/lookup.d.ts +44 -0
  23. package/src/internal/datatypes/lookup.ts +61 -152
  24. package/src/internal/datatypes/shape.d.ts +16 -0
  25. package/src/internal/datatypes/shape.ts +1 -1
  26. package/src/internal/derived-table.d.ts +4 -0
  27. package/src/internal/derived-table.ts +21 -16
  28. package/src/internal/dialect.ts +12 -1
  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 +146 -34
  34. package/src/internal/expression-ast.ts +15 -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 +4 -4
  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 +183 -0
  47. package/src/internal/predicate/atom.d.ts +28 -0
  48. package/src/internal/{predicate-atom.ts → predicate/atom.ts} +7 -0
  49. package/src/internal/{predicate-branches.ts → predicate/branches.ts} +2 -2
  50. package/src/internal/predicate/context.d.ts +67 -0
  51. package/src/internal/{predicate-context.ts → predicate/context.ts} +163 -20
  52. package/src/internal/predicate/formula.d.ts +35 -0
  53. package/src/internal/{predicate-formula.ts → predicate/formula.ts} +1 -1
  54. package/src/internal/predicate/key.d.ts +11 -0
  55. package/src/internal/predicate/key.ts +73 -0
  56. package/src/internal/{predicate-nnf.ts → predicate/nnf.ts} +2 -2
  57. package/src/internal/predicate/normalize.d.ts +53 -0
  58. package/src/internal/{predicate-normalize.ts → predicate/normalize.ts} +130 -49
  59. package/src/internal/predicate/runtime.d.ts +31 -0
  60. package/src/internal/{predicate-runtime.ts → predicate/runtime.ts} +127 -17
  61. package/src/internal/projection-alias.d.ts +13 -0
  62. package/src/internal/projections.d.ts +31 -0
  63. package/src/internal/projections.ts +1 -1
  64. package/src/internal/query-ast.d.ts +217 -0
  65. package/src/internal/query-ast.ts +1 -1
  66. package/src/internal/query-requirements.d.ts +20 -0
  67. package/src/internal/query.d.ts +775 -0
  68. package/src/internal/query.ts +683 -369
  69. package/src/internal/renderer.ts +11 -21
  70. package/src/internal/row-set.d.ts +53 -0
  71. package/src/internal/{plan.ts → row-set.ts} +11 -9
  72. package/src/internal/runtime/driver-value-mapping.ts +186 -0
  73. package/src/internal/{runtime-normalize.ts → runtime/normalize.ts} +9 -31
  74. package/src/internal/{runtime-schema.ts → runtime/schema.ts} +13 -38
  75. package/src/internal/runtime/value.d.ts +22 -0
  76. package/src/internal/{runtime-value.ts → runtime/value.ts} +2 -2
  77. package/src/internal/scalar.d.ts +107 -0
  78. package/src/internal/scalar.ts +202 -0
  79. package/src/internal/schema-derivation.d.ts +105 -0
  80. package/src/internal/schema-expression.d.ts +18 -0
  81. package/src/internal/schema-expression.ts +38 -7
  82. package/src/internal/table-options.d.ts +94 -0
  83. package/src/internal/table-options.ts +8 -2
  84. package/src/internal/table.d.ts +173 -0
  85. package/src/internal/table.ts +32 -14
  86. package/src/mysql/column.ts +95 -18
  87. package/src/mysql/datatypes/index.ts +47 -7
  88. package/src/mysql/errors/generated.ts +57336 -0
  89. package/src/mysql/errors/index.ts +1 -0
  90. package/src/mysql/errors/normalize.ts +55 -53
  91. package/src/mysql/errors/types.ts +74 -0
  92. package/src/mysql/executor.ts +88 -11
  93. package/src/mysql/function/aggregate.ts +1 -5
  94. package/src/mysql/function/core.ts +1 -4
  95. package/src/mysql/function/index.ts +0 -1
  96. package/src/mysql/function/string.ts +1 -5
  97. package/src/mysql/function/temporal.ts +12 -15
  98. package/src/mysql/function/window.ts +1 -6
  99. package/src/{internal/mysql-dialect.ts → mysql/internal/dialect.ts} +12 -6
  100. package/src/{internal/mysql-query.ts → mysql/internal/dsl.ts} +1299 -2143
  101. package/src/mysql/internal/renderer.ts +46 -0
  102. package/src/mysql/internal/sql-expression-renderer.ts +1501 -0
  103. package/src/mysql/json.ts +2 -0
  104. package/src/mysql/query.ts +111 -91
  105. package/src/mysql/renderer.ts +8 -3
  106. package/src/mysql/table.ts +1 -1
  107. package/src/mysql.ts +6 -4
  108. package/src/postgres/cast.ts +30 -16
  109. package/src/postgres/column.ts +179 -46
  110. package/src/postgres/datatypes/index.d.ts +515 -0
  111. package/src/postgres/datatypes/index.ts +22 -13
  112. package/src/postgres/datatypes/spec.d.ts +412 -0
  113. package/src/postgres/errors/generated.ts +2636 -0
  114. package/src/postgres/errors/index.ts +1 -0
  115. package/src/postgres/errors/normalize.ts +47 -62
  116. package/src/postgres/errors/types.ts +92 -34
  117. package/src/postgres/executor.ts +54 -7
  118. package/src/postgres/function/aggregate.ts +1 -5
  119. package/src/postgres/function/core.ts +12 -6
  120. package/src/postgres/function/index.ts +0 -1
  121. package/src/postgres/function/string.ts +1 -5
  122. package/src/postgres/function/temporal.ts +12 -15
  123. package/src/postgres/function/window.ts +1 -6
  124. package/src/{internal/postgres-dialect.ts → postgres/internal/dialect.ts} +12 -6
  125. package/src/{internal/postgres-query.ts → postgres/internal/dsl.ts} +1356 -2133
  126. package/src/{internal/postgres-renderer.ts → postgres/internal/renderer.ts} +17 -8
  127. package/src/postgres/internal/schema-ddl.ts +108 -0
  128. package/src/{internal/postgres-schema-model.ts → postgres/internal/schema-model.ts} +12 -6
  129. package/src/{internal → postgres/internal}/sql-expression-renderer.ts +79 -25
  130. package/src/postgres/{function/json.ts → json.ts} +77 -85
  131. package/src/postgres/metadata.ts +2 -2
  132. package/src/postgres/query.ts +113 -89
  133. package/src/postgres/renderer.ts +8 -13
  134. package/src/postgres/schema-expression.ts +2 -1
  135. package/src/postgres/schema-management.ts +1 -1
  136. package/src/postgres/table.ts +12 -4
  137. package/src/postgres/type.ts +33 -2
  138. package/src/postgres.ts +6 -4
  139. package/src/internal/expression.ts +0 -327
  140. package/src/internal/mysql-renderer.ts +0 -37
  141. package/src/internal/predicate-analysis.ts +0 -81
  142. package/src/internal/predicate-key.ts +0 -28
  143. package/src/internal/schema-ddl.ts +0 -55
  144. package/src/mysql/function/json.ts +0 -4
  145. package/src/mysql/private/query.ts +0 -1
  146. package/src/postgres/private/query.ts +0 -1
@@ -1,7 +1,8 @@
1
- import * as Query from "./query.js"
2
- import { type RenderState } from "./dialect.js"
3
- import { postgresDialect } from "./postgres-dialect.js"
4
- import { type Projection } from "./projections.js"
1
+ import * as Query from "../../internal/query.js"
2
+ import type * as Expression from "../../internal/scalar.js"
3
+ import { type RenderState } from "../../internal/dialect.js"
4
+ import { postgresDialect } from "./dialect.js"
5
+ import { type Projection } from "../../internal/projections.js"
5
6
  import { renderQueryAst } from "./sql-expression-renderer.js"
6
7
 
7
8
  /**
@@ -14,27 +15,35 @@ export interface PostgresRenderResult {
14
15
  readonly sql: string
15
16
  readonly params: readonly unknown[]
16
17
  readonly projections: readonly Projection[]
18
+ readonly valueMappings?: Expression.DriverValueMappings
19
+ }
20
+
21
+ export interface PostgresRenderOptions {
22
+ readonly valueMappings?: Expression.DriverValueMappings
17
23
  }
18
24
 
19
25
  /**
20
26
  * Renders the current query AST into Postgres SQL plus bind parameters.
21
27
  */
22
- export const renderPostgresPlan = <PlanValue extends Query.QueryPlan<any, any, any, any, any, any, any, any, any, any>>(
23
- plan: Query.DialectCompatiblePlan<PlanValue, "postgres">
28
+ export const renderPostgresPlan = <PlanValue extends Query.Plan.Any>(
29
+ plan: Query.DialectCompatiblePlan<PlanValue, "postgres">,
30
+ options: PostgresRenderOptions = {}
24
31
  ): PostgresRenderResult => {
25
32
  const state: RenderState = {
26
33
  params: [],
34
+ valueMappings: options.valueMappings,
27
35
  ctes: [],
28
36
  cteNames: new Set<string>()
29
37
  }
30
38
  const rendered = renderQueryAst(
31
- Query.getAst(plan as Query.QueryPlan<any, any, any, any, any, any, any, any, any, any>) as any,
39
+ Query.getAst(plan as Query.Plan.Any) as any,
32
40
  state,
33
41
  postgresDialect
34
42
  )
35
43
  return {
36
44
  sql: rendered.sql,
37
45
  params: state.params,
38
- projections: rendered.projections
46
+ projections: rendered.projections,
47
+ valueMappings: state.valueMappings
39
48
  }
40
49
  }
@@ -0,0 +1,108 @@
1
+ import type * as Expression from "../../internal/scalar.js"
2
+ import type { RenderState, SqlDialect } from "../../internal/dialect.js"
3
+ import * as SchemaExpression from "../../internal/schema-expression.js"
4
+ import { renderExpression } from "./sql-expression-renderer.js"
5
+ import type { DdlExpressionLike } from "../../internal/table-options.js"
6
+ import { parse, toSql } from "pgsql-ast-parser"
7
+ import { postgresDialect } from "./dialect.js"
8
+
9
+ export const renderDdlExpression = (
10
+ expression: DdlExpressionLike,
11
+ state: RenderState,
12
+ dialect: SqlDialect
13
+ ): string =>
14
+ SchemaExpression.isSchemaExpression(expression)
15
+ ? SchemaExpression.render(expression)
16
+ : renderExpression(expression as Expression.Any, state, dialect)
17
+
18
+ const escapeString = (value: string): string => `'${value.replaceAll("'", "''")}'`
19
+
20
+ const inlineLiteralDialect: SqlDialect<"postgres"> = {
21
+ ...postgresDialect,
22
+ renderLiteral(value) {
23
+ if (value === null) {
24
+ return "null"
25
+ }
26
+ if (typeof value === "boolean") {
27
+ return value ? "true" : "false"
28
+ }
29
+ if (typeof value === "number" || typeof value === "bigint") {
30
+ return String(value)
31
+ }
32
+ if (value instanceof Date) {
33
+ return escapeString(value.toISOString())
34
+ }
35
+ return escapeString(String(value))
36
+ }
37
+ }
38
+
39
+ export const renderDdlExpressionSql = (expression: DdlExpressionLike): string =>
40
+ SchemaExpression.isSchemaExpression(expression)
41
+ ? SchemaExpression.render(expression)
42
+ : renderExpression(expression as Expression.Any, {
43
+ params: [],
44
+ ctes: [],
45
+ cteNames: new Set()
46
+ }, inlineLiteralDialect)
47
+
48
+ const stripRedundantOuterParens = (value: string): string => {
49
+ let current = value.trim()
50
+ while (current.startsWith("(") && current.endsWith(")")) {
51
+ let depth = 0
52
+ let wrapsWholeExpression = true
53
+ let inSingleQuote = false
54
+ let inDoubleQuote = false
55
+ for (let index = 0; index < current.length; index++) {
56
+ const char = current[index]!
57
+ const previous = index > 0 ? current[index - 1] : undefined
58
+ if (char === "'" && !inDoubleQuote && previous !== "\\") {
59
+ inSingleQuote = !inSingleQuote
60
+ continue
61
+ }
62
+ if (char === "\"" && !inSingleQuote && previous !== "\\") {
63
+ inDoubleQuote = !inDoubleQuote
64
+ continue
65
+ }
66
+ if (inSingleQuote || inDoubleQuote) {
67
+ continue
68
+ }
69
+ if (char === "(") {
70
+ depth += 1
71
+ } else if (char === ")") {
72
+ depth -= 1
73
+ if (depth === 0 && index < current.length - 1) {
74
+ wrapsWholeExpression = false
75
+ break
76
+ }
77
+ }
78
+ }
79
+ if (!wrapsWholeExpression) {
80
+ break
81
+ }
82
+ current = current.slice(1, -1).trim()
83
+ }
84
+ return current
85
+ }
86
+
87
+ const canonicalizeDdlExpressionSql = (value: string): string =>
88
+ stripRedundantOuterParens(
89
+ value
90
+ .trim()
91
+ .replace(/\s+/g, " ")
92
+ .replace(/"[^"]+"\./g, "")
93
+ .replace(/"([A-Za-z_][A-Za-z0-9_]*)"/g, "$1")
94
+ .replace(/\bCOLLATE\b/g, "collate")
95
+ .replace(
96
+ /cast\(((?:'(?:[^']|'')*'|"[^"]+"|[a-zA-Z_][a-zA-Z0-9_]*|\([^()]+\))) as ([^)]+)\)/gi,
97
+ (_, expression: string, target: string) => `${expression}::${target.trim()}`
98
+ )
99
+ )
100
+
101
+ export const normalizeDdlExpressionSql = (expression: DdlExpressionLike): string => {
102
+ const rendered = renderDdlExpressionSql(expression)
103
+ try {
104
+ return canonicalizeDdlExpressionSql(toSql.expr(parse(rendered, "expr")))
105
+ } catch {
106
+ return canonicalizeDdlExpressionSql(rendered)
107
+ }
108
+ }
@@ -1,9 +1,9 @@
1
- import * as Table from "./table.js"
2
- import type { AnyColumnDefinition } from "./column-state.js"
1
+ import * as Table from "../../internal/table.js"
2
+ import type { AnyColumnDefinition } from "../../internal/column-state.js"
3
3
  import { normalizeDdlExpressionSql } from "./schema-ddl.js"
4
- import type { TableOptionSpec } from "./table-options.js"
5
- import type { EnumDefinition } from "../postgres/schema-management.js"
6
- import { EnumTypeId } from "../postgres/schema-management.js"
4
+ import type { TableOptionSpec } from "../../internal/table-options.js"
5
+ import type { EnumDefinition } from "../schema-management.js"
6
+ import { EnumTypeId } from "../schema-management.js"
7
7
 
8
8
  export interface EnumModel {
9
9
  readonly kind: "enum"
@@ -88,7 +88,13 @@ export const toTableModel = (table: Table.AnyTable): TableModel => {
88
88
  }
89
89
  }
90
90
 
91
- export const toEnumModel = (definition: EnumDefinition): EnumModel => ({
91
+ export const toEnumModel = <
92
+ Name extends string,
93
+ Values extends readonly [string, ...string[]],
94
+ SchemaName extends string | undefined
95
+ >(
96
+ definition: EnumDefinition<Name, Values, SchemaName>
97
+ ): EnumModel => ({
92
98
  kind: "enum",
93
99
  schemaName: definition.schemaName,
94
100
  name: definition.name,
@@ -1,14 +1,19 @@
1
- import * as Query from "./query.js"
2
- import * as Expression from "./expression.js"
3
- import * as Table from "./table.js"
4
- import * as QueryAst from "./query-ast.js"
5
- import type { RenderState, SqlDialect } from "./dialect.js"
6
- import * as ExpressionAst from "./expression-ast.js"
7
- import * as JsonPath from "./json/path.js"
8
- import { flattenSelection, type Projection } from "./projections.js"
9
- import { type SelectionValue, validateAggregationSelection } from "./aggregation-validation.js"
10
- import * as SchemaExpression from "./schema-expression.js"
11
- import type { DdlExpressionLike } from "./table-options.js"
1
+ import * as Query from "../../internal/query.js"
2
+ import * as Expression from "../../internal/scalar.js"
3
+ import * as Table from "../../internal/table.js"
4
+ import * as QueryAst from "../../internal/query-ast.js"
5
+ import type { RenderState, SqlDialect } from "../../internal/dialect.js"
6
+ import * as ExpressionAst from "../../internal/expression-ast.js"
7
+ import * as JsonPath from "../../internal/json/path.js"
8
+ import {
9
+ renderJsonSelectSql,
10
+ renderSelectSql,
11
+ toDriverValue
12
+ } from "../../internal/runtime/driver-value-mapping.js"
13
+ import { flattenSelection, type Projection } from "../../internal/projections.js"
14
+ import { type SelectionValue, validateAggregationSelection } from "../../internal/aggregation-validation.js"
15
+ import * as SchemaExpression from "../../internal/schema-expression.js"
16
+ import type { DdlExpressionLike } from "../../internal/table-options.js"
12
17
 
13
18
  const renderDbType = (
14
19
  dialect: SqlDialect,
@@ -294,11 +299,54 @@ const renderPostgresJsonValue = (
294
299
  throw new Error("Expected a JSON expression")
295
300
  }
296
301
  const rendered = renderExpression(value, state, dialect)
302
+ const ast = (value as Expression.Any & {
303
+ readonly [ExpressionAst.TypeId]: ExpressionAst.Any
304
+ })[ExpressionAst.TypeId]
305
+ if (ast.kind === "literal") {
306
+ return `cast(${rendered} as jsonb)`
307
+ }
297
308
  return value[Expression.TypeId].dbType.kind === "jsonb"
298
309
  ? rendered
299
310
  : `cast(${rendered} as jsonb)`
300
311
  }
301
312
 
313
+ const expressionDriverContext = (
314
+ expression: Expression.Any,
315
+ state: RenderState,
316
+ dialect: SqlDialect
317
+ ) => ({
318
+ dialect: dialect.name,
319
+ valueMappings: state.valueMappings,
320
+ dbType: expression[Expression.TypeId].dbType,
321
+ runtimeSchema: expression[Expression.TypeId].runtimeSchema,
322
+ driverValueMapping: expression[Expression.TypeId].driverValueMapping
323
+ })
324
+
325
+ const renderJsonInputExpression = (
326
+ expression: Expression.Any,
327
+ state: RenderState,
328
+ dialect: SqlDialect
329
+ ): string =>
330
+ renderJsonSelectSql(
331
+ renderExpression(expression, state, dialect),
332
+ expressionDriverContext(expression, state, dialect)
333
+ )
334
+
335
+ const encodeArrayValues = (
336
+ values: readonly unknown[],
337
+ column: Table.AnyTable[typeof Table.TypeId]["fields"][string],
338
+ state: RenderState,
339
+ dialect: SqlDialect
340
+ ): readonly unknown[] =>
341
+ values.map((value) =>
342
+ toDriverValue(value, {
343
+ dialect: dialect.name,
344
+ valueMappings: state.valueMappings,
345
+ dbType: column.metadata.dbType,
346
+ runtimeSchema: column.schema,
347
+ driverValueMapping: column.metadata.driverValueMapping
348
+ }))
349
+
302
350
  const renderPostgresJsonKind = (
303
351
  value: Expression.Any
304
352
  ): "json" | "jsonb" => value[Expression.TypeId].dbType.kind === "jsonb" ? "jsonb" : "json"
@@ -460,7 +508,7 @@ const renderJsonExpression = (
460
508
  : []
461
509
  const renderedEntries = entries.flatMap((entry) => [
462
510
  dialect.renderLiteral(entry.key, state),
463
- renderExpression(entry.value, state, dialect)
511
+ renderJsonInputExpression(entry.value, state, dialect)
464
512
  ])
465
513
  if (dialect.name === "postgres") {
466
514
  return `${postgresExpressionKind === "jsonb" ? "jsonb" : "json"}_build_object(${renderedEntries.join(", ")})`
@@ -474,7 +522,7 @@ const renderJsonExpression = (
474
522
  const values = Array.isArray((ast as { readonly values?: readonly Expression.Any[] }).values)
475
523
  ? (ast as { readonly values: readonly Expression.Any[] }).values
476
524
  : []
477
- const renderedValues = values.map((value) => renderExpression(value, state, dialect)).join(", ")
525
+ const renderedValues = values.map((value) => renderJsonInputExpression(value, state, dialect)).join(", ")
478
526
  if (dialect.name === "postgres") {
479
527
  return `${postgresExpressionKind === "jsonb" ? "jsonb" : "json"}_build_array(${renderedValues})`
480
528
  }
@@ -488,7 +536,7 @@ const renderJsonExpression = (
488
536
  return undefined
489
537
  }
490
538
  if (dialect.name === "postgres") {
491
- return `to_json(${renderExpression(base, state, dialect)})`
539
+ return `to_json(${renderJsonInputExpression(base, state, dialect)})`
492
540
  }
493
541
  if (dialect.name === "mysql") {
494
542
  return `cast(${renderExpression(base, state, dialect)} as json)`
@@ -499,7 +547,7 @@ const renderJsonExpression = (
499
547
  return undefined
500
548
  }
501
549
  if (dialect.name === "postgres") {
502
- return `to_jsonb(${renderExpression(base, state, dialect)})`
550
+ return `to_jsonb(${renderJsonInputExpression(base, state, dialect)})`
503
551
  }
504
552
  if (dialect.name === "mysql") {
505
553
  return `cast(${renderExpression(base, state, dialect)} as json)`
@@ -753,7 +801,7 @@ const renderSelectionList = (
753
801
  const flattened = flattenSelection(selection)
754
802
  const projections = selectionProjections(selection)
755
803
  const sql = flattened.map(({ expression, alias }) =>
756
- `${renderExpression(expression, state, dialect)} as ${dialect.quoteIdentifier(alias)}`).join(", ")
804
+ `${renderSelectSql(renderExpression(expression, state, dialect), expressionDriverContext(expression, state, dialect))} as ${dialect.quoteIdentifier(alias)}`).join(", ")
757
805
  return {
758
806
  sql,
759
807
  projections
@@ -818,7 +866,7 @@ export const renderQueryAst = (
818
866
  case "set": {
819
867
  const setAst = ast as QueryAst.Ast<Record<string, unknown>, any, "set">
820
868
  const base = renderQueryAst(
821
- Query.getAst(setAst.setBase as Query.QueryPlan<any, any, any, any, any, any, any, any, any, any>) as QueryAst.Ast<
869
+ Query.getAst(setAst.setBase as Query.Plan.Any) as QueryAst.Ast<
822
870
  Record<string, unknown>,
823
871
  any,
824
872
  QueryAst.QueryStatement
@@ -831,7 +879,7 @@ export const renderQueryAst = (
831
879
  `(${base.sql})`,
832
880
  ...(setAst.setOperations ?? []).map((entry) => {
833
881
  const rendered = renderQueryAst(
834
- Query.getAst(entry.query as Query.QueryPlan<any, any, any, any, any, any, any, any, any, any>) as QueryAst.Ast<
882
+ Query.getAst(entry.query as Query.Plan.Any) as QueryAst.Ast<
835
883
  Record<string, unknown>,
836
884
  any,
837
885
  QueryAst.QueryStatement
@@ -858,7 +906,7 @@ export const renderQueryAst = (
858
906
  } else if (insertAst.insertSource?.kind === "query") {
859
907
  const columns = insertAst.insertSource.columns.map((column) => dialect.quoteIdentifier(column)).join(", ")
860
908
  const renderedQuery = renderQueryAst(
861
- Query.getAst(insertAst.insertSource.query as Query.QueryPlan<any, any, any, any, any, any, any, any, any, any>) as QueryAst.Ast<
909
+ Query.getAst(insertAst.insertSource.query as Query.Plan.Any) as QueryAst.Ast<
862
910
  Record<string, unknown>,
863
911
  any,
864
912
  QueryAst.QueryStatement
@@ -874,14 +922,18 @@ export const renderQueryAst = (
874
922
  const table = targetSource.source as Table.AnyTable
875
923
  const fields = table[Table.TypeId].fields
876
924
  const rendered = unnestSource.values.map((entry) =>
877
- `cast(${dialect.renderLiteral(entry.values, state)} as ${renderCastType(dialect, fields[entry.columnName]!.metadata.dbType)}[])`
925
+ `cast(${dialect.renderLiteral(encodeArrayValues(entry.values, fields[entry.columnName]!, state, dialect), state)} as ${renderCastType(dialect, fields[entry.columnName]!.metadata.dbType)}[])`
878
926
  ).join(", ")
879
927
  sql += ` (${columns}) select * from unnest(${rendered})`
880
928
  } else {
881
929
  const rowCount = unnestSource.values[0]?.values.length ?? 0
882
930
  const rows = Array.from({ length: rowCount }, (_, index) =>
883
931
  `(${unnestSource.values.map((entry) =>
884
- dialect.renderLiteral(entry.values[index], state)
932
+ dialect.renderLiteral(
933
+ entry.values[index],
934
+ state,
935
+ (targetSource.source as Table.AnyTable)[Table.TypeId].fields[entry.columnName]![Expression.TypeId]
936
+ )
885
937
  ).join(", ")})`
886
938
  ).join(", ")
887
939
  sql += ` (${columns}) values ${rows}`
@@ -1151,7 +1203,7 @@ const renderSourceReference = (
1151
1203
  if (typeof source === "object" && source !== null && "kind" in source && (source as { readonly kind?: string }).kind === "cte") {
1152
1204
  const cte = source as unknown as {
1153
1205
  readonly name: string
1154
- readonly plan: Query.QueryPlan<any, any, any, any, any, any, any, any, any>
1206
+ readonly plan: Query.Plan.Any
1155
1207
  readonly recursive?: boolean
1156
1208
  }
1157
1209
  if (!state.cteNames.has(cte.name)) {
@@ -1168,7 +1220,7 @@ const renderSourceReference = (
1168
1220
  if (typeof source === "object" && source !== null && "kind" in source && (source as { readonly kind?: string }).kind === "derived") {
1169
1221
  const derived = source as unknown as {
1170
1222
  readonly name: string
1171
- readonly plan: Query.QueryPlan<any, any, any, any, any, any, any, any, any>
1223
+ readonly plan: Query.Plan.Any
1172
1224
  }
1173
1225
  if (!state.cteNames.has(derived.name)) {
1174
1226
  // derived tables are inlined, so no CTE registration is needed
@@ -1178,7 +1230,7 @@ const renderSourceReference = (
1178
1230
  if (typeof source === "object" && source !== null && "kind" in source && (source as { readonly kind?: string }).kind === "lateral") {
1179
1231
  const lateral = source as unknown as {
1180
1232
  readonly name: string
1181
- readonly plan: Query.QueryPlan<any, any, any, any, any, any, any, any, any>
1233
+ readonly plan: Query.Plan.Any
1182
1234
  }
1183
1235
  return `lateral (${renderQueryAst(Query.getAst(lateral.plan) as QueryAst.Ast<Record<string, unknown>, any, QueryAst.QueryStatement>, state, dialect).sql}) as ${dialect.quoteIdentifier(lateral.name)}`
1184
1236
  }
@@ -1253,13 +1305,15 @@ export const renderExpression = (
1253
1305
  ? dialect.quoteIdentifier(ast.columnName)
1254
1306
  : `${dialect.quoteIdentifier(ast.tableName)}.${dialect.quoteIdentifier(ast.columnName)}`
1255
1307
  case "literal":
1256
- return dialect.renderLiteral(ast.value, state)
1308
+ return dialect.renderLiteral(ast.value, state, expression[Expression.TypeId])
1257
1309
  case "excluded":
1258
1310
  return dialect.name === "mysql"
1259
1311
  ? `values(${dialect.quoteIdentifier(ast.columnName)})`
1260
1312
  : `excluded.${dialect.quoteIdentifier(ast.columnName)}`
1261
1313
  case "cast":
1262
1314
  return `cast(${renderExpression(ast.value, state, dialect)} as ${renderCastType(dialect, ast.target)})`
1315
+ case "collate":
1316
+ return `(${renderExpression(ast.value, state, dialect)} collate ${ast.collation.map((segment) => dialect.quoteIdentifier(segment)).join(".")})`
1263
1317
  case "function":
1264
1318
  return renderFunctionCall(ast.name, Array.isArray(ast.args) ? ast.args : [], state, dialect)
1265
1319
  case "eq":