@rex0220/kintone-sql-tools 3.32.0 → 3.34.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 +102 -29
- 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 +10 -10
- package/dist-engine/meta/cjs.json +9 -9
- package/dist-engine/meta/esm.json +9 -9
- package/dist-engine/meta/umd.json +9 -9
- package/dist-mcp/ksql-mcp.js +23054 -24891
- package/dist-mcpb/ksql-mcp.mcpb +0 -0
- package/package.json +5 -2
package/dist-cli/ksql.js
CHANGED
|
@@ -4260,6 +4260,15 @@ function containsStatisticalAggregate(value, seen = /* @__PURE__ */ new Set()) {
|
|
|
4260
4260
|
if (record.type === "FIELD" && typeof record.field === "string" && /^(STDDEV_POP|STDDEV_SAMP|VAR_POP|VAR_SAMP|MEDIAN|MODE)\(/i.test(record.field)) return true;
|
|
4261
4261
|
return Object.values(record).some((child) => Array.isArray(child) ? child.some((entry) => containsStatisticalAggregate(entry, seen)) : containsStatisticalAggregate(child, seen));
|
|
4262
4262
|
}
|
|
4263
|
+
function containsAggregate(value, seen = /* @__PURE__ */ new Set()) {
|
|
4264
|
+
if (value === null || typeof value !== "object") return false;
|
|
4265
|
+
if (seen.has(value)) return false;
|
|
4266
|
+
seen.add(value);
|
|
4267
|
+
const record = value;
|
|
4268
|
+
if ((record.type === "AGGREGATE" || record.type === "AGG_REF") && typeof record.func === "string" && !STATISTICAL_AGGREGATES.has(record.func)) return true;
|
|
4269
|
+
if (record.type === "FIELD" && typeof record.field === "string" && /^(COUNT|SUM|AVG|MIN|MAX|GROUP_CONCAT)\(/i.test(record.field)) return true;
|
|
4270
|
+
return Object.values(record).some((child) => Array.isArray(child) ? child.some((entry) => containsAggregate(entry, seen)) : containsAggregate(child, seen));
|
|
4271
|
+
}
|
|
4263
4272
|
function completeInputReasons(stmt) {
|
|
4264
4273
|
const reasons = /* @__PURE__ */ new Set();
|
|
4265
4274
|
if (isDmlType(stmt.type)) {
|
|
@@ -4289,6 +4298,7 @@ function completeInputReasons(stmt) {
|
|
|
4289
4298
|
break;
|
|
4290
4299
|
}
|
|
4291
4300
|
if (containsStatisticalAggregate(stmt)) reasons.add("STATISTICAL_AGGREGATE");
|
|
4301
|
+
if (containsAggregate(stmt)) reasons.add("AGGREGATE");
|
|
4292
4302
|
return reasons;
|
|
4293
4303
|
}
|
|
4294
4304
|
function requiresCompleteInput(stmt) {
|
|
@@ -4297,11 +4307,15 @@ function requiresCompleteInput(stmt) {
|
|
|
4297
4307
|
function unionCompleteInputReasons(stmt) {
|
|
4298
4308
|
const reasons = stmt.left.type === "SELECT" ? selectCompleteInputReasons(stmt.left) : unionCompleteInputReasons(stmt.left);
|
|
4299
4309
|
addReasons(reasons, selectCompleteInputReasons(stmt.right));
|
|
4310
|
+
if (!stmt.all) reasons.add("DISTINCT");
|
|
4300
4311
|
return reasons;
|
|
4301
4312
|
}
|
|
4302
4313
|
function selectCompleteInputReasons(stmt) {
|
|
4303
4314
|
const reasons = /* @__PURE__ */ new Set();
|
|
4304
|
-
|
|
4315
|
+
const grouping = normalizeGroupingSpec(stmt);
|
|
4316
|
+
if (grouping.type === "GROUPING_SETS") reasons.add("GROUPING_SETS");
|
|
4317
|
+
if (grouping.type === "PLAIN") reasons.add("GROUP_BY");
|
|
4318
|
+
if (stmt.distinct) reasons.add("DISTINCT");
|
|
4305
4319
|
if (stmt.orderBy.length > 0) reasons.add("LOCAL_ORDER");
|
|
4306
4320
|
for (const column of stmt.columns) {
|
|
4307
4321
|
if (column.type === "WINDOW_COL" && column.orderBy.length > 0) reasons.add("WINDOW_ORDER");
|
|
@@ -4313,6 +4327,7 @@ function selectCompleteInputReasons(stmt) {
|
|
|
4313
4327
|
addReasons(reasons, whereCompleteInputReasons(stmt.where));
|
|
4314
4328
|
addReasons(reasons, whereCompleteInputReasons(stmt.having));
|
|
4315
4329
|
if (containsStatisticalAggregate(stmt)) reasons.add("STATISTICAL_AGGREGATE");
|
|
4330
|
+
if (containsAggregate(stmt)) reasons.add("AGGREGATE");
|
|
4316
4331
|
return reasons;
|
|
4317
4332
|
}
|
|
4318
4333
|
function whereCompleteInputReasons(where) {
|
|
@@ -6505,19 +6520,19 @@ function collectNonAggregateFieldRefs(node, out) {
|
|
|
6505
6520
|
}
|
|
6506
6521
|
Object.values(value).forEach((item) => collectNonAggregateFieldRefs(item, out));
|
|
6507
6522
|
}
|
|
6508
|
-
function
|
|
6523
|
+
function containsAggregate2(node) {
|
|
6509
6524
|
if (node === null || typeof node !== "object") return false;
|
|
6510
|
-
if (Array.isArray(node)) return node.some(
|
|
6525
|
+
if (Array.isArray(node)) return node.some(containsAggregate2);
|
|
6511
6526
|
const value = node;
|
|
6512
6527
|
if (value["type"] === "AGG_REF" || value["type"] === "AGG_ARITH") return true;
|
|
6513
6528
|
if (value["type"] === "SELECT" || value["type"] === "SCALAR_SUBQUERY") return false;
|
|
6514
|
-
return Object.values(value).some(
|
|
6529
|
+
return Object.values(value).some(containsAggregate2);
|
|
6515
6530
|
}
|
|
6516
6531
|
function isAggregateMaterializedAlias(column) {
|
|
6517
6532
|
if (!("alias" in column) || column.alias === null) return false;
|
|
6518
6533
|
if (column.type === "AGGREGATE" || column.type === "ARITH_AGG_COL") return true;
|
|
6519
6534
|
if (column.type === "STRFUNC_COL" || column.type === "SCALAR_VALUE_COL") {
|
|
6520
|
-
return
|
|
6535
|
+
return containsAggregate2(column);
|
|
6521
6536
|
}
|
|
6522
6537
|
return false;
|
|
6523
6538
|
}
|
|
@@ -10680,6 +10695,19 @@ function statementContainsOuterJoin(statement) {
|
|
|
10680
10695
|
};
|
|
10681
10696
|
return visit(statement);
|
|
10682
10697
|
}
|
|
10698
|
+
function isOuterJoinNonPreservedTable(statement, table, isMainTable) {
|
|
10699
|
+
if (isMainTable) {
|
|
10700
|
+
return table === statement.from && statement.joins.some((join2) => join2.type === "RIGHT");
|
|
10701
|
+
}
|
|
10702
|
+
for (let index = 0; index < statement.joins.length; index += 1) {
|
|
10703
|
+
const join2 = statement.joins[index];
|
|
10704
|
+
if (join2.type === "LEFT" && table === join2.table) return true;
|
|
10705
|
+
if (join2.type === "RIGHT" && statement.joins.slice(0, index).some((previousJoin) => table === previousJoin.table)) {
|
|
10706
|
+
return true;
|
|
10707
|
+
}
|
|
10708
|
+
}
|
|
10709
|
+
return false;
|
|
10710
|
+
}
|
|
10683
10711
|
|
|
10684
10712
|
// src/core/explainMetadata.ts
|
|
10685
10713
|
function buildGroupingExplainMetadata(statement, canonicalItemCount) {
|
|
@@ -10893,8 +10921,9 @@ function getLastId(records) {
|
|
|
10893
10921
|
return Number.isFinite(id) ? id : 0;
|
|
10894
10922
|
}
|
|
10895
10923
|
var FetchAllLimitError = class extends Error {
|
|
10896
|
-
constructor(message) {
|
|
10924
|
+
constructor(message, completeInputWrapped = false) {
|
|
10897
10925
|
super(message);
|
|
10926
|
+
this.completeInputWrapped = completeInputWrapped;
|
|
10898
10927
|
this.name = "FetchAllLimitError";
|
|
10899
10928
|
}
|
|
10900
10929
|
};
|
|
@@ -12405,7 +12434,7 @@ function classifyPreGroupAlias(column) {
|
|
|
12405
12434
|
case "STRFUNC_COL":
|
|
12406
12435
|
case "SCALAR_VALUE_COL":
|
|
12407
12436
|
case "SCALAR_SUBQUERY_COL":
|
|
12408
|
-
return
|
|
12437
|
+
return containsAggregate2(column) || containsAggregateColumnNode(column) ? "AGGREGATE_DEPENDENT" : "SAFE";
|
|
12409
12438
|
}
|
|
12410
12439
|
}
|
|
12411
12440
|
var SUBTABLE_SYSTEM_COLUMNS = ["_pid", "_rid", "_idx"];
|
|
@@ -17064,11 +17093,21 @@ async function validateSelectGroupingPlanning(stmt, client, cacheContext, materi
|
|
|
17064
17093
|
}
|
|
17065
17094
|
function completeInputErrorPrefix(reasons) {
|
|
17066
17095
|
const reasonList = [...reasons].join(", ");
|
|
17067
|
-
const
|
|
17096
|
+
const aggregateSubjects = [
|
|
17097
|
+
["GROUPING_SETS", "\u5C0F\u8A08\u30FB\u7DCF\u8A08\u306E\u6B63\u3057\u3044\u7D50\u679C"],
|
|
17098
|
+
["STATISTICAL_AGGREGATE", "\u7D71\u8A08\u96C6\u7D04\u306E\u6B63\u3057\u3044\u7D50\u679C"],
|
|
17099
|
+
["AGGREGATE", "\u96C6\u8A08\u306E\u6B63\u3057\u3044\u7D50\u679C"],
|
|
17100
|
+
["GROUP_BY", "\u30B0\u30EB\u30FC\u30D7\u96C6\u8A08\u306E\u6B63\u3057\u3044\u7D50\u679C"],
|
|
17101
|
+
["DISTINCT", "DISTINCT \u306E\u6B63\u3057\u3044\u7D50\u679C"]
|
|
17102
|
+
];
|
|
17103
|
+
const hasAggregateReason = aggregateSubjects.some(([reason]) => reasons.has(reason));
|
|
17104
|
+
const hasOrderReason = reasons.has("LOCAL_ORDER") || reasons.has("WINDOW_ORDER");
|
|
17105
|
+
const legacySubject = reasons.size === 1 && reasons.has("STATISTICAL_AGGREGATE") ? "\u7D71\u8A08\u96C6\u7D04\u306E\u6B63\u3057\u3044\u7D50\u679C" : reasons.size === 1 && reasons.has("GROUPING_SETS") ? "\u5C0F\u8A08\u30FB\u7DCF\u8A08\u306E\u6B63\u3057\u3044\u7D50\u679C" : reasons.size === 1 && reasons.has("AGGREGATE") ? "\u96C6\u8A08\u306E\u6B63\u3057\u3044\u7D50\u679C" : reasons.size === 1 && reasons.has("GROUP_BY") ? "\u30B0\u30EB\u30FC\u30D7\u96C6\u8A08\u306E\u6B63\u3057\u3044\u7D50\u679C" : reasons.size === 1 && reasons.has("DISTINCT") ? "DISTINCT \u306E\u6B63\u3057\u3044\u7D50\u679C" : reasons.has("GROUPING_SETS") ? "\u30AF\u30A8\u30EA\u306E\u6B63\u3057\u3044\u7D50\u679C" : "ORDER BY\u306E\u6B63\u3057\u3044\u7D50\u679C";
|
|
17106
|
+
const subject = reasons.has("DML") || reasons.has("VALIDATE") ? legacySubject : hasAggregateReason && hasOrderReason ? "\u30AF\u30A8\u30EA\u306E\u6B63\u3057\u3044\u7D50\u679C" : hasAggregateReason ? aggregateSubjects.find(([reason]) => reasons.has(reason))[1] : "ORDER BY\u306E\u6B63\u3057\u3044\u7D50\u679C";
|
|
17068
17107
|
return `${subject}\u306B\u306F\u5B8C\u5168\u306A\u5019\u88DC\u96C6\u5408\u304C\u5FC5\u8981\u3067\u3059\u3002complete input reason: ${reasonList}\u3002`;
|
|
17069
17108
|
}
|
|
17070
17109
|
function buildCompleteInputPolicy(stmt, options, orderPlan) {
|
|
17071
|
-
const reasons = orderPlan?.kind === "CANONICAL_REST_TOP_N" || orderPlan?.kind === "KORDER_NATIVE" || orderPlan?.kind === "KORDER_CURSOR" ? completeInputReasons({ ...stmt, orderBy: [] }) : completeInputReasons(stmt);
|
|
17110
|
+
const reasons = stmt.type === "SELECT" && (orderPlan?.kind === "CANONICAL_REST_TOP_N" || orderPlan?.kind === "KORDER_NATIVE" || orderPlan?.kind === "KORDER_CURSOR") ? completeInputReasons({ ...stmt, orderBy: [] }) : completeInputReasons(stmt);
|
|
17072
17111
|
const truncateWasDisabled = reasons.size > 0 && options.onLimitReached === "truncate";
|
|
17073
17112
|
return {
|
|
17074
17113
|
reasons,
|
|
@@ -17077,9 +17116,10 @@ function buildCompleteInputPolicy(stmt, options, orderPlan) {
|
|
|
17077
17116
|
};
|
|
17078
17117
|
}
|
|
17079
17118
|
function throwCompleteInputError(policy, error) {
|
|
17080
|
-
if (policy.reasons.size > 0 && error instanceof FetchAllLimitError) {
|
|
17119
|
+
if (policy.reasons.size > 0 && error instanceof FetchAllLimitError && !error.completeInputWrapped) {
|
|
17081
17120
|
throw new FetchAllLimitError(
|
|
17082
|
-
completeInputErrorPrefix(policy.reasons) + (policy.truncateWasDisabled ? "onLimit=truncate\u306F\u4F7F\u7528\u3067\u304D\u307E\u305B\u3093\u3002" : "") + error.message
|
|
17121
|
+
completeInputErrorPrefix(policy.reasons) + (policy.truncateWasDisabled ? "onLimit=truncate\u306F\u4F7F\u7528\u3067\u304D\u307E\u305B\u3093\u3002" : "") + error.message,
|
|
17122
|
+
true
|
|
17083
17123
|
);
|
|
17084
17124
|
}
|
|
17085
17125
|
throw error;
|
|
@@ -18312,26 +18352,53 @@ async function executeFullScanSelect(stmt, client, options, cacheContext, cteCac
|
|
|
18312
18352
|
return { type: "SELECT", rows, columns, rowCount: rows.length, warnings: [...warnings] };
|
|
18313
18353
|
}
|
|
18314
18354
|
async function executeUnion(stmt, client, options, cacheContext, captureColumnMeta = false, forLibraryCapture = false) {
|
|
18315
|
-
const
|
|
18316
|
-
|
|
18317
|
-
|
|
18318
|
-
|
|
18319
|
-
|
|
18320
|
-
|
|
18321
|
-
|
|
18322
|
-
|
|
18323
|
-
|
|
18324
|
-
|
|
18355
|
+
const completePolicy = buildCompleteInputPolicy(stmt, options, null);
|
|
18356
|
+
return withCompleteInputPolicy(completePolicy, async () => {
|
|
18357
|
+
const effectiveOptions = completePolicy.effectiveOptions;
|
|
18358
|
+
const [leftResult, rightResult] = await Promise.all([
|
|
18359
|
+
stmt.left.type === "UNION" ? executeUnion(
|
|
18360
|
+
stmt.left,
|
|
18361
|
+
client,
|
|
18362
|
+
effectiveOptions,
|
|
18363
|
+
cacheContext,
|
|
18364
|
+
captureColumnMeta,
|
|
18365
|
+
forLibraryCapture
|
|
18366
|
+
) : executeSelect(
|
|
18367
|
+
stmt.left,
|
|
18368
|
+
client,
|
|
18369
|
+
effectiveOptions,
|
|
18370
|
+
cacheContext,
|
|
18371
|
+
void 0,
|
|
18372
|
+
captureColumnMeta,
|
|
18373
|
+
forLibraryCapture
|
|
18374
|
+
),
|
|
18375
|
+
executeSelect(
|
|
18376
|
+
stmt.right,
|
|
18377
|
+
client,
|
|
18378
|
+
effectiveOptions,
|
|
18379
|
+
cacheContext,
|
|
18380
|
+
void 0,
|
|
18381
|
+
captureColumnMeta,
|
|
18382
|
+
forLibraryCapture
|
|
18383
|
+
)
|
|
18384
|
+
]);
|
|
18385
|
+
const leftCols = leftResult.columns;
|
|
18386
|
+
const rightCols = rightResult.columns;
|
|
18387
|
+
const remappedRight = rightResult.rows.map((row) => {
|
|
18388
|
+
const mapped = {};
|
|
18389
|
+
leftCols.forEach((col, i) => {
|
|
18390
|
+
mapped[col] = row[rightCols[i] ?? col] ?? "";
|
|
18391
|
+
});
|
|
18392
|
+
return mapped;
|
|
18325
18393
|
});
|
|
18326
|
-
|
|
18394
|
+
const combined = [...leftResult.rows, ...remappedRight];
|
|
18395
|
+
const rows = stmt.all ? combined : deduplicateRows(combined, leftCols);
|
|
18396
|
+
const result = { type: "SELECT", rows, columns: leftCols, rowCount: rows.length };
|
|
18397
|
+
if (captureColumnMeta) {
|
|
18398
|
+
materializedMetaBySelectResult.set(result, mergeUnionColumnMeta(leftResult, rightResult));
|
|
18399
|
+
}
|
|
18400
|
+
return result;
|
|
18327
18401
|
});
|
|
18328
|
-
const combined = [...leftResult.rows, ...remappedRight];
|
|
18329
|
-
const rows = stmt.all ? combined : deduplicateRows(combined, leftCols);
|
|
18330
|
-
const result = { type: "SELECT", rows, columns: leftCols, rowCount: rows.length };
|
|
18331
|
-
if (captureColumnMeta) {
|
|
18332
|
-
materializedMetaBySelectResult.set(result, mergeUnionColumnMeta(leftResult, rightResult));
|
|
18333
|
-
}
|
|
18334
|
-
return result;
|
|
18335
18402
|
}
|
|
18336
18403
|
function deduplicateRows(rows, columns) {
|
|
18337
18404
|
const seen = /* @__PURE__ */ new Set();
|
|
@@ -18600,6 +18667,12 @@ async function fetchTableRecordsForFullScan(stmt, table, client, maxRecords, par
|
|
|
18600
18667
|
const onTruncate = (max) => {
|
|
18601
18668
|
warnings.add(`\u53D6\u5F97\u4E0A\u9650\uFF08${max} \u4EF6\uFF09\u306B\u9054\u3057\u305F\u305F\u3081\u3001${max} \u4EF6\u3067\u6253\u3061\u5207\u3063\u3066\u8868\u793A\u3057\u3066\u3044\u307E\u3059\u3002`);
|
|
18602
18669
|
markLimitReached(client, table.appId);
|
|
18670
|
+
if (isOuterJoinNonPreservedTable(stmt, table, isMainTable)) {
|
|
18671
|
+
throw new FetchAllLimitError(
|
|
18672
|
+
`\u5916\u90E8\u7D50\u5408\u306E\u6B63\u3057\u3044\u7D50\u679C\u306B\u306F\u5B8C\u5168\u306A\u5019\u88DC\u96C6\u5408\u304C\u5FC5\u8981\u3067\u3059\u3002complete input reason: OUTER_JOIN_NON_PRESERVED\uFF08APP${table.appId}\uFF09\u3002onLimit=truncate\u306F\u4F7F\u7528\u3067\u304D\u307E\u305B\u3093\u3002\u53D6\u5F97\u4EF6\u6570\u304C\u4E0A\u9650\uFF08${max} \u4EF6\uFF09\u3092\u8D85\u3048\u307E\u3057\u305F\u3002WHERE \u53E5\u3067\u7D5E\u308A\u8FBC\u3080\u304B\u3001maxRecords \u3092\u5F15\u304D\u4E0A\u3052\u3066\u304F\u3060\u3055\u3044\u3002`,
|
|
18673
|
+
true
|
|
18674
|
+
);
|
|
18675
|
+
}
|
|
18603
18676
|
};
|
|
18604
18677
|
if (!table.subtableCode) {
|
|
18605
18678
|
const baseQuery = isMainTable && allowOriginalWherePushdown ? selectToFetchAllParams(stmt, table.appId).query : "";
|