@rex0220/kintone-sql-tools 3.77.0 → 3.78.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
@@ -23045,6 +23045,14 @@ function planPlainGroupByResolution(groupBy, columns, schemas) {
23045
23045
  };
23046
23046
  }
23047
23047
 
23048
+ // src/core/projectedNameResolution.ts
23049
+ function resolveProjectedName(requested, available) {
23050
+ const names = [...available];
23051
+ if (names.includes(requested)) return requested;
23052
+ const canonical = requested.toLowerCase();
23053
+ return names.find((name) => name === canonical);
23054
+ }
23055
+
23048
23056
  // src/core/aggregateDependencyValidation.ts
23049
23057
  var NON_GROUPED_DEPENDENCY_REASON = "B65_NON_GROUPED_DEPENDENCY";
23050
23058
  var WRAPPER_EXPR = /* @__PURE__ */ new Map([
@@ -23215,10 +23223,11 @@ function walkDependency(node, context) {
23215
23223
  if (ref !== null) {
23216
23224
  if (context.clause !== "SELECT" && ref.tableAlias === null && AGGREGATE_SYNTHETIC_REFERENCE.test(ref.field)) return;
23217
23225
  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)) {
23226
+ const alias = resolveProjectedName(ref.field, context.aliases.keys());
23227
+ const targets = alias === void 0 ? [] : context.aliases.get(alias) ?? [];
23228
+ if (targets.length === 1 && alias !== void 0 && !context.resolvingAliases.has(alias)) {
23220
23229
  const resolvingAliases = new Set(context.resolvingAliases);
23221
- resolvingAliases.add(ref.field);
23230
+ resolvingAliases.add(alias);
23222
23231
  walkDependency(targets[0], { ...context, resolvingAliases });
23223
23232
  return;
23224
23233
  }
@@ -23409,7 +23418,7 @@ function containsAggregate2(node) {
23409
23418
  function isAggregateMaterializedAlias(column) {
23410
23419
  if (!("alias" in column) || column.alias === null) return false;
23411
23420
  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") {
23421
+ if (column.type === "ARITH_COL" || column.type === "STRFUNC_COL" || column.type === "SCALAR_VALUE_COL" || column.type === "CASE_COL") {
23413
23422
  return containsAggregate2(column);
23414
23423
  }
23415
23424
  return false;
@@ -23536,7 +23545,7 @@ function resolveSelectMode(stmt) {
23536
23545
  if (stmt.distinct) return "FULL_SCAN";
23537
23546
  if (hasWindowColumns(stmt.columns)) return "FULL_SCAN";
23538
23547
  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)
23548
+ (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
23549
  )) return "FULL_SCAN";
23541
23550
  if (whereRequiresJsEval(stmt.where)) return "FULL_SCAN";
23542
23551
  if (stmt.orderBy.some((o) => o.key.type !== "FIELD_NAME")) return "FULL_SCAN";
@@ -23622,7 +23631,7 @@ function convertOrderBy(item) {
23622
23631
  }
23623
23632
  function extractFields(columns) {
23624
23633
  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"
23634
+ (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
23635
  );
23627
23636
  if (hasWildcard) return [];
23628
23637
  const fields = [];
@@ -23837,7 +23846,7 @@ function collectRequiredFieldsByTable(stmt, plainGroupByPlan, sourceAware) {
23837
23846
  }
23838
23847
  return;
23839
23848
  }
23840
- if ((phase === "orderBy" || phase === "having" || phase === "groupBy") && selectAliases.has(rawName)) {
23849
+ if ((phase === "orderBy" || phase === "having" || phase === "groupBy") && resolveProjectedName(rawName, selectAliases) !== void 0) {
23841
23850
  return;
23842
23851
  }
23843
23852
  if ((phase === "orderBy" || phase === "having" || phase === "groupBy") && isAggregateSyntheticName(rawName)) {
@@ -24180,9 +24189,7 @@ function canInlineSingleCte(stmt) {
24180
24189
  if (finalQuery.type !== "SELECT") return false;
24181
24190
  if (finalQuery.from.cteName !== cteDef.name || finalQuery.joins.length > 0) return false;
24182
24191
  if (hasGroupingClause(finalQuery) || finalQuery.distinct) return false;
24183
- return !finalQuery.columns.some(
24184
- (column) => column.type === "AGGREGATE" || column.type === "ARITH_AGG_COL"
24185
- );
24192
+ return !isAggregateQueryBlock(finalQuery);
24186
24193
  }
24187
24194
  function buildInlinedQuery(stmt) {
24188
24195
  const cteBody = stmt.ctes[0].query;
@@ -27001,6 +27008,93 @@ function resolveFieldRef(row, field) {
27001
27008
  return "";
27002
27009
  }
27003
27010
 
27011
+ // src/core/expressionSemantics.ts
27012
+ var NUMBER_RETURNING_FUNCTIONS = /* @__PURE__ */ new Set([
27013
+ "LENGTH",
27014
+ "LENGTH_CHAR",
27015
+ "INSTR",
27016
+ "ROUND",
27017
+ "FLOOR",
27018
+ "CEIL",
27019
+ "TRUNCATE",
27020
+ "YEAR",
27021
+ "MONTH",
27022
+ "DAY",
27023
+ "DATEDIFF",
27024
+ "ABS",
27025
+ "MOD",
27026
+ "POWER",
27027
+ "SQRT",
27028
+ "DAYOFWEEK",
27029
+ "QUARTER",
27030
+ "WEEK"
27031
+ ]);
27032
+ var ALL_NUMERIC_ARGUMENT_FUNCTIONS = /* @__PURE__ */ new Set([
27033
+ "COALESCE",
27034
+ "ISNULL",
27035
+ "NULLIF",
27036
+ "GREATEST",
27037
+ "LEAST"
27038
+ ]);
27039
+ function resolvedKind(value) {
27040
+ if (value === "number" || value === "string") return value;
27041
+ return value?.compareMode === "number" || value?.compareMode === "recordNumber" ? "number" : "string";
27042
+ }
27043
+ function fieldRefFromLegacyName(field) {
27044
+ const dot = field.indexOf(".");
27045
+ return dot > 0 ? { type: "FIELD", tableAlias: field.slice(0, dot), field: field.slice(dot + 1) } : { type: "FIELD", tableAlias: null, field };
27046
+ }
27047
+ function aggregateResultKind(ref, resolveField2) {
27048
+ 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";
27049
+ if (ref.func === "GROUP_CONCAT") return "string";
27050
+ return ref.arg.type === "WILDCARD" ? "string" : expressionSemanticKind(ref.arg, resolveField2);
27051
+ }
27052
+ function stringFunctionSemanticKind(expr, resolveField2) {
27053
+ if (expr.func === "CAST") {
27054
+ const target = expr.args[1];
27055
+ return target?.type === "STRING" && target.value === "NUMBER" ? "number" : "string";
27056
+ }
27057
+ if (NUMBER_RETURNING_FUNCTIONS.has(expr.func)) return "number";
27058
+ if (ALL_NUMERIC_ARGUMENT_FUNCTIONS.has(expr.func) && expr.args.length > 0 && expr.args.every((arg) => expressionSemanticKind(arg, resolveField2) === "number")) return "number";
27059
+ return "string";
27060
+ }
27061
+ function expressionSemanticKind(expr, resolveField2) {
27062
+ if (expr === null || typeof expr !== "object") return "string";
27063
+ const value = expr;
27064
+ switch (value["type"]) {
27065
+ case "NUMBER":
27066
+ case "ARITH":
27067
+ case "SCALAR_ARITH":
27068
+ case "AGG_ARITH":
27069
+ return "number";
27070
+ case "STRING_FUNC":
27071
+ return stringFunctionSemanticKind(expr, resolveField2);
27072
+ case "AGG_REF":
27073
+ return aggregateResultKind(expr, resolveField2);
27074
+ case "FIELD":
27075
+ return resolvedKind(resolveField2?.(expr));
27076
+ case "FIELD_REF":
27077
+ return resolvedKind(resolveField2?.(fieldRefFromLegacyName(value["field"])));
27078
+ case "AGG_GROUP_KEY":
27079
+ return resolvedKind(resolveField2?.({
27080
+ type: "FIELD",
27081
+ tableAlias: typeof value["tableAlias"] === "string" ? value["tableAlias"] : null,
27082
+ field: value["field"]
27083
+ }));
27084
+ case "CASE_WHEN": {
27085
+ const branches = value["branches"];
27086
+ const elseResult = value["elseResult"];
27087
+ const results = [
27088
+ ...branches.map((branch) => branch.result),
27089
+ ...elseResult === null || elseResult === void 0 ? [] : [elseResult]
27090
+ ];
27091
+ return results.length > 0 && results.every((result) => expressionSemanticKind(result, resolveField2) === "number") ? "number" : "string";
27092
+ }
27093
+ default:
27094
+ return "string";
27095
+ }
27096
+ }
27097
+
27004
27098
  // src/engine/evalWhere.ts
27005
27099
  function evalWhere(expr, row, resolveFieldType, appliedKlikes, resolveFieldSemantics2, context = {}) {
27006
27100
  switch (expr.type) {
@@ -27060,33 +27154,13 @@ function evalOp(op, leftStr, right, row, fieldType, resolveFieldType, semantics
27060
27154
  const rightStr = resolveValue(right, row, resolveFieldType, resolveFieldSemantics2, context);
27061
27155
  return compareScalarValues(op, leftStr, rightStr, semantics);
27062
27156
  }
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
27157
  function semanticsForLeft(left, fieldType, resolveSemantics) {
27084
27158
  if (left.type === "FIELD") {
27085
27159
  return resolveSemantics?.(left) ?? (fieldType ? resolveFieldSemantics({ fieldType }) : syntheticSemantics("string"));
27086
27160
  }
27087
27161
  if (left.type === "ARITH_FIELD" || left.type === "AGG_FIELD") return syntheticSemantics("number");
27088
27162
  if (left.type === "FUNC_FIELD") {
27089
- return syntheticSemantics(NUMERIC_STRING_FUNCTIONS.has(left.expr.func) ? "number" : "string");
27163
+ return syntheticSemantics(stringFunctionSemanticKind(left.expr, (ref) => resolveSemantics?.(ref)));
27090
27164
  }
27091
27165
  if (left.type === "CASE_FIELD") {
27092
27166
  const results = [
@@ -27096,7 +27170,7 @@ function semanticsForLeft(left, fieldType, resolveSemantics) {
27096
27170
  const modes = results.map((result) => {
27097
27171
  if (result.type === "NUMBER" || result.type === "ARITH") return syntheticSemantics("number");
27098
27172
  if (result.type === "STRING_FUNC") {
27099
- return syntheticSemantics(NUMERIC_STRING_FUNCTIONS.has(result.func) ? "number" : "string");
27173
+ return syntheticSemantics(stringFunctionSemanticKind(result, (ref) => resolveSemantics?.(ref)));
27100
27174
  }
27101
27175
  if (result.type === "FIELD_REF") {
27102
27176
  const dot = result.field.indexOf(".");
@@ -31150,10 +31224,15 @@ function buildApplyParentSelectionPlan(where, metadata) {
31150
31224
  var REST_OFFSET_MAX = 1e4;
31151
31225
  var REST_LIMIT_MAX = 500;
31152
31226
  function fieldSemantics(item, semantics) {
31153
- return item.key.type === "FIELD_NAME" ? semantics.get(item.key.name) : void 0;
31227
+ if (item.key.type !== "FIELD_NAME") return void 0;
31228
+ const resolved = resolveProjectedName(item.key.name, semantics.keys());
31229
+ return resolved === void 0 ? void 0 : semantics.get(resolved);
31154
31230
  }
31155
31231
  function hasSelectOutputAlias(stmt, name) {
31156
- return stmt.columns.some((column) => "alias" in column && column.alias === name);
31232
+ const aliases = stmt.columns.flatMap(
31233
+ (column) => "alias" in column && column.alias !== null ? [column.alias] : []
31234
+ );
31235
+ return resolveProjectedName(name, aliases) !== void 0;
31157
31236
  }
31158
31237
  function planCanonicalOrder(input) {
31159
31238
  const { stmt } = input;
@@ -31665,7 +31744,7 @@ function applyFilter(rows, where, resolveFieldType, appliedKlikes, resolveFieldS
31665
31744
  }
31666
31745
  function hasAggregateColumns(columns) {
31667
31746
  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)
31747
+ (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
31748
  );
31670
31749
  }
31671
31750
  function applyGroupBy(rows, groupByKeys, columns, resolveAggSortKind, resolutionPlan, aliasEvaluationContext = {}) {
@@ -31819,6 +31898,16 @@ function materializeAggregateColumns(outRow, groupRows, columns, resolveAggSortK
31819
31898
  String(evalAggArithExpr(col.expr, groupRows, resolveAggSortKind, evaluationContext)),
31820
31899
  [outputKey]
31821
31900
  );
31901
+ } else if (col.type === "ARITH_COL" && containsAggregate2(col.expr)) {
31902
+ materializeAggregateDependencies(outRow, groupRows, col.expr, resolveAggSortKind, evaluationContext);
31903
+ const outputKey = col.alias ?? arithColDefaultKey(col.expr);
31904
+ const resolvedExpr = resolveAggInArithNode(col.expr, groupRows, resolveAggSortKind);
31905
+ setMaterializedSelectValue(
31906
+ outRow,
31907
+ columnIndex,
31908
+ String(evalArithExpr(resolvedExpr, outRow, evaluationContext)),
31909
+ [outputKey]
31910
+ );
31822
31911
  } else if (col.type === "STRFUNC_COL" && hasAggregateInStringFuncExpr2(col.expr)) {
31823
31912
  materializeAggregateDependencies(outRow, groupRows, col.expr, resolveAggSortKind, evaluationContext);
31824
31913
  const outputKey = col.alias ?? stringFuncDefaultKey(col.expr);
@@ -32079,9 +32168,7 @@ function resolveAggregateArgSemantics(arg, resolver) {
32079
32168
  if (arg.type === "NUMBER" || arg.type === "ARITH" || arg.type === "SCALAR_ARITH") return "number";
32080
32169
  if (arg.type === "STRING" || arg.type === "CONCAT_OP" || arg.type === "VARIABLE") return "string";
32081
32170
  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";
32171
+ return stringFunctionSemanticKind(arg, (field) => resolver?.(field));
32085
32172
  }
32086
32173
  const results = [...arg.branches.map((branch) => branch.result), ...arg.elseResult === null ? [] : [arg.elseResult]].filter((result) => result.type !== "ARRAY").map((result) => resolveAggregateArgSemantics(result, resolver));
32087
32174
  if (results.length === 0 || results.some((result) => result === void 0)) return "string";
@@ -32169,7 +32256,10 @@ function sortDecoratedRows(rows, orderBy, optionOrders, sortKinds, fieldSemantic
32169
32256
  const keyMeta = orderBy.map(({ key }) => {
32170
32257
  if (key.type === "ARITH_KEY") return { semantics: syntheticSemantics("number") };
32171
32258
  if (key.type === "FUNC_KEY") {
32172
- return { semantics: syntheticSemantics(NUMERIC_ORDER_FUNCTIONS.has(key.expr.func) ? "number" : "string") };
32259
+ return { semantics: syntheticSemantics(stringFunctionSemanticKind(
32260
+ key.expr,
32261
+ (field) => fieldSemantics2?.get(field.tableAlias ? `${field.tableAlias}.${field.field}` : field.field)
32262
+ )) };
32173
32263
  }
32174
32264
  if (key.type === "GROUPING_KEY") return { semantics: syntheticSemantics("number") };
32175
32265
  const semantics = fieldSemantics2?.get(key.name);
@@ -32209,26 +32299,6 @@ function compareDecoratedRows(a, b, orderBy, keyMeta) {
32209
32299
  function compareSortKeys(a, b, meta) {
32210
32300
  return compareCanonicalValues(a.s, b.s, meta.semantics);
32211
32301
  }
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
32302
  function evalOrderKey(key, row, aliasEvaluator, evaluationContext = {}) {
32233
32303
  const sourceRow = sourceRowForEvaluation(row);
32234
32304
  switch (key.type) {
@@ -32266,11 +32336,7 @@ function buildOrderByAliasEvaluator(columns, scalarCache, resolveFieldType, reso
32266
32336
  evaluators.set(alias, (row) => getMaterializedSelectValue(row, columnIndex) ?? "");
32267
32337
  break;
32268
32338
  case "ARITH_COL":
32269
- evaluators.set(alias, (row) => String(evalArithExpr(
32270
- column.expr,
32271
- sourceRowForEvaluation(row),
32272
- evaluationContext
32273
- )));
32339
+ evaluators.set(alias, (row) => containsAggregate2(column.expr) ? getMaterializedSelectValue(row, columnIndex) ?? "" : String(evalArithExpr(column.expr, sourceRowForEvaluation(row), evaluationContext)));
32274
32340
  break;
32275
32341
  case "STRFUNC_COL": {
32276
32342
  const source = stringFuncDefaultKey(column.expr);
@@ -32319,7 +32385,10 @@ function buildOrderByAliasEvaluator(columns, scalarCache, resolveFieldType, reso
32319
32385
  break;
32320
32386
  }
32321
32387
  }
32322
- return (name, row) => evaluators.get(name)?.(row);
32388
+ return (name, row) => {
32389
+ const resolved = resolveProjectedName(name, evaluators.keys());
32390
+ return resolved === void 0 ? void 0 : evaluators.get(resolved)?.(row);
32391
+ };
32323
32392
  }
32324
32393
  function applyWindow(rows, columns, optionOrders, sortKinds, fieldSemantics2, resolveAggSortKind, evaluationContext = {}) {
32325
32394
  const windows = columns.map((column, columnIndex) => ({ column, columnIndex })).filter((item) => item.column.type === "WINDOW_COL");
@@ -32503,7 +32572,7 @@ function evaluateSelectColumnValue(column, row, columnIndex, context = {}) {
32503
32572
  return getMaterializedSelectValue(row, columnIndex) ?? getMaterializedLookupValue(row, source) ?? getLegacyMaterializedValue(row, source) ?? "0";
32504
32573
  }
32505
32574
  case "ARITH_COL":
32506
- return String(evalArithExpr(column.expr, sourceRow, context.evaluationContext));
32575
+ return containsAggregate2(column.expr) ? getMaterializedSelectValue(row, columnIndex) ?? getMaterializedLookupValue(row, column.alias ?? arithColDefaultKey(column.expr)) ?? "" : String(evalArithExpr(column.expr, sourceRow, context.evaluationContext));
32507
32576
  case "CASE_COL":
32508
32577
  return containsAggregate2(column.expr) ? getMaterializedSelectValue(row, columnIndex) ?? getMaterializedLookupValue(row, caseMaterializedKey(column.alias, columnIndex)) ?? getLegacyMaterializedValue(row, caseMaterializedKey(column.alias, columnIndex)) ?? "" : evalCaseWhen(
32509
32578
  column.expr,
@@ -32886,6 +32955,17 @@ function resolveAggInScalarValue(expr, rows, resolveAggSortKind) {
32886
32955
  }
32887
32956
  return expr;
32888
32957
  }
32958
+ function resolveAggInArithNode(expr, rows, resolveAggSortKind) {
32959
+ if (expr.type === "STRING_FUNC") return resolveAggInStringFuncExpr(expr, rows, resolveAggSortKind);
32960
+ if (expr.type === "ARITH") {
32961
+ return {
32962
+ ...expr,
32963
+ left: resolveAggInArithNode(expr.left, rows, resolveAggSortKind),
32964
+ right: resolveAggInArithNode(expr.right, rows, resolveAggSortKind)
32965
+ };
32966
+ }
32967
+ return expr;
32968
+ }
32889
32969
  function resolveAggInCaseResult(result, rows, resolveAggSortKind) {
32890
32970
  if (result.type === "AGG_REF") {
32891
32971
  const value = evalAggregate(
@@ -32965,7 +33045,10 @@ function deriveOutputOrderSemantics(columns, resolveAggSortKind) {
32965
33045
  } else if (column.type === "LITERAL_COL" || column.type === "CASE_COL" || column.type === "SCALAR_SUBQUERY_COL" || column.type === "SCALAR_VALUE_COL") {
32966
33046
  result.set(column.alias, syntheticSemantics("string"));
32967
33047
  } else if (column.type === "STRFUNC_COL") {
32968
- result.set(column.alias, syntheticSemantics(NUMERIC_ORDER_FUNCTIONS.has(column.expr.func) ? "number" : "string"));
33048
+ result.set(column.alias, syntheticSemantics(stringFunctionSemanticKind(
33049
+ column.expr,
33050
+ (field) => resolveAggSortKind?.(field)
33051
+ )));
32969
33052
  }
32970
33053
  }
32971
33054
  return result;
@@ -35115,6 +35198,13 @@ var SearchAbortedError = class extends Error {
35115
35198
  this.name = "SearchAbortedError";
35116
35199
  }
35117
35200
  };
35201
+ function resolveMaterializedColumn(table, requested) {
35202
+ return table?.columns.includes(requested) ? requested : void 0;
35203
+ }
35204
+ function resolveMaterializedColumnMeta(table, requested) {
35205
+ const resolved = resolveMaterializedColumn(table, requested);
35206
+ return resolved === void 0 ? void 0 : table?.columnMeta?.get(resolved);
35207
+ }
35118
35208
  var materializedMetaBySelectResult = /* @__PURE__ */ new WeakMap();
35119
35209
  function getSelectColumnMeta(result) {
35120
35210
  return materializedMetaBySelectResult.get(result);
@@ -36558,7 +36648,7 @@ async function evaluateScalarSubquery(sourceQuery, client, options, cacheContext
36558
36648
  return result.rows[0]?.[result.columns[0]] ?? "";
36559
36649
  }
36560
36650
  function withScalarProbeLimit(query) {
36561
- const hasAgg = normalizeGroupingSpec(query).type !== "NONE" || query.columns.some((c) => c.type === "AGGREGATE" || c.type === "ARITH_AGG_COL");
36651
+ const hasAgg = isAggregateQueryBlock(query);
36562
36652
  if (hasAgg || query.distinct || query.limit !== null) return { query, probed: false };
36563
36653
  return { query: { ...query, limit: 2 }, probed: true };
36564
36654
  }
@@ -36656,18 +36746,18 @@ async function buildWhereFieldSemanticsResolver(stmt, client, cacheContext, mate
36656
36746
  const table = tables.find((candidate) => effectiveTableAlias(candidate) === field.tableAlias);
36657
36747
  if (!table) return void 0;
36658
36748
  if (table.cteName !== null) {
36659
- return materializedTables?.get(table.cteName)?.columnMeta?.get(field.field)?.semantics ?? syntheticSemantics("string");
36749
+ return resolveMaterializedColumnMeta(materializedTables?.get(table.cteName), field.field)?.semantics ?? syntheticSemantics("string");
36660
36750
  }
36661
36751
  return fromPhysical(table, field.field, true);
36662
36752
  }
36663
36753
  if (stmt.joins.length === 0) {
36664
36754
  if (stmt.from.cteName !== null) {
36665
- return materializedTables?.get(stmt.from.cteName)?.columnMeta?.get(field.field)?.semantics ?? syntheticSemantics("string");
36755
+ return resolveMaterializedColumnMeta(materializedTables?.get(stmt.from.cteName), field.field)?.semantics ?? syntheticSemantics("string");
36666
36756
  }
36667
36757
  return fromPhysical(stmt.from, field.field, true);
36668
36758
  }
36669
36759
  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);
36760
+ const semantics = table.cteName !== null ? resolveMaterializedColumnMeta(materializedTables?.get(table.cteName), field.field)?.semantics : fromPhysical(table, field.field, true);
36671
36761
  return semantics ? [semantics] : [];
36672
36762
  });
36673
36763
  if (matches.length === 1) return matches[0];
@@ -36795,13 +36885,20 @@ function buildHavingFieldSemanticsResolver(stmt, rowResolver) {
36795
36885
  semantics = column.func === "GROUP_CONCAT" ? syntheticSemantics("string") : syntheticSemantics("number");
36796
36886
  }
36797
36887
  } else if (column.type === "STRFUNC_COL") {
36798
- semantics = stringFunctionColumnMeta(column.expr).semantics;
36888
+ semantics = stringFunctionColumnMeta(column.expr, (ref) => {
36889
+ const resolved = rowResolver(ref);
36890
+ return resolved ? { compareMode: resolved.compareMode } : void 0;
36891
+ }).semantics;
36799
36892
  } else if (column.type === "LITERAL_COL" || column.type === "SCALAR_SUBQUERY_COL" || column.type === "CASE_COL" || column.type === "SCALAR_VALUE_COL") {
36800
36893
  semantics = syntheticSemantics("string");
36801
36894
  }
36802
36895
  if (semantics) aliases.set(column.alias, semantics);
36803
36896
  }
36804
- return (field) => field.tableAlias === null && aliases.has(field.field) ? aliases.get(field.field) : rowResolver(field);
36897
+ return (field) => {
36898
+ if (field.tableAlias !== null) return rowResolver(field);
36899
+ const alias = resolveProjectedName(field.field, aliases.keys());
36900
+ return alias === void 0 ? rowResolver(field) : aliases.get(alias);
36901
+ };
36805
36902
  }
36806
36903
  function formatWhereCapabilityFailure(result) {
36807
36904
  const reason = result.reasons.find(
@@ -36848,6 +36945,7 @@ async function assertDmlWhereCapability(stmt, client, cacheContext) {
36848
36945
  }
36849
36946
  }
36850
36947
  async function executeSelect(stmt, client, options, cacheContext, cteCache, captureColumnMeta = false, forLibraryCapture = false, windowWarningContext = "DIRECT") {
36948
+ bindSelectAliasesInHaving(stmt);
36851
36949
  let result;
36852
36950
  const subqueryWarnings = /* @__PURE__ */ new Set();
36853
36951
  await validateSelectGroupingPlanning(stmt, client, cacheContext, cteCache);
@@ -37129,7 +37227,7 @@ async function buildGroupingFieldResolver(stmt, client, cacheContext, materializ
37129
37227
  const materializedHas = (table, field) => {
37130
37228
  if (table.cteName === null) return false;
37131
37229
  const materialized = materializedTables?.get(table.cteName);
37132
- return materialized ? materialized.columns.includes(field) : true;
37230
+ return materialized ? resolveMaterializedColumn(materialized, field) !== void 0 : true;
37133
37231
  };
37134
37232
  const resolved = (table, tableIndex, field, code) => {
37135
37233
  const sameNamePhysical = tables.filter(
@@ -37532,6 +37630,145 @@ function b86FieldExists(schema, field) {
37532
37630
  if (schema.table.cteName !== null) return schema.validCodes.has(field);
37533
37631
  return b86PhysicalFieldExists(schema, field);
37534
37632
  }
37633
+ async function buildPhysicalFieldProbe(stmt, client, cacheContext) {
37634
+ const physical = [stmt.from, ...stmt.joins.map((join3) => join3.table)].filter((table) => table.cteName === null);
37635
+ const codesByApp = /* @__PURE__ */ new Map();
37636
+ await Promise.all([...new Set(physical.map((table) => table.appId))].map(async (appId) => {
37637
+ const defs = await getFieldsCached(appId, client, cacheContext);
37638
+ codesByApp.set(appId, new Set(defs.map((def) => def.code)));
37639
+ }));
37640
+ return (table, field) => {
37641
+ if (table.cteName !== null) return false;
37642
+ if (table.subtableCode || isSystemLikeFieldCode(field)) return true;
37643
+ const codes = codesByApp.get(table.appId);
37644
+ if (!codes || codes.size === 0) return true;
37645
+ return codes.has(fieldCodeForTypeLookup(table, field));
37646
+ };
37647
+ }
37648
+ async function bindProjectedNamesForSelectWithSchemas(stmt, materializedTables, client, cacheContext) {
37649
+ let consulted = false;
37650
+ bindProjectedNamesForSelect(stmt, materializedTables, () => {
37651
+ consulted = true;
37652
+ return true;
37653
+ });
37654
+ if (!consulted) return;
37655
+ bindProjectedNamesForSelect(
37656
+ stmt,
37657
+ materializedTables,
37658
+ await buildPhysicalFieldProbe(stmt, client, cacheContext)
37659
+ );
37660
+ }
37661
+ function bindProjectedNamesForSelect(stmt, materializedTables, physicalMayHave) {
37662
+ const tables = [stmt.from, ...stmt.joins.map((join3) => join3.table)];
37663
+ const tableByAlias = /* @__PURE__ */ new Map();
37664
+ for (const table of tables) {
37665
+ for (const alias of b86SourceAliases(table)) tableByAlias.set(alias, table);
37666
+ }
37667
+ const aliases = stmt.columns.flatMap(
37668
+ (column) => "alias" in column && column.alias !== null ? [column.alias] : []
37669
+ );
37670
+ const materializedColumns = (table) => table.cteName === null || table.cteName === NO_FROM_CTE_NAME ? [] : materializedTables.get(table.cteName)?.columns ?? [];
37671
+ const resolveFromTable = (table, requested) => table ? resolveProjectedName(requested, materializedColumns(table)) : void 0;
37672
+ const resolveUnqualified = (requested) => {
37673
+ if (tables.some((table) => materializedColumns(table).includes(requested))) return requested;
37674
+ const matches = tables.flatMap((table) => {
37675
+ const resolved = resolveFromTable(table, requested);
37676
+ return resolved === void 0 ? [] : [resolved];
37677
+ });
37678
+ const unique2 = [...new Set(matches)];
37679
+ if (unique2.length !== 1) return void 0;
37680
+ if (tables.some((table) => physicalMayHave(table, requested))) return requested;
37681
+ return unique2[0];
37682
+ };
37683
+ const resolveReference = (requested, tableAlias, allowSelectAlias) => {
37684
+ if (allowSelectAlias && tableAlias === null) {
37685
+ const alias = resolveProjectedName(requested, aliases);
37686
+ if (alias !== void 0) return alias;
37687
+ }
37688
+ return tableAlias === null ? resolveUnqualified(requested) ?? requested : resolveFromTable(tableByAlias.get(tableAlias), requested) ?? requested;
37689
+ };
37690
+ const resolveText = (requested, allowSelectAlias) => {
37691
+ const dot = requested.indexOf(".");
37692
+ if (dot <= 0) return resolveReference(requested, null, allowSelectAlias);
37693
+ const qualifier = requested.slice(0, dot);
37694
+ const field = requested.slice(dot + 1);
37695
+ const resolved = resolveReference(field, qualifier, false);
37696
+ return resolved === field ? requested : `${qualifier}.${resolved}`;
37697
+ };
37698
+ for (const join3 of stmt.joins) {
37699
+ if (join3.type === "CROSS") continue;
37700
+ join3.on.left.field = resolveReference(join3.on.left.field, join3.on.left.tableAlias, false);
37701
+ join3.on.right.field = resolveReference(join3.on.right.field, join3.on.right.tableAlias, false);
37702
+ }
37703
+ const seen = /* @__PURE__ */ new Set();
37704
+ const visit = (node, allowSelectAlias = false) => {
37705
+ if (node === null || typeof node !== "object") return;
37706
+ if (seen.has(node)) return;
37707
+ seen.add(node);
37708
+ if (Array.isArray(node)) {
37709
+ for (const child of node) visit(child, allowSelectAlias);
37710
+ return;
37711
+ }
37712
+ const value = node;
37713
+ if (node !== stmt && (value["type"] === "SELECT" || value["type"] === "UNION")) return;
37714
+ if (value["type"] === "FIELD" && typeof value["field"] === "string") {
37715
+ const tableAlias = typeof value["tableAlias"] === "string" ? value["tableAlias"] : null;
37716
+ value["field"] = tableAlias === null ? resolveText(value["field"], allowSelectAlias) : resolveReference(value["field"], tableAlias, allowSelectAlias);
37717
+ } else if (value["type"] === "FIELD_REF" && typeof value["field"] === "string") {
37718
+ value["field"] = resolveText(value["field"], allowSelectAlias);
37719
+ } else if (value["type"] === "AGG_GROUP_KEY" && typeof value["field"] === "string") {
37720
+ const tableAlias = typeof value["tableAlias"] === "string" ? value["tableAlias"] : null;
37721
+ value["field"] = resolveReference(value["field"], tableAlias, allowSelectAlias);
37722
+ }
37723
+ for (const child of Object.values(value)) visit(child, allowSelectAlias);
37724
+ };
37725
+ for (const column of stmt.columns) visit(column);
37726
+ visit(stmt.where);
37727
+ visit(stmt.having, true);
37728
+ visit(stmt.grouping);
37729
+ const grouping = normalizeGroupingSpec(stmt);
37730
+ if (grouping.type === "PLAIN") {
37731
+ for (const item of grouping.allItems) {
37732
+ if (item.type === "FIELD_NAME") item.name = resolveText(item.name, true);
37733
+ else visit(item);
37734
+ }
37735
+ }
37736
+ for (const item of stmt.orderBy) {
37737
+ if (item.key.type === "FIELD_NAME") item.key.name = resolveText(item.key.name, true);
37738
+ else visit(item.key);
37739
+ }
37740
+ for (const column of stmt.columns) {
37741
+ if (column.type !== "WINDOW_COL") continue;
37742
+ for (const ref of column.partitionBy) {
37743
+ ref.field = resolveReference(ref.field, ref.tableAlias, false);
37744
+ }
37745
+ for (const item of column.orderBy) {
37746
+ if (item.key.type === "FIELD_NAME") item.key.name = resolveText(item.key.name, false);
37747
+ else visit(item.key);
37748
+ }
37749
+ }
37750
+ }
37751
+ function bindSelectAliasesInHaving(stmt) {
37752
+ const aliases = stmt.columns.flatMap(
37753
+ (column) => "alias" in column && column.alias !== null ? [column.alias] : []
37754
+ );
37755
+ const visit = (node) => {
37756
+ if (node === null || typeof node !== "object") return;
37757
+ if (Array.isArray(node)) {
37758
+ node.forEach(visit);
37759
+ return;
37760
+ }
37761
+ const value = node;
37762
+ if (value["type"] === "AGG_REF" || value["type"] === "AGG_ARITH") return;
37763
+ if (value["type"] === "FIELD" && (value["tableAlias"] === null || value["tableAlias"] === void 0) && typeof value["field"] === "string") {
37764
+ const resolved = resolveProjectedName(value["field"], aliases);
37765
+ if (resolved !== void 0) value["field"] = resolved;
37766
+ }
37767
+ if (value["type"] === "SELECT" || value["type"] === "UNION") return;
37768
+ Object.values(value).forEach(visit);
37769
+ };
37770
+ visit(stmt.having);
37771
+ }
37535
37772
  function collectB86Subqueries(stmt) {
37536
37773
  const queries = [];
37537
37774
  const visitWhere = (where) => {
@@ -37666,6 +37903,7 @@ async function preflightB86QueryWithCte(query, client, cteCache, cacheContext, s
37666
37903
  await preflightB86QueryWithCte(query.right, client, cteCache, cacheContext, seen);
37667
37904
  return;
37668
37905
  }
37906
+ await bindProjectedNamesForSelectWithSchemas(query, cteCache, client, cacheContext);
37669
37907
  await validateB86SelectFieldCodes(query, client, cteCache, cacheContext);
37670
37908
  for (const subquery of collectB86Subqueries(query)) {
37671
37909
  await preflightB86QueryWithCte(subquery, client, cteCache, cacheContext, seen);
@@ -37966,7 +38204,7 @@ function collectScalarAggregateRefs(expr, out) {
37966
38204
  }
37967
38205
  }
37968
38206
  }
37969
- function collectCaseAggregateRefs(expr, out) {
38207
+ function collectNestedAggregateRefs(expr, out) {
37970
38208
  const visit = (node) => {
37971
38209
  if (node === null || typeof node !== "object") return;
37972
38210
  if (Array.isArray(node)) {
@@ -37991,12 +38229,14 @@ function collectSelectAggregateSortRefs(columns) {
37991
38229
  collectAggregateRef(column.func, column.arg, refs);
37992
38230
  } else if (column.type === "ARITH_AGG_COL") {
37993
38231
  collectAggregateOperandRefs(column.expr, refs);
38232
+ } else if (column.type === "ARITH_COL") {
38233
+ collectNestedAggregateRefs(column.expr, refs);
37994
38234
  } else if (column.type === "STRFUNC_COL") {
37995
38235
  collectStringFuncAggregateRefs(column.expr, refs);
37996
38236
  } else if (column.type === "SCALAR_VALUE_COL") {
37997
38237
  collectScalarAggregateRefs(column.expr, refs);
37998
38238
  } else if (column.type === "CASE_COL") {
37999
- collectCaseAggregateRefs(column.expr, refs);
38239
+ collectNestedAggregateRefs(column.expr, refs);
38000
38240
  }
38001
38241
  }
38002
38242
  return refs;
@@ -38066,20 +38306,20 @@ async function loadAggregateSortKindResolver(stmt, client, cacheContext, materia
38066
38306
  const table = tables.find((candidate) => effectiveTableAlias(candidate) === ref.tableAlias);
38067
38307
  if (!table) return void 0;
38068
38308
  if (table.cteName !== null) {
38069
- return materializedTables?.get(table.cteName)?.columnMeta?.get(ref.field)?.semantics ?? syntheticSemantics("string");
38309
+ return resolveMaterializedColumnMeta(materializedTables?.get(table.cteName), ref.field)?.semantics ?? syntheticSemantics("string");
38070
38310
  }
38071
38311
  info = fieldInfosByApp.get(table.appId)?.get(fieldCodeForTypeLookup(table, ref.field));
38072
38312
  }
38073
38313
  } else if (stmt.joins.length === 0) {
38074
38314
  if (stmt.from.cteName !== null) {
38075
- return materializedTables?.get(stmt.from.cteName)?.columnMeta?.get(ref.field)?.semantics ?? syntheticSemantics("string");
38315
+ return resolveMaterializedColumnMeta(materializedTables?.get(stmt.from.cteName), ref.field)?.semantics ?? syntheticSemantics("string");
38076
38316
  }
38077
38317
  info = fieldInfosByApp.get(stmt.from.appId)?.get(fieldCodeForTypeLookup(stmt.from, ref.field));
38078
38318
  } else {
38079
38319
  const matches = tables.flatMap((table) => {
38080
38320
  if (table.cteName !== null) {
38081
38321
  const materialized = materializedTables?.get(table.cteName);
38082
- return materialized?.columns.includes(ref.field) ? [materialized.columnMeta?.get(ref.field)?.semantics ?? syntheticSemantics("string")] : [];
38322
+ return resolveMaterializedColumn(materialized, ref.field) !== void 0 ? [resolveMaterializedColumnMeta(materialized, ref.field)?.semantics ?? syntheticSemantics("string")] : [];
38083
38323
  }
38084
38324
  const candidate = fieldInfosByApp.get(table.appId)?.get(fieldCodeForTypeLookup(table, ref.field));
38085
38325
  return candidate ? [semanticsForInfo(candidate, table.appId)] : [];
@@ -38144,32 +38384,13 @@ function systemColumnMeta(field) {
38144
38384
  if (field === "$revision") return syntheticColumnMeta("number");
38145
38385
  return void 0;
38146
38386
  }
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");
38387
+ function stringFunctionColumnMeta(expr, resolveField2) {
38388
+ return syntheticColumnMeta(stringFunctionSemanticKind(expr, (ref) => {
38389
+ const resolved = resolveField2?.(ref);
38390
+ if (!resolved) return void 0;
38391
+ if ("compareMode" in resolved) return resolved;
38392
+ return resolved.semantics;
38393
+ }));
38173
38394
  }
38174
38395
  function caseResultColumnMeta(result, resolveField2) {
38175
38396
  if (result.type === "STRING") return syntheticColumnMeta("string");
@@ -38182,7 +38403,7 @@ function caseResultColumnMeta(result, resolveField2) {
38182
38403
  }
38183
38404
  if (result.type === "AGG_ARITH") return syntheticColumnMeta("number");
38184
38405
  if (result.type === "NUMBER" || result.type === "ARITH" || result.type === "SCALAR_ARITH") return syntheticColumnMeta("number");
38185
- if (result.type === "STRING_FUNC") return stringFunctionColumnMeta(result);
38406
+ if (result.type === "STRING_FUNC") return stringFunctionColumnMeta(result, resolveField2);
38186
38407
  if (result.type === "FIELD_REF") return resolveField2(aggregateFieldRef(result.field)) ?? unknownStringColumnMeta();
38187
38408
  if (result.type === "FIELD") return resolveField2(result) ?? unknownStringColumnMeta();
38188
38409
  return unknownStringColumnMeta();
@@ -38213,7 +38434,7 @@ function inferAggregateArgMeta(arg, resolveField2) {
38213
38434
  if (arg.type === "FIELD") return resolveField2(arg) ?? unknownStringColumnMeta();
38214
38435
  if (arg.type === "NUMBER" || arg.type === "ARITH" || arg.type === "SCALAR_ARITH") return syntheticColumnMeta("number");
38215
38436
  if (arg.type === "STRING" || arg.type === "CONCAT_OP" || arg.type === "VARIABLE") return syntheticColumnMeta("string");
38216
- if (arg.type === "STRING_FUNC") return stringFunctionColumnMeta(arg);
38437
+ if (arg.type === "STRING_FUNC") return stringFunctionColumnMeta(arg, resolveField2);
38217
38438
  const results = arg.branches.map((branch) => caseResultColumnMeta(branch.result, resolveField2));
38218
38439
  if (arg.elseResult) results.push(caseResultColumnMeta(arg.elseResult, resolveField2));
38219
38440
  return mergeExpressionColumnMeta(results);
@@ -38257,20 +38478,20 @@ async function inferSelectColumnMeta(stmt, outputColumns, client, cacheContext,
38257
38478
  }
38258
38479
  const table = tables.find((candidate) => effectiveTableAlias(candidate) === ref.tableAlias);
38259
38480
  if (!table) return void 0;
38260
- if (table.cteName !== null) return materializedTables?.get(table.cteName)?.columnMeta?.get(ref.field);
38481
+ if (table.cteName !== null) return resolveMaterializedColumnMeta(materializedTables?.get(table.cteName), ref.field);
38261
38482
  const info = physicalInfos.get(table.appId)?.get(fieldCodeForTypeLookup(table, ref.field));
38262
38483
  return info ? materializedMetaFromFieldInfo(info, table.appId) : systemColumnMeta(ref.field);
38263
38484
  }
38264
38485
  if (stmt.joins.length === 0) {
38265
- if (stmt.from.cteName !== null) return materializedTables?.get(stmt.from.cteName)?.columnMeta?.get(ref.field);
38486
+ if (stmt.from.cteName !== null) return resolveMaterializedColumnMeta(materializedTables?.get(stmt.from.cteName), ref.field);
38266
38487
  const info = physicalInfos.get(stmt.from.appId)?.get(fieldCodeForTypeLookup(stmt.from, ref.field));
38267
38488
  return info ? materializedMetaFromFieldInfo(info, stmt.from.appId) : systemColumnMeta(ref.field);
38268
38489
  }
38269
38490
  const matches = tables.flatMap((table) => {
38270
38491
  if (table.cteName !== null) {
38271
38492
  const materialized = materializedTables?.get(table.cteName);
38272
- if (!materialized?.columns.includes(ref.field)) return [];
38273
- return [materialized.columnMeta?.get(ref.field)];
38493
+ if (resolveMaterializedColumn(materialized, ref.field) === void 0) return [];
38494
+ return [resolveMaterializedColumnMeta(materialized, ref.field)];
38274
38495
  }
38275
38496
  const info = physicalInfos.get(table.appId)?.get(fieldCodeForTypeLookup(table, ref.field));
38276
38497
  const meta = info ? materializedMetaFromFieldInfo(info, table.appId) : systemColumnMeta(ref.field);
@@ -38334,12 +38555,12 @@ async function inferSelectColumnMeta(stmt, outputColumns, client, cacheContext,
38334
38555
  meta = syntheticColumnMeta("string");
38335
38556
  } else if (column.type === "SCALAR_VALUE_COL") {
38336
38557
  const expr = column.expr;
38337
- if (expr.type === "STRING_FUNC") meta = stringFunctionColumnMeta(expr);
38558
+ if (expr.type === "STRING_FUNC") meta = stringFunctionColumnMeta(expr, resolveField2);
38338
38559
  else if (expr.type === "NUMBER" || expr.type === "SCALAR_ARITH") meta = syntheticColumnMeta("number");
38339
38560
  else if (expr.type === "FIELD") meta = resolveField2(expr);
38340
38561
  else meta = syntheticColumnMeta("string");
38341
38562
  } else if (column.type === "STRFUNC_COL") {
38342
- meta = stringFunctionColumnMeta(column.expr);
38563
+ meta = stringFunctionColumnMeta(column.expr, resolveField2);
38343
38564
  } else if (column.type === "WINDOW_COL") {
38344
38565
  meta = inferWindowColumnMeta(column, resolveField2);
38345
38566
  } else if (column.type === "CASE_COL") {
@@ -38766,7 +38987,7 @@ async function buildRecursiveFieldResolver(stmt, client, cacheContext, materiali
38766
38987
  physical.set(table.appId, new Map(infos.map((info) => [info.code, info])));
38767
38988
  }));
38768
38989
  const resolveInTable = (table, field) => {
38769
- if (table.cteName !== null) return materializedTables.get(table.cteName)?.columnMeta?.get(field);
38990
+ if (table.cteName !== null) return resolveMaterializedColumnMeta(materializedTables.get(table.cteName), field);
38770
38991
  const info = physical.get(table.appId)?.get(fieldCodeForTypeLookup(table, field));
38771
38992
  return info ? materializedMetaFromFieldInfo(info, table.appId) : systemColumnMeta(field);
38772
38993
  };
@@ -38974,7 +39195,7 @@ function rewriteRecursivePhysicalSources(stmt, sources) {
38974
39195
  };
38975
39196
  }
38976
39197
  function tableMetaForJoinKey(table, field, cache) {
38977
- return table.cteName === null ? void 0 : cache.get(table.cteName)?.columnMeta?.get(field);
39198
+ return table.cteName === null ? void 0 : resolveMaterializedColumnMeta(cache.get(table.cteName), field);
38978
39199
  }
38979
39200
  function recursiveJoinKey(value, semantics) {
38980
39201
  if (semantics.compareMode !== "number" && semantics.compareMode !== "recordNumber") return value;
@@ -39833,7 +40054,7 @@ async function tryFetchJoinRecordsBySourceKeys(stmt, join3, tables, client, maxR
39833
40054
  const targetMeta = targetInfo ? materializedMetaFromFieldInfo(targetInfo, join3.table.appId) : systemColumnMeta(joinField);
39834
40055
  let sourceMeta;
39835
40056
  if (sourceTable?.cteName !== null && sourceTable?.cteName !== void 0) {
39836
- sourceMeta = materializedTables?.get(sourceTable.cteName)?.columnMeta?.get(sourceField);
40057
+ sourceMeta = resolveMaterializedColumnMeta(materializedTables?.get(sourceTable.cteName), sourceField);
39837
40058
  } else if (sourceTable) {
39838
40059
  const sourceInfo = (await getFieldsCached(sourceTable.appId, client, cacheContext)).find((info) => info.code === fieldCodeForTypeLookup(sourceTable, sourceField));
39839
40060
  sourceMeta = sourceInfo ? materializedMetaFromFieldInfo(sourceInfo, sourceTable.appId) : systemColumnMeta(sourceField);
@@ -40030,19 +40251,19 @@ async function buildOrderSemanticsForSelect(stmt, client, cacheContext, material
40030
40251
  }
40031
40252
  const table = tables.find((candidate) => effectiveTableAlias(candidate) === ref.tableAlias);
40032
40253
  if (!table) return void 0;
40033
- if (table.cteName !== null) return materializedTables?.get(table.cteName)?.columnMeta?.get(ref.field);
40254
+ if (table.cteName !== null) return resolveMaterializedColumnMeta(materializedTables?.get(table.cteName), ref.field);
40034
40255
  const info = infosByApp.get(table.appId)?.get(fieldCodeForTypeLookup(table, ref.field));
40035
40256
  return info ? materializedMetaFromFieldInfo(info, table.appId) : systemColumnMeta(ref.field);
40036
40257
  }
40037
40258
  if (stmt.joins.length === 0) {
40038
- if (stmt.from.cteName !== null) return materializedTables?.get(stmt.from.cteName)?.columnMeta?.get(ref.field);
40259
+ if (stmt.from.cteName !== null) return resolveMaterializedColumnMeta(materializedTables?.get(stmt.from.cteName), ref.field);
40039
40260
  const info = infosByApp.get(stmt.from.appId)?.get(fieldCodeForTypeLookup(stmt.from, ref.field));
40040
40261
  return info ? materializedMetaFromFieldInfo(info, stmt.from.appId) : systemColumnMeta(ref.field);
40041
40262
  }
40042
40263
  const matches = tables.flatMap((table) => {
40043
40264
  if (table.cteName !== null) {
40044
40265
  const materialized = materializedTables?.get(table.cteName);
40045
- const meta2 = materialized?.columns.includes(ref.field) ? materialized.columnMeta?.get(ref.field) : void 0;
40266
+ const meta2 = resolveMaterializedColumnMeta(materialized, ref.field);
40046
40267
  return meta2 ? [meta2] : [];
40047
40268
  }
40048
40269
  const info = infosByApp.get(table.appId)?.get(fieldCodeForTypeLookup(table, ref.field));
@@ -40064,7 +40285,7 @@ async function buildOrderSemanticsForSelect(stmt, client, cacheContext, material
40064
40285
  } else if (column.type === "GROUPING_COL") {
40065
40286
  meta = syntheticColumnMeta("number");
40066
40287
  } 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);
40288
+ else if (column.type === "STRFUNC_COL") meta = stringFunctionColumnMeta(column.expr, resolveField2);
40068
40289
  else if (column.type === "SCALAR_SUBQUERY_COL") meta = unknownStringColumnMeta();
40069
40290
  else if (column.type === "CASE_COL") {
40070
40291
  const candidates = column.expr.branches.map((branch) => caseResultColumnMeta(branch.result, resolveField2));
@@ -40081,7 +40302,8 @@ async function buildOrderSemanticsForSelect(stmt, client, cacheContext, material
40081
40302
  }
40082
40303
  const result = /* @__PURE__ */ new Map();
40083
40304
  for (const name of names) {
40084
- const base = aliasSemantics.get(name) ?? resolveField2(aggregateFieldRef(name))?.semantics;
40305
+ const resolvedAlias = resolveProjectedName(name, aliasSemantics.keys());
40306
+ const base = (resolvedAlias === void 0 ? void 0 : aliasSemantics.get(resolvedAlias)) ?? resolveField2(aggregateFieldRef(name))?.semantics;
40085
40307
  if (!base) {
40086
40308
  const ref = aggregateFieldRef(name);
40087
40309
  if (ref.tableAlias === null && ambiguousFields.has(ref.field)) {
@@ -41120,6 +41342,29 @@ var UPDATE_FROM_UNSUPPORTED_SOURCE_TYPES = /* @__PURE__ */ new Set([
41120
41342
  "FILE"
41121
41343
  ]);
41122
41344
  async function resolveUpdateFromMatchedRecords(stmt, from, client, options, cacheContext, tempTables, snapshotFields) {
41345
+ if (from.cteName !== null) {
41346
+ const materialized = tempTables?.get(from.cteName);
41347
+ const resolveSource = (requested) => resolveProjectedName(requested, materialized?.columns ?? []) ?? requested;
41348
+ from.joinKeyField = resolveSource(from.joinKeyField);
41349
+ for (const assignment of stmt.assignments) {
41350
+ if (assignment.value.type === "SOURCE_FIELD" && assignment.value.alias === from.alias) {
41351
+ assignment.value.field = resolveSource(assignment.value.field);
41352
+ }
41353
+ }
41354
+ const visitSourceChecks = (node) => {
41355
+ if (node === null || typeof node !== "object") return;
41356
+ if (Array.isArray(node)) {
41357
+ node.forEach(visitSourceChecks);
41358
+ return;
41359
+ }
41360
+ const value = node;
41361
+ if (value["type"] === "FIELD" && value["tableAlias"] === from.alias && typeof value["field"] === "string") {
41362
+ value["field"] = resolveSource(value["field"]);
41363
+ }
41364
+ Object.values(value).forEach(visitSourceChecks);
41365
+ };
41366
+ visitSourceChecks(stmt.checkGroups);
41367
+ }
41123
41368
  const joinKind = await resolveUpdateFromTargetJoinKind(stmt, from, client, cacheContext);
41124
41369
  const checkScope = await resolveUpdateFromCheckScope(stmt, from, client, cacheContext, tempTables);
41125
41370
  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 +41456,7 @@ async function loadUpdateFromSourceRows(from, requiredSourceFields, sourceValueF
41211
41456
  const table = tempTables?.get(from.cteName);
41212
41457
  if (!table) throw new Error(`ArgumentError: temp table ${from.cteName} is not available.`);
41213
41458
  for (const field of requiredSourceFields) {
41214
- if (!table.columns.includes(field)) {
41459
+ if (resolveMaterializedColumn(table, field) === void 0) {
41215
41460
  throw new Error(`ArgumentError: UPDATE ... FROM source column ${field} does not exist.`);
41216
41461
  }
41217
41462
  }
@@ -42974,7 +43219,10 @@ function compareByOrder(a, b, orderBy, resolveSemantics, evaluationContext = {})
42974
43219
  for (const item of orderBy) {
42975
43220
  const av = evalOrderKeyForRow(item.key, a, evaluationContext);
42976
43221
  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");
43222
+ 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) => {
43223
+ const semantics2 = resolveSemantics(ref);
43224
+ return semantics2 ? { compareMode: semantics2.compareMode } : void 0;
43225
+ }).semantics ?? syntheticSemantics("string") : syntheticSemantics("number");
42978
43226
  const cmp = compareCanonicalValues(av, bv, semantics ?? syntheticSemantics("string"));
42979
43227
  if (cmp !== 0) return item.direction === "ASC" ? cmp : -cmp;
42980
43228
  }
@@ -43422,6 +43670,7 @@ async function buildExplainWhereAnalysis(query, client, cacheContext, maxRecords
43422
43670
  }
43423
43671
  if (typed["type"] === "SELECT") {
43424
43672
  const select = node;
43673
+ await bindProjectedNamesForSelectWithSchemas(select, explainRelations, tracedClient, cacheContext);
43425
43674
  analyzeStaticSelectRows(select);
43426
43675
  for (const column of select.columns) {
43427
43676
  if (column.type === "SCALAR_SUBQUERY_COL") await preflightExplainRelations(column.query);
@@ -43514,7 +43763,7 @@ async function buildExplainWhereAnalysis(query, client, cacheContext, maxRecords
43514
43763
  const sourceTable = [select.from, ...select.joins.map((candidate) => candidate.table)].find((table) => effectiveTableAlias(table) === sourceAlias);
43515
43764
  let targetMeta;
43516
43765
  if (join3.table.cteName !== null) {
43517
- targetMeta = explainRelations.get(join3.table.cteName)?.columnMeta?.get(joinField);
43766
+ targetMeta = resolveMaterializedColumnMeta(explainRelations.get(join3.table.cteName), joinField);
43518
43767
  } else {
43519
43768
  const targetInfo = (await getFieldsCached(join3.table.appId, tracedClient, cacheContext)).find((info) => info.code === fieldCodeForTypeLookup(join3.table, joinField));
43520
43769
  targetMeta = targetInfo ? materializedMetaFromFieldInfo(targetInfo, join3.table.appId) : systemColumnMeta(joinField);
@@ -43525,7 +43774,7 @@ async function buildExplainWhereAnalysis(query, client, cacheContext, maxRecords
43525
43774
  let hasEmptyValue;
43526
43775
  if (sourceTable?.cteName !== null && sourceTable?.cteName !== void 0) {
43527
43776
  const relation = explainRelations.get(sourceTable.cteName);
43528
- sourceMeta = relation?.columnMeta?.get(sourceField);
43777
+ sourceMeta = resolveMaterializedColumnMeta(relation, sourceField);
43529
43778
  if (staticExplainRelations.has(sourceTable.cteName) && relation) {
43530
43779
  sourceRowCount = relation.rows.length;
43531
43780
  values = relation.rows.map((row) => toScalarText(row[sourceField]));
@@ -45330,7 +45579,7 @@ function collectFullScanReasons(stmt) {
45330
45579
  );
45331
45580
  if (stmt.distinct)
45332
45581
  r.push("DISTINCT \u3042\u308A");
45333
- if (stmt.columns.some((c) => c.type === "AGGREGATE" || c.type === "ARITH_AGG_COL"))
45582
+ if (hasAggregateColumns(stmt.columns))
45334
45583
  r.push("\u96C6\u8A08\u95A2\u6570\uFF08COUNT / SUM \u7B49\uFF09\u3042\u308A");
45335
45584
  if (stmt.columns.some((c) => c.type === "WINDOW_COL"))
45336
45585
  r.push("\u30A6\u30A3\u30F3\u30C9\u30A6\u95A2\u6570\u3042\u308A");