effect-qb 4.0.0-beta.66 → 4.0.0-beta.92
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 +5 -2
- package/dist/index.js +9373 -0
- package/dist/mysql.js +3917 -2572
- package/dist/postgres/metadata.js +2491 -1373
- package/dist/postgres.js +5450 -5155
- package/dist/sqlite.js +6891 -5528
- package/dist/standard.js +9327 -0
- package/package.json +9 -2
- package/src/casing.ts +71 -0
- package/src/index.ts +2 -0
- package/src/internal/casing.ts +89 -0
- package/src/internal/coercion/rules.ts +13 -1
- package/src/internal/column-state.ts +21 -15
- package/src/internal/column.ts +44 -7
- package/src/internal/datatypes/define.ts +7 -1
- package/src/internal/datatypes/enrich.ts +23 -0
- package/src/internal/datatypes/lookup.ts +81 -25
- package/src/internal/datatypes/matrix.ts +903 -0
- package/src/internal/datatypes/shape.ts +2 -0
- package/src/internal/derived-table.ts +4 -36
- package/src/{mysql/internal/sql-expression-renderer.ts → internal/dialect-renderers/mysql.ts} +552 -361
- package/src/{postgres/internal/sql-expression-renderer.ts → internal/dialect-renderers/postgres.ts} +657 -400
- package/src/{sqlite/internal/sql-expression-renderer.ts → internal/dialect-renderers/sqlite.ts} +505 -347
- package/src/internal/dialect.ts +35 -0
- package/src/internal/dsl-mutation-runtime.ts +12 -162
- package/src/internal/dsl-plan-runtime.ts +10 -138
- package/src/internal/dsl-query-runtime.ts +5 -79
- package/src/internal/dsl-transaction-ddl-runtime.ts +41 -65
- package/src/internal/executor.ts +14 -16
- package/src/internal/grouping-key.ts +87 -20
- package/src/internal/implication-runtime.ts +1 -1
- package/src/internal/json/path-access.ts +351 -0
- package/src/internal/predicate/runtime.ts +3 -0
- package/src/internal/query.d.ts +38 -11
- package/src/internal/query.ts +64 -25
- package/src/internal/renderer.ts +26 -14
- package/src/internal/runtime/normalize.ts +12 -5
- package/src/internal/scalar.ts +7 -1
- package/src/internal/schema-derivation.d.ts +7 -7
- package/src/internal/schema-derivation.ts +9 -9
- package/src/internal/schema-expression.ts +2 -2
- package/src/internal/sql-expression-renderer.ts +19 -0
- package/src/internal/standard-dsl.ts +6975 -0
- package/src/internal/table-options.ts +126 -66
- package/src/internal/table.ts +652 -219
- package/src/mysql/column-extension.ts +3 -0
- package/src/mysql/column.ts +8 -9
- package/src/mysql/datatypes/index.ts +4 -2
- package/src/mysql/datatypes/spec.ts +6 -176
- package/src/mysql/executor.ts +7 -7
- package/src/mysql/internal/dialect.ts +9 -4
- package/src/mysql/internal/dsl.ts +309 -154
- package/src/mysql/internal/renderer.ts +6 -2
- package/src/mysql/json.ts +7 -2
- package/src/mysql/query-extension.ts +16 -0
- package/src/mysql/renderer.ts +37 -3
- package/src/mysql/type.ts +60 -0
- package/src/mysql.ts +7 -13
- package/src/postgres/check.ts +1 -0
- package/src/postgres/column-extension.ts +28 -0
- package/src/postgres/column.ts +2 -8
- package/src/postgres/datatypes/index.d.ts +2 -1
- package/src/postgres/datatypes/index.ts +4 -2
- package/src/postgres/datatypes/spec.ts +6 -260
- package/src/postgres/executor.ts +7 -7
- package/src/postgres/foreign-key.ts +24 -0
- package/src/postgres/function/core.ts +1 -3
- package/src/postgres/function/index.ts +1 -17
- package/src/postgres/index.ts +1 -0
- package/src/postgres/internal/dialect.ts +9 -4
- package/src/postgres/internal/dsl.ts +303 -163
- package/src/postgres/internal/renderer.ts +6 -2
- package/src/postgres/internal/schema-ddl.ts +22 -10
- package/src/postgres/internal/schema-model.ts +238 -7
- package/src/postgres/json-extension.ts +7 -0
- package/src/postgres/json.ts +762 -173
- package/src/postgres/jsonb.ts +37 -0
- package/src/postgres/primary-key.ts +24 -0
- package/src/postgres/query-extension.ts +2 -0
- package/src/postgres/renderer.ts +37 -3
- package/src/postgres/schema-management.ts +12 -11
- package/src/postgres/schema.ts +106 -15
- package/src/postgres/table.ts +205 -530
- package/src/postgres/type.ts +93 -10
- package/src/postgres/unique.ts +32 -0
- package/src/postgres.ts +20 -16
- package/src/sqlite/column-extension.ts +3 -0
- package/src/sqlite/column.ts +8 -9
- package/src/sqlite/datatypes/index.ts +4 -2
- package/src/sqlite/datatypes/spec.ts +6 -94
- package/src/sqlite/executor.ts +7 -7
- package/src/sqlite/internal/dialect.ts +9 -4
- package/src/sqlite/internal/dsl.ts +298 -154
- package/src/sqlite/internal/renderer.ts +6 -2
- package/src/sqlite/json.ts +8 -2
- package/src/sqlite/query-extension.ts +2 -0
- package/src/sqlite/renderer.ts +37 -3
- package/src/sqlite/type.ts +40 -0
- package/src/sqlite.ts +7 -13
- package/src/standard/cast.ts +113 -0
- package/src/standard/check.ts +17 -0
- package/src/standard/column.ts +163 -0
- package/src/standard/datatypes/index.ts +83 -0
- package/src/standard/datatypes/spec.ts +12 -0
- package/src/standard/dialect.ts +40 -0
- package/src/standard/foreign-key.ts +37 -0
- package/src/standard/function/aggregate.ts +2 -0
- package/src/standard/function/core.ts +2 -0
- package/src/standard/function/index.ts +18 -0
- package/src/standard/function/string.ts +2 -0
- package/src/standard/function/temporal.ts +78 -0
- package/src/standard/function/window.ts +2 -0
- package/src/standard/index.ts +17 -0
- package/src/standard/internal/renderer.ts +45 -0
- package/src/standard/json.ts +883 -0
- package/src/standard/primary-key.ts +17 -0
- package/src/standard/query.ts +152 -0
- package/src/standard/renderer.ts +49 -0
- package/src/standard/table.ts +151 -0
- package/src/standard/unique.ts +17 -0
- package/src/standard.ts +32 -0
- package/src/internal/aggregation-validation.ts +0 -57
- package/src/internal/table.d.ts +0 -180
- package/src/mysql/table.ts +0 -186
- package/src/postgres/cast.ts +0 -45
- package/src/sqlite/table.ts +0 -175
|
@@ -0,0 +1,351 @@
|
|
|
1
|
+
import { pipeArguments, type Pipeable } from "effect/Pipeable"
|
|
2
|
+
|
|
3
|
+
import * as ExpressionAst from "../expression-ast.js"
|
|
4
|
+
import * as Expression from "../scalar.js"
|
|
5
|
+
import * as JsonPath from "./path.js"
|
|
6
|
+
import type { JsonValueAtPath } from "./types.js"
|
|
7
|
+
|
|
8
|
+
const WrappedTypeId: unique symbol = Symbol.for("effect-qb/JsonPathAccess")
|
|
9
|
+
|
|
10
|
+
type JsonDb = Expression.DbType.Json<any, any>
|
|
11
|
+
|
|
12
|
+
type AnyJsonExpression = Expression.Scalar<
|
|
13
|
+
any,
|
|
14
|
+
JsonDb,
|
|
15
|
+
Expression.Nullability,
|
|
16
|
+
string,
|
|
17
|
+
Expression.ScalarKind,
|
|
18
|
+
Expression.BindingId
|
|
19
|
+
>
|
|
20
|
+
|
|
21
|
+
type JsonNullabilityOf<Output> =
|
|
22
|
+
null extends Output
|
|
23
|
+
? Exclude<Output, null> extends never ? "always" : "maybe"
|
|
24
|
+
: "never"
|
|
25
|
+
|
|
26
|
+
type IsAny<Value> = 0 extends (1 & Value) ? true : false
|
|
27
|
+
|
|
28
|
+
type SegmentTuple<Segments> = Segments extends readonly JsonPath.CanonicalSegment[]
|
|
29
|
+
? Segments
|
|
30
|
+
: readonly JsonPath.CanonicalSegment[]
|
|
31
|
+
|
|
32
|
+
type JsonAccessAst<Value> = Value extends {
|
|
33
|
+
readonly [ExpressionAst.TypeId]: infer Ast
|
|
34
|
+
} ? Ast : never
|
|
35
|
+
|
|
36
|
+
type JsonAccessParts<
|
|
37
|
+
Value,
|
|
38
|
+
Acc extends readonly JsonPath.CanonicalSegment[] = readonly [],
|
|
39
|
+
Depth extends readonly unknown[] = []
|
|
40
|
+
> =
|
|
41
|
+
Depth["length"] extends 8 ? readonly [Value, Acc] :
|
|
42
|
+
[JsonAccessAst<Value>] extends [never]
|
|
43
|
+
? readonly [Value, Acc]
|
|
44
|
+
: JsonAccessAst<Value> extends ExpressionAst.JsonAccessNode<any, infer Base extends Expression.Any, infer Segments>
|
|
45
|
+
? JsonAccessParts<Base, readonly [...SegmentTuple<Segments>, ...Acc], readonly [...Depth, unknown]>
|
|
46
|
+
: readonly [Value, Acc]
|
|
47
|
+
|
|
48
|
+
type JsonAccessRoot<Value> =
|
|
49
|
+
JsonAccessParts<Value> extends readonly [infer Base, readonly JsonPath.CanonicalSegment[]]
|
|
50
|
+
? Base
|
|
51
|
+
: Value
|
|
52
|
+
|
|
53
|
+
type JsonAccessSegments<Value> =
|
|
54
|
+
JsonAccessParts<Value> extends readonly [any, infer Segments extends readonly JsonPath.CanonicalSegment[]]
|
|
55
|
+
? Segments
|
|
56
|
+
: readonly []
|
|
57
|
+
|
|
58
|
+
type JsonAccessBase<Value> =
|
|
59
|
+
JsonAccessRoot<Value> extends Expression.Any ? JsonAccessRoot<Value> : Value
|
|
60
|
+
|
|
61
|
+
type JsonPathOutput<
|
|
62
|
+
Root,
|
|
63
|
+
Segments extends readonly JsonPath.CanonicalSegment[],
|
|
64
|
+
Operation extends string
|
|
65
|
+
> =
|
|
66
|
+
JsonValueAtPath<Exclude<Root, null>, JsonPath.Path<Segments>, Operation> |
|
|
67
|
+
(null extends Root ? null : never)
|
|
68
|
+
|
|
69
|
+
type JsonAccessExpression<
|
|
70
|
+
Base extends AnyJsonExpression,
|
|
71
|
+
Segments extends readonly JsonPath.CanonicalSegment[]
|
|
72
|
+
> = WithJsonPathAccess<
|
|
73
|
+
Expression.Scalar<
|
|
74
|
+
JsonPathOutput<Expression.RuntimeOf<JsonAccessBase<Base>>, Segments, "json.get">,
|
|
75
|
+
Expression.DbTypeOf<JsonAccessBase<Base>>,
|
|
76
|
+
JsonNullabilityOf<JsonPathOutput<Expression.RuntimeOf<JsonAccessBase<Base>>, Segments, "json.get">>,
|
|
77
|
+
Expression.DbTypeOf<JsonAccessBase<Base>>["dialect"],
|
|
78
|
+
Expression.KindOf<JsonAccessBase<Base>>,
|
|
79
|
+
Expression.DependenciesOf<JsonAccessBase<Base>>
|
|
80
|
+
> & {
|
|
81
|
+
readonly [ExpressionAst.TypeId]: ExpressionAst.JsonAccessNode<
|
|
82
|
+
JsonPath.IsExactPath<JsonPath.Path<Segments>> extends true ? "jsonPath" : "jsonTraverse",
|
|
83
|
+
JsonAccessBase<Base>,
|
|
84
|
+
Segments
|
|
85
|
+
>
|
|
86
|
+
}
|
|
87
|
+
>
|
|
88
|
+
|
|
89
|
+
type JsonKeyAccess<
|
|
90
|
+
Base extends AnyJsonExpression,
|
|
91
|
+
Key extends string
|
|
92
|
+
> = JsonAccessExpression<Base, readonly [...JsonAccessSegments<Base>, JsonPath.KeySegment<Key>]>
|
|
93
|
+
|
|
94
|
+
type JsonIndexAccess<
|
|
95
|
+
Base extends AnyJsonExpression,
|
|
96
|
+
Index extends number
|
|
97
|
+
> = JsonAccessExpression<Base, readonly [...JsonAccessSegments<Base>, JsonPath.IndexSegment<Index>]>
|
|
98
|
+
|
|
99
|
+
type ReservedPathKey =
|
|
100
|
+
| "pipe"
|
|
101
|
+
| "then"
|
|
102
|
+
| "toString"
|
|
103
|
+
| "toJSON"
|
|
104
|
+
| "valueOf"
|
|
105
|
+
| "constructor"
|
|
106
|
+
| "__proto__"
|
|
107
|
+
| "prototype"
|
|
108
|
+
| "inspect"
|
|
109
|
+
| "schema"
|
|
110
|
+
| "metadata"
|
|
111
|
+
| "columns"
|
|
112
|
+
| "name"
|
|
113
|
+
|
|
114
|
+
type KeysOfUnion<Value> = Value extends unknown ? keyof Value : never
|
|
115
|
+
|
|
116
|
+
type JsonObjectKey<Key> = Key extends string
|
|
117
|
+
? Key extends ReservedPathKey ? never :
|
|
118
|
+
Key extends `${number}` ? never :
|
|
119
|
+
Key
|
|
120
|
+
: never
|
|
121
|
+
|
|
122
|
+
type TupleNumberKey<Key> = Key extends `${infer Index extends number}` ? Index : never
|
|
123
|
+
|
|
124
|
+
type JsonTupleAccessors<
|
|
125
|
+
Base extends AnyJsonExpression,
|
|
126
|
+
Runtime extends readonly unknown[]
|
|
127
|
+
> = {
|
|
128
|
+
readonly [Key in Extract<keyof Runtime, `${number}`> as TupleNumberKey<Key>]: JsonIndexAccess<Base, TupleNumberKey<Key>>
|
|
129
|
+
} & {
|
|
130
|
+
readonly [index: number]: JsonIndexAccess<Base, number>
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
type JsonArrayAccessors<
|
|
134
|
+
Base extends AnyJsonExpression,
|
|
135
|
+
Runtime extends readonly unknown[]
|
|
136
|
+
> = number extends Runtime["length"]
|
|
137
|
+
? {
|
|
138
|
+
readonly [index: number]: JsonIndexAccess<Base, number>
|
|
139
|
+
}
|
|
140
|
+
: JsonTupleAccessors<Base, Runtime>
|
|
141
|
+
|
|
142
|
+
type JsonObjectAccessors<
|
|
143
|
+
Base extends AnyJsonExpression,
|
|
144
|
+
Runtime extends object
|
|
145
|
+
> = {
|
|
146
|
+
readonly [Key in KeysOfUnion<Runtime> as JsonObjectKey<Key>]: JsonKeyAccess<Base, JsonObjectKey<Key>>
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
type JsonObjectPredicateKeys<Runtime> =
|
|
150
|
+
Runtime extends readonly unknown[]
|
|
151
|
+
? never
|
|
152
|
+
: Runtime extends object
|
|
153
|
+
? Extract<KeysOfUnion<Runtime>, string>
|
|
154
|
+
: never
|
|
155
|
+
|
|
156
|
+
export type JsonObjectKeyOf<Value extends Expression.Any> =
|
|
157
|
+
IsAny<Expression.RuntimeOf<Value>> extends true
|
|
158
|
+
? string
|
|
159
|
+
: Exclude<Expression.RuntimeOf<Value>, null> extends infer Runtime
|
|
160
|
+
? string extends JsonObjectPredicateKeys<Runtime>
|
|
161
|
+
? string
|
|
162
|
+
: JsonObjectPredicateKeys<Runtime>
|
|
163
|
+
: never
|
|
164
|
+
|
|
165
|
+
type JsonPathAccessors<Base extends AnyJsonExpression> =
|
|
166
|
+
IsAny<Expression.RuntimeOf<Base>> extends true
|
|
167
|
+
? {}
|
|
168
|
+
: Exclude<Expression.RuntimeOf<Base>, null> extends infer Runtime
|
|
169
|
+
? Runtime extends readonly unknown[]
|
|
170
|
+
? JsonArrayAccessors<Base, Runtime>
|
|
171
|
+
: Runtime extends object
|
|
172
|
+
? JsonObjectAccessors<Base, Runtime>
|
|
173
|
+
: {}
|
|
174
|
+
: {}
|
|
175
|
+
|
|
176
|
+
export type WithJsonPathAccess<Value> = Value extends AnyJsonExpression
|
|
177
|
+
? Value & JsonPathAccessors<Value>
|
|
178
|
+
: Value
|
|
179
|
+
|
|
180
|
+
const accessKinds = new Set<string>([
|
|
181
|
+
"jsonGet",
|
|
182
|
+
"jsonPath",
|
|
183
|
+
"jsonAccess",
|
|
184
|
+
"jsonTraverse",
|
|
185
|
+
"jsonGetText",
|
|
186
|
+
"jsonPathText",
|
|
187
|
+
"jsonAccessText",
|
|
188
|
+
"jsonTraverseText"
|
|
189
|
+
])
|
|
190
|
+
|
|
191
|
+
const reservedKeys = new Set<string>([
|
|
192
|
+
"pipe",
|
|
193
|
+
"then",
|
|
194
|
+
"toString",
|
|
195
|
+
"toJSON",
|
|
196
|
+
"valueOf",
|
|
197
|
+
"constructor",
|
|
198
|
+
"__proto__",
|
|
199
|
+
"prototype",
|
|
200
|
+
"inspect",
|
|
201
|
+
"schema",
|
|
202
|
+
"metadata",
|
|
203
|
+
"columns",
|
|
204
|
+
"name"
|
|
205
|
+
])
|
|
206
|
+
|
|
207
|
+
const isObjectLike = (value: unknown): value is object =>
|
|
208
|
+
(typeof value === "object" || typeof value === "function") && value !== null
|
|
209
|
+
|
|
210
|
+
const isExpression = (value: unknown): value is Expression.Any =>
|
|
211
|
+
isObjectLike(value) && Expression.TypeId in value
|
|
212
|
+
|
|
213
|
+
const isJsonExpression = (value: unknown): value is AnyJsonExpression => {
|
|
214
|
+
if (!isExpression(value)) {
|
|
215
|
+
return false
|
|
216
|
+
}
|
|
217
|
+
const dbType = value[Expression.TypeId].dbType as { readonly kind?: string; readonly variant?: string }
|
|
218
|
+
return dbType.kind === "json" || dbType.kind === "jsonb" || dbType.variant === "json" || dbType.variant === "jsonb"
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
const isWrapped = (value: object): boolean =>
|
|
222
|
+
(value as { readonly [WrappedTypeId]?: true })[WrappedTypeId] === true
|
|
223
|
+
|
|
224
|
+
const normalizeSegment = (segment: JsonPath.CanonicalSegment): JsonPath.CanonicalSegment => {
|
|
225
|
+
switch (segment.kind) {
|
|
226
|
+
case "key":
|
|
227
|
+
return JsonPath.key(segment.key)
|
|
228
|
+
case "index":
|
|
229
|
+
return JsonPath.index(segment.index)
|
|
230
|
+
case "wildcard":
|
|
231
|
+
return JsonPath.wildcard()
|
|
232
|
+
case "slice":
|
|
233
|
+
return JsonPath.slice(segment.start, segment.end)
|
|
234
|
+
case "descend":
|
|
235
|
+
return JsonPath.descend()
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
const accessPathOf = (value: Expression.Any): {
|
|
240
|
+
readonly base: Expression.Any
|
|
241
|
+
readonly segments: readonly JsonPath.CanonicalSegment[]
|
|
242
|
+
} => {
|
|
243
|
+
const segments: JsonPath.CanonicalSegment[] = []
|
|
244
|
+
let base: Expression.Any = value
|
|
245
|
+
while (isExpression(base)) {
|
|
246
|
+
const ast = (base as Expression.Any & {
|
|
247
|
+
readonly [ExpressionAst.TypeId]?: ExpressionAst.Any
|
|
248
|
+
})[ExpressionAst.TypeId] as { readonly kind?: unknown; readonly base?: unknown; readonly segments?: unknown } | undefined
|
|
249
|
+
if (ast === undefined || typeof ast.kind !== "string" || !accessKinds.has(ast.kind) || !isExpression(ast.base) || !Array.isArray(ast.segments)) {
|
|
250
|
+
break
|
|
251
|
+
}
|
|
252
|
+
segments.unshift(...ast.segments.map(normalizeSegment))
|
|
253
|
+
base = ast.base
|
|
254
|
+
}
|
|
255
|
+
return { base, segments }
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
const isIntegerProperty = (property: string): boolean =>
|
|
259
|
+
/^(?:-?(?:0|[1-9][0-9]*))$/.test(property)
|
|
260
|
+
|
|
261
|
+
const jsonAccessKind = (
|
|
262
|
+
segments: readonly JsonPath.CanonicalSegment[]
|
|
263
|
+
): ExpressionAst.JsonAccessKind =>
|
|
264
|
+
segments.every((segment) => segment.kind === "key" || segment.kind === "index")
|
|
265
|
+
? segments.length === 1 ? "jsonGet" : "jsonPath"
|
|
266
|
+
: "jsonTraverse"
|
|
267
|
+
|
|
268
|
+
const makeExpression = <
|
|
269
|
+
Runtime,
|
|
270
|
+
Db extends Expression.DbType.Any,
|
|
271
|
+
Nullable extends Expression.Nullability,
|
|
272
|
+
Dialect extends string,
|
|
273
|
+
Kind extends Expression.ScalarKind,
|
|
274
|
+
Deps extends Expression.BindingId,
|
|
275
|
+
Ast extends ExpressionAst.Any
|
|
276
|
+
>(
|
|
277
|
+
state: Expression.State<Runtime, Db, Nullable, Dialect, Kind, Deps>,
|
|
278
|
+
ast: Ast
|
|
279
|
+
): Expression.Scalar<Runtime, Db, Nullable, Dialect, Kind, Deps> & {
|
|
280
|
+
readonly [ExpressionAst.TypeId]: Ast
|
|
281
|
+
} => {
|
|
282
|
+
const expression = Object.create(null) as Expression.Scalar<Runtime, Db, Nullable, Dialect, Kind, Deps> & {
|
|
283
|
+
[ExpressionAst.TypeId]: Ast
|
|
284
|
+
[Expression.TypeId]: Expression.State<Runtime, Db, Nullable, Dialect, Kind, Deps>
|
|
285
|
+
pipe: Pipeable["pipe"]
|
|
286
|
+
}
|
|
287
|
+
Object.defineProperty(expression, "pipe", {
|
|
288
|
+
configurable: true,
|
|
289
|
+
writable: true,
|
|
290
|
+
value: function(this: Pipeable) {
|
|
291
|
+
return pipeArguments(expression, arguments)
|
|
292
|
+
}
|
|
293
|
+
})
|
|
294
|
+
expression[Expression.TypeId] = state
|
|
295
|
+
expression[ExpressionAst.TypeId] = ast
|
|
296
|
+
return expression
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
const makePathExpression = (
|
|
300
|
+
value: AnyJsonExpression,
|
|
301
|
+
segment: JsonPath.CanonicalSegment
|
|
302
|
+
): AnyJsonExpression => {
|
|
303
|
+
const access = accessPathOf(value)
|
|
304
|
+
const segments = [...access.segments, normalizeSegment(segment)]
|
|
305
|
+
const base = access.base as AnyJsonExpression
|
|
306
|
+
const baseState = base[Expression.TypeId]
|
|
307
|
+
return withJsonPathAccess(makeExpression(
|
|
308
|
+
{
|
|
309
|
+
...baseState,
|
|
310
|
+
runtime: undefined,
|
|
311
|
+
nullability: undefined as unknown as Expression.Nullability
|
|
312
|
+
},
|
|
313
|
+
{
|
|
314
|
+
kind: jsonAccessKind(segments),
|
|
315
|
+
base,
|
|
316
|
+
segments
|
|
317
|
+
} satisfies ExpressionAst.JsonAccessNode<any, any, any>
|
|
318
|
+
) as AnyJsonExpression)
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
const pathProxyHandler: ProxyHandler<AnyJsonExpression> = {
|
|
322
|
+
get(target, property, receiver) {
|
|
323
|
+
if (typeof property === "symbol") {
|
|
324
|
+
return Reflect.get(target, property, receiver)
|
|
325
|
+
}
|
|
326
|
+
if (Reflect.has(target, property) || reservedKeys.has(property)) {
|
|
327
|
+
return Reflect.get(target, property, receiver)
|
|
328
|
+
}
|
|
329
|
+
const segment = isIntegerProperty(property)
|
|
330
|
+
? JsonPath.index(Number(property))
|
|
331
|
+
: JsonPath.key(property)
|
|
332
|
+
return makePathExpression(target, segment)
|
|
333
|
+
},
|
|
334
|
+
has(target, property) {
|
|
335
|
+
return Reflect.has(target, property)
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
export const withJsonPathAccess = <Value>(value: Value): WithJsonPathAccess<Value> => {
|
|
340
|
+
if (!isObjectLike(value) || !isJsonExpression(value) || isWrapped(value)) {
|
|
341
|
+
return value as WithJsonPathAccess<Value>
|
|
342
|
+
}
|
|
343
|
+
const proxy = new Proxy(value, pathProxyHandler) as unknown as WithJsonPathAccess<Value> & {
|
|
344
|
+
[WrappedTypeId]: true
|
|
345
|
+
}
|
|
346
|
+
Object.defineProperty(proxy, WrappedTypeId, {
|
|
347
|
+
configurable: false,
|
|
348
|
+
value: true
|
|
349
|
+
})
|
|
350
|
+
return proxy
|
|
351
|
+
}
|
|
@@ -474,6 +474,9 @@ const valueKeyOfLiteral = (value: unknown): string => {
|
|
|
474
474
|
return "null"
|
|
475
475
|
}
|
|
476
476
|
if (value instanceof Date) {
|
|
477
|
+
if (Number.isNaN(value.getTime())) {
|
|
478
|
+
throw new Error("Expected a valid Date value")
|
|
479
|
+
}
|
|
477
480
|
return `date:${value.toISOString()}`
|
|
478
481
|
}
|
|
479
482
|
return "unknown"
|
package/src/internal/query.d.ts
CHANGED
|
@@ -37,6 +37,31 @@ export interface QueryState<Outstanding extends string, AvailableNames extends s
|
|
|
37
37
|
}
|
|
38
38
|
/** Effective SQL dialect carried by an expression. */
|
|
39
39
|
export type DialectOf<Value extends Expression.Any> = Value[typeof Expression.TypeId]["dialect"];
|
|
40
|
+
type ConcreteDialect<D> = D extends "standard" ? never : D;
|
|
41
|
+
type IsDialectUnion<Union, All = Union> = Union extends any ? [
|
|
42
|
+
All
|
|
43
|
+
] extends [Union] ? false : true : false;
|
|
44
|
+
export type DialectConflictError<A extends string, B extends string> = string & {
|
|
45
|
+
readonly _tag: "DialectConflict";
|
|
46
|
+
readonly left: A;
|
|
47
|
+
readonly right: B;
|
|
48
|
+
};
|
|
49
|
+
export type MergeDialect<A extends string, B extends string> = [
|
|
50
|
+
ConcreteDialect<A>,
|
|
51
|
+
ConcreteDialect<B>
|
|
52
|
+
] extends [never, never] ? "standard" : [
|
|
53
|
+
ConcreteDialect<A>,
|
|
54
|
+
ConcreteDialect<B>
|
|
55
|
+
] extends [never, infer C extends string] ? C : [
|
|
56
|
+
ConcreteDialect<A>,
|
|
57
|
+
ConcreteDialect<B>
|
|
58
|
+
] extends [infer C extends string, never] ? C : ConcreteDialect<A> extends ConcreteDialect<B> ? ConcreteDialect<B> extends ConcreteDialect<A> ? A : DialectConflictError<A, B> : DialectConflictError<A, B>;
|
|
59
|
+
/** Collapses the portable standard tag out of a dialect union. */
|
|
60
|
+
export type NormalizeDialect<Dialect extends string> = [
|
|
61
|
+
Dialect
|
|
62
|
+
] extends [never] ? never : [
|
|
63
|
+
Exclude<Dialect, "standard">
|
|
64
|
+
] extends [never] ? "standard" : IsDialectUnion<Exclude<Dialect, "standard">> extends true ? DialectConflictError<Exclude<Dialect, "standard">, Exclude<Dialect, "standard">> : Exclude<Dialect, "standard">;
|
|
40
65
|
/** Source dependency union carried by an expression. */
|
|
41
66
|
export type DependenciesOf<Value extends Expression.Any> = Expression.DependenciesOf<Value>;
|
|
42
67
|
/** Aggregation kind carried by an expression. */
|
|
@@ -135,10 +160,11 @@ export type SelectionShape = Expression.Any | {
|
|
|
135
160
|
export type ExtractRequired<Selection> = Selection extends Expression.Any ? RequiredFromDependencies<DependenciesOf<Selection>> : Selection extends Record<string, any> ? {
|
|
136
161
|
[K in keyof Selection]: ExtractRequired<Selection[K]>;
|
|
137
162
|
}[keyof Selection] : never;
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
[K in keyof Selection]: ExtractDialect<Selection[K]>;
|
|
163
|
+
type ExtractDialectRaw<Selection> = Selection extends Expression.Any ? DialectOf<Selection> : Selection extends Record<string, any> ? {
|
|
164
|
+
[K in keyof Selection]: ExtractDialectRaw<Selection[K]>;
|
|
141
165
|
}[keyof Selection] : never;
|
|
166
|
+
/** Walks a selection tree and extracts the effective dialects referenced by its leaves. */
|
|
167
|
+
export type ExtractDialect<Selection> = NormalizeDialect<Extract<ExtractDialectRaw<Selection>, string>>;
|
|
142
168
|
/**
|
|
143
169
|
* Minimal table-like shape required by `from(...)` and joins.
|
|
144
170
|
*
|
|
@@ -419,8 +445,7 @@ export type MutationTargetNamesOf<Target extends MutationTargetInput> = Target e
|
|
|
419
445
|
export type UpdateInputOfTarget<Target extends MutationTargetInput> = Target extends MutationTargetLike ? MutationInputOf<Table.UpdateOf<Target>> : Target extends MutationTargetTuple ? Simplify<{
|
|
420
446
|
readonly [K in MutationTargetNamesOf<Target>]?: MutationInputOf<Table.UpdateOf<MutationTargetByName<Target, K>>>;
|
|
421
447
|
}> : never;
|
|
422
|
-
|
|
423
|
-
export type SourceDialectOf<Source extends SourceLike> = Source extends TableLike<any, infer Dialect> ? Dialect : Source extends {
|
|
448
|
+
type SourceDialectOfRaw<Source extends SourceLike> = Source extends TableLike<any, infer Dialect> ? Dialect : Source extends {
|
|
424
449
|
readonly kind: "derived";
|
|
425
450
|
readonly plan: infer PlanValue extends QueryPlan<any, any, any, any, any, any, any, any, any, any>;
|
|
426
451
|
} ? PlanDialectOf<PlanValue> : Source extends {
|
|
@@ -432,6 +457,8 @@ export type SourceDialectOf<Source extends SourceLike> = Source extends TableLik
|
|
|
432
457
|
} ? PlanDialectOf<PlanValue> : Source extends {
|
|
433
458
|
readonly dialect: infer Dialect extends string;
|
|
434
459
|
} ? Dialect : never;
|
|
460
|
+
/** Extracts the effective dialect from a source. */
|
|
461
|
+
export type SourceDialectOf<Source extends SourceLike> = NormalizeDialect<SourceDialectOfRaw<Source>>;
|
|
435
462
|
/** Extracts the base table name from a source. */
|
|
436
463
|
export type SourceBaseNameOf<Source extends SourceLike> = Source extends TableLike<any, any> ? Source[typeof Table.TypeId]["baseName"] : Source extends {
|
|
437
464
|
readonly kind: "derived";
|
|
@@ -493,7 +520,7 @@ export type RequiredOfPlan<PlanValue extends QueryPlan<any, any, any, any, any,
|
|
|
493
520
|
/** Extracts the available-source scope carried by a query plan. */
|
|
494
521
|
export type AvailableOfPlan<PlanValue extends QueryPlan<any, any, any, any, any, any, any, any, any, any, any, any>> = QueryPlanParts<PlanValue>["available"];
|
|
495
522
|
/** Extracts the effective dialect carried by a query plan. */
|
|
496
|
-
export type PlanDialectOf<PlanValue extends QueryPlan<any, any, any, any, any, any, any, any, any, any, any, any>> = QueryPlanParts<PlanValue>["dialect"]
|
|
523
|
+
export type PlanDialectOf<PlanValue extends QueryPlan<any, any, any, any, any, any, any, any, any, any, any, any>> = NormalizeDialect<QueryPlanParts<PlanValue>["dialect"]>;
|
|
497
524
|
/** Extracts the grouped-source phantom carried by a query plan. */
|
|
498
525
|
export type GroupedOfPlan<PlanValue extends QueryPlan<any, any, any, any, any, any, any, any, any, any, any, any>> = QueryPlanState<PlanValue>["grouped"];
|
|
499
526
|
/** Extracts the available-name phantom carried by a query plan. */
|
|
@@ -562,7 +589,7 @@ type MergeNullability<Left extends Expression.Nullability, Right extends Express
|
|
|
562
589
|
/** Folds nullability across a tuple for null-propagating scalar operators. */
|
|
563
590
|
export type MergeNullabilityTuple<Values extends readonly Expression.Any[], Current extends Expression.Nullability = "never"> = Values extends readonly [infer Head extends Expression.Any, ...infer Tail extends readonly Expression.Any[]] ? MergeNullabilityTuple<Tail, MergeNullability<Current, Expression.NullabilityOf<Head>>> : Current;
|
|
564
591
|
/** Dialect union across a tuple of expressions. */
|
|
565
|
-
export type TupleDialect<Values extends readonly Expression.Any[]> = Values[number] extends never ? never : DialectOf<Values[number]
|
|
592
|
+
export type TupleDialect<Values extends readonly Expression.Any[]> = Values[number] extends never ? never : NormalizeDialect<DialectOf<Values[number]>>;
|
|
566
593
|
/** Dependency union across a tuple of scalar expressions. */
|
|
567
594
|
export type TupleDependencies<Values extends readonly Expression.Any[]> = Values[number] extends never ? never : DependenciesOf<Values[number]>;
|
|
568
595
|
/** Builds the canonical dependency union from a string union of table names. */
|
|
@@ -661,7 +688,7 @@ type AggregationCompatibilityError<PlanValue extends QueryPlan<any, any, any, an
|
|
|
661
688
|
};
|
|
662
689
|
type DialectCompatibilityError<PlanValue extends QueryPlan<any, any, any, any, any, any, any, any, any, any>, EngineDialect extends string> = PlanValue & {
|
|
663
690
|
readonly __effect_qb_error__: "effect-qb: plan dialect is not compatible with the target renderer or executor";
|
|
664
|
-
readonly __effect_qb_plan_dialect__: PlanValue
|
|
691
|
+
readonly __effect_qb_plan_dialect__: PlanDialectOf<PlanValue>;
|
|
665
692
|
readonly __effect_qb_target_dialect__: EngineDialect;
|
|
666
693
|
readonly __effect_qb_hint__: "Use the matching dialect module or renderer/executor";
|
|
667
694
|
};
|
|
@@ -678,11 +705,11 @@ export type AggregationCompatiblePlan<PlanValue extends QueryPlan<any, any, any,
|
|
|
678
705
|
/** Narrows a query plan to aggregate-compatible, source-complete plans. */
|
|
679
706
|
export type CompletePlan<PlanValue extends QueryPlan<any, any, any, any, any, any, any, any, any, any>> = StatementOfPlan<PlanValue> extends "insert" ? InsertSourceStateOfPlan<PlanValue> extends "missing" ? InsertHasOptionalDefaults<PlanValue> extends true ? PlanValue : InsertSourceCompletenessError<PlanValue> : HasKnownOutstanding<RequiredOfPlan<PlanValue>> extends true ? SourceCompletenessError<PlanValue, Extract<RequiredOfPlan<PlanValue>, string>> : IsAggregationCompatibleSelection<SelectionOfPlan<PlanValue>, GroupedOfPlan<PlanValue>> extends true ? PlanValue : AggregationCompatibilityError<PlanValue> : HasKnownOutstanding<RequiredOfPlan<PlanValue>> extends true ? SourceCompletenessError<PlanValue, Extract<RequiredOfPlan<PlanValue>, string>> : IsAggregationCompatibleSelection<SelectionOfPlan<PlanValue>, GroupedOfPlan<PlanValue>> extends true ? PlanValue : AggregationCompatibilityError<PlanValue>;
|
|
680
707
|
/** Whether a plan dialect is compatible with a target engine dialect. */
|
|
681
|
-
type IsDialectCompatible<PlanDialect extends string, EngineDialect extends string> = [PlanDialect] extends [never] ? true :
|
|
708
|
+
type IsDialectCompatible<PlanDialect extends string, EngineDialect extends string> = [PlanDialect] extends [never] ? true : Exclude<PlanDialect, EngineDialect | "standard"> extends never ? true : false;
|
|
682
709
|
/** Narrows a complete plan to those compatible with a target engine dialect. */
|
|
683
|
-
export type DialectCompatiblePlan<PlanValue extends QueryPlan<any, any, any, any, any, any, any, any, any, any>, EngineDialect extends string> = IsDialectCompatible<PlanValue
|
|
710
|
+
export type DialectCompatiblePlan<PlanValue extends QueryPlan<any, any, any, any, any, any, any, any, any, any>, EngineDialect extends string> = IsDialectCompatible<PlanDialectOf<PlanValue>, EngineDialect> extends true ? CompletePlan<PlanValue> : DialectCompatibilityError<PlanValue, EngineDialect>;
|
|
684
711
|
/** Nested-plan compatibility used by subquery expressions such as `exists(...)`. */
|
|
685
|
-
export type DialectCompatibleNestedPlan<PlanValue extends QueryPlan<any, any, any, any, any, any, any, any, any, any>, EngineDialect extends string> = IsDialectCompatible<PlanValue
|
|
712
|
+
export type DialectCompatibleNestedPlan<PlanValue extends QueryPlan<any, any, any, any, any, any, any, any, any, any>, EngineDialect extends string> = IsDialectCompatible<PlanDialectOf<PlanValue>, EngineDialect> extends true ? AggregationCompatiblePlan<PlanValue> : DialectCompatibilityError<PlanValue, EngineDialect>;
|
|
686
713
|
type SetOperandStatement = "select" | "set";
|
|
687
714
|
type IsUnion<Value, All = Value> = Value extends any ? ([All] extends [Value] ? false : true) : never;
|
|
688
715
|
type SingleSelectedExpressionError<PlanValue extends QueryPlan<any, any, any, any, any, any, any, any, any, any>> = PlanValue & {
|
package/src/internal/query.ts
CHANGED
|
@@ -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:
|
|
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:
|
|
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
|
-
|
|
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]:
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
|
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:
|
|
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:
|
|
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
|
|
2540
|
-
|
|
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. */
|