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.
- package/README.md +1294 -0
- package/dist/mysql.js +57575 -0
- package/dist/postgres.js +6303 -0
- package/package.json +42 -0
- package/src/internal/aggregation-validation.ts +57 -0
- package/src/internal/case-analysis.ts +50 -0
- package/src/internal/coercion-analysis.ts +30 -0
- package/src/internal/coercion-errors.ts +29 -0
- package/src/internal/coercion-kind.ts +32 -0
- package/src/internal/coercion-normalize.ts +7 -0
- package/src/internal/coercion-rules.ts +25 -0
- package/src/internal/column-state.ts +453 -0
- package/src/internal/column.ts +417 -0
- package/src/internal/datatypes/define.ts +44 -0
- package/src/internal/datatypes/lookup.ts +280 -0
- package/src/internal/datatypes/shape.ts +72 -0
- package/src/internal/derived-table.ts +149 -0
- package/src/internal/dialect.ts +30 -0
- package/src/internal/executor.ts +390 -0
- package/src/internal/expression-ast.ts +349 -0
- package/src/internal/expression.ts +325 -0
- package/src/internal/grouping-key.ts +82 -0
- package/src/internal/json/ast.ts +63 -0
- package/src/internal/json/errors.ts +13 -0
- package/src/internal/json/path.ts +227 -0
- package/src/internal/json/shape.ts +1 -0
- package/src/internal/json/types.ts +386 -0
- package/src/internal/mysql-dialect.ts +39 -0
- package/src/internal/mysql-renderer.ts +37 -0
- package/src/internal/plan.ts +64 -0
- package/src/internal/postgres-dialect.ts +34 -0
- package/src/internal/postgres-renderer.ts +40 -0
- package/src/internal/predicate-analysis.ts +71 -0
- package/src/internal/predicate-atom.ts +43 -0
- package/src/internal/predicate-branches.ts +40 -0
- package/src/internal/predicate-context.ts +279 -0
- package/src/internal/predicate-formula.ts +100 -0
- package/src/internal/predicate-key.ts +28 -0
- package/src/internal/predicate-nnf.ts +12 -0
- package/src/internal/predicate-normalize.ts +202 -0
- package/src/internal/projection-alias.ts +15 -0
- package/src/internal/projections.ts +101 -0
- package/src/internal/query-ast.ts +297 -0
- package/src/internal/query-factory.ts +6757 -0
- package/src/internal/query-requirements.ts +40 -0
- package/src/internal/query.ts +1590 -0
- package/src/internal/renderer.ts +102 -0
- package/src/internal/runtime-normalize.ts +344 -0
- package/src/internal/runtime-schema.ts +428 -0
- package/src/internal/runtime-value.ts +85 -0
- package/src/internal/schema-derivation.ts +131 -0
- package/src/internal/sql-expression-renderer.ts +1353 -0
- package/src/internal/table-options.ts +225 -0
- package/src/internal/table.ts +674 -0
- package/src/mysql/column.ts +30 -0
- package/src/mysql/datatypes/index.ts +6 -0
- package/src/mysql/datatypes/spec.ts +180 -0
- package/src/mysql/errors/catalog.ts +51662 -0
- package/src/mysql/errors/fields.ts +21 -0
- package/src/mysql/errors/index.ts +18 -0
- package/src/mysql/errors/normalize.ts +232 -0
- package/src/mysql/errors/requirements.ts +73 -0
- package/src/mysql/executor.ts +134 -0
- package/src/mysql/query.ts +189 -0
- package/src/mysql/renderer.ts +19 -0
- package/src/mysql/table.ts +157 -0
- package/src/mysql.ts +18 -0
- package/src/postgres/column.ts +20 -0
- package/src/postgres/datatypes/index.ts +8 -0
- package/src/postgres/datatypes/spec.ts +264 -0
- package/src/postgres/errors/catalog.ts +452 -0
- package/src/postgres/errors/fields.ts +48 -0
- package/src/postgres/errors/index.ts +4 -0
- package/src/postgres/errors/normalize.ts +209 -0
- package/src/postgres/errors/requirements.ts +65 -0
- package/src/postgres/errors/types.ts +38 -0
- package/src/postgres/executor.ts +131 -0
- package/src/postgres/query.ts +189 -0
- package/src/postgres/renderer.ts +29 -0
- package/src/postgres/table.ts +157 -0
- 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
|
+
}
|