@rex0220/kintone-sql-tools 3.42.0 → 3.43.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 +104 -23
- package/dist-engine/index.cjs +10 -10
- package/dist-engine/index.mjs +10 -10
- package/dist-engine/ksql-engine.umd.js +10 -10
- package/dist-engine/meta/bundle-baseline.json +10 -10
- package/dist-engine/meta/cjs.json +25 -7
- package/dist-engine/meta/esm.json +25 -7
- package/dist-engine/meta/umd.json +25 -7
- package/dist-mcp/ksql-mcp.js +108 -24
- package/dist-mcpb/ksql-mcp.mcpb +0 -0
- package/package.json +1 -1
package/dist-cli/ksql.js
CHANGED
|
@@ -1038,8 +1038,9 @@ function needsSpaceBetween(prev, cur) {
|
|
|
1038
1038
|
return true;
|
|
1039
1039
|
}
|
|
1040
1040
|
var ParseError = class extends Error {
|
|
1041
|
-
constructor(
|
|
1042
|
-
super(`${
|
|
1041
|
+
constructor(rawMessage, token) {
|
|
1042
|
+
super(`${rawMessage}\uFF08\u4F4D\u7F6E ${token.pos}\u3001\u30C8\u30FC\u30AF\u30F3: \u300C${token.value}\u300D\uFF09`);
|
|
1043
|
+
this.rawMessage = rawMessage;
|
|
1043
1044
|
this.token = token;
|
|
1044
1045
|
this.name = "ParseError";
|
|
1045
1046
|
}
|
|
@@ -2425,16 +2426,33 @@ var Parser = class {
|
|
|
2425
2426
|
const byKind = PARSER_SCALAR_FUNCTION_TOKEN_MAP[this.peek().kind] ?? null;
|
|
2426
2427
|
if (byKind !== null && byKind !== "LEFT" && byKind !== "RIGHT") return byKind;
|
|
2427
2428
|
if (this.peek().kind === "IDENT" /* IDENT */) {
|
|
2428
|
-
const
|
|
2429
|
+
const nameToken = this.peek();
|
|
2430
|
+
const name = nameToken.value.toUpperCase();
|
|
2429
2431
|
if (PARSER_IDENT_SCALAR_FUNCTIONS.includes(name)) {
|
|
2430
2432
|
if (this.peekAt(1).kind === "(" /* LPAREN */) {
|
|
2431
2433
|
return name;
|
|
2432
2434
|
}
|
|
2433
2435
|
}
|
|
2436
|
+
if (this.peekAt(1).kind === "(" /* LPAREN */) {
|
|
2437
|
+
const hint = name === "DATE_SUB" ? "\u3002\u65E5\u4ED8\u3092\u6E1B\u7B97\u3059\u308B\u306B\u306F DATE_ADD \u306E\u52A0\u7B97\u5024\u3078\u8CA0\u6570\u3092\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044" : "";
|
|
2438
|
+
throw new ParseError(`\u300C${nameToken.value}\u300D\u3068\u3044\u3046\u95A2\u6570\u306F\u3042\u308A\u307E\u305B\u3093${hint}`, nameToken);
|
|
2439
|
+
}
|
|
2434
2440
|
}
|
|
2435
2441
|
return null;
|
|
2436
2442
|
}
|
|
2437
2443
|
parseStringFuncExpr() {
|
|
2444
|
+
const nameToken = this.peek();
|
|
2445
|
+
const func = this.tryStringFuncName();
|
|
2446
|
+
try {
|
|
2447
|
+
return this.parseStringFuncExprBody();
|
|
2448
|
+
} catch (error) {
|
|
2449
|
+
if (!(error instanceof ParseError)) throw error;
|
|
2450
|
+
const displayName = nameToken.value.toUpperCase();
|
|
2451
|
+
const guidance = func === "DATE_ADD" ? `${displayName} \u306E\u69CB\u6587\u306F DATE_ADD(\u5217, n, '\u5358\u4F4D') \u3067\u3059\u3002` : `${displayName} \u306E\u5F15\u6570\u69CB\u6587\u304C\u4E0D\u6B63\u3067\u3059\u3002`;
|
|
2452
|
+
throw new ParseError(`${guidance}${error.rawMessage}`, error.token);
|
|
2453
|
+
}
|
|
2454
|
+
}
|
|
2455
|
+
parseStringFuncExprBody() {
|
|
2438
2456
|
const tokenKind = this.peek().kind;
|
|
2439
2457
|
const func = this.tryStringFuncName();
|
|
2440
2458
|
this.advance();
|
|
@@ -6537,11 +6555,93 @@ function walkObjects2(node, visit) {
|
|
|
6537
6555
|
for (const value of Object.values(obj)) walkObjects2(value, visit);
|
|
6538
6556
|
}
|
|
6539
6557
|
|
|
6558
|
+
// src/core/functionArity.ts
|
|
6559
|
+
function assertArity(func, args, min, max = Number.POSITIVE_INFINITY) {
|
|
6560
|
+
if (args.length >= min && args.length <= max) return;
|
|
6561
|
+
const expected = min === max ? String(min) : max === Number.POSITIVE_INFINITY ? `${min} or more` : `${min} to ${max}`;
|
|
6562
|
+
throw new Error(`ArgumentError: ${func} expects ${expected} argument(s).`);
|
|
6563
|
+
}
|
|
6564
|
+
function assertStringFunctionArity(func, args) {
|
|
6565
|
+
switch (func) {
|
|
6566
|
+
case "UPPER":
|
|
6567
|
+
case "LOWER":
|
|
6568
|
+
case "TRIM":
|
|
6569
|
+
case "LTRIM":
|
|
6570
|
+
case "RTRIM":
|
|
6571
|
+
case "LENGTH":
|
|
6572
|
+
case "LENGTH_CHAR":
|
|
6573
|
+
case "YEAR":
|
|
6574
|
+
case "MONTH":
|
|
6575
|
+
case "DAY":
|
|
6576
|
+
case "DAYOFWEEK":
|
|
6577
|
+
case "QUARTER":
|
|
6578
|
+
case "WEEK":
|
|
6579
|
+
case "LAST_DAY":
|
|
6580
|
+
case "ABS":
|
|
6581
|
+
case "SQRT":
|
|
6582
|
+
return assertArity(func, args, 1, 1);
|
|
6583
|
+
case "SUBSTRING":
|
|
6584
|
+
case "LPAD":
|
|
6585
|
+
case "RPAD":
|
|
6586
|
+
case "REGEXP_LIKE":
|
|
6587
|
+
case "REGEXP_SUBSTR":
|
|
6588
|
+
return assertArity(func, args, 2, 3);
|
|
6589
|
+
case "LEFT":
|
|
6590
|
+
case "RIGHT":
|
|
6591
|
+
case "INSTR":
|
|
6592
|
+
case "ISNULL":
|
|
6593
|
+
case "NULLIF":
|
|
6594
|
+
case "MOD":
|
|
6595
|
+
case "POWER":
|
|
6596
|
+
case "FORMAT":
|
|
6597
|
+
case "CAST":
|
|
6598
|
+
case "DATE_FORMAT":
|
|
6599
|
+
case "DATEDIFF":
|
|
6600
|
+
return assertArity(func, args, 2, 2);
|
|
6601
|
+
case "CONCAT":
|
|
6602
|
+
case "COALESCE":
|
|
6603
|
+
case "GREATEST":
|
|
6604
|
+
case "LEAST":
|
|
6605
|
+
return assertArity(func, args, 2);
|
|
6606
|
+
case "REPLACE":
|
|
6607
|
+
case "TRANSLATE":
|
|
6608
|
+
case "DATE_ADD":
|
|
6609
|
+
return assertArity(func, args, 3, 3);
|
|
6610
|
+
case "REGEXP_REPLACE":
|
|
6611
|
+
return assertArity(func, args, 3, 5);
|
|
6612
|
+
case "ROUND":
|
|
6613
|
+
case "FLOOR":
|
|
6614
|
+
case "CEIL":
|
|
6615
|
+
case "TRUNCATE":
|
|
6616
|
+
return assertArity(func, args, 1, 2);
|
|
6617
|
+
case "CURRENT_DATE":
|
|
6618
|
+
case "CURRENT_TIMESTAMP":
|
|
6619
|
+
return assertArity(func, args, 0, 0);
|
|
6620
|
+
}
|
|
6621
|
+
}
|
|
6622
|
+
|
|
6540
6623
|
// src/core/statementValidation.ts
|
|
6541
6624
|
function validateStatementStatic(stmt) {
|
|
6625
|
+
validateStringFunctionArities(stmt);
|
|
6542
6626
|
validatePrimaryOrganizationDmlStatement(stmt);
|
|
6543
6627
|
validateKlikeStatement(stmt);
|
|
6544
6628
|
}
|
|
6629
|
+
function validateStringFunctionArities(stmt) {
|
|
6630
|
+
const visit = (value) => {
|
|
6631
|
+
if (value === null || typeof value !== "object") return;
|
|
6632
|
+
if (Array.isArray(value)) {
|
|
6633
|
+
value.forEach(visit);
|
|
6634
|
+
return;
|
|
6635
|
+
}
|
|
6636
|
+
const node = value;
|
|
6637
|
+
if (node.type === "STRING_FUNC") {
|
|
6638
|
+
const expr = node;
|
|
6639
|
+
assertStringFunctionArity(expr.func, expr.args);
|
|
6640
|
+
}
|
|
6641
|
+
Object.values(node).forEach(visit);
|
|
6642
|
+
};
|
|
6643
|
+
visit(stmt);
|
|
6644
|
+
}
|
|
6545
6645
|
|
|
6546
6646
|
// src/engine/groupingRowMeta.ts
|
|
6547
6647
|
var groupingRowMetaKey = /* @__PURE__ */ Symbol("ksql.groupingRowMeta");
|
|
@@ -7566,6 +7666,7 @@ function replaceNthMatch(input, globalRe, replacement, n) {
|
|
|
7566
7666
|
});
|
|
7567
7667
|
}
|
|
7568
7668
|
function evalStringFunc(expr, row, resolveFieldType, resolveFieldSemantics2) {
|
|
7669
|
+
assertStringFunctionArity(expr.func, expr.args);
|
|
7569
7670
|
const args = expr.args.map((a) => evalStringFuncArg(a, row, resolveFieldType, resolveFieldSemantics2));
|
|
7570
7671
|
switch (expr.func) {
|
|
7571
7672
|
case "UPPER":
|
|
@@ -7581,7 +7682,6 @@ function evalStringFunc(expr, row, resolveFieldType, resolveFieldSemantics2) {
|
|
|
7581
7682
|
case "LENGTH":
|
|
7582
7683
|
return String((args[0] ?? "").length);
|
|
7583
7684
|
case "LENGTH_CHAR":
|
|
7584
|
-
assertArity("LENGTH_CHAR", args, 1, 1);
|
|
7585
7685
|
return String([...args[0] ?? ""].length);
|
|
7586
7686
|
case "SUBSTRING": {
|
|
7587
7687
|
const str = args[0] ?? "";
|
|
@@ -7590,23 +7690,19 @@ function evalStringFunc(expr, row, resolveFieldType, resolveFieldSemantics2) {
|
|
|
7590
7690
|
return sliceSafeRange(str, start, len !== void 0 ? start + len : str.length);
|
|
7591
7691
|
}
|
|
7592
7692
|
case "LEFT": {
|
|
7593
|
-
assertArity("LEFT", args, 2, 2);
|
|
7594
7693
|
const str = args[0];
|
|
7595
7694
|
const n = Math.trunc(Number(args[1]));
|
|
7596
7695
|
return Number.isNaN(n) || n <= 0 ? "" : sliceSafePrefix(str, n);
|
|
7597
7696
|
}
|
|
7598
7697
|
case "RIGHT": {
|
|
7599
|
-
assertArity("RIGHT", args, 2, 2);
|
|
7600
7698
|
const str = args[0];
|
|
7601
7699
|
const n = Math.trunc(Number(args[1]));
|
|
7602
7700
|
return Number.isNaN(n) || n <= 0 ? "" : sliceSafeSuffix(str, n);
|
|
7603
7701
|
}
|
|
7604
7702
|
case "INSTR":
|
|
7605
|
-
assertArity("INSTR", args, 2, 2);
|
|
7606
7703
|
return String(args[0].indexOf(args[1]) + 1);
|
|
7607
7704
|
case "LPAD":
|
|
7608
7705
|
case "RPAD": {
|
|
7609
|
-
assertArity(expr.func, args, 2, 3);
|
|
7610
7706
|
const str = args[0];
|
|
7611
7707
|
const n = Math.trunc(Number(args[1]));
|
|
7612
7708
|
if (Number.isNaN(n) || n <= 0) return "";
|
|
@@ -7618,7 +7714,6 @@ function evalStringFunc(expr, row, resolveFieldType, resolveFieldSemantics2) {
|
|
|
7618
7714
|
}
|
|
7619
7715
|
case "GREATEST":
|
|
7620
7716
|
case "LEAST":
|
|
7621
|
-
assertArity(expr.func, args, 2);
|
|
7622
7717
|
return selectScalarExtreme(args, expr.func === "GREATEST" ? "greatest" : "least");
|
|
7623
7718
|
case "CONCAT":
|
|
7624
7719
|
return args.join("");
|
|
@@ -7629,22 +7724,18 @@ function evalStringFunc(expr, row, resolveFieldType, resolveFieldSemantics2) {
|
|
|
7629
7724
|
return from === "" ? str : str.split(from).join(to);
|
|
7630
7725
|
}
|
|
7631
7726
|
case "REGEXP_LIKE": {
|
|
7632
|
-
assertArity("REGEXP_LIKE", args, 2, 3);
|
|
7633
7727
|
return compileRegexp(args[1], args[2] ?? "").test(args[0]) ? "1" : "0";
|
|
7634
7728
|
}
|
|
7635
7729
|
case "REGEXP_REPLACE": {
|
|
7636
|
-
assertArity("REGEXP_REPLACE", args, 3, 5);
|
|
7637
7730
|
assertRegexpReplacement(args[2]);
|
|
7638
7731
|
const occurrence = parseRegexpOccurrence(args[4]);
|
|
7639
7732
|
const regexp = compileRegexp(args[1], args[3] ?? "", true);
|
|
7640
7733
|
return occurrence === 0 ? args[0].replace(regexp, args[2]) : replaceNthMatch(args[0], regexp, args[2], occurrence);
|
|
7641
7734
|
}
|
|
7642
7735
|
case "REGEXP_SUBSTR": {
|
|
7643
|
-
assertArity("REGEXP_SUBSTR", args, 2, 3);
|
|
7644
7736
|
return compileRegexp(args[1], args[2] ?? "").exec(args[0])?.[0] ?? "";
|
|
7645
7737
|
}
|
|
7646
7738
|
case "TRANSLATE": {
|
|
7647
|
-
assertArity("TRANSLATE", args, 3, 3);
|
|
7648
7739
|
const from = [...args[1]];
|
|
7649
7740
|
const to = [...args[2]];
|
|
7650
7741
|
if (from.length !== to.length) {
|
|
@@ -7671,7 +7762,6 @@ function evalStringFunc(expr, row, resolveFieldType, resolveFieldSemantics2) {
|
|
|
7671
7762
|
case "CEIL":
|
|
7672
7763
|
return applyRoundOp("ceil", Number(args[0] ?? "0"), Number(args[1] ?? "0"));
|
|
7673
7764
|
case "TRUNCATE":
|
|
7674
|
-
assertArity("TRUNCATE", args, 1, 2);
|
|
7675
7765
|
return applyRoundOp("trunc", Number(args[0]), Number(args[1] ?? "0"));
|
|
7676
7766
|
case "CAST": {
|
|
7677
7767
|
const val = args[0] ?? "";
|
|
@@ -7700,13 +7790,10 @@ function evalStringFunc(expr, row, resolveFieldType, resolveFieldSemantics2) {
|
|
|
7700
7790
|
return d.length >= 10 ? String(parseInt(d.slice(8, 10), 10)) : "";
|
|
7701
7791
|
}
|
|
7702
7792
|
case "DAYOFWEEK":
|
|
7703
|
-
assertArity(expr.func, args, 1, 1);
|
|
7704
7793
|
return isValidYmd(args[0]) ? String(dayOfWeekIndex(args[0]) + 1) : "";
|
|
7705
7794
|
case "QUARTER":
|
|
7706
|
-
assertArity(expr.func, args, 1, 1);
|
|
7707
7795
|
return isValidYmd(args[0]) ? String(Math.ceil(Number(args[0].slice(5, 7)) / 3)) : "";
|
|
7708
7796
|
case "WEEK":
|
|
7709
|
-
assertArity(expr.func, args, 1, 1);
|
|
7710
7797
|
return isValidYmd(args[0]) ? String(isoWeekNumber(args[0])) : "";
|
|
7711
7798
|
case "DATE_FORMAT":
|
|
7712
7799
|
return applyDateFormat(args[0] ?? "", args[1] ?? "");
|
|
@@ -7715,7 +7802,6 @@ function evalStringFunc(expr, row, resolveFieldType, resolveFieldSemantics2) {
|
|
|
7715
7802
|
case "DATE_ADD":
|
|
7716
7803
|
return applyDateAdd(args[0] ?? "", Number(args[1] ?? "0"), (args[2] ?? "DAY").toUpperCase());
|
|
7717
7804
|
case "LAST_DAY":
|
|
7718
|
-
assertArity("LAST_DAY", args, 1, 1);
|
|
7719
7805
|
return applyLastDay(args[0]);
|
|
7720
7806
|
case "ABS":
|
|
7721
7807
|
return String(Math.abs(Number(args[0] ?? "0")));
|
|
@@ -7739,11 +7825,6 @@ function evalStringFunc(expr, row, resolveFieldType, resolveFieldSemantics2) {
|
|
|
7739
7825
|
return (/* @__PURE__ */ new Date()).toISOString();
|
|
7740
7826
|
}
|
|
7741
7827
|
}
|
|
7742
|
-
function assertArity(func, args, min, max = Number.POSITIVE_INFINITY) {
|
|
7743
|
-
if (args.length >= min && args.length <= max) return;
|
|
7744
|
-
const expected = min === max ? String(min) : max === Number.POSITIVE_INFINITY ? `${min} or more` : `${min} to ${max}`;
|
|
7745
|
-
throw new Error(`ArgumentError: ${func} expects ${expected} argument(s).`);
|
|
7746
|
-
}
|
|
7747
7828
|
function parseDateParts(s) {
|
|
7748
7829
|
return {
|
|
7749
7830
|
y: s.slice(0, 4) || "0000",
|