@rex0220/kintone-sql-tools 3.69.0 → 3.71.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/README.md +1 -1
- package/dist-cli/ksql.js +27 -9
- package/dist-engine/index.cjs +14 -14
- package/dist-engine/index.mjs +14 -14
- package/dist-engine/ksql-engine.umd.js +14 -14
- package/dist-engine/meta/bundle-baseline.json +7 -7
- package/dist-engine/meta/cjs.json +3 -3
- package/dist-engine/meta/esm.json +3 -3
- package/dist-engine/meta/umd.json +3 -3
- package/dist-flow/flow-library/index.d.ts +4 -2
- package/dist-flow/flow-library/publicTypes.d.ts +76 -0
- package/dist-flow/index.cjs +13 -13
- package/dist-flow/index.mjs +13 -13
- package/dist-flow/meta/cjs.json +18 -5
- package/dist-flow/meta/esm.json +20 -5
- package/dist-mcp/ksql-mcp.js +29 -11
- package/dist-mcpb/ksql-mcp.mcpb +0 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -267,7 +267,7 @@ npm パッケージは 2 つのサブパスを **semver 対象の公開 API**
|
|
|
267
267
|
| サブパス | 用途 | 主な export |
|
|
268
268
|
|---|---|---|
|
|
269
269
|
| `@rex0220/kintone-sql-tools/engine` | **read-only** のクエリ実行(ダッシュボード等)。書込 API は構造的に遮断 | `runQuery` / `runBatch` / `explainQuery` / `createReadonlyKintoneClient` / `KsqlEngineError` / `version` |
|
|
270
|
-
| `@rex0220/kintone-sql-tools/flow` | **Flow dialect 1**(→ [言語リファレンス §27](docs/ksql_language_reference.md))のスクリプト解析・検証・**文単位実行**(バッチランナー向け・書込可能) | `parseScript` / `validateScript` / `explainScript` / `createExecutionContext` / `executeStatement` / `disposeExecutionContext` / `createKintoneClient` / `version` |
|
|
270
|
+
| `@rex0220/kintone-sql-tools/flow` | **Flow dialect 1**(→ [言語リファレンス §27](docs/ksql_language_reference.md))のスクリプト解析・検証・**文単位実行**(バッチランナー向け・書込可能) | `parseScript` / `validateScript` / `explainScript`(`asOf`/`timezone` 注入可) / `createExecutionContext`(`onChunkWritten` 書込チャンク通知) / `executeStatement` / `previewStatement`(dry-run 差分プレビュー・書込 0 回) / `disposeExecutionContext` / `createKintoneClient` / `isDmlResult`(`FlowDmlResult` 型ガード) / `version` |
|
|
271
271
|
|
|
272
272
|
`/flow` の典型的な使い方(1 文ずつ実行して結果で継続判断する):
|
|
273
273
|
|
package/dist-cli/ksql.js
CHANGED
|
@@ -18725,7 +18725,7 @@ async function executeParsedStatement(stmt, client, options, cacheContext) {
|
|
|
18725
18725
|
if (stmt.type !== "EXPLAIN") assertRelativeDatePushdownPlan(relativeDatePlan);
|
|
18726
18726
|
const unresolved = findVariableRef(stmt);
|
|
18727
18727
|
if (unresolved !== null && !isApplyParentKlikeStatement(stmt)) {
|
|
18728
|
-
throw new Error(
|
|
18728
|
+
throw new Error(undefinedBatchVariableMessage(unresolved, "in a batch"));
|
|
18729
18729
|
}
|
|
18730
18730
|
assertApplyScope("phase15b", stmt);
|
|
18731
18731
|
assertApplyExecutionScope("phase15b", stmt);
|
|
@@ -19597,6 +19597,9 @@ function evaluateScalarExpr(expr, evaluationContext = {}) {
|
|
|
19597
19597
|
function resolveBatchVariableReferences(node, variables) {
|
|
19598
19598
|
return resolveBatchVariableReferencesInternal(node, variables, false);
|
|
19599
19599
|
}
|
|
19600
|
+
function undefinedBatchVariableMessage(name, location2) {
|
|
19601
|
+
return asOfFunctionNameFromVariable(name) === null ? `ParseError: variable @${name} is not defined ${location2}.` : `ParseError: @NOW() \u306A\u3069\u306E as-of \u95A2\u6570\u306F\u57FA\u6E96\u6642\u523B\u304C\u521D\u671F\u5316\u3055\u308C\u3066\u3044\u307E\u305B\u3093\u3002`;
|
|
19602
|
+
}
|
|
19600
19603
|
function resolveBatchVariableReferencesInternal(node, variables, numericArithmeticOperand) {
|
|
19601
19604
|
if (Array.isArray(node)) {
|
|
19602
19605
|
return node.map((v) => resolveBatchVariableReferencesInternal(v, variables, false));
|
|
@@ -19606,7 +19609,7 @@ function resolveBatchVariableReferencesInternal(node, variables, numericArithmet
|
|
|
19606
19609
|
if (obj["type"] === "VARIABLE" && typeof obj["name"] === "string") {
|
|
19607
19610
|
const value = variables.get(obj["name"]);
|
|
19608
19611
|
if (value === void 0) {
|
|
19609
|
-
throw new Error(
|
|
19612
|
+
throw new Error(undefinedBatchVariableMessage(obj["name"], "in this batch"));
|
|
19610
19613
|
}
|
|
19611
19614
|
if (value.type === "array") {
|
|
19612
19615
|
throw new Error(`ParseError: array variable @${obj["name"]} can only be used as IN @${obj["name"]}.`);
|
|
@@ -19629,7 +19632,7 @@ function resolveBatchVariableReferencesInternal(node, variables, numericArithmet
|
|
|
19629
19632
|
}
|
|
19630
19633
|
if (obj["type"] === "VARIABLE_COL" && typeof obj["name"] === "string" && (typeof obj["alias"] === "string" || obj["alias"] === null)) {
|
|
19631
19634
|
const value = variables.get(obj["name"]);
|
|
19632
|
-
if (value === void 0) throw new Error(
|
|
19635
|
+
if (value === void 0) throw new Error(undefinedBatchVariableMessage(obj["name"], "in this batch"));
|
|
19633
19636
|
if (value.type === "array") throw new Error(`ParseError: array variable @${obj["name"]} cannot be used as a SELECT column.`);
|
|
19634
19637
|
if (value.type === "relative-date") {
|
|
19635
19638
|
throw new Error(`InternalError: RELATIVE_DATE variable @${obj["name"]} reached a SELECT column.`);
|
|
@@ -19655,7 +19658,7 @@ function resolveBatchVariableReferencesInternal(node, variables, numericArithmet
|
|
|
19655
19658
|
const right = resolved["right"];
|
|
19656
19659
|
if (right?.["type"] === "VARIABLE_IN_LIST" && typeof right["name"] === "string") {
|
|
19657
19660
|
const value = variables.get(right["name"]);
|
|
19658
|
-
if (value === void 0) throw new Error(
|
|
19661
|
+
if (value === void 0) throw new Error(undefinedBatchVariableMessage(right["name"], "in this batch"));
|
|
19659
19662
|
if (value.type !== "array") {
|
|
19660
19663
|
throw new Error(`ParseError: scalar variable @${right["name"]} cannot be used as IN @${right["name"]}; use IN (@${right["name"]}) instead.`);
|
|
19661
19664
|
}
|
|
@@ -22788,11 +22791,16 @@ function lookupUpsertTarget(index, keyParts) {
|
|
|
22788
22791
|
if (!index.numericKey.some(Boolean)) return void 0;
|
|
22789
22792
|
return index.normalized.get(upsertNormalizedKey(keyParts, index.numericKey));
|
|
22790
22793
|
}
|
|
22791
|
-
async function resolveUpsertTargets(appId, keyFields, rowKeyValues, client, options, fieldTypes) {
|
|
22794
|
+
async function resolveUpsertTargets(appId, keyFields, rowKeyValues, client, options, fieldTypes, previewFields) {
|
|
22792
22795
|
const maxRecords = options.maxRecords ?? 1e4;
|
|
22793
22796
|
const parallel = options.fetchParallel ?? 1;
|
|
22794
22797
|
const numericKey = keyFields.map((f) => fieldTypes.get(f) === "NUMBER");
|
|
22795
|
-
const index = {
|
|
22798
|
+
const index = {
|
|
22799
|
+
raw: /* @__PURE__ */ new Map(),
|
|
22800
|
+
normalized: /* @__PURE__ */ new Map(),
|
|
22801
|
+
numericKey,
|
|
22802
|
+
...previewFields ? { snapshots: /* @__PURE__ */ new Map() } : {}
|
|
22803
|
+
};
|
|
22796
22804
|
const setMax = (map, key, id) => {
|
|
22797
22805
|
const cur = map.get(key);
|
|
22798
22806
|
if (cur === void 0 || id > cur) map.set(key, id);
|
|
@@ -22813,20 +22821,26 @@ async function resolveUpsertTargets(appId, keyFields, rowKeyValues, client, opti
|
|
|
22813
22821
|
if (parts.some((p) => p === "")) perRowKeys.push(parts);
|
|
22814
22822
|
else batchFirstKeys.add(parts[0]);
|
|
22815
22823
|
}
|
|
22816
|
-
const fields = ["$id", ...keyFields];
|
|
22824
|
+
const fields = previewFields ? [.../* @__PURE__ */ new Set(["$id", ...keyFields, ...previewFields])] : ["$id", ...keyFields];
|
|
22817
22825
|
for (const chunk3 of splitChunks([...batchFirstKeys], UPSERT_IN_CHUNK_SIZE)) {
|
|
22818
22826
|
const query = `${keyFields[0]} in (${chunk3.map(sqlQuote).join(",")})`;
|
|
22819
22827
|
const records = await fetchAll(client.getRecords, appId, query, fields, { maxRecords, parallel });
|
|
22820
22828
|
for (const rec of records) {
|
|
22821
22829
|
const id = Number(rec["$id"]?.value);
|
|
22822
22830
|
if (!Number.isFinite(id)) continue;
|
|
22831
|
+
index.snapshots?.set(id, rec);
|
|
22823
22832
|
addRecordToIndex(keyFields.map((f) => toScalarText(rec[f]?.value)), id);
|
|
22824
22833
|
}
|
|
22825
22834
|
}
|
|
22826
22835
|
for (const parts of perRowKeys) {
|
|
22827
22836
|
const query = keyFields.map((f, i) => `${f} = ${sqlQuote(parts[i])}`).join(" and ");
|
|
22828
|
-
const
|
|
22837
|
+
const perRowFields = previewFields ? [.../* @__PURE__ */ new Set(["$id", ...previewFields])] : ["$id"];
|
|
22838
|
+
const existing = await fetchAll(client.getRecords, appId, query, perRowFields, { maxRecords, parallel });
|
|
22829
22839
|
if (existing.length === 0) continue;
|
|
22840
|
+
for (const rec of existing) {
|
|
22841
|
+
const id = Number(rec["$id"]?.value);
|
|
22842
|
+
if (Number.isFinite(id)) index.snapshots?.set(id, rec);
|
|
22843
|
+
}
|
|
22830
22844
|
addRecordToIndex(parts, maxRecordId(existing));
|
|
22831
22845
|
}
|
|
22832
22846
|
return index;
|
|
@@ -27101,7 +27115,8 @@ var EXPLAIN_FETCH_PLAN = /* @__PURE__ */ Symbol("ksql.explainFetchPlan");
|
|
|
27101
27115
|
function setExplainFetchPlan(result, plan) {
|
|
27102
27116
|
result[EXPLAIN_FETCH_PLAN] = plan;
|
|
27103
27117
|
}
|
|
27104
|
-
async function buildBatchExplainPlans(sql, client, injectedVariables, cacheContext = "batch-explain", maxRecords = 1e4, cursorMaxActive = 2, enableImport = false, dmlMaxRows = 100, dmlMaxSubtableRows = DEFAULT_APPLY_MAX_SUBTABLE_ROWS, resolveMetadata = true, recursiveCteMaxDepth, recursiveCteMaxRows, recursiveCteMaxExpansions) {
|
|
27118
|
+
async function buildBatchExplainPlans(sql, client, injectedVariables, cacheContext = "batch-explain", maxRecords = 1e4, cursorMaxActive = 2, enableImport = false, dmlMaxRows = 100, dmlMaxSubtableRows = DEFAULT_APPLY_MAX_SUBTABLE_ROWS, resolveMetadata = true, recursiveCteMaxDepth, recursiveCteMaxRows, recursiveCteMaxExpansions, asOf, timezone) {
|
|
27119
|
+
const asOfClock = createAsOfClock(asOf ?? /* @__PURE__ */ new Date(), timezone);
|
|
27105
27120
|
const recursiveLimits = resolveRecursiveCteLimits({
|
|
27106
27121
|
recursiveCteMaxDepth,
|
|
27107
27122
|
recursiveCteMaxRows,
|
|
@@ -27114,6 +27129,9 @@ async function buildBatchExplainPlans(sql, client, injectedVariables, cacheConte
|
|
|
27114
27129
|
const normalizedInjectedVariables = validateDeclaredBatchVariables(statements, injectedVariables);
|
|
27115
27130
|
const relativeDateVariables = prepareRelativeDateVariables(statements, normalizedInjectedVariables);
|
|
27116
27131
|
const variables = /* @__PURE__ */ new Map();
|
|
27132
|
+
for (const [name, value] of Object.entries(asOfClock.values)) {
|
|
27133
|
+
variables.set(asOfVariableName(name), { type: "string", value });
|
|
27134
|
+
}
|
|
27117
27135
|
const literalDeclareDefaults = /* @__PURE__ */ new Map();
|
|
27118
27136
|
const tempSchemaLedger = /* @__PURE__ */ new Map();
|
|
27119
27137
|
const plans = [];
|