@rex0220/kintone-sql-tools 2.14.0 → 2.15.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
@@ -87,6 +87,7 @@ var KEYWORDS = /* @__PURE__ */ new Map([
87
87
  ["AVG", "AVG" /* AVG */],
88
88
  ["MAX", "MAX" /* MAX */],
89
89
  ["MIN", "MIN" /* MIN */],
90
+ ["GROUP_CONCAT", "GROUP_CONCAT" /* GROUP_CONCAT */],
90
91
  ["ASSERT", "ASSERT" /* ASSERT */],
91
92
  ["AND", "AND" /* AND */],
92
93
  ["OR", "OR" /* OR */],
@@ -1079,6 +1080,7 @@ var Parser = class {
1079
1080
  func: ref.func,
1080
1081
  distinct: ref.distinct,
1081
1082
  arg: ref.arg,
1083
+ ...ref.separator !== void 0 ? { separator: ref.separator } : {},
1082
1084
  alias: alias2
1083
1085
  };
1084
1086
  }
@@ -1450,7 +1452,8 @@ var Parser = class {
1450
1452
  ["SUM" /* SUM */]: "SUM",
1451
1453
  ["AVG" /* AVG */]: "AVG",
1452
1454
  ["MAX" /* MAX */]: "MAX",
1453
- ["MIN" /* MIN */]: "MIN"
1455
+ ["MIN" /* MIN */]: "MIN",
1456
+ ["GROUP_CONCAT" /* GROUP_CONCAT */]: "GROUP_CONCAT"
1454
1457
  };
1455
1458
  const kind = this.peek().kind;
1456
1459
  return map[kind] ?? null;
@@ -1462,12 +1465,29 @@ var Parser = class {
1462
1465
  const distinct = this.consume("DISTINCT" /* DISTINCT */);
1463
1466
  let arg;
1464
1467
  if (this.consume("*" /* STAR */)) {
1468
+ if (func === "GROUP_CONCAT") {
1469
+ throw new ParseError("GROUP_CONCAT(*) \u306F\u4F7F\u7528\u3067\u304D\u307E\u305B\u3093\u3002\u30D5\u30A3\u30FC\u30EB\u30C9\u307E\u305F\u306F\u5F0F\u3092\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044", this.prev());
1470
+ }
1465
1471
  arg = { type: "WILDCARD" };
1466
1472
  } else {
1467
1473
  arg = this.parseArithAddSub();
1468
1474
  }
1475
+ let separator;
1476
+ if (this.isSoftKeyword("SEPARATOR")) {
1477
+ const separatorToken = this.advance();
1478
+ if (func !== "GROUP_CONCAT") {
1479
+ throw new ParseError("SEPARATOR \u306F GROUP_CONCAT \u3067\u306E\u307F\u4F7F\u7528\u3067\u304D\u307E\u3059", separatorToken);
1480
+ }
1481
+ separator = this.expect("STRING" /* STRING */, "SEPARATOR \u306E\u5F8C\u306B\u306F\u6587\u5B57\u5217\u30EA\u30C6\u30E9\u30EB\u304C\u5FC5\u8981\u3067\u3059").value;
1482
+ }
1469
1483
  this.expect(")" /* RPAREN */);
1470
- return { type: "AGG_REF", func, distinct, arg };
1484
+ return {
1485
+ type: "AGG_REF",
1486
+ func,
1487
+ distinct,
1488
+ arg,
1489
+ ...separator !== void 0 ? { separator } : {}
1490
+ };
1471
1491
  }
1472
1492
  // ----------------------------------------------------------
1473
1493
  // FROM / JOIN
@@ -1745,10 +1765,20 @@ var Parser = class {
1745
1765
  const distinct = this.consume("DISTINCT" /* DISTINCT */);
1746
1766
  let argStr;
1747
1767
  if (this.consume("*" /* STAR */)) {
1768
+ if (aggFunc === "GROUP_CONCAT") {
1769
+ throw new ParseError("GROUP_CONCAT(*) \u306F\u4F7F\u7528\u3067\u304D\u307E\u305B\u3093\u3002\u30D5\u30A3\u30FC\u30EB\u30C9\u307E\u305F\u306F\u5F0F\u3092\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044", this.prev());
1770
+ }
1748
1771
  argStr = "*";
1749
1772
  } else {
1750
1773
  argStr = this.parseIdentifier();
1751
1774
  }
1775
+ if (this.isSoftKeyword("SEPARATOR")) {
1776
+ const separatorToken = this.advance();
1777
+ if (aggFunc !== "GROUP_CONCAT") {
1778
+ throw new ParseError("SEPARATOR \u306F GROUP_CONCAT \u3067\u306E\u307F\u4F7F\u7528\u3067\u304D\u307E\u3059", separatorToken);
1779
+ }
1780
+ this.expect("STRING" /* STRING */, "SEPARATOR \u306E\u5F8C\u306B\u306F\u6587\u5B57\u5217\u30EA\u30C6\u30E9\u30EB\u304C\u5FC5\u8981\u3067\u3059");
1781
+ }
1752
1782
  this.expect(")" /* RPAREN */);
1753
1783
  const syntheticName = distinct ? `${aggFunc}(DISTINCT ${argStr})` : `${aggFunc}(${argStr})`;
1754
1784
  return { type: "FIELD", tableAlias: null, field: syntheticName };
@@ -1842,16 +1872,25 @@ var Parser = class {
1842
1872
  // IN リストの値
1843
1873
  parseInValues() {
1844
1874
  const values = [];
1875
+ const invalidValueMessage = "IN \u30EA\u30B9\u30C8\u306B\u306F\u6587\u5B57\u5217\u3001\u6570\u5024\u3001\u307E\u305F\u306F\u30D0\u30C3\u30C1\u5909\u6570\u304C\u5FC5\u8981\u3067\u3059";
1845
1876
  do {
1846
1877
  const tok = this.advance();
1847
1878
  if (tok.kind === "STRING" /* STRING */) {
1848
1879
  values.push({ type: "STRING", value: tok.value });
1849
1880
  } else if (tok.kind === "NUMBER" /* NUMBER */) {
1850
1881
  values.push({ type: "NUMBER", value: Number(tok.value) });
1882
+ } else if (tok.kind === "-" /* MINUS */ || tok.kind === "+" /* PLUS */) {
1883
+ const number = this.peek();
1884
+ if (number.kind !== "NUMBER" /* NUMBER */) {
1885
+ throw new ParseError(invalidValueMessage, tok);
1886
+ }
1887
+ this.advance();
1888
+ const sign = tok.kind === "-" /* MINUS */ ? -1 : 1;
1889
+ values.push({ type: "NUMBER", value: sign * Number(number.value) });
1851
1890
  } else if (tok.kind === "VARIABLE" /* VARIABLE */) {
1852
1891
  values.push({ type: "VARIABLE", name: tok.value.slice(1).toLowerCase() });
1853
1892
  } else {
1854
- throw new ParseError("IN \u30EA\u30B9\u30C8\u306B\u306F\u6587\u5B57\u5217\u3001\u6570\u5024\u3001\u307E\u305F\u306F\u30D0\u30C3\u30C1\u5909\u6570\u304C\u5FC5\u8981\u3067\u3059", tok);
1893
+ throw new ParseError(invalidValueMessage, tok);
1855
1894
  }
1856
1895
  } while (this.consume("," /* COMMA */));
1857
1896
  return values;
@@ -3348,7 +3387,7 @@ function stringFuncLabel(expr) {
3348
3387
  return `${expr.func}(${args.join(",")})`;
3349
3388
  }
3350
3389
  function isAggregateSyntheticName(name) {
3351
- return /^(COUNT|SUM|AVG|MAX|MIN)\(/i.test(name);
3390
+ return /^(COUNT|SUM|AVG|MAX|MIN|GROUP_CONCAT)\(/i.test(name);
3352
3391
  }
3353
3392
 
3354
3393
  // src/core/cteInlining.ts
@@ -5114,7 +5153,7 @@ function applyGroupBy(rows, groupByKeys, columns, resolveAggSortKind) {
5114
5153
  for (const col of columns) {
5115
5154
  if (col.type === "AGGREGATE") {
5116
5155
  const syntheticKey = aggregateSyntheticName2(col.func, col.distinct, col.arg);
5117
- const value = String(evalAggregate(col.func, col.distinct, col.arg, groupRows, resolveAggSortKind));
5156
+ const value = String(evalAggregate(col.func, col.distinct, col.arg, col.separator, groupRows, resolveAggSortKind));
5118
5157
  outRow[col.alias ?? syntheticKey] = value;
5119
5158
  if (col.alias) outRow[syntheticKey] = value;
5120
5159
  } else if (col.type === "ARITH_AGG_COL") {
@@ -5135,7 +5174,7 @@ function evalGroupByKey(key, row) {
5135
5174
  if (key.type === "FUNC_KEY") return evalStringFunc(key.expr, row);
5136
5175
  return String(evalArithExpr(key.expr, row));
5137
5176
  }
5138
- function evalAggregate(func, distinct, arg, rows, resolveAggSortKind) {
5177
+ function evalAggregate(func, distinct, arg, separator, rows, resolveAggSortKind) {
5139
5178
  if (arg.type === "WILDCARD") {
5140
5179
  return func === "COUNT" ? rows.length : 0;
5141
5180
  }
@@ -5155,6 +5194,7 @@ function evalAggregate(func, distinct, arg, rows, resolveAggSortKind) {
5155
5194
  }
5156
5195
  const eff = distinct ? [...new Set(strValues)] : strValues;
5157
5196
  if (func === "COUNT") return eff.length;
5197
+ if (func === "GROUP_CONCAT") return eff.join(separator ?? ",");
5158
5198
  const sortKind = (func === "MIN" || func === "MAX") && arg.type === "FIELD_REF" ? resolveAggSortKind?.(toAggregateFieldRef(arg.field)) : void 0;
5159
5199
  if (sortKind === "string") {
5160
5200
  if (eff.length === 0) return "";
@@ -5199,7 +5239,7 @@ function minOf(nums) {
5199
5239
  }
5200
5240
  function evalAggArithExpr(node, rows, resolveAggSortKind) {
5201
5241
  if (node.type === "NUMBER") return node.value;
5202
- if (node.type === "AGG_REF") return Number(evalAggregate(node.func, node.distinct, node.arg, rows, resolveAggSortKind));
5242
+ if (node.type === "AGG_REF") return Number(evalAggregate(node.func, node.distinct, node.arg, node.separator, rows, resolveAggSortKind));
5203
5243
  const l = evalAggArithExpr(node.left, rows, resolveAggSortKind);
5204
5244
  const r = evalAggArithExpr(node.right, rows, resolveAggSortKind);
5205
5245
  switch (node.op) {
@@ -5548,7 +5588,7 @@ function hasAggregateInStringFuncExpr2(expr) {
5548
5588
  }
5549
5589
  function resolveAggInStringFuncArg(arg, rows, resolveAggSortKind) {
5550
5590
  if (arg.type === "AGG_REF") {
5551
- const value = evalAggregate(arg.func, arg.distinct, arg.arg, rows, resolveAggSortKind);
5591
+ const value = evalAggregate(arg.func, arg.distinct, arg.arg, arg.separator, rows, resolveAggSortKind);
5552
5592
  return typeof value === "number" ? { type: "NUMBER", value } : { type: "STRING", value };
5553
5593
  }
5554
5594
  if (arg.type === "AGG_ARITH") {
@@ -5794,7 +5834,8 @@ function isValidTemporal(value, type) {
5794
5834
  const date = new Date(Date.UTC(year, month - 1, day));
5795
5835
  if (date.getUTCFullYear() !== year || date.getUTCMonth() !== month - 1 || date.getUTCDate() !== day) return false;
5796
5836
  if (type === "DATE") return true;
5797
- return /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}(?::\d{2})?(?:Z|[+-]\d{2}:\d{2})$/.test(value) && isValidTemporal(value.slice(11, value.endsWith("Z") ? -1 : value.length - 6), "TIME");
5837
+ const timePart = value.slice(11, value.endsWith("Z") ? -1 : value.length - 6).replace(/\.\d+$/, "");
5838
+ return /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}(?::\d{2})?(?:\.\d+)?(?:Z|[+-]\d{2}:\d{2})$/.test(value) && isValidTemporal(timePart, "TIME");
5798
5839
  }
5799
5840
 
5800
5841
  // src/core/dmlValidationCandidates.ts
@@ -5874,6 +5915,8 @@ var SearchAbortedError = class extends Error {
5874
5915
  this.name = "SearchAbortedError";
5875
5916
  }
5876
5917
  };
5918
+ var materializedMetaBySelectResult = /* @__PURE__ */ new WeakMap();
5919
+ var materializedMetaByValidationResult = /* @__PURE__ */ new WeakMap();
5877
5920
  async function execute(sql, client, options = {}) {
5878
5921
  const startedAt = Date.now();
5879
5922
  const stmt = parseSql(sql);
@@ -6019,16 +6062,25 @@ async function executeParsedStatement(stmt, client, options, cacheContext) {
6019
6062
  }
6020
6063
  }
6021
6064
  var TEMP_TABLE_MAX_ROWS = 1e4;
6022
- function appendValidationErrors(tempTables, name, columns, rows, maxRows) {
6065
+ function appendValidationErrors(tempTables, name, columns, rows, maxRows, columnMeta) {
6023
6066
  const current = tempTables.get(name);
6024
- if (current && (current.columns.length !== columns.length || current.columns.some((c, i) => c !== columns[i]))) {
6067
+ if (current && (current.columns.length !== columns.length || current.columns.some((c, i) => c !== columns[i]) || !materializedColumnMetaEqual(current.columnMeta, columnMeta))) {
6025
6068
  throw new Error(`ArgumentError: validation error table ${name} has a different schema.`);
6026
6069
  }
6027
6070
  const existingRows = current?.rows ?? [];
6028
6071
  if (existingRows.length + rows.length > maxRows) {
6029
6072
  throw new Error(`ArgumentError: temp table ${name} exceeds max rows (${maxRows}).`);
6030
6073
  }
6031
- tempTables.set(name, { columns: [...columns], rows: [...existingRows, ...rows] });
6074
+ tempTables.set(name, { columns: [...columns], rows: [...existingRows, ...rows], columnMeta });
6075
+ }
6076
+ function materializedColumnMetaEqual(left, right) {
6077
+ if (left === right) return true;
6078
+ if (!left || !right || left.size !== right.size) return false;
6079
+ for (const [column, meta] of left) {
6080
+ const candidate = right.get(column);
6081
+ if (!candidate || candidate.sortKind !== meta.sortKind || candidate.fieldType !== meta.fieldType) return false;
6082
+ }
6083
+ return true;
6032
6084
  }
6033
6085
  var BatchTimeoutError = class extends Error {
6034
6086
  constructor() {
@@ -6190,7 +6242,8 @@ async function executeBatchStatement(stmt, info, client, options, cacheContext,
6190
6242
  resolvedStmt.validationErrorTable,
6191
6243
  result.columns,
6192
6244
  result.errors,
6193
- options.tempTableMaxRows ?? TEMP_TABLE_MAX_ROWS
6245
+ options.tempTableMaxRows ?? TEMP_TABLE_MAX_ROWS,
6246
+ materializedMetaByValidationResult.get(result) ?? /* @__PURE__ */ new Map()
6194
6247
  );
6195
6248
  }
6196
6249
  return { result };
@@ -6214,7 +6267,11 @@ async function executeBatchStatement(stmt, info, client, options, cacheContext,
6214
6267
  onLimitReached: "error"
6215
6268
  };
6216
6269
  const result = await runSelectLike(resolvedStmt.query, client, materializeOptions, cacheContext, tempTables);
6217
- tempTables.set(resolvedStmt.name, { rows: result.rows, columns: result.columns });
6270
+ tempTables.set(resolvedStmt.name, {
6271
+ rows: result.rows,
6272
+ columns: result.columns,
6273
+ columnMeta: materializedMetaBySelectResult.get(result)
6274
+ });
6218
6275
  return { tempTable: resolvedStmt.name, rowCount: result.rows.length };
6219
6276
  }
6220
6277
  if (stmt.type === "DROP_TEMP_TABLE") {
@@ -6250,9 +6307,9 @@ async function executeBatchStatement(stmt, info, client, options, cacheContext,
6250
6307
  }
6251
6308
  async function runSelectLike(query, client, options, cacheContext, tempTables) {
6252
6309
  if (query.type === "WITH") {
6253
- return executeWith(query, client, options, cacheContext, tempTables);
6310
+ return executeWith(query, client, options, cacheContext, tempTables, true);
6254
6311
  }
6255
- return executeQueryWithCte(query, client, options, tempTables, cacheContext);
6312
+ return executeQueryWithCte(query, client, options, tempTables, cacheContext, true);
6256
6313
  }
6257
6314
  async function runWithDeadline(work, remainingMs) {
6258
6315
  if (remainingMs === null) return work;
@@ -6465,18 +6522,27 @@ function evalAssertArith(node) {
6465
6522
  }
6466
6523
  throw new Error(`ArgumentError: unsupported operand in ASSERT expression: ${node.type}`);
6467
6524
  }
6468
- async function executeSelect(stmt, client, options, cacheContext, cteCache) {
6525
+ async function executeSelect(stmt, client, options, cacheContext, cteCache, captureColumnMeta = false) {
6526
+ let result;
6469
6527
  if (isNoFromSelect(stmt)) {
6470
- return executeNoFromSelect(stmt);
6528
+ result = executeNoFromSelect(stmt);
6529
+ if (captureColumnMeta) {
6530
+ materializedMetaBySelectResult.set(result, await inferSelectColumnMeta(stmt, result.columns, client, cacheContext, cteCache));
6531
+ }
6532
+ return result;
6471
6533
  }
6472
6534
  await resolveSelectCaseSubqueries(stmt, client, options, cacheContext, cteCache);
6473
6535
  const mode = resolveSelectMode(stmt);
6474
6536
  await validateSelectFieldCodes(stmt, mode, client, cacheContext);
6475
6537
  if (mode === "SIMPLE") {
6476
- return executeSimpleSelect(stmt, client, options, cacheContext);
6538
+ result = await executeSimpleSelect(stmt, client, options, cacheContext);
6477
6539
  } else {
6478
- return executeFullScanSelect(stmt, client, options, cacheContext, cteCache);
6540
+ result = await executeFullScanSelect(stmt, client, options, cacheContext, cteCache);
6541
+ }
6542
+ if (captureColumnMeta) {
6543
+ materializedMetaBySelectResult.set(result, await inferSelectColumnMeta(stmt, result.columns, client, cacheContext, cteCache));
6479
6544
  }
6545
+ return result;
6480
6546
  }
6481
6547
  function isNoFromSelect(stmt) {
6482
6548
  return stmt.from.appId === 0 && stmt.from.cteName === NO_FROM_CTE_NAME;
@@ -6800,7 +6866,7 @@ function aggregateSortKind(info) {
6800
6866
  if (info.fieldType === "NUMBER" || info.fieldType === "RECORD_NUMBER") return "number";
6801
6867
  return AGGREGATE_STRING_FIELD_TYPES.has(info.fieldType) ? "string" : void 0;
6802
6868
  }
6803
- async function loadAggregateSortKindResolver(stmt, client, cacheContext) {
6869
+ async function loadAggregateSortKindResolver(stmt, client, cacheContext, materializedTables) {
6804
6870
  const refs = collectSelectAggregateSortRefs(stmt.columns);
6805
6871
  if (refs.length === 0) return void 0;
6806
6872
  const appIds = /* @__PURE__ */ new Set();
@@ -6816,11 +6882,9 @@ async function loadAggregateSortKindResolver(stmt, client, cacheContext) {
6816
6882
  } else if (stmt.joins.length === 0) {
6817
6883
  if (stmt.from.cteName === null) appIds.add(stmt.from.appId);
6818
6884
  } else {
6819
- if ([stmt.from, ...stmt.joins.map((join2) => join2.table)].some((table) => table.cteName !== null)) continue;
6820
6885
  for (const table of physicalTables) appIds.add(table.appId);
6821
6886
  }
6822
6887
  }
6823
- if (appIds.size === 0) return void 0;
6824
6888
  const fieldInfosByApp = new Map(
6825
6889
  await Promise.all([...appIds].map(async (appId) => {
6826
6890
  const infos = await getFieldsCached(appId, client, cacheContext);
@@ -6835,17 +6899,28 @@ async function loadAggregateSortKindResolver(stmt, client, cacheContext) {
6835
6899
  info = fieldInfosByApp.get(stmt.from.appId)?.get(ref.field);
6836
6900
  } else {
6837
6901
  const table = tables.find((candidate) => candidate.alias === ref.tableAlias);
6838
- if (!table || table.cteName !== null) return void 0;
6902
+ if (!table) return void 0;
6903
+ if (table.cteName !== null) {
6904
+ return materializedTables?.get(table.cteName)?.columnMeta?.get(ref.field)?.sortKind;
6905
+ }
6839
6906
  info = fieldInfosByApp.get(table.appId)?.get(fieldCodeForTypeLookup(table, ref.field));
6840
6907
  }
6841
6908
  } else if (stmt.joins.length === 0) {
6842
- if (stmt.from.cteName !== null) return void 0;
6909
+ if (stmt.from.cteName !== null) {
6910
+ return materializedTables?.get(stmt.from.cteName)?.columnMeta?.get(ref.field)?.sortKind;
6911
+ }
6843
6912
  info = fieldInfosByApp.get(stmt.from.appId)?.get(fieldCodeForTypeLookup(stmt.from, ref.field));
6844
6913
  } else {
6845
- if (tables.some((table) => table.cteName !== null)) return void 0;
6846
- const matches = physicalTables.map((table) => fieldInfosByApp.get(table.appId)?.get(fieldCodeForTypeLookup(table, ref.field))).filter((candidate) => candidate !== void 0);
6914
+ const matches = tables.flatMap((table) => {
6915
+ if (table.cteName !== null) {
6916
+ const materialized = materializedTables?.get(table.cteName);
6917
+ return materialized?.columns.includes(ref.field) ? [materialized.columnMeta?.get(ref.field)?.sortKind] : [];
6918
+ }
6919
+ const candidate = fieldInfosByApp.get(table.appId)?.get(fieldCodeForTypeLookup(table, ref.field));
6920
+ return candidate ? [aggregateSortKind(candidate)] : [];
6921
+ });
6847
6922
  if (matches.length !== 1) return void 0;
6848
- info = matches[0];
6923
+ return matches[0];
6849
6924
  }
6850
6925
  return info ? aggregateSortKind(info) : void 0;
6851
6926
  };
@@ -6854,6 +6929,106 @@ function fieldCodeForTypeLookup(table, field) {
6854
6929
  if (table.subtableCode && field.startsWith("_p.")) return field.slice(3);
6855
6930
  return field;
6856
6931
  }
6932
+ function materializedMetaFromFieldInfo(info) {
6933
+ return { sortKind: aggregateSortKind(info), fieldType: info.fieldType };
6934
+ }
6935
+ function selectNeedsSourceColumnMeta(stmt) {
6936
+ return stmt.columns.some(
6937
+ (column) => column.type === "FIELD" || column.type === "WILDCARD" || column.type === "PARENT_WILDCARD" || column.type === "AGGREGATE" && (column.func === "MIN" || column.func === "MAX") && column.arg.type === "FIELD_REF"
6938
+ );
6939
+ }
6940
+ async function inferSelectColumnMeta(stmt, outputColumns, client, cacheContext, materializedTables) {
6941
+ const physicalInfos = /* @__PURE__ */ new Map();
6942
+ if (selectNeedsSourceColumnMeta(stmt)) {
6943
+ await Promise.all(physicalSelectTables(stmt).map(async (table) => {
6944
+ if (physicalInfos.has(table.appId)) return;
6945
+ const infos = await getFieldsCached(table.appId, client, cacheContext);
6946
+ physicalInfos.set(table.appId, new Map(infos.map((info) => [info.code, info])));
6947
+ }));
6948
+ }
6949
+ const tables = [stmt.from, ...stmt.joins.map((join2) => join2.table)];
6950
+ const resolveField2 = (ref) => {
6951
+ if (ref.tableAlias !== null) {
6952
+ if (ref.tableAlias === "_p" && stmt.from.subtableCode && stmt.from.cteName === null) {
6953
+ const info2 = physicalInfos.get(stmt.from.appId)?.get(ref.field);
6954
+ return info2 ? materializedMetaFromFieldInfo(info2) : void 0;
6955
+ }
6956
+ const table = tables.find((candidate) => candidate.alias === ref.tableAlias);
6957
+ if (!table) return void 0;
6958
+ if (table.cteName !== null) return materializedTables?.get(table.cteName)?.columnMeta?.get(ref.field);
6959
+ const info = physicalInfos.get(table.appId)?.get(fieldCodeForTypeLookup(table, ref.field));
6960
+ return info ? materializedMetaFromFieldInfo(info) : void 0;
6961
+ }
6962
+ if (stmt.joins.length === 0) {
6963
+ if (stmt.from.cteName !== null) return materializedTables?.get(stmt.from.cteName)?.columnMeta?.get(ref.field);
6964
+ const info = physicalInfos.get(stmt.from.appId)?.get(fieldCodeForTypeLookup(stmt.from, ref.field));
6965
+ return info ? materializedMetaFromFieldInfo(info) : void 0;
6966
+ }
6967
+ const matches = tables.flatMap((table) => {
6968
+ if (table.cteName !== null) {
6969
+ const materialized = materializedTables?.get(table.cteName);
6970
+ if (!materialized?.columns.includes(ref.field)) return [];
6971
+ return [materialized.columnMeta?.get(ref.field)];
6972
+ }
6973
+ const info = physicalInfos.get(table.appId)?.get(fieldCodeForTypeLookup(table, ref.field));
6974
+ return info ? [materializedMetaFromFieldInfo(info)] : [];
6975
+ });
6976
+ return matches.length === 1 ? matches[0] : void 0;
6977
+ };
6978
+ const inferred = /* @__PURE__ */ new Map();
6979
+ const hasWildcard = stmt.columns.some((column) => column.type === "WILDCARD" || column.type === "PARENT_WILDCARD");
6980
+ if (stmt.columns.length === 1 && (stmt.columns[0].type === "WILDCARD" || stmt.columns[0].type === "PARENT_WILDCARD")) {
6981
+ for (const output of outputColumns) {
6982
+ const meta = resolveField2(aggregateFieldRef(output));
6983
+ if (meta) inferred.set(output, meta);
6984
+ }
6985
+ return inferred;
6986
+ }
6987
+ if (hasWildcard) {
6988
+ for (const output of outputColumns) {
6989
+ const meta = resolveField2(aggregateFieldRef(output));
6990
+ if (meta) inferred.set(output, meta);
6991
+ }
6992
+ }
6993
+ const explicitColumns = stmt.columns.filter(
6994
+ (column) => column.type !== "WILDCARD" && column.type !== "PARENT_WILDCARD"
6995
+ );
6996
+ explicitColumns.forEach((column, index) => {
6997
+ const output = hasWildcard ? "alias" in column && column.alias ? column.alias : void 0 : outputColumns[index];
6998
+ if (!output) return;
6999
+ let meta;
7000
+ if (column.type === "FIELD") {
7001
+ meta = resolveField2(aggregateFieldRef(column.field));
7002
+ } else if (column.type === "AGGREGATE") {
7003
+ if (column.func === "GROUP_CONCAT") {
7004
+ meta = { sortKind: "string" };
7005
+ } else if (column.func === "COUNT" || column.func === "SUM" || column.func === "AVG") {
7006
+ meta = { sortKind: "number" };
7007
+ } else if ((column.func === "MIN" || column.func === "MAX") && column.arg.type === "FIELD_REF") {
7008
+ const source = resolveField2(aggregateFieldRef(column.arg.field));
7009
+ if (source?.sortKind) meta = { sortKind: source.sortKind };
7010
+ }
7011
+ } else if (column.type === "ARITH_AGG_COL" || column.type === "ARITH_COL") {
7012
+ meta = { sortKind: "number" };
7013
+ } else if (column.type === "LITERAL_COL") {
7014
+ meta = { sortKind: "string" };
7015
+ }
7016
+ if (meta) inferred.set(output, meta);
7017
+ });
7018
+ return inferred;
7019
+ }
7020
+ function mergeUnionColumnMeta(left, right) {
7021
+ const leftMeta = materializedMetaBySelectResult.get(left);
7022
+ const rightMeta = materializedMetaBySelectResult.get(right);
7023
+ const merged = /* @__PURE__ */ new Map();
7024
+ left.columns.forEach((column, index) => {
7025
+ const a = leftMeta?.get(column);
7026
+ const rightColumn = right.columns[index];
7027
+ const b = rightColumn === void 0 ? void 0 : rightMeta?.get(rightColumn);
7028
+ if (a && b && a.sortKind === b.sortKind && a.fieldType === b.fieldType) merged.set(column, a);
7029
+ });
7030
+ return merged;
7031
+ }
6857
7032
  function buildSelectFieldTypeResolvers(stmt, fieldTypesByApp) {
6858
7033
  const tables = [stmt.from, ...stmt.joins.map((join2) => join2.table)];
6859
7034
  const physicalTables = tables.filter((table) => table.cteName === null);
@@ -6898,7 +7073,7 @@ async function executeFullScanSelect(stmt, client, options, cacheContext, cteCac
6898
7073
  const [pushdownMeta, typedInFieldTypes, aggregateSortKindResolver] = await Promise.all([
6899
7074
  loadTypedPushdownMeta(stmt, client, cacheContext),
6900
7075
  loadTypedInFieldTypes(stmt, client, cacheContext),
6901
- loadAggregateSortKindResolver(stmt, client, cacheContext)
7076
+ loadAggregateSortKindResolver(stmt, client, cacheContext, cteCache)
6902
7077
  ]);
6903
7078
  const fieldTypeResolvers = buildSelectFieldTypeResolvers(stmt, typedInFieldTypes);
6904
7079
  const pushdownPlan = buildKlikePushdownPlan(stmt, pushdownMeta);
@@ -7018,9 +7193,9 @@ function deduplicateRows(rows, columns) {
7018
7193
  return true;
7019
7194
  });
7020
7195
  }
7021
- async function executeWith(stmt, client, options, cacheContext, seed) {
7196
+ async function executeWith(stmt, client, options, cacheContext, seed, captureColumnMeta = false) {
7022
7197
  if ((seed == null || seed.size === 0) && canInlineSingleCte(stmt)) {
7023
- return executeSelect(buildInlinedQuery(stmt), client, options, cacheContext);
7198
+ return executeSelect(buildInlinedQuery(stmt), client, options, cacheContext, void 0, captureColumnMeta);
7024
7199
  }
7025
7200
  const cteCache = new Map(seed ?? []);
7026
7201
  for (const cte of stmt.ctes) {
@@ -7030,17 +7205,21 @@ async function executeWith(stmt, client, options, cacheContext, seed) {
7030
7205
  } else if (cte.query.type === "DESCRIBE") {
7031
7206
  result = await executeDescribe(cte.query, client, cacheContext);
7032
7207
  } else {
7033
- result = await executeQueryWithCte(cte.query, client, options, cteCache, cacheContext);
7208
+ result = await executeQueryWithCte(cte.query, client, options, cteCache, cacheContext, true);
7034
7209
  }
7035
- cteCache.set(cte.name, { rows: result.rows, columns: result.columns });
7210
+ cteCache.set(cte.name, {
7211
+ rows: result.rows,
7212
+ columns: result.columns,
7213
+ columnMeta: materializedMetaBySelectResult.get(result)
7214
+ });
7036
7215
  }
7037
- return executeQueryWithCte(stmt.query, client, options, cteCache, cacheContext);
7216
+ return executeQueryWithCte(stmt.query, client, options, cteCache, cacheContext, captureColumnMeta);
7038
7217
  }
7039
- async function executeQueryWithCte(query, client, options, cteCache, cacheContext) {
7218
+ async function executeQueryWithCte(query, client, options, cteCache, cacheContext, captureColumnMeta = false) {
7040
7219
  if (query.type === "UNION") {
7041
7220
  const [leftResult, rightResult] = await Promise.all([
7042
- executeQueryWithCte(query.left, client, options, cteCache, cacheContext),
7043
- executeQueryWithCte(query.right, client, options, cteCache, cacheContext)
7221
+ executeQueryWithCte(query.left, client, options, cteCache, cacheContext, captureColumnMeta),
7222
+ executeQueryWithCte(query.right, client, options, cteCache, cacheContext, captureColumnMeta)
7044
7223
  ]);
7045
7224
  const leftCols = leftResult.columns;
7046
7225
  const rightCols = rightResult.columns;
@@ -7053,13 +7232,21 @@ async function executeQueryWithCte(query, client, options, cteCache, cacheContex
7053
7232
  });
7054
7233
  const combined = [...leftResult.rows, ...remapped];
7055
7234
  const rows = query.all ? combined : deduplicateRows(combined, leftCols);
7056
- return { type: "SELECT", rows, columns: leftCols, rowCount: rows.length };
7235
+ const result2 = { type: "SELECT", rows, columns: leftCols, rowCount: rows.length };
7236
+ if (captureColumnMeta) {
7237
+ materializedMetaBySelectResult.set(result2, mergeUnionColumnMeta(leftResult, rightResult));
7238
+ }
7239
+ return result2;
7057
7240
  }
7058
7241
  const hasCteRef = query.from.cteName != null && query.from.cteName !== NO_FROM_CTE_NAME || query.joins.some((j) => j.table.cteName != null);
7059
7242
  if (!hasCteRef) {
7060
- return executeSelect(query, client, options, cacheContext, cteCache);
7243
+ return executeSelect(query, client, options, cacheContext, cteCache, captureColumnMeta);
7244
+ }
7245
+ const result = await executeFullScanWithCte(query, client, options, cteCache, cacheContext);
7246
+ if (captureColumnMeta) {
7247
+ materializedMetaBySelectResult.set(result, await inferSelectColumnMeta(query, result.columns, client, cacheContext, cteCache));
7061
7248
  }
7062
- return executeFullScanWithCte(query, client, options, cteCache, cacheContext);
7249
+ return result;
7063
7250
  }
7064
7251
  async function executeFullScanWithCte(stmt, client, options, cteCache, cacheContext) {
7065
7252
  const maxRecords = options.maxRecords ?? 1e4;
@@ -7073,7 +7260,7 @@ async function executeFullScanWithCte(stmt, client, options, cteCache, cacheCont
7073
7260
  const [pushdownMeta, typedInFieldTypes, aggregateSortKindResolver] = await Promise.all([
7074
7261
  loadTypedPushdownMeta(stmt, client, cacheContext),
7075
7262
  loadTypedInFieldTypes(stmt, client, cacheContext),
7076
- loadAggregateSortKindResolver(stmt, client, cacheContext)
7263
+ loadAggregateSortKindResolver(stmt, client, cacheContext, cteCache)
7077
7264
  ]);
7078
7265
  const fieldTypeResolvers = buildSelectFieldTypeResolvers(stmt, typedInFieldTypes);
7079
7266
  const pushdownPlan = buildKlikePushdownPlan(stmt, pushdownMeta);
@@ -7551,7 +7738,23 @@ async function prepareDmlValidation(stmt, client, options, cacheContext, tempTab
7551
7738
  errors,
7552
7739
  ...stmt.validationErrorTable ? { errTable: stmt.validationErrorTable } : stmt.onErrorSkip && stmt.errorTable ? { errTable: stmt.errorTable } : {}
7553
7740
  };
7554
- return { result, candidates, invalidRowNumbers };
7741
+ const columnMeta = /* @__PURE__ */ new Map();
7742
+ for (const column of payloadFields) {
7743
+ if (column === "$id") {
7744
+ columnMeta.set(column, { sortKind: "number", fieldType: "RECORD_NUMBER" });
7745
+ continue;
7746
+ }
7747
+ const info = infoByCode.get(column);
7748
+ if (info) columnMeta.set(column, materializedMetaFromFieldInfo(info));
7749
+ }
7750
+ columnMeta.set("$err_statement", { sortKind: "number" });
7751
+ columnMeta.set("$err_operation", { sortKind: "string" });
7752
+ columnMeta.set("$err_row", { sortKind: "number" });
7753
+ columnMeta.set("$err_field", { sortKind: "string" });
7754
+ columnMeta.set("$err_code", { sortKind: "string" });
7755
+ columnMeta.set("$err_message", { sortKind: "string" });
7756
+ materializedMetaByValidationResult.set(result, columnMeta);
7757
+ return { result, candidates, invalidRowNumbers, columnMeta };
7555
7758
  }
7556
7759
  async function executeOnErrorSkip(stmt, client, options, cacheContext, tempTables, statementNumber) {
7557
7760
  const prepared = await prepareDmlValidation(
@@ -7569,7 +7772,8 @@ async function executeOnErrorSkip(stmt, client, options, cacheContext, tempTable
7569
7772
  errTable,
7570
7773
  prepared.result.columns,
7571
7774
  prepared.result.errors,
7572
- options.tempTableMaxRows ?? TEMP_TABLE_MAX_ROWS
7775
+ options.tempTableMaxRows ?? TEMP_TABLE_MAX_ROWS,
7776
+ prepared.columnMeta
7573
7777
  );
7574
7778
  const rejectLimit = stmt.rejectLimit ?? null;
7575
7779
  if (rejectLimit !== null && prepared.result.invalidRows > rejectLimit) {
@@ -30999,6 +30999,7 @@ var KEYWORDS = /* @__PURE__ */ new Map([
30999
30999
  ["AVG", "AVG" /* AVG */],
31000
31000
  ["MAX", "MAX" /* MAX */],
31001
31001
  ["MIN", "MIN" /* MIN */],
31002
+ ["GROUP_CONCAT", "GROUP_CONCAT" /* GROUP_CONCAT */],
31002
31003
  ["ASSERT", "ASSERT" /* ASSERT */],
31003
31004
  ["AND", "AND" /* AND */],
31004
31005
  ["OR", "OR" /* OR */],
@@ -31991,6 +31992,7 @@ var Parser = class {
31991
31992
  func: ref.func,
31992
31993
  distinct: ref.distinct,
31993
31994
  arg: ref.arg,
31995
+ ...ref.separator !== void 0 ? { separator: ref.separator } : {},
31994
31996
  alias: alias2
31995
31997
  };
31996
31998
  }
@@ -32362,7 +32364,8 @@ var Parser = class {
32362
32364
  ["SUM" /* SUM */]: "SUM",
32363
32365
  ["AVG" /* AVG */]: "AVG",
32364
32366
  ["MAX" /* MAX */]: "MAX",
32365
- ["MIN" /* MIN */]: "MIN"
32367
+ ["MIN" /* MIN */]: "MIN",
32368
+ ["GROUP_CONCAT" /* GROUP_CONCAT */]: "GROUP_CONCAT"
32366
32369
  };
32367
32370
  const kind = this.peek().kind;
32368
32371
  return map2[kind] ?? null;
@@ -32374,12 +32377,29 @@ var Parser = class {
32374
32377
  const distinct = this.consume("DISTINCT" /* DISTINCT */);
32375
32378
  let arg;
32376
32379
  if (this.consume("*" /* STAR */)) {
32380
+ if (func === "GROUP_CONCAT") {
32381
+ throw new ParseError("GROUP_CONCAT(*) \u306F\u4F7F\u7528\u3067\u304D\u307E\u305B\u3093\u3002\u30D5\u30A3\u30FC\u30EB\u30C9\u307E\u305F\u306F\u5F0F\u3092\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044", this.prev());
32382
+ }
32377
32383
  arg = { type: "WILDCARD" };
32378
32384
  } else {
32379
32385
  arg = this.parseArithAddSub();
32380
32386
  }
32387
+ let separator;
32388
+ if (this.isSoftKeyword("SEPARATOR")) {
32389
+ const separatorToken = this.advance();
32390
+ if (func !== "GROUP_CONCAT") {
32391
+ throw new ParseError("SEPARATOR \u306F GROUP_CONCAT \u3067\u306E\u307F\u4F7F\u7528\u3067\u304D\u307E\u3059", separatorToken);
32392
+ }
32393
+ separator = this.expect("STRING" /* STRING */, "SEPARATOR \u306E\u5F8C\u306B\u306F\u6587\u5B57\u5217\u30EA\u30C6\u30E9\u30EB\u304C\u5FC5\u8981\u3067\u3059").value;
32394
+ }
32381
32395
  this.expect(")" /* RPAREN */);
32382
- return { type: "AGG_REF", func, distinct, arg };
32396
+ return {
32397
+ type: "AGG_REF",
32398
+ func,
32399
+ distinct,
32400
+ arg,
32401
+ ...separator !== void 0 ? { separator } : {}
32402
+ };
32383
32403
  }
32384
32404
  // ----------------------------------------------------------
32385
32405
  // FROM / JOIN
@@ -32657,10 +32677,20 @@ var Parser = class {
32657
32677
  const distinct = this.consume("DISTINCT" /* DISTINCT */);
32658
32678
  let argStr;
32659
32679
  if (this.consume("*" /* STAR */)) {
32680
+ if (aggFunc === "GROUP_CONCAT") {
32681
+ throw new ParseError("GROUP_CONCAT(*) \u306F\u4F7F\u7528\u3067\u304D\u307E\u305B\u3093\u3002\u30D5\u30A3\u30FC\u30EB\u30C9\u307E\u305F\u306F\u5F0F\u3092\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044", this.prev());
32682
+ }
32660
32683
  argStr = "*";
32661
32684
  } else {
32662
32685
  argStr = this.parseIdentifier();
32663
32686
  }
32687
+ if (this.isSoftKeyword("SEPARATOR")) {
32688
+ const separatorToken = this.advance();
32689
+ if (aggFunc !== "GROUP_CONCAT") {
32690
+ throw new ParseError("SEPARATOR \u306F GROUP_CONCAT \u3067\u306E\u307F\u4F7F\u7528\u3067\u304D\u307E\u3059", separatorToken);
32691
+ }
32692
+ this.expect("STRING" /* STRING */, "SEPARATOR \u306E\u5F8C\u306B\u306F\u6587\u5B57\u5217\u30EA\u30C6\u30E9\u30EB\u304C\u5FC5\u8981\u3067\u3059");
32693
+ }
32664
32694
  this.expect(")" /* RPAREN */);
32665
32695
  const syntheticName = distinct ? `${aggFunc}(DISTINCT ${argStr})` : `${aggFunc}(${argStr})`;
32666
32696
  return { type: "FIELD", tableAlias: null, field: syntheticName };
@@ -32754,16 +32784,25 @@ var Parser = class {
32754
32784
  // IN リストの値
32755
32785
  parseInValues() {
32756
32786
  const values = [];
32787
+ const invalidValueMessage = "IN \u30EA\u30B9\u30C8\u306B\u306F\u6587\u5B57\u5217\u3001\u6570\u5024\u3001\u307E\u305F\u306F\u30D0\u30C3\u30C1\u5909\u6570\u304C\u5FC5\u8981\u3067\u3059";
32757
32788
  do {
32758
32789
  const tok = this.advance();
32759
32790
  if (tok.kind === "STRING" /* STRING */) {
32760
32791
  values.push({ type: "STRING", value: tok.value });
32761
32792
  } else if (tok.kind === "NUMBER" /* NUMBER */) {
32762
32793
  values.push({ type: "NUMBER", value: Number(tok.value) });
32794
+ } else if (tok.kind === "-" /* MINUS */ || tok.kind === "+" /* PLUS */) {
32795
+ const number4 = this.peek();
32796
+ if (number4.kind !== "NUMBER" /* NUMBER */) {
32797
+ throw new ParseError(invalidValueMessage, tok);
32798
+ }
32799
+ this.advance();
32800
+ const sign = tok.kind === "-" /* MINUS */ ? -1 : 1;
32801
+ values.push({ type: "NUMBER", value: sign * Number(number4.value) });
32763
32802
  } else if (tok.kind === "VARIABLE" /* VARIABLE */) {
32764
32803
  values.push({ type: "VARIABLE", name: tok.value.slice(1).toLowerCase() });
32765
32804
  } else {
32766
- throw new ParseError("IN \u30EA\u30B9\u30C8\u306B\u306F\u6587\u5B57\u5217\u3001\u6570\u5024\u3001\u307E\u305F\u306F\u30D0\u30C3\u30C1\u5909\u6570\u304C\u5FC5\u8981\u3067\u3059", tok);
32805
+ throw new ParseError(invalidValueMessage, tok);
32767
32806
  }
32768
32807
  } while (this.consume("," /* COMMA */));
32769
32808
  return values;
@@ -34248,7 +34287,7 @@ function stringFuncLabel(expr) {
34248
34287
  return `${expr.func}(${args.join(",")})`;
34249
34288
  }
34250
34289
  function isAggregateSyntheticName(name) {
34251
- return /^(COUNT|SUM|AVG|MAX|MIN)\(/i.test(name);
34290
+ return /^(COUNT|SUM|AVG|MAX|MIN|GROUP_CONCAT)\(/i.test(name);
34252
34291
  }
34253
34292
 
34254
34293
  // src/core/cteInlining.ts
@@ -36014,7 +36053,7 @@ function applyGroupBy(rows, groupByKeys, columns, resolveAggSortKind) {
36014
36053
  for (const col of columns) {
36015
36054
  if (col.type === "AGGREGATE") {
36016
36055
  const syntheticKey = aggregateSyntheticName2(col.func, col.distinct, col.arg);
36017
- const value = String(evalAggregate(col.func, col.distinct, col.arg, groupRows, resolveAggSortKind));
36056
+ const value = String(evalAggregate(col.func, col.distinct, col.arg, col.separator, groupRows, resolveAggSortKind));
36018
36057
  outRow[col.alias ?? syntheticKey] = value;
36019
36058
  if (col.alias) outRow[syntheticKey] = value;
36020
36059
  } else if (col.type === "ARITH_AGG_COL") {
@@ -36035,7 +36074,7 @@ function evalGroupByKey(key, row) {
36035
36074
  if (key.type === "FUNC_KEY") return evalStringFunc(key.expr, row);
36036
36075
  return String(evalArithExpr(key.expr, row));
36037
36076
  }
36038
- function evalAggregate(func, distinct, arg, rows, resolveAggSortKind) {
36077
+ function evalAggregate(func, distinct, arg, separator, rows, resolveAggSortKind) {
36039
36078
  if (arg.type === "WILDCARD") {
36040
36079
  return func === "COUNT" ? rows.length : 0;
36041
36080
  }
@@ -36055,6 +36094,7 @@ function evalAggregate(func, distinct, arg, rows, resolveAggSortKind) {
36055
36094
  }
36056
36095
  const eff = distinct ? [...new Set(strValues)] : strValues;
36057
36096
  if (func === "COUNT") return eff.length;
36097
+ if (func === "GROUP_CONCAT") return eff.join(separator ?? ",");
36058
36098
  const sortKind = (func === "MIN" || func === "MAX") && arg.type === "FIELD_REF" ? resolveAggSortKind?.(toAggregateFieldRef(arg.field)) : void 0;
36059
36099
  if (sortKind === "string") {
36060
36100
  if (eff.length === 0) return "";
@@ -36099,7 +36139,7 @@ function minOf(nums) {
36099
36139
  }
36100
36140
  function evalAggArithExpr(node, rows, resolveAggSortKind) {
36101
36141
  if (node.type === "NUMBER") return node.value;
36102
- if (node.type === "AGG_REF") return Number(evalAggregate(node.func, node.distinct, node.arg, rows, resolveAggSortKind));
36142
+ if (node.type === "AGG_REF") return Number(evalAggregate(node.func, node.distinct, node.arg, node.separator, rows, resolveAggSortKind));
36103
36143
  const l = evalAggArithExpr(node.left, rows, resolveAggSortKind);
36104
36144
  const r = evalAggArithExpr(node.right, rows, resolveAggSortKind);
36105
36145
  switch (node.op) {
@@ -36448,7 +36488,7 @@ function hasAggregateInStringFuncExpr2(expr) {
36448
36488
  }
36449
36489
  function resolveAggInStringFuncArg(arg, rows, resolveAggSortKind) {
36450
36490
  if (arg.type === "AGG_REF") {
36451
- const value = evalAggregate(arg.func, arg.distinct, arg.arg, rows, resolveAggSortKind);
36491
+ const value = evalAggregate(arg.func, arg.distinct, arg.arg, arg.separator, rows, resolveAggSortKind);
36452
36492
  return typeof value === "number" ? { type: "NUMBER", value } : { type: "STRING", value };
36453
36493
  }
36454
36494
  if (arg.type === "AGG_ARITH") {
@@ -36694,7 +36734,8 @@ function isValidTemporal(value, type) {
36694
36734
  const date5 = new Date(Date.UTC(year, month - 1, day));
36695
36735
  if (date5.getUTCFullYear() !== year || date5.getUTCMonth() !== month - 1 || date5.getUTCDate() !== day) return false;
36696
36736
  if (type === "DATE") return true;
36697
- return /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}(?::\d{2})?(?:Z|[+-]\d{2}:\d{2})$/.test(value) && isValidTemporal(value.slice(11, value.endsWith("Z") ? -1 : value.length - 6), "TIME");
36737
+ const timePart = value.slice(11, value.endsWith("Z") ? -1 : value.length - 6).replace(/\.\d+$/, "");
36738
+ return /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}(?::\d{2})?(?:\.\d+)?(?:Z|[+-]\d{2}:\d{2})$/.test(value) && isValidTemporal(timePart, "TIME");
36698
36739
  }
36699
36740
 
36700
36741
  // src/core/dmlValidationCandidates.ts
@@ -36774,6 +36815,8 @@ var SearchAbortedError = class extends Error {
36774
36815
  this.name = "SearchAbortedError";
36775
36816
  }
36776
36817
  };
36818
+ var materializedMetaBySelectResult = /* @__PURE__ */ new WeakMap();
36819
+ var materializedMetaByValidationResult = /* @__PURE__ */ new WeakMap();
36777
36820
  async function execute(sql, client, options = {}) {
36778
36821
  const startedAt = Date.now();
36779
36822
  const stmt = parseSql(sql);
@@ -36919,16 +36962,25 @@ async function executeParsedStatement(stmt, client, options, cacheContext) {
36919
36962
  }
36920
36963
  }
36921
36964
  var TEMP_TABLE_MAX_ROWS = 1e4;
36922
- function appendValidationErrors(tempTables, name, columns, rows, maxRows) {
36965
+ function appendValidationErrors(tempTables, name, columns, rows, maxRows, columnMeta) {
36923
36966
  const current = tempTables.get(name);
36924
- if (current && (current.columns.length !== columns.length || current.columns.some((c, i) => c !== columns[i]))) {
36967
+ if (current && (current.columns.length !== columns.length || current.columns.some((c, i) => c !== columns[i]) || !materializedColumnMetaEqual(current.columnMeta, columnMeta))) {
36925
36968
  throw new Error(`ArgumentError: validation error table ${name} has a different schema.`);
36926
36969
  }
36927
36970
  const existingRows = current?.rows ?? [];
36928
36971
  if (existingRows.length + rows.length > maxRows) {
36929
36972
  throw new Error(`ArgumentError: temp table ${name} exceeds max rows (${maxRows}).`);
36930
36973
  }
36931
- tempTables.set(name, { columns: [...columns], rows: [...existingRows, ...rows] });
36974
+ tempTables.set(name, { columns: [...columns], rows: [...existingRows, ...rows], columnMeta });
36975
+ }
36976
+ function materializedColumnMetaEqual(left, right) {
36977
+ if (left === right) return true;
36978
+ if (!left || !right || left.size !== right.size) return false;
36979
+ for (const [column, meta3] of left) {
36980
+ const candidate = right.get(column);
36981
+ if (!candidate || candidate.sortKind !== meta3.sortKind || candidate.fieldType !== meta3.fieldType) return false;
36982
+ }
36983
+ return true;
36932
36984
  }
36933
36985
  var BatchTimeoutError = class extends Error {
36934
36986
  constructor() {
@@ -37090,7 +37142,8 @@ async function executeBatchStatement(stmt, info, client, options, cacheContext,
37090
37142
  resolvedStmt.validationErrorTable,
37091
37143
  result.columns,
37092
37144
  result.errors,
37093
- options.tempTableMaxRows ?? TEMP_TABLE_MAX_ROWS
37145
+ options.tempTableMaxRows ?? TEMP_TABLE_MAX_ROWS,
37146
+ materializedMetaByValidationResult.get(result) ?? /* @__PURE__ */ new Map()
37094
37147
  );
37095
37148
  }
37096
37149
  return { result };
@@ -37114,7 +37167,11 @@ async function executeBatchStatement(stmt, info, client, options, cacheContext,
37114
37167
  onLimitReached: "error"
37115
37168
  };
37116
37169
  const result = await runSelectLike(resolvedStmt.query, client, materializeOptions, cacheContext, tempTables);
37117
- tempTables.set(resolvedStmt.name, { rows: result.rows, columns: result.columns });
37170
+ tempTables.set(resolvedStmt.name, {
37171
+ rows: result.rows,
37172
+ columns: result.columns,
37173
+ columnMeta: materializedMetaBySelectResult.get(result)
37174
+ });
37118
37175
  return { tempTable: resolvedStmt.name, rowCount: result.rows.length };
37119
37176
  }
37120
37177
  if (stmt.type === "DROP_TEMP_TABLE") {
@@ -37150,9 +37207,9 @@ async function executeBatchStatement(stmt, info, client, options, cacheContext,
37150
37207
  }
37151
37208
  async function runSelectLike(query, client, options, cacheContext, tempTables) {
37152
37209
  if (query.type === "WITH") {
37153
- return executeWith(query, client, options, cacheContext, tempTables);
37210
+ return executeWith(query, client, options, cacheContext, tempTables, true);
37154
37211
  }
37155
- return executeQueryWithCte(query, client, options, tempTables, cacheContext);
37212
+ return executeQueryWithCte(query, client, options, tempTables, cacheContext, true);
37156
37213
  }
37157
37214
  async function runWithDeadline(work, remainingMs) {
37158
37215
  if (remainingMs === null) return work;
@@ -37365,18 +37422,27 @@ function evalAssertArith(node) {
37365
37422
  }
37366
37423
  throw new Error(`ArgumentError: unsupported operand in ASSERT expression: ${node.type}`);
37367
37424
  }
37368
- async function executeSelect(stmt, client, options, cacheContext, cteCache) {
37425
+ async function executeSelect(stmt, client, options, cacheContext, cteCache, captureColumnMeta = false) {
37426
+ let result;
37369
37427
  if (isNoFromSelect(stmt)) {
37370
- return executeNoFromSelect(stmt);
37428
+ result = executeNoFromSelect(stmt);
37429
+ if (captureColumnMeta) {
37430
+ materializedMetaBySelectResult.set(result, await inferSelectColumnMeta(stmt, result.columns, client, cacheContext, cteCache));
37431
+ }
37432
+ return result;
37371
37433
  }
37372
37434
  await resolveSelectCaseSubqueries(stmt, client, options, cacheContext, cteCache);
37373
37435
  const mode = resolveSelectMode(stmt);
37374
37436
  await validateSelectFieldCodes(stmt, mode, client, cacheContext);
37375
37437
  if (mode === "SIMPLE") {
37376
- return executeSimpleSelect(stmt, client, options, cacheContext);
37438
+ result = await executeSimpleSelect(stmt, client, options, cacheContext);
37377
37439
  } else {
37378
- return executeFullScanSelect(stmt, client, options, cacheContext, cteCache);
37440
+ result = await executeFullScanSelect(stmt, client, options, cacheContext, cteCache);
37441
+ }
37442
+ if (captureColumnMeta) {
37443
+ materializedMetaBySelectResult.set(result, await inferSelectColumnMeta(stmt, result.columns, client, cacheContext, cteCache));
37379
37444
  }
37445
+ return result;
37380
37446
  }
37381
37447
  function isNoFromSelect(stmt) {
37382
37448
  return stmt.from.appId === 0 && stmt.from.cteName === NO_FROM_CTE_NAME;
@@ -37700,7 +37766,7 @@ function aggregateSortKind(info) {
37700
37766
  if (info.fieldType === "NUMBER" || info.fieldType === "RECORD_NUMBER") return "number";
37701
37767
  return AGGREGATE_STRING_FIELD_TYPES.has(info.fieldType) ? "string" : void 0;
37702
37768
  }
37703
- async function loadAggregateSortKindResolver(stmt, client, cacheContext) {
37769
+ async function loadAggregateSortKindResolver(stmt, client, cacheContext, materializedTables) {
37704
37770
  const refs = collectSelectAggregateSortRefs(stmt.columns);
37705
37771
  if (refs.length === 0) return void 0;
37706
37772
  const appIds = /* @__PURE__ */ new Set();
@@ -37716,11 +37782,9 @@ async function loadAggregateSortKindResolver(stmt, client, cacheContext) {
37716
37782
  } else if (stmt.joins.length === 0) {
37717
37783
  if (stmt.from.cteName === null) appIds.add(stmt.from.appId);
37718
37784
  } else {
37719
- if ([stmt.from, ...stmt.joins.map((join) => join.table)].some((table) => table.cteName !== null)) continue;
37720
37785
  for (const table of physicalTables) appIds.add(table.appId);
37721
37786
  }
37722
37787
  }
37723
- if (appIds.size === 0) return void 0;
37724
37788
  const fieldInfosByApp = new Map(
37725
37789
  await Promise.all([...appIds].map(async (appId) => {
37726
37790
  const infos = await getFieldsCached(appId, client, cacheContext);
@@ -37735,17 +37799,28 @@ async function loadAggregateSortKindResolver(stmt, client, cacheContext) {
37735
37799
  info = fieldInfosByApp.get(stmt.from.appId)?.get(ref.field);
37736
37800
  } else {
37737
37801
  const table = tables.find((candidate) => candidate.alias === ref.tableAlias);
37738
- if (!table || table.cteName !== null) return void 0;
37802
+ if (!table) return void 0;
37803
+ if (table.cteName !== null) {
37804
+ return materializedTables?.get(table.cteName)?.columnMeta?.get(ref.field)?.sortKind;
37805
+ }
37739
37806
  info = fieldInfosByApp.get(table.appId)?.get(fieldCodeForTypeLookup(table, ref.field));
37740
37807
  }
37741
37808
  } else if (stmt.joins.length === 0) {
37742
- if (stmt.from.cteName !== null) return void 0;
37809
+ if (stmt.from.cteName !== null) {
37810
+ return materializedTables?.get(stmt.from.cteName)?.columnMeta?.get(ref.field)?.sortKind;
37811
+ }
37743
37812
  info = fieldInfosByApp.get(stmt.from.appId)?.get(fieldCodeForTypeLookup(stmt.from, ref.field));
37744
37813
  } else {
37745
- if (tables.some((table) => table.cteName !== null)) return void 0;
37746
- const matches = physicalTables.map((table) => fieldInfosByApp.get(table.appId)?.get(fieldCodeForTypeLookup(table, ref.field))).filter((candidate) => candidate !== void 0);
37814
+ const matches = tables.flatMap((table) => {
37815
+ if (table.cteName !== null) {
37816
+ const materialized = materializedTables?.get(table.cteName);
37817
+ return materialized?.columns.includes(ref.field) ? [materialized.columnMeta?.get(ref.field)?.sortKind] : [];
37818
+ }
37819
+ const candidate = fieldInfosByApp.get(table.appId)?.get(fieldCodeForTypeLookup(table, ref.field));
37820
+ return candidate ? [aggregateSortKind(candidate)] : [];
37821
+ });
37747
37822
  if (matches.length !== 1) return void 0;
37748
- info = matches[0];
37823
+ return matches[0];
37749
37824
  }
37750
37825
  return info ? aggregateSortKind(info) : void 0;
37751
37826
  };
@@ -37754,6 +37829,106 @@ function fieldCodeForTypeLookup(table, field) {
37754
37829
  if (table.subtableCode && field.startsWith("_p.")) return field.slice(3);
37755
37830
  return field;
37756
37831
  }
37832
+ function materializedMetaFromFieldInfo(info) {
37833
+ return { sortKind: aggregateSortKind(info), fieldType: info.fieldType };
37834
+ }
37835
+ function selectNeedsSourceColumnMeta(stmt) {
37836
+ return stmt.columns.some(
37837
+ (column) => column.type === "FIELD" || column.type === "WILDCARD" || column.type === "PARENT_WILDCARD" || column.type === "AGGREGATE" && (column.func === "MIN" || column.func === "MAX") && column.arg.type === "FIELD_REF"
37838
+ );
37839
+ }
37840
+ async function inferSelectColumnMeta(stmt, outputColumns, client, cacheContext, materializedTables) {
37841
+ const physicalInfos = /* @__PURE__ */ new Map();
37842
+ if (selectNeedsSourceColumnMeta(stmt)) {
37843
+ await Promise.all(physicalSelectTables(stmt).map(async (table) => {
37844
+ if (physicalInfos.has(table.appId)) return;
37845
+ const infos = await getFieldsCached(table.appId, client, cacheContext);
37846
+ physicalInfos.set(table.appId, new Map(infos.map((info) => [info.code, info])));
37847
+ }));
37848
+ }
37849
+ const tables = [stmt.from, ...stmt.joins.map((join) => join.table)];
37850
+ const resolveField2 = (ref) => {
37851
+ if (ref.tableAlias !== null) {
37852
+ if (ref.tableAlias === "_p" && stmt.from.subtableCode && stmt.from.cteName === null) {
37853
+ const info2 = physicalInfos.get(stmt.from.appId)?.get(ref.field);
37854
+ return info2 ? materializedMetaFromFieldInfo(info2) : void 0;
37855
+ }
37856
+ const table = tables.find((candidate) => candidate.alias === ref.tableAlias);
37857
+ if (!table) return void 0;
37858
+ if (table.cteName !== null) return materializedTables?.get(table.cteName)?.columnMeta?.get(ref.field);
37859
+ const info = physicalInfos.get(table.appId)?.get(fieldCodeForTypeLookup(table, ref.field));
37860
+ return info ? materializedMetaFromFieldInfo(info) : void 0;
37861
+ }
37862
+ if (stmt.joins.length === 0) {
37863
+ if (stmt.from.cteName !== null) return materializedTables?.get(stmt.from.cteName)?.columnMeta?.get(ref.field);
37864
+ const info = physicalInfos.get(stmt.from.appId)?.get(fieldCodeForTypeLookup(stmt.from, ref.field));
37865
+ return info ? materializedMetaFromFieldInfo(info) : void 0;
37866
+ }
37867
+ const matches = tables.flatMap((table) => {
37868
+ if (table.cteName !== null) {
37869
+ const materialized = materializedTables?.get(table.cteName);
37870
+ if (!materialized?.columns.includes(ref.field)) return [];
37871
+ return [materialized.columnMeta?.get(ref.field)];
37872
+ }
37873
+ const info = physicalInfos.get(table.appId)?.get(fieldCodeForTypeLookup(table, ref.field));
37874
+ return info ? [materializedMetaFromFieldInfo(info)] : [];
37875
+ });
37876
+ return matches.length === 1 ? matches[0] : void 0;
37877
+ };
37878
+ const inferred = /* @__PURE__ */ new Map();
37879
+ const hasWildcard = stmt.columns.some((column) => column.type === "WILDCARD" || column.type === "PARENT_WILDCARD");
37880
+ if (stmt.columns.length === 1 && (stmt.columns[0].type === "WILDCARD" || stmt.columns[0].type === "PARENT_WILDCARD")) {
37881
+ for (const output of outputColumns) {
37882
+ const meta3 = resolveField2(aggregateFieldRef(output));
37883
+ if (meta3) inferred.set(output, meta3);
37884
+ }
37885
+ return inferred;
37886
+ }
37887
+ if (hasWildcard) {
37888
+ for (const output of outputColumns) {
37889
+ const meta3 = resolveField2(aggregateFieldRef(output));
37890
+ if (meta3) inferred.set(output, meta3);
37891
+ }
37892
+ }
37893
+ const explicitColumns = stmt.columns.filter(
37894
+ (column) => column.type !== "WILDCARD" && column.type !== "PARENT_WILDCARD"
37895
+ );
37896
+ explicitColumns.forEach((column, index) => {
37897
+ const output = hasWildcard ? "alias" in column && column.alias ? column.alias : void 0 : outputColumns[index];
37898
+ if (!output) return;
37899
+ let meta3;
37900
+ if (column.type === "FIELD") {
37901
+ meta3 = resolveField2(aggregateFieldRef(column.field));
37902
+ } else if (column.type === "AGGREGATE") {
37903
+ if (column.func === "GROUP_CONCAT") {
37904
+ meta3 = { sortKind: "string" };
37905
+ } else if (column.func === "COUNT" || column.func === "SUM" || column.func === "AVG") {
37906
+ meta3 = { sortKind: "number" };
37907
+ } else if ((column.func === "MIN" || column.func === "MAX") && column.arg.type === "FIELD_REF") {
37908
+ const source = resolveField2(aggregateFieldRef(column.arg.field));
37909
+ if (source?.sortKind) meta3 = { sortKind: source.sortKind };
37910
+ }
37911
+ } else if (column.type === "ARITH_AGG_COL" || column.type === "ARITH_COL") {
37912
+ meta3 = { sortKind: "number" };
37913
+ } else if (column.type === "LITERAL_COL") {
37914
+ meta3 = { sortKind: "string" };
37915
+ }
37916
+ if (meta3) inferred.set(output, meta3);
37917
+ });
37918
+ return inferred;
37919
+ }
37920
+ function mergeUnionColumnMeta(left, right) {
37921
+ const leftMeta = materializedMetaBySelectResult.get(left);
37922
+ const rightMeta = materializedMetaBySelectResult.get(right);
37923
+ const merged = /* @__PURE__ */ new Map();
37924
+ left.columns.forEach((column, index) => {
37925
+ const a = leftMeta?.get(column);
37926
+ const rightColumn = right.columns[index];
37927
+ const b = rightColumn === void 0 ? void 0 : rightMeta?.get(rightColumn);
37928
+ if (a && b && a.sortKind === b.sortKind && a.fieldType === b.fieldType) merged.set(column, a);
37929
+ });
37930
+ return merged;
37931
+ }
37757
37932
  function buildSelectFieldTypeResolvers(stmt, fieldTypesByApp) {
37758
37933
  const tables = [stmt.from, ...stmt.joins.map((join) => join.table)];
37759
37934
  const physicalTables = tables.filter((table) => table.cteName === null);
@@ -37798,7 +37973,7 @@ async function executeFullScanSelect(stmt, client, options, cacheContext, cteCac
37798
37973
  const [pushdownMeta, typedInFieldTypes, aggregateSortKindResolver] = await Promise.all([
37799
37974
  loadTypedPushdownMeta(stmt, client, cacheContext),
37800
37975
  loadTypedInFieldTypes(stmt, client, cacheContext),
37801
- loadAggregateSortKindResolver(stmt, client, cacheContext)
37976
+ loadAggregateSortKindResolver(stmt, client, cacheContext, cteCache)
37802
37977
  ]);
37803
37978
  const fieldTypeResolvers = buildSelectFieldTypeResolvers(stmt, typedInFieldTypes);
37804
37979
  const pushdownPlan = buildKlikePushdownPlan(stmt, pushdownMeta);
@@ -37918,9 +38093,9 @@ function deduplicateRows(rows, columns) {
37918
38093
  return true;
37919
38094
  });
37920
38095
  }
37921
- async function executeWith(stmt, client, options, cacheContext, seed) {
38096
+ async function executeWith(stmt, client, options, cacheContext, seed, captureColumnMeta = false) {
37922
38097
  if ((seed == null || seed.size === 0) && canInlineSingleCte(stmt)) {
37923
- return executeSelect(buildInlinedQuery(stmt), client, options, cacheContext);
38098
+ return executeSelect(buildInlinedQuery(stmt), client, options, cacheContext, void 0, captureColumnMeta);
37924
38099
  }
37925
38100
  const cteCache = new Map(seed ?? []);
37926
38101
  for (const cte of stmt.ctes) {
@@ -37930,17 +38105,21 @@ async function executeWith(stmt, client, options, cacheContext, seed) {
37930
38105
  } else if (cte.query.type === "DESCRIBE") {
37931
38106
  result = await executeDescribe(cte.query, client, cacheContext);
37932
38107
  } else {
37933
- result = await executeQueryWithCte(cte.query, client, options, cteCache, cacheContext);
38108
+ result = await executeQueryWithCte(cte.query, client, options, cteCache, cacheContext, true);
37934
38109
  }
37935
- cteCache.set(cte.name, { rows: result.rows, columns: result.columns });
38110
+ cteCache.set(cte.name, {
38111
+ rows: result.rows,
38112
+ columns: result.columns,
38113
+ columnMeta: materializedMetaBySelectResult.get(result)
38114
+ });
37936
38115
  }
37937
- return executeQueryWithCte(stmt.query, client, options, cteCache, cacheContext);
38116
+ return executeQueryWithCte(stmt.query, client, options, cteCache, cacheContext, captureColumnMeta);
37938
38117
  }
37939
- async function executeQueryWithCte(query, client, options, cteCache, cacheContext) {
38118
+ async function executeQueryWithCte(query, client, options, cteCache, cacheContext, captureColumnMeta = false) {
37940
38119
  if (query.type === "UNION") {
37941
38120
  const [leftResult, rightResult] = await Promise.all([
37942
- executeQueryWithCte(query.left, client, options, cteCache, cacheContext),
37943
- executeQueryWithCte(query.right, client, options, cteCache, cacheContext)
38121
+ executeQueryWithCte(query.left, client, options, cteCache, cacheContext, captureColumnMeta),
38122
+ executeQueryWithCte(query.right, client, options, cteCache, cacheContext, captureColumnMeta)
37944
38123
  ]);
37945
38124
  const leftCols = leftResult.columns;
37946
38125
  const rightCols = rightResult.columns;
@@ -37953,13 +38132,21 @@ async function executeQueryWithCte(query, client, options, cteCache, cacheContex
37953
38132
  });
37954
38133
  const combined = [...leftResult.rows, ...remapped];
37955
38134
  const rows = query.all ? combined : deduplicateRows(combined, leftCols);
37956
- return { type: "SELECT", rows, columns: leftCols, rowCount: rows.length };
38135
+ const result2 = { type: "SELECT", rows, columns: leftCols, rowCount: rows.length };
38136
+ if (captureColumnMeta) {
38137
+ materializedMetaBySelectResult.set(result2, mergeUnionColumnMeta(leftResult, rightResult));
38138
+ }
38139
+ return result2;
37957
38140
  }
37958
38141
  const hasCteRef = query.from.cteName != null && query.from.cteName !== NO_FROM_CTE_NAME || query.joins.some((j) => j.table.cteName != null);
37959
38142
  if (!hasCteRef) {
37960
- return executeSelect(query, client, options, cacheContext, cteCache);
38143
+ return executeSelect(query, client, options, cacheContext, cteCache, captureColumnMeta);
38144
+ }
38145
+ const result = await executeFullScanWithCte(query, client, options, cteCache, cacheContext);
38146
+ if (captureColumnMeta) {
38147
+ materializedMetaBySelectResult.set(result, await inferSelectColumnMeta(query, result.columns, client, cacheContext, cteCache));
37961
38148
  }
37962
- return executeFullScanWithCte(query, client, options, cteCache, cacheContext);
38149
+ return result;
37963
38150
  }
37964
38151
  async function executeFullScanWithCte(stmt, client, options, cteCache, cacheContext) {
37965
38152
  const maxRecords2 = options.maxRecords ?? 1e4;
@@ -37973,7 +38160,7 @@ async function executeFullScanWithCte(stmt, client, options, cteCache, cacheCont
37973
38160
  const [pushdownMeta, typedInFieldTypes, aggregateSortKindResolver] = await Promise.all([
37974
38161
  loadTypedPushdownMeta(stmt, client, cacheContext),
37975
38162
  loadTypedInFieldTypes(stmt, client, cacheContext),
37976
- loadAggregateSortKindResolver(stmt, client, cacheContext)
38163
+ loadAggregateSortKindResolver(stmt, client, cacheContext, cteCache)
37977
38164
  ]);
37978
38165
  const fieldTypeResolvers = buildSelectFieldTypeResolvers(stmt, typedInFieldTypes);
37979
38166
  const pushdownPlan = buildKlikePushdownPlan(stmt, pushdownMeta);
@@ -38451,7 +38638,23 @@ async function prepareDmlValidation(stmt, client, options, cacheContext, tempTab
38451
38638
  errors,
38452
38639
  ...stmt.validationErrorTable ? { errTable: stmt.validationErrorTable } : stmt.onErrorSkip && stmt.errorTable ? { errTable: stmt.errorTable } : {}
38453
38640
  };
38454
- return { result, candidates, invalidRowNumbers };
38641
+ const columnMeta = /* @__PURE__ */ new Map();
38642
+ for (const column of payloadFields) {
38643
+ if (column === "$id") {
38644
+ columnMeta.set(column, { sortKind: "number", fieldType: "RECORD_NUMBER" });
38645
+ continue;
38646
+ }
38647
+ const info = infoByCode.get(column);
38648
+ if (info) columnMeta.set(column, materializedMetaFromFieldInfo(info));
38649
+ }
38650
+ columnMeta.set("$err_statement", { sortKind: "number" });
38651
+ columnMeta.set("$err_operation", { sortKind: "string" });
38652
+ columnMeta.set("$err_row", { sortKind: "number" });
38653
+ columnMeta.set("$err_field", { sortKind: "string" });
38654
+ columnMeta.set("$err_code", { sortKind: "string" });
38655
+ columnMeta.set("$err_message", { sortKind: "string" });
38656
+ materializedMetaByValidationResult.set(result, columnMeta);
38657
+ return { result, candidates, invalidRowNumbers, columnMeta };
38455
38658
  }
38456
38659
  async function executeOnErrorSkip(stmt, client, options, cacheContext, tempTables, statementNumber) {
38457
38660
  const prepared = await prepareDmlValidation(
@@ -38469,7 +38672,8 @@ async function executeOnErrorSkip(stmt, client, options, cacheContext, tempTable
38469
38672
  errTable,
38470
38673
  prepared.result.columns,
38471
38674
  prepared.result.errors,
38472
- options.tempTableMaxRows ?? TEMP_TABLE_MAX_ROWS
38675
+ options.tempTableMaxRows ?? TEMP_TABLE_MAX_ROWS,
38676
+ prepared.columnMeta
38473
38677
  );
38474
38678
  const rejectLimit = stmt.rejectLimit ?? null;
38475
38679
  if (rejectLimit !== null && prepared.result.invalidRows > rejectLimit) {
@@ -42210,7 +42414,7 @@ Options:
42210
42414
  -h, --help Show help
42211
42415
  `);
42212
42416
  }
42213
- var SERVER_VERSION = true ? "2.14.0" : "0.0.0-dev";
42417
+ var SERVER_VERSION = true ? "2.15.0" : "0.0.0-dev";
42214
42418
  function createServer(args) {
42215
42419
  const server = new McpServer({
42216
42420
  name: "ksql-mcp",
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rex0220/kintone-sql-tools",
3
- "version": "2.14.0",
3
+ "version": "2.15.0",
4
4
  "description": "kintone SQL plugin, CLI, and MCP tools (ksql)",
5
5
  "publishConfig": {
6
6
  "access": "public"