effect-qb 0.17.0 → 0.19.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (103) hide show
  1. package/README.md +4 -0
  2. package/dist/index.js +8065 -0
  3. package/dist/mysql.js +3053 -2505
  4. package/dist/postgres/metadata.js +1366 -1250
  5. package/dist/postgres.js +2020 -2719
  6. package/dist/sqlite.js +3226 -2732
  7. package/dist/standard.js +8019 -0
  8. package/package.json +10 -3
  9. package/src/casing.ts +71 -0
  10. package/src/index.ts +2 -0
  11. package/src/internal/casing.ts +89 -0
  12. package/src/internal/column-state.ts +11 -6
  13. package/src/internal/column.ts +44 -7
  14. package/src/internal/datatypes/define.ts +2 -1
  15. package/src/internal/datatypes/enrich.ts +23 -0
  16. package/src/internal/datatypes/lookup.ts +14 -7
  17. package/src/internal/derived-table.ts +4 -36
  18. package/src/{mysql/internal/sql-expression-renderer.ts → internal/dialect-renderers/mysql.ts} +548 -359
  19. package/src/{postgres/internal/sql-expression-renderer.ts → internal/dialect-renderers/postgres.ts} +654 -399
  20. package/src/{sqlite/internal/sql-expression-renderer.ts → internal/dialect-renderers/sqlite.ts} +501 -345
  21. package/src/internal/dialect.ts +35 -0
  22. package/src/internal/dsl-mutation-runtime.ts +12 -162
  23. package/src/internal/dsl-plan-runtime.ts +10 -138
  24. package/src/internal/dsl-query-runtime.ts +5 -79
  25. package/src/internal/dsl-transaction-ddl-runtime.ts +41 -65
  26. package/src/internal/executor.ts +10 -6
  27. package/src/internal/grouping-key.ts +87 -20
  28. package/src/internal/implication-runtime.ts +1 -1
  29. package/src/internal/predicate/runtime.ts +3 -0
  30. package/src/internal/query.d.ts +38 -11
  31. package/src/internal/query.ts +64 -25
  32. package/src/internal/renderer.ts +26 -14
  33. package/src/internal/runtime/normalize.ts +12 -5
  34. package/src/internal/scalar.ts +6 -1
  35. package/src/internal/schema-derivation.d.ts +12 -61
  36. package/src/internal/schema-derivation.ts +90 -38
  37. package/src/internal/schema-expression.ts +2 -2
  38. package/src/internal/sql-expression-renderer.ts +19 -0
  39. package/src/internal/standard-dsl.ts +6885 -0
  40. package/src/internal/table-options.ts +126 -66
  41. package/src/internal/table.d.ts +33 -32
  42. package/src/internal/table.ts +406 -155
  43. package/src/mysql/column-extension.ts +3 -0
  44. package/src/mysql/column.ts +10 -11
  45. package/src/mysql/datatypes/index.ts +3 -2
  46. package/src/mysql/executor.ts +7 -5
  47. package/src/mysql/internal/dialect.ts +9 -4
  48. package/src/mysql/internal/dsl.ts +219 -155
  49. package/src/mysql/internal/renderer.ts +6 -2
  50. package/src/mysql/json.ts +37 -0
  51. package/src/mysql/query-extension.ts +16 -0
  52. package/src/mysql/renderer.ts +31 -4
  53. package/src/mysql.ts +4 -12
  54. package/src/postgres/column-extension.ts +28 -0
  55. package/src/postgres/column.ts +5 -11
  56. package/src/postgres/datatypes/index.d.ts +2 -1
  57. package/src/postgres/datatypes/index.ts +3 -2
  58. package/src/postgres/executor.ts +7 -5
  59. package/src/postgres/function/core.ts +1 -3
  60. package/src/postgres/function/index.ts +1 -17
  61. package/src/postgres/internal/dialect.ts +9 -4
  62. package/src/postgres/internal/dsl.ts +208 -160
  63. package/src/postgres/internal/renderer.ts +6 -2
  64. package/src/postgres/internal/schema-ddl.ts +22 -10
  65. package/src/postgres/internal/schema-model.ts +238 -7
  66. package/src/postgres/json.ts +43 -7
  67. package/src/postgres/jsonb.ts +38 -0
  68. package/src/postgres/query-extension.ts +2 -0
  69. package/src/postgres/renderer.ts +31 -4
  70. package/src/postgres/schema-management.ts +17 -12
  71. package/src/postgres/schema.ts +98 -15
  72. package/src/postgres/table.ts +193 -524
  73. package/src/postgres/type.ts +8 -7
  74. package/src/postgres.ts +9 -11
  75. package/src/sqlite/column-extension.ts +3 -0
  76. package/src/sqlite/column.ts +10 -11
  77. package/src/sqlite/datatypes/index.ts +3 -2
  78. package/src/sqlite/executor.ts +7 -5
  79. package/src/sqlite/internal/dialect.ts +9 -4
  80. package/src/sqlite/internal/dsl.ts +208 -155
  81. package/src/sqlite/internal/renderer.ts +6 -2
  82. package/src/sqlite/json.ts +37 -0
  83. package/src/sqlite/query-extension.ts +2 -0
  84. package/src/sqlite/renderer.ts +31 -4
  85. package/src/sqlite.ts +4 -12
  86. package/src/standard/column.ts +163 -0
  87. package/src/standard/datatypes/index.ts +83 -0
  88. package/src/standard/datatypes/spec.ts +98 -0
  89. package/src/standard/dialect.ts +40 -0
  90. package/src/standard/function/aggregate.ts +2 -0
  91. package/src/standard/function/core.ts +2 -0
  92. package/src/standard/function/index.ts +18 -0
  93. package/src/standard/function/string.ts +2 -0
  94. package/src/standard/function/temporal.ts +78 -0
  95. package/src/standard/function/window.ts +2 -0
  96. package/src/standard/internal/renderer.ts +45 -0
  97. package/src/standard/query.ts +152 -0
  98. package/src/standard/renderer.ts +21 -0
  99. package/src/standard/table.ts +147 -0
  100. package/src/standard.ts +18 -0
  101. package/src/internal/aggregation-validation.ts +0 -57
  102. package/src/mysql/table.ts +0 -183
  103. package/src/sqlite/table.ts +0 -183
@@ -96,7 +96,7 @@ export { union_query_capabilities } from "./query-requirements.js"
96
96
  * `Pipeable.pipe(...)` plus the metadata stored under `Expression.TypeId`.
