@prisma-next/sql-runtime 0.5.0-dev.23 → 0.5.0-dev.25
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/{exports-BET5HxxT.mjs → exports-CwCgOv6w.mjs} +100 -176
- package/dist/exports-CwCgOv6w.mjs.map +1 -0
- package/dist/index-Df2GsLSH.d.mts.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/test/utils.mjs +1 -1
- package/package.json +9 -9
- package/src/codecs/decoding.ts +77 -99
- package/src/codecs/encoding.ts +47 -34
- package/src/guardrails/raw.ts +1 -50
- package/src/middleware/before-compile-chain.ts +1 -31
- package/src/middleware/budgets.ts +16 -89
- package/src/sql-runtime.ts +6 -4
- package/dist/exports-BET5HxxT.mjs.map +0 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { AsyncIterableResult, RuntimeCore, checkMiddlewareCompatibility, isRuntimeError, runWithMiddleware, runtimeError } from "@prisma-next/framework-components/runtime";
|
|
2
2
|
import { type } from "arktype";
|
|
3
|
-
import { createCodecRegistry, isQueryAst } from "@prisma-next/sql-relational-core/ast";
|
|
3
|
+
import { collectOrderedParamRefs, createCodecRegistry, isQueryAst } from "@prisma-next/sql-relational-core/ast";
|
|
4
4
|
import { ifDefined } from "@prisma-next/utils/defined";
|
|
5
5
|
import { checkContractComponentRequirements } from "@prisma-next/framework-components/components";
|
|
6
6
|
import { createExecutionStack } from "@prisma-next/framework-components/execution";
|
|
@@ -124,25 +124,21 @@ function hasAggregateWithoutGroupBy(ast) {
|
|
|
124
124
|
if (ast.groupBy !== void 0) return false;
|
|
125
125
|
return ast.projection.some((item) => item.expr.kind === "aggregate");
|
|
126
126
|
}
|
|
127
|
-
function
|
|
127
|
+
function primaryTableFromAst(ast) {
|
|
128
|
+
switch (ast.from.kind) {
|
|
129
|
+
case "table-source": return ast.from.name;
|
|
130
|
+
case "derived-table-source": return ast.from.alias;
|
|
131
|
+
default: return;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
function estimateRowsFromAst(ast, tableRows, defaultTableRows, hasAggregateWithoutGroup) {
|
|
128
135
|
if (hasAggregateWithoutGroup) return 1;
|
|
129
|
-
const table =
|
|
136
|
+
const table = primaryTableFromAst(ast);
|
|
130
137
|
if (!table) return null;
|
|
131
138
|
const tableEstimate = tableRows[table] ?? defaultTableRows;
|
|
132
139
|
if (ast.limit !== void 0) return Math.min(ast.limit, tableEstimate);
|
|
133
140
|
return tableEstimate;
|
|
134
141
|
}
|
|
135
|
-
function estimateRowsFromHeuristics(plan, tableRows, defaultTableRows) {
|
|
136
|
-
const table = plan.meta.refs?.tables?.[0];
|
|
137
|
-
if (!table) return null;
|
|
138
|
-
const tableEstimate = tableRows[table] ?? defaultTableRows;
|
|
139
|
-
const limit = plan.meta.annotations?.["limit"];
|
|
140
|
-
if (typeof limit === "number") return Math.min(limit, tableEstimate);
|
|
141
|
-
return tableEstimate;
|
|
142
|
-
}
|
|
143
|
-
function hasDetectableLimitFromHeuristics(plan) {
|
|
144
|
-
return typeof plan.meta.annotations?.["limit"] === "number";
|
|
145
|
-
}
|
|
146
142
|
function emitBudgetViolation(error, shouldBlock, ctx) {
|
|
147
143
|
if (shouldBlock) throw error;
|
|
148
144
|
ctx.log.warn({
|
|
@@ -163,11 +159,7 @@ function budgets(options) {
|
|
|
163
159
|
familyId: "sql",
|
|
164
160
|
async beforeExecute(plan, ctx) {
|
|
165
161
|
observedRowsByPlan.set(plan, { count: 0 });
|
|
166
|
-
if (isQueryAst(plan.ast))
|
|
167
|
-
if (plan.ast.kind === "select") return evaluateSelectAst(plan, plan.ast, ctx);
|
|
168
|
-
return;
|
|
169
|
-
}
|
|
170
|
-
return evaluateWithHeuristics(plan, ctx);
|
|
162
|
+
if (isQueryAst(plan.ast) && plan.ast.kind === "select") return evaluateSelectAst(plan.ast, ctx);
|
|
171
163
|
},
|
|
172
164
|
async onRow(_row, plan, _ctx) {
|
|
173
165
|
const state = observedRowsByPlan.get(plan);
|
|
@@ -190,9 +182,9 @@ function budgets(options) {
|
|
|
190
182
|
}
|
|
191
183
|
}
|
|
192
184
|
});
|
|
193
|
-
function evaluateSelectAst(
|
|
185
|
+
function evaluateSelectAst(ast, ctx) {
|
|
194
186
|
const hasAggNoGroup = hasAggregateWithoutGroupBy(ast);
|
|
195
|
-
const estimated = estimateRowsFromAst(ast, tableRows, defaultTableRows,
|
|
187
|
+
const estimated = estimateRowsFromAst(ast, tableRows, defaultTableRows, hasAggNoGroup);
|
|
196
188
|
const isUnbounded = ast.limit === void 0 && !hasAggNoGroup;
|
|
197
189
|
const shouldBlock = rowSeverity === "error" || ctx.mode === "strict";
|
|
198
190
|
if (isUnbounded) {
|
|
@@ -216,35 +208,6 @@ function budgets(options) {
|
|
|
216
208
|
maxRows
|
|
217
209
|
}), shouldBlock, ctx);
|
|
218
210
|
}
|
|
219
|
-
async function evaluateWithHeuristics(plan, ctx) {
|
|
220
|
-
const estimated = estimateRowsFromHeuristics(plan, tableRows, defaultTableRows);
|
|
221
|
-
const isUnbounded = !hasDetectableLimitFromHeuristics(plan);
|
|
222
|
-
const isSelect = plan.sql.trimStart().toUpperCase().startsWith("SELECT");
|
|
223
|
-
const shouldBlock = rowSeverity === "error" || ctx.mode === "strict";
|
|
224
|
-
if (isSelect && isUnbounded) {
|
|
225
|
-
if (estimated !== null && estimated >= maxRows) {
|
|
226
|
-
emitBudgetViolation(runtimeError("BUDGET.ROWS_EXCEEDED", "Unbounded SELECT query exceeds budget", {
|
|
227
|
-
source: "heuristic",
|
|
228
|
-
estimatedRows: estimated,
|
|
229
|
-
maxRows
|
|
230
|
-
}), shouldBlock, ctx);
|
|
231
|
-
return;
|
|
232
|
-
}
|
|
233
|
-
emitBudgetViolation(runtimeError("BUDGET.ROWS_EXCEEDED", "Unbounded SELECT query exceeds budget", {
|
|
234
|
-
source: "heuristic",
|
|
235
|
-
maxRows
|
|
236
|
-
}), shouldBlock, ctx);
|
|
237
|
-
return;
|
|
238
|
-
}
|
|
239
|
-
if (estimated !== null) {
|
|
240
|
-
if (estimated > maxRows) emitBudgetViolation(runtimeError("BUDGET.ROWS_EXCEEDED", "Estimated row count exceeds budget", {
|
|
241
|
-
source: "heuristic",
|
|
242
|
-
estimatedRows: estimated,
|
|
243
|
-
maxRows
|
|
244
|
-
}), shouldBlock, ctx);
|
|
245
|
-
return;
|
|
246
|
-
}
|
|
247
|
-
}
|
|
248
211
|
}
|
|
249
212
|
|
|
250
213
|
//#endregion
|
|
@@ -277,24 +240,12 @@ function evaluateRawGuardrails(plan, config) {
|
|
|
277
240
|
sql: snippet(plan.sql),
|
|
278
241
|
intent: plan.meta.annotations?.["intent"]
|
|
279
242
|
}));
|
|
280
|
-
const refs = plan.meta.refs;
|
|
281
|
-
if (refs) evaluateIndexCoverage(refs, lints$1);
|
|
282
243
|
return {
|
|
283
244
|
lints: lints$1,
|
|
284
245
|
budgets: budgets$1,
|
|
285
246
|
statement: statementType
|
|
286
247
|
};
|
|
287
248
|
}
|
|
288
|
-
function evaluateIndexCoverage(refs, lints$1) {
|
|
289
|
-
const predicateColumns = refs.columns ?? [];
|
|
290
|
-
if (predicateColumns.length === 0) return;
|
|
291
|
-
const indexes = refs.indexes ?? [];
|
|
292
|
-
if (indexes.length === 0) {
|
|
293
|
-
lints$1.push(createLint("LINT.UNINDEXED_PREDICATE", "warn", "Raw SQL plan predicates lack supporting indexes", { predicates: predicateColumns }));
|
|
294
|
-
return;
|
|
295
|
-
}
|
|
296
|
-
if (!predicateColumns.every((column) => indexes.some((index) => index.table === column.table && index.columns.some((col) => col.toLowerCase() === column.column.toLowerCase())))) lints$1.push(createLint("LINT.UNINDEXED_PREDICATE", "warn", "Raw SQL plan predicates lack supporting indexes", { predicates: predicateColumns }));
|
|
297
|
-
}
|
|
298
249
|
function classifyStatement(sql) {
|
|
299
250
|
const trimmed = sql.trim();
|
|
300
251
|
const lower = trimmed.toLowerCase();
|
|
@@ -781,49 +732,51 @@ function formatErrorSummary(errors) {
|
|
|
781
732
|
//#endregion
|
|
782
733
|
//#region src/codecs/decoding.ts
|
|
783
734
|
const WIRE_PREVIEW_LIMIT = 100;
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
735
|
+
const EMPTY_INCLUDE_ALIASES = /* @__PURE__ */ new Set();
|
|
736
|
+
function isAstBackedPlan(plan) {
|
|
737
|
+
return plan.ast !== void 0;
|
|
738
|
+
}
|
|
739
|
+
function projectionListFromAst(ast) {
|
|
740
|
+
if (ast.kind === "select") return ast.projection;
|
|
741
|
+
return ast.returning;
|
|
742
|
+
}
|
|
743
|
+
function buildDecodeContext(plan, registry) {
|
|
744
|
+
if (!isAstBackedPlan(plan)) return {
|
|
745
|
+
aliases: void 0,
|
|
746
|
+
codecs: /* @__PURE__ */ new Map(),
|
|
747
|
+
columnRefs: /* @__PURE__ */ new Map(),
|
|
748
|
+
includeAliases: EMPTY_INCLUDE_ALIASES
|
|
749
|
+
};
|
|
750
|
+
const projection = projectionListFromAst(plan.ast);
|
|
751
|
+
if (!projection) return {
|
|
752
|
+
aliases: void 0,
|
|
753
|
+
codecs: /* @__PURE__ */ new Map(),
|
|
754
|
+
columnRefs: /* @__PURE__ */ new Map(),
|
|
755
|
+
includeAliases: EMPTY_INCLUDE_ALIASES
|
|
756
|
+
};
|
|
757
|
+
const aliases = [];
|
|
758
|
+
const codecs = /* @__PURE__ */ new Map();
|
|
759
|
+
const columnRefs = /* @__PURE__ */ new Map();
|
|
760
|
+
const includeAliases = /* @__PURE__ */ new Set();
|
|
761
|
+
for (const item of projection) {
|
|
762
|
+
aliases.push(item.alias);
|
|
763
|
+
if (item.codecId) {
|
|
764
|
+
const codec$1 = registry.get(item.codecId);
|
|
765
|
+
if (codec$1) codecs.set(item.alias, codec$1);
|
|
795
766
|
}
|
|
767
|
+
if (item.expr.kind === "column-ref") columnRefs.set(item.alias, {
|
|
768
|
+
table: item.expr.table,
|
|
769
|
+
column: item.expr.column
|
|
770
|
+
});
|
|
771
|
+
else if (item.expr.kind === "subquery" || item.expr.kind === "json-array-agg") includeAliases.add(item.alias);
|
|
796
772
|
}
|
|
797
|
-
return null;
|
|
798
|
-
}
|
|
799
|
-
/**
|
|
800
|
-
* Builds a lookup index from column name → { table, column } ref.
|
|
801
|
-
* Called once per decodeRow invocation to avoid O(aliases × refs) linear scans.
|
|
802
|
-
*/
|
|
803
|
-
function buildColumnRefIndex(plan) {
|
|
804
|
-
const columns = plan.meta.refs?.columns;
|
|
805
|
-
if (!columns) return null;
|
|
806
|
-
const index = /* @__PURE__ */ new Map();
|
|
807
|
-
for (const ref of columns) index.set(ref.column, ref);
|
|
808
|
-
return index;
|
|
809
|
-
}
|
|
810
|
-
function parseProjectionRef(value) {
|
|
811
|
-
if (value.startsWith("include:") || value.startsWith("operation:")) return null;
|
|
812
|
-
const separatorIndex = value.indexOf(".");
|
|
813
|
-
if (separatorIndex <= 0 || separatorIndex === value.length - 1) return null;
|
|
814
773
|
return {
|
|
815
|
-
|
|
816
|
-
|
|
774
|
+
aliases,
|
|
775
|
+
codecs,
|
|
776
|
+
columnRefs,
|
|
777
|
+
includeAliases
|
|
817
778
|
};
|
|
818
779
|
}
|
|
819
|
-
function resolveColumnRefForAlias(alias, projection, fallbackColumnRefIndex) {
|
|
820
|
-
if (projection && !Array.isArray(projection)) {
|
|
821
|
-
const mappedRef = projection[alias];
|
|
822
|
-
if (typeof mappedRef !== "string") return;
|
|
823
|
-
return parseProjectionRef(mappedRef) ?? void 0;
|
|
824
|
-
}
|
|
825
|
-
return fallbackColumnRefIndex?.get(alias);
|
|
826
|
-
}
|
|
827
780
|
function previewWireValue(wireValue) {
|
|
828
781
|
if (typeof wireValue === "string") return wireValue.length > WIRE_PREVIEW_LIMIT ? `${wireValue.substring(0, WIRE_PREVIEW_LIMIT)}...` : wireValue;
|
|
829
782
|
return String(wireValue).substring(0, WIRE_PREVIEW_LIMIT);
|
|
@@ -870,11 +823,11 @@ function decodeIncludeAggregate(alias, wireValue) {
|
|
|
870
823
|
* `codec.decode → await → JSON-Schema validate → return plain value` — so
|
|
871
824
|
* sync- and async-authored codecs are indistinguishable to callers.
|
|
872
825
|
*/
|
|
873
|
-
async function decodeField(alias, wireValue,
|
|
874
|
-
if (wireValue === null
|
|
875
|
-
const codec$1 =
|
|
826
|
+
async function decodeField(alias, wireValue, ctx, jsonValidators) {
|
|
827
|
+
if (wireValue === null) return null;
|
|
828
|
+
const codec$1 = ctx.codecs.get(alias);
|
|
876
829
|
if (!codec$1) return wireValue;
|
|
877
|
-
const ref =
|
|
830
|
+
const ref = ctx.columnRefs.get(alias);
|
|
878
831
|
let decoded;
|
|
879
832
|
try {
|
|
880
833
|
decoded = await codec$1.decode(wireValue);
|
|
@@ -897,19 +850,21 @@ async function decodeField(alias, wireValue, plan, registry, jsonValidators, pro
|
|
|
897
850
|
* original error attached on `cause`.
|
|
898
851
|
*/
|
|
899
852
|
async function decodeRow(row, plan, registry, jsonValidators) {
|
|
900
|
-
const
|
|
901
|
-
const
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
853
|
+
const ctx = buildDecodeContext(plan, registry);
|
|
854
|
+
const aliases = ctx.aliases ?? Object.keys(row);
|
|
855
|
+
if (ctx.aliases !== void 0) {
|
|
856
|
+
for (const alias of ctx.aliases) if (!Object.hasOwn(row, alias)) throw runtimeError("RUNTIME.DECODE_FAILED", `Row missing projection alias "${alias}"`, {
|
|
857
|
+
alias,
|
|
858
|
+
expectedAliases: ctx.aliases,
|
|
859
|
+
presentKeys: Object.keys(row)
|
|
860
|
+
});
|
|
861
|
+
}
|
|
906
862
|
const tasks = [];
|
|
907
863
|
const includeIndices = [];
|
|
908
864
|
for (let i = 0; i < aliases.length; i++) {
|
|
909
865
|
const alias = aliases[i];
|
|
910
866
|
const wireValue = row[alias];
|
|
911
|
-
|
|
912
|
-
if (typeof projectionValue === "string" && projectionValue.startsWith("include:")) {
|
|
867
|
+
if (ctx.includeAliases.has(alias)) {
|
|
913
868
|
includeIndices.push({
|
|
914
869
|
index: i,
|
|
915
870
|
alias,
|
|
@@ -918,7 +873,7 @@ async function decodeRow(row, plan, registry, jsonValidators) {
|
|
|
918
873
|
tasks.push(Promise.resolve(void 0));
|
|
919
874
|
continue;
|
|
920
875
|
}
|
|
921
|
-
tasks.push(decodeField(alias, wireValue,
|
|
876
|
+
tasks.push(decodeField(alias, wireValue, ctx, jsonValidators));
|
|
922
877
|
}
|
|
923
878
|
const settled = await Promise.all(tasks);
|
|
924
879
|
for (const entry of includeIndices) settled[entry.index] = decodeIncludeAggregate(entry.alias, entry.value);
|
|
@@ -929,18 +884,15 @@ async function decodeRow(row, plan, registry, jsonValidators) {
|
|
|
929
884
|
|
|
930
885
|
//#endregion
|
|
931
886
|
//#region src/codecs/encoding.ts
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
return
|
|
938
|
-
}
|
|
939
|
-
function paramLabel(paramDescriptor, paramIndex) {
|
|
940
|
-
return paramDescriptor.name ?? `param[${paramIndex}]`;
|
|
887
|
+
const NO_METADATA = Object.freeze({
|
|
888
|
+
codecId: void 0,
|
|
889
|
+
name: void 0
|
|
890
|
+
});
|
|
891
|
+
function paramLabel(metadata, paramIndex) {
|
|
892
|
+
return metadata.name ?? `param[${paramIndex}]`;
|
|
941
893
|
}
|
|
942
|
-
function wrapEncodeFailure(error,
|
|
943
|
-
const label = paramLabel(
|
|
894
|
+
function wrapEncodeFailure(error, metadata, paramIndex, codecId) {
|
|
895
|
+
const label = paramLabel(metadata, paramIndex);
|
|
944
896
|
const wrapped = runtimeError("RUNTIME.ENCODE_FAILED", `Failed to encode parameter ${label} with codec '${codecId}': ${error instanceof Error ? error.message : String(error)}`, {
|
|
945
897
|
label,
|
|
946
898
|
codec: codecId,
|
|
@@ -949,21 +901,15 @@ function wrapEncodeFailure(error, paramDescriptor, paramIndex, codecId) {
|
|
|
949
901
|
wrapped.cause = error;
|
|
950
902
|
throw wrapped;
|
|
951
903
|
}
|
|
952
|
-
|
|
953
|
-
* Encodes a single parameter through its codec. Always awaits codec.encode so
|
|
954
|
-
* a Promise can never leak into the driver, even if a sync-authored codec is
|
|
955
|
-
* lifted to async by the codec() factory. Failures are wrapped in
|
|
956
|
-
* `RUNTIME.ENCODE_FAILED` with `{ label, codec, paramIndex }` and the original
|
|
957
|
-
* error attached on `cause`.
|
|
958
|
-
*/
|
|
959
|
-
async function encodeParam(value, paramDescriptor, paramIndex, registry) {
|
|
904
|
+
async function encodeParamValue(value, metadata, paramIndex, registry) {
|
|
960
905
|
if (value === null || value === void 0) return null;
|
|
961
|
-
|
|
906
|
+
if (!metadata.codecId) return value;
|
|
907
|
+
const codec$1 = registry.get(metadata.codecId);
|
|
962
908
|
if (!codec$1) return value;
|
|
963
909
|
try {
|
|
964
910
|
return await codec$1.encode(value);
|
|
965
911
|
} catch (error) {
|
|
966
|
-
wrapEncodeFailure(error,
|
|
912
|
+
wrapEncodeFailure(error, metadata, paramIndex, codec$1.id);
|
|
967
913
|
}
|
|
968
914
|
}
|
|
969
915
|
/**
|
|
@@ -973,19 +919,20 @@ async function encodeParam(value, paramDescriptor, paramIndex, registry) {
|
|
|
973
919
|
*/
|
|
974
920
|
async function encodeParams(plan, registry) {
|
|
975
921
|
if (plan.params.length === 0) return plan.params;
|
|
976
|
-
const descriptorCount = plan.meta.paramDescriptors.length;
|
|
977
922
|
const paramCount = plan.params.length;
|
|
978
|
-
const
|
|
979
|
-
|
|
980
|
-
const
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
923
|
+
const metadata = new Array(paramCount).fill(NO_METADATA);
|
|
924
|
+
if (plan.ast) {
|
|
925
|
+
const refs = collectOrderedParamRefs(plan.ast);
|
|
926
|
+
for (let i = 0; i < paramCount && i < refs.length; i++) {
|
|
927
|
+
const ref = refs[i];
|
|
928
|
+
if (ref) metadata[i] = {
|
|
929
|
+
codecId: ref.codecId,
|
|
930
|
+
name: ref.name
|
|
931
|
+
};
|
|
932
|
+
}
|
|
988
933
|
}
|
|
934
|
+
const tasks = new Array(paramCount);
|
|
935
|
+
for (let i = 0; i < paramCount; i++) tasks[i] = encodeParamValue(plan.params[i], metadata[i] ?? NO_METADATA, i, registry);
|
|
989
936
|
const encoded = await Promise.all(tasks);
|
|
990
937
|
return Object.freeze(encoded);
|
|
991
938
|
}
|
|
@@ -1024,32 +971,7 @@ async function runBeforeCompileChain(middleware, initial, ctx) {
|
|
|
1024
971
|
});
|
|
1025
972
|
current = result;
|
|
1026
973
|
}
|
|
1027
|
-
|
|
1028
|
-
const paramDescriptors = deriveParamDescriptorsFromAst(current.ast);
|
|
1029
|
-
const meta = {
|
|
1030
|
-
...current.meta,
|
|
1031
|
-
paramDescriptors
|
|
1032
|
-
};
|
|
1033
|
-
return {
|
|
1034
|
-
ast: current.ast,
|
|
1035
|
-
meta
|
|
1036
|
-
};
|
|
1037
|
-
}
|
|
1038
|
-
function deriveParamDescriptorsFromAst(ast) {
|
|
1039
|
-
const refs = ast.collectParamRefs();
|
|
1040
|
-
const seen = /* @__PURE__ */ new Set();
|
|
1041
|
-
const descriptors = [];
|
|
1042
|
-
for (const ref of refs) {
|
|
1043
|
-
if (seen.has(ref)) continue;
|
|
1044
|
-
seen.add(ref);
|
|
1045
|
-
descriptors.push({
|
|
1046
|
-
index: descriptors.length + 1,
|
|
1047
|
-
...ref.name !== void 0 ? { name: ref.name } : {},
|
|
1048
|
-
source: "dsl",
|
|
1049
|
-
...ref.codecId !== void 0 ? { codecId: ref.codecId } : {}
|
|
1050
|
-
});
|
|
1051
|
-
}
|
|
1052
|
-
return descriptors;
|
|
974
|
+
return current;
|
|
1053
975
|
}
|
|
1054
976
|
|
|
1055
977
|
//#endregion
|
|
@@ -1151,10 +1073,12 @@ var SqlRuntimeImpl = class extends RuntimeCore {
|
|
|
1151
1073
|
}
|
|
1152
1074
|
/**
|
|
1153
1075
|
* SQL pre-compile hook. Runs the registered middleware `beforeCompile`
|
|
1154
|
-
* chain over the plan's draft (AST + meta)
|
|
1155
|
-
*
|
|
1156
|
-
*
|
|
1157
|
-
*
|
|
1076
|
+
* chain over the plan's draft (AST + meta). Returns the original plan
|
|
1077
|
+
* unchanged when no middleware rewrote the AST; otherwise returns a new
|
|
1078
|
+
* plan carrying the rewritten AST and meta. The AST is the authoritative
|
|
1079
|
+
* source of execution metadata, so a rewrite needs no sidecar
|
|
1080
|
+
* reconciliation here — the lowering adapter and the encoder both walk
|
|
1081
|
+
* the rewritten AST directly.
|
|
1158
1082
|
*/
|
|
1159
1083
|
async runBeforeCompile(plan) {
|
|
1160
1084
|
const rewrittenDraft = await runBeforeCompileChain(this.middleware, {
|
|
@@ -1359,4 +1283,4 @@ function createRuntime(options) {
|
|
|
1359
1283
|
|
|
1360
1284
|
//#endregion
|
|
1361
1285
|
export { readContractMarker as a, createSqlExecutionStack as c, parseContractMarkerRow as d, lowerSqlPlan as f, validateContractCodecMappings as h, ensureTableStatement as i, lints as l, validateCodecRegistryCompleteness as m, withTransaction as n, writeContractMarker as o, extractCodecIds as p, ensureSchemaStatement as r, createExecutionContext as s, createRuntime as t, budgets as u };
|
|
1362
|
-
//# sourceMappingURL=exports-
|
|
1286
|
+
//# sourceMappingURL=exports-CwCgOv6w.mjs.map
|