@rex0220/kintone-sql-tools 3.11.0 → 3.12.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 +2 -0
- package/dist-cli/ksql.js +95 -81
- package/dist-mcp/ksql-mcp.js +233 -105
- package/dist-mcpb/ksql-mcp.mcpb +0 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -71,6 +71,8 @@ npm run build:plugin
|
|
|
71
71
|
- 一時テーブルで中間結果をサーバー内に保持し、AI のコンテキスト消費を抑えたい場合
|
|
72
72
|
- validation / EXPLAIN で論理名から最終的な物理アプリ ID への解決を確認したい場合
|
|
73
73
|
|
|
74
|
+
言語リファレンス・レシピは MCP resources(`ksql://language-reference` / `ksql://recipes`)に加えて、read-only ツール **`ksql_docs`** でも読めます。中継環境(リモート接続のプロキシ等)が resources を通さないクライアントでは、`ksql_docs` を引数なしで呼ぶと全章キーの索引が返るので、必要な章だけ `{"section":"language-reference/05-string-number-functions"}` の形で取得してください。
|
|
75
|
+
|
|
74
76
|
注意:
|
|
75
77
|
|
|
76
78
|
- `APP@profile` と `LAPP_<NAME>[@profile]` は Node.js runtime(CLI / MCP)の拡張です。plugin 側では非対応です。
|
package/dist-cli/ksql.js
CHANGED
|
@@ -577,6 +577,87 @@ function numberLiteralText(node) {
|
|
|
577
577
|
|
|
578
578
|
// src/parser/parser.ts
|
|
579
579
|
var MAX_BATCH_STATEMENTS = 20;
|
|
580
|
+
var PARSER_SCALAR_FUNCTION_TOKEN_MAP = Object.freeze({
|
|
581
|
+
["UPPER" /* UPPER */]: "UPPER",
|
|
582
|
+
["LOWER" /* LOWER */]: "LOWER",
|
|
583
|
+
["TRIM" /* TRIM */]: "TRIM",
|
|
584
|
+
["LTRIM" /* LTRIM */]: "LTRIM",
|
|
585
|
+
["RTRIM" /* RTRIM */]: "RTRIM",
|
|
586
|
+
["LENGTH" /* LENGTH */]: "LENGTH",
|
|
587
|
+
["LENGTH_CHAR" /* LENGTH_CHAR */]: "LENGTH_CHAR",
|
|
588
|
+
["SUBSTRING" /* SUBSTRING */]: "SUBSTRING",
|
|
589
|
+
["SUBSTR" /* SUBSTR */]: "SUBSTRING",
|
|
590
|
+
["LEFT" /* LEFT */]: "LEFT",
|
|
591
|
+
["RIGHT" /* RIGHT */]: "RIGHT",
|
|
592
|
+
["INSTR" /* INSTR */]: "INSTR",
|
|
593
|
+
["CONCAT" /* CONCAT */]: "CONCAT",
|
|
594
|
+
["REPLACE" /* REPLACE */]: "REPLACE",
|
|
595
|
+
["REGEXP_LIKE" /* REGEXP_LIKE */]: "REGEXP_LIKE",
|
|
596
|
+
["REGEXP_REPLACE" /* REGEXP_REPLACE */]: "REGEXP_REPLACE",
|
|
597
|
+
["REGEXP_SUBSTR" /* REGEXP_SUBSTR */]: "REGEXP_SUBSTR",
|
|
598
|
+
["TRANSLATE" /* TRANSLATE */]: "TRANSLATE",
|
|
599
|
+
["COALESCE" /* COALESCE */]: "COALESCE",
|
|
600
|
+
["ISNULL" /* ISNULL */]: "ISNULL",
|
|
601
|
+
["NULLIF" /* NULLIF */]: "NULLIF",
|
|
602
|
+
["GREATEST" /* GREATEST */]: "GREATEST",
|
|
603
|
+
["LEAST" /* LEAST */]: "LEAST",
|
|
604
|
+
["LPAD" /* LPAD */]: "LPAD",
|
|
605
|
+
["RPAD" /* RPAD */]: "RPAD",
|
|
606
|
+
["ROUND" /* ROUND */]: "ROUND",
|
|
607
|
+
["FLOOR" /* FLOOR */]: "FLOOR",
|
|
608
|
+
["CEIL" /* CEIL */]: "CEIL",
|
|
609
|
+
["CEILING" /* CEILING */]: "CEIL",
|
|
610
|
+
["TRUNCATE" /* TRUNCATE */]: "TRUNCATE",
|
|
611
|
+
["TRUNC" /* TRUNC */]: "TRUNCATE",
|
|
612
|
+
["ABS" /* ABS */]: "ABS",
|
|
613
|
+
["MOD" /* MOD */]: "MOD",
|
|
614
|
+
["POWER" /* POWER */]: "POWER",
|
|
615
|
+
["POW" /* POW */]: "POWER",
|
|
616
|
+
["SQRT" /* SQRT */]: "SQRT",
|
|
617
|
+
["FORMAT" /* FORMAT */]: "FORMAT",
|
|
618
|
+
["CAST" /* CAST */]: "CAST",
|
|
619
|
+
["CONVERT" /* CONVERT */]: "CAST",
|
|
620
|
+
["YEAR" /* YEAR */]: "YEAR",
|
|
621
|
+
["MONTH" /* MONTH */]: "MONTH",
|
|
622
|
+
["DAY" /* DAY */]: "DAY",
|
|
623
|
+
["DATE_FORMAT" /* DATE_FORMAT */]: "DATE_FORMAT",
|
|
624
|
+
["DATEDIFF" /* DATEDIFF */]: "DATEDIFF",
|
|
625
|
+
["DATE_ADD" /* DATE_ADD */]: "DATE_ADD",
|
|
626
|
+
["LAST_DAY" /* LAST_DAY */]: "LAST_DAY"
|
|
627
|
+
});
|
|
628
|
+
var PARSER_IDENT_SCALAR_FUNCTIONS = Object.freeze([
|
|
629
|
+
"CURRENT_DATE",
|
|
630
|
+
"CURRENT_TIMESTAMP"
|
|
631
|
+
]);
|
|
632
|
+
var PARSER_AGGREGATE_FUNCTION_TOKEN_MAP = Object.freeze({
|
|
633
|
+
["COUNT" /* COUNT */]: "COUNT",
|
|
634
|
+
["SUM" /* SUM */]: "SUM",
|
|
635
|
+
["AVG" /* AVG */]: "AVG",
|
|
636
|
+
["MAX" /* MAX */]: "MAX",
|
|
637
|
+
["MIN" /* MIN */]: "MIN",
|
|
638
|
+
["GROUP_CONCAT" /* GROUP_CONCAT */]: "GROUP_CONCAT"
|
|
639
|
+
});
|
|
640
|
+
var PARSER_WINDOW_FUNCTION_TOKEN_MAP = Object.freeze({
|
|
641
|
+
["ROW_NUMBER" /* ROW_NUMBER */]: "ROW_NUMBER",
|
|
642
|
+
["RANK" /* RANK */]: "RANK",
|
|
643
|
+
["DENSE_RANK" /* DENSE_RANK */]: "DENSE_RANK"
|
|
644
|
+
});
|
|
645
|
+
var PARSER_CONTEXTUAL_FUNCTION_TOKEN_MAP = Object.freeze({
|
|
646
|
+
["TODAY" /* TODAY */]: "TODAY",
|
|
647
|
+
["NOW" /* NOW */]: "NOW",
|
|
648
|
+
["LOGINUSER" /* LOGINUSER */]: "LOGINUSER"
|
|
649
|
+
});
|
|
650
|
+
function isContextualFunctionToken(kind) {
|
|
651
|
+
return PARSER_CONTEXTUAL_FUNCTION_TOKEN_MAP[kind] !== void 0;
|
|
652
|
+
}
|
|
653
|
+
var PARSER_FUNCTION_SPELLINGS = Object.freeze(Array.from(/* @__PURE__ */ new Set([
|
|
654
|
+
...Object.keys(PARSER_SCALAR_FUNCTION_TOKEN_MAP),
|
|
655
|
+
...PARSER_IDENT_SCALAR_FUNCTIONS,
|
|
656
|
+
...Object.keys(PARSER_AGGREGATE_FUNCTION_TOKEN_MAP),
|
|
657
|
+
...Object.keys(PARSER_WINDOW_FUNCTION_TOKEN_MAP),
|
|
658
|
+
...Object.keys(PARSER_CONTEXTUAL_FUNCTION_TOKEN_MAP),
|
|
659
|
+
"IF"
|
|
660
|
+
])));
|
|
580
661
|
var FUNC_CALL_PREFIX_KINDS = /* @__PURE__ */ new Set([
|
|
581
662
|
"IDENT" /* IDENT */,
|
|
582
663
|
"BIDENT" /* BIDENT */,
|
|
@@ -820,13 +901,14 @@ var Parser = class {
|
|
|
820
901
|
this.advance();
|
|
821
902
|
return { type: "STRING", value: tok.value };
|
|
822
903
|
}
|
|
823
|
-
|
|
904
|
+
const contextualFunction = PARSER_CONTEXTUAL_FUNCTION_TOKEN_MAP[tok.kind];
|
|
905
|
+
if (contextualFunction === "LOGINUSER") {
|
|
824
906
|
throw new ParseError(
|
|
825
907
|
`${context} \u306E\u53F3\u8FBA\u3067 LOGINUSER() \u306F\u4F7F\u7528\u3067\u304D\u307E\u305B\u3093\uFF08\u5B9F\u884C\u74B0\u5883\u5171\u901A\u306E\u30ED\u30B0\u30A4\u30F3\u30E6\u30FC\u30B6\u30FC\u89E3\u6C7A\u306F\u672A\u5BFE\u5FDC\u3067\u3059\uFF09`,
|
|
826
908
|
tok
|
|
827
909
|
);
|
|
828
910
|
}
|
|
829
|
-
if (
|
|
911
|
+
if (contextualFunction !== void 0) {
|
|
830
912
|
return this.parseSqlValue();
|
|
831
913
|
}
|
|
832
914
|
const expr = this.parseArithAddSub();
|
|
@@ -1581,16 +1663,7 @@ var Parser = class {
|
|
|
1581
1663
|
return { type: "FIELD", field, alias };
|
|
1582
1664
|
}
|
|
1583
1665
|
tryWindowFunc() {
|
|
1584
|
-
|
|
1585
|
-
case "ROW_NUMBER" /* ROW_NUMBER */:
|
|
1586
|
-
return "ROW_NUMBER";
|
|
1587
|
-
case "RANK" /* RANK */:
|
|
1588
|
-
return "RANK";
|
|
1589
|
-
case "DENSE_RANK" /* DENSE_RANK */:
|
|
1590
|
-
return "DENSE_RANK";
|
|
1591
|
-
default:
|
|
1592
|
-
return null;
|
|
1593
|
-
}
|
|
1666
|
+
return PARSER_WINDOW_FUNCTION_TOKEN_MAP[this.peek().kind] ?? null;
|
|
1594
1667
|
}
|
|
1595
1668
|
parseWindowColumn(func) {
|
|
1596
1669
|
this.advance();
|
|
@@ -1947,64 +2020,14 @@ var Parser = class {
|
|
|
1947
2020
|
// ──────────────────────────────────────────────────
|
|
1948
2021
|
tryStringFuncName() {
|
|
1949
2022
|
if (this.peekAt(1).kind === "(" /* LPAREN */) {
|
|
1950
|
-
|
|
1951
|
-
if (
|
|
1952
|
-
}
|
|
1953
|
-
const
|
|
1954
|
-
|
|
1955
|
-
["LOWER" /* LOWER */]: "LOWER",
|
|
1956
|
-
["TRIM" /* TRIM */]: "TRIM",
|
|
1957
|
-
["LTRIM" /* LTRIM */]: "LTRIM",
|
|
1958
|
-
["RTRIM" /* RTRIM */]: "RTRIM",
|
|
1959
|
-
["LENGTH" /* LENGTH */]: "LENGTH",
|
|
1960
|
-
["LENGTH_CHAR" /* LENGTH_CHAR */]: "LENGTH_CHAR",
|
|
1961
|
-
["SUBSTRING" /* SUBSTRING */]: "SUBSTRING",
|
|
1962
|
-
["SUBSTR" /* SUBSTR */]: "SUBSTRING",
|
|
1963
|
-
["CONCAT" /* CONCAT */]: "CONCAT",
|
|
1964
|
-
["REPLACE" /* REPLACE */]: "REPLACE",
|
|
1965
|
-
["REGEXP_LIKE" /* REGEXP_LIKE */]: "REGEXP_LIKE",
|
|
1966
|
-
["REGEXP_REPLACE" /* REGEXP_REPLACE */]: "REGEXP_REPLACE",
|
|
1967
|
-
["REGEXP_SUBSTR" /* REGEXP_SUBSTR */]: "REGEXP_SUBSTR",
|
|
1968
|
-
["TRANSLATE" /* TRANSLATE */]: "TRANSLATE",
|
|
1969
|
-
["COALESCE" /* COALESCE */]: "COALESCE",
|
|
1970
|
-
["NULLIF" /* NULLIF */]: "NULLIF",
|
|
1971
|
-
["ISNULL" /* ISNULL */]: "ISNULL",
|
|
1972
|
-
["INSTR" /* INSTR */]: "INSTR",
|
|
1973
|
-
["GREATEST" /* GREATEST */]: "GREATEST",
|
|
1974
|
-
["LEAST" /* LEAST */]: "LEAST",
|
|
1975
|
-
["LPAD" /* LPAD */]: "LPAD",
|
|
1976
|
-
["RPAD" /* RPAD */]: "RPAD",
|
|
1977
|
-
["CAST" /* CAST */]: "CAST",
|
|
1978
|
-
["CONVERT" /* CONVERT */]: "CAST",
|
|
1979
|
-
// CONVERT → CAST に正規化
|
|
1980
|
-
["FORMAT" /* FORMAT */]: "FORMAT",
|
|
1981
|
-
["ROUND" /* ROUND */]: "ROUND",
|
|
1982
|
-
["FLOOR" /* FLOOR */]: "FLOOR",
|
|
1983
|
-
["CEIL" /* CEIL */]: "CEIL",
|
|
1984
|
-
["CEILING" /* CEILING */]: "CEIL",
|
|
1985
|
-
// CEILING → CEIL に正規化
|
|
1986
|
-
["TRUNCATE" /* TRUNCATE */]: "TRUNCATE",
|
|
1987
|
-
["TRUNC" /* TRUNC */]: "TRUNCATE",
|
|
1988
|
-
// TRUNC → TRUNCATE に正規化
|
|
1989
|
-
["YEAR" /* YEAR */]: "YEAR",
|
|
1990
|
-
["MONTH" /* MONTH */]: "MONTH",
|
|
1991
|
-
["DAY" /* DAY */]: "DAY",
|
|
1992
|
-
["DATE_FORMAT" /* DATE_FORMAT */]: "DATE_FORMAT",
|
|
1993
|
-
["DATEDIFF" /* DATEDIFF */]: "DATEDIFF",
|
|
1994
|
-
["DATE_ADD" /* DATE_ADD */]: "DATE_ADD",
|
|
1995
|
-
["LAST_DAY" /* LAST_DAY */]: "LAST_DAY",
|
|
1996
|
-
["ABS" /* ABS */]: "ABS",
|
|
1997
|
-
["MOD" /* MOD */]: "MOD",
|
|
1998
|
-
["POWER" /* POWER */]: "POWER",
|
|
1999
|
-
["POW" /* POW */]: "POWER",
|
|
2000
|
-
// POW → POWER に正規化
|
|
2001
|
-
["SQRT" /* SQRT */]: "SQRT"
|
|
2002
|
-
};
|
|
2003
|
-
const byKind = map[this.peek().kind] ?? null;
|
|
2004
|
-
if (byKind !== null) return byKind;
|
|
2023
|
+
const conditional = PARSER_SCALAR_FUNCTION_TOKEN_MAP[this.peek().kind];
|
|
2024
|
+
if (conditional === "LEFT" || conditional === "RIGHT") return conditional;
|
|
2025
|
+
}
|
|
2026
|
+
const byKind = PARSER_SCALAR_FUNCTION_TOKEN_MAP[this.peek().kind] ?? null;
|
|
2027
|
+
if (byKind !== null && byKind !== "LEFT" && byKind !== "RIGHT") return byKind;
|
|
2005
2028
|
if (this.peek().kind === "IDENT" /* IDENT */) {
|
|
2006
2029
|
const name = this.peek().value.toUpperCase();
|
|
2007
|
-
if (name
|
|
2030
|
+
if (PARSER_IDENT_SCALAR_FUNCTIONS.includes(name)) {
|
|
2008
2031
|
if (this.peekAt(1).kind === "(" /* LPAREN */) {
|
|
2009
2032
|
return name;
|
|
2010
2033
|
}
|
|
@@ -2094,16 +2117,7 @@ var Parser = class {
|
|
|
2094
2117
|
return false;
|
|
2095
2118
|
}
|
|
2096
2119
|
tryAggregateFunc() {
|
|
2097
|
-
|
|
2098
|
-
["COUNT" /* COUNT */]: "COUNT",
|
|
2099
|
-
["SUM" /* SUM */]: "SUM",
|
|
2100
|
-
["AVG" /* AVG */]: "AVG",
|
|
2101
|
-
["MAX" /* MAX */]: "MAX",
|
|
2102
|
-
["MIN" /* MIN */]: "MIN",
|
|
2103
|
-
["GROUP_CONCAT" /* GROUP_CONCAT */]: "GROUP_CONCAT"
|
|
2104
|
-
};
|
|
2105
|
-
const kind = this.peek().kind;
|
|
2106
|
-
return map[kind] ?? null;
|
|
2120
|
+
return PARSER_AGGREGATE_FUNCTION_TOKEN_MAP[this.peek().kind] ?? null;
|
|
2107
2121
|
}
|
|
2108
2122
|
/** 集計関数参照を読む。SELECT 列の alias は呼び出し側で式全体の後に処理する。 */
|
|
2109
2123
|
parseAggregateRef(func) {
|
|
@@ -2464,13 +2478,13 @@ var Parser = class {
|
|
|
2464
2478
|
this.advance();
|
|
2465
2479
|
return { type: "STRING", value: tok.value };
|
|
2466
2480
|
}
|
|
2467
|
-
if (tok.kind
|
|
2481
|
+
if (isContextualFunctionToken(tok.kind)) {
|
|
2468
2482
|
this.advance();
|
|
2469
2483
|
this.expect("(" /* LPAREN */);
|
|
2470
2484
|
this.expect(")" /* RPAREN */);
|
|
2471
2485
|
return {
|
|
2472
2486
|
type: "KINTONE_FUNC",
|
|
2473
|
-
name: tok.
|
|
2487
|
+
name: PARSER_CONTEXTUAL_FUNCTION_TOKEN_MAP[tok.kind]
|
|
2474
2488
|
};
|
|
2475
2489
|
}
|
|
2476
2490
|
if (tok.kind === "CASE" /* CASE */) {
|
|
@@ -3267,7 +3281,7 @@ var Parser = class {
|
|
|
3267
3281
|
}
|
|
3268
3282
|
if (tok.kind === "VARIABLE" /* VARIABLE */) return this.parseSqlValue();
|
|
3269
3283
|
if (tok.kind === "STRING" /* STRING */) return this.parseSqlValue();
|
|
3270
|
-
if (tok.kind
|
|
3284
|
+
if (isContextualFunctionToken(tok.kind)) return this.parseSqlValue();
|
|
3271
3285
|
if (tok.kind === "IN" /* IN */) return this.parseSqlValue();
|
|
3272
3286
|
if (tok.kind === "CASE" /* CASE */ || tok.kind === "IF" /* IF */) {
|
|
3273
3287
|
return this.parseSqlValue();
|