97
97
  */
98
98
  const ExpressionProto = {
99
- pipe(this: unknown) {
99
+ pipe(this: Pipeable) {
100
100
  return pipeArguments(this, arguments)
101
101
  }
102
102
  }
@@ -108,7 +108,7 @@ const ExpressionProto = {
108
108
  * chained through `.pipe(...)`.
109
109
  */
110
110
  const PlanProto = {
111
- pipe(this: unknown) {
111
+ pipe(this: Pipeable) {
112
112
  return pipeArguments(this, arguments)
113
113
  }
114
114
  }
@@ -143,6 +143,34 @@ export interface QueryState<
143
143
 
144
144
  /** Effective SQL dialect carried by an expression. */
145
145
  export type DialectOf<Value extends Expression.Any> = Value[typeof Expression.TypeId]["dialect"]
146
+ type ConcreteDialect<D> = D extends "standard" ? never : D
147
+ type IsDialectUnion<Union, All = Union> = Union extends any
148
+ ? [All] extends [Union] ? false : true
149
+ : false
150
+ export type DialectConflictError<A extends string, B extends string> = string & {
151
+ readonly _tag: "DialectConflict"
152
+ readonly left: A
153
+ readonly right: B
154
+ }
155
+ export type MergeDialect<A extends string, B extends string> =
156
+ [ConcreteDialect<A>, ConcreteDialect<B>] extends [never, never] ? "standard"
157
+ : [ConcreteDialect<A>, ConcreteDialect<B>] extends [never, infer C extends string] ? C
158
+ : [ConcreteDialect<A>, ConcreteDialect<B>] extends [infer C extends string, never] ? C
159
+ : ConcreteDialect<A> extends ConcreteDialect<B>
160
+ ? ConcreteDialect<B> extends ConcreteDialect<A>
161
+ ? A
162
+ : DialectConflictError<A, B>
163
+ : DialectConflictError<A, B>
164
+
165
+ /** Collapses the portable standard tag out of a dialect union. */
166
+ export type NormalizeDialect<Dialect extends string> =
167
+ [Dialect] extends [never]
168
+ ? never
169
+ : [Exclude<Dialect, "standard">] extends [never]
170
+ ? "standard"
171
+ : IsDialectUnion<Exclude<Dialect, "standard">> extends true
172
+ ? DialectConflictError<Exclude<Dialect, "standard">, Exclude<Dialect, "standard">>
173
+ : Exclude<Dialect, "standard">
146
174
  /** Source dependency union carried by an expression. */
147
175
  export type DependenciesOf<Value extends Expression.Any> = Expression.DependenciesOf<Value>
148
176
  /** Aggregation kind carried by an expression. */
@@ -464,15 +492,17 @@ export type ExtractRequired<Selection> = Selection extends Expression.Any
464
492
  }[keyof Selection]
465
493
  : never
466
494
 
467
- /** Walks a selection tree and unions the dialects referenced by its leaves. */
468
- export type ExtractDialect<Selection> = Selection extends Expression.Any
495
+ type ExtractDialectRaw<Selection> = Selection extends Expression.Any
469
496
  ? DialectOf<Selection>
470
497
  : Selection extends Record<string, any>
471
498
  ? {
472
- [K in keyof Selection]: ExtractDialect<Selection[K]>
499
+ [K in keyof Selection]: ExtractDialectRaw<Selection[K]>
473
500
  }[keyof Selection]
474
501
  : never
475
502
 
503
+ /** Walks a selection tree and extracts the effective dialects referenced by its leaves. */
504
+ export type ExtractDialect<Selection> = NormalizeDialect<Extract<ExtractDialectRaw<Selection>, string>>
505
+
476
506
  /**
477
507
  * Minimal table-like shape required by `from(...)` and joins.
478
508
  *
@@ -1005,8 +1035,7 @@ export type UpdateInputOfTarget<Target extends MutationTargetInput> =
1005
1035
  }>
1006
1036
  : never
1007
1037
 
1008
- /** Extracts the effective dialect from a source. */
1009
- export type SourceDialectOf<Source extends SourceLike> =
1038
+ type SourceDialectOfRaw<Source extends SourceLike> =
1010
1039
  Source extends TableLike<any, infer Dialect> ? Dialect :
1011
1040
  Source extends { readonly kind: "derived"; readonly plan: infer PlanValue extends QueryPlan<any, any, any, any, any, any, any, any, any, any> } ? PlanDialectOf<PlanValue> :
1012
1041
  Source extends { readonly kind: "cte"; readonly plan: infer PlanValue extends QueryPlan<any, any, any, any, any, any, any, any, any, any> } ? PlanDialectOf<PlanValue> :
@@ -1014,6 +1043,9 @@ export type SourceDialectOf<Source extends SourceLike> =
1014
1043
  Source extends { readonly dialect: infer Dialect extends string } ? Dialect :
1015
1044
  never
1016
1045
 
1046
+ /** Extracts the effective dialect from a source. */
1047
+ export type SourceDialectOf<Source extends SourceLike> = NormalizeDialect<SourceDialectOfRaw<Source>>
1048
+
1017
1049
  /** Extracts the base table name from a source. */
1018
1050
  export type SourceBaseNameOf<Source extends SourceLike> =
1019
1051
  Source extends TableLike<any, any> ? Source[typeof Table.TypeId]["baseName"] :
@@ -1148,6 +1180,21 @@ type DerivedProjectionIssues<Selection> =
1148
1180
  : | DerivedProjectionDuplicateAliases<Selection>
1149
1181
  | DerivedProjectionAliasMismatches<Selection>
1150
1182
 
1183
+ export type SelectionProjectionDuplicateAliases<Selection> =
1184
+ IsBroadSelection<Selection> extends true
1185
+ ? never
1186
+ : DuplicateProjectionAliases<SelectionProjectionEntries<Selection>>
1187
+
1188
+ export type SelectionProjectionAliasCollisionError<Selection> = Selection & {
1189
+ readonly __effect_qb_error__: "effect-qb: projection aliases must be unique"
1190
+ readonly __effect_qb_duplicate_projection_aliases__: SelectionProjectionDuplicateAliases<Selection>
1191
+ }
1192
+
1193
+ export type SelectionProjectionAliasCollisionConstraint<Selection> =
1194
+ [SelectionProjectionDuplicateAliases<Selection>] extends [never]
1195
+ ? unknown
1196
+ : SelectionProjectionAliasCollisionError<Selection>
1197
+
1151
1198
  export type DerivedSourceProjectionCompatibilityError<
1152
1199
  PlanValue extends QueryPlan<any, any, any, any, any, any, any, any, any, any>
1153
1200
  > = PlanValue & {
@@ -1254,7 +1301,7 @@ export type AvailableOfPlan<
1254
1301
  /** Extracts the effective dialect carried by a query plan. */
1255
1302
  export type PlanDialectOf<
1256
1303
  PlanValue extends QueryPlan<any, any, any, any, any, any, any, any, any, any, any, any>
1257
- > = QueryPlanParts<PlanValue>["dialect"]
1304
+ > = NormalizeDialect<QueryPlanParts<PlanValue>["dialect"]>
1258
1305
  /** Extracts the grouped-source phantom carried by a query plan. */
1259
1306
  export type GroupedOfPlan<
1260
1307
  PlanValue extends QueryPlan<any, any, any, any, any, any, any, any, any, any, any, any>
@@ -1465,7 +1512,7 @@ export type MergeNullabilityTuple<
1465
1512
  /** Dialect union across a tuple of expressions. */
1466
1513
  export type TupleDialect<
1467
1514
  Values extends readonly Expression.Any[]
1468
- > = Values[number] extends never ? never : DialectOf<Values[number]>
1515
+ > = Values[number] extends never ? never : NormalizeDialect<DialectOf<Values[number]>>
1469
1516
 
1470
1517
  /** Converts a union into an intersection. */
1471
1518
  type UnionToIntersection<Union> = (
@@ -2124,7 +2171,7 @@ type DialectCompatibilityError<
2124
2171
  EngineDialect extends string
2125
2172
  > = PlanValue & {
2126
2173
  readonly __effect_qb_error__: "effect-qb: plan dialect is not compatible with the target renderer or executor"
2127
- readonly __effect_qb_plan_dialect__: PlanValue[typeof RowSet.TypeId]["dialect"]
2174
+ readonly __effect_qb_plan_dialect__: PlanDialectOf<PlanValue>
2128
2175
  readonly __effect_qb_target_dialect__: EngineDialect
2129
2176
  readonly __effect_qb_hint__: "Use the matching dialect module or renderer/executor"
2130
2177
  }
@@ -2175,7 +2222,7 @@ type IsDialectCompatible<
2175
2222
  EngineDialect extends string
2176
2223
  > = [PlanDialect] extends [never]
2177
2224
  ? true
2178
- : Exclude<PlanDialect, EngineDialect> extends never
2225
+ : Exclude<PlanDialect, EngineDialect | "standard"> extends never
2179
2226
  ? true
2180
2227
  : false
2181
2228
 
@@ -2183,7 +2230,7 @@ type IsDialectCompatible<
2183
2230
  export type DialectCompatiblePlan<
2184
2231
  PlanValue extends QueryPlan<any, any, any, any, any, any, any, any, any, any>,
2185
2232
  EngineDialect extends string
2186
- > = IsDialectCompatible<PlanValue[typeof RowSet.TypeId]["dialect"], EngineDialect> extends true
2233
+ > = IsDialectCompatible<PlanDialectOf<PlanValue>, EngineDialect> extends true
2187
2234
  ? CompletePlan<PlanValue>
2188
2235
  : DialectCompatibilityError<PlanValue, EngineDialect>
2189
2236
 
@@ -2201,7 +2248,7 @@ type NestedPlanStatementError<
2201
2248
  export type DialectCompatibleNestedPlan<
2202
2249
  PlanValue extends QueryPlan<any, any, any, any, any, any, any, any, any, any>,
2203
2250
  EngineDialect extends string
2204
- > = IsDialectCompatible<PlanValue[typeof RowSet.TypeId]["dialect"], EngineDialect> extends true
2251
+ > = IsDialectCompatible<PlanDialectOf<PlanValue>, EngineDialect> extends true
2205
2252
  ? StatementOfPlan<PlanValue> extends SelectLikeStatement
2206
2253
  ? AggregationCompatiblePlan<PlanValue>
2207
2254
  : NestedPlanStatementError<PlanValue>
@@ -2427,7 +2474,7 @@ export const makeExpression = <
2427
2474
  Object.defineProperty(expression, "pipe", {
2428
2475
  configurable: true,
2429
2476
  writable: true,
2430
- value: function(this: unknown) {
2477
+ value: function(this: Pipeable) {
2431
2478
  return pipeArguments(expression, arguments)
2432
2479
  }
2433
2480
  })
@@ -2477,7 +2524,7 @@ export const makePlan = <
2477
2524
  Object.defineProperty(plan, "pipe", {
2478
2525
  configurable: true,
2479
2526
  writable: true,
2480
- value: function(this: unknown) {
2527
+ value: function(this: Pipeable) {
2481
2528
  return pipeArguments(plan, arguments)
2482
2529
  }
2483
2530
  })
@@ -2536,16 +2583,8 @@ export const extractRequiredRuntime = (selection: SelectionShape): readonly stri
2536
2583
 
2537
2584
  /** Extracts the single top-level expression from a scalar subquery selection. */
2538
2585
  export const extractSingleSelectedExpressionRuntime = (selection: SelectionShape): Expression.Any => {
2539
- const keys = Object.keys(selection)
2540
- if (keys.length !== 1) {
2541
- throw new Error("scalar subqueries must select exactly one top-level expression")
2542
- }
2543
- const record = selection as Record<string, unknown>
2544
- const value = record[keys[0]!]
2545
- if (value === null || typeof value !== "object" || !(Expression.TypeId in (value as object))) {
2546
- throw new Error("scalar subqueries must select a scalar expression")
2547
- }
2548
- return value as unknown as Expression.Any
2586
+ const record = selection as Record<string, Expression.Any>
2587
+ return record[Object.keys(record)[0]!]!
2549
2588
  }
2550
2589
 
2551
2590
  /** Converts the plan's runtime `required` metadata into a mutable string list. */
@@ -1,7 +1,6 @@
1
1
  import * as Query from "./query.js"
2
- import type * as Expression from "./scalar.js"
2
+ import * as Expression from "./scalar.js"
3
3
  import { flattenSelection, type Projection, validateProjections } from "./projections.js"
4
- import * as Plan from "./row-set.js"
5
4
 
6
5
  /** Symbol used to attach rendered-query phantom row metadata. */
7
6
  export const TypeId: unique symbol = Symbol.for("effect-qb/Renderer")
@@ -38,8 +37,7 @@ export type RowOf<Value extends RenderedQuery<any, any>> = Value[typeof TypeId][
38
37
  *
39
38
  * Renderers only accept complete, dialect-compatible plans. The returned
40
39
  * `RenderedQuery` keeps the canonical `Query.ResultRow<...>` type attached for
41
- * downstream executor layers, and the built-in renderer also performs a
42
- * matching runtime aggregate-shape validation.
40
+ * downstream executor layers.
43
41
  */
44
42
  export interface Renderer<Dialect extends string = string> {
45
43
  readonly dialect: Dialect
@@ -91,24 +89,38 @@ export function make<Dialect extends string>(
91
89
  dialect: Dialect,
92
90
  render: CustomRender<Dialect>
93
91
  ): Renderer<Dialect> {
92
+ return makeRenderer(dialect, render, true)
93
+ }
94
+
95
+ /** Internal renderer factory for built-in renderers that derive projections from typed plans. */
96
+ export function makeTrusted<Dialect extends string>(
97
+ dialect: Dialect,
98
+ render: CustomRender<Dialect>
99
+ ): Renderer<Dialect>
100
+ export function makeTrusted<Dialect extends string>(
101
+ dialect: Dialect,
102
+ render: CustomRender<Dialect>
103
+ ): Renderer<Dialect> {
104
+ return makeRenderer(dialect, render, false)
105
+ }
106
+
107
+ const makeRenderer = <Dialect extends string>(
108
+ dialect: Dialect,
109
+ render: CustomRender<Dialect>,
110
+ validate: boolean
111
+ ): Renderer<Dialect> => {
94
112
  if (typeof render !== "function") {
95
113
  throw new Error(`Renderer.make requires an explicit render implementation for dialect: ${dialect}`)
96
114
  }
97
115
  return {
98
116
  dialect,
99
117
  render(plan) {
100
- const required = Query.currentRequiredList(plan[Plan.TypeId].required)
101
- if (required.length > 0) {
102
- throw new Error(`query references sources that are not yet in scope: ${required.join(", ")}`)
103
- }
104
- const planDialect = plan[Plan.TypeId].dialect
105
- if (planDialect !== dialect) {
106
- throw new Error("effect-qb: plan dialect is not compatible with the target renderer or executor")
107
- }
108
118
  const rendered = render(plan)
109
119
  const projections = rendered.projections ?? []
110
- validateProjections(projections)
111
- validateProjectionPathsMatchSelection(plan as Query.Plan.Any, projections)
120
+ if (validate) {
121
+ validateProjections(projections)
122
+ validateProjectionPathsMatchSelection(plan as Query.Plan.Any, projections)
123
+ }
112
124
  return {
113
125
  sql: rendered.sql,
114
126
  params: rendered.params ?? [],
@@ -23,6 +23,13 @@ const isPlainRecord = (value: unknown): value is Record<string, unknown> => {
23
23
 
24
24
  const pad = (value: number, width = 2): string => value.toString().padStart(width, "0")
25
25
 
26
+ const validDate = (value: Date): Date => {
27
+ if (Number.isNaN(value.getTime())) {
28
+ throw new Error("Expected a valid Date value")
29
+ }
30
+ return value
31
+ }
32
+
26
33
  const formatLocalDate = (value: Date): string =>
27
34
  `${pad(value.getUTCFullYear(), 4)}-${pad(value.getUTCMonth() + 1)}-${pad(value.getUTCDate())}`
28
35
 
@@ -125,7 +132,7 @@ const normalizeDecimalString = (value: unknown): string => {
125
132
 
126
133
  const normalizeLocalDate = (value: unknown): string => {
127
134
  if (value instanceof Date) {
128
- return formatLocalDate(value)
135
+ return formatLocalDate(validDate(value))
129
136
  }
130
137
  const raw = expectString(value, "local date").trim()
131
138
  if (isValidLocalDateString(raw)) {
@@ -143,7 +150,7 @@ const normalizeLocalDate = (value: unknown): string => {
143
150
 
144
151
  const normalizeLocalTime = (value: unknown): string => {
145
152
  if (value instanceof Date) {
146
- return formatLocalTime(value)
153
+ return formatLocalTime(validDate(value))
147
154
  }
148
155
  const raw = expectString(value, "local time").trim()
149
156
  if (isValidLocalTimeString(raw)) {
@@ -154,7 +161,7 @@ const normalizeLocalTime = (value: unknown): string => {
154
161
 
155
162
  const normalizeOffsetTime = (value: unknown): string => {
156
163
  if (value instanceof Date) {
157
- return `${formatLocalTime(value)}Z`
164
+ return `${formatLocalTime(validDate(value))}Z`
158
165
  }
159
166
  const raw = expectString(value, "offset time").trim()
160
167
  if (isValidOffsetTimeString(raw)) {
@@ -165,7 +172,7 @@ const normalizeOffsetTime = (value: unknown): string => {
165
172
 
166
173
  const normalizeLocalDateTime = (value: unknown): string => {
167
174
  if (value instanceof Date) {
168
- return formatLocalDateTime(value)
175
+ return formatLocalDateTime(validDate(value))
169
176
  }
170
177
  const raw = expectString(value, "local datetime").trim()
171
178
  const canonicalLocalDateTime = raw.replace(" ", "T")
@@ -184,7 +191,7 @@ const normalizeLocalDateTime = (value: unknown): string => {
184
191
 
185
192
  const normalizeInstant = (value: unknown): string => {
186
193
  if (value instanceof Date) {
187
- return value.toISOString()
194
+ return validDate(value).toISOString()
188
195
  }
189
196
  const raw = expectString(value, "instant").trim()
190
197
  if (!/[zZ]|[+-]\d{2}:\d{2}$/.test(raw)) {
@@ -143,7 +143,12 @@ export interface DriverValueMapping {
143
143
  readonly jsonSelectSql?: (sql: string, dbType: DbType.Any) => string
144
144
  }
145
145
 
146
- export type DriverValueMappings = Readonly<Record<string, DriverValueMapping | undefined>>
146
+ export type DriverValueMappings = Readonly<Partial<Record<string, DriverValueMapping>>>
147
+
148
+ export type DriverValueMappingsFor<
149
+ Kind extends string,
150
+ Family extends string
151
+ > = Readonly<Partial<Record<Kind | Family | RuntimeTag, DriverValueMapping>>>
147
152
 
148
153
  /** Canonical static metadata stored on an expression. */
149
154
  export interface State<
@@ -1,64 +1,7 @@
1
- import * as VariantSchema from "@effect/experimental/VariantSchema";
2
1
  import type * as Brand from "effect/Brand";
3
2
  import * as Schema from "effect/Schema";
4
3
  import { type AnyColumnDefinition, type HasDefault, type InsertType, type IsGenerated, type IsNullable, type SelectType, type UpdateType } from "./column-state.js";
5
- /** Variant-schema helper used to derive select / insert / update schemas. */
6
- export declare const TableSchema: {
7
- readonly Struct: <const A extends VariantSchema.Struct.Fields>(fields: A & VariantSchema.Struct.Validate<A, "insert" | "select" | "update">) => VariantSchema.Struct<A>;
8
- readonly Field: <const A extends VariantSchema.Field.ConfigWithKeys<"insert" | "select" | "update">>(config: A & { readonly [K in Exclude<keyof A, "insert" | "select" | "update">]: never; }) => VariantSchema.Field<A>;
9
- readonly FieldOnly: <const Keys extends readonly ("insert" | "select" | "update")[]>(...keys: Keys) => <S extends Schema.Schema.All | Schema.PropertySignature.All<PropertyKey>>(schema: S) => VariantSchema.Field<{ readonly [K in Keys[number]]: S; }>;
10
- readonly FieldExcept: <const Keys extends readonly ("insert" | "select" | "update")[]>(...keys: Keys) => <S extends Schema.Schema.All | Schema.PropertySignature.All<PropertyKey>>(schema: S) => VariantSchema.Field<{ readonly [K in Exclude<"insert", Keys[number]> | Exclude<"select", Keys[number]> | Exclude<"update", Keys[number]>]: S; }>;
11
- readonly fieldEvolve: {
12
- <Self extends VariantSchema.Field<any> | VariantSchema.Field.ValueAny, const Mapping extends Self extends VariantSchema.Field<infer S extends VariantSchema.Field.Config> ? { readonly [K in keyof S]?: ((variant: S[K]) => VariantSchema.Field.ValueAny) | undefined; } : {
13
- readonly insert?: ((variant: Self) => VariantSchema.Field.ValueAny) | undefined;
14
- readonly select?: ((variant: Self) => VariantSchema.Field.ValueAny) | undefined;
15
- readonly update?: ((variant: Self) => VariantSchema.Field.ValueAny) | undefined;
16
- }>(f: Mapping): (self: Self) => VariantSchema.Field<Self extends VariantSchema.Field<infer S_1 extends VariantSchema.Field.Config> ? { readonly [K in keyof S_1]: K extends keyof Mapping ? Mapping[K] extends (arg: any) => any ? ReturnType<Mapping[K]> : S_1[K] : S_1[K]; } : {
17
- readonly insert: "insert" extends infer T ? T extends "insert" ? T extends keyof Mapping ? Mapping[T] extends (arg: any) => any ? ReturnType<Mapping[T]> : Self : Self : never : never;
18
- readonly select: "select" extends infer T_1 ? T_1 extends "select" ? T_1 extends keyof Mapping ? Mapping[T_1] extends (arg: any) => any ? ReturnType<Mapping[T_1]> : Self : Self : never : never;
19
- readonly update: "update" extends infer T_2 ? T_2 extends "update" ? T_2 extends keyof Mapping ? Mapping[T_2] extends (arg: any) => any ? ReturnType<Mapping[T_2]> : Self : Self : never : never;
20
- }>;
21
- <Self extends VariantSchema.Field<any> | VariantSchema.Field.ValueAny, const Mapping_1 extends Self extends VariantSchema.Field<infer S extends VariantSchema.Field.Config> ? { readonly [K in keyof S]?: ((variant: S[K]) => VariantSchema.Field.ValueAny) | undefined; } : {
22
- readonly insert?: ((variant: Self) => VariantSchema.Field.ValueAny) | undefined;
23
- readonly select?: ((variant: Self) => VariantSchema.Field.ValueAny) | undefined;
24
- readonly update?: ((variant: Self) => VariantSchema.Field.ValueAny) | undefined;
25
- }>(self: Self, f: Mapping_1): VariantSchema.Field<Self extends VariantSchema.Field<infer S_1 extends VariantSchema.Field.Config> ? { readonly [K in keyof S_1]: K extends keyof Mapping_1 ? Mapping_1[K] extends (arg: any) => any ? ReturnType<Mapping_1[K]> : S_1[K] : S_1[K]; } : {
26
- readonly insert: "insert" extends infer T ? T extends "insert" ? T extends keyof Mapping_1 ? Mapping_1[T] extends (arg: any) => any ? ReturnType<Mapping_1[T]> : Self : Self : never : never;
27
- readonly select: "select" extends infer T_1 ? T_1 extends "select" ? T_1 extends keyof Mapping_1 ? Mapping_1[T_1] extends (arg: any) => any ? ReturnType<Mapping_1[T_1]> : Self : Self : never : never;
28
- readonly update: "update" extends infer T_2 ? T_2 extends "update" ? T_2 extends keyof Mapping_1 ? Mapping_1[T_2] extends (arg: any) => any ? ReturnType<Mapping_1[T_2]> : Self : Self : never : never;
29
- }>;
30
- };
31
- readonly fieldFromKey: {
32
- <Self extends VariantSchema.Field<any> | VariantSchema.Field.ValueAny, const Mapping_2 extends Self extends VariantSchema.Field<infer S extends VariantSchema.Field.Config> ? { readonly [K in keyof S]?: string | undefined; } : {
33
- readonly insert?: string | undefined;
34
- readonly select?: string | undefined;
35
- readonly update?: string | undefined;
36
- }>(mapping: Mapping_2): (self: Self) => VariantSchema.Field<Self extends VariantSchema.Field<infer S_1 extends VariantSchema.Field.Config> ? { readonly [K in keyof S_1]: K extends keyof Mapping_2 ? Mapping_2[K] extends string ? VariantSchema.fromKey.Rename<S_1[K], Mapping_2[K]> : S_1[K] : S_1[K]; } : {
37
- readonly insert: "insert" extends infer T ? T extends "insert" ? T extends keyof Mapping_2 ? Mapping_2[T] extends string ? VariantSchema.fromKey.Rename<Self, Mapping_2[T]> : Self : Self : never : never;
38
- readonly select: "select" extends infer T_1 ? T_1 extends "select" ? T_1 extends keyof Mapping_2 ? Mapping_2[T_1] extends string ? VariantSchema.fromKey.Rename<Self, Mapping_2[T_1]> : Self : Self : never : never;
39
- readonly update: "update" extends infer T_2 ? T_2 extends "update" ? T_2 extends keyof Mapping_2 ? Mapping_2[T_2] extends string ? VariantSchema.fromKey.Rename<Self, Mapping_2[T_2]> : Self : Self : never : never;
40
- }>;
41
- <Self extends VariantSchema.Field<any> | VariantSchema.Field.ValueAny, const Mapping_3 extends Self extends VariantSchema.Field<infer S extends VariantSchema.Field.Config> ? { readonly [K in keyof S]?: string | undefined; } : {
42
- readonly insert?: string | undefined;
43
- readonly select?: string | undefined;
44
- readonly update?: string | undefined;
45
- }>(self: Self, mapping: Mapping_3): VariantSchema.Field<Self extends VariantSchema.Field<infer S_1 extends VariantSchema.Field.Config> ? { readonly [K in keyof S_1]: K extends keyof Mapping_3 ? Mapping_3[K] extends string ? VariantSchema.fromKey.Rename<S_1[K], Mapping_3[K]> : S_1[K] : S_1[K]; } : {
46
- readonly insert: "insert" extends infer T ? T extends "insert" ? T extends keyof Mapping_3 ? Mapping_3[T] extends string ? VariantSchema.fromKey.Rename<Self, Mapping_3[T]> : Self : Self : never : never;
47
- readonly select: "select" extends infer T_1 ? T_1 extends "select" ? T_1 extends keyof Mapping_3 ? Mapping_3[T_1] extends string ? VariantSchema.fromKey.Rename<Self, Mapping_3[T_1]> : Self : Self : never : never;
48
- readonly update: "update" extends infer T_2 ? T_2 extends "update" ? T_2 extends keyof Mapping_3 ? Mapping_3[T_2] extends string ? VariantSchema.fromKey.Rename<Self, Mapping_3[T_2]> : Self : Self : never : never;
49
- }>;
50
- };
51
- readonly Class: <Self = never>(identifier: string) => <const Fields extends VariantSchema.Struct.Fields>(fields: Fields & VariantSchema.Struct.Validate<Fields, "insert" | "select" | "update">, annotations?: Schema.Annotations.Schema<Self, readonly []> | undefined) => [Self] extends [never] ? "Missing `Self` generic - use `class Self extends Class<Self>()({ ... })`" : VariantSchema.Class<Self, Fields, VariantSchema.ExtractFields<"select", Fields, true>, Schema.Struct.Type<VariantSchema.ExtractFields<"select", Fields, true>>, Schema.Struct.Encoded<VariantSchema.ExtractFields<"select", Fields, true>>, Schema.Schema.Context<VariantSchema.ExtractFields<"select", Fields, true>[keyof VariantSchema.ExtractFields<"select", Fields, true>]>, Schema.Struct.Constructor<VariantSchema.ExtractFields<"select", Fields, true>>> & {
52
- readonly insert: Schema.Struct<VariantSchema.ExtractFields<"insert", Fields, false> extends infer T ? { [K in keyof T]: T[K]; } : never>;
53
- readonly select: Schema.Struct<VariantSchema.ExtractFields<"select", Fields, false> extends infer T_1 ? { [K in keyof T_1]: T_1[K]; } : never>;
54
- readonly update: Schema.Struct<VariantSchema.ExtractFields<"update", Fields, false> extends infer T_2 ? { [K in keyof T_2]: T_2[K]; } : never>;
55
- };
56
- readonly Union: <const Members extends readonly VariantSchema.Struct<any>[]>(...members: Members) => VariantSchema.Union<Members> & VariantSchema.Union.Variants<Members, "insert" | "select" | "update">;
57
- readonly extract: {
58
- <V extends "insert" | "select" | "update">(variant: V): <A extends VariantSchema.Struct<any>>(self: A) => VariantSchema.Extract<V, A, V extends "select" ? true : false>;
59
- <V extends "insert" | "select" | "update", A extends VariantSchema.Struct<any>>(self: A, variant: V): VariantSchema.Extract<V, A, V extends "select" ? true : false>;
60
- };
61
- };
4
+ export type TableSchemaVariant = "select" | "insert" | "update";
62
5
  /** Normalized field map used by table definitions. */
63
6
  export type TableFieldMap = Record<string, AnyColumnDefinition>;
64
7
  type GeneratedKeys<Fields extends TableFieldMap> = {
@@ -91,15 +34,23 @@ export type InsertRow<TableName extends string, Fields extends TableFieldMap> =
91
34
  export type UpdateRow<TableName extends string, Fields extends TableFieldMap, PrimaryKey extends keyof Fields> = Simplify<Partial<{
92
35
  [K in UpdateKeys<Fields, PrimaryKey>]: BrandedUpdateType<Fields[K], TableName, Extract<K, string>>;
93
36
  }>>;
37
+ type SchemaOfVariant<Variant extends TableSchemaVariant, TableName extends string, Fields extends TableFieldMap, PrimaryKeyColumns extends keyof Fields & string> = Variant extends "select" ? Schema.Schema<SelectRow<TableName, Fields>> : Variant extends "insert" ? Schema.Schema<InsertRow<TableName, Fields>> : Schema.Schema<UpdateRow<TableName, Fields, PrimaryKeyColumns>>;
38
+ export declare const deriveSchema: <Variant extends TableSchemaVariant, TableName extends string, Fields extends TableFieldMap, PrimaryKeyColumns extends keyof Fields & string>(variant: Variant, tableName: TableName, fields: Fields, primaryKeyColumns: readonly PrimaryKeyColumns[]) => SchemaOfVariant<Variant, TableName, Fields, PrimaryKeyColumns>;
39
+ export declare const deriveSelectSchema: <TableName extends string, Fields extends TableFieldMap, PrimaryKeyColumns extends keyof Fields & string>(tableName: TableName, fields: Fields, primaryKeyColumns: readonly PrimaryKeyColumns[]) => Schema.Schema<SelectRow<TableName, Fields>>;
40
+ export declare const deriveInsertSchema: <TableName extends string, Fields extends TableFieldMap, PrimaryKeyColumns extends keyof Fields & string>(tableName: TableName, fields: Fields, primaryKeyColumns: readonly PrimaryKeyColumns[]) => Schema.Schema<InsertRow<TableName, Fields>>;
41
+ export declare const deriveUpdateSchema: <TableName extends string, Fields extends TableFieldMap, PrimaryKeyColumns extends keyof Fields & string>(tableName: TableName, fields: Fields, primaryKeyColumns: readonly PrimaryKeyColumns[]) => Schema.Schema<UpdateRow<TableName, Fields, PrimaryKeyColumns>>;
94
42
  /**
95
43
  * Derives the `select`, `insert`, and `update` schemas for a table.
96
44
  *
97
45
  * This is the central place where the column capability flags are turned into
98
46
  * real runtime schemas.
47
+ *
48
+ * @deprecated Prefer `deriveSelectSchema`, `deriveInsertSchema`, and
49
+ * `deriveUpdateSchema` so individual variants are derived lazily.
99
50
  */
100
51
  export declare const deriveSchemas: <TableName extends string, Fields extends TableFieldMap, PrimaryKeyColumns extends keyof Fields & string>(tableName: TableName, fields: Fields, primaryKeyColumns: readonly PrimaryKeyColumns[]) => {
101
- readonly select: Schema.Schema<{ [K in keyof { [K in keyof Fields]: BrandedSelectType<Fields[K], TableName, Extract<K, string>>; }]: { [K in keyof Fields]: BrandedSelectType<Fields[K], TableName, Extract<K, string>>; }[K]; }, { [K in keyof { [K in keyof Fields]: BrandedSelectType<Fields[K], TableName, Extract<K, string>>; }]: { [K in keyof Fields]: BrandedSelectType<Fields[K], TableName, Extract<K, string>>; }[K]; }, never>;
102
- readonly insert: Schema.Schema<{ [K in Exclude<keyof Fields, GeneratedKeys<Fields> | OptionalInsertKeys<Fields>>]: BrandedInsertType<Fields[K], TableName, Extract<K, string>>; } & { [K in OptionalInsertKeys<Fields>]?: BrandedInsertType<Fields[K], TableName, Extract<K, string>> | undefined; } extends infer T ? { [K in keyof T]: T[K]; } : never, { [K in Exclude<keyof Fields, GeneratedKeys<Fields> | OptionalInsertKeys<Fields>>]: BrandedInsertType<Fields[K], TableName, Extract<K, string>>; } & { [K in OptionalInsertKeys<Fields>]?: BrandedInsertType<Fields[K], TableName, Extract<K, string>> | undefined; } extends infer T ? { [K in keyof T]: T[K]; } : never, never>;
103
- readonly update: Schema.Schema<Partial<{ [K in Exclude<keyof Fields, PrimaryKeyColumns | GeneratedKeys<Fields>>]: BrandedUpdateType<Fields[K], TableName, Extract<K, string>>; }> extends infer T_1 ? { [K in keyof T_1]: T_1[K]; } : never, Partial<{ [K in Exclude<keyof Fields, PrimaryKeyColumns | GeneratedKeys<Fields>>]: BrandedUpdateType<Fields[K], TableName, Extract<K, string>>; }> extends infer T_1 ? { [K in keyof T_1]: T_1[K]; } : never, never>;
52
+ readonly select: Schema.Schema<SelectRow<TableName, Fields>>;
53
+ readonly insert: Schema.Schema<InsertRow<TableName, Fields>>;
54
+ readonly update: Schema.Schema<UpdateRow<TableName, Fields, PrimaryKeyColumns>>;
104
55
  };
105
56
  export {};
@@ -1,4 +1,3 @@
1
- import * as VariantSchema from "@effect/experimental/VariantSchema"
2
1
  import type * as Brand from "effect/Brand"
3
2
  import * as Schema from "effect/Schema"
4
3
 
@@ -12,13 +11,7 @@ import {
12
11
  type UpdateType
13
12
  } from "./column-state.js"
14
13
 
15
- /** Variant-schema helper used to derive select / insert / update schemas. */
16
- export const TableSchema = VariantSchema.make({
17
- variants: ["select", "insert", "update"] as const,
18
- defaultVariant: "select"
19
- })
20
-
21
- type Variants = "select" | "insert" | "update"
14
+ export type TableSchemaVariant = "select" | "insert" | "update"
22
15
 
23
16
  /** Normalized field map used by table definitions. */
24
17
  export type TableFieldMap = Record<string, AnyColumnDefinition>
@@ -153,11 +146,95 @@ const updateSchema = (
153
146
  return Schema.optional(base)
154
147
  }
155
148
 
149
+ type SchemaOfVariant<
150
+ Variant extends TableSchemaVariant,
151
+ TableName extends string,
152
+ Fields extends TableFieldMap,
153
+ PrimaryKeyColumns extends keyof Fields & string
154
+ > = Variant extends "select" ? Schema.Schema<SelectRow<TableName, Fields>>
155
+ : Variant extends "insert" ? Schema.Schema<InsertRow<TableName, Fields>>
156
+ : Schema.Schema<UpdateRow<TableName, Fields, PrimaryKeyColumns>>
157
+
158
+ const fieldSchemaForVariant = (
159
+ variant: TableSchemaVariant,
160
+ column: AnyColumnDefinition,
161
+ tableName: string,
162
+ columnName: string,
163
+ primaryKeySet: ReadonlySet<string>
164
+ ): any | undefined => {
165
+ switch (variant) {
166
+ case "select":
167
+ return selectSchema(column, tableName, columnName)
168
+ case "insert":
169
+ return insertSchema(column, tableName, columnName)
170
+ case "update":
171
+ return updateSchema(column, tableName, columnName, primaryKeySet.has(columnName))
172
+ }
173
+ }
174
+
175
+ export const deriveSchema = <
176
+ Variant extends TableSchemaVariant,
177
+ TableName extends string,
178
+ Fields extends TableFieldMap,
179
+ PrimaryKeyColumns extends keyof Fields & string
180
+ >(
181
+ variant: Variant,
182
+ tableName: TableName,
183
+ fields: Fields,
184
+ primaryKeyColumns: readonly PrimaryKeyColumns[]
185
+ ): SchemaOfVariant<Variant, TableName, Fields, PrimaryKeyColumns> => {
186
+ const primaryKeySet = new Set<string>(primaryKeyColumns)
187
+ const structFields: Record<string, any> = {}
188
+ for (const [key, column] of Object.entries(fields)) {
189
+ const schema = fieldSchemaForVariant(variant, column, tableName, key, primaryKeySet)
190
+ if (schema !== undefined) {
191
+ structFields[key] = schema
192
+ }
193
+ }
194
+ return Schema.Struct(structFields) as unknown as SchemaOfVariant<Variant, TableName, Fields, PrimaryKeyColumns>
195
+ }
196
+
197
+ export const deriveSelectSchema = <
198
+ TableName extends string,
199
+ Fields extends TableFieldMap,
200
+ PrimaryKeyColumns extends keyof Fields & string
201
+ >(
202
+ tableName: TableName,
203
+ fields: Fields,
204
+ primaryKeyColumns: readonly PrimaryKeyColumns[]
205
+ ): Schema.Schema<SelectRow<TableName, Fields>> =>
206
+ deriveSchema("select", tableName, fields, primaryKeyColumns)
207
+
208
+ export const deriveInsertSchema = <
209
+ TableName extends string,
210
+ Fields extends TableFieldMap,
211
+ PrimaryKeyColumns extends keyof Fields & string
212
+ >(
213
+ tableName: TableName,
214
+ fields: Fields,
215
+ primaryKeyColumns: readonly PrimaryKeyColumns[]
216
+ ): Schema.Schema<InsertRow<TableName, Fields>> =>
217
+ deriveSchema("insert", tableName, fields, primaryKeyColumns)
218
+
219
+ export const deriveUpdateSchema = <
220
+ TableName extends string,
221
+ Fields extends TableFieldMap,
222
+ PrimaryKeyColumns extends keyof Fields & string
223
+ >(
224
+ tableName: TableName,
225
+ fields: Fields,
226
+ primaryKeyColumns: readonly PrimaryKeyColumns[]
227
+ ): Schema.Schema<UpdateRow<TableName, Fields, PrimaryKeyColumns>> =>
228
+ deriveSchema("update", tableName, fields, primaryKeyColumns)
229
+
156
230
  /**
157
231
  * Derives the `select`, `insert`, and `update` schemas for a table.
158
232
  *
159
233
  * This is the central place where the column capability flags are turned into
160
234
  * real runtime schemas.
235
+ *
236
+ * @deprecated Prefer `deriveSelectSchema`, `deriveInsertSchema`, and
237
+ * `deriveUpdateSchema` so individual variants are derived lazily.
161
238
  */
162
239
  export const deriveSchemas = <
163
240
  TableName extends string,
@@ -171,33 +248,8 @@ export const deriveSchemas = <
171
248
  readonly select: Schema.Schema<SelectRow<TableName, Fields>>
172
249
  readonly insert: Schema.Schema<InsertRow<TableName, Fields>>
173
250
  readonly update: Schema.Schema<UpdateRow<TableName, Fields, PrimaryKeyColumns>>
174
- } => {
175
- const primaryKeySet = new Set<string>(primaryKeyColumns)
176
- const variants: Record<string, VariantSchema.Field<any>> = {}
177
- for (const [key, column] of Object.entries(fields)) {
178
- const config: Record<Variants, any> = {
179
- select: selectSchema(column, tableName, key),
180
- insert: undefined,
181
- update: undefined
182
- }
183
- const insert = insertSchema(column, tableName, key)
184
- const update = updateSchema(column, tableName, key, primaryKeySet.has(key))
185
- if (insert !== undefined) {
186
- config.insert = insert
187
- } else {
188
- delete config.insert
189
- }
190
- if (update !== undefined) {
191
- config.update = update
192
- } else {
193
- delete config.update
194
- }
195
- variants[key] = TableSchema.Field(config)
196
- }
197
- const struct = TableSchema.Struct(variants as any)
198
- return {
199
- select: TableSchema.extract(struct, "select") as unknown as Schema.Schema<SelectRow<TableName, Fields>>,
200
- insert: TableSchema.extract(struct, "insert") as unknown as Schema.Schema<InsertRow<TableName, Fields>>,
201
- update: TableSchema.extract(struct, "update") as unknown as Schema.Schema<UpdateRow<TableName, Fields, PrimaryKeyColumns>>
202
- }
203
- }
251
+ } => ({
252
+ select: deriveSelectSchema(tableName, fields, primaryKeyColumns),
253
+ insert: deriveInsertSchema(tableName, fields, primaryKeyColumns),
254
+ update: deriveUpdateSchema(tableName, fields, primaryKeyColumns)
255
+ })
@@ -6,7 +6,7 @@ export const TypeId: unique symbol = Symbol.for("effect-qb/SchemaExpression")
6
6
  export type TypeId = typeof TypeId
7
7
 
8
8
  const SchemaExpressionProto = {
9
- pipe(this: unknown) {
9
+ pipe(this: Pipeable) {
10
10
  return pipeArguments(this, arguments)
11
11
  }
12
12
  }
@@ -15,7 +15,7 @@ const attachPipe = <Value extends object>(value: Value): Value => {
15
15
  Object.defineProperty(value, "pipe", {
16
16
  configurable: true,
17
17
  writable: true,
18
- value: function(this: unknown) {
18
+ value: function(this: Value) {
19
19
  return pipeArguments(value, arguments)
20
20
  }
21
21
  })
@@ -0,0 +1,19 @@
1
+ import type { RenderedAst, RenderState, SqlDialect } from "./dialect.js"
2
+ import type * as Expression from "./scalar.js"
3
+ import type * as QueryAst from "./query-ast.js"
4
+
5
+ export const renderQueryAst = (
6
+ ast: QueryAst.Ast<Record<string, unknown>, any, QueryAst.QueryStatement>,
7
+ state: RenderState,
8
+ dialect: SqlDialect
9
+ ): RenderedAst => {
10
+ return dialect.renderQueryAst(ast, state, dialect)
11
+ }
12
+
13
+ export const renderExpression = (
14
+ expression: Expression.Any,
15
+ state: RenderState,
16
+ dialect: SqlDialect
17
+ ): string => {
18
+ return dialect.renderExpression(expression, state, dialect)
19
+ }