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.
- package/dist/mysql.js +1957 -595
- package/dist/postgres/metadata.js +2507 -182
- package/dist/postgres.js +9587 -8201
- package/dist/sqlite.js +8360 -0
- package/package.json +7 -2
- package/src/internal/column-state.ts +7 -0
- package/src/internal/column.ts +22 -0
- package/src/internal/derived-table.ts +29 -3
- package/src/internal/dialect.ts +14 -1
- package/src/internal/dsl-mutation-runtime.ts +173 -4
- package/src/internal/dsl-plan-runtime.ts +165 -20
- package/src/internal/dsl-query-runtime.ts +60 -6
- package/src/internal/dsl-transaction-ddl-runtime.ts +72 -2
- package/src/internal/executor.ts +62 -13
- package/src/internal/expression-ast.ts +3 -2
- package/src/internal/grouping-key.ts +141 -1
- package/src/internal/implication-runtime.ts +2 -1
- package/src/internal/json/types.ts +155 -40
- package/src/internal/predicate/analysis.ts +103 -1
- package/src/internal/predicate/atom.ts +7 -0
- package/src/internal/predicate/context.ts +170 -17
- package/src/internal/predicate/key.ts +64 -2
- package/src/internal/predicate/normalize.ts +115 -34
- package/src/internal/predicate/runtime.ts +144 -13
- package/src/internal/query.ts +563 -103
- package/src/internal/renderer.ts +39 -2
- package/src/internal/runtime/driver-value-mapping.ts +244 -0
- package/src/internal/runtime/normalize.ts +62 -38
- package/src/internal/runtime/schema.ts +5 -3
- package/src/internal/runtime/value.ts +153 -30
- package/src/internal/scalar.ts +11 -0
- package/src/internal/table-options.ts +108 -1
- package/src/internal/table.ts +87 -29
- package/src/mysql/column.ts +19 -2
- package/src/mysql/datatypes/index.ts +21 -0
- package/src/mysql/errors/catalog.ts +5 -5
- package/src/mysql/errors/normalize.ts +2 -2
- package/src/mysql/executor.ts +20 -5
- package/src/mysql/internal/dialect.ts +12 -6
- package/src/mysql/internal/dsl.ts +995 -263
- package/src/mysql/internal/renderer.ts +13 -3
- package/src/mysql/internal/sql-expression-renderer.ts +530 -128
- package/src/mysql/query.ts +9 -2
- package/src/mysql/renderer.ts +7 -2
- package/src/mysql/table.ts +38 -12
- package/src/postgres/cast.ts +22 -7
- package/src/postgres/column.ts +5 -2
- package/src/postgres/errors/normalize.ts +2 -2
- package/src/postgres/executor.ts +68 -10
- package/src/postgres/function/core.ts +19 -1
- package/src/postgres/internal/dialect.ts +12 -6
- package/src/postgres/internal/dsl.ts +958 -288
- package/src/postgres/internal/renderer.ts +13 -3
- package/src/postgres/internal/schema-ddl.ts +2 -1
- package/src/postgres/internal/schema-model.ts +6 -3
- package/src/postgres/internal/sql-expression-renderer.ts +477 -96
- package/src/postgres/json.ts +57 -17
- package/src/postgres/query.ts +9 -2
- package/src/postgres/renderer.ts +7 -2
- package/src/postgres/schema-management.ts +91 -4
- package/src/postgres/schema.ts +1 -1
- package/src/postgres/table.ts +189 -53
- package/src/postgres/type.ts +4 -0
- package/src/sqlite/column.ts +128 -0
- package/src/sqlite/datatypes/index.ts +79 -0
- package/src/sqlite/datatypes/spec.ts +98 -0
- package/src/sqlite/errors/catalog.ts +103 -0
- package/src/sqlite/errors/fields.ts +19 -0
- package/src/sqlite/errors/index.ts +19 -0
- package/src/sqlite/errors/normalize.ts +229 -0
- package/src/sqlite/errors/requirements.ts +71 -0
- package/src/sqlite/errors/types.ts +29 -0
- package/src/sqlite/executor.ts +227 -0
- package/src/sqlite/function/aggregate.ts +2 -0
- package/src/sqlite/function/core.ts +2 -0
- package/src/sqlite/function/index.ts +19 -0
- package/src/sqlite/function/string.ts +2 -0
- package/src/sqlite/function/temporal.ts +100 -0
- package/src/sqlite/function/window.ts +2 -0
- package/src/sqlite/internal/dialect.ts +37 -0
- package/src/sqlite/internal/dsl.ts +6926 -0
- package/src/sqlite/internal/renderer.ts +47 -0
- package/src/sqlite/internal/sql-expression-renderer.ts +1821 -0
- package/src/sqlite/json.ts +2 -0
- package/src/sqlite/query.ts +196 -0
- package/src/sqlite/renderer.ts +24 -0
- package/src/sqlite/table.ts +183 -0
- 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
|
|
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(
|
|
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<
|
|
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
|
-
:
|
|
225
|
+
: SetTupleIndexAt<Root, Index, Next>
|
|
150
226
|
: JsonPathUsageError<Operation, Root, Segment, "index segments require an array-like json value">
|
|
151
|
-
:
|
|
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
|
-
:
|
|
243
|
+
: DropTupleIndexAt<Root, Index>
|
|
168
244
|
: JsonPathUsageError<Operation, Root, Segment, "index segments require an array-like json value">
|
|
169
|
-
:
|
|
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
|
-
:
|
|
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
|
-
:
|
|
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
|
-
:
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
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
|
-
:
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
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
|
-
:
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
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
|
-
|
|
368
|
-
|
|
369
|
-
:
|
|
370
|
-
:
|
|
371
|
-
:
|
|
372
|
-
:
|
|
373
|
-
:
|
|
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
|
|
377
|
-
NormalizeJsonLiteral<Value> extends
|
|
378
|
-
|
|
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
|
|
383
|
-
?
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
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>
|