effect-qb 0.17.0 → 0.20.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (137) hide show
  1. package/README.md +11 -1
  2. package/dist/index.js +9376 -0
  3. package/dist/mysql.js +4092 -2671
  4. package/dist/postgres/metadata.js +2589 -1402
  5. package/dist/postgres.js +3953 -3583
  6. package/dist/sqlite.js +5527 -4088
  7. package/dist/standard.js +9330 -0
  8. package/package.json +9 -4
  9. package/src/casing.ts +71 -0
  10. package/src/index.ts +2 -0
  11. package/src/internal/casing.ts +89 -0
  12. package/src/internal/coercion/rules.ts +13 -1
  13. package/src/internal/column-state.d.ts +3 -3
  14. package/src/internal/column-state.ts +24 -18
  15. package/src/internal/column.ts +52 -15
  16. package/src/internal/datatypes/define.ts +7 -1
  17. package/src/internal/datatypes/enrich.ts +23 -0
  18. package/src/internal/datatypes/lookup.ts +81 -25
  19. package/src/internal/datatypes/matrix.ts +903 -0
  20. package/src/internal/datatypes/shape.ts +2 -0
  21. package/src/internal/derived-table.ts +4 -36
  22. package/src/{mysql/internal/sql-expression-renderer.ts → internal/dialect-renderers/mysql.ts} +552 -361
  23. package/src/{postgres/internal/sql-expression-renderer.ts → internal/dialect-renderers/postgres.ts} +657 -400
  24. package/src/{sqlite/internal/sql-expression-renderer.ts → internal/dialect-renderers/sqlite.ts} +505 -347
  25. package/src/internal/dialect.ts +36 -1
  26. package/src/internal/dsl-mutation-runtime.ts +12 -162
  27. package/src/internal/dsl-plan-runtime.ts +10 -138
  28. package/src/internal/dsl-query-runtime.ts +5 -79
  29. package/src/internal/dsl-transaction-ddl-runtime.ts +41 -65
  30. package/src/internal/executor.ts +66 -49
  31. package/src/internal/grouping-key.ts +87 -20
  32. package/src/internal/implication-runtime.ts +1 -1
  33. package/src/internal/json/path-access.ts +351 -0
  34. package/src/internal/predicate/runtime.ts +3 -0
  35. package/src/internal/query.d.ts +39 -12
  36. package/src/internal/query.ts +65 -26
  37. package/src/internal/renderer.ts +26 -14
  38. package/src/internal/runtime/driver-value-mapping.ts +3 -3
  39. package/src/internal/runtime/normalize.ts +12 -5
  40. package/src/internal/runtime/schema.ts +28 -38
  41. package/src/internal/runtime/value.ts +20 -23
  42. package/src/internal/scalar.d.ts +1 -1
  43. package/src/internal/scalar.ts +8 -2
  44. package/src/internal/schema-derivation.d.ts +12 -61
  45. package/src/internal/schema-derivation.ts +95 -43
  46. package/src/internal/schema-expression.ts +2 -2
  47. package/src/internal/sql-expression-renderer.ts +19 -0
  48. package/src/internal/standard-dsl.ts +6978 -0
  49. package/src/internal/table-options.ts +126 -66
  50. package/src/internal/table.ts +819 -237
  51. package/src/mysql/column-extension.ts +3 -0
  52. package/src/mysql/column.ts +14 -15
  53. package/src/mysql/datatypes/index.ts +4 -2
  54. package/src/mysql/datatypes/spec.ts +6 -176
  55. package/src/mysql/errors/normalize.ts +0 -1
  56. package/src/mysql/executor.ts +11 -11
  57. package/src/mysql/function/temporal.ts +1 -1
  58. package/src/mysql/internal/dialect.ts +9 -4
  59. package/src/mysql/internal/dsl.ts +334 -170
  60. package/src/mysql/internal/renderer.ts +6 -2
  61. package/src/mysql/json.ts +7 -2
  62. package/src/mysql/query-extension.ts +16 -0
  63. package/src/mysql/renderer.ts +37 -3
  64. package/src/mysql/type.ts +60 -0
  65. package/src/mysql.ts +7 -13
  66. package/src/postgres/check.ts +1 -0
  67. package/src/postgres/column-extension.ts +28 -0
  68. package/src/postgres/column.ts +13 -19
  69. package/src/postgres/datatypes/index.d.ts +2 -1
  70. package/src/postgres/datatypes/index.ts +4 -2
  71. package/src/postgres/datatypes/spec.ts +6 -260
  72. package/src/postgres/errors/normalize.ts +0 -1
  73. package/src/postgres/executor.ts +11 -11
  74. package/src/postgres/foreign-key.ts +24 -0
  75. package/src/postgres/function/core.ts +1 -3
  76. package/src/postgres/function/index.ts +1 -17
  77. package/src/postgres/function/temporal.ts +1 -1
  78. package/src/postgres/index.ts +1 -0
  79. package/src/postgres/internal/dialect.ts +9 -4
  80. package/src/postgres/internal/dsl.ts +328 -179
  81. package/src/postgres/internal/renderer.ts +6 -2
  82. package/src/postgres/internal/schema-ddl.ts +22 -10
  83. package/src/postgres/internal/schema-model.ts +238 -7
  84. package/src/postgres/json-extension.ts +7 -0
  85. package/src/postgres/json.ts +762 -173
  86. package/src/postgres/jsonb.ts +37 -0
  87. package/src/postgres/primary-key.ts +24 -0
  88. package/src/postgres/query-extension.ts +2 -0
  89. package/src/postgres/renderer.ts +37 -3
  90. package/src/postgres/schema-management.ts +13 -13
  91. package/src/postgres/schema.ts +106 -15
  92. package/src/postgres/table.ts +205 -538
  93. package/src/postgres/type.ts +93 -10
  94. package/src/postgres/unique.ts +32 -0
  95. package/src/postgres.ts +20 -16
  96. package/src/sqlite/column-extension.ts +3 -0
  97. package/src/sqlite/column.ts +14 -15
  98. package/src/sqlite/datatypes/index.ts +4 -2
  99. package/src/sqlite/datatypes/spec.ts +6 -94
  100. package/src/sqlite/errors/normalize.ts +0 -1
  101. package/src/sqlite/executor.ts +11 -11
  102. package/src/sqlite/function/temporal.ts +1 -1
  103. package/src/sqlite/internal/dialect.ts +9 -4
  104. package/src/sqlite/internal/dsl.ts +307 -159
  105. package/src/sqlite/internal/renderer.ts +6 -2
  106. package/src/sqlite/json.ts +8 -2
  107. package/src/sqlite/query-extension.ts +2 -0
  108. package/src/sqlite/renderer.ts +37 -3
  109. package/src/sqlite/type.ts +40 -0
  110. package/src/sqlite.ts +7 -13
  111. package/src/standard/cast.ts +113 -0
  112. package/src/standard/check.ts +17 -0
  113. package/src/standard/column.ts +163 -0
  114. package/src/standard/datatypes/index.ts +83 -0
  115. package/src/standard/datatypes/spec.ts +12 -0
  116. package/src/standard/dialect.ts +40 -0
  117. package/src/standard/foreign-key.ts +37 -0
  118. package/src/standard/function/aggregate.ts +2 -0
  119. package/src/standard/function/core.ts +2 -0
  120. package/src/standard/function/index.ts +18 -0
  121. package/src/standard/function/string.ts +2 -0
  122. package/src/standard/function/temporal.ts +78 -0
  123. package/src/standard/function/window.ts +2 -0
  124. package/src/standard/index.ts +17 -0
  125. package/src/standard/internal/renderer.ts +45 -0
  126. package/src/standard/json.ts +883 -0
  127. package/src/standard/primary-key.ts +17 -0
  128. package/src/standard/query.ts +152 -0
  129. package/src/standard/renderer.ts +49 -0
  130. package/src/standard/table.ts +151 -0
  131. package/src/standard/unique.ts +17 -0
  132. package/src/standard.ts +32 -0
  133. package/src/internal/aggregation-validation.ts +0 -57
  134. package/src/internal/table.d.ts +0 -173
  135. package/src/mysql/table.ts +0 -183
  136. package/src/postgres/cast.ts +0 -45
  137. package/src/sqlite/table.ts +0 -183
