@rex0220/kintone-sql-tools 3.46.0 → 3.47.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-cli/ksql.js +213 -33
- package/dist-engine/index.cjs +9 -9
- package/dist-engine/index.mjs +9 -9
- package/dist-engine/ksql-engine.umd.js +9 -9
- package/dist-engine/meta/bundle-baseline.json +7 -7
- package/dist-engine/meta/cjs.json +6 -6
- package/dist-engine/meta/esm.json +6 -6
- package/dist-engine/meta/umd.json +6 -6
- package/dist-mcp/ksql-mcp.js +223 -38
- package/dist-mcpb/ksql-mcp.mcpb +0 -0
- package/package.json +1 -1
package/dist-cli/ksql.js
CHANGED
|
@@ -11619,6 +11619,42 @@ var LOCAL_COLLECTION_TYPES = /* @__PURE__ */ new Set([
|
|
|
11619
11619
|
function nativeWhereOperatorsForType(fieldType) {
|
|
11620
11620
|
return NATIVE_OPERATORS.get(fieldType) ?? /* @__PURE__ */ new Set();
|
|
11621
11621
|
}
|
|
11622
|
+
function normalizeChoiceEquality(where, resolveField2) {
|
|
11623
|
+
const rewrites = [];
|
|
11624
|
+
const visit = (node) => {
|
|
11625
|
+
if (node.type === "BINARY") {
|
|
11626
|
+
if ((node.op === "=" || node.op === "!=" || node.op === "<>") && node.left.type === "FIELD" && node.right.type === "STRING" && node.right.value !== "") {
|
|
11627
|
+
const semantics = resolveField2(node.left);
|
|
11628
|
+
if (semantics !== void 0 && semantics.compareMode === "option" && LOCAL_SCALAR_TYPES.has(semantics.fieldType) && nativeWhereOperatorsForType(semantics.fieldType).has("in") && semantics.optionOrder?.has(node.right.value) === true) {
|
|
11629
|
+
const normalizedOperator = node.op === "=" ? "IN" : "NOT_IN";
|
|
11630
|
+
rewrites.push({
|
|
11631
|
+
field: node.left,
|
|
11632
|
+
originalOperator: node.op,
|
|
11633
|
+
normalizedOperator,
|
|
11634
|
+
value: node.right.value
|
|
11635
|
+
});
|
|
11636
|
+
return {
|
|
11637
|
+
...node,
|
|
11638
|
+
op: normalizedOperator,
|
|
11639
|
+
right: { type: "IN_LIST", values: [node.right] }
|
|
11640
|
+
};
|
|
11641
|
+
}
|
|
11642
|
+
}
|
|
11643
|
+
return node;
|
|
11644
|
+
}
|
|
11645
|
+
if (node.type === "LOGICAL") {
|
|
11646
|
+
const left = visit(node.left);
|
|
11647
|
+
const right = visit(node.right);
|
|
11648
|
+
return left === node.left && right === node.right ? node : { ...node, left, right };
|
|
11649
|
+
}
|
|
11650
|
+
if (node.type === "GROUP" || node.type === "NOT") {
|
|
11651
|
+
const expr = visit(node.expr);
|
|
11652
|
+
return expr === node.expr ? node : { ...node, expr };
|
|
11653
|
+
}
|
|
11654
|
+
return node;
|
|
11655
|
+
};
|
|
11656
|
+
return { normalizedWhere: visit(where), rewrites };
|
|
11657
|
+
}
|
|
11622
11658
|
function classifyWhereCapability(where, resolveField2) {
|
|
11623
11659
|
if (where === null) {
|
|
11624
11660
|
return { capability: "EXACT_PUSHDOWN", reasons: [{ code: "WHERE_EXACT" }] };
|
|
@@ -16399,18 +16435,18 @@ async function assertRelativeDateExecutionPlan(stmt, client, cacheContext) {
|
|
|
16399
16435
|
}
|
|
16400
16436
|
async function resolveRelativeDateExecutionPlan(stmt, client, cacheContext) {
|
|
16401
16437
|
return buildRelativeDatePushdownPlan(stmt, {
|
|
16402
|
-
select: (select) =>
|
|
16438
|
+
select: async (select) => {
|
|
16439
|
+
const { resolver } = await normalizeSelectChoiceEquality(select, client, cacheContext);
|
|
16440
|
+
return classifyWhereCapability(select.where, resolver);
|
|
16441
|
+
},
|
|
16403
16442
|
dml: (dml) => resolveDmlWhereCapability(dml, client, cacheContext),
|
|
16404
16443
|
prefilterDecomposition: async (select) => {
|
|
16405
16444
|
if (select.where === null) return null;
|
|
16406
|
-
const resolver = await
|
|
16407
|
-
select,
|
|
16408
|
-
client,
|
|
16409
|
-
cacheContext
|
|
16410
|
-
);
|
|
16445
|
+
const { resolver } = await normalizeSelectChoiceEquality(select, client, cacheContext);
|
|
16411
16446
|
return decomposeRelativeDatePrefilter(select, resolver);
|
|
16412
16447
|
},
|
|
16413
16448
|
joinServerFunctionPlan: async (select) => {
|
|
16449
|
+
await normalizeSelectChoiceEquality(select, client, cacheContext);
|
|
16414
16450
|
const metadata = await loadTypedPushdownMeta(select, client, cacheContext);
|
|
16415
16451
|
const runtimePlan = buildRuntimeJoinPushdownPlan(select, metadata);
|
|
16416
16452
|
if (runtimePlan === null) return null;
|
|
@@ -17480,7 +17516,10 @@ async function buildWhereFieldSemanticsResolver(stmt, client, cacheContext, mate
|
|
|
17480
17516
|
if (node === null || typeof node !== "object") return;
|
|
17481
17517
|
const value = node;
|
|
17482
17518
|
if (value["type"] === "SELECT") return;
|
|
17483
|
-
|
|
17519
|
+
const operator = String(value["op"]);
|
|
17520
|
+
const right = value["right"];
|
|
17521
|
+
const needsOptionExistence = ["=", "!=", "<>"].includes(operator) && right?.["type"] === "STRING" && right["value"] !== "";
|
|
17522
|
+
if (value["type"] === "BINARY" && ([">", "<", ">=", "<="].includes(operator) || needsOptionExistence)) {
|
|
17484
17523
|
const left = value["left"];
|
|
17485
17524
|
if (left?.["type"] === "FIELD" && typeof left["field"] === "string") {
|
|
17486
17525
|
orderedFields.add(left["field"]);
|
|
@@ -17547,6 +17586,49 @@ async function buildWhereFieldSemanticsResolver(stmt, client, cacheContext, mate
|
|
|
17547
17586
|
return matches.length > 1 ? syntheticSemantics("string") : void 0;
|
|
17548
17587
|
};
|
|
17549
17588
|
}
|
|
17589
|
+
var choiceEqualityRewritesBySelect = /* @__PURE__ */ new WeakMap();
|
|
17590
|
+
async function normalizeSelectChoiceEquality(stmt, client, cacheContext, materializedTables, forcePhysicalMetadata = false) {
|
|
17591
|
+
const resolver = await buildWhereFieldSemanticsResolver(
|
|
17592
|
+
stmt,
|
|
17593
|
+
client,
|
|
17594
|
+
cacheContext,
|
|
17595
|
+
materializedTables,
|
|
17596
|
+
forcePhysicalMetadata
|
|
17597
|
+
);
|
|
17598
|
+
if (stmt.where === null) return { resolver, rewrites: [] };
|
|
17599
|
+
const normalization = normalizeChoiceEquality(stmt.where, resolver);
|
|
17600
|
+
stmt.where = normalization.normalizedWhere;
|
|
17601
|
+
if (normalization.rewrites.length > 0) {
|
|
17602
|
+
choiceEqualityRewritesBySelect.set(stmt, normalization.rewrites);
|
|
17603
|
+
}
|
|
17604
|
+
return { resolver, rewrites: normalization.rewrites };
|
|
17605
|
+
}
|
|
17606
|
+
function hasDefaultRangeAggregateWindow(stmt) {
|
|
17607
|
+
return stmt.columns.some(
|
|
17608
|
+
(column) => column.type === "WINDOW_COL" && column.windowKind === "AGGREGATE" && column.orderBy.length > 0 && column.frame?.source === "DEFAULT"
|
|
17609
|
+
);
|
|
17610
|
+
}
|
|
17611
|
+
function collectDefaultRangeWindowWarnings(stmt, resolveField2, context) {
|
|
17612
|
+
const canProveSinglePhysicalInput = context === "DIRECT" && stmt.joins.length === 0 && stmt.from.cteName === null && stmt.from.subtableCode == null;
|
|
17613
|
+
const warnings = [];
|
|
17614
|
+
for (const column of stmt.columns) {
|
|
17615
|
+
if (column.type !== "WINDOW_COL" || column.windowKind !== "AGGREGATE" || column.orderBy.length === 0 || column.frame?.source !== "DEFAULT") continue;
|
|
17616
|
+
const hasTotalOrderKey = canProveSinglePhysicalInput && column.orderBy.some((item) => {
|
|
17617
|
+
if (item.key.type !== "FIELD_NAME") return false;
|
|
17618
|
+
const ref = aggregateFieldRef(item.key.name);
|
|
17619
|
+
return ref.field === "$id" || resolveField2(ref)?.fieldType === "RECORD_NUMBER";
|
|
17620
|
+
});
|
|
17621
|
+
if (hasTotalOrderKey) continue;
|
|
17622
|
+
warnings.push(
|
|
17623
|
+
`${column.alias} \u306F\u65E2\u5B9A\u30D5\u30EC\u30FC\u30E0\uFF08RANGE\uFF09\u3067\u8A55\u4FA1\u3055\u308C\u307E\u3059\u3002ORDER BY \u306E\u5024\u304C\u540C\u3058\u884C\u306F\u3059\u3079\u3066\u540C\u3058\u5024\u306B\u306A\u308A\u307E\u3059\u3002\u884C\u3054\u3068\u306E\u5024\u304C\u5FC5\u8981\u306A\u3089 ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW \u3092\u660E\u793A\u3059\u308B\u304B\u3001ORDER BY \u306B\u30EC\u30B3\u30FC\u30C9\u756A\u53F7\u306A\u3069\u306E\u30BF\u30A4\u30D6\u30EC\u30FC\u30AF\u30AD\u30FC\u3092\u8DB3\u3057\u3066\u304F\u3060\u3055\u3044\u3002`
|
|
17624
|
+
);
|
|
17625
|
+
}
|
|
17626
|
+
return warnings;
|
|
17627
|
+
}
|
|
17628
|
+
function mergeSelectWarnings(result, additional) {
|
|
17629
|
+
if (additional.length === 0) return result;
|
|
17630
|
+
return { ...result, warnings: [.../* @__PURE__ */ new Set([...result.warnings ?? [], ...additional])] };
|
|
17631
|
+
}
|
|
17550
17632
|
function selectCaseConditionsNeedFieldMetadata(stmt) {
|
|
17551
17633
|
const visit = (value) => {
|
|
17552
17634
|
if (value === null || typeof value !== "object") return false;
|
|
@@ -17603,11 +17685,6 @@ function buildHavingFieldSemanticsResolver(stmt, rowResolver) {
|
|
|
17603
17685
|
}
|
|
17604
17686
|
return (field) => field.tableAlias === null && aliases.has(field.field) ? aliases.get(field.field) : rowResolver(field);
|
|
17605
17687
|
}
|
|
17606
|
-
async function resolveSelectWhereCapability(stmt, client, cacheContext, materializedTables) {
|
|
17607
|
-
if (stmt.where === null) return classifyWhereCapability(null, () => void 0);
|
|
17608
|
-
const resolver = await buildWhereFieldSemanticsResolver(stmt, client, cacheContext, materializedTables);
|
|
17609
|
-
return classifyWhereCapability(stmt.where, resolver);
|
|
17610
|
-
}
|
|
17611
17688
|
function formatWhereCapabilityFailure(result) {
|
|
17612
17689
|
const reason = result.reasons.find(
|
|
17613
17690
|
(candidate) => candidate.code === "WHERE_FIELD_UNRESOLVED" || candidate.code === "WHERE_OPERATOR_UNSUPPORTED" || candidate.code === "WHERE_OPERATOR_INVALID_FOR_FIELD_TYPE"
|
|
@@ -17652,7 +17729,7 @@ async function assertDmlWhereCapability(stmt, client, cacheContext) {
|
|
|
17652
17729
|
);
|
|
17653
17730
|
}
|
|
17654
17731
|
}
|
|
17655
|
-
async function executeSelect(stmt, client, options, cacheContext, cteCache, captureColumnMeta = false, forLibraryCapture = false) {
|
|
17732
|
+
async function executeSelect(stmt, client, options, cacheContext, cteCache, captureColumnMeta = false, forLibraryCapture = false, windowWarningContext = "DIRECT") {
|
|
17656
17733
|
let result;
|
|
17657
17734
|
await validateSelectGroupingPlanning(stmt, client, cacheContext, cteCache);
|
|
17658
17735
|
if (isNoFromSelect(stmt)) {
|
|
@@ -17665,6 +17742,18 @@ async function executeSelect(stmt, client, options, cacheContext, cteCache, capt
|
|
|
17665
17742
|
}
|
|
17666
17743
|
return result;
|
|
17667
17744
|
}
|
|
17745
|
+
const { resolver: fieldSemanticsResolver } = await normalizeSelectChoiceEquality(
|
|
17746
|
+
stmt,
|
|
17747
|
+
client,
|
|
17748
|
+
cacheContext,
|
|
17749
|
+
cteCache,
|
|
17750
|
+
hasDefaultRangeAggregateWindow(stmt)
|
|
17751
|
+
);
|
|
17752
|
+
const defaultRangeWarnings = collectDefaultRangeWindowWarnings(
|
|
17753
|
+
stmt,
|
|
17754
|
+
fieldSemanticsResolver,
|
|
17755
|
+
windowWarningContext
|
|
17756
|
+
);
|
|
17668
17757
|
const plainGroupByPlan = await buildRuntimePlainGroupByPlan(
|
|
17669
17758
|
stmt,
|
|
17670
17759
|
client,
|
|
@@ -17672,7 +17761,10 @@ async function executeSelect(stmt, client, options, cacheContext, cteCache, capt
|
|
|
17672
17761
|
cteCache
|
|
17673
17762
|
);
|
|
17674
17763
|
await resolveSelectCaseSubqueries(stmt, client, options, cacheContext, cteCache);
|
|
17675
|
-
const whereCapability = rememberSelectWhereCapability(
|
|
17764
|
+
const whereCapability = rememberSelectWhereCapability(
|
|
17765
|
+
stmt,
|
|
17766
|
+
classifyWhereCapability(stmt.where, fieldSemanticsResolver)
|
|
17767
|
+
);
|
|
17676
17768
|
if (whereCapability.capability === "UNSUPPORTED") {
|
|
17677
17769
|
throw new Error(`ArgumentError: WHERE predicate is unsupported (${formatWhereCapabilityFailure(whereCapability)}).`);
|
|
17678
17770
|
}
|
|
@@ -17759,7 +17851,7 @@ async function executeSelect(stmt, client, options, cacheContext, cteCache, capt
|
|
|
17759
17851
|
await inferSelectColumnMeta(stmt, result.columns, client, cacheContext, cteCache, forLibraryCapture)
|
|
17760
17852
|
);
|
|
17761
17853
|
}
|
|
17762
|
-
return result;
|
|
17854
|
+
return mergeSelectWarnings(result, defaultRangeWarnings);
|
|
17763
17855
|
}
|
|
17764
17856
|
async function buildRuntimePlainGroupByPlan(stmt, client, cacheContext, materializedTables) {
|
|
17765
17857
|
if (stmt.groupBy.length === 0) return void 0;
|
|
@@ -19270,7 +19362,8 @@ async function executeUnion(stmt, client, options, cacheContext, captureColumnMe
|
|
|
19270
19362
|
cacheContext,
|
|
19271
19363
|
void 0,
|
|
19272
19364
|
captureColumnMeta,
|
|
19273
|
-
forLibraryCapture
|
|
19365
|
+
forLibraryCapture,
|
|
19366
|
+
"DERIVED"
|
|
19274
19367
|
),
|
|
19275
19368
|
executeSelect(
|
|
19276
19369
|
markCountTotalCountRoot(stmt.right),
|
|
@@ -19279,7 +19372,8 @@ async function executeUnion(stmt, client, options, cacheContext, captureColumnMe
|
|
|
19279
19372
|
cacheContext,
|
|
19280
19373
|
void 0,
|
|
19281
19374
|
captureColumnMeta,
|
|
19282
|
-
forLibraryCapture
|
|
19375
|
+
forLibraryCapture,
|
|
19376
|
+
"DERIVED"
|
|
19283
19377
|
)
|
|
19284
19378
|
]);
|
|
19285
19379
|
const leftCols = leftResult.columns;
|
|
@@ -19293,7 +19387,17 @@ async function executeUnion(stmt, client, options, cacheContext, captureColumnMe
|
|
|
19293
19387
|
});
|
|
19294
19388
|
const combined = [...leftResult.rows, ...remappedRight];
|
|
19295
19389
|
const rows = stmt.all ? combined : deduplicateRows(combined, leftCols);
|
|
19296
|
-
const
|
|
19390
|
+
const warnings = [.../* @__PURE__ */ new Set([
|
|
19391
|
+
...leftResult.warnings ?? [],
|
|
19392
|
+
...rightResult.warnings ?? []
|
|
19393
|
+
])];
|
|
19394
|
+
const result = {
|
|
19395
|
+
type: "SELECT",
|
|
19396
|
+
rows,
|
|
19397
|
+
columns: leftCols,
|
|
19398
|
+
rowCount: rows.length,
|
|
19399
|
+
warnings
|
|
19400
|
+
};
|
|
19297
19401
|
if (captureColumnMeta) {
|
|
19298
19402
|
materializedMetaBySelectResult.set(result, mergeUnionColumnMeta(leftResult, rightResult));
|
|
19299
19403
|
}
|
|
@@ -19311,25 +19415,44 @@ function deduplicateRows(rows, columns) {
|
|
|
19311
19415
|
}
|
|
19312
19416
|
async function executeWith(stmt, client, options, cacheContext, seed, captureColumnMeta = false) {
|
|
19313
19417
|
if ((seed == null || seed.size === 0) && canInlineSingleCte(stmt)) {
|
|
19314
|
-
return executeSelect(
|
|
19418
|
+
return executeSelect(
|
|
19419
|
+
buildInlinedQuery(stmt),
|
|
19420
|
+
client,
|
|
19421
|
+
options,
|
|
19422
|
+
cacheContext,
|
|
19423
|
+
void 0,
|
|
19424
|
+
captureColumnMeta,
|
|
19425
|
+
false,
|
|
19426
|
+
"DERIVED"
|
|
19427
|
+
);
|
|
19315
19428
|
}
|
|
19316
19429
|
const cteCache = new Map(seed ?? []);
|
|
19430
|
+
const warnings = /* @__PURE__ */ new Set();
|
|
19317
19431
|
for (const cte of stmt.ctes) {
|
|
19318
|
-
let
|
|
19432
|
+
let result2;
|
|
19319
19433
|
if (cte.query.type === "SHOW_APPS") {
|
|
19320
|
-
|
|
19434
|
+
result2 = await executeShowApps(client);
|
|
19321
19435
|
} else if (cte.query.type === "DESCRIBE") {
|
|
19322
|
-
|
|
19436
|
+
result2 = await executeDescribe(cte.query, client, cacheContext);
|
|
19323
19437
|
} else {
|
|
19324
|
-
|
|
19438
|
+
result2 = await executeQueryWithCte(cte.query, client, options, cteCache, cacheContext, true);
|
|
19325
19439
|
}
|
|
19440
|
+
for (const warning of result2.warnings ?? []) warnings.add(warning);
|
|
19326
19441
|
cteCache.set(cte.name, {
|
|
19327
|
-
rows:
|
|
19328
|
-
columns:
|
|
19329
|
-
columnMeta: materializedMetaBySelectResult.get(
|
|
19442
|
+
rows: result2.rows,
|
|
19443
|
+
columns: result2.columns,
|
|
19444
|
+
columnMeta: materializedMetaBySelectResult.get(result2)
|
|
19330
19445
|
});
|
|
19331
19446
|
}
|
|
19332
|
-
|
|
19447
|
+
const result = await executeQueryWithCte(
|
|
19448
|
+
stmt.query,
|
|
19449
|
+
client,
|
|
19450
|
+
options,
|
|
19451
|
+
cteCache,
|
|
19452
|
+
cacheContext,
|
|
19453
|
+
captureColumnMeta
|
|
19454
|
+
);
|
|
19455
|
+
return mergeSelectWarnings(result, [...warnings]);
|
|
19333
19456
|
}
|
|
19334
19457
|
async function executeQueryWithCte(query, client, options, cteCache, cacheContext, captureColumnMeta = false, b86PreflightComplete = false) {
|
|
19335
19458
|
if (!b86PreflightComplete) {
|
|
@@ -19351,7 +19474,17 @@ async function executeQueryWithCte(query, client, options, cteCache, cacheContex
|
|
|
19351
19474
|
});
|
|
19352
19475
|
const combined = [...leftResult.rows, ...remapped];
|
|
19353
19476
|
const rows = query.all ? combined : deduplicateRows(combined, leftCols);
|
|
19354
|
-
const
|
|
19477
|
+
const warnings = [.../* @__PURE__ */ new Set([
|
|
19478
|
+
...leftResult.warnings ?? [],
|
|
19479
|
+
...rightResult.warnings ?? []
|
|
19480
|
+
])];
|
|
19481
|
+
const result2 = {
|
|
19482
|
+
type: "SELECT",
|
|
19483
|
+
rows,
|
|
19484
|
+
columns: leftCols,
|
|
19485
|
+
rowCount: rows.length,
|
|
19486
|
+
warnings
|
|
19487
|
+
};
|
|
19355
19488
|
if (captureColumnMeta) {
|
|
19356
19489
|
materializedMetaBySelectResult.set(result2, mergeUnionColumnMeta(leftResult, rightResult));
|
|
19357
19490
|
}
|
|
@@ -19359,7 +19492,16 @@ async function executeQueryWithCte(query, client, options, cteCache, cacheContex
|
|
|
19359
19492
|
}
|
|
19360
19493
|
const hasCteRef = query.from.cteName != null && query.from.cteName !== NO_FROM_CTE_NAME || query.joins.some((j) => j.table.cteName != null);
|
|
19361
19494
|
if (!hasCteRef) {
|
|
19362
|
-
return executeSelect(
|
|
19495
|
+
return executeSelect(
|
|
19496
|
+
query,
|
|
19497
|
+
client,
|
|
19498
|
+
options,
|
|
19499
|
+
cacheContext,
|
|
19500
|
+
cteCache,
|
|
19501
|
+
captureColumnMeta,
|
|
19502
|
+
false,
|
|
19503
|
+
"DERIVED"
|
|
19504
|
+
);
|
|
19363
19505
|
}
|
|
19364
19506
|
const result = await executeFullScanWithCte(query, client, options, cteCache, cacheContext);
|
|
19365
19507
|
if (captureColumnMeta) {
|
|
@@ -19407,6 +19549,18 @@ async function executeFullScanWithCte(stmt, client, options, cteCache, cacheCont
|
|
|
19407
19549
|
for (const table of [stmt.from, ...stmt.joins.map((join2) => join2.table)]) {
|
|
19408
19550
|
if (table.cteName !== null) requireMaterializedTable(table.cteName);
|
|
19409
19551
|
}
|
|
19552
|
+
const { resolver: choiceAndWindowResolver } = await normalizeSelectChoiceEquality(
|
|
19553
|
+
stmt,
|
|
19554
|
+
client,
|
|
19555
|
+
cacheContext,
|
|
19556
|
+
cteCache,
|
|
19557
|
+
hasDefaultRangeAggregateWindow(stmt)
|
|
19558
|
+
);
|
|
19559
|
+
const defaultRangeWarnings = collectDefaultRangeWindowWarnings(
|
|
19560
|
+
stmt,
|
|
19561
|
+
choiceAndWindowResolver,
|
|
19562
|
+
"DERIVED"
|
|
19563
|
+
);
|
|
19410
19564
|
const maxRecords = options.maxRecords ?? 1e4;
|
|
19411
19565
|
const warnings = /* @__PURE__ */ new Set();
|
|
19412
19566
|
const parallel = options.fetchParallel ?? 1;
|
|
@@ -19415,7 +19569,7 @@ async function executeFullScanWithCte(stmt, client, options, cteCache, cacheCont
|
|
|
19415
19569
|
resolveSubqueries(stmt.having, client, options, cacheContext, cteCache),
|
|
19416
19570
|
resolveSelectCaseSubqueries(stmt, client, options, cacheContext, cteCache)
|
|
19417
19571
|
]);
|
|
19418
|
-
const whereCapability =
|
|
19572
|
+
const whereCapability = classifyWhereCapability(stmt.where, choiceAndWindowResolver);
|
|
19419
19573
|
if (whereCapability.capability === "UNSUPPORTED") {
|
|
19420
19574
|
throw new Error(`ArgumentError: WHERE predicate is unsupported (${formatWhereCapabilityFailure(whereCapability)}).`);
|
|
19421
19575
|
}
|
|
@@ -19544,7 +19698,10 @@ async function executeFullScanWithCte(stmt, client, options, cteCache, cacheCont
|
|
|
19544
19698
|
client,
|
|
19545
19699
|
cacheContext
|
|
19546
19700
|
);
|
|
19547
|
-
return
|
|
19701
|
+
return mergeSelectWarnings(
|
|
19702
|
+
{ type: "SELECT", rows, columns, rowCount: rows.length, warnings: [...warnings] },
|
|
19703
|
+
defaultRangeWarnings
|
|
19704
|
+
);
|
|
19548
19705
|
}
|
|
19549
19706
|
async function restoreEmptyWildcardColumns(stmt, rows, columns, client, cacheContext) {
|
|
19550
19707
|
if (rows.length !== 0 || columns.length !== 0 || stmt.columns.length !== 1 || stmt.columns[0].type !== "WILDCARD" || stmt.joins.length !== 0 || stmt.from.cteName !== null) {
|
|
@@ -22958,6 +23115,7 @@ async function resolveScalarColumns(columns, client, options, cacheContext, cteC
|
|
|
22958
23115
|
return cache;
|
|
22959
23116
|
}
|
|
22960
23117
|
var explainJoinPushdownPlans = /* @__PURE__ */ new WeakMap();
|
|
23118
|
+
var explainChoiceEqualityRewrites = /* @__PURE__ */ new WeakMap();
|
|
22961
23119
|
var validateExplainInfo = /* @__PURE__ */ new WeakMap();
|
|
22962
23120
|
var applyParentExplainPlan = /* @__PURE__ */ new WeakMap();
|
|
22963
23121
|
async function buildExplainWhereAnalysis(query, client, cacheContext, maxRecords = 1e4, relativeDatePlan) {
|
|
@@ -23013,7 +23171,13 @@ async function buildExplainWhereAnalysis(query, client, cacheContext, maxRecords
|
|
|
23013
23171
|
if (needsWhereSchema || select.orderBy.length > 0 || select.columns.some((column) => column.type === "WINDOW_COL" && column.orderBy.length > 0)) {
|
|
23014
23172
|
physicalApps.forEach((appId) => fieldApps.add(appId));
|
|
23015
23173
|
}
|
|
23016
|
-
const
|
|
23174
|
+
const { resolver, rewrites } = await normalizeSelectChoiceEquality(
|
|
23175
|
+
select,
|
|
23176
|
+
tracedClient,
|
|
23177
|
+
cacheContext
|
|
23178
|
+
);
|
|
23179
|
+
if (rewrites.length > 0) explainChoiceEqualityRewrites.set(select, rewrites);
|
|
23180
|
+
const capability = classifyWhereCapability(select.where, resolver);
|
|
23017
23181
|
const relativeNode = relativeNodeFor(select);
|
|
23018
23182
|
if (capability.capability === "UNSUPPORTED" && !relativeNode) {
|
|
23019
23183
|
throw new Error(`ArgumentError: WHERE predicate is unsupported (${formatWhereCapabilityFailure(capability)}).`);
|
|
@@ -23125,7 +23289,13 @@ async function buildExplainWhereAnalysis(query, client, cacheContext, maxRecords
|
|
|
23125
23289
|
await visit(query);
|
|
23126
23290
|
if (typeof query === "object" && query !== null && query.type === "WITH" && canInlineSingleCte(query)) {
|
|
23127
23291
|
const inlined = buildInlinedQuery(query);
|
|
23128
|
-
const
|
|
23292
|
+
const { resolver, rewrites } = await normalizeSelectChoiceEquality(
|
|
23293
|
+
inlined,
|
|
23294
|
+
tracedClient,
|
|
23295
|
+
cacheContext
|
|
23296
|
+
);
|
|
23297
|
+
if (rewrites.length > 0) explainChoiceEqualityRewrites.set(inlined, rewrites);
|
|
23298
|
+
const capability = classifyWhereCapability(inlined.where, resolver);
|
|
23129
23299
|
const relativeNode = relativeNodeFor(inlined);
|
|
23130
23300
|
if (capability.capability === "UNSUPPORTED" && !relativeNode) {
|
|
23131
23301
|
throw new Error(`ArgumentError: WHERE predicate is unsupported (${formatWhereCapabilityFailure(capability)}).`);
|
|
@@ -23897,6 +24067,13 @@ function buildValidatePlan(stmt, label) {
|
|
|
23897
24067
|
lines.push(" records/mutation API during EXPLAIN: none; violation count unavailable");
|
|
23898
24068
|
return lines;
|
|
23899
24069
|
}
|
|
24070
|
+
function formatChoiceEqualityRewrite(rewrite) {
|
|
24071
|
+
const field = rewrite.field.tableAlias ? `${rewrite.field.tableAlias}.${rewrite.field.field}` : rewrite.field.field;
|
|
24072
|
+
const originalValue = rewrite.value.replace(/'/g, "''");
|
|
24073
|
+
const normalizedValue = rewrite.value.replace(/\\/g, "\\\\").replace(/"/g, '\\"');
|
|
24074
|
+
const normalizedOperator = rewrite.normalizedOperator === "IN" ? "in" : "not in";
|
|
24075
|
+
return ` pushdown normalized: ${field} ${rewrite.originalOperator} '${originalValue}' -> ${field} ${normalizedOperator} ("${normalizedValue}")`;
|
|
24076
|
+
}
|
|
23900
24077
|
function buildSelectPlan(stmt, label, capabilities, orderPlans, plainGroupByPlans, allowTotalCountPlan = true, emitFetch = true, collector = { sources: [] }, sourceRole = "main") {
|
|
23901
24078
|
const whereCapability = capabilities?.get(stmt) ?? (capabilities ? [...capabilities].find(([candidate]) => JSON.stringify(candidate) === JSON.stringify(stmt))?.[1] : void 0);
|
|
23902
24079
|
const orderPlan = orderPlans?.get(stmt) ?? (orderPlans ? [...orderPlans].find(([candidate]) => JSON.stringify(candidate) === JSON.stringify(stmt))?.[1] : void 0);
|
|
@@ -23914,6 +24091,9 @@ function buildSelectPlan(stmt, label, capabilities, orderPlans, plainGroupByPlan
|
|
|
23914
24091
|
);
|
|
23915
24092
|
if (label) lines.push(label);
|
|
23916
24093
|
lines.push(` mode: ${mode}`);
|
|
24094
|
+
for (const rewrite of explainChoiceEqualityRewrites.get(stmt) ?? choiceEqualityRewritesBySelect.get(stmt) ?? []) {
|
|
24095
|
+
lines.push(formatChoiceEqualityRewrite(rewrite));
|
|
24096
|
+
}
|
|
23917
24097
|
if (groupingMetadata) {
|
|
23918
24098
|
lines.push(` grouping source: ${groupingMetadata.source}`);
|
|
23919
24099
|
lines.push(
|