effect-qb 0.12.3

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 (81) hide show
  1. package/README.md +1294 -0
  2. package/dist/mysql.js +57575 -0
  3. package/dist/postgres.js +6303 -0
  4. package/package.json +42 -0
  5. package/src/internal/aggregation-validation.ts +57 -0
  6. package/src/internal/case-analysis.ts +50 -0
  7. package/src/internal/coercion-analysis.ts +30 -0
  8. package/src/internal/coercion-errors.ts +29 -0
  9. package/src/internal/coercion-kind.ts +32 -0
  10. package/src/internal/coercion-normalize.ts +7 -0
  11. package/src/internal/coercion-rules.ts +25 -0
  12. package/src/internal/column-state.ts +453 -0
  13. package/src/internal/column.ts +417 -0
  14. package/src/internal/datatypes/define.ts +44 -0
  15. package/src/internal/datatypes/lookup.ts +280 -0
  16. package/src/internal/datatypes/shape.ts +72 -0
  17. package/src/internal/derived-table.ts +149 -0
  18. package/src/internal/dialect.ts +30 -0
  19. package/src/internal/executor.ts +390 -0
  20. package/src/internal/expression-ast.ts +349 -0
  21. package/src/internal/expression.ts +325 -0
  22. package/src/internal/grouping-key.ts +82 -0
  23. package/src/internal/json/ast.ts +63 -0
  24. package/src/internal/json/errors.ts +13 -0
  25. package/src/internal/json/path.ts +227 -0
  26. package/src/internal/json/shape.ts +1 -0
  27. package/src/internal/json/types.ts +386 -0
  28. package/src/internal/mysql-dialect.ts +39 -0
  29. package/src/internal/mysql-renderer.ts +37 -0
  30. package/src/internal/plan.ts +64 -0
  31. package/src/internal/postgres-dialect.ts +34 -0
  32. package/src/internal/postgres-renderer.ts +40 -0
  33. package/src/internal/predicate-analysis.ts +71 -0
  34. package/src/internal/predicate-atom.ts +43 -0
  35. package/src/internal/predicate-branches.ts +40 -0
  36. package/src/internal/predicate-context.ts +279 -0
  37. package/src/internal/predicate-formula.ts +100 -0
  38. package/src/internal/predicate-key.ts +28 -0
  39. package/src/internal/predicate-nnf.ts +12 -0
  40. package/src/internal/predicate-normalize.ts +202 -0
  41. package/src/internal/projection-alias.ts +15 -0
  42. package/src/internal/projections.ts +101 -0
  43. package/src/internal/query-ast.ts +297 -0
  44. package/src/internal/query-factory.ts +6757 -0
  45. package/src/internal/query-requirements.ts +40 -0
  46. package/src/internal/query.ts +1590 -0
  47. package/src/internal/renderer.ts +102 -0
  48. package/src/internal/runtime-normalize.ts +344 -0
  49. package/src/internal/runtime-schema.ts +428 -0
  50. package/src/internal/runtime-value.ts +85 -0
  51. package/src/internal/schema-derivation.ts +131 -0
  52. package/src/internal/sql-expression-renderer.ts +1353 -0
  53. package/src/internal/table-options.ts +225 -0
  54. package/src/internal/table.ts +674 -0
  55. package/src/mysql/column.ts +30 -0
  56. package/src/mysql/datatypes/index.ts +6 -0
  57. package/src/mysql/datatypes/spec.ts +180 -0
  58. package/src/mysql/errors/catalog.ts +51662 -0
  59. package/src/mysql/errors/fields.ts +21 -0
  60. package/src/mysql/errors/index.ts +18 -0
  61. package/src/mysql/errors/normalize.ts +232 -0
  62. package/src/mysql/errors/requirements.ts +73 -0
  63. package/src/mysql/executor.ts +134 -0
  64. package/src/mysql/query.ts +189 -0
  65. package/src/mysql/renderer.ts +19 -0
  66. package/src/mysql/table.ts +157 -0
  67. package/src/mysql.ts +18 -0
  68. package/src/postgres/column.ts +20 -0
  69. package/src/postgres/datatypes/index.ts +8 -0
  70. package/src/postgres/datatypes/spec.ts +264 -0
  71. package/src/postgres/errors/catalog.ts +452 -0
  72. package/src/postgres/errors/fields.ts +48 -0
  73. package/src/postgres/errors/index.ts +4 -0
  74. package/src/postgres/errors/normalize.ts +209 -0
  75. package/src/postgres/errors/requirements.ts +65 -0
  76. package/src/postgres/errors/types.ts +38 -0
  77. package/src/postgres/executor.ts +131 -0
  78. package/src/postgres/query.ts +189 -0
  79. package/src/postgres/renderer.ts +29 -0
  80. package/src/postgres/table.ts +157 -0
  81. package/src/postgres.ts +18 -0
