@rex0220/kintone-sql-tools 3.64.0 → 3.65.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
@@ -10008,6 +10008,10 @@ function resolveField(field, row, resolveFieldType, resolveFieldSemantics2) {
10008
10008
  if (field.type === "ARITH_FIELD") return String(evalArithExpr(field.expr, row));
10009
10009
  if (field.type === "CASE_FIELD") return evalCaseWhen(field.expr, row, resolveFieldType, resolveFieldSemantics2);
10010
10010
  if (field.type === "GROUPING_FIELD") return evalGroupingRef(field.ref, row);
10011
+ if (field.aggregateRef) {
10012
+ const ref = field.aggregateRef;
10013
+ return resolveFieldRef(row, aggregateSyntheticName(ref.func, ref.distinct, ref.arg));
10014
+ }
10011
10015
  const key = field.tableAlias ? `${field.tableAlias}.${field.field}` : field.field;
10012
10016
  return resolveFieldRef(row, key);
10013
10017
  }
@@ -14129,6 +14133,7 @@ async function deriveEmptyWildcardColumns(fields, subtableCode, loadProcessStatu
14129
14133
  // src/engine/process.ts
14130
14134
  var materializedSelectValues = /* @__PURE__ */ new WeakMap();
14131
14135
  var sourceRows = /* @__PURE__ */ new WeakMap();
14136
+ var UNRESOLVED_AGGREGATE_COMPARISON_WARNING = "\u6BD4\u8F03\u6761\u4EF6\u3067\u53C2\u7167\u3057\u305F\u96C6\u8A08\u5024\u3092\u78BA\u8A8D\u3067\u304D\u307E\u305B\u3093\u3002SELECT \u30EA\u30B9\u30C8\u306B\u540C\u3058\u96C6\u8A08\u5F0F\u3092\u542B\u3081\u3066\u304F\u3060\u3055\u3044\u3002";
14132
14137
  function asProcessingRow(source) {
14133
14138
  if (sourceRows.has(source)) return source;
14134
14139
  let row;
@@ -14177,6 +14182,31 @@ function getMaterializedLookupValue(row, key) {
14177
14182
  function getLegacyMaterializedValue(row, key) {
14178
14183
  return materializedSelectValues.has(row) ? void 0 : row[key];
14179
14184
  }
14185
+ function warnOnUnresolvedAggregateComparisons(node, rows, warnings) {
14186
+ if (!warnings || rows.length === 0) return;
14187
+ const keys = /* @__PURE__ */ new Set();
14188
+ const visit = (value) => {
14189
+ if (value === null || typeof value !== "object") return;
14190
+ if (Array.isArray(value)) {
14191
+ value.forEach(visit);
14192
+ return;
14193
+ }
14194
+ const record = value;
14195
+ if (record["type"] === "FIELD" && record["aggregateRef"] !== void 0) {
14196
+ const ref = record["aggregateRef"];
14197
+ keys.add(aggregateSyntheticName(ref.func, ref.distinct, ref.arg));
14198
+ return;
14199
+ }
14200
+ if (record["type"] === "SELECT" || record["type"] === "SCALAR_SUBQUERY") return;
14201
+ Object.values(record).forEach(visit);
14202
+ };
14203
+ visit(node);
14204
+ if ([...keys].some((key) => rows.some(
14205
+ (row) => getMaterializedLookupValue(row, key) === void 0 && row[key] === void 0
14206
+ ))) {
14207
+ warnings.add(UNRESOLVED_AGGREGATE_COMPARISON_WARNING);
14208
+ }
14209
+ }
14180
14210
  function havingEvaluationRow(row) {
14181
14211
  const lookups = materializedSelectValues.get(row)?.byLookupKey;
14182
14212
  if (!lookups || lookups.size === 0) return row;
@@ -15481,7 +15511,8 @@ function runFullScan(input) {
15481
15511
  tableColumns,
15482
15512
  hiddenQualifiedAliases,
15483
15513
  resolvedGroupingSpec,
15484
- plainGroupByPlan
15514
+ plainGroupByPlan,
15515
+ warnings
15485
15516
  } = input;
15486
15517
  const effectiveOrderSemantics = deriveOutputOrderSemantics(stmt.columns, aggregateSortKindResolver);
15487
15518
  for (const [key, value] of orderSemantics ?? []) effectiveOrderSemantics.set(key, value);
@@ -15537,7 +15568,9 @@ function runFullScan(input) {
15537
15568
  }
15538
15569
  );
15539
15570
  }
15571
+ warnOnUnresolvedAggregateComparisons(stmt.columns, rows, warnings);
15540
15572
  const resolveHavingSemantics = (field) => field.aggregateRef ? aggregateResultSemantics(field.aggregateRef, aggregateSortKindResolver) : havingFieldSemanticsResolver?.(field);
15573
+ warnOnUnresolvedAggregateComparisons(stmt.having, rows, warnings);
15541
15574
  rows = applyHaving(rows, stmt.having, havingFieldTypeResolver, resolveHavingSemantics);
15542
15575
  rows = applyWindow(
15543
15576
  rows,
@@ -18838,6 +18871,7 @@ async function assertDmlWhereCapability(stmt, client, cacheContext) {
18838
18871
  }
18839
18872
  async function executeSelect(stmt, client, options, cacheContext, cteCache, captureColumnMeta = false, forLibraryCapture = false, windowWarningContext = "DIRECT") {
18840
18873
  let result;
18874
+ const subqueryWarnings = /* @__PURE__ */ new Set();
18841
18875
  await validateSelectGroupingPlanning(stmt, client, cacheContext, cteCache);
18842
18876
  if (isNoFromSelect(stmt)) {
18843
18877
  result = executeNoFromSelect(stmt);
@@ -18867,7 +18901,7 @@ async function executeSelect(stmt, client, options, cacheContext, cteCache, capt
18867
18901
  cacheContext,
18868
18902
  cteCache
18869
18903
  );
18870
- await resolveSelectCaseSubqueries(stmt, client, options, cacheContext, cteCache);
18904
+ await resolveSelectCaseSubqueries(stmt, client, options, cacheContext, subqueryWarnings, cteCache);
18871
18905
  const whereCapability = rememberSelectWhereCapability(
18872
18906
  stmt,
18873
18907
  classifyWhereCapability(stmt.where, fieldSemanticsResolver)
@@ -18958,7 +18992,11 @@ async function executeSelect(stmt, client, options, cacheContext, cteCache, capt
18958
18992
  await inferSelectColumnMeta(stmt, result.columns, client, cacheContext, cteCache, forLibraryCapture)
18959
18993
  );
18960
18994
  }
18961
- return mergeSelectWarnings(result, [...defaultRangeWarnings, ...subtableFieldWarnings]);
18995
+ return mergeSelectWarnings(result, [
18996
+ ...subqueryWarnings,
18997
+ ...defaultRangeWarnings,
18998
+ ...subtableFieldWarnings
18999
+ ]);
18962
19000
  }
18963
19001
  function subtableGroupingAdvice(fieldName, owners) {
18964
19002
  if (owners.length === 1) {
@@ -20426,8 +20464,8 @@ async function executeFullScanSelect(stmt, client, options, cacheContext, cteCac
20426
20464
  const warnings = /* @__PURE__ */ new Set();
20427
20465
  const parallel = options.fetchParallel ?? 1;
20428
20466
  await Promise.all([
20429
- resolveSubqueries(stmt.where, client, options, cacheContext, cteCache),
20430
- resolveSubqueries(stmt.having, client, options, cacheContext, cteCache)
20467
+ resolveSubqueries(stmt.where, client, options, cacheContext, warnings, cteCache),
20468
+ resolveSubqueries(stmt.having, client, options, cacheContext, warnings, cteCache)
20431
20469
  ]);
20432
20470
  const [pushdownMeta, typedInFieldTypes, aggregateSortKindResolver] = await Promise.all([
20433
20471
  loadTypedPushdownMeta(stmt, client, cacheContext),
@@ -20461,7 +20499,14 @@ async function executeFullScanSelect(stmt, client, options, cacheContext, cteCac
20461
20499
  const mainBoundQuery = boundServerFunctionPlan?.queriesByAlias.get(
20462
20500
  stmt.from.alias
20463
20501
  ) ?? "";
20464
- const scalarCache = await resolveScalarColumns(stmt.columns, client, options, cacheContext, cteCache);
20502
+ const scalarCache = await resolveScalarColumns(
20503
+ stmt.columns,
20504
+ client,
20505
+ options,
20506
+ cacheContext,
20507
+ warnings,
20508
+ cteCache
20509
+ );
20465
20510
  const constantFalse = isConstantFalseWhere(stmt.where);
20466
20511
  const mainFetch = constantFalse ? Promise.resolve([]) : fetchTableRecordsForFullScan(
20467
20512
  stmt,
@@ -20565,7 +20610,8 @@ async function executeFullScanSelect(stmt, client, options, cacheContext, cteCac
20565
20610
  appliedKlikes: prefilterPlan?.appliedKlikes ?? pushdownPlan.appliedKlikes,
20566
20611
  ...prefilterPlan ? { residualWhere: prefilterPlan.residualWhere } : boundServerFunctionPlan ? { residualWhere: boundServerFunctionPlan.joinPlan.residualWhere } : {},
20567
20612
  resolvedGroupingSpec: resolvedGroupingSpecs.get(stmt),
20568
- plainGroupByPlan
20613
+ plainGroupByPlan,
20614
+ warnings
20569
20615
  });
20570
20616
  const columns = await restoreEmptyWildcardColumns(
20571
20617
  stmt,
@@ -20832,9 +20878,9 @@ async function executeFullScanWithCte(stmt, client, options, cteCache, cacheCont
20832
20878
  const warnings = /* @__PURE__ */ new Set();
20833
20879
  const parallel = options.fetchParallel ?? 1;
20834
20880
  await Promise.all([
20835
- resolveSubqueries(stmt.where, client, options, cacheContext, cteCache),
20836
- resolveSubqueries(stmt.having, client, options, cacheContext, cteCache),
20837
- resolveSelectCaseSubqueries(stmt, client, options, cacheContext, cteCache)
20881
+ resolveSubqueries(stmt.where, client, options, cacheContext, warnings, cteCache),
20882
+ resolveSubqueries(stmt.having, client, options, cacheContext, warnings, cteCache),
20883
+ resolveSelectCaseSubqueries(stmt, client, options, cacheContext, warnings, cteCache)
20838
20884
  ]);
20839
20885
  const whereCapability = classifyWhereCapability(stmt.where, choiceAndWindowResolver);
20840
20886
  if (whereCapability.capability === "UNSUPPORTED") {
@@ -20874,6 +20920,7 @@ async function executeFullScanWithCte(stmt, client, options, cteCache, cacheCont
20874
20920
  client,
20875
20921
  effectiveOptions,
20876
20922
  cacheContext,
20923
+ warnings,
20877
20924
  cteCache
20878
20925
  );
20879
20926
  const orderByMetaPromise = Promise.resolve(orderMeta);
@@ -24337,17 +24384,17 @@ function parseSql(sql, enableImport = false) {
24337
24384
  throw e;
24338
24385
  }
24339
24386
  }
24340
- async function resolveSubqueries(where, client, options, cacheContext, cteCache) {
24387
+ async function resolveSubqueries(where, client, options, cacheContext, warnings, cteCache) {
24341
24388
  const tasks = [];
24342
- collectSubqueryTasks(where, client, options, cacheContext, tasks, cteCache);
24389
+ collectSubqueryTasks(where, client, options, cacheContext, tasks, warnings, cteCache);
24343
24390
  await Promise.all(tasks);
24344
24391
  }
24345
- async function resolveSelectCaseSubqueries(stmt, client, options, cacheContext, cteCache) {
24392
+ async function resolveSelectCaseSubqueries(stmt, client, options, cacheContext, warnings, cteCache) {
24346
24393
  const tasks = [];
24347
24394
  for (const column of stmt.columns) {
24348
24395
  if (column.type !== "CASE_COL") continue;
24349
24396
  for (const branch of column.expr.branches) {
24350
- tasks.push(resolveSubqueries(branch.condition, client, options, cacheContext, cteCache));
24397
+ tasks.push(resolveSubqueries(branch.condition, client, options, cacheContext, warnings, cteCache));
24351
24398
  }
24352
24399
  }
24353
24400
  await Promise.all(tasks);
@@ -24358,19 +24405,21 @@ function runSubquery(query, client, options, cacheContext, cteCache) {
24358
24405
  }
24359
24406
  return executeSelect(query, client, options, cacheContext);
24360
24407
  }
24361
- function collectSubqueryTasks(where, client, options, cacheContext, tasks, cteCache) {
24408
+ function collectSubqueryTasks(where, client, options, cacheContext, tasks, warnings, cteCache) {
24362
24409
  if (where === null) return;
24363
24410
  switch (where.type) {
24364
24411
  case "BINARY": {
24365
24412
  const right = where.right;
24366
24413
  if (right.type === "SUBQUERY_IN_LIST") {
24367
24414
  tasks.push(runSubquery(right.query, client, options, cacheContext, cteCache).then((result) => {
24415
+ for (const warning of result.warnings ?? []) warnings.add(warning);
24368
24416
  const col = right.column ?? (result.columns[0] ?? "");
24369
24417
  right.resolved = new Set(result.rows.map((r) => r[col] ?? ""));
24370
24418
  }));
24371
24419
  }
24372
24420
  if (right.type === "SCALAR_SUBQUERY") {
24373
24421
  tasks.push(runSubquery(right.query, client, options, cacheContext, cteCache).then((result) => {
24422
+ for (const warning of result.warnings ?? []) warnings.add(warning);
24374
24423
  if (result.rowCount === 0) throw new Error("\u30B9\u30AB\u30E9\u30FC\u30B5\u30D6\u30AF\u30A8\u30EA\u304C\u5024\u3092\u8FD4\u3057\u307E\u305B\u3093\u3067\u3057\u305F");
24375
24424
  if (result.rowCount > 1) throw new Error("\u30B9\u30AB\u30E9\u30FC\u30B5\u30D6\u30AF\u30A8\u30EA\u304C\u8907\u6570\u884C\u3092\u8FD4\u3057\u307E\u3057\u305F\uFF081\u884C\u306E\u307F\u8A31\u53EF\uFF09");
24376
24425
  const col = result.columns[0] ?? "";
@@ -24380,16 +24429,17 @@ function collectSubqueryTasks(where, client, options, cacheContext, tasks, cteCa
24380
24429
  break;
24381
24430
  }
24382
24431
  case "LOGICAL":
24383
- collectSubqueryTasks(where.left, client, options, cacheContext, tasks, cteCache);
24384
- collectSubqueryTasks(where.right, client, options, cacheContext, tasks, cteCache);
24432
+ collectSubqueryTasks(where.left, client, options, cacheContext, tasks, warnings, cteCache);
24433
+ collectSubqueryTasks(where.right, client, options, cacheContext, tasks, warnings, cteCache);
24385
24434
  break;
24386
24435
  case "NOT":
24387
24436
  case "GROUP":
24388
- collectSubqueryTasks(where.expr, client, options, cacheContext, tasks, cteCache);
24437
+ collectSubqueryTasks(where.expr, client, options, cacheContext, tasks, warnings, cteCache);
24389
24438
  break;
24390
24439
  case "EXISTS": {
24391
24440
  const node = where;
24392
24441
  tasks.push(runSubquery(node.query, client, options, cacheContext, cteCache).then((result) => {
24442
+ for (const warning of result.warnings ?? []) warnings.add(warning);
24393
24443
  node.resolved = result.rowCount > 0;
24394
24444
  }));
24395
24445
  break;
@@ -24409,7 +24459,7 @@ async function resolveSetSubqueries(assignments, client, options, cacheContext)
24409
24459
  a.value = { type: "STRING", value: resolved };
24410
24460
  }
24411
24461
  }
24412
- async function resolveScalarColumns(columns, client, options, cacheContext, cteCache) {
24462
+ async function resolveScalarColumns(columns, client, options, cacheContext, warnings, cteCache) {
24413
24463
  const byQuery = /* @__PURE__ */ new Map();
24414
24464
  const pending = [];
24415
24465
  for (let i = 0; i < columns.length; i++) {
@@ -24419,6 +24469,7 @@ async function resolveScalarColumns(columns, client, options, cacheContext, cteC
24419
24469
  let promise = byQuery.get(key);
24420
24470
  if (!promise) {
24421
24471
  promise = runSubquery(col.query, client, options, cacheContext, cteCache).then((result) => {
24472
+ for (const warning of result.warnings ?? []) warnings.add(warning);
24422
24473
  if (result.rowCount === 0) throw new Error("\u30B9\u30AB\u30E9\u30FC\u30B5\u30D6\u30AF\u30A8\u30EA\u304C\u5024\u3092\u8FD4\u3057\u307E\u305B\u3093\u3067\u3057\u305F");
24423
24474
  if (result.rowCount > 1) throw new Error("\u30B9\u30AB\u30E9\u30FC\u30B5\u30D6\u30AF\u30A8\u30EA\u304C\u8907\u6570\u884C\u3092\u8FD4\u3057\u307E\u3057\u305F\uFF081\u884C\u306E\u307F\u8A31\u53EF\uFF09");
24424
24475
  const firstCol = result.columns[0] ?? "";