@dbsp/adapter-pgsql 1.6.0 → 1.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +8 -3
- package/dist/index.js +631 -207
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -663,9 +663,6 @@ function funcCall(name, args = [], options = {}) {
|
|
|
663
663
|
function coalesceExpr(args) {
|
|
664
664
|
return { CoalesceExpr: { args } };
|
|
665
665
|
}
|
|
666
|
-
function coalesce(...args) {
|
|
667
|
-
return funcCall("coalesce", args);
|
|
668
|
-
}
|
|
669
666
|
function sortBy(expr, direction = "DEFAULT", nulls = "DEFAULT") {
|
|
670
667
|
const sb = {
|
|
671
668
|
node: expr,
|
|
@@ -4486,6 +4483,11 @@ var init_relation_filter = __esm({
|
|
|
4486
4483
|
|
|
4487
4484
|
// src/subquery-emission.ts
|
|
4488
4485
|
import { isParamIntent as isParamIntent5 } from "@dbsp/types";
|
|
4486
|
+
function isColumnOrderBy(orderBy) {
|
|
4487
|
+
return Array.isArray(orderBy) && orderBy.every(
|
|
4488
|
+
(item) => typeof item === "object" && item !== null && "column" in item && typeof item.column === "string"
|
|
4489
|
+
);
|
|
4490
|
+
}
|
|
4489
4491
|
function assertNoDroppedDecisionModifiers(decision, use) {
|
|
4490
4492
|
const d = decision;
|
|
4491
4493
|
const unsupported = [];
|
|
@@ -4604,8 +4606,9 @@ function buildPredicateSubquerySelect(use, sourceIntent, decision, ctx, state, d
|
|
|
4604
4606
|
],
|
|
4605
4607
|
...whereClause && { whereClause }
|
|
4606
4608
|
};
|
|
4607
|
-
|
|
4608
|
-
|
|
4609
|
+
const orderBy = isColumnOrderBy(decision.orderBy) ? decision.orderBy : void 0;
|
|
4610
|
+
if (orderBy && orderBy.length > 0) {
|
|
4611
|
+
stmt.sortClause = orderBy.map(
|
|
4609
4612
|
(o) => sortBy(
|
|
4610
4613
|
columnRef(o.column, targetAlias, void 0, ctx.naming),
|
|
4611
4614
|
o.direction ?? "ASC",
|
|
@@ -4856,10 +4859,7 @@ var init_where = __esm({
|
|
|
4856
4859
|
hasRelationHandler,
|
|
4857
4860
|
hasNoRelationHandler
|
|
4858
4861
|
];
|
|
4859
|
-
allWhereHandlers = [
|
|
4860
|
-
...simpleWhereHandlers,
|
|
4861
|
-
...complexWhereHandlers
|
|
4862
|
-
];
|
|
4862
|
+
allWhereHandlers = [...simpleWhereHandlers, ...complexWhereHandlers];
|
|
4863
4863
|
}
|
|
4864
4864
|
});
|
|
4865
4865
|
|
|
@@ -5098,19 +5098,19 @@ var init_shared = __esm({
|
|
|
5098
5098
|
});
|
|
5099
5099
|
|
|
5100
5100
|
// src/handlers/include/json-agg.ts
|
|
5101
|
-
import {
|
|
5101
|
+
import { resolveJsonAggOrderKey } from "@dbsp/types";
|
|
5102
|
+
function isJsonAggOrderBy(orderBy) {
|
|
5103
|
+
return Array.isArray(orderBy) && orderBy.every((item) => typeof item === "string");
|
|
5104
|
+
}
|
|
5102
5105
|
function resolveJsonAggOrderBy(decision, targetTable, ctx) {
|
|
5103
5106
|
const table = ctx.model?.getTable(targetTable);
|
|
5104
5107
|
if (table) {
|
|
5105
|
-
const
|
|
5106
|
-
|
|
5107
|
-
columns: table.columns.map((col) => col.name),
|
|
5108
|
-
fallback: true
|
|
5109
|
-
};
|
|
5110
|
-
return orderIntent.columns.length > 0 ? orderIntent : void 0;
|
|
5108
|
+
const orderKey = resolveJsonAggOrderKey(table);
|
|
5109
|
+
return orderKey.columns.length > 0 ? orderKey : void 0;
|
|
5111
5110
|
}
|
|
5112
|
-
|
|
5113
|
-
|
|
5111
|
+
const decisionOrderBy = isJsonAggOrderBy(decision.orderBy) ? decision.orderBy : void 0;
|
|
5112
|
+
return decisionOrderBy && decisionOrderBy.length > 0 ? {
|
|
5113
|
+
columns: decisionOrderBy,
|
|
5114
5114
|
fallback: decision.orderByFallback === true
|
|
5115
5115
|
} : void 0;
|
|
5116
5116
|
}
|
|
@@ -5210,7 +5210,7 @@ var init_json_agg = __esm({
|
|
|
5210
5210
|
});
|
|
5211
5211
|
|
|
5212
5212
|
// src/handlers/include/lateral.ts
|
|
5213
|
-
import { toColumnList as
|
|
5213
|
+
import { toColumnList as toColumnList6 } from "@dbsp/types";
|
|
5214
5214
|
function buildLateralTargets(columns, alias, ctx) {
|
|
5215
5215
|
if (columns && columns.length > 0 && !(columns.length === 1 && columns[0] === "*")) {
|
|
5216
5216
|
return columns.map((col) => ({
|
|
@@ -5312,7 +5312,7 @@ var init_lateral = __esm({
|
|
|
5312
5312
|
lateralIncludeHandler = {
|
|
5313
5313
|
strategy: "lateral",
|
|
5314
5314
|
compile(decision, ctx, state) {
|
|
5315
|
-
const sourceColumn =
|
|
5315
|
+
const sourceColumn = toColumnList6(decision.sourceColumn);
|
|
5316
5316
|
if (sourceColumn.length === 0) {
|
|
5317
5317
|
throw new Error(
|
|
5318
5318
|
"Missing required column 'sourceColumn' in lateral include"
|
|
@@ -5382,10 +5382,6 @@ __export(handlers_exports, {
|
|
|
5382
5382
|
LOGICAL_OPERATORS: () => LOGICAL_OPERATORS,
|
|
5383
5383
|
NULL_OPERATORS: () => NULL_OPERATORS,
|
|
5384
5384
|
PATTERN_OPERATORS: () => PATTERN_OPERATORS,
|
|
5385
|
-
aggregateExpressionHandlers: () => aggregateExpressionHandlers,
|
|
5386
|
-
allExpressionHandlers: () => allExpressionHandlers,
|
|
5387
|
-
allIncludeHandlers: () => allIncludeHandlers,
|
|
5388
|
-
allWhereHandlers: () => allWhereHandlers,
|
|
5389
5385
|
andHandler: () => andHandler,
|
|
5390
5386
|
anyHandler: () => anyHandler,
|
|
5391
5387
|
arithmeticHandler: () => arithmeticHandler,
|
|
@@ -5396,12 +5392,9 @@ __export(handlers_exports, {
|
|
|
5396
5392
|
clearHandlers: () => clearHandlers,
|
|
5397
5393
|
coalesceHandler: () => coalesceHandler,
|
|
5398
5394
|
columnAliasHandler: () => columnAliasHandler,
|
|
5399
|
-
columnExpressionHandlers: () => columnExpressionHandlers,
|
|
5400
5395
|
columnHandler: () => columnHandler,
|
|
5401
5396
|
comparisonHandler: () => comparisonHandler,
|
|
5402
5397
|
compileExpressionIntent: () => compileExpressionIntent,
|
|
5403
|
-
complexWhereHandlers: () => complexWhereHandlers,
|
|
5404
|
-
conditionalExpressionHandlers: () => conditionalExpressionHandlers,
|
|
5405
5398
|
countDistinctHandler: () => countDistinctHandler,
|
|
5406
5399
|
countHandler: () => countHandler,
|
|
5407
5400
|
createCompilerState: () => createCompilerState,
|
|
@@ -5438,7 +5431,6 @@ __export(handlers_exports, {
|
|
|
5438
5431
|
jsonComparisonHandler: () => jsonComparisonHandler,
|
|
5439
5432
|
jsonContainsHandler: () => jsonContainsHandler,
|
|
5440
5433
|
jsonExistsHandler: () => jsonExistsHandler,
|
|
5441
|
-
jsonExpressionHandlers: () => jsonExpressionHandlers,
|
|
5442
5434
|
jsonExtractHandler: () => jsonExtractHandler,
|
|
5443
5435
|
jsonPathExtractHandler: () => jsonPathExtractHandler,
|
|
5444
5436
|
lagHandler: () => lagHandler,
|
|
@@ -5459,11 +5451,9 @@ __export(handlers_exports, {
|
|
|
5459
5451
|
orHandler: () => orHandler,
|
|
5460
5452
|
prefixedRelationColumnHandler: () => prefixedRelationColumnHandler,
|
|
5461
5453
|
pseudoColumnHandler: () => pseudoColumnHandler,
|
|
5462
|
-
pseudoExpressionHandlers: () => pseudoExpressionHandlers,
|
|
5463
5454
|
rangeHandler: () => rangeHandler,
|
|
5464
5455
|
rankHandler: () => rankHandler,
|
|
5465
5456
|
rawExistsHandler: () => rawExistsHandler,
|
|
5466
|
-
rawExpressionHandlers: () => rawExpressionHandlers,
|
|
5467
5457
|
rawHandler: () => rawHandler,
|
|
5468
5458
|
registerAllExpressionHandlers: () => registerAllExpressionHandlers,
|
|
5469
5459
|
registerAllIncludeHandlers: () => registerAllIncludeHandlers,
|
|
@@ -5475,7 +5465,6 @@ __export(handlers_exports, {
|
|
|
5475
5465
|
relationAliasHandler: () => relationAliasHandler,
|
|
5476
5466
|
relationColumnHandler: () => relationColumnHandler,
|
|
5477
5467
|
relationColumnsHandler: () => relationColumnsHandler,
|
|
5478
|
-
relationExpressionHandlers: () => relationExpressionHandlers,
|
|
5479
5468
|
relationFilterHandler: () => relationFilterHandler,
|
|
5480
5469
|
relationStarHandler: () => relationStarHandler,
|
|
5481
5470
|
rowNumberHandler: () => rowNumberHandler,
|
|
@@ -5485,8 +5474,7 @@ __export(handlers_exports, {
|
|
|
5485
5474
|
singleHopPseudoHandler: () => singleHopPseudoHandler,
|
|
5486
5475
|
sqlFunctionHandler: () => sqlFunctionHandler,
|
|
5487
5476
|
starHandler: () => starHandler,
|
|
5488
|
-
sumHandler: () => sumHandler
|
|
5489
|
-
windowExpressionHandlers: () => windowExpressionHandlers
|
|
5477
|
+
sumHandler: () => sumHandler
|
|
5490
5478
|
});
|
|
5491
5479
|
function registerWhereHandler(handler) {
|
|
5492
5480
|
for (const op3 of handler.operators) {
|
|
@@ -6267,6 +6255,7 @@ function buildRecursiveScalarSubquery(config) {
|
|
|
6267
6255
|
pkColumn,
|
|
6268
6256
|
fkColumn,
|
|
6269
6257
|
outerAlias,
|
|
6258
|
+
outerSeedColumn,
|
|
6270
6259
|
isAncestors,
|
|
6271
6260
|
maxDepth,
|
|
6272
6261
|
selectColumn,
|
|
@@ -6277,6 +6266,9 @@ function buildRecursiveScalarSubquery(config) {
|
|
|
6277
6266
|
const dbPk = naming.toDatabase(pkColumn);
|
|
6278
6267
|
const dbFk = naming.toDatabase(fkColumn);
|
|
6279
6268
|
const dbOuter = naming.toDatabase(outerAlias);
|
|
6269
|
+
const dbOuterSeed = naming.toDatabase(
|
|
6270
|
+
outerSeedColumn ?? (isAncestors ? fkColumn : pkColumn)
|
|
6271
|
+
);
|
|
6280
6272
|
const innerAlias = "__n";
|
|
6281
6273
|
const anchorSelect = {
|
|
6282
6274
|
targetList: [
|
|
@@ -6345,7 +6337,7 @@ function buildRecursiveScalarSubquery(config) {
|
|
|
6345
6337
|
ColumnRef: {
|
|
6346
6338
|
fields: [
|
|
6347
6339
|
{ String: { sval: dbOuter } },
|
|
6348
|
-
{ String: { sval:
|
|
6340
|
+
{ String: { sval: dbOuterSeed } }
|
|
6349
6341
|
]
|
|
6350
6342
|
}
|
|
6351
6343
|
}
|
|
@@ -6365,7 +6357,7 @@ function buildRecursiveScalarSubquery(config) {
|
|
|
6365
6357
|
ColumnRef: {
|
|
6366
6358
|
fields: [
|
|
6367
6359
|
{ String: { sval: dbOuter } },
|
|
6368
|
-
{ String: { sval:
|
|
6360
|
+
{ String: { sval: dbOuterSeed } }
|
|
6369
6361
|
]
|
|
6370
6362
|
}
|
|
6371
6363
|
}
|
|
@@ -6429,15 +6421,7 @@ function buildRecursiveScalarSubquery(config) {
|
|
|
6429
6421
|
}
|
|
6430
6422
|
],
|
|
6431
6423
|
fromClause: [
|
|
6432
|
-
// FROM __rc
|
|
6433
|
-
{
|
|
6434
|
-
RangeVar: {
|
|
6435
|
-
relname: cteAlias,
|
|
6436
|
-
inh: true,
|
|
6437
|
-
relpersistence: "p"
|
|
6438
|
-
}
|
|
6439
|
-
},
|
|
6440
|
-
// INNER JOIN table AS __n
|
|
6424
|
+
// FROM __rc INNER JOIN table AS __n
|
|
6441
6425
|
{
|
|
6442
6426
|
JoinExpr: {
|
|
6443
6427
|
jointype: "JOIN_INNER",
|
|
@@ -6520,7 +6504,7 @@ function buildRecursiveScalarSubquery(config) {
|
|
|
6520
6504
|
},
|
|
6521
6505
|
integerNode(maxDepth)
|
|
6522
6506
|
),
|
|
6523
|
-
// pk <> ALL(__visited)
|
|
6507
|
+
// pk <> ALL(__visited) - cycle detection
|
|
6524
6508
|
{
|
|
6525
6509
|
A_Expr: {
|
|
6526
6510
|
kind: "AEXPR_OP_ALL",
|
|
@@ -6565,20 +6549,35 @@ function buildRecursiveScalarSubquery(config) {
|
|
|
6565
6549
|
targetList: [
|
|
6566
6550
|
{
|
|
6567
6551
|
ResTarget: {
|
|
6568
|
-
val:
|
|
6569
|
-
funcCall(
|
|
6570
|
-
|
|
6571
|
-
|
|
6572
|
-
|
|
6573
|
-
|
|
6574
|
-
|
|
6575
|
-
|
|
6552
|
+
val: coalesceExpr([
|
|
6553
|
+
funcCall(
|
|
6554
|
+
"json_agg",
|
|
6555
|
+
[
|
|
6556
|
+
{
|
|
6557
|
+
ColumnRef: {
|
|
6558
|
+
fields: [
|
|
6559
|
+
{ String: { sval: cteAlias } },
|
|
6560
|
+
{ String: { sval: dbSelectCol } }
|
|
6561
|
+
]
|
|
6562
|
+
}
|
|
6576
6563
|
}
|
|
6564
|
+
],
|
|
6565
|
+
{
|
|
6566
|
+
orderBy: [
|
|
6567
|
+
sortBy({
|
|
6568
|
+
ColumnRef: {
|
|
6569
|
+
fields: [
|
|
6570
|
+
{ String: { sval: cteAlias } },
|
|
6571
|
+
{ String: { sval: "__depth" } }
|
|
6572
|
+
]
|
|
6573
|
+
}
|
|
6574
|
+
})
|
|
6575
|
+
]
|
|
6577
6576
|
}
|
|
6578
|
-
|
|
6577
|
+
),
|
|
6579
6578
|
// Empty array fallback: '[]'::json
|
|
6580
|
-
typeCast(
|
|
6581
|
-
)
|
|
6579
|
+
typeCast({ A_Const: { sval: { sval: "[]" } } }, "json")
|
|
6580
|
+
])
|
|
6582
6581
|
}
|
|
6583
6582
|
}
|
|
6584
6583
|
],
|
|
@@ -6915,6 +6914,14 @@ var init_raw = __esm({
|
|
|
6915
6914
|
});
|
|
6916
6915
|
|
|
6917
6916
|
// src/handlers/expression/relation.ts
|
|
6917
|
+
function resolveRelationAlias(relation, state, options = {}) {
|
|
6918
|
+
if (options.resolveDottedLeaf && relation.includes(".")) {
|
|
6919
|
+
const segments = relation.split(".");
|
|
6920
|
+
const leaf = segments[segments.length - 1];
|
|
6921
|
+
return state.aliases.get(relation) ?? state.aliases.get(leaf) ?? leaf;
|
|
6922
|
+
}
|
|
6923
|
+
return state.aliases.get(relation) ?? relation;
|
|
6924
|
+
}
|
|
6918
6925
|
var relationStarHandler, relationColumnHandler, relationColumnsHandler, relationAliasHandler, prefixedRelationColumnHandler;
|
|
6919
6926
|
var init_relation = __esm({
|
|
6920
6927
|
"src/handlers/expression/relation.ts"() {
|
|
@@ -6947,14 +6954,9 @@ var init_relation = __esm({
|
|
|
6947
6954
|
if (!column) {
|
|
6948
6955
|
throw new Error("Relation column handler requires column name");
|
|
6949
6956
|
}
|
|
6950
|
-
|
|
6951
|
-
|
|
6952
|
-
|
|
6953
|
-
const leaf = segments[segments.length - 1];
|
|
6954
|
-
alias = state.aliases.get(relation) ?? state.aliases.get(leaf) ?? leaf;
|
|
6955
|
-
} else {
|
|
6956
|
-
alias = state.aliases.get(relation) ?? relation;
|
|
6957
|
-
}
|
|
6957
|
+
const alias = resolveRelationAlias(relation, state, {
|
|
6958
|
+
resolveDottedLeaf: true
|
|
6959
|
+
});
|
|
6958
6960
|
if (column === "*") {
|
|
6959
6961
|
return columnRefStar(alias, ctx.naming);
|
|
6960
6962
|
}
|
|
@@ -6972,7 +6974,7 @@ var init_relation = __esm({
|
|
|
6972
6974
|
if (!columns || columns.length === 0) {
|
|
6973
6975
|
throw new Error("Relation columns handler requires columns array");
|
|
6974
6976
|
}
|
|
6975
|
-
const alias =
|
|
6977
|
+
const alias = resolveRelationAlias(relation, state);
|
|
6976
6978
|
const column = columns[0];
|
|
6977
6979
|
const colRef = columnRef(column, alias, void 0, ctx.naming);
|
|
6978
6980
|
const outputAlias = decision.alias;
|
|
@@ -6998,7 +7000,7 @@ var init_relation = __esm({
|
|
|
6998
7000
|
if (!column) {
|
|
6999
7001
|
throw new Error("Relation alias handler requires column name");
|
|
7000
7002
|
}
|
|
7001
|
-
const tableAlias =
|
|
7003
|
+
const tableAlias = resolveRelationAlias(relation, state);
|
|
7002
7004
|
const colRef = columnRef(column, tableAlias, void 0, ctx.naming);
|
|
7003
7005
|
if (!outputAlias) {
|
|
7004
7006
|
return colRef;
|
|
@@ -7037,6 +7039,11 @@ var init_relation = __esm({
|
|
|
7037
7039
|
});
|
|
7038
7040
|
|
|
7039
7041
|
// src/handlers/expression/window.ts
|
|
7042
|
+
function isWindowOrderBy(orderBy) {
|
|
7043
|
+
return Array.isArray(orderBy) && orderBy.every(
|
|
7044
|
+
(item) => typeof item === "object" && item !== null && "column" in item && typeof item.column === "string"
|
|
7045
|
+
);
|
|
7046
|
+
}
|
|
7040
7047
|
function buildSortBy(column, direction, ctx) {
|
|
7041
7048
|
const tableAlias = ctx.currentAlias ?? ctx.rootTable;
|
|
7042
7049
|
const colRef = columnRef(column, tableAlias, void 0, ctx.naming);
|
|
@@ -7049,7 +7056,7 @@ function buildSortBy(column, direction, ctx) {
|
|
|
7049
7056
|
}
|
|
7050
7057
|
function buildWindowDef(decision, ctx) {
|
|
7051
7058
|
const partition = decision.partition;
|
|
7052
|
-
const orderBy = decision.orderBy;
|
|
7059
|
+
const orderBy = isWindowOrderBy(decision.orderBy) ? decision.orderBy : void 0;
|
|
7053
7060
|
const frame = decision.frame;
|
|
7054
7061
|
const tableAlias = ctx.currentAlias ?? ctx.rootTable;
|
|
7055
7062
|
const windowDef = { frameOptions: WINDOW_FRAME_DEFAULT };
|
|
@@ -7264,15 +7271,8 @@ var init_expression = __esm({
|
|
|
7264
7271
|
lastValueHandler,
|
|
7265
7272
|
genericWindowHandler
|
|
7266
7273
|
];
|
|
7267
|
-
rawExpressionHandlers = [
|
|
7268
|
-
|
|
7269
|
-
sqlFunctionHandler,
|
|
7270
|
-
literalHandler
|
|
7271
|
-
];
|
|
7272
|
-
jsonExpressionHandlers = [
|
|
7273
|
-
jsonExtractHandler,
|
|
7274
|
-
jsonPathExtractHandler
|
|
7275
|
-
];
|
|
7274
|
+
rawExpressionHandlers = [rawHandler, sqlFunctionHandler, literalHandler];
|
|
7275
|
+
jsonExpressionHandlers = [jsonExtractHandler, jsonPathExtractHandler];
|
|
7276
7276
|
pseudoExpressionHandlers = [
|
|
7277
7277
|
pseudoColumnHandler,
|
|
7278
7278
|
singleHopPseudoHandler,
|
|
@@ -7313,7 +7313,7 @@ import {
|
|
|
7313
7313
|
isParamIntent as isParamIntent6,
|
|
7314
7314
|
NQL_SELECT_SCALAR_FUNCTION_ALLOWLIST,
|
|
7315
7315
|
NQL_SELECT_WINDOW_FUNCTION_ALLOWLIST,
|
|
7316
|
-
toColumnList as
|
|
7316
|
+
toColumnList as toColumnList7
|
|
7317
7317
|
} from "@dbsp/types";
|
|
7318
7318
|
import {
|
|
7319
7319
|
getNqlBindingRefName,
|
|
@@ -8379,6 +8379,7 @@ init_case_value();
|
|
|
8379
8379
|
init_custom();
|
|
8380
8380
|
init_expression();
|
|
8381
8381
|
init_param_value();
|
|
8382
|
+
init_pseudo();
|
|
8382
8383
|
init_window();
|
|
8383
8384
|
init_include();
|
|
8384
8385
|
init_shared();
|
|
@@ -8425,7 +8426,7 @@ function trustedRelationHasMultipleHops(relation) {
|
|
|
8425
8426
|
if (typeof relation !== "string") return relation.length > 1;
|
|
8426
8427
|
return relation.split(".").length > 1;
|
|
8427
8428
|
}
|
|
8428
|
-
function
|
|
8429
|
+
function isJsonAggOrderBy2(orderBy) {
|
|
8429
8430
|
return Array.isArray(orderBy) && orderBy.every((item) => typeof item === "string");
|
|
8430
8431
|
}
|
|
8431
8432
|
function isExpressionOrderBy(orderBy) {
|
|
@@ -8434,8 +8435,12 @@ function isExpressionOrderBy(orderBy) {
|
|
|
8434
8435
|
);
|
|
8435
8436
|
}
|
|
8436
8437
|
function mapToHandlerDecision(pd, rootTable, defaultPk, deriveFk) {
|
|
8437
|
-
const jsonAggOrderBy =
|
|
8438
|
+
const jsonAggOrderBy = isJsonAggOrderBy2(pd.orderBy) ? pd.orderBy : void 0;
|
|
8438
8439
|
const expressionOrderBy = isExpressionOrderBy(pd.orderBy) ? pd.orderBy : void 0;
|
|
8440
|
+
const handlerOrderBy = jsonAggOrderBy ?? expressionOrderBy?.map((o) => ({
|
|
8441
|
+
column: o.field,
|
|
8442
|
+
direction: o.direction?.toUpperCase() ?? "ASC"
|
|
8443
|
+
}));
|
|
8439
8444
|
const derivedFkColumns = deriveFkColumns(
|
|
8440
8445
|
pd,
|
|
8441
8446
|
pd.sourceTable ?? rootTable,
|
|
@@ -8470,7 +8475,6 @@ function mapToHandlerDecision(pd, rootTable, defaultPk, deriveFk) {
|
|
|
8470
8475
|
relationType: pd.relationType,
|
|
8471
8476
|
foreignKey: pd.foreignKey,
|
|
8472
8477
|
parentKey: pd.parentKey,
|
|
8473
|
-
targetPrimaryKey: pd.targetPrimaryKey ?? jsonAggOrderBy,
|
|
8474
8478
|
orderByFallback: pd.orderByFallback,
|
|
8475
8479
|
dataType: pd.dataType,
|
|
8476
8480
|
traversal: pd.traversal,
|
|
@@ -8486,10 +8490,7 @@ function mapToHandlerDecision(pd, rootTable, defaultPk, deriveFk) {
|
|
|
8486
8490
|
include: pd.include?.map(
|
|
8487
8491
|
(c) => mapToHandlerDecision(c, rootTable, defaultPk, deriveFk)
|
|
8488
8492
|
),
|
|
8489
|
-
orderBy:
|
|
8490
|
-
column: o.field,
|
|
8491
|
-
direction: o.direction?.toUpperCase() ?? "ASC"
|
|
8492
|
-
})),
|
|
8493
|
+
orderBy: handlerOrderBy,
|
|
8493
8494
|
partition: pd.partitionBy,
|
|
8494
8495
|
jsonPath: pd.jsonPath,
|
|
8495
8496
|
jsonMode: pd.jsonMode,
|
|
@@ -9048,8 +9049,11 @@ var PlanCompiler = class _PlanCompiler {
|
|
|
9048
9049
|
isNqlBindingRoot(plan) {
|
|
9049
9050
|
return hasBindingName(this.bindingNames, plan.rootTable, this.naming);
|
|
9050
9051
|
}
|
|
9052
|
+
allocateBindingRelationAlias() {
|
|
9053
|
+
return `rc_${this.bindingRelationColumnSubqueryIndex++}`;
|
|
9054
|
+
}
|
|
9051
9055
|
buildCorrelatedRelationRefs(fields, plan) {
|
|
9052
|
-
const relatedAlias =
|
|
9056
|
+
const relatedAlias = this.allocateBindingRelationAlias();
|
|
9053
9057
|
const relatedTable = rangeVar(
|
|
9054
9058
|
fields.targetTable,
|
|
9055
9059
|
relatedAlias,
|
|
@@ -9068,12 +9072,93 @@ var PlanCompiler = class _PlanCompiler {
|
|
|
9068
9072
|
relatedColumn
|
|
9069
9073
|
};
|
|
9070
9074
|
}
|
|
9075
|
+
bindingRelationHasCompleteManyToManyProof(fields) {
|
|
9076
|
+
return (fields.relationType === "manyToMany" || fields.relationType === "belongsToMany") && fields.through !== void 0 && fields.throughSourceColumn !== void 0 && fields.throughTargetColumn !== void 0;
|
|
9077
|
+
}
|
|
9078
|
+
bindingRelationName(fields) {
|
|
9079
|
+
return typeof fields.relation === "string" ? fields.relation : fields.relation.join(".");
|
|
9080
|
+
}
|
|
9081
|
+
bindingRelationNameLooksRecursive(fields) {
|
|
9082
|
+
const relationName = this.bindingRelationName(fields).toLowerCase();
|
|
9083
|
+
return relationName === "ascendant" || relationName === "descendant";
|
|
9084
|
+
}
|
|
9085
|
+
compileBindingRecursiveRelationColumnSubquery(fields, plan, dialectCapabilities) {
|
|
9086
|
+
const recursive = fields.recursive;
|
|
9087
|
+
if (recursive === void 0) {
|
|
9088
|
+
throw new Error(
|
|
9089
|
+
`NQL binding recursive relation-column proof for '${plan.rootTable}' is missing recursive metadata.`
|
|
9090
|
+
);
|
|
9091
|
+
}
|
|
9092
|
+
if (fields.cardinality !== "many") {
|
|
9093
|
+
throw new Error(
|
|
9094
|
+
`NQL binding recursive relation-column proof for '${plan.rootTable}' must use cardinality 'many'.`
|
|
9095
|
+
);
|
|
9096
|
+
}
|
|
9097
|
+
if (fields.sourceColumn.length !== 1) {
|
|
9098
|
+
throw new Error(
|
|
9099
|
+
`NQL binding recursive relation-column proof for '${plan.rootTable}' must carry exactly one projected seed column.`
|
|
9100
|
+
);
|
|
9101
|
+
}
|
|
9102
|
+
if (dialectCapabilities?.supportsRecursiveCTE === false) {
|
|
9103
|
+
throw new Error(
|
|
9104
|
+
`Recursive NQL binding relation columns require a dialect with supportsRecursiveCTE; current dialect (${dialectCapabilities.name}) declared it unsupported.`
|
|
9105
|
+
);
|
|
9106
|
+
}
|
|
9107
|
+
assertDialectCapability(
|
|
9108
|
+
dialectCapabilities,
|
|
9109
|
+
"supportsJsonAgg",
|
|
9110
|
+
"JSON aggregation for NQL binding relation columns is"
|
|
9111
|
+
);
|
|
9112
|
+
const seedColumn = fields.sourceColumn[0];
|
|
9113
|
+
if (!seedColumn) {
|
|
9114
|
+
throw new Error(
|
|
9115
|
+
`NQL binding recursive relation-column proof for '${plan.rootTable}' is missing its projected seed column.`
|
|
9116
|
+
);
|
|
9117
|
+
}
|
|
9118
|
+
const relatedAlias = this.allocateBindingRelationAlias();
|
|
9119
|
+
return buildRecursiveScalarSubquery({
|
|
9120
|
+
cteAlias: `__${relatedAlias}`,
|
|
9121
|
+
table: fields.targetTable,
|
|
9122
|
+
pkColumn: recursive.targetKeyColumn,
|
|
9123
|
+
fkColumn: recursive.selfRefColumn,
|
|
9124
|
+
outerAlias: plan.rootTable,
|
|
9125
|
+
outerSeedColumn: seedColumn,
|
|
9126
|
+
isAncestors: recursive.direction === "up",
|
|
9127
|
+
maxDepth: recursive.maxDepth,
|
|
9128
|
+
selectColumn: fields.selectedColumn,
|
|
9129
|
+
ctx: this.createHandlerContext(plan, plan.rootTable)
|
|
9130
|
+
});
|
|
9131
|
+
}
|
|
9071
9132
|
compileBindingRelationColumnSubquery(fields, plan, dialectCapabilities) {
|
|
9072
9133
|
if (fields.selectedColumn === void 0) {
|
|
9073
9134
|
throw new Error(
|
|
9074
9135
|
`NQL binding relation-column proof for '${plan.rootTable}' is missing selectedColumn.`
|
|
9075
9136
|
);
|
|
9076
9137
|
}
|
|
9138
|
+
if (fields.recursive !== void 0) {
|
|
9139
|
+
return this.compileBindingRecursiveRelationColumnSubquery(
|
|
9140
|
+
fields,
|
|
9141
|
+
plan,
|
|
9142
|
+
dialectCapabilities
|
|
9143
|
+
);
|
|
9144
|
+
}
|
|
9145
|
+
if (this.bindingRelationNameLooksRecursive(fields)) {
|
|
9146
|
+
throw new Error(
|
|
9147
|
+
`NQL binding recursive relation-column proof for '${plan.rootTable}' is missing recursive metadata.`
|
|
9148
|
+
);
|
|
9149
|
+
}
|
|
9150
|
+
const isManyToManyRelation = fields.relationType === "manyToMany" || fields.relationType === "belongsToMany";
|
|
9151
|
+
const hasCompleteManyToManyProof = this.bindingRelationHasCompleteManyToManyProof(fields);
|
|
9152
|
+
if (isManyToManyRelation && (fields.cardinality !== "many" || !hasCompleteManyToManyProof)) {
|
|
9153
|
+
if (fields.cardinality !== "many") {
|
|
9154
|
+
throw new Error(
|
|
9155
|
+
`NQL binding relation-column proof for '${plan.rootTable}' is manyToMany but must use cardinality 'many' with complete junction proof (through, throughSourceColumn, throughTargetColumn) (ref-#192).`
|
|
9156
|
+
);
|
|
9157
|
+
}
|
|
9158
|
+
throw new Error(
|
|
9159
|
+
`NQL binding relation-column proof for '${plan.rootTable}' is manyToMany but missing complete junction proof (through, throughSourceColumn, throughTargetColumn) (ref-#192).`
|
|
9160
|
+
);
|
|
9161
|
+
}
|
|
9077
9162
|
if (fields.cardinality === "one") {
|
|
9078
9163
|
const { relatedAlias, relatedTable, relatedColumn } = this.buildCorrelatedRelationRefs(fields, plan);
|
|
9079
9164
|
if (fields.hops.length === 0 && trustedRelationHasMultipleHops(fields.relation)) {
|
|
@@ -9152,9 +9237,14 @@ var PlanCompiler = class _PlanCompiler {
|
|
|
9152
9237
|
};
|
|
9153
9238
|
}
|
|
9154
9239
|
if (fields.cardinality === "many") {
|
|
9155
|
-
if (fields.relationType !== "hasMany") {
|
|
9240
|
+
if (fields.relationType !== "hasMany" && fields.relationType !== "manyToMany" && fields.relationType !== "belongsToMany") {
|
|
9156
9241
|
throw new Error(
|
|
9157
|
-
`NQL binding relation-column proof for '${plan.rootTable}' has cardinality 'many' but relationType '${fields.relationType ?? "unknown"}' is not supported; only hasMany can be aggregated (ref-#192).`
|
|
9242
|
+
`NQL binding relation-column proof for '${plan.rootTable}' has cardinality 'many' but relationType '${fields.relationType ?? "unknown"}' is not supported; only hasMany or manyToMany can be aggregated (ref-#192).`
|
|
9243
|
+
);
|
|
9244
|
+
}
|
|
9245
|
+
if ((fields.relationType === "manyToMany" || fields.relationType === "belongsToMany") && !hasCompleteManyToManyProof) {
|
|
9246
|
+
throw new Error(
|
|
9247
|
+
`NQL binding relation-column proof for '${plan.rootTable}' is manyToMany but missing complete junction proof (through, throughSourceColumn, throughTargetColumn) (ref-#192).`
|
|
9158
9248
|
);
|
|
9159
9249
|
}
|
|
9160
9250
|
if (dialectCapabilities?.supportsJsonAgg === false) {
|
|
@@ -9163,6 +9253,37 @@ var PlanCompiler = class _PlanCompiler {
|
|
|
9163
9253
|
);
|
|
9164
9254
|
}
|
|
9165
9255
|
const { relatedAlias, relatedTable, relatedColumn } = this.buildCorrelatedRelationRefs(fields, plan);
|
|
9256
|
+
const junctionAlias = hasCompleteManyToManyProof ? this.allocateBindingRelationAlias() : void 0;
|
|
9257
|
+
const handlerContext = this.createHandlerContext(plan);
|
|
9258
|
+
const fromNode = hasCompleteManyToManyProof ? innerJoin(
|
|
9259
|
+
relatedTable,
|
|
9260
|
+
rangeVar(
|
|
9261
|
+
fields.through,
|
|
9262
|
+
junctionAlias,
|
|
9263
|
+
this.schemaForRangeVar(plan, fields.through),
|
|
9264
|
+
this.naming
|
|
9265
|
+
),
|
|
9266
|
+
buildKeyCorrelation(
|
|
9267
|
+
relatedAlias,
|
|
9268
|
+
fields.targetColumn,
|
|
9269
|
+
junctionAlias,
|
|
9270
|
+
[fields.throughTargetColumn],
|
|
9271
|
+
handlerContext
|
|
9272
|
+
)
|
|
9273
|
+
) : relatedTable;
|
|
9274
|
+
const whereNode = hasCompleteManyToManyProof ? buildKeyCorrelation(
|
|
9275
|
+
junctionAlias,
|
|
9276
|
+
[fields.throughSourceColumn],
|
|
9277
|
+
plan.rootTable,
|
|
9278
|
+
fields.sourceColumn,
|
|
9279
|
+
handlerContext
|
|
9280
|
+
) : buildKeyCorrelation(
|
|
9281
|
+
relatedAlias,
|
|
9282
|
+
fields.targetColumn,
|
|
9283
|
+
plan.rootTable,
|
|
9284
|
+
fields.sourceColumn,
|
|
9285
|
+
handlerContext
|
|
9286
|
+
);
|
|
9166
9287
|
return {
|
|
9167
9288
|
SubLink: {
|
|
9168
9289
|
subLinkType: "EXPR_SUBLINK",
|
|
@@ -9185,14 +9306,8 @@ var PlanCompiler = class _PlanCompiler {
|
|
|
9185
9306
|
}
|
|
9186
9307
|
}
|
|
9187
9308
|
],
|
|
9188
|
-
from: [
|
|
9189
|
-
where:
|
|
9190
|
-
relatedAlias,
|
|
9191
|
-
fields.targetColumn,
|
|
9192
|
-
plan.rootTable,
|
|
9193
|
-
fields.sourceColumn,
|
|
9194
|
-
this.createHandlerContext(plan)
|
|
9195
|
-
)
|
|
9309
|
+
from: [fromNode],
|
|
9310
|
+
where: whereNode
|
|
9196
9311
|
})
|
|
9197
9312
|
}
|
|
9198
9313
|
};
|
|
@@ -10357,8 +10472,8 @@ var PlanCompiler = class _PlanCompiler {
|
|
|
10357
10472
|
this.schemaForRangeVar(plan, decision.targetTable ?? ""),
|
|
10358
10473
|
this.naming
|
|
10359
10474
|
);
|
|
10360
|
-
const sourceColumn =
|
|
10361
|
-
const targetColumn =
|
|
10475
|
+
const sourceColumn = toColumnList7(decision.sourceColumn);
|
|
10476
|
+
const targetColumn = toColumnList7(decision.targetColumn);
|
|
10362
10477
|
if (sourceColumn.length === 0) {
|
|
10363
10478
|
throw new Error("Missing required column 'sourceColumn' in compileJoin");
|
|
10364
10479
|
}
|
|
@@ -10797,6 +10912,12 @@ function buildSequenceClause(verb, seqName, seq, includeCycleNoCycle = false) {
|
|
|
10797
10912
|
}
|
|
10798
10913
|
return `${parts.join(" ")};`;
|
|
10799
10914
|
}
|
|
10915
|
+
function failSafeUnknownDownChange(kind) {
|
|
10916
|
+
return {
|
|
10917
|
+
sql: `-- WARNING: Cannot reverse unsupported SchemaChange kind "${kind}"`,
|
|
10918
|
+
destructive: true
|
|
10919
|
+
};
|
|
10920
|
+
}
|
|
10800
10921
|
function isChangeSupported(kind, caps) {
|
|
10801
10922
|
switch (kind) {
|
|
10802
10923
|
case "create_enum":
|
|
@@ -11249,188 +11370,381 @@ function changeToUpSQL(change, schemaName) {
|
|
|
11249
11370
|
function changeToDownSQL(change, schemaName) {
|
|
11250
11371
|
switch (change.kind) {
|
|
11251
11372
|
case "create_table":
|
|
11252
|
-
return
|
|
11373
|
+
return {
|
|
11374
|
+
sql: `DROP TABLE IF EXISTS ${qualifyTable(change.table, schemaName)} CASCADE;`,
|
|
11375
|
+
destructive: true
|
|
11376
|
+
};
|
|
11253
11377
|
case "drop_table":
|
|
11254
|
-
return
|
|
11378
|
+
return {
|
|
11379
|
+
sql: `-- WARNING: Cannot reverse drop_table "${change.table}" -- table data was lost`,
|
|
11380
|
+
destructive: true
|
|
11381
|
+
};
|
|
11255
11382
|
case "add_column":
|
|
11256
|
-
return
|
|
11383
|
+
return {
|
|
11384
|
+
sql: `ALTER TABLE ${qualifyTable(change.table, schemaName)} DROP COLUMN ${quoteIdent2(change.column, "alias")} CASCADE;`,
|
|
11385
|
+
destructive: true
|
|
11386
|
+
};
|
|
11257
11387
|
case "drop_column":
|
|
11258
|
-
return
|
|
11388
|
+
return {
|
|
11389
|
+
sql: `-- WARNING: Cannot reverse drop_column "${change.table}"."${change.column}" -- column data was lost`,
|
|
11390
|
+
destructive: true
|
|
11391
|
+
};
|
|
11259
11392
|
case "alter_column_type": {
|
|
11260
11393
|
const fromType = change.meta?.fromType;
|
|
11261
11394
|
if (!fromType) {
|
|
11262
|
-
return
|
|
11395
|
+
return {
|
|
11396
|
+
sql: `-- WARNING: Cannot reverse alter_column_type "${change.table}"."${change.column}" -- missing migration metadata`,
|
|
11397
|
+
destructive: true
|
|
11398
|
+
};
|
|
11263
11399
|
}
|
|
11264
|
-
return
|
|
11400
|
+
return {
|
|
11401
|
+
sql: `ALTER TABLE ${qualifyTable(change.table, schemaName)} ALTER COLUMN ${quoteIdent2(change.column, "alias")} TYPE ${fromType};`,
|
|
11402
|
+
destructive: true
|
|
11403
|
+
};
|
|
11265
11404
|
}
|
|
11266
11405
|
case "alter_column_nullable": {
|
|
11267
11406
|
const oldNullable = change.meta?.oldNullable;
|
|
11268
11407
|
if (oldNullable === void 0) {
|
|
11269
|
-
return
|
|
11408
|
+
return {
|
|
11409
|
+
sql: `-- WARNING: Cannot reverse alter_column_nullable "${change.table}"."${change.column}" -- missing migration metadata`,
|
|
11410
|
+
destructive: true
|
|
11411
|
+
};
|
|
11270
11412
|
}
|
|
11271
11413
|
const action = oldNullable ? "DROP NOT NULL" : "SET NOT NULL";
|
|
11272
|
-
return
|
|
11414
|
+
return {
|
|
11415
|
+
sql: `ALTER TABLE ${qualifyTable(change.table, schemaName)} ALTER COLUMN ${quoteIdent2(change.column, "alias")} ${action};`,
|
|
11416
|
+
// Allowlisted: restores the recorded prior nullability metadata.
|
|
11417
|
+
destructive: false
|
|
11418
|
+
};
|
|
11273
11419
|
}
|
|
11274
11420
|
case "alter_column_default": {
|
|
11275
11421
|
const oldDefault = change.meta?.oldDefault;
|
|
11276
11422
|
if (oldDefault === void 0) {
|
|
11277
|
-
return
|
|
11423
|
+
return {
|
|
11424
|
+
sql: `-- WARNING: Cannot reverse alter_column_default "${change.table}"."${change.column}" -- missing migration metadata`,
|
|
11425
|
+
destructive: true
|
|
11426
|
+
};
|
|
11278
11427
|
}
|
|
11279
11428
|
if (oldDefault === null) {
|
|
11280
|
-
return
|
|
11429
|
+
return {
|
|
11430
|
+
sql: `ALTER TABLE ${qualifyTable(change.table, schemaName)} ALTER COLUMN ${quoteIdent2(change.column, "alias")} DROP DEFAULT;`,
|
|
11431
|
+
// Allowlisted: restores the recorded prior state of "no default".
|
|
11432
|
+
destructive: false
|
|
11433
|
+
};
|
|
11281
11434
|
}
|
|
11282
|
-
return
|
|
11435
|
+
return {
|
|
11436
|
+
sql: `ALTER TABLE ${qualifyTable(change.table, schemaName)} ALTER COLUMN ${quoteIdent2(change.column, "alias")} SET DEFAULT ${formatDefault(oldDefault)};`,
|
|
11437
|
+
// Allowlisted: restores the recorded prior default value.
|
|
11438
|
+
destructive: false
|
|
11439
|
+
};
|
|
11283
11440
|
}
|
|
11284
11441
|
case "add_primary_key": {
|
|
11285
|
-
return
|
|
11442
|
+
return {
|
|
11443
|
+
sql: `ALTER TABLE ${qualifyTable(change.table, schemaName)} DROP CONSTRAINT IF EXISTS ${quoteIdent2(pkName(change.table), "alias")} CASCADE;`,
|
|
11444
|
+
destructive: true
|
|
11445
|
+
};
|
|
11446
|
+
}
|
|
11447
|
+
case "drop_primary_key": {
|
|
11448
|
+
const columns = change.meta?.columns;
|
|
11449
|
+
if (Array.isArray(columns) && columns.length > 0) {
|
|
11450
|
+
const pkCols = columns.map((n) => quoteIdent2(n, "alias")).join(", ");
|
|
11451
|
+
return {
|
|
11452
|
+
sql: `ALTER TABLE ${qualifyTable(change.table, schemaName)} ADD CONSTRAINT ${quoteIdent2(pkName(change.table), "alias")} PRIMARY KEY (${pkCols});`,
|
|
11453
|
+
// Allowlisted: re-adds the dropped primary-key constraint from metadata.
|
|
11454
|
+
destructive: false
|
|
11455
|
+
};
|
|
11456
|
+
}
|
|
11457
|
+
return {
|
|
11458
|
+
sql: `-- WARNING: Cannot reverse drop_primary_key "${change.table}" -- columns unknown`,
|
|
11459
|
+
destructive: true
|
|
11460
|
+
};
|
|
11286
11461
|
}
|
|
11287
|
-
case "drop_primary_key":
|
|
11288
|
-
return `-- WARNING: Cannot reverse drop_primary_key "${change.table}" -- columns unknown`;
|
|
11289
11462
|
case "add_foreign_key": {
|
|
11290
11463
|
const fk = change.meta?.fk;
|
|
11291
|
-
if (!fk) return void 0;
|
|
11464
|
+
if (!fk) return { sql: void 0, destructive: true };
|
|
11292
11465
|
const constraintName = quoteIdent2(
|
|
11293
11466
|
fkName(change.table, fk.columns),
|
|
11294
11467
|
"alias"
|
|
11295
11468
|
);
|
|
11296
|
-
return
|
|
11469
|
+
return {
|
|
11470
|
+
sql: `ALTER TABLE ${qualifyTable(change.table, schemaName)} DROP CONSTRAINT IF EXISTS ${constraintName} CASCADE;`,
|
|
11471
|
+
destructive: true
|
|
11472
|
+
};
|
|
11473
|
+
}
|
|
11474
|
+
case "drop_foreign_key": {
|
|
11475
|
+
const fk = change.meta?.fk;
|
|
11476
|
+
if (!fk) {
|
|
11477
|
+
return {
|
|
11478
|
+
sql: `-- WARNING: Cannot reverse drop_foreign_key "${change.table}" -- FK definition was lost`,
|
|
11479
|
+
destructive: true
|
|
11480
|
+
};
|
|
11481
|
+
}
|
|
11482
|
+
return {
|
|
11483
|
+
sql: generateAddFKSQL(change.table, fk, schemaName),
|
|
11484
|
+
// Allowlisted: re-adds the dropped foreign-key constraint from metadata.
|
|
11485
|
+
destructive: false
|
|
11486
|
+
};
|
|
11297
11487
|
}
|
|
11298
|
-
case "drop_foreign_key":
|
|
11299
|
-
return `-- WARNING: Cannot reverse drop_foreign_key "${change.table}" -- FK definition was lost`;
|
|
11300
11488
|
case "alter_foreign_key": {
|
|
11301
11489
|
const oldFk = change.meta?.oldFk;
|
|
11302
|
-
if (!oldFk) {
|
|
11303
|
-
return `-- WARNING: Cannot reverse alter_foreign_key "${change.table}" -- missing migration metadata`;
|
|
11304
|
-
}
|
|
11305
11490
|
const fk = change.meta?.fk;
|
|
11491
|
+
if (!oldFk || !fk) {
|
|
11492
|
+
return {
|
|
11493
|
+
sql: `-- WARNING: Cannot reverse alter_foreign_key "${change.table}" -- missing migration metadata`,
|
|
11494
|
+
destructive: true
|
|
11495
|
+
};
|
|
11496
|
+
}
|
|
11306
11497
|
const constraintName = quoteIdent2(
|
|
11307
11498
|
fkName(change.table, fk.columns),
|
|
11308
11499
|
"alias"
|
|
11309
11500
|
);
|
|
11310
11501
|
const drop = `ALTER TABLE ${qualifyTable(change.table, schemaName)} DROP CONSTRAINT IF EXISTS ${constraintName};`;
|
|
11311
11502
|
const add = generateAddFKSQL(change.table, oldFk, schemaName);
|
|
11312
|
-
return `${drop}
|
|
11313
|
-
${add}
|
|
11503
|
+
return { sql: `${drop}
|
|
11504
|
+
${add}`, destructive: false };
|
|
11314
11505
|
}
|
|
11315
11506
|
case "create_index": {
|
|
11316
11507
|
const idx = change.meta?.index;
|
|
11317
|
-
if (!idx) return void 0;
|
|
11508
|
+
if (!idx) return { sql: void 0, destructive: true };
|
|
11318
11509
|
const indexName = quoteIdent2(
|
|
11319
11510
|
idxName(change.table, idx.columns, idx.name),
|
|
11320
11511
|
"alias"
|
|
11321
11512
|
);
|
|
11322
11513
|
const schemaPrefix = schemaName ? `${quoteIdent2(schemaName, "alias")}.` : "";
|
|
11323
|
-
return
|
|
11514
|
+
return {
|
|
11515
|
+
sql: `DROP INDEX IF EXISTS ${schemaPrefix}${indexName};`,
|
|
11516
|
+
destructive: true
|
|
11517
|
+
};
|
|
11518
|
+
}
|
|
11519
|
+
case "drop_index": {
|
|
11520
|
+
const idx = change.meta?.index;
|
|
11521
|
+
if (!idx) {
|
|
11522
|
+
return {
|
|
11523
|
+
sql: `-- WARNING: Cannot reverse drop_index "${change.table}" -- index definition was lost`,
|
|
11524
|
+
destructive: true
|
|
11525
|
+
};
|
|
11526
|
+
}
|
|
11527
|
+
return {
|
|
11528
|
+
sql: upCreateIndex(change, schemaName),
|
|
11529
|
+
// Allowlisted: re-creates the dropped index from metadata.
|
|
11530
|
+
destructive: false
|
|
11531
|
+
};
|
|
11324
11532
|
}
|
|
11325
|
-
case "drop_index":
|
|
11326
|
-
return `-- WARNING: Cannot reverse drop_index "${change.table}" -- index definition was lost`;
|
|
11327
11533
|
case "add_check_constraint": {
|
|
11328
11534
|
const check = change.meta?.check;
|
|
11329
|
-
if (!check) return void 0;
|
|
11330
|
-
return
|
|
11535
|
+
if (!check) return { sql: void 0, destructive: true };
|
|
11536
|
+
return {
|
|
11537
|
+
sql: `ALTER TABLE ${qualifyTable(change.table, schemaName)} DROP CONSTRAINT IF EXISTS ${quoteIdent2(check.name, "alias")};`,
|
|
11538
|
+
destructive: true
|
|
11539
|
+
};
|
|
11331
11540
|
}
|
|
11332
11541
|
case "drop_check_constraint": {
|
|
11333
11542
|
const check = change.meta?.check;
|
|
11334
|
-
if (!check) return void 0;
|
|
11543
|
+
if (!check) return { sql: void 0, destructive: true };
|
|
11335
11544
|
validateSqlExpression(
|
|
11336
11545
|
check.expression,
|
|
11337
11546
|
"migration check constraint (down)"
|
|
11338
11547
|
);
|
|
11339
|
-
return
|
|
11548
|
+
return {
|
|
11549
|
+
sql: "DO $$ BEGIN ALTER TABLE " + qualifyTable(change.table, schemaName) + " ADD CONSTRAINT " + quoteIdent2(check.name, "alias") + " " + check.expression + "; EXCEPTION WHEN duplicate_object THEN NULL; END $$;",
|
|
11550
|
+
// Allowlisted: re-adds the dropped CHECK constraint from metadata.
|
|
11551
|
+
destructive: false
|
|
11552
|
+
};
|
|
11340
11553
|
}
|
|
11341
11554
|
case "create_enum": {
|
|
11342
11555
|
const enumDef = change.meta?.enum;
|
|
11343
|
-
if (!enumDef) return void 0;
|
|
11556
|
+
if (!enumDef) return { sql: void 0, destructive: true };
|
|
11344
11557
|
const enumName = schemaName ? `${quoteIdent2(schemaName, "alias")}.${quoteIdent2(enumDef.name, "alias")}` : quoteIdent2(enumDef.name, "alias");
|
|
11345
|
-
return
|
|
11558
|
+
return {
|
|
11559
|
+
sql: `DROP TYPE IF EXISTS ${enumName} CASCADE;`,
|
|
11560
|
+
destructive: true
|
|
11561
|
+
};
|
|
11346
11562
|
}
|
|
11347
11563
|
case "drop_enum": {
|
|
11348
11564
|
const enumDef = change.meta?.enum;
|
|
11349
|
-
if (!enumDef) return void 0;
|
|
11565
|
+
if (!enumDef) return { sql: void 0, destructive: true };
|
|
11350
11566
|
const enumName = schemaName ? `${quoteIdent2(schemaName, "alias")}.${quoteIdent2(enumDef.name, "alias")}` : quoteIdent2(enumDef.name, "alias");
|
|
11351
11567
|
const values = enumDef.values.map((v) => `'${v.replace(/'/g, "''")}'`).join(", ");
|
|
11352
|
-
return
|
|
11568
|
+
return {
|
|
11569
|
+
sql: `CREATE TYPE ${enumName} AS ENUM (${values});`,
|
|
11570
|
+
// Allowlisted: re-creates the dropped enum type from metadata.
|
|
11571
|
+
destructive: false
|
|
11572
|
+
};
|
|
11353
11573
|
}
|
|
11354
11574
|
case "alter_enum_add_value":
|
|
11355
|
-
return
|
|
11575
|
+
return {
|
|
11576
|
+
sql: `-- ALTER TYPE ADD VALUE cannot be reversed in PostgreSQL`,
|
|
11577
|
+
destructive: true
|
|
11578
|
+
};
|
|
11356
11579
|
case "alter_column_collation": {
|
|
11357
|
-
return
|
|
11580
|
+
return {
|
|
11581
|
+
sql: `-- WARNING: Cannot reverse alter_column_collation "${change.table}"."${change.column}" -- previous collation unknown`,
|
|
11582
|
+
destructive: true
|
|
11583
|
+
};
|
|
11358
11584
|
}
|
|
11359
11585
|
case "alter_column_identity": {
|
|
11360
11586
|
const col = change.meta?.column;
|
|
11361
11587
|
const prevIdentity = change.meta?.previousIdentity;
|
|
11362
|
-
if (!col) return void 0;
|
|
11588
|
+
if (!col) return { sql: void 0, destructive: true };
|
|
11363
11589
|
const table = qualifyTable(change.table, schemaName);
|
|
11364
11590
|
const column = quoteIdent2(change.column, "alias");
|
|
11365
11591
|
if (prevIdentity && !col.identity) {
|
|
11366
11592
|
const gen2 = prevIdentity === "always" ? "ALWAYS" : "BY DEFAULT";
|
|
11367
|
-
return
|
|
11593
|
+
return {
|
|
11594
|
+
sql: `ALTER TABLE ${table} ALTER COLUMN ${column} ADD GENERATED ${gen2} AS IDENTITY;`,
|
|
11595
|
+
// Allowlisted: re-adds the previously recorded identity metadata.
|
|
11596
|
+
destructive: false
|
|
11597
|
+
};
|
|
11368
11598
|
}
|
|
11369
11599
|
if (!prevIdentity && col.identity) {
|
|
11370
|
-
return
|
|
11600
|
+
return {
|
|
11601
|
+
sql: `ALTER TABLE ${table} ALTER COLUMN ${column} DROP IDENTITY IF EXISTS;`,
|
|
11602
|
+
destructive: true
|
|
11603
|
+
};
|
|
11604
|
+
}
|
|
11605
|
+
if (!prevIdentity && !col.identity) {
|
|
11606
|
+
return {
|
|
11607
|
+
sql: `-- WARNING: Cannot reverse alter_column_identity "${change.table}"."${change.column}" -- missing previous identity metadata`,
|
|
11608
|
+
destructive: true
|
|
11609
|
+
};
|
|
11371
11610
|
}
|
|
11372
11611
|
const gen = prevIdentity === "always" ? "ALWAYS" : "BY DEFAULT";
|
|
11373
|
-
return
|
|
11612
|
+
return {
|
|
11613
|
+
sql: `ALTER TABLE ${table} ALTER COLUMN ${column} SET GENERATED ${gen};`,
|
|
11614
|
+
// Allowlisted: restores the recorded prior identity generation mode.
|
|
11615
|
+
destructive: false
|
|
11616
|
+
};
|
|
11374
11617
|
}
|
|
11375
11618
|
case "add_comment": {
|
|
11376
11619
|
const target = change.meta?.target;
|
|
11377
11620
|
if (target === "table") {
|
|
11378
|
-
return
|
|
11621
|
+
return {
|
|
11622
|
+
sql: `COMMENT ON TABLE ${qualifyTable(change.table, schemaName)} IS NULL;`,
|
|
11623
|
+
destructive: true
|
|
11624
|
+
};
|
|
11379
11625
|
}
|
|
11380
|
-
return
|
|
11626
|
+
return {
|
|
11627
|
+
sql: `COMMENT ON COLUMN ${qualifyTable(change.table, schemaName)}.${quoteIdent2(change.column, "alias")} IS NULL;`,
|
|
11628
|
+
destructive: true
|
|
11629
|
+
};
|
|
11381
11630
|
}
|
|
11382
11631
|
case "drop_comment": {
|
|
11383
|
-
|
|
11632
|
+
const target = change.meta?.target;
|
|
11633
|
+
const comment = change.meta?.comment;
|
|
11634
|
+
if (typeof comment === "string") {
|
|
11635
|
+
const escaped = comment.replace(/'/g, "''");
|
|
11636
|
+
if (target === "table") {
|
|
11637
|
+
return {
|
|
11638
|
+
sql: `COMMENT ON TABLE ${qualifyTable(change.table, schemaName)} IS '${escaped}';`,
|
|
11639
|
+
// Allowlisted: re-adds the dropped table comment from metadata.
|
|
11640
|
+
destructive: false
|
|
11641
|
+
};
|
|
11642
|
+
}
|
|
11643
|
+
if (target === "column") {
|
|
11644
|
+
return {
|
|
11645
|
+
sql: `COMMENT ON COLUMN ${qualifyTable(change.table, schemaName)}.${quoteIdent2(change.column, "alias")} IS '${escaped}';`,
|
|
11646
|
+
// Allowlisted: re-adds the dropped column comment from metadata.
|
|
11647
|
+
destructive: false
|
|
11648
|
+
};
|
|
11649
|
+
}
|
|
11650
|
+
}
|
|
11651
|
+
return {
|
|
11652
|
+
sql: `-- WARNING: Cannot reverse drop_comment "${change.table}"${change.column ? `."${change.column}"` : ""} -- comment text was lost`,
|
|
11653
|
+
destructive: true
|
|
11654
|
+
};
|
|
11384
11655
|
}
|
|
11385
11656
|
case "create_extension": {
|
|
11386
11657
|
const ext = change.meta?.extension;
|
|
11387
|
-
if (ext == null) return void 0;
|
|
11388
|
-
return
|
|
11658
|
+
if (ext == null) return { sql: void 0, destructive: true };
|
|
11659
|
+
return {
|
|
11660
|
+
sql: `DROP EXTENSION IF EXISTS ${quoteExtensionName(ext)} CASCADE;`,
|
|
11661
|
+
destructive: true
|
|
11662
|
+
};
|
|
11389
11663
|
}
|
|
11390
11664
|
case "drop_extension": {
|
|
11391
11665
|
const ext = change.meta?.extension;
|
|
11392
|
-
if (ext == null) return void 0;
|
|
11393
|
-
return
|
|
11666
|
+
if (ext == null) return { sql: void 0, destructive: true };
|
|
11667
|
+
return {
|
|
11668
|
+
sql: `CREATE EXTENSION IF NOT EXISTS ${quoteExtensionName(ext)};`,
|
|
11669
|
+
// Allowlisted: re-creates the dropped extension from metadata.
|
|
11670
|
+
destructive: false
|
|
11671
|
+
};
|
|
11394
11672
|
}
|
|
11395
11673
|
case "create_sequence": {
|
|
11396
11674
|
const seq = change.meta?.sequence;
|
|
11397
|
-
if (!seq) return void 0;
|
|
11675
|
+
if (!seq) return { sql: void 0, destructive: true };
|
|
11398
11676
|
const seqName = schemaName ? `${quoteIdent2(schemaName, "alias")}.${quoteIdent2(seq.name, "alias")}` : quoteIdent2(seq.name, "alias");
|
|
11399
|
-
return
|
|
11677
|
+
return {
|
|
11678
|
+
sql: `DROP SEQUENCE IF EXISTS ${seqName} CASCADE;`,
|
|
11679
|
+
destructive: true
|
|
11680
|
+
};
|
|
11400
11681
|
}
|
|
11401
11682
|
case "alter_sequence": {
|
|
11402
11683
|
const prevSeq = change.meta?.previousSequence;
|
|
11403
11684
|
if (!prevSeq) {
|
|
11404
|
-
return
|
|
11685
|
+
return {
|
|
11686
|
+
sql: `-- WARNING: Cannot reverse alter_sequence "${change.table}" -- missing migration metadata`,
|
|
11687
|
+
destructive: true
|
|
11688
|
+
};
|
|
11405
11689
|
}
|
|
11406
11690
|
const seqName = schemaName ? `${quoteIdent2(schemaName, "alias")}.${quoteIdent2(prevSeq.name, "alias")}` : quoteIdent2(prevSeq.name, "alias");
|
|
11407
|
-
return
|
|
11691
|
+
return {
|
|
11692
|
+
sql: buildSequenceClause("ALTER SEQUENCE", seqName, prevSeq, true),
|
|
11693
|
+
// Allowlisted: restores the recorded prior sequence metadata.
|
|
11694
|
+
destructive: false
|
|
11695
|
+
};
|
|
11408
11696
|
}
|
|
11409
11697
|
case "drop_sequence": {
|
|
11410
11698
|
const seq = change.meta?.sequence;
|
|
11411
|
-
if (!seq) return void 0;
|
|
11699
|
+
if (!seq) return { sql: void 0, destructive: true };
|
|
11412
11700
|
const seqName = schemaName ? `${quoteIdent2(schemaName, "alias")}.${quoteIdent2(seq.name, "alias")}` : quoteIdent2(seq.name, "alias");
|
|
11413
|
-
return
|
|
11701
|
+
return {
|
|
11702
|
+
sql: buildSequenceClause("CREATE SEQUENCE", seqName, seq),
|
|
11703
|
+
// Allowlisted: re-creates the dropped sequence from metadata.
|
|
11704
|
+
destructive: false
|
|
11705
|
+
};
|
|
11414
11706
|
}
|
|
11415
11707
|
case "validate_constraint":
|
|
11416
|
-
return
|
|
11708
|
+
return {
|
|
11709
|
+
sql: `-- VALIDATE CONSTRAINT cannot be reversed in PostgreSQL (table: "${change.table}")`,
|
|
11710
|
+
destructive: true
|
|
11711
|
+
};
|
|
11417
11712
|
case "enable_rls":
|
|
11418
|
-
return
|
|
11713
|
+
return {
|
|
11714
|
+
sql: `ALTER TABLE ${qualifyTable(change.table, schemaName)} DISABLE ROW LEVEL SECURITY;`,
|
|
11715
|
+
destructive: true
|
|
11716
|
+
};
|
|
11419
11717
|
case "disable_rls":
|
|
11420
|
-
return
|
|
11718
|
+
return {
|
|
11719
|
+
sql: `ALTER TABLE ${qualifyTable(change.table, schemaName)} ENABLE ROW LEVEL SECURITY;`,
|
|
11720
|
+
// Allowlisted: re-enables the previously present RLS security control.
|
|
11721
|
+
destructive: false
|
|
11722
|
+
};
|
|
11421
11723
|
case "create_policy": {
|
|
11422
11724
|
const policy = change.meta?.policy;
|
|
11423
|
-
if (!policy) return void 0;
|
|
11424
|
-
return
|
|
11725
|
+
if (!policy) return { sql: void 0, destructive: true };
|
|
11726
|
+
return {
|
|
11727
|
+
sql: `DROP POLICY IF EXISTS ${quoteIdent2(policy.name, "alias")} ON ${qualifyTable(change.table, schemaName)};`,
|
|
11728
|
+
destructive: true
|
|
11729
|
+
};
|
|
11425
11730
|
}
|
|
11426
11731
|
case "drop_policy": {
|
|
11427
11732
|
const policy = change.meta?.policy;
|
|
11428
|
-
if (!policy) return void 0;
|
|
11429
|
-
return
|
|
11733
|
+
if (!policy) return { sql: void 0, destructive: true };
|
|
11734
|
+
return {
|
|
11735
|
+
sql: buildPolicySQL(change.table, policy, schemaName),
|
|
11736
|
+
// Allowlisted: re-creates the dropped RLS policy from metadata.
|
|
11737
|
+
destructive: false
|
|
11738
|
+
};
|
|
11430
11739
|
}
|
|
11740
|
+
default:
|
|
11741
|
+
return failSafeUnknownDownChange(change.kind);
|
|
11431
11742
|
}
|
|
11432
11743
|
}
|
|
11433
11744
|
function generateDownSQL(diff, options) {
|
|
11745
|
+
return generateDownMigrationSQL(diff, options).statements;
|
|
11746
|
+
}
|
|
11747
|
+
function generateDownMigrationSQL(diff, options) {
|
|
11434
11748
|
const schemaName = options?.schemaName;
|
|
11435
11749
|
const includeDestructive = options?.includeDestructive ?? true;
|
|
11436
11750
|
const changes = includeDestructive ? diff.changes : diff.changes.filter((c) => !c.destructive);
|
|
@@ -11479,13 +11793,15 @@ function generateDownSQL(diff, options) {
|
|
|
11479
11793
|
phases[phase].push(change);
|
|
11480
11794
|
}
|
|
11481
11795
|
const statements = [];
|
|
11796
|
+
let destructive = false;
|
|
11482
11797
|
for (let i = phases.length - 1; i >= 0; i--) {
|
|
11483
11798
|
for (const change of phases[i]) {
|
|
11484
|
-
const
|
|
11485
|
-
|
|
11799
|
+
const down = changeToDownSQL(change, schemaName);
|
|
11800
|
+
destructive = down.destructive || destructive;
|
|
11801
|
+
if (down.sql) statements.push(down.sql);
|
|
11486
11802
|
}
|
|
11487
11803
|
}
|
|
11488
|
-
return statements;
|
|
11804
|
+
return { statements, destructive };
|
|
11489
11805
|
}
|
|
11490
11806
|
function generateCreateTableSQL(table, schemaName) {
|
|
11491
11807
|
const qualTable = qualifyTable(table.name, schemaName);
|
|
@@ -11778,29 +12094,36 @@ function generateCreatePolicy(tableName, policy, schemaName, naming) {
|
|
|
11778
12094
|
// src/ddl/migration-file.ts
|
|
11779
12095
|
function generateMigrationFile(diff, options) {
|
|
11780
12096
|
const upStatements = generateMigrationSQL(diff, options);
|
|
11781
|
-
const
|
|
12097
|
+
const downMigration = generateDownMigrationSQL(diff, options);
|
|
12098
|
+
const downStatements = downMigration.statements;
|
|
12099
|
+
const destructiveHeader = `-- dbsp:destructive: ${downMigration.destructive ? "true" : "false"}`;
|
|
11782
12100
|
const header = options?.name ? `-- Migration: ${options.name}
|
|
11783
12101
|
-- Generated by: dbsp migrate dev
|
|
11784
12102
|
-- Date: ${(/* @__PURE__ */ new Date()).toISOString()}
|
|
12103
|
+
${destructiveHeader}
|
|
11785
12104
|
|
|
11786
|
-
` :
|
|
12105
|
+
` : `${destructiveHeader}
|
|
12106
|
+
|
|
12107
|
+
`;
|
|
11787
12108
|
const upSection = upStatements.length > 0 ? `${upStatements.join(";\n\n")};
|
|
11788
12109
|
` : "";
|
|
11789
12110
|
const downSection = downStatements.length > 0 ? `${downStatements.join(";\n\n")};
|
|
11790
12111
|
` : "";
|
|
11791
|
-
|
|
11792
|
-
-- DOWN
|
|
12112
|
+
const separatorPrefix = upSection.length > 0 ? "\n" : "";
|
|
12113
|
+
return `${header}${upSection}${separatorPrefix}-- DOWN
|
|
11793
12114
|
|
|
11794
12115
|
${downSection}`;
|
|
11795
12116
|
}
|
|
11796
12117
|
function parseMigrationFile(content) {
|
|
12118
|
+
const destructive = parseDestructiveHeader(content);
|
|
11797
12119
|
const separatorRegex = /^\s*-- DOWN\s*$/m;
|
|
11798
12120
|
const match = separatorRegex.exec(content);
|
|
11799
12121
|
if (!match) {
|
|
11800
12122
|
return {
|
|
11801
12123
|
upStatements: splitStatements(content),
|
|
11802
12124
|
downStatements: [],
|
|
11803
|
-
hasDown: false
|
|
12125
|
+
hasDown: false,
|
|
12126
|
+
destructive
|
|
11804
12127
|
};
|
|
11805
12128
|
}
|
|
11806
12129
|
const upContent = content.slice(0, match.index);
|
|
@@ -11808,9 +12131,36 @@ function parseMigrationFile(content) {
|
|
|
11808
12131
|
return {
|
|
11809
12132
|
upStatements: splitStatements(upContent),
|
|
11810
12133
|
downStatements: splitStatements(downContent),
|
|
11811
|
-
hasDown: true
|
|
12134
|
+
hasDown: true,
|
|
12135
|
+
destructive
|
|
11812
12136
|
};
|
|
11813
12137
|
}
|
|
12138
|
+
function parseDestructiveHeader(content) {
|
|
12139
|
+
let destructive;
|
|
12140
|
+
let found = false;
|
|
12141
|
+
for (const line of content.split(/\r?\n/)) {
|
|
12142
|
+
const trimmed = line.trim();
|
|
12143
|
+
if (trimmed.length === 0) {
|
|
12144
|
+
continue;
|
|
12145
|
+
}
|
|
12146
|
+
if (/^--\s*DOWN\s*$/i.test(trimmed)) {
|
|
12147
|
+
break;
|
|
12148
|
+
}
|
|
12149
|
+
if (!trimmed.startsWith("--")) {
|
|
12150
|
+
break;
|
|
12151
|
+
}
|
|
12152
|
+
const match = /^--\s*dbsp:destructive:\s*(true|false)\s*$/i.exec(trimmed);
|
|
12153
|
+
if (!match) {
|
|
12154
|
+
continue;
|
|
12155
|
+
}
|
|
12156
|
+
if (found) {
|
|
12157
|
+
return void 0;
|
|
12158
|
+
}
|
|
12159
|
+
found = true;
|
|
12160
|
+
destructive = match[1]?.toLowerCase() === "true";
|
|
12161
|
+
}
|
|
12162
|
+
return found ? destructive : void 0;
|
|
12163
|
+
}
|
|
11814
12164
|
function isDestructiveDown(downStatements) {
|
|
11815
12165
|
const destructivePatterns = [
|
|
11816
12166
|
/DROP\s+TABLE/i,
|
|
@@ -12933,6 +13283,7 @@ function vectorDims(column) {
|
|
|
12933
13283
|
// src/introspection.ts
|
|
12934
13284
|
init_assert_field();
|
|
12935
13285
|
import { ModelIRImpl } from "@dbsp/core";
|
|
13286
|
+
import { buildRelationKeyFields } from "@dbsp/types";
|
|
12936
13287
|
function parseExpressionsList(raw) {
|
|
12937
13288
|
const results = [];
|
|
12938
13289
|
let depth = 0;
|
|
@@ -13488,9 +13839,10 @@ function inferRelations(fksByConstraint, filteredTables) {
|
|
|
13488
13839
|
for (const [, fk] of fksByConstraint) {
|
|
13489
13840
|
if (!filteredSet.has(fk.source) || !filteredSet.has(fk.target)) continue;
|
|
13490
13841
|
const belongsToName = deriveRelationName(fk.cols[0], fk.target);
|
|
13491
|
-
const
|
|
13492
|
-
|
|
13493
|
-
|
|
13842
|
+
const relationFk = {
|
|
13843
|
+
columns: fk.cols,
|
|
13844
|
+
references: { table: fk.target, columns: fk.refs }
|
|
13845
|
+
};
|
|
13494
13846
|
const belongsToKey = `${fk.source}.${belongsToName}`;
|
|
13495
13847
|
if (!relations.has(belongsToKey)) {
|
|
13496
13848
|
relations.set(belongsToKey, {
|
|
@@ -13498,8 +13850,7 @@ function inferRelations(fksByConstraint, filteredTables) {
|
|
|
13498
13850
|
type: "belongsTo",
|
|
13499
13851
|
source: fk.source,
|
|
13500
13852
|
target: fk.target,
|
|
13501
|
-
|
|
13502
|
-
...keyOverride !== void 0 && { targetKey: keyOverride },
|
|
13853
|
+
...buildRelationKeyFields(relationFk, "belongsTo"),
|
|
13503
13854
|
cardinality: "one",
|
|
13504
13855
|
optionality: "optional",
|
|
13505
13856
|
includeStrategy: "auto",
|
|
@@ -13515,8 +13866,7 @@ function inferRelations(fksByConstraint, filteredTables) {
|
|
|
13515
13866
|
type: "hasMany",
|
|
13516
13867
|
source: fk.target,
|
|
13517
13868
|
target: fk.source,
|
|
13518
|
-
|
|
13519
|
-
...keyOverride !== void 0 && { sourceKey: keyOverride },
|
|
13869
|
+
...buildRelationKeyFields(relationFk, "inverse"),
|
|
13520
13870
|
cardinality: "many",
|
|
13521
13871
|
optionality: "optional",
|
|
13522
13872
|
includeStrategy: "auto",
|
|
@@ -14419,7 +14769,7 @@ import { getNqlBindingRefName as getNqlBindingRefName2, isNqlBindingRef as isNql
|
|
|
14419
14769
|
|
|
14420
14770
|
// src/adapter-compiler-includes.ts
|
|
14421
14771
|
init_ast_helpers();
|
|
14422
|
-
import { toColumnList as
|
|
14772
|
+
import { toColumnList as toColumnList8 } from "@dbsp/types";
|
|
14423
14773
|
init_handlers();
|
|
14424
14774
|
function compileSubqueryInclude(info, parentIds, _options, deps) {
|
|
14425
14775
|
const schemaName = deps.schemaName;
|
|
@@ -14431,7 +14781,7 @@ function compileSubqueryInclude(info, parentIds, _options, deps) {
|
|
|
14431
14781
|
parameters: []
|
|
14432
14782
|
};
|
|
14433
14783
|
}
|
|
14434
|
-
const fkColumns =
|
|
14784
|
+
const fkColumns = toColumnList8(info.foreignKey);
|
|
14435
14785
|
if (fkColumns.length === 0) {
|
|
14436
14786
|
throw new Error(
|
|
14437
14787
|
"Subquery include requires at least one foreignKey column."
|
|
@@ -14529,7 +14879,7 @@ function compileSubqueryIncludeManyToMany(info, parentIds, schemaName, state, de
|
|
|
14529
14879
|
const throughTable = info.through;
|
|
14530
14880
|
const throughSourceKey = info.throughSourceKey;
|
|
14531
14881
|
const throughTargetKey = info.throughTargetKey;
|
|
14532
|
-
const targetPkColumns =
|
|
14882
|
+
const targetPkColumns = toColumnList8(info.sourceKey);
|
|
14533
14883
|
if (targetPkColumns.length !== 1) {
|
|
14534
14884
|
throw new Error(
|
|
14535
14885
|
`Many-to-many subquery include requires a single-column target key; got ${JSON.stringify(targetPkColumns)}.`
|
|
@@ -14624,7 +14974,7 @@ import {
|
|
|
14624
14974
|
POSTGRESQL_CAPABILITIES,
|
|
14625
14975
|
plan as planFn
|
|
14626
14976
|
} from "@dbsp/core";
|
|
14627
|
-
import { toColumnList as
|
|
14977
|
+
import { toColumnList as toColumnList11 } from "@dbsp/types";
|
|
14628
14978
|
|
|
14629
14979
|
// src/adapter-compiler-select.ts
|
|
14630
14980
|
init_assert_field();
|
|
@@ -14632,7 +14982,7 @@ init_ast_helpers();
|
|
|
14632
14982
|
init_binding_registry();
|
|
14633
14983
|
init_compile_where();
|
|
14634
14984
|
import { countDistinctRelationPathsByName } from "@dbsp/core";
|
|
14635
|
-
import { toColumnList as
|
|
14985
|
+
import { toColumnList as toColumnList10 } from "@dbsp/types";
|
|
14636
14986
|
init_compiler_utils();
|
|
14637
14987
|
init_types();
|
|
14638
14988
|
init_intent_to_decisions();
|
|
@@ -14642,7 +14992,7 @@ init_param_ref();
|
|
|
14642
14992
|
init_assert_field();
|
|
14643
14993
|
init_intent_to_decisions();
|
|
14644
14994
|
import { deriveRelationPathFromIntentPath } from "@dbsp/core";
|
|
14645
|
-
import { toColumnList as
|
|
14995
|
+
import { toColumnList as toColumnList9 } from "@dbsp/types";
|
|
14646
14996
|
function findExistsIntents(where) {
|
|
14647
14997
|
if (!where || typeof where !== "object") return [];
|
|
14648
14998
|
const w = where;
|
|
@@ -14663,7 +15013,7 @@ function findExistsIntents(where) {
|
|
|
14663
15013
|
function resolveRelation(model, sourceTable, relationName) {
|
|
14664
15014
|
const rel = model.getRelation(`${sourceTable}.${relationName}`);
|
|
14665
15015
|
if (!rel) return void 0;
|
|
14666
|
-
const foreignKeyColumns =
|
|
15016
|
+
const foreignKeyColumns = toColumnList9(rel.foreignKey);
|
|
14667
15017
|
const foreignKey = foreignKeyColumns.length > 0 ? foreignKeyColumns : void 0;
|
|
14668
15018
|
const relationType = rel.type;
|
|
14669
15019
|
return { target: rel.target, foreignKey, relationType };
|
|
@@ -14887,7 +15237,7 @@ function buildMultiHopExistsChain(hops, rootTable, outerOperator, innerCondition
|
|
|
14887
15237
|
const hopRelations = [];
|
|
14888
15238
|
for (const hop of hops) {
|
|
14889
15239
|
const rel = model.getRelation(`${currentSource}.${hop}`);
|
|
14890
|
-
const foreignKeyColumns = rel ?
|
|
15240
|
+
const foreignKeyColumns = rel ? toColumnList9(rel.foreignKey) : [];
|
|
14891
15241
|
const foreignKey = foreignKeyColumns.length > 0 ? foreignKeyColumns : void 0;
|
|
14892
15242
|
const relationType = rel?.type === "belongsTo" ? "belongsTo" : rel?.type === "hasMany" || rel?.type === "hasOne" ? rel.type : void 0;
|
|
14893
15243
|
const parentKey = relationType === "belongsTo" ? rel?.targetKey : rel?.sourceKey;
|
|
@@ -14998,7 +15348,7 @@ function enrichExistsStubsInConditions(conditions, sourceTable, model) {
|
|
|
14998
15348
|
`exists('${relation}'): no relation '${relation}' is declared on table '${sourceTable}'. Use rawExists(subquery(...)) for an EXISTS over an undeclared or uncorrelated subquery.`
|
|
14999
15349
|
);
|
|
15000
15350
|
}
|
|
15001
|
-
const foreignKeyColumns =
|
|
15351
|
+
const foreignKeyColumns = toColumnList9(rel.foreignKey);
|
|
15002
15352
|
const foreignKey = foreignKeyColumns.length > 0 ? foreignKeyColumns : void 0;
|
|
15003
15353
|
const relationType = rel.type === "belongsTo" ? "belongsTo" : rel.type === "hasMany" || rel.type === "hasOne" ? rel.type : void 0;
|
|
15004
15354
|
const parentKey = relationType === "belongsTo" ? rel.targetKey : rel.sourceKey;
|
|
@@ -15058,7 +15408,7 @@ function buildEnrichedExistsDecision(d, matchingIntent, rootTable, model) {
|
|
|
15058
15408
|
const relIR = model && context.relation ? model.getRelation(
|
|
15059
15409
|
`${sourceTableForRelation}.${context.relation}`
|
|
15060
15410
|
) : void 0;
|
|
15061
|
-
const foreignKeyColumns = relIR ?
|
|
15411
|
+
const foreignKeyColumns = relIR ? toColumnList9(relIR.foreignKey) : [];
|
|
15062
15412
|
const foreignKey = foreignKeyColumns.length > 0 ? foreignKeyColumns : void 0;
|
|
15063
15413
|
const relationType = relIR?.type === "belongsTo" ? "belongsTo" : relIR?.type === "hasMany" || relIR?.type === "hasOne" ? relIR.type : void 0;
|
|
15064
15414
|
const parentKey = relationType === "belongsTo" ? relIR?.targetKey : relIR?.sourceKey;
|
|
@@ -15395,10 +15745,7 @@ function toIncludeDecision(d, choice, plan, defaultPk = DEFAULT_PK_COLUMN, deriv
|
|
|
15395
15745
|
...relationType && { relationType },
|
|
15396
15746
|
foreignKey,
|
|
15397
15747
|
parentKey,
|
|
15398
|
-
...context.
|
|
15399
|
-
targetPrimaryKey: context.targetPrimaryKey,
|
|
15400
|
-
orderBy: context.targetPrimaryKey
|
|
15401
|
-
} : {},
|
|
15748
|
+
...context.targetOrderKey && context.targetOrderKey.length > 0 ? { orderBy: context.targetOrderKey } : {},
|
|
15402
15749
|
...context.orderByFallback ? { orderByFallback: true } : {},
|
|
15403
15750
|
...context.intentPath && { intentPath: context.intentPath },
|
|
15404
15751
|
...limit != null && { limit }
|
|
@@ -15470,7 +15817,7 @@ function synthesizeMissingJoinDecisions(plan, coveredRelations, model, defaultPk
|
|
|
15470
15817
|
(r) => r.name === alias || snakeToCamel(r.name) === alias
|
|
15471
15818
|
);
|
|
15472
15819
|
if (!rel) continue;
|
|
15473
|
-
const rawFkColumns =
|
|
15820
|
+
const rawFkColumns = toColumnList9(rel.foreignKey);
|
|
15474
15821
|
const rawFk = rawFkColumns.length > 0 ? rawFkColumns : [
|
|
15475
15822
|
deriveFk(
|
|
15476
15823
|
rel.type === "belongsTo" ? rel.target : sourceTable,
|
|
@@ -15498,7 +15845,7 @@ function synthesizeMissingJoinDecisions(plan, coveredRelations, model, defaultPk
|
|
|
15498
15845
|
relationType: rel.type
|
|
15499
15846
|
},
|
|
15500
15847
|
foreignKey: rawFk,
|
|
15501
|
-
parentKey: rel.type === "belongsTo" ?
|
|
15848
|
+
parentKey: rel.type === "belongsTo" ? toColumnList9(rel.targetKey).length > 0 ? toColumnList9(rel.targetKey) : [defaultPk] : toColumnList9(rel.sourceKey).length > 0 ? toColumnList9(rel.sourceKey) : [defaultPk],
|
|
15502
15849
|
columns,
|
|
15503
15850
|
joinType: inc.join,
|
|
15504
15851
|
...conditions && { conditions }
|
|
@@ -15594,9 +15941,6 @@ function assertSafeTypeName(typeName, colIndex) {
|
|
|
15594
15941
|
}
|
|
15595
15942
|
}
|
|
15596
15943
|
}
|
|
15597
|
-
function bridgeLegacyDecisions(decisions) {
|
|
15598
|
-
return decisions;
|
|
15599
|
-
}
|
|
15600
15944
|
function buildBatchValuesRangeFn(bv, startParamIndex, aliasOverride) {
|
|
15601
15945
|
const params = [];
|
|
15602
15946
|
let paramIdx = startParamIndex - 1;
|
|
@@ -15655,10 +15999,10 @@ function compileJoinIntents(joins, rootTable, schemaName, deps) {
|
|
|
15655
15999
|
);
|
|
15656
16000
|
}
|
|
15657
16001
|
const isBelongsTo = rel.type === "belongsTo";
|
|
15658
|
-
const rawFk =
|
|
16002
|
+
const rawFk = toColumnList10(rel.foreignKey);
|
|
15659
16003
|
const fkColumns = rawFk.length > 0 ? rawFk : [deriveFk(isBelongsTo ? rootTable : rel.target, defaultPk)];
|
|
15660
|
-
const sourceKey =
|
|
15661
|
-
const targetKey =
|
|
16004
|
+
const sourceKey = toColumnList10(rel.sourceKey);
|
|
16005
|
+
const targetKey = toColumnList10(rel.targetKey);
|
|
15662
16006
|
const sourceColumn = isBelongsTo ? fkColumns : sourceKey.length > 0 ? sourceKey : [defaultPk];
|
|
15663
16007
|
const targetColumn = isBelongsTo ? targetKey.length > 0 ? targetKey : [defaultPk] : fkColumns;
|
|
15664
16008
|
const alias = intent.alias ?? intent.relation;
|
|
@@ -16003,7 +16347,7 @@ function compileSelect(plan, options, deps) {
|
|
|
16003
16347
|
} else {
|
|
16004
16348
|
simplifiedPlan = {
|
|
16005
16349
|
rootTable: plan.rootTable,
|
|
16006
|
-
decisions:
|
|
16350
|
+
decisions: plan.decisions,
|
|
16007
16351
|
...schemaName ? { schema: schemaName } : {}
|
|
16008
16352
|
};
|
|
16009
16353
|
}
|
|
@@ -16023,8 +16367,8 @@ function compileWithIncludes(plan, options, deps) {
|
|
|
16023
16367
|
const relationName = ctx.includeAlias ?? ctx.relation;
|
|
16024
16368
|
if (!relationName) continue;
|
|
16025
16369
|
const rawFk = deriveForeignKey(ctx, deps.deriveFk, deps.defaultPk) ?? deps.defaultPk;
|
|
16026
|
-
const fk =
|
|
16027
|
-
const parentKey =
|
|
16370
|
+
const fk = toColumnList10(rawFk);
|
|
16371
|
+
const parentKey = toColumnList10(ctx.parentKey);
|
|
16028
16372
|
const isBelongsTo = ctx.relationType === "belongsTo";
|
|
16029
16373
|
const sourceKey = isBelongsTo ? fk : parentKey.length > 0 ? parentKey : [deps.defaultPk];
|
|
16030
16374
|
const targetFk = isBelongsTo ? parentKey.length > 0 ? parentKey : [deps.defaultPk] : fk;
|
|
@@ -16090,7 +16434,7 @@ function prependSourceCte(sql, parameters, sourceName, sourceCte, naming) {
|
|
|
16090
16434
|
};
|
|
16091
16435
|
}
|
|
16092
16436
|
function resolveMutationExistsForeignKey(foreignKey, relationName) {
|
|
16093
|
-
const columns =
|
|
16437
|
+
const columns = toColumnList11(foreignKey);
|
|
16094
16438
|
if (columns.length === 0) return void 0;
|
|
16095
16439
|
if (columns.some((column) => column.length === 0)) {
|
|
16096
16440
|
throw new Error(
|
|
@@ -16110,13 +16454,13 @@ function resolveExistsRelation(sourceTable, relation, model) {
|
|
|
16110
16454
|
return {
|
|
16111
16455
|
targetTable,
|
|
16112
16456
|
...fk2 !== void 0 && { sourceColumn: fk2 },
|
|
16113
|
-
targetColumn:
|
|
16457
|
+
targetColumn: toColumnList11(rel.targetKey).length > 0 ? toColumnList11(rel.targetKey) : ["id"]
|
|
16114
16458
|
};
|
|
16115
16459
|
}
|
|
16116
16460
|
const fk = resolveMutationExistsForeignKey(rel.foreignKey, relationName);
|
|
16117
16461
|
return {
|
|
16118
16462
|
targetTable,
|
|
16119
|
-
sourceColumn:
|
|
16463
|
+
sourceColumn: toColumnList11(rel.sourceKey).length > 0 ? toColumnList11(rel.sourceKey) : ["id"],
|
|
16120
16464
|
...fk !== void 0 && { targetColumn: fk }
|
|
16121
16465
|
};
|
|
16122
16466
|
}
|
|
@@ -18038,6 +18382,9 @@ function orderedNqlBindingNames(bundle) {
|
|
|
18038
18382
|
}
|
|
18039
18383
|
return names;
|
|
18040
18384
|
}
|
|
18385
|
+
function runtimeBindingSourceTable(bundle, name) {
|
|
18386
|
+
return bundle.mutationBindings?.get(name)?.table ?? bundle.bindings?.get(name)?.from;
|
|
18387
|
+
}
|
|
18041
18388
|
function mapRuntimeBindingColumnType(type) {
|
|
18042
18389
|
switch (type) {
|
|
18043
18390
|
case "string":
|
|
@@ -18090,13 +18437,13 @@ function resolveRuntimeBindingColumnType(bindingName, sourceTable, columnName) {
|
|
|
18090
18437
|
);
|
|
18091
18438
|
if (column === void 0) {
|
|
18092
18439
|
throw new Error(
|
|
18093
|
-
`NQL runtime binding '${bindingName}' cannot resolve projected column '${columnName}' on source
|
|
18440
|
+
`NQL runtime binding '${bindingName}' cannot resolve projected column '${columnName}' on source table '${sourceTable.name}'.`
|
|
18094
18441
|
);
|
|
18095
18442
|
}
|
|
18096
18443
|
const dbType = column.originalDbType?.trim() || mapRuntimeBindingColumnType(column.type);
|
|
18097
18444
|
if (dbType === void 0 || dbType.trim() === "") {
|
|
18098
18445
|
throw new Error(
|
|
18099
|
-
`NQL runtime binding '${bindingName}' cannot resolve a PostgreSQL type for projected column '${columnName}' on source
|
|
18446
|
+
`NQL runtime binding '${bindingName}' cannot resolve a PostgreSQL type for projected column '${columnName}' on source table '${sourceTable.name}'.`
|
|
18100
18447
|
);
|
|
18101
18448
|
}
|
|
18102
18449
|
const typeName = dbType.trim();
|
|
@@ -18119,7 +18466,7 @@ function resolveRuntimeBindingColumnTypes(name, binding, model, sourceTableName)
|
|
|
18119
18466
|
const sourceTable = findRuntimeBindingSourceTable(model, sourceTableName);
|
|
18120
18467
|
if (sourceTable === void 0) {
|
|
18121
18468
|
throw new Error(
|
|
18122
|
-
`NQL runtime binding '${name}' cannot resolve source
|
|
18469
|
+
`NQL runtime binding '${name}' cannot resolve source table '${sourceTableName}' in the model.`
|
|
18123
18470
|
);
|
|
18124
18471
|
}
|
|
18125
18472
|
return binding.columns.map(
|
|
@@ -18136,6 +18483,73 @@ function assertRuntimeBindingValuesParameterCount(name, binding, parameterOffset
|
|
|
18136
18483
|
`NQL runtime binding '${name}' would materialize ${valueParameterCount} VALUES parameters; limit is ${MAX_NQL_RUNTIME_BINDING_VALUES_PARAMETERS}. Current parameter offset is ${parameterOffset}, which would make ${totalParameterCount} total parameters before compiling the final statement.`
|
|
18137
18484
|
);
|
|
18138
18485
|
}
|
|
18486
|
+
function resolvePgTypeForColumnTypeInfo(bindingName, column, info) {
|
|
18487
|
+
if (info.kind === "aggregate" && info.fn !== "count") {
|
|
18488
|
+
throw new Error(
|
|
18489
|
+
`NQL runtime binding '${bindingName}' cannot resolve a PostgreSQL type for projected column '${column}': unsupported aggregate kind '${String(info.fn)}'.`
|
|
18490
|
+
);
|
|
18491
|
+
}
|
|
18492
|
+
const rawType = info.kind === "aggregate" ? "bigint" : info.originalDbType?.trim() || mapRuntimeBindingColumnType(info.type);
|
|
18493
|
+
if (rawType === void 0 || rawType.trim() === "") {
|
|
18494
|
+
throw new Error(
|
|
18495
|
+
`NQL runtime binding '${bindingName}' cannot resolve a PostgreSQL type for projected column '${column}'.`
|
|
18496
|
+
);
|
|
18497
|
+
}
|
|
18498
|
+
const typeName = rawType.trim();
|
|
18499
|
+
try {
|
|
18500
|
+
validateTypeName4(typeName);
|
|
18501
|
+
} catch (error) {
|
|
18502
|
+
const reason = error instanceof Error ? error.message : String(error);
|
|
18503
|
+
throw new Error(
|
|
18504
|
+
`NQL runtime binding '${bindingName}' cannot use PostgreSQL cast type for projected column '${column}': ${reason}`
|
|
18505
|
+
);
|
|
18506
|
+
}
|
|
18507
|
+
return typeName;
|
|
18508
|
+
}
|
|
18509
|
+
function resolveRuntimeBindingCteColumnTypes(name, binding) {
|
|
18510
|
+
const columnTypes = binding.columnTypes;
|
|
18511
|
+
if (columnTypes === void 0) {
|
|
18512
|
+
throw new Error(
|
|
18513
|
+
`NQL runtime binding '${name}' cannot resolve typed columns without a columnTypes map.`
|
|
18514
|
+
);
|
|
18515
|
+
}
|
|
18516
|
+
return binding.columns.map((column) => {
|
|
18517
|
+
const info = columnTypes[column];
|
|
18518
|
+
if (info === void 0) {
|
|
18519
|
+
throw new Error(
|
|
18520
|
+
`NQL runtime binding '${name}' is missing type info for projected column '${column}'.`
|
|
18521
|
+
);
|
|
18522
|
+
}
|
|
18523
|
+
return resolvePgTypeForColumnTypeInfo(name, column, info);
|
|
18524
|
+
});
|
|
18525
|
+
}
|
|
18526
|
+
function compileTypedNqlRuntimeBindingCte(name, binding, naming, parameterOffset, cteName, columnSql) {
|
|
18527
|
+
const pgTypes = resolveRuntimeBindingCteColumnTypes(name, binding);
|
|
18528
|
+
const anchorColumns = binding.columns.map(
|
|
18529
|
+
(column, columnIndex) => `CAST(NULL AS ${pgTypes[columnIndex]}) AS ${quoteIdent2(naming.toDatabase(column), "column")}`
|
|
18530
|
+
).join(", ");
|
|
18531
|
+
const sourceAnchorSql = `SELECT ${anchorColumns} WHERE false`;
|
|
18532
|
+
if (binding.rows.length === 0) {
|
|
18533
|
+
return {
|
|
18534
|
+
cte: `${cteName} (${columnSql}) as (${sourceAnchorSql})`,
|
|
18535
|
+
parameters: []
|
|
18536
|
+
};
|
|
18537
|
+
}
|
|
18538
|
+
assertRuntimeBindingValuesParameterCount(name, binding, parameterOffset);
|
|
18539
|
+
const parameters = [];
|
|
18540
|
+
let nextParam = parameterOffset + 1;
|
|
18541
|
+
const valuesSql = binding.rows.map((row) => {
|
|
18542
|
+
const placeholders = binding.columns.map((column, columnIndex) => {
|
|
18543
|
+
parameters.push(row[column]);
|
|
18544
|
+
return `$${nextParam++}::${pgTypes[columnIndex]}`;
|
|
18545
|
+
});
|
|
18546
|
+
return `(${placeholders.join(", ")})`;
|
|
18547
|
+
}).join(", ");
|
|
18548
|
+
return {
|
|
18549
|
+
cte: `${cteName} (${columnSql}) as (${sourceAnchorSql} UNION ALL VALUES ${valuesSql})`,
|
|
18550
|
+
parameters
|
|
18551
|
+
};
|
|
18552
|
+
}
|
|
18139
18553
|
function compileNqlRuntimeBindingCte(name, binding, naming, parameterOffset, sourceTable, schemaName, model) {
|
|
18140
18554
|
if (binding.columns.length === 0) {
|
|
18141
18555
|
throw new Error(
|
|
@@ -18144,9 +18558,19 @@ function compileNqlRuntimeBindingCte(name, binding, naming, parameterOffset, sou
|
|
|
18144
18558
|
}
|
|
18145
18559
|
const cteName = quoteIdent2(emittedBindName(name, naming), "alias");
|
|
18146
18560
|
const columnSql = binding.columns.map((column) => quoteIdent2(naming.toDatabase(column), "column")).join(", ");
|
|
18561
|
+
if (binding.columnTypes !== void 0) {
|
|
18562
|
+
return compileTypedNqlRuntimeBindingCte(
|
|
18563
|
+
name,
|
|
18564
|
+
binding,
|
|
18565
|
+
naming,
|
|
18566
|
+
parameterOffset,
|
|
18567
|
+
cteName,
|
|
18568
|
+
columnSql
|
|
18569
|
+
);
|
|
18570
|
+
}
|
|
18147
18571
|
if (sourceTable === void 0) {
|
|
18148
18572
|
throw new Error(
|
|
18149
|
-
`NQL runtime binding '${name}' cannot materialize a typed relation because its source
|
|
18573
|
+
`NQL runtime binding '${name}' cannot materialize a typed relation because its source table is unavailable.`
|
|
18150
18574
|
);
|
|
18151
18575
|
}
|
|
18152
18576
|
const projectedColumns = binding.columns.map((column) => quoteIdent2(naming.toDatabase(column), "column")).join(", ");
|
|
@@ -18421,7 +18845,7 @@ var PgsqlAdapter = class _PgsqlAdapter {
|
|
|
18421
18845
|
runtimeBinding,
|
|
18422
18846
|
naming,
|
|
18423
18847
|
parameters.length,
|
|
18424
|
-
bundle
|
|
18848
|
+
runtimeBindingSourceTable(bundle, name),
|
|
18425
18849
|
deps.schemaName,
|
|
18426
18850
|
deps.model
|
|
18427
18851
|
);
|