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,386 @@
|
|
|
1
|
+
import type * as JsonPath from "./path.js"
|
|
2
|
+
import type { JsonPathUsageError } from "./errors.js"
|
|
3
|
+
|
|
4
|
+
export type JsonPrimitive = string | number | boolean | null
|
|
5
|
+
|
|
6
|
+
export type JsonValue =
|
|
7
|
+
| JsonPrimitive
|
|
8
|
+
| readonly JsonValue[]
|
|
9
|
+
| { readonly [key: string]: JsonValue }
|
|
10
|
+
|
|
11
|
+
type OptionalKeyOf<ObjectType extends object, Key extends PropertyKey> =
|
|
12
|
+
Key extends keyof ObjectType
|
|
13
|
+
? {} extends Pick<ObjectType, Key> ? true : false
|
|
14
|
+
: true
|
|
15
|
+
|
|
16
|
+
type NormalizeJsonTuple<Values extends readonly unknown[]> =
|
|
17
|
+
Values extends readonly []
|
|
18
|
+
? readonly []
|
|
19
|
+
: Values extends readonly [infer Head, ...infer Tail]
|
|
20
|
+
? readonly [NormalizeJsonLiteral<Head>, ...NormalizeJsonTuple<Tail>]
|
|
21
|
+
: readonly NormalizeJsonLiteral<Values[number]>[]
|
|
22
|
+
|
|
23
|
+
type NormalizeJsonObject<ObjectType extends object> = {
|
|
24
|
+
readonly [Key in keyof ObjectType as Key extends string ? Key : never]:
|
|
25
|
+
NormalizeJsonLiteral<Exclude<ObjectType[Key], undefined>>
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export type NormalizeJsonLiteral<Value> =
|
|
29
|
+
[Value] extends [never] ? never :
|
|
30
|
+
Value extends JsonPrimitive ? Value :
|
|
31
|
+
Value extends undefined | bigint | symbol | Date | ((...args: readonly any[]) => any) ? never :
|
|
32
|
+
Value extends readonly unknown[] ? NormalizeJsonTuple<Value> :
|
|
33
|
+
Value extends object ? NormalizeJsonObject<Value> :
|
|
34
|
+
never
|
|
35
|
+
|
|
36
|
+
export type JsonLiteralInput = JsonPrimitive | readonly JsonLiteralInput[] | {
|
|
37
|
+
readonly [key: string]: JsonLiteralInput
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
type StripNull<Value> = Exclude<Value, null>
|
|
41
|
+
|
|
42
|
+
type KeyStep<
|
|
43
|
+
Root,
|
|
44
|
+
Key extends string,
|
|
45
|
+
Operation extends string
|
|
46
|
+
> = Root extends readonly unknown[]
|
|
47
|
+
? JsonPathUsageError<Operation, Root, JsonPath.KeySegment<Key>, "key segments cannot be applied to arrays">
|
|
48
|
+
: Root extends object
|
|
49
|
+
? Key extends keyof Root
|
|
50
|
+
? NormalizeJsonLiteral<Exclude<Root[Key], undefined>> | (OptionalKeyOf<Root, Key> extends true ? null : never)
|
|
51
|
+
: Root extends Record<string, infer Value>
|
|
52
|
+
? NormalizeJsonLiteral<Value> | null
|
|
53
|
+
: null
|
|
54
|
+
: JsonPathUsageError<Operation, Root, JsonPath.KeySegment<Key>, "key segments require an object-like json value">
|
|
55
|
+
|
|
56
|
+
type TupleIndex<
|
|
57
|
+
Values extends readonly unknown[],
|
|
58
|
+
Index extends number,
|
|
59
|
+
Count extends readonly unknown[] = []
|
|
60
|
+
> = Values extends readonly [infer Head, ...infer Tail]
|
|
61
|
+
? Count["length"] extends Index
|
|
62
|
+
? Head
|
|
63
|
+
: TupleIndex<Tail, Index, [...Count, unknown]>
|
|
64
|
+
: never
|
|
65
|
+
|
|
66
|
+
type DropTupleIndex<
|
|
67
|
+
Values extends readonly unknown[],
|
|
68
|
+
Index extends number,
|
|
69
|
+
Count extends readonly unknown[] = []
|
|
70
|
+
> = Values extends readonly [infer Head, ...infer Tail]
|
|
71
|
+
? Count["length"] extends Index
|
|
72
|
+
? readonly [...Tail]
|
|
73
|
+
: readonly [Head, ...DropTupleIndex<Tail, Index, [...Count, unknown]>]
|
|
74
|
+
: readonly []
|
|
75
|
+
|
|
76
|
+
type SetTupleIndex<
|
|
77
|
+
Values extends readonly unknown[],
|
|
78
|
+
Index extends number,
|
|
79
|
+
Next,
|
|
80
|
+
Count extends readonly unknown[] = []
|
|
81
|
+
> = Values extends readonly [infer Head, ...infer Tail]
|
|
82
|
+
? Count["length"] extends Index
|
|
83
|
+
? readonly [Next, ...Tail]
|
|
84
|
+
: readonly [Head, ...SetTupleIndex<Tail, Index, Next, [...Count, unknown]>]
|
|
85
|
+
: readonly NormalizeJsonLiteral<Next>[]
|
|
86
|
+
|
|
87
|
+
type InsertTupleIndex<
|
|
88
|
+
Values extends readonly unknown[],
|
|
89
|
+
Index extends number,
|
|
90
|
+
Next,
|
|
91
|
+
After extends boolean,
|
|
92
|
+
Count extends readonly unknown[] = []
|
|
93
|
+
> = Values extends readonly [infer Head, ...infer Tail]
|
|
94
|
+
? Count["length"] extends Index
|
|
95
|
+
? After extends true
|
|
96
|
+
? readonly [Head, NormalizeJsonLiteral<Next>, ...Tail]
|
|
97
|
+
: readonly [NormalizeJsonLiteral<Next>, Head, ...Tail]
|
|
98
|
+
: readonly [Head, ...InsertTupleIndex<Tail, Index, Next, After, [...Count, unknown]>]
|
|
99
|
+
: readonly NormalizeJsonLiteral<Next>[]
|
|
100
|
+
|
|
101
|
+
type IndexStep<
|
|
102
|
+
Root,
|
|
103
|
+
Index extends number,
|
|
104
|
+
Operation extends string
|
|
105
|
+
> = Root extends readonly unknown[]
|
|
106
|
+
? number extends Root["length"]
|
|
107
|
+
? NormalizeJsonLiteral<Root[number]> | null
|
|
108
|
+
: NormalizeJsonLiteral<TupleIndex<Root, Index>> | (TupleIndex<Root, Index> extends never ? null : never)
|
|
109
|
+
: JsonPathUsageError<Operation, Root, JsonPath.IndexSegment<Index>, "index segments require an array-like json value">
|
|
110
|
+
|
|
111
|
+
type NonExactStep<
|
|
112
|
+
Root,
|
|
113
|
+
Segment extends JsonPath.CanonicalSegment
|
|
114
|
+
> = Segment extends JsonPath.WildcardSegment
|
|
115
|
+
? NormalizeJsonLiteral<Root> | null
|
|
116
|
+
: Segment extends JsonPath.SliceSegment<any, any>
|
|
117
|
+
? NormalizeJsonLiteral<Root> | null
|
|
118
|
+
: Segment extends JsonPath.DescendSegment
|
|
119
|
+
? NormalizeJsonLiteral<Root> | null
|
|
120
|
+
: never
|
|
121
|
+
|
|
122
|
+
type StepValue<
|
|
123
|
+
Root,
|
|
124
|
+
Segment extends JsonPath.CanonicalSegment,
|
|
125
|
+
Operation extends string
|
|
126
|
+
> = Segment extends JsonPath.KeySegment<infer Key extends string>
|
|
127
|
+
? KeyStep<Root, Key, Operation>
|
|
128
|
+
: Segment extends JsonPath.IndexSegment<infer Index extends number>
|
|
129
|
+
? IndexStep<Root, Index, Operation>
|
|
130
|
+
: NonExactStep<Root, Segment>
|
|
131
|
+
|
|
132
|
+
type StepSet<
|
|
133
|
+
Root,
|
|
134
|
+
Segment extends JsonPath.CanonicalSegment,
|
|
135
|
+
Next,
|
|
136
|
+
Operation extends string
|
|
137
|
+
> = Segment extends JsonPath.KeySegment<infer Key extends string>
|
|
138
|
+
? Root extends readonly unknown[]
|
|
139
|
+
? JsonPathUsageError<Operation, Root, Segment, "key segments cannot update arrays">
|
|
140
|
+
: Root extends object
|
|
141
|
+
? Omit<Root, Key> & {
|
|
142
|
+
readonly [K in Key]: NormalizeJsonLiteral<Next>
|
|
143
|
+
}
|
|
144
|
+
: JsonPathUsageError<Operation, Root, Segment, "key segments require an object-like json value">
|
|
145
|
+
: Segment extends JsonPath.IndexSegment<infer Index extends number>
|
|
146
|
+
? Root extends readonly unknown[]
|
|
147
|
+
? number extends Root["length"]
|
|
148
|
+
? readonly (NormalizeJsonLiteral<Root[number]> | NormalizeJsonLiteral<Next>)[]
|
|
149
|
+
: SetTupleIndex<Root, Index, Next>
|
|
150
|
+
: JsonPathUsageError<Operation, Root, Segment, "index segments require an array-like json value">
|
|
151
|
+
: NormalizeJsonLiteral<Root>
|
|
152
|
+
|
|
153
|
+
type StepDelete<
|
|
154
|
+
Root,
|
|
155
|
+
Segment extends JsonPath.CanonicalSegment,
|
|
156
|
+
Operation extends string
|
|
157
|
+
> = Segment extends JsonPath.KeySegment<infer Key extends string>
|
|
158
|
+
? Root extends readonly unknown[]
|
|
159
|
+
? JsonPathUsageError<Operation, Root, Segment, "key segments cannot delete from arrays">
|
|
160
|
+
: Root extends object
|
|
161
|
+
? Omit<Root, Key>
|
|
162
|
+
: JsonPathUsageError<Operation, Root, Segment, "key segments require an object-like json value">
|
|
163
|
+
: Segment extends JsonPath.IndexSegment<infer Index extends number>
|
|
164
|
+
? Root extends readonly unknown[]
|
|
165
|
+
? number extends Root["length"]
|
|
166
|
+
? Root
|
|
167
|
+
: DropTupleIndex<Root, Index>
|
|
168
|
+
: JsonPathUsageError<Operation, Root, Segment, "index segments require an array-like json value">
|
|
169
|
+
: NormalizeJsonLiteral<Root>
|
|
170
|
+
|
|
171
|
+
type StepInsert<
|
|
172
|
+
Root,
|
|
173
|
+
Segment extends JsonPath.CanonicalSegment,
|
|
174
|
+
Next,
|
|
175
|
+
After extends boolean,
|
|
176
|
+
Operation extends string
|
|
177
|
+
> = Segment extends JsonPath.IndexSegment<infer Index extends number>
|
|
178
|
+
? Root extends readonly unknown[]
|
|
179
|
+
? number extends Root["length"]
|
|
180
|
+
? readonly (NormalizeJsonLiteral<Root[number]> | NormalizeJsonLiteral<Next>)[]
|
|
181
|
+
: InsertTupleIndex<Root, Index, Next, After>
|
|
182
|
+
: JsonPathUsageError<Operation, Root, Segment, "index segments require an array-like json value">
|
|
183
|
+
: Segment extends JsonPath.KeySegment<infer Key extends string>
|
|
184
|
+
? Root extends readonly unknown[]
|
|
185
|
+
? JsonPathUsageError<Operation, Root, Segment, "key segments cannot insert into arrays">
|
|
186
|
+
: Root extends object
|
|
187
|
+
? Key extends keyof Root
|
|
188
|
+
? Root
|
|
189
|
+
: Root & {
|
|
190
|
+
readonly [K in Key]: NormalizeJsonLiteral<Next>
|
|
191
|
+
}
|
|
192
|
+
: JsonPathUsageError<Operation, Root, Segment, "key segments require an object-like json value">
|
|
193
|
+
: NormalizeJsonLiteral<Root>
|
|
194
|
+
|
|
195
|
+
type RecurseValue<
|
|
196
|
+
Current,
|
|
197
|
+
Segments extends readonly JsonPath.CanonicalSegment[],
|
|
198
|
+
Operation extends string
|
|
199
|
+
> = Segments extends readonly [infer Head extends JsonPath.CanonicalSegment, ...infer Tail extends readonly JsonPath.CanonicalSegment[]]
|
|
200
|
+
? StepValue<Current, Head, Operation> extends infer Next
|
|
201
|
+
? Next extends JsonPathUsageError<any, any, any, any>
|
|
202
|
+
? Next
|
|
203
|
+
: Tail extends readonly []
|
|
204
|
+
? Next
|
|
205
|
+
: null extends Next
|
|
206
|
+
? RecurseValue<StripNull<Next>, Tail, Operation> | null
|
|
207
|
+
: RecurseValue<Next, Tail, Operation>
|
|
208
|
+
: never
|
|
209
|
+
: NormalizeJsonLiteral<Current>
|
|
210
|
+
|
|
211
|
+
type RecurseSet<
|
|
212
|
+
Current,
|
|
213
|
+
Segments extends readonly JsonPath.CanonicalSegment[],
|
|
214
|
+
Next,
|
|
215
|
+
Operation extends string
|
|
216
|
+
> = Segments extends readonly [infer Head extends JsonPath.CanonicalSegment, ...infer Tail extends readonly JsonPath.CanonicalSegment[]]
|
|
217
|
+
? Tail extends readonly []
|
|
218
|
+
? StepSet<Current, Head, Next, Operation>
|
|
219
|
+
: StepValue<Current, Head, Operation> extends infer Child
|
|
220
|
+
? Child extends JsonPathUsageError<any, any, any, any>
|
|
221
|
+
? Child
|
|
222
|
+
: StepSet<
|
|
223
|
+
Current,
|
|
224
|
+
Head,
|
|
225
|
+
RecurseSet<StripNull<Child>, Tail, Next, Operation>,
|
|
226
|
+
Operation
|
|
227
|
+
>
|
|
228
|
+
: never
|
|
229
|
+
: NormalizeJsonLiteral<Next>
|
|
230
|
+
|
|
231
|
+
type RecurseDelete<
|
|
232
|
+
Current,
|
|
233
|
+
Segments extends readonly JsonPath.CanonicalSegment[],
|
|
234
|
+
Operation extends string
|
|
235
|
+
> = Segments extends readonly [infer Head extends JsonPath.CanonicalSegment, ...infer Tail extends readonly JsonPath.CanonicalSegment[]]
|
|
236
|
+
? Tail extends readonly []
|
|
237
|
+
? StepDelete<Current, Head, Operation>
|
|
238
|
+
: StepValue<Current, Head, Operation> extends infer Child
|
|
239
|
+
? Child extends JsonPathUsageError<any, any, any, any>
|
|
240
|
+
? Child
|
|
241
|
+
: StepSet<
|
|
242
|
+
Current,
|
|
243
|
+
Head,
|
|
244
|
+
RecurseDelete<StripNull<Child>, Tail, Operation>,
|
|
245
|
+
Operation
|
|
246
|
+
>
|
|
247
|
+
: never
|
|
248
|
+
: NormalizeJsonLiteral<Current>
|
|
249
|
+
|
|
250
|
+
type RecurseInsert<
|
|
251
|
+
Current,
|
|
252
|
+
Segments extends readonly JsonPath.CanonicalSegment[],
|
|
253
|
+
Next,
|
|
254
|
+
After extends boolean,
|
|
255
|
+
Operation extends string
|
|
256
|
+
> = Segments extends readonly [infer Head extends JsonPath.CanonicalSegment, ...infer Tail extends readonly JsonPath.CanonicalSegment[]]
|
|
257
|
+
? Tail extends readonly []
|
|
258
|
+
? StepInsert<Current, Head, Next, After, Operation>
|
|
259
|
+
: StepValue<Current, Head, Operation> extends infer Child
|
|
260
|
+
? Child extends JsonPathUsageError<any, any, any, any>
|
|
261
|
+
? Child
|
|
262
|
+
: StepSet<
|
|
263
|
+
Current,
|
|
264
|
+
Head,
|
|
265
|
+
RecurseInsert<StripNull<Child>, Tail, Next, After, Operation>,
|
|
266
|
+
Operation
|
|
267
|
+
>
|
|
268
|
+
: never
|
|
269
|
+
: NormalizeJsonLiteral<Current>
|
|
270
|
+
|
|
271
|
+
export type JsonValueAtPath<
|
|
272
|
+
Root,
|
|
273
|
+
PathValue extends JsonPath.Path<any>,
|
|
274
|
+
Operation extends string = "json.get"
|
|
275
|
+
> = RecurseValue<NormalizeJsonLiteral<Root>, JsonPath.SegmentsOf<PathValue>, Operation>
|
|
276
|
+
|
|
277
|
+
export type JsonSetAtPath<
|
|
278
|
+
Root,
|
|
279
|
+
PathValue extends JsonPath.Path<any>,
|
|
280
|
+
Next,
|
|
281
|
+
Operation extends string = "json.set"
|
|
282
|
+
> = RecurseSet<NormalizeJsonLiteral<Root>, JsonPath.SegmentsOf<PathValue>, Next, Operation>
|
|
283
|
+
|
|
284
|
+
export type JsonInsertAtPath<
|
|
285
|
+
Root,
|
|
286
|
+
PathValue extends JsonPath.Path<any>,
|
|
287
|
+
Next,
|
|
288
|
+
After extends boolean = false,
|
|
289
|
+
Operation extends string = "json.insert"
|
|
290
|
+
> = RecurseInsert<NormalizeJsonLiteral<Root>, JsonPath.SegmentsOf<PathValue>, Next, After, Operation>
|
|
291
|
+
|
|
292
|
+
export type JsonDeleteAtPath<
|
|
293
|
+
Root,
|
|
294
|
+
PathValue extends JsonPath.Path<any>,
|
|
295
|
+
Operation extends string = "json.delete"
|
|
296
|
+
> = RecurseDelete<NormalizeJsonLiteral<Root>, JsonPath.SegmentsOf<PathValue>, Operation>
|
|
297
|
+
|
|
298
|
+
type ArrayElement<Value> = Value extends readonly (infer Element)[] ? Element : never
|
|
299
|
+
|
|
300
|
+
type MergeJsonObjects<
|
|
301
|
+
Left extends object,
|
|
302
|
+
Right extends object
|
|
303
|
+
> = Omit<Left, keyof Right> & Right
|
|
304
|
+
|
|
305
|
+
type StripNullsTuple<Values extends readonly unknown[]> =
|
|
306
|
+
Values extends readonly []
|
|
307
|
+
? readonly []
|
|
308
|
+
: Values extends readonly [infer Head, ...infer Tail]
|
|
309
|
+
? readonly [JsonStripNullsResult<Head>, ...StripNullsTuple<Tail>]
|
|
310
|
+
: readonly JsonStripNullsResult<Values[number]>[]
|
|
311
|
+
|
|
312
|
+
type StripNullsObject<ObjectType extends object> = (
|
|
313
|
+
{
|
|
314
|
+
readonly [Key in keyof ObjectType as Key extends string
|
|
315
|
+
? null extends NormalizeJsonLiteral<Exclude<ObjectType[Key], undefined>>
|
|
316
|
+
? never
|
|
317
|
+
: Key
|
|
318
|
+
: never]-?: JsonStripNullsResult<Exclude<ObjectType[Key], null>>
|
|
319
|
+
} & {
|
|
320
|
+
readonly [Key in keyof ObjectType as Key extends string
|
|
321
|
+
? null extends NormalizeJsonLiteral<Exclude<ObjectType[Key], undefined>>
|
|
322
|
+
? Key
|
|
323
|
+
: never
|
|
324
|
+
: never]?: JsonStripNullsResult<Exclude<ObjectType[Key], null>>
|
|
325
|
+
}
|
|
326
|
+
)
|
|
327
|
+
|
|
328
|
+
export type JsonStripNullsResult<Value> =
|
|
329
|
+
Value extends null ? null :
|
|
330
|
+
Value extends readonly unknown[] ? StripNullsTuple<Value> :
|
|
331
|
+
Value extends object ? StripNullsObject<Value> :
|
|
332
|
+
Value
|
|
333
|
+
|
|
334
|
+
export type JsonConcatResult<
|
|
335
|
+
Left,
|
|
336
|
+
Right
|
|
337
|
+
> = NormalizeJsonLiteral<Left> extends infer NormalizedLeft
|
|
338
|
+
? NormalizeJsonLiteral<Right> extends infer NormalizedRight
|
|
339
|
+
? NormalizedLeft extends readonly unknown[]
|
|
340
|
+
? NormalizedRight extends readonly unknown[]
|
|
341
|
+
? number extends NormalizedLeft["length"] | NormalizedRight["length"]
|
|
342
|
+
? readonly (ArrayElement<NormalizedLeft> | ArrayElement<NormalizedRight>)[]
|
|
343
|
+
: readonly [...NormalizedLeft, ...NormalizedRight]
|
|
344
|
+
: unknown
|
|
345
|
+
: NormalizedLeft extends object
|
|
346
|
+
? NormalizedRight extends object
|
|
347
|
+
? MergeJsonObjects<NormalizedLeft, NormalizedRight>
|
|
348
|
+
: unknown
|
|
349
|
+
: unknown
|
|
350
|
+
: never
|
|
351
|
+
: never
|
|
352
|
+
|
|
353
|
+
export type JsonBuildObject<
|
|
354
|
+
Shape extends Record<string, unknown>
|
|
355
|
+
> = {
|
|
356
|
+
readonly [K in keyof Shape]: NormalizeJsonLiteral<Shape[K]>
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
export type JsonBuildArray<
|
|
360
|
+
Values extends readonly unknown[]
|
|
361
|
+
> = {
|
|
362
|
+
readonly [K in keyof Values]: NormalizeJsonLiteral<Values[K]>
|
|
363
|
+
} & readonly unknown[]
|
|
364
|
+
|
|
365
|
+
export type JsonTextResult<Value> = Value extends JsonPrimitive ? `${Value}` : string
|
|
366
|
+
|
|
367
|
+
export type JsonTypeName<Value> =
|
|
368
|
+
NormalizeJsonLiteral<Value> extends null ? "null"
|
|
369
|
+
: NormalizeJsonLiteral<Value> extends string ? "string"
|
|
370
|
+
: NormalizeJsonLiteral<Value> extends number ? "number"
|
|
371
|
+
: NormalizeJsonLiteral<Value> extends boolean ? "boolean"
|
|
372
|
+
: NormalizeJsonLiteral<Value> extends readonly unknown[] ? "array"
|
|
373
|
+
: NormalizeJsonLiteral<Value> extends object ? "object"
|
|
374
|
+
: "unknown"
|
|
375
|
+
|
|
376
|
+
export type JsonLengthResult<Value> =
|
|
377
|
+
NormalizeJsonLiteral<Value> extends readonly unknown[] ? number :
|
|
378
|
+
NormalizeJsonLiteral<Value> extends object ? number :
|
|
379
|
+
null
|
|
380
|
+
|
|
381
|
+
export type JsonKeysResult<Value> =
|
|
382
|
+
NormalizeJsonLiteral<Value> extends object
|
|
383
|
+
? NormalizeJsonLiteral<Value> extends readonly unknown[]
|
|
384
|
+
? readonly []
|
|
385
|
+
: readonly Extract<keyof NormalizeJsonLiteral<Value>, string>[]
|
|
386
|
+
: null
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { RenderState, SqlDialect } from "./dialect.js"
|
|
2
|
+
|
|
3
|
+
const quoteIdentifier = (value: string): string => `\`${value.replaceAll("`", "``")}\``
|
|
4
|
+
|
|
5
|
+
const renderLiteral = (value: unknown, state: RenderState): string => {
|
|
6
|
+
if (value === null) {
|
|
7
|
+
return "null"
|
|
8
|
+
}
|
|
9
|
+
if (typeof value === "boolean") {
|
|
10
|
+
return value ? "true" : "false"
|
|
11
|
+
}
|
|
12
|
+
state.params.push(value)
|
|
13
|
+
return "?"
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Internal runtime dialect sketch for MySQL.
|
|
18
|
+
*
|
|
19
|
+
* This is intentionally not wired into the public renderer surface yet. It
|
|
20
|
+
* exists to pressure-test the current abstraction seam and to document the
|
|
21
|
+
* concrete SQL differences we still need to account for as dialect support
|
|
22
|
+
* grows.
|
|
23
|
+
*/
|
|
24
|
+
export const mysqlDialect: SqlDialect<"mysql"> = {
|
|
25
|
+
name: "mysql",
|
|
26
|
+
quoteIdentifier,
|
|
27
|
+
renderLiteral,
|
|
28
|
+
renderTableReference(tableName, baseTableName, schemaName) {
|
|
29
|
+
const renderedBase = schemaName
|
|
30
|
+
? `${quoteIdentifier(schemaName)}.${quoteIdentifier(baseTableName)}`
|
|
31
|
+
: quoteIdentifier(baseTableName)
|
|
32
|
+
return tableName === baseTableName
|
|
33
|
+
? renderedBase
|
|
34
|
+
: `${renderedBase} as ${quoteIdentifier(tableName)}`
|
|
35
|
+
},
|
|
36
|
+
renderConcat(values) {
|
|
37
|
+
return `concat(${values.join(", ")})`
|
|
38
|
+
}
|
|
39
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import * as Query from "./query.js"
|
|
2
|
+
import { type RenderState } from "./dialect.js"
|
|
3
|
+
import { mysqlDialect } from "./mysql-dialect.js"
|
|
4
|
+
import { type Projection } from "./projections.js"
|
|
5
|
+
import { renderQueryAst } from "./sql-expression-renderer.js"
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Internal rendered-query payload produced by the built-in MySQL renderer.
|
|
9
|
+
*/
|
|
10
|
+
export interface MysqlRenderResult {
|
|
11
|
+
readonly sql: string
|
|
12
|
+
readonly params: readonly unknown[]
|
|
13
|
+
readonly projections: readonly Projection[]
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Renders the current query AST into MySQL-shaped SQL plus bind parameters.
|
|
18
|
+
*/
|
|
19
|
+
export const renderMysqlPlan = <PlanValue extends Query.QueryPlan<any, any, any, any, any, any, any, any, any>>(
|
|
20
|
+
plan: Query.DialectCompatiblePlan<PlanValue, "mysql">
|
|
21
|
+
): MysqlRenderResult => {
|
|
22
|
+
const state: RenderState = {
|
|
23
|
+
params: [],
|
|
24
|
+
ctes: [],
|
|
25
|
+
cteNames: new Set<string>()
|
|
26
|
+
}
|
|
27
|
+
const rendered = renderQueryAst(
|
|
28
|
+
Query.getAst(plan as Query.QueryPlan<any, any, any, any, any, any, any, any, any>) as any,
|
|
29
|
+
state,
|
|
30
|
+
mysqlDialect
|
|
31
|
+
)
|
|
32
|
+
return {
|
|
33
|
+
sql: rendered.sql,
|
|
34
|
+
params: state.params,
|
|
35
|
+
projections: rendered.projections
|
|
36
|
+
}
|
|
37
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import type { Pipeable } from "effect/Pipeable"
|
|
2
|
+
|
|
3
|
+
/** Symbol used to attach logical-plan metadata to runtime values. */
|
|
4
|
+
export const TypeId: unique symbol = Symbol.for("effect-qb/Plan")
|
|
5
|
+
|
|
6
|
+
export type TypeId = typeof TypeId
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Source availability mode within a query scope.
|
|
10
|
+
*
|
|
11
|
+
* `required` means the source is guaranteed to produce a row at this point in
|
|
12
|
+
* the plan. `optional` means the source may be absent, such as the nullable
|
|
13
|
+
* side of a left join.
|
|
14
|
+
*/
|
|
15
|
+
export type SourceMode = "required" | "optional"
|
|
16
|
+
|
|
17
|
+
/** Source made available to a plan. */
|
|
18
|
+
export interface Source<Name extends string = string, Mode extends SourceMode = SourceMode> {
|
|
19
|
+
readonly name: Name
|
|
20
|
+
readonly mode: Mode
|
|
21
|
+
readonly baseName?: string
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Canonical static metadata stored on a plan.
|
|
26
|
+
*
|
|
27
|
+
* `required` tracks sources that the selection references but which are not yet
|
|
28
|
+
* in scope. `available` tracks sources already in scope for subsequent query
|
|
29
|
+
* operations.
|
|
30
|
+
*/
|
|
31
|
+
export interface State<
|
|
32
|
+
Selection,
|
|
33
|
+
Required,
|
|
34
|
+
Available extends Record<string, Source>,
|
|
35
|
+
Dialect extends string
|
|
36
|
+
> {
|
|
37
|
+
readonly selection: Selection
|
|
38
|
+
readonly required: Required
|
|
39
|
+
readonly available: Available
|
|
40
|
+
readonly dialect: Dialect
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* A composable logical query plan.
|
|
45
|
+
*
|
|
46
|
+
* Tables implement this interface as already-complete plans. Future query
|
|
47
|
+
* builders such as `select()` and `from()` should produce and transform values
|
|
48
|
+
* with this same structure.
|
|
49
|
+
*/
|
|
50
|
+
export interface Plan<
|
|
51
|
+
Selection,
|
|
52
|
+
Required = never,
|
|
53
|
+
Available extends Record<string, Source> = {},
|
|
54
|
+
Dialect extends string = never
|
|
55
|
+
> extends Pipeable {
|
|
56
|
+
readonly [TypeId]: State<Selection, Required, Available, Dialect>
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/** Convenience alias for any plan-like value. */
|
|
60
|
+
export type Any = Plan<any, any, Record<string, Source>, string>
|
|
61
|
+
/** Extracts a plan's selection shape. */
|
|
62
|
+
export type SelectionOf<Value extends Any> = Value[typeof TypeId]["selection"]
|
|
63
|
+
/** Extracts a plan's effective dialect. */
|
|
64
|
+
export type DialectOf<Value extends Any> = Value[typeof TypeId]["dialect"]
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { RenderState, SqlDialect } from "./dialect.js"
|
|
2
|
+
|
|
3
|
+
const quoteIdentifier = (value: string): string => `"${value.replaceAll("\"", "\"\"")}"`
|
|
4
|
+
|
|
5
|
+
const renderLiteral = (value: unknown, state: RenderState): string => {
|
|
6
|
+
if (value === null) {
|
|
7
|
+
return "null"
|
|
8
|
+
}
|
|
9
|
+
if (typeof value === "boolean") {
|
|
10
|
+
return value ? "true" : "false"
|
|
11
|
+
}
|
|
12
|
+
state.params.push(value)
|
|
13
|
+
return `$${state.params.length}`
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Built-in runtime dialect implementation for Postgres.
|
|
18
|
+
*/
|
|
19
|
+
export const postgresDialect: SqlDialect<"postgres"> = {
|
|
20
|
+
name: "postgres",
|
|
21
|
+
quoteIdentifier,
|
|
22
|
+
renderLiteral,
|
|
23
|
+
renderTableReference(tableName, baseTableName, schemaName) {
|
|
24
|
+
const renderedBase = schemaName
|
|
25
|
+
? `${quoteIdentifier(schemaName)}.${quoteIdentifier(baseTableName)}`
|
|
26
|
+
: quoteIdentifier(baseTableName)
|
|
27
|
+
return tableName === baseTableName
|
|
28
|
+
? renderedBase
|
|
29
|
+
: `${renderedBase} as ${quoteIdentifier(tableName)}`
|
|
30
|
+
},
|
|
31
|
+
renderConcat(values) {
|
|
32
|
+
return `(${values.join(" || ")})`
|
|
33
|
+
}
|
|
34
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import * as Query from "./query.js"
|
|
2
|
+
import { type RenderState } from "./dialect.js"
|
|
3
|
+
import { postgresDialect } from "./postgres-dialect.js"
|
|
4
|
+
import { type Projection } from "./projections.js"
|
|
5
|
+
import { renderQueryAst } from "./sql-expression-renderer.js"
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Minimal rendered-query payload produced by the built-in Postgres renderer.
|
|
9
|
+
*
|
|
10
|
+
* The public `Renderer` wrapper adds dialect branding and validates projection
|
|
11
|
+
* metadata before exposing the final `RenderedQuery`.
|
|
12
|
+
*/
|
|
13
|
+
export interface PostgresRenderResult {
|
|
14
|
+
readonly sql: string
|
|
15
|
+
readonly params: readonly unknown[]
|
|
16
|
+
readonly projections: readonly Projection[]
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Renders the current query AST into Postgres SQL plus bind parameters.
|
|
21
|
+
*/
|
|
22
|
+
export const renderPostgresPlan = <PlanValue extends Query.QueryPlan<any, any, any, any, any, any, any, any, any>>(
|
|
23
|
+
plan: Query.DialectCompatiblePlan<PlanValue, "postgres">
|
|
24
|
+
): PostgresRenderResult => {
|
|
25
|
+
const state: RenderState = {
|
|
26
|
+
params: [],
|
|
27
|
+
ctes: [],
|
|
28
|
+
cteNames: new Set<string>()
|
|
29
|
+
}
|
|
30
|
+
const rendered = renderQueryAst(
|
|
31
|
+
Query.getAst(plan as Query.QueryPlan<any, any, any, any, any, any, any, any, any>) as any,
|
|
32
|
+
state,
|
|
33
|
+
postgresDialect
|
|
34
|
+
)
|
|
35
|
+
return {
|
|
36
|
+
sql: rendered.sql,
|
|
37
|
+
params: state.params,
|
|
38
|
+
projections: rendered.projections
|
|
39
|
+
}
|
|
40
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import type { AnalyzeFormula } from "./predicate-context.js"
|
|
2
|
+
import type { FormulaOfPredicate } from "./predicate-normalize.js"
|
|
3
|
+
import type { And, Not, PredicateFormula, TrueFormula } from "./predicate-formula.js"
|
|
4
|
+
|
|
5
|
+
type ContextOf<Formula extends PredicateFormula> = AnalyzeFormula<Formula>
|
|
6
|
+
|
|
7
|
+
export type GuaranteedNonNullKeys<
|
|
8
|
+
Assumptions extends PredicateFormula
|
|
9
|
+
> = ContextOf<Assumptions>["nonNullKeys"]
|
|
10
|
+
|
|
11
|
+
export type GuaranteedNullKeys<
|
|
12
|
+
Assumptions extends PredicateFormula
|
|
13
|
+
> = ContextOf<Assumptions>["nullKeys"]
|
|
14
|
+
|
|
15
|
+
export type GuaranteedSourceNames<
|
|
16
|
+
Assumptions extends PredicateFormula
|
|
17
|
+
> = ContextOf<Assumptions>["sourceNames"]
|
|
18
|
+
|
|
19
|
+
export type GuaranteedEqLiteral<
|
|
20
|
+
Assumptions extends PredicateFormula,
|
|
21
|
+
Key extends string
|
|
22
|
+
> = Key extends keyof ContextOf<Assumptions>["eqLiterals"]
|
|
23
|
+
? ContextOf<Assumptions>["eqLiterals"][Key]
|
|
24
|
+
: never
|
|
25
|
+
|
|
26
|
+
type IsContradiction<Formula extends PredicateFormula> =
|
|
27
|
+
ContextOf<Formula>["contradiction"] extends true ? true : false
|
|
28
|
+
|
|
29
|
+
type ContradictoryAssumption<
|
|
30
|
+
Assumptions extends PredicateFormula,
|
|
31
|
+
Formula extends PredicateFormula
|
|
32
|
+
> = IsContradiction<And<Assumptions, Formula>>
|
|
33
|
+
|
|
34
|
+
type ContradictionFromNegation<
|
|
35
|
+
Assumptions extends PredicateFormula,
|
|
36
|
+
Formula extends PredicateFormula
|
|
37
|
+
> = IsContradiction<And<Assumptions, Not<Formula>>>
|
|
38
|
+
|
|
39
|
+
export type AssumeFormulaTrue<
|
|
40
|
+
Assumptions extends PredicateFormula,
|
|
41
|
+
Formula extends PredicateFormula
|
|
42
|
+
> = Assumptions extends TrueFormula
|
|
43
|
+
? Formula
|
|
44
|
+
: And<Assumptions, Formula>
|
|
45
|
+
|
|
46
|
+
export type AssumeFormulaFalse<
|
|
47
|
+
Assumptions extends PredicateFormula,
|
|
48
|
+
Formula extends PredicateFormula
|
|
49
|
+
> = Assumptions extends TrueFormula
|
|
50
|
+
? Not<Formula>
|
|
51
|
+
: And<Assumptions, Not<Formula>>
|
|
52
|
+
|
|
53
|
+
export type AssumeTrue<
|
|
54
|
+
Assumptions extends PredicateFormula,
|
|
55
|
+
Predicate
|
|
56
|
+
> = AssumeFormulaTrue<Assumptions, FormulaOfPredicate<Predicate>>
|
|
57
|
+
|
|
58
|
+
export type AssumeFalse<
|
|
59
|
+
Assumptions extends PredicateFormula,
|
|
60
|
+
Predicate
|
|
61
|
+
> = AssumeFormulaFalse<Assumptions, FormulaOfPredicate<Predicate>>
|
|
62
|
+
|
|
63
|
+
export type Contradicts<
|
|
64
|
+
Assumptions extends PredicateFormula,
|
|
65
|
+
Predicate
|
|
66
|
+
> = ContradictoryAssumption<Assumptions, FormulaOfPredicate<Predicate>>
|
|
67
|
+
|
|
68
|
+
export type Implies<
|
|
69
|
+
Assumptions extends PredicateFormula,
|
|
70
|
+
Predicate
|
|
71
|
+
> = ContradictionFromNegation<Assumptions, FormulaOfPredicate<Predicate>>
|