effect-qb 0.15.0 → 0.17.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 (88) hide show
  1. package/dist/mysql.js +1957 -595
  2. package/dist/postgres/metadata.js +2507 -182
  3. package/dist/postgres.js +9587 -8201
  4. package/dist/sqlite.js +8360 -0
  5. package/package.json +7 -2
  6. package/src/internal/column-state.ts +7 -0
  7. package/src/internal/column.ts +22 -0
  8. package/src/internal/derived-table.ts +29 -3
  9. package/src/internal/dialect.ts +14 -1
  10. package/src/internal/dsl-mutation-runtime.ts +173 -4
  11. package/src/internal/dsl-plan-runtime.ts +165 -20
  12. package/src/internal/dsl-query-runtime.ts +60 -6
  13. package/src/internal/dsl-transaction-ddl-runtime.ts +72 -2
  14. package/src/internal/executor.ts +62 -13
  15. package/src/internal/expression-ast.ts +3 -2
  16. package/src/internal/grouping-key.ts +141 -1
  17. package/src/internal/implication-runtime.ts +2 -1
  18. package/src/internal/json/types.ts +155 -40
  19. package/src/internal/predicate/analysis.ts +103 -1
  20. package/src/internal/predicate/atom.ts +7 -0
  21. package/src/internal/predicate/context.ts +170 -17
  22. package/src/internal/predicate/key.ts +64 -2
  23. package/src/internal/predicate/normalize.ts +115 -34
  24. package/src/internal/predicate/runtime.ts +144 -13
  25. package/src/internal/query.ts +563 -103
  26. package/src/internal/renderer.ts +39 -2
  27. package/src/internal/runtime/driver-value-mapping.ts +244 -0
  28. package/src/internal/runtime/normalize.ts +62 -38
  29. package/src/internal/runtime/schema.ts +5 -3
  30. package/src/internal/runtime/value.ts +153 -30
  31. package/src/internal/scalar.ts +11 -0
  32. package/src/internal/table-options.ts +108 -1
  33. package/src/internal/table.ts +87 -29
  34. package/src/mysql/column.ts +19 -2
  35. package/src/mysql/datatypes/index.ts +21 -0
  36. package/src/mysql/errors/catalog.ts +5 -5
  37. package/src/mysql/errors/normalize.ts +2 -2
  38. package/src/mysql/executor.ts +20 -5
  39. package/src/mysql/internal/dialect.ts +12 -6
  40. package/src/mysql/internal/dsl.ts +995 -263
  41. package/src/mysql/internal/renderer.ts +13 -3
  42. package/src/mysql/internal/sql-expression-renderer.ts +530 -128
  43. package/src/mysql/query.ts +9 -2
  44. package/src/mysql/renderer.ts +7 -2
  45. package/src/mysql/table.ts +38 -12
  46. package/src/postgres/cast.ts +22 -7
  47. package/src/postgres/column.ts +5 -2
  48. package/src/postgres/errors/normalize.ts +2 -2
  49. package/src/postgres/executor.ts +68 -10
  50. package/src/postgres/function/core.ts +19 -1
  51. package/src/postgres/internal/dialect.ts +12 -6
  52. package/src/postgres/internal/dsl.ts +958 -288
  53. package/src/postgres/internal/renderer.ts +13 -3
  54. package/src/postgres/internal/schema-ddl.ts +2 -1
  55. package/src/postgres/internal/schema-model.ts +6 -3
  56. package/src/postgres/internal/sql-expression-renderer.ts +477 -96
  57. package/src/postgres/json.ts +57 -17
  58. package/src/postgres/query.ts +9 -2
  59. package/src/postgres/renderer.ts +7 -2
  60. package/src/postgres/schema-management.ts +91 -4
  61. package/src/postgres/schema.ts +1 -1
  62. package/src/postgres/table.ts +189 -53
  63. package/src/postgres/type.ts +4 -0
  64. package/src/sqlite/column.ts +128 -0
  65. package/src/sqlite/datatypes/index.ts +79 -0
  66. package/src/sqlite/datatypes/spec.ts +98 -0
  67. package/src/sqlite/errors/catalog.ts +103 -0
  68. package/src/sqlite/errors/fields.ts +19 -0
  69. package/src/sqlite/errors/index.ts +19 -0
  70. package/src/sqlite/errors/normalize.ts +229 -0
  71. package/src/sqlite/errors/requirements.ts +71 -0
  72. package/src/sqlite/errors/types.ts +29 -0
  73. package/src/sqlite/executor.ts +227 -0
  74. package/src/sqlite/function/aggregate.ts +2 -0
  75. package/src/sqlite/function/core.ts +2 -0
  76. package/src/sqlite/function/index.ts +19 -0
  77. package/src/sqlite/function/string.ts +2 -0
  78. package/src/sqlite/function/temporal.ts +100 -0
  79. package/src/sqlite/function/window.ts +2 -0
  80. package/src/sqlite/internal/dialect.ts +37 -0
  81. package/src/sqlite/internal/dsl.ts +6926 -0
  82. package/src/sqlite/internal/renderer.ts +47 -0
  83. package/src/sqlite/internal/sql-expression-renderer.ts +1821 -0
  84. package/src/sqlite/json.ts +2 -0
  85. package/src/sqlite/query.ts +196 -0
  86. package/src/sqlite/renderer.ts +24 -0
  87. package/src/sqlite/table.ts +183 -0
  88. package/src/sqlite.ts +22 -0
