@prisma-next/sql-builder 0.5.0-dev.9 → 0.6.0-dev.1
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/{db-Cggb4WvK.d.mts → db-DkZcNekS.d.mts} +72 -126
- package/dist/db-DkZcNekS.d.mts.map +1 -0
- package/dist/exports/types.d.mts +1 -1
- package/dist/exports/types.mjs +1 -1
- package/dist/index.d.mts +1 -1
- package/dist/index.mjs +1 -1
- package/dist/runtime/index.d.mts +16 -8
- package/dist/runtime/index.d.mts.map +1 -1
- package/dist/runtime/index.mjs +130 -98
- package/dist/runtime/index.mjs.map +1 -1
- package/package.json +17 -18
- package/src/expression.ts +33 -78
- package/src/runtime/builder-base.ts +26 -40
- package/src/runtime/expression-impl.ts +14 -9
- package/src/runtime/field-proxy.ts +20 -1
- package/src/runtime/functions.ts +87 -49
- package/src/runtime/mutation-impl.ts +28 -10
- package/src/scope.ts +9 -6
- package/dist/db-Cggb4WvK.d.mts.map +0 -1
package/dist/runtime/index.mjs
CHANGED
|
@@ -1,29 +1,50 @@
|
|
|
1
|
-
import { AggregateExpr, AndExpr, BinaryExpr, ColumnRef, DeleteAst, DerivedTableSource, ExistsExpr, IdentifierRef, InsertAst, JoinAst, ListExpression, LiteralExpr, NullCheckExpr,
|
|
2
|
-
|
|
1
|
+
import { AggregateExpr, AndExpr, BinaryExpr, ColumnRef, DeleteAst, DerivedTableSource, ExistsExpr, IdentifierRef, InsertAst, JoinAst, ListExpression, LiteralExpr, NullCheckExpr, OrExpr, OrderByItem, ParamRef, ProjectionItem, SelectAst, SubqueryExpr, TableSource, UpdateAst, collectOrderedParamRefs } from "@prisma-next/sql-relational-core/ast";
|
|
2
|
+
import { refsOf, toExpr } from "@prisma-next/sql-relational-core/expression";
|
|
3
3
|
//#region src/runtime/expression-impl.ts
|
|
4
4
|
/**
|
|
5
|
-
* Runtime wrapper around a relational-core AST expression node.
|
|
6
|
-
*
|
|
5
|
+
* Runtime wrapper around a relational-core AST expression node. Carries ScopeField metadata (codecId, nullable) so aggregate-like combinators can propagate the input codec onto their result.
|
|
6
|
+
*
|
|
7
|
+
* `refs` records the column-bound binding (`{ table, column }`) when known — the field-proxy populates it for both the namespaced form (`f.user.email` → `ColumnRef`) and the top-level shortcut (`f.email` → `IdentifierRef` + refs metadata). Encode-side dispatch and the `validateParamRefRefs` pass read it via `refsOf(expression)`.
|
|
7
8
|
*/
|
|
8
9
|
var ExpressionImpl = class {
|
|
9
10
|
ast;
|
|
10
|
-
|
|
11
|
-
|
|
11
|
+
returnType;
|
|
12
|
+
refs;
|
|
13
|
+
constructor(ast, returnType, refs) {
|
|
12
14
|
this.ast = ast;
|
|
13
|
-
this.
|
|
15
|
+
this.returnType = returnType;
|
|
16
|
+
this.refs = refs;
|
|
14
17
|
}
|
|
15
18
|
buildAst() {
|
|
16
19
|
return this.ast;
|
|
17
20
|
}
|
|
18
21
|
};
|
|
19
|
-
|
|
20
22
|
//#endregion
|
|
21
23
|
//#region src/runtime/field-proxy.ts
|
|
24
|
+
/**
|
|
25
|
+
* For a top-level field name, find the namespace (table alias) that contributed it. When exactly one namespace owns the field, the top-level binding is unambiguously column-bound and we record that `(table, column)` pair on the `ExpressionImpl` so encode-side dispatch (`forColumn`) and the `validateParamRefRefs` pass can find it. The AST stays as `IdentifierRef` to preserve SQL rendering — adapters render top-level
|
|
26
|
+
* identifiers without an explicit table qualifier — so this change is metadata-only and produces no SQL drift.
|
|
27
|
+
*/
|
|
28
|
+
function findUniqueNamespaceFor$1(scope, fieldName) {
|
|
29
|
+
let found;
|
|
30
|
+
for (const [namespace, fields] of Object.entries(scope.namespaces)) if (Object.hasOwn(fields, fieldName)) {
|
|
31
|
+
if (found !== void 0) return void 0;
|
|
32
|
+
found = namespace;
|
|
33
|
+
}
|
|
34
|
+
return found;
|
|
35
|
+
}
|
|
22
36
|
function createFieldProxy(scope) {
|
|
23
37
|
return new Proxy({}, { get(_target, prop) {
|
|
24
38
|
if (Object.hasOwn(scope.topLevel, prop)) {
|
|
25
39
|
const topField = scope.topLevel[prop];
|
|
26
|
-
if (topField)
|
|
40
|
+
if (topField) {
|
|
41
|
+
const namespace = findUniqueNamespaceFor$1(scope, prop);
|
|
42
|
+
const refs = namespace ? {
|
|
43
|
+
table: namespace,
|
|
44
|
+
column: prop
|
|
45
|
+
} : void 0;
|
|
46
|
+
return new ExpressionImpl(IdentifierRef.of(prop), topField, refs);
|
|
47
|
+
}
|
|
27
48
|
}
|
|
28
49
|
if (Object.hasOwn(scope.namespaces, prop)) {
|
|
29
50
|
const nsFields = scope.namespaces[prop];
|
|
@@ -39,49 +60,78 @@ function createNamespaceProxy(namespaceName, fields) {
|
|
|
39
60
|
}
|
|
40
61
|
} });
|
|
41
62
|
}
|
|
42
|
-
|
|
43
63
|
//#endregion
|
|
44
64
|
//#region src/runtime/functions.ts
|
|
45
65
|
const BOOL_FIELD = {
|
|
46
66
|
codecId: "pg/bool@1",
|
|
47
67
|
nullable: false
|
|
48
68
|
};
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
69
|
+
const resolve = toExpr;
|
|
70
|
+
/**
|
|
71
|
+
* Resolve a binary-comparison operand into an AST expression, threading the column-bound side's `codecId` + `refs` to the raw-value side.
|
|
72
|
+
*
|
|
73
|
+
* For `fns.eq(f.email, 'alice@example.com')`, `f.email` is the column-bound expression carrying a `ColumnRef` AST and a `returnType.codecId` (`pg/varchar@1`); the raw string operand has no codec context. By deriving the codec context from the column-bound side and forwarding it via `toExpr(value, codecId, refs)`, the resulting `ParamRef` carries the column refs that encode-side `forColumn` dispatch needs (and that the
|
|
74
|
+
* validator pass requires for parameterized codec ids like `pg/varchar@1` with a length parameter).
|
|
75
|
+
*/
|
|
76
|
+
function resolveOperand(operand, otherCodecId, otherRefs) {
|
|
77
|
+
if (isExpressionLike(operand)) return operand.buildAst();
|
|
78
|
+
return toExpr(operand, otherCodecId, otherRefs);
|
|
79
|
+
}
|
|
80
|
+
function isExpressionLike(value) {
|
|
81
|
+
return typeof value === "object" && value !== null && "buildAst" in value && typeof value.buildAst === "function";
|
|
82
|
+
}
|
|
83
|
+
function operandCodecId(operand) {
|
|
84
|
+
if (!isExpressionLike(operand)) return void 0;
|
|
85
|
+
return operand.returnType?.codecId;
|
|
52
86
|
}
|
|
53
|
-
function
|
|
54
|
-
|
|
87
|
+
function operandRefs(operand) {
|
|
88
|
+
return refsOf(operand);
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Resolves an Expression via `buildAst()`, or wraps a raw value as a `LiteralExpr` — an SQL literal inlined into the query text, not a bound parameter.
|
|
92
|
+
*
|
|
93
|
+
* Used for `and` / `or` operands. The usual operand is an `Expression<bool>` (e.g. the result of `fns.eq`), which this function passes through by calling `buildAst()`. The only time the raw-value branch fires is when the caller writes `fns.and(true, x)` or similar — inlining `TRUE`/`FALSE` literals lets the SQL planner statically simplify `TRUE AND x` to `x`, which it cannot do for an opaque `ParamRef`.
|
|
94
|
+
*/
|
|
95
|
+
function toLiteralExpr(value) {
|
|
96
|
+
if (typeof value === "object" && value !== null && "buildAst" in value && typeof value.buildAst === "function") return value.buildAst();
|
|
55
97
|
return new LiteralExpr(value);
|
|
56
98
|
}
|
|
57
99
|
function boolExpr(astNode) {
|
|
58
100
|
return new ExpressionImpl(astNode, BOOL_FIELD);
|
|
59
101
|
}
|
|
102
|
+
function binaryWithSharedCodec(a, b, build) {
|
|
103
|
+
const aCodecId = operandCodecId(a);
|
|
104
|
+
const bCodecId = operandCodecId(b);
|
|
105
|
+
const aRefs = operandRefs(a);
|
|
106
|
+
return build(resolveOperand(a, bCodecId, operandRefs(b)), resolveOperand(b, aCodecId, aRefs));
|
|
107
|
+
}
|
|
60
108
|
function eq(a, b) {
|
|
61
109
|
if (b === null) return boolExpr(NullCheckExpr.isNull(resolve(a)));
|
|
62
110
|
if (a === null) return boolExpr(NullCheckExpr.isNull(resolve(b)));
|
|
63
|
-
return boolExpr(new BinaryExpr("eq",
|
|
111
|
+
return boolExpr(binaryWithSharedCodec(a, b, (l, r) => new BinaryExpr("eq", l, r)));
|
|
64
112
|
}
|
|
65
113
|
function ne(a, b) {
|
|
66
114
|
if (b === null) return boolExpr(NullCheckExpr.isNotNull(resolve(a)));
|
|
67
115
|
if (a === null) return boolExpr(NullCheckExpr.isNotNull(resolve(b)));
|
|
68
|
-
return boolExpr(new BinaryExpr("neq",
|
|
116
|
+
return boolExpr(binaryWithSharedCodec(a, b, (l, r) => new BinaryExpr("neq", l, r)));
|
|
69
117
|
}
|
|
70
118
|
function comparison(a, b, op) {
|
|
71
|
-
return boolExpr(new BinaryExpr(op,
|
|
119
|
+
return boolExpr(binaryWithSharedCodec(a, b, (l, r) => new BinaryExpr(op, l, r)));
|
|
72
120
|
}
|
|
73
121
|
function inOrNotIn(expr, valuesOrSubquery, op) {
|
|
74
122
|
const left = expr.buildAst();
|
|
123
|
+
const leftCodecId = expr.returnType.codecId;
|
|
124
|
+
const leftRefs = refsOf(expr);
|
|
75
125
|
const binaryFn = op === "in" ? BinaryExpr.in : BinaryExpr.notIn;
|
|
76
126
|
if (Array.isArray(valuesOrSubquery)) {
|
|
77
|
-
const refs = valuesOrSubquery.map((v) =>
|
|
127
|
+
const refs = valuesOrSubquery.map((v) => resolveOperand(v, leftCodecId, leftRefs));
|
|
78
128
|
return boolExpr(binaryFn(left, ListExpression.of(refs)));
|
|
79
129
|
}
|
|
80
130
|
return boolExpr(binaryFn(left, SubqueryExpr.of(valuesOrSubquery.buildAst())));
|
|
81
131
|
}
|
|
82
132
|
function numericAgg(fn, expr) {
|
|
83
133
|
return new ExpressionImpl(AggregateExpr[fn](expr.buildAst()), {
|
|
84
|
-
codecId: expr.
|
|
134
|
+
codecId: expr.returnType.codecId,
|
|
85
135
|
nullable: true
|
|
86
136
|
});
|
|
87
137
|
}
|
|
@@ -93,8 +143,8 @@ function createBuiltinFunctions() {
|
|
|
93
143
|
gte: (a, b) => comparison(a, b, "gte"),
|
|
94
144
|
lt: (a, b) => comparison(a, b, "lt"),
|
|
95
145
|
lte: (a, b) => comparison(a, b, "lte"),
|
|
96
|
-
and: (...exprs) => boolExpr(AndExpr.of(exprs.map(
|
|
97
|
-
or: (...exprs) => boolExpr(OrExpr.of(exprs.map(
|
|
146
|
+
and: (...exprs) => boolExpr(AndExpr.of(exprs.map(toLiteralExpr))),
|
|
147
|
+
or: (...exprs) => boolExpr(OrExpr.of(exprs.map(toLiteralExpr))),
|
|
98
148
|
exists: (subquery) => boolExpr(ExistsExpr.exists(subquery.buildAst())),
|
|
99
149
|
notExists: (subquery) => boolExpr(ExistsExpr.notExists(subquery.buildAst())),
|
|
100
150
|
in: (expr, valuesOrSubquery) => inOrNotIn(expr, valuesOrSubquery, "in"),
|
|
@@ -116,35 +166,17 @@ function createAggregateOnlyFunctions() {
|
|
|
116
166
|
max: (expr) => numericAgg("max", expr)
|
|
117
167
|
};
|
|
118
168
|
}
|
|
119
|
-
function
|
|
120
|
-
return (...args) => {
|
|
121
|
-
const resolvedArgs = args.map((arg, i) => {
|
|
122
|
-
if (arg instanceof ExpressionImpl) return arg.buildAst();
|
|
123
|
-
const codecId = entry.args[i]?.codecId;
|
|
124
|
-
return ParamRef.of(arg, codecId ? { codecId } : void 0);
|
|
125
|
-
});
|
|
126
|
-
const self = resolvedArgs[0];
|
|
127
|
-
const restArgs = resolvedArgs.slice(1);
|
|
128
|
-
return new ExpressionImpl(new OperationExpr({
|
|
129
|
-
method: name,
|
|
130
|
-
self,
|
|
131
|
-
args: restArgs.length > 0 ? restArgs : void 0,
|
|
132
|
-
returns: entry.returns,
|
|
133
|
-
lowering: entry.lowering
|
|
134
|
-
}), entry.returns);
|
|
135
|
-
};
|
|
136
|
-
}
|
|
137
|
-
function createFunctions(queryOperationTypes) {
|
|
169
|
+
function createFunctions(operations) {
|
|
138
170
|
const builtins = createBuiltinFunctions();
|
|
139
171
|
return new Proxy({}, { get(_target, prop) {
|
|
140
172
|
const builtin = builtins[prop];
|
|
141
173
|
if (builtin) return builtin;
|
|
142
|
-
const
|
|
143
|
-
if (
|
|
174
|
+
const op = operations[prop];
|
|
175
|
+
if (op) return op.impl;
|
|
144
176
|
} });
|
|
145
177
|
}
|
|
146
|
-
function createAggregateFunctions(
|
|
147
|
-
const baseFns = createFunctions(
|
|
178
|
+
function createAggregateFunctions(operations) {
|
|
179
|
+
const baseFns = createFunctions(operations);
|
|
148
180
|
const aggregates = createAggregateOnlyFunctions();
|
|
149
181
|
return new Proxy({}, { get(_target, prop) {
|
|
150
182
|
const agg = aggregates[prop];
|
|
@@ -152,7 +184,6 @@ function createAggregateFunctions(queryOperationTypes) {
|
|
|
152
184
|
return baseFns[prop];
|
|
153
185
|
} });
|
|
154
186
|
}
|
|
155
|
-
|
|
156
187
|
//#endregion
|
|
157
188
|
//#region src/runtime/builder-base.ts
|
|
158
189
|
var BuilderBase = class {
|
|
@@ -195,6 +226,17 @@ function combineWhereExprs(exprs) {
|
|
|
195
226
|
if (exprs.length === 1) return exprs[0];
|
|
196
227
|
return AndExpr.of(exprs);
|
|
197
228
|
}
|
|
229
|
+
/**
|
|
230
|
+
* Same uniqueness rule as the field-proxy's `findUniqueNamespaceFor`: when exactly one namespace owns a top-level field, the binding is unambiguous. Used by `select('col', ...)` to attach `refs` metadata to the resulting `ProjectionItem` while keeping the AST as `IdentifierRef` (so SQL renders unchanged).
|
|
231
|
+
*/
|
|
232
|
+
function findUniqueNamespaceFor(scope, fieldName) {
|
|
233
|
+
let found;
|
|
234
|
+
for (const [namespace, fields] of Object.entries(scope.namespaces)) if (Object.hasOwn(fields, fieldName)) {
|
|
235
|
+
if (found !== void 0) return void 0;
|
|
236
|
+
found = namespace;
|
|
237
|
+
}
|
|
238
|
+
return found;
|
|
239
|
+
}
|
|
198
240
|
function buildSelectAst(state) {
|
|
199
241
|
const where = combineWhereExprs(state.where);
|
|
200
242
|
return new SelectAst({
|
|
@@ -212,36 +254,12 @@ function buildSelectAst(state) {
|
|
|
212
254
|
selectAllIntent: void 0
|
|
213
255
|
});
|
|
214
256
|
}
|
|
215
|
-
function buildQueryPlan(ast,
|
|
216
|
-
const
|
|
217
|
-
const codecs = {};
|
|
218
|
-
for (const [alias, field] of Object.entries(rowFields)) {
|
|
219
|
-
projectionTypes[alias] = field.codecId;
|
|
220
|
-
codecs[alias] = field.codecId;
|
|
221
|
-
}
|
|
222
|
-
const paramRefs = ast.collectParamRefs();
|
|
223
|
-
const seen = /* @__PURE__ */ new Set();
|
|
224
|
-
const uniqueRefs = [];
|
|
225
|
-
for (const ref of paramRefs) if (!seen.has(ref)) {
|
|
226
|
-
seen.add(ref);
|
|
227
|
-
uniqueRefs.push(ref);
|
|
228
|
-
}
|
|
229
|
-
const paramValues = uniqueRefs.map((r) => r.value);
|
|
230
|
-
const paramDescriptors = uniqueRefs.map((ref, i) => ({
|
|
231
|
-
index: i + 1,
|
|
232
|
-
source: "dsl",
|
|
233
|
-
...ref.codecId ? { codecId: ref.codecId } : {}
|
|
234
|
-
}));
|
|
235
|
-
for (const [i, ref] of uniqueRefs.entries()) if (ref.codecId) codecs[`$${i + 1}`] = ref.codecId;
|
|
236
|
-
const hasProjectionTypes = Object.keys(projectionTypes).length > 0;
|
|
237
|
-
const hasCodecs = Object.keys(codecs).length > 0;
|
|
257
|
+
function buildQueryPlan(ast, ctx) {
|
|
258
|
+
const paramValues = collectOrderedParamRefs(ast).map((r) => r.value);
|
|
238
259
|
const meta = Object.freeze({
|
|
239
260
|
target: ctx.target,
|
|
240
261
|
storageHash: ctx.storageHash,
|
|
241
|
-
lane: "dsl"
|
|
242
|
-
paramDescriptors,
|
|
243
|
-
...hasProjectionTypes ? { projectionTypes } : {},
|
|
244
|
-
...hasCodecs ? { annotations: Object.freeze({ codecs: Object.freeze(codecs) }) } : {}
|
|
262
|
+
lane: "dsl"
|
|
245
263
|
});
|
|
246
264
|
return Object.freeze({
|
|
247
265
|
ast,
|
|
@@ -250,7 +268,7 @@ function buildQueryPlan(ast, rowFields, ctx) {
|
|
|
250
268
|
});
|
|
251
269
|
}
|
|
252
270
|
function buildPlan(state, ctx) {
|
|
253
|
-
return buildQueryPlan(buildSelectAst(state),
|
|
271
|
+
return buildQueryPlan(buildSelectAst(state), ctx);
|
|
254
272
|
}
|
|
255
273
|
function tableToScope(name, table) {
|
|
256
274
|
const fields = {};
|
|
@@ -314,7 +332,12 @@ function resolveSelectArgs(args, scope, ctx) {
|
|
|
314
332
|
for (const colName of args) {
|
|
315
333
|
const field = scope.topLevel[colName];
|
|
316
334
|
if (!field) throw new Error(`Column "${colName}" not found in scope`);
|
|
317
|
-
|
|
335
|
+
const namespace = findUniqueNamespaceFor(scope, colName);
|
|
336
|
+
const refs = namespace ? {
|
|
337
|
+
table: namespace,
|
|
338
|
+
column: colName
|
|
339
|
+
} : void 0;
|
|
340
|
+
projections.push(ProjectionItem.of(colName, IdentifierRef.of(colName), field.codecId, refs));
|
|
318
341
|
newRowFields[colName] = field;
|
|
319
342
|
}
|
|
320
343
|
return {
|
|
@@ -327,8 +350,9 @@ function resolveSelectArgs(args, scope, ctx) {
|
|
|
327
350
|
const exprFn = args[1];
|
|
328
351
|
const fns = createAggregateFunctions(ctx.queryOperationTypes);
|
|
329
352
|
const result = exprFn(createFieldProxy(scope), fns);
|
|
330
|
-
|
|
331
|
-
|
|
353
|
+
const field = result.returnType;
|
|
354
|
+
projections.push(ProjectionItem.of(alias, result.buildAst(), field.codecId));
|
|
355
|
+
newRowFields[alias] = field;
|
|
332
356
|
return {
|
|
333
357
|
projections,
|
|
334
358
|
newRowFields
|
|
@@ -339,8 +363,9 @@ function resolveSelectArgs(args, scope, ctx) {
|
|
|
339
363
|
const fns = createAggregateFunctions(ctx.queryOperationTypes);
|
|
340
364
|
const record = callbackFn(createFieldProxy(scope), fns);
|
|
341
365
|
for (const [key, expr] of Object.entries(record)) {
|
|
342
|
-
|
|
343
|
-
|
|
366
|
+
const field = expr.returnType;
|
|
367
|
+
projections.push(ProjectionItem.of(key, expr.buildAst(), field.codecId));
|
|
368
|
+
newRowFields[key] = field;
|
|
344
369
|
}
|
|
345
370
|
return {
|
|
346
371
|
projections,
|
|
@@ -381,9 +406,9 @@ function resolveGroupBy(args, scope, rowFields, ctx) {
|
|
|
381
406
|
}
|
|
382
407
|
function resolveDistinctOn(args, scope, rowFields, ctx) {
|
|
383
408
|
if (args.length === 1 && typeof args[0] === "function") {
|
|
384
|
-
const combined
|
|
409
|
+
const combined = orderByScopeOf(scope, rowFields);
|
|
385
410
|
const fns = createFunctions(ctx.queryOperationTypes);
|
|
386
|
-
return [args[0](createFieldProxy(combined
|
|
411
|
+
return [args[0](createFieldProxy(combined), fns).buildAst()];
|
|
387
412
|
}
|
|
388
413
|
const combined = orderByScopeOf(scope, rowFields);
|
|
389
414
|
return args.map((colName) => {
|
|
@@ -391,7 +416,6 @@ function resolveDistinctOn(args, scope, rowFields, ctx) {
|
|
|
391
416
|
return IdentifierRef.of(colName);
|
|
392
417
|
});
|
|
393
418
|
}
|
|
394
|
-
|
|
395
419
|
//#endregion
|
|
396
420
|
//#region src/runtime/query-impl.ts
|
|
397
421
|
var QueryBase = class extends BuilderBase {
|
|
@@ -477,7 +501,6 @@ var GroupedQueryImpl = class GroupedQueryImpl extends QueryBase {
|
|
|
477
501
|
return this.clone(cloneState(this.state, { orderBy: [...this.state.orderBy, item] }));
|
|
478
502
|
}
|
|
479
503
|
};
|
|
480
|
-
|
|
481
504
|
//#endregion
|
|
482
505
|
//#region src/runtime/joined-tables-impl.ts
|
|
483
506
|
var JoinedTablesImpl = class JoinedTablesImpl extends BuilderBase {
|
|
@@ -555,14 +578,19 @@ var JoinedTablesImpl = class JoinedTablesImpl extends BuilderBase {
|
|
|
555
578
|
}), this.ctx);
|
|
556
579
|
}
|
|
557
580
|
};
|
|
558
|
-
|
|
559
581
|
//#endregion
|
|
560
582
|
//#region src/runtime/mutation-impl.ts
|
|
561
583
|
function buildParamValues(values, table, tableName, op, ctx) {
|
|
562
584
|
const params = {};
|
|
563
585
|
for (const [col, value] of Object.entries(values)) {
|
|
564
586
|
const column = table.columns[col];
|
|
565
|
-
params[col] = ParamRef.of(value, column ? {
|
|
587
|
+
params[col] = ParamRef.of(value, column ? {
|
|
588
|
+
codecId: column.codecId,
|
|
589
|
+
refs: {
|
|
590
|
+
table: tableName,
|
|
591
|
+
column: col
|
|
592
|
+
}
|
|
593
|
+
} : void 0);
|
|
566
594
|
}
|
|
567
595
|
for (const def of ctx.applyMutationDefaults({
|
|
568
596
|
op,
|
|
@@ -570,12 +598,18 @@ function buildParamValues(values, table, tableName, op, ctx) {
|
|
|
570
598
|
values
|
|
571
599
|
})) {
|
|
572
600
|
const column = table.columns[def.column];
|
|
573
|
-
params[def.column] = ParamRef.of(def.value, column ? {
|
|
601
|
+
params[def.column] = ParamRef.of(def.value, column ? {
|
|
602
|
+
codecId: column.codecId,
|
|
603
|
+
refs: {
|
|
604
|
+
table: tableName,
|
|
605
|
+
column: def.column
|
|
606
|
+
}
|
|
607
|
+
} : void 0);
|
|
574
608
|
}
|
|
575
609
|
return params;
|
|
576
610
|
}
|
|
577
|
-
function
|
|
578
|
-
return columns.map((col) => ColumnRef.of(tableName, col));
|
|
611
|
+
function buildReturningProjections(tableName, columns, rowFields) {
|
|
612
|
+
return columns.map((col) => ProjectionItem.of(col, ColumnRef.of(tableName, col), rowFields[col]?.codecId));
|
|
579
613
|
}
|
|
580
614
|
function evaluateWhere(whereCallback, scope, queryOperationTypes) {
|
|
581
615
|
return whereCallback(createFieldProxy(scope), createFunctions(queryOperationTypes)).buildAst();
|
|
@@ -608,8 +642,8 @@ var InsertQueryImpl = class InsertQueryImpl extends BuilderBase {
|
|
|
608
642
|
build() {
|
|
609
643
|
const paramValues = buildParamValues(this.#values, this.#table, this.#tableName, "create", this.ctx);
|
|
610
644
|
let ast = InsertAst.into(TableSource.named(this.#tableName)).withValues(paramValues);
|
|
611
|
-
if (this.#returningColumns.length > 0) ast = ast.withReturning(
|
|
612
|
-
return buildQueryPlan(ast, this
|
|
645
|
+
if (this.#returningColumns.length > 0) ast = ast.withReturning(buildReturningProjections(this.#tableName, this.#returningColumns, this.#rowFields));
|
|
646
|
+
return buildQueryPlan(ast, this.ctx);
|
|
613
647
|
}
|
|
614
648
|
};
|
|
615
649
|
var UpdateQueryImpl = class UpdateQueryImpl extends BuilderBase {
|
|
@@ -646,8 +680,8 @@ var UpdateQueryImpl = class UpdateQueryImpl extends BuilderBase {
|
|
|
646
680
|
const setParams = buildParamValues(this.#setValues, this.#table, this.#tableName, "update", this.ctx);
|
|
647
681
|
const whereExpr = combineWhereExprs(this.#whereCallbacks.map((cb) => evaluateWhere(cb, this.#scope, this.ctx.queryOperationTypes)));
|
|
648
682
|
let ast = UpdateAst.table(TableSource.named(this.#tableName)).withSet(setParams).withWhere(whereExpr);
|
|
649
|
-
if (this.#returningColumns.length > 0) ast = ast.withReturning(
|
|
650
|
-
return buildQueryPlan(ast, this
|
|
683
|
+
if (this.#returningColumns.length > 0) ast = ast.withReturning(buildReturningProjections(this.#tableName, this.#returningColumns, this.#rowFields));
|
|
684
|
+
return buildQueryPlan(ast, this.ctx);
|
|
651
685
|
}
|
|
652
686
|
};
|
|
653
687
|
var DeleteQueryImpl = class DeleteQueryImpl extends BuilderBase {
|
|
@@ -679,11 +713,10 @@ var DeleteQueryImpl = class DeleteQueryImpl extends BuilderBase {
|
|
|
679
713
|
build() {
|
|
680
714
|
const whereExpr = combineWhereExprs(this.#whereCallbacks.map((cb) => evaluateWhere(cb, this.#scope, this.ctx.queryOperationTypes)));
|
|
681
715
|
let ast = DeleteAst.from(TableSource.named(this.#tableName)).withWhere(whereExpr);
|
|
682
|
-
if (this.#returningColumns.length > 0) ast = ast.withReturning(
|
|
683
|
-
return buildQueryPlan(ast, this
|
|
716
|
+
if (this.#returningColumns.length > 0) ast = ast.withReturning(buildReturningProjections(this.#tableName, this.#returningColumns, this.#rowFields));
|
|
717
|
+
return buildQueryPlan(ast, this.ctx);
|
|
684
718
|
}
|
|
685
719
|
};
|
|
686
|
-
|
|
687
720
|
//#endregion
|
|
688
721
|
//#region src/runtime/table-proxy-impl.ts
|
|
689
722
|
var TableProxyImpl = class TableProxyImpl extends BuilderBase {
|
|
@@ -741,7 +774,6 @@ var TableProxyImpl = class TableProxyImpl extends BuilderBase {
|
|
|
741
774
|
return new JoinedTablesImpl(emptyState(this.#fromSource, this.#scope), this.ctx);
|
|
742
775
|
}
|
|
743
776
|
};
|
|
744
|
-
|
|
745
777
|
//#endregion
|
|
746
778
|
//#region src/runtime/sql.ts
|
|
747
779
|
function sql(options) {
|
|
@@ -751,7 +783,7 @@ function sql(options) {
|
|
|
751
783
|
queryOperationTypes: context.queryOperations.entries(),
|
|
752
784
|
target: context.contract.target ?? "unknown",
|
|
753
785
|
storageHash: context.contract.storage.storageHash ?? "unknown",
|
|
754
|
-
applyMutationDefaults: (options
|
|
786
|
+
applyMutationDefaults: (options) => context.applyMutationDefaults(options)
|
|
755
787
|
};
|
|
756
788
|
return new Proxy({}, { get(_target, prop) {
|
|
757
789
|
const tables = context.contract.storage.tables;
|
|
@@ -759,7 +791,7 @@ function sql(options) {
|
|
|
759
791
|
if (table) return new TableProxyImpl(prop, table, prop, ctx);
|
|
760
792
|
} });
|
|
761
793
|
}
|
|
762
|
-
|
|
763
794
|
//#endregion
|
|
764
795
|
export { ExpressionImpl, createAggregateFunctions, createFieldProxy, createFunctions, sql };
|
|
796
|
+
|
|
765
797
|
//# sourceMappingURL=index.mjs.map
|