@harperfast/harper 5.2.0-alpha.6 → 5.2.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dataLayer/harperBridge/ResourceBridge.ts +7 -0
- package/dist/dataLayer/harperBridge/ResourceBridge.js +8 -0
- package/dist/dataLayer/harperBridge/ResourceBridge.js.map +1 -1
- package/dist/resources/Resource.js +5 -2
- package/dist/resources/Resource.js.map +1 -1
- package/dist/resources/Table.d.ts +3 -1
- package/dist/resources/Table.js +13 -3
- package/dist/resources/Table.js.map +1 -1
- package/dist/resources/databases.js +21 -0
- package/dist/resources/databases.js.map +1 -1
- package/dist/sqlEngine/binder/bind.d.ts +72 -0
- package/dist/sqlEngine/binder/bind.js +289 -0
- package/dist/sqlEngine/binder/bind.js.map +1 -0
- package/dist/sqlEngine/config.d.ts +35 -0
- package/dist/sqlEngine/config.js +62 -0
- package/dist/sqlEngine/config.js.map +1 -0
- package/dist/sqlEngine/diff/differential.d.ts +23 -0
- package/dist/sqlEngine/diff/differential.js +90 -0
- package/dist/sqlEngine/diff/differential.js.map +1 -0
- package/dist/sqlEngine/errors.d.ts +22 -0
- package/dist/sqlEngine/errors.js +36 -0
- package/dist/sqlEngine/errors.js.map +1 -0
- package/dist/sqlEngine/executor/runMutation.d.ts +35 -0
- package/dist/sqlEngine/executor/runMutation.js +352 -0
- package/dist/sqlEngine/executor/runMutation.js.map +1 -0
- package/dist/sqlEngine/executor/runSelect.d.ts +7 -0
- package/dist/sqlEngine/executor/runSelect.js +14 -0
- package/dist/sqlEngine/executor/runSelect.js.map +1 -0
- package/dist/sqlEngine/expressions/compile.d.ts +24 -0
- package/dist/sqlEngine/expressions/compile.js +326 -0
- package/dist/sqlEngine/expressions/compile.js.map +1 -0
- package/dist/sqlEngine/functions/aggregates.d.ts +12 -0
- package/dist/sqlEngine/functions/aggregates.js +299 -0
- package/dist/sqlEngine/functions/aggregates.js.map +1 -0
- package/dist/sqlEngine/functions/registry.d.ts +36 -0
- package/dist/sqlEngine/functions/registry.js +33 -0
- package/dist/sqlEngine/functions/registry.js.map +1 -0
- package/dist/sqlEngine/functions/standard.d.ts +9 -0
- package/dist/sqlEngine/functions/standard.js +86 -0
- package/dist/sqlEngine/functions/standard.js.map +1 -0
- package/dist/sqlEngine/index.d.ts +29 -0
- package/dist/sqlEngine/index.js +62 -0
- package/dist/sqlEngine/index.js.map +1 -0
- package/dist/sqlEngine/logical/build.d.ts +20 -0
- package/dist/sqlEngine/logical/build.js +326 -0
- package/dist/sqlEngine/logical/build.js.map +1 -0
- package/dist/sqlEngine/logical/op.d.ts +105 -0
- package/dist/sqlEngine/logical/op.js +10 -0
- package/dist/sqlEngine/logical/op.js.map +1 -0
- package/dist/sqlEngine/optimizer/joinAnalysis.d.ts +37 -0
- package/dist/sqlEngine/optimizer/joinAnalysis.js +144 -0
- package/dist/sqlEngine/optimizer/joinAnalysis.js.map +1 -0
- package/dist/sqlEngine/optimizer/optimize.d.ts +13 -0
- package/dist/sqlEngine/optimizer/optimize.js +53 -0
- package/dist/sqlEngine/optimizer/optimize.js.map +1 -0
- package/dist/sqlEngine/optimizer/ruleEngine.d.ts +7 -0
- package/dist/sqlEngine/optimizer/ruleEngine.js +26 -0
- package/dist/sqlEngine/optimizer/ruleEngine.js.map +1 -0
- package/dist/sqlEngine/optimizer/rules/limitPushdown.d.ts +19 -0
- package/dist/sqlEngine/optimizer/rules/limitPushdown.js +55 -0
- package/dist/sqlEngine/optimizer/rules/limitPushdown.js.map +1 -0
- package/dist/sqlEngine/optimizer/rules/planJoins.d.ts +19 -0
- package/dist/sqlEngine/optimizer/rules/planJoins.js +62 -0
- package/dist/sqlEngine/optimizer/rules/planJoins.js.map +1 -0
- package/dist/sqlEngine/optimizer/rules/predicateNormalize.d.ts +18 -0
- package/dist/sqlEngine/optimizer/rules/predicateNormalize.js +80 -0
- package/dist/sqlEngine/optimizer/rules/predicateNormalize.js.map +1 -0
- package/dist/sqlEngine/optimizer/rules/predicatePushdown.d.ts +11 -0
- package/dist/sqlEngine/optimizer/rules/predicatePushdown.js +48 -0
- package/dist/sqlEngine/optimizer/rules/predicatePushdown.js.map +1 -0
- package/dist/sqlEngine/optimizer/rules/projectionPushdown.d.ts +23 -0
- package/dist/sqlEngine/optimizer/rules/projectionPushdown.js +160 -0
- package/dist/sqlEngine/optimizer/rules/projectionPushdown.js.map +1 -0
- package/dist/sqlEngine/optimizer/rules/sortFromIndex.d.ts +14 -0
- package/dist/sqlEngine/optimizer/rules/sortFromIndex.js +49 -0
- package/dist/sqlEngine/optimizer/rules/sortFromIndex.js.map +1 -0
- package/dist/sqlEngine/optimizer/rules/validateScannable.d.ts +15 -0
- package/dist/sqlEngine/optimizer/rules/validateScannable.js +60 -0
- package/dist/sqlEngine/optimizer/rules/validateScannable.js.map +1 -0
- package/dist/sqlEngine/optimizer/whereToConditions.d.ts +85 -0
- package/dist/sqlEngine/optimizer/whereToConditions.js +484 -0
- package/dist/sqlEngine/optimizer/whereToConditions.js.map +1 -0
- package/dist/sqlEngine/parser/ast.d.ts +139 -0
- package/dist/sqlEngine/parser/ast.js +10 -0
- package/dist/sqlEngine/parser/ast.js.map +1 -0
- package/dist/sqlEngine/parser/normalizer.d.ts +28 -0
- package/dist/sqlEngine/parser/normalizer.js +413 -0
- package/dist/sqlEngine/parser/normalizer.js.map +1 -0
- package/dist/sqlEngine/parser/parse.d.ts +14 -0
- package/dist/sqlEngine/parser/parse.js +20 -0
- package/dist/sqlEngine/parser/parse.js.map +1 -0
- package/dist/sqlEngine/physical/PhysicalDistinct.d.ts +9 -0
- package/dist/sqlEngine/physical/PhysicalDistinct.js +29 -0
- package/dist/sqlEngine/physical/PhysicalDistinct.js.map +1 -0
- package/dist/sqlEngine/physical/PhysicalFilter.d.ts +10 -0
- package/dist/sqlEngine/physical/PhysicalFilter.js +25 -0
- package/dist/sqlEngine/physical/PhysicalFilter.js.map +1 -0
- package/dist/sqlEngine/physical/PhysicalHashAggregate.d.ts +27 -0
- package/dist/sqlEngine/physical/PhysicalHashAggregate.js +100 -0
- package/dist/sqlEngine/physical/PhysicalHashAggregate.js.map +1 -0
- package/dist/sqlEngine/physical/PhysicalHashJoin.d.ts +29 -0
- package/dist/sqlEngine/physical/PhysicalHashJoin.js +93 -0
- package/dist/sqlEngine/physical/PhysicalHashJoin.js.map +1 -0
- package/dist/sqlEngine/physical/PhysicalIndexNestedLoopJoin.d.ts +36 -0
- package/dist/sqlEngine/physical/PhysicalIndexNestedLoopJoin.js +78 -0
- package/dist/sqlEngine/physical/PhysicalIndexNestedLoopJoin.js.map +1 -0
- package/dist/sqlEngine/physical/PhysicalIndexScan.d.ts +22 -0
- package/dist/sqlEngine/physical/PhysicalIndexScan.js +77 -0
- package/dist/sqlEngine/physical/PhysicalIndexScan.js.map +1 -0
- package/dist/sqlEngine/physical/PhysicalLimit.d.ts +5 -0
- package/dist/sqlEngine/physical/PhysicalLimit.js +28 -0
- package/dist/sqlEngine/physical/PhysicalLimit.js.map +1 -0
- package/dist/sqlEngine/physical/PhysicalNestedLoopJoin.d.ts +20 -0
- package/dist/sqlEngine/physical/PhysicalNestedLoopJoin.js +51 -0
- package/dist/sqlEngine/physical/PhysicalNestedLoopJoin.js.map +1 -0
- package/dist/sqlEngine/physical/PhysicalProject.d.ts +18 -0
- package/dist/sqlEngine/physical/PhysicalProject.js +117 -0
- package/dist/sqlEngine/physical/PhysicalProject.js.map +1 -0
- package/dist/sqlEngine/physical/PhysicalQualify.d.ts +13 -0
- package/dist/sqlEngine/physical/PhysicalQualify.js +29 -0
- package/dist/sqlEngine/physical/PhysicalQualify.js.map +1 -0
- package/dist/sqlEngine/physical/PhysicalSort.d.ts +12 -0
- package/dist/sqlEngine/physical/PhysicalSort.js +59 -0
- package/dist/sqlEngine/physical/PhysicalSort.js.map +1 -0
- package/dist/sqlEngine/physical/op.d.ts +11 -0
- package/dist/sqlEngine/physical/op.js +9 -0
- package/dist/sqlEngine/physical/op.js.map +1 -0
- package/dist/sqlEngine/physical/plan.d.ts +23 -0
- package/dist/sqlEngine/physical/plan.js +162 -0
- package/dist/sqlEngine/physical/plan.js.map +1 -0
- package/dist/sqlEngine/router.d.ts +26 -0
- package/dist/sqlEngine/router.js +48 -0
- package/dist/sqlEngine/router.js.map +1 -0
- package/dist/sqlEngine/types.d.ts +37 -0
- package/dist/sqlEngine/types.js +13 -0
- package/dist/sqlEngine/types.js.map +1 -0
- package/dist/sqlTranslator/index.js +7 -1
- package/dist/sqlTranslator/index.js.map +1 -1
- package/dist/validation/deleteValidator.js +10 -2
- package/dist/validation/deleteValidator.js.map +1 -1
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
- package/resources/DESIGN.md +17 -16
- package/resources/Resource.ts +5 -2
- package/resources/Table.ts +23 -3
- package/resources/databases.ts +24 -0
- package/sqlTranslator/index.ts +16 -6
- package/studio/web/assets/{Chat-CTjtL8Z4.js → Chat-BZks8dVF.js} +2 -2
- package/studio/web/assets/{Chat-CTjtL8Z4.js.map → Chat-BZks8dVF.js.map} +1 -1
- package/studio/web/assets/{FloatingChat-CafHR4Ur.js → FloatingChat-Dic8paVO.js} +4 -4
- package/studio/web/assets/{FloatingChat-CafHR4Ur.js.map → FloatingChat-Dic8paVO.js.map} +1 -1
- package/studio/web/assets/{applications-Buh_q0Vj.js → applications-uOXkeUIN.js} +2 -2
- package/studio/web/assets/{applications-Buh_q0Vj.js.map → applications-uOXkeUIN.js.map} +1 -1
- package/studio/web/assets/{index-0hXeECkS.js → index-i-2wrKhv.js} +6 -6
- package/studio/web/assets/{index-0hXeECkS.js.map → index-i-2wrKhv.js.map} +1 -1
- package/studio/web/assets/{index.lazy-B00B7VBT.js → index.lazy-Csk8eCoB.js} +4 -4
- package/studio/web/assets/{index.lazy-B00B7VBT.js.map → index.lazy-Csk8eCoB.js.map} +1 -1
- package/studio/web/assets/{profile-Cg2wwYPn.js → profile-Sb3mGDl6.js} +2 -2
- package/studio/web/assets/{profile-Cg2wwYPn.js.map → profile-Sb3mGDl6.js.map} +1 -1
- package/studio/web/assets/{setComponentFile-DCaDIvyB.js → setComponentFile-BgZcaPJ2.js} +2 -2
- package/studio/web/assets/{setComponentFile-DCaDIvyB.js.map → setComponentFile-BgZcaPJ2.js.map} +1 -1
- package/studio/web/assets/{setup-CAVcAQjK.js → setup-DKtlLgmT.js} +2 -2
- package/studio/web/assets/{setup-CAVcAQjK.js.map → setup-DKtlLgmT.js.map} +1 -1
- package/studio/web/assets/{status-BRXorNdD.js → status-B45iLeug.js} +2 -2
- package/studio/web/assets/{status-BRXorNdD.js.map → status-B45iLeug.js.map} +1 -1
- package/studio/web/assets/{swagger-ui-react-Dy1D62vO.js → swagger-ui-react-Csu4026e.js} +2 -2
- package/studio/web/assets/{swagger-ui-react-Dy1D62vO.js.map → swagger-ui-react-Csu4026e.js.map} +1 -1
- package/studio/web/assets/{tsMode-A8gbL74v.js → tsMode-DVgxUr_l.js} +2 -2
- package/studio/web/assets/{tsMode-A8gbL74v.js.map → tsMode-DVgxUr_l.js.map} +1 -1
- package/studio/web/assets/{useEntityRestURL-cDodrVcQ.js → useEntityRestURL-yfDQMV1f.js} +2 -2
- package/studio/web/assets/{useEntityRestURL-cDodrVcQ.js.map → useEntityRestURL-yfDQMV1f.js.map} +1 -1
- package/studio/web/index.html +1 -1
- package/validation/deleteValidator.ts +11 -2
|
@@ -0,0 +1,352 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Phase 4 mutation executors: INSERT / UPDATE / DELETE.
|
|
4
|
+
*
|
|
5
|
+
* Writes go through the Resource API exactly as production code does: the
|
|
6
|
+
* `databases`-resolved entry is the Table class, whose static
|
|
7
|
+
* `create`/`put`/`patch`/`delete`/`get` methods each call `transaction(context,
|
|
8
|
+
* …)` internally and *join* an already-open transaction on the context
|
|
9
|
+
* (resources/Resource.ts). So the whole mutation runs inside a single
|
|
10
|
+
* `transaction(context, …)`; every per-row write joins it and the batch commits
|
|
11
|
+
* (or aborts) atomically.
|
|
12
|
+
*
|
|
13
|
+
* UPDATE/DELETE find their target rows by running the ordinary SELECT pipeline
|
|
14
|
+
* (a synthetic `SELECT … FROM target WHERE …`) inside the same transaction, so
|
|
15
|
+
* the read sees a consistent snapshot with the writes.
|
|
16
|
+
*
|
|
17
|
+
* Response shapes match the legacy SQL path (dataLayer/insert.ts,
|
|
18
|
+
* dataLayer/delete.ts) so callers see no difference:
|
|
19
|
+
* INSERT → { message: "inserted N of M records", inserted_hashes, skipped_hashes }
|
|
20
|
+
* UPDATE → { message: "updated N of M records", update_hashes, skipped_hashes }
|
|
21
|
+
* DELETE → { message: "N of M records successfully deleted", deleted_hashes, skipped_hashes }
|
|
22
|
+
*/
|
|
23
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
24
|
+
exports._setTransactionRunner = _setTransactionRunner;
|
|
25
|
+
exports.runInsert = runInsert;
|
|
26
|
+
exports.runUpdate = runUpdate;
|
|
27
|
+
exports.runDelete = runDelete;
|
|
28
|
+
const bind_ts_1 = require("../binder/bind.js");
|
|
29
|
+
const build_ts_1 = require("../logical/build.js");
|
|
30
|
+
const optimize_ts_1 = require("../optimizer/optimize.js");
|
|
31
|
+
const plan_ts_1 = require("../physical/plan.js");
|
|
32
|
+
const runSelect_ts_1 = require("./runSelect.js");
|
|
33
|
+
const compile_ts_1 = require("../expressions/compile.js");
|
|
34
|
+
const errors_ts_1 = require("../errors.js");
|
|
35
|
+
const tracked_ts_1 = require("../../resources/tracked.js");
|
|
36
|
+
/**
|
|
37
|
+
* If a SET assignment is a self-referential increment/decrement by a numeric
|
|
38
|
+
* literal — `col = col + N`, `col = N + col`, or `col = col - N` — return the
|
|
39
|
+
* signed delta. Such an assignment MUST be applied as an atomic CRDT `Addition`
|
|
40
|
+
* (the same primitive REST/ops `addTo` uses), not as a read-compute-write of an
|
|
41
|
+
* absolute value: two concurrent `SET qty = qty + 1` statements that both read
|
|
42
|
+
* the same pre-value would otherwise clobber each other and silently lose an
|
|
43
|
+
* increment (F-146). Returns undefined for any other shape (including
|
|
44
|
+
* `col = col + col` or `col = otherCol + N`), which stays on the absolute path.
|
|
45
|
+
*/
|
|
46
|
+
function selfIncrementDelta(column, expr) {
|
|
47
|
+
if (expr.kind !== 'binop' || (expr.op !== '+' && expr.op !== '-'))
|
|
48
|
+
return undefined;
|
|
49
|
+
const isThisColumn = (n) => n.kind === 'column' && n.name === column && n.table == null;
|
|
50
|
+
const numericLiteral = (n) => n.kind === 'literal' && (typeof n.value === 'number' || typeof n.value === 'bigint') ? n.value : undefined;
|
|
51
|
+
if (expr.op === '+') {
|
|
52
|
+
// col + N or N + col (addition commutes)
|
|
53
|
+
if (isThisColumn(expr.left))
|
|
54
|
+
return numericLiteral(expr.right);
|
|
55
|
+
if (isThisColumn(expr.right))
|
|
56
|
+
return numericLiteral(expr.left);
|
|
57
|
+
return undefined;
|
|
58
|
+
}
|
|
59
|
+
// col - N only (N - col is not an accumulator)
|
|
60
|
+
if (!isThisColumn(expr.left))
|
|
61
|
+
return undefined;
|
|
62
|
+
const n = numericLiteral(expr.right);
|
|
63
|
+
if (n === undefined)
|
|
64
|
+
return undefined;
|
|
65
|
+
return -n;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Collects every column an assignment expression reads, so the UPDATE selector
|
|
69
|
+
* can project exactly what's needed instead of the whole row (see call site in
|
|
70
|
+
* runUpdate for why over-fetching matters here). Assignments are compiled via
|
|
71
|
+
* compileExpr before this runs, which already rejects `cast`/`aggCall`/`subquery`
|
|
72
|
+
* nodes, so those are unreachable here and need no case.
|
|
73
|
+
*/
|
|
74
|
+
function collectReferencedColumns(expr, out) {
|
|
75
|
+
switch (expr.kind) {
|
|
76
|
+
case 'column':
|
|
77
|
+
out.add(expr.name);
|
|
78
|
+
return;
|
|
79
|
+
case 'literal':
|
|
80
|
+
case 'star':
|
|
81
|
+
return;
|
|
82
|
+
case 'binop':
|
|
83
|
+
collectReferencedColumns(expr.left, out);
|
|
84
|
+
collectReferencedColumns(expr.right, out);
|
|
85
|
+
return;
|
|
86
|
+
case 'logical':
|
|
87
|
+
for (const a of expr.args)
|
|
88
|
+
collectReferencedColumns(a, out);
|
|
89
|
+
return;
|
|
90
|
+
case 'in':
|
|
91
|
+
collectReferencedColumns(expr.expr, out);
|
|
92
|
+
for (const e of expr.list)
|
|
93
|
+
collectReferencedColumns(e, out);
|
|
94
|
+
return;
|
|
95
|
+
case 'between':
|
|
96
|
+
collectReferencedColumns(expr.expr, out);
|
|
97
|
+
collectReferencedColumns(expr.low, out);
|
|
98
|
+
collectReferencedColumns(expr.high, out);
|
|
99
|
+
return;
|
|
100
|
+
case 'like':
|
|
101
|
+
collectReferencedColumns(expr.expr, out);
|
|
102
|
+
collectReferencedColumns(expr.pattern, out);
|
|
103
|
+
if (expr.escape)
|
|
104
|
+
collectReferencedColumns(expr.escape, out);
|
|
105
|
+
return;
|
|
106
|
+
case 'isNull':
|
|
107
|
+
collectReferencedColumns(expr.expr, out);
|
|
108
|
+
return;
|
|
109
|
+
case 'case':
|
|
110
|
+
for (const c of expr.cases) {
|
|
111
|
+
collectReferencedColumns(c.when, out);
|
|
112
|
+
collectReferencedColumns(c.then, out);
|
|
113
|
+
}
|
|
114
|
+
if (expr.else)
|
|
115
|
+
collectReferencedColumns(expr.else, out);
|
|
116
|
+
return;
|
|
117
|
+
case 'funcCall':
|
|
118
|
+
for (const a of expr.args)
|
|
119
|
+
collectReferencedColumns(a, out);
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Mirror the legacy ResourceBridge.upsertRecords schema-evolution path: on a
|
|
125
|
+
* dynamic-schema (non-`schemaDefined`) table, any referenced column that isn't
|
|
126
|
+
* yet an attribute is added via `Table.addAttributes` (indexed, matching legacy).
|
|
127
|
+
*
|
|
128
|
+
* Two reasons this must run, not just be skipped:
|
|
129
|
+
* - Parity of side effect: legacy INSERT/UPDATE auto-creates+indexes new
|
|
130
|
+
* columns, so the new engine must too or later queries on that column diverge.
|
|
131
|
+
* - Parity of validation: `addAttributes` enforces the attribute-name rules and
|
|
132
|
+
* throws `ClientError('Attribute names cannot include backticks or forward
|
|
133
|
+
* slashes')` for an invalid name — the same 400 the legacy path produces. This
|
|
134
|
+
* is a deterministic client error (not `EngineUnsupportedError`), so `auto`
|
|
135
|
+
* surfaces it identically rather than falling back.
|
|
136
|
+
*
|
|
137
|
+
* Called inside the write transaction (as legacy does), before any row write, so
|
|
138
|
+
* an invalid-name rejection aborts the txn with nothing persisted.
|
|
139
|
+
*/
|
|
140
|
+
async function ensureAttributes(table, columns) {
|
|
141
|
+
if (table.schemaDefined || !table.addAttributes)
|
|
142
|
+
return;
|
|
143
|
+
const existing = table.attributes ?? [];
|
|
144
|
+
const seen = new Set();
|
|
145
|
+
const newAttributes = [];
|
|
146
|
+
for (const name of columns) {
|
|
147
|
+
if (seen.has(name))
|
|
148
|
+
continue;
|
|
149
|
+
seen.add(name);
|
|
150
|
+
if (!existing.find((a) => a.name === name))
|
|
151
|
+
newAttributes.push({ name, indexed: true });
|
|
152
|
+
}
|
|
153
|
+
if (newAttributes.length > 0)
|
|
154
|
+
await table.addAttributes(newAttributes);
|
|
155
|
+
}
|
|
156
|
+
let _transactionRunner = null;
|
|
157
|
+
/** Test hook: override the transaction runner. Pass null to restore the default. */
|
|
158
|
+
function _setTransactionRunner(runner) {
|
|
159
|
+
_transactionRunner = runner;
|
|
160
|
+
}
|
|
161
|
+
function getTransactionRunner() {
|
|
162
|
+
if (_transactionRunner)
|
|
163
|
+
return _transactionRunner;
|
|
164
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
165
|
+
const mod = require('../../resources/transaction.js');
|
|
166
|
+
return mod.transaction;
|
|
167
|
+
}
|
|
168
|
+
function tableOf(bound) {
|
|
169
|
+
return bound.boundTable.resource;
|
|
170
|
+
}
|
|
171
|
+
function primaryKeyOf(boundTable) {
|
|
172
|
+
if (!boundTable.primaryKey) {
|
|
173
|
+
throw new errors_ts_1.EngineRuntimeError(`table "${boundTable.database}.${boundTable.table}" has no primary key`);
|
|
174
|
+
}
|
|
175
|
+
return boundTable.primaryKey;
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Builds the physical plan for `SELECT <projection> FROM <target> WHERE <where>`.
|
|
179
|
+
* Kept separate from execution so it runs BEFORE the write transaction is opened:
|
|
180
|
+
* if the selector can't be planned (e.g. a non-indexable WHERE), the
|
|
181
|
+
* EngineUnsupportedError is thrown before any transaction/side effect, so 'auto'
|
|
182
|
+
* mode falls back to legacy cleanly rather than aborting a half-open txn.
|
|
183
|
+
*/
|
|
184
|
+
function buildSelectorPlan(boundTable, where, projection) {
|
|
185
|
+
const select = {
|
|
186
|
+
kind: 'select',
|
|
187
|
+
distinct: false,
|
|
188
|
+
projections: projection,
|
|
189
|
+
from: { database: boundTable.database, table: boundTable.table, alias: boundTable.alias },
|
|
190
|
+
joins: [],
|
|
191
|
+
where,
|
|
192
|
+
};
|
|
193
|
+
return (0, plan_ts_1.compileToPhysical)((0, optimize_ts_1.optimize)((0, build_ts_1.buildLogicalPlan)((0, bind_ts_1.bindSelect)(select))));
|
|
194
|
+
}
|
|
195
|
+
async function runInsert(bound, ctx) {
|
|
196
|
+
const table = tableOf(bound);
|
|
197
|
+
const pk = primaryKeyOf(bound.boundTable);
|
|
198
|
+
// Evaluate every VALUES row up front (literals / constant expressions — no
|
|
199
|
+
// per-table row context). The normalizer only produces the VALUES (array)
|
|
200
|
+
// form; INSERT … SELECT is rejected earlier.
|
|
201
|
+
if (!Array.isArray(bound.values)) {
|
|
202
|
+
throw new errors_ts_1.EngineRuntimeError('INSERT … SELECT is not supported');
|
|
203
|
+
}
|
|
204
|
+
const records = bound.values.map((row) => {
|
|
205
|
+
const record = {};
|
|
206
|
+
for (let i = 0; i < bound.columns.length; i++) {
|
|
207
|
+
record[bound.columns[i]] = (0, compile_ts_1.compileExpr)(row[i], false).eval({});
|
|
208
|
+
}
|
|
209
|
+
return record;
|
|
210
|
+
});
|
|
211
|
+
const transaction = getTransactionRunner();
|
|
212
|
+
const context = { user: ctx.user };
|
|
213
|
+
return transaction(context, async () => {
|
|
214
|
+
// Auto-create + validate any new columns first (legacy parity, and the
|
|
215
|
+
// source of the attribute-name validation), before any row write.
|
|
216
|
+
await ensureAttributes(table, bound.columns);
|
|
217
|
+
const inserted_hashes = [];
|
|
218
|
+
const skipped_hashes = [];
|
|
219
|
+
for (const record of records) {
|
|
220
|
+
let id = record[pk];
|
|
221
|
+
if (id == null) {
|
|
222
|
+
// No primary key supplied: generate one (UUID by default).
|
|
223
|
+
id = table.getNewId ? table.getNewId() : undefined;
|
|
224
|
+
if (id == null)
|
|
225
|
+
throw new errors_ts_1.EngineRuntimeError('could not generate a primary key for INSERT');
|
|
226
|
+
record[pk] = id;
|
|
227
|
+
}
|
|
228
|
+
else {
|
|
229
|
+
// INSERT (not upsert) skips rows whose key already exists, matching
|
|
230
|
+
// the legacy createRecords semantics (reported in skipped_hashes).
|
|
231
|
+
const existing = await table.get(id, context);
|
|
232
|
+
if (existing != null) {
|
|
233
|
+
skipped_hashes.push(id);
|
|
234
|
+
continue;
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
await table.put(record, context);
|
|
238
|
+
inserted_hashes.push(id);
|
|
239
|
+
}
|
|
240
|
+
const total = inserted_hashes.length + skipped_hashes.length;
|
|
241
|
+
return {
|
|
242
|
+
message: `inserted ${inserted_hashes.length} of ${total} records`,
|
|
243
|
+
inserted_hashes,
|
|
244
|
+
skipped_hashes,
|
|
245
|
+
};
|
|
246
|
+
});
|
|
247
|
+
}
|
|
248
|
+
async function runUpdate(bound, ctx) {
|
|
249
|
+
const table = tableOf(bound);
|
|
250
|
+
const pk = primaryKeyOf(bound.boundTable);
|
|
251
|
+
// A `col = col ± N` assignment is applied as an atomic Addition delta (see
|
|
252
|
+
// selfIncrementDelta); every other assignment is evaluated against the matched
|
|
253
|
+
// row and written as an absolute value.
|
|
254
|
+
const assignments = bound.assignments.map((a) => {
|
|
255
|
+
const delta = selfIncrementDelta(a.column, a.expr);
|
|
256
|
+
return delta === undefined
|
|
257
|
+
? { column: a.column, eval: (0, compile_ts_1.compileExpr)(a.expr, false).eval }
|
|
258
|
+
: { column: a.column, delta };
|
|
259
|
+
});
|
|
260
|
+
// Plan the selector before opening the transaction (clean fallback on reject).
|
|
261
|
+
// Project only the primary key plus whatever columns a row-dependent assignment
|
|
262
|
+
// actually reads (e.g. `total = price * qty`) — not the whole row. A `col = col
|
|
263
|
+
// ± N` delta reads nothing (it's applied as an Addition, never evaluated against
|
|
264
|
+
// the row), and most SET clauses are plain literals, so the common case needs
|
|
265
|
+
// only the primary key — the same minimal read legacy's SQL UPDATE and this
|
|
266
|
+
// module's own runDelete already use.
|
|
267
|
+
const neededColumns = new Set([pk]);
|
|
268
|
+
bound.assignments.forEach((a, i) => {
|
|
269
|
+
if (!('delta' in assignments[i]))
|
|
270
|
+
collectReferencedColumns(a.expr, neededColumns);
|
|
271
|
+
});
|
|
272
|
+
const projection = [...neededColumns].map((name) => ({
|
|
273
|
+
expr: { kind: 'column', name },
|
|
274
|
+
}));
|
|
275
|
+
const selector = buildSelectorPlan(bound.boundTable, bound.where, projection);
|
|
276
|
+
const transaction = getTransactionRunner();
|
|
277
|
+
const context = { user: ctx.user };
|
|
278
|
+
// The row-finder above is a SELECT, and a plain SELECT is right to hide a row
|
|
279
|
+
// whose TTL has passed but hasn't been swept yet. An UPDATE isn't a SELECT
|
|
280
|
+
// though: it's about to overwrite that row's TTL, and every other write surface
|
|
281
|
+
// (REST PUT/PATCH, ops update) still finds and resets a not-yet-swept-but-expired
|
|
282
|
+
// row because they load it by id directly, bypassing the freshness check a read
|
|
283
|
+
// applies. Without includeExpiredRows, the row-finder would drop such a row from
|
|
284
|
+
// its result, so the UPDATE silently touches nothing and the TTL never resets
|
|
285
|
+
// (QA-269).
|
|
286
|
+
const selectCtx = { ...ctx, includeExpiredRows: true };
|
|
287
|
+
return transaction(context, async () => {
|
|
288
|
+
// Auto-create + validate any new columns the SET clause introduces
|
|
289
|
+
// (legacy parity + attribute-name validation), before any row write.
|
|
290
|
+
await ensureAttributes(table, assignments.map((a) => a.column));
|
|
291
|
+
const rows = await (0, runSelect_ts_1.runSelect)(selector, selectCtx);
|
|
292
|
+
const update_hashes = [];
|
|
293
|
+
const skipped_hashes = [];
|
|
294
|
+
for (const row of rows) {
|
|
295
|
+
const id = row[pk];
|
|
296
|
+
if (id == null) {
|
|
297
|
+
skipped_hashes.push(id);
|
|
298
|
+
continue;
|
|
299
|
+
}
|
|
300
|
+
const patch = {};
|
|
301
|
+
for (const a of assignments) {
|
|
302
|
+
patch[a.column] = 'delta' in a ? new tracked_ts_1.Addition(a.delta) : a.eval(row);
|
|
303
|
+
}
|
|
304
|
+
await table.patch(id, patch, context);
|
|
305
|
+
update_hashes.push(id);
|
|
306
|
+
}
|
|
307
|
+
const total = update_hashes.length + skipped_hashes.length;
|
|
308
|
+
return {
|
|
309
|
+
message: `updated ${update_hashes.length} of ${total} records`,
|
|
310
|
+
update_hashes,
|
|
311
|
+
skipped_hashes,
|
|
312
|
+
};
|
|
313
|
+
});
|
|
314
|
+
}
|
|
315
|
+
async function runDelete(bound, ctx) {
|
|
316
|
+
const table = tableOf(bound);
|
|
317
|
+
const pk = primaryKeyOf(bound.boundTable);
|
|
318
|
+
// Plan the selector before opening the transaction (clean fallback on reject).
|
|
319
|
+
// Only the primary key is needed to delete.
|
|
320
|
+
const selector = buildSelectorPlan(bound.boundTable, bound.where, [{ expr: { kind: 'column', name: pk } }]);
|
|
321
|
+
const transaction = getTransactionRunner();
|
|
322
|
+
const context = { user: ctx.user };
|
|
323
|
+
// Same reasoning as runUpdate: REST DELETE removes a not-yet-swept-but-expired
|
|
324
|
+
// row immediately because it targets by id directly; the row-finder here should
|
|
325
|
+
// match that rather than silently skipping a row the sweep hasn't caught up to yet.
|
|
326
|
+
const selectCtx = { ...ctx, includeExpiredRows: true };
|
|
327
|
+
return transaction(context, async () => {
|
|
328
|
+
const rows = await (0, runSelect_ts_1.runSelect)(selector, selectCtx);
|
|
329
|
+
const deleted_hashes = [];
|
|
330
|
+
const skipped_hashes = [];
|
|
331
|
+
for (const row of rows) {
|
|
332
|
+
const id = row[pk];
|
|
333
|
+
if (id == null) {
|
|
334
|
+
skipped_hashes.push(id);
|
|
335
|
+
continue;
|
|
336
|
+
}
|
|
337
|
+
await table.delete(id, context);
|
|
338
|
+
deleted_hashes.push(id);
|
|
339
|
+
}
|
|
340
|
+
const total = deleted_hashes.length + skipped_hashes.length;
|
|
341
|
+
// Legacy SQL DELETE pluralizes "record" by the deleted count
|
|
342
|
+
// (sqlTranslator/deleteTranslator.ts + harperBridge.deleteRecords):
|
|
343
|
+
// "1 of 1 record …" but "0 of 0 records …".
|
|
344
|
+
const noun = deleted_hashes.length === 1 ? 'record' : 'records';
|
|
345
|
+
return {
|
|
346
|
+
message: `${deleted_hashes.length} of ${total} ${noun} successfully deleted`,
|
|
347
|
+
deleted_hashes,
|
|
348
|
+
skipped_hashes,
|
|
349
|
+
};
|
|
350
|
+
});
|
|
351
|
+
}
|
|
352
|
+
//# sourceMappingURL=runMutation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runMutation.js","sourceRoot":"","sources":["../../../sqlEngine/executor/runMutation.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Drives the root iterator for a SELECT plan and shapes the result.
|
|
3
|
+
* Phase 0 stub.
|
|
4
|
+
*/
|
|
5
|
+
import type { PhysicalOp } from '../physical/op.ts';
|
|
6
|
+
import type { Row, SqlEngineContext } from '../types.ts';
|
|
7
|
+
export declare function runSelect(plan: PhysicalOp, ctx: SqlEngineContext): Promise<Row[]>;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Drives the root iterator for a SELECT plan and shapes the result.
|
|
4
|
+
* Phase 0 stub.
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.runSelect = runSelect;
|
|
8
|
+
async function runSelect(plan, ctx) {
|
|
9
|
+
const out = [];
|
|
10
|
+
for await (const row of plan.execute(ctx))
|
|
11
|
+
out.push(row);
|
|
12
|
+
return out;
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=runSelect.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runSelect.js","sourceRoot":"","sources":["../../../sqlEngine/executor/runSelect.ts"],"names":[],"mappings":";AAAA;;;GAGG;;AAKH,8BAIC;AAJM,KAAK,UAAU,SAAS,CAAC,IAAgB,EAAE,GAAqB;IACtE,MAAM,GAAG,GAAU,EAAE,CAAC;IACtB,IAAI,KAAK,EAAE,MAAM,GAAG,IAAI,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC;QAAE,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACzD,OAAO,GAAG,CAAC;AACZ,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lowers an ExprNode to a row-context closure.
|
|
3
|
+
*
|
|
4
|
+
* The compiler runs once per query at physical-plan time; the resulting
|
|
5
|
+
* closure is invoked per row by Filter/Project operators. SQL three-valued
|
|
6
|
+
* logic for AND/OR/NOT is handled here so residual filters match Resource API
|
|
7
|
+
* semantics (NULL → drop). Coercion is loose to match AlaSQL behavior.
|
|
8
|
+
*/
|
|
9
|
+
import type { ExprNode } from '../parser/ast.ts';
|
|
10
|
+
import type { Row, SqlType } from '../types.ts';
|
|
11
|
+
export interface CompiledExpr {
|
|
12
|
+
eval(row: Row): unknown;
|
|
13
|
+
type: SqlType;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Compiles an expression to a per-row closure.
|
|
17
|
+
*
|
|
18
|
+
* When `qualified` is true (join queries), column references are looked up by
|
|
19
|
+
* their canonical `<alias>.<name>` key — the binder has set `column.table` to
|
|
20
|
+
* the owning alias and the scan output is keyed the same way (see
|
|
21
|
+
* physical/PhysicalQualify). Single-table queries pass `qualified = false` and
|
|
22
|
+
* columns resolve by bare name.
|
|
23
|
+
*/
|
|
24
|
+
export declare function compileExpr(expr: ExprNode, qualified?: boolean): CompiledExpr;
|