effect-qb 0.14.0 → 0.16.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 (146) hide show
  1. package/dist/mysql.js +61555 -4252
  2. package/dist/postgres/metadata.js +728 -104
  3. package/dist/postgres.js +6906 -4023
  4. package/package.json +15 -2
  5. package/src/internal/aggregation-validation.ts +3 -3
  6. package/src/internal/case-analysis.d.ts +18 -0
  7. package/src/internal/case-analysis.ts +4 -4
  8. package/src/internal/coercion/analysis.d.ts +7 -0
  9. package/src/internal/{coercion-analysis.ts → coercion/analysis.ts} +3 -3
  10. package/src/internal/coercion/errors.d.ts +17 -0
  11. package/src/internal/{coercion-errors.ts → coercion/errors.ts} +1 -1
  12. package/src/internal/coercion/kind.d.ts +4 -0
  13. package/src/internal/{coercion-kind.ts → coercion/kind.ts} +2 -2
  14. package/src/internal/{coercion-normalize.ts → coercion/normalize.ts} +1 -1
  15. package/src/internal/coercion/rules.d.ts +6 -0
  16. package/src/internal/{coercion-rules.ts → coercion/rules.ts} +2 -2
  17. package/src/internal/column-state.d.ts +190 -0
  18. package/src/internal/column-state.ts +43 -47
  19. package/src/internal/column.ts +43 -305
  20. package/src/internal/datatypes/define.d.ts +17 -0
  21. package/src/internal/datatypes/define.ts +18 -4
  22. package/src/internal/datatypes/lookup.d.ts +44 -0
  23. package/src/internal/datatypes/lookup.ts +61 -152
  24. package/src/internal/datatypes/shape.d.ts +16 -0
  25. package/src/internal/datatypes/shape.ts +1 -1
  26. package/src/internal/derived-table.d.ts +4 -0
  27. package/src/internal/derived-table.ts +21 -16
  28. package/src/internal/dialect.ts +12 -1
  29. package/src/internal/dsl-mutation-runtime.ts +378 -0
  30. package/src/internal/dsl-plan-runtime.ts +387 -0
  31. package/src/internal/dsl-query-runtime.ts +160 -0
  32. package/src/internal/dsl-transaction-ddl-runtime.ts +263 -0
  33. package/src/internal/executor.ts +146 -34
  34. package/src/internal/expression-ast.ts +15 -5
  35. package/src/internal/grouping-key.d.ts +3 -0
  36. package/src/internal/grouping-key.ts +1 -1
  37. package/src/internal/implication-runtime.d.ts +15 -0
  38. package/src/internal/implication-runtime.ts +4 -4
  39. package/src/internal/json/ast.d.ts +30 -0
  40. package/src/internal/json/ast.ts +1 -1
  41. package/src/internal/json/errors.d.ts +8 -0
  42. package/src/internal/json/path.d.ts +75 -0
  43. package/src/internal/json/path.ts +1 -1
  44. package/src/internal/json/types.d.ts +62 -0
  45. package/src/internal/predicate/analysis.d.ts +20 -0
  46. package/src/internal/predicate/analysis.ts +183 -0
  47. package/src/internal/predicate/atom.d.ts +28 -0
  48. package/src/internal/{predicate-atom.ts → predicate/atom.ts} +7 -0
  49. package/src/internal/{predicate-branches.ts → predicate/branches.ts} +2 -2
  50. package/src/internal/predicate/context.d.ts +67 -0
  51. package/src/internal/{predicate-context.ts → predicate/context.ts} +163 -20
  52. package/src/internal/predicate/formula.d.ts +35 -0
  53. package/src/internal/{predicate-formula.ts → predicate/formula.ts} +1 -1
  54. package/src/internal/predicate/key.d.ts +11 -0
  55. package/src/internal/predicate/key.ts +73 -0
  56. package/src/internal/{predicate-nnf.ts → predicate/nnf.ts} +2 -2
  57. package/src/internal/predicate/normalize.d.ts +53 -0
  58. package/src/internal/{predicate-normalize.ts → predicate/normalize.ts} +130 -49
  59. package/src/internal/predicate/runtime.d.ts +31 -0
  60. package/src/internal/{predicate-runtime.ts → predicate/runtime.ts} +127 -17
  61. package/src/internal/projection-alias.d.ts +13 -0
  62. package/src/internal/projections.d.ts +31 -0
  63. package/src/internal/projections.ts +1 -1
  64. package/src/internal/query-ast.d.ts +217 -0
  65. package/src/internal/query-ast.ts +1 -1
  66. package/src/internal/query-requirements.d.ts +20 -0
  67. package/src/internal/query.d.ts +775 -0
  68. package/src/internal/query.ts +683 -369
  69. package/src/internal/renderer.ts +11 -21
  70. package/src/internal/row-set.d.ts +53 -0
  71. package/src/internal/{plan.ts → row-set.ts} +11 -9
  72. package/src/internal/runtime/driver-value-mapping.ts +186 -0
  73. package/src/internal/{runtime-normalize.ts → runtime/normalize.ts} +9 -31
  74. package/src/internal/{runtime-schema.ts → runtime/schema.ts} +13 -38
  75. package/src/internal/runtime/value.d.ts +22 -0
  76. package/src/internal/{runtime-value.ts → runtime/value.ts} +2 -2
  77. package/src/internal/scalar.d.ts +107 -0
  78. package/src/internal/scalar.ts +202 -0
  79. package/src/internal/schema-derivation.d.ts +105 -0
  80. package/src/internal/schema-expression.d.ts +18 -0
  81. package/src/internal/schema-expression.ts +38 -7
  82. package/src/internal/table-options.d.ts +94 -0
  83. package/src/internal/table-options.ts +8 -2
  84. package/src/internal/table.d.ts +173 -0
  85. package/src/internal/table.ts +32 -14
  86. package/src/mysql/column.ts +95 -18
  87. package/src/mysql/datatypes/index.ts +47 -7
  88. package/src/mysql/errors/generated.ts +57336 -0
  89. package/src/mysql/errors/index.ts +1 -0
  90. package/src/mysql/errors/normalize.ts +55 -53
  91. package/src/mysql/errors/types.ts +74 -0
  92. package/src/mysql/executor.ts +88 -11
  93. package/src/mysql/function/aggregate.ts +1 -5
  94. package/src/mysql/function/core.ts +1 -4
  95. package/src/mysql/function/index.ts +0 -1
  96. package/src/mysql/function/string.ts +1 -5
  97. package/src/mysql/function/temporal.ts +12 -15
  98. package/src/mysql/function/window.ts +1 -6
  99. package/src/{internal/mysql-dialect.ts → mysql/internal/dialect.ts} +12 -6
  100. package/src/{internal/mysql-query.ts → mysql/internal/dsl.ts} +1299 -2143
  101. package/src/mysql/internal/renderer.ts +46 -0
  102. package/src/mysql/internal/sql-expression-renderer.ts +1501 -0
  103. package/src/mysql/json.ts +2 -0
  104. package/src/mysql/query.ts +111 -91
  105. package/src/mysql/renderer.ts +8 -3
  106. package/src/mysql/table.ts +1 -1
  107. package/src/mysql.ts +6 -4
  108. package/src/postgres/cast.ts +30 -16
  109. package/src/postgres/column.ts +179 -46
  110. package/src/postgres/datatypes/index.d.ts +515 -0
  111. package/src/postgres/datatypes/index.ts +22 -13
  112. package/src/postgres/datatypes/spec.d.ts +412 -0
  113. package/src/postgres/errors/generated.ts +2636 -0
  114. package/src/postgres/errors/index.ts +1 -0
  115. package/src/postgres/errors/normalize.ts +47 -62
  116. package/src/postgres/errors/types.ts +92 -34
  117. package/src/postgres/executor.ts +54 -7
  118. package/src/postgres/function/aggregate.ts +1 -5
  119. package/src/postgres/function/core.ts +12 -6
  120. package/src/postgres/function/index.ts +0 -1
  121. package/src/postgres/function/string.ts +1 -5
  122. package/src/postgres/function/temporal.ts +12 -15
  123. package/src/postgres/function/window.ts +1 -6
  124. package/src/{internal/postgres-dialect.ts → postgres/internal/dialect.ts} +12 -6
  125. package/src/{internal/postgres-query.ts → postgres/internal/dsl.ts} +1356 -2133
  126. package/src/{internal/postgres-renderer.ts → postgres/internal/renderer.ts} +17 -8
  127. package/src/postgres/internal/schema-ddl.ts +108 -0
  128. package/src/{internal/postgres-schema-model.ts → postgres/internal/schema-model.ts} +12 -6
  129. package/src/{internal → postgres/internal}/sql-expression-renderer.ts +79 -25
  130. package/src/postgres/{function/json.ts → json.ts} +77 -85
  131. package/src/postgres/metadata.ts +2 -2
  132. package/src/postgres/query.ts +113 -89
  133. package/src/postgres/renderer.ts +8 -13
  134. package/src/postgres/schema-expression.ts +2 -1
  135. package/src/postgres/schema-management.ts +1 -1
  136. package/src/postgres/table.ts +12 -4
  137. package/src/postgres/type.ts +33 -2
  138. package/src/postgres.ts +6 -4
  139. package/src/internal/expression.ts +0 -327
  140. package/src/internal/mysql-renderer.ts +0 -37
  141. package/src/internal/predicate-analysis.ts +0 -81
  142. package/src/internal/predicate-key.ts +0 -28
  143. package/src/internal/schema-ddl.ts +0 -55
  144. package/src/mysql/function/json.ts +0 -4
  145. package/src/mysql/private/query.ts +0 -1
  146. package/src/postgres/private/query.ts +0 -1
