@prisma-next/sql-lane 0.0.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/README.md +62 -0
- package/dist/chunk-5OSV5CZC.js +1545 -0
- package/dist/chunk-5OSV5CZC.js.map +1 -0
- package/dist/exports/sql.d.ts +5 -0
- package/dist/exports/sql.js +11 -0
- package/dist/exports/sql.js.map +1 -0
- package/dist/index.d.ts +171 -0
- package/dist/index.js +11 -0
- package/dist/index.js.map +1 -0
- package/package.json +44 -0
|
@@ -0,0 +1,1545 @@
|
|
|
1
|
+
// src/raw.ts
|
|
2
|
+
import { planInvalid } from "@prisma-next/plan";
|
|
3
|
+
var POSTGRES_TARGET = "postgres";
|
|
4
|
+
var RAW_OPTIONS_SENTINEL = Symbol("rawOptions");
|
|
5
|
+
function createRawFactory(contract) {
|
|
6
|
+
if (contract.target !== POSTGRES_TARGET) {
|
|
7
|
+
throw planInvalid("Raw lane currently supports only postgres target", {
|
|
8
|
+
expectedTarget: POSTGRES_TARGET,
|
|
9
|
+
actualTarget: contract.target
|
|
10
|
+
});
|
|
11
|
+
}
|
|
12
|
+
const factory = ((first, ...rest) => {
|
|
13
|
+
if (isTemplateInvocation(first)) {
|
|
14
|
+
const { values, options: options2 } = splitTemplateValues(rest);
|
|
15
|
+
const compiled = compileTemplateToPositional(first, values);
|
|
16
|
+
return buildRawPlan({
|
|
17
|
+
contract,
|
|
18
|
+
sql: compiled.sql,
|
|
19
|
+
params: compiled.params,
|
|
20
|
+
paramDescriptors: compiled.paramDescriptors,
|
|
21
|
+
...options2 ? { options: options2 } : {}
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
const text = first;
|
|
25
|
+
const [options] = rest;
|
|
26
|
+
if (!options) {
|
|
27
|
+
throw planInvalid("Function form requires params option");
|
|
28
|
+
}
|
|
29
|
+
if (!Array.isArray(options.params)) {
|
|
30
|
+
throw planInvalid("Function form params must be an array");
|
|
31
|
+
}
|
|
32
|
+
const paramDescriptors = buildSequentialDescriptors(options.params.length);
|
|
33
|
+
return buildRawPlan({
|
|
34
|
+
contract,
|
|
35
|
+
sql: text,
|
|
36
|
+
params: options.params,
|
|
37
|
+
paramDescriptors,
|
|
38
|
+
options
|
|
39
|
+
});
|
|
40
|
+
});
|
|
41
|
+
factory.with = (options) => {
|
|
42
|
+
return ((strings, ...values) => {
|
|
43
|
+
const compiled = compileTemplateToPositional(strings, values);
|
|
44
|
+
return buildRawPlan({
|
|
45
|
+
contract,
|
|
46
|
+
sql: compiled.sql,
|
|
47
|
+
params: compiled.params,
|
|
48
|
+
paramDescriptors: compiled.paramDescriptors,
|
|
49
|
+
options
|
|
50
|
+
});
|
|
51
|
+
});
|
|
52
|
+
};
|
|
53
|
+
return factory;
|
|
54
|
+
}
|
|
55
|
+
function compileTemplateToPositional(strings, values) {
|
|
56
|
+
let sql2 = "";
|
|
57
|
+
const params = [];
|
|
58
|
+
const paramDescriptors = [];
|
|
59
|
+
strings.forEach((part, index) => {
|
|
60
|
+
sql2 += part;
|
|
61
|
+
if (index < values.length) {
|
|
62
|
+
const value = values[index];
|
|
63
|
+
const placeholderIndex = params.push(value);
|
|
64
|
+
sql2 += `$${placeholderIndex}`;
|
|
65
|
+
paramDescriptors.push({
|
|
66
|
+
index: placeholderIndex,
|
|
67
|
+
name: `p${placeholderIndex}`,
|
|
68
|
+
source: "raw"
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
return {
|
|
73
|
+
sql: sql2,
|
|
74
|
+
params,
|
|
75
|
+
paramDescriptors
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
function buildRawPlan(args) {
|
|
79
|
+
const params = Array.from(args.params);
|
|
80
|
+
const descriptors = args.paramDescriptors.map(
|
|
81
|
+
(descriptor) => Object.freeze({ ...descriptor, source: "raw" })
|
|
82
|
+
);
|
|
83
|
+
const meta = buildRawMeta({
|
|
84
|
+
contract: args.contract,
|
|
85
|
+
paramDescriptors: descriptors,
|
|
86
|
+
...args.options ? { options: args.options } : {}
|
|
87
|
+
});
|
|
88
|
+
return Object.freeze({
|
|
89
|
+
sql: args.sql,
|
|
90
|
+
params: Object.freeze(params),
|
|
91
|
+
meta
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
function buildRawMeta(args) {
|
|
95
|
+
const { contract, paramDescriptors, options } = args;
|
|
96
|
+
const meta = {
|
|
97
|
+
target: POSTGRES_TARGET,
|
|
98
|
+
...contract.targetFamily ? { targetFamily: contract.targetFamily } : {},
|
|
99
|
+
coreHash: contract.coreHash,
|
|
100
|
+
...contract.profileHash !== void 0 ? { profileHash: contract.profileHash } : {},
|
|
101
|
+
lane: "raw",
|
|
102
|
+
paramDescriptors: Object.freeze([...paramDescriptors]),
|
|
103
|
+
...options?.annotations ? { annotations: Object.freeze({ ...options.annotations }) } : {},
|
|
104
|
+
...options?.refs ? { refs: freezeRefs(options.refs) } : {},
|
|
105
|
+
...options?.projection ? { projection: Object.freeze([...options.projection]) } : {}
|
|
106
|
+
};
|
|
107
|
+
return Object.freeze(meta);
|
|
108
|
+
}
|
|
109
|
+
function freezeRefs(refs) {
|
|
110
|
+
return Object.freeze({
|
|
111
|
+
...refs.tables ? { tables: Object.freeze([...refs.tables]) } : {},
|
|
112
|
+
...refs.columns ? {
|
|
113
|
+
columns: Object.freeze(
|
|
114
|
+
refs.columns.map((col) => Object.freeze({ ...col }))
|
|
115
|
+
)
|
|
116
|
+
} : {},
|
|
117
|
+
...refs.indexes ? {
|
|
118
|
+
indexes: Object.freeze(
|
|
119
|
+
refs.indexes.map(
|
|
120
|
+
(index) => Object.freeze({
|
|
121
|
+
...index,
|
|
122
|
+
columns: Object.freeze([...index.columns])
|
|
123
|
+
})
|
|
124
|
+
)
|
|
125
|
+
)
|
|
126
|
+
} : {}
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
function buildSequentialDescriptors(count) {
|
|
130
|
+
return Array.from(
|
|
131
|
+
{ length: count },
|
|
132
|
+
(_, idx) => Object.freeze({
|
|
133
|
+
index: idx + 1,
|
|
134
|
+
name: `p${idx + 1}`,
|
|
135
|
+
source: "raw"
|
|
136
|
+
})
|
|
137
|
+
);
|
|
138
|
+
}
|
|
139
|
+
function isTemplateInvocation(value) {
|
|
140
|
+
return Array.isArray(value) && Object.hasOwn(value, "raw");
|
|
141
|
+
}
|
|
142
|
+
function rawOptions(options) {
|
|
143
|
+
return Object.freeze({
|
|
144
|
+
[RAW_OPTIONS_SENTINEL]: true,
|
|
145
|
+
value: options
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
function splitTemplateValues(values) {
|
|
149
|
+
if (values.length === 0) {
|
|
150
|
+
return { values };
|
|
151
|
+
}
|
|
152
|
+
const last = values[values.length - 1];
|
|
153
|
+
if (!isOptionsSentinel(last)) {
|
|
154
|
+
return { values };
|
|
155
|
+
}
|
|
156
|
+
return {
|
|
157
|
+
values: values.slice(0, values.length - 1),
|
|
158
|
+
options: last.value
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
function isOptionsSentinel(value) {
|
|
162
|
+
return typeof value === "object" && value !== null && RAW_OPTIONS_SENTINEL in value;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
// src/sql/builder.ts
|
|
166
|
+
import { createJoinOnBuilder as createJoinOnBuilder2 } from "@prisma-next/sql-relational-core/ast";
|
|
167
|
+
|
|
168
|
+
// src/sql/mutation-builder.ts
|
|
169
|
+
import {
|
|
170
|
+
createColumnRef as createColumnRef2,
|
|
171
|
+
createDeleteAst,
|
|
172
|
+
createInsertAst,
|
|
173
|
+
createParamRef as createParamRef2,
|
|
174
|
+
createTableRef,
|
|
175
|
+
createUpdateAst
|
|
176
|
+
} from "@prisma-next/sql-relational-core/ast";
|
|
177
|
+
|
|
178
|
+
// src/utils/errors.ts
|
|
179
|
+
import { planInvalid as planInvalid2 } from "@prisma-next/plan";
|
|
180
|
+
function errorAliasPathEmpty() {
|
|
181
|
+
throw planInvalid2("Alias path cannot be empty");
|
|
182
|
+
}
|
|
183
|
+
function errorAliasCollision(path, alias, existingPath) {
|
|
184
|
+
throw planInvalid2(
|
|
185
|
+
`Alias collision: path ${path.join(".")} would generate alias "${alias}" which conflicts with path ${existingPath?.join(".") ?? "unknown"}`
|
|
186
|
+
);
|
|
187
|
+
}
|
|
188
|
+
function errorLimitMustBeNonNegativeInteger() {
|
|
189
|
+
throw planInvalid2("Limit must be a non-negative integer");
|
|
190
|
+
}
|
|
191
|
+
function errorChildProjectionMustBeSpecified() {
|
|
192
|
+
throw planInvalid2("Child projection must be specified");
|
|
193
|
+
}
|
|
194
|
+
function errorIncludeRequiresCapabilities(target) {
|
|
195
|
+
throw planInvalid2(
|
|
196
|
+
"includeMany requires lateral and jsonAgg capabilities",
|
|
197
|
+
target ? { target } : void 0,
|
|
198
|
+
[
|
|
199
|
+
"Enable capabilities for your target in contract.capabilities[target]",
|
|
200
|
+
"For SQL includes, set both 'lateral' and 'jsonAgg' to true",
|
|
201
|
+
"If your database lacks lateral/json_agg, use explicit joins + group aggregates"
|
|
202
|
+
],
|
|
203
|
+
[
|
|
204
|
+
"docs/Architecture Overview.md",
|
|
205
|
+
"docs/reference/extensions-glossary.md",
|
|
206
|
+
"packages/targets/postgres-adapter/README.md"
|
|
207
|
+
]
|
|
208
|
+
);
|
|
209
|
+
}
|
|
210
|
+
function errorIncludeCapabilitiesNotTrue(target, values) {
|
|
211
|
+
throw planInvalid2(
|
|
212
|
+
"includeMany requires lateral and jsonAgg capabilities to be true",
|
|
213
|
+
target ? { target, values } : void 0,
|
|
214
|
+
[
|
|
215
|
+
"Set contract.capabilities[target].lateral = true and .jsonAgg = true",
|
|
216
|
+
"If the target does not support these, avoid includeMany and compose a two-step plan"
|
|
217
|
+
],
|
|
218
|
+
[
|
|
219
|
+
"docs/Architecture Overview.md",
|
|
220
|
+
"docs/reference/extensions-glossary.md",
|
|
221
|
+
"packages/targets/postgres-adapter/README.md"
|
|
222
|
+
]
|
|
223
|
+
);
|
|
224
|
+
}
|
|
225
|
+
function errorUnknownTable(tableName) {
|
|
226
|
+
throw planInvalid2(`Unknown table ${tableName}`);
|
|
227
|
+
}
|
|
228
|
+
function errorSelfJoinNotSupported() {
|
|
229
|
+
throw planInvalid2("Self-joins are not supported in MVP");
|
|
230
|
+
}
|
|
231
|
+
function errorChildProjectionEmpty() {
|
|
232
|
+
throw planInvalid2("Child projection must not be empty");
|
|
233
|
+
}
|
|
234
|
+
function errorIncludeAliasCollision(alias, type) {
|
|
235
|
+
throw planInvalid2(
|
|
236
|
+
`Alias collision: include alias "${alias}" conflicts with existing ${type} alias`
|
|
237
|
+
);
|
|
238
|
+
}
|
|
239
|
+
function errorMissingColumnForAlias(alias, index) {
|
|
240
|
+
throw planInvalid2(`Missing column for alias ${alias ?? "unknown"} at index ${index}`);
|
|
241
|
+
}
|
|
242
|
+
function errorMissingAlias(index) {
|
|
243
|
+
throw planInvalid2(`Missing alias at index ${index}`);
|
|
244
|
+
}
|
|
245
|
+
function errorInvalidColumnForAlias(alias, index) {
|
|
246
|
+
throw planInvalid2(`Invalid column for alias ${alias} at index ${index}`);
|
|
247
|
+
}
|
|
248
|
+
function errorFromMustBeCalled() {
|
|
249
|
+
throw planInvalid2("from() must be called before building a query");
|
|
250
|
+
}
|
|
251
|
+
function errorSelectMustBeCalled() {
|
|
252
|
+
throw planInvalid2("select() must be called before build()");
|
|
253
|
+
}
|
|
254
|
+
function errorMissingParameter(paramName) {
|
|
255
|
+
throw planInvalid2(`Missing value for parameter ${paramName}`);
|
|
256
|
+
}
|
|
257
|
+
function errorInvalidProjectionValue(path) {
|
|
258
|
+
throw planInvalid2(
|
|
259
|
+
`Invalid projection value at path ${path.join(".")}: expected ColumnBuilder or nested object`
|
|
260
|
+
);
|
|
261
|
+
}
|
|
262
|
+
function errorIncludeAliasNotFound(alias) {
|
|
263
|
+
throw planInvalid2(
|
|
264
|
+
`Include alias "${alias}" not found. Did you call includeMany() with alias "${alias}"?`
|
|
265
|
+
);
|
|
266
|
+
}
|
|
267
|
+
function errorInvalidProjectionKey(key) {
|
|
268
|
+
throw planInvalid2(
|
|
269
|
+
`Invalid projection value at key "${key}": expected ColumnBuilder, boolean true (for includes), or nested object`
|
|
270
|
+
);
|
|
271
|
+
}
|
|
272
|
+
function errorProjectionEmpty() {
|
|
273
|
+
throw planInvalid2("select() requires at least one column or include");
|
|
274
|
+
}
|
|
275
|
+
function errorReturningRequiresCapability(target) {
|
|
276
|
+
throw planInvalid2(
|
|
277
|
+
"returning() requires returning capability",
|
|
278
|
+
target ? { target } : void 0,
|
|
279
|
+
[
|
|
280
|
+
"Enable 'returning' for your target in contract.capabilities[target]",
|
|
281
|
+
"PostgreSQL supports RETURNING; MySQL does not",
|
|
282
|
+
"If unsupported, remove returning() and fetch with a follow-up select()"
|
|
283
|
+
],
|
|
284
|
+
[
|
|
285
|
+
"docs/Architecture Overview.md",
|
|
286
|
+
"docs/reference/extensions-glossary.md",
|
|
287
|
+
"packages/targets/postgres-adapter/README.md"
|
|
288
|
+
]
|
|
289
|
+
);
|
|
290
|
+
}
|
|
291
|
+
function errorReturningCapabilityNotTrue(target, value) {
|
|
292
|
+
throw planInvalid2(
|
|
293
|
+
"returning() requires returning capability to be true",
|
|
294
|
+
target ? { target, value } : void 0,
|
|
295
|
+
[
|
|
296
|
+
"Set contract.capabilities[target].returning = true",
|
|
297
|
+
"If your database/adapter cannot support RETURNING, remove returning() and select after"
|
|
298
|
+
],
|
|
299
|
+
[
|
|
300
|
+
"docs/Architecture Overview.md",
|
|
301
|
+
"docs/reference/extensions-glossary.md",
|
|
302
|
+
"packages/targets/postgres-adapter/README.md"
|
|
303
|
+
]
|
|
304
|
+
);
|
|
305
|
+
}
|
|
306
|
+
function errorUnknownColumn(columnName, tableName) {
|
|
307
|
+
throw planInvalid2(`Unknown column ${columnName} in table ${tableName}`);
|
|
308
|
+
}
|
|
309
|
+
function errorWhereMustBeCalledForUpdate() {
|
|
310
|
+
throw planInvalid2("where() must be called before building an UPDATE query");
|
|
311
|
+
}
|
|
312
|
+
function errorFailedToBuildWhereClause() {
|
|
313
|
+
throw planInvalid2("Failed to build WHERE clause");
|
|
314
|
+
}
|
|
315
|
+
function errorWhereMustBeCalledForDelete() {
|
|
316
|
+
throw planInvalid2("where() must be called before building a DELETE query");
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
// src/utils/capabilities.ts
|
|
320
|
+
function checkIncludeCapabilities(contract) {
|
|
321
|
+
const target = contract.target;
|
|
322
|
+
const contractCapabilities = contract.capabilities;
|
|
323
|
+
const declaredTargetCapabilities = contractCapabilities?.[target];
|
|
324
|
+
if (!contractCapabilities || !declaredTargetCapabilities) {
|
|
325
|
+
errorIncludeRequiresCapabilities(target);
|
|
326
|
+
}
|
|
327
|
+
if (declaredTargetCapabilities["lateral"] !== true || declaredTargetCapabilities["jsonAgg"] !== true) {
|
|
328
|
+
errorIncludeCapabilitiesNotTrue(target, {
|
|
329
|
+
lateral: declaredTargetCapabilities["lateral"],
|
|
330
|
+
jsonAgg: declaredTargetCapabilities["jsonAgg"]
|
|
331
|
+
});
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
function checkReturningCapability(contract) {
|
|
335
|
+
const target = contract.target;
|
|
336
|
+
const capabilities = contract.capabilities;
|
|
337
|
+
if (!capabilities || !capabilities[target]) {
|
|
338
|
+
errorReturningRequiresCapability(target);
|
|
339
|
+
}
|
|
340
|
+
const targetCapabilities = capabilities[target];
|
|
341
|
+
if (targetCapabilities["returning"] !== true) {
|
|
342
|
+
errorReturningCapabilityNotTrue(target, targetCapabilities["returning"]);
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
// src/sql/plan.ts
|
|
347
|
+
import { compact } from "@prisma-next/sql-relational-core/ast";
|
|
348
|
+
|
|
349
|
+
// src/utils/guards.ts
|
|
350
|
+
function extractBaseColumnRef(expr) {
|
|
351
|
+
if (expr.kind === "col") {
|
|
352
|
+
return expr;
|
|
353
|
+
}
|
|
354
|
+
return extractBaseColumnRef(expr.self);
|
|
355
|
+
}
|
|
356
|
+
function collectColumnRefs(expr) {
|
|
357
|
+
if (expr.kind === "col") {
|
|
358
|
+
return [expr];
|
|
359
|
+
}
|
|
360
|
+
if (expr.kind === "operation") {
|
|
361
|
+
const refs = collectColumnRefs(expr.self);
|
|
362
|
+
for (const arg of expr.args) {
|
|
363
|
+
refs.push(...collectColumnRefs(arg));
|
|
364
|
+
}
|
|
365
|
+
return refs;
|
|
366
|
+
}
|
|
367
|
+
return [];
|
|
368
|
+
}
|
|
369
|
+
function isOperationExpr(expr) {
|
|
370
|
+
return typeof expr === "object" && expr !== null && "kind" in expr && expr.kind === "operation";
|
|
371
|
+
}
|
|
372
|
+
function getColumnInfo(expr) {
|
|
373
|
+
if (isOperationExpr(expr)) {
|
|
374
|
+
const baseCol = extractBaseColumnRef(expr);
|
|
375
|
+
return { table: baseCol.table, column: baseCol.column };
|
|
376
|
+
}
|
|
377
|
+
const colBuilder = expr;
|
|
378
|
+
return { table: colBuilder.table, column: colBuilder.column };
|
|
379
|
+
}
|
|
380
|
+
function isColumnBuilder(value) {
|
|
381
|
+
return typeof value === "object" && value !== null && "kind" in value && value.kind === "column";
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
// src/sql/plan.ts
|
|
385
|
+
function buildMeta(args) {
|
|
386
|
+
const refsColumns = /* @__PURE__ */ new Map();
|
|
387
|
+
const refsTables = /* @__PURE__ */ new Set([args.table.name]);
|
|
388
|
+
for (const column of args.projection.columns) {
|
|
389
|
+
const operationExpr = column._operationExpr;
|
|
390
|
+
if (operationExpr) {
|
|
391
|
+
const allRefs = collectColumnRefs(operationExpr);
|
|
392
|
+
for (const ref of allRefs) {
|
|
393
|
+
refsColumns.set(`${ref.table}.${ref.column}`, {
|
|
394
|
+
table: ref.table,
|
|
395
|
+
column: ref.column
|
|
396
|
+
});
|
|
397
|
+
}
|
|
398
|
+
} else {
|
|
399
|
+
const col = column;
|
|
400
|
+
if (col.table && col.column) {
|
|
401
|
+
refsColumns.set(`${col.table}.${col.column}`, {
|
|
402
|
+
table: col.table,
|
|
403
|
+
column: col.column
|
|
404
|
+
});
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
if (args.joins) {
|
|
409
|
+
for (const join of args.joins) {
|
|
410
|
+
refsTables.add(join.table.name);
|
|
411
|
+
const onLeft = join.on.left;
|
|
412
|
+
const onRight = join.on.right;
|
|
413
|
+
refsColumns.set(`${onLeft.table}.${onLeft.column}`, {
|
|
414
|
+
table: onLeft.table,
|
|
415
|
+
column: onLeft.column
|
|
416
|
+
});
|
|
417
|
+
refsColumns.set(`${onRight.table}.${onRight.column}`, {
|
|
418
|
+
table: onRight.table,
|
|
419
|
+
column: onRight.column
|
|
420
|
+
});
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
if (args.includes) {
|
|
424
|
+
for (const include of args.includes) {
|
|
425
|
+
refsTables.add(include.table.name);
|
|
426
|
+
const onLeft = include.on.left;
|
|
427
|
+
const onRight = include.on.right;
|
|
428
|
+
if (onLeft.table && onLeft.column && onRight.table && onRight.column) {
|
|
429
|
+
refsColumns.set(`${onLeft.table}.${onLeft.column}`, {
|
|
430
|
+
table: onLeft.table,
|
|
431
|
+
column: onLeft.column
|
|
432
|
+
});
|
|
433
|
+
refsColumns.set(`${onRight.table}.${onRight.column}`, {
|
|
434
|
+
table: onRight.table,
|
|
435
|
+
column: onRight.column
|
|
436
|
+
});
|
|
437
|
+
}
|
|
438
|
+
for (const column of include.childProjection.columns) {
|
|
439
|
+
const col = column;
|
|
440
|
+
if (col.table && col.column) {
|
|
441
|
+
refsColumns.set(`${col.table}.${col.column}`, {
|
|
442
|
+
table: col.table,
|
|
443
|
+
column: col.column
|
|
444
|
+
});
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
if (include.childWhere) {
|
|
448
|
+
const colInfo = getColumnInfo(include.childWhere.left);
|
|
449
|
+
refsColumns.set(`${colInfo.table}.${colInfo.column}`, {
|
|
450
|
+
table: colInfo.table,
|
|
451
|
+
column: colInfo.column
|
|
452
|
+
});
|
|
453
|
+
}
|
|
454
|
+
if (include.childOrderBy) {
|
|
455
|
+
const orderBy = include.childOrderBy;
|
|
456
|
+
if (orderBy.expr) {
|
|
457
|
+
const colInfo = getColumnInfo(orderBy.expr);
|
|
458
|
+
refsColumns.set(`${colInfo.table}.${colInfo.column}`, {
|
|
459
|
+
table: colInfo.table,
|
|
460
|
+
column: colInfo.column
|
|
461
|
+
});
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
if (args.where) {
|
|
467
|
+
const whereLeft = args.where.left;
|
|
468
|
+
const operationExpr = whereLeft._operationExpr;
|
|
469
|
+
if (operationExpr) {
|
|
470
|
+
const allRefs = collectColumnRefs(operationExpr);
|
|
471
|
+
for (const ref of allRefs) {
|
|
472
|
+
refsColumns.set(`${ref.table}.${ref.column}`, {
|
|
473
|
+
table: ref.table,
|
|
474
|
+
column: ref.column
|
|
475
|
+
});
|
|
476
|
+
}
|
|
477
|
+
} else {
|
|
478
|
+
const colBuilder = whereLeft;
|
|
479
|
+
if (colBuilder.table && colBuilder.column) {
|
|
480
|
+
refsColumns.set(`${colBuilder.table}.${colBuilder.column}`, {
|
|
481
|
+
table: colBuilder.table,
|
|
482
|
+
column: colBuilder.column
|
|
483
|
+
});
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
if (args.orderBy) {
|
|
488
|
+
const orderBy = args.orderBy;
|
|
489
|
+
const orderByExpr = orderBy.expr;
|
|
490
|
+
if (orderByExpr) {
|
|
491
|
+
if (isOperationExpr(orderByExpr)) {
|
|
492
|
+
const allRefs = collectColumnRefs(orderByExpr);
|
|
493
|
+
for (const ref of allRefs) {
|
|
494
|
+
refsColumns.set(`${ref.table}.${ref.column}`, {
|
|
495
|
+
table: ref.table,
|
|
496
|
+
column: ref.column
|
|
497
|
+
});
|
|
498
|
+
}
|
|
499
|
+
} else {
|
|
500
|
+
const colBuilder = orderByExpr;
|
|
501
|
+
if (colBuilder.table && colBuilder.column) {
|
|
502
|
+
refsColumns.set(`${colBuilder.table}.${colBuilder.column}`, {
|
|
503
|
+
table: colBuilder.table,
|
|
504
|
+
column: colBuilder.column
|
|
505
|
+
});
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
const includeAliases = new Set(args.includes?.map((inc) => inc.alias) ?? []);
|
|
511
|
+
const projectionMap = Object.fromEntries(
|
|
512
|
+
args.projection.aliases.map((alias, index) => {
|
|
513
|
+
if (includeAliases.has(alias)) {
|
|
514
|
+
return [alias, `include:${alias}`];
|
|
515
|
+
}
|
|
516
|
+
const column = args.projection.columns[index];
|
|
517
|
+
if (!column) {
|
|
518
|
+
errorMissingColumnForAlias(alias, index);
|
|
519
|
+
}
|
|
520
|
+
const col = column;
|
|
521
|
+
if (!col.table || !col.column) {
|
|
522
|
+
return [alias, `include:${alias}`];
|
|
523
|
+
}
|
|
524
|
+
const operationExpr = col._operationExpr;
|
|
525
|
+
if (operationExpr) {
|
|
526
|
+
return [alias, `operation:${operationExpr.method}`];
|
|
527
|
+
}
|
|
528
|
+
return [alias, `${col.table}.${col.column}`];
|
|
529
|
+
})
|
|
530
|
+
);
|
|
531
|
+
const projectionTypes = {};
|
|
532
|
+
for (let i = 0; i < args.projection.aliases.length; i++) {
|
|
533
|
+
const alias = args.projection.aliases[i];
|
|
534
|
+
if (!alias || includeAliases.has(alias)) {
|
|
535
|
+
continue;
|
|
536
|
+
}
|
|
537
|
+
const column = args.projection.columns[i];
|
|
538
|
+
if (!column) {
|
|
539
|
+
continue;
|
|
540
|
+
}
|
|
541
|
+
const operationExpr = column._operationExpr;
|
|
542
|
+
if (operationExpr) {
|
|
543
|
+
if (operationExpr.returns.kind === "typeId") {
|
|
544
|
+
projectionTypes[alias] = operationExpr.returns.type;
|
|
545
|
+
} else if (operationExpr.returns.kind === "builtin") {
|
|
546
|
+
projectionTypes[alias] = operationExpr.returns.type;
|
|
547
|
+
}
|
|
548
|
+
} else {
|
|
549
|
+
const col = column;
|
|
550
|
+
const columnMeta = col.columnMeta;
|
|
551
|
+
if (columnMeta?.type) {
|
|
552
|
+
projectionTypes[alias] = columnMeta.type;
|
|
553
|
+
}
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
|
+
const projectionCodecs = {};
|
|
557
|
+
for (let i = 0; i < args.projection.aliases.length; i++) {
|
|
558
|
+
const alias = args.projection.aliases[i];
|
|
559
|
+
if (!alias || includeAliases.has(alias)) {
|
|
560
|
+
continue;
|
|
561
|
+
}
|
|
562
|
+
const column = args.projection.columns[i];
|
|
563
|
+
if (!column) {
|
|
564
|
+
continue;
|
|
565
|
+
}
|
|
566
|
+
const operationExpr = column._operationExpr;
|
|
567
|
+
if (operationExpr) {
|
|
568
|
+
if (operationExpr.returns.kind === "typeId") {
|
|
569
|
+
projectionCodecs[alias] = operationExpr.returns.type;
|
|
570
|
+
}
|
|
571
|
+
} else {
|
|
572
|
+
const col = column;
|
|
573
|
+
const columnMeta = col.columnMeta;
|
|
574
|
+
if (columnMeta?.type) {
|
|
575
|
+
projectionCodecs[alias] = columnMeta.type;
|
|
576
|
+
}
|
|
577
|
+
}
|
|
578
|
+
}
|
|
579
|
+
const allCodecs = {
|
|
580
|
+
...projectionCodecs,
|
|
581
|
+
...args.paramCodecs ? args.paramCodecs : {}
|
|
582
|
+
};
|
|
583
|
+
return Object.freeze(
|
|
584
|
+
compact({
|
|
585
|
+
target: args.contract.target,
|
|
586
|
+
targetFamily: args.contract.targetFamily,
|
|
587
|
+
coreHash: args.contract.coreHash,
|
|
588
|
+
lane: "dsl",
|
|
589
|
+
refs: {
|
|
590
|
+
tables: Array.from(refsTables),
|
|
591
|
+
columns: Array.from(refsColumns.values())
|
|
592
|
+
},
|
|
593
|
+
projection: projectionMap,
|
|
594
|
+
projectionTypes: Object.keys(projectionTypes).length > 0 ? projectionTypes : void 0,
|
|
595
|
+
annotations: Object.keys(allCodecs).length > 0 ? Object.freeze({ codecs: Object.freeze(allCodecs) }) : void 0,
|
|
596
|
+
paramDescriptors: args.paramDescriptors,
|
|
597
|
+
profileHash: args.contract.profileHash
|
|
598
|
+
})
|
|
599
|
+
);
|
|
600
|
+
}
|
|
601
|
+
|
|
602
|
+
// src/sql/predicate-builder.ts
|
|
603
|
+
import {
|
|
604
|
+
createBinaryExpr,
|
|
605
|
+
createColumnRef,
|
|
606
|
+
createParamRef
|
|
607
|
+
} from "@prisma-next/sql-relational-core/ast";
|
|
608
|
+
function buildWhereExpr(contract, where, paramsMap, descriptors, values) {
|
|
609
|
+
const placeholder = where.right;
|
|
610
|
+
const paramName = placeholder.name;
|
|
611
|
+
if (!Object.hasOwn(paramsMap, paramName)) {
|
|
612
|
+
errorMissingParameter(paramName);
|
|
613
|
+
}
|
|
614
|
+
const value = paramsMap[paramName];
|
|
615
|
+
const index = values.push(value);
|
|
616
|
+
let leftExpr;
|
|
617
|
+
let codecId;
|
|
618
|
+
const operationExpr = where.left._operationExpr;
|
|
619
|
+
if (operationExpr) {
|
|
620
|
+
leftExpr = operationExpr;
|
|
621
|
+
} else {
|
|
622
|
+
const colBuilder = where.left;
|
|
623
|
+
const meta = colBuilder.columnMeta ?? {};
|
|
624
|
+
descriptors.push({
|
|
625
|
+
name: paramName,
|
|
626
|
+
source: "dsl",
|
|
627
|
+
refs: { table: colBuilder.table, column: colBuilder.column },
|
|
628
|
+
...typeof meta.type === "string" ? { type: meta.type } : {},
|
|
629
|
+
...typeof meta.nullable === "boolean" ? { nullable: meta.nullable } : {}
|
|
630
|
+
});
|
|
631
|
+
const contractTable = contract.storage.tables[colBuilder.table];
|
|
632
|
+
const columnMeta = contractTable?.columns[colBuilder.column];
|
|
633
|
+
codecId = columnMeta?.type;
|
|
634
|
+
leftExpr = createColumnRef(colBuilder.table, colBuilder.column);
|
|
635
|
+
}
|
|
636
|
+
const rightParam = createParamRef(index, paramName);
|
|
637
|
+
return {
|
|
638
|
+
expr: createBinaryExpr("eq", leftExpr, rightParam),
|
|
639
|
+
...codecId ? { codecId } : {},
|
|
640
|
+
paramName
|
|
641
|
+
};
|
|
642
|
+
}
|
|
643
|
+
|
|
644
|
+
// src/sql/mutation-builder.ts
|
|
645
|
+
var InsertBuilderImpl = class _InsertBuilderImpl {
|
|
646
|
+
contract;
|
|
647
|
+
context;
|
|
648
|
+
table;
|
|
649
|
+
values;
|
|
650
|
+
returningColumns = [];
|
|
651
|
+
constructor(options, table, values) {
|
|
652
|
+
this.context = options.context;
|
|
653
|
+
this.contract = options.context.contract;
|
|
654
|
+
this.table = table;
|
|
655
|
+
this.values = values;
|
|
656
|
+
}
|
|
657
|
+
returning(...columns) {
|
|
658
|
+
checkReturningCapability(this.contract);
|
|
659
|
+
const builder = new _InsertBuilderImpl(
|
|
660
|
+
{
|
|
661
|
+
context: this.context
|
|
662
|
+
},
|
|
663
|
+
this.table,
|
|
664
|
+
this.values
|
|
665
|
+
);
|
|
666
|
+
builder.returningColumns = [...this.returningColumns, ...columns];
|
|
667
|
+
return builder;
|
|
668
|
+
}
|
|
669
|
+
build(options) {
|
|
670
|
+
const paramsMap = options?.params ?? {};
|
|
671
|
+
const paramDescriptors = [];
|
|
672
|
+
const paramValues = [];
|
|
673
|
+
const paramCodecs = {};
|
|
674
|
+
const contractTable = this.contract.storage.tables[this.table.name];
|
|
675
|
+
if (!contractTable) {
|
|
676
|
+
errorUnknownTable(this.table.name);
|
|
677
|
+
}
|
|
678
|
+
const values = {};
|
|
679
|
+
for (const [columnName, placeholder] of Object.entries(this.values)) {
|
|
680
|
+
if (!contractTable.columns[columnName]) {
|
|
681
|
+
errorUnknownColumn(columnName, this.table.name);
|
|
682
|
+
}
|
|
683
|
+
const paramName = placeholder.name;
|
|
684
|
+
if (!Object.hasOwn(paramsMap, paramName)) {
|
|
685
|
+
errorMissingParameter(paramName);
|
|
686
|
+
}
|
|
687
|
+
const value = paramsMap[paramName];
|
|
688
|
+
const index = paramValues.push(value);
|
|
689
|
+
const columnMeta = contractTable.columns[columnName];
|
|
690
|
+
const codecId = columnMeta?.type;
|
|
691
|
+
if (codecId && paramName) {
|
|
692
|
+
paramCodecs[paramName] = codecId;
|
|
693
|
+
}
|
|
694
|
+
paramDescriptors.push({
|
|
695
|
+
name: paramName,
|
|
696
|
+
source: "dsl",
|
|
697
|
+
refs: { table: this.table.name, column: columnName },
|
|
698
|
+
...codecId ? { type: codecId } : {},
|
|
699
|
+
...columnMeta?.nullable !== void 0 ? { nullable: columnMeta.nullable } : {}
|
|
700
|
+
});
|
|
701
|
+
values[columnName] = createParamRef2(index, paramName);
|
|
702
|
+
}
|
|
703
|
+
const returning = this.returningColumns.map((col) => {
|
|
704
|
+
const c = col;
|
|
705
|
+
return createColumnRef2(c.table, c.column);
|
|
706
|
+
});
|
|
707
|
+
const ast = createInsertAst({
|
|
708
|
+
table: createTableRef(this.table.name),
|
|
709
|
+
values,
|
|
710
|
+
returning
|
|
711
|
+
});
|
|
712
|
+
const returningProjection = {
|
|
713
|
+
aliases: this.returningColumns.map((col) => {
|
|
714
|
+
const c = col;
|
|
715
|
+
return c.column;
|
|
716
|
+
}),
|
|
717
|
+
columns: this.returningColumns
|
|
718
|
+
};
|
|
719
|
+
const planMeta = buildMeta({
|
|
720
|
+
contract: this.contract,
|
|
721
|
+
table: this.table,
|
|
722
|
+
projection: returning.length > 0 ? returningProjection : { aliases: [], columns: [] },
|
|
723
|
+
paramDescriptors,
|
|
724
|
+
...Object.keys(paramCodecs).length > 0 ? { paramCodecs } : {}
|
|
725
|
+
});
|
|
726
|
+
const queryPlan = Object.freeze({
|
|
727
|
+
ast,
|
|
728
|
+
params: paramValues,
|
|
729
|
+
meta: {
|
|
730
|
+
...planMeta,
|
|
731
|
+
lane: "dsl",
|
|
732
|
+
annotations: {
|
|
733
|
+
...planMeta.annotations,
|
|
734
|
+
intent: "write",
|
|
735
|
+
isMutation: true
|
|
736
|
+
}
|
|
737
|
+
}
|
|
738
|
+
});
|
|
739
|
+
return queryPlan;
|
|
740
|
+
}
|
|
741
|
+
};
|
|
742
|
+
var UpdateBuilderImpl = class _UpdateBuilderImpl {
|
|
743
|
+
contract;
|
|
744
|
+
context;
|
|
745
|
+
table;
|
|
746
|
+
set;
|
|
747
|
+
wherePredicate;
|
|
748
|
+
returningColumns = [];
|
|
749
|
+
constructor(options, table, set) {
|
|
750
|
+
this.context = options.context;
|
|
751
|
+
this.contract = options.context.contract;
|
|
752
|
+
this.table = table;
|
|
753
|
+
this.set = set;
|
|
754
|
+
}
|
|
755
|
+
where(predicate) {
|
|
756
|
+
const builder = new _UpdateBuilderImpl(
|
|
757
|
+
{
|
|
758
|
+
context: this.context
|
|
759
|
+
},
|
|
760
|
+
this.table,
|
|
761
|
+
this.set
|
|
762
|
+
);
|
|
763
|
+
builder.wherePredicate = predicate;
|
|
764
|
+
builder.returningColumns = [...this.returningColumns];
|
|
765
|
+
return builder;
|
|
766
|
+
}
|
|
767
|
+
returning(...columns) {
|
|
768
|
+
checkReturningCapability(this.contract);
|
|
769
|
+
const builder = new _UpdateBuilderImpl(
|
|
770
|
+
{
|
|
771
|
+
context: this.context
|
|
772
|
+
},
|
|
773
|
+
this.table,
|
|
774
|
+
this.set
|
|
775
|
+
);
|
|
776
|
+
if (this.wherePredicate) {
|
|
777
|
+
builder.wherePredicate = this.wherePredicate;
|
|
778
|
+
}
|
|
779
|
+
builder.returningColumns = [...this.returningColumns, ...columns];
|
|
780
|
+
return builder;
|
|
781
|
+
}
|
|
782
|
+
build(options) {
|
|
783
|
+
if (!this.wherePredicate) {
|
|
784
|
+
errorWhereMustBeCalledForUpdate();
|
|
785
|
+
}
|
|
786
|
+
const paramsMap = options?.params ?? {};
|
|
787
|
+
const paramDescriptors = [];
|
|
788
|
+
const paramValues = [];
|
|
789
|
+
const paramCodecs = {};
|
|
790
|
+
const contractTable = this.contract.storage.tables[this.table.name];
|
|
791
|
+
if (!contractTable) {
|
|
792
|
+
errorUnknownTable(this.table.name);
|
|
793
|
+
}
|
|
794
|
+
const set = {};
|
|
795
|
+
for (const [columnName, placeholder] of Object.entries(this.set)) {
|
|
796
|
+
if (!contractTable.columns[columnName]) {
|
|
797
|
+
errorUnknownColumn(columnName, this.table.name);
|
|
798
|
+
}
|
|
799
|
+
const paramName = placeholder.name;
|
|
800
|
+
if (!Object.hasOwn(paramsMap, paramName)) {
|
|
801
|
+
errorMissingParameter(paramName);
|
|
802
|
+
}
|
|
803
|
+
const value = paramsMap[paramName];
|
|
804
|
+
const index = paramValues.push(value);
|
|
805
|
+
const columnMeta = contractTable.columns[columnName];
|
|
806
|
+
const codecId = columnMeta?.type;
|
|
807
|
+
if (codecId && paramName) {
|
|
808
|
+
paramCodecs[paramName] = codecId;
|
|
809
|
+
}
|
|
810
|
+
paramDescriptors.push({
|
|
811
|
+
name: paramName,
|
|
812
|
+
source: "dsl",
|
|
813
|
+
refs: { table: this.table.name, column: columnName },
|
|
814
|
+
...codecId ? { type: codecId } : {},
|
|
815
|
+
...columnMeta?.nullable !== void 0 ? { nullable: columnMeta.nullable } : {}
|
|
816
|
+
});
|
|
817
|
+
set[columnName] = createParamRef2(index, paramName);
|
|
818
|
+
}
|
|
819
|
+
const whereResult = buildWhereExpr(
|
|
820
|
+
this.contract,
|
|
821
|
+
this.wherePredicate,
|
|
822
|
+
paramsMap,
|
|
823
|
+
paramDescriptors,
|
|
824
|
+
paramValues
|
|
825
|
+
);
|
|
826
|
+
const whereExpr = whereResult.expr;
|
|
827
|
+
if (!whereExpr) {
|
|
828
|
+
errorFailedToBuildWhereClause();
|
|
829
|
+
}
|
|
830
|
+
if (whereResult.codecId && whereResult.paramName) {
|
|
831
|
+
paramCodecs[whereResult.paramName] = whereResult.codecId;
|
|
832
|
+
}
|
|
833
|
+
const returning = this.returningColumns.map((col) => {
|
|
834
|
+
const c = col;
|
|
835
|
+
return createColumnRef2(c.table, c.column);
|
|
836
|
+
});
|
|
837
|
+
const ast = createUpdateAst({
|
|
838
|
+
table: createTableRef(this.table.name),
|
|
839
|
+
set,
|
|
840
|
+
where: whereExpr,
|
|
841
|
+
returning
|
|
842
|
+
});
|
|
843
|
+
const returningProjection = {
|
|
844
|
+
aliases: this.returningColumns.map((col) => {
|
|
845
|
+
const c = col;
|
|
846
|
+
return c.column;
|
|
847
|
+
}),
|
|
848
|
+
columns: this.returningColumns
|
|
849
|
+
};
|
|
850
|
+
const planMeta = buildMeta({
|
|
851
|
+
contract: this.contract,
|
|
852
|
+
table: this.table,
|
|
853
|
+
projection: returning.length > 0 ? returningProjection : { aliases: [], columns: [] },
|
|
854
|
+
paramDescriptors,
|
|
855
|
+
...Object.keys(paramCodecs).length > 0 ? { paramCodecs } : {},
|
|
856
|
+
where: this.wherePredicate
|
|
857
|
+
});
|
|
858
|
+
const queryPlan = Object.freeze({
|
|
859
|
+
ast,
|
|
860
|
+
params: paramValues,
|
|
861
|
+
meta: {
|
|
862
|
+
...planMeta,
|
|
863
|
+
lane: "dsl",
|
|
864
|
+
annotations: {
|
|
865
|
+
...planMeta.annotations,
|
|
866
|
+
intent: "write",
|
|
867
|
+
isMutation: true,
|
|
868
|
+
hasWhere: true
|
|
869
|
+
}
|
|
870
|
+
}
|
|
871
|
+
});
|
|
872
|
+
return queryPlan;
|
|
873
|
+
}
|
|
874
|
+
};
|
|
875
|
+
var DeleteBuilderImpl = class _DeleteBuilderImpl {
|
|
876
|
+
contract;
|
|
877
|
+
context;
|
|
878
|
+
table;
|
|
879
|
+
wherePredicate;
|
|
880
|
+
returningColumns = [];
|
|
881
|
+
constructor(options, table) {
|
|
882
|
+
this.context = options.context;
|
|
883
|
+
this.contract = options.context.contract;
|
|
884
|
+
this.table = table;
|
|
885
|
+
}
|
|
886
|
+
where(predicate) {
|
|
887
|
+
const builder = new _DeleteBuilderImpl(
|
|
888
|
+
{
|
|
889
|
+
context: this.context
|
|
890
|
+
},
|
|
891
|
+
this.table
|
|
892
|
+
);
|
|
893
|
+
builder.wherePredicate = predicate;
|
|
894
|
+
builder.returningColumns = [...this.returningColumns];
|
|
895
|
+
return builder;
|
|
896
|
+
}
|
|
897
|
+
returning(...columns) {
|
|
898
|
+
checkReturningCapability(this.contract);
|
|
899
|
+
const builder = new _DeleteBuilderImpl(
|
|
900
|
+
{
|
|
901
|
+
context: this.context
|
|
902
|
+
},
|
|
903
|
+
this.table
|
|
904
|
+
);
|
|
905
|
+
if (this.wherePredicate) {
|
|
906
|
+
builder.wherePredicate = this.wherePredicate;
|
|
907
|
+
}
|
|
908
|
+
builder.returningColumns = [...this.returningColumns, ...columns];
|
|
909
|
+
return builder;
|
|
910
|
+
}
|
|
911
|
+
build(options) {
|
|
912
|
+
if (!this.wherePredicate) {
|
|
913
|
+
errorWhereMustBeCalledForDelete();
|
|
914
|
+
}
|
|
915
|
+
const paramsMap = options?.params ?? {};
|
|
916
|
+
const paramDescriptors = [];
|
|
917
|
+
const paramValues = [];
|
|
918
|
+
const paramCodecs = {};
|
|
919
|
+
const contractTable = this.contract.storage.tables[this.table.name];
|
|
920
|
+
if (!contractTable) {
|
|
921
|
+
errorUnknownTable(this.table.name);
|
|
922
|
+
}
|
|
923
|
+
const whereResult = buildWhereExpr(
|
|
924
|
+
this.contract,
|
|
925
|
+
this.wherePredicate,
|
|
926
|
+
paramsMap,
|
|
927
|
+
paramDescriptors,
|
|
928
|
+
paramValues
|
|
929
|
+
);
|
|
930
|
+
const whereExpr = whereResult.expr;
|
|
931
|
+
if (!whereExpr) {
|
|
932
|
+
errorFailedToBuildWhereClause();
|
|
933
|
+
}
|
|
934
|
+
if (whereResult.codecId && whereResult.paramName) {
|
|
935
|
+
paramCodecs[whereResult.paramName] = whereResult.codecId;
|
|
936
|
+
}
|
|
937
|
+
const returning = this.returningColumns.map((col) => {
|
|
938
|
+
const c = col;
|
|
939
|
+
return createColumnRef2(c.table, c.column);
|
|
940
|
+
});
|
|
941
|
+
const ast = createDeleteAst({
|
|
942
|
+
table: createTableRef(this.table.name),
|
|
943
|
+
where: whereExpr,
|
|
944
|
+
returning
|
|
945
|
+
});
|
|
946
|
+
const returningProjection = {
|
|
947
|
+
aliases: this.returningColumns.map((col) => {
|
|
948
|
+
const c = col;
|
|
949
|
+
return c.column;
|
|
950
|
+
}),
|
|
951
|
+
columns: this.returningColumns
|
|
952
|
+
};
|
|
953
|
+
const planMeta = buildMeta({
|
|
954
|
+
contract: this.contract,
|
|
955
|
+
table: this.table,
|
|
956
|
+
projection: returning.length > 0 ? returningProjection : { aliases: [], columns: [] },
|
|
957
|
+
paramDescriptors,
|
|
958
|
+
...Object.keys(paramCodecs).length > 0 ? { paramCodecs } : {},
|
|
959
|
+
where: this.wherePredicate
|
|
960
|
+
});
|
|
961
|
+
const queryPlan = Object.freeze({
|
|
962
|
+
ast,
|
|
963
|
+
params: paramValues,
|
|
964
|
+
meta: {
|
|
965
|
+
...planMeta,
|
|
966
|
+
lane: "dsl",
|
|
967
|
+
annotations: {
|
|
968
|
+
...planMeta.annotations,
|
|
969
|
+
intent: "write",
|
|
970
|
+
isMutation: true,
|
|
971
|
+
hasWhere: true
|
|
972
|
+
}
|
|
973
|
+
}
|
|
974
|
+
});
|
|
975
|
+
return queryPlan;
|
|
976
|
+
}
|
|
977
|
+
};
|
|
978
|
+
|
|
979
|
+
// src/sql/select-builder.ts
|
|
980
|
+
import {
|
|
981
|
+
createColumnRef as createColumnRef5,
|
|
982
|
+
createJoinOnBuilder,
|
|
983
|
+
createOrderByItem as createOrderByItem2,
|
|
984
|
+
createSelectAst,
|
|
985
|
+
createTableRef as createTableRef4
|
|
986
|
+
} from "@prisma-next/sql-relational-core/ast";
|
|
987
|
+
|
|
988
|
+
// src/sql/include-builder.ts
|
|
989
|
+
import {
|
|
990
|
+
createColumnRef as createColumnRef3,
|
|
991
|
+
createJoinOnExpr,
|
|
992
|
+
createOrderByItem,
|
|
993
|
+
createTableRef as createTableRef2
|
|
994
|
+
} from "@prisma-next/sql-relational-core/ast";
|
|
995
|
+
|
|
996
|
+
// src/sql/projection.ts
|
|
997
|
+
function generateAlias(path) {
|
|
998
|
+
if (path.length === 0) {
|
|
999
|
+
errorAliasPathEmpty();
|
|
1000
|
+
}
|
|
1001
|
+
return path.join("_");
|
|
1002
|
+
}
|
|
1003
|
+
var AliasTracker = class {
|
|
1004
|
+
aliases = /* @__PURE__ */ new Set();
|
|
1005
|
+
aliasToPath = /* @__PURE__ */ new Map();
|
|
1006
|
+
register(path) {
|
|
1007
|
+
const alias = generateAlias(path);
|
|
1008
|
+
if (this.aliases.has(alias)) {
|
|
1009
|
+
const existingPath = this.aliasToPath.get(alias);
|
|
1010
|
+
errorAliasCollision(path, alias, existingPath);
|
|
1011
|
+
}
|
|
1012
|
+
this.aliases.add(alias);
|
|
1013
|
+
this.aliasToPath.set(alias, path);
|
|
1014
|
+
return alias;
|
|
1015
|
+
}
|
|
1016
|
+
getPath(alias) {
|
|
1017
|
+
return this.aliasToPath.get(alias);
|
|
1018
|
+
}
|
|
1019
|
+
has(alias) {
|
|
1020
|
+
return this.aliases.has(alias);
|
|
1021
|
+
}
|
|
1022
|
+
};
|
|
1023
|
+
function flattenProjection(projection, tracker, currentPath = []) {
|
|
1024
|
+
const aliases = [];
|
|
1025
|
+
const columns = [];
|
|
1026
|
+
for (const [key, value] of Object.entries(projection)) {
|
|
1027
|
+
const path = [...currentPath, key];
|
|
1028
|
+
if (isColumnBuilder(value)) {
|
|
1029
|
+
const alias = tracker.register(path);
|
|
1030
|
+
aliases.push(alias);
|
|
1031
|
+
columns.push(value);
|
|
1032
|
+
} else if (typeof value === "object" && value !== null) {
|
|
1033
|
+
const nested = flattenProjection(value, tracker, path);
|
|
1034
|
+
aliases.push(...nested.aliases);
|
|
1035
|
+
columns.push(...nested.columns);
|
|
1036
|
+
} else {
|
|
1037
|
+
errorInvalidProjectionValue(path);
|
|
1038
|
+
}
|
|
1039
|
+
}
|
|
1040
|
+
return { aliases, columns };
|
|
1041
|
+
}
|
|
1042
|
+
function buildProjectionState(_table, projection, includes) {
|
|
1043
|
+
const tracker = new AliasTracker();
|
|
1044
|
+
const aliases = [];
|
|
1045
|
+
const columns = [];
|
|
1046
|
+
for (const [key, value] of Object.entries(projection)) {
|
|
1047
|
+
if (value === true) {
|
|
1048
|
+
const matchingInclude = includes?.find((inc) => inc.alias === key);
|
|
1049
|
+
if (!matchingInclude) {
|
|
1050
|
+
errorIncludeAliasNotFound(key);
|
|
1051
|
+
}
|
|
1052
|
+
aliases.push(key);
|
|
1053
|
+
columns.push({
|
|
1054
|
+
kind: "column",
|
|
1055
|
+
table: matchingInclude.table.name,
|
|
1056
|
+
column: "",
|
|
1057
|
+
columnMeta: { type: "core/json@1", nullable: true }
|
|
1058
|
+
});
|
|
1059
|
+
} else if (isColumnBuilder(value)) {
|
|
1060
|
+
const alias = tracker.register([key]);
|
|
1061
|
+
aliases.push(alias);
|
|
1062
|
+
columns.push(value);
|
|
1063
|
+
} else if (typeof value === "object" && value !== null) {
|
|
1064
|
+
const nested = flattenProjection(value, tracker, [key]);
|
|
1065
|
+
aliases.push(...nested.aliases);
|
|
1066
|
+
columns.push(...nested.columns);
|
|
1067
|
+
} else {
|
|
1068
|
+
errorInvalidProjectionKey(key);
|
|
1069
|
+
}
|
|
1070
|
+
}
|
|
1071
|
+
if (aliases.length === 0) {
|
|
1072
|
+
errorProjectionEmpty();
|
|
1073
|
+
}
|
|
1074
|
+
return { aliases, columns };
|
|
1075
|
+
}
|
|
1076
|
+
|
|
1077
|
+
// src/sql/include-builder.ts
|
|
1078
|
+
var IncludeChildBuilderImpl = class _IncludeChildBuilderImpl {
|
|
1079
|
+
contract;
|
|
1080
|
+
codecTypes;
|
|
1081
|
+
table;
|
|
1082
|
+
childProjection;
|
|
1083
|
+
childWhere;
|
|
1084
|
+
childOrderBy;
|
|
1085
|
+
childLimit;
|
|
1086
|
+
constructor(contract, codecTypes, table) {
|
|
1087
|
+
this.contract = contract;
|
|
1088
|
+
this.codecTypes = codecTypes;
|
|
1089
|
+
this.table = table;
|
|
1090
|
+
}
|
|
1091
|
+
select(projection) {
|
|
1092
|
+
const projectionState = buildProjectionState(this.table, projection);
|
|
1093
|
+
const builder = new _IncludeChildBuilderImpl(this.contract, this.codecTypes, this.table);
|
|
1094
|
+
builder.childProjection = projectionState;
|
|
1095
|
+
if (this.childWhere !== void 0) {
|
|
1096
|
+
builder.childWhere = this.childWhere;
|
|
1097
|
+
}
|
|
1098
|
+
if (this.childOrderBy !== void 0) {
|
|
1099
|
+
builder.childOrderBy = this.childOrderBy;
|
|
1100
|
+
}
|
|
1101
|
+
if (this.childLimit !== void 0) {
|
|
1102
|
+
builder.childLimit = this.childLimit;
|
|
1103
|
+
}
|
|
1104
|
+
return builder;
|
|
1105
|
+
}
|
|
1106
|
+
where(expr) {
|
|
1107
|
+
const builder = new _IncludeChildBuilderImpl(
|
|
1108
|
+
this.contract,
|
|
1109
|
+
this.codecTypes,
|
|
1110
|
+
this.table
|
|
1111
|
+
);
|
|
1112
|
+
if (this.childProjection !== void 0) {
|
|
1113
|
+
builder.childProjection = this.childProjection;
|
|
1114
|
+
}
|
|
1115
|
+
builder.childWhere = expr;
|
|
1116
|
+
if (this.childOrderBy !== void 0) {
|
|
1117
|
+
builder.childOrderBy = this.childOrderBy;
|
|
1118
|
+
}
|
|
1119
|
+
if (this.childLimit !== void 0) {
|
|
1120
|
+
builder.childLimit = this.childLimit;
|
|
1121
|
+
}
|
|
1122
|
+
return builder;
|
|
1123
|
+
}
|
|
1124
|
+
orderBy(order) {
|
|
1125
|
+
const builder = new _IncludeChildBuilderImpl(
|
|
1126
|
+
this.contract,
|
|
1127
|
+
this.codecTypes,
|
|
1128
|
+
this.table
|
|
1129
|
+
);
|
|
1130
|
+
if (this.childProjection !== void 0) {
|
|
1131
|
+
builder.childProjection = this.childProjection;
|
|
1132
|
+
}
|
|
1133
|
+
if (this.childWhere !== void 0) {
|
|
1134
|
+
builder.childWhere = this.childWhere;
|
|
1135
|
+
}
|
|
1136
|
+
builder.childOrderBy = order;
|
|
1137
|
+
if (this.childLimit !== void 0) {
|
|
1138
|
+
builder.childLimit = this.childLimit;
|
|
1139
|
+
}
|
|
1140
|
+
return builder;
|
|
1141
|
+
}
|
|
1142
|
+
limit(count) {
|
|
1143
|
+
if (!Number.isInteger(count) || count < 0) {
|
|
1144
|
+
errorLimitMustBeNonNegativeInteger();
|
|
1145
|
+
}
|
|
1146
|
+
const builder = new _IncludeChildBuilderImpl(
|
|
1147
|
+
this.contract,
|
|
1148
|
+
this.codecTypes,
|
|
1149
|
+
this.table
|
|
1150
|
+
);
|
|
1151
|
+
if (this.childProjection !== void 0) {
|
|
1152
|
+
builder.childProjection = this.childProjection;
|
|
1153
|
+
}
|
|
1154
|
+
if (this.childWhere !== void 0) {
|
|
1155
|
+
builder.childWhere = this.childWhere;
|
|
1156
|
+
}
|
|
1157
|
+
if (this.childOrderBy !== void 0) {
|
|
1158
|
+
builder.childOrderBy = this.childOrderBy;
|
|
1159
|
+
}
|
|
1160
|
+
builder.childLimit = count;
|
|
1161
|
+
return builder;
|
|
1162
|
+
}
|
|
1163
|
+
getState() {
|
|
1164
|
+
if (!this.childProjection) {
|
|
1165
|
+
errorChildProjectionMustBeSpecified();
|
|
1166
|
+
}
|
|
1167
|
+
const state = {
|
|
1168
|
+
childProjection: this.childProjection
|
|
1169
|
+
};
|
|
1170
|
+
if (this.childWhere !== void 0) {
|
|
1171
|
+
state.childWhere = this.childWhere;
|
|
1172
|
+
}
|
|
1173
|
+
if (this.childOrderBy !== void 0) {
|
|
1174
|
+
state.childOrderBy = this.childOrderBy;
|
|
1175
|
+
}
|
|
1176
|
+
if (this.childLimit !== void 0) {
|
|
1177
|
+
state.childLimit = this.childLimit;
|
|
1178
|
+
}
|
|
1179
|
+
return state;
|
|
1180
|
+
}
|
|
1181
|
+
};
|
|
1182
|
+
function buildIncludeAst(include, contract, paramsMap, paramDescriptors, paramValues) {
|
|
1183
|
+
const childOrderBy = include.childOrderBy ? (() => {
|
|
1184
|
+
const orderBy = include.childOrderBy;
|
|
1185
|
+
const orderExpr = orderBy.expr;
|
|
1186
|
+
const expr = (() => {
|
|
1187
|
+
if (isOperationExpr(orderExpr)) {
|
|
1188
|
+
const baseCol = extractBaseColumnRef(orderExpr);
|
|
1189
|
+
return createColumnRef3(baseCol.table, baseCol.column);
|
|
1190
|
+
}
|
|
1191
|
+
const colBuilder = orderExpr;
|
|
1192
|
+
return createColumnRef3(colBuilder.table, colBuilder.column);
|
|
1193
|
+
})();
|
|
1194
|
+
return [createOrderByItem(expr, orderBy.dir)];
|
|
1195
|
+
})() : void 0;
|
|
1196
|
+
let childWhere;
|
|
1197
|
+
if (include.childWhere) {
|
|
1198
|
+
const whereResult = buildWhereExpr(
|
|
1199
|
+
contract,
|
|
1200
|
+
include.childWhere,
|
|
1201
|
+
paramsMap,
|
|
1202
|
+
paramDescriptors,
|
|
1203
|
+
paramValues
|
|
1204
|
+
);
|
|
1205
|
+
childWhere = whereResult.expr;
|
|
1206
|
+
}
|
|
1207
|
+
const onLeft = include.on.left;
|
|
1208
|
+
const onRight = include.on.right;
|
|
1209
|
+
const leftCol = createColumnRef3(onLeft.table, onLeft.column);
|
|
1210
|
+
const rightCol = createColumnRef3(onRight.table, onRight.column);
|
|
1211
|
+
const onExpr = createJoinOnExpr(leftCol, rightCol);
|
|
1212
|
+
return {
|
|
1213
|
+
kind: "includeMany",
|
|
1214
|
+
alias: include.alias,
|
|
1215
|
+
child: {
|
|
1216
|
+
table: createTableRef2(include.table.name),
|
|
1217
|
+
on: onExpr,
|
|
1218
|
+
...childWhere ? { where: childWhere } : {},
|
|
1219
|
+
...childOrderBy ? { orderBy: childOrderBy } : {},
|
|
1220
|
+
...typeof include.childLimit === "number" ? { limit: include.childLimit } : {},
|
|
1221
|
+
project: include.childProjection.aliases.map((alias, idx) => {
|
|
1222
|
+
const column = include.childProjection.columns[idx];
|
|
1223
|
+
if (!column || !alias) {
|
|
1224
|
+
errorMissingColumnForAlias(alias ?? "unknown", idx);
|
|
1225
|
+
}
|
|
1226
|
+
const col = column;
|
|
1227
|
+
return {
|
|
1228
|
+
alias,
|
|
1229
|
+
expr: createColumnRef3(col.table, col.column)
|
|
1230
|
+
};
|
|
1231
|
+
})
|
|
1232
|
+
}
|
|
1233
|
+
};
|
|
1234
|
+
}
|
|
1235
|
+
|
|
1236
|
+
// src/sql/join-builder.ts
|
|
1237
|
+
import {
|
|
1238
|
+
createColumnRef as createColumnRef4,
|
|
1239
|
+
createJoin,
|
|
1240
|
+
createJoinOnExpr as createJoinOnExpr2,
|
|
1241
|
+
createTableRef as createTableRef3
|
|
1242
|
+
} from "@prisma-next/sql-relational-core/ast";
|
|
1243
|
+
function buildJoinAst(join) {
|
|
1244
|
+
const onLeft = join.on.left;
|
|
1245
|
+
const onRight = join.on.right;
|
|
1246
|
+
const leftCol = createColumnRef4(onLeft.table, onLeft.column);
|
|
1247
|
+
const rightCol = createColumnRef4(onRight.table, onRight.column);
|
|
1248
|
+
const onExpr = createJoinOnExpr2(leftCol, rightCol);
|
|
1249
|
+
return createJoin(join.joinType, createTableRef3(join.table.name), onExpr);
|
|
1250
|
+
}
|
|
1251
|
+
|
|
1252
|
+
// src/sql/select-builder.ts
|
|
1253
|
+
var SelectBuilderImpl = class _SelectBuilderImpl {
|
|
1254
|
+
contract;
|
|
1255
|
+
codecTypes;
|
|
1256
|
+
context;
|
|
1257
|
+
state = {};
|
|
1258
|
+
constructor(options, state) {
|
|
1259
|
+
this.context = options.context;
|
|
1260
|
+
this.contract = options.context.contract;
|
|
1261
|
+
this.codecTypes = options.context.contract.mappings.codecTypes;
|
|
1262
|
+
if (state) {
|
|
1263
|
+
this.state = state;
|
|
1264
|
+
}
|
|
1265
|
+
}
|
|
1266
|
+
from(table) {
|
|
1267
|
+
return new _SelectBuilderImpl(
|
|
1268
|
+
{
|
|
1269
|
+
context: this.context
|
|
1270
|
+
},
|
|
1271
|
+
{ ...this.state, from: table }
|
|
1272
|
+
);
|
|
1273
|
+
}
|
|
1274
|
+
innerJoin(table, on) {
|
|
1275
|
+
return this._addJoin("inner", table, on);
|
|
1276
|
+
}
|
|
1277
|
+
leftJoin(table, on) {
|
|
1278
|
+
return this._addJoin("left", table, on);
|
|
1279
|
+
}
|
|
1280
|
+
rightJoin(table, on) {
|
|
1281
|
+
return this._addJoin("right", table, on);
|
|
1282
|
+
}
|
|
1283
|
+
fullJoin(table, on) {
|
|
1284
|
+
return this._addJoin("full", table, on);
|
|
1285
|
+
}
|
|
1286
|
+
includeMany(childTable, on, childBuilder, options) {
|
|
1287
|
+
checkIncludeCapabilities(this.contract);
|
|
1288
|
+
if (!this.contract.storage.tables[childTable.name]) {
|
|
1289
|
+
errorUnknownTable(childTable.name);
|
|
1290
|
+
}
|
|
1291
|
+
const joinOnBuilder = createJoinOnBuilder();
|
|
1292
|
+
const onPredicate = on(joinOnBuilder);
|
|
1293
|
+
const onLeft = onPredicate.left;
|
|
1294
|
+
const onRight = onPredicate.right;
|
|
1295
|
+
if (onLeft.table === onRight.table) {
|
|
1296
|
+
errorSelfJoinNotSupported();
|
|
1297
|
+
}
|
|
1298
|
+
const childBuilderImpl = new IncludeChildBuilderImpl(
|
|
1299
|
+
this.contract,
|
|
1300
|
+
this.codecTypes,
|
|
1301
|
+
childTable
|
|
1302
|
+
);
|
|
1303
|
+
const builtChild = childBuilder(
|
|
1304
|
+
childBuilderImpl
|
|
1305
|
+
);
|
|
1306
|
+
const childState = builtChild.getState();
|
|
1307
|
+
if (childState.childProjection.aliases.length === 0) {
|
|
1308
|
+
errorChildProjectionEmpty();
|
|
1309
|
+
}
|
|
1310
|
+
const alias = options?.alias ?? childTable.name;
|
|
1311
|
+
if (this.state.projection) {
|
|
1312
|
+
if (this.state.projection.aliases.includes(alias)) {
|
|
1313
|
+
errorIncludeAliasCollision(alias, "projection");
|
|
1314
|
+
}
|
|
1315
|
+
}
|
|
1316
|
+
const existingIncludes = this.state.includes ?? [];
|
|
1317
|
+
if (existingIncludes.some((inc) => inc.alias === alias)) {
|
|
1318
|
+
errorIncludeAliasCollision(alias, "include");
|
|
1319
|
+
}
|
|
1320
|
+
const includeState = {
|
|
1321
|
+
alias,
|
|
1322
|
+
table: childTable,
|
|
1323
|
+
on: onPredicate,
|
|
1324
|
+
childProjection: childState.childProjection,
|
|
1325
|
+
...childState.childWhere !== void 0 ? { childWhere: childState.childWhere } : {},
|
|
1326
|
+
...childState.childOrderBy !== void 0 ? { childOrderBy: childState.childOrderBy } : {},
|
|
1327
|
+
...childState.childLimit !== void 0 ? { childLimit: childState.childLimit } : {}
|
|
1328
|
+
};
|
|
1329
|
+
const newIncludes = [...existingIncludes, includeState];
|
|
1330
|
+
return new _SelectBuilderImpl(
|
|
1331
|
+
{
|
|
1332
|
+
context: this.context
|
|
1333
|
+
},
|
|
1334
|
+
{ ...this.state, includes: newIncludes }
|
|
1335
|
+
);
|
|
1336
|
+
}
|
|
1337
|
+
_addJoin(joinType, table, on) {
|
|
1338
|
+
const fromTable = this.ensureFrom();
|
|
1339
|
+
if (!this.contract.storage.tables[table.name]) {
|
|
1340
|
+
errorUnknownTable(table.name);
|
|
1341
|
+
}
|
|
1342
|
+
if (table.name === fromTable.name) {
|
|
1343
|
+
errorSelfJoinNotSupported();
|
|
1344
|
+
}
|
|
1345
|
+
const joinOnBuilder = createJoinOnBuilder();
|
|
1346
|
+
const onPredicate = on(joinOnBuilder);
|
|
1347
|
+
const joinState = {
|
|
1348
|
+
joinType,
|
|
1349
|
+
table,
|
|
1350
|
+
on: onPredicate
|
|
1351
|
+
};
|
|
1352
|
+
const existingJoins = this.state.joins ?? [];
|
|
1353
|
+
const newJoins = [...existingJoins, joinState];
|
|
1354
|
+
return new _SelectBuilderImpl(
|
|
1355
|
+
{
|
|
1356
|
+
context: this.context
|
|
1357
|
+
},
|
|
1358
|
+
{ ...this.state, joins: newJoins }
|
|
1359
|
+
);
|
|
1360
|
+
}
|
|
1361
|
+
where(expr) {
|
|
1362
|
+
return new _SelectBuilderImpl(
|
|
1363
|
+
{
|
|
1364
|
+
context: this.context
|
|
1365
|
+
},
|
|
1366
|
+
{ ...this.state, where: expr }
|
|
1367
|
+
);
|
|
1368
|
+
}
|
|
1369
|
+
select(projection) {
|
|
1370
|
+
const table = this.ensureFrom();
|
|
1371
|
+
const projectionState = buildProjectionState(table, projection, this.state.includes);
|
|
1372
|
+
return new _SelectBuilderImpl(
|
|
1373
|
+
{
|
|
1374
|
+
context: this.context
|
|
1375
|
+
},
|
|
1376
|
+
{ ...this.state, projection: projectionState }
|
|
1377
|
+
);
|
|
1378
|
+
}
|
|
1379
|
+
orderBy(order) {
|
|
1380
|
+
return new _SelectBuilderImpl(
|
|
1381
|
+
{
|
|
1382
|
+
context: this.context
|
|
1383
|
+
},
|
|
1384
|
+
{ ...this.state, orderBy: order }
|
|
1385
|
+
);
|
|
1386
|
+
}
|
|
1387
|
+
limit(count) {
|
|
1388
|
+
if (!Number.isInteger(count) || count < 0) {
|
|
1389
|
+
errorLimitMustBeNonNegativeInteger();
|
|
1390
|
+
}
|
|
1391
|
+
return new _SelectBuilderImpl(
|
|
1392
|
+
{
|
|
1393
|
+
context: this.context
|
|
1394
|
+
},
|
|
1395
|
+
{ ...this.state, limit: count }
|
|
1396
|
+
);
|
|
1397
|
+
}
|
|
1398
|
+
build(options) {
|
|
1399
|
+
const table = this.ensureFrom();
|
|
1400
|
+
const projection = this.ensureProjection();
|
|
1401
|
+
const paramsMap = options?.params ?? {};
|
|
1402
|
+
const contractTable = this.contract.storage.tables[table.name];
|
|
1403
|
+
if (!contractTable) {
|
|
1404
|
+
errorUnknownTable(table.name);
|
|
1405
|
+
}
|
|
1406
|
+
const paramDescriptors = [];
|
|
1407
|
+
const paramValues = [];
|
|
1408
|
+
const paramCodecs = {};
|
|
1409
|
+
const whereResult = this.state.where ? buildWhereExpr(this.contract, this.state.where, paramsMap, paramDescriptors, paramValues) : void 0;
|
|
1410
|
+
const whereExpr = whereResult?.expr;
|
|
1411
|
+
if (whereResult?.codecId && whereResult.paramName) {
|
|
1412
|
+
paramCodecs[whereResult.paramName] = whereResult.codecId;
|
|
1413
|
+
}
|
|
1414
|
+
const orderByClause = this.state.orderBy ? (() => {
|
|
1415
|
+
const orderBy = this.state.orderBy;
|
|
1416
|
+
const orderExpr = orderBy.expr;
|
|
1417
|
+
const expr = isOperationExpr(orderExpr) ? orderExpr : (() => {
|
|
1418
|
+
const colBuilder = orderExpr;
|
|
1419
|
+
return createColumnRef5(colBuilder.table, colBuilder.column);
|
|
1420
|
+
})();
|
|
1421
|
+
return [createOrderByItem2(expr, orderBy.dir)];
|
|
1422
|
+
})() : void 0;
|
|
1423
|
+
const joins = this.state.joins?.map((join) => buildJoinAst(join));
|
|
1424
|
+
const includes = this.state.includes?.map(
|
|
1425
|
+
(include) => buildIncludeAst(include, this.contract, paramsMap, paramDescriptors, paramValues)
|
|
1426
|
+
);
|
|
1427
|
+
const projectEntries = [];
|
|
1428
|
+
for (let i = 0; i < projection.aliases.length; i++) {
|
|
1429
|
+
const alias = projection.aliases[i];
|
|
1430
|
+
if (!alias) {
|
|
1431
|
+
errorMissingAlias(i);
|
|
1432
|
+
}
|
|
1433
|
+
const column = projection.columns[i];
|
|
1434
|
+
if (!column) {
|
|
1435
|
+
errorMissingColumnForAlias(alias, i);
|
|
1436
|
+
}
|
|
1437
|
+
const matchingInclude = this.state.includes?.find((inc) => inc.alias === alias);
|
|
1438
|
+
if (matchingInclude) {
|
|
1439
|
+
projectEntries.push({
|
|
1440
|
+
alias,
|
|
1441
|
+
expr: { kind: "includeRef", alias }
|
|
1442
|
+
});
|
|
1443
|
+
} else {
|
|
1444
|
+
const operationExpr = column._operationExpr;
|
|
1445
|
+
if (operationExpr) {
|
|
1446
|
+
projectEntries.push({
|
|
1447
|
+
alias,
|
|
1448
|
+
expr: operationExpr
|
|
1449
|
+
});
|
|
1450
|
+
} else {
|
|
1451
|
+
const col = column;
|
|
1452
|
+
const tableName = col.table;
|
|
1453
|
+
const columnName = col.column;
|
|
1454
|
+
if (!tableName || !columnName) {
|
|
1455
|
+
errorInvalidColumnForAlias(alias, i);
|
|
1456
|
+
}
|
|
1457
|
+
projectEntries.push({
|
|
1458
|
+
alias,
|
|
1459
|
+
expr: createColumnRef5(tableName, columnName)
|
|
1460
|
+
});
|
|
1461
|
+
}
|
|
1462
|
+
}
|
|
1463
|
+
}
|
|
1464
|
+
const ast = createSelectAst({
|
|
1465
|
+
from: createTableRef4(table.name),
|
|
1466
|
+
joins,
|
|
1467
|
+
includes,
|
|
1468
|
+
project: projectEntries,
|
|
1469
|
+
where: whereExpr,
|
|
1470
|
+
orderBy: orderByClause,
|
|
1471
|
+
limit: this.state.limit
|
|
1472
|
+
});
|
|
1473
|
+
const planMeta = buildMeta({
|
|
1474
|
+
contract: this.contract,
|
|
1475
|
+
table,
|
|
1476
|
+
projection,
|
|
1477
|
+
joins: this.state.joins,
|
|
1478
|
+
includes: this.state.includes,
|
|
1479
|
+
paramDescriptors,
|
|
1480
|
+
paramCodecs,
|
|
1481
|
+
where: this.state.where,
|
|
1482
|
+
orderBy: this.state.orderBy
|
|
1483
|
+
});
|
|
1484
|
+
const queryPlan = Object.freeze({
|
|
1485
|
+
ast,
|
|
1486
|
+
params: paramValues,
|
|
1487
|
+
meta: planMeta
|
|
1488
|
+
});
|
|
1489
|
+
return queryPlan;
|
|
1490
|
+
}
|
|
1491
|
+
ensureFrom() {
|
|
1492
|
+
if (!this.state.from) {
|
|
1493
|
+
errorFromMustBeCalled();
|
|
1494
|
+
}
|
|
1495
|
+
return this.state.from;
|
|
1496
|
+
}
|
|
1497
|
+
ensureProjection() {
|
|
1498
|
+
if (!this.state.projection) {
|
|
1499
|
+
errorSelectMustBeCalled();
|
|
1500
|
+
}
|
|
1501
|
+
return this.state.projection;
|
|
1502
|
+
}
|
|
1503
|
+
};
|
|
1504
|
+
|
|
1505
|
+
// src/sql/builder.ts
|
|
1506
|
+
function sql(options) {
|
|
1507
|
+
const builder = new SelectBuilderImpl(
|
|
1508
|
+
options
|
|
1509
|
+
);
|
|
1510
|
+
const rawFactory = createRawFactory(options.context.contract);
|
|
1511
|
+
Object.defineProperty(builder, "raw", {
|
|
1512
|
+
value: rawFactory,
|
|
1513
|
+
enumerable: true,
|
|
1514
|
+
configurable: false
|
|
1515
|
+
});
|
|
1516
|
+
Object.defineProperty(builder, "insert", {
|
|
1517
|
+
value: (table, values) => {
|
|
1518
|
+
return new InsertBuilderImpl(options, table, values);
|
|
1519
|
+
},
|
|
1520
|
+
enumerable: true,
|
|
1521
|
+
configurable: false
|
|
1522
|
+
});
|
|
1523
|
+
Object.defineProperty(builder, "update", {
|
|
1524
|
+
value: (table, set) => {
|
|
1525
|
+
return new UpdateBuilderImpl(options, table, set);
|
|
1526
|
+
},
|
|
1527
|
+
enumerable: true,
|
|
1528
|
+
configurable: false
|
|
1529
|
+
});
|
|
1530
|
+
Object.defineProperty(builder, "delete", {
|
|
1531
|
+
value: (table) => {
|
|
1532
|
+
return new DeleteBuilderImpl(options, table);
|
|
1533
|
+
},
|
|
1534
|
+
enumerable: true,
|
|
1535
|
+
configurable: false
|
|
1536
|
+
});
|
|
1537
|
+
return builder;
|
|
1538
|
+
}
|
|
1539
|
+
|
|
1540
|
+
export {
|
|
1541
|
+
rawOptions,
|
|
1542
|
+
createJoinOnBuilder2 as createJoinOnBuilder,
|
|
1543
|
+
sql
|
|
1544
|
+
};
|
|
1545
|
+
//# sourceMappingURL=chunk-5OSV5CZC.js.map
|