@rex0220/kintone-sql-tools 3.78.0 → 3.79.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
@@ -16622,7 +16622,8 @@ __export(index_exports, {
16622
16622
  runWithArgv: () => runWithArgv,
16623
16623
  shouldExitOnEmpty: () => shouldExitOnEmpty,
16624
16624
  toCliImportError: () => toCliImportError,
16625
- writeBatchOutput: () => writeBatchOutput
16625
+ writeBatchOutput: () => writeBatchOutput,
16626
+ writeSingleSelectWarnings: () => writeSingleSelectWarnings
16626
16627
  });
16627
16628
  module.exports = __toCommonJS(index_exports);
16628
16629
  var import_fs3 = require("fs");
@@ -35211,6 +35212,15 @@ function getSelectColumnMeta(result) {
35211
35212
  }
35212
35213
  var materializedMetaByValidationResult = /* @__PURE__ */ new WeakMap();
35213
35214
  var importSourceByDmlStatement = /* @__PURE__ */ new WeakMap();
35215
+ var sourceWarningsByDmlStatement = /* @__PURE__ */ new WeakMap();
35216
+ function rememberDmlSourceWarnings(statement, warnings) {
35217
+ if (!warnings?.length) return;
35218
+ sourceWarningsByDmlStatement.set(statement, [...new Set(warnings)]);
35219
+ }
35220
+ function outcomeWithResultWarnings(statement, result) {
35221
+ const warnings = sourceWarningsByDmlStatement.get(statement);
35222
+ return { result, ...warnings?.length ? { warnings } : {} };
35223
+ }
35214
35224
  var statementEvaluationContextKey = /* @__PURE__ */ Symbol("statementEvaluationContext");
35215
35225
  var importSourceMaterializedCallbackKey = /* @__PURE__ */ Symbol("importSourceMaterializedCallback");
35216
35226
  var nativeUpsertExecutionKey = /* @__PURE__ */ Symbol("nativeUpsertExecution");
@@ -36011,13 +36021,17 @@ async function executeBatch(sql, client, options = {}) {
36011
36021
  }
36012
36022
  }
36013
36023
  metrics.elapsedMs = Date.now() - startedAt;
36024
+ const warnings = [.../* @__PURE__ */ new Set([
36025
+ ...dialect1Warnings,
36026
+ ...results.flatMap((statement) => statement.warnings ?? [])
36027
+ ])];
36014
36028
  const batchResult = {
36015
36029
  ok: results.every((r) => r.status === "success" || r.skippedReason === "exit"),
36016
36030
  statementCount: statements.length,
36017
36031
  statements: results,
36018
36032
  analysis,
36019
36033
  metrics,
36020
- ...dialect1Warnings.length > 0 ? { warnings: dialect1Warnings } : {}
36034
+ ...warnings.length > 0 ? { warnings } : {}
36021
36035
  };
36022
36036
  const observer = options[batchCompletionObserverKey];