@@ -1,8 +1,8 @@
1
- import type * as Expression from "./expression.js"
2
- import type * as ExpressionAst from "./expression-ast.js"
3
- import type { ColumnKeyOfExpression, ValueKey } from "./predicate-key.js"
4
- import type { AllFormula, AnyFormula, AtomFormula, FalseFormula, NotFormula, PredicateFormula, TrueFormula } from "./predicate-formula.js"
5
- import type { EqColumnAtom, EqLiteralAtom, NeqLiteralAtom, NonNullAtom, NullAtom, UnknownAtom } from "./predicate-atom.js"
1
+ import type * as Expression from "../scalar.js"
2
+ import type * as ExpressionAst from "../expression-ast.js"
3
+ import type { PredicateKeyOfExpression, ValueKey } from "./key.js"
4
+ import type { AllFormula, AnyFormula, AtomFormula, FalseFormula, NotFormula, PredicateFormula, TrueFormula } from "./formula.js"
5
+ import type { EqColumnAtom, EqLiteralAtom, LiteralSetAtom, NeqLiteralAtom, NonNullAtom, NullAtom, UnknownAtom } from "./atom.js"
6
6
 
7
7
  type AstOf<Value extends Expression.Any> = Value extends {
8
8
  readonly [ExpressionAst.TypeId]: infer Ast extends ExpressionAst.Any
@@ -16,13 +16,13 @@ type True = TrueFormula
16
16
  type False = FalseFormula
17
17
 
18
18
  type UnknownTag<Tag extends string> = AtomFormula<UnknownAtom<Tag>>
19
- type AtomOf<Atom extends import("./predicate-atom.js").PredicateAtom> = AtomFormula<Atom>
20
- type FactOf<Atom extends import("./predicate-atom.js").PredicateAtom> = AtomFormula<Atom>
19
+ type AtomOf<Atom extends import("./atom.js").PredicateAtom> = AtomFormula<Atom>
20
+ type FactOf<Atom extends import("./atom.js").PredicateAtom> = AtomFormula<Atom>
21
21
 
22
22
  type NonNullFactsOfExpression<Value extends Expression.Any> =
23
- [ColumnKeyOfExpression<Value>] extends [never]
23
+ [PredicateKeyOfExpression<Value>] extends [never]
24
24
  ? never
25
- : FactOf<NonNullAtom<ColumnKeyOfExpression<Value>>>
25
+ : FactOf<NonNullAtom<PredicateKeyOfExpression<Value>>>
26
26
 
27
27
  type CombineFacts<
28
28
  Left extends PredicateFormula,
@@ -31,7 +31,7 @@ type CombineFacts<
31
31
  ? Right
32
32
  : [Right] extends [never]
33
33
  ? Left
34
- : import("./predicate-formula.js").NormalizeBooleanConstants<AllFormula<[Left, Right]>>
34
+ : import("./formula.js").NormalizeBooleanConstants<AllFormula<[Left, Right]>>
35
35
 
36
36
  type FactsOfExpressions<Values extends readonly Expression.Any[]> =
37
37
  Values extends readonly [
@@ -45,8 +45,8 @@ type FormulaOfEq<
45
45
  Left extends Expression.Any,
46
46
  Right extends Expression.Any
47
47
  > =
48
- [ColumnKeyOfExpression<Left>] extends [never]
49
- ? [ColumnKeyOfExpression<Right>] extends [never]
48
+ [PredicateKeyOfExpression<Left>] extends [never]
49
+ ? [PredicateKeyOfExpression<Right>] extends [never]
50
50
  ? LiteralValueOfExpression<Left> extends infer LeftLiteral
51
51
  ? LiteralValueOfExpression<Right> extends infer RightLiteral
52
52
  ? [LeftLiteral] extends [never]
@@ -67,24 +67,24 @@ type FormulaOfEq<
67
67
  ? UnknownTag<"eq:unsupported">
68
68
  : LeftLiteral extends null
69
69
  ? False
70
- : AtomOf<EqLiteralAtom<ColumnKeyOfExpression<Right>, ValueKey<LeftLiteral>>>
70
+ : AtomOf<EqLiteralAtom<PredicateKeyOfExpression<Right>, ValueKey<LeftLiteral>>>
71
71
  : UnknownTag<"eq:unsupported">
72
- : [ColumnKeyOfExpression<Right>] extends [never]
72
+ : [PredicateKeyOfExpression<Right>] extends [never]
73
73
  ? LiteralValueOfExpression<Right> extends infer RightLiteral
74
74
  ? [RightLiteral] extends [never]
75
75
  ? UnknownTag<"eq:unsupported">
76
76
  : RightLiteral extends null
77
77
  ? False
78
- : AtomOf<EqLiteralAtom<ColumnKeyOfExpression<Left>, ValueKey<RightLiteral>>>
78
+ : AtomOf<EqLiteralAtom<PredicateKeyOfExpression<Left>, ValueKey<RightLiteral>>>
79
79
  : UnknownTag<"eq:unsupported">
80
- : AtomOf<import("./predicate-atom.js").EqColumnAtom<ColumnKeyOfExpression<Left>, ColumnKeyOfExpression<Right>>>
80
+ : AtomOf<import("./atom.js").EqColumnAtom<PredicateKeyOfExpression<Left>, PredicateKeyOfExpression<Right>>>
81
81
 
82
82
  type FormulaOfNeq<
83
83
  Left extends Expression.Any,
84
84
  Right extends Expression.Any
85
85
  > =
86
- [ColumnKeyOfExpression<Left>] extends [never]
87
- ? [ColumnKeyOfExpression<Right>] extends [never]
86
+ [PredicateKeyOfExpression<Left>] extends [never]
87
+ ? [PredicateKeyOfExpression<Right>] extends [never]
88
88
  ? LiteralValueOfExpression<Left> extends infer LeftLiteral
89
89
  ? LiteralValueOfExpression<Right> extends infer RightLiteral
90
90
  ? [LeftLiteral] extends [never]
@@ -105,15 +105,15 @@ type FormulaOfNeq<
105
105
  ? UnknownTag<"neq:unsupported">
106
106
  : LeftLiteral extends null
107
107
  ? False
108
- : AtomOf<NeqLiteralAtom<ColumnKeyOfExpression<Right>, ValueKey<LeftLiteral>>>
108
+ : AtomOf<NeqLiteralAtom<PredicateKeyOfExpression<Right>, ValueKey<LeftLiteral>>>
109
109
  : UnknownTag<"neq:unsupported">
110
- : [ColumnKeyOfExpression<Right>] extends [never]
110
+ : [PredicateKeyOfExpression<Right>] extends [never]
111
111
  ? LiteralValueOfExpression<Right> extends infer RightLiteral
112
112
  ? [RightLiteral] extends [never]
113
113
  ? UnknownTag<"neq:unsupported">
114
114
  : RightLiteral extends null
115
115
  ? False
116
- : AtomOf<NeqLiteralAtom<ColumnKeyOfExpression<Left>, ValueKey<RightLiteral>>>
116
+ : AtomOf<NeqLiteralAtom<PredicateKeyOfExpression<Left>, ValueKey<RightLiteral>>>
117
117
  : UnknownTag<"neq:unsupported">
118
118
  : CombineFacts<NonNullFactsOfExpression<Left>, NonNullFactsOfExpression<Right>>
119
119
 
@@ -127,47 +127,96 @@ type FormulaOfIsNotDistinctFrom<
127
127
  ? [RightLiteral] extends [never]
128
128
  ? UnknownTag<"isNotDistinctFrom:unsupported">
129
129
  : RightLiteral extends null
130
- ? [ColumnKeyOfExpression<Left>] extends [never]
130
+ ? [PredicateKeyOfExpression<Left>] extends [never]
131
131
  ? UnknownTag<"isNotDistinctFrom:unsupported">
132
- : AtomOf<NullAtom<ColumnKeyOfExpression<Left>>>
132
+ : AtomOf<NullAtom<PredicateKeyOfExpression<Left>>>
133
133
  : UnknownTag<"isNotDistinctFrom:unsupported">
134
134
  : LeftLiteral extends null
135
- ? [ColumnKeyOfExpression<Right>] extends [never]
135
+ ? [PredicateKeyOfExpression<Right>] extends [never]
136
136
  ? UnknownTag<"isNotDistinctFrom:unsupported">
137
- : AtomOf<NullAtom<ColumnKeyOfExpression<Right>>>
137
+ : AtomOf<NullAtom<PredicateKeyOfExpression<Right>>>
138
138
  : RightLiteral extends null
139
- ? [ColumnKeyOfExpression<Left>] extends [never]
139
+ ? [PredicateKeyOfExpression<Left>] extends [never]
140
140
  ? UnknownTag<"isNotDistinctFrom:unsupported">
141
- : AtomOf<NullAtom<ColumnKeyOfExpression<Left>>>
142
- : [ColumnKeyOfExpression<Left>] extends [never]
143
- ? [ColumnKeyOfExpression<Right>] extends [never]
141
+ : AtomOf<NullAtom<PredicateKeyOfExpression<Left>>>
142
+ : [PredicateKeyOfExpression<Left>] extends [never]
143
+ ? [PredicateKeyOfExpression<Right>] extends [never]
144
144
  ? CombineFacts<NonNullFactsOfExpression<Left>, NonNullFactsOfExpression<Right>>
145
- : AtomOf<EqLiteralAtom<ColumnKeyOfExpression<Right>, ValueKey<LeftLiteral>>>
146
- : AtomOf<EqLiteralAtom<ColumnKeyOfExpression<Left>, ValueKey<RightLiteral>>>
145
+ : AtomOf<EqLiteralAtom<PredicateKeyOfExpression<Right>, ValueKey<LeftLiteral>>>
146
+ : AtomOf<EqLiteralAtom<PredicateKeyOfExpression<Left>, ValueKey<RightLiteral>>>
147
147
  : UnknownTag<"isNotDistinctFrom:unsupported">
148
148
  : UnknownTag<"isNotDistinctFrom:unsupported">
149
149
 
150
150
  type OrFormulas<
151
151
  Items extends readonly PredicateFormula[]
152
- > = import("./predicate-formula.js").NormalizeBooleanConstants<AnyFormula<Items>>
152
+ > = import("./formula.js").NormalizeBooleanConstants<AnyFormula<Items>>
153
153
 
154
154
  type AndFormulas<
155
155
  Items extends readonly PredicateFormula[]
156
- > = import("./predicate-formula.js").NormalizeBooleanConstants<AllFormula<Items>>
156
+ > = import("./formula.js").NormalizeBooleanConstants<AllFormula<Items>>
157
157
 
158
158
  type FormulaTupleOf<
159
159
  Values extends readonly Expression.Any[]
160
- > = {
161
- readonly [K in keyof Values]: Values[K] extends Expression.Any ? FormulaOfExpression<Values[K]> : never
162
- } & readonly PredicateFormula[]
160
+ > = Values extends readonly [
161
+ infer Head extends Expression.Any,
162
+ ...infer Tail extends readonly Expression.Any[]
163
+ ]
164
+ ? readonly [FormulaOfExpression<Head>, ...FormulaTupleOf<Tail>]
165
+ : readonly []
163
166
 
164
167
  type AllFormulaOfValues<
165
168
  Values extends readonly Expression.Any[]
166
- > = import("./predicate-formula.js").NormalizeBooleanConstants<AllFormula<FormulaTupleOf<Values>>>
169
+ > = import("./formula.js").NormalizeBooleanConstants<AllFormula<FormulaTupleOf<Values>>>
167
170
 
168
171
  type AnyFormulaOfValues<
169
172
  Values extends readonly Expression.Any[]
170
- > = import("./predicate-formula.js").NormalizeBooleanConstants<AnyFormula<FormulaTupleOf<Values>>>
173
+ > = FormulaTupleOf<Values> extends infer Formulas extends readonly PredicateFormula[]
174
+ ? [CompactOrLiteralSet<Formulas>] extends [infer Compact extends PredicateFormula]
175
+ ? [Compact] extends [never]
176
+ ? import("./formula.js").NormalizeBooleanConstants<AnyFormula<Formulas>>
177
+ : Compact
178
+ : import("./formula.js").NormalizeBooleanConstants<AnyFormula<Formulas>>
179
+ : import("./formula.js").NormalizeBooleanConstants<AnyFormula<FormulaTupleOf<Values>>>
180
+
181
+ type LiteralSetDetails<Formula extends PredicateFormula> =
182
+ Formula extends AtomFormula<EqLiteralAtom<infer Key extends string, infer Value extends string>>
183
+ ? readonly [Key, Value]
184
+ : Formula extends AtomFormula<LiteralSetAtom<infer Key extends string, infer Values extends string>>
185
+ ? readonly [Key, Values]
186
+ : never
187
+
188
+ type IsUnion<Value, Candidate = Value> =
189
+ [Value] extends [never]
190
+ ? false
191
+ : Value extends unknown
192
+ ? [Candidate] extends [Value] ? false : true
193
+ : false
194
+
195
+ type CompactOrLiteralSet<
196
+ Items extends readonly PredicateFormula[],
197
+ Key extends string = never,
198
+ Values extends string = never,
199
+ Seen extends readonly unknown[] = []
200
+ > = Seen["length"] extends 20
201
+ ? never
202
+ : Items extends readonly [
203
+ infer Head extends PredicateFormula,
204
+ ...infer Tail extends readonly PredicateFormula[]
205
+ ]
206
+ ? LiteralSetDetails<Head> extends readonly [infer HeadKey extends string, infer HeadValues extends string]
207
+ ? IsUnion<HeadKey> extends true
208
+ ? never
209
+ : [Key] extends [never]
210
+ ? CompactOrLiteralSet<Tail, HeadKey, HeadValues, readonly [...Seen, unknown]>
211
+ : [HeadKey] extends [Key]
212
+ ? [Key] extends [HeadKey]
213
+ ? CompactOrLiteralSet<Tail, Key, Values | HeadValues, readonly [...Seen, unknown]>
214
+ : never
215
+ : never
216
+ : never
217
+ : [Key] extends [never]
218
+ ? never
219
+ : AtomOf<LiteralSetAtom<Key, Values>>
171
220
 
172
221
  type FormulaOfInValues<
173
222
  Left extends Expression.Any,
@@ -180,6 +229,38 @@ type FormulaOfInValues<
180
229
  ? FormulaOfInValues<Left, Tail, [...Current, FormulaOfEq<Left, Head>]>
181
230
  : Current
182
231
 
232
+ type LiteralSetValuesOf<
233
+ Values extends readonly Expression.Any[],
234
+ Current extends string = never,
235
+ Seen extends readonly unknown[] = []
236
+ > = Seen["length"] extends 20
237
+ ? string
238
+ : Values extends readonly [
239
+ infer Head extends Expression.Any,
240
+ ...infer Tail extends readonly Expression.Any[]
241
+ ]
242
+ ? LiteralValueOfExpression<Head> extends infer Literal
243
+ ? [Literal] extends [never]
244
+ ? never
245
+ : Literal extends null
246
+ ? never
247
+ : LiteralSetValuesOf<Tail, Current | ValueKey<Literal>, readonly [...Seen, unknown]>
248
+ : never
249
+ : Current
250
+
251
+ type FormulaOfIn<
252
+ Left extends Expression.Any,
253
+ Values extends readonly Expression.Any[]
254
+ > = [PredicateKeyOfExpression<Left>] extends [never]
255
+ ? OrFormulas<FormulaOfInValues<Left, Values>>
256
+ : LiteralSetValuesOf<Values> extends infer ValueSet extends string
257
+ ? [ValueSet] extends [never]
258
+ ? OrFormulas<FormulaOfInValues<Left, Values>>
259
+ : string extends ValueSet
260
+ ? CombineFacts<NonNullFactsOfExpression<Left>, UnknownTag<"in:literal-set-too-large">>
261
+ : AtomOf<LiteralSetAtom<PredicateKeyOfExpression<Left>, ValueSet>>
262
+ : OrFormulas<FormulaOfInValues<Left, Values>>
263
+
183
264
  type FormulaOfNotInValues<
184
265
  Left extends Expression.Any,
185
266
  Values extends readonly Expression.Any[],
@@ -200,12 +281,12 @@ type FormulaOfVariadic<
200
281
  ? AnyFormulaOfValues<Values>
201
282
  : Kind extends "in"
202
283
  ? Values extends readonly [infer Left extends Expression.Any, ...infer Tail extends readonly Expression.Any[]]
203
- ? OrFormulas<FormulaOfInValues<Left, Tail>>
284
+ ? FormulaOfIn<Left, Tail>
204
285
  : False
205
- : Kind extends "notIn"
206
- ? Values extends readonly [infer Left extends Expression.Any, ...infer Tail extends readonly Expression.Any[]]
207
- ? AndFormulas<FormulaOfNotInValues<Left, Tail>>
208
- : True
286
+ : Kind extends "notIn"
287
+ ? Values extends readonly [infer Left extends Expression.Any, ...infer Tail extends readonly Expression.Any[]]
288
+ ? CombineFacts<NonNullFactsOfExpression<Left>, AndFormulas<FormulaOfNotInValues<Left, Tail>>>
289
+ : True
209
290
  : Kind extends "between"
210
291
  ? FactsOfExpressions<Values> extends infer Facts extends PredicateFormula
211
292
  ? [Facts] extends [never]
@@ -218,15 +299,15 @@ type FormulaOfUnary<
218
299
  Kind extends ExpressionAst.UnaryKind,
219
300
  Inner extends Expression.Any
220
301
  > = Kind extends "isNull"
221
- ? [ColumnKeyOfExpression<Inner>] extends [never]
302
+ ? [PredicateKeyOfExpression<Inner>] extends [never]
222
303
  ? UnknownTag<"isNull:unsupported">
223
- : AtomOf<NullAtom<ColumnKeyOfExpression<Inner>>>
304
+ : AtomOf<NullAtom<PredicateKeyOfExpression<Inner>>>
224
305
  : Kind extends "isNotNull"
225
- ? [ColumnKeyOfExpression<Inner>] extends [never]
306
+ ? [PredicateKeyOfExpression<Inner>] extends [never]
226
307
  ? UnknownTag<"isNotNull:unsupported">
227
- : AtomOf<NonNullAtom<ColumnKeyOfExpression<Inner>>>
308
+ : AtomOf<NonNullAtom<PredicateKeyOfExpression<Inner>>>
228
309
  : Kind extends "not"
229
- ? import("./predicate-formula.js").Not<FormulaOfExpression<Inner>>
310
+ ? import("./formula.js").Not<FormulaOfExpression<Inner>>
230
311
  : UnknownTag<`unary:${Kind}`>
231
312
 
232
313
  type FormulaOfBinary<
@@ -242,7 +323,7 @@ type FormulaOfBinary<
242
323
  : Kind extends "isNotDistinctFrom"
243
324
  ? FormulaOfIsNotDistinctFrom<Left, Right>
244
325
  : Kind extends "isDistinctFrom"
245
- ? import("./predicate-formula.js").Not<FormulaOfIsNotDistinctFrom<Left, Right>>
326
+ ? import("./formula.js").Not<FormulaOfIsNotDistinctFrom<Left, Right>>
246
327
  : CombineFacts<NonNullFactsOfExpression<Left>, NonNullFactsOfExpression<Right>>
247
328
 
248
329
  type FormulaOfAst<
@@ -0,0 +1,31 @@
1
+ import * as Expression from "../scalar.js";
2
+ import type { PredicateAtom } from "./atom.js";
3
+ import type { AtomFormula, FalseFormula, PredicateFormula, TrueFormula } from "./formula.js";
4
+ export interface RuntimeContext {
5
+ readonly nonNullKeys: ReadonlySet<string>;
6
+ readonly nullKeys: ReadonlySet<string>;
7
+ readonly eqLiterals: ReadonlyMap<string, string>;
8
+ readonly neqLiterals: ReadonlyMap<string, ReadonlySet<string>>;
9
+ readonly sourceNames: ReadonlySet<string>;
10
+ readonly contradiction: boolean;
11
+ readonly unknown: boolean;
12
+ }
13
+ export declare const trueFormula: () => TrueFormula;
14
+ export declare const falseFormula: () => FalseFormula;
15
+ export declare const atomFormula: <Atom extends PredicateAtom>(atom: Atom) => AtomFormula<Atom>;
16
+ export declare const allFormula: (items: readonly PredicateFormula[]) => PredicateFormula;
17
+ export declare const anyFormula: (items: readonly PredicateFormula[]) => PredicateFormula;
18
+ export declare const notFormula: (item: PredicateFormula) => PredicateFormula;
19
+ export declare const andFormula: (left: PredicateFormula, right: PredicateFormula) => PredicateFormula;
20
+ export declare const orFormula: (left: PredicateFormula, right: PredicateFormula) => PredicateFormula;
21
+ export declare const analyzeFormula: (formula: PredicateFormula) => RuntimeContext;
22
+ export declare const normalizeFormula: (formula: PredicateFormula) => PredicateFormula;
23
+ export declare const formulaOfExpression: (value: Expression.Any) => PredicateFormula;
24
+ export declare const formulaOfPredicate: (value: boolean | Expression.Any) => PredicateFormula;
25
+ export declare const assumeFormulaTrue: (assumptions: PredicateFormula, formula: PredicateFormula) => PredicateFormula;
26
+ export declare const assumeFormulaFalse: (assumptions: PredicateFormula, formula: PredicateFormula) => PredicateFormula;
27
+ export declare const contradictsFormula: (assumptions: PredicateFormula, formula: PredicateFormula) => boolean;
28
+ export declare const impliesFormula: (assumptions: PredicateFormula, formula: PredicateFormula) => boolean;
29
+ export declare const guaranteedNonNullKeys: (assumptions: PredicateFormula) => ReadonlySet<string>;
30
+ export declare const guaranteedNullKeys: (assumptions: PredicateFormula) => ReadonlySet<string>;
31
+ export declare const guaranteedSourceNames: (assumptions: PredicateFormula) => ReadonlySet<string>;
@@ -1,14 +1,15 @@
1
- import * as Expression from "./expression.js"
2
- import * as ExpressionAst from "./expression-ast.js"
3
- import type { PredicateAtom } from "./predicate-atom.js"
1
+ import * as Expression from "../scalar.js"
2
+ import * as ExpressionAst from "../expression-ast.js"
3
+ import type { PredicateAtom } from "./atom.js"
4
4
  import type {
5
5
  EqColumnAtom,
6
6
  EqLiteralAtom,
7
+ LiteralSetAtom,
7
8
  NeqLiteralAtom,
8
9
  NonNullAtom,
9
10
  NullAtom,
10
11
  UnknownAtom
11
- } from "./predicate-atom.js"
12
+ } from "./atom.js"
12
13
  import type {
13
14
  AllFormula,
14
15
  AnyFormula,
@@ -17,13 +18,14 @@ import type {
17
18
  NotFormula,
18
19
  PredicateFormula,
19
20
  TrueFormula
20
- } from "./predicate-formula.js"
21
+ } from "./formula.js"
21
22
 
22
23
  export interface RuntimeContext {
23
24
  readonly nonNullKeys: ReadonlySet<string>
24
25
  readonly nullKeys: ReadonlySet<string>
25
26
  readonly eqLiterals: ReadonlyMap<string, string>
26
27
  readonly neqLiterals: ReadonlyMap<string, ReadonlySet<string>>
28
+ readonly literalSets: ReadonlyMap<string, ReadonlySet<string>>
27
29
  readonly sourceNames: ReadonlySet<string>
28
30
  readonly contradiction: boolean
29
31
  readonly unknown: boolean
@@ -34,6 +36,7 @@ type MutableContext = {
34
36
  nullKeys: Set<string>
35
37
  eqLiterals: Map<string, string>
36
38
  neqLiterals: Map<string, Set<string>>
39
+ literalSets: Map<string, Set<string>>
37
40
  sourceNames: Set<string>
38
41
  contradiction: boolean
39
42
  unknown: boolean
@@ -72,6 +75,7 @@ const emptyContext = (): MutableContext => ({
72
75
  nullKeys: new Set(),
73
76
  eqLiterals: new Map(),
74
77
  neqLiterals: new Map(),
78
+ literalSets: new Map(),
75
79
  sourceNames: new Set(),
76
80
  contradiction: false,
77
81
  unknown: false
@@ -84,6 +88,9 @@ const cloneContext = (context: MutableContext): MutableContext => ({
84
88
  neqLiterals: new Map(
85
89
  Array.from(context.neqLiterals.entries(), ([key, values]) => [key, new Set(values)])
86
90
  ),
91
+ literalSets: new Map(
92
+ Array.from(context.literalSets.entries(), ([key, values]) => [key, new Set(values)])
93
+ ),
87
94
  sourceNames: new Set(context.sourceNames),
88
95
  contradiction: context.contradiction,
89
96
  unknown: context.unknown
@@ -123,7 +130,12 @@ const addEqLiteral = (context: MutableContext, key: string, value: string): void
123
130
  if (neqValues?.has(value)) {
124
131
  context.contradiction = true
125
132
  }
133
+ const existingSet = context.literalSets.get(key)
134
+ if (existingSet !== undefined && !existingSet.has(value)) {
135
+ context.contradiction = true
136
+ }
126
137
  context.eqLiterals.set(key, value)
138
+ context.literalSets.set(key, new Set([value]))
127
139
  }
128
140
 
129
141
  const addNeqLiteral = (context: MutableContext, key: string, value: string): void => {
@@ -136,6 +148,24 @@ const addNeqLiteral = (context: MutableContext, key: string, value: string): voi
136
148
  context.neqLiterals.set(key, values)
137
149
  }
138
150
 
151
+ const addLiteralSet = (context: MutableContext, key: string, values: ReadonlySet<string>): void => {
152
+ addNonNull(context, key)
153
+ const existingEq = context.eqLiterals.get(key)
154
+ if (existingEq !== undefined && !values.has(existingEq)) {
155
+ context.contradiction = true
156
+ }
157
+ const existing = context.literalSets.get(key)
158
+ context.literalSets.set(
159
+ key,
160
+ existing === undefined
161
+ ? new Set(values)
162
+ : new Set(Array.from(existing).filter((value) => values.has(value)))
163
+ )
164
+ if (context.literalSets.get(key)?.size === 0) {
165
+ context.contradiction = true
166
+ }
167
+ }
168
+
139
169
  const applyEqColumn = (context: MutableContext, left: string, right: string): void => {
140
170
  const leftValue = context.eqLiterals.get(left)
141
171
  const rightValue = context.eqLiterals.get(right)
@@ -176,6 +206,9 @@ const applyAtom = (context: MutableContext, atom: PredicateAtom): void => {
176
206
  case "neq-literal":
177
207
  addNeqLiteral(context, atom.key, atom.value)
178
208
  return
209
+ case "literal-set":
210
+ addLiteralSet(context, atom.key, new Set(atom.values))
211
+ return
179
212
  case "eq-column":
180
213
  applyEqColumn(context, atom.left, atom.right)
181
214
  return
@@ -199,6 +232,9 @@ const applyNegativeAtom = (context: MutableContext, atom: PredicateAtom): void =
199
232
  case "neq-literal":
200
233
  addEqLiteral(context, atom.key, atom.value)
201
234
  return
235
+ case "literal-set":
236
+ addNonNull(context, atom.key)
237
+ return
202
238
  case "eq-column":
203
239
  addNonNull(context, atom.left)
204
240
  addNonNull(context, atom.right)
@@ -240,6 +276,21 @@ const intersectNeqLiterals = (
240
276
  return result
241
277
  }
242
278
 
279
+ const unionLiteralSets = (
280
+ left: ReadonlyMap<string, ReadonlySet<string>>,
281
+ right: ReadonlyMap<string, ReadonlySet<string>>
282
+ ): Map<string, Set<string>> => {
283
+ const result = new Map<string, Set<string>>()
284
+ for (const [key, leftValues] of left) {
285
+ const rightValues = right.get(key)
286
+ if (rightValues === undefined) {
287
+ continue
288
+ }
289
+ result.set(key, new Set([...leftValues, ...rightValues]))
290
+ }
291
+ return result
292
+ }
293
+
243
294
  const intersectContexts = (left: MutableContext, right: MutableContext): MutableContext => {
244
295
  if (left.contradiction) {
245
296
  return cloneContext(right)
@@ -252,6 +303,7 @@ const intersectContexts = (left: MutableContext, right: MutableContext): Mutable
252
303
  nullKeys: new Set(Array.from(left.nullKeys).filter((key) => right.nullKeys.has(key))),
253
304
  eqLiterals: intersectEqLiterals(left.eqLiterals, right.eqLiterals),
254
305
  neqLiterals: intersectNeqLiterals(left.neqLiterals, right.neqLiterals),
306
+ literalSets: unionLiteralSets(left.literalSets, right.literalSets),
255
307
  sourceNames: new Set(Array.from(left.sourceNames).filter((name) => right.sourceNames.has(name))),
256
308
  contradiction: false,
257
309
  unknown: left.unknown || right.unknown
@@ -337,6 +389,53 @@ const columnKeyOfExpression = (value: Expression.Any): string | undefined => {
337
389
  return ast.kind === "column" ? `${ast.tableName}.${ast.columnName}` : undefined
338
390
  }
339
391
 
392
+ const sameDbType = (left: Expression.DbType.Any, right: Expression.DbType.Any): boolean =>
393
+ left.dialect === right.dialect && left.kind === right.kind
394
+
395
+ const jsonPathPredicateKeyOfExpression = (value: Expression.Any): string | undefined => {
396
+ const ast = astOf(value)
397
+ switch (ast.kind) {
398
+ case "jsonGetText":
399
+ case "jsonPathText":
400
+ case "jsonAccessText":
401
+ case "jsonTraverseText": {
402
+ const jsonAst = ast as ExpressionAst.JsonAccessNode
403
+ const segments = jsonAst.segments
404
+ if (segments.length === 0 || segments.length > 8) {
405
+ return undefined
406
+ }
407
+ const path: Array<string> = []
408
+ for (const segment of segments) {
409
+ if (typeof segment !== "object" || segment === null || segment.kind !== "key") {
410
+ return undefined
411
+ }
412
+ path.push(segment.key)
413
+ }
414
+ if (path.length === 0) {
415
+ return undefined
416
+ }
417
+ const baseKey = columnKeyOfExpression(jsonAst.base)
418
+ return baseKey === undefined ? undefined : `${baseKey}#json:${path.join(".")}`
419
+ }
420
+ default:
421
+ return undefined
422
+ }
423
+ }
424
+
425
+ const predicateKeyOfExpression = (value: Expression.Any): string | undefined =>
426
+ columnKeyOfExpression(value) ?? castPredicateKeyOfExpression(value) ?? jsonPathPredicateKeyOfExpression(value)
427
+
428
+ const castPredicateKeyOfExpression = (value: Expression.Any): string | undefined => {
429
+ const ast = astOf(value)
430
+ if (ast.kind !== "cast") {
431
+ return undefined
432
+ }
433
+ const source = ast.value as Expression.Any
434
+ return sameDbType(source[Expression.TypeId].dbType, ast.target)
435
+ ? predicateKeyOfExpression(source)
436
+ : undefined
437
+ }
438
+
340
439
  const valueKeyOfLiteral = (value: unknown): string => {
341
440
  if (typeof value === "string") {
342
441
  return `string:${value}`
@@ -357,7 +456,7 @@ const valueKeyOfLiteral = (value: unknown): string => {
357
456
  }
358
457
 
359
458
  const nonNullFactsOfExpression = (value: Expression.Any): PredicateFormula | undefined => {
360
- const key = columnKeyOfExpression(value)
459
+ const key = predicateKeyOfExpression(value)
361
460
  return key === undefined ? undefined : atomFormula<NonNullAtom<string>>({ kind: "is-not-null", key })
362
461
  }
363
462
 
@@ -375,8 +474,8 @@ const combineFacts = (
375
474
  }
376
475
 
377
476
  const formulaOfEq = (left: Expression.Any, right: Expression.Any): PredicateFormula => {
378
- const leftKey = columnKeyOfExpression(left)
379
- const rightKey = columnKeyOfExpression(right)
477
+ const leftKey = predicateKeyOfExpression(left)
478
+ const rightKey = predicateKeyOfExpression(right)
380
479
  const leftAst = astOf(left)
381
480
  const rightAst = astOf(right)
382
481
  const leftLiteral = leftAst.kind === "literal" ? leftAst.value : undefined
@@ -428,8 +527,8 @@ const formulaOfEq = (left: Expression.Any, right: Expression.Any): PredicateForm
428
527
  }
429
528
 
430
529
  const formulaOfNeq = (left: Expression.Any, right: Expression.Any): PredicateFormula => {
431
- const leftKey = columnKeyOfExpression(left)
432
- const rightKey = columnKeyOfExpression(right)
530
+ const leftKey = predicateKeyOfExpression(left)
531
+ const rightKey = predicateKeyOfExpression(right)
433
532
  const leftAst = astOf(left)
434
533
  const rightAst = astOf(right)
435
534
  const leftLiteral = leftAst.kind === "literal" ? leftAst.value : undefined
@@ -477,8 +576,8 @@ const formulaOfNeq = (left: Expression.Any, right: Expression.Any): PredicateFor
477
576
  }
478
577
 
479
578
  const formulaOfIsNotDistinctFrom = (left: Expression.Any, right: Expression.Any): PredicateFormula => {
480
- const leftKey = columnKeyOfExpression(left)
481
- const rightKey = columnKeyOfExpression(right)
579
+ const leftKey = predicateKeyOfExpression(left)
580
+ const rightKey = predicateKeyOfExpression(right)
482
581
  const leftAst = astOf(left)
483
582
  const rightAst = astOf(right)
484
583
  const leftLiteral = leftAst.kind === "literal" ? leftAst.value : undefined
@@ -587,13 +686,13 @@ export const formulaOfExpression = (value: Expression.Any): PredicateFormula =>
587
686
  }
588
687
  return unknownTag("literal:non-boolean")
589
688
  case "isNull": {
590
- const key = columnKeyOfExpression(ast.value)
689
+ const key = predicateKeyOfExpression(ast.value)
591
690
  return key === undefined
592
691
  ? unknownTag("isNull:unsupported")
593
692
  : atomFormula<NullAtom<string>>({ kind: "is-null", key })
594
693
  }
595
694
  case "isNotNull": {
596
- const key = columnKeyOfExpression(ast.value)
695
+ const key = predicateKeyOfExpression(ast.value)
597
696
  return key === undefined
598
697
  ? unknownTag("isNotNull:unsupported")
599
698
  : atomFormula<NonNullAtom<string>>({ kind: "is-not-null", key })
@@ -614,15 +713,26 @@ export const formulaOfExpression = (value: Expression.Any): PredicateFormula =>
614
713
  return anyFormula(ast.values.map((value: Expression.Any) => formulaOfExpression(value)))
615
714
  case "in": {
616
715
  const [left, ...rest] = ast.values
617
- return left === undefined
618
- ? falseFormula()
716
+ if (left === undefined) {
717
+ return falseFormula()
718
+ }
719
+ const key = predicateKeyOfExpression(left)
720
+ const literalValues = rest.map((entry: Expression.Any) => {
721
+ const entryAst = astOf(entry)
722
+ return entryAst.kind === "literal" && entryAst.value !== null ? valueKeyOfLiteral(entryAst.value) : undefined
723
+ })
724
+ return key !== undefined && literalValues.every((entry): entry is string => entry !== undefined)
725
+ ? atomFormula<LiteralSetAtom<string, string>>({ kind: "literal-set", key, values: literalValues })
619
726
  : anyFormula(rest.map((value: Expression.Any) => formulaOfEq(left, value)))
620
727
  }
621
728
  case "notIn": {
622
729
  const [left, ...rest] = ast.values
623
730
  return left === undefined
624
731
  ? trueFormula()
625
- : allFormula(rest.map((value: Expression.Any) => formulaOfNeq(left, value)))
732
+ : combineFacts(
733
+ nonNullFactsOfExpression(left),
734
+ allFormula(rest.map((value: Expression.Any) => formulaOfNeq(left, value)))
735
+ )
626
736
  }
627
737
  case "between":
628
738
  return combineFacts(
@@ -0,0 +1,13 @@
1
+ /** Symbol used to attach explicit projection-alias metadata to an expression. */
2
+ export declare const TypeId: unique symbol;
3
+ export type TypeId = typeof TypeId;
4
+ /**
5
+ * Projection-alias metadata carried by a runtime expression wrapper.
6
+ *
7
+ * This is intentionally orthogonal to the scalar expression AST. Aliasing does
8
+ * not change SQL semantics; it only changes how a selected expression is named
9
+ * in the rendered `SELECT ... AS ...` list.
10
+ */
11
+ export interface State<Alias extends string = string> {
12
+ readonly alias: Alias;
13
+ }
@@ -0,0 +1,31 @@
1
+ import * as Expression from "./scalar.js";
2
+ /**
3
+ * Flat projection metadata shared by renderers and executors.
4
+ *
5
+ * `path` identifies where a value should be decoded in the nested result row,
6
+ * while `alias` is the flat SQL column alias used by the rendered query.
7
+ */
8
+ export interface Projection {
9
+ readonly path: readonly string[];
10
+ readonly alias: string;
11
+ }
12
+ /** Selection leaf paired with its resolved projection alias. */
13
+ export interface FlattenedProjection {
14
+ readonly path: readonly string[];
15
+ readonly expression: Expression.Any;
16
+ readonly alias: string;
17
+ }
18
+ /**
19
+ * Flattens a nested selection object into leaf expressions with decode paths
20
+ * and resolved SQL aliases.
21
+ */
22
+ export declare const flattenSelection: (selection: Record<string, unknown>, path?: readonly string[]) => readonly FlattenedProjection[];
23
+ /**
24
+ * Validates the flattened projection set shared by renderer and executor code.
25
+ *
26
+ * This rejects:
27
+ * - duplicate SQL aliases
28
+ * - duplicate decode paths
29
+ * - conflicting prefix paths like `profile` and `profile.id`
30
+ */
31
+ export declare const validateProjections: (projections: readonly Projection[]) => void;
@@ -1,4 +1,4 @@
1
- import * as Expression from "./expression.js"
1
+ import * as Expression from "./scalar.js"
2
2
  import * as ProjectionAlias from "./projection-alias.js"
3
3
 
4
4
  /**