@rex0220/kintone-sql-tools 3.43.0 → 3.44.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.
@@ -30555,6 +30555,7 @@ function arithLabel(node, topLevel = false) {
30555
30555
  function fieldValueLabel(value) {
30556
30556
  if (value.type === "FIELD") return value.tableAlias ? `${value.tableAlias}.${value.field}` : value.field;
30557
30557
  if (value.type === "FUNC_FIELD") return stringFuncLabel(value.expr);
30558
+ if (value.type === "AGG_FIELD") return aggregateOperandLabel(value.expr);
30558
30559
  if (value.type === "ARITH_FIELD") return arithLabel(value.expr);
30559
30560
  if (value.type === "GROUPING_FIELD") {
30560
30561
  const field = value.ref.field;
@@ -30608,6 +30609,8 @@ function whereLabel(expr) {
30608
30609
  }
30609
30610
  function caseResultLabel(result) {
30610
30611
  if (result.type === "ARRAY") return `[${result.elements.map((entry) => quote(entry.value)).join(",")}]`;
30612
+ if (result.type === "AGG_REF") return aggregateSyntheticName(result.func, result.distinct, result.arg);
30613
+ if (result.type === "AGG_ARITH") return aggregateOperandLabel(result);
30611
30614
  if (result.type === "FIELD_REF" || result.type === "ARITH") return arithLabel(result);
30612
30615
  return scalarValueLabel(result);
30613
30616
  }
@@ -31952,8 +31955,17 @@ var Parser = class {
31952
31955
  if (column.type === "AGGREGATE" || column.type === "ARITH_AGG_COL") return true;
31953
31956
  if (column.type === "STRFUNC_COL") return column.expr.args.some((arg) => this.stringFuncArgHasAggregate(arg));
31954
31957
  if (column.type === "SCALAR_VALUE_COL") return this.scalarValueHasAggregate(column.expr);
31958
+ if (column.type === "CASE_COL") return this.nodeHasAggregate(column.expr);
31955
31959
  return false;
31956
31960
  }
31961
+ nodeHasAggregate(node) {
31962
+ if (node === null || typeof node !== "object") return false;
31963
+ if (Array.isArray(node)) return node.some((value2) => this.nodeHasAggregate(value2));
31964
+ const value = node;
31965
+ if (value["type"] === "AGG_REF" || value["type"] === "AGG_ARITH") return true;
31966
+ if (value["type"] === "SELECT" || value["type"] === "SCALAR_SUBQUERY") return false;
31967
+ return Object.values(value).some((child) => this.nodeHasAggregate(child));
31968
+ }
31957
31969
  stringFuncArgHasAggregate(arg) {
31958
31970
  if (arg.type === "AGG_REF" || arg.type === "AGG_ARITH") return true;
31959
31971
  return this.scalarValueHasAggregate(arg);
@@ -31964,11 +31976,7 @@ var Parser = class {
31964
31976
  return this.scalarValueHasAggregate(expr.left) || this.scalarValueHasAggregate(expr.right);
31965
31977
  }
31966
31978
  if (expr.type === "CASE_WHEN") {
31967
- const results = [...expr.branches.map((b) => b.result), ...expr.elseResult ? [expr.elseResult] : []];
31968
- return results.some((result) => {
31969
- if (result.type === "ARRAY" || result.type === "FIELD_REF" || result.type === "ARITH") return false;
31970
- return this.scalarValueHasAggregate(result);
31971
- });
31979
+ return this.nodeHasAggregate(expr);
31972
31980
  }
31973
31981
  return false;
31974
31982
  }
@@ -32225,9 +32233,9 @@ var Parser = class {
32225
32233
  this.expect("(" /* LPAREN */);
32226
32234
  const condition = this.parseCaseCondition(allowGroupingCondition);
32227
32235
  this.expect("," /* COMMA */);
32228
- const thenResult = this.parseCaseResult();
32236
+ const thenResult = this.parseCaseResult(allowGroupingCondition);
32229
32237
  this.expect("," /* COMMA */);
32230
- const elseResult = this.parseCaseResult();
32238
+ const elseResult = this.parseCaseResult(allowGroupingCondition);
32231
32239
  this.expect(")" /* RPAREN */);
32232
32240
  return {
32233
32241
  type: "CASE_WHEN",
@@ -32242,7 +32250,7 @@ var Parser = class {
32242
32250
  this.advance();
32243
32251
  const condition = this.parseCaseCondition(allowGroupingCondition);
32244
32252
  this.expect("THEN" /* THEN */);
32245
- const result = this.parseCaseResult();
32253
+ const result = this.parseCaseResult(allowGroupingCondition);
32246
32254
  branches.push({ condition, result });
32247
32255
  }
32248
32256
  if (branches.length === 0) {
@@ -32250,7 +32258,7 @@ var Parser = class {
32250
32258
  }
32251
32259
  let elseResult = null;
32252
32260
  if (this.consume("ELSE" /* ELSE */)) {
32253
- elseResult = this.parseCaseResult();
32261
+ elseResult = this.parseCaseResult(allowGroupingCondition);
32254
32262
  }
32255
32263
  this.expect("END" /* END */);
32256
32264
  return { type: "CASE_WHEN", branches, elseResult };
@@ -32260,7 +32268,7 @@ var Parser = class {
32260
32268
  return this.parseWhereExpr("SELECT_CASE");
32261
32269
  }
32262
32270
  /** THEN / ELSE の結果値。`||` を含む場合だけ新スカラー文法へ渡す。 */
32263
- parseCaseResult() {
32271
+ parseCaseResult(allowAggregateResult = false) {
32264
32272
  const tok = this.peek();
32265
32273
  if (this.insideAggregateArg > 0 && this.tryAggregateFunc() !== null) {
32266
32274
  throw new ParseError("\u96C6\u8A08\u95A2\u6570\u306E\u5F15\u6570\u5185\u306B\u96C6\u8A08\u95A2\u6570\u306F\u4F7F\u7528\u3067\u304D\u307E\u305B\u3093", tok);
@@ -32268,6 +32276,10 @@ var Parser = class {
32268
32276
  if (tok.kind === "[" /* LBRACKET */) {
32269
32277
  return this.parseArrayLiteral();
32270
32278
  }
32279
+ const aggregateFunc = this.tryAggregateFunc();
32280
+ if (aggregateFunc !== null && allowAggregateResult) {
32281
+ return this.continueAggArith(this.parseAggregateRef(aggregateFunc));
32282
+ }
32271
32283
  if (this.hasTopLevelTokenBeforeValueEnd("||" /* CONCAT_OP */)) {
32272
32284
  return this.parseScalarValueExpr({ allowAggregateArgs: true });
32273
32285
  }
@@ -32791,8 +32803,19 @@ var Parser = class {
32791
32803
  throw new ParseError("\u96C6\u8A08\u95A2\u6570\u306E\u5F15\u6570\u5185\u306B\u96C6\u8A08\u95A2\u6570\u306F\u4F7F\u7528\u3067\u304D\u307E\u305B\u3093", this.peek());
32792
32804
  }
32793
32805
  const ref = this.parseAggregateRef(aggFunc);
32806
+ if (this.isArithOp(this.peek().kind)) {
32807
+ return {
32808
+ type: "AGG_FIELD",
32809
+ expr: this.continueAggArith(ref)
32810
+ };
32811
+ }
32794
32812
  const syntheticName = aggregateSyntheticName(ref.func, ref.distinct, ref.arg);
32795
- return { type: "FIELD", tableAlias: null, field: syntheticName };
32813
+ return {
32814
+ type: "FIELD",
32815
+ tableAlias: null,
32816
+ field: syntheticName,
32817
+ ...this.groupingFieldContext === "SELECT_CASE" || this.groupingFieldContext === "HAVING" ? { aggregateRef: ref } : {}
32818
+ };
32796
32819
  }
32797
32820
  if (this.peek().kind === "CASE" /* CASE */) {
32798
32821
  const expr = this.parseCaseWhenExpr();
@@ -34995,6 +35018,9 @@ function convertField(field) {
34995
35018
  `WHERE \u53E5\u306E\u95A2\u6570\uFF08${field.expr.func}\uFF09\u306F kintone \u30AF\u30A8\u30EA\u306B\u5909\u63DB\u3067\u304D\u307E\u305B\u3093`
34996
35019
  );
34997
35020
  }
35021
+ if (field.type === "AGG_FIELD") {
35022
+ throw new KintoneQueryError("HAVING \u53E5\u306E\u96C6\u8A08\u7B97\u8853\u5F0F\u306F kintone \u30AF\u30A8\u30EA\u306B\u5909\u63DB\u3067\u304D\u307E\u305B\u3093");
35023
+ }
34998
35024
  if (field.type === "ARITH_FIELD") {
34999
35025
  throw new KintoneQueryError("WHERE \u53E5\u306E\u7B97\u8853\u5F0F\u306F kintone \u30AF\u30A8\u30EA\u306B\u5909\u63DB\u3067\u304D\u307E\u305B\u3093");
35000
35026
  }
@@ -35133,195 +35159,470 @@ var KintoneQueryError = class extends Error {
35133
35159
  }
35134
35160
  };
35135
35161
 
35136
- // src/converter/selectToKintone.ts
35137
- function hasWindowColumns(columns) {
35138
- return columns.some((column) => column.type === "WINDOW_COL");
35139
- }
35140
- function resolveSelectMode(stmt) {
35141
- if (stmt.from.subtableCode) return "FULL_SCAN";
35142
- if (stmt.joins.some((j) => j.table.subtableCode)) return "FULL_SCAN";
35143
- if (stmt.joins.length > 0) return "FULL_SCAN";
35144
- if (normalizeGroupingSpec(stmt).type !== "NONE") return "FULL_SCAN";
35145
- if (stmt.distinct) return "FULL_SCAN";
35146
- if (hasWindowColumns(stmt.columns)) return "FULL_SCAN";
35147
- if (stmt.columns.some(
35148
- (c) => c.type === "AGGREGATE" || c.type === "ARITH_AGG_COL" || c.type === "SCALAR_SUBQUERY_COL" || c.type === "STRFUNC_COL" && hasAggregateInStringFuncExpr(c.expr) || c.type === "SCALAR_VALUE_COL" && scalarValueHasAggregate(c.expr)
35149
- )) return "FULL_SCAN";
35150
- if (whereRequiresJsEval(stmt.where)) return "FULL_SCAN";
35151
- if (stmt.orderBy.some((o) => o.key.type !== "FIELD_NAME")) return "FULL_SCAN";
35152
- return "SIMPLE";
35162
+ // src/core/groupingValidation.ts
35163
+ init_define_KSQL_DOCS();
35164
+
35165
+ // src/engine/groupingRowMeta.ts
35166
+ init_define_KSQL_DOCS();
35167
+ var groupingRowMetaKey = /* @__PURE__ */ Symbol("ksql.groupingRowMeta");
35168
+ var groupingRefCanonicalIds = /* @__PURE__ */ new WeakMap();
35169
+ function attachGroupingRowMeta(row, includedCanonicalIds) {
35170
+ Object.defineProperty(row, groupingRowMetaKey, {
35171
+ value: { includedCanonicalIds },
35172
+ enumerable: false,
35173
+ configurable: false,
35174
+ writable: false
35175
+ });
35176
+ return row;
35153
35177
  }
35154
- function whereRequiresJsEval(where) {
35155
- if (where === null) return false;
35156
- switch (where.type) {
35157
- case "BOOLEAN":
35158
- return true;
35159
- case "BINARY":
35160
- return isFunc(where.left) || where.right.type === "ARITH_VALUE" || where.right.type === "CASE_VALUE" || where.right.type === "SUBQUERY_IN_LIST" || where.right.type === "SCALAR_SUBQUERY" || isLike(where);
35161
- case "NULL_CHECK":
35162
- return isFunc(where.field);
35163
- case "LOGICAL":
35164
- return whereRequiresJsEval(where.left) || whereRequiresJsEval(where.right);
35165
- case "NOT":
35166
- case "GROUP":
35167
- return whereRequiresJsEval(where.expr);
35168
- case "EXISTS":
35169
- return true;
35170
- }
35178
+ function getGroupingRowMeta(row) {
35179
+ return row[groupingRowMetaKey];
35171
35180
  }
35172
- function isFunc(fv) {
35173
- return fv.type === "FUNC_FIELD" || fv.type === "ARITH_FIELD" || fv.type === "CASE_FIELD";
35181
+ function readGroupingMembership(row) {
35182
+ return getGroupingRowMeta(row)?.includedCanonicalIds;
35174
35183
  }
35175
- function selectToKintoneParams(stmt) {
35176
- const queryParts = [];
35177
- const hasPagination = stmt.limit !== null || stmt.offset !== null;
35178
- const shouldInjectDefaultOrder = hasPagination && stmt.orderBy.length === 0;
35179
- if (stmt.where !== null) {
35180
- queryParts.push(whereToKintone(stmt.where));
35181
- }
35182
- if (stmt.orderBy.length > 0) {
35183
- const orderStr = stmt.orderBy.map(convertOrderBy).join(", ");
35184
- queryParts.push(`order by ${orderStr}`);
35185
- } else if (shouldInjectDefaultOrder) {
35186
- queryParts.push("order by $id asc");
35187
- }
35188
- if (stmt.limit !== null) {
35189
- queryParts.push(`limit ${stmt.limit}`);
35190
- }
35191
- if (stmt.offset !== null) {
35192
- queryParts.push(`offset ${stmt.offset}`);
35193
- }
35194
- return {
35195
- app: stmt.from.appId,
35196
- query: queryParts.join(" "),
35197
- fields: extractFields(stmt.columns),
35198
- totalCount: false
35199
- };
35184
+ function bindGroupingRefCanonicalId(ref, canonicalId) {
35185
+ groupingRefCanonicalIds.set(ref, canonicalId);
35200
35186
  }
35201
- function selectToFetchAllParams(stmt, appId) {
35202
- const queryParts = [];
35203
- if (stmt.where !== null && stmt.joins.length === 0 && !whereRequiresJsEval(stmt.where)) {
35204
- queryParts.push(whereToKintone(stmt.where));
35187
+ function evalGroupingRef(ref, row) {
35188
+ const membership = readGroupingMembership(row);
35189
+ if (!membership) {
35190
+ throw new Error("internal error: GROUPING() evaluation requires B65 grouping row membership.");
35205
35191
  }
35206
- return {
35207
- app: appId,
35208
- query: queryParts.join(" "),
35209
- fields: []
35210
- // 全件取得なので全フィールドを取得する
35211
- };
35212
- }
35213
- function selectToFetchAllFields(stmt, targetTable, plainGroupByPlan) {
35214
- const plan = collectRequiredFieldsByTable(stmt, plainGroupByPlan);
35215
- const target = plan.get(targetTable);
35216
- if (!target) return [];
35217
- if (target.allFields) return [];
35218
- const fields = new Set(target.fields);
35219
- if (target.table.subtableCode) {
35220
- fields.add(target.table.subtableCode);
35192
+ const canonicalId = groupingRefCanonicalIds.get(ref);
35193
+ if (!canonicalId) {
35194
+ throw new Error("internal error: GROUPING() reference was not resolved during B65 planning.");
35221
35195
  }
35222
- if (fields.size === 0) fields.add("$id");
35223
- return [...fields];
35196
+ return membership.has(canonicalId) ? "0" : "1";
35224
35197
  }
35225
- function convertOrderBy(item) {
35226
- const dir = item.direction === "ASC" ? "asc" : "desc";
35227
- if (item.key.type !== "FIELD_NAME") {
35228
- throw new Error("ORDER BY \u5F0F\u306F kintone \u30AF\u30A8\u30EA\u306B\u5909\u63DB\u3067\u304D\u307E\u305B\u3093\uFF08FULL_SCAN \u304C\u5FC5\u8981\u3067\u3059\uFF09");
35198
+
35199
+ // src/core/groupingValidation.ts
35200
+ var enforceGroupingPlanningCandidateLimits = (facts) => {
35201
+ if (facts.expandedSetCount > B65_MAX_GROUPING_SETS) {
35202
+ throw new Error(
35203
+ `ArgumentError: B65 expanded grouping set count ${facts.expandedSetCount} exceeds limit ${B65_MAX_GROUPING_SETS} (reason=GROUPING_SET_LIMIT_EXCEEDED).`
35204
+ );
35229
35205
  }
35230
- return `${item.key.name} ${dir}`;
35231
- }
35232
- function extractFields(columns) {
35233
- const hasWildcard = columns.some(
35234
- (c) => c.type === "WILDCARD" || c.type === "AGGREGATE" || c.type === "ARITH_AGG_COL" || c.type === "CASE_COL" || c.type === "SCALAR_SUBQUERY_COL"
35235
- );
35236
- if (hasWildcard) return [];
35237
- const fields = [];
35238
- for (const col of columns) {
35239
- if (col.type === "FIELD") {
35240
- fields.push(normalizeSimpleFieldRef(col.field));
35241
- } else if (col.type === "ARITH_COL") {
35242
- collectArithNode(col.expr, fields);
35243
- } else if (col.type === "STRFUNC_COL") {
35244
- collectStringFuncFields(col.expr, fields);
35245
- } else if (col.type === "SCALAR_VALUE_COL") {
35246
- collectScalarValueFields(col.expr, fields);
35247
- }
35206
+ if (facts.canonicalItemCount > B65_MAX_GROUPING_ITEMS) {
35207
+ throw new Error(
35208
+ `ArgumentError: B65 canonical grouping item count ${facts.canonicalItemCount} exceeds limit ${B65_MAX_GROUPING_ITEMS} (reason=GROUPING_ITEM_LIMIT_EXCEEDED).`
35209
+ );
35248
35210
  }
35249
- return [...new Set(fields)];
35250
- }
35251
- function collectArithFields(expr, out) {
35252
- collectArithNode(expr.left, out);
35253
- collectArithNode(expr.right, out);
35254
- }
35255
- function collectArithNode(node, out) {
35256
- if (node.type === "VARIABLE") throw new Error(
35257
- `InternalError: unresolved arithmetic variable @${node.name} reached SELECT field collection.`
35258
- );
35259
- if (node.type === "FIELD_REF") out.push(normalizeSimpleFieldRef(node.field));
35260
- else if (node.type === "ARITH") collectArithFields(node, out);
35261
- else if (node.type === "STRING_FUNC") collectStringFuncFields(node, out);
35262
- }
35263
- function normalizeSimpleFieldRef(field) {
35264
- const dot = field.indexOf(".");
35265
- if (dot <= 0) return field;
35266
- const unqualified = field.slice(dot + 1);
35267
- return unqualified || field;
35211
+ };
35212
+ function displayField(field) {
35213
+ return field.tableAlias ? `${field.tableAlias}.${field.field}` : field.field;
35268
35214
  }
35269
- function collectStringFuncFields(expr, out) {
35270
- for (const arg of expr.args) {
35271
- collectStringFuncArgFields(arg, out);
35272
- }
35215
+ function refFromName(name) {
35216
+ const dot = name.indexOf(".");
35217
+ return dot > 0 ? { type: "FIELD", tableAlias: name.slice(0, dot), field: name.slice(dot + 1) } : { type: "FIELD", tableAlias: null, field: name };
35273
35218
  }
35274
- function collectStringFuncArgFields(arg, out) {
35275
- if (arg.type === "AGG_REF" || arg.type === "AGG_ARITH") {
35276
- collectAggOperandFields(arg, out);
35219
+ function collectGroupingRefs(node, out) {
35220
+ if (node === null || typeof node !== "object") return;
35221
+ if (Array.isArray(node)) {
35222
+ node.forEach((item) => collectGroupingRefs(item, out));
35277
35223
  return;
35278
35224
  }
35279
- collectScalarValueFields(arg, out);
35280
- }
35281
- function collectScalarValueFields(expr, out) {
35282
- if (expr.type === "FIELD") {
35283
- out.push(normalizeSimpleFieldRef(expr.tableAlias ? `${expr.tableAlias}.${expr.field}` : expr.field));
35225
+ const value = node;
35226
+ if (value["type"] === "SELECT" || value["type"] === "SCALAR_SUBQUERY") return;
35227
+ if (value["type"] === "GROUPING_REF") {
35228
+ out.push(value);
35284
35229
  return;
35285
35230
  }
35286
- if (expr.type === "STRING_FUNC") {
35287
- collectStringFuncFields(expr, out);
35231
+ Object.values(value).forEach((item) => collectGroupingRefs(item, out));
35232
+ }
35233
+ function collectAggregateArgumentGroupingRefs(node, out) {
35234
+ if (node === null || typeof node !== "object") return;
35235
+ if (Array.isArray(node)) {
35236
+ node.forEach((item) => collectAggregateArgumentGroupingRefs(item, out));
35288
35237
  return;
35289
35238
  }
35290
- if (expr.type === "SCALAR_ARITH" || expr.type === "CONCAT_OP") {
35291
- collectScalarValueFields(expr.left, out);
35292
- collectScalarValueFields(expr.right, out);
35239
+ const value = node;
35240
+ if (value["type"] === "SELECT" || value["type"] === "SCALAR_SUBQUERY") return;
35241
+ if (value["type"] === "AGGREGATE" || value["type"] === "AGG_REF") {
35242
+ collectGroupingRefs(value["arg"], out);
35293
35243
  return;
35294
35244
  }
35295
- if (expr.type === "CASE_WHEN") {
35296
- for (const branch of expr.branches) collectCaseResultScalarFields(branch.result, out);
35297
- if (expr.elseResult) collectCaseResultScalarFields(expr.elseResult, out);
35298
- }
35245
+ Object.values(value).forEach((item) => collectAggregateArgumentGroupingRefs(item, out));
35299
35246
  }
35300
- function collectCaseResultScalarFields(result, out) {
35301
- if (result.type === "ARRAY") return;
35302
- if (result.type === "FIELD_REF" || result.type === "ARITH") {
35303
- collectArithNode(result, out);
35247
+ function collectNonAggregateFieldRefs(node, out) {
35248
+ if (node === null || typeof node !== "object") return;
35249
+ if (Array.isArray(node)) {
35250
+ node.forEach((item) => collectNonAggregateFieldRefs(item, out));
35304
35251
  return;
35305
35252
  }
35306
- collectScalarValueFields(result, out);
35307
- }
35308
- function collectAggOperandFields(node, out) {
35309
- if (node.type === "AGG_REF") {
35310
- if (node.arg.type !== "WILDCARD") collectAggregateArgFields(node.arg, out);
35253
+ const value = node;
35254
+ const type = value["type"];
35255
+ if (type === "SELECT" || type === "SCALAR_SUBQUERY" || type === "GROUPING_REF" || type === "AGG_REF" || type === "AGG_ARITH") return;
35256
+ if (type === "FIELD" && value["aggregateRef"] !== void 0) return;
35257
+ if (type === "FIELD" && typeof value["field"] === "string") {
35258
+ out.push({
35259
+ type: "FIELD",
35260
+ tableAlias: typeof value["tableAlias"] === "string" ? value["tableAlias"] : null,
35261
+ field: value["field"]
35262
+ });
35311
35263
  return;
35312
35264
  }
35313
- if (node.type === "AGG_ARITH") {
35314
- collectAggOperandFields(node.left, out);
35315
- collectAggOperandFields(node.right, out);
35265
+ if (type === "FIELD_REF" && typeof value["field"] === "string") {
35266
+ out.push(refFromName(value["field"]));
35267
+ return;
35316
35268
  }
35269
+ Object.values(value).forEach((item) => collectNonAggregateFieldRefs(item, out));
35317
35270
  }
35318
- function collectAggregateArgFields(node, out) {
35319
- if (node.type === "FIELD_REF" || node.type === "ARITH") collectArithNode(node, out);
35320
- else collectScalarValueFields(node, out);
35321
- }
35322
- function hasAggregateInStringFuncExpr(expr) {
35323
- return expr.args.some((arg) => {
35324
- if (arg.type === "AGG_REF" || arg.type === "AGG_ARITH") return true;
35271
+ function containsAggregate2(node) {
35272
+ if (node === null || typeof node !== "object") return false;
35273
+ if (Array.isArray(node)) return node.some(containsAggregate2);
35274
+ const value = node;
35275
+ if (value["type"] === "AGG_REF" || value["type"] === "AGG_ARITH") return true;
35276
+ if (value["type"] === "SELECT" || value["type"] === "SCALAR_SUBQUERY") return false;
35277
+ return Object.values(value).some(containsAggregate2);
35278
+ }
35279
+ function isAggregateMaterializedAlias(column) {
35280
+ if (!("alias" in column) || column.alias === null) return false;
35281
+ if (column.type === "AGGREGATE" || column.type === "ARITH_AGG_COL") return true;
35282
+ if (column.type === "STRFUNC_COL" || column.type === "SCALAR_VALUE_COL" || column.type === "CASE_COL") {
35283
+ return containsAggregate2(column);
35284
+ }
35285
+ return false;
35286
+ }
35287
+ function outputAliases(columns) {
35288
+ return new Set(columns.flatMap(
35289
+ (column) => "alias" in column && typeof column.alias === "string" ? [column.alias] : []
35290
+ ));
35291
+ }
35292
+ function isAggregateSyntheticReference(ref) {
35293
+ return ref.tableAlias === null && /^(COUNT|SUM|AVG|MAX|MIN|GROUP_CONCAT|STDDEV_POP|STDDEV_SAMP|VAR_POP|VAR_SAMP|MEDIAN|MODE)\(/.test(ref.field);
35294
+ }
35295
+ function validateGroupingRefMembership(ref, resolve3, canonicalItems) {
35296
+ const resolved = resolve3(ref.field);
35297
+ if (!resolved.physical) {
35298
+ throw new Error(`ArgumentError: B65 grouping reference ${displayField(ref.field)} must resolve to a physical APP field.`);
35299
+ }
35300
+ if (!canonicalItems.has(resolved.canonicalId)) {
35301
+ throw new Error(
35302
+ `ArgumentError: B65 GROUPING argument ${displayField(ref.field)} is not present in grouping allItems (reason=B65_GROUPING_ARG_NOT_ITEM).`
35303
+ );
35304
+ }
35305
+ bindGroupingRefCanonicalId(ref, resolved.canonicalId);
35306
+ }
35307
+ function validateDependency(ref, resolve3, canonicalItems, context) {
35308
+ const resolved = resolve3(ref);
35309
+ if (!resolved.physical || !canonicalItems.has(resolved.canonicalId)) {
35310
+ throw new Error(
35311
+ `ArgumentError: B65 non-aggregate field ${displayField(ref)} in ${context} is not a grouping item (reason=B65_NON_GROUPED_DEPENDENCY).`
35312
+ );
35313
+ }
35314
+ }
35315
+ function keyDependencies(key) {
35316
+ if (key.type === "GROUPING_KEY") return [];
35317
+ if (key.type === "FIELD_NAME") return [refFromName(key.name)];
35318
+ const refs = [];
35319
+ collectNonAggregateFieldRefs(key, refs);
35320
+ return refs;
35321
+ }
35322
+ function validateGroupingStatic(stmt) {
35323
+ const normalized = normalizeGroupingSpec(stmt);
35324
+ const groupingRefs = [];
35325
+ for (const column of stmt.columns) {
35326
+ if (column.type !== "WINDOW_COL") collectGroupingRefs(column, groupingRefs);
35327
+ }
35328
+ collectGroupingRefs(stmt.having, groupingRefs);
35329
+ collectGroupingRefs(stmt.orderBy, groupingRefs);
35330
+ const forbiddenGroupingRefs = [];
35331
+ collectGroupingRefs(stmt.where, forbiddenGroupingRefs);
35332
+ collectGroupingRefs(stmt.joins, forbiddenGroupingRefs);
35333
+ collectAggregateArgumentGroupingRefs(stmt.columns, forbiddenGroupingRefs);
35334
+ collectAggregateArgumentGroupingRefs(stmt.having, forbiddenGroupingRefs);
35335
+ for (const column of stmt.columns) {
35336
+ if (column.type === "WINDOW_COL") collectGroupingRefs(column, forbiddenGroupingRefs);
35337
+ }
35338
+ if (forbiddenGroupingRefs.length > 0) {
35339
+ throw new Error(
35340
+ "ArgumentError: B65 GROUPING() is not allowed in WHERE, JOIN, window, aggregate arguments, or DML expressions."
35341
+ );
35342
+ }
35343
+ if (normalized.type !== "GROUPING_SETS") {
35344
+ if (groupingRefs.length > 0) {
35345
+ throw new Error("ArgumentError: B65 GROUPING() requires GROUP BY ROLLUP or GROUPING SETS.");
35346
+ }
35347
+ return;
35348
+ }
35349
+ if (stmt.orderMode === "KINTONE_NATIVE") {
35350
+ throw new Error("ArgumentError: B65 KORDER BY is not supported in Phase1.");
35351
+ }
35352
+ if (stmt.columns.some((column) => column.type === "WINDOW_COL")) {
35353
+ throw new Error("ArgumentError: B65 window functions are not supported in Phase1.");
35354
+ }
35355
+ if (stmt.columns.some(
35356
+ (column) => column.type === "WILDCARD" || column.type === "PARENT_WILDCARD"
35357
+ )) {
35358
+ throw new Error("ArgumentError: B65 wildcard projection is not supported in Phase1.");
35359
+ }
35360
+ }
35361
+ function validateGroupingPlanning(stmt, resolve3, planningGuardHook = () => void 0) {
35362
+ validateGroupingStatic(stmt);
35363
+ const normalized = normalizeGroupingSpec(stmt);
35364
+ const groupingRefs = [];
35365
+ for (const column of stmt.columns) {
35366
+ if (column.type !== "WINDOW_COL") collectGroupingRefs(column, groupingRefs);
35367
+ }
35368
+ collectGroupingRefs(stmt.having, groupingRefs);
35369
+ collectGroupingRefs(stmt.orderBy, groupingRefs);
35370
+ if (normalized.type !== "GROUPING_SETS") {
35371
+ return null;
35372
+ }
35373
+ const resolvedSpec = resolveGroupingSpec(stmt, resolve3);
35374
+ const canonicalItems = /* @__PURE__ */ new Set();
35375
+ const resolvedItems = [];
35376
+ for (const item of resolvedSpec.allItems) {
35377
+ const resolved = item;
35378
+ if (!resolved.physical) {
35379
+ throw new Error(`ArgumentError: B65 grouping item ${displayField(item.field)} must resolve to a physical APP field.`);
35380
+ }
35381
+ if (!canonicalItems.has(resolved.canonicalId)) {
35382
+ canonicalItems.add(resolved.canonicalId);
35383
+ resolvedItems.push(resolved);
35384
+ }
35385
+ }
35386
+ planningGuardHook({
35387
+ expandedSetCount: normalized.sets.length,
35388
+ canonicalItemCount: canonicalItems.size
35389
+ });
35390
+ for (const ref of groupingRefs) {
35391
+ validateGroupingRefMembership(ref, resolve3, canonicalItems);
35392
+ }
35393
+ const aliases = outputAliases(stmt.columns);
35394
+ for (const column of stmt.columns) {
35395
+ if (column.type === "GROUPING_COL" || column.type === "AGGREGATE" || column.type === "ARITH_AGG_COL" || column.type === "LITERAL_COL" || column.type === "VARIABLE_COL" || column.type === "SCALAR_SUBQUERY_COL") continue;
35396
+ const refs = [];
35397
+ if (column.type === "FIELD") refs.push(refFromName(column.field));
35398
+ else collectNonAggregateFieldRefs(column, refs);
35399
+ for (const ref of refs) validateDependency(ref, resolve3, canonicalItems, "SELECT");
35400
+ }
35401
+ if (stmt.having) {
35402
+ const refs = [];
35403
+ collectNonAggregateFieldRefs(stmt.having, refs);
35404
+ for (const ref of refs) {
35405
+ if (ref.tableAlias === null && aliases.has(ref.field) || isAggregateSyntheticReference(ref)) continue;
35406
+ validateDependency(ref, resolve3, canonicalItems, "HAVING");
35407
+ }
35408
+ }
35409
+ for (const order of stmt.orderBy) {
35410
+ for (const ref of keyDependencies(order.key)) {
35411
+ if (ref.tableAlias === null && aliases.has(ref.field) || isAggregateSyntheticReference(ref)) continue;
35412
+ validateDependency(ref, resolve3, canonicalItems, "ORDER BY");
35413
+ }
35414
+ }
35415
+ const collisionKeys = /* @__PURE__ */ new Set();
35416
+ for (const item of resolvedItems) {
35417
+ collisionKeys.add(item.directKey);
35418
+ if (item.unqualifiedBridgeKey !== null) collisionKeys.add(item.unqualifiedBridgeKey);
35419
+ }
35420
+ for (const column of stmt.columns) {
35421
+ if (!isAggregateMaterializedAlias(column)) continue;
35422
+ const alias = "alias" in column ? column.alias : null;
35423
+ if (alias === null) continue;
35424
+ if (collisionKeys.has(alias)) {
35425
+ throw new Error(
35426
+ `ArgumentError: B65 aggregate alias ${alias} collides with a grouping runtime key (reason=B65_AGGREGATE_ALIAS_COLLISION).`
35427
+ );
35428
+ }
35429
+ }
35430
+ return resolvedSpec;
35431
+ }
35432
+
35433
+ // src/converter/selectToKintone.ts
35434
+ function hasWindowColumns(columns) {
35435
+ return columns.some((column) => column.type === "WINDOW_COL");
35436
+ }
35437
+ function resolveSelectMode(stmt) {
35438
+ if (stmt.from.subtableCode) return "FULL_SCAN";
35439
+ if (stmt.joins.some((j) => j.table.subtableCode)) return "FULL_SCAN";
35440
+ if (stmt.joins.length > 0) return "FULL_SCAN";
35441
+ if (normalizeGroupingSpec(stmt).type !== "NONE") return "FULL_SCAN";
35442
+ if (stmt.distinct) return "FULL_SCAN";
35443
+ if (hasWindowColumns(stmt.columns)) return "FULL_SCAN";
35444
+ if (stmt.columns.some(
35445
+ (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)
35446
+ )) return "FULL_SCAN";
35447
+ if (whereRequiresJsEval(stmt.where)) return "FULL_SCAN";
35448
+ if (stmt.orderBy.some((o) => o.key.type !== "FIELD_NAME")) return "FULL_SCAN";
35449
+ return "SIMPLE";
35450
+ }
35451
+ function whereRequiresJsEval(where) {
35452
+ if (where === null) return false;
35453
+ switch (where.type) {
35454
+ case "BOOLEAN":
35455
+ return true;
35456
+ case "BINARY":
35457
+ return isFunc(where.left) || where.right.type === "ARITH_VALUE" || where.right.type === "CASE_VALUE" || where.right.type === "SUBQUERY_IN_LIST" || where.right.type === "SCALAR_SUBQUERY" || isLike(where);
35458
+ case "NULL_CHECK":
35459
+ return isFunc(where.field);
35460
+ case "LOGICAL":
35461
+ return whereRequiresJsEval(where.left) || whereRequiresJsEval(where.right);
35462
+ case "NOT":
35463
+ case "GROUP":
35464
+ return whereRequiresJsEval(where.expr);
35465
+ case "EXISTS":
35466
+ return true;
35467
+ }
35468
+ }
35469
+ function isFunc(fv) {
35470
+ return fv.type === "FUNC_FIELD" || fv.type === "ARITH_FIELD" || fv.type === "CASE_FIELD";
35471
+ }
35472
+ function selectToKintoneParams(stmt) {
35473
+ const queryParts = [];
35474
+ const hasPagination = stmt.limit !== null || stmt.offset !== null;
35475
+ const shouldInjectDefaultOrder = hasPagination && stmt.orderBy.length === 0;
35476
+ if (stmt.where !== null) {
35477
+ queryParts.push(whereToKintone(stmt.where));
35478
+ }
35479
+ if (stmt.orderBy.length > 0) {
35480
+ const orderStr = stmt.orderBy.map(convertOrderBy).join(", ");
35481
+ queryParts.push(`order by ${orderStr}`);
35482
+ } else if (shouldInjectDefaultOrder) {
35483
+ queryParts.push("order by $id asc");
35484
+ }
35485
+ if (stmt.limit !== null) {
35486
+ queryParts.push(`limit ${stmt.limit}`);
35487
+ }
35488
+ if (stmt.offset !== null) {
35489
+ queryParts.push(`offset ${stmt.offset}`);
35490
+ }
35491
+ return {
35492
+ app: stmt.from.appId,
35493
+ query: queryParts.join(" "),
35494
+ fields: extractFields(stmt.columns),
35495
+ totalCount: false
35496
+ };
35497
+ }
35498
+ function selectToFetchAllParams(stmt, appId) {
35499
+ const queryParts = [];
35500
+ if (stmt.where !== null && stmt.joins.length === 0 && !whereRequiresJsEval(stmt.where)) {
35501
+ queryParts.push(whereToKintone(stmt.where));
35502
+ }
35503
+ return {
35504
+ app: appId,
35505
+ query: queryParts.join(" "),
35506
+ fields: []
35507
+ // 全件取得なので全フィールドを取得する
35508
+ };
35509
+ }
35510
+ function selectToFetchAllFields(stmt, targetTable, plainGroupByPlan) {
35511
+ const plan = collectRequiredFieldsByTable(stmt, plainGroupByPlan);
35512
+ const target = plan.get(targetTable);
35513
+ if (!target) return [];
35514
+ if (target.allFields) return [];
35515
+ const fields = new Set(target.fields);
35516
+ if (target.table.subtableCode) {
35517
+ fields.add(target.table.subtableCode);
35518
+ }
35519
+ if (fields.size === 0) fields.add("$id");
35520
+ return [...fields];
35521
+ }
35522
+ function convertOrderBy(item) {
35523
+ const dir = item.direction === "ASC" ? "asc" : "desc";
35524
+ if (item.key.type !== "FIELD_NAME") {
35525
+ throw new Error("ORDER BY \u5F0F\u306F kintone \u30AF\u30A8\u30EA\u306B\u5909\u63DB\u3067\u304D\u307E\u305B\u3093\uFF08FULL_SCAN \u304C\u5FC5\u8981\u3067\u3059\uFF09");
35526
+ }
35527
+ return `${item.key.name} ${dir}`;
35528
+ }
35529
+ function extractFields(columns) {
35530
+ const hasWildcard = columns.some(
35531
+ (c) => c.type === "WILDCARD" || c.type === "AGGREGATE" || c.type === "ARITH_AGG_COL" || c.type === "CASE_COL" || c.type === "SCALAR_SUBQUERY_COL"
35532
+ );
35533
+ if (hasWildcard) return [];
35534
+ const fields = [];
35535
+ for (const col of columns) {
35536
+ if (col.type === "FIELD") {
35537
+ fields.push(normalizeSimpleFieldRef(col.field));
35538
+ } else if (col.type === "ARITH_COL") {
35539
+ collectArithNode(col.expr, fields);
35540
+ } else if (col.type === "STRFUNC_COL") {
35541
+ collectStringFuncFields(col.expr, fields);
35542
+ } else if (col.type === "SCALAR_VALUE_COL") {
35543
+ collectScalarValueFields(col.expr, fields);
35544
+ }
35545
+ }
35546
+ return [...new Set(fields)];
35547
+ }
35548
+ function collectArithFields(expr, out) {
35549
+ collectArithNode(expr.left, out);
35550
+ collectArithNode(expr.right, out);
35551
+ }
35552
+ function collectArithNode(node, out) {
35553
+ if (node.type === "VARIABLE") throw new Error(
35554
+ `InternalError: unresolved arithmetic variable @${node.name} reached SELECT field collection.`
35555
+ );
35556
+ if (node.type === "FIELD_REF") out.push(normalizeSimpleFieldRef(node.field));
35557
+ else if (node.type === "ARITH") collectArithFields(node, out);
35558
+ else if (node.type === "STRING_FUNC") collectStringFuncFields(node, out);
35559
+ }
35560
+ function normalizeSimpleFieldRef(field) {
35561
+ const dot = field.indexOf(".");
35562
+ if (dot <= 0) return field;
35563
+ const unqualified = field.slice(dot + 1);
35564
+ return unqualified || field;
35565
+ }
35566
+ function collectStringFuncFields(expr, out) {
35567
+ for (const arg of expr.args) {
35568
+ collectStringFuncArgFields(arg, out);
35569
+ }
35570
+ }
35571
+ function collectStringFuncArgFields(arg, out) {
35572
+ if (arg.type === "AGG_REF" || arg.type === "AGG_ARITH") {
35573
+ collectAggOperandFields(arg, out);
35574
+ return;
35575
+ }
35576
+ collectScalarValueFields(arg, out);
35577
+ }
35578
+ function collectScalarValueFields(expr, out) {
35579
+ if (expr.type === "FIELD") {
35580
+ out.push(normalizeSimpleFieldRef(expr.tableAlias ? `${expr.tableAlias}.${expr.field}` : expr.field));
35581
+ return;
35582
+ }
35583
+ if (expr.type === "STRING_FUNC") {
35584
+ collectStringFuncFields(expr, out);
35585
+ return;
35586
+ }
35587
+ if (expr.type === "SCALAR_ARITH" || expr.type === "CONCAT_OP") {
35588
+ collectScalarValueFields(expr.left, out);
35589
+ collectScalarValueFields(expr.right, out);
35590
+ return;
35591
+ }
35592
+ if (expr.type === "CASE_WHEN") {
35593
+ for (const branch of expr.branches) collectCaseResultScalarFields(branch.result, out);
35594
+ if (expr.elseResult) collectCaseResultScalarFields(expr.elseResult, out);
35595
+ }
35596
+ }
35597
+ function collectCaseResultScalarFields(result, out) {
35598
+ if (result.type === "ARRAY") return;
35599
+ if (result.type === "AGG_REF" || result.type === "AGG_ARITH") {
35600
+ collectAggOperandFields(result, out);
35601
+ return;
35602
+ }
35603
+ if (result.type === "FIELD_REF" || result.type === "ARITH") {
35604
+ collectArithNode(result, out);
35605
+ return;
35606
+ }
35607
+ collectScalarValueFields(result, out);
35608
+ }
35609
+ function collectAggOperandFields(node, out) {
35610
+ if (node.type === "AGG_REF") {
35611
+ if (node.arg.type !== "WILDCARD") collectAggregateArgFields(node.arg, out);
35612
+ return;
35613
+ }
35614
+ if (node.type === "AGG_ARITH") {
35615
+ collectAggOperandFields(node.left, out);
35616
+ collectAggOperandFields(node.right, out);
35617
+ }
35618
+ }
35619
+ function collectAggregateArgFields(node, out) {
35620
+ if (node.type === "FIELD_REF" || node.type === "ARITH") collectArithNode(node, out);
35621
+ else collectScalarValueFields(node, out);
35622
+ }
35623
+ function hasAggregateInStringFuncExpr(expr) {
35624
+ return expr.args.some((arg) => {
35625
+ if (arg.type === "AGG_REF" || arg.type === "AGG_ARITH") return true;
35325
35626
  return scalarValueHasAggregate(arg);
35326
35627
  });
35327
35628
  }
@@ -35336,6 +35637,7 @@ function scalarValueHasAggregate(expr) {
35336
35637
  return false;
35337
35638
  }
35338
35639
  function caseResultHasAggregate(result) {
35640
+ if (result.type === "AGG_REF" || result.type === "AGG_ARITH") return true;
35339
35641
  if (result.type === "ARRAY" || result.type === "FIELD_REF" || result.type === "ARITH") return false;
35340
35642
  return scalarValueHasAggregate(result);
35341
35643
  }
@@ -35544,6 +35846,10 @@ function collectRequiredFieldsByTable(stmt, plainGroupByPlan, sourceAware) {
35544
35846
  };
35545
35847
  const walkCaseResult = (result, phase = "select") => {
35546
35848
  if (result.type === "ARRAY") return;
35849
+ if (result.type === "AGG_REF" || result.type === "AGG_ARITH") {
35850
+ walkAgg(result, phase);
35851
+ return;
35852
+ }
35547
35853
  if (result.type === "FIELD_REF" || result.type === "ARITH") {
35548
35854
  walkArith(result, phase);
35549
35855
  return;
@@ -35559,6 +35865,10 @@ function collectRequiredFieldsByTable(stmt, plainGroupByPlan, sourceAware) {
35559
35865
  };
35560
35866
  const walkFieldValue = (fv, phase = "select") => {
35561
35867
  if (fv.type === "FIELD") {
35868
+ if (fv.aggregateRef) {
35869
+ walkAgg(fv.aggregateRef, phase);
35870
+ return;
35871
+ }
35562
35872
  addFieldRef(fv.field, fv.tableAlias, phase);
35563
35873
  return;
35564
35874
  }
@@ -35566,6 +35876,10 @@ function collectRequiredFieldsByTable(stmt, plainGroupByPlan, sourceAware) {
35566
35876
  walkStringFunc(fv.expr, phase);
35567
35877
  return;
35568
35878
  }
35879
+ if (fv.type === "AGG_FIELD") {
35880
+ walkAgg(fv.expr, phase);
35881
+ return;
35882
+ }
35569
35883
  if (fv.type === "ARITH_FIELD") {
35570
35884
  walkArith(fv.expr, phase);
35571
35885
  return;
@@ -36313,492 +36627,222 @@ function validateNestedSelects(node) {
36313
36627
  if (obj.type === "SELECT") validateSelect(obj);
36314
36628
  }, true);
36315
36629
  }
36316
- function containsKlike(node) {
36317
- let found = false;
36318
- walkObjects(node, (obj) => {
36319
- if (obj.type === "BINARY" && (obj.op === "KLIKE" || obj.op === "NOT_KLIKE")) found = true;
36320
- });
36321
- return found;
36322
- }
36323
- function containsKlikeOutsideWhereAndNestedSelects(node, allowedWhere) {
36324
- let found = false;
36325
- const visit = (value) => {
36326
- if (found || value === allowedWhere || value === null || typeof value !== "object") return;
36327
- if (Array.isArray(value)) {
36328
- for (const item of value) visit(item);
36329
- return;
36330
- }
36331
- const obj = value;
36332
- if (obj.type === "SELECT") return;
36333
- if (obj.type === "BINARY" && (obj.op === "KLIKE" || obj.op === "NOT_KLIKE")) {
36334
- found = true;
36335
- return;
36336
- }
36337
- for (const child of Object.values(obj)) visit(child);
36338
- };
36339
- visit(node);
36340
- return found;
36341
- }
36342
- function isDescendantOf(root, target) {
36343
- if (root === null) return false;
36344
- if (root === target) return true;
36345
- switch (root.type) {
36346
- case "LOGICAL":
36347
- return isDescendantOf(root.left, target) || isDescendantOf(root.right, target);
36348
- case "NOT":
36349
- case "GROUP":
36350
- return isDescendantOf(root.expr, target);
36351
- case "BINARY":
36352
- case "NULL_CHECK":
36353
- case "EXISTS":
36354
- return false;
36355
- case "BOOLEAN":
36356
- return false;
36357
- }
36358
- }
36359
- function walkWithoutNestedSelects(node, visitWhere) {
36360
- if (Array.isArray(node)) {
36361
- for (const value of node) walkWithoutNestedSelects(value, visitWhere);
36362
- return;
36363
- }
36364
- if (node === null || typeof node !== "object") return;
36365
- const obj = node;
36366
- if (obj.type === "BINARY" || obj.type === "NULL_CHECK" || obj.type === "LOGICAL" || obj.type === "NOT" || obj.type === "GROUP" || obj.type === "EXISTS") {
36367
- visitWhere(obj);
36368
- }
36369
- for (const value of Object.values(obj)) {
36370
- if (value !== node && isSelectObject(value)) continue;
36371
- walkWithoutNestedSelects(value, visitWhere);
36372
- }
36373
- }
36374
- function walkObjects(node, visit, skipRoot = false) {
36375
- if (Array.isArray(node)) {
36376
- for (const value of node) walkObjects(value, visit);
36377
- return;
36378
- }
36379
- if (node === null || typeof node !== "object") return;
36380
- const obj = node;
36381
- if (!skipRoot) visit(obj);
36382
- for (const value of Object.values(obj)) walkObjects(value, visit);
36383
- }
36384
- function isSelectObject(value) {
36385
- return value !== null && typeof value === "object" && value.type === "SELECT";
36386
- }
36387
-
36388
- // src/core/primaryOrganizationDmlValidation.ts
36389
- init_define_KSQL_DOCS();
36390
- var PrimaryOrganizationDmlValidationError = class extends Error {
36391
- constructor() {
36392
- super(
36393
- "ArgumentError: PRIMARY_ORGANIZATION() \u306F DML \u306E WHERE \u3067\u306F\u4F7F\u7528\u3067\u304D\u307E\u305B\u3093"
36394
- );
36395
- this.name = "ArgumentError";
36396
- }
36397
- };
36398
- function validatePrimaryOrganizationDmlStatement(stmt) {
36399
- const target = stmt.type === "EXPLAIN" ? stmt.query : stmt;
36400
- switch (target.type) {
36401
- case "UPDATE":
36402
- case "DELETE":
36403
- case "UPSERT":
36404
- case "UPSERT_SELECT":
36405
- case "INSERT_SELECT":
36406
- if (hasPrimaryOrganizationInWhere(target)) {
36407
- throw new PrimaryOrganizationDmlValidationError();
36408
- }
36409
- return;
36410
- default:
36411
- return;
36412
- }
36413
- }
36414
- function hasPrimaryOrganizationInWhere(node) {
36415
- let found = false;
36416
- walkObjects2(node, (obj) => {
36417
- if (found || !Object.prototype.hasOwnProperty.call(obj, "where")) return;
36418
- if (containsPrimaryOrganization(obj.where)) found = true;
36419
- });
36420
- return found;
36421
- }
36422
- function containsPrimaryOrganization(node) {
36423
- let found = false;
36424
- walkObjects2(node, (obj) => {
36425
- if (obj.type === "KINTONE_FUNC" && obj.name === "PRIMARY_ORGANIZATION") {
36426
- found = true;
36427
- }
36428
- });
36429
- return found;
36430
- }
36431
- function walkObjects2(node, visit) {
36432
- if (Array.isArray(node)) {
36433
- for (const value of node) walkObjects2(value, visit);
36434
- return;
36435
- }
36436
- if (node === null || typeof node !== "object") return;
36437
- const obj = node;
36438
- visit(obj);
36439
- for (const value of Object.values(obj)) walkObjects2(value, visit);
36440
- }
36441
-
36442
- // src/core/statementValidation.ts
36443
- init_define_KSQL_DOCS();
36444
-
36445
- // src/core/functionArity.ts
36446
- init_define_KSQL_DOCS();
36447
- function assertArity(func, args, min, max = Number.POSITIVE_INFINITY) {
36448
- if (args.length >= min && args.length <= max) return;
36449
- const expected = min === max ? String(min) : max === Number.POSITIVE_INFINITY ? `${min} or more` : `${min} to ${max}`;
36450
- throw new Error(`ArgumentError: ${func} expects ${expected} argument(s).`);
36451
- }
36452
- function assertStringFunctionArity(func, args) {
36453
- switch (func) {
36454
- case "UPPER":
36455
- case "LOWER":
36456
- case "TRIM":
36457
- case "LTRIM":
36458
- case "RTRIM":
36459
- case "LENGTH":
36460
- case "LENGTH_CHAR":
36461
- case "YEAR":
36462
- case "MONTH":
36463
- case "DAY":
36464
- case "DAYOFWEEK":
36465
- case "QUARTER":
36466
- case "WEEK":
36467
- case "LAST_DAY":
36468
- case "ABS":
36469
- case "SQRT":
36470
- return assertArity(func, args, 1, 1);
36471
- case "SUBSTRING":
36472
- case "LPAD":
36473
- case "RPAD":
36474
- case "REGEXP_LIKE":
36475
- case "REGEXP_SUBSTR":
36476
- return assertArity(func, args, 2, 3);
36477
- case "LEFT":
36478
- case "RIGHT":
36479
- case "INSTR":
36480
- case "ISNULL":
36481
- case "NULLIF":
36482
- case "MOD":
36483
- case "POWER":
36484
- case "FORMAT":
36485
- case "CAST":
36486
- case "DATE_FORMAT":
36487
- case "DATEDIFF":
36488
- return assertArity(func, args, 2, 2);
36489
- case "CONCAT":
36490
- case "COALESCE":
36491
- case "GREATEST":
36492
- case "LEAST":
36493
- return assertArity(func, args, 2);
36494
- case "REPLACE":
36495
- case "TRANSLATE":
36496
- case "DATE_ADD":
36497
- return assertArity(func, args, 3, 3);
36498
- case "REGEXP_REPLACE":
36499
- return assertArity(func, args, 3, 5);
36500
- case "ROUND":
36501
- case "FLOOR":
36502
- case "CEIL":
36503
- case "TRUNCATE":
36504
- return assertArity(func, args, 1, 2);
36505
- case "CURRENT_DATE":
36506
- case "CURRENT_TIMESTAMP":
36507
- return assertArity(func, args, 0, 0);
36508
- }
36509
- }
36510
-
36511
- // src/core/statementValidation.ts
36512
- function validateStatementStatic(stmt) {
36513
- validateStringFunctionArities(stmt);
36514
- validatePrimaryOrganizationDmlStatement(stmt);
36515
- validateKlikeStatement(stmt);
36630
+ function containsKlike(node) {
36631
+ let found = false;
36632
+ walkObjects(node, (obj) => {
36633
+ if (obj.type === "BINARY" && (obj.op === "KLIKE" || obj.op === "NOT_KLIKE")) found = true;
36634
+ });
36635
+ return found;
36516
36636
  }
36517
- function validateStringFunctionArities(stmt) {
36637
+ function containsKlikeOutsideWhereAndNestedSelects(node, allowedWhere) {
36638
+ let found = false;
36518
36639
  const visit = (value) => {
36519
- if (value === null || typeof value !== "object") return;
36640
+ if (found || value === allowedWhere || value === null || typeof value !== "object") return;
36520
36641
  if (Array.isArray(value)) {
36521
- value.forEach(visit);
36642
+ for (const item of value) visit(item);
36522
36643
  return;
36523
36644
  }
36524
- const node = value;
36525
- if (node.type === "STRING_FUNC") {
36526
- const expr = node;
36527
- assertStringFunctionArity(expr.func, expr.args);
36645
+ const obj = value;
36646
+ if (obj.type === "SELECT") return;
36647
+ if (obj.type === "BINARY" && (obj.op === "KLIKE" || obj.op === "NOT_KLIKE")) {
36648
+ found = true;
36649
+ return;
36528
36650
  }
36529
- Object.values(node).forEach(visit);
36651
+ for (const child of Object.values(obj)) visit(child);
36530
36652
  };
36531
- visit(stmt);
36532
- }
36533
-
36534
- // src/core/groupingValidation.ts
36535
- init_define_KSQL_DOCS();
36536
-
36537
- // src/engine/groupingRowMeta.ts
36538
- init_define_KSQL_DOCS();
36539
- var groupingRowMetaKey = /* @__PURE__ */ Symbol("ksql.groupingRowMeta");
36540
- var groupingRefCanonicalIds = /* @__PURE__ */ new WeakMap();
36541
- function attachGroupingRowMeta(row, includedCanonicalIds) {
36542
- Object.defineProperty(row, groupingRowMetaKey, {
36543
- value: { includedCanonicalIds },
36544
- enumerable: false,
36545
- configurable: false,
36546
- writable: false
36547
- });
36548
- return row;
36549
- }
36550
- function getGroupingRowMeta(row) {
36551
- return row[groupingRowMetaKey];
36552
- }
36553
- function readGroupingMembership(row) {
36554
- return getGroupingRowMeta(row)?.includedCanonicalIds;
36555
- }
36556
- function bindGroupingRefCanonicalId(ref, canonicalId) {
36557
- groupingRefCanonicalIds.set(ref, canonicalId);
36558
- }
36559
- function evalGroupingRef(ref, row) {
36560
- const membership = readGroupingMembership(row);
36561
- if (!membership) {
36562
- throw new Error("internal error: GROUPING() evaluation requires B65 grouping row membership.");
36563
- }
36564
- const canonicalId = groupingRefCanonicalIds.get(ref);
36565
- if (!canonicalId) {
36566
- throw new Error("internal error: GROUPING() reference was not resolved during B65 planning.");
36567
- }
36568
- return membership.has(canonicalId) ? "0" : "1";
36653
+ visit(node);
36654
+ return found;
36569
36655
  }
36570
-
36571
- // src/core/groupingValidation.ts
36572
- var enforceGroupingPlanningCandidateLimits = (facts) => {
36573
- if (facts.expandedSetCount > B65_MAX_GROUPING_SETS) {
36574
- throw new Error(
36575
- `ArgumentError: B65 expanded grouping set count ${facts.expandedSetCount} exceeds limit ${B65_MAX_GROUPING_SETS} (reason=GROUPING_SET_LIMIT_EXCEEDED).`
36576
- );
36577
- }
36578
- if (facts.canonicalItemCount > B65_MAX_GROUPING_ITEMS) {
36579
- throw new Error(
36580
- `ArgumentError: B65 canonical grouping item count ${facts.canonicalItemCount} exceeds limit ${B65_MAX_GROUPING_ITEMS} (reason=GROUPING_ITEM_LIMIT_EXCEEDED).`
36581
- );
36656
+ function isDescendantOf(root, target) {
36657
+ if (root === null) return false;
36658
+ if (root === target) return true;
36659
+ switch (root.type) {
36660
+ case "LOGICAL":
36661
+ return isDescendantOf(root.left, target) || isDescendantOf(root.right, target);
36662
+ case "NOT":
36663
+ case "GROUP":
36664
+ return isDescendantOf(root.expr, target);
36665
+ case "BINARY":
36666
+ case "NULL_CHECK":
36667
+ case "EXISTS":
36668
+ return false;
36669
+ case "BOOLEAN":
36670
+ return false;
36582
36671
  }
36583
- };
36584
- function displayField(field) {
36585
- return field.tableAlias ? `${field.tableAlias}.${field.field}` : field.field;
36586
- }
36587
- function refFromName(name) {
36588
- const dot = name.indexOf(".");
36589
- return dot > 0 ? { type: "FIELD", tableAlias: name.slice(0, dot), field: name.slice(dot + 1) } : { type: "FIELD", tableAlias: null, field: name };
36590
36672
  }
36591
- function collectGroupingRefs(node, out) {
36592
- if (node === null || typeof node !== "object") return;
36673
+ function walkWithoutNestedSelects(node, visitWhere) {
36593
36674
  if (Array.isArray(node)) {
36594
- node.forEach((item) => collectGroupingRefs(item, out));
36595
- return;
36596
- }
36597
- const value = node;
36598
- if (value["type"] === "SELECT" || value["type"] === "SCALAR_SUBQUERY") return;
36599
- if (value["type"] === "GROUPING_REF") {
36600
- out.push(value);
36675
+ for (const value of node) walkWithoutNestedSelects(value, visitWhere);
36601
36676
  return;
36602
36677
  }
36603
- Object.values(value).forEach((item) => collectGroupingRefs(item, out));
36604
- }
36605
- function collectAggregateArgumentGroupingRefs(node, out) {
36606
36678
  if (node === null || typeof node !== "object") return;
36607
- if (Array.isArray(node)) {
36608
- node.forEach((item) => collectAggregateArgumentGroupingRefs(item, out));
36609
- return;
36679
+ const obj = node;
36680
+ if (obj.type === "BINARY" || obj.type === "NULL_CHECK" || obj.type === "LOGICAL" || obj.type === "NOT" || obj.type === "GROUP" || obj.type === "EXISTS") {
36681
+ visitWhere(obj);
36610
36682
  }
36611
- const value = node;
36612
- if (value["type"] === "SELECT" || value["type"] === "SCALAR_SUBQUERY") return;
36613
- if (value["type"] === "AGGREGATE" || value["type"] === "AGG_REF") {
36614
- collectGroupingRefs(value["arg"], out);
36615
- return;
36683
+ for (const value of Object.values(obj)) {
36684
+ if (value !== node && isSelectObject(value)) continue;
36685
+ walkWithoutNestedSelects(value, visitWhere);
36616
36686
  }
36617
- Object.values(value).forEach((item) => collectAggregateArgumentGroupingRefs(item, out));
36618
36687
  }
36619
- function collectNonAggregateFieldRefs(node, out) {
36620
- if (node === null || typeof node !== "object") return;
36688
+ function walkObjects(node, visit, skipRoot = false) {
36621
36689
  if (Array.isArray(node)) {
36622
- node.forEach((item) => collectNonAggregateFieldRefs(item, out));
36623
- return;
36624
- }
36625
- const value = node;
36626
- const type = value["type"];
36627
- if (type === "SELECT" || type === "SCALAR_SUBQUERY" || type === "GROUPING_REF" || type === "AGG_REF" || type === "AGG_ARITH") return;
36628
- if (type === "FIELD" && typeof value["field"] === "string") {
36629
- out.push({
36630
- type: "FIELD",
36631
- tableAlias: typeof value["tableAlias"] === "string" ? value["tableAlias"] : null,
36632
- field: value["field"]
36633
- });
36634
- return;
36635
- }
36636
- if (type === "FIELD_REF" && typeof value["field"] === "string") {
36637
- out.push(refFromName(value["field"]));
36690
+ for (const value of node) walkObjects(value, visit);
36638
36691
  return;
36639
36692
  }
36640
- Object.values(value).forEach((item) => collectNonAggregateFieldRefs(item, out));
36641
- }
36642
- function containsAggregate2(node) {
36643
- if (node === null || typeof node !== "object") return false;
36644
- if (Array.isArray(node)) return node.some(containsAggregate2);
36645
- const value = node;
36646
- if (value["type"] === "AGG_REF" || value["type"] === "AGG_ARITH") return true;
36647
- if (value["type"] === "SELECT" || value["type"] === "SCALAR_SUBQUERY") return false;
36648
- return Object.values(value).some(containsAggregate2);
36649
- }
36650
- function isAggregateMaterializedAlias(column) {
36651
- if (!("alias" in column) || column.alias === null) return false;
36652
- if (column.type === "AGGREGATE" || column.type === "ARITH_AGG_COL") return true;
36653
- if (column.type === "STRFUNC_COL" || column.type === "SCALAR_VALUE_COL") {
36654
- return containsAggregate2(column);
36655
- }
36656
- return false;
36657
- }
36658
- function outputAliases(columns) {
36659
- return new Set(columns.flatMap(
36660
- (column) => "alias" in column && typeof column.alias === "string" ? [column.alias] : []
36661
- ));
36662
- }
36663
- function isAggregateSyntheticReference(ref) {
36664
- return ref.tableAlias === null && /^(COUNT|SUM|AVG|MAX|MIN|GROUP_CONCAT|STDDEV_POP|STDDEV_SAMP|VAR_POP|VAR_SAMP|MEDIAN|MODE)\(/.test(ref.field);
36665
- }
36666
- function validateGroupingRefMembership(ref, resolve3, canonicalItems) {
36667
- const resolved = resolve3(ref.field);
36668
- if (!resolved.physical) {
36669
- throw new Error(`ArgumentError: B65 grouping reference ${displayField(ref.field)} must resolve to a physical APP field.`);
36670
- }
36671
- if (!canonicalItems.has(resolved.canonicalId)) {
36672
- throw new Error(
36673
- `ArgumentError: B65 GROUPING argument ${displayField(ref.field)} is not present in grouping allItems (reason=B65_GROUPING_ARG_NOT_ITEM).`
36674
- );
36675
- }
36676
- bindGroupingRefCanonicalId(ref, resolved.canonicalId);
36677
- }
36678
- function validateDependency(ref, resolve3, canonicalItems, context) {
36679
- const resolved = resolve3(ref);
36680
- if (!resolved.physical || !canonicalItems.has(resolved.canonicalId)) {
36681
- throw new Error(
36682
- `ArgumentError: B65 non-aggregate field ${displayField(ref)} in ${context} is not a grouping item (reason=B65_NON_GROUPED_DEPENDENCY).`
36683
- );
36684
- }
36693
+ if (node === null || typeof node !== "object") return;
36694
+ const obj = node;
36695
+ if (!skipRoot) visit(obj);
36696
+ for (const value of Object.values(obj)) walkObjects(value, visit);
36685
36697
  }
36686
- function keyDependencies(key) {
36687
- if (key.type === "GROUPING_KEY") return [];
36688
- if (key.type === "FIELD_NAME") return [refFromName(key.name)];
36689
- const refs = [];
36690
- collectNonAggregateFieldRefs(key, refs);
36691
- return refs;
36698
+ function isSelectObject(value) {
36699
+ return value !== null && typeof value === "object" && value.type === "SELECT";
36692
36700
  }
36693
- function validateGroupingStatic(stmt) {
36694
- const normalized = normalizeGroupingSpec(stmt);
36695
- const groupingRefs = [];
36696
- for (const column of stmt.columns) {
36697
- if (column.type !== "WINDOW_COL") collectGroupingRefs(column, groupingRefs);
36698
- }
36699
- collectGroupingRefs(stmt.having, groupingRefs);
36700
- collectGroupingRefs(stmt.orderBy, groupingRefs);
36701
- const forbiddenGroupingRefs = [];
36702
- collectGroupingRefs(stmt.where, forbiddenGroupingRefs);
36703
- collectGroupingRefs(stmt.joins, forbiddenGroupingRefs);
36704
- collectAggregateArgumentGroupingRefs(stmt.columns, forbiddenGroupingRefs);
36705
- collectAggregateArgumentGroupingRefs(stmt.having, forbiddenGroupingRefs);
36706
- for (const column of stmt.columns) {
36707
- if (column.type === "WINDOW_COL") collectGroupingRefs(column, forbiddenGroupingRefs);
36708
- }
36709
- if (forbiddenGroupingRefs.length > 0) {
36710
- throw new Error(
36711
- "ArgumentError: B65 GROUPING() is not allowed in WHERE, JOIN, window, aggregate arguments, or DML expressions."
36701
+
36702
+ // src/core/primaryOrganizationDmlValidation.ts
36703
+ init_define_KSQL_DOCS();
36704
+ var PrimaryOrganizationDmlValidationError = class extends Error {
36705
+ constructor() {
36706
+ super(
36707
+ "ArgumentError: PRIMARY_ORGANIZATION() \u306F DML \u306E WHERE \u3067\u306F\u4F7F\u7528\u3067\u304D\u307E\u305B\u3093"
36712
36708
  );
36709
+ this.name = "ArgumentError";
36713
36710
  }
36714
- if (normalized.type !== "GROUPING_SETS") {
36715
- if (groupingRefs.length > 0) {
36716
- throw new Error("ArgumentError: B65 GROUPING() requires GROUP BY ROLLUP or GROUPING SETS.");
36717
- }
36718
- return;
36719
- }
36720
- if (stmt.orderMode === "KINTONE_NATIVE") {
36721
- throw new Error("ArgumentError: B65 KORDER BY is not supported in Phase1.");
36722
- }
36723
- if (stmt.columns.some((column) => column.type === "WINDOW_COL")) {
36724
- throw new Error("ArgumentError: B65 window functions are not supported in Phase1.");
36725
- }
36726
- if (stmt.columns.some(
36727
- (column) => column.type === "WILDCARD" || column.type === "PARENT_WILDCARD"
36728
- )) {
36729
- throw new Error("ArgumentError: B65 wildcard projection is not supported in Phase1.");
36711
+ };
36712
+ function validatePrimaryOrganizationDmlStatement(stmt) {
36713
+ const target = stmt.type === "EXPLAIN" ? stmt.query : stmt;
36714
+ switch (target.type) {
36715
+ case "UPDATE":
36716
+ case "DELETE":
36717
+ case "UPSERT":
36718
+ case "UPSERT_SELECT":
36719
+ case "INSERT_SELECT":
36720
+ if (hasPrimaryOrganizationInWhere(target)) {
36721
+ throw new PrimaryOrganizationDmlValidationError();
36722
+ }
36723
+ return;
36724
+ default:
36725
+ return;
36730
36726
  }
36731
36727
  }
36732
- function validateGroupingPlanning(stmt, resolve3, planningGuardHook = () => void 0) {
36733
- validateGroupingStatic(stmt);
36734
- const normalized = normalizeGroupingSpec(stmt);
36735
- const groupingRefs = [];
36736
- for (const column of stmt.columns) {
36737
- if (column.type !== "WINDOW_COL") collectGroupingRefs(column, groupingRefs);
36738
- }
36739
- collectGroupingRefs(stmt.having, groupingRefs);
36740
- collectGroupingRefs(stmt.orderBy, groupingRefs);
36741
- if (normalized.type !== "GROUPING_SETS") {
36742
- return null;
36743
- }
36744
- const resolvedSpec = resolveGroupingSpec(stmt, resolve3);
36745
- const canonicalItems = /* @__PURE__ */ new Set();
36746
- const resolvedItems = [];
36747
- for (const item of resolvedSpec.allItems) {
36748
- const resolved = item;
36749
- if (!resolved.physical) {
36750
- throw new Error(`ArgumentError: B65 grouping item ${displayField(item.field)} must resolve to a physical APP field.`);
36751
- }
36752
- if (!canonicalItems.has(resolved.canonicalId)) {
36753
- canonicalItems.add(resolved.canonicalId);
36754
- resolvedItems.push(resolved);
36728
+ function hasPrimaryOrganizationInWhere(node) {
36729
+ let found = false;
36730
+ walkObjects2(node, (obj) => {
36731
+ if (found || !Object.prototype.hasOwnProperty.call(obj, "where")) return;
36732
+ if (containsPrimaryOrganization(obj.where)) found = true;
36733
+ });
36734
+ return found;
36735
+ }
36736
+ function containsPrimaryOrganization(node) {
36737
+ let found = false;
36738
+ walkObjects2(node, (obj) => {
36739
+ if (obj.type === "KINTONE_FUNC" && obj.name === "PRIMARY_ORGANIZATION") {
36740
+ found = true;
36755
36741
  }
36756
- }
36757
- planningGuardHook({
36758
- expandedSetCount: normalized.sets.length,
36759
- canonicalItemCount: canonicalItems.size
36760
36742
  });
36761
- for (const ref of groupingRefs) {
36762
- validateGroupingRefMembership(ref, resolve3, canonicalItems);
36763
- }
36764
- const aliases = outputAliases(stmt.columns);
36765
- for (const column of stmt.columns) {
36766
- if (column.type === "GROUPING_COL" || column.type === "AGGREGATE" || column.type === "ARITH_AGG_COL" || column.type === "LITERAL_COL" || column.type === "VARIABLE_COL" || column.type === "SCALAR_SUBQUERY_COL") continue;
36767
- const refs = [];
36768
- if (column.type === "FIELD") refs.push(refFromName(column.field));
36769
- else collectNonAggregateFieldRefs(column, refs);
36770
- for (const ref of refs) validateDependency(ref, resolve3, canonicalItems, "SELECT");
36743
+ return found;
36744
+ }
36745
+ function walkObjects2(node, visit) {
36746
+ if (Array.isArray(node)) {
36747
+ for (const value of node) walkObjects2(value, visit);
36748
+ return;
36771
36749
  }
36772
- if (stmt.having) {
36773
- const refs = [];
36774
- collectNonAggregateFieldRefs(stmt.having, refs);
36775
- for (const ref of refs) {
36776
- if (ref.tableAlias === null && aliases.has(ref.field) || isAggregateSyntheticReference(ref)) continue;
36777
- validateDependency(ref, resolve3, canonicalItems, "HAVING");
36778
- }
36750
+ if (node === null || typeof node !== "object") return;
36751
+ const obj = node;
36752
+ visit(obj);
36753
+ for (const value of Object.values(obj)) walkObjects2(value, visit);
36754
+ }
36755
+
36756
+ // src/core/statementValidation.ts
36757
+ init_define_KSQL_DOCS();
36758
+
36759
+ // src/core/functionArity.ts
36760
+ init_define_KSQL_DOCS();
36761
+ function assertArity(func, args, min, max = Number.POSITIVE_INFINITY) {
36762
+ if (args.length >= min && args.length <= max) return;
36763
+ const expected = min === max ? String(min) : max === Number.POSITIVE_INFINITY ? `${min} or more` : `${min} to ${max}`;
36764
+ throw new Error(`ArgumentError: ${func} expects ${expected} argument(s).`);
36765
+ }
36766
+ function assertStringFunctionArity(func, args) {
36767
+ switch (func) {
36768
+ case "UPPER":
36769
+ case "LOWER":
36770
+ case "TRIM":
36771
+ case "LTRIM":
36772
+ case "RTRIM":
36773
+ case "LENGTH":
36774
+ case "LENGTH_CHAR":
36775
+ case "YEAR":
36776
+ case "MONTH":
36777
+ case "DAY":
36778
+ case "DAYOFWEEK":
36779
+ case "QUARTER":
36780
+ case "WEEK":
36781
+ case "LAST_DAY":
36782
+ case "ABS":
36783
+ case "SQRT":
36784
+ return assertArity(func, args, 1, 1);
36785
+ case "SUBSTRING":
36786
+ case "LPAD":
36787
+ case "RPAD":
36788
+ case "REGEXP_LIKE":
36789
+ case "REGEXP_SUBSTR":
36790
+ return assertArity(func, args, 2, 3);
36791
+ case "LEFT":
36792
+ case "RIGHT":
36793
+ case "INSTR":
36794
+ case "ISNULL":
36795
+ case "NULLIF":
36796
+ case "MOD":
36797
+ case "POWER":
36798
+ case "FORMAT":
36799
+ case "CAST":
36800
+ case "DATE_FORMAT":
36801
+ case "DATEDIFF":
36802
+ return assertArity(func, args, 2, 2);
36803
+ case "CONCAT":
36804
+ case "COALESCE":
36805
+ case "GREATEST":
36806
+ case "LEAST":
36807
+ return assertArity(func, args, 2);
36808
+ case "REPLACE":
36809
+ case "TRANSLATE":
36810
+ case "DATE_ADD":
36811
+ return assertArity(func, args, 3, 3);
36812
+ case "REGEXP_REPLACE":
36813
+ return assertArity(func, args, 3, 5);
36814
+ case "ROUND":
36815
+ case "FLOOR":
36816
+ case "CEIL":
36817
+ case "TRUNCATE":
36818
+ return assertArity(func, args, 1, 2);
36819
+ case "CURRENT_DATE":
36820
+ case "CURRENT_TIMESTAMP":
36821
+ return assertArity(func, args, 0, 0);
36779
36822
  }
36780
- for (const order of stmt.orderBy) {
36781
- for (const ref of keyDependencies(order.key)) {
36782
- if (ref.tableAlias === null && aliases.has(ref.field) || isAggregateSyntheticReference(ref)) continue;
36783
- validateDependency(ref, resolve3, canonicalItems, "ORDER BY");
36823
+ }
36824
+
36825
+ // src/core/statementValidation.ts
36826
+ function validateStatementStatic(stmt) {
36827
+ validateStringFunctionArities(stmt);
36828
+ validatePrimaryOrganizationDmlStatement(stmt);
36829
+ validateKlikeStatement(stmt);
36830
+ }
36831
+ function validateStringFunctionArities(stmt) {
36832
+ const visit = (value) => {
36833
+ if (value === null || typeof value !== "object") return;
36834
+ if (Array.isArray(value)) {
36835
+ value.forEach(visit);
36836
+ return;
36784
36837
  }
36785
- }
36786
- const collisionKeys = /* @__PURE__ */ new Set();
36787
- for (const item of resolvedItems) {
36788
- collisionKeys.add(item.directKey);
36789
- if (item.unqualifiedBridgeKey !== null) collisionKeys.add(item.unqualifiedBridgeKey);
36790
- }
36791
- for (const column of stmt.columns) {
36792
- if (!isAggregateMaterializedAlias(column)) continue;
36793
- const alias = "alias" in column ? column.alias : null;
36794
- if (alias === null) continue;
36795
- if (collisionKeys.has(alias)) {
36796
- throw new Error(
36797
- `ArgumentError: B65 aggregate alias ${alias} collides with a grouping runtime key (reason=B65_AGGREGATE_ALIAS_COLLISION).`
36798
- );
36838
+ const node = value;
36839
+ if (node.type === "STRING_FUNC") {
36840
+ const expr = node;
36841
+ assertStringFunctionArity(expr.func, expr.args);
36799
36842
  }
36800
- }
36801
- return resolvedSpec;
36843
+ Object.values(node).forEach(visit);
36844
+ };
36845
+ visit(stmt);
36802
36846
  }
36803
36847
 
36804
36848
  // src/core/batch.ts
@@ -37896,10 +37940,32 @@ function formatWithComma(num, digits) {
37896
37940
  return decStr ? `${intFmt}.${decStr}` : intFmt;
37897
37941
  }
37898
37942
  function evalStringFuncArg(arg, row, resolveFieldType, resolveFieldSemantics2) {
37899
- if (arg.type === "AGG_REF" || arg.type === "AGG_ARITH") return "";
37943
+ if (arg.type === "AGG_REF" || arg.type === "AGG_ARITH") {
37944
+ return String(evalMaterializedAggregateOperand(arg, row));
37945
+ }
37900
37946
  if (arg.type === "NUMBER") return numberLiteralText(arg);
37901
37947
  return String(evalScalarValueExpr(arg, row, resolveFieldType, resolveFieldSemantics2));
37902
37948
  }
37949
+ function evalMaterializedAggregateOperand(node, row) {
37950
+ if (node.type === "NUMBER") return node.value;
37951
+ if (node.type === "AGG_REF") {
37952
+ return row[aggregateSyntheticName(node.func, node.distinct, node.arg)] ?? "";
37953
+ }
37954
+ const left = Number(evalMaterializedAggregateOperand(node.left, row));
37955
+ const right = Number(evalMaterializedAggregateOperand(node.right, row));
37956
+ switch (node.op) {
37957
+ case "+":
37958
+ return left + right;
37959
+ case "-":
37960
+ return left - right;
37961
+ case "*":
37962
+ return left * right;
37963
+ case "/":
37964
+ return right !== 0 ? left / right : NaN;
37965
+ case "%":
37966
+ return right !== 0 ? left % right : NaN;
37967
+ }
37968
+ }
37903
37969
  function resolveFieldRef(row, field) {
37904
37970
  const direct = row[field];
37905
37971
  if (direct !== void 0) return direct;
@@ -37994,7 +38060,7 @@ function semanticsForLeft(left, fieldType, resolveSemantics) {
37994
38060
  if (left.type === "FIELD") {
37995
38061
  return resolveSemantics?.(left) ?? (fieldType ? resolveFieldSemantics({ fieldType }) : syntheticSemantics("string"));
37996
38062
  }
37997
- if (left.type === "ARITH_FIELD") return syntheticSemantics("number");
38063
+ if (left.type === "ARITH_FIELD" || left.type === "AGG_FIELD") return syntheticSemantics("number");
37998
38064
  if (left.type === "FUNC_FIELD") {
37999
38065
  return syntheticSemantics(NUMERIC_STRING_FUNCTIONS.has(left.expr.func) ? "number" : "string");
38000
38066
  }
@@ -38087,6 +38153,7 @@ function evalLogical(expr, row, resolveFieldType, appliedKlikes, resolveFieldSem
38087
38153
  }
38088
38154
  function resolveField(field, row, resolveFieldType, resolveFieldSemantics2) {
38089
38155
  if (field.type === "FUNC_FIELD") return evalStringFunc(field.expr, row);
38156
+ if (field.type === "AGG_FIELD") return String(evalMaterializedAggregateOperand(field.expr, row));
38090
38157
  if (field.type === "ARITH_FIELD") return String(evalArithExpr(field.expr, row));
38091
38158
  if (field.type === "CASE_FIELD") return evalCaseWhen(field.expr, row, resolveFieldType, resolveFieldSemantics2);
38092
38159
  if (field.type === "GROUPING_FIELD") return evalGroupingRef(field.ref, row);
@@ -38144,12 +38211,20 @@ function evalCaseWhenNullable(expr, row, resolveFieldType, resolveFieldSemantics
38144
38211
  }
38145
38212
  function evalCaseResultNullable(result, row, resolveFieldType, resolveFieldSemantics2) {
38146
38213
  if (result.type === "ARRAY") return result.elements.map((entry) => entry.value).join(",");
38214
+ if (result.type === "AGG_REF") {
38215
+ return row[aggregateSyntheticName(result.func, result.distinct, result.arg)] ?? "";
38216
+ }
38217
+ if (result.type === "AGG_ARITH") return row[aggregateOperandLabel(result)] ?? "";
38147
38218
  if (result.type === "FIELD_REF") return row[result.field] ?? "";
38148
38219
  if (result.type === "ARITH") return evalArithExpr(result, row);
38149
38220
  return evalScalarValueExprNullable(result, row, resolveFieldType, resolveFieldSemantics2);
38150
38221
  }
38151
38222
  function evalCaseResult(result, row, resolveFieldType, resolveFieldSemantics2) {
38152
38223
  if (result.type === "ARRAY") return result.elements.map((e) => e.value).join(",");
38224
+ if (result.type === "AGG_REF") {
38225
+ return row[aggregateSyntheticName(result.func, result.distinct, result.arg)] ?? "";
38226
+ }
38227
+ if (result.type === "AGG_ARITH") return row[aggregateOperandLabel(result)] ?? "";
38153
38228
  if (result.type === "FIELD_REF") {
38154
38229
  return row[result.field] ?? "";
38155
38230
  }
@@ -38415,6 +38490,10 @@ function collectAggregateArgFields2(node, out) {
38415
38490
  }
38416
38491
  function collectCaseResultFields(result, out) {
38417
38492
  if (result.type === "ARRAY") return;
38493
+ if (result.type === "AGG_REF" || result.type === "AGG_ARITH") {
38494
+ collectAggOperandFields2(result, out);
38495
+ return;
38496
+ }
38418
38497
  if (result.type === "FIELD_REF" || result.type === "ARITH") {
38419
38498
  collectArithNode2(result, out);
38420
38499
  return;
@@ -38636,6 +38715,9 @@ function evalCaseResultValue(result, row, fieldType) {
38636
38715
  if (result.type === "ARRAY") {
38637
38716
  return convertArray(result.elements.map((e) => e.value), fieldType);
38638
38717
  }
38718
+ if (result.type === "AGG_REF" || result.type === "AGG_ARITH") {
38719
+ throw new Error("InternalError: aggregate CASE result reached DML evaluation.");
38720
+ }
38639
38721
  if (result.type === "STRING") {
38640
38722
  return convertString2(result.value, fieldType);
38641
38723
  }
@@ -42871,7 +42953,7 @@ function applyFilter(rows, where, resolveFieldType, appliedKlikes, resolveFieldS
42871
42953
  }
42872
42954
  function hasAggregateColumns(columns) {
42873
42955
  return columns.some(
42874
- (c) => c.type === "AGGREGATE" || c.type === "ARITH_AGG_COL" || c.type === "STRFUNC_COL" && hasAggregateInStringFuncExpr2(c.expr) || c.type === "SCALAR_VALUE_COL" && scalarValueHasAggregate2(c.expr)
42956
+ (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)
42875
42957
  );
42876
42958
  }
42877
42959
  function applyGroupBy(rows, groupByKeys, columns, resolveAggSortKind, resolutionPlan, aliasEvaluationContext = {}) {
@@ -42976,26 +43058,72 @@ function groupingItemValue(item, row) {
42976
43058
  return row[item.directKey] ?? (item.unqualifiedBridgeKey === null ? void 0 : row[item.unqualifiedBridgeKey]) ?? "";
42977
43059
  }
42978
43060
  function materializeAggregateColumns(outRow, groupRows, columns, resolveAggSortKind) {
42979
- for (const col of columns) {
43061
+ for (const [columnIndex, col] of columns.entries()) {
42980
43062
  if (col.type === "AGGREGATE") {
42981
43063
  const syntheticKey = aggregateSyntheticName(col.func, col.distinct, col.arg);
42982
43064
  const value = String(evalAggregate(col.func, col.distinct, col.arg, col.separator, groupRows, resolveAggSortKind));
42983
43065
  outRow[col.alias ?? syntheticKey] = value;
42984
43066
  if (col.alias) outRow[syntheticKey] = value;
42985
43067
  } else if (col.type === "ARITH_AGG_COL") {
43068
+ materializeAggregateDependencies(outRow, groupRows, col.expr, resolveAggSortKind);
42986
43069
  const outputKey = col.alias ?? aggArithDefaultKey(col.expr);
42987
43070
  outRow[outputKey] = String(evalAggArithExpr(col.expr, groupRows, resolveAggSortKind));
42988
43071
  } else if (col.type === "STRFUNC_COL" && hasAggregateInStringFuncExpr2(col.expr)) {
43072
+ materializeAggregateDependencies(outRow, groupRows, col.expr, resolveAggSortKind);
42989
43073
  const outputKey = col.alias ?? stringFuncDefaultKey(col.expr);
42990
43074
  const resolvedExpr = resolveAggInStringFuncExpr(col.expr, groupRows, resolveAggSortKind);
42991
43075
  outRow[outputKey] = evalStringFunc(resolvedExpr, outRow);
42992
43076
  } else if (col.type === "SCALAR_VALUE_COL" && scalarValueHasAggregate2(col.expr)) {
43077
+ materializeAggregateDependencies(outRow, groupRows, col.expr, resolveAggSortKind);
42993
43078
  const outputKey = col.alias ?? scalarValueDefaultKey(col.expr);
42994
43079
  const resolvedExpr = resolveAggInScalarValue(col.expr, groupRows, resolveAggSortKind);
42995
43080
  outRow[outputKey] = String(evalScalarValueExpr(resolvedExpr, outRow));
43081
+ } else if (col.type === "CASE_COL" && containsAggregate2(col.expr)) {
43082
+ materializeAggregateDependencies(outRow, groupRows, col.expr, resolveAggSortKind);
43083
+ const resolvedExpr = resolveAggInCaseExpr(col.expr, groupRows, resolveAggSortKind);
43084
+ const resolveAggregateSemantics = (field) => field.aggregateRef ? aggregateResultSemantics(field.aggregateRef, resolveAggSortKind) : void 0;
43085
+ outRow[caseMaterializedKey(col.alias, columnIndex)] = evalCaseWhen(
43086
+ resolvedExpr,
43087
+ outRow,
43088
+ void 0,
43089
+ resolveAggregateSemantics
43090
+ );
42996
43091
  }
42997
43092
  }
42998
43093
  }
43094
+ function caseMaterializedKey(alias, columnIndex) {
43095
+ return alias ?? `__ksql_case_column_${columnIndex}`;
43096
+ }
43097
+ function collectAggregateRefs(node, out) {
43098
+ if (node === null || typeof node !== "object") return;
43099
+ if (Array.isArray(node)) {
43100
+ node.forEach((value2) => collectAggregateRefs(value2, out));
43101
+ return;
43102
+ }
43103
+ const value = node;
43104
+ if (value["type"] === "AGG_REF") {
43105
+ out.push(value);
43106
+ return;
43107
+ }
43108
+ if (value["type"] === "SELECT" || value["type"] === "SCALAR_SUBQUERY") return;
43109
+ Object.values(value).forEach((child) => collectAggregateRefs(child, out));
43110
+ }
43111
+ function materializeAggregateDependencies(outRow, rows, node, resolveAggSortKind) {
43112
+ const refs = [];
43113
+ collectAggregateRefs(node, refs);
43114
+ for (const ref of refs) {
43115
+ const key = aggregateSyntheticName(ref.func, ref.distinct, ref.arg);
43116
+ if (outRow[key] !== void 0) continue;
43117
+ outRow[key] = String(evalAggregate(
43118
+ ref.func,
43119
+ ref.distinct,
43120
+ ref.arg,
43121
+ ref.separator,
43122
+ rows,
43123
+ resolveAggSortKind
43124
+ ));
43125
+ }
43126
+ }
42999
43127
  function evalGroupByKey(key, row, resolution, columns, aliasEvaluationContext) {
43000
43128
  if (key.type === "FIELD_NAME") {
43001
43129
  if (!resolution) return row[key.name] ?? "";
@@ -43036,7 +43164,7 @@ function evalAggregate(func, distinct, arg, separator, rows, resolveAggSortKind)
43036
43164
  const raw = row[arg.field];
43037
43165
  if (raw === void 0 || raw === "" && func !== "MIN" && func !== "MAX") continue;
43038
43166
  strVal = raw;
43039
- } else if (arg.type === "ARITH" || arg.type === "NUMBER" || arg.type === "STRING_FUNC") {
43167
+ } else if (arg.type === "ARITH" || arg.type === "NUMBER") {
43040
43168
  const n = evalArithExpr(arg, row);
43041
43169
  if (isNaN(n)) continue;
43042
43170
  strVal = String(n);
@@ -43168,6 +43296,16 @@ function resolveAggregateArgSemantics(arg, resolver) {
43168
43296
  const first = results[0];
43169
43297
  return results.every((result) => JSON.stringify(result) === JSON.stringify(first)) ? first : kinds[0];
43170
43298
  }
43299
+ function aggregateResultSemantics(ref, resolver) {
43300
+ 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") {
43301
+ return syntheticSemantics("number");
43302
+ }
43303
+ if (ref.func === "GROUP_CONCAT" || ref.func === "MODE") {
43304
+ return syntheticSemantics("string");
43305
+ }
43306
+ const semantics = ref.arg.type === "WILDCARD" ? "string" : resolveAggregateArgSemantics(ref.arg, resolver) ?? "string";
43307
+ return typeof semantics === "string" ? syntheticSemantics(semantics) : semantics;
43308
+ }
43171
43309
  function applyHaving(rows, having, resolveFieldType, resolveFieldSemantics2) {
43172
43310
  if (having === null) return rows;
43173
43311
  return rows.filter((row) => evalWhere(having, row, resolveFieldType, void 0, resolveFieldSemantics2));
@@ -43327,7 +43465,7 @@ function buildOrderByAliasEvaluator(columns, scalarCache, resolveFieldType, reso
43327
43465
  break;
43328
43466
  }
43329
43467
  case "CASE_COL":
43330
- evaluators.set(alias, (row) => evalCaseWhen(column.expr, row, resolveFieldType, resolveFieldSemantics2));
43468
+ evaluators.set(alias, (row) => containsAggregate2(column.expr) ? row[alias] ?? "" : evalCaseWhen(column.expr, row, resolveFieldType, resolveFieldSemantics2));
43331
43469
  break;
43332
43470
  case "SCALAR_VALUE_COL": {
43333
43471
  const source = scalarValueDefaultKey(column.expr);
@@ -43416,7 +43554,7 @@ function evaluateSelectColumnValue(column, row, columnIndex, context = {}) {
43416
43554
  case "ARITH_COL":
43417
43555
  return String(evalArithExpr(column.expr, row));
43418
43556
  case "CASE_COL":
43419
- return evalCaseWhen(
43557
+ return containsAggregate2(column.expr) ? row[caseMaterializedKey(column.alias, columnIndex)] ?? "" : evalCaseWhen(
43420
43558
  column.expr,
43421
43559
  row,
43422
43560
  context.resolveFieldType,
@@ -43481,13 +43619,14 @@ function project(rows, columns, scalarCache, resolveFieldType, sourceColumns2, r
43481
43619
  return { rows: projected2, columns: cols };
43482
43620
  }
43483
43621
  const defaultFieldKeys = buildDefaultFieldOutputKeys(columns);
43622
+ const defaultCaseKeys = buildDefaultCaseOutputKeys(columns);
43484
43623
  const hasWildcard = columns.some(
43485
43624
  (col) => col.type === "WILDCARD" || col.type === "PARENT_WILDCARD"
43486
43625
  );
43487
- const outputKeys = hasWildcard ? null : computeOutputKeys(columns, defaultFieldKeys);
43626
+ const outputKeys = hasWildcard ? null : computeOutputKeys(columns, defaultFieldKeys, defaultCaseKeys);
43488
43627
  const orderedKeys = outputKeys ?? [];
43489
43628
  if (hasWildcard && rows.length === 0) {
43490
- return { rows: [], columns: computeExplicitOutputKeys(columns, defaultFieldKeys) };
43629
+ return { rows: [], columns: computeExplicitOutputKeys(columns, defaultFieldKeys, defaultCaseKeys) };
43491
43630
  }
43492
43631
  const projected = rows.map((row, rowIdx) => {
43493
43632
  const out = {};
@@ -43554,7 +43693,7 @@ function project(rows, columns, scalarCache, resolveFieldType, sourceColumns2, r
43554
43693
  break;
43555
43694
  }
43556
43695
  case "CASE_COL": {
43557
- const key = outputKeys?.[colIdx] ?? col.alias ?? "case";
43696
+ const key = outputKeys?.[colIdx] ?? col.alias ?? defaultCaseKeys.get(colIdx) ?? "case";
43558
43697
  out[key] = value;
43559
43698
  if (outputKeys === null && rowIdx === 0) orderedKeys.push(key);
43560
43699
  break;
@@ -43595,15 +43734,15 @@ function project(rows, columns, scalarCache, resolveFieldType, sourceColumns2, r
43595
43734
  });
43596
43735
  return { rows: projected, columns: orderedKeys };
43597
43736
  }
43598
- function computeOutputKeys(columns, defaultFieldKeys) {
43599
- return columns.map((col, colIdx) => computeOutputKey(col, colIdx, defaultFieldKeys));
43737
+ function computeOutputKeys(columns, defaultFieldKeys, defaultCaseKeys) {
43738
+ return columns.map((col, colIdx) => computeOutputKey(col, colIdx, defaultFieldKeys, defaultCaseKeys));
43600
43739
  }
43601
- function computeExplicitOutputKeys(columns, defaultFieldKeys) {
43740
+ function computeExplicitOutputKeys(columns, defaultFieldKeys, defaultCaseKeys) {
43602
43741
  const keys = [];
43603
43742
  const seen = /* @__PURE__ */ new Set();
43604
43743
  for (const [colIdx, col] of columns.entries()) {
43605
43744
  if (col.type === "WILDCARD" || col.type === "PARENT_WILDCARD") continue;
43606
- const key = computeOutputKey(col, colIdx, defaultFieldKeys);
43745
+ const key = computeOutputKey(col, colIdx, defaultFieldKeys, defaultCaseKeys);
43607
43746
  if (!seen.has(key)) {
43608
43747
  seen.add(key);
43609
43748
  keys.push(key);
@@ -43611,7 +43750,7 @@ function computeExplicitOutputKeys(columns, defaultFieldKeys) {
43611
43750
  }
43612
43751
  return keys;
43613
43752
  }
43614
- function computeOutputKey(col, colIdx, defaultFieldKeys) {
43753
+ function computeOutputKey(col, colIdx, defaultFieldKeys, defaultCaseKeys) {
43615
43754
  switch (col.type) {
43616
43755
  case "VARIABLE_COL":
43617
43756
  throw new Error(`internal error: unresolved SELECT variable @${col.name}`);
@@ -43626,7 +43765,7 @@ function computeOutputKey(col, colIdx, defaultFieldKeys) {
43626
43765
  case "ARITH_COL":
43627
43766
  return col.alias ?? arithColDefaultKey(col.expr);
43628
43767
  case "CASE_COL":
43629
- return col.alias ?? "case";
43768
+ return col.alias ?? defaultCaseKeys.get(colIdx) ?? "case";
43630
43769
  case "STRFUNC_COL":
43631
43770
  return col.alias ?? stringFuncDefaultKey(col.expr);
43632
43771
  case "SCALAR_VALUE_COL":
@@ -43642,6 +43781,24 @@ function computeOutputKey(col, colIdx, defaultFieldKeys) {
43642
43781
  throw new Error("internal: computeOutputKey received a wildcard column");
43643
43782
  }
43644
43783
  }
43784
+ function buildDefaultCaseOutputKeys(columns) {
43785
+ const used = new Set(columns.flatMap(
43786
+ (column) => "alias" in column && column.alias !== null ? [column.alias] : []
43787
+ ));
43788
+ const keys = /* @__PURE__ */ new Map();
43789
+ let suffix = 1;
43790
+ for (const [columnIndex, column] of columns.entries()) {
43791
+ if (column.type !== "CASE_COL" || column.alias !== null) continue;
43792
+ let key;
43793
+ do {
43794
+ key = suffix === 1 ? "case" : `case_${suffix}`;
43795
+ suffix++;
43796
+ } while (used.has(key));
43797
+ used.add(key);
43798
+ keys.set(columnIndex, key);
43799
+ }
43800
+ return keys;
43801
+ }
43645
43802
  function buildDefaultFieldOutputKeys(columns) {
43646
43803
  const qualifierCollisionCount = /* @__PURE__ */ new Map();
43647
43804
  for (const col of columns) {
@@ -43731,6 +43888,7 @@ function scalarValueHasAggregate2(expr) {
43731
43888
  return false;
43732
43889
  }
43733
43890
  function caseResultHasAggregate2(result) {
43891
+ if (result.type === "AGG_REF" || result.type === "AGG_ARITH") return true;
43734
43892
  if (result.type === "ARRAY" || result.type === "FIELD_REF" || result.type === "ARITH") return false;
43735
43893
  return scalarValueHasAggregate2(result);
43736
43894
  }
@@ -43753,6 +43911,7 @@ function resolveAggInStringFuncArg(arg, rows, resolveAggSortKind) {
43753
43911
  }
43754
43912
  function resolveAggInScalarValue(expr, rows, resolveAggSortKind) {
43755
43913
  if (expr.type === "STRING_FUNC") return resolveAggInStringFuncExpr(expr, rows, resolveAggSortKind);
43914
+ if (expr.type === "CASE_WHEN") return resolveAggInCaseExpr(expr, rows, resolveAggSortKind);
43756
43915
  if (expr.type === "SCALAR_ARITH" || expr.type === "CONCAT_OP") {
43757
43916
  return {
43758
43917
  ...expr,
@@ -43762,6 +43921,35 @@ function resolveAggInScalarValue(expr, rows, resolveAggSortKind) {
43762
43921
  }
43763
43922
  return expr;
43764
43923
  }
43924
+ function resolveAggInCaseResult(result, rows, resolveAggSortKind) {
43925
+ if (result.type === "AGG_REF") {
43926
+ const value = evalAggregate(
43927
+ result.func,
43928
+ result.distinct,
43929
+ result.arg,
43930
+ result.separator,
43931
+ rows,
43932
+ resolveAggSortKind
43933
+ );
43934
+ return typeof value === "number" ? { type: "NUMBER", value, raw: String(value) } : { type: "STRING", value };
43935
+ }
43936
+ if (result.type === "AGG_ARITH") {
43937
+ const value = evalAggArithExpr(result, rows, resolveAggSortKind);
43938
+ return { type: "NUMBER", value, raw: String(value) };
43939
+ }
43940
+ if (result.type === "ARRAY" || result.type === "FIELD_REF" || result.type === "ARITH") return result;
43941
+ return resolveAggInScalarValue(result, rows, resolveAggSortKind);
43942
+ }
43943
+ function resolveAggInCaseExpr(expr, rows, resolveAggSortKind) {
43944
+ return {
43945
+ ...expr,
43946
+ branches: expr.branches.map((branch) => ({
43947
+ ...branch,
43948
+ result: resolveAggInCaseResult(branch.result, rows, resolveAggSortKind)
43949
+ })),
43950
+ elseResult: expr.elseResult === null ? null : resolveAggInCaseResult(expr.elseResult, rows, resolveAggSortKind)
43951
+ };
43952
+ }
43765
43953
  function resolveAggInStringFuncExpr(expr, rows, resolveAggSortKind) {
43766
43954
  return {
43767
43955
  type: "STRING_FUNC",
@@ -43884,7 +44072,8 @@ function runFullScan(input) {
43884
44072
  }
43885
44073
  );
43886
44074
  }
43887
- rows = applyHaving(rows, stmt.having, havingFieldTypeResolver, havingFieldSemanticsResolver);
44075
+ const resolveHavingSemantics = (field) => field.aggregateRef ? aggregateResultSemantics(field.aggregateRef, aggregateSortKindResolver) : havingFieldSemanticsResolver?.(field);
44076
+ rows = applyHaving(rows, stmt.having, havingFieldTypeResolver, resolveHavingSemantics);
43888
44077
  rows = applyWindow(rows, stmt.columns, optionOrders, sortKinds, effectiveOrderSemantics);
43889
44078
  if (stmt.distinct) {
43890
44079
  rows = applyDistinct(
@@ -47451,7 +47640,7 @@ function scalarValueHasFieldRef(expr) {
47451
47640
  }
47452
47641
  if (expr.type === "CASE_WHEN") {
47453
47642
  const results = [...expr.branches.map((branch) => branch.result), ...expr.elseResult ? [expr.elseResult] : []];
47454
- return results.some((result) => result.type !== "ARRAY" && (result.type === "FIELD_REF" || result.type === "ARITH" ? arithHasFieldRef(result) : scalarValueHasFieldRef(result)));
47643
+ return results.some((result) => result.type !== "ARRAY" && (result.type === "FIELD_REF" || result.type === "ARITH" ? arithHasFieldRef(result) : result.type === "AGG_REF" || result.type === "AGG_ARITH" ? true : scalarValueHasFieldRef(result)));
47455
47644
  }
47456
47645
  return false;
47457
47646
  }
@@ -48003,7 +48192,8 @@ function collectAggregateArgFieldRefs(arg, out) {
48003
48192
  }
48004
48193
  if (arg.type === "CASE_WHEN") {
48005
48194
  for (const result of [...arg.branches.map((branch) => branch.result), ...arg.elseResult ? [arg.elseResult] : []]) {
48006
- if (result.type !== "ARRAY") collectAggregateArgFieldRefs(result, out);
48195
+ if (result.type === "AGG_REF" || result.type === "AGG_ARITH") collectAggregateOperandRefs(result, out);
48196
+ else if (result.type !== "ARRAY") collectAggregateArgFieldRefs(result, out);
48007
48197
  }
48008
48198
  }
48009
48199
  }
@@ -48040,10 +48230,29 @@ function collectScalarAggregateRefs(expr, out) {
48040
48230
  const results = [...expr.branches.map((branch) => branch.result), ...expr.elseResult ? [expr.elseResult] : []];
48041
48231
  for (const result of results) {
48042
48232
  if (result.type === "STRING_FUNC") collectStringFuncAggregateRefs(result, out);
48233
+ else if (result.type === "AGG_REF" || result.type === "AGG_ARITH") collectAggregateOperandRefs(result, out);
48043
48234
  else if (result.type !== "ARRAY" && result.type !== "FIELD_REF" && result.type !== "ARITH") collectScalarAggregateRefs(result, out);
48044
48235
  }
48045
48236
  }
48046
48237
  }
48238
+ function collectCaseAggregateRefs(expr, out) {
48239
+ const visit = (node) => {
48240
+ if (node === null || typeof node !== "object") return;
48241
+ if (Array.isArray(node)) {
48242
+ node.forEach(visit);
48243
+ return;
48244
+ }
48245
+ const value = node;
48246
+ if (value["type"] === "AGG_REF") {
48247
+ const aggregate = value;
48248
+ collectAggregateRef(aggregate.func, aggregate.arg, out);
48249
+ return;
48250
+ }
48251
+ if (value["type"] === "SELECT" || value["type"] === "SCALAR_SUBQUERY") return;
48252
+ Object.values(value).forEach(visit);
48253
+ };
48254
+ visit(expr);
48255
+ }
48047
48256
  function collectSelectAggregateSortRefs(columns) {
48048
48257
  const refs = [];
48049
48258
  for (const column of columns) {
@@ -48055,6 +48264,8 @@ function collectSelectAggregateSortRefs(columns) {
48055
48264
  collectStringFuncAggregateRefs(column.expr, refs);
48056
48265
  } else if (column.type === "SCALAR_VALUE_COL") {
48057
48266
  collectScalarAggregateRefs(column.expr, refs);
48267
+ } else if (column.type === "CASE_COL") {
48268
+ collectCaseAggregateRefs(column.expr, refs);
48058
48269
  }
48059
48270
  }
48060
48271
  return refs;
@@ -48232,6 +48443,13 @@ function stringFunctionColumnMeta(expr) {
48232
48443
  function caseResultColumnMeta(result, resolveField2) {
48233
48444
  if (result.type === "STRING") return syntheticColumnMeta("string");
48234
48445
  if (result.type === "ARRAY") return unsupportedColumnMeta();
48446
+ if (result.type === "AGG_REF") {
48447
+ if (result.func === "MIN" || result.func === "MAX" || result.func === "MODE") {
48448
+ return result.arg.type === "WILDCARD" ? unknownStringColumnMeta() : inferAggregateArgMeta(result.arg, resolveField2);
48449
+ }
48450
+ return result.func === "GROUP_CONCAT" ? syntheticColumnMeta("string") : syntheticColumnMeta("number");
48451
+ }
48452
+ if (result.type === "AGG_ARITH") return syntheticColumnMeta("number");
48235
48453
  if (result.type === "NUMBER" || result.type === "ARITH" || result.type === "SCALAR_ARITH") return syntheticColumnMeta("number");
48236
48454
  if (result.type === "STRING_FUNC") return stringFunctionColumnMeta(result);
48237
48455
  if (result.type === "FIELD_REF") return resolveField2(aggregateFieldRef(result.field)) ?? unknownStringColumnMeta();
@@ -57508,7 +57726,7 @@ Nested JSON/CSV subtable mutation is fail-closed on MCP: use VALIDATE ONLY/EXPLA
57508
57726
  JSON child IDs are rejected and replacement renumbers all rows.
57509
57727
  `);
57510
57728
  }
57511
- var SERVER_VERSION = true ? "3.43.0" : "0.0.0-dev";
57729
+ var SERVER_VERSION = true ? "3.44.0" : "0.0.0-dev";
57512
57730
  var FUNCTION_CATALOG_PARAGRAPH = `Complete function catalog \u2014 Scalar: ${KSQL_FUNCTION_CATALOG.scalar.join(" ")}. Aggregate: ${KSQL_FUNCTION_CATALOG.aggregate.join(" ")}. Variance and standard-deviation aggregates use explicit POP/SAMP names; unqualified STDDEV and VARIANCE are unsupported. Window: ${KSQL_FUNCTION_CATALOG.window.join(" ")} (OVER and AS alias required). Contextual: ${KSQL_FUNCTION_CATALOG.contextual.join(" ")} (kintone predicates; WHERE server-only/fail-closed; INNER JOIN direct-APP exact pushdown supported; local LOGINUSER is empty on all surfaces). Aliases: ${KSQL_FUNCTION_CATALOG.aliases.join(" ")}. Syntax: ${KSQL_FUNCTION_CATALOG.syntax.join(" ")}. This list is complete; functions from other dialects such as IFNULL do not exist. Use ksql_docs for arguments and constraints.`;
57513
57731
  var KSQL_MCP_INSTRUCTIONS = `kSQL MCP server version ${SERVER_VERSION}.
57514
57732