@rex0220/kintone-sql-tools 3.77.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");
@@ -23045,6 +23046,14 @@ function planPlainGroupByResolution(groupBy, columns, schemas) {
23045
23046
  };
23046
23047
  }
23047
23048
 
23049
+ // src/core/projectedNameResolution.ts
23050
+ function resolveProjectedName(requested, available) {
23051
+ const names = [...available];
23052
+ if (names.includes(requested)) return requested;
23053
+ const canonical = requested.toLowerCase();
23054
+ return names.find((name) => name === canonical);
23055
+ }
23056
+
23048
23057
  // src/core/aggregateDependencyValidation.ts
23049
23058
  var NON_GROUPED_DEPENDENCY_REASON = "B65_NON_GROUPED_DEPENDENCY";
23050
23059
  var WRAPPER_EXPR = /* @__PURE__ */ new Map([
@@ -23215,10 +23224,11 @@ function walkDependency(node, context) {
23215
23224
  if (ref !== null) {
23216
23225
  if (context.clause !== "SELECT" && ref.tableAlias === null && AGGREGATE_SYNTHETIC_REFERENCE.test(ref.field)) return;
23217
23226
  if (context.clause !== "SELECT" && ref.tableAlias === null) {
23218
- const targets = context.aliases.get(ref.field) ?? [];
23219
- if (targets.length === 1 && !context.resolvingAliases.has(ref.field)) {
23227
+ const alias = resolveProjectedName(ref.field, context.aliases.keys());
23228
+ const targets = alias === void 0 ? [] : context.aliases.get(alias) ?? [];
23229
+ if (targets.length === 1 && alias !== void 0 && !context.resolvingAliases.has(alias)) {
23220
23230
  const resolvingAliases = new Set(context.resolvingAliases);
23221
- resolvingAliases.add(ref.field);
23231
+ resolvingAliases.add(alias);
23222
23232
  walkDependency(targets[0], { ...context, resolvingAliases });
23223
23233
  return;
23224
23234
  }
@@ -23409,7 +23419,7 @@ function containsAggregate2(node) {
23409
23419
  function isAggregateMaterializedAlias(column) {
23410
23420
  if (!("alias" in column) || column.alias === null) return false;
23411
23421
  if (column.type === "AGGREGATE" || column.type === "ARITH_AGG_COL") return true;
23412
- if (column.type === "STRFUNC_COL" || column.type === "SCALAR_VALUE_COL" || column.type === "CASE_COL") {
23422
+ if (column.type === "ARITH_COL" || column.type === "STRFUNC_COL" || column.type === "SCALAR_VALUE_COL" || column.type === "CASE_COL") {
23413
23423
  return containsAggregate2(column);
23414
23424
  }
23415
23425
  return false;
@@ -23536,7 +23546,7 @@ function resolveSelectMode(stmt) {
23536
23546
  if (stmt.distinct) return "FULL_SCAN";
23537
23547
  if (hasWindowColumns(stmt.columns)) return "FULL_SCAN";
23538
23548
  if (stmt.columns.some(
23539
- (c) => c.type === "AGGREGATE" || c.type === "ARITH_AGG_COL" || c.type === "SCALAR_SUBQUERY_COL" || c.type === "CASE_COL" && containsAggregate2(c.expr) || c.type === "STRFUNC_COL" && hasAggregateInStringFuncExpr(c.expr) || c.type === "SCALAR_VALUE_COL" && scalarValueHasAggregate(c.expr)
23549
+ (c) => c.type === "AGGREGATE" || c.type === "ARITH_AGG_COL" || c.type === "ARITH_COL" && containsAggregate2(c.expr) || c.type === "SCALAR_SUBQUERY_COL" || c.type === "CASE_COL" && containsAggregate2(c.expr) || c.type === "STRFUNC_COL" && hasAggregateInStringFuncExpr(c.expr) || c.type === "SCALAR_VALUE_COL" && scalarValueHasAggregate(c.expr)
23540
23550
  )) return "FULL_SCAN";
23541
23551
  if (whereRequiresJsEval(stmt.where)) return "FULL_SCAN";
23542
23552
  if (stmt.orderBy.some((o) => o.key.type !== "FIELD_NAME")) return "FULL_SCAN";
@@ -23622,7 +23632,7 @@ function convertOrderBy(item) {
23622
23632
  }
23623
23633
  function extractFields(columns) {
23624
23634
  const hasWildcard = columns.some(
23625
- (c) => c.type === "WILDCARD" || c.type === "AGGREGATE" || c.type === "ARITH_AGG_COL" || c.type === "CASE_COL" || c.type === "SCALAR_SUBQUERY_COL"
23635
+ (c) => c.type === "WILDCARD" || c.type === "AGGREGATE" || c.type === "ARITH_AGG_COL" || c.type === "ARITH_COL" && containsAggregate2(c.expr) || c.type === "CASE_COL" || c.type === "SCALAR_SUBQUERY_COL"
23626
23636
  );
23627
23637
  if (hasWildcard) return [];
23628
23638
  const fields = [];
@@ -23837,7 +23847,7 @@ function collectRequiredFieldsByTable(stmt, plainGroupByPlan, sourceAware) {
23837
23847
  }
23838
23848
  return;
23839
23849
  }
23840
- if ((phase === "orderBy" || phase === "having" || phase === "groupBy") && selectAliases.has(rawName)) {
23850
+ if ((phase === "orderBy" || phase === "having" || phase === "groupBy") && resolveProjectedName(rawName, selectAliases) !== void 0) {
23841
23851
  return;
23842
23852
  }
23843
23853
  if ((phase === "orderBy" || phase === "having" || phase === "groupBy") && isAggregateSyntheticName(rawName)) {
@@ -24180,9 +24190,7 @@ function canInlineSingleCte(stmt) {
24180
24190
  if (finalQuery.type !== "SELECT") return false;
24181
24191
  if (finalQuery.from.cteName !== cteDef.name || finalQuery.joins.length > 0) return false;
24182
24192
  if (hasGroupingClause(finalQuery) || finalQuery.distinct) return false;
24183
- return !finalQuery.columns.some(
24184
- (column) => column.type === "AGGREGATE" || column.type === "ARITH_AGG_COL"
24185
- );
24193
+ return !isAggregateQueryBlock(finalQuery);
24186
24194
  }
24187
24195
  function buildInlinedQuery(stmt) {
24188
24196
  const cteBody = stmt.ctes[0].query;
@@ -27001,6 +27009,93 @@ function resolveFieldRef(row, field) {
27001
27009
  return "";
27002
27010
  }
27003
27011
 
27012
+ // src/core/expressionSemantics.ts
27013
+ var NUMBER_RETURNING_FUNCTIONS = /* @__PURE__ */ new Set([
27014
+ "LENGTH",
27015
+ "LENGTH_CHAR",
27016
+ "INSTR",
27017
+ "ROUND",
27018
+ "FLOOR",
27019
+ "CEIL",
27020
+ "TRUNCATE",
27021
+ "YEAR",
27022
+ "MONTH",
27023
+ "DAY",
27024
+ "DATEDIFF",
27025
+ "ABS",
27026
+ "MOD",
27027
+ "POWER",
27028
+ "SQRT",
27029
+ "DAYOFWEEK",
27030
+ "QUARTER",
27031
+ "WEEK"
27032
+ ]);
27033
+ var ALL_NUMERIC_ARGUMENT_FUNCTIONS = /* @__PURE__ */ new Set([
27034
+ "COALESCE",
27035
+ "ISNULL",
27036
+ "NULLIF",
27037
+ "GREATEST",
27038
+ "LEAST"
27039
+ ]);
27040
+ function resolvedKind(value) {
27041
+ if (value === "number" || value === "string") return value;
27042
+ return value?.compareMode === "number" || value?.compareMode === "recordNumber" ? "number" : "string";
27043
+ }
27044
+ function fieldRefFromLegacyName(field) {
27045
+ const dot = field.indexOf(".");
27046
+ return dot > 0 ? { type: "FIELD", tableAlias: field.slice(0, dot), field: field.slice(dot + 1) } : { type: "FIELD", tableAlias: null, field };
27047
+ }
27048
+ function aggregateResultKind(ref, resolveField2) {
27049
+ if (ref.func === "COUNT" || ref.func === "SUM" || ref.func === "AVG" || ref.func === "STDDEV_POP" || ref.func === "STDDEV_SAMP" || ref.func === "VAR_POP" || ref.func === "VAR_SAMP" || ref.func === "MEDIAN") return "number";
27050
+ if (ref.func === "GROUP_CONCAT") return "string";
27051
+ return ref.arg.type === "WILDCARD" ? "string" : expressionSemanticKind(ref.arg, resolveField2);
27052
+ }
27053
+ function stringFunctionSemanticKind(expr, resolveField2) {
27054
+ if (expr.func === "CAST") {
27055
+ const target = expr.args[1];
27056
+ return target?.type === "STRING" && target.value === "NUMBER" ? "number" : "string";
27057
+ }
27058
+ if (NUMBER_RETURNING_FUNCTIONS.has(expr.func)) return "number";
27059
+ if (ALL_NUMERIC_ARGUMENT_FUNCTIONS.has(expr.func) && expr.args.length > 0 && expr.args.every((arg) => expressionSemanticKind(arg, resolveField2) === "number")) return "number";
27060
+ return "string";
27061
+ }
27062
+ function expressionSemanticKind(expr, resolveField2) {
27063
+ if (expr === null || typeof expr !== "object") return "string";
27064
+ const value = expr;
27065
+ switch (value["type"]) {
27066
+ case "NUMBER":
27067
+ case "ARITH":
27068
+ case "SCALAR_ARITH":
27069
+ case "AGG_ARITH":
27070
+ return "number";
27071
+ case "STRING_FUNC":
27072
+ return stringFunctionSemanticKind(expr, resolveField2);
27073
+ case "AGG_REF":
27074
+ return aggregateResultKind(expr, resolveField2);
27075
+ case "FIELD":
27076
+ return resolvedKind(resolveField2?.(expr));
27077
+ case "FIELD_REF":
27078
+ return resolvedKind(resolveField2?.(fieldRefFromLegacyName(value["field"])));
27079
+ case "AGG_GROUP_KEY":
27080
+ return resolvedKind(resolveField2?.({
27081
+ type: "FIELD",
27082
+ tableAlias: typeof value["tableAlias"] === "string" ? value["tableAlias"] : null,
27083
+ field: value["field"]
27084
+ }));
27085
+ case "CASE_WHEN": {
27086
+ const branches = value["branches"];
27087
+ const elseResult = value["elseResult"];
27088
+ const results = [
27089
+ ...branches.map((branch) => branch.result),
27090
+ ...elseResult === null || elseResult === void 0 ? [] : [elseResult]
27091
+ ];
27092
+ return results.length > 0 && results.every((result) => expressionSemanticKind(result, resolveField2) === "number") ? "number" : "string";
27093
+ }
27094
+ default:
27095
+ return "string";
27096
+ }
27097
+ }
27098
+
27004
27099
  // src/engine/evalWhere.ts
27005
27100
  function evalWhere(expr, row, resolveFieldType, appliedKlikes, resolveFieldSemantics2, context = {}) {
27006
27101
  switch (expr.type) {
@@ -27060,33 +27155,13 @@ function evalOp(op, leftStr, right, row, fieldType, resolveFieldType, semantics
27060
27155
  const rightStr = resolveValue(right, row, resolveFieldType, resolveFieldSemantics2, context);
27061
27156
  return compareScalarValues(op, leftStr, rightStr, semantics);
27062
27157
  }
27063
- var NUMERIC_STRING_FUNCTIONS = /* @__PURE__ */ new Set([
27064
- "LENGTH",
27065
- "LENGTH_CHAR",
27066
- "INSTR",
27067
- "ROUND",
27068
- "FLOOR",
27069
- "CEIL",
27070
- "TRUNCATE",
27071
- "YEAR",
27072
- "MONTH",
27073
- "DAY",
27074
- "DATEDIFF",
27075
- "ABS",
27076
- "MOD",
27077
- "POWER",
27078
- "SQRT",
27079
- "DAYOFWEEK",
27080
- "QUARTER",
27081
- "WEEK"
27082
- ]);
27083
27158
  function semanticsForLeft(left, fieldType, resolveSemantics) {
27084
27159
  if (left.type === "FIELD") {
27085
27160
  return resolveSemantics?.(left) ?? (fieldType ? resolveFieldSemantics({ fieldType }) : syntheticSemantics("string"));
27086
27161
  }
27087
27162
  if (left.type === "ARITH_FIELD" || left.type === "AGG_FIELD") return syntheticSemantics("number");
27088
27163
  if (left.type === "FUNC_FIELD") {
27089
- return syntheticSemantics(NUMERIC_STRING_FUNCTIONS.has(left.expr.func) ? "number" : "string");
27164
+ return syntheticSemantics(stringFunctionSemanticKind(left.expr, (ref) => resolveSemantics?.(ref)));
27090
27165
  }
27091
27166
  if (left.type === "CASE_FIELD") {
27092
27167
  const results = [
@@ -27096,7 +27171,7 @@ function semanticsForLeft(left, fieldType, resolveSemantics) {
27096
27171
  const modes = results.map((result) => {
27097
27172
  if (result.type === "NUMBER" || result.type === "ARITH") return syntheticSemantics("number");
27098
27173
  if (result.type === "STRING_FUNC") {
27099
- return syntheticSemantics(NUMERIC_STRING_FUNCTIONS.has(result.func) ? "number" : "string");
27174
+ return syntheticSemantics(stringFunctionSemanticKind(result, (ref) => resolveSemantics?.(ref)));
27100
27175
  }
27101
27176
  if (result.type === "FIELD_REF") {
27102
27177
  const dot = result.field.indexOf(".");
@@ -31150,10 +31225,15 @@ function buildApplyParentSelectionPlan(where, metadata) {
31150
31225
  var REST_OFFSET_MAX = 1e4;
31151
31226
  var REST_LIMIT_MAX = 500;
31152
31227
  function fieldSemantics(item, semantics) {
31153
- return item.key.type === "FIELD_NAME" ? semantics.get(item.key.name) : void 0;
31228
+ if (item.key.type !== "FIELD_NAME") return void 0;
31229
+ const resolved = resolveProjectedName(item.key.name, semantics.keys());
31230
+ return resolved === void 0 ? void 0 : semantics.get(resolved);
31154
31231
  }
31155
31232
  function hasSelectOutputAlias(stmt, name) {
31156
- return stmt.columns.some((column) => "alias" in column && column.alias === name);
31233
+ const aliases = stmt.columns.flatMap(
31234
+ (column) => "alias" in column && column.alias !== null ? [column.alias] : []
31235
+ );
31236
+ return resolveProjectedName(name, aliases) !== void 0;
31157
31237
  }
31158
31238
  function planCanonicalOrder(input) {
31159
31239
  const { stmt } = input;
@@ -31665,7 +31745,7 @@ function applyFilter(rows, where, resolveFieldType, appliedKlikes, resolveFieldS
31665
31745
  }
31666
31746
  function hasAggregateColumns(columns) {
31667
31747
  return columns.some(
31668
- (c) => c.type === "AGGREGATE" || c.type === "ARITH_AGG_COL" || c.type === "CASE_COL" && containsAggregate2(c.expr) || c.type === "STRFUNC_COL" && hasAggregateInStringFuncExpr2(c.expr) || c.type === "SCALAR_VALUE_COL" && scalarValueHasAggregate2(c.expr)
31748
+ (c) => c.type === "AGGREGATE" || c.type === "ARITH_AGG_COL" || c.type === "ARITH_COL" && containsAggregate2(c.expr) || c.type === "CASE_COL" && containsAggregate2(c.expr) || c.type === "STRFUNC_COL" && hasAggregateInStringFuncExpr2(c.expr) || c.type === "SCALAR_VALUE_COL" && scalarValueHasAggregate2(c.expr)
31669
31749
  );
31670
31750
  }
31671
31751
  function applyGroupBy(rows, groupByKeys, columns, resolveAggSortKind, resolutionPlan, aliasEvaluationContext = {}) {
@@ -31819,6 +31899,16 @@ function materializeAggregateColumns(outRow, groupRows, columns, resolveAggSortK
31819
31899
  String(evalAggArithExpr(col.expr, groupRows, resolveAggSortKind, evaluationContext)),
31820
31900
  [outputKey]
31821
31901
  );
31902
+ } else if (col.type === "ARITH_COL" && containsAggregate2(col.expr)) {
31903
+ materializeAggregateDependencies(outRow, groupRows, col.expr, resolveAggSortKind, evaluationContext);
31904
+ const outputKey = col.alias ?? arithColDefaultKey(col.expr);
31905
+ const resolvedExpr = resolveAggInArithNode(col.expr, groupRows, resolveAggSortKind);
31906
+ setMaterializedSelectValue(
31907
+ outRow,
31908
+ columnIndex,
31909
+ String(evalArithExpr(resolvedExpr, outRow, evaluationContext)),
31910
+ [outputKey]
31911
+ );
31822
31912
  } else if (col.type === "STRFUNC_COL" && hasAggregateInStringFuncExpr2(col.expr)) {
31823
31913
  materializeAggregateDependencies(outRow, groupRows, col.expr, resolveAggSortKind, evaluationContext);
31824
31914
  const outputKey = col.alias ?? stringFuncDefaultKey(col.expr);
@@ -32079,9 +32169,7 @@ function resolveAggregateArgSemantics(arg, resolver) {
32079
32169
  if (arg.type === "NUMBER" || arg.type === "ARITH" || arg.type === "SCALAR_ARITH") return "number";
32080
32170
  if (arg.type === "STRING" || arg.type === "CONCAT_OP" || arg.type === "VARIABLE") return "string";
32081
32171
  if (arg.type === "STRING_FUNC") {
32082
- const numeric = /* @__PURE__ */ new Set(["LENGTH", "LENGTH_CHAR", "INSTR", "ROUND", "FLOOR", "CEIL", "TRUNCATE", "YEAR", "MONTH", "DAY", "DATEDIFF", "ABS", "MOD", "POWER", "SQRT", "DAYOFWEEK", "QUARTER", "WEEK"]);
32083
- if (arg.func === "CAST") return arg.args[1]?.type === "STRING" && arg.args[1].value === "NUMBER" ? "number" : "string";
32084
- return numeric.has(arg.func) ? "number" : "string";
32172
+ return stringFunctionSemanticKind(arg, (field) => resolver?.(field));
32085
32173
  }
32086
32174
  const results = [...arg.branches.map((branch) => branch.result), ...arg.elseResult === null ? [] : [arg.elseResult]].filter((result) => result.type !== "ARRAY").map((result) => resolveAggregateArgSemantics(result, resolver));
32087
32175
  if (results.length === 0 || results.some((result) => result === void 0)) return "string";
@@ -32169,7 +32257,10 @@ function sortDecoratedRows(rows, orderBy, optionOrders, sortKinds, fieldSemantic
32169
32257
  const keyMeta = orderBy.map(({ key }) => {
32170
32258
  if (key.type === "ARITH_KEY") return { semantics: syntheticSemantics("number") };
32171
32259
  if (key.type === "FUNC_KEY") {
32172
- return { semantics: syntheticSemantics(NUMERIC_ORDER_FUNCTIONS.has(key.expr.func) ? "number" : "string") };
32260
+ return { semantics: syntheticSemantics(stringFunctionSemanticKind(
32261
+ key.expr,
32262
+ (field) => fieldSemantics2?.get(field.tableAlias ? `${field.tableAlias}.${field.field}` : field.field)
32263
+ )) };
32173
32264
  }
32174
32265
  if (key.type === "GROUPING_KEY") return { semantics: syntheticSemantics("number") };
32175
32266
  const semantics = fieldSemantics2?.get(key.name);
@@ -32209,26 +32300,6 @@ function compareDecoratedRows(a, b, orderBy, keyMeta) {
32209
32300
  function compareSortKeys(a, b, meta) {
32210
32301
  return compareCanonicalValues(a.s, b.s, meta.semantics);
32211
32302
  }
32212
- var NUMERIC_ORDER_FUNCTIONS = /* @__PURE__ */ new Set([
32213
- "LENGTH",
32214
- "LENGTH_CHAR",
32215
- "INSTR",
32216
- "ROUND",
32217
- "FLOOR",
32218
- "CEIL",
32219
- "TRUNCATE",
32220
- "YEAR",
32221
- "MONTH",
32222
- "DAY",
32223
- "DATEDIFF",
32224
- "ABS",
32225
- "MOD",
32226
- "POWER",
32227
- "SQRT",
32228
- "DAYOFWEEK",
32229
- "QUARTER",
32230
- "WEEK"
32231
- ]);
32232
32303
  function evalOrderKey(key, row, aliasEvaluator, evaluationContext = {}) {
32233
32304
  const sourceRow = sourceRowForEvaluation(row);
32234
32305
  switch (key.type) {
@@ -32266,11 +32337,7 @@ function buildOrderByAliasEvaluator(columns, scalarCache, resolveFieldType, reso
32266
32337
  evaluators.set(alias, (row) => getMaterializedSelectValue(row, columnIndex) ?? "");
32267
32338
  break;
32268
32339
  case "ARITH_COL":
32269
- evaluators.set(alias, (row) => String(evalArithExpr(
32270
- column.expr,
32271
- sourceRowForEvaluation(row),
32272
- evaluationContext
32273
- )));
32340
+ evaluators.set(alias, (row) => containsAggregate2(column.expr) ? getMaterializedSelectValue(row, columnIndex) ?? "" : String(evalArithExpr(column.expr, sourceRowForEvaluation(row), evaluationContext)));
32274
32341
  break;
32275
32342
  case "STRFUNC_COL": {
32276
32343
  const source = stringFuncDefaultKey(column.expr);
@@ -32319,7 +32386,10 @@ function buildOrderByAliasEvaluator(columns, scalarCache, resolveFieldType, reso
32319
32386
  break;
32320
32387
  }
32321
32388
  }
32322
- return (name, row) => evaluators.get(name)?.(row);
32389
+ return (name, row) => {
32390
+ const resolved = resolveProjectedName(name, evaluators.keys());
32391
+ return resolved === void 0 ? void 0 : evaluators.get(resolved)?.(row);
32392
+ };
32323
32393
  }
32324
32394
  function applyWindow(rows, columns, optionOrders, sortKinds, fieldSemantics2, resolveAggSortKind, evaluationContext = {}) {
32325
32395
  const windows = columns.map((column, columnIndex) => ({ column, columnIndex })).filter((item) => item.column.type === "WINDOW_COL");
@@ -32503,7 +32573,7 @@ function evaluateSelectColumnValue(column, row, columnIndex, context = {}) {
32503
32573
  return getMaterializedSelectValue(row, columnIndex) ?? getMaterializedLookupValue(row, source) ?? getLegacyMaterializedValue(row, source) ?? "0";
32504
32574
  }
32505
32575
  case "ARITH_COL":
32506
- return String(evalArithExpr(column.expr, sourceRow, context.evaluationContext));
32576
+ return containsAggregate2(column.expr) ? getMaterializedSelectValue(row, columnIndex) ?? getMaterializedLookupValue(row, column.alias ?? arithColDefaultKey(column.expr)) ?? "" : String(evalArithExpr(column.expr, sourceRow, context.evaluationContext));
32507
32577
  case "CASE_COL":
32508
32578
  return containsAggregate2(column.expr) ? getMaterializedSelectValue(row, columnIndex) ?? getMaterializedLookupValue(row, caseMaterializedKey(column.alias, columnIndex)) ?? getLegacyMaterializedValue(row, caseMaterializedKey(column.alias, columnIndex)) ?? "" : evalCaseWhen(
32509
32579
  column.expr,
@@ -32886,6 +32956,17 @@ function resolveAggInScalarValue(expr, rows, resolveAggSortKind) {
32886
32956
  }
32887
32957
  return expr;
32888
32958
  }
32959
+ function resolveAggInArithNode(expr, rows, resolveAggSortKind) {
32960
+ if (expr.type === "STRING_FUNC") return resolveAggInStringFuncExpr(expr, rows, resolveAggSortKind);
32961
+ if (expr.type === "ARITH") {
32962
+ return {
32963
+ ...expr,
32964
+ left: resolveAggInArithNode(expr.left, rows, resolveAggSortKind),
32965
+ right: resolveAggInArithNode(expr.right, rows, resolveAggSortKind)
32966
+ };
32967
+ }
32968
+ return expr;
32969
+ }
32889
32970
  function resolveAggInCaseResult(result, rows, resolveAggSortKind) {
32890
32971
  if (result.type === "AGG_REF") {
32891
32972
  const value = evalAggregate(
@@ -32965,7 +33046,10 @@ function deriveOutputOrderSemantics(columns, resolveAggSortKind) {
32965
33046
  } else if (column.type === "LITERAL_COL" || column.type === "CASE_COL" || column.type === "SCALAR_SUBQUERY_COL" || column.type === "SCALAR_VALUE_COL") {
32966
33047
  result.set(column.alias, syntheticSemantics("string"));
32967
33048
  } else if (column.type === "STRFUNC_COL") {
32968
- result.set(column.alias, syntheticSemantics(NUMERIC_ORDER_FUNCTIONS.has(column.expr.func) ? "number" : "string"));
33049
+ result.set(column.alias, syntheticSemantics(stringFunctionSemanticKind(
33050
+ column.expr,
33051
+ (field) => resolveAggSortKind?.(field)
33052
+ )));
32969
33053
  }
32970
33054
  }
32971
33055
  return result;
@@ -35115,12 +35199,28 @@ var SearchAbortedError = class extends Error {
35115
35199
  this.name = "SearchAbortedError";
35116
35200
  }
35117
35201
  };
35202
+ function resolveMaterializedColumn(table, requested) {
35203
+ return table?.columns.includes(requested) ? requested : void 0;
35204
+ }
35205
+ function resolveMaterializedColumnMeta(table, requested) {
35206
+ const resolved = resolveMaterializedColumn(table, requested);
35207
+ return resolved === void 0 ? void 0 : table?.columnMeta?.get(resolved);
35208
+ }
35118
35209
  var materializedMetaBySelectResult = /* @__PURE__ */ new WeakMap();
35119
35210
  function getSelectColumnMeta(result) {
35120
35211
  return materializedMetaBySelectResult.get(result);
35121
35212
  }
35122
35213
  var materializedMetaByValidationResult = /* @__PURE__ */ new WeakMap();
35123
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
+ }
35124
35224
  var statementEvaluationContextKey = /* @__PURE__ */ Symbol("statementEvaluationContext");
35125
35225
  var importSourceMaterializedCallbackKey = /* @__PURE__ */ Symbol("importSourceMaterializedCallback");
35126
35226
  var nativeUpsertExecutionKey = /* @__PURE__ */ Symbol("nativeUpsertExecution");
@@ -35921,13 +36021,17 @@ async function executeBatch(sql, client, options = {}) {
35921
36021
  }
35922
36022
  }
35923
36023
  metrics.elapsedMs = Date.now() - startedAt;
36024
+ const warnings = [.../* @__PURE__ */ new Set([
36025
+ ...dialect1Warnings,
36026
+ ...results.flatMap((statement) => statement.warnings ?? [])
36027
+ ])];
35924
36028
  const batchResult = {
35925
36029
  ok: results.every((r) => r.status === "success" || r.skippedReason === "exit"),
35926
36030
  statementCount: statements.length,
35927
36031
  statements: results,
35928
36032
  analysis,
35929
36033
  metrics,
35930
- ...dialect1Warnings.length > 0 ? { warnings: dialect1Warnings } : {}
36034
+ ...warnings.length > 0 ? { warnings } : {}
35931
36035
  };
35932
36036
  const observer = options[batchCompletionObserverKey];
35933
36037
  if (observer) {
@@ -36038,7 +36142,7 @@ async function executeBatchStatement(context) {
36038
36142
  }
36039
36143
  await assertRelativeDateExecutionPlan(resolvedStmt, client, cacheContext);
36040
36144
  if (resolvedStmt.type === "VALIDATE") {
36041
- const result = await executeExistingRecordValidationCore(
36145
+ const result2 = await executeExistingRecordValidationCore(
36042
36146
  resolvedStmt,
36043
36147
  client,
36044
36148
  { ...options, onLimitReached: "error" },
@@ -36048,19 +36152,20 @@ async function executeBatchStatement(context) {
36048
36152
  appendValidationErrors(
36049
36153
  tempTables,
36050
36154
  resolvedStmt.errorTable,
36051
- result.columns,
36052
- result.rows,
36155
+ result2.columns,
36156
+ result2.rows,
36053
36157
  options.tempTableMaxRows ?? TEMP_TABLE_MAX_ROWS,
36054
- materializedMetaBySelectResult.get(result) ?? existingValidationColumnMeta(resolvedStmt.summary === true)
36158
+ materializedMetaBySelectResult.get(result2) ?? existingValidationColumnMeta(resolvedStmt.summary === true)
36055
36159
  );
36056
36160
  }
36057
- return { result };
36161
+ return { result: result2 };
36058
36162
  }
36059
36163
  if (resolvedStmt.type === "IMPORT") {
36060
- return { result: await executeImport(resolvedStmt, client, options, cacheContext, tempTables) };
36164
+ const result2 = await executeImport(resolvedStmt, client, options, cacheContext, tempTables);
36165
+ return outcomeWithResultWarnings(resolvedStmt, result2);
36061
36166
  }
36062
36167
  if ("validateOnly" in resolvedStmt && resolvedStmt.validateOnly === true) {
36063
- const result = await executeDmlValidation(
36168
+ const result2 = await executeDmlValidation(
36064
36169
  resolvedStmt,
36065
36170
  client,
36066
36171
  { ...options, onLimitReached: "error" },
@@ -36072,25 +36177,24 @@ async function executeBatchStatement(context) {
36072
36177
  appendValidationErrors(
36073
36178
  tempTables,
36074
36179
  resolvedStmt.validationErrorTable,
36075
- result.columns,
36076
- result.errors,
36180
+ result2.columns,
36181
+ result2.errors,
36077
36182
  options.tempTableMaxRows ?? TEMP_TABLE_MAX_ROWS,
36078
- materializedMetaByValidationResult.get(result) ?? /* @__PURE__ */ new Map()
36183
+ materializedMetaByValidationResult.get(result2) ?? /* @__PURE__ */ new Map()
36079
36184
  );
36080
36185
  }
36081
- return { result };
36186
+ return outcomeWithResultWarnings(resolvedStmt, result2);
36082
36187
  }
36083
36188
  if ("onErrorSkip" in resolvedStmt && resolvedStmt.onErrorSkip === true) {
36084
- return {
36085
- result: await executeOnErrorSkip(
36086
- resolvedStmt,
36087
- client,
36088
- { ...options, onLimitReached: "error" },
36089
- cacheContext,
36090
- tempTables,
36091
- info.index + 1
36092
- )
36093
- };
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);
36094
36198
  }
36095
36199
  if (resolvedStmt.type === "CREATE_TEMP_TABLE") {
36096
36200
  const materializeOptions = {
@@ -36098,13 +36202,17 @@ async function executeBatchStatement(context) {
36098
36202
  maxRecords: options.tempTableMaxRows ?? TEMP_TABLE_MAX_ROWS,
36099
36203
  onLimitReached: "error"
36100
36204
  };
36101
- const result = await runSelectLike(resolvedStmt.query, client, materializeOptions, cacheContext, tempTables);
36205
+ const result2 = await runSelectLike(resolvedStmt.query, client, materializeOptions, cacheContext, tempTables);
36102
36206
  tempTables.set(resolvedStmt.name, {
36103
- rows: result.rows,
36104
- columns: result.columns,
36105
- columnMeta: materializedMetaBySelectResult.get(result)
36207
+ rows: result2.rows,
36208
+ columns: result2.columns,
36209
+ columnMeta: materializedMetaBySelectResult.get(result2)
36106
36210
  });
36107
- 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
+ };
36108
36216
  }
36109
36217
  if (stmt.type === "DROP_TEMP_TABLE") {
36110
36218
  tempTables.delete(stmt.name);
@@ -36120,12 +36228,12 @@ async function executeBatchStatement(context) {
36120
36228
  }
36121
36229
  }
36122
36230
  if (resolvedStmt.type === "ASSERT") {
36123
- const result = await executeAssert(resolvedStmt, client, options, cacheContext, tempTables);
36124
- return result.warning !== void 0 ? { result } : {};
36231
+ const result2 = await executeAssert(resolvedStmt, client, options, cacheContext, tempTables);
36232
+ return result2.warning !== void 0 ? { result: result2 } : {};
36125
36233
  }
36126
36234
  if (resolvedStmt.type === "EXIT") {
36127
- const result = await executeExit(resolvedStmt, client, options, cacheContext, tempTables);
36128
- return { result, ...result.exited ? { exitTriggered: true } : {} };
36235
+ const result2 = await executeExit(resolvedStmt, client, options, cacheContext, tempTables);
36236
+ return { result: result2, ...result2.exited ? { exitTriggered: true } : {} };
36129
36237
  }
36130
36238
  if (info.tempTablesReferenced.length > 0) {
36131
36239
  if (resolvedStmt.type === "SELECT" || resolvedStmt.type === "UNION") {
@@ -36144,17 +36252,20 @@ async function executeBatchStatement(context) {
36144
36252
  return { result: await executeWith(resolvedStmt, client, options, cacheContext, tempTables) };
36145
36253
  }
36146
36254
  if (resolvedStmt.type === "INSERT_SELECT") {
36147
- return { result: await executeInsertSelect(resolvedStmt, client, options, cacheContext, tempTables) };
36255
+ const result2 = await executeInsertSelect(resolvedStmt, client, options, cacheContext, tempTables);
36256
+ return outcomeWithResultWarnings(resolvedStmt, result2);
36148
36257
  }
36149
36258
  if (resolvedStmt.type === "UPSERT_SELECT") {
36150
- return { result: await executeUpsertSelect(resolvedStmt, client, options, cacheContext, tempTables) };
36259
+ const result2 = await executeUpsertSelect(resolvedStmt, client, options, cacheContext, tempTables);
36260
+ return outcomeWithResultWarnings(resolvedStmt, result2);
36151
36261
  }
36152
36262
  if (resolvedStmt.type === "UPDATE" && resolvedStmt.from?.cteName != null) {
36153
36263
  return { result: await executeUpdate(resolvedStmt, client, options, cacheContext, tempTables) };
36154
36264
  }
36155
36265
  throw new Error(`ArgumentError: temp table references in ${stmt.type} are not supported yet.`);
36156
36266
  }
36157
- return { result: await executeParsedStatement(resolvedStmt, client, options, cacheContext) };
36267
+ const result = await executeParsedStatement(resolvedStmt, client, options, cacheContext);
36268
+ return outcomeWithResultWarnings(resolvedStmt, result);
36158
36269
  }
36159
36270
  async function runSelectLike(query, client, options, cacheContext, tempTables) {
36160
36271
  if (query.type === "WITH") {
@@ -36558,7 +36669,7 @@ async function evaluateScalarSubquery(sourceQuery, client, options, cacheContext
36558
36669
  return result.rows[0]?.[result.columns[0]] ?? "";
36559
36670
  }
36560
36671
  function withScalarProbeLimit(query) {
36561
- const hasAgg = normalizeGroupingSpec(query).type !== "NONE" || query.columns.some((c) => c.type === "AGGREGATE" || c.type === "ARITH_AGG_COL");
36672
+ const hasAgg = isAggregateQueryBlock(query);
36562
36673
  if (hasAgg || query.distinct || query.limit !== null) return { query, probed: false };
36563
36674
  return { query: { ...query, limit: 2 }, probed: true };
36564
36675
  }
@@ -36656,18 +36767,19 @@ async function buildWhereFieldSemanticsResolver(stmt, client, cacheContext, mate
36656
36767
  const table = tables.find((candidate) => effectiveTableAlias(candidate) === field.tableAlias);
36657
36768
  if (!table) return void 0;
36658
36769
  if (table.cteName !== null) {
36659
- return materializedTables?.get(table.cteName)?.columnMeta?.get(field.field)?.semantics ?? syntheticSemantics("string");
36770
+ return resolveMaterializedColumnMeta(materializedTables?.get(table.cteName), field.field)?.semantics ?? syntheticSemantics("string");
36660
36771
  }
36661
36772
  return fromPhysical(table, field.field, true);
36662
36773
  }
36663
36774
  if (stmt.joins.length === 0) {
36664
36775
  if (stmt.from.cteName !== null) {
36665
- return materializedTables?.get(stmt.from.cteName)?.columnMeta?.get(field.field)?.semantics ?? syntheticSemantics("string");
36776
+ return resolveMaterializedColumnMeta(materializedTables?.get(stmt.from.cteName), field.field)?.semantics ?? syntheticSemantics("string");
36666
36777
  }
36667
36778
  return fromPhysical(stmt.from, field.field, true);
36668
36779
  }
36669
36780
  const matches = tables.flatMap((table) => {
36670
- const semantics = table.cteName !== null ? materializedTables?.get(table.cteName)?.columnMeta?.get(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);
36671
36783
  return semantics ? [semantics] : [];
36672
36784
  });
36673
36785
  if (matches.length === 1) return matches[0];
@@ -36795,13 +36907,20 @@ function buildHavingFieldSemanticsResolver(stmt, rowResolver) {
36795
36907
  semantics = column.func === "GROUP_CONCAT" ? syntheticSemantics("string") : syntheticSemantics("number");
36796
36908
  }
36797
36909
  } else if (column.type === "STRFUNC_COL") {
36798
- semantics = stringFunctionColumnMeta(column.expr).semantics;
36910
+ semantics = stringFunctionColumnMeta(column.expr, (ref) => {
36911
+ const resolved = rowResolver(ref);
36912
+ return resolved ? { compareMode: resolved.compareMode } : void 0;
36913
+ }).semantics;
36799
36914
  } else if (column.type === "LITERAL_COL" || column.type === "SCALAR_SUBQUERY_COL" || column.type === "CASE_COL" || column.type === "SCALAR_VALUE_COL") {
36800
36915
  semantics = syntheticSemantics("string");
36801
36916
  }
36802
36917
  if (semantics) aliases.set(column.alias, semantics);
36803
36918
  }
36804
- return (field) => field.tableAlias === null && aliases.has(field.field) ? aliases.get(field.field) : rowResolver(field);
36919
+ return (field) => {
36920
+ if (field.tableAlias !== null) return rowResolver(field);
36921
+ const alias = resolveProjectedName(field.field, aliases.keys());
36922
+ return alias === void 0 ? rowResolver(field) : aliases.get(alias);
36923
+ };
36805
36924
  }
36806
36925
  function formatWhereCapabilityFailure(result) {
36807
36926
  const reason = result.reasons.find(
@@ -36848,6 +36967,7 @@ async function assertDmlWhereCapability(stmt, client, cacheContext) {
36848
36967
  }
36849
36968
  }
36850
36969
  async function executeSelect(stmt, client, options, cacheContext, cteCache, captureColumnMeta = false, forLibraryCapture = false, windowWarningContext = "DIRECT") {
36970
+ bindSelectAliasesInHaving(stmt);
36851
36971
  let result;
36852
36972
  const subqueryWarnings = /* @__PURE__ */ new Set();
36853
36973
  await validateSelectGroupingPlanning(stmt, client, cacheContext, cteCache);
@@ -37129,7 +37249,7 @@ async function buildGroupingFieldResolver(stmt, client, cacheContext, materializ
37129
37249
  const materializedHas = (table, field) => {
37130
37250
  if (table.cteName === null) return false;
37131
37251
  const materialized = materializedTables?.get(table.cteName);
37132
- return materialized ? materialized.columns.includes(field) : true;
37252
+ return materialized ? resolveMaterializedColumn(materialized, field) !== void 0 : true;
37133
37253
  };
37134
37254
  const resolved = (table, tableIndex, field, code) => {
37135
37255
  const sameNamePhysical = tables.filter(
@@ -37532,6 +37652,145 @@ function b86FieldExists(schema, field) {
37532
37652
  if (schema.table.cteName !== null) return schema.validCodes.has(field);
37533
37653
  return b86PhysicalFieldExists(schema, field);
37534
37654
  }
37655
+ async function buildPhysicalFieldProbe(stmt, client, cacheContext) {
37656
+ const physical = [stmt.from, ...stmt.joins.map((join3) => join3.table)].filter((table) => table.cteName === null);
37657
+ const codesByApp = /* @__PURE__ */ new Map();
37658
+ await Promise.all([...new Set(physical.map((table) => table.appId))].map(async (appId) => {
37659
+ const defs = await getFieldsCached(appId, client, cacheContext);
37660
+ codesByApp.set(appId, new Set(defs.map((def) => def.code)));
37661
+ }));
37662
+ return (table, field) => {
37663
+ if (table.cteName !== null) return false;
37664
+ if (table.subtableCode || isSystemLikeFieldCode(field)) return true;
37665
+ const codes = codesByApp.get(table.appId);
37666
+ if (!codes || codes.size === 0) return true;
37667
+ return codes.has(fieldCodeForTypeLookup(table, field));
37668
+ };
37669
+ }
37670
+ async function bindProjectedNamesForSelectWithSchemas(stmt, materializedTables, client, cacheContext) {
37671
+ let consulted = false;
37672
+ bindProjectedNamesForSelect(stmt, materializedTables, () => {
37673
+ consulted = true;
37674
+ return true;
37675
+ });
37676
+ if (!consulted) return;
37677
+ bindProjectedNamesForSelect(
37678
+ stmt,
37679
+ materializedTables,
37680
+ await buildPhysicalFieldProbe(stmt, client, cacheContext)
37681
+ );
37682
+ }
37683
+ function bindProjectedNamesForSelect(stmt, materializedTables, physicalMayHave) {
37684
+ const tables = [stmt.from, ...stmt.joins.map((join3) => join3.table)];
37685
+ const tableByAlias = /* @__PURE__ */ new Map();
37686
+ for (const table of tables) {
37687
+ for (const alias of b86SourceAliases(table)) tableByAlias.set(alias, table);
37688
+ }
37689
+ const aliases = stmt.columns.flatMap(
37690
+ (column) => "alias" in column && column.alias !== null ? [column.alias] : []
37691
+ );
37692
+ const materializedColumns = (table) => table.cteName === null || table.cteName === NO_FROM_CTE_NAME ? [] : materializedTables.get(table.cteName)?.columns ?? [];
37693
+ const resolveFromTable = (table, requested) => table ? resolveProjectedName(requested, materializedColumns(table)) : void 0;
37694
+ const resolveUnqualified = (requested) => {
37695
+ if (tables.some((table) => materializedColumns(table).includes(requested))) return requested;
37696
+ const matches = tables.flatMap((table) => {
37697
+ const resolved = resolveFromTable(table, requested);
37698
+ return resolved === void 0 ? [] : [resolved];
37699
+ });
37700
+ const unique2 = [...new Set(matches)];
37701
+ if (unique2.length !== 1) return void 0;
37702
+ if (tables.some((table) => physicalMayHave(table, requested))) return requested;
37703
+ return unique2[0];
37704
+ };
37705
+ const resolveReference = (requested, tableAlias, allowSelectAlias) => {
37706
+ if (allowSelectAlias && tableAlias === null) {
37707
+ const alias = resolveProjectedName(requested, aliases);
37708
+ if (alias !== void 0) return alias;
37709
+ }
37710
+ return tableAlias === null ? resolveUnqualified(requested) ?? requested : resolveFromTable(tableByAlias.get(tableAlias), requested) ?? requested;
37711
+ };
37712
+ const resolveText = (requested, allowSelectAlias) => {
37713
+ const dot = requested.indexOf(".");
37714
+ if (dot <= 0) return resolveReference(requested, null, allowSelectAlias);
37715
+ const qualifier = requested.slice(0, dot);
37716
+ const field = requested.slice(dot + 1);
37717
+ const resolved = resolveReference(field, qualifier, false);
37718
+ return resolved === field ? requested : `${qualifier}.${resolved}`;
37719
+ };
37720
+ for (const join3 of stmt.joins) {
37721
+ if (join3.type === "CROSS") continue;
37722
+ join3.on.left.field = resolveReference(join3.on.left.field, join3.on.left.tableAlias, false);
37723
+ join3.on.right.field = resolveReference(join3.on.right.field, join3.on.right.tableAlias, false);
37724
+ }
37725
+ const seen = /* @__PURE__ */ new Set();
37726
+ const visit = (node, allowSelectAlias = false) => {
37727
+ if (node === null || typeof node !== "object") return;
37728
+ if (seen.has(node)) return;
37729
+ seen.add(node);
37730
+ if (Array.isArray(node)) {
37731
+ for (const child of node) visit(child, allowSelectAlias);
37732
+ return;
37733
+ }
37734
+ const value = node;
37735
+ if (node !== stmt && (value["type"] === "SELECT" || value["type"] === "UNION")) return;
37736
+ if (value["type"] === "FIELD" && typeof value["field"] === "string") {
37737
+ const tableAlias = typeof value["tableAlias"] === "string" ? value["tableAlias"] : null;
37738
+ value["field"] = tableAlias === null ? resolveText(value["field"], allowSelectAlias) : resolveReference(value["field"], tableAlias, allowSelectAlias);
37739
+ } else if (value["type"] === "FIELD_REF" && typeof value["field"] === "string") {
37740
+ value["field"] = resolveText(value["field"], allowSelectAlias);
37741
+ } else if (value["type"] === "AGG_GROUP_KEY" && typeof value["field"] === "string") {
37742
+ const tableAlias = typeof value["tableAlias"] === "string" ? value["tableAlias"] : null;
37743
+ value["field"] = resolveReference(value["field"], tableAlias, allowSelectAlias);
37744
+ }
37745
+ for (const child of Object.values(value)) visit(child, allowSelectAlias);
37746
+ };
37747
+ for (const column of stmt.columns) visit(column);
37748
+ visit(stmt.where);
37749
+ visit(stmt.having, true);
37750
+ visit(stmt.grouping);
37751
+ const grouping = normalizeGroupingSpec(stmt);
37752
+ if (grouping.type === "PLAIN") {
37753
+ for (const item of grouping.allItems) {
37754
+ if (item.type === "FIELD_NAME") item.name = resolveText(item.name, true);
37755
+ else visit(item);
37756
+ }
37757
+ }
37758
+ for (const item of stmt.orderBy) {
37759
+ if (item.key.type === "FIELD_NAME") item.key.name = resolveText(item.key.name, true);
37760
+ else visit(item.key);
37761
+ }
37762
+ for (const column of stmt.columns) {
37763
+ if (column.type !== "WINDOW_COL") continue;
37764
+ for (const ref of column.partitionBy) {
37765
+ ref.field = resolveReference(ref.field, ref.tableAlias, false);
37766
+ }
37767
+ for (const item of column.orderBy) {
37768
+ if (item.key.type === "FIELD_NAME") item.key.name = resolveText(item.key.name, false);
37769
+ else visit(item.key);
37770
+ }
37771
+ }
37772
+ }
37773
+ function bindSelectAliasesInHaving(stmt) {
37774
+ const aliases = stmt.columns.flatMap(
37775
+ (column) => "alias" in column && column.alias !== null ? [column.alias] : []
37776
+ );
37777
+ const visit = (node) => {
37778
+ if (node === null || typeof node !== "object") return;
37779
+ if (Array.isArray(node)) {
37780
+ node.forEach(visit);
37781
+ return;
37782
+ }
37783
+ const value = node;
37784
+ if (value["type"] === "AGG_REF" || value["type"] === "AGG_ARITH") return;
37785
+ if (value["type"] === "FIELD" && (value["tableAlias"] === null || value["tableAlias"] === void 0) && typeof value["field"] === "string") {
37786
+ const resolved = resolveProjectedName(value["field"], aliases);
37787
+ if (resolved !== void 0) value["field"] = resolved;
37788
+ }
37789
+ if (value["type"] === "SELECT" || value["type"] === "UNION") return;
37790
+ Object.values(value).forEach(visit);
37791
+ };
37792
+ visit(stmt.having);
37793
+ }
37535
37794
  function collectB86Subqueries(stmt) {
37536
37795
  const queries = [];
37537
37796
  const visitWhere = (where) => {
@@ -37569,9 +37828,10 @@ function collectB86Subqueries(stmt) {
37569
37828
  }
37570
37829
  return queries;
37571
37830
  }
37572
- async function validateB86SelectFieldCodes(stmt, client, cteCache, cacheContext) {
37831
+ async function validateB86SelectFieldCodes(stmt, client, cteCache, cacheContext, cachedPhysicalFieldsOnly = false) {
37573
37832
  const tables = [stmt.from, ...stmt.joins.map((join3) => join3.table)];
37574
37833
  const materializedByTable = /* @__PURE__ */ new Map();
37834
+ const unavailableMaterializedTables = /* @__PURE__ */ new Set();
37575
37835
  const effectiveAliases = /* @__PURE__ */ new Set();
37576
37836
  for (const table of tables) {
37577
37837
  const alias = effectiveTableAlias(table);
@@ -37585,6 +37845,10 @@ async function validateB86SelectFieldCodes(stmt, client, cteCache, cacheContext)
37585
37845
  if (table.cteName === null || table.cteName === NO_FROM_CTE_NAME) continue;
37586
37846
  const materialized = cteCache.get(table.cteName);
37587
37847
  if (!materialized) {
37848
+ if (cachedPhysicalFieldsOnly) {
37849
+ unavailableMaterializedTables.add(table);
37850
+ continue;
37851
+ }
37588
37852
  throw new Error(`ArgumentError: materialized source ${table.cteName} is not available.`);
37589
37853
  }
37590
37854
  if (materialized.rows.length > 0 && materialized.columns.length === 0) {
@@ -37601,6 +37865,16 @@ async function validateB86SelectFieldCodes(stmt, client, cteCache, cacheContext)
37601
37865
  }
37602
37866
  const schemas = /* @__PURE__ */ new Map();
37603
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
+ }
37604
37878
  const materialized = materializedByTable.get(table);
37605
37879
  if (materialized) {
37606
37880
  schemas.set(table, {
@@ -37613,12 +37887,12 @@ async function validateB86SelectFieldCodes(stmt, client, cteCache, cacheContext)
37613
37887
  return;
37614
37888
  }
37615
37889
  if (table.cteName === NO_FROM_CTE_NAME) return;
37616
- const defs = await getFieldsCached(table.appId, client, cacheContext);
37890
+ const defs = cachedPhysicalFieldsOnly ? await getFieldsIfCached(table.appId, cacheContext) : await getFieldsCached(table.appId, client, cacheContext);
37617
37891
  schemas.set(table, {
37618
37892
  table,
37619
37893
  label: b86SourceLabel(table),
37620
- validCodes: new Set(defs.map((def) => def.code)),
37621
- authoritative: defs.length > 0,
37894
+ validCodes: new Set((defs ?? []).map((def) => def.code)),
37895
+ authoritative: defs !== null && defs.length > 0,
37622
37896
  schemaUnavailable: false
37623
37897
  });
37624
37898
  }));
@@ -37666,6 +37940,7 @@ async function preflightB86QueryWithCte(query, client, cteCache, cacheContext, s
37666
37940
  await preflightB86QueryWithCte(query.right, client, cteCache, cacheContext, seen);
37667
37941
  return;
37668
37942
  }
37943
+ await bindProjectedNamesForSelectWithSchemas(query, cteCache, client, cacheContext);
37669
37944
  await validateB86SelectFieldCodes(query, client, cteCache, cacheContext);
37670
37945
  for (const subquery of collectB86Subqueries(query)) {
37671
37946
  await preflightB86QueryWithCte(subquery, client, cteCache, cacheContext, seen);
@@ -37966,7 +38241,7 @@ function collectScalarAggregateRefs(expr, out) {
37966
38241
  }
37967
38242
  }
37968
38243
  }
37969
- function collectCaseAggregateRefs(expr, out) {
38244
+ function collectNestedAggregateRefs(expr, out) {
37970
38245
  const visit = (node) => {
37971
38246
  if (node === null || typeof node !== "object") return;
37972
38247
  if (Array.isArray(node)) {
@@ -37991,12 +38266,14 @@ function collectSelectAggregateSortRefs(columns) {
37991
38266
  collectAggregateRef(column.func, column.arg, refs);
37992
38267
  } else if (column.type === "ARITH_AGG_COL") {
37993
38268
  collectAggregateOperandRefs(column.expr, refs);
38269
+ } else if (column.type === "ARITH_COL") {
38270
+ collectNestedAggregateRefs(column.expr, refs);
37994
38271
  } else if (column.type === "STRFUNC_COL") {
37995
38272
  collectStringFuncAggregateRefs(column.expr, refs);
37996
38273
  } else if (column.type === "SCALAR_VALUE_COL") {
37997
38274
  collectScalarAggregateRefs(column.expr, refs);
37998
38275
  } else if (column.type === "CASE_COL") {
37999
- collectCaseAggregateRefs(column.expr, refs);
38276
+ collectNestedAggregateRefs(column.expr, refs);
38000
38277
  }
38001
38278
  }
38002
38279
  return refs;
@@ -38066,20 +38343,20 @@ async function loadAggregateSortKindResolver(stmt, client, cacheContext, materia
38066
38343
  const table = tables.find((candidate) => effectiveTableAlias(candidate) === ref.tableAlias);
38067
38344
  if (!table) return void 0;
38068
38345
  if (table.cteName !== null) {
38069
- return materializedTables?.get(table.cteName)?.columnMeta?.get(ref.field)?.semantics ?? syntheticSemantics("string");
38346
+ return resolveMaterializedColumnMeta(materializedTables?.get(table.cteName), ref.field)?.semantics ?? syntheticSemantics("string");
38070
38347
  }
38071
38348
  info = fieldInfosByApp.get(table.appId)?.get(fieldCodeForTypeLookup(table, ref.field));
38072
38349
  }
38073
38350
  } else if (stmt.joins.length === 0) {
38074
38351
  if (stmt.from.cteName !== null) {
38075
- return materializedTables?.get(stmt.from.cteName)?.columnMeta?.get(ref.field)?.semantics ?? syntheticSemantics("string");
38352
+ return resolveMaterializedColumnMeta(materializedTables?.get(stmt.from.cteName), ref.field)?.semantics ?? syntheticSemantics("string");
38076
38353
  }
38077
38354
  info = fieldInfosByApp.get(stmt.from.appId)?.get(fieldCodeForTypeLookup(stmt.from, ref.field));
38078
38355
  } else {
38079
38356
  const matches = tables.flatMap((table) => {
38080
38357
  if (table.cteName !== null) {
38081
38358
  const materialized = materializedTables?.get(table.cteName);
38082
- return materialized?.columns.includes(ref.field) ? [materialized.columnMeta?.get(ref.field)?.semantics ?? syntheticSemantics("string")] : [];
38359
+ return resolveMaterializedColumn(materialized, ref.field) !== void 0 ? [resolveMaterializedColumnMeta(materialized, ref.field)?.semantics ?? syntheticSemantics("string")] : [];
38083
38360
  }
38084
38361
  const candidate = fieldInfosByApp.get(table.appId)?.get(fieldCodeForTypeLookup(table, ref.field));
38085
38362
  return candidate ? [semanticsForInfo(candidate, table.appId)] : [];
@@ -38144,32 +38421,13 @@ function systemColumnMeta(field) {
38144
38421
  if (field === "$revision") return syntheticColumnMeta("number");
38145
38422
  return void 0;
38146
38423
  }
38147
- var NUMBER_RETURNING_STRING_FUNCTIONS = /* @__PURE__ */ new Set([
38148
- "LENGTH",
38149
- "LENGTH_CHAR",
38150
- "INSTR",
38151
- "ROUND",
38152
- "FLOOR",
38153
- "CEIL",
38154
- "TRUNCATE",
38155
- "YEAR",
38156
- "MONTH",
38157
- "DAY",
38158
- "DATEDIFF",
38159
- "ABS",
38160
- "MOD",
38161
- "POWER",
38162
- "SQRT",
38163
- "DAYOFWEEK",
38164
- "QUARTER",
38165
- "WEEK"
38166
- ]);
38167
- function stringFunctionColumnMeta(expr) {
38168
- if (expr.func === "CAST") {
38169
- const target = expr.args[1];
38170
- return target?.type === "STRING" && target.value === "NUMBER" ? syntheticColumnMeta("number") : syntheticColumnMeta("string");
38171
- }
38172
- return NUMBER_RETURNING_STRING_FUNCTIONS.has(expr.func) ? syntheticColumnMeta("number") : syntheticColumnMeta("string");
38424
+ function stringFunctionColumnMeta(expr, resolveField2) {
38425
+ return syntheticColumnMeta(stringFunctionSemanticKind(expr, (ref) => {
38426
+ const resolved = resolveField2?.(ref);
38427
+ if (!resolved) return void 0;
38428
+ if ("compareMode" in resolved) return resolved;
38429
+ return resolved.semantics;
38430
+ }));
38173
38431
  }
38174
38432
  function caseResultColumnMeta(result, resolveField2) {
38175
38433
  if (result.type === "STRING") return syntheticColumnMeta("string");
@@ -38182,7 +38440,7 @@ function caseResultColumnMeta(result, resolveField2) {
38182
38440
  }
38183
38441
  if (result.type === "AGG_ARITH") return syntheticColumnMeta("number");
38184
38442
  if (result.type === "NUMBER" || result.type === "ARITH" || result.type === "SCALAR_ARITH") return syntheticColumnMeta("number");
38185
- if (result.type === "STRING_FUNC") return stringFunctionColumnMeta(result);
38443
+ if (result.type === "STRING_FUNC") return stringFunctionColumnMeta(result, resolveField2);
38186
38444
  if (result.type === "FIELD_REF") return resolveField2(aggregateFieldRef(result.field)) ?? unknownStringColumnMeta();
38187
38445
  if (result.type === "FIELD") return resolveField2(result) ?? unknownStringColumnMeta();
38188
38446
  return unknownStringColumnMeta();
@@ -38213,7 +38471,7 @@ function inferAggregateArgMeta(arg, resolveField2) {
38213
38471
  if (arg.type === "FIELD") return resolveField2(arg) ?? unknownStringColumnMeta();
38214
38472
  if (arg.type === "NUMBER" || arg.type === "ARITH" || arg.type === "SCALAR_ARITH") return syntheticColumnMeta("number");
38215
38473
  if (arg.type === "STRING" || arg.type === "CONCAT_OP" || arg.type === "VARIABLE") return syntheticColumnMeta("string");
38216
- if (arg.type === "STRING_FUNC") return stringFunctionColumnMeta(arg);
38474
+ if (arg.type === "STRING_FUNC") return stringFunctionColumnMeta(arg, resolveField2);
38217
38475
  const results = arg.branches.map((branch) => caseResultColumnMeta(branch.result, resolveField2));
38218
38476
  if (arg.elseResult) results.push(caseResultColumnMeta(arg.elseResult, resolveField2));
38219
38477
  return mergeExpressionColumnMeta(results);
@@ -38257,20 +38515,20 @@ async function inferSelectColumnMeta(stmt, outputColumns, client, cacheContext,
38257
38515
  }
38258
38516
  const table = tables.find((candidate) => effectiveTableAlias(candidate) === ref.tableAlias);
38259
38517
  if (!table) return void 0;
38260
- if (table.cteName !== null) return materializedTables?.get(table.cteName)?.columnMeta?.get(ref.field);
38518
+ if (table.cteName !== null) return resolveMaterializedColumnMeta(materializedTables?.get(table.cteName), ref.field);
38261
38519
  const info = physicalInfos.get(table.appId)?.get(fieldCodeForTypeLookup(table, ref.field));
38262
38520
  return info ? materializedMetaFromFieldInfo(info, table.appId) : systemColumnMeta(ref.field);
38263
38521
  }
38264
38522
  if (stmt.joins.length === 0) {
38265
- if (stmt.from.cteName !== null) return materializedTables?.get(stmt.from.cteName)?.columnMeta?.get(ref.field);
38523
+ if (stmt.from.cteName !== null) return resolveMaterializedColumnMeta(materializedTables?.get(stmt.from.cteName), ref.field);
38266
38524
  const info = physicalInfos.get(stmt.from.appId)?.get(fieldCodeForTypeLookup(stmt.from, ref.field));
38267
38525
  return info ? materializedMetaFromFieldInfo(info, stmt.from.appId) : systemColumnMeta(ref.field);
38268
38526
  }
38269
38527
  const matches = tables.flatMap((table) => {
38270
38528
  if (table.cteName !== null) {
38271
38529
  const materialized = materializedTables?.get(table.cteName);
38272
- if (!materialized?.columns.includes(ref.field)) return [];
38273
- return [materialized.columnMeta?.get(ref.field)];
38530
+ if (resolveMaterializedColumn(materialized, ref.field) === void 0) return [];
38531
+ return [resolveMaterializedColumnMeta(materialized, ref.field)];
38274
38532
  }
38275
38533
  const info = physicalInfos.get(table.appId)?.get(fieldCodeForTypeLookup(table, ref.field));
38276
38534
  const meta = info ? materializedMetaFromFieldInfo(info, table.appId) : systemColumnMeta(ref.field);
@@ -38334,12 +38592,12 @@ async function inferSelectColumnMeta(stmt, outputColumns, client, cacheContext,
38334
38592
  meta = syntheticColumnMeta("string");
38335
38593
  } else if (column.type === "SCALAR_VALUE_COL") {
38336
38594
  const expr = column.expr;
38337
- if (expr.type === "STRING_FUNC") meta = stringFunctionColumnMeta(expr);
38595
+ if (expr.type === "STRING_FUNC") meta = stringFunctionColumnMeta(expr, resolveField2);
38338
38596
  else if (expr.type === "NUMBER" || expr.type === "SCALAR_ARITH") meta = syntheticColumnMeta("number");
38339
38597
  else if (expr.type === "FIELD") meta = resolveField2(expr);
38340
38598
  else meta = syntheticColumnMeta("string");
38341
38599
  } else if (column.type === "STRFUNC_COL") {
38342
- meta = stringFunctionColumnMeta(column.expr);
38600
+ meta = stringFunctionColumnMeta(column.expr, resolveField2);
38343
38601
  } else if (column.type === "WINDOW_COL") {
38344
38602
  meta = inferWindowColumnMeta(column, resolveField2);
38345
38603
  } else if (column.type === "CASE_COL") {
@@ -38766,7 +39024,7 @@ async function buildRecursiveFieldResolver(stmt, client, cacheContext, materiali
38766
39024
  physical.set(table.appId, new Map(infos.map((info) => [info.code, info])));
38767
39025
  }));
38768
39026
  const resolveInTable = (table, field) => {
38769
- if (table.cteName !== null) return materializedTables.get(table.cteName)?.columnMeta?.get(field);
39027
+ if (table.cteName !== null) return resolveMaterializedColumnMeta(materializedTables.get(table.cteName), field);
38770
39028
  const info = physical.get(table.appId)?.get(fieldCodeForTypeLookup(table, field));
38771
39029
  return info ? materializedMetaFromFieldInfo(info, table.appId) : systemColumnMeta(field);
38772
39030
  };
@@ -38974,7 +39232,7 @@ function rewriteRecursivePhysicalSources(stmt, sources) {
38974
39232
  };
38975
39233
  }
38976
39234
  function tableMetaForJoinKey(table, field, cache) {
38977
- return table.cteName === null ? void 0 : cache.get(table.cteName)?.columnMeta?.get(field);
39235
+ return table.cteName === null ? void 0 : resolveMaterializedColumnMeta(cache.get(table.cteName), field);
38978
39236
  }
38979
39237
  function recursiveJoinKey(value, semantics) {
38980
39238
  if (semantics.compareMode !== "number" && semantics.compareMode !== "recordNumber") return value;
@@ -39833,7 +40091,7 @@ async function tryFetchJoinRecordsBySourceKeys(stmt, join3, tables, client, maxR
39833
40091
  const targetMeta = targetInfo ? materializedMetaFromFieldInfo(targetInfo, join3.table.appId) : systemColumnMeta(joinField);
39834
40092
  let sourceMeta;
39835
40093
  if (sourceTable?.cteName !== null && sourceTable?.cteName !== void 0) {
39836
- sourceMeta = materializedTables?.get(sourceTable.cteName)?.columnMeta?.get(sourceField);
40094
+ sourceMeta = resolveMaterializedColumnMeta(materializedTables?.get(sourceTable.cteName), sourceField);
39837
40095
  } else if (sourceTable) {
39838
40096
  const sourceInfo = (await getFieldsCached(sourceTable.appId, client, cacheContext)).find((info) => info.code === fieldCodeForTypeLookup(sourceTable, sourceField));
39839
40097
  sourceMeta = sourceInfo ? materializedMetaFromFieldInfo(sourceInfo, sourceTable.appId) : systemColumnMeta(sourceField);
@@ -40030,19 +40288,19 @@ async function buildOrderSemanticsForSelect(stmt, client, cacheContext, material
40030
40288
  }
40031
40289
  const table = tables.find((candidate) => effectiveTableAlias(candidate) === ref.tableAlias);
40032
40290
  if (!table) return void 0;
40033
- if (table.cteName !== null) return materializedTables?.get(table.cteName)?.columnMeta?.get(ref.field);
40291
+ if (table.cteName !== null) return resolveMaterializedColumnMeta(materializedTables?.get(table.cteName), ref.field);
40034
40292
  const info = infosByApp.get(table.appId)?.get(fieldCodeForTypeLookup(table, ref.field));
40035
40293
  return info ? materializedMetaFromFieldInfo(info, table.appId) : systemColumnMeta(ref.field);
40036
40294
  }
40037
40295
  if (stmt.joins.length === 0) {
40038
- if (stmt.from.cteName !== null) return materializedTables?.get(stmt.from.cteName)?.columnMeta?.get(ref.field);
40296
+ if (stmt.from.cteName !== null) return resolveMaterializedColumnMeta(materializedTables?.get(stmt.from.cteName), ref.field);
40039
40297
  const info = infosByApp.get(stmt.from.appId)?.get(fieldCodeForTypeLookup(stmt.from, ref.field));
40040
40298
  return info ? materializedMetaFromFieldInfo(info, stmt.from.appId) : systemColumnMeta(ref.field);
40041
40299
  }
40042
40300
  const matches = tables.flatMap((table) => {
40043
40301
  if (table.cteName !== null) {
40044
40302
  const materialized = materializedTables?.get(table.cteName);
40045
- const meta2 = materialized?.columns.includes(ref.field) ? materialized.columnMeta?.get(ref.field) : void 0;
40303
+ const meta2 = resolveMaterializedColumnMeta(materialized, ref.field);
40046
40304
  return meta2 ? [meta2] : [];
40047
40305
  }
40048
40306
  const info = infosByApp.get(table.appId)?.get(fieldCodeForTypeLookup(table, ref.field));
@@ -40064,7 +40322,7 @@ async function buildOrderSemanticsForSelect(stmt, client, cacheContext, material
40064
40322
  } else if (column.type === "GROUPING_COL") {
40065
40323
  meta = syntheticColumnMeta("number");
40066
40324
  } else if (column.type === "LITERAL_COL" || column.type === "SCALAR_VALUE_COL") meta = syntheticColumnMeta("string");
40067
- else if (column.type === "STRFUNC_COL") meta = stringFunctionColumnMeta(column.expr);
40325
+ else if (column.type === "STRFUNC_COL") meta = stringFunctionColumnMeta(column.expr, resolveField2);
40068
40326
  else if (column.type === "SCALAR_SUBQUERY_COL") meta = unknownStringColumnMeta();
40069
40327
  else if (column.type === "CASE_COL") {
40070
40328
  const candidates = column.expr.branches.map((branch) => caseResultColumnMeta(branch.result, resolveField2));
@@ -40081,7 +40339,8 @@ async function buildOrderSemanticsForSelect(stmt, client, cacheContext, material
40081
40339
  }
40082
40340
  const result = /* @__PURE__ */ new Map();
40083
40341
  for (const name of names) {
40084
- const base = aliasSemantics.get(name) ?? resolveField2(aggregateFieldRef(name))?.semantics;
40342
+ const resolvedAlias = resolveProjectedName(name, aliasSemantics.keys());
40343
+ const base = (resolvedAlias === void 0 ? void 0 : aliasSemantics.get(resolvedAlias)) ?? resolveField2(aggregateFieldRef(name))?.semantics;
40085
40344
  if (!base) {
40086
40345
  const ref = aggregateFieldRef(name);
40087
40346
  if (ref.tableAlias === null && ambiguousFields.has(ref.field)) {
@@ -41120,6 +41379,29 @@ var UPDATE_FROM_UNSUPPORTED_SOURCE_TYPES = /* @__PURE__ */ new Set([
41120
41379
  "FILE"
41121
41380
  ]);
41122
41381
  async function resolveUpdateFromMatchedRecords(stmt, from, client, options, cacheContext, tempTables, snapshotFields) {
41382
+ if (from.cteName !== null) {
41383
+ const materialized = tempTables?.get(from.cteName);
41384
+ const resolveSource = (requested) => resolveProjectedName(requested, materialized?.columns ?? []) ?? requested;
41385
+ from.joinKeyField = resolveSource(from.joinKeyField);
41386
+ for (const assignment of stmt.assignments) {
41387
+ if (assignment.value.type === "SOURCE_FIELD" && assignment.value.alias === from.alias) {
41388
+ assignment.value.field = resolveSource(assignment.value.field);
41389
+ }
41390
+ }
41391
+ const visitSourceChecks = (node) => {
41392
+ if (node === null || typeof node !== "object") return;
41393
+ if (Array.isArray(node)) {
41394
+ node.forEach(visitSourceChecks);
41395
+ return;
41396
+ }
41397
+ const value = node;
41398
+ if (value["type"] === "FIELD" && value["tableAlias"] === from.alias && typeof value["field"] === "string") {
41399
+ value["field"] = resolveSource(value["field"]);
41400
+ }
41401
+ Object.values(value).forEach(visitSourceChecks);
41402
+ };
41403
+ visitSourceChecks(stmt.checkGroups);
41404
+ }
41123
41405
  const joinKind = await resolveUpdateFromTargetJoinKind(stmt, from, client, cacheContext);
41124
41406
  const checkScope = await resolveUpdateFromCheckScope(stmt, from, client, cacheContext, tempTables);
41125
41407
  const sourceFields = [...new Set(stmt.assignments.filter((a) => a.value.type === "SOURCE_FIELD").map((a) => a.value.type === "SOURCE_FIELD" ? a.value.field : "").concat(checkScope.sourceFields))];
@@ -41211,7 +41493,7 @@ async function loadUpdateFromSourceRows(from, requiredSourceFields, sourceValueF
41211
41493
  const table = tempTables?.get(from.cteName);
41212
41494
  if (!table) throw new Error(`ArgumentError: temp table ${from.cteName} is not available.`);
41213
41495
  for (const field of requiredSourceFields) {
41214
- if (!table.columns.includes(field)) {
41496
+ if (resolveMaterializedColumn(table, field) === void 0) {
41215
41497
  throw new Error(`ArgumentError: UPDATE ... FROM source column ${field} does not exist.`);
41216
41498
  }
41217
41499
  }
@@ -41522,6 +41804,8 @@ async function executeImport(stmt, client, options, cacheContext, tempTables) {
41522
41804
  importSourceByDmlStatement.set(generated, executionSource);
41523
41805
  const withAudit = (result2) => {
41524
41806
  if (executionSource.audit) Object.assign(result2, { importAudit: executionSource.audit });
41807
+ const warnings = sourceWarningsByDmlStatement.get(generated);
41808
+ if (warnings?.length) sourceWarningsByDmlStatement.set(stmt, warnings);
41525
41809
  return result2;
41526
41810
  };
41527
41811
  if (generated.validateOnly) {
@@ -41811,6 +42095,7 @@ async function materializeDmlSource(stmt, client, options, cacheContext, tempTab
41811
42095
  const imported = importSourceByDmlStatement.get(stmt);
41812
42096
  if (!imported) {
41813
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);
41814
42099
  return { rows: selected2.rows, columns: selected2.columns, columnMeta: materializedMetaBySelectResult.get(selected2) };
41815
42100
  }
41816
42101
  const payload = await loadImportSource(imported.handle, imported.cache);
@@ -41826,6 +42111,7 @@ async function materializeDmlSource(stmt, client, options, cacheContext, tempTab
41826
42111
  const tables = new Map(tempTables ?? []);
41827
42112
  tables.set(IMPORT_PROJECTION_SOURCE, raw);
41828
42113
  const selected = await executeQueryWithCte(projection, client, { ...options, onLimitReached: "error" }, tables, cacheContext, true);
42114
+ rememberDmlSourceWarnings(stmt, selected.warnings);
41829
42115
  return { rows: selected.rows, columns: selected.columns, columnMeta: materializedMetaBySelectResult.get(selected) };
41830
42116
  }
41831
42117
  var dmlSourceMaterializer = { materialize: materializeDmlSource };
@@ -42974,7 +43260,10 @@ function compareByOrder(a, b, orderBy, resolveSemantics, evaluationContext = {})
42974
43260
  for (const item of orderBy) {
42975
43261
  const av = evalOrderKeyForRow(item.key, a, evaluationContext);
42976
43262
  const bv = evalOrderKeyForRow(item.key, b, evaluationContext);
42977
- const semantics = item.key.type === "FIELD_NAME" ? resolveSemantics(aggregateFieldRef(item.key.name)) : item.key.type === "ARITH_KEY" ? syntheticSemantics("number") : item.key.type === "FUNC_KEY" ? stringFunctionColumnMeta(item.key.expr).semantics ?? syntheticSemantics("string") : syntheticSemantics("number");
43263
+ const semantics = item.key.type === "FIELD_NAME" ? resolveSemantics(aggregateFieldRef(item.key.name)) : item.key.type === "ARITH_KEY" ? syntheticSemantics("number") : item.key.type === "FUNC_KEY" ? stringFunctionColumnMeta(item.key.expr, (ref) => {
43264
+ const semantics2 = resolveSemantics(ref);
43265
+ return semantics2 ? { compareMode: semantics2.compareMode } : void 0;
43266
+ }).semantics ?? syntheticSemantics("string") : syntheticSemantics("number");
42978
43267
  const cmp = compareCanonicalValues(av, bv, semantics ?? syntheticSemantics("string"));
42979
43268
  if (cmp !== 0) return item.direction === "ASC" ? cmp : -cmp;
42980
43269
  }
@@ -43255,6 +43544,7 @@ async function buildExplainWhereAnalysis(query, client, cacheContext, maxRecords
43255
43544
  const capabilities = /* @__PURE__ */ new Map();
43256
43545
  const orderPlans = /* @__PURE__ */ new Map();
43257
43546
  const plainGroupByPlans = /* @__PURE__ */ new Map();
43547
+ const explainSelectsForColumnCheck = [];
43258
43548
  const seen = /* @__PURE__ */ new Set();
43259
43549
  const sharedRelativeDatePlan = relativeDatePlan ?? await resolveRelativeDateExecutionPlan(query, tracedClient, cacheContext);
43260
43550
  const relativeNodeFor = (source) => sharedRelativeDatePlan.nodes.find(
@@ -43388,6 +43678,13 @@ async function buildExplainWhereAnalysis(query, client, cacheContext, maxRecords
43388
43678
  if (typed["type"] === "WITH") {
43389
43679
  const withStatement = node;
43390
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
+ }
43391
43688
  await preflightExplainRelations(cte.query);
43392
43689
  if (cte.query.type === "GENERATE_SERIES") {
43393
43690
  if (cte.query.args.some((arg) => arg.type === "VARIABLE")) {
@@ -43422,6 +43719,9 @@ async function buildExplainWhereAnalysis(query, client, cacheContext, maxRecords
43422
43719
  }
43423
43720
  if (typed["type"] === "SELECT") {
43424
43721
  const select = node;
43722
+ await bindProjectedNamesForSelectWithSchemas(select, explainRelations, tracedClient, cacheContext);
43723
+ await validateB86SelectFieldCodes(select, tracedClient, explainRelations, cacheContext, true);
43724
+ explainSelectsForColumnCheck.push(select);
43425
43725
  analyzeStaticSelectRows(select);
43426
43726
  for (const column of select.columns) {
43427
43727
  if (column.type === "SCALAR_SUBQUERY_COL") await preflightExplainRelations(column.query);
@@ -43485,7 +43785,8 @@ async function buildExplainWhereAnalysis(query, client, cacheContext, maxRecords
43485
43785
  const { resolver, rewrites } = await normalizeSelectChoiceEquality(
43486
43786
  select,
43487
43787
  tracedClient,
43488
- cacheContext
43788
+ cacheContext,
43789
+ explainRelations
43489
43790
  );
43490
43791
  if (rewrites.length > 0) explainChoiceEqualityRewrites.set(select, rewrites);
43491
43792
  const capability = classifyWhereCapability(select.where, resolver);
@@ -43514,7 +43815,7 @@ async function buildExplainWhereAnalysis(query, client, cacheContext, maxRecords
43514
43815
  const sourceTable = [select.from, ...select.joins.map((candidate) => candidate.table)].find((table) => effectiveTableAlias(table) === sourceAlias);
43515
43816
  let targetMeta;
43516
43817
  if (join3.table.cteName !== null) {
43517
- targetMeta = explainRelations.get(join3.table.cteName)?.columnMeta?.get(joinField);
43818
+ targetMeta = resolveMaterializedColumnMeta(explainRelations.get(join3.table.cteName), joinField);
43518
43819
  } else {
43519
43820
  const targetInfo = (await getFieldsCached(join3.table.appId, tracedClient, cacheContext)).find((info) => info.code === fieldCodeForTypeLookup(join3.table, joinField));
43520
43821
  targetMeta = targetInfo ? materializedMetaFromFieldInfo(targetInfo, join3.table.appId) : systemColumnMeta(joinField);
@@ -43525,7 +43826,7 @@ async function buildExplainWhereAnalysis(query, client, cacheContext, maxRecords
43525
43826
  let hasEmptyValue;
43526
43827
  if (sourceTable?.cteName !== null && sourceTable?.cteName !== void 0) {
43527
43828
  const relation = explainRelations.get(sourceTable.cteName);
43528
- sourceMeta = relation?.columnMeta?.get(sourceField);
43829
+ sourceMeta = resolveMaterializedColumnMeta(relation, sourceField);
43529
43830
  if (staticExplainRelations.has(sourceTable.cteName) && relation) {
43530
43831
  sourceRowCount = relation.rows.length;
43531
43832
  values = relation.rows.map((row) => toScalarText(row[sourceField]));
@@ -43683,6 +43984,9 @@ async function buildExplainWhereAnalysis(query, client, cacheContext, maxRecords
43683
43984
  }));
43684
43985
  }
43685
43986
  }
43987
+ for (const select of explainSelectsForColumnCheck) {
43988
+ await validateB86SelectFieldCodes(select, tracedClient, explainRelations, cacheContext, true);
43989
+ }
43686
43990
  return {
43687
43991
  capabilities,
43688
43992
  orderPlans,
@@ -45330,7 +45634,7 @@ function collectFullScanReasons(stmt) {
45330
45634
  );
45331
45635
  if (stmt.distinct)
45332
45636
  r.push("DISTINCT \u3042\u308A");
45333
- if (stmt.columns.some((c) => c.type === "AGGREGATE" || c.type === "ARITH_AGG_COL"))
45637
+ if (hasAggregateColumns(stmt.columns))
45334
45638
  r.push("\u96C6\u8A08\u95A2\u6570\uFF08COUNT / SUM \u7B49\uFF09\u3042\u308A");
45335
45639
  if (stmt.columns.some((c) => c.type === "WINDOW_COL"))
45336
45640
  r.push("\u30A6\u30A3\u30F3\u30C9\u30A6\u95A2\u6570\u3042\u308A");
@@ -46455,6 +46759,7 @@ function buildBatchEnvelope(batch, options = {}) {
46455
46759
  if (s.status === "skipped" && s.skippedReason) entry.skippedReason = s.skippedReason;
46456
46760
  if (s.tempTable !== void 0) entry.tempTable = s.tempTable;
46457
46761
  if (s.rowCount !== void 0) entry.rowCount = s.rowCount;
46762
+ if (s.warnings?.length) entry.warnings = s.warnings;
46458
46763
  if (s.status === "success" && s.result?.type === "SELECT") {
46459
46764
  totalRows += s.result.rowCount;
46460
46765
  if (maxTotalRecords !== void 0 && totalRows > maxTotalRecords) {
@@ -46511,8 +46816,9 @@ function buildBatchEnvelope(batch, options = {}) {
46511
46816
  statementCount: batch.statementCount,
46512
46817
  statements,
46513
46818
  results,
46514
- // バッチ全体の警告(仕様 §6.2)。文ごとの警告は results[].warnings に入る
46515
- warnings: []
46819
+ // バッチ全体の警告(仕様 §6.2)=dialect 1 の警告 + 結果セットを持たない文(CREATE TEMP TABLE・
46820
+ // SELECT-based DML)の実行時警告(B188・文順・重複なし)。SELECT の文ごとの警告は従来どおり results[].warnings
46821
+ warnings: batch.warnings ?? []
46516
46822
  };
46517
46823
  }
46518
46824
 
@@ -49074,12 +49380,23 @@ function buildBatchStatementSummary(s) {
49074
49380
  }
49075
49381
  }
49076
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
+ }
49077
49387
  return parts.join(" ");
49078
49388
  }
49079
49389
  function buildSelectSummary(result) {
49080
49390
  const validateSummary = result.validateStats ? ` errorRecords=${result.validateStats.errorRecords} errorCount=${result.validateStats.errorCount}` : "";
49081
49391
  return `rowCount=${result.rowCount}${validateSummary}`;
49082
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
+ }
49083
49400
  function buildBatchDmlConfirmMessage(analysis) {
49084
49401
  const lines = ["[DML Confirm] batch"];
49085
49402
  for (const s of analysis.statements) {
@@ -50543,6 +50860,7 @@ query=${label}`);
50543
50860
  process.stderr.write(`${buildSelectSummary(result)}
50544
50861
  `);
50545
50862
  }
50863
+ writeSingleSelectWarnings(result, format, quiet);
50546
50864
  if (exportPlan) {
50547
50865
  const exportCode = runSingleSelectCliExport(exportPlan, result, quiet);
50548
50866
  if (exportCode !== 0) return exportCode;
@@ -50603,5 +50921,6 @@ if (isDirectCliRun()) {
50603
50921
  runWithArgv,
50604
50922
  shouldExitOnEmpty,
50605
50923
  toCliImportError,
50606
- writeBatchOutput
50924
+ writeBatchOutput,
50925
+ writeSingleSelectWarnings
50607
50926
  });