@rex0220/kintone-sql-tools 3.38.0 → 3.39.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 +126 -15
- package/dist-engine/index.cjs +9 -9
- package/dist-engine/index.mjs +10 -10
- package/dist-engine/ksql-engine.umd.js +10 -10
- package/dist-engine/meta/bundle-baseline.json +7 -7
- package/dist-engine/meta/cjs.json +10 -10
- package/dist-engine/meta/esm.json +10 -10
- package/dist-engine/meta/umd.json +10 -10
- package/dist-mcp/ksql-mcp.js +128 -17
- package/dist-mcpb/ksql-mcp.mcpb +0 -0
- package/package.json +1 -1
package/dist-cli/ksql.js
CHANGED
|
@@ -1175,13 +1175,38 @@ var Parser = class {
|
|
|
1175
1175
|
parseDeclareVariable() {
|
|
1176
1176
|
this.advance();
|
|
1177
1177
|
const variable = this.expect("VARIABLE" /* VARIABLE */, "DECLARE \u306E\u5F8C\u306B\u306F\u5909\u6570\u540D\uFF08\u4F8B: @name\uFF09\u304C\u5FC5\u8981\u3067\u3059");
|
|
1178
|
+
const relativeDate = this.peek().kind === "IDENT" /* IDENT */ && this.peek().value.toUpperCase() === "RELATIVE_DATE";
|
|
1179
|
+
if (relativeDate) this.advance();
|
|
1178
1180
|
this.expect("=" /* EQ */);
|
|
1181
|
+
if (relativeDate) {
|
|
1182
|
+
return {
|
|
1183
|
+
type: "DECLARE_VARIABLE",
|
|
1184
|
+
name: variable.value.slice(1).toLowerCase(),
|
|
1185
|
+
annotation: "RELATIVE_DATE",
|
|
1186
|
+
default: this.parseRelativeDateVariableToken()
|
|
1187
|
+
};
|
|
1188
|
+
}
|
|
1179
1189
|
const expr = this.parseScalarExpr("DECLARE", false);
|
|
1180
1190
|
if (expr.type === "SCALAR_SUBQUERY") {
|
|
1181
1191
|
throw new ParseError("DECLARE \u306E\u65E2\u5B9A\u5024\u306B\u30B9\u30AB\u30E9\u30FC\u30B5\u30D6\u30AF\u30A8\u30EA\u306F\u4F7F\u7528\u3067\u304D\u307E\u305B\u3093", this.peek());
|
|
1182
1192
|
}
|
|
1183
1193
|
return { type: "DECLARE_VARIABLE", name: variable.value.slice(1).toLowerCase(), default: expr };
|
|
1184
1194
|
}
|
|
1195
|
+
/** RELATIVE_DATE 宣言専用。WHERE と同じ関数パーサーを使い、日付系14個だけを許可する。 */
|
|
1196
|
+
parseRelativeDateVariableToken() {
|
|
1197
|
+
const tok = this.peek();
|
|
1198
|
+
const contextualFunction = PARSER_CONTEXTUAL_FUNCTION_TOKEN_MAP[tok.kind];
|
|
1199
|
+
if (contextualFunction === "TODAY" || contextualFunction === "NOW") {
|
|
1200
|
+
return this.parseSqlValue();
|
|
1201
|
+
}
|
|
1202
|
+
if (tok.kind === "IDENT" /* IDENT */ && this.peekAt(1).kind === "(" /* LPAREN */ && isRelativeDateFunctionName(tok.value.toUpperCase())) {
|
|
1203
|
+
return this.parseRelativeDateFunction();
|
|
1204
|
+
}
|
|
1205
|
+
throw new ParseError(
|
|
1206
|
+
"RELATIVE_DATE \u306E\u65E2\u5B9A\u5024\u306B\u306F\u30B5\u30DD\u30FC\u30C8\u5BFE\u8C61\u306E\u76F8\u5BFE\u65E5\u4ED8\u95A2\u6570\u30C8\u30FC\u30AF\u30F3\u304C\u5FC5\u8981\u3067\u3059",
|
|
1207
|
+
tok
|
|
1208
|
+
);
|
|
1209
|
+
}
|
|
1185
1210
|
/** SET / DECLARE RHS 専用。既存式パーサーで構文を読み、フィールド参照を明示的に拒否する。 */
|
|
1186
1211
|
parseScalarExpr(context, allowScalarSubquery) {
|
|
1187
1212
|
const tok = this.peek();
|
|
@@ -6807,9 +6832,10 @@ function collectRefs(node, tempRefs, appIds) {
|
|
|
6807
6832
|
for (const v of Object.values(obj)) collectRefs(v, tempRefs, appIds);
|
|
6808
6833
|
}
|
|
6809
6834
|
}
|
|
6810
|
-
|
|
6835
|
+
var RELATIVE_DATE_COMPARISON_OPS = /* @__PURE__ */ new Set(["=", "!=", "<>", ">", "<", ">=", "<="]);
|
|
6836
|
+
function collectVariableRefs(node, refs, inWhere = false) {
|
|
6811
6837
|
if (Array.isArray(node)) {
|
|
6812
|
-
for (const v of node) collectVariableRefs(v, refs);
|
|
6838
|
+
for (const v of node) collectVariableRefs(v, refs, inWhere);
|
|
6813
6839
|
return;
|
|
6814
6840
|
}
|
|
6815
6841
|
if (node !== null && typeof node === "object") {
|
|
@@ -6818,13 +6844,27 @@ function collectVariableRefs(node, refs) {
|
|
|
6818
6844
|
if ((type === "VARIABLE" || type === "VARIABLE_COL" || type === "VARIABLE_IN_LIST") && typeof obj["name"] === "string") {
|
|
6819
6845
|
refs.push({
|
|
6820
6846
|
name: obj["name"],
|
|
6821
|
-
kind: type === "VARIABLE" ? "scalar" : type === "VARIABLE_COL" ? "select-column" : "array-in-list"
|
|
6847
|
+
kind: type === "VARIABLE" ? "scalar" : type === "VARIABLE_COL" ? "select-column" : "array-in-list",
|
|
6848
|
+
relativeDateAllowed: inWhere
|
|
6822
6849
|
});
|
|
6823
6850
|
return;
|
|
6824
6851
|
}
|
|
6825
|
-
|
|
6852
|
+
const preservesWhereContext = type === "BINARY" || type === "LOGICAL" || type === "NOT" || type === "GROUP" || type === "NULL_CHECK" || type === "BOOLEAN";
|
|
6853
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
6854
|
+
const directVariable = value !== null && typeof value === "object" && value["type"] === "VARIABLE";
|
|
6855
|
+
const directComparisonRight = inWhere && type === "BINARY" && key === "right" && directVariable && RELATIVE_DATE_COMPARISON_OPS.has(String(obj["op"]));
|
|
6856
|
+
collectVariableRefs(
|
|
6857
|
+
value,
|
|
6858
|
+
refs,
|
|
6859
|
+
key === "where" ? true : type === "BINARY" && key === "right" && directVariable ? directComparisonRight : preservesWhereContext ? inWhere : false
|
|
6860
|
+
);
|
|
6861
|
+
}
|
|
6826
6862
|
}
|
|
6827
6863
|
}
|
|
6864
|
+
function isRelativeDateDmlUse(stmt) {
|
|
6865
|
+
const target = stmt.type === "EXPLAIN" ? stmt.query : stmt;
|
|
6866
|
+
return isDmlType(target.type) || target.type === "VALIDATE";
|
|
6867
|
+
}
|
|
6828
6868
|
function validateGroupingStaticQueries(node) {
|
|
6829
6869
|
if (Array.isArray(node)) {
|
|
6830
6870
|
for (const value of node) validateGroupingStaticQueries(value);
|
|
@@ -6919,6 +6959,18 @@ function analyzeBatch(statements) {
|
|
|
6919
6959
|
index
|
|
6920
6960
|
);
|
|
6921
6961
|
}
|
|
6962
|
+
if (def.relativeDate && isRelativeDateDmlUse(stmt)) {
|
|
6963
|
+
throw new BatchAnalysisError(
|
|
6964
|
+
`ArgumentError: RELATIVE_DATE variable @${use.name} cannot be used in DML or VALIDATE statements.`,
|
|
6965
|
+
index
|
|
6966
|
+
);
|
|
6967
|
+
}
|
|
6968
|
+
if (def.relativeDate && !use.relativeDateAllowed) {
|
|
6969
|
+
throw new BatchAnalysisError(
|
|
6970
|
+
`ArgumentError: RELATIVE_DATE variable @${use.name} can only be used as a WHERE comparison right operand or BETWEEN boundary.`,
|
|
6971
|
+
index
|
|
6972
|
+
);
|
|
6973
|
+
}
|
|
6922
6974
|
if (!referencedThisStatement.has(use.name)) {
|
|
6923
6975
|
def.referencedBy.push(index);
|
|
6924
6976
|
referencedThisStatement.add(use.name);
|
|
@@ -6931,6 +6983,7 @@ function analyzeBatch(statements) {
|
|
|
6931
6983
|
variableDefs.set(stmt.name, {
|
|
6932
6984
|
index,
|
|
6933
6985
|
kind: stmt.type === "SET_VARIABLE" && stmt.expr.type === "ARRAY" ? "array" : "scalar",
|
|
6986
|
+
relativeDate: stmt.type === "DECLARE_VARIABLE" && stmt.annotation === "RELATIVE_DATE",
|
|
6934
6987
|
referencedBy: []
|
|
6935
6988
|
});
|
|
6936
6989
|
variableOrder.push(stmt.name);
|
|
@@ -16123,6 +16176,7 @@ async function executeBatch(sql, client, options = {}) {
|
|
|
16123
16176
|
throw new Error("UnsupportedError: APPLY mutation requires allowApplyMutation=true");
|
|
16124
16177
|
}
|
|
16125
16178
|
const injectedVariables = validateDeclaredBatchVariables(statements, options.variables);
|
|
16179
|
+
const relativeDateVariables = prepareRelativeDateVariables(statements, injectedVariables);
|
|
16126
16180
|
const batchOptions = { ...options, variables: injectedVariables };
|
|
16127
16181
|
if (options.continueOnError && analysis.containsDml) {
|
|
16128
16182
|
throw new Error("ArgumentError: continueOnError is not allowed for batches containing DML.");
|
|
@@ -16194,7 +16248,16 @@ async function executeBatch(sql, client, options = {}) {
|
|
|
16194
16248
|
);
|
|
16195
16249
|
const cursorScope = wrapClientWithCursorScope(statementClient);
|
|
16196
16250
|
const outcome = await runWithDeadline(
|
|
16197
|
-
executeBatchStatement(
|
|
16251
|
+
executeBatchStatement(
|
|
16252
|
+
statements[i],
|
|
16253
|
+
info,
|
|
16254
|
+
cursorScope.client,
|
|
16255
|
+
stmtOptions,
|
|
16256
|
+
cacheContext,
|
|
16257
|
+
tempTables,
|
|
16258
|
+
variables,
|
|
16259
|
+
relativeDateVariables
|
|
16260
|
+
),
|
|
16198
16261
|
remaining,
|
|
16199
16262
|
cursorScope.closeActive
|
|
16200
16263
|
);
|
|
@@ -16239,7 +16302,7 @@ function statementHasApplyMutation(statement) {
|
|
|
16239
16302
|
}
|
|
16240
16303
|
return statement.type === "UPSERT" && statement.validateOnly !== true && Boolean(statement.onInsertApplyBlocks?.length || statement.onUpdateApplyBlocks?.length);
|
|
16241
16304
|
}
|
|
16242
|
-
async function executeBatchStatement(stmt, info, client, options, cacheContext, tempTables, variables) {
|
|
16305
|
+
async function executeBatchStatement(stmt, info, client, options, cacheContext, tempTables, variables, relativeDateVariables) {
|
|
16243
16306
|
if (stmt.type === "SET_VARIABLE") {
|
|
16244
16307
|
const resolvedStmt2 = resolveBatchVariableReferences(stmt, variables);
|
|
16245
16308
|
validateStatementStatic(resolvedStmt2);
|
|
@@ -16284,6 +16347,13 @@ async function executeBatchStatement(stmt, info, client, options, cacheContext,
|
|
|
16284
16347
|
return {};
|
|
16285
16348
|
}
|
|
16286
16349
|
if (stmt.type === "DECLARE_VARIABLE") {
|
|
16350
|
+
if (stmt.annotation === "RELATIVE_DATE") {
|
|
16351
|
+
variables.set(stmt.name, {
|
|
16352
|
+
type: "relative-date",
|
|
16353
|
+
value: relativeDateVariables.get(stmt.name)
|
|
16354
|
+
});
|
|
16355
|
+
return {};
|
|
16356
|
+
}
|
|
16287
16357
|
const injected = options.variables ?? {};
|
|
16288
16358
|
if (Object.prototype.hasOwnProperty.call(injected, stmt.name)) {
|
|
16289
16359
|
variables.set(stmt.name, { type: "string", value: injected[stmt.name] });
|
|
@@ -16507,6 +16577,32 @@ function parseSqlBatch(sql, enableImport = false) {
|
|
|
16507
16577
|
const tokens = new Lexer(sql).tokenize();
|
|
16508
16578
|
return new Parser(tokens, { import: enableImport }).parseStatements();
|
|
16509
16579
|
}
|
|
16580
|
+
function parseRelativeDateVariableValue(name, value) {
|
|
16581
|
+
try {
|
|
16582
|
+
const statements = parseSqlBatch(`DECLARE @__b111 RELATIVE_DATE = ${value}`);
|
|
16583
|
+
const declaration = statements[0];
|
|
16584
|
+
if (statements.length !== 1 || declaration?.type !== "DECLARE_VARIABLE" || declaration.annotation !== "RELATIVE_DATE") {
|
|
16585
|
+
throw new Error("token was not consumed as one RELATIVE_DATE declaration");
|
|
16586
|
+
}
|
|
16587
|
+
return declaration.default;
|
|
16588
|
+
} catch (error) {
|
|
16589
|
+
const detail = error instanceof Error ? ` ${error.message}` : "";
|
|
16590
|
+
throw new Error(
|
|
16591
|
+
`ArgumentError: RELATIVE_DATE variable @${name} requires one supported relative-date function token.${detail}`
|
|
16592
|
+
);
|
|
16593
|
+
}
|
|
16594
|
+
}
|
|
16595
|
+
function prepareRelativeDateVariables(statements, injectedVariables) {
|
|
16596
|
+
const prepared = /* @__PURE__ */ new Map();
|
|
16597
|
+
for (const stmt of statements) {
|
|
16598
|
+
if (stmt.type !== "DECLARE_VARIABLE" || stmt.annotation !== "RELATIVE_DATE") continue;
|
|
16599
|
+
prepared.set(
|
|
16600
|
+
stmt.name,
|
|
16601
|
+
Object.prototype.hasOwnProperty.call(injectedVariables, stmt.name) ? parseRelativeDateVariableValue(stmt.name, injectedVariables[stmt.name]) : stmt.default
|
|
16602
|
+
);
|
|
16603
|
+
}
|
|
16604
|
+
return prepared;
|
|
16605
|
+
}
|
|
16510
16606
|
function evaluateScalarExpr(expr) {
|
|
16511
16607
|
switch (expr.type) {
|
|
16512
16608
|
case "STRING":
|
|
@@ -16543,7 +16639,8 @@ function resolveBatchVariableReferencesInternal(node, variables, numericArithmet
|
|
|
16543
16639
|
if (value.type === "array") {
|
|
16544
16640
|
throw new Error(`ParseError: array variable @${obj["name"]} can only be used as IN @${obj["name"]}.`);
|
|
16545
16641
|
}
|
|
16546
|
-
if (
|
|
16642
|
+
if (value.type === "relative-date") return value.value;
|
|
16643
|
+
if (numericArithmeticOperand && value.type !== "number" && !(value.type === "string" && value.placeholder === true)) {
|
|
16547
16644
|
throw new Error(
|
|
16548
16645
|
`ArgumentError: variable @${obj["name"]} is not numeric and cannot be used in arithmetic.`
|
|
16549
16646
|
);
|
|
@@ -16554,6 +16651,9 @@ function resolveBatchVariableReferencesInternal(node, variables, numericArithmet
|
|
|
16554
16651
|
const value = variables.get(obj["name"]);
|
|
16555
16652
|
if (value === void 0) throw new Error(`ParseError: variable @${obj["name"]} is not defined in this batch.`);
|
|
16556
16653
|
if (value.type === "array") throw new Error(`ParseError: array variable @${obj["name"]} cannot be used as a SELECT column.`);
|
|
16654
|
+
if (value.type === "relative-date") {
|
|
16655
|
+
throw new Error(`InternalError: RELATIVE_DATE variable @${obj["name"]} reached a SELECT column.`);
|
|
16656
|
+
}
|
|
16557
16657
|
const aliasDisplay = typeof obj["aliasDisplay"] === "string" ? { aliasDisplay: obj["aliasDisplay"] } : {};
|
|
16558
16658
|
return value.type === "number" ? { type: "ARITH_COL", expr: { type: "NUMBER", value: value.value, raw: value.raw ?? String(value.value) }, alias: obj["alias"], ...aliasDisplay } : { type: "LITERAL_COL", value: value.value, alias: obj["alias"], ...aliasDisplay };
|
|
16559
16659
|
}
|
|
@@ -22673,7 +22773,8 @@ async function buildBatchExplainPlans(sql, client, injectedVariables, cacheConte
|
|
|
22673
22773
|
try {
|
|
22674
22774
|
const statements = parseSqlBatch(sql, enableImport);
|
|
22675
22775
|
const analysis = analyzeBatch(statements);
|
|
22676
|
-
validateDeclaredBatchVariables(statements, injectedVariables);
|
|
22776
|
+
const normalizedInjectedVariables = validateDeclaredBatchVariables(statements, injectedVariables);
|
|
22777
|
+
const relativeDateVariables = prepareRelativeDateVariables(statements, normalizedInjectedVariables);
|
|
22677
22778
|
const variables = /* @__PURE__ */ new Map();
|
|
22678
22779
|
const plans = [];
|
|
22679
22780
|
for (let i = 0; i < statements.length; i++) {
|
|
@@ -22706,7 +22807,7 @@ async function buildBatchExplainPlans(sql, client, injectedVariables, cacheConte
|
|
|
22706
22807
|
plan: statementPlan.length === 0 ? metadataPlan : [statementPlan[0], ...metadataPlan, ...statementPlan.slice(1)]
|
|
22707
22808
|
});
|
|
22708
22809
|
if (stmt.type === "SET_VARIABLE" || stmt.type === "DECLARE_VARIABLE") {
|
|
22709
|
-
variables.set(stmt.name, stmt.type === "SET_VARIABLE" && stmt.expr.type === "ARRAY" ? { type: "array", elements: stmt.expr.elements.map((element) => ({ type: "string", value: element.value })) } : { type: "string", value: `@${stmt.name}`, placeholder: true });
|
|
22810
|
+
variables.set(stmt.name, stmt.type === "DECLARE_VARIABLE" && stmt.annotation === "RELATIVE_DATE" ? { type: "relative-date", value: relativeDateVariables.get(stmt.name) } : stmt.type === "SET_VARIABLE" && stmt.expr.type === "ARRAY" ? { type: "array", elements: stmt.expr.elements.map((element) => ({ type: "string", value: element.value })) } : { type: "string", value: `@${stmt.name}`, placeholder: true });
|
|
22710
22811
|
}
|
|
22711
22812
|
}
|
|
22712
22813
|
return { statementCount: statements.length, statements: plans };
|
|
@@ -22745,6 +22846,12 @@ function buildBatchStatementPlan(stmt, info, capabilities, orderPlans, dmlMaxRow
|
|
|
22745
22846
|
];
|
|
22746
22847
|
}
|
|
22747
22848
|
if (stmt.type === "DECLARE_VARIABLE") {
|
|
22849
|
+
if (stmt.annotation === "RELATIVE_DATE") {
|
|
22850
|
+
return [
|
|
22851
|
+
`DECLARE @${stmt.name} RELATIVE_DATE = <relative-date token>`,
|
|
22852
|
+
" value: \u5916\u90E8\u6CE8\u5165\u304C\u3042\u308C\u3070\u63A1\u7528\u3001\u306A\u3051\u308C\u3070\u65E2\u5B9A\u30C8\u30FC\u30AF\u30F3\u3092\u4F7F\u7528\uFF08\u5024\u306F\u975E\u516C\u958B\uFF09"
|
|
22853
|
+
];
|
|
22854
|
+
}
|
|
22748
22855
|
return [
|
|
22749
22856
|
`DECLARE @${stmt.name} = <default scalar expression>`,
|
|
22750
22857
|
" value: \u5916\u90E8\u6CE8\u5165\u304C\u3042\u308C\u3070\u63A1\u7528\u3001\u306A\u3051\u308C\u3070\u65E2\u5B9A\u5024\u3092\u5B9F\u884C\u6642\u306B1\u56DE\u8A55\u4FA1\uFF08\u5024\u306F\u975E\u516C\u958B\uFF09"
|
|
@@ -25374,13 +25481,17 @@ function restoreSqlDiagnosticValue(value, bindings, options = {}) {
|
|
|
25374
25481
|
return `${dmlTarget[1]}${target}`;
|
|
25375
25482
|
}
|
|
25376
25483
|
}
|
|
25377
|
-
|
|
25378
|
-
|
|
25379
|
-
|
|
25484
|
+
if (bindings.size === 0) return value;
|
|
25485
|
+
const mappedIds = [...bindings.keys()].sort((a, b) => String(b).length - String(a).length);
|
|
25486
|
+
const internalApp = new RegExp(
|
|
25487
|
+
`APP(${mappedIds.join("|")})(?!\\d)(\\s+AS\\s+[^\\s()]+)?(?:\\s+\\(\\1\\))?`,
|
|
25488
|
+
"g"
|
|
25489
|
+
);
|
|
25490
|
+
return value.replace(internalApp, (_match, mappedIdText, alias) => {
|
|
25491
|
+
const binding = bindings.get(Number(mappedIdText));
|
|
25380
25492
|
const display = binding.source === "logical" ? displayMode === "physical" ? `LAPP_${binding.logicalName} -> APP${binding.appId}` : `LAPP_${binding.logicalName}@${binding.profile}` : displayMode === "physical" ? `APP${binding.appId}` : `APP${binding.appId}@${binding.profile}`;
|
|
25381
|
-
|
|
25382
|
-
}
|
|
25383
|
-
return restored;
|
|
25493
|
+
return `${display}${alias ?? ""}`;
|
|
25494
|
+
});
|
|
25384
25495
|
}
|
|
25385
25496
|
if (Array.isArray(value)) {
|
|
25386
25497
|
return value.map((item) => restoreSqlDiagnosticValue(item, bindings, options));
|