@rex0220/kintone-sql-tools 3.34.1 → 3.36.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 CHANGED
@@ -116,6 +116,7 @@ var KEYWORDS = /* @__PURE__ */ new Map([
116
116
  ["TODAY", "TODAY" /* TODAY */],
117
117
  ["NOW", "NOW" /* NOW */],
118
118
  ["LOGINUSER", "LOGINUSER" /* LOGINUSER */],
119
+ ["PRIMARY_ORGANIZATION", "PRIMARY_ORGANIZATION" /* PRIMARY_ORGANIZATION */],
119
120
  ["CASE", "CASE" /* CASE */],
120
121
  ["WHEN", "WHEN" /* WHEN */],
121
122
  ["THEN", "THEN" /* THEN */],
@@ -804,7 +805,8 @@ var RELATIVE_DATE_FUNCTION_NAMES = /* @__PURE__ */ new Set([
804
805
  var LEGACY_KINTONE_FUNCTION_NAMES = /* @__PURE__ */ new Set([
805
806
  "TODAY",
806
807
  "NOW",
807
- "LOGINUSER"
808
+ "LOGINUSER",
809
+ "PRIMARY_ORGANIZATION"
808
810
  ]);
809
811
  var SERVER_ONLY_WHERE_FUNCTION_NAMES = /* @__PURE__ */ new Set([
810
812
  ...LEGACY_KINTONE_FUNCTION_NAMES,
@@ -917,7 +919,8 @@ var PARSER_WINDOW_FUNCTION_TOKEN_MAP = Object.freeze({
917
919
  var PARSER_CONTEXTUAL_FUNCTION_TOKEN_MAP = Object.freeze({
918
920
  ["TODAY" /* TODAY */]: "TODAY",
919
921
  ["NOW" /* NOW */]: "NOW",
920
- ["LOGINUSER" /* LOGINUSER */]: "LOGINUSER"
922
+ ["LOGINUSER" /* LOGINUSER */]: "LOGINUSER",
923
+ ["PRIMARY_ORGANIZATION" /* PRIMARY_ORGANIZATION */]: "PRIMARY_ORGANIZATION"
921
924
  });
922
925
  function isContextualFunctionToken(kind) {
923
926
  return PARSER_CONTEXTUAL_FUNCTION_TOKEN_MAP[kind] !== void 0;
@@ -974,6 +977,7 @@ var FUNC_CALL_PREFIX_KINDS = /* @__PURE__ */ new Set([
974
977
  "TODAY" /* TODAY */,
975
978
  "NOW" /* NOW */,
976
979
  "LOGINUSER" /* LOGINUSER */,
980
+ "PRIMARY_ORGANIZATION" /* PRIMARY_ORGANIZATION */,
977
981
  "UPPER" /* UPPER */,
978
982
  "LOWER" /* LOWER */,
979
983
  "TRIM" /* TRIM */,
@@ -1219,6 +1223,12 @@ var Parser = class {
1219
1223
  tok
1220
1224
  );
1221
1225
  }
1226
+ if (contextualFunction === "PRIMARY_ORGANIZATION") {
1227
+ throw new ParseError(
1228
+ `${context} \u306E\u53F3\u8FBA\u3067 PRIMARY_ORGANIZATION() \u306F\u4F7F\u7528\u3067\u304D\u307E\u305B\u3093\uFF08\u5B9F\u884C\u74B0\u5883\u5171\u901A\u306E\u512A\u5148\u7D44\u7E54\u89E3\u6C7A\u306F\u672A\u5BFE\u5FDC\u3067\u3059\uFF09`,
1229
+ tok
1230
+ );
1231
+ }
1222
1232
  if (contextualFunction !== void 0) {
1223
1233
  return this.parseSqlValue();
1224
1234
  }
@@ -3095,6 +3105,23 @@ var Parser = class {
3095
3105
  if (this.peek().kind === "," /* COMMA */) {
3096
3106
  throw new ParseError(mixedLoginUserMessage, this.peek());
3097
3107
  }
3108
+ } else if (tok.kind === "PRIMARY_ORGANIZATION" /* PRIMARY_ORGANIZATION */) {
3109
+ const mixedPrimaryOrganizationMessage = "PRIMARY_ORGANIZATION() \u306F IN / NOT IN \u30EA\u30B9\u30C8\u306E\u5358\u72EC\u8981\u7D20\u3068\u3057\u3066\u306E\u307F\u4F7F\u7528\u3067\u304D\u307E\u3059";
3110
+ if (values.length > 0) {
3111
+ throw new ParseError(mixedPrimaryOrganizationMessage, tok);
3112
+ }
3113
+ this.expect(
3114
+ "(" /* LPAREN */,
3115
+ "PRIMARY_ORGANIZATION \u306E\u76F4\u5F8C\u306B\u306F\u7A7A\u5F15\u6570\u306E () \u304C\u5FC5\u8981\u3067\u3059"
3116
+ );
3117
+ this.expect(
3118
+ ")" /* RPAREN */,
3119
+ "PRIMARY_ORGANIZATION \u306E\u76F4\u5F8C\u306B\u306F\u7A7A\u5F15\u6570\u306E () \u304C\u5FC5\u8981\u3067\u3059"
3120
+ );
3121
+ values.push({ type: "KINTONE_FUNC", name: "PRIMARY_ORGANIZATION" });
3122
+ if (this.peek().kind === "," /* COMMA */) {
3123
+ throw new ParseError(mixedPrimaryOrganizationMessage, this.peek());
3124
+ }
3098
3125
  } else {
3099
3126
  throw new ParseError(invalidValueMessage, tok);
3100
3127
  }
@@ -5078,6 +5105,7 @@ function convertKintoneFunc(v) {
5078
5105
  case "TODAY":
5079
5106
  case "NOW":
5080
5107
  case "LOGINUSER":
5108
+ case "PRIMARY_ORGANIZATION":
5081
5109
  return `${v.name}()`;
5082
5110
  }
5083
5111
  return convertRelativeDateFunction(v);
@@ -6416,6 +6444,65 @@ function isSelectObject(value) {
6416
6444
  return value !== null && typeof value === "object" && value.type === "SELECT";
6417
6445
  }
6418
6446
 
6447
+ // src/core/primaryOrganizationDmlValidation.ts
6448
+ var PrimaryOrganizationDmlValidationError = class extends Error {
6449
+ constructor() {
6450
+ super(
6451
+ "ArgumentError: PRIMARY_ORGANIZATION() \u306F DML \u306E WHERE \u3067\u306F\u4F7F\u7528\u3067\u304D\u307E\u305B\u3093"
6452
+ );
6453
+ this.name = "ArgumentError";
6454
+ }
6455
+ };
6456
+ function validatePrimaryOrganizationDmlStatement(stmt) {
6457
+ const target = stmt.type === "EXPLAIN" ? stmt.query : stmt;
6458
+ switch (target.type) {
6459
+ case "UPDATE":
6460
+ case "DELETE":
6461
+ case "UPSERT":
6462
+ case "UPSERT_SELECT":
6463
+ case "INSERT_SELECT":
6464
+ if (hasPrimaryOrganizationInWhere(target)) {
6465
+ throw new PrimaryOrganizationDmlValidationError();
6466
+ }
6467
+ return;
6468
+ default:
6469
+ return;
6470
+ }
6471
+ }
6472
+ function hasPrimaryOrganizationInWhere(node) {
6473
+ let found = false;
6474
+ walkObjects2(node, (obj) => {
6475
+ if (found || !Object.prototype.hasOwnProperty.call(obj, "where")) return;
6476
+ if (containsPrimaryOrganization(obj.where)) found = true;
6477
+ });
6478
+ return found;
6479
+ }
6480
+ function containsPrimaryOrganization(node) {
6481
+ let found = false;
6482
+ walkObjects2(node, (obj) => {
6483
+ if (obj.type === "KINTONE_FUNC" && obj.name === "PRIMARY_ORGANIZATION") {
6484
+ found = true;
6485
+ }
6486
+ });
6487
+ return found;
6488
+ }
6489
+ function walkObjects2(node, visit) {
6490
+ if (Array.isArray(node)) {
6491
+ for (const value of node) walkObjects2(value, visit);
6492
+ return;
6493
+ }
6494
+ if (node === null || typeof node !== "object") return;
6495
+ const obj = node;
6496
+ visit(obj);
6497
+ for (const value of Object.values(obj)) walkObjects2(value, visit);
6498
+ }
6499
+
6500
+ // src/core/statementValidation.ts
6501
+ function validateStatementStatic(stmt) {
6502
+ validatePrimaryOrganizationDmlStatement(stmt);
6503
+ validateKlikeStatement(stmt);
6504
+ }
6505
+
6419
6506
  // src/engine/groupingRowMeta.ts
6420
6507
  var groupingRowMetaKey = /* @__PURE__ */ Symbol("ksql.groupingRowMeta");
6421
6508
  var groupingRefCanonicalIds = /* @__PURE__ */ new WeakMap();
@@ -6751,9 +6838,9 @@ function analyzeBatch(statements) {
6751
6838
  }
6752
6839
  try {
6753
6840
  assertApplyScope("phase15b", stmt);
6754
- validateKlikeStatement(stmt);
6841
+ validateStatementStatic(stmt);
6755
6842
  } catch (error) {
6756
- if (error instanceof KlikeValidationError) {
6843
+ if (error instanceof KlikeValidationError || error instanceof PrimaryOrganizationDmlValidationError) {
6757
6844
  throw new BatchAnalysisError(error.message, index);
6758
6845
  }
6759
6846
  if (error instanceof Error && /^(UnsupportedError|ArgumentError): APPLY /.test(error.message)) {
@@ -8014,6 +8101,7 @@ function resolveKintoneFunc(name) {
8014
8101
  case "NOW":
8015
8102
  return now.toISOString();
8016
8103
  case "LOGINUSER":
8104
+ case "PRIMARY_ORGANIZATION":
8017
8105
  return "";
8018
8106
  }
8019
8107
  }
@@ -10968,12 +11056,14 @@ var RELATIVE_DATE_OPERATORS = new Set(RANGE_AND_EQUALITY);
10968
11056
  var LEGACY_KINTONE_FUNCTION_FIELD_TYPES = /* @__PURE__ */ new Map([
10969
11057
  ["TODAY", /* @__PURE__ */ new Set(["DATE", "DATETIME", "CREATED_TIME", "UPDATED_TIME"])],
10970
11058
  ["NOW", /* @__PURE__ */ new Set(["DATETIME", "CREATED_TIME", "UPDATED_TIME"])],
10971
- ["LOGINUSER", /* @__PURE__ */ new Set(["CREATOR", "MODIFIER", "USER_SELECT"])]
11059
+ ["LOGINUSER", /* @__PURE__ */ new Set(["CREATOR", "MODIFIER", "USER_SELECT"])],
11060
+ ["PRIMARY_ORGANIZATION", /* @__PURE__ */ new Set(["ORGANIZATION_SELECT"])]
10972
11061
  ]);
10973
11062
  var LEGACY_KINTONE_FUNCTION_OPERATORS = /* @__PURE__ */ new Map([
10974
11063
  ["TODAY", new Set(RANGE_AND_EQUALITY)],
10975
11064
  ["NOW", new Set(RANGE_AND_EQUALITY)],
10976
- ["LOGINUSER", /* @__PURE__ */ new Set(["in", "not in"])]
11065
+ ["LOGINUSER", /* @__PURE__ */ new Set(["in", "not in"])],
11066
+ ["PRIMARY_ORGANIZATION", /* @__PURE__ */ new Set(["in", "not in"])]
10977
11067
  ]);
10978
11068
  var EQUALITY_IN = ["=", "!=", "in", "not in"];
10979
11069
  var NATIVE_OPERATORS = /* @__PURE__ */ new Map([
@@ -15666,7 +15756,7 @@ async function executeParsedStatement(stmt, client, options, cacheContext) {
15666
15756
  }
15667
15757
  assertApplyScope("phase15b", stmt);
15668
15758
  assertApplyExecutionScope("phase15b", stmt);
15669
- validateKlikeStatement(stmt);
15759
+ validateStatementStatic(stmt);
15670
15760
  if (stmt.type !== "EXPLAIN") {
15671
15761
  await validateStatementGroupingPlanning(stmt, client, cacheContext);
15672
15762
  }
@@ -16137,7 +16227,7 @@ function statementHasApplyMutation(statement) {
16137
16227
  async function executeBatchStatement(stmt, info, client, options, cacheContext, tempTables, variables) {
16138
16228
  if (stmt.type === "SET_VARIABLE") {
16139
16229
  const resolvedStmt2 = resolveBatchVariableReferences(stmt, variables);
16140
- validateKlikeStatement(resolvedStmt2);
16230
+ validateStatementStatic(resolvedStmt2);
16141
16231
  await assertRelativeDateExecutionPlan(resolvedStmt2, client, cacheContext);
16142
16232
  if (resolvedStmt2.expr.type === "ARRAY") {
16143
16233
  variables.set(stmt.name, {
@@ -16194,7 +16284,7 @@ async function executeBatchStatement(stmt, info, client, options, cacheContext,
16194
16284
  const resolvedStmt = resolveBatchVariableReferences(stmt, variables);
16195
16285
  assertApplyScope("phase15b", resolvedStmt);
16196
16286
  assertApplyExecutionScope("phase15b", resolvedStmt);
16197
- validateKlikeStatement(resolvedStmt);
16287
+ validateStatementStatic(resolvedStmt);
16198
16288
  await assertRelativeDateExecutionPlan(resolvedStmt, client, cacheContext);
16199
16289
  if (resolvedStmt.type === "VALIDATE") {
16200
16290
  const result = await executeExistingRecordValidationCore(
@@ -18162,18 +18252,20 @@ function rememberSelectWhereCapability(stmt, capability) {
18162
18252
  }
18163
18253
  function isCountStarTotalCountEligible(stmt, whereCapability) {
18164
18254
  if (whereCapability.capability !== "EXACT_PUSHDOWN") return false;
18165
- if (stmt.columns.length !== 1) return false;
18166
- const column = stmt.columns[0];
18167
- if (column?.type !== "AGGREGATE" || column.func !== "COUNT" || column.distinct || column.arg.type !== "WILDCARD") {
18168
- return false;
18169
- }
18255
+ const countColumns = stmt.columns.filter(
18256
+ (column) => column.type === "AGGREGATE" && column.func === "COUNT" && !column.distinct && column.arg.type === "WILDCARD"
18257
+ );
18258
+ if (countColumns.length !== 1) return false;
18259
+ if (stmt.columns.some(
18260
+ (column) => column !== countColumns[0] && column.type !== "LITERAL_COL"
18261
+ )) return false;
18170
18262
  return !stmt.distinct && normalizeGroupingSpec(stmt).type === "NONE" && stmt.having === null && stmt.joins.length === 0 && stmt.from.cteName === null && !stmt.from.subtableCode && stmt.limit === null && stmt.offset === null;
18171
18263
  }
18172
18264
  function isValidTotalCount(value) {
18173
18265
  return typeof value === "string" && /^(?:0|[1-9]\d*)$/.test(value);
18174
18266
  }
18175
18267
  async function tryCountStarWithTotalCount(stmt, client) {
18176
- const countColumn = stmt.columns[0];
18268
+ const countColumn = stmt.columns.find((column) => column.type === "AGGREGATE");
18177
18269
  if (countColumn?.type !== "AGGREGATE") return null;
18178
18270
  const baseQuery = stmt.where === null ? "" : whereToKintone(stmt.where);
18179
18271
  const response = await client.getRecords({
@@ -18184,11 +18276,15 @@ async function tryCountStarWithTotalCount(stmt, client) {
18184
18276
  });
18185
18277
  if (response.searchAborted) throw new SearchAbortedError();
18186
18278
  if (!isValidTotalCount(response.totalCount)) return null;
18187
- const column = countColumn.alias ?? "COUNT(*)";
18279
+ const countKey = countColumn.alias ?? "COUNT(*)";
18280
+ const projected = project(
18281
+ [{ [countKey]: response.totalCount }],
18282
+ stmt.columns
18283
+ );
18188
18284
  return {
18189
18285
  type: "SELECT",
18190
- rows: [{ [column]: response.totalCount }],
18191
- columns: [column],
18286
+ rows: projected.rows,
18287
+ columns: projected.columns,
18192
18288
  rowCount: 1,
18193
18289
  warnings: []
18194
18290
  };
@@ -18364,7 +18460,7 @@ async function executeUnion(stmt, client, options, cacheContext, captureColumnMe
18364
18460
  captureColumnMeta,
18365
18461
  forLibraryCapture
18366
18462
  ) : executeSelect(
18367
- stmt.left,
18463
+ markCountTotalCountRoot(stmt.left),
18368
18464
  client,
18369
18465
  effectiveOptions,
18370
18466
  cacheContext,
@@ -18373,7 +18469,7 @@ async function executeUnion(stmt, client, options, cacheContext, captureColumnMe
18373
18469
  forLibraryCapture
18374
18470
  ),
18375
18471
  executeSelect(
18376
- stmt.right,
18472
+ markCountTotalCountRoot(stmt.right),
18377
18473
  client,
18378
18474
  effectiveOptions,
18379
18475
  cacheContext,
@@ -21950,7 +22046,7 @@ function parseSql(sql, enableImport = false) {
21950
22046
  const tokens = new Lexer(sql).tokenize();
21951
22047
  const stmt = new Parser(tokens, { import: enableImport }).parse();
21952
22048
  assertApplyScope("phase15b", stmt);
21953
- validateKlikeStatement(stmt);
22049
+ validateStatementStatic(stmt);
21954
22050
  return stmt;
21955
22051
  } catch (e) {
21956
22052
  if (e instanceof LexError || e instanceof ParseError) {
@@ -22553,7 +22649,7 @@ async function buildBatchExplainPlans(sql, client, injectedVariables, cacheConte
22553
22649
  for (let i = 0; i < statements.length; i++) {
22554
22650
  const stmt = statements[i];
22555
22651
  const planStmt = stmt.type === "SET_VARIABLE" ? stmt.expr.type === "SCALAR_SUBQUERY" ? { ...stmt, expr: resolveBatchVariableReferences(stmt.expr, variables) } : stmt : resolveBatchVariableReferences(stmt, variables);
22556
- validateKlikeStatement(planStmt);
22652
+ validateStatementStatic(planStmt);
22557
22653
  const relativeDatePlan = await resolveRelativeDateExecutionPlan(planStmt, client, invocationCacheContext);
22558
22654
  const whereAnalysis = await buildExplainWhereAnalysis(
22559
22655
  planStmt,
@@ -23050,7 +23146,7 @@ function buildUnionPlan(stmt, capabilities, orderPlans, plainGroupByPlans) {
23050
23146
  const lines = [];
23051
23147
  selects.forEach((sel, i) => {
23052
23148
  if (i > 0) lines.push("");
23053
- lines.push(...buildSelectPlan(sel, `[union:${i + 1}]`, capabilities, orderPlans, plainGroupByPlans, false));
23149
+ lines.push(...buildSelectPlan(sel, `[union:${i + 1}]`, capabilities, orderPlans, plainGroupByPlans, true));
23054
23150
  });
23055
23151
  return lines;
23056
23152
  }
@@ -23506,13 +23602,13 @@ var OperationCancelledError = class extends Error {
23506
23602
  function parseSqlStatement(sql, capabilities = {}) {
23507
23603
  const tokens = new Lexer(sql).tokenize();
23508
23604
  const stmt = new Parser(tokens, capabilities).parse();
23509
- validateKlikeStatement(stmt);
23605
+ validateStatementStatic(stmt);
23510
23606
  return stmt;
23511
23607
  }
23512
23608
  function parseSqlStatements(sql, capabilities = {}) {
23513
23609
  const tokens = new Lexer(sql).tokenize();
23514
23610
  const statements = new Parser(tokens, capabilities).parseStatements();
23515
- statements.forEach(validateKlikeStatement);
23611
+ statements.forEach(validateStatementStatic);
23516
23612
  return statements;
23517
23613
  }
23518
23614