@dbsp/adapter-pgsql 1.1.1 → 1.2.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 +42 -16
- package/dist/index.js +909 -193
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -1074,6 +1074,19 @@ var init_param_ref = __esm({
|
|
|
1074
1074
|
}
|
|
1075
1075
|
});
|
|
1076
1076
|
|
|
1077
|
+
// src/handlers/expression/param-value.ts
|
|
1078
|
+
function bindParameter(value, state) {
|
|
1079
|
+
const idx = ++state.paramIndex;
|
|
1080
|
+
state.parameters.push(value);
|
|
1081
|
+
return createParamRef(idx);
|
|
1082
|
+
}
|
|
1083
|
+
var init_param_value = __esm({
|
|
1084
|
+
"src/handlers/expression/param-value.ts"() {
|
|
1085
|
+
"use strict";
|
|
1086
|
+
init_param_ref();
|
|
1087
|
+
}
|
|
1088
|
+
});
|
|
1089
|
+
|
|
1077
1090
|
// src/handlers/expression/case-value.ts
|
|
1078
1091
|
function resolveCaseValue(value, alias, schema, naming, state, nestedCaseHandler) {
|
|
1079
1092
|
if (value === null || value === void 0) {
|
|
@@ -1083,12 +1096,12 @@ function resolveCaseValue(value, alias, schema, naming, state, nestedCaseHandler
|
|
|
1083
1096
|
return columnRef(value, alias, schema, naming);
|
|
1084
1097
|
}
|
|
1085
1098
|
if (typeof value !== "object") {
|
|
1086
|
-
|
|
1087
|
-
state.parameters.push(value);
|
|
1088
|
-
return createParamRef(idx);
|
|
1099
|
+
return bindParameter(value, state);
|
|
1089
1100
|
}
|
|
1090
1101
|
const expr = value;
|
|
1091
1102
|
switch (expr.kind) {
|
|
1103
|
+
case "param":
|
|
1104
|
+
return bindParameter(expr.value, state);
|
|
1092
1105
|
case "literal":
|
|
1093
1106
|
if (expr.value === null || expr.value === void 0)
|
|
1094
1107
|
return nullConstNode();
|
|
@@ -1099,11 +1112,7 @@ function resolveCaseValue(value, alias, schema, naming, state, nestedCaseHandler
|
|
|
1099
1112
|
return integerNode(expr.value);
|
|
1100
1113
|
return floatNode(String(expr.value));
|
|
1101
1114
|
}
|
|
1102
|
-
|
|
1103
|
-
const idx = ++state.paramIndex;
|
|
1104
|
-
state.parameters.push(expr.value);
|
|
1105
|
-
return createParamRef(idx);
|
|
1106
|
-
}
|
|
1115
|
+
return bindParameter(expr.value, state);
|
|
1107
1116
|
case "column":
|
|
1108
1117
|
return columnRef(expr.column, alias, schema, naming);
|
|
1109
1118
|
case "arithmetic": {
|
|
@@ -1139,9 +1148,7 @@ function resolveCaseValue(value, alias, schema, naming, state, nestedCaseHandler
|
|
|
1139
1148
|
}
|
|
1140
1149
|
// falls through
|
|
1141
1150
|
default: {
|
|
1142
|
-
|
|
1143
|
-
state.parameters.push(value);
|
|
1144
|
-
return createParamRef(idx);
|
|
1151
|
+
return bindParameter(value, state);
|
|
1145
1152
|
}
|
|
1146
1153
|
}
|
|
1147
1154
|
}
|
|
@@ -1149,7 +1156,7 @@ var init_case_value = __esm({
|
|
|
1149
1156
|
"src/handlers/expression/case-value.ts"() {
|
|
1150
1157
|
"use strict";
|
|
1151
1158
|
init_ast_helpers();
|
|
1152
|
-
|
|
1159
|
+
init_param_value();
|
|
1153
1160
|
}
|
|
1154
1161
|
});
|
|
1155
1162
|
|
|
@@ -1428,7 +1435,17 @@ function handleAggregateExpression(expr, rootTable, decisions, applyFilter) {
|
|
|
1428
1435
|
const aggAs = expr.as;
|
|
1429
1436
|
const aggDistinct = expr.distinct;
|
|
1430
1437
|
const aggFilter = expr.filter;
|
|
1431
|
-
|
|
1438
|
+
const aggExtraArgs = Array.isArray(expr.extraArgs) ? expr.extraArgs : void 0;
|
|
1439
|
+
if (!aggField && aggExtraArgs?.length) {
|
|
1440
|
+
const decision = {
|
|
1441
|
+
type: "selectNqlFunction",
|
|
1442
|
+
function: aggFunc,
|
|
1443
|
+
args: aggExtraArgs,
|
|
1444
|
+
table: rootTable
|
|
1445
|
+
};
|
|
1446
|
+
if (aggAs) decision.alias = aggAs;
|
|
1447
|
+
decisions.push(decision);
|
|
1448
|
+
} else if (aggFunc === "count" && !aggField) {
|
|
1432
1449
|
const decision = {
|
|
1433
1450
|
type: "selectFunction",
|
|
1434
1451
|
function: "count",
|
|
@@ -1480,6 +1497,16 @@ function handleRawExpression(expr, rootTable, decisions) {
|
|
|
1480
1497
|
if (expr.as) decision.alias = expr.as;
|
|
1481
1498
|
decisions.push(decision);
|
|
1482
1499
|
}
|
|
1500
|
+
function handleFunctionExpression(expr, rootTable, decisions) {
|
|
1501
|
+
const decision = {
|
|
1502
|
+
type: "selectNqlFunction",
|
|
1503
|
+
function: expr.name,
|
|
1504
|
+
args: expr.args ?? [],
|
|
1505
|
+
table: rootTable
|
|
1506
|
+
};
|
|
1507
|
+
if (expr.as) decision.alias = expr.as;
|
|
1508
|
+
decisions.push(decision);
|
|
1509
|
+
}
|
|
1483
1510
|
function handleWindowExpression(expr, rootTable, decisions) {
|
|
1484
1511
|
const windowFunc = expr.function;
|
|
1485
1512
|
const windowAlias = expr.alias;
|
|
@@ -1592,6 +1619,7 @@ var init_select_expression_handlers = __esm({
|
|
|
1592
1619
|
aggregate: (expr, rootTable, decisions, applyFilter) => handleAggregateExpression(expr, rootTable, decisions, applyFilter),
|
|
1593
1620
|
coalesce: (expr, rootTable, decisions) => handleCoalesceExpression(expr, rootTable, decisions),
|
|
1594
1621
|
raw: (expr, rootTable, decisions) => handleRawExpression(expr, rootTable, decisions),
|
|
1622
|
+
function: (expr, rootTable, decisions) => handleFunctionExpression(expr, rootTable, decisions),
|
|
1595
1623
|
window: (expr, rootTable, decisions) => handleWindowExpression(expr, rootTable, decisions),
|
|
1596
1624
|
case: (expr, rootTable, decisions, applyFilter, convertCondition) => handleCaseExpression(
|
|
1597
1625
|
expr,
|
|
@@ -1601,7 +1629,8 @@ var init_select_expression_handlers = __esm({
|
|
|
1601
1629
|
convertCondition
|
|
1602
1630
|
),
|
|
1603
1631
|
relationColumn: (expr, rootTable, decisions) => handleRelationColumnExpression(expr, rootTable, decisions),
|
|
1604
|
-
|
|
1632
|
+
pseudoColumn: () => {
|
|
1633
|
+
},
|
|
1605
1634
|
arithmetic: (expr, rootTable, decisions) => handleArithmeticExpression(expr, rootTable, decisions),
|
|
1606
1635
|
jsonExtract: (expr, rootTable, decisions) => handleJsonExtractExpression(expr, rootTable, decisions),
|
|
1607
1636
|
jsonPathExtract: (expr, rootTable, decisions) => handleJsonPathExtractExpression(expr, rootTable, decisions),
|
|
@@ -1612,12 +1641,17 @@ var init_select_expression_handlers = __esm({
|
|
|
1612
1641
|
ref: (expr, rootTable, decisions) => handleCustomExpressionSelect(expr, rootTable, decisions),
|
|
1613
1642
|
param: (expr, rootTable, decisions) => handleCustomExpressionSelect(expr, rootTable, decisions),
|
|
1614
1643
|
cast: (expr, rootTable, decisions) => handleCustomExpressionSelect(expr, rootTable, decisions),
|
|
1615
|
-
unary: (expr, rootTable, decisions) => handleCustomExpressionSelect(expr, rootTable, decisions)
|
|
1644
|
+
unary: (expr, rootTable, decisions) => handleCustomExpressionSelect(expr, rootTable, decisions),
|
|
1645
|
+
subquery: (expr, rootTable, decisions) => handleCustomExpressionSelect(expr, rootTable, decisions),
|
|
1646
|
+
namedArg: (expr, rootTable, decisions) => handleCustomExpressionSelect(expr, rootTable, decisions),
|
|
1647
|
+
star: (expr, rootTable, decisions) => handleCustomExpressionSelect(expr, rootTable, decisions),
|
|
1648
|
+
array: (expr, rootTable, decisions) => handleCustomExpressionSelect(expr, rootTable, decisions)
|
|
1616
1649
|
};
|
|
1617
1650
|
}
|
|
1618
1651
|
});
|
|
1619
1652
|
|
|
1620
1653
|
// src/intent-to-decisions.ts
|
|
1654
|
+
import { isParamIntent } from "@dbsp/types";
|
|
1621
1655
|
function intentToDecisions(intent, rootTable) {
|
|
1622
1656
|
const decisions = [];
|
|
1623
1657
|
if (intent.select) {
|
|
@@ -1680,16 +1714,18 @@ function convertSelect(select, rootTable) {
|
|
|
1680
1714
|
const columns = select.columns;
|
|
1681
1715
|
for (const exprUnknown of columns) {
|
|
1682
1716
|
const expr = exprUnknown;
|
|
1683
|
-
const
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
|
|
1687
|
-
rootTable,
|
|
1688
|
-
decisions,
|
|
1689
|
-
applyFilterCondition,
|
|
1690
|
-
convertWhereCondition
|
|
1691
|
-
);
|
|
1717
|
+
const kind = typeof expr.kind === "string" ? expr.kind : String(expr.kind);
|
|
1718
|
+
const handler = EXPRESSION_HANDLERS[kind];
|
|
1719
|
+
if (!handler) {
|
|
1720
|
+
throw new UnknownSelectExpressionKindError(kind);
|
|
1692
1721
|
}
|
|
1722
|
+
handler(
|
|
1723
|
+
expr,
|
|
1724
|
+
rootTable,
|
|
1725
|
+
decisions,
|
|
1726
|
+
(decision, filter, table) => applyFilterCondition(decision, filter, table),
|
|
1727
|
+
(condition, table) => convertWhereCondition(condition, table)
|
|
1728
|
+
);
|
|
1693
1729
|
}
|
|
1694
1730
|
return decisions;
|
|
1695
1731
|
}
|
|
@@ -1822,10 +1858,12 @@ function isOuterRef(value) {
|
|
|
1822
1858
|
function containsOuterRef(where) {
|
|
1823
1859
|
if (!where || typeof where !== "object") return false;
|
|
1824
1860
|
const w = where;
|
|
1861
|
+
if (isParamIntent(w)) return false;
|
|
1825
1862
|
if (isOuterRef(w)) return true;
|
|
1826
1863
|
for (const value of Object.values(w)) {
|
|
1827
1864
|
if (Array.isArray(value)) {
|
|
1828
|
-
for (
|
|
1865
|
+
for (let i = 0; i < value.length; i++) {
|
|
1866
|
+
const item = value[i];
|
|
1829
1867
|
if (containsOuterRef(item)) return true;
|
|
1830
1868
|
}
|
|
1831
1869
|
} else if (typeof value === "object" && value !== null) {
|
|
@@ -2122,7 +2160,7 @@ function convertWhereCondition(condition, rootTable) {
|
|
|
2122
2160
|
table: rootTable
|
|
2123
2161
|
};
|
|
2124
2162
|
}
|
|
2125
|
-
case "jsonContains":
|
|
2163
|
+
case "jsonContains": {
|
|
2126
2164
|
return {
|
|
2127
2165
|
type: "where",
|
|
2128
2166
|
column: cond.field,
|
|
@@ -2130,6 +2168,7 @@ function convertWhereCondition(condition, rootTable) {
|
|
|
2130
2168
|
value: cond.value,
|
|
2131
2169
|
table: rootTable
|
|
2132
2170
|
};
|
|
2171
|
+
}
|
|
2133
2172
|
case "any":
|
|
2134
2173
|
return {
|
|
2135
2174
|
type: "where",
|
|
@@ -2186,10 +2225,20 @@ function convertOrderBy(order, rootTable) {
|
|
|
2186
2225
|
}
|
|
2187
2226
|
return decision;
|
|
2188
2227
|
}
|
|
2228
|
+
var UnknownSelectExpressionKindError;
|
|
2189
2229
|
var init_intent_to_decisions = __esm({
|
|
2190
2230
|
"src/intent-to-decisions.ts"() {
|
|
2191
2231
|
"use strict";
|
|
2192
2232
|
init_select_expression_handlers();
|
|
2233
|
+
UnknownSelectExpressionKindError = class extends Error {
|
|
2234
|
+
constructor(kind) {
|
|
2235
|
+
super(`Unknown SELECT expression kind: ${kind}`);
|
|
2236
|
+
this.kind = kind;
|
|
2237
|
+
this.name = "UnknownSelectExpressionKindError";
|
|
2238
|
+
}
|
|
2239
|
+
kind;
|
|
2240
|
+
code = "ERR_ADAPTER_UNKNOWN_SELECT_EXPRESSION_KIND";
|
|
2241
|
+
};
|
|
2193
2242
|
}
|
|
2194
2243
|
});
|
|
2195
2244
|
|
|
@@ -2750,8 +2799,19 @@ var init_compiler_utils = __esm({
|
|
|
2750
2799
|
}
|
|
2751
2800
|
});
|
|
2752
2801
|
|
|
2802
|
+
// src/param-intent.ts
|
|
2803
|
+
import { isParamIntent as isParamIntent2 } from "@dbsp/types";
|
|
2804
|
+
function unwrapParamIntent(value) {
|
|
2805
|
+
return isParamIntent2(value) ? value.value : value;
|
|
2806
|
+
}
|
|
2807
|
+
var init_param_intent = __esm({
|
|
2808
|
+
"src/param-intent.ts"() {
|
|
2809
|
+
"use strict";
|
|
2810
|
+
}
|
|
2811
|
+
});
|
|
2812
|
+
|
|
2753
2813
|
// src/handlers/where/utils.ts
|
|
2754
|
-
import { isFieldRef } from "@dbsp/types";
|
|
2814
|
+
import { isFieldRef, isParamIntent as isParamIntent3 } from "@dbsp/types";
|
|
2755
2815
|
function buildColumnRef(column, ctx) {
|
|
2756
2816
|
if (column.includes(".")) {
|
|
2757
2817
|
const dotIndex = column.indexOf(".");
|
|
@@ -2763,15 +2823,27 @@ function buildColumnRef(column, ctx) {
|
|
|
2763
2823
|
return columnRef(column, alias, void 0, ctx.naming);
|
|
2764
2824
|
}
|
|
2765
2825
|
function buildParamRef(value, state) {
|
|
2766
|
-
|
|
2767
|
-
|
|
2768
|
-
|
|
2826
|
+
const boundValue = unwrapParamIntent(value);
|
|
2827
|
+
if (isParamRef(boundValue)) {
|
|
2828
|
+
state.parameters.push(boundValue.value);
|
|
2829
|
+
return createParamRef(boundValue.paramIndex);
|
|
2769
2830
|
}
|
|
2770
2831
|
state.paramIndex++;
|
|
2771
|
-
state.parameters.push(
|
|
2832
|
+
state.parameters.push(boundValue);
|
|
2772
2833
|
return createParamRef(state.paramIndex);
|
|
2773
2834
|
}
|
|
2774
|
-
function compileValue(value, state, columnType) {
|
|
2835
|
+
function compileValue(value, state, columnType, forceParam = false) {
|
|
2836
|
+
const boundValue = unwrapParamIntent(value);
|
|
2837
|
+
if (isParamIntent3(value)) {
|
|
2838
|
+
const idx2 = ++state.paramIndex;
|
|
2839
|
+
state.parameters.push(boundValue);
|
|
2840
|
+
return columnType ? createTypeCastParamRef(idx2, columnType) : createParamRef(idx2);
|
|
2841
|
+
}
|
|
2842
|
+
if (forceParam) {
|
|
2843
|
+
const idx2 = ++state.paramIndex;
|
|
2844
|
+
state.parameters.push(boundValue);
|
|
2845
|
+
return columnType ? createTypeCastParamRef(idx2, columnType) : createParamRef(idx2);
|
|
2846
|
+
}
|
|
2775
2847
|
if (value === null || value === void 0) {
|
|
2776
2848
|
return nullConstNode();
|
|
2777
2849
|
}
|
|
@@ -2783,7 +2855,10 @@ function compileValue(value, state, columnType) {
|
|
|
2783
2855
|
state.parameters.push(value);
|
|
2784
2856
|
return columnType ? createTypeCastParamRef(idx, columnType) : createParamRef(idx);
|
|
2785
2857
|
}
|
|
2786
|
-
function compileValueOrFieldRef(value, ctx, state, columnType) {
|
|
2858
|
+
function compileValueOrFieldRef(value, ctx, state, columnType, forceParam = false) {
|
|
2859
|
+
if (forceParam || isParamIntent3(value)) {
|
|
2860
|
+
return compileValue(value, state, columnType, true);
|
|
2861
|
+
}
|
|
2787
2862
|
if (isFieldRef(value)) {
|
|
2788
2863
|
const alias = value.scope === "outer" ? ctx.outerAlias ?? ctx.rootTable : ctx.currentAlias ?? ctx.rootTable;
|
|
2789
2864
|
return columnRef(value.column, alias, void 0, ctx.naming);
|
|
@@ -2803,9 +2878,11 @@ var init_utils = __esm({
|
|
|
2803
2878
|
"src/handlers/where/utils.ts"() {
|
|
2804
2879
|
"use strict";
|
|
2805
2880
|
init_ast_helpers();
|
|
2881
|
+
init_param_intent();
|
|
2806
2882
|
init_param_ref();
|
|
2807
2883
|
init_validate();
|
|
2808
2884
|
init_types();
|
|
2885
|
+
init_param_intent();
|
|
2809
2886
|
}
|
|
2810
2887
|
});
|
|
2811
2888
|
|
|
@@ -2835,6 +2912,7 @@ var init_any = __esm({
|
|
|
2835
2912
|
"src/handlers/where/any.ts"() {
|
|
2836
2913
|
"use strict";
|
|
2837
2914
|
init_compiler_utils();
|
|
2915
|
+
init_param_intent();
|
|
2838
2916
|
init_param_ref();
|
|
2839
2917
|
init_types();
|
|
2840
2918
|
init_utils();
|
|
@@ -2845,7 +2923,8 @@ var init_any = __esm({
|
|
|
2845
2923
|
if (!column) {
|
|
2846
2924
|
throw new Error("ANY handler requires a column");
|
|
2847
2925
|
}
|
|
2848
|
-
const
|
|
2926
|
+
const rawValues = unwrapParamIntent(decision.values);
|
|
2927
|
+
const values = Array.isArray(rawValues) ? rawValues : [];
|
|
2849
2928
|
const columnNode = buildColumnRef(column, ctx);
|
|
2850
2929
|
let pgBaseType;
|
|
2851
2930
|
if (decision.dataType) {
|
|
@@ -2875,6 +2954,7 @@ var betweenHandler;
|
|
|
2875
2954
|
var init_between = __esm({
|
|
2876
2955
|
"src/handlers/where/between.ts"() {
|
|
2877
2956
|
"use strict";
|
|
2957
|
+
init_param_intent();
|
|
2878
2958
|
init_param_ref();
|
|
2879
2959
|
init_utils();
|
|
2880
2960
|
betweenHandler = {
|
|
@@ -2884,16 +2964,18 @@ var init_between = __esm({
|
|
|
2884
2964
|
if (!column) {
|
|
2885
2965
|
throw new Error("BETWEEN handler requires a column");
|
|
2886
2966
|
}
|
|
2887
|
-
const range = decision.value;
|
|
2967
|
+
const range = unwrapParamIntent(decision.value);
|
|
2888
2968
|
if (!Array.isArray(range) || range.length !== 2) {
|
|
2889
2969
|
throw new Error("BETWEEN condition requires [min, max] array");
|
|
2890
2970
|
}
|
|
2891
2971
|
const columnNode = buildColumnRef(column, ctx);
|
|
2972
|
+
const minValue = unwrapParamIntent(range[0]);
|
|
2973
|
+
const maxValue = unwrapParamIntent(range[1]);
|
|
2892
2974
|
const minIdx = ++state.paramIndex;
|
|
2893
|
-
state.parameters.push(
|
|
2975
|
+
state.parameters.push(minValue);
|
|
2894
2976
|
const minNode = createParamRef(minIdx);
|
|
2895
2977
|
const maxIdx = ++state.paramIndex;
|
|
2896
|
-
state.parameters.push(
|
|
2978
|
+
state.parameters.push(maxValue);
|
|
2897
2979
|
const maxNode = createParamRef(maxIdx);
|
|
2898
2980
|
return {
|
|
2899
2981
|
A_Expr: {
|
|
@@ -2969,6 +3051,7 @@ var init_custom_expression = __esm({
|
|
|
2969
3051
|
"src/handlers/where/custom-expression.ts"() {
|
|
2970
3052
|
"use strict";
|
|
2971
3053
|
init_ast_helpers();
|
|
3054
|
+
init_param_intent();
|
|
2972
3055
|
init_param_ref();
|
|
2973
3056
|
init_custom();
|
|
2974
3057
|
OP_MAP = {
|
|
@@ -2994,7 +3077,7 @@ var init_custom_expression = __esm({
|
|
|
2994
3077
|
return leftNode;
|
|
2995
3078
|
}
|
|
2996
3079
|
const idx = ++state.paramIndex;
|
|
2997
|
-
state.parameters.push(decision.value);
|
|
3080
|
+
state.parameters.push(unwrapParamIntent(decision.value));
|
|
2998
3081
|
const rightNode = createParamRef(idx);
|
|
2999
3082
|
const rawOp = decision.subqueryOperator ?? decision.operator ?? "=";
|
|
3000
3083
|
const sqlOp = OP_MAP[rawOp];
|
|
@@ -3202,6 +3285,7 @@ var init_exists = __esm({
|
|
|
3202
3285
|
});
|
|
3203
3286
|
|
|
3204
3287
|
// src/handlers/where/in.ts
|
|
3288
|
+
import { isParamIntent as isParamIntent4 } from "@dbsp/types";
|
|
3205
3289
|
function createInExpr(columnNode, state, values, columnType) {
|
|
3206
3290
|
state.paramIndex++;
|
|
3207
3291
|
state.parameters.push(values);
|
|
@@ -3228,11 +3312,22 @@ function createNotInExpr(columnNode, state, values, columnType) {
|
|
|
3228
3312
|
}
|
|
3229
3313
|
};
|
|
3230
3314
|
}
|
|
3315
|
+
function isWholeArrayParamList(value) {
|
|
3316
|
+
return value.length === 1 && isParamIntent4(value[0]) && Array.isArray(value[0].value);
|
|
3317
|
+
}
|
|
3318
|
+
function unwrapCompilerInListValues(value) {
|
|
3319
|
+
const values = [];
|
|
3320
|
+
for (const item of value) {
|
|
3321
|
+
values.push(unwrapParamIntent(item));
|
|
3322
|
+
}
|
|
3323
|
+
return values;
|
|
3324
|
+
}
|
|
3231
3325
|
var inHandler;
|
|
3232
3326
|
var init_in = __esm({
|
|
3233
3327
|
"src/handlers/where/in.ts"() {
|
|
3234
3328
|
"use strict";
|
|
3235
3329
|
init_ast_helpers();
|
|
3330
|
+
init_param_intent();
|
|
3236
3331
|
init_param_ref();
|
|
3237
3332
|
init_types();
|
|
3238
3333
|
init_utils();
|
|
@@ -3241,7 +3336,7 @@ var init_in = __esm({
|
|
|
3241
3336
|
compile(decision, ctx, state) {
|
|
3242
3337
|
const operator = decision.operator ?? "in";
|
|
3243
3338
|
const column = decision.column;
|
|
3244
|
-
const value = decision.value;
|
|
3339
|
+
const value = unwrapParamIntent(decision.value);
|
|
3245
3340
|
if (!column) {
|
|
3246
3341
|
throw new Error("In handler requires a column");
|
|
3247
3342
|
}
|
|
@@ -3251,7 +3346,7 @@ var init_in = __esm({
|
|
|
3251
3346
|
`[in handler] Received a non-array value for operator '${operator}' on column '${column}'. This is a compiler bug: ${hint}. File a bug report.`
|
|
3252
3347
|
);
|
|
3253
3348
|
}
|
|
3254
|
-
const values = value;
|
|
3349
|
+
const values = isWholeArrayParamList(value) ? value[0].value : unwrapCompilerInListValues(value);
|
|
3255
3350
|
if (values.length === 0) {
|
|
3256
3351
|
if (operator === COLLECTION_OPERATORS.NOT_IN || operator === "notIn") {
|
|
3257
3352
|
return booleanConstNode(true);
|
|
@@ -3494,6 +3589,7 @@ var RANGE_OP_MAP, rangeHandler;
|
|
|
3494
3589
|
var init_range = __esm({
|
|
3495
3590
|
"src/handlers/where/range.ts"() {
|
|
3496
3591
|
"use strict";
|
|
3592
|
+
init_param_intent();
|
|
3497
3593
|
init_param_ref();
|
|
3498
3594
|
init_types();
|
|
3499
3595
|
init_utils();
|
|
@@ -3511,11 +3607,14 @@ var init_range = __esm({
|
|
|
3511
3607
|
}
|
|
3512
3608
|
const operator = decision.operator ?? "contains";
|
|
3513
3609
|
const pgOp = RANGE_OP_MAP[operator] ?? operator;
|
|
3514
|
-
const
|
|
3610
|
+
const rawValue = decision.value;
|
|
3611
|
+
const value = unwrapParamIntent(rawValue);
|
|
3515
3612
|
const columnNode = buildColumnRef(column, ctx);
|
|
3516
3613
|
let paramValue;
|
|
3517
3614
|
let isScalar = false;
|
|
3518
|
-
if (
|
|
3615
|
+
if (value !== rawValue) {
|
|
3616
|
+
paramValue = value;
|
|
3617
|
+
} else if (isRangeValue(value)) {
|
|
3519
3618
|
const lower = value.lower ?? "";
|
|
3520
3619
|
const upper = value.upper ?? "";
|
|
3521
3620
|
paramValue = `[${lower},${upper})`;
|
|
@@ -3699,7 +3798,7 @@ function handleExpressionIntent(intent, ctx, handlerCtx) {
|
|
|
3699
3798
|
return leftNode;
|
|
3700
3799
|
}
|
|
3701
3800
|
const idx = ++ctx.paramState.paramIndex;
|
|
3702
|
-
ctx.paramState.parameters.push(exprIntent.value);
|
|
3801
|
+
ctx.paramState.parameters.push(unwrapParamIntent(exprIntent.value));
|
|
3703
3802
|
const rightNode = createParamRef(idx);
|
|
3704
3803
|
const sqlOp = OP_MAP2[exprIntent.operator] ?? "=";
|
|
3705
3804
|
return binaryExpr(sqlOp, leftNode, rightNode);
|
|
@@ -3981,9 +4080,13 @@ function compileWhereIntent(intent, ctx) {
|
|
|
3981
4080
|
if (exprRefResult !== null) return exprRefResult;
|
|
3982
4081
|
}
|
|
3983
4082
|
const needsColumn = intent.kind === "comparison" || intent.kind === "null";
|
|
4083
|
+
const rawIntent = intent;
|
|
3984
4084
|
const bridged = needsColumn ? {
|
|
3985
4085
|
...intent,
|
|
3986
|
-
column:
|
|
4086
|
+
column: rawIntent.field,
|
|
4087
|
+
..."value" in rawIntent && {
|
|
4088
|
+
value: rawIntent.value
|
|
4089
|
+
}
|
|
3987
4090
|
} : intent;
|
|
3988
4091
|
return dispatcher(bridged, handlerCtx, ctx.paramState);
|
|
3989
4092
|
}
|
|
@@ -3999,6 +4102,7 @@ var init_compile_where = __esm({
|
|
|
3999
4102
|
init_utils();
|
|
4000
4103
|
init_intent_to_decisions();
|
|
4001
4104
|
init_naming_plugin();
|
|
4105
|
+
init_param_intent();
|
|
4002
4106
|
init_param_ref();
|
|
4003
4107
|
registerWhereDispatcherFactory(createWhereDispatcher);
|
|
4004
4108
|
OP_MAP2 = {
|
|
@@ -4037,7 +4141,8 @@ var init_raw_exists = __esm({
|
|
|
4037
4141
|
subIntent,
|
|
4038
4142
|
state.paramIndex,
|
|
4039
4143
|
ctx.naming,
|
|
4040
|
-
ctx.schema
|
|
4144
|
+
ctx.schema,
|
|
4145
|
+
"rawExists"
|
|
4041
4146
|
);
|
|
4042
4147
|
if (innerParams) {
|
|
4043
4148
|
for (const p of innerParams) {
|
|
@@ -4169,6 +4274,7 @@ var init_relation_filter = __esm({
|
|
|
4169
4274
|
});
|
|
4170
4275
|
|
|
4171
4276
|
// src/subquery-emission.ts
|
|
4277
|
+
import { isParamIntent as isParamIntent5 } from "@dbsp/types";
|
|
4172
4278
|
function assertNoDroppedDecisionModifiers(decision, use) {
|
|
4173
4279
|
const d = decision;
|
|
4174
4280
|
const unsupported = [];
|
|
@@ -4287,6 +4393,12 @@ function buildPredicateSubquerySelect(use, sourceIntent, decision, ctx, state, d
|
|
|
4287
4393
|
if (decision.limit != null) {
|
|
4288
4394
|
if (typeof decision.limit === "number") {
|
|
4289
4395
|
stmt.limitCount = integerNode(decision.limit);
|
|
4396
|
+
} else if (isParamIntent5(decision.limit)) {
|
|
4397
|
+
state.parameters.push(unwrapParamIntent(decision.limit));
|
|
4398
|
+
state.paramIndex++;
|
|
4399
|
+
stmt.limitCount = {
|
|
4400
|
+
ParamRef: { number: state.paramIndex }
|
|
4401
|
+
};
|
|
4290
4402
|
} else {
|
|
4291
4403
|
const limitObj = decision.limit;
|
|
4292
4404
|
if (typeof limitObj.paramIndex !== "number") {
|
|
@@ -4304,6 +4416,7 @@ var init_subquery_emission = __esm({
|
|
|
4304
4416
|
"use strict";
|
|
4305
4417
|
init_ast_helpers();
|
|
4306
4418
|
init_intent_to_decisions();
|
|
4419
|
+
init_param_intent();
|
|
4307
4420
|
}
|
|
4308
4421
|
});
|
|
4309
4422
|
|
|
@@ -4714,12 +4827,13 @@ var init_join = __esm({
|
|
|
4714
4827
|
const targets = [];
|
|
4715
4828
|
const columns = decision.columns;
|
|
4716
4829
|
const columnAliases = decision.columnAliases;
|
|
4830
|
+
const hydrationPrefix = decision.hydrationPrefix ?? relation ?? targetAlias;
|
|
4717
4831
|
if (columns && columns.length > 0) {
|
|
4718
4832
|
if (columns.length === 1 && columns[0] === "*") {
|
|
4719
4833
|
targets.push(starTarget(targetAlias, ctx.naming));
|
|
4720
4834
|
} else {
|
|
4721
4835
|
for (const col of columns) {
|
|
4722
|
-
const outputAlias = columnAliases?.[col] ?? `${
|
|
4836
|
+
const outputAlias = columnAliases?.[col] ?? `${hydrationPrefix}.${col}`;
|
|
4723
4837
|
targets.push(columnTarget(col, outputAlias, targetAlias, ctx.naming));
|
|
4724
4838
|
}
|
|
4725
4839
|
}
|
|
@@ -5048,6 +5162,7 @@ __export(handlers_exports, {
|
|
|
5048
5162
|
genericWindowHandler: () => genericWindowHandler,
|
|
5049
5163
|
getExpressionHandler: () => getExpressionHandler,
|
|
5050
5164
|
getIncludeHandler: () => getIncludeHandler,
|
|
5165
|
+
getNqlSafeExpressionHandler: () => getNqlSafeExpressionHandler,
|
|
5051
5166
|
getRegisteredOperators: () => getRegisteredOperators,
|
|
5052
5167
|
getRegistryStats: () => getRegistryStats,
|
|
5053
5168
|
getWhereHandler: () => getWhereHandler,
|
|
@@ -5158,6 +5273,10 @@ function getExpressionHandler(type) {
|
|
|
5158
5273
|
}
|
|
5159
5274
|
return handler;
|
|
5160
5275
|
}
|
|
5276
|
+
function getNqlSafeExpressionHandler(type) {
|
|
5277
|
+
const handler = expressionHandlers.get(type);
|
|
5278
|
+
return handler?.nqlSafe === true ? handler : void 0;
|
|
5279
|
+
}
|
|
5161
5280
|
function getIncludeHandler(strategy) {
|
|
5162
5281
|
const handler = includeHandlers.get(strategy);
|
|
5163
5282
|
if (!handler) {
|
|
@@ -5179,7 +5298,7 @@ function ensureHandlersRegistered() {
|
|
|
5179
5298
|
handlersInitialized = true;
|
|
5180
5299
|
registerAllWhereHandlers();
|
|
5181
5300
|
}
|
|
5182
|
-
function normalizeToDecision(input) {
|
|
5301
|
+
function normalizeToDecision(input, ctx) {
|
|
5183
5302
|
if (input.column !== void 0) {
|
|
5184
5303
|
const raw2 = input;
|
|
5185
5304
|
if (raw2.jsonPath && raw2.jsonPath.length > 0) {
|
|
@@ -5202,7 +5321,7 @@ function normalizeToDecision(input) {
|
|
|
5202
5321
|
type: op3,
|
|
5203
5322
|
operator: op3,
|
|
5204
5323
|
conditions: (raw.conditions ?? []).map(
|
|
5205
|
-
(c) => normalizeToDecision(c)
|
|
5324
|
+
(c) => normalizeToDecision(c, ctx)
|
|
5206
5325
|
)
|
|
5207
5326
|
};
|
|
5208
5327
|
}
|
|
@@ -5214,7 +5333,7 @@ function normalizeToDecision(input) {
|
|
|
5214
5333
|
switch (kind) {
|
|
5215
5334
|
case "comparison": {
|
|
5216
5335
|
if (raw.jsonPath) {
|
|
5217
|
-
|
|
5336
|
+
const decision = {
|
|
5218
5337
|
type: "where",
|
|
5219
5338
|
column: raw.field,
|
|
5220
5339
|
operator: "jsonComparison",
|
|
@@ -5222,6 +5341,7 @@ function normalizeToDecision(input) {
|
|
|
5222
5341
|
jsonPath: raw.jsonPath,
|
|
5223
5342
|
jsonMode: raw.jsonMode ?? "text"
|
|
5224
5343
|
};
|
|
5344
|
+
return decision;
|
|
5225
5345
|
}
|
|
5226
5346
|
return {
|
|
5227
5347
|
type: "where",
|
|
@@ -5235,7 +5355,7 @@ function normalizeToDecision(input) {
|
|
|
5235
5355
|
type: "and",
|
|
5236
5356
|
operator: "and",
|
|
5237
5357
|
conditions: (raw.conditions ?? []).map(
|
|
5238
|
-
(c) => normalizeToDecision(c)
|
|
5358
|
+
(c) => normalizeToDecision(c, ctx)
|
|
5239
5359
|
)
|
|
5240
5360
|
};
|
|
5241
5361
|
case "or":
|
|
@@ -5243,14 +5363,14 @@ function normalizeToDecision(input) {
|
|
|
5243
5363
|
type: "or",
|
|
5244
5364
|
operator: "or",
|
|
5245
5365
|
conditions: (raw.conditions ?? []).map(
|
|
5246
|
-
(c) => normalizeToDecision(c)
|
|
5366
|
+
(c) => normalizeToDecision(c, ctx)
|
|
5247
5367
|
)
|
|
5248
5368
|
};
|
|
5249
5369
|
case "not":
|
|
5250
5370
|
return {
|
|
5251
5371
|
type: "not",
|
|
5252
5372
|
operator: "not",
|
|
5253
|
-
conditions: [normalizeToDecision(raw.condition)]
|
|
5373
|
+
conditions: [normalizeToDecision(raw.condition, ctx)]
|
|
5254
5374
|
};
|
|
5255
5375
|
case "null":
|
|
5256
5376
|
return {
|
|
@@ -5274,7 +5394,7 @@ function normalizeToDecision(input) {
|
|
|
5274
5394
|
);
|
|
5275
5395
|
const rawSelect = sub.select;
|
|
5276
5396
|
const selectColumn = typeof rawSelect === "string" ? rawSelect : isSelectWithFields(rawSelect) ? rawSelect.fields?.[0] ?? "*" : "*";
|
|
5277
|
-
const subConditions = sub.where ? [normalizeToDecision(sub.where)] : [];
|
|
5397
|
+
const subConditions = sub.where ? [normalizeToDecision(sub.where, ctx)] : [];
|
|
5278
5398
|
const rawLimit = sub.limit;
|
|
5279
5399
|
const rawOrderBy = sub.orderBy;
|
|
5280
5400
|
return {
|
|
@@ -5309,13 +5429,14 @@ function normalizeToDecision(input) {
|
|
|
5309
5429
|
operator: raw.caseInsensitive ? "ilike" : "like",
|
|
5310
5430
|
value: raw.pattern
|
|
5311
5431
|
};
|
|
5312
|
-
case "jsonContains":
|
|
5432
|
+
case "jsonContains": {
|
|
5313
5433
|
return {
|
|
5314
5434
|
type: "where",
|
|
5315
5435
|
column: raw.field,
|
|
5316
5436
|
operator: raw.reversed ? "jsonContainedBy" : "jsonContains",
|
|
5317
5437
|
value: raw.value
|
|
5318
5438
|
};
|
|
5439
|
+
}
|
|
5319
5440
|
case "jsonExists":
|
|
5320
5441
|
return {
|
|
5321
5442
|
type: "where",
|
|
@@ -5326,7 +5447,7 @@ function normalizeToDecision(input) {
|
|
|
5326
5447
|
case "exists":
|
|
5327
5448
|
case "notExists": {
|
|
5328
5449
|
const relation = raw.relation;
|
|
5329
|
-
const conditions = raw.where ? [normalizeToDecision(raw.where)] : void 0;
|
|
5450
|
+
const conditions = raw.where ? [normalizeToDecision(raw.where, ctx)] : void 0;
|
|
5330
5451
|
const targetTable = raw.targetTable ?? relation;
|
|
5331
5452
|
const sourceColumn = raw.sourceColumn;
|
|
5332
5453
|
const targetColumn = raw.targetColumn;
|
|
@@ -5355,7 +5476,7 @@ function normalizeToDecision(input) {
|
|
|
5355
5476
|
function createWhereDispatcher() {
|
|
5356
5477
|
return (decision, ctx, state) => {
|
|
5357
5478
|
ensureHandlersRegistered();
|
|
5358
|
-
const normalized = normalizeToDecision(decision);
|
|
5479
|
+
const normalized = normalizeToDecision(decision, ctx);
|
|
5359
5480
|
const rawOperator = normalized.operator ?? "=";
|
|
5360
5481
|
const operator = OPERATOR_ALIASES[rawOperator] ?? rawOperator;
|
|
5361
5482
|
const handler = getWhereHandler(operator);
|
|
@@ -5508,16 +5629,18 @@ function resolveOperand(operand, ctx, state) {
|
|
|
5508
5629
|
const alias = ctx.currentAlias ?? ctx.rootTable;
|
|
5509
5630
|
return columnRef(operand, alias, void 0, ctx.naming);
|
|
5510
5631
|
}
|
|
5511
|
-
|
|
5512
|
-
|
|
5513
|
-
|
|
5632
|
+
if (typeof operand === "object" && operand !== null && "kind" in operand && ctx.compileNqlSelectExpression) {
|
|
5633
|
+
return ctx.compileNqlSelectExpression(operand, ctx, state);
|
|
5634
|
+
}
|
|
5635
|
+
return bindParameter(unwrapParamIntent(operand), state);
|
|
5514
5636
|
}
|
|
5515
5637
|
var arithmeticHandler;
|
|
5516
5638
|
var init_arithmetic = __esm({
|
|
5517
5639
|
"src/handlers/expression/arithmetic.ts"() {
|
|
5518
5640
|
"use strict";
|
|
5519
5641
|
init_ast_helpers();
|
|
5520
|
-
|
|
5642
|
+
init_param_intent();
|
|
5643
|
+
init_param_value();
|
|
5521
5644
|
arithmeticHandler = {
|
|
5522
5645
|
types: ["arithmetic", "math", "calc"],
|
|
5523
5646
|
compile(decision, ctx, state) {
|
|
@@ -5552,8 +5675,9 @@ var init_case = __esm({
|
|
|
5552
5675
|
"src/handlers/expression/case.ts"() {
|
|
5553
5676
|
"use strict";
|
|
5554
5677
|
init_ast_helpers();
|
|
5555
|
-
|
|
5678
|
+
init_param_intent();
|
|
5556
5679
|
init_case_value();
|
|
5680
|
+
init_param_value();
|
|
5557
5681
|
caseHandler = {
|
|
5558
5682
|
types: ["case", "CASE", "caseWhen"],
|
|
5559
5683
|
compile(decision, ctx, state) {
|
|
@@ -5599,13 +5723,12 @@ var init_case = __esm({
|
|
|
5599
5723
|
const tableAlias = ctx.currentAlias ?? ctx.rootTable;
|
|
5600
5724
|
const testExpr = columnRef(column, tableAlias, void 0, ctx.naming);
|
|
5601
5725
|
const args = conditions.map((cond) => {
|
|
5602
|
-
const whenParamNumber = ++state.paramIndex;
|
|
5603
5726
|
const whenDecision = cond.when;
|
|
5604
|
-
|
|
5605
|
-
|
|
5606
|
-
|
|
5607
|
-
|
|
5608
|
-
const thenResult =
|
|
5727
|
+
const whenExpr = bindParameter(
|
|
5728
|
+
unwrapParamIntent(whenDecision.value ?? cond.when),
|
|
5729
|
+
state
|
|
5730
|
+
);
|
|
5731
|
+
const thenResult = bindParameter(unwrapParamIntent(cond.then), state);
|
|
5609
5732
|
const caseWhen = {
|
|
5610
5733
|
expr: whenExpr,
|
|
5611
5734
|
result: thenResult
|
|
@@ -5614,9 +5737,7 @@ var init_case = __esm({
|
|
|
5614
5737
|
});
|
|
5615
5738
|
let defresult;
|
|
5616
5739
|
if (elseValue !== void 0) {
|
|
5617
|
-
|
|
5618
|
-
state.parameters.push(elseValue);
|
|
5619
|
-
defresult = createParamRef(paramNumber);
|
|
5740
|
+
defresult = bindParameter(unwrapParamIntent(elseValue), state);
|
|
5620
5741
|
}
|
|
5621
5742
|
const caseExpr = {
|
|
5622
5743
|
arg: testExpr,
|
|
@@ -5642,18 +5763,21 @@ function buildValueNode(value, ctx, state) {
|
|
|
5642
5763
|
return columnRef(decision.column, tableAlias, void 0, ctx.naming);
|
|
5643
5764
|
}
|
|
5644
5765
|
}
|
|
5645
|
-
|
|
5646
|
-
|
|
5647
|
-
|
|
5766
|
+
if (typeof value === "object" && value !== null && "kind" in value && ctx.compileNqlSelectExpression) {
|
|
5767
|
+
return ctx.compileNqlSelectExpression(value, ctx, state);
|
|
5768
|
+
}
|
|
5769
|
+
return bindParameter(unwrapParamIntent(value), state);
|
|
5648
5770
|
}
|
|
5649
5771
|
var coalesceHandler, nullIfHandler, greatestHandler, leastHandler;
|
|
5650
5772
|
var init_coalesce = __esm({
|
|
5651
5773
|
"src/handlers/expression/coalesce.ts"() {
|
|
5652
5774
|
"use strict";
|
|
5653
5775
|
init_ast_helpers();
|
|
5654
|
-
|
|
5776
|
+
init_param_intent();
|
|
5777
|
+
init_param_value();
|
|
5655
5778
|
coalesceHandler = {
|
|
5656
5779
|
types: ["coalesce", "COALESCE", "ifNull", "nvl"],
|
|
5780
|
+
nqlSafe: true,
|
|
5657
5781
|
compile(decision, ctx, state) {
|
|
5658
5782
|
const args = decision.args;
|
|
5659
5783
|
const column = decision.column;
|
|
@@ -5693,9 +5817,7 @@ var init_coalesce = __esm({
|
|
|
5693
5817
|
}
|
|
5694
5818
|
const tableAlias = ctx.currentAlias ?? ctx.rootTable;
|
|
5695
5819
|
const colRef = columnRef(column, tableAlias, void 0, ctx.naming);
|
|
5696
|
-
const
|
|
5697
|
-
state.parameters.push(value);
|
|
5698
|
-
const valueRef = createParamRef(paramNumber);
|
|
5820
|
+
const valueRef = bindParameter(unwrapParamIntent(value), state);
|
|
5699
5821
|
return {
|
|
5700
5822
|
NullIfExpr: {
|
|
5701
5823
|
args: [colRef, valueRef]
|
|
@@ -5793,11 +5915,30 @@ var init_column = __esm({
|
|
|
5793
5915
|
});
|
|
5794
5916
|
|
|
5795
5917
|
// src/handlers/expression/json.ts
|
|
5918
|
+
function normalizeJsonPathArgs(args) {
|
|
5919
|
+
if (!args || args.length === 0) return [];
|
|
5920
|
+
if (args.length === 1) {
|
|
5921
|
+
const first = args[0];
|
|
5922
|
+
const unwrappedFirst = unwrapParamIntent(first);
|
|
5923
|
+
if (first !== unwrappedFirst) {
|
|
5924
|
+
return unwrappedFirst;
|
|
5925
|
+
}
|
|
5926
|
+
if (Array.isArray(first)) {
|
|
5927
|
+
return first.map(unwrapParamIntent);
|
|
5928
|
+
}
|
|
5929
|
+
if (typeof first === "string" && first.startsWith("{") && first.endsWith("}")) {
|
|
5930
|
+
const inner = first.slice(1, -1);
|
|
5931
|
+
return inner.length === 0 ? [] : inner.split(",");
|
|
5932
|
+
}
|
|
5933
|
+
}
|
|
5934
|
+
return args.map(unwrapParamIntent);
|
|
5935
|
+
}
|
|
5796
5936
|
var jsonExtractHandler, jsonPathExtractHandler;
|
|
5797
5937
|
var init_json2 = __esm({
|
|
5798
5938
|
"src/handlers/expression/json.ts"() {
|
|
5799
5939
|
"use strict";
|
|
5800
5940
|
init_ast_helpers();
|
|
5941
|
+
init_param_intent();
|
|
5801
5942
|
init_utils();
|
|
5802
5943
|
jsonExtractHandler = {
|
|
5803
5944
|
types: ["jsonExtract"],
|
|
@@ -5834,10 +5975,10 @@ var init_json2 = __esm({
|
|
|
5834
5975
|
throw new Error("JSON path extract handler requires a column");
|
|
5835
5976
|
}
|
|
5836
5977
|
const mode = decision.jsonMode ?? "text";
|
|
5837
|
-
const
|
|
5978
|
+
const path = normalizeJsonPathArgs(decision.args);
|
|
5838
5979
|
const alias = ctx.currentAlias ?? ctx.rootTable;
|
|
5839
5980
|
const left = columnRef(column, alias, void 0, ctx.naming);
|
|
5840
|
-
const right = compileValue(
|
|
5981
|
+
const right = compileValue(path, state);
|
|
5841
5982
|
const op3 = mode === "text" ? "#>>" : "#>";
|
|
5842
5983
|
return {
|
|
5843
5984
|
A_Expr: {
|
|
@@ -6432,6 +6573,8 @@ var rawHandler, sqlFunctionHandler, literalHandler;
|
|
|
6432
6573
|
var init_raw = __esm({
|
|
6433
6574
|
"src/handlers/expression/raw.ts"() {
|
|
6434
6575
|
"use strict";
|
|
6576
|
+
init_param_intent();
|
|
6577
|
+
init_param_value();
|
|
6435
6578
|
rawHandler = {
|
|
6436
6579
|
types: ["raw", "RAW", "rawSql", "rawExpression"],
|
|
6437
6580
|
compile(decision, ctx, _state) {
|
|
@@ -6466,17 +6609,9 @@ var init_raw = __esm({
|
|
|
6466
6609
|
if (args && Array.isArray(args)) {
|
|
6467
6610
|
for (const arg of args) {
|
|
6468
6611
|
if (typeof arg === "object" && arg !== null && "type" in arg) {
|
|
6469
|
-
|
|
6470
|
-
state.parameters.push(arg);
|
|
6471
|
-
argNodes.push({
|
|
6472
|
-
ParamRef: { number: paramNumber }
|
|
6473
|
-
});
|
|
6612
|
+
argNodes.push(bindParameter(unwrapParamIntent(arg), state));
|
|
6474
6613
|
} else {
|
|
6475
|
-
|
|
6476
|
-
state.parameters.push(arg);
|
|
6477
|
-
argNodes.push({
|
|
6478
|
-
ParamRef: { number: paramNumber }
|
|
6479
|
-
});
|
|
6614
|
+
argNodes.push(bindParameter(unwrapParamIntent(arg), state));
|
|
6480
6615
|
}
|
|
6481
6616
|
}
|
|
6482
6617
|
}
|
|
@@ -6698,13 +6833,9 @@ function createLagLeadHandler(funcName, types) {
|
|
|
6698
6833
|
const colRef = columnRef(column, tableAlias, void 0, ctx.naming);
|
|
6699
6834
|
const args = [colRef];
|
|
6700
6835
|
const offset = decision.args?.[0] ?? 1;
|
|
6701
|
-
|
|
6702
|
-
state.parameters.push(offset);
|
|
6703
|
-
args.push(createParamRef(offsetParamNumber));
|
|
6836
|
+
args.push(bindParameter(unwrapParamIntent(offset), state));
|
|
6704
6837
|
if (decision.value !== void 0) {
|
|
6705
|
-
|
|
6706
|
-
state.parameters.push(decision.value);
|
|
6707
|
-
args.push(createParamRef(defaultParamNumber));
|
|
6838
|
+
args.push(bindParameter(unwrapParamIntent(decision.value), state));
|
|
6708
6839
|
}
|
|
6709
6840
|
return buildWindowFunction(funcName, args, decision, ctx);
|
|
6710
6841
|
}
|
|
@@ -6730,7 +6861,8 @@ var init_window = __esm({
|
|
|
6730
6861
|
"src/handlers/expression/window.ts"() {
|
|
6731
6862
|
"use strict";
|
|
6732
6863
|
init_ast_helpers();
|
|
6733
|
-
|
|
6864
|
+
init_param_intent();
|
|
6865
|
+
init_param_value();
|
|
6734
6866
|
WINDOW_FRAME_DEFAULT = 1034;
|
|
6735
6867
|
rowNumberHandler = createNoArgWindowHandler("row_number", [
|
|
6736
6868
|
"rowNumber",
|
|
@@ -6747,9 +6879,7 @@ var init_window = __esm({
|
|
|
6747
6879
|
types: ["ntile", "NTILE"],
|
|
6748
6880
|
compile(decision, ctx, state) {
|
|
6749
6881
|
const n = decision.value ?? decision.args?.[0] ?? 4;
|
|
6750
|
-
const
|
|
6751
|
-
state.parameters.push(n);
|
|
6752
|
-
const nRef = createParamRef(paramNumber);
|
|
6882
|
+
const nRef = bindParameter(unwrapParamIntent(n), state);
|
|
6753
6883
|
return buildWindowFunction("ntile", [nRef], decision, ctx);
|
|
6754
6884
|
}
|
|
6755
6885
|
};
|
|
@@ -6790,15 +6920,11 @@ var init_window = __esm({
|
|
|
6790
6920
|
}
|
|
6791
6921
|
if (decision.args && Array.isArray(decision.args)) {
|
|
6792
6922
|
for (const arg of decision.args) {
|
|
6793
|
-
|
|
6794
|
-
state.parameters.push(arg);
|
|
6795
|
-
args.push(createParamRef(paramNumber));
|
|
6923
|
+
args.push(bindParameter(unwrapParamIntent(arg), state));
|
|
6796
6924
|
}
|
|
6797
6925
|
}
|
|
6798
6926
|
if (decision.value !== void 0) {
|
|
6799
|
-
|
|
6800
|
-
state.parameters.push(decision.value);
|
|
6801
|
-
args.push(createParamRef(defaultParamNumber));
|
|
6927
|
+
args.push(bindParameter(unwrapParamIntent(decision.value), state));
|
|
6802
6928
|
}
|
|
6803
6929
|
return buildWindowFunction(funcName, args, decision, ctx);
|
|
6804
6930
|
}
|
|
@@ -6915,6 +7041,12 @@ init_ast_helpers();
|
|
|
6915
7041
|
// src/compiler.ts
|
|
6916
7042
|
init_assert_field();
|
|
6917
7043
|
init_ast_helpers();
|
|
7044
|
+
import { InvalidOperationError as InvalidOperationError2 } from "@dbsp/core";
|
|
7045
|
+
import {
|
|
7046
|
+
isParamIntent as isParamIntent6,
|
|
7047
|
+
NQL_SELECT_SCALAR_FUNCTION_ALLOWLIST,
|
|
7048
|
+
NQL_SELECT_WINDOW_FUNCTION_ALLOWLIST
|
|
7049
|
+
} from "@dbsp/types";
|
|
6918
7050
|
|
|
6919
7051
|
// src/pgsql-deparser.ts
|
|
6920
7052
|
function deparse(node) {
|
|
@@ -7972,6 +8104,7 @@ function deparseQuoted(ast) {
|
|
|
7972
8104
|
init_case_value();
|
|
7973
8105
|
init_custom();
|
|
7974
8106
|
init_expression();
|
|
8107
|
+
init_param_value();
|
|
7975
8108
|
init_window();
|
|
7976
8109
|
init_include();
|
|
7977
8110
|
init_shared();
|
|
@@ -7980,9 +8113,39 @@ init_types();
|
|
|
7980
8113
|
init_utils();
|
|
7981
8114
|
init_intent_to_decisions();
|
|
7982
8115
|
init_naming_plugin();
|
|
8116
|
+
init_param_intent();
|
|
7983
8117
|
init_param_ref();
|
|
7984
8118
|
init_subquery_emission();
|
|
8119
|
+
init_validate();
|
|
7985
8120
|
registerWhereDispatcherFactory(createWhereDispatcher);
|
|
8121
|
+
var UnhandledNqlSelectExpressionKindError = class extends Error {
|
|
8122
|
+
constructor(kind) {
|
|
8123
|
+
super(`Unhandled NQL SELECT expression intent kind: ${kind}`);
|
|
8124
|
+
this.kind = kind;
|
|
8125
|
+
this.name = "UnhandledNqlSelectExpressionKindError";
|
|
8126
|
+
}
|
|
8127
|
+
kind;
|
|
8128
|
+
code = "ERR_ADAPTER_UNHANDLED_NQL_SELECT_EXPRESSION_KIND";
|
|
8129
|
+
};
|
|
8130
|
+
var UnsupportedNqlSelectFunctionError = class extends Error {
|
|
8131
|
+
constructor(functionName) {
|
|
8132
|
+
super(`Unsupported function in SELECT context: ${functionName}()`);
|
|
8133
|
+
this.functionName = functionName;
|
|
8134
|
+
this.name = "UnsupportedNqlSelectFunctionError";
|
|
8135
|
+
}
|
|
8136
|
+
functionName;
|
|
8137
|
+
code = "ERR_ADAPTER_UNSUPPORTED_NQL_SELECT_FUNCTION";
|
|
8138
|
+
};
|
|
8139
|
+
function assertNqlSelectScalarFunctionAllowed(functionName) {
|
|
8140
|
+
if (!NQL_SELECT_SCALAR_FUNCTION_ALLOWLIST.has(functionName.toLowerCase())) {
|
|
8141
|
+
throw new UnsupportedNqlSelectFunctionError(functionName);
|
|
8142
|
+
}
|
|
8143
|
+
}
|
|
8144
|
+
function assertNqlSelectWindowFunctionAllowed(functionName) {
|
|
8145
|
+
if (!NQL_SELECT_WINDOW_FUNCTION_ALLOWLIST.has(functionName.toLowerCase())) {
|
|
8146
|
+
throw new UnsupportedNqlSelectFunctionError(functionName);
|
|
8147
|
+
}
|
|
8148
|
+
}
|
|
7986
8149
|
function mapToHandlerDecision(pd, rootTable, defaultPk, deriveFk) {
|
|
7987
8150
|
return {
|
|
7988
8151
|
type: pd.type,
|
|
@@ -8006,6 +8169,8 @@ function mapToHandlerDecision(pd, rootTable, defaultPk, deriveFk) {
|
|
|
8006
8169
|
strategy: pd.choice === "subquery" ? "json_agg" : pd.choice,
|
|
8007
8170
|
relation: pd.relation ?? pd.relationName,
|
|
8008
8171
|
relationName: pd.relationName,
|
|
8172
|
+
relationPath: pd.relationPath,
|
|
8173
|
+
hydrationPrefix: pd.hydrationPrefix,
|
|
8009
8174
|
relationType: pd.relationType,
|
|
8010
8175
|
foreignKey: pd.foreignKey,
|
|
8011
8176
|
parentKey: pd.parentKey,
|
|
@@ -8058,6 +8223,77 @@ function isPrecompiledJoinDecision(d) {
|
|
|
8058
8223
|
function isBatchValuesJoinDecision(d) {
|
|
8059
8224
|
return isPrecompiledJoinDecision(d) && d.batchValuesParams !== void 0;
|
|
8060
8225
|
}
|
|
8226
|
+
function getRelationIdentityPath(decision, rootTable) {
|
|
8227
|
+
if (decision.relationPath) return decision.relationPath;
|
|
8228
|
+
const relationName = decision.relationName ?? decision.relation;
|
|
8229
|
+
if (!relationName && !decision.targetTable) return void 0;
|
|
8230
|
+
const source = decision.sourceTable ?? rootTable;
|
|
8231
|
+
const target = decision.targetTable ?? "";
|
|
8232
|
+
const sourceColumn = decision.sourceColumn ?? decision.foreignKey ?? "";
|
|
8233
|
+
return `__legacy__:${source}:${relationName ?? target}:${sourceColumn}:${target}`;
|
|
8234
|
+
}
|
|
8235
|
+
function getParentRelationPath(relationPath) {
|
|
8236
|
+
if (!relationPath || relationPath.startsWith("__legacy__:")) return void 0;
|
|
8237
|
+
const lastDot = relationPath.lastIndexOf(".");
|
|
8238
|
+
return lastDot > 0 ? relationPath.slice(0, lastDot) : void 0;
|
|
8239
|
+
}
|
|
8240
|
+
function mergeColumnLists(current, next) {
|
|
8241
|
+
if (!current) return next ? [...next] : void 0;
|
|
8242
|
+
if (!next) return current;
|
|
8243
|
+
if (current.includes("*") || next.includes("*")) return ["*"];
|
|
8244
|
+
const merged = [...current];
|
|
8245
|
+
for (const column of next) {
|
|
8246
|
+
if (!merged.includes(column)) merged.push(column);
|
|
8247
|
+
}
|
|
8248
|
+
return merged;
|
|
8249
|
+
}
|
|
8250
|
+
function mergeDuplicateJoinIncludeDecisions(decisions, rootTable) {
|
|
8251
|
+
const merged = [];
|
|
8252
|
+
const seenByPath = /* @__PURE__ */ new Map();
|
|
8253
|
+
for (const decision of decisions) {
|
|
8254
|
+
const identityPath = decision.type === "includeStrategy" && decision.choice === "join" ? getRelationIdentityPath(decision, rootTable) : void 0;
|
|
8255
|
+
if (!identityPath) {
|
|
8256
|
+
merged.push(decision);
|
|
8257
|
+
continue;
|
|
8258
|
+
}
|
|
8259
|
+
const existing = seenByPath.get(identityPath);
|
|
8260
|
+
if (!existing) {
|
|
8261
|
+
const copy = {
|
|
8262
|
+
...decision,
|
|
8263
|
+
...decision.columns ? { columns: [...decision.columns] } : {},
|
|
8264
|
+
...decision.columnAliases ? { columnAliases: { ...decision.columnAliases } } : {},
|
|
8265
|
+
...decision.conditions ? { conditions: [...decision.conditions] } : {}
|
|
8266
|
+
};
|
|
8267
|
+
seenByPath.set(identityPath, copy);
|
|
8268
|
+
merged.push(copy);
|
|
8269
|
+
continue;
|
|
8270
|
+
}
|
|
8271
|
+
const existingJoinType = existing.joinType ?? "left";
|
|
8272
|
+
const nextJoinType = decision.joinType ?? "left";
|
|
8273
|
+
if (existingJoinType !== nextJoinType) {
|
|
8274
|
+
throw new InvalidOperationError2(
|
|
8275
|
+
"include",
|
|
8276
|
+
`Conflicting join options for relation path '${identityPath}'. Already registered as ${existingJoinType}, got ${nextJoinType}.`
|
|
8277
|
+
);
|
|
8278
|
+
}
|
|
8279
|
+
const mutable = existing;
|
|
8280
|
+
const columns = mergeColumnLists(existing.columns, decision.columns);
|
|
8281
|
+
if (columns) mutable.columns = columns;
|
|
8282
|
+
if (decision.columnAliases) {
|
|
8283
|
+
mutable.columnAliases = {
|
|
8284
|
+
...decision.columnAliases,
|
|
8285
|
+
...existing.columnAliases ?? {}
|
|
8286
|
+
};
|
|
8287
|
+
}
|
|
8288
|
+
if (decision.conditions && decision.conditions.length > 0) {
|
|
8289
|
+
mutable.conditions = [
|
|
8290
|
+
...existing.conditions ?? [],
|
|
8291
|
+
...decision.conditions
|
|
8292
|
+
];
|
|
8293
|
+
}
|
|
8294
|
+
}
|
|
8295
|
+
return merged;
|
|
8296
|
+
}
|
|
8061
8297
|
function renumberParamRefsInAst(node, offset) {
|
|
8062
8298
|
if (offset === 0) return node;
|
|
8063
8299
|
return renumberNode(node, offset);
|
|
@@ -8114,9 +8350,9 @@ var PlanCompiler = class _PlanCompiler {
|
|
|
8114
8350
|
/** CTE nodes from include handlers (e.g., CTE strategy) */
|
|
8115
8351
|
pendingCtes = [];
|
|
8116
8352
|
/**
|
|
8117
|
-
* Maps
|
|
8118
|
-
* Populated as join decisions are compiled so later hops can find
|
|
8119
|
-
*
|
|
8353
|
+
* Maps relation-dotted include path → JOIN alias for multi-hop FK resolution.
|
|
8354
|
+
* Populated as join decisions are compiled so later hops can find the
|
|
8355
|
+
* correct source alias (e.g., 'callee.file' reads parent path 'callee').
|
|
8120
8356
|
*/
|
|
8121
8357
|
joinAliasMap = /* @__PURE__ */ new Map();
|
|
8122
8358
|
/**
|
|
@@ -8143,6 +8379,13 @@ var PlanCompiler = class _PlanCompiler {
|
|
|
8143
8379
|
...this.model != null && { model: this.model }
|
|
8144
8380
|
};
|
|
8145
8381
|
}
|
|
8382
|
+
findAliasForLegacySourceTable(sourceTable) {
|
|
8383
|
+
let alias;
|
|
8384
|
+
for (const entry of this.joinAliasMap.values()) {
|
|
8385
|
+
if (entry.targetTable === sourceTable) alias = entry.alias;
|
|
8386
|
+
}
|
|
8387
|
+
return alias;
|
|
8388
|
+
}
|
|
8146
8389
|
/**
|
|
8147
8390
|
* Dispatch a PlanDecision through the unified WHERE handler system.
|
|
8148
8391
|
* Bridges PlanCompiler's state to handler types, calls dispatcher, syncs back.
|
|
@@ -8293,7 +8536,21 @@ var PlanCompiler = class _PlanCompiler {
|
|
|
8293
8536
|
const combined = condNodes.length === 1 ? condNodes[0] : andExpr(...condNodes);
|
|
8294
8537
|
handlerDecision._compiledFilterWhere = combined;
|
|
8295
8538
|
}
|
|
8296
|
-
const
|
|
8539
|
+
const relationIdentityPath = decision.choice === "join" ? getRelationIdentityPath(decision, plan.rootTable) : void 0;
|
|
8540
|
+
const requestedJoinType = decision.joinType ?? "left";
|
|
8541
|
+
const existingJoin = relationIdentityPath ? this.joinAliasMap.get(relationIdentityPath) : void 0;
|
|
8542
|
+
if (existingJoin) {
|
|
8543
|
+
if (existingJoin.joinType !== requestedJoinType) {
|
|
8544
|
+
throw new InvalidOperationError2(
|
|
8545
|
+
"include",
|
|
8546
|
+
`Conflicting join options for relation path '${relationIdentityPath}'. Already registered as ${existingJoin.joinType}, got ${requestedJoinType}.`
|
|
8547
|
+
);
|
|
8548
|
+
}
|
|
8549
|
+
return {};
|
|
8550
|
+
}
|
|
8551
|
+
const parentRelationPath = getParentRelationPath(relationIdentityPath);
|
|
8552
|
+
const parentAlias = parentRelationPath ? this.joinAliasMap.get(parentRelationPath)?.alias : void 0;
|
|
8553
|
+
const sourceAlias = parentAlias ?? (decision.sourceTable && decision.sourceTable !== plan.rootTable ? this.findAliasForLegacySourceTable(decision.sourceTable) ?? decision.sourceTable : plan.rootTable);
|
|
8297
8554
|
const ctx = {
|
|
8298
8555
|
...this.handlerCtx(),
|
|
8299
8556
|
currentAlias: sourceAlias
|
|
@@ -8314,6 +8571,7 @@ var PlanCompiler = class _PlanCompiler {
|
|
|
8314
8571
|
while (this.usedJoinAliases.has(alias)) {
|
|
8315
8572
|
alias = `${candidateAlias}_${counter++}`;
|
|
8316
8573
|
}
|
|
8574
|
+
validateIdentifier(alias, "alias");
|
|
8317
8575
|
this.usedJoinAliases.add(alias);
|
|
8318
8576
|
finalJoinAlias = alias;
|
|
8319
8577
|
if (alias !== candidateAlias) {
|
|
@@ -8323,11 +8581,12 @@ var PlanCompiler = class _PlanCompiler {
|
|
|
8323
8581
|
}
|
|
8324
8582
|
const result = handler.compile(handlerDecision, ctx, handlerState);
|
|
8325
8583
|
this.state.paramIndex = handlerState.paramIndex;
|
|
8326
|
-
if (decision.choice === "join" &&
|
|
8327
|
-
this.joinAliasMap.set(
|
|
8328
|
-
|
|
8329
|
-
|
|
8330
|
-
|
|
8584
|
+
if (decision.choice === "join" && relationIdentityPath && finalJoinAlias) {
|
|
8585
|
+
this.joinAliasMap.set(relationIdentityPath, {
|
|
8586
|
+
alias: finalJoinAlias,
|
|
8587
|
+
joinType: requestedJoinType,
|
|
8588
|
+
...decision.targetTable && { targetTable: decision.targetTable }
|
|
8589
|
+
});
|
|
8331
8590
|
}
|
|
8332
8591
|
const out = {};
|
|
8333
8592
|
if (result.targets) out.targets = result.targets;
|
|
@@ -8353,6 +8612,7 @@ var PlanCompiler = class _PlanCompiler {
|
|
|
8353
8612
|
this.rawJoins = [];
|
|
8354
8613
|
this.pendingCtes = [];
|
|
8355
8614
|
this.joinAliasMap = /* @__PURE__ */ new Map();
|
|
8615
|
+
this.usedJoinAliases = /* @__PURE__ */ new Set();
|
|
8356
8616
|
const queryType = this.detectQueryType(plan.decisions);
|
|
8357
8617
|
let ast;
|
|
8358
8618
|
switch (queryType) {
|
|
@@ -8402,7 +8662,9 @@ var PlanCompiler = class _PlanCompiler {
|
|
|
8402
8662
|
defaultPkColumnName: this.defaultPk,
|
|
8403
8663
|
deriveFkColumnName: this.deriveFk,
|
|
8404
8664
|
...plan.schema ?? this.schema ? { schema: plan.schema ?? this.schema } : {},
|
|
8405
|
-
...this.model != null && { model: this.model }
|
|
8665
|
+
...this.model != null && { model: this.model },
|
|
8666
|
+
compileSubquery: (query, paramOffset) => this.compileExpressionSubquery(query, paramOffset),
|
|
8667
|
+
compileNqlSelectExpression: (value, handlerCtx, state) => this.compileNqlFunctionArg(value, handlerCtx, state)
|
|
8406
8668
|
};
|
|
8407
8669
|
}
|
|
8408
8670
|
/** Build a fresh HandlerCompilerState sharing the current parameter array. */
|
|
@@ -8415,6 +8677,247 @@ var PlanCompiler = class _PlanCompiler {
|
|
|
8415
8677
|
joins: []
|
|
8416
8678
|
};
|
|
8417
8679
|
}
|
|
8680
|
+
compileExpressionSubquery(query, paramOffset) {
|
|
8681
|
+
const innerCompiler = new _PlanCompiler({
|
|
8682
|
+
naming: this.naming,
|
|
8683
|
+
...this.schema !== void 0 && {
|
|
8684
|
+
schema: this.schema
|
|
8685
|
+
},
|
|
8686
|
+
defaultPkColumnName: this.defaultPk,
|
|
8687
|
+
deriveFkColumnName: this.deriveFk
|
|
8688
|
+
});
|
|
8689
|
+
const innerPlan = {
|
|
8690
|
+
rootTable: query.from,
|
|
8691
|
+
decisions: intentToDecisions(query, query.from)
|
|
8692
|
+
};
|
|
8693
|
+
const innerResult = innerCompiler.compile(innerPlan);
|
|
8694
|
+
const renumbered = renumberParamRefsInAst(innerResult.ast, paramOffset);
|
|
8695
|
+
return { ast: renumbered, parameters: innerResult.parameters };
|
|
8696
|
+
}
|
|
8697
|
+
compileGenericNqlFunction(functionName, args, ctx, state) {
|
|
8698
|
+
assertNqlSelectScalarFunctionAllowed(functionName);
|
|
8699
|
+
validateIdentifier(functionName, "function");
|
|
8700
|
+
const argNodes = args.map(
|
|
8701
|
+
(arg) => this.compileNqlFunctionArg(arg, ctx, state)
|
|
8702
|
+
);
|
|
8703
|
+
return funcCall(functionName, argNodes);
|
|
8704
|
+
}
|
|
8705
|
+
compileNqlFunctionArg(arg, ctx, state) {
|
|
8706
|
+
if (typeof arg === "string") {
|
|
8707
|
+
return buildColumnRef(arg, ctx);
|
|
8708
|
+
}
|
|
8709
|
+
if (typeof arg === "object" && arg !== null) {
|
|
8710
|
+
const record = arg;
|
|
8711
|
+
if (typeof record.$ref === "string") {
|
|
8712
|
+
return buildColumnRef(record.$ref, ctx);
|
|
8713
|
+
}
|
|
8714
|
+
if (typeof record.kind !== "string") {
|
|
8715
|
+
const legacyKind = typeof record.$op === "string" ? `$op:${record.$op}` : typeof record.$fn === "string" ? `$fn:${record.$fn}` : "object";
|
|
8716
|
+
throw new UnhandledNqlSelectExpressionKindError(legacyKind);
|
|
8717
|
+
}
|
|
8718
|
+
switch (record.kind) {
|
|
8719
|
+
case "column":
|
|
8720
|
+
if (typeof record.column !== "string") {
|
|
8721
|
+
throw new Error("NQL column expression requires a column name");
|
|
8722
|
+
}
|
|
8723
|
+
return buildColumnRef(record.column, ctx);
|
|
8724
|
+
case "columnAlias":
|
|
8725
|
+
if (typeof record.column !== "string") {
|
|
8726
|
+
throw new Error(
|
|
8727
|
+
"NQL columnAlias expression requires a column name"
|
|
8728
|
+
);
|
|
8729
|
+
}
|
|
8730
|
+
return buildColumnRef(record.column, ctx);
|
|
8731
|
+
case "relationColumn": {
|
|
8732
|
+
const relation = record.relation;
|
|
8733
|
+
const column = record.column;
|
|
8734
|
+
if (typeof relation !== "string" || typeof column !== "string") {
|
|
8735
|
+
throw new Error(
|
|
8736
|
+
"NQL relationColumn expression requires relation and column"
|
|
8737
|
+
);
|
|
8738
|
+
}
|
|
8739
|
+
return buildColumnRef(`${relation}.${column}`, ctx);
|
|
8740
|
+
}
|
|
8741
|
+
case "param":
|
|
8742
|
+
if (!("value" in record)) {
|
|
8743
|
+
throw new Error("NQL param expression requires a value");
|
|
8744
|
+
}
|
|
8745
|
+
return bindParameter(record.value, state);
|
|
8746
|
+
case "literal":
|
|
8747
|
+
if (!("value" in record)) {
|
|
8748
|
+
throw new Error("NQL literal expression requires a value");
|
|
8749
|
+
}
|
|
8750
|
+
return compileValue(record.value, state);
|
|
8751
|
+
case "function": {
|
|
8752
|
+
const nestedName = record.name;
|
|
8753
|
+
const nestedArgs = record.args;
|
|
8754
|
+
if (typeof nestedName !== "string") {
|
|
8755
|
+
throw new Error("NQL function argument requires a function name");
|
|
8756
|
+
}
|
|
8757
|
+
return this.compileGenericNqlFunction(
|
|
8758
|
+
nestedName,
|
|
8759
|
+
Array.isArray(nestedArgs) ? nestedArgs : [],
|
|
8760
|
+
ctx,
|
|
8761
|
+
state
|
|
8762
|
+
);
|
|
8763
|
+
}
|
|
8764
|
+
case "coalesce": {
|
|
8765
|
+
const handler = getExpressionHandler("coalesce");
|
|
8766
|
+
return handler.compile(
|
|
8767
|
+
{
|
|
8768
|
+
type: "coalesce",
|
|
8769
|
+
args: Array.isArray(record.fields) ? record.fields : []
|
|
8770
|
+
},
|
|
8771
|
+
ctx,
|
|
8772
|
+
state
|
|
8773
|
+
);
|
|
8774
|
+
}
|
|
8775
|
+
case "aggregate": {
|
|
8776
|
+
const fn4 = record.function;
|
|
8777
|
+
if (typeof fn4 !== "string") {
|
|
8778
|
+
throw new Error(
|
|
8779
|
+
"NQL aggregate expression requires a function name"
|
|
8780
|
+
);
|
|
8781
|
+
}
|
|
8782
|
+
const aggregateArgs = [];
|
|
8783
|
+
if (record.field === "*") {
|
|
8784
|
+
aggregateArgs.push({ kind: "star" });
|
|
8785
|
+
} else if (typeof record.field === "string") {
|
|
8786
|
+
aggregateArgs.push(record.field);
|
|
8787
|
+
}
|
|
8788
|
+
if (Array.isArray(record.extraArgs)) {
|
|
8789
|
+
aggregateArgs.push(...record.extraArgs);
|
|
8790
|
+
}
|
|
8791
|
+
return this.compileGenericNqlFunction(fn4, aggregateArgs, ctx, state);
|
|
8792
|
+
}
|
|
8793
|
+
case "arithmetic": {
|
|
8794
|
+
const operator = record.operator;
|
|
8795
|
+
if (typeof operator !== "string") {
|
|
8796
|
+
throw new Error("NQL arithmetic expression requires an operator");
|
|
8797
|
+
}
|
|
8798
|
+
if (!("left" in record) || !("right" in record)) {
|
|
8799
|
+
throw new Error(
|
|
8800
|
+
"NQL arithmetic expression requires left and right operands"
|
|
8801
|
+
);
|
|
8802
|
+
}
|
|
8803
|
+
const handler = getExpressionHandler("arithmetic");
|
|
8804
|
+
return handler.compile(
|
|
8805
|
+
{
|
|
8806
|
+
type: "arithmetic",
|
|
8807
|
+
operator,
|
|
8808
|
+
args: [record.left, record.right]
|
|
8809
|
+
},
|
|
8810
|
+
ctx,
|
|
8811
|
+
state
|
|
8812
|
+
);
|
|
8813
|
+
}
|
|
8814
|
+
case "case":
|
|
8815
|
+
return this.compileNqlCaseExpressionArg(record, ctx, state);
|
|
8816
|
+
case "jsonExtract": {
|
|
8817
|
+
const handler = getExpressionHandler("jsonExtract");
|
|
8818
|
+
return handler.compile(
|
|
8819
|
+
{
|
|
8820
|
+
type: "jsonExtract",
|
|
8821
|
+
column: record.field,
|
|
8822
|
+
args: Array.isArray(record.path) ? record.path : [],
|
|
8823
|
+
jsonMode: record.mode
|
|
8824
|
+
},
|
|
8825
|
+
ctx,
|
|
8826
|
+
state
|
|
8827
|
+
);
|
|
8828
|
+
}
|
|
8829
|
+
case "jsonPathExtract": {
|
|
8830
|
+
const handler = getExpressionHandler("jsonPathExtract");
|
|
8831
|
+
return handler.compile(
|
|
8832
|
+
{
|
|
8833
|
+
type: "jsonPathExtract",
|
|
8834
|
+
column: record.field,
|
|
8835
|
+
args: Array.isArray(record.path) ? [record.path] : typeof record.path === "string" ? [record.path] : [],
|
|
8836
|
+
jsonMode: record.mode
|
|
8837
|
+
},
|
|
8838
|
+
ctx,
|
|
8839
|
+
state
|
|
8840
|
+
);
|
|
8841
|
+
}
|
|
8842
|
+
case "window":
|
|
8843
|
+
return genericWindowHandler.compile(
|
|
8844
|
+
{
|
|
8845
|
+
type: "window",
|
|
8846
|
+
function: record.function,
|
|
8847
|
+
column: record.field,
|
|
8848
|
+
args: typeof record.offset === "number" ? [record.offset] : void 0,
|
|
8849
|
+
value: record.defaultValue,
|
|
8850
|
+
partition: record.over?.partitionBy,
|
|
8851
|
+
orderBy: record.over?.orderBy?.map((item) => ({
|
|
8852
|
+
column: item.field,
|
|
8853
|
+
direction: item.direction?.toUpperCase()
|
|
8854
|
+
}))
|
|
8855
|
+
},
|
|
8856
|
+
ctx,
|
|
8857
|
+
state
|
|
8858
|
+
);
|
|
8859
|
+
case "customOp":
|
|
8860
|
+
case "customFn":
|
|
8861
|
+
case "ref":
|
|
8862
|
+
case "cast":
|
|
8863
|
+
case "unary":
|
|
8864
|
+
case "namedArg":
|
|
8865
|
+
case "star":
|
|
8866
|
+
case "array":
|
|
8867
|
+
case "subquery":
|
|
8868
|
+
return compileExpressionIntent(
|
|
8869
|
+
record,
|
|
8870
|
+
ctx,
|
|
8871
|
+
state
|
|
8872
|
+
);
|
|
8873
|
+
default:
|
|
8874
|
+
throw new UnhandledNqlSelectExpressionKindError(record.kind);
|
|
8875
|
+
}
|
|
8876
|
+
}
|
|
8877
|
+
return compileValue(arg, state);
|
|
8878
|
+
}
|
|
8879
|
+
compileNqlCaseExpressionArg(expr, ctx, state) {
|
|
8880
|
+
const whenClauses = expr.when;
|
|
8881
|
+
if (!Array.isArray(whenClauses) || whenClauses.length === 0) {
|
|
8882
|
+
throw new Error("NQL CASE expression requires at least one WHEN clause");
|
|
8883
|
+
}
|
|
8884
|
+
const dispatcher = createWhereDispatcher();
|
|
8885
|
+
const args = whenClauses.map((branch) => {
|
|
8886
|
+
const condition = branch.condition;
|
|
8887
|
+
const result = branch.result;
|
|
8888
|
+
const conditionDecision = convertWhereCondition(
|
|
8889
|
+
condition,
|
|
8890
|
+
ctx.rootTable
|
|
8891
|
+
);
|
|
8892
|
+
if (!conditionDecision) {
|
|
8893
|
+
throw new Error("NQL CASE WHEN condition could not be compiled");
|
|
8894
|
+
}
|
|
8895
|
+
const whenNode = dispatcher(
|
|
8896
|
+
mapToHandlerDecision(
|
|
8897
|
+
conditionDecision,
|
|
8898
|
+
ctx.rootTable,
|
|
8899
|
+
this.defaultPk,
|
|
8900
|
+
this.deriveFk
|
|
8901
|
+
),
|
|
8902
|
+
ctx,
|
|
8903
|
+
state
|
|
8904
|
+
);
|
|
8905
|
+
const thenNode = this.compileNqlFunctionArg(result, ctx, state);
|
|
8906
|
+
return {
|
|
8907
|
+
CaseWhen: {
|
|
8908
|
+
expr: whenNode,
|
|
8909
|
+
result: thenNode
|
|
8910
|
+
}
|
|
8911
|
+
};
|
|
8912
|
+
});
|
|
8913
|
+
const defresult = expr.else !== void 0 ? this.compileNqlFunctionArg(expr.else, ctx, state) : void 0;
|
|
8914
|
+
return {
|
|
8915
|
+
CaseExpr: {
|
|
8916
|
+
args,
|
|
8917
|
+
...defresult !== void 0 ? { defresult } : {}
|
|
8918
|
+
}
|
|
8919
|
+
};
|
|
8920
|
+
}
|
|
8418
8921
|
/**
|
|
8419
8922
|
* Compile a SELECT-list target via expression handler.
|
|
8420
8923
|
* Wraps the node in a ResTarget and pushes it onto targetList.
|
|
@@ -8468,6 +8971,41 @@ var PlanCompiler = class _PlanCompiler {
|
|
|
8468
8971
|
});
|
|
8469
8972
|
break;
|
|
8470
8973
|
}
|
|
8974
|
+
case "selectNqlFunction": {
|
|
8975
|
+
ensureExpressionHandlersRegistered();
|
|
8976
|
+
const funcType = decision.function;
|
|
8977
|
+
if (!funcType) break;
|
|
8978
|
+
assertNqlSelectScalarFunctionAllowed(funcType);
|
|
8979
|
+
const ctx = this.createHandlerContext(
|
|
8980
|
+
plan,
|
|
8981
|
+
decision.table ?? plan.rootTable
|
|
8982
|
+
);
|
|
8983
|
+
const state = this.createHandlerState();
|
|
8984
|
+
const safeHandler = getNqlSafeExpressionHandler(funcType);
|
|
8985
|
+
const node = safeHandler ? safeHandler.compile(
|
|
8986
|
+
mapToHandlerDecision(
|
|
8987
|
+
decision,
|
|
8988
|
+
plan.rootTable,
|
|
8989
|
+
this.defaultPk,
|
|
8990
|
+
this.deriveFk
|
|
8991
|
+
),
|
|
8992
|
+
ctx,
|
|
8993
|
+
state
|
|
8994
|
+
) : this.compileGenericNqlFunction(
|
|
8995
|
+
funcType,
|
|
8996
|
+
decision.args ?? [],
|
|
8997
|
+
ctx,
|
|
8998
|
+
state
|
|
8999
|
+
);
|
|
9000
|
+
this.state.paramIndex = state.paramIndex;
|
|
9001
|
+
targetList.push({
|
|
9002
|
+
ResTarget: {
|
|
9003
|
+
val: node,
|
|
9004
|
+
...decision.alias ? { name: this.naming.toDatabase(decision.alias) } : {}
|
|
9005
|
+
}
|
|
9006
|
+
});
|
|
9007
|
+
break;
|
|
9008
|
+
}
|
|
8471
9009
|
case "selectExpression": {
|
|
8472
9010
|
if (decision.expressionType === "case") {
|
|
8473
9011
|
const caseNode = this.compileCaseExpression(decision);
|
|
@@ -8564,6 +9102,7 @@ var PlanCompiler = class _PlanCompiler {
|
|
|
8564
9102
|
case "selectWindow": {
|
|
8565
9103
|
const winFuncName = decision.function;
|
|
8566
9104
|
if (!winFuncName) break;
|
|
9105
|
+
assertNqlSelectWindowFunctionAllowed(winFuncName);
|
|
8567
9106
|
const winHandler = genericWindowHandler;
|
|
8568
9107
|
const ctx = this.createHandlerContext(
|
|
8569
9108
|
plan,
|
|
@@ -8726,7 +9265,11 @@ var PlanCompiler = class _PlanCompiler {
|
|
|
8726
9265
|
if (decision.choice !== "join" || !decision.conditions || decision.conditions.length === 0) {
|
|
8727
9266
|
return where;
|
|
8728
9267
|
}
|
|
8729
|
-
const
|
|
9268
|
+
const relationIdentityPath = getRelationIdentityPath(
|
|
9269
|
+
decision,
|
|
9270
|
+
this.currentRootTable
|
|
9271
|
+
);
|
|
9272
|
+
const joinAlias = (relationIdentityPath ? this.joinAliasMap.get(relationIdentityPath)?.alias : void 0) ?? decision.relationName;
|
|
8730
9273
|
for (const cond of decision.conditions) {
|
|
8731
9274
|
const condExpr = this.dispatchWhere(
|
|
8732
9275
|
cond,
|
|
@@ -8853,6 +9396,10 @@ var PlanCompiler = class _PlanCompiler {
|
|
|
8853
9396
|
return selectStmt(options);
|
|
8854
9397
|
}
|
|
8855
9398
|
compileSelect(plan) {
|
|
9399
|
+
const decisions = mergeDuplicateJoinIncludeDecisions(
|
|
9400
|
+
plan.decisions,
|
|
9401
|
+
plan.rootTable
|
|
9402
|
+
);
|
|
8856
9403
|
const targetList = [];
|
|
8857
9404
|
const from = this.compileFromClause(plan);
|
|
8858
9405
|
let where;
|
|
@@ -8862,10 +9409,11 @@ var PlanCompiler = class _PlanCompiler {
|
|
|
8862
9409
|
let limit;
|
|
8863
9410
|
let offset;
|
|
8864
9411
|
let distinct = false;
|
|
8865
|
-
for (const decision of
|
|
9412
|
+
for (const decision of decisions) {
|
|
8866
9413
|
switch (decision.type) {
|
|
8867
9414
|
case "select":
|
|
8868
9415
|
case "selectFunction":
|
|
9416
|
+
case "selectNqlFunction":
|
|
8869
9417
|
case "selectExpression":
|
|
8870
9418
|
case "selectRelationColumn":
|
|
8871
9419
|
case "selectPseudoColumn":
|
|
@@ -8903,6 +9451,10 @@ var PlanCompiler = class _PlanCompiler {
|
|
|
8903
9451
|
case "limit":
|
|
8904
9452
|
if (typeof decision.limit === "number") {
|
|
8905
9453
|
limit = integerNode(decision.limit);
|
|
9454
|
+
} else if (isParamIntent6(decision.limit)) {
|
|
9455
|
+
this.state.parameters.push(unwrapParamIntent(decision.limit));
|
|
9456
|
+
this.state.paramIndex++;
|
|
9457
|
+
limit = createParamRef(this.state.paramIndex);
|
|
8906
9458
|
} else if (decision.limit?.paramIndex !== void 0) {
|
|
8907
9459
|
limit = createParamRef(decision.limit.paramIndex);
|
|
8908
9460
|
this.state.parameters.push(void 0);
|
|
@@ -8911,6 +9463,10 @@ var PlanCompiler = class _PlanCompiler {
|
|
|
8911
9463
|
case "offset":
|
|
8912
9464
|
if (typeof decision.offset === "number") {
|
|
8913
9465
|
offset = integerNode(decision.offset);
|
|
9466
|
+
} else if (isParamIntent6(decision.offset)) {
|
|
9467
|
+
this.state.parameters.push(unwrapParamIntent(decision.offset));
|
|
9468
|
+
this.state.paramIndex++;
|
|
9469
|
+
offset = createParamRef(this.state.paramIndex);
|
|
8914
9470
|
} else if (decision.offset?.paramIndex !== void 0) {
|
|
8915
9471
|
offset = createParamRef(decision.offset.paramIndex);
|
|
8916
9472
|
this.state.parameters.push(void 0);
|
|
@@ -12520,8 +13076,10 @@ function matchGlob(pattern, value) {
|
|
|
12520
13076
|
init_ast_helpers();
|
|
12521
13077
|
init_compiler_utils();
|
|
12522
13078
|
init_handlers();
|
|
13079
|
+
init_param_intent();
|
|
12523
13080
|
init_param_ref();
|
|
12524
13081
|
import { isSqlRaw } from "@dbsp/core";
|
|
13082
|
+
import { isParamIntent as isParamIntent7 } from "@dbsp/types";
|
|
12525
13083
|
function buildReturningList(columns, tableRef, ctx) {
|
|
12526
13084
|
if (!columns || columns.length === 0) return void 0;
|
|
12527
13085
|
const { naming } = ctx;
|
|
@@ -12779,7 +13337,7 @@ function compileInsertFrom(config, ctx, state) {
|
|
|
12779
13337
|
}
|
|
12780
13338
|
let limitCount;
|
|
12781
13339
|
if (config.limit !== void 0) {
|
|
12782
|
-
limitCount =
|
|
13340
|
+
limitCount = limitToNode(config.limit, state);
|
|
12783
13341
|
}
|
|
12784
13342
|
const sourceRelation = {
|
|
12785
13343
|
relname: dbSourceTable,
|
|
@@ -12854,7 +13412,7 @@ function compileUpsertFrom(config, ctx, state) {
|
|
|
12854
13412
|
}
|
|
12855
13413
|
let limitCount;
|
|
12856
13414
|
if (config.limit !== void 0) {
|
|
12857
|
-
limitCount =
|
|
13415
|
+
limitCount = limitToNode(config.limit, state);
|
|
12858
13416
|
}
|
|
12859
13417
|
const sourceRelation = {
|
|
12860
13418
|
relname: dbSourceTable,
|
|
@@ -12928,11 +13486,22 @@ var RANGE_TYPES = /* @__PURE__ */ new Set([
|
|
|
12928
13486
|
"int8range",
|
|
12929
13487
|
"numrange"
|
|
12930
13488
|
]);
|
|
12931
|
-
function valueToNode(value, state, dbType) {
|
|
12932
|
-
|
|
13489
|
+
function valueToNode(value, state, dbType, forceParam = false) {
|
|
13490
|
+
const isParam = isParamIntent7(value);
|
|
13491
|
+
const boundValue = unwrapParamIntent(value);
|
|
13492
|
+
if (boundValue === null || boundValue === void 0) {
|
|
13493
|
+
if (forceParam || isParam) {
|
|
13494
|
+
state.parameters.push(boundValue);
|
|
13495
|
+
state.paramIndex++;
|
|
13496
|
+
return dbType && RANGE_TYPES.has(dbType) ? createTypeCastParamRef(state.paramIndex, dbType) : {
|
|
13497
|
+
ParamRef: {
|
|
13498
|
+
number: state.paramIndex
|
|
13499
|
+
}
|
|
13500
|
+
};
|
|
13501
|
+
}
|
|
12933
13502
|
return { A_Const: { isnull: true } };
|
|
12934
13503
|
}
|
|
12935
|
-
state.parameters.push(
|
|
13504
|
+
state.parameters.push(boundValue);
|
|
12936
13505
|
state.paramIndex++;
|
|
12937
13506
|
if (dbType && RANGE_TYPES.has(dbType)) {
|
|
12938
13507
|
return createTypeCastParamRef(state.paramIndex, dbType);
|
|
@@ -12943,6 +13512,18 @@ function valueToNode(value, state, dbType) {
|
|
|
12943
13512
|
}
|
|
12944
13513
|
};
|
|
12945
13514
|
}
|
|
13515
|
+
function limitToNode(limit, state) {
|
|
13516
|
+
if (isParamIntent7(limit)) {
|
|
13517
|
+
state.parameters.push(unwrapParamIntent(limit));
|
|
13518
|
+
state.paramIndex++;
|
|
13519
|
+
return {
|
|
13520
|
+
ParamRef: {
|
|
13521
|
+
number: state.paramIndex
|
|
13522
|
+
}
|
|
13523
|
+
};
|
|
13524
|
+
}
|
|
13525
|
+
return { A_Const: { ival: { ival: limit } } };
|
|
13526
|
+
}
|
|
12946
13527
|
function compileMutation(decision, ctx, state) {
|
|
12947
13528
|
const type = decision.type;
|
|
12948
13529
|
const table = decision.table ?? ctx.rootTable;
|
|
@@ -12982,6 +13563,7 @@ function compileMutation(decision, ctx, state) {
|
|
|
12982
13563
|
init_ast_helpers();
|
|
12983
13564
|
init_compiler_utils();
|
|
12984
13565
|
init_handlers();
|
|
13566
|
+
init_param_intent();
|
|
12985
13567
|
init_param_ref();
|
|
12986
13568
|
function buildOnConflictClause(config, ctx, state) {
|
|
12987
13569
|
const naming = ctx.naming;
|
|
@@ -13141,7 +13723,7 @@ function compileUnnestUpsert(config, ctx, state) {
|
|
|
13141
13723
|
}
|
|
13142
13724
|
function valueToParam(state, value) {
|
|
13143
13725
|
if (value !== void 0) {
|
|
13144
|
-
state.parameters.push(value);
|
|
13726
|
+
state.parameters.push(unwrapParamIntent(value));
|
|
13145
13727
|
}
|
|
13146
13728
|
state.paramIndex++;
|
|
13147
13729
|
return {
|
|
@@ -13382,7 +13964,7 @@ function compileSubqueryIncludeManyToMany(info, parentIds, schemaName, state, de
|
|
|
13382
13964
|
// src/adapter-compiler-mutations.ts
|
|
13383
13965
|
init_compile_where();
|
|
13384
13966
|
init_compiler_utils();
|
|
13385
|
-
import { InvalidOperationError as
|
|
13967
|
+
import { InvalidOperationError as InvalidOperationError3, isSqlRaw as isSqlRaw2 } from "@dbsp/core";
|
|
13386
13968
|
init_handlers();
|
|
13387
13969
|
function whereIntentAsDecision(where) {
|
|
13388
13970
|
return where;
|
|
@@ -13460,9 +14042,8 @@ function compileInsert2(intent, options, deps) {
|
|
|
13460
14042
|
const state = createCompilerState();
|
|
13461
14043
|
const firstRow = intent.values?.[0] ?? {};
|
|
13462
14044
|
const columns = Object.keys(firstRow);
|
|
13463
|
-
const
|
|
13464
|
-
|
|
13465
|
-
);
|
|
14045
|
+
const rows = intent.values ?? [];
|
|
14046
|
+
const values = rows.map((row) => columns.map((col) => row[col]));
|
|
13466
14047
|
const columnTypes = getColumnTypes(intent.table, columns, deps);
|
|
13467
14048
|
const config = {
|
|
13468
14049
|
table: intent.table,
|
|
@@ -13473,7 +14054,7 @@ function compileInsert2(intent, options, deps) {
|
|
|
13473
14054
|
};
|
|
13474
14055
|
const maxBatchSize = options?.maxBatchSize;
|
|
13475
14056
|
if (maxBatchSize !== void 0 && values.length > maxBatchSize) {
|
|
13476
|
-
throw new
|
|
14057
|
+
throw new InvalidOperationError3(
|
|
13477
14058
|
"insert",
|
|
13478
14059
|
`Batch size ${values.length} exceeds maxBatchSize ${maxBatchSize}`
|
|
13479
14060
|
);
|
|
@@ -13549,7 +14130,7 @@ function compileBatchUpdate(intent, _options, deps) {
|
|
|
13549
14130
|
};
|
|
13550
14131
|
const state = createCompilerState();
|
|
13551
14132
|
if (intent.updates.length === 0) {
|
|
13552
|
-
throw new
|
|
14133
|
+
throw new InvalidOperationError3(
|
|
13553
14134
|
"update",
|
|
13554
14135
|
"batchSet requires at least one row"
|
|
13555
14136
|
);
|
|
@@ -13558,7 +14139,7 @@ function compileBatchUpdate(intent, _options, deps) {
|
|
|
13558
14139
|
const matchColumns = [...intent.matchColumns];
|
|
13559
14140
|
for (const mc of matchColumns) {
|
|
13560
14141
|
if (!allColumns.includes(mc)) {
|
|
13561
|
-
throw new
|
|
14142
|
+
throw new InvalidOperationError3(
|
|
13562
14143
|
"update",
|
|
13563
14144
|
`Match column "${mc}" not found in update data. Each row must include the match column(s).`
|
|
13564
14145
|
);
|
|
@@ -13581,7 +14162,13 @@ function compileBatchUpdate(intent, _options, deps) {
|
|
|
13581
14162
|
naming: deps.naming,
|
|
13582
14163
|
...schemaName !== void 0 && { schemaName },
|
|
13583
14164
|
...deps.model !== void 0 && { model: deps.model },
|
|
13584
|
-
compileSubquery: (sqIntent, paramOffset) => buildSubqueryFromIntent(
|
|
14165
|
+
compileSubquery: (sqIntent, paramOffset) => buildSubqueryFromIntent(
|
|
14166
|
+
sqIntent,
|
|
14167
|
+
paramOffset,
|
|
14168
|
+
deps.naming,
|
|
14169
|
+
schemaName,
|
|
14170
|
+
"rawExists"
|
|
14171
|
+
)
|
|
13585
14172
|
};
|
|
13586
14173
|
whereGuard = compileWhereIntent(intent.where, whereCtx);
|
|
13587
14174
|
}
|
|
@@ -13685,7 +14272,7 @@ function compileUpsert2(intent, options, deps) {
|
|
|
13685
14272
|
};
|
|
13686
14273
|
const maxBatchSize = options?.maxBatchSize;
|
|
13687
14274
|
if (maxBatchSize !== void 0 && values.length > maxBatchSize) {
|
|
13688
|
-
throw new
|
|
14275
|
+
throw new InvalidOperationError3(
|
|
13689
14276
|
"upsert",
|
|
13690
14277
|
`Batch size ${values.length} exceeds maxBatchSize ${maxBatchSize}`
|
|
13691
14278
|
);
|
|
@@ -13738,6 +14325,7 @@ function compileUpsertFrom2(intent, options, deps) {
|
|
|
13738
14325
|
init_assert_field();
|
|
13739
14326
|
init_ast_helpers();
|
|
13740
14327
|
init_compile_where();
|
|
14328
|
+
import { countDistinctRelationPathsByName } from "@dbsp/core";
|
|
13741
14329
|
init_compiler_utils();
|
|
13742
14330
|
init_types();
|
|
13743
14331
|
init_intent_to_decisions();
|
|
@@ -13746,6 +14334,7 @@ init_param_ref();
|
|
|
13746
14334
|
// src/plan-decision-extractor.ts
|
|
13747
14335
|
init_assert_field();
|
|
13748
14336
|
init_intent_to_decisions();
|
|
14337
|
+
import { deriveRelationPathFromIntentPath } from "@dbsp/core";
|
|
13749
14338
|
function findExistsIntents(where) {
|
|
13750
14339
|
if (!where || typeof where !== "object") return [];
|
|
13751
14340
|
const w = where;
|
|
@@ -13790,7 +14379,9 @@ function resolveIncludeByPath(includes, intentPath, relationName) {
|
|
|
13790
14379
|
}
|
|
13791
14380
|
if (resolved) return resolved;
|
|
13792
14381
|
}
|
|
13793
|
-
return includes.find(
|
|
14382
|
+
return includes.find(
|
|
14383
|
+
(i) => i.relation === relationName || i.via === relationName
|
|
14384
|
+
);
|
|
13794
14385
|
}
|
|
13795
14386
|
function deriveForeignKey(context, deriveFk = defaultFkDerivation, defaultPk = DEFAULT_PK_COLUMN) {
|
|
13796
14387
|
const fk = context.foreignKey ?? context.sourceFK;
|
|
@@ -13815,24 +14406,6 @@ function mapComparisonOperator(op3) {
|
|
|
13815
14406
|
};
|
|
13816
14407
|
return map[op3] ?? "=";
|
|
13817
14408
|
}
|
|
13818
|
-
function valueToNode2(value) {
|
|
13819
|
-
if (typeof value === "string") {
|
|
13820
|
-
return { A_Const: { sval: { sval: value } } };
|
|
13821
|
-
}
|
|
13822
|
-
if (typeof value === "number") {
|
|
13823
|
-
if (Number.isInteger(value)) {
|
|
13824
|
-
return { A_Const: { ival: { ival: value } } };
|
|
13825
|
-
}
|
|
13826
|
-
return { A_Const: { fval: { fval: String(value) } } };
|
|
13827
|
-
}
|
|
13828
|
-
if (typeof value === "boolean") {
|
|
13829
|
-
return { A_Const: { boolval: { boolval: value } } };
|
|
13830
|
-
}
|
|
13831
|
-
if (value === null) {
|
|
13832
|
-
return { A_Const: { isnull: true } };
|
|
13833
|
-
}
|
|
13834
|
-
return { A_Const: { sval: { sval: String(value) } } };
|
|
13835
|
-
}
|
|
13836
14409
|
function convertWhereToDecisions(where, table) {
|
|
13837
14410
|
if (!where || typeof where !== "object") return [];
|
|
13838
14411
|
const w = where;
|
|
@@ -14499,6 +15072,11 @@ function toIncludeDecision(d, choice, plan, defaultPk = DEFAULT_PK_COLUMN, deriv
|
|
|
14499
15072
|
type: "includeStrategy",
|
|
14500
15073
|
choice: effectiveChoice,
|
|
14501
15074
|
relationName,
|
|
15075
|
+
relationPath: deriveRelationPathFromIntentPath(
|
|
15076
|
+
Array.isArray(plan.intent?.include) ? plan.intent.include : void 0,
|
|
15077
|
+
context.intentPath,
|
|
15078
|
+
relationName
|
|
15079
|
+
) ?? relationName,
|
|
14502
15080
|
targetTable: context.target,
|
|
14503
15081
|
...context.sourceTable && { sourceTable: context.sourceTable },
|
|
14504
15082
|
...relationType && { relationType },
|
|
@@ -14513,6 +15091,11 @@ function toJoinIncludeDecision(d, plan, defaultPk = DEFAULT_PK_COLUMN, deriveFk
|
|
|
14513
15091
|
const relationName = context.relation ?? context.includeAlias;
|
|
14514
15092
|
if (!context.target || !relationName) return void 0;
|
|
14515
15093
|
const intentPath = context?.intentPath;
|
|
15094
|
+
const relationPath = deriveRelationPathFromIntentPath(
|
|
15095
|
+
Array.isArray(plan.intent?.include) ? plan.intent.include : void 0,
|
|
15096
|
+
intentPath,
|
|
15097
|
+
relationName
|
|
15098
|
+
) ?? relationName;
|
|
14516
15099
|
const includeIntent = resolveIncludeByPath(
|
|
14517
15100
|
plan.intent?.include,
|
|
14518
15101
|
intentPath,
|
|
@@ -14540,6 +15123,7 @@ function toJoinIncludeDecision(d, plan, defaultPk = DEFAULT_PK_COLUMN, deriveFk
|
|
|
14540
15123
|
type: "includeStrategy",
|
|
14541
15124
|
choice: "join",
|
|
14542
15125
|
relationName,
|
|
15126
|
+
relationPath,
|
|
14543
15127
|
targetTable: context.target,
|
|
14544
15128
|
...context.sourceTable && { sourceTable: context.sourceTable },
|
|
14545
15129
|
...relationType && { relationType },
|
|
@@ -14585,6 +15169,7 @@ function synthesizeMissingJoinDecisions(plan, coveredRelations, model, defaultPk
|
|
|
14585
15169
|
type: "includeStrategy",
|
|
14586
15170
|
choice: "join",
|
|
14587
15171
|
relationName: alias,
|
|
15172
|
+
relationPath: alias,
|
|
14588
15173
|
targetTable: rel.target,
|
|
14589
15174
|
sourceTable,
|
|
14590
15175
|
...rel.type && {
|
|
@@ -14881,22 +15466,11 @@ function buildRelationColumnsMap(decisions, includedRelations) {
|
|
|
14881
15466
|
}
|
|
14882
15467
|
return map;
|
|
14883
15468
|
}
|
|
14884
|
-
function findRelationMapKey(map, relationName) {
|
|
14885
|
-
if (map.has(relationName)) return relationName;
|
|
14886
|
-
const suffix = `.${relationName}`;
|
|
14887
|
-
for (const key of map.keys()) {
|
|
14888
|
-
if (key.endsWith(suffix)) return key;
|
|
14889
|
-
}
|
|
14890
|
-
return void 0;
|
|
14891
|
-
}
|
|
14892
15469
|
function injectAndValidateRelationColumns(enrichedUnifiedDecisions, relationColumnsMap, model) {
|
|
14893
15470
|
if (relationColumnsMap.size === 0) return;
|
|
14894
15471
|
for (const d of enrichedUnifiedDecisions) {
|
|
14895
15472
|
if (d.type === "includeStrategy" && d.relationName) {
|
|
14896
|
-
const mapKey =
|
|
14897
|
-
relationColumnsMap,
|
|
14898
|
-
d.relationName
|
|
14899
|
-
);
|
|
15473
|
+
const mapKey = d.relationPath ?? d.relationName;
|
|
14900
15474
|
const entries = mapKey ? relationColumnsMap.get(mapKey) : void 0;
|
|
14901
15475
|
if (entries) {
|
|
14902
15476
|
const mut = d;
|
|
@@ -14931,6 +15505,27 @@ function injectAndValidateRelationColumns(enrichedUnifiedDecisions, relationColu
|
|
|
14931
15505
|
}
|
|
14932
15506
|
}
|
|
14933
15507
|
}
|
|
15508
|
+
function applyJoinHydrationPrefixes(decisions) {
|
|
15509
|
+
const usages = [];
|
|
15510
|
+
for (const d of decisions) {
|
|
15511
|
+
if (d.type !== "includeStrategy" || d.choice !== "join" || !d.relationName) {
|
|
15512
|
+
continue;
|
|
15513
|
+
}
|
|
15514
|
+
const relationName = d.relationName;
|
|
15515
|
+
const relationPath = d.relationPath ?? relationName;
|
|
15516
|
+
usages.push({ relationName, relationPath });
|
|
15517
|
+
}
|
|
15518
|
+
const pathCountsByRelation = countDistinctRelationPathsByName(usages);
|
|
15519
|
+
for (const d of decisions) {
|
|
15520
|
+
if (d.type !== "includeStrategy" || d.choice !== "join" || !d.relationName) {
|
|
15521
|
+
continue;
|
|
15522
|
+
}
|
|
15523
|
+
const relationName = d.relationName;
|
|
15524
|
+
const relationPath = d.relationPath ?? relationName;
|
|
15525
|
+
const usesFullPath = (pathCountsByRelation.get(relationName) ?? 0) > 1;
|
|
15526
|
+
d.hydrationPrefix = usesFullPath ? relationPath : relationName;
|
|
15527
|
+
}
|
|
15528
|
+
}
|
|
14934
15529
|
function enrichRangeDecisions(allDecisions, model, rootTable) {
|
|
14935
15530
|
if (!model) return;
|
|
14936
15531
|
for (let i = 0; i < allDecisions.length; i++) {
|
|
@@ -15019,6 +15614,7 @@ function compileSelect(plan, options, deps) {
|
|
|
15019
15614
|
...allUnifiedIncludeDecisions
|
|
15020
15615
|
];
|
|
15021
15616
|
stripJoinColumnsForAggregation(enrichedUnifiedDecisions, execIntent);
|
|
15617
|
+
applyJoinHydrationPrefixes(enrichedUnifiedDecisions);
|
|
15022
15618
|
const includedRelations = new Set(
|
|
15023
15619
|
enrichedUnifiedDecisions.filter((d) => d.type === "includeStrategy").map((d) => d.relationName).filter(Boolean)
|
|
15024
15620
|
);
|
|
@@ -15116,6 +15712,7 @@ function compileWithIncludes(plan, options, deps) {
|
|
|
15116
15712
|
init_ast_helpers();
|
|
15117
15713
|
init_compiler_utils();
|
|
15118
15714
|
init_handlers();
|
|
15715
|
+
init_utils();
|
|
15119
15716
|
init_param_ref();
|
|
15120
15717
|
|
|
15121
15718
|
// src/recursive/cte-compiler.ts
|
|
@@ -15829,6 +16426,7 @@ function buildEdgeTableRecursiveCte(config) {
|
|
|
15829
16426
|
// src/adapter-compiler-recursive.ts
|
|
15830
16427
|
function compileRecursive(report, _model, _options, deps) {
|
|
15831
16428
|
const schemaName = deps.schemaName;
|
|
16429
|
+
const state = createCompilerState();
|
|
15832
16430
|
const intent = report.intent;
|
|
15833
16431
|
const traversal = intent.traversal;
|
|
15834
16432
|
const trackPath = intent.track?.path !== void 0;
|
|
@@ -15848,7 +16446,7 @@ function compileRecursive(report, _model, _options, deps) {
|
|
|
15848
16446
|
const selectColumns = Array.from(/* @__PURE__ */ new Set([nodeIdColumn, ...startSelect]));
|
|
15849
16447
|
const edgeFrom = traversal.direction === "in" ? traversal.edgeTo : traversal.edgeFrom;
|
|
15850
16448
|
const edgeTo = traversal.direction === "in" ? traversal.edgeFrom : traversal.edgeTo;
|
|
15851
|
-
const anchorWhere = intent.start.where ? buildRecursiveAnchorWhere(intent.start.where, "__n", deps) : void 0;
|
|
16449
|
+
const anchorWhere = intent.start.where ? buildRecursiveAnchorWhere(intent.start.where, "__n", deps, state) : void 0;
|
|
15852
16450
|
const base = {
|
|
15853
16451
|
cteAlias: intent.cteName,
|
|
15854
16452
|
table,
|
|
@@ -15974,11 +16572,10 @@ function compileRecursive(report, _model, _options, deps) {
|
|
|
15974
16572
|
const sql = deparseQuoted({ SelectStmt: selectStmt2 });
|
|
15975
16573
|
return {
|
|
15976
16574
|
sql,
|
|
15977
|
-
parameters:
|
|
16575
|
+
parameters: state.parameters
|
|
15978
16576
|
};
|
|
15979
16577
|
}
|
|
15980
|
-
function compileCteQuery(intent,
|
|
15981
|
-
const schemaName = deps.schemaName;
|
|
16578
|
+
function compileCteQuery(intent, options, deps) {
|
|
15982
16579
|
const state = createCompilerState();
|
|
15983
16580
|
const allCteParams = [];
|
|
15984
16581
|
const cteSqlFragments = [];
|
|
@@ -15992,8 +16589,8 @@ function compileCteQuery(intent, _options, deps) {
|
|
|
15992
16589
|
isRecursive = true;
|
|
15993
16590
|
const { sql: cteSql, params: cteParams } = buildRawCte(
|
|
15994
16591
|
cte,
|
|
15995
|
-
|
|
15996
|
-
|
|
16592
|
+
deps,
|
|
16593
|
+
options
|
|
15997
16594
|
);
|
|
15998
16595
|
allCteParams.push(...cteParams);
|
|
15999
16596
|
cteSqlFragments.push(cteSql);
|
|
@@ -16011,12 +16608,7 @@ function compileCteQuery(intent, _options, deps) {
|
|
|
16011
16608
|
isAmbiguous: false
|
|
16012
16609
|
}
|
|
16013
16610
|
};
|
|
16014
|
-
const
|
|
16015
|
-
const innerCompiled = compileSelect(
|
|
16016
|
-
innerPlanReport,
|
|
16017
|
-
innerCompileOptions,
|
|
16018
|
-
deps
|
|
16019
|
-
);
|
|
16611
|
+
const innerCompiled = compileSelect(innerPlanReport, options, deps);
|
|
16020
16612
|
const currentParamOffset = allCteParams.length;
|
|
16021
16613
|
const renumberedInnerSql = currentParamOffset > 0 ? innerCompiled.sql.replace(
|
|
16022
16614
|
/\$([0-9]+)/g,
|
|
@@ -16031,7 +16623,6 @@ function compileCteQuery(intent, _options, deps) {
|
|
|
16031
16623
|
);
|
|
16032
16624
|
}
|
|
16033
16625
|
}
|
|
16034
|
-
const outerCompileOptions = schemaName !== void 0 ? { schemaName } : {};
|
|
16035
16626
|
const outerPlanReport = {
|
|
16036
16627
|
rootTable: intent.query.from,
|
|
16037
16628
|
decisions: [],
|
|
@@ -16044,11 +16635,7 @@ function compileCteQuery(intent, _options, deps) {
|
|
|
16044
16635
|
isAmbiguous: false
|
|
16045
16636
|
}
|
|
16046
16637
|
};
|
|
16047
|
-
const outerCompiled = compileSelect(
|
|
16048
|
-
outerPlanReport,
|
|
16049
|
-
outerCompileOptions,
|
|
16050
|
-
deps
|
|
16051
|
-
);
|
|
16638
|
+
const outerCompiled = compileSelect(outerPlanReport, options, deps);
|
|
16052
16639
|
const cteParamCount = allCteParams.length;
|
|
16053
16640
|
const renumberedOuterSql = cteParamCount > 0 ? outerCompiled.sql.replace(
|
|
16054
16641
|
/\$([0-9]+)/g,
|
|
@@ -16114,8 +16701,7 @@ function buildUnnestCte(cte, state, deps) {
|
|
|
16114
16701
|
}
|
|
16115
16702
|
};
|
|
16116
16703
|
}
|
|
16117
|
-
function buildRawCte(cte,
|
|
16118
|
-
const compileOptions = schemaName !== void 0 ? { schemaName } : {};
|
|
16704
|
+
function buildRawCte(cte, deps, options) {
|
|
16119
16705
|
const basePlanReport = {
|
|
16120
16706
|
rootTable: cte.base.from,
|
|
16121
16707
|
decisions: [],
|
|
@@ -16124,7 +16710,7 @@ function buildRawCte(cte, schemaName, deps) {
|
|
|
16124
16710
|
intent: cte.base,
|
|
16125
16711
|
metadata: { planningTimeMs: 0, relationsAnalyzed: 0, isAmbiguous: false }
|
|
16126
16712
|
};
|
|
16127
|
-
const baseCompiled = compileSelect(basePlanReport,
|
|
16713
|
+
const baseCompiled = compileSelect(basePlanReport, options, deps);
|
|
16128
16714
|
const stepPlanReport = {
|
|
16129
16715
|
rootTable: cte.step.from,
|
|
16130
16716
|
decisions: [],
|
|
@@ -16133,7 +16719,7 @@ function buildRawCte(cte, schemaName, deps) {
|
|
|
16133
16719
|
intent: cte.step,
|
|
16134
16720
|
metadata: { planningTimeMs: 0, relationsAnalyzed: 0, isAmbiguous: false }
|
|
16135
16721
|
};
|
|
16136
|
-
const stepCompiled = compileSelect(stepPlanReport,
|
|
16722
|
+
const stepCompiled = compileSelect(stepPlanReport, options, deps);
|
|
16137
16723
|
const baseParamCount = baseCompiled.parameters.length;
|
|
16138
16724
|
const renumberedStepSql = baseParamCount > 0 ? stepCompiled.sql.replace(
|
|
16139
16725
|
/\$([0-9]+)/g,
|
|
@@ -16159,7 +16745,7 @@ function buildRawCte(cte, schemaName, deps) {
|
|
|
16159
16745
|
params: allParams
|
|
16160
16746
|
};
|
|
16161
16747
|
}
|
|
16162
|
-
function buildRecursiveAnchorWhere(where, tableAlias, deps) {
|
|
16748
|
+
function buildRecursiveAnchorWhere(where, tableAlias, deps, state) {
|
|
16163
16749
|
if (!where || typeof where !== "object") {
|
|
16164
16750
|
return { A_Const: { boolval: { boolval: true } } };
|
|
16165
16751
|
}
|
|
@@ -16176,7 +16762,7 @@ function buildRecursiveAnchorWhere(where, tableAlias, deps) {
|
|
|
16176
16762
|
}
|
|
16177
16763
|
};
|
|
16178
16764
|
const op3 = mapComparisonOperator(w.operator);
|
|
16179
|
-
const right =
|
|
16765
|
+
const right = compileValue(w.value, state, void 0, true);
|
|
16180
16766
|
return {
|
|
16181
16767
|
A_Expr: {
|
|
16182
16768
|
kind: "AEXPR_OP",
|
|
@@ -16188,14 +16774,14 @@ function buildRecursiveAnchorWhere(where, tableAlias, deps) {
|
|
|
16188
16774
|
}
|
|
16189
16775
|
case "and": {
|
|
16190
16776
|
const conditions = w.conditions.map(
|
|
16191
|
-
(c) => buildRecursiveAnchorWhere(c, tableAlias, deps)
|
|
16777
|
+
(c) => buildRecursiveAnchorWhere(c, tableAlias, deps, state)
|
|
16192
16778
|
);
|
|
16193
16779
|
if (conditions.length === 1) return conditions[0];
|
|
16194
16780
|
return { BoolExpr: { boolop: "AND_EXPR", args: conditions } };
|
|
16195
16781
|
}
|
|
16196
16782
|
case "or": {
|
|
16197
16783
|
const conditions = w.conditions.map(
|
|
16198
|
-
(c) => buildRecursiveAnchorWhere(c, tableAlias, deps)
|
|
16784
|
+
(c) => buildRecursiveAnchorWhere(c, tableAlias, deps, state)
|
|
16199
16785
|
);
|
|
16200
16786
|
if (conditions.length === 1) return conditions[0];
|
|
16201
16787
|
return { BoolExpr: { boolop: "OR_EXPR", args: conditions } };
|
|
@@ -16374,12 +16960,12 @@ function compileLeafOrBranch(intent, compileFn) {
|
|
|
16374
16960
|
const result = compileFn(intent);
|
|
16375
16961
|
return { sql: result.sql, parameters: result.parameters };
|
|
16376
16962
|
}
|
|
16377
|
-
function createLeafCompileFn(adapter, model, planFn2) {
|
|
16963
|
+
function createLeafCompileFn(adapter, model, planFn2, options) {
|
|
16378
16964
|
return (query) => {
|
|
16379
16965
|
const planReport = planFn2(query, model, {
|
|
16380
16966
|
dialectCapabilities: adapter.dialectCapabilities
|
|
16381
16967
|
});
|
|
16382
|
-
return adapter.compile(planReport, { model });
|
|
16968
|
+
return adapter.compile(planReport, { ...options, model });
|
|
16383
16969
|
};
|
|
16384
16970
|
}
|
|
16385
16971
|
|
|
@@ -16498,6 +17084,15 @@ function mapFetchDirection(direction) {
|
|
|
16498
17084
|
|
|
16499
17085
|
// src/pgsql-adapter.ts
|
|
16500
17086
|
init_validate();
|
|
17087
|
+
function renumberSqlParams(sql, offset) {
|
|
17088
|
+
if (offset === 0) return sql;
|
|
17089
|
+
return sql.replace(/\$(\d+)/g, (_match, num) => {
|
|
17090
|
+
return `$${Number.parseInt(num, 10) + offset}`;
|
|
17091
|
+
});
|
|
17092
|
+
}
|
|
17093
|
+
function isCompiledNqlQuery(input) {
|
|
17094
|
+
return !("intent" in input) && ("query" in input || "cteQuery" in input || "mutation" in input || "setOperation" in input || "bindings" in input || "mutationBindings" in input);
|
|
17095
|
+
}
|
|
16501
17096
|
var PgsqlAdapter = class _PgsqlAdapter {
|
|
16502
17097
|
pool;
|
|
16503
17098
|
client;
|
|
@@ -16577,6 +17172,124 @@ var PgsqlAdapter = class _PgsqlAdapter {
|
|
|
16577
17172
|
deriveFk: this.deriveFk
|
|
16578
17173
|
};
|
|
16579
17174
|
}
|
|
17175
|
+
requireNqlCompileModel(options) {
|
|
17176
|
+
const model = options?.model ?? this.model;
|
|
17177
|
+
if (model === void 0) {
|
|
17178
|
+
throw new Error(
|
|
17179
|
+
"Compiling an NQL bundle requires a model. Pass { model } to adapter.compile(compiledNql, { model }) or configure the adapter with a model."
|
|
17180
|
+
);
|
|
17181
|
+
}
|
|
17182
|
+
return model;
|
|
17183
|
+
}
|
|
17184
|
+
compileNqlMutation(bundle, options) {
|
|
17185
|
+
const mutation = bundle.mutation;
|
|
17186
|
+
if (mutation === void 0) {
|
|
17187
|
+
throw new Error("NQL bundle did not contain a mutation intent.");
|
|
17188
|
+
}
|
|
17189
|
+
switch (mutation.type) {
|
|
17190
|
+
case "insert":
|
|
17191
|
+
return compileInsert2(
|
|
17192
|
+
mutation,
|
|
17193
|
+
options,
|
|
17194
|
+
this.buildCompileDeps(options)
|
|
17195
|
+
);
|
|
17196
|
+
case "insert_from":
|
|
17197
|
+
return compileInsertFrom2(
|
|
17198
|
+
mutation,
|
|
17199
|
+
options,
|
|
17200
|
+
this.buildCompileDeps(options)
|
|
17201
|
+
);
|
|
17202
|
+
case "update":
|
|
17203
|
+
return compileUpdate2(
|
|
17204
|
+
mutation,
|
|
17205
|
+
options,
|
|
17206
|
+
this.buildCompileDeps(options)
|
|
17207
|
+
);
|
|
17208
|
+
case "delete":
|
|
17209
|
+
return compileDelete2(
|
|
17210
|
+
mutation,
|
|
17211
|
+
options,
|
|
17212
|
+
this.buildCompileDeps(options)
|
|
17213
|
+
);
|
|
17214
|
+
case "upsert":
|
|
17215
|
+
return compileUpsert2(
|
|
17216
|
+
mutation,
|
|
17217
|
+
options,
|
|
17218
|
+
this.buildCompileDeps(options)
|
|
17219
|
+
);
|
|
17220
|
+
case "upsert_from":
|
|
17221
|
+
return compileUpsertFrom2(
|
|
17222
|
+
mutation,
|
|
17223
|
+
options,
|
|
17224
|
+
this.buildCompileDeps(options)
|
|
17225
|
+
);
|
|
17226
|
+
}
|
|
17227
|
+
throw new Error(
|
|
17228
|
+
`Unsupported NQL mutation type: ${mutation.type}`
|
|
17229
|
+
);
|
|
17230
|
+
}
|
|
17231
|
+
compileNqlBundleLeaf(bundle, options) {
|
|
17232
|
+
if (bundle.query !== void 0) {
|
|
17233
|
+
const model = this.requireNqlCompileModel(options);
|
|
17234
|
+
const planReport = planFn(bundle.query, model, {
|
|
17235
|
+
dialectCapabilities: this.dialectCapabilities
|
|
17236
|
+
});
|
|
17237
|
+
return compileSelect(
|
|
17238
|
+
planReport,
|
|
17239
|
+
options,
|
|
17240
|
+
this.buildCompileDeps(options)
|
|
17241
|
+
);
|
|
17242
|
+
}
|
|
17243
|
+
if (bundle.cteQuery !== void 0) {
|
|
17244
|
+
return compileCteQuery(
|
|
17245
|
+
bundle.cteQuery,
|
|
17246
|
+
options,
|
|
17247
|
+
this.buildCompileDeps(options)
|
|
17248
|
+
);
|
|
17249
|
+
}
|
|
17250
|
+
if (bundle.setOperation !== void 0) {
|
|
17251
|
+
const model = this.requireNqlCompileModel(options);
|
|
17252
|
+
return this.compileSetOperation(
|
|
17253
|
+
bundle.setOperation,
|
|
17254
|
+
model,
|
|
17255
|
+
options
|
|
17256
|
+
);
|
|
17257
|
+
}
|
|
17258
|
+
if (bundle.mutation !== void 0) {
|
|
17259
|
+
return this.compileNqlMutation(bundle, options);
|
|
17260
|
+
}
|
|
17261
|
+
throw new Error("NQL bundle did not contain a compilable intent.");
|
|
17262
|
+
}
|
|
17263
|
+
compileNqlBundle(bundle, options) {
|
|
17264
|
+
const ctes = [];
|
|
17265
|
+
const parameters = [];
|
|
17266
|
+
for (const [name, queryIntent] of bundle.bindings ?? []) {
|
|
17267
|
+
const cteName = quoteIdent2(name, "alias");
|
|
17268
|
+
const bindingBundle = bundle.mutationBindings?.has(name) ? { mutation: bundle.mutationBindings.get(name) } : { query: queryIntent };
|
|
17269
|
+
const compiled2 = this.compileNqlBundleLeaf(bindingBundle, options);
|
|
17270
|
+
ctes.push(
|
|
17271
|
+
`${cteName} as (${renumberSqlParams(compiled2.sql, parameters.length)})`
|
|
17272
|
+
);
|
|
17273
|
+
parameters.push(...compiled2.parameters);
|
|
17274
|
+
}
|
|
17275
|
+
const leafBundle = {
|
|
17276
|
+
...bundle.query !== void 0 && { query: bundle.query },
|
|
17277
|
+
...bundle.cteQuery !== void 0 && { cteQuery: bundle.cteQuery },
|
|
17278
|
+
...bundle.mutation !== void 0 && { mutation: bundle.mutation },
|
|
17279
|
+
...bundle.returning !== void 0 && { returning: bundle.returning },
|
|
17280
|
+
...bundle.setOperation !== void 0 && {
|
|
17281
|
+
setOperation: bundle.setOperation
|
|
17282
|
+
}
|
|
17283
|
+
};
|
|
17284
|
+
const compiled = this.compileNqlBundleLeaf(leafBundle, options);
|
|
17285
|
+
if (ctes.length === 0) {
|
|
17286
|
+
return compiled;
|
|
17287
|
+
}
|
|
17288
|
+
return {
|
|
17289
|
+
sql: `WITH ${ctes.join(", ")} ${renumberSqlParams(compiled.sql, parameters.length)}`,
|
|
17290
|
+
parameters: [...parameters, ...compiled.parameters]
|
|
17291
|
+
};
|
|
17292
|
+
}
|
|
16580
17293
|
/**
|
|
16581
17294
|
* Returns the pool/client executor, or throws if in compile-only mode.
|
|
16582
17295
|
*/
|
|
@@ -16616,6 +17329,9 @@ var PgsqlAdapter = class _PgsqlAdapter {
|
|
|
16616
17329
|
* Compile a plan to executable SQL.
|
|
16617
17330
|
*/
|
|
16618
17331
|
compile(plan, options) {
|
|
17332
|
+
if (isCompiledNqlQuery(plan)) {
|
|
17333
|
+
return this.compileNqlBundle(plan, options);
|
|
17334
|
+
}
|
|
16619
17335
|
return compileSelect(plan, options, this.buildCompileDeps(options));
|
|
16620
17336
|
}
|
|
16621
17337
|
/**
|
|
@@ -16779,8 +17495,8 @@ var PgsqlAdapter = class _PgsqlAdapter {
|
|
|
16779
17495
|
/**
|
|
16780
17496
|
* Compile a set operation (UNION / INTERSECT / EXCEPT) to SQL.
|
|
16781
17497
|
*/
|
|
16782
|
-
compileSetOperation(intent, model,
|
|
16783
|
-
const compileFn = createLeafCompileFn(this, model, planFn);
|
|
17498
|
+
compileSetOperation(intent, model, options) {
|
|
17499
|
+
const compileFn = createLeafCompileFn(this, model, planFn, options);
|
|
16784
17500
|
const result = compileSetOperation(intent, compileFn);
|
|
16785
17501
|
return {
|
|
16786
17502
|
sql: result.sql,
|