36023
36037
  if (observer) {
@@ -36128,7 +36142,7 @@ async function executeBatchStatement(context) {
36128
36142
  }
36129
36143
  await assertRelativeDateExecutionPlan(resolvedStmt, client, cacheContext);
36130
36144
  if (resolvedStmt.type === "VALIDATE") {
36131
- const result = await executeExistingRecordValidationCore(
36145
+ const result2 = await executeExistingRecordValidationCore(
36132
36146
  resolvedStmt,
36133
36147
  client,
36134
36148
  { ...options, onLimitReached: "error" },
@@ -36138,19 +36152,20 @@ async function executeBatchStatement(context) {
36138
36152
  appendValidationErrors(
36139
36153
  tempTables,
36140
36154
  resolvedStmt.errorTable,
36141
- result.columns,
36142
- result.rows,
36155
+ result2.columns,
36156
+ result2.rows,
36143
36157
  options.tempTableMaxRows ?? TEMP_TABLE_MAX_ROWS,
36144
- materializedMetaBySelectResult.get(result) ?? existingValidationColumnMeta(resolvedStmt.summary === true)
36158
+ materializedMetaBySelectResult.get(result2) ?? existingValidationColumnMeta(resolvedStmt.summary === true)
36145
36159
  );
36146
36160
  }
36147
- return { result };
36161
+ return { result: result2 };
36148
36162
  }
36149
36163
  if (resolvedStmt.type === "IMPORT") {
36150
- return { result: await executeImport(resolvedStmt, client, options, cacheContext, tempTables) };
36164
+ const result2 = await executeImport(resolvedStmt, client, options, cacheContext, tempTables);
36165
+ return outcomeWithResultWarnings(resolvedStmt, result2);
36151
36166
  }
36152
36167
  if ("validateOnly" in resolvedStmt && resolvedStmt.validateOnly === true) {
36153
- const result = await executeDmlValidation(
36168
+ const result2 = await executeDmlValidation(
36154
36169
  resolvedStmt,
36155
36170
  client,
36156
36171
  { ...options, onLimitReached: "error" },
@@ -36162,25 +36177,24 @@ async function executeBatchStatement(context) {
36162
36177
  appendValidationErrors(
36163
36178
  tempTables,
36164
36179
  resolvedStmt.validationErrorTable,
36165
- result.columns,
36166
- result.errors,
36180
+ result2.columns,
36181
+ result2.errors,
36167
36182
  options.tempTableMaxRows ?? TEMP_TABLE_MAX_ROWS,
36168
- materializedMetaByValidationResult.get(result) ?? /* @__PURE__ */ new Map()
36183
+ materializedMetaByValidationResult.get(result2) ?? /* @__PURE__ */ new Map()
36169
36184
  );
36170
36185
  }
36171
- return { result };
36186
+ return outcomeWithResultWarnings(resolvedStmt, result2);
36172
36187
  }
36173
36188
  if ("onErrorSkip" in resolvedStmt && resolvedStmt.onErrorSkip === true) {
36174
- return {
36175
- result: await executeOnErrorSkip(
36176
- resolvedStmt,
36177
- client,
36178
- { ...options, onLimitReached: "error" },
36179
- cacheContext,
36180
- tempTables,
36181
- info.index + 1
36182
- )
36183
- };
36189
+ const result2 = await executeOnErrorSkip(
36190
+ resolvedStmt,
36191
+ client,
36192
+ { ...options, onLimitReached: "error" },
36193
+ cacheContext,
36194
+ tempTables,
36195
+ info.index + 1
36196
+ );
36197
+ return outcomeWithResultWarnings(resolvedStmt, result2);
36184
36198
  }
36185
36199
  if (resolvedStmt.type === "CREATE_TEMP_TABLE") {
36186
36200
  const materializeOptions = {
@@ -36188,13 +36202,17 @@ async function executeBatchStatement(context) {
36188
36202
  maxRecords: options.tempTableMaxRows ?? TEMP_TABLE_MAX_ROWS,
36189
36203
  onLimitReached: "error"
36190
36204
  };
36191
- const result = await runSelectLike(resolvedStmt.query, client, materializeOptions, cacheContext, tempTables);
36205
+ const result2 = await runSelectLike(resolvedStmt.query, client, materializeOptions, cacheContext, tempTables);
36192
36206
  tempTables.set(resolvedStmt.name, {
36193
- rows: result.rows,
36194
- columns: result.columns,
36195
- columnMeta: materializedMetaBySelectResult.get(result)
36207
+ rows: result2.rows,
36208
+ columns: result2.columns,
36209
+ columnMeta: materializedMetaBySelectResult.get(result2)
36196
36210
  });
36197
- return { tempTable: resolvedStmt.name, rowCount: result.rows.length };
36211
+ return {
36212
+ tempTable: resolvedStmt.name,
36213
+ rowCount: result2.rows.length,
36214
+ ...result2.warnings?.length ? { warnings: [...result2.warnings] } : {}
36215
+ };
36198
36216
  }
36199
36217
  if (stmt.type === "DROP_TEMP_TABLE") {
36200
36218
  tempTables.delete(stmt.name);
@@ -36210,12 +36228,12 @@ async function executeBatchStatement(context) {
36210
36228
  }
36211
36229
  }
36212
36230
  if (resolvedStmt.type === "ASSERT") {
36213
- const result = await executeAssert(resolvedStmt, client, options, cacheContext, tempTables);
36214
- return result.warning !== void 0 ? { result } : {};
36231
+ const result2 = await executeAssert(resolvedStmt, client, options, cacheContext, tempTables);
36232
+ return result2.warning !== void 0 ? { result: result2 } : {};
36215
36233
  }
36216
36234
  if (resolvedStmt.type === "EXIT") {
36217
- const result = await executeExit(resolvedStmt, client, options, cacheContext, tempTables);
36218
- return { result, ...result.exited ? { exitTriggered: true } : {} };
36235
+ const result2 = await executeExit(resolvedStmt, client, options, cacheContext, tempTables);
36236
+ return { result: result2, ...result2.exited ? { exitTriggered: true } : {} };
36219
36237
  }
36220
36238
  if (info.tempTablesReferenced.length > 0) {
36221
36239
  if (resolvedStmt.type === "SELECT" || resolvedStmt.type === "UNION") {
@@ -36234,17 +36252,20 @@ async function executeBatchStatement(context) {
36234
36252
  return { result: await executeWith(resolvedStmt, client, options, cacheContext, tempTables) };
36235
36253
  }
36236
36254
  if (resolvedStmt.type === "INSERT_SELECT") {
36237
- return { result: await executeInsertSelect(resolvedStmt, client, options, cacheContext, tempTables) };
36255
+ const result2 = await executeInsertSelect(resolvedStmt, client, options, cacheContext, tempTables);
36256
+ return outcomeWithResultWarnings(resolvedStmt, result2);
36238
36257
  }
36239
36258
  if (resolvedStmt.type === "UPSERT_SELECT") {
36240
- return { result: await executeUpsertSelect(resolvedStmt, client, options, cacheContext, tempTables) };
36259
+ const result2 = await executeUpsertSelect(resolvedStmt, client, options, cacheContext, tempTables);
36260
+ return outcomeWithResultWarnings(resolvedStmt, result2);
36241
36261
  }
36242
36262
  if (resolvedStmt.type === "UPDATE" && resolvedStmt.from?.cteName != null) {
36243
36263
  return { result: await executeUpdate(resolvedStmt, client, options, cacheContext, tempTables) };
36244
36264
  }
36245
36265
  throw new Error(`ArgumentError: temp table references in ${stmt.type} are not supported yet.`);
36246
36266
  }
36247
- return { result: await executeParsedStatement(resolvedStmt, client, options, cacheContext) };
36267
+ const result = await executeParsedStatement(resolvedStmt, client, options, cacheContext);
36268
+ return outcomeWithResultWarnings(resolvedStmt, result);
36248
36269
  }
36249
36270
  async function runSelectLike(query, client, options, cacheContext, tempTables) {
36250
36271
  if (query.type === "WITH") {
@@ -36757,7 +36778,8 @@ async function buildWhereFieldSemanticsResolver(stmt, client, cacheContext, mate
36757
36778
  return fromPhysical(stmt.from, field.field, true);
36758
36779
  }
36759
36780
  const matches = tables.flatMap((table) => {
36760
- const semantics = table.cteName !== null ? resolveMaterializedColumnMeta(materializedTables?.get(table.cteName), field.field)?.semantics : fromPhysical(table, field.field, true);
36781
+ const materialized = table.cteName !== null ? materializedTables?.get(table.cteName) : void 0;
36782
+ const semantics = table.cteName !== null ? resolveMaterializedColumn(materialized, field.field) !== void 0 ? resolveMaterializedColumnMeta(materialized, field.field)?.semantics ?? syntheticSemantics("string") : void 0 : fromPhysical(table, field.field, true);
36761
36783
  return semantics ? [semantics] : [];
36762
36784
  });
36763
36785
  if (matches.length === 1) return matches[0];
@@ -37806,9 +37828,10 @@ function collectB86Subqueries(stmt) {
37806
37828
  }
37807
37829
  return queries;
37808
37830
  }
37809
- async function validateB86SelectFieldCodes(stmt, client, cteCache, cacheContext) {
37831
+ async function validateB86SelectFieldCodes(stmt, client, cteCache, cacheContext, cachedPhysicalFieldsOnly = false) {
37810
37832
  const tables = [stmt.from, ...stmt.joins.map((join3) => join3.table)];
37811
37833
  const materializedByTable = /* @__PURE__ */ new Map();
37834
+ const unavailableMaterializedTables = /* @__PURE__ */ new Set();
37812
37835
  const effectiveAliases = /* @__PURE__ */ new Set();
37813
37836
  for (const table of tables) {
37814
37837
  const alias = effectiveTableAlias(table);
@@ -37822,6 +37845,10 @@ async function validateB86SelectFieldCodes(stmt, client, cteCache, cacheContext)
37822
37845
  if (table.cteName === null || table.cteName === NO_FROM_CTE_NAME) continue;
37823
37846
  const materialized = cteCache.get(table.cteName);
37824
37847
  if (!materialized) {
37848
+ if (cachedPhysicalFieldsOnly) {
37849
+ unavailableMaterializedTables.add(table);
37850
+ continue;
37851
+ }
37825
37852
  throw new Error(`ArgumentError: materialized source ${table.cteName} is not available.`);
37826
37853
  }
37827
37854
  if (materialized.rows.length > 0 && materialized.columns.length === 0) {
@@ -37838,6 +37865,16 @@ async function validateB86SelectFieldCodes(stmt, client, cteCache, cacheContext)
37838
37865
  }
37839
37866
  const schemas = /* @__PURE__ */ new Map();
37840
37867
  await Promise.all(tables.map(async (table) => {
37868
+ if (unavailableMaterializedTables.has(table)) {
37869
+ schemas.set(table, {
37870
+ table,
37871
+ label: b86SourceLabel(table),
37872
+ validCodes: /* @__PURE__ */ new Set(),
37873
+ authoritative: false,
37874
+ schemaUnavailable: true
37875
+ });
37876
+ return;
37877
+ }
37841
37878
  const materialized = materializedByTable.get(table);
37842
37879
  if (materialized) {
37843
37880
  schemas.set(table, {
@@ -37850,12 +37887,12 @@ async function validateB86SelectFieldCodes(stmt, client, cteCache, cacheContext)
37850
37887
  return;
37851
37888
  }
37852
37889
  if (table.cteName === NO_FROM_CTE_NAME) return;
37853
- const defs = await getFieldsCached(table.appId, client, cacheContext);
37890
+ const defs = cachedPhysicalFieldsOnly ? await getFieldsIfCached(table.appId, cacheContext) : await getFieldsCached(table.appId, client, cacheContext);
37854
37891
  schemas.set(table, {
37855
37892
  table,
37856
37893
  label: b86SourceLabel(table),
37857
- validCodes: new Set(defs.map((def) => def.code)),
37858
- authoritative: defs.length > 0,
37894
+ validCodes: new Set((defs ?? []).map((def) => def.code)),
37895
+ authoritative: defs !== null && defs.length > 0,
37859
37896
  schemaUnavailable: false
37860
37897
  });
37861
37898
  }));
@@ -41767,6 +41804,8 @@ async function executeImport(stmt, client, options, cacheContext, tempTables) {
41767
41804
  importSourceByDmlStatement.set(generated, executionSource);
41768
41805
  const withAudit = (result2) => {
41769
41806
  if (executionSource.audit) Object.assign(result2, { importAudit: executionSource.audit });
41807
+ const warnings = sourceWarningsByDmlStatement.get(generated);
41808
+ if (warnings?.length) sourceWarningsByDmlStatement.set(stmt, warnings);
41770
41809
  return result2;
41771
41810
  };
41772
41811
  if (generated.validateOnly) {
@@ -42056,6 +42095,7 @@ async function materializeDmlSource(stmt, client, options, cacheContext, tempTab
42056
42095
  const imported = importSourceByDmlStatement.get(stmt);
42057
42096
  if (!imported) {
42058
42097
  const selected2 = tempTables && tempTables.size > 0 ? await executeQueryWithCte(stmt.select, client, options, tempTables, cacheContext, true) : await executeSelect(stmt.select, client, options, cacheContext, void 0, true);
42098
+ rememberDmlSourceWarnings(stmt, selected2.warnings);
42059
42099
  return { rows: selected2.rows, columns: selected2.columns, columnMeta: materializedMetaBySelectResult.get(selected2) };
42060
42100
  }
42061
42101
  const payload = await loadImportSource(imported.handle, imported.cache);
@@ -42071,6 +42111,7 @@ async function materializeDmlSource(stmt, client, options, cacheContext, tempTab
42071
42111
  const tables = new Map(tempTables ?? []);
42072
42112
  tables.set(IMPORT_PROJECTION_SOURCE, raw);
42073
42113
  const selected = await executeQueryWithCte(projection, client, { ...options, onLimitReached: "error" }, tables, cacheContext, true);
42114
+ rememberDmlSourceWarnings(stmt, selected.warnings);
42074
42115
  return { rows: selected.rows, columns: selected.columns, columnMeta: materializedMetaBySelectResult.get(selected) };
42075
42116
  }
42076
42117
  var dmlSourceMaterializer = { materialize: materializeDmlSource };
@@ -43503,6 +43544,7 @@ async function buildExplainWhereAnalysis(query, client, cacheContext, maxRecords
43503
43544
  const capabilities = /* @__PURE__ */ new Map();
43504
43545
  const orderPlans = /* @__PURE__ */ new Map();
43505
43546
  const plainGroupByPlans = /* @__PURE__ */ new Map();
43547
+ const explainSelectsForColumnCheck = [];
43506
43548
  const seen = /* @__PURE__ */ new Set();
43507
43549
  const sharedRelativeDatePlan = relativeDatePlan ?? await resolveRelativeDateExecutionPlan(query, tracedClient, cacheContext);
43508
43550
  const relativeNodeFor = (source) => sharedRelativeDatePlan.nodes.find(
@@ -43636,6 +43678,13 @@ async function buildExplainWhereAnalysis(query, client, cacheContext, maxRecords
43636
43678
  if (typed["type"] === "WITH") {
43637
43679
  const withStatement = node;
43638
43680
  for (const cte of withStatement.ctes) {
43681
+ if (cte.recursiveSpec) {
43682
+ const columns2 = recursiveOutputColumns(cte);
43683
+ if (cte.recursiveSpec.cycle) columns2.push(cte.recursiveSpec.cycle.markColumn);
43684
+ explainRelations.set(cte.name, { rows: [], columns: columns2 });
43685
+ await preflightExplainRelations(cte.query);
43686
+ continue;
43687
+ }
43639
43688
  await preflightExplainRelations(cte.query);
43640
43689
  if (cte.query.type === "GENERATE_SERIES") {
43641
43690
  if (cte.query.args.some((arg) => arg.type === "VARIABLE")) {
@@ -43671,6 +43720,8 @@ async function buildExplainWhereAnalysis(query, client, cacheContext, maxRecords
43671
43720
  if (typed["type"] === "SELECT") {
43672
43721
  const select = node;
43673
43722
  await bindProjectedNamesForSelectWithSchemas(select, explainRelations, tracedClient, cacheContext);
43723
+ await validateB86SelectFieldCodes(select, tracedClient, explainRelations, cacheContext, true);
43724
+ explainSelectsForColumnCheck.push(select);
43674
43725
  analyzeStaticSelectRows(select);
43675
43726
  for (const column of select.columns) {
43676
43727
  if (column.type === "SCALAR_SUBQUERY_COL") await preflightExplainRelations(column.query);
@@ -43734,7 +43785,8 @@ async function buildExplainWhereAnalysis(query, client, cacheContext, maxRecords
43734
43785
  const { resolver, rewrites } = await normalizeSelectChoiceEquality(
43735
43786
  select,
43736
43787
  tracedClient,
43737
- cacheContext
43788
+ cacheContext,
43789
+ explainRelations
43738
43790
  );
43739
43791
  if (rewrites.length > 0) explainChoiceEqualityRewrites.set(select, rewrites);
43740
43792
  const capability = classifyWhereCapability(select.where, resolver);
@@ -43932,6 +43984,9 @@ async function buildExplainWhereAnalysis(query, client, cacheContext, maxRecords
43932
43984
  }));
43933
43985
  }
43934
43986
  }
43987
+ for (const select of explainSelectsForColumnCheck) {
43988
+ await validateB86SelectFieldCodes(select, tracedClient, explainRelations, cacheContext, true);
43989
+ }
43935
43990
  return {
43936
43991
  capabilities,
43937
43992
  orderPlans,
@@ -46704,6 +46759,7 @@ function buildBatchEnvelope(batch, options = {}) {
46704
46759
  if (s.status === "skipped" && s.skippedReason) entry.skippedReason = s.skippedReason;
46705
46760
  if (s.tempTable !== void 0) entry.tempTable = s.tempTable;
46706
46761
  if (s.rowCount !== void 0) entry.rowCount = s.rowCount;
46762
+ if (s.warnings?.length) entry.warnings = s.warnings;
46707
46763
  if (s.status === "success" && s.result?.type === "SELECT") {
46708
46764
  totalRows += s.result.rowCount;
46709
46765
  if (maxTotalRecords !== void 0 && totalRows > maxTotalRecords) {
@@ -46760,8 +46816,9 @@ function buildBatchEnvelope(batch, options = {}) {
46760
46816
  statementCount: batch.statementCount,
46761
46817
  statements,
46762
46818
  results,
46763
- // バッチ全体の警告(仕様 §6.2)。文ごとの警告は results[].warnings に入る
46764
- warnings: []
46819
+ // バッチ全体の警告(仕様 §6.2)=dialect 1 の警告 + 結果セットを持たない文(CREATE TEMP TABLE・
46820
+ // SELECT-based DML)の実行時警告(B188・文順・重複なし)。SELECT の文ごとの警告は従来どおり results[].warnings
46821
+ warnings: batch.warnings ?? []
46765
46822
  };
46766
46823
  }
46767
46824
 
@@ -49323,12 +49380,23 @@ function buildBatchStatementSummary(s) {
49323
49380
  }
49324
49381
  }
49325
49382
  if (s.status === "skipped" && s.skippedReason) parts.push(`reason=${s.skippedReason}`);
49383
+ const warnings = s.warnings ?? (s.result?.type === "SELECT" ? s.result.warnings : void 0);
49384
+ if (s.status === "success" && warnings) {
49385
+ for (const warning of warnings) parts.push(`warning=${warning}`);
49386
+ }
49326
49387
  return parts.join(" ");
49327
49388
  }
49328
49389
  function buildSelectSummary(result) {
49329
49390
  const validateSummary = result.validateStats ? ` errorRecords=${result.validateStats.errorRecords} errorCount=${result.validateStats.errorCount}` : "";
49330
49391
  return `rowCount=${result.rowCount}${validateSummary}`;
49331
49392
  }
49393
+ function writeSingleSelectWarnings(result, format, quiet) {
49394
+ if (quiet || format === "json") return;
49395
+ for (const warning of result.warnings ?? []) {
49396
+ process.stderr.write(`warning=${warning}
49397
+ `);
49398
+ }
49399
+ }
49332
49400
  function buildBatchDmlConfirmMessage(analysis) {
49333
49401
  const lines = ["[DML Confirm] batch"];
49334
49402
  for (const s of analysis.statements) {
@@ -50792,6 +50860,7 @@ query=${label}`);
50792
50860
  process.stderr.write(`${buildSelectSummary(result)}
50793
50861
  `);
50794
50862
  }
50863
+ writeSingleSelectWarnings(result, format, quiet);
50795
50864
  if (exportPlan) {
50796
50865
  const exportCode = runSingleSelectCliExport(exportPlan, result, quiet);
50797
50866
  if (exportCode !== 0) return exportCode;
@@ -50852,5 +50921,6 @@ if (isDirectCliRun()) {
50852
50921
  runWithArgv,
50853
50922
  shouldExitOnEmpty,
50854
50923
  toCliImportError,
50855
- writeBatchOutput
50924
+ writeBatchOutput,
50925
+ writeSingleSelectWarnings
50856
50926
  });