@rex0220/kintone-sql-tools 2.2.0 → 2.3.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 +79 -17
- package/dist-mcp/ksql-mcp.js +80 -18
- package/dist-mcpb/ksql-mcp.mcpb +0 -0
- package/package.json +1 -1
package/dist-cli/ksql.js
CHANGED
|
@@ -629,7 +629,22 @@ var Parser = class {
|
|
|
629
629
|
throw new ParseError("SET \u306E\u53F3\u8FBA\u3067 NULL \u306F\u4F7F\u7528\u3067\u304D\u307E\u305B\u3093\uFF08Phase 1a\uFF09", tok);
|
|
630
630
|
}
|
|
631
631
|
if (tok.kind === "(" /* LPAREN */ && this.peekAt(1).kind === "SELECT" /* SELECT */) {
|
|
632
|
-
|
|
632
|
+
this.advance();
|
|
633
|
+
const query = this.parseSelect();
|
|
634
|
+
this.expect(")" /* RPAREN */);
|
|
635
|
+
if (this.isArithOp(this.peek().kind)) {
|
|
636
|
+
throw new ParseError(
|
|
637
|
+
"\u30B9\u30AB\u30E9\u30FC\u30B5\u30D6\u30AF\u30A8\u30EA\u306E\u5F8C\u306B\u7B97\u8853\u6F14\u7B97\u5B50\u306F\u4F7F\u7528\u3067\u304D\u307E\u305B\u3093\u3002\u30B5\u30D6\u30AF\u30A8\u30EA\u5185\u3067\u8A08\u7B97\u3057\u3066\u304F\u3060\u3055\u3044",
|
|
638
|
+
this.peek()
|
|
639
|
+
);
|
|
640
|
+
}
|
|
641
|
+
const hasWildcard = query.columns.some(
|
|
642
|
+
(c) => c.type === "WILDCARD" || c.type === "PARENT_WILDCARD"
|
|
643
|
+
);
|
|
644
|
+
if (!hasWildcard && query.columns.length !== 1) {
|
|
645
|
+
throw new ParseError("scalar subquery in SET must return exactly 1 column.", tok);
|
|
646
|
+
}
|
|
647
|
+
return { type: "SCALAR_SUBQUERY", query };
|
|
633
648
|
}
|
|
634
649
|
if (tok.kind === "STRING" /* STRING */) {
|
|
635
650
|
this.advance();
|
|
@@ -4920,7 +4935,26 @@ async function executeBatch(sql, client, options = {}) {
|
|
|
4920
4935
|
}
|
|
4921
4936
|
async function executeBatchStatement(stmt, info, client, options, cacheContext, tempTables, variables) {
|
|
4922
4937
|
if (stmt.type === "SET_VARIABLE") {
|
|
4923
|
-
|
|
4938
|
+
const resolvedStmt2 = resolveVariableRefs(stmt, variables);
|
|
4939
|
+
if (resolvedStmt2.expr.type === "SCALAR_SUBQUERY") {
|
|
4940
|
+
try {
|
|
4941
|
+
const value = await evaluateScalarSubquery(
|
|
4942
|
+
resolvedStmt2.expr.query,
|
|
4943
|
+
client,
|
|
4944
|
+
options,
|
|
4945
|
+
cacheContext,
|
|
4946
|
+
tempTables
|
|
4947
|
+
);
|
|
4948
|
+
variables.set(stmt.name, { type: "string", value });
|
|
4949
|
+
} catch (e) {
|
|
4950
|
+
if (e instanceof ScalarSubqueryError) {
|
|
4951
|
+
throw new Error(`ArgumentError: ${e.message}`);
|
|
4952
|
+
}
|
|
4953
|
+
throw e;
|
|
4954
|
+
}
|
|
4955
|
+
} else {
|
|
4956
|
+
variables.set(stmt.name, evaluateScalarExpr(resolvedStmt2.expr));
|
|
4957
|
+
}
|
|
4924
4958
|
return {};
|
|
4925
4959
|
}
|
|
4926
4960
|
const resolvedStmt = resolveVariableRefs(stmt, variables);
|
|
@@ -5083,6 +5117,12 @@ var AssertError = class extends Error {
|
|
|
5083
5117
|
this.name = "AssertError";
|
|
5084
5118
|
}
|
|
5085
5119
|
};
|
|
5120
|
+
var ScalarSubqueryError = class extends Error {
|
|
5121
|
+
constructor(message) {
|
|
5122
|
+
super(message);
|
|
5123
|
+
this.name = "ScalarSubqueryError";
|
|
5124
|
+
}
|
|
5125
|
+
};
|
|
5086
5126
|
async function executeAssert(stmt, client, options, cacheContext, tempTables) {
|
|
5087
5127
|
const left = await evalAssertOperand(stmt.left, client, options, cacheContext, tempTables);
|
|
5088
5128
|
if (stmt.op === "BETWEEN") {
|
|
@@ -5116,25 +5156,38 @@ async function evalAssertOperand(operand, client, options, cacheContext, tempTab
|
|
|
5116
5156
|
case "ARITH":
|
|
5117
5157
|
return String(evalAssertArith(operand));
|
|
5118
5158
|
case "SCALAR_SUBQUERY": {
|
|
5119
|
-
|
|
5120
|
-
|
|
5121
|
-
|
|
5122
|
-
|
|
5123
|
-
|
|
5159
|
+
try {
|
|
5160
|
+
return await evaluateScalarSubquery(
|
|
5161
|
+
operand.query,
|
|
5162
|
+
client,
|
|
5163
|
+
options,
|
|
5164
|
+
cacheContext,
|
|
5165
|
+
tempTables
|
|
5124
5166
|
);
|
|
5167
|
+
} catch (e) {
|
|
5168
|
+
if (e instanceof ScalarSubqueryError) throw new AssertError(e.message);
|
|
5169
|
+
throw e;
|
|
5125
5170
|
}
|
|
5126
|
-
if (result.rowCount === 0) {
|
|
5127
|
-
throw new AssertError("scalar subquery returned no rows (expected 1 row).");
|
|
5128
|
-
}
|
|
5129
|
-
if (result.rowCount > 1) {
|
|
5130
|
-
const rows = probed && result.rowCount === 2 ? "2 or more rows" : `${result.rowCount} rows`;
|
|
5131
|
-
throw new AssertError(`scalar subquery returned ${rows} (expected 1 row).`);
|
|
5132
|
-
}
|
|
5133
|
-
const col = result.columns[0] ?? "";
|
|
5134
|
-
return result.rows[0]?.[col] ?? "";
|
|
5135
5171
|
}
|
|
5136
5172
|
}
|
|
5137
5173
|
}
|
|
5174
|
+
async function evaluateScalarSubquery(sourceQuery, client, options, cacheContext, tempTables) {
|
|
5175
|
+
const { query, probed } = withScalarProbeLimit(sourceQuery);
|
|
5176
|
+
const result = await runSubquery(query, client, options, cacheContext, tempTables);
|
|
5177
|
+
if (result.columns.length !== 1) {
|
|
5178
|
+
throw new ScalarSubqueryError(
|
|
5179
|
+
`scalar subquery returned ${result.columns.length} columns (expected 1 column).`
|
|
5180
|
+
);
|
|
5181
|
+
}
|
|
5182
|
+
if (result.rowCount === 0) {
|
|
5183
|
+
throw new ScalarSubqueryError("scalar subquery returned no rows (expected 1 row).");
|
|
5184
|
+
}
|
|
5185
|
+
if (result.rowCount > 1) {
|
|
5186
|
+
const rows = probed && result.rowCount === 2 ? "2 or more rows" : `${result.rowCount} rows`;
|
|
5187
|
+
throw new ScalarSubqueryError(`scalar subquery returned ${rows} (expected 1 row).`);
|
|
5188
|
+
}
|
|
5189
|
+
return result.rows[0]?.[result.columns[0]] ?? "";
|
|
5190
|
+
}
|
|
5138
5191
|
function withScalarProbeLimit(query) {
|
|
5139
5192
|
const hasAgg = query.groupBy.length > 0 || query.columns.some((c) => c.type === "AGGREGATE" || c.type === "ARITH_AGG_COL");
|
|
5140
5193
|
if (hasAgg || query.distinct || query.limit !== null) return { query, probed: false };
|
|
@@ -6636,7 +6689,7 @@ function buildBatchExplainPlans(sql) {
|
|
|
6636
6689
|
return {
|
|
6637
6690
|
statementCount: statements.length,
|
|
6638
6691
|
statements: statements.map((stmt, i) => {
|
|
6639
|
-
const planStmt = stmt.type === "SET_VARIABLE" ? stmt : resolveVariableRefs(stmt, variables);
|
|
6692
|
+
const planStmt = stmt.type === "SET_VARIABLE" ? stmt.expr.type === "SCALAR_SUBQUERY" ? { ...stmt, expr: resolveVariableRefs(stmt.expr, variables) } : stmt : resolveVariableRefs(stmt, variables);
|
|
6640
6693
|
const result = {
|
|
6641
6694
|
index: i,
|
|
6642
6695
|
type: analysis.statements[i].statementType,
|
|
@@ -6665,6 +6718,15 @@ function buildBatchStatementPlan(stmt, info) {
|
|
|
6665
6718
|
];
|
|
6666
6719
|
}
|
|
6667
6720
|
if (stmt.type === "SET_VARIABLE") {
|
|
6721
|
+
if (stmt.expr.type === "SCALAR_SUBQUERY") {
|
|
6722
|
+
const subInfo = hasTempTableRef(stmt.expr.query) ? info : { ...info, tempTablesReferenced: [] };
|
|
6723
|
+
return [
|
|
6724
|
+
`SET @${stmt.name} = (SELECT ...)`,
|
|
6725
|
+
" value: \u30B5\u30D6\u30AF\u30A8\u30EA\u3092\u5B9F\u884C\u6642\u306B1\u56DE\u8A55\u4FA1\uFF081\u884C1\u5217\u30FB\u30D0\u30C3\u30C1\u5185\u5B9A\u6570\u30FB\u7D50\u679C\u30E1\u30BF\u30C7\u30FC\u30BF\u306B\u306F\u975E\u516C\u958B\uFF09",
|
|
6726
|
+
" subquery:",
|
|
6727
|
+
...buildPlanForBatchQuery(stmt.expr.query, subInfo).map((l) => ` ${l}`)
|
|
6728
|
+
];
|
|
6729
|
+
}
|
|
6668
6730
|
return [
|
|
6669
6731
|
`SET @${stmt.name} = <scalar expression>`,
|
|
6670
6732
|
" value: \u5B9F\u884C\u6642\u306B1\u56DE\u8A55\u4FA1\uFF08\u30D0\u30C3\u30C1\u5185\u5B9A\u6570\u30FB\u7D50\u679C\u30E1\u30BF\u30C7\u30FC\u30BF\u306B\u306F\u975E\u516C\u958B\uFF09"
|
package/dist-mcp/ksql-mcp.js
CHANGED
|
@@ -31542,7 +31542,22 @@ var Parser = class {
|
|
|
31542
31542
|
throw new ParseError("SET \u306E\u53F3\u8FBA\u3067 NULL \u306F\u4F7F\u7528\u3067\u304D\u307E\u305B\u3093\uFF08Phase 1a\uFF09", tok);
|
|
31543
31543
|
}
|
|
31544
31544
|
if (tok.kind === "(" /* LPAREN */ && this.peekAt(1).kind === "SELECT" /* SELECT */) {
|
|
31545
|
-
|
|
31545
|
+
this.advance();
|
|
31546
|
+
const query = this.parseSelect();
|
|
31547
|
+
this.expect(")" /* RPAREN */);
|
|
31548
|
+
if (this.isArithOp(this.peek().kind)) {
|
|
31549
|
+
throw new ParseError(
|
|
31550
|
+
"\u30B9\u30AB\u30E9\u30FC\u30B5\u30D6\u30AF\u30A8\u30EA\u306E\u5F8C\u306B\u7B97\u8853\u6F14\u7B97\u5B50\u306F\u4F7F\u7528\u3067\u304D\u307E\u305B\u3093\u3002\u30B5\u30D6\u30AF\u30A8\u30EA\u5185\u3067\u8A08\u7B97\u3057\u3066\u304F\u3060\u3055\u3044",
|
|
31551
|
+
this.peek()
|
|
31552
|
+
);
|
|
31553
|
+
}
|
|
31554
|
+
const hasWildcard = query.columns.some(
|
|
31555
|
+
(c) => c.type === "WILDCARD" || c.type === "PARENT_WILDCARD"
|
|
31556
|
+
);
|
|
31557
|
+
if (!hasWildcard && query.columns.length !== 1) {
|
|
31558
|
+
throw new ParseError("scalar subquery in SET must return exactly 1 column.", tok);
|
|
31559
|
+
}
|
|
31560
|
+
return { type: "SCALAR_SUBQUERY", query };
|
|
31546
31561
|
}
|
|
31547
31562
|
if (tok.kind === "STRING" /* STRING */) {
|
|
31548
31563
|
this.advance();
|
|
@@ -35821,7 +35836,26 @@ async function executeBatch(sql, client, options = {}) {
|
|
|
35821
35836
|
}
|
|
35822
35837
|
async function executeBatchStatement(stmt, info, client, options, cacheContext, tempTables, variables) {
|
|
35823
35838
|
if (stmt.type === "SET_VARIABLE") {
|
|
35824
|
-
|
|
35839
|
+
const resolvedStmt2 = resolveVariableRefs(stmt, variables);
|
|
35840
|
+
if (resolvedStmt2.expr.type === "SCALAR_SUBQUERY") {
|
|
35841
|
+
try {
|
|
35842
|
+
const value = await evaluateScalarSubquery(
|
|
35843
|
+
resolvedStmt2.expr.query,
|
|
35844
|
+
client,
|
|
35845
|
+
options,
|
|
35846
|
+
cacheContext,
|
|
35847
|
+
tempTables
|
|
35848
|
+
);
|
|
35849
|
+
variables.set(stmt.name, { type: "string", value });
|
|
35850
|
+
} catch (e) {
|
|
35851
|
+
if (e instanceof ScalarSubqueryError) {
|
|
35852
|
+
throw new Error(`ArgumentError: ${e.message}`);
|
|
35853
|
+
}
|
|
35854
|
+
throw e;
|
|
35855
|
+
}
|
|
35856
|
+
} else {
|
|
35857
|
+
variables.set(stmt.name, evaluateScalarExpr(resolvedStmt2.expr));
|
|
35858
|
+
}
|
|
35825
35859
|
return {};
|
|
35826
35860
|
}
|
|
35827
35861
|
const resolvedStmt = resolveVariableRefs(stmt, variables);
|
|
@@ -35984,6 +36018,12 @@ var AssertError = class extends Error {
|
|
|
35984
36018
|
this.name = "AssertError";
|
|
35985
36019
|
}
|
|
35986
36020
|
};
|
|
36021
|
+
var ScalarSubqueryError = class extends Error {
|
|
36022
|
+
constructor(message) {
|
|
36023
|
+
super(message);
|
|
36024
|
+
this.name = "ScalarSubqueryError";
|
|
36025
|
+
}
|
|
36026
|
+
};
|
|
35987
36027
|
async function executeAssert(stmt, client, options, cacheContext, tempTables) {
|
|
35988
36028
|
const left = await evalAssertOperand(stmt.left, client, options, cacheContext, tempTables);
|
|
35989
36029
|
if (stmt.op === "BETWEEN") {
|
|
@@ -36017,25 +36057,38 @@ async function evalAssertOperand(operand, client, options, cacheContext, tempTab
|
|
|
36017
36057
|
case "ARITH":
|
|
36018
36058
|
return String(evalAssertArith(operand));
|
|
36019
36059
|
case "SCALAR_SUBQUERY": {
|
|
36020
|
-
|
|
36021
|
-
|
|
36022
|
-
|
|
36023
|
-
|
|
36024
|
-
|
|
36060
|
+
try {
|
|
36061
|
+
return await evaluateScalarSubquery(
|
|
36062
|
+
operand.query,
|
|
36063
|
+
client,
|
|
36064
|
+
options,
|
|
36065
|
+
cacheContext,
|
|
36066
|
+
tempTables
|
|
36025
36067
|
);
|
|
36068
|
+
} catch (e) {
|
|
36069
|
+
if (e instanceof ScalarSubqueryError) throw new AssertError(e.message);
|
|
36070
|
+
throw e;
|
|
36026
36071
|
}
|
|
36027
|
-
if (result.rowCount === 0) {
|
|
36028
|
-
throw new AssertError("scalar subquery returned no rows (expected 1 row).");
|
|
36029
|
-
}
|
|
36030
|
-
if (result.rowCount > 1) {
|
|
36031
|
-
const rows = probed && result.rowCount === 2 ? "2 or more rows" : `${result.rowCount} rows`;
|
|
36032
|
-
throw new AssertError(`scalar subquery returned ${rows} (expected 1 row).`);
|
|
36033
|
-
}
|
|
36034
|
-
const col = result.columns[0] ?? "";
|
|
36035
|
-
return result.rows[0]?.[col] ?? "";
|
|
36036
36072
|
}
|
|
36037
36073
|
}
|
|
36038
36074
|
}
|
|
36075
|
+
async function evaluateScalarSubquery(sourceQuery, client, options, cacheContext, tempTables) {
|
|
36076
|
+
const { query, probed } = withScalarProbeLimit(sourceQuery);
|
|
36077
|
+
const result = await runSubquery(query, client, options, cacheContext, tempTables);
|
|
36078
|
+
if (result.columns.length !== 1) {
|
|
36079
|
+
throw new ScalarSubqueryError(
|
|
36080
|
+
`scalar subquery returned ${result.columns.length} columns (expected 1 column).`
|
|
36081
|
+
);
|
|
36082
|
+
}
|
|
36083
|
+
if (result.rowCount === 0) {
|
|
36084
|
+
throw new ScalarSubqueryError("scalar subquery returned no rows (expected 1 row).");
|
|
36085
|
+
}
|
|
36086
|
+
if (result.rowCount > 1) {
|
|
36087
|
+
const rows = probed && result.rowCount === 2 ? "2 or more rows" : `${result.rowCount} rows`;
|
|
36088
|
+
throw new ScalarSubqueryError(`scalar subquery returned ${rows} (expected 1 row).`);
|
|
36089
|
+
}
|
|
36090
|
+
return result.rows[0]?.[result.columns[0]] ?? "";
|
|
36091
|
+
}
|
|
36039
36092
|
function withScalarProbeLimit(query) {
|
|
36040
36093
|
const hasAgg = query.groupBy.length > 0 || query.columns.some((c) => c.type === "AGGREGATE" || c.type === "ARITH_AGG_COL");
|
|
36041
36094
|
if (hasAgg || query.distinct || query.limit !== null) return { query, probed: false };
|
|
@@ -37537,7 +37590,7 @@ function buildBatchExplainPlans(sql) {
|
|
|
37537
37590
|
return {
|
|
37538
37591
|
statementCount: statements.length,
|
|
37539
37592
|
statements: statements.map((stmt, i) => {
|
|
37540
|
-
const planStmt = stmt.type === "SET_VARIABLE" ? stmt : resolveVariableRefs(stmt, variables);
|
|
37593
|
+
const planStmt = stmt.type === "SET_VARIABLE" ? stmt.expr.type === "SCALAR_SUBQUERY" ? { ...stmt, expr: resolveVariableRefs(stmt.expr, variables) } : stmt : resolveVariableRefs(stmt, variables);
|
|
37541
37594
|
const result = {
|
|
37542
37595
|
index: i,
|
|
37543
37596
|
type: analysis.statements[i].statementType,
|
|
@@ -37566,6 +37619,15 @@ function buildBatchStatementPlan(stmt, info) {
|
|
|
37566
37619
|
];
|
|
37567
37620
|
}
|
|
37568
37621
|
if (stmt.type === "SET_VARIABLE") {
|
|
37622
|
+
if (stmt.expr.type === "SCALAR_SUBQUERY") {
|
|
37623
|
+
const subInfo = hasTempTableRef(stmt.expr.query) ? info : { ...info, tempTablesReferenced: [] };
|
|
37624
|
+
return [
|
|
37625
|
+
`SET @${stmt.name} = (SELECT ...)`,
|
|
37626
|
+
" value: \u30B5\u30D6\u30AF\u30A8\u30EA\u3092\u5B9F\u884C\u6642\u306B1\u56DE\u8A55\u4FA1\uFF081\u884C1\u5217\u30FB\u30D0\u30C3\u30C1\u5185\u5B9A\u6570\u30FB\u7D50\u679C\u30E1\u30BF\u30C7\u30FC\u30BF\u306B\u306F\u975E\u516C\u958B\uFF09",
|
|
37627
|
+
" subquery:",
|
|
37628
|
+
...buildPlanForBatchQuery(stmt.expr.query, subInfo).map((l) => ` ${l}`)
|
|
37629
|
+
];
|
|
37630
|
+
}
|
|
37569
37631
|
return [
|
|
37570
37632
|
`SET @${stmt.name} = <scalar expression>`,
|
|
37571
37633
|
" value: \u5B9F\u884C\u6642\u306B1\u56DE\u8A55\u4FA1\uFF08\u30D0\u30C3\u30C1\u5185\u5B9A\u6570\u30FB\u7D50\u679C\u30E1\u30BF\u30C7\u30FC\u30BF\u306B\u306F\u975E\u516C\u958B\uFF09"
|
|
@@ -40014,7 +40076,7 @@ Options:
|
|
|
40014
40076
|
-h, --help Show help
|
|
40015
40077
|
`);
|
|
40016
40078
|
}
|
|
40017
|
-
var SERVER_VERSION = true ? "2.
|
|
40079
|
+
var SERVER_VERSION = true ? "2.3.0" : "0.0.0-dev";
|
|
40018
40080
|
function createServer(args) {
|
|
40019
40081
|
const server = new McpServer({
|
|
40020
40082
|
name: "ksql-mcp",
|
package/dist-mcpb/ksql-mcp.mcpb
CHANGED
|
Binary file
|