@rex0220/kintone-sql-tools 2.6.0 → 2.8.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.
@@ -1811,7 +1811,7 @@ var require_code2 = __commonJS({
1811
1811
  }
1812
1812
  }
1813
1813
  exports2.validateArray = validateArray;
1814
- function validateUnion(cxt) {
1814
+ function validateUnion2(cxt) {
1815
1815
  const { gen, schema, keyword, it } = cxt;
1816
1816
  if (!Array.isArray(schema))
1817
1817
  throw new Error("ajv implementation error");
@@ -1833,7 +1833,7 @@ var require_code2 = __commonJS({
1833
1833
  }));
1834
1834
  cxt.result(valid, () => cxt.reset(), () => cxt.error(true));
1835
1835
  }
1836
- exports2.validateUnion = validateUnion;
1836
+ exports2.validateUnion = validateUnion2;
1837
1837
  }
1838
1838
  });
1839
1839
 
@@ -31007,6 +31007,7 @@ var KEYWORDS = /* @__PURE__ */ new Map([
31007
31007
  ["IS", "IS" /* IS */],
31008
31008
  ["NULL", "NULL" /* NULL */],
31009
31009
  ["LIKE", "LIKE" /* LIKE */],
31010
+ ["KLIKE", "KLIKE" /* KLIKE */],
31010
31011
  ["IN", "IN" /* IN */],
31011
31012
  ["BETWEEN", "BETWEEN" /* BETWEEN */],
31012
31013
  ["TODAY", "TODAY" /* TODAY */],
@@ -32532,7 +32533,7 @@ var Parser = class {
32532
32533
  }
32533
32534
  return false;
32534
32535
  }
32535
- // 比較演算子: =, !=, <>, >, <, >=, <=, LIKE, IN, IS NULL
32536
+ // 比較演算子: =, !=, <>, >, <, >=, <=, LIKE, KLIKE, IN, IS NULL
32536
32537
  parseCompareExpr() {
32537
32538
  if (this.peek().kind === "(" /* LPAREN */ && !this.isArithParen()) {
32538
32539
  this.advance();
@@ -32568,8 +32569,12 @@ var Parser = class {
32568
32569
  const pattern = this.parseSqlValue();
32569
32570
  return { type: "BINARY", op: "NOT_LIKE", left: field, right: pattern };
32570
32571
  }
32572
+ if (this.consume("KLIKE" /* KLIKE */)) {
32573
+ const pattern = this.parseKlikePattern();
32574
+ return { type: "BINARY", op: "NOT_KLIKE", left: field, right: pattern };
32575
+ }
32571
32576
  throw new ParseError(
32572
- "NOT \u306E\u5F8C\u306B\u306F IN \u307E\u305F\u306F LIKE \u304C\u5FC5\u8981\u3067\u3059",
32577
+ "NOT \u306E\u5F8C\u306B\u306F IN\u3001LIKE\u3001KLIKE \u306E\u3044\u305A\u308C\u304B\u304C\u5FC5\u8981\u3067\u3059",
32573
32578
  this.peek()
32574
32579
  );
32575
32580
  }
@@ -32579,6 +32584,10 @@ var Parser = class {
32579
32584
  this.expect(")" /* RPAREN */);
32580
32585
  return { type: "BINARY", op: "IN", left: field, right: right2 };
32581
32586
  }
32587
+ if (this.consume("KLIKE" /* KLIKE */)) {
32588
+ const pattern = this.parseKlikePattern();
32589
+ return { type: "BINARY", op: "KLIKE", left: field, right: pattern };
32590
+ }
32582
32591
  const op = this.parseCompareOp();
32583
32592
  const right = this.parseSqlValue();
32584
32593
  return { type: "BINARY", op, left: field, right };
@@ -32604,11 +32613,27 @@ var Parser = class {
32604
32613
  return "LIKE";
32605
32614
  default:
32606
32615
  throw new ParseError(
32607
- "\u6BD4\u8F03\u6F14\u7B97\u5B50\uFF08=, !=, >, <, >=, <=, LIKE, IN, IS\uFF09\u304C\u5FC5\u8981\u3067\u3059",
32616
+ "\u6BD4\u8F03\u6F14\u7B97\u5B50\uFF08=, !=, >, <, >=, <=, LIKE, KLIKE, IN, IS\uFF09\u304C\u5FC5\u8981\u3067\u3059",
32608
32617
  tok
32609
32618
  );
32610
32619
  }
32611
32620
  }
32621
+ /** KLIKE / NOT KLIKE の右辺。kintone キーワードは文字列値だけを受け付ける。 */
32622
+ parseKlikePattern() {
32623
+ const tok = this.peek();
32624
+ if (tok.kind === "STRING" /* STRING */) {
32625
+ this.advance();
32626
+ return { type: "STRING", value: tok.value };
32627
+ }
32628
+ if (tok.kind === "VARIABLE" /* VARIABLE */) {
32629
+ this.advance();
32630
+ return { type: "VARIABLE", name: tok.value.slice(1).toLowerCase() };
32631
+ }
32632
+ throw new ParseError(
32633
+ "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",
32634
+ tok
32635
+ );
32636
+ }
32612
32637
  // WHERE / HAVING の左辺
32613
32638
  // - 文字列・数値関数: UPPER(f) / LENGTH(f) / ROUND(f, 2) ...
32614
32639
  // - 集計関数(HAVING のみ): COUNT(*) / SUM(f) ...
@@ -33247,238 +33272,6 @@ function getInsertValuesCount(stmt) {
33247
33272
  return Array.isArray(obj.values) ? obj.values.length : null;
33248
33273
  }
33249
33274
 
33250
- // src/core/batch.ts
33251
- var MAX_TEMP_TABLES = 16;
33252
- var MAX_BATCH_VARIABLES = 64;
33253
- var BatchAnalysisError = class extends Error {
33254
- constructor(message, statementIndex) {
33255
- super(message);
33256
- this.statementIndex = statementIndex;
33257
- }
33258
- };
33259
- function collectRefs(node, tempRefs, appIds) {
33260
- if (Array.isArray(node)) {
33261
- for (const v of node) collectRefs(v, tempRefs, appIds);
33262
- return;
33263
- }
33264
- if (node !== null && typeof node === "object") {
33265
- const obj = node;
33266
- const cte = obj["cteName"];
33267
- if (typeof cte === "string" && cte.startsWith("#")) tempRefs.add(cte);
33268
- const appId = obj["appId"];
33269
- if (typeof appId === "number" && appId > 0) appIds.add(appId);
33270
- for (const v of Object.values(obj)) collectRefs(v, tempRefs, appIds);
33271
- }
33272
- }
33273
- function collectVariableRefs(node, refs) {
33274
- if (Array.isArray(node)) {
33275
- for (const v of node) collectVariableRefs(v, refs);
33276
- return;
33277
- }
33278
- if (node !== null && typeof node === "object") {
33279
- const obj = node;
33280
- if (obj["type"] === "VARIABLE" && typeof obj["name"] === "string") {
33281
- refs.add(obj["name"]);
33282
- return;
33283
- }
33284
- for (const v of Object.values(obj)) collectVariableRefs(v, refs);
33285
- }
33286
- }
33287
- function analyzeBatch(statements) {
33288
- if (statements.length === 0) {
33289
- throw new BatchAnalysisError("ArgumentError: SQL is empty.", 0);
33290
- }
33291
- if (statements.length === 1) {
33292
- const t = statements[0].type;
33293
- if (t === "SET_VARIABLE" || t === "DECLARE_VARIABLE") {
33294
- const verb = t === "SET_VARIABLE" ? "SET" : "DECLARE";
33295
- throw new BatchAnalysisError(`ArgumentError: ${verb} variable requires a batch.`, 0);
33296
- }
33297
- if (t === "CREATE_TEMP_TABLE" || t === "DROP_TEMP_TABLE") {
33298
- const verb = t === "CREATE_TEMP_TABLE" ? "CREATE TEMP TABLE" : "DROP TEMP TABLE";
33299
- throw new BatchAnalysisError(
33300
- `ArgumentError: ${verb} requires a batch (temp tables are batch-scoped).`,
33301
- 0
33302
- );
33303
- }
33304
- }
33305
- const defined = /* @__PURE__ */ new Map();
33306
- const createdOrder = [];
33307
- const results = [];
33308
- const variableDefs = /* @__PURE__ */ new Map();
33309
- const variableOrder = [];
33310
- statements.forEach((stmt, index) => {
33311
- const statementType = getStatementType(stmt);
33312
- const created = [];
33313
- const dropped = [];
33314
- const refs = /* @__PURE__ */ new Set();
33315
- const stmtAppIds = /* @__PURE__ */ new Set();
33316
- const dependsOn = /* @__PURE__ */ new Set();
33317
- const variableRefs = /* @__PURE__ */ new Set();
33318
- collectVariableRefs(stmt, variableRefs);
33319
- for (const name of variableRefs) {
33320
- const def = variableDefs.get(name);
33321
- if (def === void 0) {
33322
- throw new BatchAnalysisError(
33323
- `ParseError: variable @${name} is not defined before statement ${index + 1}.`,
33324
- index
33325
- );
33326
- }
33327
- def.referencedBy.push(index);
33328
- }
33329
- if (stmt.type === "SET_VARIABLE" || stmt.type === "DECLARE_VARIABLE") {
33330
- if (variableDefs.has(stmt.name)) {
33331
- throw new BatchAnalysisError(`ParseError: variable @${stmt.name} is already defined.`, index);
33332
- }
33333
- variableDefs.set(stmt.name, { index, referencedBy: [] });
33334
- variableOrder.push(stmt.name);
33335
- if (variableOrder.length > MAX_BATCH_VARIABLES) {
33336
- throw new BatchAnalysisError(
33337
- `ParseError: batch exceeds ${MAX_BATCH_VARIABLES} variables.`,
33338
- index
33339
- );
33340
- }
33341
- }
33342
- if (stmt.type === "CREATE_TEMP_TABLE") {
33343
- collectRefs(stmt.query, refs, stmtAppIds);
33344
- } else if (stmt.type === "DROP_TEMP_TABLE") {
33345
- } else {
33346
- collectRefs(stmt, refs, stmtAppIds);
33347
- }
33348
- let tempOnlySource = false;
33349
- if (stmt.type === "INSERT_SELECT" || stmt.type === "UPSERT_SELECT") {
33350
- const srcTemp = /* @__PURE__ */ new Set();
33351
- const srcApps = /* @__PURE__ */ new Set();
33352
- collectRefs(stmt.select, srcTemp, srcApps);
33353
- tempOnlySource = srcTemp.size > 0 && srcApps.size === 0;
33354
- }
33355
- for (const name of refs) {
33356
- const at = defined.get(name);
33357
- if (at === void 0) {
33358
- throw new BatchAnalysisError(
33359
- `ParseError: temp table ${name} is not defined in this batch.`,
33360
- index
33361
- );
33362
- }
33363
- dependsOn.add(at);
33364
- }
33365
- if (stmt.type === "CREATE_TEMP_TABLE") {
33366
- if (defined.has(stmt.name)) {
33367
- throw new BatchAnalysisError(
33368
- `ParseError: temp table ${stmt.name} is already defined.`,
33369
- index
33370
- );
33371
- }
33372
- defined.set(stmt.name, index);
33373
- createdOrder.push(stmt.name);
33374
- created.push(stmt.name);
33375
- if (defined.size > MAX_TEMP_TABLES) {
33376
- throw new BatchAnalysisError(
33377
- `ParseError: batch exceeds ${MAX_TEMP_TABLES} temp tables.`,
33378
- index
33379
- );
33380
- }
33381
- }
33382
- if (stmt.type === "DROP_TEMP_TABLE") {
33383
- const at = defined.get(stmt.name);
33384
- if (at === void 0) {
33385
- throw new BatchAnalysisError(
33386
- `ParseError: temp table ${stmt.name} is not defined in this batch.`,
33387
- index
33388
- );
33389
- }
33390
- dependsOn.add(at);
33391
- dropped.push(stmt.name);
33392
- defined.delete(stmt.name);
33393
- }
33394
- results.push({
33395
- index,
33396
- statementType,
33397
- isDml: isDmlType(statementType),
33398
- isReadOnly: isReadOnlyType(statementType),
33399
- hasWhere: hasWhereClause(stmt),
33400
- insertValuesCount: getInsertValuesCount(stmt),
33401
- appIds: [...stmtAppIds].sort((a, b) => a - b),
33402
- tempTablesCreated: created,
33403
- tempTablesReferenced: [...refs],
33404
- tempTablesDropped: dropped,
33405
- dependsOn: [...dependsOn].sort((a, b) => a - b),
33406
- tempOnlySource,
33407
- targetAppId: isDmlType(statementType) && typeof stmt.appId === "number" ? stmt.appId : null
33408
- });
33409
- });
33410
- const containsDml = results.some((r) => r.isDml);
33411
- const variables = variableOrder.map((name) => ({
33412
- name,
33413
- referencedBy: [...variableDefs.get(name).referencedBy]
33414
- }));
33415
- return {
33416
- statementCount: statements.length,
33417
- isReadOnlyBatch: !containsDml && results.every((r) => r.isReadOnly),
33418
- containsDml,
33419
- tempTables: createdOrder,
33420
- variables,
33421
- warnings: variables.filter((v) => v.referencedBy.length === 0).map((v) => `variable @${v.name} is never used.`),
33422
- statements: results
33423
- };
33424
- }
33425
-
33426
- // src/core/batchVariables.ts
33427
- var VARIABLE_NAME_RE = /^[A-Za-z_][A-Za-z0-9_]{0,63}$/;
33428
- function normalizeBatchVariableName(name) {
33429
- if (!VARIABLE_NAME_RE.test(name)) {
33430
- throw new Error(
33431
- `ArgumentError: invalid variable name "${name}". Use a name without @ matching [A-Za-z_][A-Za-z0-9_]{0,63}.`
33432
- );
33433
- }
33434
- return name.toLowerCase();
33435
- }
33436
- function normalizeBatchVariables(input) {
33437
- const normalized = /* @__PURE__ */ Object.create(null);
33438
- for (const [rawName, value] of Object.entries(input ?? {})) {
33439
- const name = normalizeBatchVariableName(rawName);
33440
- if (Object.prototype.hasOwnProperty.call(normalized, name)) {
33441
- throw new Error(`ArgumentError: variable "${rawName}" is specified more than once.`);
33442
- }
33443
- normalized[name] = value;
33444
- }
33445
- return normalized;
33446
- }
33447
- function validateDeclaredBatchVariables(statements, input) {
33448
- const normalized = normalizeBatchVariables(input);
33449
- const declared = new Set(
33450
- statements.filter((stmt) => stmt.type === "DECLARE_VARIABLE").map((stmt) => stmt.name)
33451
- );
33452
- for (const name of Object.keys(normalized)) {
33453
- if (!declared.has(name)) {
33454
- throw new Error(`ArgumentError: injected variable @${name} is not declared.`);
33455
- }
33456
- }
33457
- return normalized;
33458
- }
33459
-
33460
- // src/core/scalarCompare.ts
33461
- function compareScalarValues(op, leftStr, rightStr) {
33462
- if (op === "=") return leftStr === rightStr;
33463
- if (op === "!=" || op === "<>") return leftStr !== rightStr;
33464
- const rightNum = Number(rightStr);
33465
- if (leftStr === "" && rightStr !== "" && Number.isFinite(rightNum)) {
33466
- return op === "<" || op === "<=";
33467
- }
33468
- const leftNum = Number(leftStr);
33469
- const numeric = !Number.isNaN(leftNum) && !Number.isNaN(rightNum);
33470
- switch (op) {
33471
- case ">":
33472
- return numeric ? leftNum > rightNum : leftStr > rightStr;
33473
- case "<":
33474
- return numeric ? leftNum < rightNum : leftStr < rightStr;
33475
- case ">=":
33476
- return numeric ? leftNum >= rightNum : leftStr >= rightStr;
33477
- case "<=":
33478
- return numeric ? leftNum <= rightNum : leftStr <= rightStr;
33479
- }
33480
- }
33481
-
33482
33275
  // src/engine/pushDownNot.ts
33483
33276
  function pushDownNot(expr) {
33484
33277
  switch (expr.type) {
@@ -33528,6 +33321,10 @@ function negateOp(op) {
33528
33321
  return "NOT_LIKE";
33529
33322
  case "NOT_LIKE":
33530
33323
  return "LIKE";
33324
+ case "KLIKE":
33325
+ return "NOT_KLIKE";
33326
+ case "NOT_KLIKE":
33327
+ return "KLIKE";
33531
33328
  case "IN":
33532
33329
  return "NOT_IN";
33533
33330
  case "NOT_IN":
@@ -33542,6 +33339,9 @@ function likePatternHasWildcard(pattern) {
33542
33339
  function isLike(where) {
33543
33340
  return where.type === "BINARY" && (where.op === "LIKE" || where.op === "NOT_LIKE");
33544
33341
  }
33342
+ function isKlike(where) {
33343
+ return where.type === "BINARY" && (where.op === "KLIKE" || where.op === "NOT_KLIKE");
33344
+ }
33545
33345
  function whereHasLike(where) {
33546
33346
  if (where === null) return false;
33547
33347
  if (isLike(where)) return true;
@@ -33557,6 +33357,21 @@ function whereHasLike(where) {
33557
33357
  return false;
33558
33358
  }
33559
33359
  }
33360
+ function whereHasKlike(where) {
33361
+ if (where === null) return false;
33362
+ if (isKlike(where)) return true;
33363
+ switch (where.type) {
33364
+ case "LOGICAL":
33365
+ return whereHasKlike(where.left) || whereHasKlike(where.right);
33366
+ case "NOT":
33367
+ case "GROUP":
33368
+ return whereHasKlike(where.expr);
33369
+ case "BINARY":
33370
+ case "NULL_CHECK":
33371
+ case "EXISTS":
33372
+ return false;
33373
+ }
33374
+ }
33560
33375
 
33561
33376
  // src/converter/whereToKintone.ts
33562
33377
  function whereToKintone(expr) {
@@ -33605,6 +33420,10 @@ function convertOp(op) {
33605
33420
  return "like";
33606
33421
  case "NOT_LIKE":
33607
33422
  return "not like";
33423
+ case "KLIKE":
33424
+ return "like";
33425
+ case "NOT_KLIKE":
33426
+ return "not like";
33608
33427
  case "IN":
33609
33428
  return "in";
33610
33429
  case "NOT_IN":
@@ -34198,6 +34017,434 @@ function isAggregateSyntheticName(name) {
34198
34017
  return /^(COUNT|SUM|AVG|MAX|MIN)\(/i.test(name);
34199
34018
  }
34200
34019
 
34020
+ // src/core/klikeValidation.ts
34021
+ var KlikeValidationError = class extends Error {
34022
+ constructor(message) {
34023
+ super(`ArgumentError: ${message}`);
34024
+ this.name = "ArgumentError";
34025
+ }
34026
+ };
34027
+ function validateKlikeStatement(stmt) {
34028
+ validateStatement(stmt);
34029
+ }
34030
+ function validateStatement(stmt) {
34031
+ switch (stmt.type) {
34032
+ case "SELECT":
34033
+ validateSelect(stmt);
34034
+ return;
34035
+ case "UNION":
34036
+ validateUnion(stmt);
34037
+ return;
34038
+ case "WITH":
34039
+ validateWith(stmt);
34040
+ return;
34041
+ case "EXPLAIN":
34042
+ validateStatement(stmt.query);
34043
+ return;
34044
+ case "CREATE_TEMP_TABLE":
34045
+ validateSelectLike(stmt.query);
34046
+ return;
34047
+ case "SET_VARIABLE":
34048
+ case "DECLARE_VARIABLE":
34049
+ case "ASSERT":
34050
+ validateNestedSelects(stmt);
34051
+ return;
34052
+ case "INSERT":
34053
+ case "INSERT_SELECT":
34054
+ case "UPSERT":
34055
+ case "UPSERT_SELECT":
34056
+ case "UPDATE":
34057
+ case "DELETE":
34058
+ case "REORDER":
34059
+ if (containsKlike(stmt)) {
34060
+ throw new KlikeValidationError(
34061
+ "KLIKE / NOT KLIKE \u306F v1 \u3067\u306F\u5168 DML\uFF08UPDATE / DELETE / INSERT / UPSERT / REORDER\uFF09\u3067\u4F7F\u7528\u3067\u304D\u307E\u305B\u3093"
34062
+ );
34063
+ }
34064
+ return;
34065
+ case "SHOW_APPS":
34066
+ case "DESCRIBE":
34067
+ case "DROP_TEMP_TABLE":
34068
+ return;
34069
+ }
34070
+ }
34071
+ function validateSelectLike(query) {
34072
+ if (query.type === "SELECT") validateSelect(query);
34073
+ else if (query.type === "UNION") validateUnion(query);
34074
+ else validateWith(query);
34075
+ }
34076
+ function validateUnion(stmt) {
34077
+ validateSelectLike(stmt.left);
34078
+ validateSelect(stmt.right);
34079
+ }
34080
+ function validateWith(stmt) {
34081
+ const inlined = buildEffectiveInlineSelect(stmt);
34082
+ if (inlined !== null) {
34083
+ validateSelect(inlined);
34084
+ return;
34085
+ }
34086
+ for (const cte of stmt.ctes) {
34087
+ if (cte.query.type === "SELECT") validateSelect(cte.query);
34088
+ else if (cte.query.type === "UNION") validateUnion(cte.query);
34089
+ }
34090
+ validateSelectLike(stmt.query);
34091
+ }
34092
+ function validateSelect(stmt) {
34093
+ validateOwnKlikeExpressions(stmt);
34094
+ if (whereHasKlike(stmt.where)) {
34095
+ const inMemorySource = stmt.from.cteName !== null || stmt.joins.some((join) => join.table.cteName !== null);
34096
+ if (inMemorySource || resolveSelectMode(stmt) === "FULL_SCAN") {
34097
+ throw new KlikeValidationError(
34098
+ "KLIKE / NOT KLIKE \u306F kintone \u3078\u62BC\u3057\u4E0B\u3052\u308B SIMPLE SELECT \u3067\u306E\u307F\u4F7F\u7528\u3067\u304D\u307E\u3059\u3002\u3053\u306E SELECT \u306F FULL_SCAN \u306B\u306A\u308A\u307E\u3059"
34099
+ );
34100
+ }
34101
+ }
34102
+ validateNestedSelects(stmt);
34103
+ }
34104
+ function validateOwnKlikeExpressions(stmt) {
34105
+ walkWithoutNestedSelects(stmt, (where) => {
34106
+ if (!isKlike(where)) return;
34107
+ if (!isDescendantOf(stmt.where, where)) {
34108
+ throw new KlikeValidationError("KLIKE / NOT KLIKE \u306F SELECT \u306E WHERE \u53E5\u3067\u306E\u307F\u4F7F\u7528\u3067\u304D\u307E\u3059");
34109
+ }
34110
+ const right = where.right;
34111
+ if (right.type !== "STRING" && right.type !== "VARIABLE") {
34112
+ throw new KlikeValidationError(
34113
+ "KLIKE / NOT KLIKE \u306E\u53F3\u8FBA\u306B\u306F\u6587\u5B57\u5217\u30EA\u30C6\u30E9\u30EB\u307E\u305F\u306F\u6587\u5B57\u5217\u30D0\u30C3\u30C1\u5909\u6570\u304C\u5FC5\u8981\u3067\u3059"
34114
+ );
34115
+ }
34116
+ if (right.type === "STRING" && right.value.includes("%")) {
34117
+ throw new KlikeValidationError(
34118
+ "KLIKE / NOT KLIKE \u306E\u691C\u7D22\u8A9E\u306B % \u306F\u4F7F\u7528\u3067\u304D\u307E\u305B\u3093\u3002SQL \u30EF\u30A4\u30EB\u30C9\u30AB\u30FC\u30C9\u691C\u7D22\u306B\u306F LIKE \u3092\u4F7F\u7528\u3057\u3066\u304F\u3060\u3055\u3044"
34119
+ );
34120
+ }
34121
+ });
34122
+ }
34123
+ function validateNestedSelects(node) {
34124
+ walkObjects(node, (obj) => {
34125
+ if (obj.type === "SELECT") validateSelect(obj);
34126
+ }, true);
34127
+ }
34128
+ function buildEffectiveInlineSelect(stmt) {
34129
+ if (stmt.ctes.length !== 1) return null;
34130
+ const cte = stmt.ctes[0];
34131
+ if (cte.query.type !== "SELECT" || resolveSelectMode(cte.query) !== "SIMPLE") return null;
34132
+ if (stmt.query.type !== "SELECT") return null;
34133
+ const final = stmt.query;
34134
+ if (final.from.cteName !== cte.name || final.joins.length > 0) return null;
34135
+ if (final.groupBy.length > 0 || final.distinct) return null;
34136
+ if (final.columns.some(
34137
+ (column) => column.type === "AGGREGATE" || column.type === "ARITH_AGG_COL"
34138
+ )) return null;
34139
+ const where = cte.query.where === null ? final.where : final.where === null ? cte.query.where : { type: "LOGICAL", op: "AND", left: cte.query.where, right: final.where };
34140
+ const columns = final.columns.every((column) => column.type === "WILDCARD") ? cte.query.columns : final.columns;
34141
+ return {
34142
+ type: "SELECT",
34143
+ from: cte.query.from,
34144
+ joins: [],
34145
+ columns,
34146
+ where,
34147
+ groupBy: [],
34148
+ having: null,
34149
+ orderBy: final.orderBy.length > 0 ? final.orderBy : cte.query.orderBy,
34150
+ limit: final.limit ?? cte.query.limit,
34151
+ offset: final.offset ?? cte.query.offset,
34152
+ distinct: false
34153
+ };
34154
+ }
34155
+ function containsKlike(node) {
34156
+ let found = false;
34157
+ walkObjects(node, (obj) => {
34158
+ if (obj.type === "BINARY" && (obj.op === "KLIKE" || obj.op === "NOT_KLIKE")) found = true;
34159
+ });
34160
+ return found;
34161
+ }
34162
+ function isDescendantOf(root, target) {
34163
+ if (root === null) return false;
34164
+ if (root === target) return true;
34165
+ switch (root.type) {
34166
+ case "LOGICAL":
34167
+ return isDescendantOf(root.left, target) || isDescendantOf(root.right, target);
34168
+ case "NOT":
34169
+ case "GROUP":
34170
+ return isDescendantOf(root.expr, target);
34171
+ case "BINARY":
34172
+ case "NULL_CHECK":
34173
+ case "EXISTS":
34174
+ return false;
34175
+ }
34176
+ }
34177
+ function walkWithoutNestedSelects(node, visitWhere) {
34178
+ if (Array.isArray(node)) {
34179
+ for (const value of node) walkWithoutNestedSelects(value, visitWhere);
34180
+ return;
34181
+ }
34182
+ if (node === null || typeof node !== "object") return;
34183
+ const obj = node;
34184
+ if (obj.type === "BINARY" || obj.type === "NULL_CHECK" || obj.type === "LOGICAL" || obj.type === "NOT" || obj.type === "GROUP" || obj.type === "EXISTS") {
34185
+ visitWhere(obj);
34186
+ }
34187
+ for (const value of Object.values(obj)) {
34188
+ if (value !== node && isSelectObject(value)) continue;
34189
+ walkWithoutNestedSelects(value, visitWhere);
34190
+ }
34191
+ }
34192
+ function walkObjects(node, visit, skipRoot = false) {
34193
+ if (Array.isArray(node)) {
34194
+ for (const value of node) walkObjects(value, visit);
34195
+ return;
34196
+ }
34197
+ if (node === null || typeof node !== "object") return;
34198
+ const obj = node;
34199
+ if (!skipRoot) visit(obj);
34200
+ for (const value of Object.values(obj)) walkObjects(value, visit);
34201
+ }
34202
+ function isSelectObject(value) {
34203
+ return value !== null && typeof value === "object" && value.type === "SELECT";
34204
+ }
34205
+
34206
+ // src/core/batch.ts
34207
+ var MAX_TEMP_TABLES = 16;
34208
+ var MAX_BATCH_VARIABLES = 64;
34209
+ var BatchAnalysisError = class extends Error {
34210
+ constructor(message, statementIndex) {
34211
+ super(message);
34212
+ this.statementIndex = statementIndex;
34213
+ }
34214
+ };
34215
+ function collectRefs(node, tempRefs, appIds) {
34216
+ if (Array.isArray(node)) {
34217
+ for (const v of node) collectRefs(v, tempRefs, appIds);
34218
+ return;
34219
+ }
34220
+ if (node !== null && typeof node === "object") {
34221
+ const obj = node;
34222
+ const cte = obj["cteName"];
34223
+ if (typeof cte === "string" && cte.startsWith("#")) tempRefs.add(cte);
34224
+ const appId = obj["appId"];
34225
+ if (typeof appId === "number" && appId > 0) appIds.add(appId);
34226
+ for (const v of Object.values(obj)) collectRefs(v, tempRefs, appIds);
34227
+ }
34228
+ }
34229
+ function collectVariableRefs(node, refs) {
34230
+ if (Array.isArray(node)) {
34231
+ for (const v of node) collectVariableRefs(v, refs);
34232
+ return;
34233
+ }
34234
+ if (node !== null && typeof node === "object") {
34235
+ const obj = node;
34236
+ if (obj["type"] === "VARIABLE" && typeof obj["name"] === "string") {
34237
+ refs.add(obj["name"]);
34238
+ return;
34239
+ }
34240
+ for (const v of Object.values(obj)) collectVariableRefs(v, refs);
34241
+ }
34242
+ }
34243
+ function analyzeBatch(statements) {
34244
+ if (statements.length === 0) {
34245
+ throw new BatchAnalysisError("ArgumentError: SQL is empty.", 0);
34246
+ }
34247
+ statements.forEach((stmt, index) => {
34248
+ try {
34249
+ validateKlikeStatement(stmt);
34250
+ } catch (error51) {
34251
+ if (error51 instanceof KlikeValidationError) {
34252
+ throw new BatchAnalysisError(error51.message, index);
34253
+ }
34254
+ throw error51;
34255
+ }
34256
+ });
34257
+ if (statements.length === 1) {
34258
+ const t = statements[0].type;
34259
+ if (t === "SET_VARIABLE" || t === "DECLARE_VARIABLE") {
34260
+ const verb = t === "SET_VARIABLE" ? "SET" : "DECLARE";
34261
+ throw new BatchAnalysisError(`ArgumentError: ${verb} variable requires a batch.`, 0);
34262
+ }
34263
+ if (t === "CREATE_TEMP_TABLE" || t === "DROP_TEMP_TABLE") {
34264
+ const verb = t === "CREATE_TEMP_TABLE" ? "CREATE TEMP TABLE" : "DROP TEMP TABLE";
34265
+ throw new BatchAnalysisError(
34266
+ `ArgumentError: ${verb} requires a batch (temp tables are batch-scoped).`,
34267
+ 0
34268
+ );
34269
+ }
34270
+ }
34271
+ const defined = /* @__PURE__ */ new Map();
34272
+ const createdOrder = [];
34273
+ const results = [];
34274
+ const variableDefs = /* @__PURE__ */ new Map();
34275
+ const variableOrder = [];
34276
+ statements.forEach((stmt, index) => {
34277
+ const statementType = getStatementType(stmt);
34278
+ const created = [];
34279
+ const dropped = [];
34280
+ const refs = /* @__PURE__ */ new Set();
34281
+ const stmtAppIds = /* @__PURE__ */ new Set();
34282
+ const dependsOn = /* @__PURE__ */ new Set();
34283
+ const variableRefs = /* @__PURE__ */ new Set();
34284
+ collectVariableRefs(stmt, variableRefs);
34285
+ for (const name of variableRefs) {
34286
+ const def = variableDefs.get(name);
34287
+ if (def === void 0) {
34288
+ throw new BatchAnalysisError(
34289
+ `ParseError: variable @${name} is not defined before statement ${index + 1}.`,
34290
+ index
34291
+ );
34292
+ }
34293
+ def.referencedBy.push(index);
34294
+ }
34295
+ if (stmt.type === "SET_VARIABLE" || stmt.type === "DECLARE_VARIABLE") {
34296
+ if (variableDefs.has(stmt.name)) {
34297
+ throw new BatchAnalysisError(`ParseError: variable @${stmt.name} is already defined.`, index);
34298
+ }
34299
+ variableDefs.set(stmt.name, { index, referencedBy: [] });
34300
+ variableOrder.push(stmt.name);
34301
+ if (variableOrder.length > MAX_BATCH_VARIABLES) {
34302
+ throw new BatchAnalysisError(
34303
+ `ParseError: batch exceeds ${MAX_BATCH_VARIABLES} variables.`,
34304
+ index
34305
+ );
34306
+ }
34307
+ }
34308
+ if (stmt.type === "CREATE_TEMP_TABLE") {
34309
+ collectRefs(stmt.query, refs, stmtAppIds);
34310
+ } else if (stmt.type === "DROP_TEMP_TABLE") {
34311
+ } else {
34312
+ collectRefs(stmt, refs, stmtAppIds);
34313
+ }
34314
+ let tempOnlySource = false;
34315
+ if (stmt.type === "INSERT_SELECT" || stmt.type === "UPSERT_SELECT") {
34316
+ const srcTemp = /* @__PURE__ */ new Set();
34317
+ const srcApps = /* @__PURE__ */ new Set();
34318
+ collectRefs(stmt.select, srcTemp, srcApps);
34319
+ tempOnlySource = srcTemp.size > 0 && srcApps.size === 0;
34320
+ }
34321
+ for (const name of refs) {
34322
+ const at = defined.get(name);
34323
+ if (at === void 0) {
34324
+ throw new BatchAnalysisError(
34325
+ `ParseError: temp table ${name} is not defined in this batch.`,
34326
+ index
34327
+ );
34328
+ }
34329
+ dependsOn.add(at);
34330
+ }
34331
+ if (stmt.type === "CREATE_TEMP_TABLE") {
34332
+ if (defined.has(stmt.name)) {
34333
+ throw new BatchAnalysisError(
34334
+ `ParseError: temp table ${stmt.name} is already defined.`,
34335
+ index
34336
+ );
34337
+ }
34338
+ defined.set(stmt.name, index);
34339
+ createdOrder.push(stmt.name);
34340
+ created.push(stmt.name);
34341
+ if (defined.size > MAX_TEMP_TABLES) {
34342
+ throw new BatchAnalysisError(
34343
+ `ParseError: batch exceeds ${MAX_TEMP_TABLES} temp tables.`,
34344
+ index
34345
+ );
34346
+ }
34347
+ }
34348
+ if (stmt.type === "DROP_TEMP_TABLE") {
34349
+ const at = defined.get(stmt.name);
34350
+ if (at === void 0) {
34351
+ throw new BatchAnalysisError(
34352
+ `ParseError: temp table ${stmt.name} is not defined in this batch.`,
34353
+ index
34354
+ );
34355
+ }
34356
+ dependsOn.add(at);
34357
+ dropped.push(stmt.name);
34358
+ defined.delete(stmt.name);
34359
+ }
34360
+ results.push({
34361
+ index,
34362
+ statementType,
34363
+ isDml: isDmlType(statementType),
34364
+ isReadOnly: isReadOnlyType(statementType),
34365
+ hasWhere: hasWhereClause(stmt),
34366
+ insertValuesCount: getInsertValuesCount(stmt),
34367
+ appIds: [...stmtAppIds].sort((a, b) => a - b),
34368
+ tempTablesCreated: created,
34369
+ tempTablesReferenced: [...refs],
34370
+ tempTablesDropped: dropped,
34371
+ dependsOn: [...dependsOn].sort((a, b) => a - b),
34372
+ tempOnlySource,
34373
+ targetAppId: isDmlType(statementType) && typeof stmt.appId === "number" ? stmt.appId : null
34374
+ });
34375
+ });
34376
+ const containsDml = results.some((r) => r.isDml);
34377
+ const variables = variableOrder.map((name) => ({
34378
+ name,
34379
+ referencedBy: [...variableDefs.get(name).referencedBy]
34380
+ }));
34381
+ return {
34382
+ statementCount: statements.length,
34383
+ isReadOnlyBatch: !containsDml && results.every((r) => r.isReadOnly),
34384
+ containsDml,
34385
+ tempTables: createdOrder,
34386
+ variables,
34387
+ warnings: variables.filter((v) => v.referencedBy.length === 0).map((v) => `variable @${v.name} is never used.`),
34388
+ statements: results
34389
+ };
34390
+ }
34391
+
34392
+ // src/core/batchVariables.ts
34393
+ var VARIABLE_NAME_RE = /^[A-Za-z_][A-Za-z0-9_]{0,63}$/;
34394
+ function normalizeBatchVariableName(name) {
34395
+ if (!VARIABLE_NAME_RE.test(name)) {
34396
+ throw new Error(
34397
+ `ArgumentError: invalid variable name "${name}". Use a name without @ matching [A-Za-z_][A-Za-z0-9_]{0,63}.`
34398
+ );
34399
+ }
34400
+ return name.toLowerCase();
34401
+ }
34402
+ function normalizeBatchVariables(input) {
34403
+ const normalized = /* @__PURE__ */ Object.create(null);
34404
+ for (const [rawName, value] of Object.entries(input ?? {})) {
34405
+ const name = normalizeBatchVariableName(rawName);
34406
+ if (Object.prototype.hasOwnProperty.call(normalized, name)) {
34407
+ throw new Error(`ArgumentError: variable "${rawName}" is specified more than once.`);
34408
+ }
34409
+ normalized[name] = value;
34410
+ }
34411
+ return normalized;
34412
+ }
34413
+ function validateDeclaredBatchVariables(statements, input) {
34414
+ const normalized = normalizeBatchVariables(input);
34415
+ const declared = new Set(
34416
+ statements.filter((stmt) => stmt.type === "DECLARE_VARIABLE").map((stmt) => stmt.name)
34417
+ );
34418
+ for (const name of Object.keys(normalized)) {
34419
+ if (!declared.has(name)) {
34420
+ throw new Error(`ArgumentError: injected variable @${name} is not declared.`);
34421
+ }
34422
+ }
34423
+ return normalized;
34424
+ }
34425
+
34426
+ // src/core/scalarCompare.ts
34427
+ function compareScalarValues(op, leftStr, rightStr) {
34428
+ if (op === "=") return leftStr === rightStr;
34429
+ if (op === "!=" || op === "<>") return leftStr !== rightStr;
34430
+ const rightNum = Number(rightStr);
34431
+ if (leftStr === "" && rightStr !== "" && Number.isFinite(rightNum)) {
34432
+ return op === "<" || op === "<=";
34433
+ }
34434
+ const leftNum = Number(leftStr);
34435
+ const numeric = !Number.isNaN(leftNum) && !Number.isNaN(rightNum);
34436
+ switch (op) {
34437
+ case ">":
34438
+ return numeric ? leftNum > rightNum : leftStr > rightStr;
34439
+ case "<":
34440
+ return numeric ? leftNum < rightNum : leftStr < rightStr;
34441
+ case ">=":
34442
+ return numeric ? leftNum >= rightNum : leftStr >= rightStr;
34443
+ case "<=":
34444
+ return numeric ? leftNum <= rightNum : leftStr <= rightStr;
34445
+ }
34446
+ }
34447
+
34201
34448
  // src/engine/evalFunc.ts
34202
34449
  function evalArithExpr(expr, row) {
34203
34450
  if (expr.type === "NUMBER") return expr.value;
@@ -34454,6 +34701,9 @@ function evalOp(op, leftStr, right, row, fieldType, resolveFieldType) {
34454
34701
  const pattern = resolveValue(right, row, resolveFieldType);
34455
34702
  return !matchLike(leftStr, pattern);
34456
34703
  }
34704
+ if (op === "KLIKE" || op === "NOT_KLIKE") {
34705
+ throw new Error("KLIKE / NOT KLIKE \u306F JavaScript \u5074\u3067\u306F\u8A55\u4FA1\u3067\u304D\u307E\u305B\u3093\uFF08SIMPLE SELECT \u3067\u306E\u307F\u4F7F\u7528\u3067\u304D\u307E\u3059\uFF09");
34706
+ }
34457
34707
  const rightStr = resolveValue(right, row, resolveFieldType);
34458
34708
  return compareScalarValues(op, leftStr, rightStr);
34459
34709
  }
@@ -34609,6 +34859,11 @@ function matchLike(value, pattern) {
34609
34859
 
34610
34860
  // src/converter/dmlToKintone.ts
34611
34861
  function assertDmlWhereIsSafe(where) {
34862
+ if (whereHasKlike(where)) {
34863
+ throw new DmlConvertError(
34864
+ "UPDATE / DELETE \u306E WHERE \u306B KLIKE / NOT KLIKE \u306F\u4F7F\u7528\u3067\u304D\u307E\u305B\u3093\u3002kintone \u30AD\u30FC\u30EF\u30FC\u30C9\u691C\u7D22\u306E\u6253\u3061\u5207\u308A\u3092\u691C\u51FA\u3067\u304D\u306A\u3044\u305F\u3081\u3001v1 \u3067\u306F\u5168 DML \u3067\u5B89\u5168\u4E0A\u62D2\u5426\u3057\u307E\u3057\u305F\u3002"
34865
+ );
34866
+ }
34612
34867
  if (!whereHasLike(where)) return;
34613
34868
  throw new DmlConvertError(
34614
34869
  "UPDATE / DELETE \u306E WHERE \u306B LIKE / NOT LIKE \u306F\u4F7F\u7528\u3067\u304D\u307E\u305B\u3093\u3002LIKE \u306F kSQL \u306E\u610F\u5473\u8AD6\u306B\u5F93\u3063\u3066 JS \u3067\u8A55\u4FA1\u3059\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059\u304C\u3001\u89AA\u30EC\u30B3\u30FC\u30C9 DML \u306B\u306F JS \u8A55\u4FA1\u7D4C\u8DEF\u304C\u306A\u3044\u305F\u3081\u3001\u5B89\u5168\u4E0A\u62D2\u5426\u3057\u307E\u3057\u305F\u3002SELECT \u3067\u5BFE\u8C61\u30EC\u30B3\u30FC\u30C9\u756A\u53F7\u3092\u78BA\u8A8D\u3057\u3001IN \u307E\u305F\u306F\u5B8C\u5168\u4E00\u81F4\u3067\u5BFE\u8C61\u3092\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044\u3002"
@@ -35137,7 +35392,8 @@ var SELECTION_IN_FIELD_TYPES = /* @__PURE__ */ new Set([
35137
35392
  "DROP_DOWN",
35138
35393
  "RADIO_BUTTON",
35139
35394
  "CHECK_BOX",
35140
- "MULTI_SELECT"
35395
+ "MULTI_SELECT",
35396
+ "STATUS"
35141
35397
  ]);
35142
35398
  function isSelectionInComparison(expr, options) {
35143
35399
  if (!isSelectionInCandidate(expr, options)) return false;
@@ -35788,6 +36044,7 @@ function createEmptyMetrics() {
35788
36044
  deleteCalls: 0,
35789
36045
  fieldCalls: 0,
35790
36046
  appsCalls: 0,
36047
+ processStatusCalls: 0,
35791
36048
  fetchedRows: 0,
35792
36049
  elapsedMs: 0
35793
36050
  };
@@ -35819,6 +36076,10 @@ function wrapClientWithMetrics(client, metrics) {
35819
36076
  getFields: (appId) => {
35820
36077
  metrics.fieldCalls += 1;
35821
36078
  return client.getFields(appId);
36079
+ },
36080
+ getProcessStatuses: (appId) => {
36081
+ metrics.processStatusCalls += 1;
36082
+ return client.getProcessStatuses(appId);
35822
36083
  }
35823
36084
  };
35824
36085
  }
@@ -35832,6 +36093,7 @@ async function executeParsedStatement(stmt, client, options, cacheContext) {
35832
36093
  if (unresolved !== null) {
35833
36094
  throw new Error(`ParseError: variable @${unresolved} is not defined in a batch.`);
35834
36095
  }
36096
+ validateKlikeStatement(stmt);
35835
36097
  switch (stmt.type) {
35836
36098
  case "SELECT":
35837
36099
  return executeSelect(stmt, client, options, cacheContext);
@@ -35968,6 +36230,7 @@ async function executeBatch(sql, client, options = {}) {
35968
36230
  async function executeBatchStatement(stmt, info, client, options, cacheContext, tempTables, variables) {
35969
36231
  if (stmt.type === "SET_VARIABLE") {
35970
36232
  const resolvedStmt2 = resolveVariableRefs(stmt, variables);
36233
+ validateKlikeStatement(resolvedStmt2);
35971
36234
  if (resolvedStmt2.expr.type === "SCALAR_SUBQUERY") {
35972
36235
  try {
35973
36236
  const value = await evaluateScalarSubquery(
@@ -36000,6 +36263,7 @@ async function executeBatchStatement(stmt, info, client, options, cacheContext,
36000
36263
  return {};
36001
36264
  }
36002
36265
  const resolvedStmt = resolveVariableRefs(stmt, variables);
36266
+ validateKlikeStatement(resolvedStmt);
36003
36267
  if (resolvedStmt.type === "CREATE_TEMP_TABLE") {
36004
36268
  const materializeOptions = {
36005
36269
  ...options,
@@ -36425,22 +36689,36 @@ function extractMainTypedPushdownCandidate(stmt) {
36425
36689
  return extractTypedPushdownCandidates(stmt.where, { tableAlias: stmt.from.alias });
36426
36690
  }
36427
36691
  async function loadTypedPushdownMeta(stmt, client, cacheContext) {
36428
- const appIds = /* @__PURE__ */ new Set();
36429
- if (extractMainTypedPushdownCandidate(stmt) !== null) appIds.add(stmt.from.appId);
36692
+ const candidatesByApp = /* @__PURE__ */ new Map();
36693
+ const addCandidate = (appId, candidate) => {
36694
+ if (candidate === null) return;
36695
+ const existing = candidatesByApp.get(appId);
36696
+ if (existing) existing.push(candidate);
36697
+ else candidatesByApp.set(appId, [candidate]);
36698
+ };
36699
+ addCandidate(stmt.from.appId, extractMainTypedPushdownCandidate(stmt));
36430
36700
  if (stmt.where !== null) {
36431
36701
  for (const join of stmt.joins) {
36432
36702
  if (!join.table.alias || join.table.subtableCode || join.table.cteName !== null) continue;
36433
36703
  const candidate = extractTypedPushdownCandidates(stmt.where, {
36434
36704
  tableAlias: join.table.alias
36435
36705
  });
36436
- if (candidate !== null) appIds.add(join.table.appId);
36706
+ addCandidate(join.table.appId, candidate);
36437
36707
  }
36438
36708
  }
36439
- const entries = await Promise.all([...appIds].map(async (appId) => {
36709
+ const entries = await Promise.all([...candidatesByApp.entries()].map(async ([appId, candidates]) => {
36440
36710
  const [fieldTypes, fieldOptions] = await Promise.all([
36441
36711
  getFieldTypeMap(appId, client, cacheContext),
36442
36712
  getFieldOptionSetMapByApp(appId, client, cacheContext)
36443
36713
  ]);
36714
+ const statusFields = collectCandidateFieldCodes(candidates).filter((fieldCode) => fieldTypes.get(fieldCode) === "STATUS");
36715
+ if (statusFields.length > 0) {
36716
+ const process4 = await getProcessStatusesCached(appId, client, cacheContext);
36717
+ if (process4.enable && process4.states.length > 0) {
36718
+ const states = new Set(process4.states);
36719
+ for (const fieldCode of statusFields) fieldOptions.set(fieldCode, states);
36720
+ }
36721
+ }
36444
36722
  return [appId, fieldTypes, fieldOptions];
36445
36723
  }));
36446
36724
  return {
@@ -36448,6 +36726,23 @@ async function loadTypedPushdownMeta(stmt, client, cacheContext) {
36448
36726
  fieldOptionsByApp: new Map(entries.map(([appId, , fieldOptions]) => [appId, fieldOptions]))
36449
36727
  };
36450
36728
  }
36729
+ function collectCandidateFieldCodes(candidates) {
36730
+ const fields = /* @__PURE__ */ new Set();
36731
+ const visit = (expr) => {
36732
+ if (expr.type === "BINARY") {
36733
+ if (expr.left.type === "FIELD") fields.add(expr.left.field);
36734
+ return;
36735
+ }
36736
+ if (expr.type === "LOGICAL") {
36737
+ visit(expr.left);
36738
+ visit(expr.right);
36739
+ return;
36740
+ }
36741
+ if (expr.type === "GROUP" || expr.type === "NOT") visit(expr.expr);
36742
+ };
36743
+ for (const candidate of candidates) visit(candidate);
36744
+ return [...fields];
36745
+ }
36451
36746
  function collectTypedInFieldRefs(expr, out) {
36452
36747
  if (expr === null) return;
36453
36748
  switch (expr.type) {
@@ -37073,6 +37368,7 @@ var fieldTypeCache = /* @__PURE__ */ new Map();
37073
37368
  var optionOrderCache = /* @__PURE__ */ new Map();
37074
37369
  var sortKindCache = /* @__PURE__ */ new Map();
37075
37370
  var fieldInfoCache = /* @__PURE__ */ new Map();
37371
+ var processStatusCache = /* @__PURE__ */ new Map();
37076
37372
  function getScopedCacheValue(root, cacheContext, appId) {
37077
37373
  return root.get(cacheContext)?.get(appId);
37078
37374
  }
@@ -37094,6 +37390,13 @@ async function getFieldsCached(appId, client, cacheContext) {
37094
37390
  setScopedCacheValue(fieldInfoCache, cacheContext, appId, loading);
37095
37391
  return loading;
37096
37392
  }
37393
+ async function getProcessStatusesCached(appId, client, cacheContext) {
37394
+ const cached2 = getScopedCacheValue(processStatusCache, cacheContext, appId);
37395
+ if (cached2) return cached2;
37396
+ const loading = client.getProcessStatuses(appId);
37397
+ setScopedCacheValue(processStatusCache, cacheContext, appId, loading);
37398
+ return loading;
37399
+ }
37097
37400
  async function getFieldTypeMap(appId, client, cacheContext) {
37098
37401
  const cached2 = getScopedCacheValue(fieldTypeCache, cacheContext, appId);
37099
37402
  if (cached2) return cached2;
@@ -37829,7 +38132,9 @@ async function executeDescribe(stmt, client, cacheContext) {
37829
38132
  function parseSql(sql) {
37830
38133
  try {
37831
38134
  const tokens = new Lexer(sql).tokenize();
37832
- return new Parser(tokens).parse();
38135
+ const stmt = new Parser(tokens).parse();
38136
+ validateKlikeStatement(stmt);
38137
+ return stmt;
37833
38138
  } catch (e) {
37834
38139
  if (e instanceof LexError || e instanceof ParseError) {
37835
38140
  throw e;
@@ -37940,6 +38245,7 @@ function buildBatchExplainPlans(sql, injectedVariables) {
37940
38245
  statementCount: statements.length,
37941
38246
  statements: statements.map((stmt, i) => {
37942
38247
  const planStmt = stmt.type === "SET_VARIABLE" ? stmt.expr.type === "SCALAR_SUBQUERY" ? { ...stmt, expr: resolveVariableRefs(stmt.expr, variables) } : stmt : resolveVariableRefs(stmt, variables);
38248
+ validateKlikeStatement(planStmt);
37943
38249
  const result = {
37944
38250
  index: i,
37945
38251
  type: analysis.statements[i].statementType,
@@ -38373,11 +38679,15 @@ var OperationCancelledError = class extends Error {
38373
38679
  // src/core/sql.ts
38374
38680
  function parseSqlStatement(sql) {
38375
38681
  const tokens = new Lexer(sql).tokenize();
38376
- return new Parser(tokens).parse();
38682
+ const stmt = new Parser(tokens).parse();
38683
+ validateKlikeStatement(stmt);
38684
+ return stmt;
38377
38685
  }
38378
38686
  function parseSqlStatements(sql) {
38379
38687
  const tokens = new Lexer(sql).tokenize();
38380
- return new Parser(tokens).parseStatements();
38688
+ const statements = new Parser(tokens).parseStatements();
38689
+ statements.forEach(validateKlikeStatement);
38690
+ return statements;
38381
38691
  }
38382
38692
 
38383
38693
  // src/output/batchEnvelope.ts
@@ -38755,6 +39065,7 @@ function withRequestGate(client, gate) {
38755
39065
  getRecords: (params) => gate.runReadOnly(() => client.getRecords(params)),
38756
39066
  getApps: () => gate.runReadOnly(() => client.getApps()),
38757
39067
  getFields: (appId) => gate.runReadOnly(() => client.getFields(appId)),
39068
+ getProcessStatuses: (appId) => gate.runReadOnly(() => client.getProcessStatuses(appId)),
38758
39069
  postRecords: (params) => gate.runMutation(() => client.postRecords(params)),
38759
39070
  putRecords: (params) => gate.runMutation(() => client.putRecords(params)),
38760
39071
  deleteRecords: (params) => gate.runMutation(() => client.deleteRecords(params))
@@ -38989,6 +39300,16 @@ function createNodeKintoneClient(baseUrl, tokenResolver) {
38989
39300
  appId
38990
39301
  );
38991
39302
  return flattenFormFieldProperties(res.properties);
39303
+ },
39304
+ async getProcessStatuses(appId) {
39305
+ const qs = new URLSearchParams();
39306
+ qs.set("app", String(appId));
39307
+ qs.set("lang", "user");
39308
+ const res = await requestJson(`${apiBasePath}/app/status.json?${qs.toString()}`, { method: "GET" }, appId);
39309
+ return {
39310
+ enable: res.enable,
39311
+ states: Object.values(res.states ?? {}).map((state) => state.name)
39312
+ };
38992
39313
  }
38993
39314
  };
38994
39315
  }
@@ -39496,6 +39817,12 @@ async function createKsqlRuntime(serverOptions, input) {
39496
39817
  if (!routed) throw new Error(`AuthError: profile "${binding.profile}" is not resolved for APP${appId}.`);
39497
39818
  return routed.getFields(binding.appId);
39498
39819
  },
39820
+ getProcessStatuses: (appId) => {
39821
+ const binding = resolveRuntimeBinding(runtimeContext.sqlContext, appId);
39822
+ const routed = runtimeContext.clientsByProfile.get(binding.profile);
39823
+ if (!routed) throw new Error(`AuthError: profile "${binding.profile}" is not resolved for APP${appId}.`);
39824
+ return routed.getProcessStatuses(binding.appId);
39825
+ },
39499
39826
  getApps: () => defaultClient.getApps()
39500
39827
  };
39501
39828
  const gatedClient = withRequestGate(
@@ -39720,7 +40047,10 @@ function noOpClient() {
39720
40047
  putRecords: fail,
39721
40048
  deleteRecords: fail,
39722
40049
  getApps: fail,
39723
- getFields: fail
40050
+ getFields: fail,
40051
+ async getProcessStatuses() {
40052
+ return { enable: false, states: [] };
40053
+ }
39724
40054
  };
39725
40055
  }
39726
40056
  function getServerConfigPath(serverOptions) {
@@ -40451,7 +40781,7 @@ Options:
40451
40781
  -h, --help Show help
40452
40782
  `);
40453
40783
  }
40454
- var SERVER_VERSION = true ? "2.6.0" : "0.0.0-dev";
40784
+ var SERVER_VERSION = true ? "2.8.0" : "0.0.0-dev";
40455
40785
  function createServer(args) {
40456
40786
  const server = new McpServer({
40457
40787
  name: "ksql-mcp",