effect-qb 0.12.3

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 (81) hide show
  1. package/README.md +1294 -0
  2. package/dist/mysql.js +57575 -0
  3. package/dist/postgres.js +6303 -0
  4. package/package.json +42 -0
  5. package/src/internal/aggregation-validation.ts +57 -0
  6. package/src/internal/case-analysis.ts +50 -0
  7. package/src/internal/coercion-analysis.ts +30 -0
  8. package/src/internal/coercion-errors.ts +29 -0
  9. package/src/internal/coercion-kind.ts +32 -0
  10. package/src/internal/coercion-normalize.ts +7 -0
  11. package/src/internal/coercion-rules.ts +25 -0
  12. package/src/internal/column-state.ts +453 -0
  13. package/src/internal/column.ts +417 -0
  14. package/src/internal/datatypes/define.ts +44 -0
  15. package/src/internal/datatypes/lookup.ts +280 -0
  16. package/src/internal/datatypes/shape.ts +72 -0
  17. package/src/internal/derived-table.ts +149 -0
  18. package/src/internal/dialect.ts +30 -0
  19. package/src/internal/executor.ts +390 -0
  20. package/src/internal/expression-ast.ts +349 -0
  21. package/src/internal/expression.ts +325 -0
  22. package/src/internal/grouping-key.ts +82 -0
  23. package/src/internal/json/ast.ts +63 -0
  24. package/src/internal/json/errors.ts +13 -0
  25. package/src/internal/json/path.ts +227 -0
  26. package/src/internal/json/shape.ts +1 -0
  27. package/src/internal/json/types.ts +386 -0
  28. package/src/internal/mysql-dialect.ts +39 -0
  29. package/src/internal/mysql-renderer.ts +37 -0
  30. package/src/internal/plan.ts +64 -0
  31. package/src/internal/postgres-dialect.ts +34 -0
  32. package/src/internal/postgres-renderer.ts +40 -0
  33. package/src/internal/predicate-analysis.ts +71 -0
  34. package/src/internal/predicate-atom.ts +43 -0
  35. package/src/internal/predicate-branches.ts +40 -0
  36. package/src/internal/predicate-context.ts +279 -0
  37. package/src/internal/predicate-formula.ts +100 -0
  38. package/src/internal/predicate-key.ts +28 -0
  39. package/src/internal/predicate-nnf.ts +12 -0
  40. package/src/internal/predicate-normalize.ts +202 -0
  41. package/src/internal/projection-alias.ts +15 -0
  42. package/src/internal/projections.ts +101 -0
  43. package/src/internal/query-ast.ts +297 -0
  44. package/src/internal/query-factory.ts +6757 -0
  45. package/src/internal/query-requirements.ts +40 -0
  46. package/src/internal/query.ts +1590 -0
  47. package/src/internal/renderer.ts +102 -0
  48. package/src/internal/runtime-normalize.ts +344 -0
  49. package/src/internal/runtime-schema.ts +428 -0
  50. package/src/internal/runtime-value.ts +85 -0
  51. package/src/internal/schema-derivation.ts +131 -0
  52. package/src/internal/sql-expression-renderer.ts +1353 -0
  53. package/src/internal/table-options.ts +225 -0
  54. package/src/internal/table.ts +674 -0
  55. package/src/mysql/column.ts +30 -0
  56. package/src/mysql/datatypes/index.ts +6 -0
  57. package/src/mysql/datatypes/spec.ts +180 -0
  58. package/src/mysql/errors/catalog.ts +51662 -0
  59. package/src/mysql/errors/fields.ts +21 -0
  60. package/src/mysql/errors/index.ts +18 -0
  61. package/src/mysql/errors/normalize.ts +232 -0
  62. package/src/mysql/errors/requirements.ts +73 -0
  63. package/src/mysql/executor.ts +134 -0
  64. package/src/mysql/query.ts +189 -0
  65. package/src/mysql/renderer.ts +19 -0
  66. package/src/mysql/table.ts +157 -0
  67. package/src/mysql.ts +18 -0
  68. package/src/postgres/column.ts +20 -0
  69. package/src/postgres/datatypes/index.ts +8 -0
  70. package/src/postgres/datatypes/spec.ts +264 -0
  71. package/src/postgres/errors/catalog.ts +452 -0
  72. package/src/postgres/errors/fields.ts +48 -0
  73. package/src/postgres/errors/index.ts +4 -0
  74. package/src/postgres/errors/normalize.ts +209 -0
  75. package/src/postgres/errors/requirements.ts +65 -0
  76. package/src/postgres/errors/types.ts +38 -0
  77. package/src/postgres/executor.ts +131 -0
  78. package/src/postgres/query.ts +189 -0
  79. package/src/postgres/renderer.ts +29 -0
  80. package/src/postgres/table.ts +157 -0
  81. package/src/postgres.ts +18 -0