@@ -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"
@@ -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
- /** Walks a selection tree and unions the dialects referenced by its leaves. */
139
- export type ExtractDialect<Selection> = Selection extends Expression.Any ? DialectOf<Selection> : Selection extends Record<string, any> ? {
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
- /** Extracts the effective dialect from a source. */
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[typeof RowSet.TypeId]["dialect"];
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 : Extract<PlanDialect, EngineDialect> extends never ? false : 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[typeof RowSet.TypeId]["dialect"], EngineDialect> extends true ? CompletePlan<PlanValue> : DialectCompatibilityError<PlanValue, EngineDialect>;
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[typeof RowSet.TypeId]["dialect"], EngineDialect> extends true ? AggregationCompatiblePlan<PlanValue> : DialectCompatibilityError<PlanValue, EngineDialect>;
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 & {
@@ -743,7 +770,7 @@ export declare const mergeManyDependencies: <Values extends readonly Expression.
743
770
  export declare const makeExpression: <Runtime, Db extends Expression.DbType.Any, Nullable extends Expression.Nullability, Dialect extends string, Kind extends Expression.ScalarKind, Deps extends string = never, Ast extends ExpressionAst.Any = ExpressionAst.Any, GroupKey extends string = GroupingKeyOfAst<Ast>>(state: {
744
771
  readonly runtime: Runtime;
745
772
  readonly dbType: Db;
746
- readonly runtimeSchema?: Schema.Schema.Any | undefined;
773
+ readonly runtimeSchema?: Schema.Top | undefined;
747
774
  readonly nullability: Nullable;
748
775
  readonly dialect: Dialect;
749
776
  readonly kind?: Kind | undefined;