@rex0220/kintone-sql-tools 3.68.0 → 3.70.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 +38 -0
- package/dist-cli/ksql.js +330 -64
- package/dist-engine/index.cjs +16 -16
- package/dist-engine/index.mjs +16 -16
- package/dist-engine/ksql-engine.umd.js +16 -16
- package/dist-engine/meta/bundle-baseline.json +10 -10
- package/dist-engine/meta/cjs.json +100 -43
- package/dist-engine/meta/esm.json +100 -43
- package/dist-engine/meta/umd.json +100 -43
- package/dist-flow/flow-library/errors.d.ts +6 -0
- package/dist-flow/flow-library/index.d.ts +13 -0
- package/dist-flow/flow-library/publicTypes.d.ts +271 -0
- package/dist-flow/flow-library/writableClient.d.ts +2 -0
- package/dist-flow/index.cjs +18 -0
- package/dist-flow/index.mjs +18 -0
- package/dist-flow/meta/cjs.json +2346 -0
- package/dist-flow/meta/esm.json +2357 -0
- package/dist-flow/types/ast.d.ts +881 -0
- package/dist-mcp/ksql-mcp.js +686 -162
- package/dist-mcpb/ksql-mcp.mcpb +0 -0
- package/package.json +12 -3
package/dist-cli/ksql.js
CHANGED
|
@@ -677,6 +677,75 @@ function resolveGroupingSpec(stmt, resolve2) {
|
|
|
677
677
|
};
|
|
678
678
|
}
|
|
679
679
|
|
|
680
|
+
// src/core/asOfClock.ts
|
|
681
|
+
var AS_OF_FUNCTION_NAMES = [
|
|
682
|
+
"NOW",
|
|
683
|
+
"TODAY",
|
|
684
|
+
"MONTH_START",
|
|
685
|
+
"NEXT_MONTH_START"
|
|
686
|
+
];
|
|
687
|
+
var AS_OF_VARIABLE_PREFIX = "\0as-of:";
|
|
688
|
+
function asOfVariableName(name) {
|
|
689
|
+
return `${AS_OF_VARIABLE_PREFIX}${name}`;
|
|
690
|
+
}
|
|
691
|
+
function asOfFunctionNameFromVariable(name) {
|
|
692
|
+
if (!name.startsWith(AS_OF_VARIABLE_PREFIX)) return null;
|
|
693
|
+
const candidate = name.slice(AS_OF_VARIABLE_PREFIX.length);
|
|
694
|
+
return isAsOfFunctionName(candidate) ? candidate : null;
|
|
695
|
+
}
|
|
696
|
+
function isAsOfFunctionName(name) {
|
|
697
|
+
return AS_OF_FUNCTION_NAMES.includes(name);
|
|
698
|
+
}
|
|
699
|
+
function createAsOfClock(asOf = /* @__PURE__ */ new Date(), timezone) {
|
|
700
|
+
if (!(asOf instanceof Date) || !Number.isFinite(asOf.getTime())) {
|
|
701
|
+
throw new Error("ArgumentError: asOf must be a valid Date.");
|
|
702
|
+
}
|
|
703
|
+
let formatter;
|
|
704
|
+
try {
|
|
705
|
+
formatter = new Intl.DateTimeFormat("en-CA", {
|
|
706
|
+
...timezone === void 0 ? {} : { timeZone: timezone },
|
|
707
|
+
year: "numeric",
|
|
708
|
+
month: "2-digit",
|
|
709
|
+
day: "2-digit"
|
|
710
|
+
});
|
|
711
|
+
formatter.format(asOf);
|
|
712
|
+
} catch {
|
|
713
|
+
throw new Error(`ArgumentError: invalid IANA timezone: ${timezone ?? ""}.`);
|
|
714
|
+
}
|
|
715
|
+
const parts = formatter.formatToParts(asOf);
|
|
716
|
+
const year = partNumber(parts, "year");
|
|
717
|
+
const month = partNumber(parts, "month");
|
|
718
|
+
const day = partNumber(parts, "day");
|
|
719
|
+
const today = `${pad4(year)}-${pad2(month)}-${pad2(day)}`;
|
|
720
|
+
const monthStart = `${pad4(year)}-${pad2(month)}-01`;
|
|
721
|
+
const nextYear = month === 12 ? year + 1 : year;
|
|
722
|
+
const nextMonth = month === 12 ? 1 : month + 1;
|
|
723
|
+
return {
|
|
724
|
+
asOf: new Date(asOf.getTime()),
|
|
725
|
+
...timezone === void 0 ? {} : { timezone },
|
|
726
|
+
values: {
|
|
727
|
+
NOW: asOf.toISOString(),
|
|
728
|
+
TODAY: today,
|
|
729
|
+
MONTH_START: monthStart,
|
|
730
|
+
NEXT_MONTH_START: `${pad4(nextYear)}-${pad2(nextMonth)}-01`
|
|
731
|
+
}
|
|
732
|
+
};
|
|
733
|
+
}
|
|
734
|
+
function partNumber(parts, type) {
|
|
735
|
+
const value = parts.find((part) => part.type === type)?.value;
|
|
736
|
+
const parsed = Number(value);
|
|
737
|
+
if (!Number.isInteger(parsed)) {
|
|
738
|
+
throw new Error(`InternalError: Intl.DateTimeFormat did not return ${type}.`);
|
|
739
|
+
}
|
|
740
|
+
return parsed;
|
|
741
|
+
}
|
|
742
|
+
function pad2(value) {
|
|
743
|
+
return String(value).padStart(2, "0");
|
|
744
|
+
}
|
|
745
|
+
function pad4(value) {
|
|
746
|
+
return String(value).padStart(4, "0");
|
|
747
|
+
}
|
|
748
|
+
|
|
680
749
|
// src/core/aggregateExpression.ts
|
|
681
750
|
function quote(value) {
|
|
682
751
|
return `'${value.replace(/'/g, "''")}'`;
|
|
@@ -1095,6 +1164,19 @@ var Parser = class {
|
|
|
1095
1164
|
this.activeCteDefinition = null;
|
|
1096
1165
|
this.provisionalRecursiveCte = null;
|
|
1097
1166
|
this.allowSelectArithVariable = false;
|
|
1167
|
+
if (capabilities.dialect1) {
|
|
1168
|
+
for (let index = 0; index + 1 < tokens.length; index++) {
|
|
1169
|
+
const token = tokens[index];
|
|
1170
|
+
if (token.kind !== "VARIABLE" /* VARIABLE */ || tokens[index + 1].kind !== "(" /* LPAREN */) continue;
|
|
1171
|
+
const name = token.value.slice(1).toUpperCase();
|
|
1172
|
+
if (!isAsOfFunctionName(name)) {
|
|
1173
|
+
throw new ParseError(
|
|
1174
|
+
`\u4F7F\u7528\u53EF\u80FD\u306A as-of \u95A2\u6570\u306F ${AS_OF_FUNCTION_NAMES.map((item) => `@${item}`).join("/")} \u3067\u3059`,
|
|
1175
|
+
token
|
|
1176
|
+
);
|
|
1177
|
+
}
|
|
1178
|
+
}
|
|
1179
|
+
}
|
|
1098
1180
|
}
|
|
1099
1181
|
// ----------------------------------------------------------
|
|
1100
1182
|
// 公開 API
|
|
@@ -1264,6 +1346,10 @@ var Parser = class {
|
|
|
1264
1346
|
parseScalarExpr(context, allowScalarSubquery) {
|
|
1265
1347
|
const tok = this.peek();
|
|
1266
1348
|
if (tok.kind === "VARIABLE" /* VARIABLE */) {
|
|
1349
|
+
if (this.peekAt(1).kind === "(" /* LPAREN */ && this.capabilities.dialect1) {
|
|
1350
|
+
this.advance();
|
|
1351
|
+
return this.finishVariableReference(tok);
|
|
1352
|
+
}
|
|
1267
1353
|
throw new ParseError(`${context} \u306E\u53F3\u8FBA\u3067\u306F\u4ED6\u306E\u5909\u6570\u3092\u53C2\u7167\u3067\u304D\u307E\u305B\u3093`, tok);
|
|
1268
1354
|
}
|
|
1269
1355
|
if (tok.kind === "NULL" /* NULL */) {
|
|
@@ -1803,12 +1889,28 @@ var Parser = class {
|
|
|
1803
1889
|
throw new ParseError("\u3053\u306E\u69CB\u6587\u306B\u306F -- @ksql dialect: 1 \u306E\u5BA3\u8A00\u304C\u5FC5\u8981\u3067\u3059", tok);
|
|
1804
1890
|
}
|
|
1805
1891
|
}
|
|
1892
|
+
/** VARIABLE + `()` is the dialect-1 as-of call syntax; a bare VARIABLE stays unchanged. */
|
|
1893
|
+
finishVariableReference(tok) {
|
|
1894
|
+
const ordinary = { type: "VARIABLE", name: tok.value.slice(1).toLowerCase() };
|
|
1895
|
+
if (this.peek().kind !== "(" /* LPAREN */) return ordinary;
|
|
1896
|
+
if (!this.capabilities.dialect1) return ordinary;
|
|
1897
|
+
const name = tok.value.slice(1).toUpperCase();
|
|
1898
|
+
if (!isAsOfFunctionName(name)) {
|
|
1899
|
+
throw new ParseError(
|
|
1900
|
+
`\u4F7F\u7528\u53EF\u80FD\u306A as-of \u95A2\u6570\u306F ${AS_OF_FUNCTION_NAMES.map((item) => `@${item}`).join("/")} \u3067\u3059`,
|
|
1901
|
+
tok
|
|
1902
|
+
);
|
|
1903
|
+
}
|
|
1904
|
+
this.advance();
|
|
1905
|
+
this.expect(")" /* RPAREN */, `@${name} \u306F\u5F15\u6570\u306A\u3057\u306E () \u3067\u547C\u3073\u51FA\u3057\u3066\u304F\u3060\u3055\u3044`);
|
|
1906
|
+
return { type: "VARIABLE", name: asOfVariableName(name) };
|
|
1907
|
+
}
|
|
1806
1908
|
/** ASSERT のオペランド: 文字列 / スカラーサブクエリ / 数値算術式 */
|
|
1807
1909
|
parseAssertOperand() {
|
|
1808
1910
|
const tok = this.peek();
|
|
1809
1911
|
if (tok.kind === "VARIABLE" /* VARIABLE */) {
|
|
1810
1912
|
this.advance();
|
|
1811
|
-
return
|
|
1913
|
+
return this.finishVariableReference(tok);
|
|
1812
1914
|
}
|
|
1813
1915
|
if (tok.kind === "STRING" /* STRING */) {
|
|
1814
1916
|
this.advance();
|
|
@@ -2182,7 +2284,7 @@ var Parser = class {
|
|
|
2182
2284
|
}
|
|
2183
2285
|
if (tok.kind === "VARIABLE" /* VARIABLE */) {
|
|
2184
2286
|
this.advance();
|
|
2185
|
-
args.push(
|
|
2287
|
+
args.push(this.finishVariableReference(tok));
|
|
2186
2288
|
continue;
|
|
2187
2289
|
}
|
|
2188
2290
|
let sign = "";
|
|
@@ -2267,15 +2369,21 @@ var Parser = class {
|
|
|
2267
2369
|
return this.withAliasDisplay({ type: "SCALAR_VALUE_COL", expr, alias: parsedAlias2?.alias ?? null }, parsedAlias2);
|
|
2268
2370
|
}
|
|
2269
2371
|
if (this.peek().kind === "VARIABLE" /* VARIABLE */) {
|
|
2270
|
-
const variable = this.advance();
|
|
2271
|
-
|
|
2272
|
-
|
|
2372
|
+
const variable = this.finishVariableReference(this.advance());
|
|
2373
|
+
const asOfFunction = asOfFunctionNameFromVariable(variable.name);
|
|
2374
|
+
let parsedAlias2 = null;
|
|
2375
|
+
if (asOfFunction === null) {
|
|
2376
|
+
if (!this.consume("AS" /* AS */)) {
|
|
2377
|
+
throw new ParseError("SELECT \u5217\u306E\u30D0\u30C3\u30C1\u5909\u6570\u306B\u306F AS alias \u304C\u5FC5\u8981\u3067\u3059", this.peek());
|
|
2378
|
+
}
|
|
2379
|
+
parsedAlias2 = this.parseAliasName();
|
|
2380
|
+
} else if (this.consume("AS" /* AS */)) {
|
|
2381
|
+
parsedAlias2 = this.parseAliasName();
|
|
2273
2382
|
}
|
|
2274
|
-
const parsedAlias2 = this.parseAliasName();
|
|
2275
2383
|
return this.withAliasDisplay({
|
|
2276
2384
|
type: "VARIABLE_COL",
|
|
2277
|
-
name: variable.
|
|
2278
|
-
alias: parsedAlias2
|
|
2385
|
+
name: variable.name,
|
|
2386
|
+
alias: parsedAlias2?.alias ?? null
|
|
2279
2387
|
}, parsedAlias2);
|
|
2280
2388
|
}
|
|
2281
2389
|
const windowFunc = this.tryWindowFunc();
|
|
@@ -2611,7 +2719,7 @@ var Parser = class {
|
|
|
2611
2719
|
}
|
|
2612
2720
|
if (this.peek().kind === "VARIABLE" /* VARIABLE */) {
|
|
2613
2721
|
const tok = this.advance();
|
|
2614
|
-
return
|
|
2722
|
+
return this.finishVariableReference(tok);
|
|
2615
2723
|
}
|
|
2616
2724
|
const aggFunc = this.tryAggregateFunc();
|
|
2617
2725
|
if (aggFunc !== null) {
|
|
@@ -2771,7 +2879,7 @@ var Parser = class {
|
|
|
2771
2879
|
}
|
|
2772
2880
|
if (tok.kind === "VARIABLE" /* VARIABLE */) {
|
|
2773
2881
|
this.advance();
|
|
2774
|
-
return
|
|
2882
|
+
return this.finishVariableReference(tok);
|
|
2775
2883
|
}
|
|
2776
2884
|
if (tok.kind === "CASE" /* CASE */) {
|
|
2777
2885
|
if (!allowCase) throw new ParseError("\u3053\u306E\u30B9\u30AB\u30E9\u30FC\u5024\u5F0F\u3067\u306F CASE \u3092\u4F7F\u7528\u3067\u304D\u307E\u305B\u3093", tok);
|
|
@@ -2871,7 +2979,7 @@ var Parser = class {
|
|
|
2871
2979
|
}
|
|
2872
2980
|
if (this.allowSelectArithVariable && tok.kind === "VARIABLE" /* VARIABLE */) {
|
|
2873
2981
|
this.advance();
|
|
2874
|
-
return
|
|
2982
|
+
return this.finishVariableReference(tok);
|
|
2875
2983
|
}
|
|
2876
2984
|
if (tok.kind === "IDENT" /* IDENT */ || tok.kind === "BIDENT" /* BIDENT */) {
|
|
2877
2985
|
this.advance();
|
|
@@ -3479,7 +3587,7 @@ var Parser = class {
|
|
|
3479
3587
|
}
|
|
3480
3588
|
if (tok.kind === "VARIABLE" /* VARIABLE */) {
|
|
3481
3589
|
this.advance();
|
|
3482
|
-
return
|
|
3590
|
+
return this.finishVariableReference(tok);
|
|
3483
3591
|
}
|
|
3484
3592
|
throw new ParseError(
|
|
3485
3593
|
"KLIKE / NOT KLIKE \u306E\u53F3\u8FBA\u306B\u306F\u6587\u5B57\u5217\u30EA\u30C6\u30E9\u30EB\u307E\u305F\u306F\u30D0\u30C3\u30C1\u5909\u6570\u304C\u5FC5\u8981\u3067\u3059",
|
|
@@ -3672,7 +3780,7 @@ var Parser = class {
|
|
|
3672
3780
|
const tok = this.peek();
|
|
3673
3781
|
if (tok.kind === "VARIABLE" /* VARIABLE */) {
|
|
3674
3782
|
this.advance();
|
|
3675
|
-
return
|
|
3783
|
+
return this.finishVariableReference(tok);
|
|
3676
3784
|
}
|
|
3677
3785
|
if (tok.kind === "STRING" /* STRING */) {
|
|
3678
3786
|
this.advance();
|
|
@@ -3728,6 +3836,9 @@ var Parser = class {
|
|
|
3728
3836
|
"VARIABLE" /* VARIABLE */,
|
|
3729
3837
|
"IN / NOT IN \u306E\u5F8C\u306B\u306F (\u5024\u30EA\u30B9\u30C8\u307E\u305F\u306F SELECT) \u304B\u914D\u5217\u5909\u6570\u304C\u5FC5\u8981\u3067\u3059"
|
|
3730
3838
|
);
|
|
3839
|
+
if (this.peek().kind === "(" /* LPAREN */ && this.capabilities.dialect1) {
|
|
3840
|
+
return { type: "IN_LIST", values: [this.finishVariableReference(variable)] };
|
|
3841
|
+
}
|
|
3731
3842
|
return { type: "VARIABLE_IN_LIST", name: variable.value.slice(1).toLowerCase() };
|
|
3732
3843
|
}
|
|
3733
3844
|
parseInListOrSubquery() {
|
|
@@ -3759,7 +3870,7 @@ var Parser = class {
|
|
|
3759
3870
|
const sign = tok.kind === "-" /* MINUS */ ? "-" : "+";
|
|
3760
3871
|
values.push(makeNumberLiteral(`${sign}${number.value}`));
|
|
3761
3872
|
} else if (tok.kind === "VARIABLE" /* VARIABLE */) {
|
|
3762
|
-
values.push(
|
|
3873
|
+
values.push(this.finishVariableReference(tok));
|
|
3763
3874
|
} else if (tok.kind === "LOGINUSER" /* LOGINUSER */) {
|
|
3764
3875
|
if (values.length > 0) {
|
|
3765
3876
|
throw new ParseError(mixedLoginUserMessage, tok);
|
|
@@ -9282,6 +9393,7 @@ function collectVariableRefs(node, refs, inWhere = false) {
|
|
|
9282
9393
|
const obj = node;
|
|
9283
9394
|
const type = obj["type"];
|
|
9284
9395
|
if ((type === "VARIABLE" || type === "VARIABLE_COL" || type === "VARIABLE_IN_LIST") && typeof obj["name"] === "string") {
|
|
9396
|
+
if (asOfFunctionNameFromVariable(obj["name"]) !== null) return;
|
|
9285
9397
|
refs.push({
|
|
9286
9398
|
name: obj["name"],
|
|
9287
9399
|
kind: type === "VARIABLE" ? "scalar" : type === "VARIABLE_COL" ? "select-column" : "array-in-list",
|
|
@@ -16465,7 +16577,14 @@ var DiagnosticCodes = {
|
|
|
16465
16577
|
HEADER_INVALID_DIALECT: "KSQL1006",
|
|
16466
16578
|
LOGICAL_APP_UNRESOLVED: "KSQL1101",
|
|
16467
16579
|
LEX_ERROR: "KSQL1201",
|
|
16468
|
-
PARSE_ERROR: "KSQL1202"
|
|
16580
|
+
PARSE_ERROR: "KSQL1202",
|
|
16581
|
+
DIALECT1_REQUIRED: "KSQL1203",
|
|
16582
|
+
UPDATE_KEY_COMPOSITE: "KSQL1301",
|
|
16583
|
+
UPDATE_KEY_FIELD_TYPE: "KSQL1302",
|
|
16584
|
+
UPDATE_KEY_NOT_UNIQUE: "KSQL1303",
|
|
16585
|
+
SUBTABLE_DML_FORBIDDEN: "KSQL1304",
|
|
16586
|
+
BARE_INSERT_NOT_IDEMPOTENT: "KSQL1305",
|
|
16587
|
+
SERVER_TIME_FUNCTION_NOT_AS_OF: "KSQL1306"
|
|
16469
16588
|
};
|
|
16470
16589
|
function sourceLocationAt(source, offset) {
|
|
16471
16590
|
const target = Math.max(0, Math.min(offset, source.length));
|
|
@@ -16596,6 +16715,86 @@ function findLineEnd(source, start) {
|
|
|
16596
16715
|
return { contentEnd, next: i };
|
|
16597
16716
|
}
|
|
16598
16717
|
|
|
16718
|
+
// src/core/sql.ts
|
|
16719
|
+
function parseSqlStatements(sql, capabilities = {}) {
|
|
16720
|
+
const tokens = new Lexer(sql).tokenize();
|
|
16721
|
+
const statements = new Parser(tokens, capabilities).parseStatements();
|
|
16722
|
+
statements.forEach(validateStatementStatic);
|
|
16723
|
+
return statements;
|
|
16724
|
+
}
|
|
16725
|
+
function parseSqlStatementsForScript(sql, capabilities = {}) {
|
|
16726
|
+
const header = parseScriptHeader(sql);
|
|
16727
|
+
const headerError = header.diagnostics.find((diagnostic2) => diagnostic2.severity === "error");
|
|
16728
|
+
if (header.hasDirectives && headerError) {
|
|
16729
|
+
throw new Error(`${headerError.code}: ${headerError.message} (${headerError.line}:${headerError.column})`);
|
|
16730
|
+
}
|
|
16731
|
+
const scriptSql = header.hasDirectives ? sql.slice(header.headerEnd) : sql;
|
|
16732
|
+
const scriptCapabilities = header.hasDirectives ? { ...capabilities, dialect1: header.meta.dialect === 1 } : capabilities;
|
|
16733
|
+
return {
|
|
16734
|
+
statements: parseSqlStatements(scriptSql, scriptCapabilities),
|
|
16735
|
+
meta: header.meta
|
|
16736
|
+
};
|
|
16737
|
+
}
|
|
16738
|
+
|
|
16739
|
+
// src/core/dialect1Validation.ts
|
|
16740
|
+
var DIALECT1_SERVER_TIME_FUNCTION_WARNING = "bare \u306E\u6642\u523B\u4F9D\u5B58\u95A2\u6570\u306F kintone \u30B5\u30FC\u30D0\u30FC\u8A55\u4FA1\u306E\u305F\u3081 as-of \u306E\u5BFE\u8C61\u5916\u3067\u3059\u3002\u518D\u73FE\u6027\u304C\u5FC5\u8981\u306A\u3089 @ \u4ED8\u304D\u95A2\u6570\u3092\u4F7F\u7528\u3057\u3066\u304F\u3060\u3055\u3044\u3002";
|
|
16741
|
+
function validateDialect1UpdateKey(statement, fieldInfos) {
|
|
16742
|
+
if (fieldInfos === void 0) {
|
|
16743
|
+
return statement.keyFields.length === 1 ? [] : [{
|
|
16744
|
+
code: DiagnosticCodes.UPDATE_KEY_COMPOSITE,
|
|
16745
|
+
severity: "error",
|
|
16746
|
+
message: "dialect 1 \u306E UPSERT / MERGE \u306E\u30AD\u30FC\u306F\u5358\u4E00\u30D5\u30A3\u30FC\u30EB\u30C9\u3067\u3042\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059\u3002\u8907\u5408\u30AD\u30FC\u306E\u4EE3\u308F\u308A\u306B\u3001\u9023\u7D50\u30AD\u30FC\u30D5\u30A3\u30FC\u30EB\u30C9\uFF08\u4F8B: \u9867\u5BA2\u30B3\u30FC\u30C9_\u5E74\u6708\uFF09\u3092\u30A2\u30D7\u30EA\u5074\u306B\u7528\u610F\u3057\u3066\u304F\u3060\u3055\u3044\u3002"
|
|
16747
|
+
}];
|
|
16748
|
+
}
|
|
16749
|
+
if (statement.keyFields.length !== 1) return [];
|
|
16750
|
+
const key = statement.keyFields[0];
|
|
16751
|
+
const field = fieldInfos.find((candidate) => candidate.code === key);
|
|
16752
|
+
const issues = [];
|
|
16753
|
+
if (field === void 0 || field.fieldType !== "SINGLE_LINE_TEXT" && field.fieldType !== "NUMBER") {
|
|
16754
|
+
issues.push({
|
|
16755
|
+
code: DiagnosticCodes.UPDATE_KEY_FIELD_TYPE,
|
|
16756
|
+
severity: "error",
|
|
16757
|
+
message: field === void 0 ? `UPSERT / MERGE \u306E\u30AD\u30FC\u300C${key}\u300D\u304C APP${statement.appId} \u306E\u30D5\u30A9\u30FC\u30E0\u306B\u5B58\u5728\u3057\u307E\u305B\u3093\u3002\u91CD\u8907\u7981\u6B62\u3092\u8A2D\u5B9A\u3057\u305F\u6587\u5B57\u5217\uFF081\u884C\uFF09\u307E\u305F\u306F\u6570\u5024\u30D5\u30A3\u30FC\u30EB\u30C9\u3092\u30AD\u30FC\u306B\u3057\u3066\u304F\u3060\u3055\u3044\u3002` : `UPSERT / MERGE \u306E\u30AD\u30FC\u300C${key}\u300D\u306E\u578B ${field.fieldType} \u306F\u4F7F\u7528\u3067\u304D\u307E\u305B\u3093\u3002\u91CD\u8907\u7981\u6B62\u3092\u8A2D\u5B9A\u3057\u305F\u6587\u5B57\u5217\uFF081\u884C\uFF09\u307E\u305F\u306F\u6570\u5024\u30D5\u30A3\u30FC\u30EB\u30C9\u3092\u30AD\u30FC\u306B\u3057\u3066\u304F\u3060\u3055\u3044\u3002`
|
|
16758
|
+
});
|
|
16759
|
+
}
|
|
16760
|
+
if (field?.isUnique === false) {
|
|
16761
|
+
issues.push({
|
|
16762
|
+
code: DiagnosticCodes.UPDATE_KEY_NOT_UNIQUE,
|
|
16763
|
+
severity: "error",
|
|
16764
|
+
message: `UPSERT / MERGE \u306E\u30AD\u30FC\u300C${key}\u300D\u306F\u91CD\u8907\u7981\u6B62\u3067\u306F\u3042\u308A\u307E\u305B\u3093\u3002\u30A2\u30D7\u30EA\u306E\u30D5\u30A3\u30FC\u30EB\u30C9\u8A2D\u5B9A\u3067\u300C\u5024\u306E\u91CD\u8907\u3092\u7981\u6B62\u3059\u308B\u300D\u3092\u6709\u52B9\u306B\u3057\u3066\u304F\u3060\u3055\u3044\u3002`
|
|
16765
|
+
});
|
|
16766
|
+
} else if (field !== void 0 && field.isUnique === void 0) {
|
|
16767
|
+
issues.push({
|
|
16768
|
+
code: DiagnosticCodes.UPDATE_KEY_NOT_UNIQUE,
|
|
16769
|
+
severity: "warning",
|
|
16770
|
+
message: `UPSERT / MERGE \u306E\u30AD\u30FC\u300C${key}\u300D\u306E\u91CD\u8907\u7981\u6B62\u8A2D\u5B9A\u3092 schema resolver \u304B\u3089\u78BA\u8A8D\u3067\u304D\u307E\u305B\u3093\u3002isUnique \u3092\u8FD4\u3059 resolver \u3092\u4F7F\u7528\u3057\u3001\u30A2\u30D7\u30EA\u5074\u3067\u300C\u5024\u306E\u91CD\u8907\u3092\u7981\u6B62\u3059\u308B\u300D\u304C\u6709\u52B9\u304B\u78BA\u8A8D\u3057\u3066\u304F\u3060\u3055\u3044\u3002`
|
|
16771
|
+
});
|
|
16772
|
+
}
|
|
16773
|
+
return issues;
|
|
16774
|
+
}
|
|
16775
|
+
function statementHasBareServerTimeFunctionInWhere(statement) {
|
|
16776
|
+
let found = false;
|
|
16777
|
+
const visit = (node) => {
|
|
16778
|
+
if (found || node === null || typeof node !== "object") return;
|
|
16779
|
+
if (Array.isArray(node)) {
|
|
16780
|
+
node.forEach(visit);
|
|
16781
|
+
return;
|
|
16782
|
+
}
|
|
16783
|
+
const value = node;
|
|
16784
|
+
const where = value["where"];
|
|
16785
|
+
if (where !== null && typeof where === "object") {
|
|
16786
|
+
const names = serverOnlyFunctionOccurrencesInWhere(where);
|
|
16787
|
+
if (names.some((name) => name === "TODAY" || name === "NOW" || isRelativeDateFunctionName(name))) {
|
|
16788
|
+
found = true;
|
|
16789
|
+
return;
|
|
16790
|
+
}
|
|
16791
|
+
}
|
|
16792
|
+
Object.values(value).forEach(visit);
|
|
16793
|
+
};
|
|
16794
|
+
visit(statement);
|
|
16795
|
+
return found;
|
|
16796
|
+
}
|
|
16797
|
+
|
|
16599
16798
|
// src/core/dmlPrevalidation.ts
|
|
16600
16799
|
function collectDmlPrevalidationSnapshotFields(fieldIndex) {
|
|
16601
16800
|
return [
|
|
@@ -18526,7 +18725,7 @@ async function executeParsedStatement(stmt, client, options, cacheContext) {
|
|
|
18526
18725
|
if (stmt.type !== "EXPLAIN") assertRelativeDatePushdownPlan(relativeDatePlan);
|
|
18527
18726
|
const unresolved = findVariableRef(stmt);
|
|
18528
18727
|
if (unresolved !== null && !isApplyParentKlikeStatement(stmt)) {
|
|
18529
|
-
throw new Error(
|
|
18728
|
+
throw new Error(undefinedBatchVariableMessage(unresolved, "in a batch"));
|
|
18530
18729
|
}
|
|
18531
18730
|
assertApplyScope("phase15b", stmt);
|
|
18532
18731
|
assertApplyExecutionScope("phase15b", stmt);
|
|
@@ -18885,17 +19084,10 @@ var BatchTimeoutError = class extends Error {
|
|
|
18885
19084
|
}
|
|
18886
19085
|
};
|
|
18887
19086
|
async function executeBatch(sql, client, options = {}) {
|
|
19087
|
+
const asOfClock = createAsOfClock(options.asOf ?? /* @__PURE__ */ new Date(), options.timezone);
|
|
18888
19088
|
resolveRecursiveCteLimits(options);
|
|
18889
|
-
const
|
|
18890
|
-
const
|
|
18891
|
-
if (header.hasDirectives && headerError) {
|
|
18892
|
-
throw new Error(`${headerError.code}: ${headerError.message} (${headerError.line}:${headerError.column})`);
|
|
18893
|
-
}
|
|
18894
|
-
const statements = parseSqlBatch(
|
|
18895
|
-
header.hasDirectives ? sql.slice(header.headerEnd) : sql,
|
|
18896
|
-
options.enableImport === true,
|
|
18897
|
-
header.hasDirectives && header.meta.dialect === 1
|
|
18898
|
-
);
|
|
19089
|
+
const { statements, meta } = parseSqlStatementsForScript(sql, { import: options.enableImport === true });
|
|
19090
|
+
const dialect1Warnings = meta.dialect === 1 && statements.some(statementHasBareServerTimeFunctionInWhere) ? [DIALECT1_SERVER_TIME_FUNCTION_WARNING] : [];
|
|
18899
19091
|
const analysis = analyzeBatch(statements);
|
|
18900
19092
|
statements.forEach((statement) => assertApplyExecutionScope("phase15b", statement));
|
|
18901
19093
|
if (options.allowApplyMutation !== true && statements.some(
|
|
@@ -18929,6 +19121,9 @@ async function executeBatch(sql, client, options = {}) {
|
|
|
18929
19121
|
try {
|
|
18930
19122
|
const tempTables = /* @__PURE__ */ new Map();
|
|
18931
19123
|
const variables = /* @__PURE__ */ new Map();
|
|
19124
|
+
for (const [name, value] of Object.entries(asOfClock.values)) {
|
|
19125
|
+
variables.set(asOfVariableName(name), { type: "string", value });
|
|
19126
|
+
}
|
|
18932
19127
|
const results = [];
|
|
18933
19128
|
const failed = /* @__PURE__ */ new Set();
|
|
18934
19129
|
let aborted = null;
|
|
@@ -18985,7 +19180,8 @@ async function executeBatch(sql, client, options = {}) {
|
|
|
18985
19180
|
tempTables,
|
|
18986
19181
|
variables,
|
|
18987
19182
|
relativeDateVariables,
|
|
18988
|
-
clock: statementEvaluationContext(boundOptions)
|
|
19183
|
+
clock: statementEvaluationContext(boundOptions),
|
|
19184
|
+
dialect: meta.dialect
|
|
18989
19185
|
};
|
|
18990
19186
|
const outcome = await runWithDeadline(
|
|
18991
19187
|
executeBatchStatement(statementContext),
|
|
@@ -18994,6 +19190,9 @@ async function executeBatch(sql, client, options = {}) {
|
|
|
18994
19190
|
);
|
|
18995
19191
|
if (outcome.result) {
|
|
18996
19192
|
outcome.result = attachSearchAbortWarning(outcome.result, searchAbortCollector);
|
|
19193
|
+
if (dialect1Warnings.length > 0 && statementHasBareServerTimeFunctionInWhere(statements[i]) && outcome.result.type === "SELECT") {
|
|
19194
|
+
outcome.result = mergeSelectWarnings(outcome.result, dialect1Warnings);
|
|
19195
|
+
}
|
|
18997
19196
|
}
|
|
18998
19197
|
const { exitTriggered, ...statementOutcome } = outcome;
|
|
18999
19198
|
results.push({ ...base, status: "success", ...statementOutcome });
|
|
@@ -19023,7 +19222,8 @@ async function executeBatch(sql, client, options = {}) {
|
|
|
19023
19222
|
statementCount: statements.length,
|
|
19024
19223
|
statements: results,
|
|
19025
19224
|
analysis,
|
|
19026
|
-
metrics
|
|
19225
|
+
metrics,
|
|
19226
|
+
...dialect1Warnings.length > 0 ? { warnings: dialect1Warnings } : {}
|
|
19027
19227
|
};
|
|
19028
19228
|
} finally {
|
|
19029
19229
|
releaseMetadataCacheScope(cacheContext);
|
|
@@ -19045,7 +19245,8 @@ async function executeBatchStatement(context) {
|
|
|
19045
19245
|
tempTables,
|
|
19046
19246
|
variables,
|
|
19047
19247
|
relativeDateVariables,
|
|
19048
|
-
clock
|
|
19248
|
+
clock,
|
|
19249
|
+
dialect
|
|
19049
19250
|
} = context;
|
|
19050
19251
|
if (stmt.type === "SET_VARIABLE") {
|
|
19051
19252
|
const resolvedStmt2 = resolveBatchVariableReferences(stmt, variables);
|
|
@@ -19117,6 +19318,18 @@ async function executeBatchStatement(context) {
|
|
|
19117
19318
|
assertApplyScope("phase15b", resolvedStmt);
|
|
19118
19319
|
assertApplyExecutionScope("phase15b", resolvedStmt);
|
|
19119
19320
|
validateStatementStatic(resolvedStmt);
|
|
19321
|
+
if (dialect === 1 && (resolvedStmt.type === "INSERT" || resolvedStmt.type === "UPDATE" || resolvedStmt.type === "DELETE") && resolvedStmt.subtableCode) {
|
|
19322
|
+
throw new Error(
|
|
19323
|
+
"ArgumentError: dialect 1 \u3067\u306F\u30B5\u30D6\u30C6\u30FC\u30D6\u30EB\u4EEE\u60F3\u30C6\u30FC\u30D6\u30EB\u3078\u306E DML \u306F\u3067\u304D\u307E\u305B\u3093\u3002SELECT \u306F\u53EF\u80FD\u3067\u3059\u3002\u89AA\u30A2\u30D7\u30EA\u3092\u5BFE\u8C61\u306B\u3057\u3066\u304F\u3060\u3055\u3044\u3002"
|
|
19324
|
+
);
|
|
19325
|
+
}
|
|
19326
|
+
if (dialect === 1 && (resolvedStmt.type === "UPSERT" || resolvedStmt.type === "UPSERT_SELECT")) {
|
|
19327
|
+
const staticIssue = validateDialect1UpdateKey(resolvedStmt)[0];
|
|
19328
|
+
if (staticIssue) throw new Error(`ArgumentError: ${staticIssue.message}`);
|
|
19329
|
+
const fieldInfos = await getFieldsCached(resolvedStmt.appId, client, cacheContext);
|
|
19330
|
+
const schemaIssue = validateDialect1UpdateKey(resolvedStmt, fieldInfos)[0];
|
|
19331
|
+
if (schemaIssue) throw new Error(`ArgumentError: ${schemaIssue.message}`);
|
|
19332
|
+
}
|
|
19120
19333
|
await assertRelativeDateExecutionPlan(resolvedStmt, client, cacheContext);
|
|
19121
19334
|
if (resolvedStmt.type === "VALIDATE") {
|
|
19122
19335
|
const result = await executeExistingRecordValidationCore(
|
|
@@ -19377,11 +19590,16 @@ function evaluateScalarExpr(expr, evaluationContext = {}) {
|
|
|
19377
19590
|
}
|
|
19378
19591
|
return { type: "number", value, raw: String(value) };
|
|
19379
19592
|
}
|
|
19593
|
+
case "VARIABLE":
|
|
19594
|
+
throw new Error(`InternalError: unresolved variable @${expr.name} reached scalar evaluation.`);
|
|
19380
19595
|
}
|
|
19381
19596
|
}
|
|
19382
19597
|
function resolveBatchVariableReferences(node, variables) {
|
|
19383
19598
|
return resolveBatchVariableReferencesInternal(node, variables, false);
|
|
19384
19599
|
}
|
|
19600
|
+
function undefinedBatchVariableMessage(name, location2) {
|
|
19601
|
+
return asOfFunctionNameFromVariable(name) === null ? `ParseError: variable @${name} is not defined ${location2}.` : `ParseError: @NOW() \u306A\u3069\u306E as-of \u95A2\u6570\u306F\u57FA\u6E96\u6642\u523B\u304C\u521D\u671F\u5316\u3055\u308C\u3066\u3044\u307E\u305B\u3093\u3002`;
|
|
19602
|
+
}
|
|
19385
19603
|
function resolveBatchVariableReferencesInternal(node, variables, numericArithmeticOperand) {
|
|
19386
19604
|
if (Array.isArray(node)) {
|
|
19387
19605
|
return node.map((v) => resolveBatchVariableReferencesInternal(v, variables, false));
|
|
@@ -19391,7 +19609,7 @@ function resolveBatchVariableReferencesInternal(node, variables, numericArithmet
|
|
|
19391
19609
|
if (obj["type"] === "VARIABLE" && typeof obj["name"] === "string") {
|
|
19392
19610
|
const value = variables.get(obj["name"]);
|
|
19393
19611
|
if (value === void 0) {
|
|
19394
|
-
throw new Error(
|
|
19612
|
+
throw new Error(undefinedBatchVariableMessage(obj["name"], "in this batch"));
|
|
19395
19613
|
}
|
|
19396
19614
|
if (value.type === "array") {
|
|
19397
19615
|
throw new Error(`ParseError: array variable @${obj["name"]} can only be used as IN @${obj["name"]}.`);
|
|
@@ -19412,9 +19630,9 @@ function resolveBatchVariableReferencesInternal(node, variables, numericArithmet
|
|
|
19412
19630
|
raw: numericArithmeticOperand === "AGG_ARITH" ? `@${obj["name"]}` : value.raw ?? String(value.value)
|
|
19413
19631
|
} : { type: "STRING", value: value.value, fromVariable: true };
|
|
19414
19632
|
}
|
|
19415
|
-
if (obj["type"] === "VARIABLE_COL" && typeof obj["name"] === "string" && typeof obj["alias"] === "string") {
|
|
19633
|
+
if (obj["type"] === "VARIABLE_COL" && typeof obj["name"] === "string" && (typeof obj["alias"] === "string" || obj["alias"] === null)) {
|
|
19416
19634
|
const value = variables.get(obj["name"]);
|
|
19417
|
-
if (value === void 0) throw new Error(
|
|
19635
|
+
if (value === void 0) throw new Error(undefinedBatchVariableMessage(obj["name"], "in this batch"));
|
|
19418
19636
|
if (value.type === "array") throw new Error(`ParseError: array variable @${obj["name"]} cannot be used as a SELECT column.`);
|
|
19419
19637
|
if (value.type === "relative-date") {
|
|
19420
19638
|
throw new Error(`InternalError: RELATIVE_DATE variable @${obj["name"]} reached a SELECT column.`);
|
|
@@ -19440,7 +19658,7 @@ function resolveBatchVariableReferencesInternal(node, variables, numericArithmet
|
|
|
19440
19658
|
const right = resolved["right"];
|
|
19441
19659
|
if (right?.["type"] === "VARIABLE_IN_LIST" && typeof right["name"] === "string") {
|
|
19442
19660
|
const value = variables.get(right["name"]);
|
|
19443
|
-
if (value === void 0) throw new Error(
|
|
19661
|
+
if (value === void 0) throw new Error(undefinedBatchVariableMessage(right["name"], "in this batch"));
|
|
19444
19662
|
if (value.type !== "array") {
|
|
19445
19663
|
throw new Error(`ParseError: scalar variable @${right["name"]} cannot be used as IN @${right["name"]}; use IN (@${right["name"]}) instead.`);
|
|
19446
19664
|
}
|
|
@@ -26886,7 +27104,8 @@ var EXPLAIN_FETCH_PLAN = /* @__PURE__ */ Symbol("ksql.explainFetchPlan");
|
|
|
26886
27104
|
function setExplainFetchPlan(result, plan) {
|
|
26887
27105
|
result[EXPLAIN_FETCH_PLAN] = plan;
|
|
26888
27106
|
}
|
|
26889
|
-
async function buildBatchExplainPlans(sql, client, injectedVariables, cacheContext = "batch-explain", maxRecords = 1e4, cursorMaxActive = 2, enableImport = false, dmlMaxRows = 100, dmlMaxSubtableRows = DEFAULT_APPLY_MAX_SUBTABLE_ROWS, resolveMetadata = true, recursiveCteMaxDepth, recursiveCteMaxRows, recursiveCteMaxExpansions) {
|
|
27107
|
+
async function buildBatchExplainPlans(sql, client, injectedVariables, cacheContext = "batch-explain", maxRecords = 1e4, cursorMaxActive = 2, enableImport = false, dmlMaxRows = 100, dmlMaxSubtableRows = DEFAULT_APPLY_MAX_SUBTABLE_ROWS, resolveMetadata = true, recursiveCteMaxDepth, recursiveCteMaxRows, recursiveCteMaxExpansions, asOf, timezone) {
|
|
27108
|
+
const asOfClock = createAsOfClock(asOf ?? /* @__PURE__ */ new Date(), timezone);
|
|
26890
27109
|
const recursiveLimits = resolveRecursiveCteLimits({
|
|
26891
27110
|
recursiveCteMaxDepth,
|
|
26892
27111
|
recursiveCteMaxRows,
|
|
@@ -26894,20 +27113,14 @@ async function buildBatchExplainPlans(sql, client, injectedVariables, cacheConte
|
|
|
26894
27113
|
});
|
|
26895
27114
|
const invocationCacheContext = createInvocationCacheContext(cacheContext);
|
|
26896
27115
|
try {
|
|
26897
|
-
const
|
|
26898
|
-
const headerError = header.diagnostics.find((diagnostic2) => diagnostic2.severity === "error");
|
|
26899
|
-
if (header.hasDirectives && headerError) {
|
|
26900
|
-
throw new Error(`${headerError.code}: ${headerError.message} (${headerError.line}:${headerError.column})`);
|
|
26901
|
-
}
|
|
26902
|
-
const statements = parseSqlBatch(
|
|
26903
|
-
header.hasDirectives ? sql.slice(header.headerEnd) : sql,
|
|
26904
|
-
enableImport,
|
|
26905
|
-
header.hasDirectives && header.meta.dialect === 1
|
|
26906
|
-
);
|
|
27116
|
+
const { statements, meta } = parseSqlStatementsForScript(sql, { import: enableImport });
|
|
26907
27117
|
const analysis = analyzeBatch(statements);
|
|
26908
27118
|
const normalizedInjectedVariables = validateDeclaredBatchVariables(statements, injectedVariables);
|
|
26909
27119
|
const relativeDateVariables = prepareRelativeDateVariables(statements, normalizedInjectedVariables);
|
|
26910
27120
|
const variables = /* @__PURE__ */ new Map();
|
|
27121
|
+
for (const [name, value] of Object.entries(asOfClock.values)) {
|
|
27122
|
+
variables.set(asOfVariableName(name), { type: "string", value });
|
|
27123
|
+
}
|
|
26911
27124
|
const literalDeclareDefaults = /* @__PURE__ */ new Map();
|
|
26912
27125
|
const tempSchemaLedger = /* @__PURE__ */ new Map();
|
|
26913
27126
|
const plans = [];
|
|
@@ -26984,10 +27197,16 @@ async function buildBatchExplainPlans(sql, client, injectedVariables, cacheConte
|
|
|
26984
27197
|
), cursorMaxActive)
|
|
26985
27198
|
];
|
|
26986
27199
|
const metadataPlan = explainMetadataLines(whereAnalysis);
|
|
27200
|
+
const dialect1Estimate = meta.dialect === 1 ? buildDialect1ApiEstimateLines(
|
|
27201
|
+
planStmt,
|
|
27202
|
+
analysis.statements[i],
|
|
27203
|
+
maxRecords,
|
|
27204
|
+
dmlMaxRows
|
|
27205
|
+
) : [];
|
|
26987
27206
|
plans.push({
|
|
26988
27207
|
index: i,
|
|
26989
27208
|
type: analysis.statements[i].statementType,
|
|
26990
|
-
plan: statementPlan.length === 0 ? metadataPlan : [statementPlan[0], ...metadataPlan, ...statementPlan.slice(1)]
|
|
27209
|
+
plan: statementPlan.length === 0 ? [...metadataPlan, ...dialect1Estimate] : [statementPlan[0], ...metadataPlan, ...statementPlan.slice(1), ...dialect1Estimate]
|
|
26991
27210
|
});
|
|
26992
27211
|
fetchStatements.push({
|
|
26993
27212
|
index: i,
|
|
@@ -27012,6 +27231,63 @@ async function buildBatchExplainPlans(sql, client, injectedVariables, cacheConte
|
|
|
27012
27231
|
releaseMetadataCacheScope(invocationCacheContext);
|
|
27013
27232
|
}
|
|
27014
27233
|
}
|
|
27234
|
+
function buildDialect1ApiEstimateLines(statement, analysis, maxRecords, dmlMaxRows) {
|
|
27235
|
+
const lines = [" estimated API consumption (dialect 1):"];
|
|
27236
|
+
const sources = collectPhysicalExplainSources(statement);
|
|
27237
|
+
if ((statement.type === "UPDATE" || statement.type === "DELETE") && !sources.includes(`APP${statement.appId}`)) {
|
|
27238
|
+
sources.unshift(`APP${statement.appId}`);
|
|
27239
|
+
}
|
|
27240
|
+
const maxReadRequests = Math.ceil(maxRecords / 500);
|
|
27241
|
+
for (const source of sources) {
|
|
27242
|
+
lines.push(
|
|
27243
|
+
` read ${source}: \u4E0D\u660E\uFF08\u4E0A\u9650 maxRecords=${maxRecords} \u3068\u4EEE\u5B9A: \u6700\u5927 ${maxReadRequests} \u56DE\u3001500 \u4EF6/\u56DE\uFF09`
|
|
27244
|
+
);
|
|
27245
|
+
}
|
|
27246
|
+
const metadataApps = [.../* @__PURE__ */ new Set([
|
|
27247
|
+
...analysis.appIds,
|
|
27248
|
+
...analysis.targetAppId === null ? [] : [analysis.targetAppId]
|
|
27249
|
+
])];
|
|
27250
|
+
lines.push(
|
|
27251
|
+
` metadata: GET form fields \xD7 ${metadataApps.length} \u30A2\u30D7\u30EA\uFF08\u30AD\u30E3\u30C3\u30B7\u30E5\u6E08\u307F\u306F\u8FFD\u52A0 0 \u56DE\uFF09`
|
|
27252
|
+
);
|
|
27253
|
+
if (statement.type === "UPSERT" || statement.type === "UPSERT_SELECT") {
|
|
27254
|
+
if (statement.type === "UPSERT") {
|
|
27255
|
+
lines.push(
|
|
27256
|
+
` UPSERT pre-read: ${Math.ceil(statement.values.length / UPSERT_IN_CHUNK_SIZE)} \u56DE\uFF08${statement.values.length} \u884C\u3001${UPSERT_IN_CHUNK_SIZE} \u30AD\u30FC/\u56DE\uFF09`
|
|
27257
|
+
);
|
|
27258
|
+
} else {
|
|
27259
|
+
lines.push(
|
|
27260
|
+
` UPSERT pre-read: \u4E0D\u660E\uFF08\u4E0A\u9650 dmlMaxRows=${dmlMaxRows} \u3068\u4EEE\u5B9A: \u6700\u5927 ${Math.ceil(dmlMaxRows / UPSERT_IN_CHUNK_SIZE)} \u56DE\u3001${UPSERT_IN_CHUNK_SIZE} \u30AD\u30FC/\u56DE\uFF09`
|
|
27261
|
+
);
|
|
27262
|
+
}
|
|
27263
|
+
}
|
|
27264
|
+
const knownRows = statement.type === "INSERT" || statement.type === "UPSERT" ? statement.values.length : null;
|
|
27265
|
+
if (statement.type === "INSERT" || statement.type === "INSERT_SELECT" || statement.type === "UPSERT" || statement.type === "UPSERT_SELECT" || statement.type === "UPDATE" || statement.type === "DELETE") {
|
|
27266
|
+
lines.push(knownRows === null ? ` write: \u4E0D\u660E\uFF08\u4E0A\u9650 dmlMaxRows=${dmlMaxRows} \u3068\u4EEE\u5B9A: \u6700\u5927 ${Math.ceil(dmlMaxRows / 100)} \u56DE\u3001100 \u4EF6/HTTP \u30EA\u30AF\u30A8\u30B9\u30C8\uFF09` : ` write: ${Math.ceil(knownRows / 100)} \u56DE\uFF08${knownRows} \u884C\u3001100 \u4EF6/HTTP \u30EA\u30AF\u30A8\u30B9\u30C8\uFF09`);
|
|
27267
|
+
lines.push(" reference: bulkRequest \u306F\u672A\u5B9F\u88C5\u3002\u66F8\u8FBC\u30B5\u30D6\u30EA\u30AF\u30A8\u30B9\u30C8\u6570\u306F HTTP \u66F8\u8FBC\u56DE\u6570\u3068\u540C\u3058");
|
|
27268
|
+
}
|
|
27269
|
+
return lines;
|
|
27270
|
+
}
|
|
27271
|
+
function collectPhysicalExplainSources(statement) {
|
|
27272
|
+
const sources = [];
|
|
27273
|
+
const visit = (node) => {
|
|
27274
|
+
if (Array.isArray(node)) {
|
|
27275
|
+
node.forEach(visit);
|
|
27276
|
+
return;
|
|
27277
|
+
}
|
|
27278
|
+
if (node === null || typeof node !== "object") return;
|
|
27279
|
+
const value = node;
|
|
27280
|
+
if (typeof value["appId"] === "number" && Object.prototype.hasOwnProperty.call(value, "alias") && Object.prototype.hasOwnProperty.call(value, "cteName") && value["cteName"] === null && value["appId"] > 0) {
|
|
27281
|
+
const app = `APP${value["appId"]}`;
|
|
27282
|
+
const subtable = typeof value["subtableCode"] === "string" ? `$${value["subtableCode"]}` : "";
|
|
27283
|
+
const alias = typeof value["alias"] === "string" && value["alias"] !== app ? ` AS ${value["alias"]}` : "";
|
|
27284
|
+
sources.push(`${app}${subtable}${alias}`);
|
|
27285
|
+
}
|
|
27286
|
+
Object.values(value).forEach(visit);
|
|
27287
|
+
};
|
|
27288
|
+
visit(statement);
|
|
27289
|
+
return sources;
|
|
27290
|
+
}
|
|
27015
27291
|
function buildBatchStatementPlan(stmt, info, capabilities, orderPlans, plainGroupByPlans, dmlMaxRows = 100, dmlMaxSubtableRows = DEFAULT_APPLY_MAX_SUBTABLE_ROWS, collector = { sources: [] }, tempSchemaLedger = /* @__PURE__ */ new Map(), createdSchema, explainContext = defaultRecursiveExplainContext()) {
|
|
27016
27292
|
if (stmt.type === "CREATE_TEMP_TABLE") {
|
|
27017
27293
|
return [
|
|
@@ -28491,20 +28767,6 @@ var OperationCancelledError = class extends Error {
|
|
|
28491
28767
|
}
|
|
28492
28768
|
};
|
|
28493
28769
|
|
|
28494
|
-
// src/core/sql.ts
|
|
28495
|
-
function parseSqlStatement(sql, capabilities = {}) {
|
|
28496
|
-
const tokens = new Lexer(sql).tokenize();
|
|
28497
|
-
const stmt = new Parser(tokens, capabilities).parse();
|
|
28498
|
-
validateStatementStatic(stmt);
|
|
28499
|
-
return stmt;
|
|
28500
|
-
}
|
|
28501
|
-
function parseSqlStatements(sql, capabilities = {}) {
|
|
28502
|
-
const tokens = new Lexer(sql).tokenize();
|
|
28503
|
-
const statements = new Parser(tokens, capabilities).parseStatements();
|
|
28504
|
-
statements.forEach(validateStatementStatic);
|
|
28505
|
-
return statements;
|
|
28506
|
-
}
|
|
28507
|
-
|
|
28508
28770
|
// src/core/displayFormat.ts
|
|
28509
28771
|
var DATE_RE = /^\d{4}-\d{2}-\d{2}$/;
|
|
28510
28772
|
var DATETIME_RE = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}/;
|
|
@@ -30217,7 +30479,7 @@ function toParseInput(sql) {
|
|
|
30217
30479
|
}
|
|
30218
30480
|
function tryParseStatements(sql) {
|
|
30219
30481
|
try {
|
|
30220
|
-
const stmts =
|
|
30482
|
+
const { statements: stmts } = parseSqlStatementsForScript(toParseInput(sql));
|
|
30221
30483
|
return {
|
|
30222
30484
|
kind: "ok",
|
|
30223
30485
|
count: stmts.length,
|
|
@@ -30232,7 +30494,11 @@ function tryParseStatements(sql) {
|
|
|
30232
30494
|
if (e instanceof ParseError) {
|
|
30233
30495
|
return { kind: "fail", continuable: e.token.kind === "EOF" /* EOF */, message: e.message };
|
|
30234
30496
|
}
|
|
30235
|
-
|
|
30497
|
+
return {
|
|
30498
|
+
kind: "fail",
|
|
30499
|
+
continuable: false,
|
|
30500
|
+
message: e instanceof Error ? e.message : String(e)
|
|
30501
|
+
};
|
|
30236
30502
|
}
|
|
30237
30503
|
}
|
|
30238
30504
|
|
|
@@ -31421,7 +31687,7 @@ async function confirmDmlInConsole(sql, opts, queue, defaultProfile = "dev", res
|
|
|
31421
31687
|
if (!opts.allowDml || opts.yes || opts.dryRun) return true;
|
|
31422
31688
|
try {
|
|
31423
31689
|
const normalized = normalizeSqlAppProfiles(sql, defaultProfile, resolutionContext);
|
|
31424
|
-
const statements =
|
|
31690
|
+
const { statements } = parseSqlStatementsForScript(normalized.normalizedSql);
|
|
31425
31691
|
if (statements.length > 1) {
|
|
31426
31692
|
const analysis = analyzeBatch(statements);
|
|
31427
31693
|
if (!analysis.containsDml) return true;
|
|
@@ -31871,7 +32137,7 @@ async function run() {
|
|
|
31871
32137
|
}
|
|
31872
32138
|
const importEnabled = Object.keys(args.importCsv).length > 0 || Object.keys(args.importJson).length > 0;
|
|
31873
32139
|
try {
|
|
31874
|
-
const statements =
|
|
32140
|
+
const { statements } = parseSqlStatementsForScript(sql, { import: importEnabled });
|
|
31875
32141
|
parsedStatements = statements;
|
|
31876
32142
|
const hasApply = (statement) => statement.type === "UPDATE" || statement.type === "INSERT" ? (statement.applyBlocks?.length ?? 0) > 0 : statement.type === "UPSERT" ? (statement.onInsertApplyBlocks?.length ?? 0) > 0 || (statement.onUpdateApplyBlocks?.length ?? 0) > 0 : false;
|
|
31877
32143
|
containsApplyStatement = statements.some(hasApply);
|
|
@@ -31892,7 +32158,7 @@ async function run() {
|
|
|
31892
32158
|
isBatchSql = true;
|
|
31893
32159
|
batchContainsDml = batchAnalysis.containsDml;
|
|
31894
32160
|
} else {
|
|
31895
|
-
const stmt =
|
|
32161
|
+
const stmt = statements[0];
|
|
31896
32162
|
parsedStmt = stmt;
|
|
31897
32163
|
stmtType = getStatementType(stmt);
|
|
31898
32164
|
isDmlStatement = writesKintone(stmt);
|