@@ -0,0 +1,280 @@
1
+ import type * as Expression from ".././expression.js"
2
+ import type { mysqlDatatypeFamilies, mysqlDatatypeKinds } from "../../mysql/datatypes/spec.js"
3
+ import type { postgresDatatypeFamilies, postgresDatatypeKinds } from "../../postgres/datatypes/spec.js"
4
+ import type { RuntimeOfTag, RuntimeTag } from "./shape.js"
5
+
6
+ type KnownDialect = "postgres" | "mysql"
7
+
8
+ type DialectKinds<Dialect extends KnownDialect> =
9
+ Dialect extends "postgres" ? typeof postgresDatatypeKinds :
10
+ typeof mysqlDatatypeKinds
11
+
12
+ type DialectFamilies<Dialect extends KnownDialect> =
13
+ Dialect extends "postgres" ? typeof postgresDatatypeFamilies :
14
+ typeof mysqlDatatypeFamilies
15
+
16
+ type StripParameterizedKind<Kind extends string> =
17
+ Kind extends `${infer Base}(${string}`
18
+ ? StripParameterizedKind<Base>
19
+ : Kind
20
+
21
+ type StripArrayKind<Kind extends string> =
22
+ Kind extends `${infer Base}[]`
23
+ ? StripArrayKind<Base>
24
+ : Kind
25
+
26
+ type BaseKind<Kind extends string> = StripArrayKind<StripParameterizedKind<Kind>>
27
+
28
+ type IsArrayKind<Kind extends string> = Kind extends `${string}[]` ? true : false
29
+
30
+ type ExactKindFamily =
31
+ | "array"
32
+ | "range"
33
+ | "multirange"
34
+ | "record"
35
+ | "enum"
36
+ | "set"
37
+
38
+ type KnownKindFamily<
39
+ Dialect extends KnownDialect,
40
+ Kind extends string
41
+ > = IsArrayKind<Kind> extends true
42
+ ? "array"
43
+ : BaseKind<Kind> extends "null"
44
+ ? "null"
45
+ : BaseKind<Kind> extends keyof DialectKinds<Dialect>
46
+ ? DialectKinds<Dialect>[BaseKind<Kind>] extends { readonly family: infer Family extends string }
47
+ ? Family
48
+ : never
49
+ : `other:${Dialect}:${Kind}`
50
+
51
+ type KnownKindRuntimeTag<
52
+ Dialect extends KnownDialect,
53
+ Kind extends string
54
+ > = IsArrayKind<Kind> extends true
55
+ ? "array"
56
+ : BaseKind<Kind> extends "null"
57
+ ? "null"
58
+ : BaseKind<Kind> extends keyof DialectKinds<Dialect>
59
+ ? DialectKinds<Dialect>[BaseKind<Kind>] extends { readonly runtime: infer Runtime extends RuntimeTag }
60
+ ? Runtime
61
+ : "unknown"
62
+ : "unknown"
63
+
64
+ type FamilyCastTargets<
65
+ Dialect extends KnownDialect,
66
+ Family extends string
67
+ > = Family extends keyof DialectFamilies<Dialect>
68
+ ? DialectFamilies<Dialect>[Family] extends { readonly castTargets: readonly (infer CastTarget extends string)[] }
69
+ ? CastTarget
70
+ : never
71
+ : never
72
+
73
+ type FamilyHasTextualTrait<
74
+ Dialect extends KnownDialect,
75
+ Family extends string
76
+ > = Family extends keyof DialectFamilies<Dialect>
77
+ ? DialectFamilies<Dialect>[Family] extends { readonly traits: infer Traits }
78
+ ? Traits extends { readonly textual: true }
79
+ ? true
80
+ : false
81
+ : false
82
+ : false
83
+
84
+ type BaseFamilyOf<
85
+ Dialect extends KnownDialect,
86
+ Kind extends string
87
+ > = Kind extends keyof DialectKinds<Dialect>
88
+ ? DialectKinds<Dialect>[Kind] extends { readonly family: infer Family extends string }
89
+ ? Family
90
+ : never
91
+ : `other:${Dialect}:${Kind}`
92
+
93
+ type BaseRuntimeTagOf<
94
+ Dialect extends KnownDialect,
95
+ Kind extends string
96
+ > = Kind extends keyof DialectKinds<Dialect>
97
+ ? DialectKinds<Dialect>[Kind] extends { readonly runtime: infer Runtime extends RuntimeTag }
98
+ ? Runtime
99
+ : "unknown"
100
+ : "unknown"
101
+
102
+ type BaseCompareGroupOf<
103
+ Dialect extends KnownDialect,
104
+ Kind extends string
105
+ > = BaseFamilyOf<Dialect, Kind> extends ExactKindFamily
106
+ ? Kind
107
+ : BaseFamilyOf<Dialect, Kind> extends keyof DialectFamilies<Dialect>
108
+ ? DialectFamilies<Dialect>[BaseFamilyOf<Dialect, Kind>] extends { readonly compareGroup: infer CompareGroup extends string }
109
+ ? CompareGroup
110
+ : never
111
+ : BaseFamilyOf<Dialect, Kind>
112
+
113
+ export type FamilyOfDbType<Db extends Expression.DbType.Any> =
114
+ Db extends Expression.DbType.Domain<any, infer Base extends Expression.DbType.Any, any>
115
+ ? FamilyOfDbType<Base>
116
+ : Db extends Expression.DbType.Array<any, any, any>
117
+ ? "array"
118
+ : Db extends Expression.DbType.Range<any, any, any>
119
+ ? "range"
120
+ : Db extends Expression.DbType.Multirange<any, any, any>
121
+ ? "multirange"
122
+ : Db extends Expression.DbType.Composite<any, any, any>
123
+ ? "record"
124
+ : Db extends Expression.DbType.Enum<any, any>
125
+ ? "enum"
126
+ : Db extends Expression.DbType.Set<any, any>
127
+ ? "set"
128
+ : Db extends Expression.DbType.Json<any, any>
129
+ ? "json"
130
+ : Db extends Expression.DbType.Base<infer Dialect extends KnownDialect, infer Kind extends string>
131
+ ? BaseFamilyOf<Dialect, Kind>
132
+ : "other:unknown:unknown"
133
+
134
+ export type CompareGroupOfDbType<Db extends Expression.DbType.Any> =
135
+ Db extends Expression.DbType.Domain<any, infer Base extends Expression.DbType.Any, any>
136
+ ? CompareGroupOfDbType<Base>
137
+ : Db extends Expression.DbType.Array<any, any, infer Kind extends string>
138
+ ? Kind
139
+ : Db extends Expression.DbType.Range<any, any, infer Kind extends string>
140
+ ? Kind
141
+ : Db extends Expression.DbType.Multirange<any, any, infer Kind extends string>
142
+ ? Kind
143
+ : Db extends Expression.DbType.Composite<any, any, infer Kind extends string>
144
+ ? Kind
145
+ : Db extends Expression.DbType.Enum<any, infer Kind extends string>
146
+ ? Kind
147
+ : Db extends Expression.DbType.Set<any, infer Kind extends string>
148
+ ? Kind
149
+ : Db extends Expression.DbType.Json<any, any>
150
+ ? never
151
+ : Db extends Expression.DbType.Base<infer Dialect extends KnownDialect, infer Kind extends string>
152
+ ? BaseCompareGroupOf<Dialect, Kind>
153
+ : "other:unknown:unknown"
154
+
155
+ export type RuntimeOfDbType<Db extends Expression.DbType.Any> =
156
+ Db extends Expression.DbType.Domain<any, infer Base extends Expression.DbType.Any, any>
157
+ ? RuntimeOfDbType<Base>
158
+ : Db extends Expression.DbType.Array<any, infer Element extends Expression.DbType.Any, any>
159
+ ? ReadonlyArray<RuntimeOfDbType<Element>>
160
+ : Db extends Expression.DbType.Composite<any, infer Fields extends Record<string, Expression.DbType.Any>, any>
161
+ ? { readonly [K in keyof Fields]: RuntimeOfDbType<Fields[K]> }
162
+ : Db extends Expression.DbType.Range<any, any, any> | Expression.DbType.Multirange<any, any, any>
163
+ ? unknown
164
+ : Db extends Expression.DbType.Json<any, any>
165
+ ? import("../runtime-value.js").JsonValue
166
+ : Db extends Expression.DbType.Enum<any, any> | Expression.DbType.Set<any, any>
167
+ ? string
168
+ : Db extends Expression.DbType.Base<infer Dialect extends KnownDialect, infer Kind extends string>
169
+ ? BaseRuntimeTagOf<Dialect, Kind> extends infer Runtime extends RuntimeTag
170
+ ? RuntimeOfTag<Runtime>
171
+ : unknown
172
+ : unknown
173
+
174
+ export type CanCompareDbTypes<
175
+ Left extends Expression.DbType.Any,
176
+ Right extends Expression.DbType.Any,
177
+ Dialect extends string
178
+ > = Left extends { readonly dialect: Dialect }
179
+ ? Right extends { readonly dialect: Dialect }
180
+ ? CompareGroupOfDbType<Left> extends never
181
+ ? false
182
+ : CompareGroupOfDbType<Right> extends never
183
+ ? false
184
+ : CompareGroupOfDbType<Left> extends "null"
185
+ ? false
186
+ : CompareGroupOfDbType<Right> extends "null"
187
+ ? false
188
+ : [CompareGroupOfDbType<Left>] extends [CompareGroupOfDbType<Right>]
189
+ ? [CompareGroupOfDbType<Right>] extends [CompareGroupOfDbType<Left>]
190
+ ? true
191
+ : false
192
+ : false
193
+ : false
194
+ : false
195
+
196
+ export type CanContainDbTypes<
197
+ Left extends Expression.DbType.Any,
198
+ Right extends Expression.DbType.Any,
199
+ Dialect extends string
200
+ > = Left extends { readonly dialect: Dialect }
201
+ ? Right extends { readonly dialect: Dialect }
202
+ ? FamilyOfDbType<Left> extends "array" | "range" | "multirange"
203
+ ? FamilyOfDbType<Right> extends "array" | "range" | "multirange"
204
+ ? [CompareGroupOfDbType<Left>] extends [CompareGroupOfDbType<Right>]
205
+ ? [CompareGroupOfDbType<Right>] extends [CompareGroupOfDbType<Left>]
206
+ ? true
207
+ : false
208
+ : false
209
+ : false
210
+ : false
211
+ : false
212
+ : false
213
+
214
+ export type CanTextuallyCoerceDbType<
215
+ Db extends Expression.DbType.Any,
216
+ Dialect extends string
217
+ > = Db extends { readonly dialect: Dialect }
218
+ ? Db extends Expression.DbType.Domain<any, infer Base extends Expression.DbType.Any, any>
219
+ ? CanTextuallyCoerceDbType<Base, Dialect>
220
+ : Db extends Expression.DbType.Enum<any, any> | Expression.DbType.Set<any, any>
221
+ ? true
222
+ : Db extends Expression.DbType.Json<any, any>
223
+ ? false
224
+ : Db extends Expression.DbType.Base<infer D extends KnownDialect, infer Kind extends string>
225
+ ? Kind extends keyof DialectKinds<D>
226
+ ? FamilyHasTextualTrait<D, BaseFamilyOf<D, Kind>> extends true
227
+ ? true
228
+ : false
229
+ : false
230
+ : false
231
+ : false
232
+
233
+ export type CanCastDbType<
234
+ Source extends Expression.DbType.Any,
235
+ Target extends Expression.DbType.Any,
236
+ Dialect extends string
237
+ > = Source extends { readonly dialect: Dialect }
238
+ ? Target extends { readonly dialect: Dialect }
239
+ ? Source extends Expression.DbType.Domain<any, infer Base extends Expression.DbType.Any, any>
240
+ ? CanCastDbType<Base, Target, Dialect>
241
+ : Target extends Expression.DbType.Domain<any, infer TargetBase extends Expression.DbType.Any, any>
242
+ ? CanCastDbType<Source, TargetBase, Dialect>
243
+ : [CompareGroupOfDbType<Source>] extends [CompareGroupOfDbType<Target>]
244
+ ? [CompareGroupOfDbType<Target>] extends [CompareGroupOfDbType<Source>]
245
+ ? true
246
+ : false
247
+ : Target extends
248
+ | Expression.DbType.Array<any, any, any>
249
+ | Expression.DbType.Range<any, any, any>
250
+ | Expression.DbType.Multirange<any, any, any>
251
+ | Expression.DbType.Composite<any, any, any>
252
+ | Expression.DbType.Enum<any, any>
253
+ | Expression.DbType.Set<any, any>
254
+ ? true
255
+ : Source extends Expression.DbType.Base<infer SourceDialect extends KnownDialect, infer SourceKind extends string>
256
+ ? Target extends Expression.DbType.Base<infer TargetDialect extends KnownDialect, infer TargetKind extends string>
257
+ ? SourceDialect extends TargetDialect
258
+ ? SourceKind extends keyof DialectKinds<SourceDialect>
259
+ ? TargetKind extends keyof DialectKinds<TargetDialect>
260
+ ? BaseFamilyOf<SourceDialect, SourceKind> extends ExactKindFamily
261
+ ? BaseFamilyOf<SourceDialect, TargetKind> extends "text"
262
+ ? FamilyCastTargets<SourceDialect, Extract<BaseFamilyOf<SourceDialect, SourceKind>, string>> extends infer Targets extends string
263
+ ? "text" extends Targets
264
+ ? true
265
+ : false
266
+ : false
267
+ : false
268
+ : BaseFamilyOf<SourceDialect, TargetKind> extends FamilyCastTargets<
269
+ SourceDialect,
270
+ Extract<BaseFamilyOf<SourceDialect, SourceKind>, string>
271
+ >
272
+ ? true
273
+ : false
274
+ : false
275
+ : false
276
+ : false
277
+ : false
278
+ : false
279
+ : false
280
+ : false
@@ -0,0 +1,72 @@
1
+ import type {
2
+ BigIntString,
3
+ DecimalString,
4
+ InstantString,
5
+ JsonValue,
6
+ LocalDateString,
7
+ LocalDateTimeString,
8
+ LocalTimeString,
9
+ OffsetTimeString,
10
+ YearString
11
+ } from "../runtime-value.js"
12
+
13
+ export type RuntimeTag =
14
+ | "string"
15
+ | "number"
16
+ | "bigintString"
17
+ | "boolean"
18
+ | "json"
19
+ | "localDate"
20
+ | "localTime"
21
+ | "offsetTime"
22
+ | "localDateTime"
23
+ | "instant"
24
+ | "year"
25
+ | "decimalString"
26
+ | "bytes"
27
+ | "array"
28
+ | "record"
29
+ | "unknown"
30
+ | "null"
31
+
32
+ export type RuntimeOfTag<Tag extends RuntimeTag> =
33
+ Tag extends "string" ? string :
34
+ Tag extends "number" ? number :
35
+ Tag extends "bigintString" ? BigIntString :
36
+ Tag extends "boolean" ? boolean :
37
+ Tag extends "json" ? JsonValue :
38
+ Tag extends "localDate" ? LocalDateString :
39
+ Tag extends "localTime" ? LocalTimeString :
40
+ Tag extends "offsetTime" ? OffsetTimeString :
41
+ Tag extends "localDateTime" ? LocalDateTimeString :
42
+ Tag extends "instant" ? InstantString :
43
+ Tag extends "year" ? YearString :
44
+ Tag extends "decimalString" ? DecimalString :
45
+ Tag extends "bytes" ? Uint8Array :
46
+ Tag extends "array" ? ReadonlyArray<unknown> :
47
+ Tag extends "record" ? Record<string, unknown> :
48
+ Tag extends "null" ? null :
49
+ unknown
50
+
51
+ export interface DatatypeTraits {
52
+ readonly textual?: true
53
+ readonly ordered?: true
54
+ }
55
+
56
+ export interface DatatypeFamilySpec<
57
+ CompareGroup extends string = string,
58
+ CastTargets extends readonly string[] = readonly string[],
59
+ Traits extends DatatypeTraits = DatatypeTraits
60
+ > {
61
+ readonly compareGroup: CompareGroup
62
+ readonly castTargets: CastTargets
63
+ readonly traits: Traits
64
+ }
65
+
66
+ export interface DatatypeKindSpec<
67
+ Family extends string = string,
68
+ Runtime extends RuntimeTag = RuntimeTag
69
+ > {
70
+ readonly family: Family
71
+ readonly runtime: Runtime
72
+ }
@@ -0,0 +1,149 @@
1
+ import { pipeArguments } from "effect/Pipeable"
2
+
3
+ import * as Expression from "./expression.js"
4
+ import * as Plan from "./plan.js"
5
+ import {
6
+ type CompletePlan,
7
+ type CteSource,
8
+ type DerivedSelectionOf,
9
+ type DerivedSource,
10
+ type LateralSource,
11
+ type QueryPlan,
12
+ getAst,
13
+ makeExpression,
14
+ type SelectionOfPlan
15
+ } from "./query.js"
16
+ import * as ExpressionAst from "./expression-ast.js"
17
+ import { flattenSelection } from "./projections.js"
18
+
19
+ const DerivedProto = {
20
+ pipe(this: unknown) {
21
+ return pipeArguments(this, arguments)
22
+ }
23
+ }
24
+
25
+ const setPath = (
26
+ target: Record<string, unknown>,
27
+ path: readonly string[],
28
+ value: unknown
29
+ ): void => {
30
+ let current = target
31
+ for (let index = 0; index < path.length - 1; index++) {
32
+ const segment = path[index]!
33
+ const existing = current[segment]
34
+ if (typeof existing === "object" && existing !== null && !Array.isArray(existing)) {
35
+ current = existing as Record<string, unknown>
36
+ continue
37
+ }
38
+ const next: Record<string, unknown> = {}
39
+ current[segment] = next
40
+ current = next
41
+ }
42
+ current[path[path.length - 1]!] = value
43
+ }
44
+
45
+ const pathAlias = (path: readonly string[]): string => path.join("__")
46
+
47
+ const reboundedColumns = <
48
+ PlanValue extends QueryPlan<any, any, any, any, any, any, any, any, any>,
49
+ Alias extends string
50
+ >(
51
+ plan: PlanValue,
52
+ alias: Alias
53
+ ): DerivedSelectionOf<SelectionOfPlan<PlanValue>, Alias> => {
54
+ const ast = getAst(plan)
55
+ const selection = {} as Record<string, unknown>
56
+ for (const projection of flattenSelection(ast.select as Record<string, unknown>)) {
57
+ const expectedAlias = pathAlias(projection.path)
58
+ if (projection.alias !== expectedAlias) {
59
+ throw new Error(
60
+ `Derived subqueries currently require path-based output aliases; expected '${expectedAlias}' for path '${projection.path.join(".")}'`
61
+ )
62
+ }
63
+ const expression = projection.expression
64
+ setPath(selection, projection.path, makeExpression({
65
+ runtime: undefined as never,
66
+ dbType: expression[Expression.TypeId].dbType,
67
+ runtimeSchema: expression[Expression.TypeId].runtimeSchema,
68
+ nullability: expression[Expression.TypeId].nullability,
69
+ dialect: expression[Expression.TypeId].dialect,
70
+ aggregation: "scalar",
71
+ source: {
72
+ tableName: alias,
73
+ columnName: projection.alias,
74
+ baseTableName: alias
75
+ },
76
+ sourceNullability: "propagate" as const,
77
+ dependencies: {
78
+ [alias]: true
79
+ } as Record<Alias, true>
80
+ }, {
81
+ kind: "column",
82
+ tableName: alias,
83
+ columnName: projection.alias
84
+ } satisfies ExpressionAst.ColumnNode<Alias, string>))
85
+ }
86
+ return selection as DerivedSelectionOf<SelectionOfPlan<PlanValue>, Alias>
87
+ }
88
+
89
+ export const makeDerivedSource = <
90
+ PlanValue extends QueryPlan<any, any, any, any, any, any, any, any, any>,
91
+ Alias extends string
92
+ >(
93
+ plan: CompletePlan<PlanValue>,
94
+ alias: Alias
95
+ ): DerivedSource<PlanValue, Alias> => {
96
+ const columns = reboundedColumns(plan, alias)
97
+ const derived = Object.create(DerivedProto) as Record<string, unknown>
98
+ Object.assign(derived, columns)
99
+ derived.kind = "derived"
100
+ derived.name = alias
101
+ derived.baseName = alias
102
+ derived.dialect = plan[Plan.TypeId].dialect
103
+ derived.plan = plan
104
+ derived.required = undefined as never
105
+ derived.columns = columns
106
+ return derived as unknown as DerivedSource<PlanValue, Alias>
107
+ }
108
+
109
+ export const makeCteSource = <
110
+ PlanValue extends QueryPlan<any, any, any, any, any, any, any, any, any>,
111
+ Alias extends string
112
+ >(
113
+ plan: CompletePlan<PlanValue>,
114
+ alias: Alias,
115
+ recursive = false
116
+ ): CteSource<PlanValue, Alias> => {
117
+ const columns = reboundedColumns(plan, alias)
118
+ const cte = Object.create(DerivedProto) as Record<string, unknown>
119
+ Object.assign(cte, columns)
120
+ cte.kind = "cte"
121
+ cte.name = alias
122
+ cte.baseName = alias
123
+ cte.dialect = plan[Plan.TypeId].dialect
124
+ cte.plan = plan
125
+ cte.recursive = recursive
126
+ cte.required = undefined as never
127
+ cte.columns = columns
128
+ return cte as unknown as CteSource<PlanValue, Alias>
129
+ }
130
+
131
+ export const makeLateralSource = <
132
+ PlanValue extends QueryPlan<any, any, any, any, any, any, any, any, any>,
133
+ Alias extends string
134
+ >(
135
+ plan: PlanValue,
136
+ alias: Alias
137
+ ): LateralSource<PlanValue, Alias> => {
138
+ const columns = reboundedColumns(plan, alias)
139
+ const lateral = Object.create(DerivedProto) as Record<string, unknown>
140
+ Object.assign(lateral, columns)
141
+ lateral.kind = "lateral"
142
+ lateral.name = alias
143
+ lateral.baseName = alias
144
+ lateral.dialect = plan[Plan.TypeId].dialect
145
+ lateral.plan = plan
146
+ lateral.required = undefined as never
147
+ lateral.columns = columns
148
+ return lateral as unknown as LateralSource<PlanValue, Alias>
149
+ }
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Mutable rendering state shared while serializing SQL for a concrete dialect.
3
+ *
4
+ * Dialect implementations append bound parameter values into `params` and
5
+ * refer to them positionally in the emitted SQL text.
6
+ */
7
+ export interface RenderState {
8
+ readonly params: unknown[]
9
+ readonly ctes: {
10
+ readonly name: string
11
+ readonly sql: string
12
+ readonly recursive?: boolean
13
+ }[]
14
+ readonly cteNames: Set<string>
15
+ }
16
+
17
+ /**
18
+ * Minimal runtime contract for a SQL dialect.
19
+ *
20
+ * This is intentionally small for the first abstraction pass. It covers the
21
+ * renderer seams that are already dialect-sensitive today: identifier quoting,
22
+ * literal serialization, and table-reference rendering.
23
+ */
24
+ export interface SqlDialect<Name extends string = string> {
25
+ readonly name: Name
26
+ quoteIdentifier(value: string): string
27
+ renderLiteral(value: unknown, state: RenderState): string
28
+ renderTableReference(tableName: string, baseTableName: string, schemaName?: string): string
29
+ renderConcat(values: readonly string[]): string
30
+ }