@rex0220/kintone-sql-tools 3.1.0 → 3.2.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 +185 -25
- package/dist-mcp/ksql-mcp.js +186 -26
- package/dist-mcpb/ksql-mcp.mcpb +0 -0
- package/package.json +1 -1
package/dist-cli/ksql.js
CHANGED
|
@@ -117,6 +117,7 @@ var KEYWORDS = /* @__PURE__ */ new Map([
|
|
|
117
117
|
["LTRIM", "LTRIM" /* LTRIM */],
|
|
118
118
|
["RTRIM", "RTRIM" /* RTRIM */],
|
|
119
119
|
["LENGTH", "LENGTH" /* LENGTH */],
|
|
120
|
+
["LENGTH_CHAR", "LENGTH_CHAR" /* LENGTH_CHAR */],
|
|
120
121
|
["SUBSTRING", "SUBSTRING" /* SUBSTRING */],
|
|
121
122
|
["SUBSTR", "SUBSTR" /* SUBSTR */],
|
|
122
123
|
["CONCAT", "CONCAT" /* CONCAT */],
|
|
@@ -129,6 +130,7 @@ var KEYWORDS = /* @__PURE__ */ new Map([
|
|
|
129
130
|
["LEAST", "LEAST" /* LEAST */],
|
|
130
131
|
["LPAD", "LPAD" /* LPAD */],
|
|
131
132
|
["RPAD", "RPAD" /* RPAD */],
|
|
133
|
+
["TRANSLATE", "TRANSLATE" /* TRANSLATE */],
|
|
132
134
|
["CAST", "CAST" /* CAST */],
|
|
133
135
|
["CONVERT", "CONVERT" /* CONVERT */],
|
|
134
136
|
["FORMAT", "FORMAT" /* FORMAT */],
|
|
@@ -488,10 +490,12 @@ var FUNC_CALL_PREFIX_KINDS = /* @__PURE__ */ new Set([
|
|
|
488
490
|
"LTRIM" /* LTRIM */,
|
|
489
491
|
"RTRIM" /* RTRIM */,
|
|
490
492
|
"LENGTH" /* LENGTH */,
|
|
493
|
+
"LENGTH_CHAR" /* LENGTH_CHAR */,
|
|
491
494
|
"SUBSTRING" /* SUBSTRING */,
|
|
492
495
|
"SUBSTR" /* SUBSTR */,
|
|
493
496
|
"CONCAT" /* CONCAT */,
|
|
494
497
|
"REPLACE" /* REPLACE */,
|
|
498
|
+
"TRANSLATE" /* TRANSLATE */,
|
|
495
499
|
"COALESCE" /* COALESCE */,
|
|
496
500
|
"NULLIF" /* NULLIF */,
|
|
497
501
|
"ISNULL" /* ISNULL */,
|
|
@@ -543,6 +547,7 @@ var ParseError = class extends Error {
|
|
|
543
547
|
var Parser = class {
|
|
544
548
|
constructor(tokens) {
|
|
545
549
|
this.tokens = tokens;
|
|
550
|
+
this.allowUnaryPlusNumber = false;
|
|
546
551
|
this.pos = 0;
|
|
547
552
|
/** WITH 句で定義された CTE 名のセット(parseTableRef で参照) */
|
|
548
553
|
this.cteNames = /* @__PURE__ */ new Set();
|
|
@@ -1311,8 +1316,16 @@ var Parser = class {
|
|
|
1311
1316
|
this.expect(")" /* RPAREN */);
|
|
1312
1317
|
return expr;
|
|
1313
1318
|
}
|
|
1319
|
+
if (this.allowUnaryPlusNumber && this.peek().kind === "+" /* PLUS */) {
|
|
1320
|
+
this.advance();
|
|
1321
|
+
const number = this.expect("NUMBER" /* NUMBER */, "\u5358\u9805 + \u306E\u76F4\u5F8C\u306B\u306F\u6570\u5024\u30EA\u30C6\u30E9\u30EB\u304C\u5FC5\u8981\u3067\u3059");
|
|
1322
|
+
return { type: "NUMBER", value: Number(number.value) };
|
|
1323
|
+
}
|
|
1314
1324
|
if (this.peek().kind === "-" /* MINUS */) {
|
|
1315
1325
|
this.advance();
|
|
1326
|
+
if (this.peek().kind === "-" /* MINUS */ || this.peek().kind === "+" /* PLUS */) {
|
|
1327
|
+
throw new ParseError("\u5358\u9805\u7B26\u53F7\u3092\u91CD\u306D\u3066\u6307\u5B9A\u3059\u308B\u3053\u3068\u306F\u3067\u304D\u307E\u305B\u3093", this.peek());
|
|
1328
|
+
}
|
|
1316
1329
|
const operand = this.parseArithPrimary();
|
|
1317
1330
|
if (operand.type === "NUMBER") return { type: "NUMBER", value: -operand.value };
|
|
1318
1331
|
return { type: "ARITH", left: { type: "NUMBER", value: 0 }, op: "-", right: operand };
|
|
@@ -1422,10 +1435,12 @@ var Parser = class {
|
|
|
1422
1435
|
["LTRIM" /* LTRIM */]: "LTRIM",
|
|
1423
1436
|
["RTRIM" /* RTRIM */]: "RTRIM",
|
|
1424
1437
|
["LENGTH" /* LENGTH */]: "LENGTH",
|
|
1438
|
+
["LENGTH_CHAR" /* LENGTH_CHAR */]: "LENGTH_CHAR",
|
|
1425
1439
|
["SUBSTRING" /* SUBSTRING */]: "SUBSTRING",
|
|
1426
1440
|
["SUBSTR" /* SUBSTR */]: "SUBSTRING",
|
|
1427
1441
|
["CONCAT" /* CONCAT */]: "CONCAT",
|
|
1428
1442
|
["REPLACE" /* REPLACE */]: "REPLACE",
|
|
1443
|
+
["TRANSLATE" /* TRANSLATE */]: "TRANSLATE",
|
|
1429
1444
|
["COALESCE" /* COALESCE */]: "COALESCE",
|
|
1430
1445
|
["NULLIF" /* NULLIF */]: "NULLIF",
|
|
1431
1446
|
["ISNULL" /* ISNULL */]: "ISNULL",
|
|
@@ -2186,6 +2201,11 @@ var Parser = class {
|
|
|
2186
2201
|
} else if (this.peek().kind === "IF" /* IF */) {
|
|
2187
2202
|
const expr = this.parseIfExpr();
|
|
2188
2203
|
row.push({ type: "CASE_VALUE", expr });
|
|
2204
|
+
} else if (this.peek().kind === "-" /* MINUS */ || this.peek().kind === "+" /* PLUS */) {
|
|
2205
|
+
const sign = this.advance();
|
|
2206
|
+
const number = this.expect("NUMBER" /* NUMBER */, "INSERT \u306E\u5358\u9805\u7B26\u53F7\u306E\u76F4\u5F8C\u306B\u306F\u6570\u5024\u30EA\u30C6\u30E9\u30EB\u304C\u5FC5\u8981\u3067\u3059");
|
|
2207
|
+
const value = Number(number.value);
|
|
2208
|
+
row.push({ type: "NUMBER", value: sign.kind === "-" /* MINUS */ ? -value : value });
|
|
2189
2209
|
} else {
|
|
2190
2210
|
const tok = this.advance();
|
|
2191
2211
|
if (tok.kind === "STRING" /* STRING */) {
|
|
@@ -2215,6 +2235,12 @@ var Parser = class {
|
|
|
2215
2235
|
const { appId, subtableCode } = extractTableRef(name, this.prev());
|
|
2216
2236
|
this.expect("SET" /* SET */);
|
|
2217
2237
|
const assignments = this.parseAssignments();
|
|
2238
|
+
if (subtableCode && assignments.some((a) => a.value.type === "STRING_FUNC")) {
|
|
2239
|
+
throw new ParseError(
|
|
2240
|
+
"\u30B5\u30D6\u30C6\u30FC\u30D6\u30EB UPDATE SET \u3067\u306F\u6587\u5B57\u5217\u95A2\u6570\u3092\u76F4\u63A5\u4F7F\u7528\u3067\u304D\u307E\u305B\u3093",
|
|
2241
|
+
this.prev()
|
|
2242
|
+
);
|
|
2243
|
+
}
|
|
2218
2244
|
let from = null;
|
|
2219
2245
|
if (this.consume("FROM" /* FROM */)) {
|
|
2220
2246
|
const table = this.parseTableRef();
|
|
@@ -2258,7 +2284,14 @@ var Parser = class {
|
|
|
2258
2284
|
from.targetFilter = decomposed.targetFilter;
|
|
2259
2285
|
} else if (assignments.some((a) => a.value.type === "SOURCE_FIELD")) {
|
|
2260
2286
|
throw new ParseError(
|
|
2261
|
-
"SET \u306E\u5024\u306B\
|
|
2287
|
+
"SET \u306E\u5024\u306B\u30D5\u30A3\u30FC\u30EB\u30C9\u53C2\u7167\u3092\u5358\u72EC\u3067\u6307\u5B9A\u3059\u308B\u3053\u3068\u306F\u3067\u304D\u307E\u305B\u3093",
|
|
2288
|
+
whereTok
|
|
2289
|
+
);
|
|
2290
|
+
} else if (assignments.some(
|
|
2291
|
+
(a) => a.value.type === "STRING_FUNC" && this.nodeContainsAnyQualifier(a.value)
|
|
2292
|
+
)) {
|
|
2293
|
+
throw new ParseError(
|
|
2294
|
+
"UPDATE SET \u306E\u6587\u5B57\u5217\u95A2\u6570\u3067\u306F\u66F4\u65B0\u5148\u30D5\u30A3\u30FC\u30EB\u30C9\u3092\u4FEE\u98FE\u3057\u306A\u3044\u3067\u304F\u3060\u3055\u3044",
|
|
2262
2295
|
whereTok
|
|
2263
2296
|
);
|
|
2264
2297
|
}
|
|
@@ -2325,6 +2358,12 @@ var Parser = class {
|
|
|
2325
2358
|
}
|
|
2326
2359
|
validateUpdateFromAssignments(assignments, sourceAlias, tok) {
|
|
2327
2360
|
for (const assignment of assignments) {
|
|
2361
|
+
if (assignment.value.type === "STRING_FUNC") {
|
|
2362
|
+
throw new ParseError(
|
|
2363
|
+
"UPDATE ... FROM \u306E SET \u3067\u306F\u6587\u5B57\u5217\u95A2\u6570\u3092\u76F4\u63A5\u4F7F\u7528\u3067\u304D\u307E\u305B\u3093",
|
|
2364
|
+
tok
|
|
2365
|
+
);
|
|
2366
|
+
}
|
|
2328
2367
|
if (assignment.value.type === "SOURCE_FIELD") {
|
|
2329
2368
|
if (assignment.value.alias.toLowerCase() !== sourceAlias.toLowerCase()) {
|
|
2330
2369
|
throw new ParseError(`UPDATE ... FROM \u306E SET \u53C2\u7167\u306F\u30BD\u30FC\u30B9 alias ${sourceAlias} \u3067\u4FEE\u98FE\u3057\u3066\u304F\u3060\u3055\u3044`, tok);
|
|
@@ -2464,9 +2503,17 @@ var Parser = class {
|
|
|
2464
2503
|
this.expect(")" /* RPAREN */);
|
|
2465
2504
|
return { type: "SCALAR_SUBQUERY", query };
|
|
2466
2505
|
}
|
|
2467
|
-
const
|
|
2506
|
+
const previousAllowUnaryPlusNumber = this.allowUnaryPlusNumber;
|
|
2507
|
+
this.allowUnaryPlusNumber = true;
|
|
2508
|
+
let node;
|
|
2509
|
+
try {
|
|
2510
|
+
node = this.parseArithAddSub();
|
|
2511
|
+
} finally {
|
|
2512
|
+
this.allowUnaryPlusNumber = previousAllowUnaryPlusNumber;
|
|
2513
|
+
}
|
|
2468
2514
|
if (node.type === "NUMBER") return node;
|
|
2469
2515
|
if (node.type === "ARITH") return node;
|
|
2516
|
+
if (node.type === "STRING_FUNC") return node;
|
|
2470
2517
|
if (node.type === "FIELD_REF") {
|
|
2471
2518
|
const dot = node.field.indexOf(".");
|
|
2472
2519
|
if (dot > 0 && dot < node.field.length - 1) {
|
|
@@ -2474,7 +2521,7 @@ var Parser = class {
|
|
|
2474
2521
|
}
|
|
2475
2522
|
}
|
|
2476
2523
|
throw new ParseError(
|
|
2477
|
-
"SET \u306E\u5024\u306B\
|
|
2524
|
+
"SET \u306E\u5024\u306B\u30D5\u30A3\u30FC\u30EB\u30C9\u53C2\u7167\u3092\u5358\u72EC\u3067\u6307\u5B9A\u3059\u308B\u3053\u3068\u306F\u3067\u304D\u307E\u305B\u3093",
|
|
2478
2525
|
tok
|
|
2479
2526
|
);
|
|
2480
2527
|
}
|
|
@@ -4499,6 +4546,43 @@ function applyRoundOp(op, num, digits) {
|
|
|
4499
4546
|
if (digits > 0) return String(parseFloat(raw.toFixed(digits)));
|
|
4500
4547
|
return String(raw);
|
|
4501
4548
|
}
|
|
4549
|
+
function isHighSurrogate(codeUnit) {
|
|
4550
|
+
return codeUnit >= 55296 && codeUnit <= 56319;
|
|
4551
|
+
}
|
|
4552
|
+
function isLowSurrogate(codeUnit) {
|
|
4553
|
+
return codeUnit >= 56320 && codeUnit <= 57343;
|
|
4554
|
+
}
|
|
4555
|
+
function splitsSurrogatePair(value, index) {
|
|
4556
|
+
return index > 0 && index < value.length && isHighSurrogate(value.charCodeAt(index - 1)) && isLowSurrogate(value.charCodeAt(index));
|
|
4557
|
+
}
|
|
4558
|
+
function normalizeSliceIndex(index, length) {
|
|
4559
|
+
if (Number.isNaN(index) || index === Number.NEGATIVE_INFINITY) return 0;
|
|
4560
|
+
if (index === Number.POSITIVE_INFINITY) return length;
|
|
4561
|
+
const integer = Math.trunc(index);
|
|
4562
|
+
return integer < 0 ? Math.max(length + integer, 0) : Math.min(integer, length);
|
|
4563
|
+
}
|
|
4564
|
+
function sliceSafePrefix(value, budget) {
|
|
4565
|
+
let end = Math.min(Math.max(0, budget), value.length);
|
|
4566
|
+
if (splitsSurrogatePair(value, end)) end -= 1;
|
|
4567
|
+
return value.slice(0, end);
|
|
4568
|
+
}
|
|
4569
|
+
function sliceSafeSuffix(value, budget) {
|
|
4570
|
+
let start = Math.max(0, value.length - budget);
|
|
4571
|
+
if (splitsSurrogatePair(value, start)) start += 1;
|
|
4572
|
+
return value.slice(start);
|
|
4573
|
+
}
|
|
4574
|
+
function sliceSafeRange(value, rawStart, rawEnd) {
|
|
4575
|
+
let start = normalizeSliceIndex(rawStart, value.length);
|
|
4576
|
+
let end = normalizeSliceIndex(rawEnd, value.length);
|
|
4577
|
+
if (end <= start) return "";
|
|
4578
|
+
if (splitsSurrogatePair(value, start)) start += 1;
|
|
4579
|
+
if (splitsSurrogatePair(value, end)) end -= 1;
|
|
4580
|
+
return value.slice(start, Math.max(start, end));
|
|
4581
|
+
}
|
|
4582
|
+
function makeSafePadding(pad, gap) {
|
|
4583
|
+
const repeated = pad.repeat(Math.ceil(gap / pad.length));
|
|
4584
|
+
return sliceSafePrefix(repeated, gap);
|
|
4585
|
+
}
|
|
4502
4586
|
function evalStringFunc(expr, row) {
|
|
4503
4587
|
const args = expr.args.map((a) => evalStringFuncArg(a, row));
|
|
4504
4588
|
switch (expr.func) {
|
|
@@ -4514,23 +4598,26 @@ function evalStringFunc(expr, row) {
|
|
|
4514
4598
|
return (args[0] ?? "").trimEnd();
|
|
4515
4599
|
case "LENGTH":
|
|
4516
4600
|
return String((args[0] ?? "").length);
|
|
4601
|
+
case "LENGTH_CHAR":
|
|
4602
|
+
assertArity("LENGTH_CHAR", args, 1, 1);
|
|
4603
|
+
return String([...args[0] ?? ""].length);
|
|
4517
4604
|
case "SUBSTRING": {
|
|
4518
4605
|
const str = args[0] ?? "";
|
|
4519
4606
|
const start = Math.max(0, Number(args[1] ?? "1") - 1);
|
|
4520
4607
|
const len = args[2] !== void 0 ? Number(args[2]) : void 0;
|
|
4521
|
-
return len !== void 0 ?
|
|
4608
|
+
return sliceSafeRange(str, start, len !== void 0 ? start + len : str.length);
|
|
4522
4609
|
}
|
|
4523
4610
|
case "LEFT": {
|
|
4524
4611
|
assertArity("LEFT", args, 2, 2);
|
|
4525
4612
|
const str = args[0];
|
|
4526
4613
|
const n = Math.trunc(Number(args[1]));
|
|
4527
|
-
return Number.isNaN(n) || n <= 0 ? "" : str
|
|
4614
|
+
return Number.isNaN(n) || n <= 0 ? "" : sliceSafePrefix(str, n);
|
|
4528
4615
|
}
|
|
4529
4616
|
case "RIGHT": {
|
|
4530
4617
|
assertArity("RIGHT", args, 2, 2);
|
|
4531
4618
|
const str = args[0];
|
|
4532
4619
|
const n = Math.trunc(Number(args[1]));
|
|
4533
|
-
return Number.isNaN(n) || n <= 0 ? "" : str
|
|
4620
|
+
return Number.isNaN(n) || n <= 0 ? "" : sliceSafeSuffix(str, n);
|
|
4534
4621
|
}
|
|
4535
4622
|
case "INSTR":
|
|
4536
4623
|
assertArity("INSTR", args, 2, 2);
|
|
@@ -4541,10 +4628,11 @@ function evalStringFunc(expr, row) {
|
|
|
4541
4628
|
const str = args[0];
|
|
4542
4629
|
const n = Math.trunc(Number(args[1]));
|
|
4543
4630
|
if (Number.isNaN(n) || n <= 0) return "";
|
|
4544
|
-
if (str.length >= n) return str
|
|
4631
|
+
if (str.length >= n) return sliceSafePrefix(str, n);
|
|
4545
4632
|
const pad = args[2] ?? " ";
|
|
4546
4633
|
if (pad === "") return str;
|
|
4547
|
-
|
|
4634
|
+
const padding = makeSafePadding(pad, n - str.length);
|
|
4635
|
+
return expr.func === "LPAD" ? padding + str : str + padding;
|
|
4548
4636
|
}
|
|
4549
4637
|
case "GREATEST":
|
|
4550
4638
|
case "LEAST":
|
|
@@ -4558,6 +4646,21 @@ function evalStringFunc(expr, row) {
|
|
|
4558
4646
|
const to = args[2] ?? "";
|
|
4559
4647
|
return from === "" ? str : str.split(from).join(to);
|
|
4560
4648
|
}
|
|
4649
|
+
case "TRANSLATE": {
|
|
4650
|
+
assertArity("TRANSLATE", args, 3, 3);
|
|
4651
|
+
const from = [...args[1]];
|
|
4652
|
+
const to = [...args[2]];
|
|
4653
|
+
if (from.length !== to.length) {
|
|
4654
|
+
throw new Error(
|
|
4655
|
+
`ArgumentError: TRANSLATE \u306E from \u3068 to \u306F\u540C\u3058\u6587\u5B57\u6570\u3067\u3042\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059\uFF08from=${from.length}, to=${to.length}\uFF09`
|
|
4656
|
+
);
|
|
4657
|
+
}
|
|
4658
|
+
const map = /* @__PURE__ */ new Map();
|
|
4659
|
+
from.forEach((ch, i) => {
|
|
4660
|
+
if (!map.has(ch)) map.set(ch, to[i]);
|
|
4661
|
+
});
|
|
4662
|
+
return [...args[0]].map((ch) => map.get(ch) ?? ch).join("");
|
|
4663
|
+
}
|
|
4561
4664
|
case "COALESCE":
|
|
4562
4665
|
return args.find((a) => a !== "") ?? "";
|
|
4563
4666
|
case "NULLIF":
|
|
@@ -4795,6 +4898,7 @@ function evalOp(op, leftStr, right, row, fieldType, resolveFieldType, semantics
|
|
|
4795
4898
|
}
|
|
4796
4899
|
var NUMERIC_STRING_FUNCTIONS = /* @__PURE__ */ new Set([
|
|
4797
4900
|
"LENGTH",
|
|
4901
|
+
"LENGTH_CHAR",
|
|
4798
4902
|
"INSTR",
|
|
4799
4903
|
"ROUND",
|
|
4800
4904
|
"FLOOR",
|
|
@@ -5042,7 +5146,7 @@ function updateToPutBatches(stmt, ids, fieldTypes = /* @__PURE__ */ new Map()) {
|
|
|
5042
5146
|
function buildUpdateRecord(assignments, fieldTypes) {
|
|
5043
5147
|
const record = {};
|
|
5044
5148
|
for (const { field, value } of assignments) {
|
|
5045
|
-
if (value.type === "ARITH" || value.type === "CASE_VALUE" || value.type === "SOURCE_FIELD") continue;
|
|
5149
|
+
if (value.type === "ARITH" || value.type === "CASE_VALUE" || value.type === "STRING_FUNC" || value.type === "SOURCE_FIELD") continue;
|
|
5046
5150
|
record[field] = { value: toKintoneValue(value, fieldTypes.get(field)) };
|
|
5047
5151
|
}
|
|
5048
5152
|
return record;
|
|
@@ -5052,12 +5156,19 @@ function hasArithAssignment(stmt) {
|
|
|
5052
5156
|
(a) => a.value.type === "ARITH" || a.value.type === "CASE_VALUE"
|
|
5053
5157
|
);
|
|
5054
5158
|
}
|
|
5159
|
+
function hasRowDependentAssignment(stmt) {
|
|
5160
|
+
return stmt.assignments.some(
|
|
5161
|
+
(a) => a.value.type === "ARITH" || a.value.type === "CASE_VALUE" || a.value.type === "STRING_FUNC"
|
|
5162
|
+
);
|
|
5163
|
+
}
|
|
5055
5164
|
function updateToGetQueryForArith(stmt) {
|
|
5056
5165
|
assertDmlWhereIsSafe(stmt.where);
|
|
5057
5166
|
const refFields = /* @__PURE__ */ new Set();
|
|
5058
5167
|
for (const { value } of stmt.assignments) {
|
|
5059
5168
|
if (value.type === "ARITH") {
|
|
5060
5169
|
collectArithFields2(value, refFields);
|
|
5170
|
+
} else if (value.type === "STRING_FUNC") {
|
|
5171
|
+
collectStringFuncFields2(value, refFields);
|
|
5061
5172
|
} else if (value.type === "CASE_VALUE") {
|
|
5062
5173
|
collectCaseFields(value.expr, refFields);
|
|
5063
5174
|
}
|
|
@@ -5144,6 +5255,8 @@ function updateToPutBatchesArith(stmt, records, fieldTypes = /* @__PURE__ */ new
|
|
|
5144
5255
|
for (const { field, value } of stmt.assignments) {
|
|
5145
5256
|
if (value.type === "ARITH") {
|
|
5146
5257
|
record[field] = { value: String(evalArith(value, raw)) };
|
|
5258
|
+
} else if (value.type === "STRING_FUNC") {
|
|
5259
|
+
record[field] = { value: evalStringFunc(value, row) };
|
|
5147
5260
|
} else if (value.type === "CASE_VALUE") {
|
|
5148
5261
|
record[field] = { value: evalCaseWhenValue(value.expr, row, fieldTypes.get(field)) };
|
|
5149
5262
|
} else if (value.type === "SOURCE_FIELD") {
|
|
@@ -5192,6 +5305,8 @@ function updateFromToPutBatches(stmt, matched, fieldTypes = /* @__PURE__ */ new
|
|
|
5192
5305
|
throw new DmlConvertError(`\u6570\u5024\u30D5\u30A3\u30FC\u30EB\u30C9 ${field} \u306B\u5909\u63DB\u3067\u304D\u306A\u3044\u5024\u3067\u3059: ${raw}`);
|
|
5193
5306
|
}
|
|
5194
5307
|
record[field] = { value: toKintoneValue({ type: "STRING", value: raw }, fieldType) };
|
|
5308
|
+
} else if (value.type === "STRING_FUNC") {
|
|
5309
|
+
throw new DmlConvertError("UPDATE ... FROM \u306E SET \u3067\u306F\u6587\u5B57\u5217\u95A2\u6570\u3092\u76F4\u63A5\u4F7F\u7528\u3067\u304D\u307E\u305B\u3093");
|
|
5195
5310
|
} else if (value.type === "ARITH") {
|
|
5196
5311
|
record[field] = { value: String(evalArith(value, target)) };
|
|
5197
5312
|
} else if (value.type === "CASE_VALUE") {
|
|
@@ -6083,6 +6198,7 @@ function compareSortKeys(a, b, meta) {
|
|
|
6083
6198
|
}
|
|
6084
6199
|
var NUMERIC_ORDER_FUNCTIONS = /* @__PURE__ */ new Set([
|
|
6085
6200
|
"LENGTH",
|
|
6201
|
+
"LENGTH_CHAR",
|
|
6086
6202
|
"INSTR",
|
|
6087
6203
|
"ROUND",
|
|
6088
6204
|
"FLOOR",
|
|
@@ -8303,6 +8419,7 @@ function systemColumnMeta(field) {
|
|
|
8303
8419
|
}
|
|
8304
8420
|
var NUMBER_RETURNING_STRING_FUNCTIONS = /* @__PURE__ */ new Set([
|
|
8305
8421
|
"LENGTH",
|
|
8422
|
+
"LENGTH_CHAR",
|
|
8306
8423
|
"INSTR",
|
|
8307
8424
|
"ROUND",
|
|
8308
8425
|
"FLOOR",
|
|
@@ -9270,6 +9387,28 @@ var NON_WRITABLE_FIELD_TYPES = /* @__PURE__ */ new Set([
|
|
|
9270
9387
|
"CATEGORY",
|
|
9271
9388
|
"REFERENCE_TABLE"
|
|
9272
9389
|
]);
|
|
9390
|
+
function assertWritableTopLevelDmlFields(appId, targetFields, fieldInfos) {
|
|
9391
|
+
const infoByCode = new Map(fieldInfos.map((field) => [field.code, field]));
|
|
9392
|
+
for (const code of targetFields) {
|
|
9393
|
+
const info = infoByCode.get(code);
|
|
9394
|
+
if (!info) {
|
|
9395
|
+
throw new Error(`ArgumentError: DML target field ${code} does not exist.`);
|
|
9396
|
+
}
|
|
9397
|
+
if (info.inSubtable) {
|
|
9398
|
+
throw new Error(
|
|
9399
|
+
`ArgumentError: DML target field ${code} is inside a subtable. Use subtable DML syntax (for example, APP${appId}$\u30C6\u30FC\u30D6\u30EB).`
|
|
9400
|
+
);
|
|
9401
|
+
}
|
|
9402
|
+
if (info.writable === false || NON_WRITABLE_FIELD_TYPES.has(info.fieldType)) {
|
|
9403
|
+
throw new Error(`ArgumentError: DML target field ${code} is not writable (${info.fieldType}).`);
|
|
9404
|
+
}
|
|
9405
|
+
}
|
|
9406
|
+
}
|
|
9407
|
+
async function loadWritableTopLevelDmlFields(appId, targetFields, client, cacheContext) {
|
|
9408
|
+
const fieldInfos = await getFieldsCached(appId, client, cacheContext);
|
|
9409
|
+
assertWritableTopLevelDmlFields(appId, targetFields, fieldInfos);
|
|
9410
|
+
return fieldInfos;
|
|
9411
|
+
}
|
|
9273
9412
|
async function executeDmlValidation(stmt, client, options, cacheContext, tempTables, statementNumber) {
|
|
9274
9413
|
return (await prepareDmlValidation(stmt, client, options, cacheContext, tempTables, statementNumber)).result;
|
|
9275
9414
|
}
|
|
@@ -9281,24 +9420,22 @@ var RejectLimitExceededError = class extends Error {
|
|
|
9281
9420
|
}
|
|
9282
9421
|
};
|
|
9283
9422
|
async function prepareDmlValidation(stmt, client, options, cacheContext, tempTables, statementNumber) {
|
|
9284
|
-
if (stmt.type === "UPDATE") {
|
|
9285
|
-
await assertDmlWhereCapability(stmt, client, cacheContext);
|
|
9286
|
-
}
|
|
9287
9423
|
const operation = stmt.type === "UPDATE" ? "UPDATE" : stmt.type.startsWith("UPSERT") ? "UPSERT" : "INSERT";
|
|
9288
9424
|
const payloadFields = stmt.type === "UPDATE" ? ["$id", ...stmt.assignments.map((a) => a.field)] : [...stmt.fields];
|
|
9289
9425
|
if (new Set(payloadFields).size !== payloadFields.length) {
|
|
9290
9426
|
throw new Error("ArgumentError: DML target fields contain duplicates.");
|
|
9291
9427
|
}
|
|
9292
|
-
const fieldInfos = await getFieldsCached(stmt.appId, client, cacheContext);
|
|
9293
|
-
const infoByCode = new Map(fieldInfos.map((field) => [field.code, field]));
|
|
9294
9428
|
const targetFields = stmt.type === "UPDATE" ? stmt.assignments.map((a) => a.field) : stmt.fields;
|
|
9295
|
-
|
|
9296
|
-
|
|
9297
|
-
|
|
9298
|
-
|
|
9299
|
-
|
|
9300
|
-
|
|
9429
|
+
const fieldInfos = await loadWritableTopLevelDmlFields(
|
|
9430
|
+
stmt.appId,
|
|
9431
|
+
targetFields,
|
|
9432
|
+
client,
|
|
9433
|
+
cacheContext
|
|
9434
|
+
);
|
|
9435
|
+
if (stmt.type === "UPDATE") {
|
|
9436
|
+
await assertDmlWhereCapability(stmt, client, cacheContext);
|
|
9301
9437
|
}
|
|
9438
|
+
const infoByCode = new Map(fieldInfos.map((field) => [field.code, field]));
|
|
9302
9439
|
const candidates = await materializeValidationCandidates(stmt, operation, client, options, cacheContext, tempTables, infoByCode);
|
|
9303
9440
|
const { errors, invalidRows, invalidRowNumbers } = validateDmlCandidates(
|
|
9304
9441
|
candidates,
|
|
@@ -9467,7 +9604,7 @@ async function materializeUpdateValidationCandidates(stmt, client, options, cach
|
|
|
9467
9604
|
await resolveSetSubqueries(stmt.assignments, client, options, cacheContext);
|
|
9468
9605
|
const fieldTypes = await getFieldTypeMap(stmt.appId, client, cacheContext);
|
|
9469
9606
|
let records;
|
|
9470
|
-
if (
|
|
9607
|
+
if (hasRowDependentAssignment(stmt)) {
|
|
9471
9608
|
const getParams = updateToGetQueryForArith(stmt);
|
|
9472
9609
|
const resolved = await fetchRecordsForSharedPlan(client.getRecords, getParams.app, getParams.query, [...getParams.fields], {
|
|
9473
9610
|
maxRecords: options.maxRecords ?? 1e4,
|
|
@@ -9676,6 +9813,7 @@ async function executeInsert(stmt, client, options, cacheContext) {
|
|
|
9676
9813
|
if (stmt.subtableCode) {
|
|
9677
9814
|
return executeInsertSubtable(stmt, client, options, cacheContext);
|
|
9678
9815
|
}
|
|
9816
|
+
await loadWritableTopLevelDmlFields(stmt.appId, stmt.fields, client, cacheContext);
|
|
9679
9817
|
const fieldTypes = await getFieldTypeMap(stmt.appId, client, cacheContext);
|
|
9680
9818
|
const batches = insertToPostBatches(stmt, fieldTypes);
|
|
9681
9819
|
const createdIds = [];
|
|
@@ -9690,6 +9828,7 @@ async function executeInsert(stmt, client, options, cacheContext) {
|
|
|
9690
9828
|
};
|
|
9691
9829
|
}
|
|
9692
9830
|
async function executeInsertSelect(stmt, client, options, cacheContext, cteCache) {
|
|
9831
|
+
await loadWritableTopLevelDmlFields(stmt.appId, stmt.fields, client, cacheContext);
|
|
9693
9832
|
const selectResult = cteCache !== void 0 && cteCache.size > 0 ? await executeQueryWithCte(stmt.select, client, options, cteCache, cacheContext) : await executeSelect(stmt.select, client, options, cacheContext);
|
|
9694
9833
|
const { rows, columns } = selectResult;
|
|
9695
9834
|
if (columns.length !== stmt.fields.length) {
|
|
@@ -9724,17 +9863,24 @@ async function executeInsertSelect(stmt, client, options, cacheContext, cteCache
|
|
|
9724
9863
|
};
|
|
9725
9864
|
}
|
|
9726
9865
|
async function executeUpdate(stmt, client, options, cacheContext, tempTables) {
|
|
9727
|
-
await assertDmlWhereCapability(stmt, client, cacheContext);
|
|
9728
9866
|
if (stmt.subtableCode) {
|
|
9867
|
+
await assertDmlWhereCapability(stmt, client, cacheContext);
|
|
9729
9868
|
return executeUpdateSubtable(stmt, client, options, cacheContext);
|
|
9730
9869
|
}
|
|
9870
|
+
await loadWritableTopLevelDmlFields(
|
|
9871
|
+
stmt.appId,
|
|
9872
|
+
stmt.assignments.map((assignment) => assignment.field),
|
|
9873
|
+
client,
|
|
9874
|
+
cacheContext
|
|
9875
|
+
);
|
|
9876
|
+
await assertDmlWhereCapability(stmt, client, cacheContext);
|
|
9731
9877
|
if (stmt.from != null) {
|
|
9732
9878
|
return executeUpdateFrom(stmt, stmt.from, client, options, cacheContext, tempTables);
|
|
9733
9879
|
}
|
|
9734
9880
|
const maxRecords = options.maxRecords ?? 1e4;
|
|
9735
9881
|
await resolveSetSubqueries(stmt.assignments, client, options, cacheContext);
|
|
9736
9882
|
const fieldTypes = await getFieldTypeMap(stmt.appId, client, cacheContext);
|
|
9737
|
-
if (
|
|
9883
|
+
if (hasRowDependentAssignment(stmt)) {
|
|
9738
9884
|
const getParams2 = updateToGetQueryForArith(stmt);
|
|
9739
9885
|
const resolved2 = await fetchRecordsForSharedPlan(
|
|
9740
9886
|
client.getRecords,
|
|
@@ -9828,6 +9974,7 @@ async function executeDelete(stmt, client, options, cacheContext) {
|
|
|
9828
9974
|
return { type: "DELETE", deletedCount: ids.length };
|
|
9829
9975
|
}
|
|
9830
9976
|
async function executeUpsert(stmt, client, options, cacheContext) {
|
|
9977
|
+
await loadWritableTopLevelDmlFields(stmt.appId, stmt.fields, client, cacheContext);
|
|
9831
9978
|
const toInsert = [];
|
|
9832
9979
|
const toUpdate = [];
|
|
9833
9980
|
const fieldTypes = await getFieldTypeMap(stmt.appId, client, cacheContext);
|
|
@@ -10254,6 +10401,7 @@ function evalOrderKeyForRow(key, row) {
|
|
|
10254
10401
|
}
|
|
10255
10402
|
}
|
|
10256
10403
|
async function executeUpsertSelect(stmt, client, options, cacheContext, cteCache) {
|
|
10404
|
+
await loadWritableTopLevelDmlFields(stmt.appId, stmt.fields, client, cacheContext);
|
|
10257
10405
|
const selectResult = cteCache !== void 0 && cteCache.size > 0 ? await executeQueryWithCte(stmt.select, client, options, cteCache, cacheContext) : await executeSelect(stmt.select, client, options, cacheContext);
|
|
10258
10406
|
const { rows, columns } = selectResult;
|
|
10259
10407
|
if (columns.length !== stmt.fields.length) {
|
|
@@ -10889,6 +11037,8 @@ function buildInsertSelectPlan(stmt, label, capabilities, orderPlans) {
|
|
|
10889
11037
|
}
|
|
10890
11038
|
function buildUpdatePlan(stmt, label, capabilities, orderPlans) {
|
|
10891
11039
|
const isArith = hasArithAssignment(stmt);
|
|
11040
|
+
const isStringFunc = stmt.assignments.some((a) => a.value.type === "STRING_FUNC");
|
|
11041
|
+
const isRowDependent = hasRowDependentAssignment(stmt);
|
|
10892
11042
|
const isSubq = stmt.assignments.some((a) => a.value.type === "SCALAR_SUBQUERY");
|
|
10893
11043
|
const lines = [];
|
|
10894
11044
|
if (label) lines.push(label);
|
|
@@ -10905,10 +11055,11 @@ function buildUpdatePlan(stmt, label, capabilities, orderPlans) {
|
|
|
10905
11055
|
lines.push(` api: GET /k/v1/records.json \u2192 PUT /k/v1/records.json`);
|
|
10906
11056
|
const setTypes = [];
|
|
10907
11057
|
if (isArith) setTypes.push("\u7B97\u8853 SET\uFF08\u73FE\u5728\u5024\u3092\u53D6\u5F97\u3057\u3066\u8A08\u7B97\uFF09");
|
|
11058
|
+
if (isStringFunc) setTypes.push("\u6587\u5B57\u5217\u95A2\u6570 SET\uFF08\u73FE\u5728\u5024\u3092\u53D6\u5F97\u3057\u3066\u8A55\u4FA1\uFF09");
|
|
10908
11059
|
if (isSubq) setTypes.push("\u30B9\u30AB\u30E9\u30FC\u30B5\u30D6\u30AF\u30A8\u30EA SET");
|
|
10909
|
-
if (!
|
|
11060
|
+
if (!isRowDependent && !isSubq) setTypes.push("\u5358\u7D14 SET");
|
|
10910
11061
|
lines.push(` set type: ${setTypes.join(", ")}`);
|
|
10911
|
-
if (
|
|
11062
|
+
if (isRowDependent) {
|
|
10912
11063
|
const refFields = collectArithRefFields(stmt);
|
|
10913
11064
|
if (refFields.length > 0) {
|
|
10914
11065
|
lines.push(` ref fields: ${refFields.join(", ")}\uFF08GET \u306B\u542B\u3081\u308B\uFF09`);
|
|
@@ -10994,6 +11145,7 @@ function collectArithRefFields(stmt) {
|
|
|
10994
11145
|
const refs = /* @__PURE__ */ new Set();
|
|
10995
11146
|
for (const { value } of stmt.assignments) {
|
|
10996
11147
|
if (value.type === "ARITH") collectArithNodeRefs(value, refs);
|
|
11148
|
+
if (value.type === "STRING_FUNC") collectArithNodeRefs(value, refs);
|
|
10997
11149
|
}
|
|
10998
11150
|
return [...refs];
|
|
10999
11151
|
}
|
|
@@ -11006,6 +11158,13 @@ function collectArithNodeRefs(node, out) {
|
|
|
11006
11158
|
collectArithNodeRefs(node.left, out);
|
|
11007
11159
|
collectArithNodeRefs(node.right, out);
|
|
11008
11160
|
}
|
|
11161
|
+
if (node.type === "STRING_FUNC") {
|
|
11162
|
+
for (const arg of node.args) {
|
|
11163
|
+
if (arg.type !== "STRING" && arg.type !== "AGG_REF" && arg.type !== "AGG_ARITH") {
|
|
11164
|
+
collectArithNodeRefs(arg, out);
|
|
11165
|
+
}
|
|
11166
|
+
}
|
|
11167
|
+
}
|
|
11009
11168
|
}
|
|
11010
11169
|
function formatAssignment(a) {
|
|
11011
11170
|
const v = a.value;
|
|
@@ -11013,6 +11172,7 @@ function formatAssignment(a) {
|
|
|
11013
11172
|
if (v.type === "NUMBER") return `${a.field} = ${v.value}`;
|
|
11014
11173
|
if (v.type === "ARITH") return `${a.field} = ${formatArithExprStr(v)}`;
|
|
11015
11174
|
if (v.type === "CASE_VALUE") return `${a.field} = CASE WHEN ...`;
|
|
11175
|
+
if (v.type === "STRING_FUNC") return `${a.field} = ${v.func}(...)`;
|
|
11016
11176
|
if (v.type === "SCALAR_SUBQUERY") return `${a.field} = (SELECT ...)`;
|
|
11017
11177
|
if (v.type === "SOURCE_FIELD") return `${a.field} = ${v.alias}.${v.field}`;
|
|
11018
11178
|
return `${a.field} = (${v.type})`;
|
package/dist-mcp/ksql-mcp.js
CHANGED
|
@@ -31029,6 +31029,7 @@ var KEYWORDS = /* @__PURE__ */ new Map([
|
|
|
31029
31029
|
["LTRIM", "LTRIM" /* LTRIM */],
|
|
31030
31030
|
["RTRIM", "RTRIM" /* RTRIM */],
|
|
31031
31031
|
["LENGTH", "LENGTH" /* LENGTH */],
|
|
31032
|
+
["LENGTH_CHAR", "LENGTH_CHAR" /* LENGTH_CHAR */],
|
|
31032
31033
|
["SUBSTRING", "SUBSTRING" /* SUBSTRING */],
|
|
31033
31034
|
["SUBSTR", "SUBSTR" /* SUBSTR */],
|
|
31034
31035
|
["CONCAT", "CONCAT" /* CONCAT */],
|
|
@@ -31041,6 +31042,7 @@ var KEYWORDS = /* @__PURE__ */ new Map([
|
|
|
31041
31042
|
["LEAST", "LEAST" /* LEAST */],
|
|
31042
31043
|
["LPAD", "LPAD" /* LPAD */],
|
|
31043
31044
|
["RPAD", "RPAD" /* RPAD */],
|
|
31045
|
+
["TRANSLATE", "TRANSLATE" /* TRANSLATE */],
|
|
31044
31046
|
["CAST", "CAST" /* CAST */],
|
|
31045
31047
|
["CONVERT", "CONVERT" /* CONVERT */],
|
|
31046
31048
|
["FORMAT", "FORMAT" /* FORMAT */],
|
|
@@ -31400,10 +31402,12 @@ var FUNC_CALL_PREFIX_KINDS = /* @__PURE__ */ new Set([
|
|
|
31400
31402
|
"LTRIM" /* LTRIM */,
|
|
31401
31403
|
"RTRIM" /* RTRIM */,
|
|
31402
31404
|
"LENGTH" /* LENGTH */,
|
|
31405
|
+
"LENGTH_CHAR" /* LENGTH_CHAR */,
|
|
31403
31406
|
"SUBSTRING" /* SUBSTRING */,
|
|
31404
31407
|
"SUBSTR" /* SUBSTR */,
|
|
31405
31408
|
"CONCAT" /* CONCAT */,
|
|
31406
31409
|
"REPLACE" /* REPLACE */,
|
|
31410
|
+
"TRANSLATE" /* TRANSLATE */,
|
|
31407
31411
|
"COALESCE" /* COALESCE */,
|
|
31408
31412
|
"NULLIF" /* NULLIF */,
|
|
31409
31413
|
"ISNULL" /* ISNULL */,
|
|
@@ -31455,6 +31459,7 @@ var ParseError = class extends Error {
|
|
|
31455
31459
|
var Parser = class {
|
|
31456
31460
|
constructor(tokens) {
|
|
31457
31461
|
this.tokens = tokens;
|
|
31462
|
+
this.allowUnaryPlusNumber = false;
|
|
31458
31463
|
this.pos = 0;
|
|
31459
31464
|
/** WITH 句で定義された CTE 名のセット(parseTableRef で参照) */
|
|
31460
31465
|
this.cteNames = /* @__PURE__ */ new Set();
|
|
@@ -32223,8 +32228,16 @@ var Parser = class {
|
|
|
32223
32228
|
this.expect(")" /* RPAREN */);
|
|
32224
32229
|
return expr;
|
|
32225
32230
|
}
|
|
32231
|
+
if (this.allowUnaryPlusNumber && this.peek().kind === "+" /* PLUS */) {
|
|
32232
|
+
this.advance();
|
|
32233
|
+
const number4 = this.expect("NUMBER" /* NUMBER */, "\u5358\u9805 + \u306E\u76F4\u5F8C\u306B\u306F\u6570\u5024\u30EA\u30C6\u30E9\u30EB\u304C\u5FC5\u8981\u3067\u3059");
|
|
32234
|
+
return { type: "NUMBER", value: Number(number4.value) };
|
|
32235
|
+
}
|
|
32226
32236
|
if (this.peek().kind === "-" /* MINUS */) {
|
|
32227
32237
|
this.advance();
|
|
32238
|
+
if (this.peek().kind === "-" /* MINUS */ || this.peek().kind === "+" /* PLUS */) {
|
|
32239
|
+
throw new ParseError("\u5358\u9805\u7B26\u53F7\u3092\u91CD\u306D\u3066\u6307\u5B9A\u3059\u308B\u3053\u3068\u306F\u3067\u304D\u307E\u305B\u3093", this.peek());
|
|
32240
|
+
}
|
|
32228
32241
|
const operand = this.parseArithPrimary();
|
|
32229
32242
|
if (operand.type === "NUMBER") return { type: "NUMBER", value: -operand.value };
|
|
32230
32243
|
return { type: "ARITH", left: { type: "NUMBER", value: 0 }, op: "-", right: operand };
|
|
@@ -32334,10 +32347,12 @@ var Parser = class {
|
|
|
32334
32347
|
["LTRIM" /* LTRIM */]: "LTRIM",
|
|
32335
32348
|
["RTRIM" /* RTRIM */]: "RTRIM",
|
|
32336
32349
|
["LENGTH" /* LENGTH */]: "LENGTH",
|
|
32350
|
+
["LENGTH_CHAR" /* LENGTH_CHAR */]: "LENGTH_CHAR",
|
|
32337
32351
|
["SUBSTRING" /* SUBSTRING */]: "SUBSTRING",
|
|
32338
32352
|
["SUBSTR" /* SUBSTR */]: "SUBSTRING",
|
|
32339
32353
|
["CONCAT" /* CONCAT */]: "CONCAT",
|
|
32340
32354
|
["REPLACE" /* REPLACE */]: "REPLACE",
|
|
32355
|
+
["TRANSLATE" /* TRANSLATE */]: "TRANSLATE",
|
|
32341
32356
|
["COALESCE" /* COALESCE */]: "COALESCE",
|
|
32342
32357
|
["NULLIF" /* NULLIF */]: "NULLIF",
|
|
32343
32358
|
["ISNULL" /* ISNULL */]: "ISNULL",
|
|
@@ -33098,6 +33113,11 @@ var Parser = class {
|
|
|
33098
33113
|
} else if (this.peek().kind === "IF" /* IF */) {
|
|
33099
33114
|
const expr = this.parseIfExpr();
|
|
33100
33115
|
row.push({ type: "CASE_VALUE", expr });
|
|
33116
|
+
} else if (this.peek().kind === "-" /* MINUS */ || this.peek().kind === "+" /* PLUS */) {
|
|
33117
|
+
const sign = this.advance();
|
|
33118
|
+
const number4 = this.expect("NUMBER" /* NUMBER */, "INSERT \u306E\u5358\u9805\u7B26\u53F7\u306E\u76F4\u5F8C\u306B\u306F\u6570\u5024\u30EA\u30C6\u30E9\u30EB\u304C\u5FC5\u8981\u3067\u3059");
|
|
33119
|
+
const value = Number(number4.value);
|
|
33120
|
+
row.push({ type: "NUMBER", value: sign.kind === "-" /* MINUS */ ? -value : value });
|
|
33101
33121
|
} else {
|
|
33102
33122
|
const tok = this.advance();
|
|
33103
33123
|
if (tok.kind === "STRING" /* STRING */) {
|
|
@@ -33127,6 +33147,12 @@ var Parser = class {
|
|
|
33127
33147
|
const { appId, subtableCode } = extractTableRef(name, this.prev());
|
|
33128
33148
|
this.expect("SET" /* SET */);
|
|
33129
33149
|
const assignments = this.parseAssignments();
|
|
33150
|
+
if (subtableCode && assignments.some((a) => a.value.type === "STRING_FUNC")) {
|
|
33151
|
+
throw new ParseError(
|
|
33152
|
+
"\u30B5\u30D6\u30C6\u30FC\u30D6\u30EB UPDATE SET \u3067\u306F\u6587\u5B57\u5217\u95A2\u6570\u3092\u76F4\u63A5\u4F7F\u7528\u3067\u304D\u307E\u305B\u3093",
|
|
33153
|
+
this.prev()
|
|
33154
|
+
);
|
|
33155
|
+
}
|
|
33130
33156
|
let from = null;
|
|
33131
33157
|
if (this.consume("FROM" /* FROM */)) {
|
|
33132
33158
|
const table = this.parseTableRef();
|
|
@@ -33170,7 +33196,14 @@ var Parser = class {
|
|
|
33170
33196
|
from.targetFilter = decomposed.targetFilter;
|
|
33171
33197
|
} else if (assignments.some((a) => a.value.type === "SOURCE_FIELD")) {
|
|
33172
33198
|
throw new ParseError(
|
|
33173
|
-
"SET \u306E\u5024\u306B\
|
|
33199
|
+
"SET \u306E\u5024\u306B\u30D5\u30A3\u30FC\u30EB\u30C9\u53C2\u7167\u3092\u5358\u72EC\u3067\u6307\u5B9A\u3059\u308B\u3053\u3068\u306F\u3067\u304D\u307E\u305B\u3093",
|
|
33200
|
+
whereTok
|
|
33201
|
+
);
|
|
33202
|
+
} else if (assignments.some(
|
|
33203
|
+
(a) => a.value.type === "STRING_FUNC" && this.nodeContainsAnyQualifier(a.value)
|
|
33204
|
+
)) {
|
|
33205
|
+
throw new ParseError(
|
|
33206
|
+
"UPDATE SET \u306E\u6587\u5B57\u5217\u95A2\u6570\u3067\u306F\u66F4\u65B0\u5148\u30D5\u30A3\u30FC\u30EB\u30C9\u3092\u4FEE\u98FE\u3057\u306A\u3044\u3067\u304F\u3060\u3055\u3044",
|
|
33174
33207
|
whereTok
|
|
33175
33208
|
);
|
|
33176
33209
|
}
|
|
@@ -33237,6 +33270,12 @@ var Parser = class {
|
|
|
33237
33270
|
}
|
|
33238
33271
|
validateUpdateFromAssignments(assignments, sourceAlias, tok) {
|
|
33239
33272
|
for (const assignment of assignments) {
|
|
33273
|
+
if (assignment.value.type === "STRING_FUNC") {
|
|
33274
|
+
throw new ParseError(
|
|
33275
|
+
"UPDATE ... FROM \u306E SET \u3067\u306F\u6587\u5B57\u5217\u95A2\u6570\u3092\u76F4\u63A5\u4F7F\u7528\u3067\u304D\u307E\u305B\u3093",
|
|
33276
|
+
tok
|
|
33277
|
+
);
|
|
33278
|
+
}
|
|
33240
33279
|
if (assignment.value.type === "SOURCE_FIELD") {
|
|
33241
33280
|
if (assignment.value.alias.toLowerCase() !== sourceAlias.toLowerCase()) {
|
|
33242
33281
|
throw new ParseError(`UPDATE ... FROM \u306E SET \u53C2\u7167\u306F\u30BD\u30FC\u30B9 alias ${sourceAlias} \u3067\u4FEE\u98FE\u3057\u3066\u304F\u3060\u3055\u3044`, tok);
|
|
@@ -33376,9 +33415,17 @@ var Parser = class {
|
|
|
33376
33415
|
this.expect(")" /* RPAREN */);
|
|
33377
33416
|
return { type: "SCALAR_SUBQUERY", query };
|
|
33378
33417
|
}
|
|
33379
|
-
const
|
|
33418
|
+
const previousAllowUnaryPlusNumber = this.allowUnaryPlusNumber;
|
|
33419
|
+
this.allowUnaryPlusNumber = true;
|
|
33420
|
+
let node;
|
|
33421
|
+
try {
|
|
33422
|
+
node = this.parseArithAddSub();
|
|
33423
|
+
} finally {
|
|
33424
|
+
this.allowUnaryPlusNumber = previousAllowUnaryPlusNumber;
|
|
33425
|
+
}
|
|
33380
33426
|
if (node.type === "NUMBER") return node;
|
|
33381
33427
|
if (node.type === "ARITH") return node;
|
|
33428
|
+
if (node.type === "STRING_FUNC") return node;
|
|
33382
33429
|
if (node.type === "FIELD_REF") {
|
|
33383
33430
|
const dot = node.field.indexOf(".");
|
|
33384
33431
|
if (dot > 0 && dot < node.field.length - 1) {
|
|
@@ -33386,7 +33433,7 @@ var Parser = class {
|
|
|
33386
33433
|
}
|
|
33387
33434
|
}
|
|
33388
33435
|
throw new ParseError(
|
|
33389
|
-
"SET \u306E\u5024\u306B\
|
|
33436
|
+
"SET \u306E\u5024\u306B\u30D5\u30A3\u30FC\u30EB\u30C9\u53C2\u7167\u3092\u5358\u72EC\u3067\u6307\u5B9A\u3059\u308B\u3053\u3068\u306F\u3067\u304D\u307E\u305B\u3093",
|
|
33390
33437
|
tok
|
|
33391
33438
|
);
|
|
33392
33439
|
}
|
|
@@ -35399,6 +35446,43 @@ function applyRoundOp(op, num, digits) {
|
|
|
35399
35446
|
if (digits > 0) return String(parseFloat(raw.toFixed(digits)));
|
|
35400
35447
|
return String(raw);
|
|
35401
35448
|
}
|
|
35449
|
+
function isHighSurrogate(codeUnit) {
|
|
35450
|
+
return codeUnit >= 55296 && codeUnit <= 56319;
|
|
35451
|
+
}
|
|
35452
|
+
function isLowSurrogate(codeUnit) {
|
|
35453
|
+
return codeUnit >= 56320 && codeUnit <= 57343;
|
|
35454
|
+
}
|
|
35455
|
+
function splitsSurrogatePair(value, index) {
|
|
35456
|
+
return index > 0 && index < value.length && isHighSurrogate(value.charCodeAt(index - 1)) && isLowSurrogate(value.charCodeAt(index));
|
|
35457
|
+
}
|
|
35458
|
+
function normalizeSliceIndex(index, length) {
|
|
35459
|
+
if (Number.isNaN(index) || index === Number.NEGATIVE_INFINITY) return 0;
|
|
35460
|
+
if (index === Number.POSITIVE_INFINITY) return length;
|
|
35461
|
+
const integer2 = Math.trunc(index);
|
|
35462
|
+
return integer2 < 0 ? Math.max(length + integer2, 0) : Math.min(integer2, length);
|
|
35463
|
+
}
|
|
35464
|
+
function sliceSafePrefix(value, budget) {
|
|
35465
|
+
let end = Math.min(Math.max(0, budget), value.length);
|
|
35466
|
+
if (splitsSurrogatePair(value, end)) end -= 1;
|
|
35467
|
+
return value.slice(0, end);
|
|
35468
|
+
}
|
|
35469
|
+
function sliceSafeSuffix(value, budget) {
|
|
35470
|
+
let start = Math.max(0, value.length - budget);
|
|
35471
|
+
if (splitsSurrogatePair(value, start)) start += 1;
|
|
35472
|
+
return value.slice(start);
|
|
35473
|
+
}
|
|
35474
|
+
function sliceSafeRange(value, rawStart, rawEnd) {
|
|
35475
|
+
let start = normalizeSliceIndex(rawStart, value.length);
|
|
35476
|
+
let end = normalizeSliceIndex(rawEnd, value.length);
|
|
35477
|
+
if (end <= start) return "";
|
|
35478
|
+
if (splitsSurrogatePair(value, start)) start += 1;
|
|
35479
|
+
if (splitsSurrogatePair(value, end)) end -= 1;
|
|
35480
|
+
return value.slice(start, Math.max(start, end));
|
|
35481
|
+
}
|
|
35482
|
+
function makeSafePadding(pad, gap) {
|
|
35483
|
+
const repeated = pad.repeat(Math.ceil(gap / pad.length));
|
|
35484
|
+
return sliceSafePrefix(repeated, gap);
|
|
35485
|
+
}
|
|
35402
35486
|
function evalStringFunc(expr, row) {
|
|
35403
35487
|
const args = expr.args.map((a) => evalStringFuncArg(a, row));
|
|
35404
35488
|
switch (expr.func) {
|
|
@@ -35414,23 +35498,26 @@ function evalStringFunc(expr, row) {
|
|
|
35414
35498
|
return (args[0] ?? "").trimEnd();
|
|
35415
35499
|
case "LENGTH":
|
|
35416
35500
|
return String((args[0] ?? "").length);
|
|
35501
|
+
case "LENGTH_CHAR":
|
|
35502
|
+
assertArity("LENGTH_CHAR", args, 1, 1);
|
|
35503
|
+
return String([...args[0] ?? ""].length);
|
|
35417
35504
|
case "SUBSTRING": {
|
|
35418
35505
|
const str = args[0] ?? "";
|
|
35419
35506
|
const start = Math.max(0, Number(args[1] ?? "1") - 1);
|
|
35420
35507
|
const len = args[2] !== void 0 ? Number(args[2]) : void 0;
|
|
35421
|
-
return len !== void 0 ?
|
|
35508
|
+
return sliceSafeRange(str, start, len !== void 0 ? start + len : str.length);
|
|
35422
35509
|
}
|
|
35423
35510
|
case "LEFT": {
|
|
35424
35511
|
assertArity("LEFT", args, 2, 2);
|
|
35425
35512
|
const str = args[0];
|
|
35426
35513
|
const n = Math.trunc(Number(args[1]));
|
|
35427
|
-
return Number.isNaN(n) || n <= 0 ? "" : str
|
|
35514
|
+
return Number.isNaN(n) || n <= 0 ? "" : sliceSafePrefix(str, n);
|
|
35428
35515
|
}
|
|
35429
35516
|
case "RIGHT": {
|
|
35430
35517
|
assertArity("RIGHT", args, 2, 2);
|
|
35431
35518
|
const str = args[0];
|
|
35432
35519
|
const n = Math.trunc(Number(args[1]));
|
|
35433
|
-
return Number.isNaN(n) || n <= 0 ? "" : str
|
|
35520
|
+
return Number.isNaN(n) || n <= 0 ? "" : sliceSafeSuffix(str, n);
|
|
35434
35521
|
}
|
|
35435
35522
|
case "INSTR":
|
|
35436
35523
|
assertArity("INSTR", args, 2, 2);
|
|
@@ -35441,10 +35528,11 @@ function evalStringFunc(expr, row) {
|
|
|
35441
35528
|
const str = args[0];
|
|
35442
35529
|
const n = Math.trunc(Number(args[1]));
|
|
35443
35530
|
if (Number.isNaN(n) || n <= 0) return "";
|
|
35444
|
-
if (str.length >= n) return str
|
|
35531
|
+
if (str.length >= n) return sliceSafePrefix(str, n);
|
|
35445
35532
|
const pad = args[2] ?? " ";
|
|
35446
35533
|
if (pad === "") return str;
|
|
35447
|
-
|
|
35534
|
+
const padding = makeSafePadding(pad, n - str.length);
|
|
35535
|
+
return expr.func === "LPAD" ? padding + str : str + padding;
|
|
35448
35536
|
}
|
|
35449
35537
|
case "GREATEST":
|
|
35450
35538
|
case "LEAST":
|
|
@@ -35458,6 +35546,21 @@ function evalStringFunc(expr, row) {
|
|
|
35458
35546
|
const to = args[2] ?? "";
|
|
35459
35547
|
return from === "" ? str : str.split(from).join(to);
|
|
35460
35548
|
}
|
|
35549
|
+
case "TRANSLATE": {
|
|
35550
|
+
assertArity("TRANSLATE", args, 3, 3);
|
|
35551
|
+
const from = [...args[1]];
|
|
35552
|
+
const to = [...args[2]];
|
|
35553
|
+
if (from.length !== to.length) {
|
|
35554
|
+
throw new Error(
|
|
35555
|
+
`ArgumentError: TRANSLATE \u306E from \u3068 to \u306F\u540C\u3058\u6587\u5B57\u6570\u3067\u3042\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059\uFF08from=${from.length}, to=${to.length}\uFF09`
|
|
35556
|
+
);
|
|
35557
|
+
}
|
|
35558
|
+
const map2 = /* @__PURE__ */ new Map();
|
|
35559
|
+
from.forEach((ch, i) => {
|
|
35560
|
+
if (!map2.has(ch)) map2.set(ch, to[i]);
|
|
35561
|
+
});
|
|
35562
|
+
return [...args[0]].map((ch) => map2.get(ch) ?? ch).join("");
|
|
35563
|
+
}
|
|
35461
35564
|
case "COALESCE":
|
|
35462
35565
|
return args.find((a) => a !== "") ?? "";
|
|
35463
35566
|
case "NULLIF":
|
|
@@ -35695,6 +35798,7 @@ function evalOp(op, leftStr, right, row, fieldType, resolveFieldType, semantics
|
|
|
35695
35798
|
}
|
|
35696
35799
|
var NUMERIC_STRING_FUNCTIONS = /* @__PURE__ */ new Set([
|
|
35697
35800
|
"LENGTH",
|
|
35801
|
+
"LENGTH_CHAR",
|
|
35698
35802
|
"INSTR",
|
|
35699
35803
|
"ROUND",
|
|
35700
35804
|
"FLOOR",
|
|
@@ -35942,7 +36046,7 @@ function updateToPutBatches(stmt, ids, fieldTypes = /* @__PURE__ */ new Map()) {
|
|
|
35942
36046
|
function buildUpdateRecord(assignments, fieldTypes) {
|
|
35943
36047
|
const record2 = {};
|
|
35944
36048
|
for (const { field, value } of assignments) {
|
|
35945
|
-
if (value.type === "ARITH" || value.type === "CASE_VALUE" || value.type === "SOURCE_FIELD") continue;
|
|
36049
|
+
if (value.type === "ARITH" || value.type === "CASE_VALUE" || value.type === "STRING_FUNC" || value.type === "SOURCE_FIELD") continue;
|
|
35946
36050
|
record2[field] = { value: toKintoneValue(value, fieldTypes.get(field)) };
|
|
35947
36051
|
}
|
|
35948
36052
|
return record2;
|
|
@@ -35952,12 +36056,19 @@ function hasArithAssignment(stmt) {
|
|
|
35952
36056
|
(a) => a.value.type === "ARITH" || a.value.type === "CASE_VALUE"
|
|
35953
36057
|
);
|
|
35954
36058
|
}
|
|
36059
|
+
function hasRowDependentAssignment(stmt) {
|
|
36060
|
+
return stmt.assignments.some(
|
|
36061
|
+
(a) => a.value.type === "ARITH" || a.value.type === "CASE_VALUE" || a.value.type === "STRING_FUNC"
|
|
36062
|
+
);
|
|
36063
|
+
}
|
|
35955
36064
|
function updateToGetQueryForArith(stmt) {
|
|
35956
36065
|
assertDmlWhereIsSafe(stmt.where);
|
|
35957
36066
|
const refFields = /* @__PURE__ */ new Set();
|
|
35958
36067
|
for (const { value } of stmt.assignments) {
|
|
35959
36068
|
if (value.type === "ARITH") {
|
|
35960
36069
|
collectArithFields2(value, refFields);
|
|
36070
|
+
} else if (value.type === "STRING_FUNC") {
|
|
36071
|
+
collectStringFuncFields2(value, refFields);
|
|
35961
36072
|
} else if (value.type === "CASE_VALUE") {
|
|
35962
36073
|
collectCaseFields(value.expr, refFields);
|
|
35963
36074
|
}
|
|
@@ -36044,6 +36155,8 @@ function updateToPutBatchesArith(stmt, records, fieldTypes = /* @__PURE__ */ new
|
|
|
36044
36155
|
for (const { field, value } of stmt.assignments) {
|
|
36045
36156
|
if (value.type === "ARITH") {
|
|
36046
36157
|
record2[field] = { value: String(evalArith(value, raw)) };
|
|
36158
|
+
} else if (value.type === "STRING_FUNC") {
|
|
36159
|
+
record2[field] = { value: evalStringFunc(value, row) };
|
|
36047
36160
|
} else if (value.type === "CASE_VALUE") {
|
|
36048
36161
|
record2[field] = { value: evalCaseWhenValue(value.expr, row, fieldTypes.get(field)) };
|
|
36049
36162
|
} else if (value.type === "SOURCE_FIELD") {
|
|
@@ -36092,6 +36205,8 @@ function updateFromToPutBatches(stmt, matched, fieldTypes = /* @__PURE__ */ new
|
|
|
36092
36205
|
throw new DmlConvertError(`\u6570\u5024\u30D5\u30A3\u30FC\u30EB\u30C9 ${field} \u306B\u5909\u63DB\u3067\u304D\u306A\u3044\u5024\u3067\u3059: ${raw}`);
|
|
36093
36206
|
}
|
|
36094
36207
|
record2[field] = { value: toKintoneValue({ type: "STRING", value: raw }, fieldType) };
|
|
36208
|
+
} else if (value.type === "STRING_FUNC") {
|
|
36209
|
+
throw new DmlConvertError("UPDATE ... FROM \u306E SET \u3067\u306F\u6587\u5B57\u5217\u95A2\u6570\u3092\u76F4\u63A5\u4F7F\u7528\u3067\u304D\u307E\u305B\u3093");
|
|
36095
36210
|
} else if (value.type === "ARITH") {
|
|
36096
36211
|
record2[field] = { value: String(evalArith(value, target)) };
|
|
36097
36212
|
} else if (value.type === "CASE_VALUE") {
|
|
@@ -36983,6 +37098,7 @@ function compareSortKeys(a, b, meta3) {
|
|
|
36983
37098
|
}
|
|
36984
37099
|
var NUMERIC_ORDER_FUNCTIONS = /* @__PURE__ */ new Set([
|
|
36985
37100
|
"LENGTH",
|
|
37101
|
+
"LENGTH_CHAR",
|
|
36986
37102
|
"INSTR",
|
|
36987
37103
|
"ROUND",
|
|
36988
37104
|
"FLOOR",
|
|
@@ -39203,6 +39319,7 @@ function systemColumnMeta(field) {
|
|
|
39203
39319
|
}
|
|
39204
39320
|
var NUMBER_RETURNING_STRING_FUNCTIONS = /* @__PURE__ */ new Set([
|
|
39205
39321
|
"LENGTH",
|
|
39322
|
+
"LENGTH_CHAR",
|
|
39206
39323
|
"INSTR",
|
|
39207
39324
|
"ROUND",
|
|
39208
39325
|
"FLOOR",
|
|
@@ -40170,6 +40287,28 @@ var NON_WRITABLE_FIELD_TYPES = /* @__PURE__ */ new Set([
|
|
|
40170
40287
|
"CATEGORY",
|
|
40171
40288
|
"REFERENCE_TABLE"
|
|
40172
40289
|
]);
|
|
40290
|
+
function assertWritableTopLevelDmlFields(appId, targetFields, fieldInfos) {
|
|
40291
|
+
const infoByCode = new Map(fieldInfos.map((field) => [field.code, field]));
|
|
40292
|
+
for (const code of targetFields) {
|
|
40293
|
+
const info = infoByCode.get(code);
|
|
40294
|
+
if (!info) {
|
|
40295
|
+
throw new Error(`ArgumentError: DML target field ${code} does not exist.`);
|
|
40296
|
+
}
|
|
40297
|
+
if (info.inSubtable) {
|
|
40298
|
+
throw new Error(
|
|
40299
|
+
`ArgumentError: DML target field ${code} is inside a subtable. Use subtable DML syntax (for example, APP${appId}$\u30C6\u30FC\u30D6\u30EB).`
|
|
40300
|
+
);
|
|
40301
|
+
}
|
|
40302
|
+
if (info.writable === false || NON_WRITABLE_FIELD_TYPES.has(info.fieldType)) {
|
|
40303
|
+
throw new Error(`ArgumentError: DML target field ${code} is not writable (${info.fieldType}).`);
|
|
40304
|
+
}
|
|
40305
|
+
}
|
|
40306
|
+
}
|
|
40307
|
+
async function loadWritableTopLevelDmlFields(appId, targetFields, client, cacheContext) {
|
|
40308
|
+
const fieldInfos = await getFieldsCached(appId, client, cacheContext);
|
|
40309
|
+
assertWritableTopLevelDmlFields(appId, targetFields, fieldInfos);
|
|
40310
|
+
return fieldInfos;
|
|
40311
|
+
}
|
|
40173
40312
|
async function executeDmlValidation(stmt, client, options, cacheContext, tempTables, statementNumber) {
|
|
40174
40313
|
return (await prepareDmlValidation(stmt, client, options, cacheContext, tempTables, statementNumber)).result;
|
|
40175
40314
|
}
|
|
@@ -40181,24 +40320,22 @@ var RejectLimitExceededError = class extends Error {
|
|
|
40181
40320
|
}
|
|
40182
40321
|
};
|
|
40183
40322
|
async function prepareDmlValidation(stmt, client, options, cacheContext, tempTables, statementNumber) {
|
|
40184
|
-
if (stmt.type === "UPDATE") {
|
|
40185
|
-
await assertDmlWhereCapability(stmt, client, cacheContext);
|
|
40186
|
-
}
|
|
40187
40323
|
const operation = stmt.type === "UPDATE" ? "UPDATE" : stmt.type.startsWith("UPSERT") ? "UPSERT" : "INSERT";
|
|
40188
40324
|
const payloadFields = stmt.type === "UPDATE" ? ["$id", ...stmt.assignments.map((a) => a.field)] : [...stmt.fields];
|
|
40189
40325
|
if (new Set(payloadFields).size !== payloadFields.length) {
|
|
40190
40326
|
throw new Error("ArgumentError: DML target fields contain duplicates.");
|
|
40191
40327
|
}
|
|
40192
|
-
const fieldInfos = await getFieldsCached(stmt.appId, client, cacheContext);
|
|
40193
|
-
const infoByCode = new Map(fieldInfos.map((field) => [field.code, field]));
|
|
40194
40328
|
const targetFields = stmt.type === "UPDATE" ? stmt.assignments.map((a) => a.field) : stmt.fields;
|
|
40195
|
-
|
|
40196
|
-
|
|
40197
|
-
|
|
40198
|
-
|
|
40199
|
-
|
|
40200
|
-
|
|
40329
|
+
const fieldInfos = await loadWritableTopLevelDmlFields(
|
|
40330
|
+
stmt.appId,
|
|
40331
|
+
targetFields,
|
|
40332
|
+
client,
|
|
40333
|
+
cacheContext
|
|
40334
|
+
);
|
|
40335
|
+
if (stmt.type === "UPDATE") {
|
|
40336
|
+
await assertDmlWhereCapability(stmt, client, cacheContext);
|
|
40201
40337
|
}
|
|
40338
|
+
const infoByCode = new Map(fieldInfos.map((field) => [field.code, field]));
|
|
40202
40339
|
const candidates = await materializeValidationCandidates(stmt, operation, client, options, cacheContext, tempTables, infoByCode);
|
|
40203
40340
|
const { errors, invalidRows, invalidRowNumbers } = validateDmlCandidates(
|
|
40204
40341
|
candidates,
|
|
@@ -40367,7 +40504,7 @@ async function materializeUpdateValidationCandidates(stmt, client, options, cach
|
|
|
40367
40504
|
await resolveSetSubqueries(stmt.assignments, client, options, cacheContext);
|
|
40368
40505
|
const fieldTypes = await getFieldTypeMap(stmt.appId, client, cacheContext);
|
|
40369
40506
|
let records;
|
|
40370
|
-
if (
|
|
40507
|
+
if (hasRowDependentAssignment(stmt)) {
|
|
40371
40508
|
const getParams = updateToGetQueryForArith(stmt);
|
|
40372
40509
|
const resolved = await fetchRecordsForSharedPlan(client.getRecords, getParams.app, getParams.query, [...getParams.fields], {
|
|
40373
40510
|
maxRecords: options.maxRecords ?? 1e4,
|
|
@@ -40576,6 +40713,7 @@ async function executeInsert(stmt, client, options, cacheContext) {
|
|
|
40576
40713
|
if (stmt.subtableCode) {
|
|
40577
40714
|
return executeInsertSubtable(stmt, client, options, cacheContext);
|
|
40578
40715
|
}
|
|
40716
|
+
await loadWritableTopLevelDmlFields(stmt.appId, stmt.fields, client, cacheContext);
|
|
40579
40717
|
const fieldTypes = await getFieldTypeMap(stmt.appId, client, cacheContext);
|
|
40580
40718
|
const batches = insertToPostBatches(stmt, fieldTypes);
|
|
40581
40719
|
const createdIds = [];
|
|
@@ -40590,6 +40728,7 @@ async function executeInsert(stmt, client, options, cacheContext) {
|
|
|
40590
40728
|
};
|
|
40591
40729
|
}
|
|
40592
40730
|
async function executeInsertSelect(stmt, client, options, cacheContext, cteCache) {
|
|
40731
|
+
await loadWritableTopLevelDmlFields(stmt.appId, stmt.fields, client, cacheContext);
|
|
40593
40732
|
const selectResult = cteCache !== void 0 && cteCache.size > 0 ? await executeQueryWithCte(stmt.select, client, options, cteCache, cacheContext) : await executeSelect(stmt.select, client, options, cacheContext);
|
|
40594
40733
|
const { rows, columns } = selectResult;
|
|
40595
40734
|
if (columns.length !== stmt.fields.length) {
|
|
@@ -40624,17 +40763,24 @@ async function executeInsertSelect(stmt, client, options, cacheContext, cteCache
|
|
|
40624
40763
|
};
|
|
40625
40764
|
}
|
|
40626
40765
|
async function executeUpdate(stmt, client, options, cacheContext, tempTables) {
|
|
40627
|
-
await assertDmlWhereCapability(stmt, client, cacheContext);
|
|
40628
40766
|
if (stmt.subtableCode) {
|
|
40767
|
+
await assertDmlWhereCapability(stmt, client, cacheContext);
|
|
40629
40768
|
return executeUpdateSubtable(stmt, client, options, cacheContext);
|
|
40630
40769
|
}
|
|
40770
|
+
await loadWritableTopLevelDmlFields(
|
|
40771
|
+
stmt.appId,
|
|
40772
|
+
stmt.assignments.map((assignment) => assignment.field),
|
|
40773
|
+
client,
|
|
40774
|
+
cacheContext
|
|
40775
|
+
);
|
|
40776
|
+
await assertDmlWhereCapability(stmt, client, cacheContext);
|
|
40631
40777
|
if (stmt.from != null) {
|
|
40632
40778
|
return executeUpdateFrom(stmt, stmt.from, client, options, cacheContext, tempTables);
|
|
40633
40779
|
}
|
|
40634
40780
|
const maxRecords2 = options.maxRecords ?? 1e4;
|
|
40635
40781
|
await resolveSetSubqueries(stmt.assignments, client, options, cacheContext);
|
|
40636
40782
|
const fieldTypes = await getFieldTypeMap(stmt.appId, client, cacheContext);
|
|
40637
|
-
if (
|
|
40783
|
+
if (hasRowDependentAssignment(stmt)) {
|
|
40638
40784
|
const getParams2 = updateToGetQueryForArith(stmt);
|
|
40639
40785
|
const resolved2 = await fetchRecordsForSharedPlan(
|
|
40640
40786
|
client.getRecords,
|
|
@@ -40728,6 +40874,7 @@ async function executeDelete(stmt, client, options, cacheContext) {
|
|
|
40728
40874
|
return { type: "DELETE", deletedCount: ids.length };
|
|
40729
40875
|
}
|
|
40730
40876
|
async function executeUpsert(stmt, client, options, cacheContext) {
|
|
40877
|
+
await loadWritableTopLevelDmlFields(stmt.appId, stmt.fields, client, cacheContext);
|
|
40731
40878
|
const toInsert = [];
|
|
40732
40879
|
const toUpdate = [];
|
|
40733
40880
|
const fieldTypes = await getFieldTypeMap(stmt.appId, client, cacheContext);
|
|
@@ -41154,6 +41301,7 @@ function evalOrderKeyForRow(key, row) {
|
|
|
41154
41301
|
}
|
|
41155
41302
|
}
|
|
41156
41303
|
async function executeUpsertSelect(stmt, client, options, cacheContext, cteCache) {
|
|
41304
|
+
await loadWritableTopLevelDmlFields(stmt.appId, stmt.fields, client, cacheContext);
|
|
41157
41305
|
const selectResult = cteCache !== void 0 && cteCache.size > 0 ? await executeQueryWithCte(stmt.select, client, options, cteCache, cacheContext) : await executeSelect(stmt.select, client, options, cacheContext);
|
|
41158
41306
|
const { rows, columns } = selectResult;
|
|
41159
41307
|
if (columns.length !== stmt.fields.length) {
|
|
@@ -41789,6 +41937,8 @@ function buildInsertSelectPlan(stmt, label, capabilities, orderPlans) {
|
|
|
41789
41937
|
}
|
|
41790
41938
|
function buildUpdatePlan(stmt, label, capabilities, orderPlans) {
|
|
41791
41939
|
const isArith = hasArithAssignment(stmt);
|
|
41940
|
+
const isStringFunc = stmt.assignments.some((a) => a.value.type === "STRING_FUNC");
|
|
41941
|
+
const isRowDependent = hasRowDependentAssignment(stmt);
|
|
41792
41942
|
const isSubq = stmt.assignments.some((a) => a.value.type === "SCALAR_SUBQUERY");
|
|
41793
41943
|
const lines = [];
|
|
41794
41944
|
if (label) lines.push(label);
|
|
@@ -41805,10 +41955,11 @@ function buildUpdatePlan(stmt, label, capabilities, orderPlans) {
|
|
|
41805
41955
|
lines.push(` api: GET /k/v1/records.json \u2192 PUT /k/v1/records.json`);
|
|
41806
41956
|
const setTypes = [];
|
|
41807
41957
|
if (isArith) setTypes.push("\u7B97\u8853 SET\uFF08\u73FE\u5728\u5024\u3092\u53D6\u5F97\u3057\u3066\u8A08\u7B97\uFF09");
|
|
41958
|
+
if (isStringFunc) setTypes.push("\u6587\u5B57\u5217\u95A2\u6570 SET\uFF08\u73FE\u5728\u5024\u3092\u53D6\u5F97\u3057\u3066\u8A55\u4FA1\uFF09");
|
|
41808
41959
|
if (isSubq) setTypes.push("\u30B9\u30AB\u30E9\u30FC\u30B5\u30D6\u30AF\u30A8\u30EA SET");
|
|
41809
|
-
if (!
|
|
41960
|
+
if (!isRowDependent && !isSubq) setTypes.push("\u5358\u7D14 SET");
|
|
41810
41961
|
lines.push(` set type: ${setTypes.join(", ")}`);
|
|
41811
|
-
if (
|
|
41962
|
+
if (isRowDependent) {
|
|
41812
41963
|
const refFields = collectArithRefFields(stmt);
|
|
41813
41964
|
if (refFields.length > 0) {
|
|
41814
41965
|
lines.push(` ref fields: ${refFields.join(", ")}\uFF08GET \u306B\u542B\u3081\u308B\uFF09`);
|
|
@@ -41894,6 +42045,7 @@ function collectArithRefFields(stmt) {
|
|
|
41894
42045
|
const refs = /* @__PURE__ */ new Set();
|
|
41895
42046
|
for (const { value } of stmt.assignments) {
|
|
41896
42047
|
if (value.type === "ARITH") collectArithNodeRefs(value, refs);
|
|
42048
|
+
if (value.type === "STRING_FUNC") collectArithNodeRefs(value, refs);
|
|
41897
42049
|
}
|
|
41898
42050
|
return [...refs];
|
|
41899
42051
|
}
|
|
@@ -41906,6 +42058,13 @@ function collectArithNodeRefs(node, out) {
|
|
|
41906
42058
|
collectArithNodeRefs(node.left, out);
|
|
41907
42059
|
collectArithNodeRefs(node.right, out);
|
|
41908
42060
|
}
|
|
42061
|
+
if (node.type === "STRING_FUNC") {
|
|
42062
|
+
for (const arg of node.args) {
|
|
42063
|
+
if (arg.type !== "STRING" && arg.type !== "AGG_REF" && arg.type !== "AGG_ARITH") {
|
|
42064
|
+
collectArithNodeRefs(arg, out);
|
|
42065
|
+
}
|
|
42066
|
+
}
|
|
42067
|
+
}
|
|
41909
42068
|
}
|
|
41910
42069
|
function formatAssignment(a) {
|
|
41911
42070
|
const v = a.value;
|
|
@@ -41913,6 +42072,7 @@ function formatAssignment(a) {
|
|
|
41913
42072
|
if (v.type === "NUMBER") return `${a.field} = ${v.value}`;
|
|
41914
42073
|
if (v.type === "ARITH") return `${a.field} = ${formatArithExprStr(v)}`;
|
|
41915
42074
|
if (v.type === "CASE_VALUE") return `${a.field} = CASE WHEN ...`;
|
|
42075
|
+
if (v.type === "STRING_FUNC") return `${a.field} = ${v.func}(...)`;
|
|
41916
42076
|
if (v.type === "SCALAR_SUBQUERY") return `${a.field} = (SELECT ...)`;
|
|
41917
42077
|
if (v.type === "SOURCE_FIELD") return `${a.field} = ${v.alias}.${v.field}`;
|
|
41918
42078
|
return `${a.field} = (${v.type})`;
|
|
@@ -44507,7 +44667,7 @@ Options:
|
|
|
44507
44667
|
-h, --help Show help
|
|
44508
44668
|
`);
|
|
44509
44669
|
}
|
|
44510
|
-
var SERVER_VERSION = true ? "3.
|
|
44670
|
+
var SERVER_VERSION = true ? "3.2.0" : "0.0.0-dev";
|
|
44511
44671
|
function createServer(args) {
|
|
44512
44672
|
const server = new McpServer({
|
|
44513
44673
|
name: "ksql-mcp",
|
package/dist-mcpb/ksql-mcp.mcpb
CHANGED
|
Binary file
|