@@ -1,5 +1,23 @@
1
1
  import * as Expression from "./scalar.js"
2
2
  import * as ExpressionAst from "./expression-ast.js"
3
+ import * as JsonPath from "./json/path.js"
4
+ import { columnPredicateKey } from "./predicate/runtime.js"
5
+
6
+ const subqueryPlanIds = new WeakMap<object, string>()
7
+ let nextSubqueryPlanId = 0
8
+
9
+ const subqueryPlanGroupingKey = (plan: unknown): string => {
10
+ if (plan === null || typeof plan !== "object") {
11
+ return "unknown"
12
+ }
13
+ const existing = subqueryPlanIds.get(plan)
14
+ if (existing !== undefined) {
15
+ return existing
16
+ }
17
+ const next = `${nextSubqueryPlanId++}`
18
+ subqueryPlanIds.set(plan, next)
19
+ return next
20
+ }
3
21
 
4
22
  const literalGroupingKey = (value: unknown): string => {
5
23
  if (value instanceof Date) {
@@ -20,17 +38,84 @@ const literalGroupingKey = (value: unknown): string => {
20
38
  }
21
39
  }
22
40
 
41
+ const isExpression = (value: unknown): value is Expression.Any =>
42
+ value !== null && typeof value === "object" && Expression.TypeId in value
43
+
44
+ const expressionGroupingKey = (value: unknown): string =>
45
+ isExpression(value) ? groupingKeyOfExpression(value) : "missing"
46
+
47
+ const escapeGroupingText = (value: string): string =>
48
+ value
49
+ .replace(/\\/g, "\\\\")
50
+ .replace(/,/g, "\\,")
51
+ .replace(/\|/g, "\\|")
52
+ .replace(/=/g, "\\=")
53
+ .replace(/>/g, "\\>")
54
+
55
+ const jsonSegmentGroupingKey = (segment: unknown): string => {
56
+ if (segment !== null && typeof segment === "object" && "kind" in segment) {
57
+ switch ((segment as { readonly kind: string }).kind) {
58
+ case "key":
59
+ return `key:${escapeGroupingText((segment as JsonPath.KeySegment).key)}`
60
+ case "index":
61
+ return `index:${(segment as JsonPath.IndexSegment).index}`
62
+ case "wildcard":
63
+ return "wildcard"
64
+ case "slice": {
65
+ const slice = segment as JsonPath.SliceSegment
66
+ return `slice:${slice.start ?? ""}:${slice.end ?? ""}`
67
+ }
68
+ case "descend":
69
+ return "descend"
70
+ }
71
+ }
72
+ if (typeof segment === "string") {
73
+ return `key:${escapeGroupingText(segment)}`
74
+ }
75
+ if (typeof segment === "number") {
76
+ return `index:${segment}`
77
+ }
78
+ return "unknown"
79
+ }
80
+
81
+ const jsonPathGroupingKey = (segments: readonly unknown[] | undefined): string =>
82
+ (segments ?? []).map(jsonSegmentGroupingKey).join(",")
83
+
84
+ const isJsonPath = (value: unknown): value is JsonPath.Path =>
85
+ value !== null && typeof value === "object" && JsonPath.TypeId in value
86
+
87
+ const jsonOpaquePathGroupingKey = (value: unknown): string => {
88
+ if (isJsonPath(value)) {
89
+ return `jsonpath:${jsonPathGroupingKey(value.segments)}`
90
+ }
91
+ if (typeof value === "string") {
92
+ return `jsonpath:${escapeGroupingText(value)}`
93
+ }
94
+ if (isExpression(value)) {
95
+ return `jsonpath:${groupingKeyOfExpression(value)}`
96
+ }
97
+ return "jsonpath:unknown"
98
+ }
99
+
100
+ const jsonEntryGroupingKey = (
101
+ entry: { readonly key: string; readonly value: Expression.Any }
102
+ ): string => `${escapeGroupingText(entry.key)}=>${groupingKeyOfExpression(entry.value)}`
103
+
23
104
  export const groupingKeyOfExpression = (expression: Expression.Any): string => {
24
105
  const ast = (expression as Expression.Any & {
25
106
  readonly [ExpressionAst.TypeId]: ExpressionAst.Any
26
107
  })[ExpressionAst.TypeId]
27
108
  switch (ast.kind) {
28
109
  case "column":
29
- return `column:${ast.tableName}.${ast.columnName}`
110
+ return `column:${columnPredicateKey(ast.tableName, ast.columnName)}`
30
111
  case "literal":
31
112
  return `literal:${literalGroupingKey(ast.value)}`
32
113
  case "cast":
33
114
  return `cast(${groupingKeyOfExpression(ast.value)} as ${ast.target.dialect}:${ast.target.kind})`
115
+ case "collate":
116
+ return `collate(${groupingKeyOfExpression(ast.value)},${ast.collation.map(escapeGroupingText).join(",")})`
117
+ case "function":
118
+ return `function(${escapeGroupingText(ast.name)},${ast.args.map(groupingKeyOfExpression).join(",")})`
34
119
  case "isNull":
35
120
  case "isNotNull":
36
121
  case "not":
@@ -48,8 +133,15 @@ export const groupingKeyOfExpression = (expression: Expression.Any): string => {
48
133
  case "gte":
49
134
  case "like":
50
135
  case "ilike":
136
+ case "regexMatch":
137
+ case "regexIMatch":
138
+ case "regexNotMatch":
139
+ case "regexNotIMatch":
51
140
  case "isDistinctFrom":
52
141
  case "isNotDistinctFrom":
142
+ case "contains":
143
+ case "containedBy":
144
+ case "overlaps":
53
145
  return `${ast.kind}(${groupingKeyOfExpression(ast.left)},${groupingKeyOfExpression(ast.right)})`
54
146
  case "and":
55
147
  case "or":
@@ -62,6 +154,54 @@ export const groupingKeyOfExpression = (expression: Expression.Any): string => {
62
154
  case "case":
63
155
  return `case(${ast.branches.map((branch: ExpressionAst.CaseBranchNode) =>
64
156
  `when:${groupingKeyOfExpression(branch.when)}=>${groupingKeyOfExpression(branch.then)}`).join("|")};else:${groupingKeyOfExpression(ast.else)})`
157
+ case "exists":
158
+ return `exists(${subqueryPlanGroupingKey(ast.plan)})`
159
+ case "scalarSubquery":
160
+ return `scalarSubquery(${subqueryPlanGroupingKey(ast.plan)})`
161
+ case "inSubquery":
162
+ return `inSubquery(${groupingKeyOfExpression(ast.left)},${subqueryPlanGroupingKey(ast.plan)})`
163
+ case "comparisonAny":
164
+ case "comparisonAll":
165
+ return `${ast.kind}(${ast.operator},${groupingKeyOfExpression(ast.left)},${subqueryPlanGroupingKey(ast.plan)})`
166
+ case "jsonGet":
167
+ case "jsonPath":
168
+ case "jsonAccess":
169
+ case "jsonTraverse":
170
+ case "jsonGetText":
171
+ case "jsonPathText":
172
+ case "jsonAccessText":
173
+ case "jsonTraverseText":
174
+ return `json(${ast.kind},${expressionGroupingKey(ast.base)},${jsonPathGroupingKey(ast.segments)})`
175
+ case "jsonHasKey":
176
+ case "jsonKeyExists":
177
+ case "jsonHasAnyKeys":
178
+ case "jsonHasAllKeys":
179
+ return `json(${ast.kind},${expressionGroupingKey(ast.base)},${(ast.keys ?? []).map(escapeGroupingText).join(",")})`
180
+ case "jsonConcat":
181
+ case "jsonMerge":
182
+ return `json(${ast.kind},${expressionGroupingKey(ast.left)},${expressionGroupingKey(ast.right)},)`
183
+ case "jsonDelete":
184
+ case "jsonDeletePath":
185
+ case "jsonRemove":
186
+ return `json(${ast.kind},${expressionGroupingKey(ast.base)},${expressionGroupingKey(undefined)},${jsonPathGroupingKey(ast.segments)})`
187
+ case "jsonSet":
188
+ return `json(${ast.kind},${expressionGroupingKey(ast.base)},${expressionGroupingKey(ast.newValue)},${jsonPathGroupingKey(ast.segments)})`
189
+ case "jsonInsert":
190
+ return `json(${ast.kind},${expressionGroupingKey(ast.base)},${expressionGroupingKey(ast.insert)},${jsonPathGroupingKey(ast.segments)})`
191
+ case "jsonPathExists":
192
+ case "jsonPathMatch":
193
+ return `json(${ast.kind},${expressionGroupingKey(ast.base)},${jsonOpaquePathGroupingKey(ast.query)})`
194
+ case "jsonBuildObject":
195
+ return `json(${ast.kind},${(ast.entries ?? []).map(jsonEntryGroupingKey).join("|")})`
196
+ case "jsonBuildArray":
197
+ return `json(${ast.kind},${(ast.values ?? []).map(groupingKeyOfExpression).join(",")})`
198
+ case "jsonToJson":
199
+ case "jsonToJsonb":
200
+ case "jsonTypeOf":
201
+ case "jsonLength":
202
+ case "jsonKeys":
203
+ case "jsonStripNulls":
204
+ return `json(${ast.kind},${expressionGroupingKey(ast.value)})`
65
205
  default:
66
206
  throw new Error("Unsupported expression for grouping key generation")
67
207
  }
@@ -5,6 +5,7 @@ import * as Table from "./table.js"
5
5
  import type { PredicateFormula } from "./predicate/formula.js"
6
6
  import {
7
7
  assumeFormulaTrue,
8
+ columnPredicateKey,
8
9
  contradictsFormula,
9
10
  guaranteedNonNullKeys,
10
11
  guaranteedNullKeys,
@@ -43,7 +44,7 @@ const collectPresenceWitnesses = (
43
44
  const expression = selection as unknown as AstBackedExpression
44
45
  const ast = expression[ExpressionAst.TypeId]
45
46
  if (ast.kind === "column" && expression[Expression.TypeId].nullability === "never") {
46
- output.add(`${ast.tableName}.${ast.columnName}`)
47
+ output.add(columnPredicateKey(ast.tableName, ast.columnName))
47
48
  }
48
49
  return
49
50
  }
@@ -63,6 +63,23 @@ type TupleIndex<
63
63
  : TupleIndex<Tail, Index, [...Count, unknown]>
64
64
  : never
65
65
 
66
+ type TupleIndexFromEnd<
67
+ Values extends readonly unknown[],
68
+ Distance extends number,
69
+ Count extends readonly unknown[] = [unknown]
70
+ > = Values extends readonly [...infer Rest, infer Last]
71
+ ? Count["length"] extends Distance
72
+ ? Last
73
+ : TupleIndexFromEnd<Rest, Distance, [...Count, unknown]>
74
+ : never
75
+
76
+ type TupleIndexAt<
77
+ Values extends readonly unknown[],
78
+ Index extends number
79
+ > = `${Index}` extends `-${infer Distance extends number}`
80
+ ? TupleIndexFromEnd<Values, Distance>
81
+ : TupleIndex<Values, Index>
82
+
66
83
  type DropTupleIndex<
67
84
  Values extends readonly unknown[],
68
85
  Index extends number,
@@ -73,6 +90,23 @@ type DropTupleIndex<
73
90
  : readonly [Head, ...DropTupleIndex<Tail, Index, [...Count, unknown]>]
74
91
  : readonly []
75
92
 
93
+ type DropTupleIndexFromEnd<
94
+ Values extends readonly unknown[],
95
+ Distance extends number,
96
+ Count extends readonly unknown[] = [unknown]
97
+ > = Values extends readonly [...infer Rest, infer Last]
98
+ ? Count["length"] extends Distance
99
+ ? readonly [...Rest]
100
+ : readonly [...DropTupleIndexFromEnd<Rest, Distance, [...Count, unknown]>, Last]
101
+ : readonly []
102
+
103
+ type DropTupleIndexAt<
104
+ Values extends readonly unknown[],
105
+ Index extends number
106
+ > = `${Index}` extends `-${infer Distance extends number}`
107
+ ? DropTupleIndexFromEnd<Values, Distance>
108
+ : DropTupleIndex<Values, Index>
109
+
76
110
  type SetTupleIndex<
77
111
  Values extends readonly unknown[],
78
112
  Index extends number,
@@ -84,6 +118,25 @@ type SetTupleIndex<
84
118
  : readonly [Head, ...SetTupleIndex<Tail, Index, Next, [...Count, unknown]>]
85
119
  : readonly NormalizeJsonLiteral<Next>[]
86
120
 
121
+ type SetTupleIndexFromEnd<
122
+ Values extends readonly unknown[],
123
+ Distance extends number,
124
+ Next,
125
+ Count extends readonly unknown[] = [unknown]
126
+ > = Values extends readonly [...infer Rest, infer Last]
127
+ ? Count["length"] extends Distance
128
+ ? readonly [...Rest, NormalizeJsonLiteral<Next>]
129
+ : readonly [...SetTupleIndexFromEnd<Rest, Distance, Next, [...Count, unknown]>, Last]
130
+ : readonly NormalizeJsonLiteral<Next>[]
131
+
132
+ type SetTupleIndexAt<
133
+ Values extends readonly unknown[],
134
+ Index extends number,
135
+ Next
136
+ > = `${Index}` extends `-${infer Distance extends number}`
137
+ ? SetTupleIndexFromEnd<Values, Distance, Next>
138
+ : SetTupleIndex<Values, Index, Next>
139
+
87
140
  type InsertTupleIndex<
88
141
  Values extends readonly unknown[],
89
142
  Index extends number,
@@ -98,6 +151,29 @@ type InsertTupleIndex<
98
151
  : readonly [Head, ...InsertTupleIndex<Tail, Index, Next, After, [...Count, unknown]>]
99
152
  : readonly NormalizeJsonLiteral<Next>[]
100
153
 
154
+ type InsertTupleIndexFromEnd<
155
+ Values extends readonly unknown[],
156
+ Distance extends number,
157
+ Next,
158
+ After extends boolean,
159
+ Count extends readonly unknown[] = [unknown]
160
+ > = Values extends readonly [...infer Rest, infer Last]
161
+ ? Count["length"] extends Distance
162
+ ? After extends true
163
+ ? readonly [...Rest, Last, NormalizeJsonLiteral<Next>]
164
+ : readonly [...Rest, NormalizeJsonLiteral<Next>, Last]
165
+ : readonly [...InsertTupleIndexFromEnd<Rest, Distance, Next, After, [...Count, unknown]>, Last]
166
+ : readonly NormalizeJsonLiteral<Next>[]
167
+
168
+ type InsertTupleIndexAt<
169
+ Values extends readonly unknown[],
170
+ Index extends number,
171
+ Next,
172
+ After extends boolean
173
+ > = `${Index}` extends `-${infer Distance extends number}`
174
+ ? InsertTupleIndexFromEnd<Values, Distance, Next, After>
175
+ : InsertTupleIndex<Values, Index, Next, After>
176
+
101
177
  type IndexStep<
102
178
  Root,
103
179
  Index extends number,
@@ -105,7 +181,7 @@ type IndexStep<
105
181
  > = Root extends readonly unknown[]
106
182
  ? number extends Root["length"]
107
183
  ? NormalizeJsonLiteral<Root[number]> | null
108
- : NormalizeJsonLiteral<TupleIndex<Root, Index>> | (TupleIndex<Root, Index> extends never ? null : never)
184
+ : NormalizeJsonLiteral<TupleIndexAt<Root, Index>> | (TupleIndexAt<Root, Index> extends never ? null : never)
109
185
  : JsonPathUsageError<Operation, Root, JsonPath.IndexSegment<Index>, "index segments require an array-like json value">
110
186
 
111
187
  type NonExactStep<
@@ -146,9 +222,9 @@ type StepSet<
146
222
  ? Root extends readonly unknown[]
147
223
  ? number extends Root["length"]
148
224
  ? readonly (NormalizeJsonLiteral<Root[number]> | NormalizeJsonLiteral<Next>)[]
149
- : SetTupleIndex<Root, Index, Next>
225
+ : SetTupleIndexAt<Root, Index, Next>
150
226
  : JsonPathUsageError<Operation, Root, Segment, "index segments require an array-like json value">
151
- : NormalizeJsonLiteral<Root>
227
+ : JsonPathUsageError<Operation, Root, Segment, "mutation paths require exact key/index segments">
152
228
 
153
229
  type StepDelete<
154
230
  Root,
@@ -164,9 +240,9 @@ type StepDelete<
164
240
  ? Root extends readonly unknown[]
165
241
  ? number extends Root["length"]
166
242
  ? Root
167
- : DropTupleIndex<Root, Index>
243
+ : DropTupleIndexAt<Root, Index>
168
244
  : JsonPathUsageError<Operation, Root, Segment, "index segments require an array-like json value">
169
- : NormalizeJsonLiteral<Root>
245
+ : JsonPathUsageError<Operation, Root, Segment, "mutation paths require exact key/index segments">
170
246
 
171
247
  type StepInsert<
172
248
  Root,
@@ -178,7 +254,7 @@ type StepInsert<
178
254
  ? Root extends readonly unknown[]
179
255
  ? number extends Root["length"]
180
256
  ? readonly (NormalizeJsonLiteral<Root[number]> | NormalizeJsonLiteral<Next>)[]
181
- : InsertTupleIndex<Root, Index, Next, After>
257
+ : InsertTupleIndexAt<Root, Index, Next, After>
182
258
  : JsonPathUsageError<Operation, Root, Segment, "index segments require an array-like json value">
183
259
  : Segment extends JsonPath.KeySegment<infer Key extends string>
184
260
  ? Root extends readonly unknown[]
@@ -190,7 +266,7 @@ type StepInsert<
190
266
  readonly [K in Key]: NormalizeJsonLiteral<Next>
191
267
  }
192
268
  : JsonPathUsageError<Operation, Root, Segment, "key segments require an object-like json value">
193
- : NormalizeJsonLiteral<Root>
269
+ : JsonPathUsageError<Operation, Root, Segment, "mutation paths require exact key/index segments">
194
270
 
195
271
  type RecurseValue<
196
272
  Current,
@@ -219,12 +295,16 @@ type RecurseSet<
219
295
  : StepValue<Current, Head, Operation> extends infer Child
220
296
  ? Child extends JsonPathUsageError<any, any, any, any>
221
297
  ? Child
222
- : StepSet<
223
- Current,
224
- Head,
225
- RecurseSet<StripNull<Child>, Tail, Next, Operation>,
226
- Operation
227
- >
298
+ : RecurseSet<StripNull<Child>, Tail, Next, Operation> extends infer UpdatedChild
299
+ ? UpdatedChild extends JsonPathUsageError<any, any, any, any>
300
+ ? UpdatedChild
301
+ : StepSet<
302
+ Current,
303
+ Head,
304
+ UpdatedChild,
305
+ Operation
306
+ >
307
+ : never
228
308
  : never
229
309
  : NormalizeJsonLiteral<Next>
230
310
 
@@ -238,12 +318,16 @@ type RecurseDelete<
238
318
  : StepValue<Current, Head, Operation> extends infer Child
239
319
  ? Child extends JsonPathUsageError<any, any, any, any>
240
320
  ? Child
241
- : StepSet<
242
- Current,
243
- Head,
244
- RecurseDelete<StripNull<Child>, Tail, Operation>,
245
- Operation
246
- >
321
+ : RecurseDelete<StripNull<Child>, Tail, Operation> extends infer UpdatedChild
322
+ ? UpdatedChild extends JsonPathUsageError<any, any, any, any>
323
+ ? UpdatedChild
324
+ : StepSet<
325
+ Current,
326
+ Head,
327
+ UpdatedChild,
328
+ Operation
329
+ >
330
+ : never
247
331
  : never
248
332
  : NormalizeJsonLiteral<Current>
249
333
 
@@ -259,12 +343,16 @@ type RecurseInsert<
259
343
  : StepValue<Current, Head, Operation> extends infer Child
260
344
  ? Child extends JsonPathUsageError<any, any, any, any>
261
345
  ? Child
262
- : StepSet<
263
- Current,
264
- Head,
265
- RecurseInsert<StripNull<Child>, Tail, Next, After, Operation>,
266
- Operation
267
- >
346
+ : RecurseInsert<StripNull<Child>, Tail, Next, After, Operation> extends infer UpdatedChild
347
+ ? UpdatedChild extends JsonPathUsageError<any, any, any, any>
348
+ ? UpdatedChild
349
+ : StepSet<
350
+ Current,
351
+ Head,
352
+ UpdatedChild,
353
+ Operation
354
+ >
355
+ : never
268
356
  : never
269
357
  : NormalizeJsonLiteral<Current>
270
358
 
@@ -364,23 +452,50 @@ export type JsonBuildArray<
364
452
 
365
453
  export type JsonTextResult<Value> = Value extends JsonPrimitive ? `${Value}` : string
366
454
 
367
- export type JsonTypeName<Value> =
368
- NormalizeJsonLiteral<Value> extends null ? "null"
369
- : NormalizeJsonLiteral<Value> extends string ? "string"
370
- : NormalizeJsonLiteral<Value> extends number ? "number"
371
- : NormalizeJsonLiteral<Value> extends boolean ? "boolean"
372
- : NormalizeJsonLiteral<Value> extends readonly unknown[] ? "array"
373
- : NormalizeJsonLiteral<Value> extends object ? "object"
455
+ type JsonTypeNameOfNormalized<Value> =
456
+ Value extends null ? "null"
457
+ : Value extends string ? "string"
458
+ : Value extends number ? "number"
459
+ : Value extends boolean ? "boolean"
460
+ : Value extends readonly unknown[] ? "array"
461
+ : Value extends object ? "object"
374
462
  : "unknown"
375
463
 
376
- export type JsonLengthResult<Value> =
377
- NormalizeJsonLiteral<Value> extends readonly unknown[] ? number :
378
- NormalizeJsonLiteral<Value> extends object ? number :
464
+ export type JsonTypeName<Value> =
465
+ [NormalizeJsonLiteral<Value>] extends [never]
466
+ ? "unknown"
467
+ : NormalizeJsonLiteral<Value> extends infer Normalized
468
+ ? Normalized extends unknown
469
+ ? JsonTypeNameOfNormalized<Normalized>
470
+ : never
471
+ : never
472
+
473
+ type JsonLengthResultOfNormalized<Value> =
474
+ Value extends readonly unknown[] ? number :
475
+ Value extends object ? number :
379
476
  null
380
477
 
478
+ export type JsonLengthResult<Value> =
479
+ [NormalizeJsonLiteral<Value>] extends [never]
480
+ ? null
481
+ : NormalizeJsonLiteral<Value> extends infer Normalized
482
+ ? Normalized extends unknown
483
+ ? JsonLengthResultOfNormalized<Normalized>
484
+ : never
485
+ : never
486
+
487
+ type JsonKeysResultOfNormalized<Value> =
488
+ Value extends readonly unknown[]
489
+ ? null
490
+ : Value extends object
491
+ ? readonly Extract<keyof Value, string>[]
492
+ : null
493
+
381
494
  export type JsonKeysResult<Value> =
382
- NormalizeJsonLiteral<Value> extends object
383
- ? NormalizeJsonLiteral<Value> extends readonly unknown[]
384
- ? readonly []
385
- : readonly Extract<keyof NormalizeJsonLiteral<Value>, string>[]
386
- : null
495
+ [NormalizeJsonLiteral<Value>] extends [never]
496
+ ? null
497
+ : NormalizeJsonLiteral<Value> extends infer Normalized
498
+ ? Normalized extends unknown
499
+ ? JsonKeysResultOfNormalized<Normalized>
500
+ : never
501
+ : never
@@ -1,9 +1,74 @@
1
- import type { AnalyzeFormula } from "./context.js"
1
+ import type { AnalyzeFormula, AssumeFactsFalse, AssumeFactsTrue, PredicateContext } from "./context.js"
2
2
  import type { FormulaOfPredicate } from "./normalize.js"
3
3
  import type { And, Not, PredicateFormula, TrueFormula } from "./formula.js"
4
4
 
5
5
  type ContextOf<Formula extends PredicateFormula> = AnalyzeFormula<Formula>
6
6
 
7
+ export type EmptyFacts = AnalyzeFormula<TrueFormula>
8
+
9
+ export type FactsOfFormula<
10
+ Formula extends PredicateFormula
11
+ > = AnalyzeFormula<Formula>
12
+
13
+ export interface PredicateState<
14
+ Formula extends PredicateFormula = PredicateFormula,
15
+ Facts extends PredicateContext = PredicateContext
16
+ > {
17
+ readonly formula: Formula
18
+ readonly facts: Facts
19
+ }
20
+
21
+ export type EmptyPredicateState = PredicateState<TrueFormula, EmptyFacts>
22
+
23
+ export type PredicateStateFormula<
24
+ State extends PredicateState
25
+ > = State["formula"]
26
+
27
+ export type PredicateStateFacts<
28
+ State extends PredicateState
29
+ > = State["facts"]
30
+
31
+ export type GuaranteedNonNullKeysInFacts<
32
+ Facts extends PredicateContext
33
+ > = Facts["nonNullKeys"]
34
+
35
+ export type GuaranteedNullKeysInFacts<
36
+ Facts extends PredicateContext
37
+ > = Facts["nullKeys"]
38
+
39
+ export type GuaranteedSourceNamesInFacts<
40
+ Facts extends PredicateContext
41
+ > = Facts["sourceNames"]
42
+
43
+ export type GuaranteedLiteralSetInFacts<
44
+ Facts extends PredicateContext,
45
+ Key extends string
46
+ > = [Facts["literalSets"]] extends [{ readonly [K in Key]: infer Values }]
47
+ ? Values
48
+ : never
49
+
50
+ export type GuaranteedEqLiteralInFacts<
51
+ Facts extends PredicateContext,
52
+ Key extends string
53
+ > = [Facts["eqLiterals"]] extends [{ readonly [K in Key]: infer Values }]
54
+ ? Values
55
+ : never
56
+
57
+ export type GuaranteedNeqLiteralInFacts<
58
+ Facts extends PredicateContext,
59
+ Key extends string
60
+ > = [Facts["neqLiterals"]] extends [{ readonly [K in Key]: infer Values }]
61
+ ? Values
62
+ : never
63
+
64
+ export type GuaranteedJsonLiteralSetInFacts<
65
+ Facts extends PredicateContext,
66
+ ColumnKey extends string,
67
+ Path extends string
68
+ > = [Facts["jsonLiteralSets"]] extends [{ readonly [C in ColumnKey]: { readonly [P in Path]: infer Values } }]
69
+ ? Values
70
+ : never
71
+
7
72
  export type GuaranteedNonNullKeys<
8
73
  Assumptions extends PredicateFormula
9
74
  > = ContextOf<Assumptions>["nonNullKeys"]
@@ -23,6 +88,17 @@ export type GuaranteedEqLiteral<
23
88
  ? ContextOf<Assumptions>["eqLiterals"][Key]
24
89
  : never
25
90
 
91
+ export type GuaranteedLiteralSets<
92
+ Assumptions extends PredicateFormula
93
+ > = ContextOf<Assumptions>["literalSets"]
94
+
95
+ export type GuaranteedLiteralSet<
96
+ Assumptions extends PredicateFormula,
97
+ Key extends string
98
+ > = Key extends keyof ContextOf<Assumptions>["literalSets"]
99
+ ? ContextOf<Assumptions>["literalSets"][Key]
100
+ : never
101
+
26
102
  type IsContradiction<Formula extends PredicateFormula> =
27
103
  ContextOf<Formula>["contradiction"] extends true ? true : false
28
104
 
@@ -70,6 +146,32 @@ export type AssumeFalse<
70
146
  Predicate
71
147
  > = AssumeFormulaFalse<Assumptions, FormulaOfPredicate<Predicate>>
72
148
 
149
+ export type AssumePredicateStateFormulaTrue<
150
+ State extends PredicateState,
151
+ Formula extends PredicateFormula
152
+ > = PredicateState<
153
+ AssumeFormulaTrue<PredicateStateFormula<State>, Formula>,
154
+ AssumeFactsTrue<PredicateStateFacts<State>, Formula>
155
+ >
156
+
157
+ export type AssumePredicateStateFormulaFalse<
158
+ State extends PredicateState,
159
+ Formula extends PredicateFormula
160
+ > = PredicateState<
161
+ AssumeFormulaFalse<PredicateStateFormula<State>, Formula>,
162
+ AssumeFactsFalse<PredicateStateFacts<State>, Formula>
163
+ >
164
+
165
+ export type AssumePredicateStateTrue<
166
+ State extends PredicateState,
167
+ Predicate
168
+ > = AssumePredicateStateFormulaTrue<State, FormulaOfPredicate<Predicate>>
169
+
170
+ export type AssumePredicateStateFalse<
171
+ State extends PredicateState,
172
+ Predicate
173
+ > = AssumePredicateStateFormulaFalse<State, FormulaOfPredicate<Predicate>>
174
+
73
175
  export type Contradicts<
74
176
  Assumptions extends PredicateFormula,
75
177
  Predicate
@@ -20,6 +20,12 @@ export interface NeqLiteralAtom<Key extends string, Value extends string> {
20
20
  readonly value: Value
21
21
  }
22
22
 
23
+ export interface LiteralSetAtom<Key extends string, Values extends string> {
24
+ readonly kind: "literal-set"
25
+ readonly key: Key
26
+ readonly values: readonly Values[]
27
+ }
28
+
23
29
  export interface EqColumnAtom<
24
30
  LeftKey extends string,
25
31
  RightKey extends string
@@ -39,5 +45,6 @@ export type PredicateAtom =
39
45
  | NonNullAtom<string>
40
46
  | EqLiteralAtom<string, string>
41
47
  | NeqLiteralAtom<string, string>
48
+ | LiteralSetAtom<string, string>
42
49
  | EqColumnAtom<string, string>
43
50
  | UnknownAtom<string>