@@ -0,0 +1,202 @@
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"
6
+
7
+ type AstOf<Value extends Expression.Any> = Value extends {
8
+ readonly [ExpressionAst.TypeId]: infer Ast extends ExpressionAst.Any
9
+ } ? Ast : never
10
+
11
+ type LiteralValueOfExpression<Value extends Expression.Any> = AstOf<Value> extends ExpressionAst.LiteralNode<infer Literal>
12
+ ? Literal
13
+ : never
14
+
15
+ type True = TrueFormula
16
+ type False = FalseFormula
17
+
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>
21
+
22
+ type NonNullFactsOfExpression<Value extends Expression.Any> =
23
+ [ColumnKeyOfExpression<Value>] extends [never]
24
+ ? never
25
+ : FactOf<NonNullAtom<ColumnKeyOfExpression<Value>>>
26
+
27
+ type CombineFacts<
28
+ Left extends PredicateFormula,
29
+ Right extends PredicateFormula
30
+ > = [Left] extends [never]
31
+ ? Right
32
+ : [Right] extends [never]
33
+ ? Left
34
+ : import("./predicate-formula.js").NormalizeBooleanConstants<AllFormula<[Left, Right]>>
35
+
36
+ type FactsOfExpressions<Values extends readonly Expression.Any[]> =
37
+ Values extends readonly [
38
+ infer Head extends Expression.Any,
39
+ ...infer Tail extends readonly Expression.Any[]
40
+ ]
41
+ ? CombineFacts<FormulaOfExpression<Head>, FactsOfExpressions<Tail>>
42
+ : never
43
+
44
+ type FormulaOfEq<
45
+ Left extends Expression.Any,
46
+ Right extends Expression.Any
47
+ > =
48
+ [ColumnKeyOfExpression<Left>] extends [never]
49
+ ? [ColumnKeyOfExpression<Right>] extends [never]
50
+ ? LiteralValueOfExpression<Left> extends infer LeftLiteral
51
+ ? LiteralValueOfExpression<Right> extends infer RightLiteral
52
+ ? [LeftLiteral] extends [never]
53
+ ? UnknownTag<"eq:unsupported">
54
+ : [RightLiteral] extends [never]
55
+ ? UnknownTag<"eq:unsupported">
56
+ : LeftLiteral extends null
57
+ ? False
58
+ : RightLiteral extends null
59
+ ? False
60
+ : [LeftLiteral] extends [RightLiteral]
61
+ ? True
62
+ : False
63
+ : UnknownTag<"eq:unsupported">
64
+ : UnknownTag<"eq:unsupported">
65
+ : LiteralValueOfExpression<Left> extends infer LeftLiteral
66
+ ? [LeftLiteral] extends [never]
67
+ ? UnknownTag<"eq:unsupported">
68
+ : LeftLiteral extends null
69
+ ? False
70
+ : AtomOf<EqLiteralAtom<ColumnKeyOfExpression<Right>, ValueKey<LeftLiteral>>>
71
+ : UnknownTag<"eq:unsupported">
72
+ : [ColumnKeyOfExpression<Right>] extends [never]
73
+ ? LiteralValueOfExpression<Right> extends infer RightLiteral
74
+ ? [RightLiteral] extends [never]
75
+ ? UnknownTag<"eq:unsupported">
76
+ : RightLiteral extends null
77
+ ? False
78
+ : AtomOf<EqLiteralAtom<ColumnKeyOfExpression<Left>, ValueKey<RightLiteral>>>
79
+ : UnknownTag<"eq:unsupported">
80
+ : AtomOf<import("./predicate-atom.js").EqColumnAtom<ColumnKeyOfExpression<Left>, ColumnKeyOfExpression<Right>>>
81
+
82
+ type FormulaOfVariadic<
83
+ Kind extends ExpressionAst.VariadicKind,
84
+ Values extends readonly Expression.Any[]
85
+ > = Kind extends "and"
86
+ ? import("./predicate-formula.js").NormalizeBooleanConstants<import("./predicate-formula.js").AllFormula<{
87
+ readonly [K in keyof Values]: Values[K] extends Expression.Any ? FormulaOfExpression<Values[K]> : never
88
+ } & readonly PredicateFormula[]>>
89
+ : Kind extends "or"
90
+ ? import("./predicate-formula.js").NormalizeBooleanConstants<import("./predicate-formula.js").AnyFormula<{
91
+ readonly [K in keyof Values]: Values[K] extends Expression.Any ? FormulaOfExpression<Values[K]> : never
92
+ } & readonly PredicateFormula[]>>
93
+ : Kind extends "in" | "notIn" | "between"
94
+ ? FactsOfExpressions<Values> extends infer Facts extends PredicateFormula
95
+ ? [Facts] extends [never]
96
+ ? UnknownTag<`variadic:${Kind}`>
97
+ : Facts
98
+ : UnknownTag<`variadic:${Kind}`>
99
+ : UnknownTag<`variadic:${Kind}`>
100
+
101
+ export type FormulaOfExpression<Value extends Expression.Any> =
102
+ AstOf<Value> extends infer Ast extends ExpressionAst.Any
103
+ ? Ast extends ExpressionAst.LiteralNode<infer Literal>
104
+ ? Literal extends true
105
+ ? True
106
+ : Literal extends false
107
+ ? False
108
+ : UnknownTag<"literal:non-boolean">
109
+ : Ast extends ExpressionAst.UnaryNode<infer Kind extends ExpressionAst.UnaryKind, infer Inner extends Expression.Any>
110
+ ? Kind extends "isNull"
111
+ ? [ColumnKeyOfExpression<Inner>] extends [never]
112
+ ? UnknownTag<"isNull:unsupported">
113
+ : AtomOf<NullAtom<ColumnKeyOfExpression<Inner>>>
114
+ : Kind extends "isNotNull"
115
+ ? [ColumnKeyOfExpression<Inner>] extends [never]
116
+ ? UnknownTag<"isNotNull:unsupported">
117
+ : AtomOf<NonNullAtom<ColumnKeyOfExpression<Inner>>>
118
+ : Kind extends "not"
119
+ ? import("./predicate-formula.js").Not<FormulaOfExpression<Inner>>
120
+ : UnknownTag<`unary:${Kind}`>
121
+ : Ast extends ExpressionAst.BinaryNode<"eq", infer Left extends Expression.Any, infer Right extends Expression.Any>
122
+ ? FormulaOfEq<Left, Right>
123
+ : Ast extends ExpressionAst.BinaryNode<"neq", infer Left extends Expression.Any, infer Right extends Expression.Any>
124
+ ? Left extends Expression.Any
125
+ ? Right extends Expression.Any
126
+ ? [ColumnKeyOfExpression<Left>] extends [never]
127
+ ? [ColumnKeyOfExpression<Right>] extends [never]
128
+ ? LiteralValueOfExpression<Left> extends infer LeftLiteral
129
+ ? LiteralValueOfExpression<Right> extends infer RightLiteral
130
+ ? [LeftLiteral] extends [never]
131
+ ? UnknownTag<"neq:unsupported">
132
+ : [RightLiteral] extends [never]
133
+ ? UnknownTag<"neq:unsupported">
134
+ : LeftLiteral extends null
135
+ ? False
136
+ : RightLiteral extends null
137
+ ? False
138
+ : [LeftLiteral] extends [RightLiteral]
139
+ ? False
140
+ : True
141
+ : UnknownTag<"neq:unsupported">
142
+ : UnknownTag<"neq:unsupported">
143
+ : CombineFacts<NonNullFactsOfExpression<Left>, NonNullFactsOfExpression<Right>>
144
+ : CombineFacts<NonNullFactsOfExpression<Left>, NonNullFactsOfExpression<Right>>
145
+ : UnknownTag<"neq:unsupported">
146
+ : UnknownTag<"neq:unsupported">
147
+ : Ast extends ExpressionAst.BinaryNode<infer Kind extends "lt" | "lte" | "gt" | "gte" | "like" | "ilike" | "isDistinctFrom" | "isNotDistinctFrom" | "contains" | "containedBy" | "overlaps", infer Left extends Expression.Any, infer Right extends Expression.Any>
148
+ ? Kind extends "isNotDistinctFrom"
149
+ ? Left extends Expression.Any
150
+ ? Right extends Expression.Any
151
+ ? LiteralValueOfExpression<Left> extends infer LeftLiteral
152
+ ? LiteralValueOfExpression<Right> extends infer RightLiteral
153
+ ? [LeftLiteral] extends [never]
154
+ ? [RightLiteral] extends [never]
155
+ ? UnknownTag<"isNotDistinctFrom:unsupported">
156
+ : RightLiteral extends null
157
+ ? [ColumnKeyOfExpression<Left>] extends [never]
158
+ ? UnknownTag<"isNotDistinctFrom:unsupported">
159
+ : AtomOf<NullAtom<ColumnKeyOfExpression<Left>>>
160
+ : UnknownTag<"isNotDistinctFrom:unsupported">
161
+ : LeftLiteral extends null
162
+ ? [ColumnKeyOfExpression<Right>] extends [never]
163
+ ? UnknownTag<"isNotDistinctFrom:unsupported">
164
+ : AtomOf<NullAtom<ColumnKeyOfExpression<Right>>>
165
+ : RightLiteral extends null
166
+ ? [ColumnKeyOfExpression<Left>] extends [never]
167
+ ? UnknownTag<"isNotDistinctFrom:unsupported">
168
+ : AtomOf<NullAtom<ColumnKeyOfExpression<Left>>>
169
+ : [ColumnKeyOfExpression<Left>] extends [never]
170
+ ? [ColumnKeyOfExpression<Right>] extends [never]
171
+ ? CombineFacts<NonNullFactsOfExpression<Left>, NonNullFactsOfExpression<Right>>
172
+ : AtomOf<EqLiteralAtom<ColumnKeyOfExpression<Right>, ValueKey<LeftLiteral>>>
173
+ : AtomOf<EqLiteralAtom<ColumnKeyOfExpression<Left>, ValueKey<RightLiteral>>>
174
+ : UnknownTag<"isNotDistinctFrom:unsupported">
175
+ : UnknownTag<"isNotDistinctFrom:unsupported">
176
+ : UnknownTag<"isNotDistinctFrom:unsupported">
177
+ : UnknownTag<"isNotDistinctFrom:unsupported">
178
+ : Kind extends "isDistinctFrom"
179
+ ? UnknownTag<"isDistinctFrom:unsupported">
180
+ : CombineFacts<NonNullFactsOfExpression<Left>, NonNullFactsOfExpression<Right>>
181
+ : Ast extends ExpressionAst.VariadicNode<"and", infer Values extends readonly Expression.Any[]>
182
+ ? import("./predicate-formula.js").NormalizeBooleanConstants<import("./predicate-formula.js").AllFormula<{
183
+ readonly [K in keyof Values]: Values[K] extends Expression.Any ? FormulaOfExpression<Values[K]> : never
184
+ } & readonly PredicateFormula[]>>
185
+ : Ast extends ExpressionAst.VariadicNode<"or", infer Values extends readonly Expression.Any[]>
186
+ ? import("./predicate-formula.js").NormalizeBooleanConstants<import("./predicate-formula.js").AnyFormula<{
187
+ readonly [K in keyof Values]: Values[K] extends Expression.Any ? FormulaOfExpression<Values[K]> : never
188
+ } & readonly PredicateFormula[]>>
189
+ : Ast extends ExpressionAst.VariadicNode<infer Kind extends "in" | "notIn" | "between", infer Values extends readonly Expression.Any[]>
190
+ ? CombineFacts<NonNullFactsOfExpression<Values[number]>, UnknownTag<`variadic:${Kind}`>>
191
+ : Ast extends ExpressionAst.BinaryNode<infer Kind extends ExpressionAst.BinaryKind, infer Left extends Expression.Any, infer Right extends Expression.Any>
192
+ ? Kind extends "eq"
193
+ ? FormulaOfEq<Left, Right>
194
+ : CombineFacts<NonNullFactsOfExpression<Left>, NonNullFactsOfExpression<Right>>
195
+ : UnknownTag<`expr:${Ast["kind"]}`>
196
+ : UnknownTag<"missing-ast">
197
+
198
+ export type FormulaOfPredicate<Value> =
199
+ Value extends true ? True :
200
+ Value extends false ? False :
201
+ Value extends Expression.Any ? FormulaOfExpression<Value> :
202
+ UnknownTag<"predicate:unsupported">
@@ -0,0 +1,15 @@
1
+ /** Symbol used to attach explicit projection-alias metadata to an expression. */
2
+ export const TypeId: unique symbol = Symbol.for("effect-qb/ProjectionAlias")
3
+
4
+ export type TypeId = typeof TypeId
5
+
6
+ /**
7
+ * Projection-alias metadata carried by a runtime expression wrapper.
8
+ *
9
+ * This is intentionally orthogonal to the scalar expression AST. Aliasing does
10
+ * not change SQL semantics; it only changes how a selected expression is named
11
+ * in the rendered `SELECT ... AS ...` list.
12
+ */
13
+ export interface State<Alias extends string = string> {
14
+ readonly alias: Alias
15
+ }
@@ -0,0 +1,101 @@
1
+ import * as Expression from "./expression.js"
2
+ import * as ProjectionAlias from "./projection-alias.js"
3
+
4
+ /**
5
+ * Flat projection metadata shared by renderers and executors.
6
+ *
7
+ * `path` identifies where a value should be decoded in the nested result row,
8
+ * while `alias` is the flat SQL column alias used by the rendered query.
9
+ */
10
+ export interface Projection {
11
+ readonly path: readonly string[]
12
+ readonly alias: string
13
+ }
14
+
15
+ /** Selection leaf paired with its resolved projection alias. */
16
+ export interface FlattenedProjection {
17
+ readonly path: readonly string[]
18
+ readonly expression: Expression.Any
19
+ readonly alias: string
20
+ }
21
+
22
+ const aliasFromPath = (path: readonly string[]): string => path.join("__")
23
+
24
+ const isExpression = (value: unknown): value is Expression.Any =>
25
+ typeof value === "object" && value !== null && Expression.TypeId in value
26
+
27
+ const projectionAliasOf = (expression: Expression.Any): string | undefined =>
28
+ ProjectionAlias.TypeId in expression
29
+ ? (expression as Expression.Any & {
30
+ readonly [ProjectionAlias.TypeId]: ProjectionAlias.State
31
+ })[ProjectionAlias.TypeId].alias
32
+ : undefined
33
+
34
+ const pathKeyOf = (path: readonly string[]): string => JSON.stringify(path)
35
+
36
+ const formatProjectionPath = (path: readonly string[]): string => path.join(".")
37
+
38
+ const isPrefixPath = (
39
+ left: readonly string[],
40
+ right: readonly string[]
41
+ ): boolean =>
42
+ left.length < right.length && left.every((segment, index) => segment === right[index])
43
+
44
+ /**
45
+ * Flattens a nested selection object into leaf expressions with decode paths
46
+ * and resolved SQL aliases.
47
+ */
48
+ export const flattenSelection = (
49
+ selection: Record<string, unknown>,
50
+ path: readonly string[] = []
51
+ ): ReadonlyArray<FlattenedProjection> => {
52
+ const fields: Array<FlattenedProjection> = []
53
+ for (const [key, value] of Object.entries(selection)) {
54
+ const nextPath = [...path, key]
55
+ if (isExpression(value)) {
56
+ fields.push({
57
+ path: nextPath,
58
+ expression: value,
59
+ alias: projectionAliasOf(value) ?? aliasFromPath(nextPath)
60
+ })
61
+ continue
62
+ }
63
+ fields.push(...flattenSelection(value as Record<string, unknown>, nextPath))
64
+ }
65
+ return fields
66
+ }
67
+
68
+ /**
69
+ * Validates the flattened projection set shared by renderer and executor code.
70
+ *
71
+ * This rejects:
72
+ * - duplicate SQL aliases
73
+ * - duplicate decode paths
74
+ * - conflicting prefix paths like `profile` and `profile.id`
75
+ */
76
+ export const validateProjections = (projections: readonly Projection[]): void => {
77
+ const seen = new Set<string>()
78
+ const pathKeys = new Set<string>()
79
+ for (const projection of projections) {
80
+ if (seen.has(projection.alias)) {
81
+ throw new Error(`Duplicate projection alias: ${projection.alias}`)
82
+ }
83
+ seen.add(projection.alias)
84
+ const pathKey = pathKeyOf(projection.path)
85
+ if (pathKeys.has(pathKey)) {
86
+ throw new Error(`Duplicate projection path: ${formatProjectionPath(projection.path)}`)
87
+ }
88
+ pathKeys.add(pathKey)
89
+ }
90
+ for (let index = 0; index < projections.length; index++) {
91
+ const current = projections[index]!
92
+ for (let compareIndex = index + 1; compareIndex < projections.length; compareIndex++) {
93
+ const other = projections[compareIndex]!
94
+ if (isPrefixPath(current.path, other.path) || isPrefixPath(other.path, current.path)) {
95
+ throw new Error(
96
+ `Conflicting projection paths: ${formatProjectionPath(current.path)} conflicts with ${formatProjectionPath(other.path)}`
97
+ )
98
+ }
99
+ }
100
+ }
101
+ }
@@ -0,0 +1,297 @@
1
+ import type * as Expression from "./expression.js"
2
+
3
+ /** Symbol used to attach query-clause AST metadata to query-plan values. */
4
+ export const TypeId: unique symbol = Symbol.for("effect-qb/QueryAst")
5
+
6
+ export type TypeId = typeof TypeId
7
+
8
+ /** Statement kinds supported by the current query AST. */
9
+ export type QueryStatement =
10
+ | "select"
11
+ | "set"
12
+ | "insert"
13
+ | "update"
14
+ | "delete"
15
+ | "truncate"
16
+ | "merge"
17
+ | "transaction"
18
+ | "commit"
19
+ | "rollback"
20
+ | "savepoint"
21
+ | "rollbackTo"
22
+ | "releaseSavepoint"
23
+ | "createTable"
24
+ | "createIndex"
25
+ | "dropIndex"
26
+ | "alterTable"
27
+ | "dropTable"
28
+
29
+ /** Base `FROM` clause recorded by the query AST. */
30
+ export interface FromClause<TableName extends string = string> {
31
+ readonly kind: "from"
32
+ readonly tableName: TableName
33
+ readonly baseTableName: string
34
+ readonly source: unknown
35
+ }
36
+
37
+ /** Boolean predicate recorded in a `WHERE` clause. */
38
+ export interface WhereClause<Predicate extends Expression.Any = Expression.Any> {
39
+ readonly kind: "where"
40
+ readonly predicate: Predicate
41
+ }
42
+
43
+ /** Boolean predicate recorded in a `HAVING` clause. */
44
+ export interface HavingClause<Predicate extends Expression.Any = Expression.Any> {
45
+ readonly kind: "having"
46
+ readonly predicate: Predicate
47
+ }
48
+
49
+ /** Assignment recorded in a mutation statement. */
50
+ export interface AssignmentClause<Value extends Expression.Any = Expression.Any> {
51
+ readonly tableName?: string
52
+ readonly columnName: string
53
+ readonly value: Value
54
+ }
55
+
56
+ /** One row in a multi-row `values (...)` insert source. */
57
+ export interface InsertValuesRowClause<
58
+ Values extends readonly AssignmentClause[] = readonly AssignmentClause[]
59
+ > {
60
+ readonly values: Values
61
+ }
62
+
63
+ /** Additional insert source kinds beyond a single literal row. */
64
+ export type InsertSourceClause =
65
+ | {
66
+ readonly kind: "values"
67
+ readonly columns: readonly [string, ...string[]]
68
+ readonly rows: readonly [InsertValuesRowClause, ...InsertValuesRowClause[]]
69
+ }
70
+ | {
71
+ readonly kind: "query"
72
+ readonly columns: readonly [string, ...string[]]
73
+ readonly query: unknown
74
+ }
75
+ | {
76
+ readonly kind: "unnest"
77
+ readonly columns: readonly [string, ...string[]]
78
+ readonly values: readonly {
79
+ readonly columnName: string
80
+ readonly values: readonly unknown[]
81
+ }[]
82
+ }
83
+
84
+ /** One branch inside a `merge` statement. */
85
+ export type MergeMatchedClause<
86
+ Predicate extends Expression.Any | undefined = Expression.Any | undefined
87
+ > =
88
+ | {
89
+ readonly kind: "update"
90
+ readonly values: readonly AssignmentClause[]
91
+ readonly predicate?: Predicate
92
+ }
93
+ | {
94
+ readonly kind: "delete"
95
+ readonly predicate?: Predicate
96
+ }
97
+
98
+ /** Insert branch inside a `merge` statement. */
99
+ export interface MergeNotMatchedClause<
100
+ Predicate extends Expression.Any | undefined = Expression.Any | undefined
101
+ > {
102
+ readonly kind: "insert"
103
+ readonly values: readonly AssignmentClause[]
104
+ readonly predicate?: Predicate
105
+ }
106
+
107
+ /** Payload recorded by a `merge` statement. */
108
+ export interface MergeClause<
109
+ On extends Expression.Any = Expression.Any,
110
+ Predicate extends Expression.Any | undefined = Expression.Any | undefined
111
+ > {
112
+ readonly kind: "merge"
113
+ readonly on: On
114
+ readonly whenMatched?: MergeMatchedClause<Predicate>
115
+ readonly whenNotMatched?: MergeNotMatchedClause<Predicate>
116
+ }
117
+
118
+ /** DDL payload recorded by schema-manipulation statements. */
119
+ export type DdlClause =
120
+ | {
121
+ readonly kind: "createTable"
122
+ readonly ifNotExists: boolean
123
+ }
124
+ | {
125
+ readonly kind: "dropTable"
126
+ readonly ifExists: boolean
127
+ }
128
+ | {
129
+ readonly kind: "createIndex"
130
+ readonly name: string
131
+ readonly columns: readonly [string, ...string[]]
132
+ readonly unique: boolean
133
+ readonly ifNotExists: boolean
134
+ }
135
+ | {
136
+ readonly kind: "dropIndex"
137
+ readonly name: string
138
+ readonly ifExists: boolean
139
+ }
140
+
141
+ /** Truncate payload recorded by a truncate statement. */
142
+ export interface TruncateClause {
143
+ readonly kind: "truncate"
144
+ readonly restartIdentity: boolean
145
+ readonly cascade: boolean
146
+ }
147
+
148
+ /** Transaction-control payload recorded by transactional statements. */
149
+ export type TransactionClause =
150
+ | {
151
+ readonly kind: "transaction"
152
+ readonly isolationLevel?: "read committed" | "repeatable read" | "serializable"
153
+ readonly readOnly?: boolean
154
+ }
155
+ | {
156
+ readonly kind: "commit"
157
+ }
158
+ | {
159
+ readonly kind: "rollback"
160
+ }
161
+ | {
162
+ readonly kind: "savepoint"
163
+ readonly name: string
164
+ }
165
+ | {
166
+ readonly kind: "rollbackTo"
167
+ readonly name: string
168
+ }
169
+ | {
170
+ readonly kind: "releaseSavepoint"
171
+ readonly name: string
172
+ }
173
+ | {
174
+ readonly kind: "dropTable"
175
+ readonly ifExists: boolean
176
+ }
177
+ | {
178
+ readonly kind: "createIndex"
179
+ readonly name: string
180
+ readonly columns: readonly [string, ...string[]]
181
+ readonly unique: boolean
182
+ readonly ifNotExists: boolean
183
+ }
184
+ | {
185
+ readonly kind: "dropIndex"
186
+ readonly name: string
187
+ readonly ifExists: boolean
188
+ }
189
+
190
+ /** Locking mode attached to a select statement. */
191
+ export interface LockClause {
192
+ readonly kind: "lock"
193
+ readonly mode: "update" | "share" | "lowPriority" | "ignore" | "quick"
194
+ readonly nowait?: boolean
195
+ readonly skipLocked?: boolean
196
+ }
197
+
198
+ /** Conflict target attached to a Postgres insert statement. */
199
+ export type ConflictTargetClause =
200
+ | {
201
+ readonly kind: "columns"
202
+ readonly columns: readonly [string, ...string[]]
203
+ readonly where?: Expression.Any
204
+ }
205
+ | {
206
+ readonly kind: "constraint"
207
+ readonly name: string
208
+ }
209
+
210
+ /** Conflict clause attached to an insert statement. */
211
+ export interface ConflictClause {
212
+ readonly kind: "conflict"
213
+ readonly target?: ConflictTargetClause
214
+ readonly action: "doNothing" | "doUpdate"
215
+ readonly values?: readonly AssignmentClause[]
216
+ readonly where?: Expression.Any
217
+ }
218
+
219
+ /** Join kinds supported by the current query layer. */
220
+ export type JoinKind = "inner" | "left" | "right" | "full" | "cross"
221
+
222
+ /** Join clause recorded by the query AST. */
223
+ export interface JoinClause<
224
+ TableName extends string = string,
225
+ Kind extends JoinKind = JoinKind,
226
+ On extends Expression.Any | undefined = Expression.Any | undefined
227
+ > {
228
+ readonly kind: Kind
229
+ readonly tableName: TableName
230
+ readonly baseTableName: string
231
+ readonly source: unknown
232
+ readonly on?: On
233
+ }
234
+
235
+ /** Sort direction recorded by an `ORDER BY` clause. */
236
+ export type OrderDirection = "asc" | "desc"
237
+
238
+ /** Ordering clause recorded by the query AST. */
239
+ export interface OrderByClause<Value extends Expression.Any = Expression.Any> {
240
+ readonly kind: "orderBy"
241
+ readonly value: Value
242
+ readonly direction: OrderDirection
243
+ }
244
+
245
+ /** Set-operator kinds supported by compound queries. */
246
+ export type SetOperatorKind = "union" | "intersect" | "except"
247
+
248
+ /** Compound-query clause recorded by the query AST. */
249
+ export interface SetOperationClause {
250
+ readonly kind: SetOperatorKind
251
+ readonly all?: boolean
252
+ readonly query: unknown
253
+ }
254
+
255
+ /**
256
+ * Internal query AST stored alongside public `Plan` metadata.
257
+ *
258
+ * The public plan state tracks selection, required sources, available sources,
259
+ * and dialect. This AST captures the clause ordering needed to eventually
260
+ * render or optimize a SQL query.
261
+ */
262
+ export interface Ast<
263
+ Selection = unknown,
264
+ Grouped extends string = never,
265
+ Statement extends QueryStatement = "select"
266
+ > {
267
+ readonly kind: Statement
268
+ readonly select: Selection
269
+ readonly distinct?: boolean
270
+ readonly distinctOn?: readonly Expression.Any[]
271
+ readonly setBase?: unknown
272
+ readonly recursive?: boolean
273
+ readonly from?: FromClause
274
+ readonly fromSources?: readonly FromClause[]
275
+ readonly into?: FromClause
276
+ readonly target?: FromClause
277
+ readonly targets?: readonly FromClause[]
278
+ readonly using?: FromClause
279
+ readonly values?: readonly AssignmentClause[]
280
+ readonly insertSource?: InsertSourceClause
281
+ readonly set?: readonly AssignmentClause[]
282
+ readonly ddl?: DdlClause
283
+ readonly truncate?: TruncateClause
284
+ readonly merge?: MergeClause
285
+ readonly transaction?: TransactionClause
286
+ readonly lock?: LockClause
287
+ readonly conflict?: ConflictClause
288
+ readonly where: readonly WhereClause[]
289
+ readonly having: readonly HavingClause[]
290
+ readonly joins: readonly JoinClause[]
291
+ readonly groupBy: readonly Expression.Any[]
292
+ readonly orderBy: readonly OrderByClause[]
293
+ readonly limit?: Expression.Any
294
+ readonly offset?: Expression.Any
295
+ readonly setOperations?: readonly SetOperationClause[]
296
+ readonly groupedSources?: Grouped
297
+ }