@rex0220/kintone-sql-tools 3.80.0 → 3.81.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
@@ -17726,6 +17726,10 @@ var Parser = class {
17726
17726
  this.scalarAllowsCase = true;
17727
17727
  this.pos = 0;
17728
17728
  this.insideAggregateArg = 0;
17729
+ /** 現在解析中の SELECT リストから切り出した非公開ウィンドウ列。 */
17730
+ this.hiddenWindows = null;
17731
+ this.insideWindowExpression = 0;
17732
+ this.insideWindowContainingSelectExpression = 0;
17729
17733
  /** GROUPING(field) is limited to the explicitly selected query context. */
17730
17734
  this.groupingFieldContext = "FORBIDDEN";
17731
17735
  /** True only while parsing an actual SQL WHERE clause (including nested groups). */
@@ -18612,7 +18616,16 @@ var Parser = class {
18612
18616
  parseSelect(allowKorder = false) {
18613
18617
  this.expect("SELECT" /* SELECT */);
18614
18618
  const distinct = this.consume("DISTINCT" /* DISTINCT */);
18615
- const columns = this.parseSelectColumns();
18619
+ const previousHiddenWindows = this.hiddenWindows;
18620
+ this.hiddenWindows = [];
18621
+ let columns;
18622
+ let hiddenWindows;
18623
+ try {
18624
+ columns = this.parseSelectColumns();
18625
+ hiddenWindows = this.hiddenWindows;
18626
+ } finally {
18627
+ this.hiddenWindows = previousHiddenWindows;
18628
+ }
18616
18629
  const hasFrom = this.consume("FROM" /* FROM */);
18617
18630
  const from = hasFrom ? this.parseTableRef() : { appId: 0, alias: null, cteName: NO_FROM_CTE_NAME };
18618
18631
  const joins = hasFrom ? this.parseJoins() : [];
@@ -18656,11 +18669,6 @@ var Parser = class {
18656
18669
  }
18657
18670
  const limit = this.consume("LIMIT" /* LIMIT */) ? this.parseUnsignedInt() : null;
18658
18671
  const offset = this.consume("OFFSET" /* OFFSET */) ? this.parseUnsignedInt() : null;
18659
- const hasWindow = columns.some((column) => column.type === "WINDOW_COL");
18660
- const hasAggregate = columns.some((column) => this.selectColumnHasAggregate(column));
18661
- if (hasWindow && (groupBy.length > 0 || grouping !== void 0 || hasAggregate)) {
18662
- throw new ParseError("\u30A6\u30A3\u30F3\u30C9\u30A6\u95A2\u6570\u306F GROUP BY / \u96C6\u8A08\u95A2\u6570\u3068\u540C\u3058 SELECT \u3067\u306F\u4F7F\u7528\u3067\u304D\u307E\u305B\u3093", this.peek());
18663
- }
18664
18672
  if (grouping && orderMode === "KINTONE_NATIVE") {
18665
18673
  throw new ParseError("B65: KORDER BY cannot be combined with grouping sets in Phase1.", this.peek());
18666
18674
  }
@@ -18669,6 +18677,7 @@ var Parser = class {
18669
18677
  type: "SELECT",
18670
18678
  distinct,
18671
18679
  columns,
18680
+ ...hiddenWindows.length > 0 ? { hiddenWindows } : {},
18672
18681
  from,
18673
18682
  joins,
18674
18683
  where,
@@ -18928,16 +18937,34 @@ var Parser = class {
18928
18937
  const parsedAlias2 = this.consume("AS" /* AS */) ? this.parseAliasName() : null;
18929
18938
  return this.withAliasDisplay({ type: "GROUPING_COL", ref, alias: parsedAlias2?.alias ?? null }, parsedAlias2);
18930
18939
  }
18940
+ if (this.startsWithWindowFunction() && this.leadingFunctionArgumentContainsOver()) {
18941
+ throw new ParseError(WINDOW_RESULT_IN_EXPRESSION_MESSAGE, this.peek());
18942
+ }
18943
+ if (this.hasNestedAggregateWindowInSelectColumn() && !this.startsWithStandaloneWindowColumn()) {
18944
+ this.insideWindowContainingSelectExpression++;
18945
+ let expr;
18946
+ try {
18947
+ expr = this.parseScalarValueExpr({ allowCase: true, allowAggregateArgs: true });
18948
+ } finally {
18949
+ this.insideWindowContainingSelectExpression--;
18950
+ }
18951
+ const parsedAlias2 = this.consume("AS" /* AS */) ? this.parseAliasName() : null;
18952
+ if (expr.type === "CASE_WHEN") {
18953
+ return this.withAliasDisplay({ type: "CASE_COL", expr, alias: parsedAlias2?.alias ?? null }, parsedAlias2);
18954
+ }
18955
+ if (expr.type === "STRING_FUNC") {
18956
+ return this.withAliasDisplay({ type: "STRFUNC_COL", expr, alias: parsedAlias2?.alias ?? null }, parsedAlias2);
18957
+ }
18958
+ return this.withAliasDisplay({
18959
+ type: "SCALAR_VALUE_COL",
18960
+ expr,
18961
+ alias: parsedAlias2?.alias ?? null
18962
+ }, parsedAlias2);
18963
+ }
18931
18964
  const valueWindowFunc = this.tryValueWindowFunc();
18932
18965
  if (valueWindowFunc !== null) {
18933
18966
  return this.parseValueWindowColumn(valueWindowFunc);
18934
18967
  }
18935
- if (this.tryAggregateFunc() === null && this.hasNestedAggregateWindowInSelectColumn()) {
18936
- throw new ParseError(
18937
- WINDOW_RESULT_IN_EXPRESSION_MESSAGE,
18938
- this.peek()
18939
- );
18940
- }
18941
18968
  if (this.isNonAggregateArithmeticStartWithAggregate()) {
18942
18969
  throw new ParseError(
18943
18970
  `\u96C6\u8A08\u7B97\u8853\u5F0F\u306F\u96C6\u8A08\u95A2\u6570\u304B\u3089\u59CB\u307E\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059\uFF08${this.peek().value}\uFF09\u3002`,
@@ -18993,10 +19020,13 @@ var Parser = class {
18993
19020
  }
18994
19021
  const aggFunc = this.tryAggregateFunc();
18995
19022
  if (aggFunc !== null) {
18996
- const ref = this.parseAggregateRef(aggFunc);
19023
+ const ref = this.parseAggregateRef(aggFunc, true);
18997
19024
  if (this.isSoftKeyword("OVER")) {
18998
19025
  return this.parseAggregateWindowColumn(ref);
18999
19026
  }
19027
+ if (ref.arg.type === "FIELD" && ref.arg.aggregateRef !== void 0) {
19028
+ 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());
19029
+ }
19000
19030
  if (this.isArithOp(this.peek().kind)) {
19001
19031
  const expr = this.continueAggArith(ref);
19002
19032
  const parsedAlias3 = this.consume("AS" /* AS */) ? this.parseAliasName() : null;
@@ -19081,13 +19111,137 @@ var Parser = class {
19081
19111
  }
19082
19112
  }
19083
19113
  }
19114
+ if (PARSER_WINDOW_FUNCTION_TOKEN_MAP[token.kind] !== void 0 && this.tokens[index + 1]?.kind === "(" /* LPAREN */) {
19115
+ let windowDepth = 0;
19116
+ for (let cursor = index + 1; cursor < this.tokens.length; cursor++) {
19117
+ const candidate = this.tokens[cursor];
19118
+ if (candidate.kind === "(" /* LPAREN */) windowDepth++;
19119
+ else if (candidate.kind === ")" /* RPAREN */ && --windowDepth === 0) {
19120
+ const next = this.tokens[cursor + 1];
19121
+ if (next?.kind === "IDENT" /* IDENT */ && next.value.toUpperCase() === "OVER") return true;
19122
+ break;
19123
+ }
19124
+ }
19125
+ }
19084
19126
  if (this.tryValueWindowFunc(index) !== null) return true;
19085
19127
  if (token.kind === "(" /* LPAREN */) depth++;
19086
19128
  else if (token.kind === ")" /* RPAREN */) depth--;
19087
19129
  }
19088
19130
  return false;
19089
19131
  }
19090
- parseWindowColumn(func) {
19132
+ /** 先頭の window が SELECT 列全体を占める従来の公開 WINDOW_COL か。 */
19133
+ startsWithStandaloneWindowColumn() {
19134
+ const valueWindow = this.tryValueWindowFunc();
19135
+ const rankingWindow = this.tryWindowFunc();
19136
+ const aggregateWindow = this.tryAggregateFunc();
19137
+ if (valueWindow === null && rankingWindow === null && aggregateWindow === null) return false;
19138
+ let depth = 0;
19139
+ let functionClose = -1;
19140
+ for (let index = this.pos + 1; index < this.tokens.length; index++) {
19141
+ const token = this.tokens[index];
19142
+ if (token.kind === "(" /* LPAREN */) depth++;
19143
+ else if (token.kind === ")" /* RPAREN */ && --depth === 0) {
19144
+ functionClose = index;
19145
+ break;
19146
+ }
19147
+ }
19148
+ const overIndex = functionClose + 1;
19149
+ if (functionClose < 0 || this.tokens[overIndex]?.kind !== "IDENT" /* IDENT */ || this.tokens[overIndex].value.toUpperCase() !== "OVER") return false;
19150
+ if (overIndex < 0 || this.tokens[overIndex + 1]?.kind !== "(" /* LPAREN */) return false;
19151
+ depth = 0;
19152
+ for (let index = overIndex + 1; index < this.tokens.length; index++) {
19153
+ const token = this.tokens[index];
19154
+ if (token.kind === "(" /* LPAREN */) depth++;
19155
+ else if (token.kind === ")" /* RPAREN */ && --depth === 0) {
19156
+ const next = this.tokens[index + 1]?.kind;
19157
+ return next === "AS" /* AS */ || next === "," /* COMMA */ || next === "FROM" /* FROM */ || next === ";" /* SEMICOLON */ || next === "EOF" /* EOF */;
19158
+ }
19159
+ }
19160
+ return false;
19161
+ }
19162
+ startsWithWindowFunction() {
19163
+ if (this.tryValueWindowFunc() !== null || this.tryWindowFunc() !== null) return true;
19164
+ if (this.tryAggregateFunc() === null) return false;
19165
+ let depth = 0;
19166
+ for (let index = this.pos + 1; index < this.tokens.length; index++) {
19167
+ const token = this.tokens[index];
19168
+ if (token.kind === "(" /* LPAREN */) depth++;
19169
+ else if (token.kind === ")" /* RPAREN */ && --depth === 0) {
19170
+ const next = this.tokens[index + 1];
19171
+ return next?.kind === "IDENT" /* IDENT */ && next.value.toUpperCase() === "OVER";
19172
+ }
19173
+ }
19174
+ return false;
19175
+ }
19176
+ leadingFunctionArgumentContainsOver() {
19177
+ let depth = 0;
19178
+ for (let index = this.pos + 1; index < this.tokens.length; index++) {
19179
+ const token = this.tokens[index];
19180
+ if (token.kind === "(" /* LPAREN */) depth++;
19181
+ else if (token.kind === ")" /* RPAREN */ && --depth === 0) return false;
19182
+ if (depth > 0 && token.kind === "IDENT" /* IDENT */ && token.value.toUpperCase() === "OVER") return true;
19183
+ }
19184
+ return false;
19185
+ }
19186
+ registerHiddenWindow(window) {
19187
+ if (this.hiddenWindows === null) {
19188
+ throw new ParseError(WINDOW_RESULT_IN_EXPRESSION_MESSAGE, this.peek());
19189
+ }
19190
+ const canonical = JSON.stringify({ ...window, alias: "" });
19191
+ const existing = this.hiddenWindows.find(
19192
+ (candidate) => JSON.stringify({ ...candidate, alias: "" }) === canonical
19193
+ );
19194
+ if (existing) return existing.alias;
19195
+ const alias = `__ksql_window_${this.hiddenWindows.length}`;
19196
+ this.hiddenWindows.push({ ...window, alias });
19197
+ return alias;
19198
+ }
19199
+ parseHiddenWindowReference() {
19200
+ if (this.hiddenWindows === null) return null;
19201
+ const valueFunc = this.tryValueWindowFunc();
19202
+ const rankingFunc = this.tryWindowFunc();
19203
+ const aggregateFunc = this.tryAggregateFunc();
19204
+ if (valueFunc === null && rankingFunc === null && aggregateFunc === null) return null;
19205
+ if (this.insideWindowExpression > 0) {
19206
+ throw new ParseError(WINDOW_RESULT_IN_EXPRESSION_MESSAGE, this.peek());
19207
+ }
19208
+ let argumentDepth = 0;
19209
+ for (let index = this.pos + 1; index < this.tokens.length; index++) {
19210
+ const token = this.tokens[index];
19211
+ if (token.kind === "(" /* LPAREN */) argumentDepth++;
19212
+ else if (token.kind === ")" /* RPAREN */ && --argumentDepth === 0) break;
19213
+ if (argumentDepth > 0 && token.kind === "IDENT" /* IDENT */ && token.value.toUpperCase() === "OVER") {
19214
+ throw new ParseError(WINDOW_RESULT_IN_EXPRESSION_MESSAGE, token);
19215
+ }
19216
+ }
19217
+ const startPos = this.pos;
19218
+ this.insideWindowExpression++;
19219
+ try {
19220
+ let window;
19221
+ if (valueFunc !== null) {
19222
+ window = this.parseValueWindowColumn(valueFunc, "");
19223
+ } else if (rankingFunc !== null) {
19224
+ window = this.parseWindowColumn(rankingFunc, "");
19225
+ } else {
19226
+ const ref = this.parseAggregateRef(aggregateFunc, true);
19227
+ if (!this.isSoftKeyword("OVER")) {
19228
+ this.pos = startPos;
19229
+ return null;
19230
+ }
19231
+ window = this.parseAggregateWindowColumn(ref, "");
19232
+ }
19233
+ const field = this.registerHiddenWindow(window);
19234
+ return { type: "FIELD", tableAlias: null, field, hiddenWindowRef: true };
19235
+ } finally {
19236
+ this.insideWindowExpression--;
19237
+ }
19238
+ }
19239
+ parseWindowPartitionKey() {
19240
+ if (this.isGroupingFunctionStart()) return this.parseGroupingRef();
19241
+ const ref = this.parseQualifiedIdent();
19242
+ return { type: "FIELD", tableAlias: ref.tableAlias, field: ref.field };
19243
+ }
19244
+ parseWindowColumn(func, hiddenAlias) {
19091
19245
  this.advance();
19092
19246
  this.expect("(" /* LPAREN */);
19093
19247
  if (this.peek().kind !== ")" /* RPAREN */) {
@@ -19101,22 +19255,33 @@ var Parser = class {
19101
19255
  this.advance();
19102
19256
  this.expect("BY" /* BY */, "PARTITION \u306E\u5F8C\u306B\u306F BY \u304C\u5FC5\u8981\u3067\u3059");
19103
19257
  do {
19104
- const ref = this.parseQualifiedIdent();
19105
- partitionBy.push({ type: "FIELD", tableAlias: ref.tableAlias, field: ref.field });
19258
+ partitionBy.push(this.parseWindowPartitionKey());
19106
19259
  } while (this.consume("," /* COMMA */));
19107
19260
  }
19108
- const orderBy = this.consume("ORDER" /* ORDER */) ? (this.expect("BY" /* BY */), this.parseOrderBy(false)) : [];
19261
+ const orderBy = this.consume("ORDER" /* ORDER */) ? (this.expect("BY" /* BY */), this.parseOrderBy()) : [];
19109
19262
  this.expect(")" /* RPAREN */);
19263
+ if (hiddenAlias !== void 0) {
19264
+ return { type: "WINDOW_COL", func, partitionBy, orderBy, alias: hiddenAlias };
19265
+ }
19110
19266
  if (!this.consume("AS" /* AS */)) {
19111
19267
  throw new ParseError("\u30A6\u30A3\u30F3\u30C9\u30A6\u95A2\u6570\u306B\u306F AS alias \u304C\u5FC5\u8981\u3067\u3059", this.peek());
19112
19268
  }
19113
19269
  const parsedAlias = this.parseAliasName();
19114
19270
  return this.withAliasDisplay({ type: "WINDOW_COL", func, partitionBy, orderBy, alias: parsedAlias.alias }, parsedAlias);
19115
19271
  }
19116
- parseValueWindowColumn(valueFunc) {
19272
+ parseValueWindowColumn(valueFunc, hiddenAlias) {
19117
19273
  this.advance();
19118
19274
  this.expect("(" /* LPAREN */);
19119
- const arg = this.parseScalarValueExpr({ allowCase: true, allowAggregateArgs: false });
19275
+ const aggregateFunc = this.tryAggregateFunc();
19276
+ const arg = aggregateFunc === null ? this.parseScalarValueExpr({ allowCase: true, allowAggregateArgs: false }) : (() => {
19277
+ const ref = this.parseAggregateRef(aggregateFunc);
19278
+ return {
19279
+ type: "FIELD",
19280
+ tableAlias: null,
19281
+ field: aggregateSyntheticName(ref.func, ref.distinct, ref.arg),
19282
+ aggregateRef: ref
19283
+ };
19284
+ })();
19120
19285
  let offset = 1;
19121
19286
  if (this.consume("," /* COMMA */)) {
19122
19287
  const token = this.expect("NUMBER" /* NUMBER */, `${valueFunc} \u306E offset \u306F\u975E\u8CA0\u306E\u6574\u6570\u30EA\u30C6\u30E9\u30EB\u3060\u3051\u3067\u3059`);
@@ -19133,19 +19298,30 @@ var Parser = class {
19133
19298
  this.advance();
19134
19299
  this.expect("BY" /* BY */, "PARTITION \u306E\u5F8C\u306B\u306F BY \u304C\u5FC5\u8981\u3067\u3059");
19135
19300
  do {
19136
- const field = this.parseQualifiedIdent();
19137
- partitionBy.push({ type: "FIELD", tableAlias: field.tableAlias, field: field.field });
19301
+ partitionBy.push(this.parseWindowPartitionKey());
19138
19302
  } while (this.consume("," /* COMMA */));
19139
19303
  }
19140
19304
  if (!this.consume("ORDER" /* ORDER */)) {
19141
19305
  throw new ParseError(`${valueFunc} \u306E OVER \u306B\u306F ORDER BY \u304C\u5FC5\u8981\u3067\u3059`, this.peek());
19142
19306
  }
19143
19307
  this.expect("BY" /* BY */);
19144
- const orderBy = this.parseOrderBy(false);
19308
+ const orderBy = this.parseOrderBy();
19145
19309
  this.expect(")" /* RPAREN */);
19146
- if (this.isArithOp(this.peek().kind) || this.peek().kind === "||" /* CONCAT_OP */) {
19310
+ if (hiddenAlias === void 0 && (this.isArithOp(this.peek().kind) || this.peek().kind === "||" /* CONCAT_OP */)) {
19147
19311
  throw new ParseError(WINDOW_RESULT_IN_EXPRESSION_MESSAGE, this.peek());
19148
19312
  }
19313
+ if (hiddenAlias !== void 0) {
19314
+ return {
19315
+ type: "WINDOW_COL",
19316
+ windowKind: "VALUE",
19317
+ valueFunc,
19318
+ arg,
19319
+ offset,
19320
+ partitionBy,
19321
+ orderBy,
19322
+ alias: hiddenAlias
19323
+ };
19324
+ }
19149
19325
  if (!this.consume("AS" /* AS */)) {
19150
19326
  throw new ParseError("\u30A6\u30A3\u30F3\u30C9\u30A6\u95A2\u6570\u306B\u306F AS alias \u304C\u5FC5\u8981\u3067\u3059", this.peek());
19151
19327
  }
@@ -19161,7 +19337,7 @@ var Parser = class {
19161
19337
  alias: parsedAlias.alias
19162
19338
  }, parsedAlias);
19163
19339
  }
19164
- parseAggregateWindowColumn(ref) {
19340
+ parseAggregateWindowColumn(ref, hiddenAlias) {
19165
19341
  const supported = /* @__PURE__ */ new Set(["SUM", "COUNT", "AVG", "MIN", "MAX"]);
19166
19342
  if (!supported.has(ref.func)) {
19167
19343
  throw new ParseError(
@@ -19179,11 +19355,10 @@ var Parser = class {
19179
19355
  this.advance();
19180
19356
  this.expect("BY" /* BY */, "PARTITION \u306E\u5F8C\u306B\u306F BY \u304C\u5FC5\u8981\u3067\u3059");
19181
19357
  do {
19182
- const field = this.parseQualifiedIdent();
19183
- partitionBy.push({ type: "FIELD", tableAlias: field.tableAlias, field: field.field });
19358
+ partitionBy.push(this.parseWindowPartitionKey());
19184
19359
  } while (this.consume("," /* COMMA */));
19185
19360
  }
19186
- const orderBy = this.consume("ORDER" /* ORDER */) ? (this.expect("BY" /* BY */), this.parseOrderBy(false)) : [];
19361
+ const orderBy = this.consume("ORDER" /* ORDER */) ? (this.expect("BY" /* BY */), this.parseOrderBy()) : [];
19187
19362
  let frame = orderBy.length > 0 ? { unit: "RANGE", source: "DEFAULT" } : null;
19188
19363
  if (this.isSoftKeyword("ROWS") || this.isSoftKeyword("RANGE")) {
19189
19364
  if (orderBy.length === 0) {
@@ -19200,12 +19375,24 @@ var Parser = class {
19200
19375
  frame = { unit, source: "EXPLICIT" };
19201
19376
  }
19202
19377
  this.expect(")" /* RPAREN */);
19203
- if (this.isArithOp(this.peek().kind)) {
19378
+ if (hiddenAlias === void 0 && this.isArithOp(this.peek().kind)) {
19204
19379
  throw new ParseError(
19205
19380
  WINDOW_RESULT_IN_EXPRESSION_MESSAGE,
19206
19381
  this.peek()
19207
19382
  );
19208
19383
  }
19384
+ if (hiddenAlias !== void 0) {
19385
+ return {
19386
+ type: "WINDOW_COL",
19387
+ windowKind: "AGGREGATE",
19388
+ aggFunc: ref.func,
19389
+ arg: ref.arg,
19390
+ frame,
19391
+ partitionBy,
19392
+ orderBy,
19393
+ alias: hiddenAlias
19394
+ };
19395
+ }
19209
19396
  if (!this.consume("AS" /* AS */)) {
19210
19397
  throw new ParseError("\u30A6\u30A3\u30F3\u30C9\u30A6\u95A2\u6570\u306B\u306F AS alias \u304C\u5FC5\u8981\u3067\u3059", this.peek());
19211
19398
  }
@@ -19431,6 +19618,8 @@ var Parser = class {
19431
19618
  }
19432
19619
  parseScalarPrimary(allowCase) {
19433
19620
  const tok = this.peek();
19621
+ const hiddenWindow = this.parseHiddenWindowReference();
19622
+ if (hiddenWindow) return hiddenWindow;
19434
19623
  if (tok.kind === "(" /* LPAREN */) {
19435
19624
  if (this.peekAt(1).kind === "SELECT" /* SELECT */) throw new ParseError("\u30B9\u30AB\u30E9\u30FC\u5024\u5F0F\u306B\u30B5\u30D6\u30AF\u30A8\u30EA\u306F\u4F7F\u7528\u3067\u304D\u307E\u305B\u3093", tok);
19436
19625
  this.advance();
@@ -19464,9 +19653,18 @@ var Parser = class {
19464
19653
  }
19465
19654
  if (tok.kind === "CASE" /* CASE */) {
19466
19655
  if (!allowCase) throw new ParseError("\u3053\u306E\u30B9\u30AB\u30E9\u30FC\u5024\u5F0F\u3067\u306F CASE \u3092\u4F7F\u7528\u3067\u304D\u307E\u305B\u3093", tok);
19467
- return this.parseCaseWhenExpr();
19656
+ return this.parseCaseWhenExpr(this.hiddenWindows !== null);
19468
19657
  }
19469
19658
  if (this.tryAggregateFunc() !== null) {
19659
+ if (this.scalarAllowsAggregateArgs && this.insideWindowContainingSelectExpression > 0) {
19660
+ const ref = this.parseAggregateRef(this.tryAggregateFunc(), true);
19661
+ return {
19662
+ type: "FIELD",
19663
+ tableAlias: null,
19664
+ field: aggregateSyntheticName(ref.func, ref.distinct, ref.arg),
19665
+ aggregateRef: ref
19666
+ };
19667
+ }
19470
19668
  throw new ParseError(
19471
19669
  this.insideAggregateArg > 0 ? "\u96C6\u8A08\u95A2\u6570\u306E\u5F15\u6570\u5185\u306B\u96C6\u8A08\u95A2\u6570\u306F\u4F7F\u7528\u3067\u304D\u307E\u305B\u3093" : "\u30B9\u30AB\u30E9\u30FC\u5024\u5F0F\u306B\u96C6\u7D04\u95A2\u6570\u306F\u4F7F\u7528\u3067\u304D\u307E\u305B\u3093",
19472
19670
  tok
@@ -19531,6 +19729,10 @@ var Parser = class {
19531
19729
  return left;
19532
19730
  }
19533
19731
  parseArithPrimary() {
19732
+ const hiddenWindow = this.parseHiddenWindowReference();
19733
+ if (hiddenWindow) {
19734
+ return { type: "FIELD_REF", field: hiddenWindow.field, hiddenWindowRef: true };
19735
+ }
19534
19736
  if (this.consume("(" /* LPAREN */)) {
19535
19737
  const expr = this.parseArithAddSub();
19536
19738
  this.expect(")" /* RPAREN */);
@@ -19628,6 +19830,7 @@ var Parser = class {
19628
19830
  /** THEN / ELSE の結果値。`||` を含む場合だけ新スカラー文法へ渡す。 */
19629
19831
  parseCaseResult(allowAggregateResult = false) {
19630
19832
  const tok = this.peek();
19833
+ if (this.hiddenWindows !== null && this.startsWithWindowFunction()) return this.parseArithAddSub();
19631
19834
  if (this.insideAggregateArg > 0 && this.tryAggregateFunc() !== null) {
19632
19835
  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);
19633
19836
  }
@@ -19759,6 +19962,9 @@ var Parser = class {
19759
19962
  }
19760
19963
  /** 文字列関数の引数: ScalarValueExpr / 集計算術式 */
19761
19964
  parseStringFuncArg() {
19965
+ if (this.insideWindowContainingSelectExpression > 0) {
19966
+ return this.parseScalarAddSubConcat(this.scalarAllowsCase);
19967
+ }
19762
19968
  if (this.scalarAllowsAggregateArgs) {
19763
19969
  const startPos = this.pos;
19764
19970
  try {
@@ -19782,7 +19988,7 @@ var Parser = class {
19782
19988
  return PARSER_AGGREGATE_FUNCTION_TOKEN_MAP[this.peek().kind] ?? null;
19783
19989
  }
19784
19990
  /** 集計関数参照を読む。SELECT 列の alias は呼び出し側で式全体の後に処理する。 */
19785
- parseAggregateRef(func) {
19991
+ parseAggregateRef(func, allowMaterializedAggregateArg = false) {
19786
19992
  this.advance();
19787
19993
  this.expect("(" /* LPAREN */);
19788
19994
  const distinct = this.consume("DISTINCT" /* DISTINCT */);
@@ -19791,7 +19997,15 @@ var Parser = class {
19791
19997
  throw new ParseError("MODE \u3067\u306F DISTINCT \u306F\u4F7F\u7528\u3067\u304D\u307E\u305B\u3093", distinctToken);
19792
19998
  }
19793
19999
  let arg;
19794
- if (this.consume("*" /* STAR */)) {
20000
+ if (allowMaterializedAggregateArg && this.tryAggregateFunc() !== null) {
20001
+ const nested = this.parseAggregateRef(this.tryAggregateFunc());
20002
+ arg = {
20003
+ type: "FIELD",
20004
+ tableAlias: null,
20005
+ field: aggregateSyntheticName(nested.func, nested.distinct, nested.arg),
20006
+ aggregateRef: nested
20007
+ };
20008
+ } else if (this.consume("*" /* STAR */)) {
19795
20009
  if (!aggregateAcceptsWildcard(func)) {
19796
20010
  throw new ParseError(`${func}(*) \u306F\u4F7F\u7528\u3067\u304D\u307E\u305B\u3093\u3002\u30D5\u30A3\u30FC\u30EB\u30C9\u307E\u305F\u306F\u5F0F\u3092\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044`, this.prev());
19797
20011
  }
@@ -20180,6 +20394,20 @@ var Parser = class {
20180
20394
  // - 集計関数(HAVING のみ): COUNT(*) / SUM(f) ...
20181
20395
  // - 通常フィールド参照: [alias.]field
20182
20396
  parseFieldValue() {
20397
+ const hiddenWindow = this.parseHiddenWindowReference();
20398
+ if (hiddenWindow) {
20399
+ if (this.isArithOp(this.peek().kind)) {
20400
+ return {
20401
+ type: "ARITH_FIELD",
20402
+ expr: this.continueArith({
20403
+ type: "FIELD_REF",
20404
+ field: hiddenWindow.field,
20405
+ hiddenWindowRef: true
20406
+ })
20407
+ };
20408
+ }
20409
+ return hiddenWindow;
20410
+ }
20183
20411
  if (this.groupingFieldContext === "HAVING" && this.isNonAggregateArithmeticStartWithAggregate()) {
20184
20412
  throw new ParseError(
20185
20413
  `\u96C6\u8A08\u7B97\u8853\u5F0F\u306F\u96C6\u8A08\u95A2\u6570\u304B\u3089\u59CB\u307E\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059\uFF08${this.peek().value}\uFF09\u3002`,
@@ -20683,7 +20911,14 @@ var Parser = class {
20683
20911
  const start = this.pos;
20684
20912
  const ref = this.parseAggregateRef(aggregateStart);
20685
20913
  if (this.isSoftKeyword("OVER")) {
20686
- throw new ParseError("\u30A6\u30A3\u30F3\u30C9\u30A6\u95A2\u6570\u306F SELECT \u5217\u306B\u306E\u307F\u8A18\u8FF0\u3067\u304D\u307E\u3059", this.peek());
20914
+ throw new ParseError(WINDOW_RESULT_IN_EXPRESSION_MESSAGE, this.peek());
20915
+ }
20916
+ if (!this.isArithOp(this.peek().kind)) {
20917
+ return {
20918
+ type: "FIELD_NAME",
20919
+ name: aggregateSyntheticName(ref.func, ref.distinct, ref.arg),
20920
+ aggregateRef: ref
20921
+ };
20687
20922
  }
20688
20923
  this.pos = start;
20689
20924
  void ref;
@@ -21460,7 +21695,7 @@ var Parser = class {
21460
21695
  }
21461
21696
  rejectAggregateWindowOutsideSelect() {
21462
21697
  if (this.isSoftKeyword("OVER")) {
21463
- throw new ParseError("\u30A6\u30A3\u30F3\u30C9\u30A6\u95A2\u6570\u306F SELECT \u5217\u306B\u306E\u307F\u8A18\u8FF0\u3067\u304D\u307E\u3059", this.peek());
21698
+ throw new ParseError(WINDOW_RESULT_IN_EXPRESSION_MESSAGE, this.peek());
21464
21699
  }
21465
21700
  }
21466
21701
  validateUpdateFromAssignments(assignments, sourceAlias, tok) {
@@ -21779,6 +22014,9 @@ var Parser = class {
21779
22014
  }
21780
22015
  const digitPrefixed = this.tryParseDigitPrefixedIdentifier();
21781
22016
  if (digitPrefixed !== null) return digitPrefixed;
22017
+ if (this.startsWithWindowFunction()) {
22018
+ throw new ParseError(WINDOW_RESULT_IN_EXPRESSION_MESSAGE, tok);
22019
+ }
21782
22020
  throw new ParseError(
21783
22021
  "\u30D5\u30A3\u30FC\u30EB\u30C9\u540D\u307E\u305F\u306F\u30C6\u30FC\u30D6\u30EB\u540D\u304C\u5FC5\u8981\u3067\u3059",
21784
22022
  tok
@@ -21995,7 +22233,7 @@ function selectCompleteInputReasons(stmt) {
21995
22233
  if (grouping.type === "PLAIN") reasons.add("GROUP_BY");
21996
22234
  if (stmt.distinct) reasons.add("DISTINCT");
21997
22235
  if (stmt.orderBy.length > 0) reasons.add("LOCAL_ORDER");
21998
- for (const column of stmt.columns) {
22236
+ for (const column of [...stmt.columns, ...stmt.hiddenWindows ?? []]) {
21999
22237
  if (column.type === "WINDOW_COL" && column.windowKind === "AGGREGATE") {
22000
22238
  reasons.add("AGGREGATE_WINDOW");
22001
22239
  } else if (column.type === "WINDOW_COL" && column.orderBy.length > 0) {
@@ -23215,6 +23453,7 @@ function walkDependency(node, context) {
23215
23453
  return;
23216
23454
  }
23217
23455
  const value = node;
23456
+ if (value["hiddenWindowRef"] === true) return;
23218
23457
  if (isQueryBoundary(value) || isAggregateBoundary(value) || isWindowBoundary(value)) return;
23219
23458
  if (value["type"] === "GROUPING_REF" || value["type"] === "GROUPING_FIELD" || value["type"] === "GROUPING_COL" || value["type"] === "GROUPING_KEY") return;
23220
23459
  if (value["type"] === "WILDCARD" || value["type"] === "PARENT_WILDCARD") {
@@ -23255,8 +23494,24 @@ function walkDependency(node, context) {
23255
23494
  }
23256
23495
  function validateAggregateDependencies(stmt, policy) {
23257
23496
  const aliases = aliasesByName(stmt.columns);
23258
- for (const column of stmt.columns) {
23259
- if (column.type === "WINDOW_COL") continue;
23497
+ for (const column of [...stmt.columns, ...stmt.hiddenWindows ?? []]) {
23498
+ if (column.type === "WINDOW_COL") {
23499
+ const windowExpressions = [
23500
+ ...column.partitionBy,
23501
+ ...column.orderBy.map((order) => order.key.type === "FIELD_NAME" ? order.key.aggregateRef ?? refFromName(order.key.name) : order.key),
23502
+ ...column.windowKind === "AGGREGATE" || column.windowKind === "VALUE" ? [column.arg] : []
23503
+ ];
23504
+ for (const expression of windowExpressions) {
23505
+ walkDependency(expression, {
23506
+ clause: "ORDER BY",
23507
+ expression,
23508
+ policy,
23509
+ aliases,
23510
+ resolvingAliases: /* @__PURE__ */ new Set()
23511
+ });
23512
+ }
23513
+ continue;
23514
+ }
23260
23515
  walkDependency(column, {
23261
23516
  clause: "SELECT",
23262
23517
  expression: column,
@@ -23440,7 +23695,7 @@ function validateGroupingStatic(stmt) {
23440
23695
  const normalized = normalizeGroupingSpec(stmt);
23441
23696
  const groupingRefs = [];
23442
23697
  for (const column of stmt.columns) {
23443
- if (column.type !== "WINDOW_COL") collectGroupingRefs(column, groupingRefs);
23698
+ collectGroupingRefs(column, groupingRefs);
23444
23699
  }
23445
23700
  collectGroupingRefs(stmt.having, groupingRefs);
23446
23701
  collectGroupingRefs(stmt.orderBy, groupingRefs);
@@ -23449,9 +23704,6 @@ function validateGroupingStatic(stmt) {
23449
23704
  collectGroupingRefs(stmt.joins, forbiddenGroupingRefs);
23450
23705
  collectAggregateArgumentGroupingRefs(stmt.columns, forbiddenGroupingRefs);
23451
23706
  collectAggregateArgumentGroupingRefs(stmt.having, forbiddenGroupingRefs);
23452
- for (const column of stmt.columns) {
23453
- if (column.type === "WINDOW_COL") collectGroupingRefs(column, forbiddenGroupingRefs);
23454
- }
23455
23707
  if (forbiddenGroupingRefs.length > 0) {
23456
23708
  throw new Error(
23457
23709
  "ArgumentError: GROUPING() is not allowed in WHERE, JOIN, window, aggregate arguments, or DML expressions."
@@ -23467,9 +23719,6 @@ function validateGroupingStatic(stmt) {
23467
23719
  if (stmt.orderMode === "KINTONE_NATIVE") {
23468
23720
  throw new Error("ArgumentError: KORDER BY is not supported with extended grouping.");
23469
23721
  }
23470
- if (stmt.columns.some((column) => column.type === "WINDOW_COL")) {
23471
- throw new Error("ArgumentError: window functions are not supported with extended grouping.");
23472
- }
23473
23722
  if (stmt.columns.some(
23474
23723
  (column) => column.type === "WILDCARD" || column.type === "PARENT_WILDCARD"
23475
23724
  )) {
@@ -23483,7 +23732,7 @@ function validateGroupingPlanning(stmt, resolve3, planningGuardHook = () => void
23483
23732
  const normalized = normalizeGroupingSpec(stmt);
23484
23733
  const groupingRefs = [];
23485
23734
  for (const column of stmt.columns) {
23486
- if (column.type !== "WINDOW_COL") collectGroupingRefs(column, groupingRefs);
23735
+ collectGroupingRefs(column, groupingRefs);
23487
23736
  }
23488
23737
  collectGroupingRefs(stmt.having, groupingRefs);
23489
23738
  collectGroupingRefs(stmt.orderBy, groupingRefs);
@@ -23544,7 +23793,7 @@ function resolveSelectMode(stmt) {
23544
23793
  if (stmt.joins.length > 0) return "FULL_SCAN";
23545
23794
  if (normalizeGroupingSpec(stmt).type !== "NONE") return "FULL_SCAN";
23546
23795
  if (stmt.distinct) return "FULL_SCAN";
23547
- if (hasWindowColumns(stmt.columns)) return "FULL_SCAN";
23796
+ if (hasWindowColumns(stmt.columns) || (stmt.hiddenWindows?.length ?? 0) > 0) return "FULL_SCAN";
23548
23797
  if (stmt.columns.some(
23549
23798
  (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)
23550
23799
  )) return "FULL_SCAN";
@@ -23784,6 +24033,7 @@ function collectRequiredFieldsByTable(stmt, plainGroupByPlan, sourceAware) {
23784
24033
  }
23785
24034
  }
23786
24035
  const selectAliases = collectSelectOutputNames(stmt.columns);
24036
+ const windowMaterializedAliases = collectAggregateMaterializedNames(stmt.columns);
23787
24037
  const markAll = (table) => {
23788
24038
  const st = states.get(table);
23789
24039
  if (!st) return;
@@ -23896,6 +24146,7 @@ function collectRequiredFieldsByTable(stmt, plainGroupByPlan, sourceAware) {
23896
24146
  );
23897
24147
  }
23898
24148
  if (node.type === "FIELD_REF") {
24149
+ if (node.hiddenWindowRef) return;
23899
24150
  addFieldName(node.field, phase);
23900
24151
  return;
23901
24152
  }
@@ -23934,6 +24185,11 @@ function collectRequiredFieldsByTable(stmt, plainGroupByPlan, sourceAware) {
23934
24185
  };
23935
24186
  const walkScalar = (expr, phase = "select") => {
23936
24187
  if (expr.type === "FIELD") {
24188
+ if (expr.hiddenWindowRef) return;
24189
+ if (expr.aggregateRef) {
24190
+ walkAgg(expr.aggregateRef, phase);
24191
+ return;
24192
+ }
23937
24193
  addFieldRef(expr.field, expr.tableAlias, phase);
23938
24194
  return;
23939
24195
  }
@@ -24046,6 +24302,10 @@ function collectRequiredFieldsByTable(stmt, plainGroupByPlan, sourceAware) {
24046
24302
  };
24047
24303
  const walkOrderByKey = (k, phase = "orderBy") => {
24048
24304
  if (k.type === "FIELD_NAME") {
24305
+ if (k.aggregateRef) {
24306
+ walkAgg(k.aggregateRef, phase);
24307
+ return;
24308
+ }
24049
24309
  addFieldName(k.name, phase);
24050
24310
  return;
24051
24311
  }
@@ -24058,7 +24318,7 @@ function collectRequiredFieldsByTable(stmt, plainGroupByPlan, sourceAware) {
24058
24318
  }
24059
24319
  walkStringFunc(k.expr, phase);
24060
24320
  };
24061
- for (const col of stmt.columns) {
24321
+ for (const col of [...stmt.columns, ...stmt.hiddenWindows ?? []]) {
24062
24322
  switch (col.type) {
24063
24323
  case "WILDCARD":
24064
24324
  markAllTargetTables();
@@ -24099,8 +24359,13 @@ function collectRequiredFieldsByTable(stmt, plainGroupByPlan, sourceAware) {
24099
24359
  if ((col.windowKind === "AGGREGATE" || col.windowKind === "VALUE") && col.arg.type !== "WILDCARD") {
24100
24360
  walkAggregateArg(col.arg, "select");
24101
24361
  }
24102
- for (const ref of col.partitionBy) addFieldRef(ref.field, ref.tableAlias, "select");
24103
- for (const item of col.orderBy) walkOrderByKey(item.key, "select");
24362
+ for (const ref of col.partitionBy) {
24363
+ if (ref.type === "FIELD") addFieldRef(ref.field, ref.tableAlias, "select");
24364
+ }
24365
+ for (const item of col.orderBy) {
24366
+ const isMaterializedAlias = item.key.type === "FIELD_NAME" && (item.key.aggregateRef !== void 0 || windowMaterializedAliases.has(item.key.name));
24367
+ walkOrderByKey(item.key, isMaterializedAlias ? "orderBy" : "select");
24368
+ }
24104
24369
  break;
24105
24370
  }
24106
24371
  }
@@ -24124,6 +24389,16 @@ function collectRequiredFieldsByTable(stmt, plainGroupByPlan, sourceAware) {
24124
24389
  for (const ob of stmt.orderBy) walkOrderByKey(ob.key);
24125
24390
  return states;
24126
24391
  }
24392
+ function collectAggregateMaterializedNames(columns) {
24393
+ const names = /* @__PURE__ */ new Set();
24394
+ for (const col of columns) {
24395
+ const materialized = col.type === "AGGREGATE" || col.type === "ARITH_AGG_COL" || col.type === "ARITH_COL" && containsAggregate2(col.expr) || col.type === "CASE_COL" && containsAggregate2(col.expr) || col.type === "STRFUNC_COL" && hasAggregateInStringFuncExpr(col.expr) || col.type === "SCALAR_VALUE_COL" && scalarValueHasAggregate(col.expr);
24396
+ if (!materialized) continue;
24397
+ if (col.alias) names.add(col.alias);
24398
+ if (col.type === "AGGREGATE") names.add(aggregateSyntheticName(col.func, col.distinct, col.arg));
24399
+ }
24400
+ return names;
24401
+ }
24127
24402
  function collectSelectOutputNames(columns) {
24128
24403
  const names = /* @__PURE__ */ new Set();
24129
24404
  for (const col of columns) {
@@ -30338,7 +30613,7 @@ function selectNeedsOwnMetadata(statement) {
30338
30613
  (join3) => join3.type !== "CROSS" && join3.table.appId > 0 && join3.table.cteName === null && (join3.on.left.field !== "$id" || join3.on.right.field !== "$id")
30339
30614
  ) || statement.columns.some(
30340
30615
  (column) => column.type === "WINDOW_COL" && column.orderBy.length > 0
30341
- );
30616
+ ) || (statement.hiddenWindows ?? []).some((column) => column.orderBy.length > 0);
30342
30617
  }
30343
30618
  function cteQueriesContainPhysicalSelect(ctes) {
30344
30619
  if (!Array.isArray(ctes)) return false;
@@ -31240,7 +31515,7 @@ function planCanonicalOrder(input) {
31240
31515
  const reasons = [];
31241
31516
  const windowOrderBy = stmt.columns.flatMap(
31242
31517
  (column) => column.type === "WINDOW_COL" ? column.orderBy : []
31243
- );
31518
+ ).concat((stmt.hiddenWindows ?? []).flatMap((column) => column.orderBy));
31244
31519
  const allOrderBy = [...stmt.orderBy, ...windowOrderBy];
31245
31520
  for (const item of allOrderBy) {
31246
31521
  if (item.key.type !== "FIELD_NAME") continue;
@@ -31564,7 +31839,7 @@ function materializedValuesFor(row) {
31564
31839
  }
31565
31840
  function setMaterializedSelectValue(row, columnIndex, value, lookupKeys = []) {
31566
31841
  const values = materializedValuesFor(row);
31567
- values.byColumn.set(columnIndex, value);
31842
+ if (columnIndex !== null) values.byColumn.set(columnIndex, value);
31568
31843
  for (const key of lookupKeys) values.byLookupKey.set(key, value);
31569
31844
  }
31570
31845
  function getMaterializedSelectValue(row, columnIndex) {
@@ -31745,10 +32020,10 @@ function applyFilter(rows, where, resolveFieldType, appliedKlikes, resolveFieldS
31745
32020
  }
31746
32021
  function hasAggregateColumns(columns) {
31747
32022
  return columns.some(
31748
- (c) => c.type === "AGGREGATE" || c.type === "ARITH_AGG_COL" || c.type === "ARITH_COL" && containsAggregate2(c.expr) || c.type === "CASE_COL" && containsAggregate2(c.expr) || c.type === "STRFUNC_COL" && hasAggregateInStringFuncExpr2(c.expr) || c.type === "SCALAR_VALUE_COL" && scalarValueHasAggregate2(c.expr)
32023
+ (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) || c.type === "WINDOW_COL" && ((c.windowKind === "AGGREGATE" || c.windowKind === "VALUE") && containsAggregate2(c.arg) || c.orderBy.some((item) => item.key.type === "FIELD_NAME" && item.key.aggregateRef !== void 0))
31749
32024
  );
31750
32025
  }
31751
- function applyGroupBy(rows, groupByKeys, columns, resolveAggSortKind, resolutionPlan, aliasEvaluationContext = {}, having = null) {
32026
+ function applyGroupBy(rows, groupByKeys, columns, resolveAggSortKind, resolutionPlan, aliasEvaluationContext = {}, having = null, hiddenWindows = []) {
31752
32027
  if (resolutionPlan && resolutionPlan.items.length !== groupByKeys.length) {
31753
32028
  throw new Error("InternalError: plain GROUP BY resolution plan length does not match group keys.");
31754
32029
  }
@@ -31804,11 +32079,25 @@ function applyGroupBy(rows, groupByKeys, columns, resolveAggSortKind, resolution
31804
32079
  resolveAggSortKind,
31805
32080
  aliasEvaluationContext.evaluationContext
31806
32081
  );
32082
+ materializeAggregateDependencies(
32083
+ outRow,
32084
+ groupRows,
32085
+ columns.filter((column) => column.type === "WINDOW_COL"),
32086
+ resolveAggSortKind,
32087
+ aliasEvaluationContext.evaluationContext
32088
+ );
32089
+ materializeAggregateDependencies(
32090
+ outRow,
32091
+ groupRows,
32092
+ hiddenWindows,
32093
+ resolveAggSortKind,
32094
+ aliasEvaluationContext.evaluationContext
32095
+ );
31807
32096
  result.push(outRow);
31808
32097
  }
31809
32098
  return result;
31810
32099
  }
31811
- function applyGroupingSets(rows, spec, columns, resolveAggSortKind, limits = {}, having = null) {
32100
+ function applyGroupingSets(rows, spec, columns, resolveAggSortKind, limits = {}, having = null, hiddenWindows = []) {
31812
32101
  const result = [];
31813
32102
  let generatedRows = 0;
31814
32103
  const countBucket = () => {
@@ -31875,6 +32164,20 @@ function applyGroupingSets(rows, spec, columns, resolveAggSortKind, limits = {},
31875
32164
  resolveAggSortKind,
31876
32165
  limits.evaluationContext
31877
32166
  );
32167
+ materializeAggregateDependencies(
32168
+ outRow,
32169
+ groupRows,
32170
+ hiddenWindows,
32171
+ resolveAggSortKind,
32172
+ limits.evaluationContext
32173
+ );
32174
+ materializeAggregateDependencies(
32175
+ outRow,
32176
+ groupRows,
32177
+ columns.filter((column) => column.type === "WINDOW_COL"),
32178
+ resolveAggSortKind,
32179
+ limits.evaluationContext
32180
+ );
31878
32181
  attachGroupingRowMeta(outRow, includedCanonicalIds);
31879
32182
  result.push(outRow);
31880
32183
  }
@@ -31887,6 +32190,10 @@ function groupingItemValue(item, row) {
31887
32190
  }
31888
32191
  function materializeAggregateColumns(outRow, groupRows, columns, resolveAggSortKind, evaluationContext = {}) {
31889
32192
  for (const [columnIndex, col] of columns.entries()) {
32193
+ if (containsHiddenWindowRef(col)) {
32194
+ materializeAggregateDependencies(outRow, groupRows, col, resolveAggSortKind, evaluationContext);
32195
+ continue;
32196
+ }
31890
32197
  if (col.type === "AGGREGATE") {
31891
32198
  const syntheticKey = aggregateSyntheticName(col.func, col.distinct, col.arg);
31892
32199
  const value = String(evalAggregate(
@@ -31963,6 +32270,14 @@ function materializeAggregateColumns(outRow, groupRows, columns, resolveAggSortK
31963
32270
  }
31964
32271
  }
31965
32272
  }
32273
+ function containsHiddenWindowRef(node) {
32274
+ if (node === null || typeof node !== "object") return false;
32275
+ if (Array.isArray(node)) return node.some(containsHiddenWindowRef);
32276
+ const value = node;
32277
+ if (value["hiddenWindowRef"] === true) return true;
32278
+ if (value["type"] === "SELECT" || value["type"] === "SCALAR_SUBQUERY") return false;
32279
+ return Object.values(value).some(containsHiddenWindowRef);
32280
+ }
31966
32281
  function caseMaterializedKey(alias, columnIndex) {
31967
32282
  return alias ?? `__ksql_case_column_${columnIndex}`;
31968
32283
  }
@@ -32179,7 +32494,7 @@ function aggArithDefaultKey(node) {
32179
32494
  }
32180
32495
  function resolveAggregateArgSemantics(arg, resolver) {
32181
32496
  if (arg.type === "FIELD_REF") return resolver?.(toAggregateFieldRef(arg.field)) ?? "string";
32182
- if (arg.type === "FIELD") return resolver?.(arg) ?? "string";
32497
+ if (arg.type === "FIELD") return arg.aggregateRef ? aggregateResultSemantics(arg.aggregateRef, resolver) : resolver?.(arg) ?? "string";
32183
32498
  if (arg.type === "NUMBER" || arg.type === "ARITH" || arg.type === "SCALAR_ARITH") return "number";
32184
32499
  if (arg.type === "STRING" || arg.type === "CONCAT_OP" || arg.type === "VARIABLE") return "string";
32185
32500
  if (arg.type === "STRING_FUNC") {
@@ -32405,14 +32720,15 @@ function buildOrderByAliasEvaluator(columns, scalarCache, resolveFieldType, reso
32405
32720
  return resolved === void 0 ? void 0 : evaluators.get(resolved)?.(row);
32406
32721
  };
32407
32722
  }
32408
- function applyWindow(rows, columns, optionOrders, sortKinds, fieldSemantics2, resolveAggSortKind, evaluationContext = {}) {
32723
+ function applyWindow(rows, columns, optionOrders, sortKinds, fieldSemantics2, resolveAggSortKind, evaluationContext = {}, hiddenWindows = []) {
32409
32724
  const windows = columns.map((column, columnIndex) => ({ column, columnIndex })).filter((item) => item.column.type === "WINDOW_COL");
32725
+ windows.push(...hiddenWindows.map((column) => ({ column, columnIndex: null })));
32410
32726
  if (rows.length === 0 || windows.length === 0) return rows;
32411
32727
  for (let index = 0; index < rows.length; index++) rows[index] = asProcessingRow(rows[index]);
32412
32728
  for (const { column: window, columnIndex } of windows) {
32413
32729
  const partitions = /* @__PURE__ */ new Map();
32414
32730
  for (const row of rows) {
32415
- const key = JSON.stringify(window.partitionBy.map((ref) => resolveWindowField(row, ref)));
32731
+ const key = JSON.stringify(window.partitionBy.map((ref) => resolveWindowPartitionKey(row, ref)));
32416
32732
  const partition = partitions.get(key);
32417
32733
  if (partition) partition.push(row);
32418
32734
  else partitions.set(key, [row]);
@@ -32462,7 +32778,7 @@ function applyWindow(rows, columns, optionOrders, sortKinds, fieldSemantics2, re
32462
32778
  function evaluateValueWindowArg(arg, row, evaluationContext = {}) {
32463
32779
  const value = evalScalarValueExprNullable(
32464
32780
  arg,
32465
- sourceRowForEvaluation(row),
32781
+ havingEvaluationRow(row),
32466
32782
  void 0,
32467
32783
  void 0,
32468
32784
  evaluationContext
@@ -32493,7 +32809,7 @@ function applyAggregateWindow(window, columnIndex, sortedResult, resolveAggSortK
32493
32809
  const values = window.arg.type === "WILDCARD" ? null : aggregateRowValues(
32494
32810
  window.aggFunc,
32495
32811
  window.arg,
32496
- sorted.map((item) => item.row),
32812
+ sorted.map((item) => havingEvaluationRow(item.row)),
32497
32813
  evaluationContext
32498
32814
  );
32499
32815
  const comparison = window.arg.type === "WILDCARD" ? void 0 : resolveAggregateArgSemantics(window.arg, resolveAggSortKind);
@@ -32546,9 +32862,10 @@ function applyAggregateWindow(window, columnIndex, sortedResult, resolveAggSortK
32546
32862
  setMaterializedSelectValue(sorted[index].row, columnIndex, output[index], [window.alias]);
32547
32863
  }
32548
32864
  }
32549
- function resolveWindowField(row, ref) {
32865
+ function resolveWindowPartitionKey(row, ref) {
32866
+ if (ref.type === "GROUPING_REF") return evalGroupingRef(ref, row);
32550
32867
  const name = ref.tableAlias ? `${ref.tableAlias}.${ref.field}` : ref.field;
32551
- return resolveFieldRef(sourceRowForEvaluation(row), name);
32868
+ return resolveFieldRef(havingEvaluationRow(row), name);
32552
32869
  }
32553
32870
  function applyLimit(rows, limit, offset) {
32554
32871
  const start = offset ?? 0;
@@ -32556,7 +32873,8 @@ function applyLimit(rows, limit, offset) {
32556
32873
  return rows.slice(start, start + limit);
32557
32874
  }
32558
32875
  function evaluateSelectColumnValue(column, row, columnIndex, context = {}) {
32559
- const sourceRow = sourceRowForEvaluation(row);
32876
+ const hasHiddenWindow = containsHiddenWindowRef(column);
32877
+ const sourceRow = hasHiddenWindow ? havingEvaluationRow(row) : sourceRowForEvaluation(row);
32560
32878
  switch (column.type) {
32561
32879
  case "VARIABLE_COL":
32562
32880
  throw new Error(`internal error: unresolved SELECT variable @${column.name}`);
@@ -32587,9 +32905,9 @@ function evaluateSelectColumnValue(column, row, columnIndex, context = {}) {
32587
32905
  return getMaterializedSelectValue(row, columnIndex) ?? getMaterializedLookupValue(row, source) ?? getLegacyMaterializedValue(row, source) ?? "0";
32588
32906
  }
32589
32907
  case "ARITH_COL":
32590
- return containsAggregate2(column.expr) ? getMaterializedSelectValue(row, columnIndex) ?? getMaterializedLookupValue(row, column.alias ?? arithColDefaultKey(column.expr)) ?? "" : String(evalArithExpr(column.expr, sourceRow, context.evaluationContext));
32908
+ return containsAggregate2(column.expr) && !hasHiddenWindow ? getMaterializedSelectValue(row, columnIndex) ?? getMaterializedLookupValue(row, column.alias ?? arithColDefaultKey(column.expr)) ?? "" : String(evalArithExpr(column.expr, sourceRow, context.evaluationContext));
32591
32909
  case "CASE_COL":
32592
- return containsAggregate2(column.expr) ? getMaterializedSelectValue(row, columnIndex) ?? getMaterializedLookupValue(row, caseMaterializedKey(column.alias, columnIndex)) ?? getLegacyMaterializedValue(row, caseMaterializedKey(column.alias, columnIndex)) ?? "" : evalCaseWhen(
32910
+ return containsAggregate2(column.expr) && !hasHiddenWindow ? getMaterializedSelectValue(row, columnIndex) ?? getMaterializedLookupValue(row, caseMaterializedKey(column.alias, columnIndex)) ?? getLegacyMaterializedValue(row, caseMaterializedKey(column.alias, columnIndex)) ?? "" : evalCaseWhen(
32593
32911
  column.expr,
32594
32912
  sourceRow,
32595
32913
  context.resolveFieldType,
@@ -32600,7 +32918,7 @@ function evaluateSelectColumnValue(column, row, columnIndex, context = {}) {
32600
32918
  return evalGroupingRef(column.ref, row);
32601
32919
  case "STRFUNC_COL": {
32602
32920
  const source = stringFuncDefaultKey(column.expr);
32603
- return hasAggregateInStringFuncExpr2(column.expr) ? getMaterializedSelectValue(row, columnIndex) ?? getMaterializedLookupValue(row, column.alias ?? source) ?? getMaterializedLookupValue(row, source) ?? getLegacyMaterializedValue(row, column.alias ?? source) ?? getLegacyMaterializedValue(row, source) ?? evalStringFunc(
32921
+ return hasAggregateInStringFuncExpr2(column.expr) && !hasHiddenWindow ? getMaterializedSelectValue(row, columnIndex) ?? getMaterializedLookupValue(row, column.alias ?? source) ?? getMaterializedLookupValue(row, source) ?? getLegacyMaterializedValue(row, column.alias ?? source) ?? getLegacyMaterializedValue(row, source) ?? evalStringFunc(
32604
32922
  column.expr,
32605
32923
  sourceRow,
32606
32924
  context.resolveFieldType,
@@ -32616,7 +32934,7 @@ function evaluateSelectColumnValue(column, row, columnIndex, context = {}) {
32616
32934
  }
32617
32935
  case "SCALAR_VALUE_COL": {
32618
32936
  const source = scalarValueDefaultKey(column.expr);
32619
- return scalarValueHasAggregate2(column.expr) ? getMaterializedSelectValue(row, columnIndex) ?? getMaterializedLookupValue(row, column.alias ?? source) ?? getMaterializedLookupValue(row, source) ?? getLegacyMaterializedValue(row, column.alias ?? source) ?? getLegacyMaterializedValue(row, source) ?? "" : String(evalScalarValueExpr(
32937
+ return scalarValueHasAggregate2(column.expr) && !hasHiddenWindow ? getMaterializedSelectValue(row, columnIndex) ?? getMaterializedLookupValue(row, column.alias ?? source) ?? getMaterializedLookupValue(row, source) ?? getLegacyMaterializedValue(row, column.alias ?? source) ?? getLegacyMaterializedValue(row, source) ?? "" : String(evalScalarValueExpr(
32620
32938
  column.expr,
32621
32939
  sourceRow,
32622
32940
  context.resolveFieldType,
@@ -33038,9 +33356,33 @@ function mergeKnownColumns(left, right, rows) {
33038
33356
  ...Object.keys(rows[0] ?? {})
33039
33357
  ])];
33040
33358
  }
33041
- function deriveOutputOrderSemantics(columns, resolveAggSortKind) {
33359
+ function deriveOutputOrderSemantics(columns, resolveAggSortKind, hiddenWindows = []) {
33042
33360
  const result = /* @__PURE__ */ new Map();
33361
+ const hiddenSemantics = new Map(hiddenWindows.map((window) => [
33362
+ window.alias,
33363
+ windowResultSemantics(window, resolveAggSortKind)
33364
+ ]));
33365
+ const resolveExpressionField = (field) => hiddenSemantics.get(field.field) ?? resolveAggSortKind?.(field);
33043
33366
  for (const column of columns) {
33367
+ if (column.type === "AGGREGATE") {
33368
+ result.set(
33369
+ aggregateSyntheticName(column.func, column.distinct, column.arg),
33370
+ aggregateResultSemantics({
33371
+ type: "AGG_REF",
33372
+ func: column.func,
33373
+ distinct: column.distinct,
33374
+ arg: column.arg,
33375
+ ...column.separator !== void 0 ? { separator: column.separator } : {}
33376
+ }, resolveAggSortKind)
33377
+ );
33378
+ }
33379
+ if (column.type === "WINDOW_COL") {
33380
+ for (const item of column.orderBy) {
33381
+ if (item.key.type === "FIELD_NAME" && item.key.aggregateRef) {
33382
+ result.set(item.key.name, aggregateResultSemantics(item.key.aggregateRef, resolveAggSortKind));
33383
+ }
33384
+ }
33385
+ }
33044
33386
  if (!("alias" in column) || !column.alias) continue;
33045
33387
  if (column.type === "ARITH_COL" || column.type === "ARITH_AGG_COL") {
33046
33388
  result.set(column.alias, syntheticSemantics("number"));
@@ -33057,17 +33399,29 @@ function deriveOutputOrderSemantics(columns, resolveAggSortKind) {
33057
33399
  } else if (column.func === "GROUP_CONCAT") {
33058
33400
  result.set(column.alias, syntheticSemantics("string"));
33059
33401
  }
33060
- } else if (column.type === "LITERAL_COL" || column.type === "CASE_COL" || column.type === "SCALAR_SUBQUERY_COL" || column.type === "SCALAR_VALUE_COL") {
33402
+ } else if (column.type === "LITERAL_COL" || column.type === "SCALAR_SUBQUERY_COL") {
33061
33403
  result.set(column.alias, syntheticSemantics("string"));
33404
+ } else if (column.type === "CASE_COL" || column.type === "SCALAR_VALUE_COL") {
33405
+ result.set(column.alias, syntheticSemantics(expressionSemanticKind(column.expr, resolveExpressionField)));
33062
33406
  } else if (column.type === "STRFUNC_COL") {
33063
33407
  result.set(column.alias, syntheticSemantics(stringFunctionSemanticKind(
33064
33408
  column.expr,
33065
- (field) => resolveAggSortKind?.(field)
33409
+ resolveExpressionField
33066
33410
  )));
33067
33411
  }
33068
33412
  }
33069
33413
  return result;
33070
33414
  }
33415
+ function windowResultSemantics(window, resolveAggSortKind) {
33416
+ if (isRankingWindow(window) || isAggregateWindow(window) && (window.aggFunc === "COUNT" || window.aggFunc === "SUM" || window.aggFunc === "AVG")) {
33417
+ return syntheticSemantics("number");
33418
+ }
33419
+ if ((isAggregateWindow(window) || isValueWindow(window)) && window.arg.type !== "WILDCARD") {
33420
+ const semantics = resolveAggregateArgSemantics(window.arg, resolveAggSortKind) ?? "string";
33421
+ return typeof semantics === "string" ? syntheticSemantics(semantics) : semantics;
33422
+ }
33423
+ return syntheticSemantics("string");
33424
+ }
33071
33425
  function runFullScan(input) {
33072
33426
  const {
33073
33427
  stmt,
@@ -33090,8 +33444,17 @@ function runFullScan(input) {
33090
33444
  warnings,
33091
33445
  evaluationContext
33092
33446
  } = input;
33093
- const effectiveOrderSemantics = deriveOutputOrderSemantics(stmt.columns, aggregateSortKindResolver);
33447
+ const effectiveOrderSemantics = deriveOutputOrderSemantics(
33448
+ stmt.columns,
33449
+ aggregateSortKindResolver,
33450
+ stmt.hiddenWindows
33451
+ );
33094
33452
  for (const [key, value] of orderSemantics ?? []) effectiveOrderSemantics.set(key, value);
33453
+ const hiddenWindowSemantics = new Map((stmt.hiddenWindows ?? []).map((window) => [
33454
+ window.alias,
33455
+ windowResultSemantics(window, aggregateSortKindResolver)
33456
+ ]));
33457
+ const expressionFieldSemanticsResolver = (field) => hiddenWindowSemantics.get(field.field) ?? fieldSemanticsResolver?.(field);
33095
33458
  let rows = [];
33096
33459
  const mainAlias = stmt.from.alias;
33097
33460
  const mainRecords = tables.get(mainAlias) ?? tables.get(null) ?? [];
@@ -33136,9 +33499,13 @@ function runFullScan(input) {
33136
33499
  stmt.columns,
33137
33500
  aggregateSortKindResolver,
33138
33501
  { maxGeneratedRows: B65_MAX_GENERATED_ROWS, evaluationContext },
33139
- stmt.having
33502
+ stmt.having,
33503
+ stmt.hiddenWindows
33140
33504
  );
33141
- } else if (grouping.type === "PLAIN" || hasAggregateColumns(stmt.columns)) {
33505
+ } else if (grouping.type === "PLAIN" || hasAggregateColumns([
33506
+ ...stmt.columns,
33507
+ ...stmt.hiddenWindows ?? []
33508
+ ])) {
33142
33509
  rows = applyGroupBy(
33143
33510
  rows,
33144
33511
  grouping.type === "PLAIN" ? grouping.allItems : [],
@@ -33151,7 +33518,8 @@ function runFullScan(input) {
33151
33518
  resolveFieldSemantics: fieldSemanticsResolver,
33152
33519
  evaluationContext
33153
33520
  },
33154
- stmt.having
33521
+ stmt.having,
33522
+ stmt.hiddenWindows
33155
33523
  );
33156
33524
  }
33157
33525
  warnOnUnresolvedAggregateComparisons(stmt.columns, rows, warnings);
@@ -33171,7 +33539,8 @@ function runFullScan(input) {
33171
33539
  sortKinds,
33172
33540
  effectiveOrderSemantics,
33173
33541
  aggregateSortKindResolver,
33174
- evaluationContext
33542
+ evaluationContext,
33543
+ stmt.hiddenWindows
33175
33544
  );
33176
33545
  if (stmt.distinct) {
33177
33546
  rows = applyDistinct(
@@ -33179,7 +33548,7 @@ function runFullScan(input) {
33179
33548
  stmt.columns,
33180
33549
  scalarCache,
33181
33550
  fieldTypeResolver,
33182
- fieldSemanticsResolver,
33551
+ expressionFieldSemanticsResolver,
33183
33552
  evaluationContext
33184
33553
  );
33185
33554
  }
@@ -33193,7 +33562,7 @@ function runFullScan(input) {
33193
33562
  stmt.columns,
33194
33563
  scalarCache,
33195
33564
  fieldTypeResolver,
33196
- fieldSemanticsResolver,
33565
+ expressionFieldSemanticsResolver,
33197
33566
  evaluationContext
33198
33567
  ),
33199
33568
  evaluationContext
@@ -33205,7 +33574,7 @@ function runFullScan(input) {
33205
33574
  scalarCache,
33206
33575
  fieldTypeResolver,
33207
33576
  sourceColumns2,
33208
- fieldSemanticsResolver,
33577
+ expressionFieldSemanticsResolver,
33209
33578
  hiddenQualifiedAliases,
33210
33579
  evaluationContext
33211
33580
  );
@@ -36820,15 +37189,46 @@ async function normalizeSelectChoiceEquality(stmt, client, cacheContext, materia
36820
37189
  }
36821
37190
  return { resolver, rewrites: normalization.rewrites };
36822
37191
  }
37192
+ function selectWindowColumns(stmt) {
37193
+ return [
37194
+ ...stmt.columns.filter((column) => column.type === "WINDOW_COL"),
37195
+ ...stmt.hiddenWindows ?? []
37196
+ ];
37197
+ }
36823
37198
  function hasDefaultRangeAggregateWindow(stmt) {
36824
- return stmt.columns.some(
36825
- (column) => column.type === "WINDOW_COL" && column.windowKind === "AGGREGATE" && column.orderBy.length > 0 && column.frame?.source === "DEFAULT"
37199
+ return selectWindowColumns(stmt).some(
37200
+ (column) => column.windowKind === "AGGREGATE" && column.orderBy.length > 0 && column.frame?.source === "DEFAULT"
36826
37201
  );
36827
37202
  }
36828
37203
  function hasWindowNeedingOrderProof(stmt) {
36829
- return hasDefaultRangeAggregateWindow(stmt) || stmt.columns.some((column) => column.type === "WINDOW_COL" && column.windowKind === "VALUE");
37204
+ return hasDefaultRangeAggregateWindow(stmt) || selectWindowColumns(stmt).some((column) => column.windowKind === "VALUE");
37205
+ }
37206
+ function sameSelectGroupOrderIsUnique(stmt, orderBy) {
37207
+ const grouping = normalizeGroupingSpec(stmt);
37208
+ if (grouping.type !== "PLAIN" || grouping.allItems.length === 0) return false;
37209
+ return grouping.allItems.every((groupKey) => {
37210
+ if (orderBy.some((item) => {
37211
+ if (groupKey.type === "FIELD_NAME" && item.key.type === "FIELD_NAME") {
37212
+ return item.key.name === groupKey.name;
37213
+ }
37214
+ return groupKey.type === item.key.type && JSON.stringify(groupKey) === JSON.stringify(item.key);
37215
+ })) return true;
37216
+ return stmt.columns.some((column) => {
37217
+ if (!("alias" in column) || column.alias === null) return false;
37218
+ if (!orderBy.some((item) => item.key.type === "FIELD_NAME" && item.key.name === column.alias)) return false;
37219
+ if (groupKey.type === "FIELD_NAME" && column.type === "FIELD") return column.field === groupKey.name;
37220
+ if (groupKey.type === "ARITH_KEY" && column.type === "ARITH_COL") {
37221
+ return JSON.stringify(groupKey.expr) === JSON.stringify(column.expr);
37222
+ }
37223
+ if (groupKey.type === "FUNC_KEY" && column.type === "STRFUNC_COL") {
37224
+ return JSON.stringify(groupKey.expr) === JSON.stringify(column.expr);
37225
+ }
37226
+ return false;
37227
+ });
37228
+ });
36830
37229
  }
36831
37230
  function canProveTotalWindowOrder(stmt, orderBy, resolveField2, context, generatedColumn) {
37231
+ if (sameSelectGroupOrderIsUnique(stmt, orderBy)) return true;
36832
37232
  if (generatedColumn !== void 0 && stmt.joins.length === 0 && stmt.from.cteName !== null) {
36833
37233
  return orderBy.some((item) => {
36834
37234
  if (item.key.type !== "FIELD_NAME") return false;
@@ -36951,9 +37351,7 @@ function formatWhereCapabilityFailure(result) {
36951
37351
  return details || "reason=WHERE_UNSUPPORTED";
36952
37352
  }
36953
37353
  function hasCanonicalOrder(stmt) {
36954
- return stmt.orderBy.length > 0 || stmt.columns.some(
36955
- (column) => column.type === "WINDOW_COL" && column.orderBy.length > 0
36956
- );
37354
+ return stmt.orderBy.length > 0 || selectWindowColumns(stmt).some((column) => column.orderBy.length > 0);
36957
37355
  }
36958
37356
  async function resolveDmlWhereCapability(stmt, client, cacheContext) {
36959
37357
  if (stmt.subtableCode || stmt.type === "UPDATE" && stmt.from != null) {
@@ -37411,7 +37809,7 @@ function arithHasFieldRef(node) {
37411
37809
  `InternalError: unresolved arithmetic variable @${node.name} reached SELECT planning.`
37412
37810
  );
37413
37811
  }
37414
- if (node.type === "FIELD_REF") return true;
37812
+ if (node.type === "FIELD_REF") return node.hiddenWindowRef !== true;
37415
37813
  if (node.type === "ARITH") return arithHasFieldRef(node.left) || arithHasFieldRef(node.right);
37416
37814
  if (node.type === "STRING_FUNC") return stringFuncHasFieldRef(node);
37417
37815
  return false;
@@ -37423,7 +37821,7 @@ function stringFuncArgHasFieldRef(arg) {
37423
37821
  return scalarValueHasFieldRef(arg);
37424
37822
  }
37425
37823
  function scalarValueHasFieldRef(expr) {
37426
- if (expr.type === "FIELD") return true;
37824
+ if (expr.type === "FIELD") return expr.hiddenWindowRef !== true;
37427
37825
  if (expr.type === "STRING_FUNC") return stringFuncHasFieldRef(expr);
37428
37826
  if (expr.type === "SCALAR_ARITH" || expr.type === "CONCAT_OP") {
37429
37827
  return scalarValueHasFieldRef(expr.left) || scalarValueHasFieldRef(expr.right);
@@ -37481,7 +37879,8 @@ function executeNoFromSelect(stmt, options) {
37481
37879
  void 0,
37482
37880
  void 0,
37483
37881
  void 0,
37484
- statementEvaluationContext(options)
37882
+ statementEvaluationContext(options),
37883
+ stmt.hiddenWindows
37485
37884
  );
37486
37885
  const { rows: projected, columns } = project(
37487
37886
  windowed,
@@ -37760,7 +38159,7 @@ function bindProjectedNamesForSelect(stmt, materializedTables, physicalMayHave)
37760
38159
  }
37761
38160
  for (const child of Object.values(value)) visit(child, allowSelectAlias);
37762
38161
  };
37763
- for (const column of stmt.columns) visit(column);
38162
+ for (const column of [...stmt.columns, ...stmt.hiddenWindows ?? []]) visit(column);
37764
38163
  visit(stmt.where);
37765
38164
  visit(stmt.having, true);
37766
38165
  visit(stmt.grouping);
@@ -37775,9 +38174,9 @@ function bindProjectedNamesForSelect(stmt, materializedTables, physicalMayHave)
37775
38174
  if (item.key.type === "FIELD_NAME") item.key.name = resolveText(item.key.name, true);
37776
38175
  else visit(item.key);
37777
38176
  }
37778
- for (const column of stmt.columns) {
37779
- if (column.type !== "WINDOW_COL") continue;
38177
+ for (const column of selectWindowColumns(stmt)) {
37780
38178
  for (const ref of column.partitionBy) {
38179
+ if (ref.type !== "FIELD") continue;
37781
38180
  ref.field = resolveReference(ref.field, ref.tableAlias, false);
37782
38181
  }
37783
38182
  for (const item of column.orderBy) {
@@ -38484,7 +38883,7 @@ function mergeExpressionColumnMeta(candidates) {
38484
38883
  }
38485
38884
  function inferAggregateArgMeta(arg, resolveField2) {
38486
38885
  if (arg.type === "FIELD_REF") return resolveField2(aggregateFieldRef(arg.field)) ?? unknownStringColumnMeta();
38487
- if (arg.type === "FIELD") return resolveField2(arg) ?? unknownStringColumnMeta();
38886
+ if (arg.type === "FIELD") return arg.aggregateRef ? aggregateResultColumnMeta(arg.aggregateRef, resolveField2) : resolveField2(arg) ?? unknownStringColumnMeta();
38488
38887
  if (arg.type === "NUMBER" || arg.type === "ARITH" || arg.type === "SCALAR_ARITH") return syntheticColumnMeta("number");
38489
38888
  if (arg.type === "STRING" || arg.type === "CONCAT_OP" || arg.type === "VARIABLE") return syntheticColumnMeta("string");
38490
38889
  if (arg.type === "STRING_FUNC") return stringFunctionColumnMeta(arg, resolveField2);
@@ -38492,6 +38891,15 @@ function inferAggregateArgMeta(arg, resolveField2) {
38492
38891
  if (arg.elseResult) results.push(caseResultColumnMeta(arg.elseResult, resolveField2));
38493
38892
  return mergeExpressionColumnMeta(results);
38494
38893
  }
38894
+ function aggregateResultColumnMeta(ref, resolveField2) {
38895
+ 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") {
38896
+ return syntheticColumnMeta("number");
38897
+ }
38898
+ if (ref.func === "GROUP_CONCAT" || ref.func === "MODE" || ref.arg.type === "WILDCARD") {
38899
+ return syntheticColumnMeta("string");
38900
+ }
38901
+ return inferAggregateArgMeta(ref.arg, resolveField2);
38902
+ }
38495
38903
  function inferWindowColumnMeta(column, resolveField2) {
38496
38904
  if (column.windowKind === "VALUE") {
38497
38905
  return inferAggregateArgMeta(column.arg, resolveField2);
@@ -38508,7 +38916,7 @@ function withDisplayName(meta, displayName) {
38508
38916
  return { ...meta ?? {}, displayName };
38509
38917
  }
38510
38918
  function selectNeedsSourceColumnMeta(stmt) {
38511
- return stmt.columns.some(
38919
+ return (stmt.hiddenWindows?.length ?? 0) > 0 || stmt.columns.some(
38512
38920
  (column) => column.type === "FIELD" || column.type === "WILDCARD" || column.type === "PARENT_WILDCARD" || column.type === "CASE_COL" || column.type === "AGGREGATE" && (column.func === "MIN" || column.func === "MAX" || column.func === "MODE") || column.type === "WINDOW_COL" && (column.windowKind === "VALUE" || column.windowKind === "AGGREGATE" && (column.aggFunc === "MIN" || column.aggFunc === "MAX"))
38513
38921
  );
38514
38922
  }
@@ -38566,6 +38974,11 @@ async function inferSelectColumnMeta(stmt, outputColumns, client, cacheContext,
38566
38974
  return meta && publicSourceApp !== void 0 ? { ...meta, publicSourceApp } : meta;
38567
38975
  };
38568
38976
  const inferred = /* @__PURE__ */ new Map();
38977
+ const hiddenWindowMeta = new Map((stmt.hiddenWindows ?? []).map((window) => [
38978
+ window.alias,
38979
+ inferWindowColumnMeta(window, resolveField2)
38980
+ ]));
38981
+ const resolveExpressionField = (ref) => ref.hiddenWindowRef ? hiddenWindowMeta.get(ref.field) : resolveField2(ref);
38569
38982
  const hasWildcard = stmt.columns.some((column) => column.type === "WILDCARD" || column.type === "PARENT_WILDCARD");
38570
38983
  if (stmt.columns.length === 1 && (stmt.columns[0].type === "WILDCARD" || stmt.columns[0].type === "PARENT_WILDCARD")) {
38571
38984
  for (const output of outputColumns) {
@@ -38608,17 +39021,17 @@ async function inferSelectColumnMeta(stmt, outputColumns, client, cacheContext,
38608
39021
  meta = syntheticColumnMeta("string");
38609
39022
  } else if (column.type === "SCALAR_VALUE_COL") {
38610
39023
  const expr = column.expr;
38611
- if (expr.type === "STRING_FUNC") meta = stringFunctionColumnMeta(expr, resolveField2);
39024
+ if (expr.type === "STRING_FUNC") meta = stringFunctionColumnMeta(expr, resolveExpressionField);
38612
39025
  else if (expr.type === "NUMBER" || expr.type === "SCALAR_ARITH") meta = syntheticColumnMeta("number");
38613
- else if (expr.type === "FIELD") meta = resolveField2(expr);
39026
+ else if (expr.type === "FIELD") meta = resolveExpressionField(expr);
38614
39027
  else meta = syntheticColumnMeta("string");
38615
39028
  } else if (column.type === "STRFUNC_COL") {
38616
- meta = stringFunctionColumnMeta(column.expr, resolveField2);
39029
+ meta = stringFunctionColumnMeta(column.expr, resolveExpressionField);
38617
39030
  } else if (column.type === "WINDOW_COL") {
38618
39031
  meta = inferWindowColumnMeta(column, resolveField2);
38619
39032
  } else if (column.type === "CASE_COL") {
38620
- const results = column.expr.branches.map((branch) => caseResultColumnMeta(branch.result, resolveField2));
38621
- if (column.expr.elseResult) results.push(caseResultColumnMeta(column.expr.elseResult, resolveField2));
39033
+ const results = column.expr.branches.map((branch) => caseResultColumnMeta(branch.result, resolveExpressionField));
39034
+ if (column.expr.elseResult) results.push(caseResultColumnMeta(column.expr.elseResult, resolveExpressionField));
38622
39035
  meta = mergeExpressionColumnMeta(results);
38623
39036
  } else if (column.type === "SCALAR_SUBQUERY_COL") {
38624
39037
  meta = unknownStringColumnMeta();
@@ -40277,7 +40690,7 @@ async function getSortKindMapByApp(appId, client, cacheContext) {
40277
40690
  function orderByFieldNames(stmt) {
40278
40691
  const items = [
40279
40692
  ...stmt.orderBy,
40280
- ...stmt.columns.flatMap((column) => column.type === "WINDOW_COL" ? column.orderBy : [])
40693
+ ...selectWindowColumns(stmt).flatMap((column) => column.orderBy)
40281
40694
  ];
40282
40695
  return [...new Set(items.flatMap(
40283
40696
  (item) => item.key.type === "FIELD_NAME" ? [item.key.name] : []
@@ -40327,6 +40740,11 @@ async function buildOrderSemanticsForSelect(stmt, client, cacheContext, material
40327
40740
  return matches.length === 1 ? matches[0] : void 0;
40328
40741
  };
40329
40742
  const aliasSemantics = /* @__PURE__ */ new Map();
40743
+ const hiddenWindowMeta = new Map((stmt.hiddenWindows ?? []).map((window) => [
40744
+ window.alias,
40745
+ inferWindowColumnMeta(window, resolveField2)
40746
+ ]));
40747
+ const resolveExpressionField = (ref) => ref.hiddenWindowRef ? hiddenWindowMeta.get(ref.field) : resolveField2(ref);
40330
40748
  for (const column of stmt.columns) {
40331
40749
  if (!("alias" in column) || !column.alias) continue;
40332
40750
  let meta;
@@ -40337,12 +40755,18 @@ async function buildOrderSemanticsForSelect(stmt, client, cacheContext, material
40337
40755
  meta = inferWindowColumnMeta(column, resolveField2);
40338
40756
  } else if (column.type === "GROUPING_COL") {
40339
40757
  meta = syntheticColumnMeta("number");
40340
- } else if (column.type === "LITERAL_COL" || column.type === "SCALAR_VALUE_COL") meta = syntheticColumnMeta("string");
40341
- else if (column.type === "STRFUNC_COL") meta = stringFunctionColumnMeta(column.expr, resolveField2);
40758
+ } else if (column.type === "LITERAL_COL") meta = syntheticColumnMeta("string");
40759
+ else if (column.type === "SCALAR_VALUE_COL") {
40760
+ const expr = column.expr;
40761
+ if (expr.type === "STRING_FUNC") meta = stringFunctionColumnMeta(expr, resolveExpressionField);
40762
+ else if (expr.type === "NUMBER" || expr.type === "SCALAR_ARITH") meta = syntheticColumnMeta("number");
40763
+ else if (expr.type === "FIELD") meta = resolveExpressionField(expr);
40764
+ else meta = syntheticColumnMeta("string");
40765
+ } else if (column.type === "STRFUNC_COL") meta = stringFunctionColumnMeta(column.expr, resolveExpressionField);
40342
40766
  else if (column.type === "SCALAR_SUBQUERY_COL") meta = unknownStringColumnMeta();
40343
40767
  else if (column.type === "CASE_COL") {
40344
- const candidates = column.expr.branches.map((branch) => caseResultColumnMeta(branch.result, resolveField2));
40345
- if (column.expr.elseResult) candidates.push(caseResultColumnMeta(column.expr.elseResult, resolveField2));
40768
+ const candidates = column.expr.branches.map((branch) => caseResultColumnMeta(branch.result, resolveExpressionField));
40769
+ if (column.expr.elseResult) candidates.push(caseResultColumnMeta(column.expr.elseResult, resolveExpressionField));
40346
40770
  meta = mergeExpressionColumnMeta(candidates);
40347
40771
  } else if (column.type === "AGGREGATE") {
40348
40772
  if (column.func === "MIN" || column.func === "MAX" || column.func === "MODE") {
@@ -40353,10 +40777,16 @@ async function buildOrderSemanticsForSelect(stmt, client, cacheContext, material
40353
40777
  }
40354
40778
  if (meta?.semantics) aliasSemantics.set(column.alias, meta.semantics);
40355
40779
  }
40780
+ const aggregateOrderRefs = /* @__PURE__ */ new Map();
40781
+ for (const item of selectWindowColumns(stmt).flatMap((column) => column.orderBy)) {
40782
+ if (item.key.type === "FIELD_NAME" && item.key.aggregateRef) {
40783
+ aggregateOrderRefs.set(item.key.name, item.key.aggregateRef);
40784
+ }
40785
+ }
40356
40786
  const result = /* @__PURE__ */ new Map();
40357
40787
  for (const name of names) {
40358
40788
  const resolvedAlias = resolveProjectedName(name, aliasSemantics.keys());
40359
- const base = (resolvedAlias === void 0 ? void 0 : aliasSemantics.get(resolvedAlias)) ?? resolveField2(aggregateFieldRef(name))?.semantics;
40789
+ const base = (resolvedAlias === void 0 ? void 0 : aliasSemantics.get(resolvedAlias)) ?? (aggregateOrderRefs.has(name) ? aggregateResultColumnMeta(aggregateOrderRefs.get(name), resolveField2).semantics : void 0) ?? resolveField2(aggregateFieldRef(name))?.semantics;
40360
40790
  if (!base) {
40361
40791
  const ref = aggregateFieldRef(name);
40362
40792
  if (ref.tableAlias === null && ambiguousFields.has(ref.field)) {
@@ -40379,9 +40809,7 @@ async function buildOrderSemanticsForSelect(stmt, client, cacheContext, material
40379
40809
  return result;
40380
40810
  }
40381
40811
  async function buildOrderByMetaForSelect(stmt, client, cacheContext, materializedTables) {
40382
- const hasWindowOrderBy = stmt.columns.some(
40383
- (column) => column.type === "WINDOW_COL" && column.orderBy.length > 0
40384
- );
40812
+ const hasWindowOrderBy = selectWindowColumns(stmt).some((column) => column.orderBy.length > 0);
40385
40813
  if (stmt.orderBy.length === 0 && !hasWindowOrderBy) {
40386
40814
  return { optionOrders: /* @__PURE__ */ new Map(), sortKinds: /* @__PURE__ */ new Map(), semantics: /* @__PURE__ */ new Map() };
40387
40815
  }
@@ -43606,7 +44034,7 @@ async function buildExplainWhereAnalysis(query, client, cacheContext, maxRecords
43606
44034
  if (isConstantFalseWhere(select.where)) currentRows = 0;
43607
44035
  else if (select.where !== null) currentRows = null;
43608
44036
  const grouping = normalizeGroupingSpec(select);
43609
- if (grouping.type !== "NONE" || select.distinct || select.having !== null || isAggregateQueryBlock(select) || select.columns.some((column) => column.type === "WINDOW_COL")) {
44037
+ if (grouping.type !== "NONE" || select.distinct || select.having !== null || isAggregateQueryBlock(select) || selectWindowColumns(select).length > 0) {
43610
44038
  currentRows = null;
43611
44039
  }
43612
44040
  if (currentRows !== null) {
@@ -43795,7 +44223,7 @@ async function buildExplainWhereAnalysis(query, client, cacheContext, maxRecords
43795
44223
  }
43796
44224
  const physicalApps = [select.from, ...select.joins.map((join3) => join3.table)].filter((table) => table.cteName === null).map((table) => table.appId);
43797
44225
  const needsWhereSchema = whereNeedsFieldMetadata(select.where);
43798
- if (needsWhereSchema || select.orderBy.length > 0 || select.columns.some((column) => column.type === "WINDOW_COL" && column.orderBy.length > 0)) {
44226
+ if (needsWhereSchema || select.orderBy.length > 0 || selectWindowColumns(select).some((column) => column.orderBy.length > 0)) {
43799
44227
  physicalApps.forEach((appId) => fieldApps.add(appId));
43800
44228
  }
43801
44229
  const { resolver, rewrites } = await normalizeSelectChoiceEquality(
@@ -43875,7 +44303,7 @@ async function buildExplainWhereAnalysis(query, client, cacheContext, maxRecords
43875
44303
  joinKeyPlans.set(joinAlias, { plan, queries, additionalQuery, additionalRelation });
43876
44304
  }
43877
44305
  if (joinKeyPlans.size > 0) explainJoinKeyPrefilters.set(select, joinKeyPlans);
43878
- if (select.orderBy.length > 0 || select.columns.some((column) => column.type === "WINDOW_COL" && column.orderBy.length > 0)) {
44306
+ if (select.orderBy.length > 0 || selectWindowColumns(select).some((column) => column.orderBy.length > 0)) {
43879
44307
  const meta = await buildOrderByMetaForSelect(select, tracedClient, cacheContext);
43880
44308
  if (select.orderMode !== "KINTONE_NATIVE") {
43881
44309
  for (const semantics of meta.semantics.values()) {
@@ -45191,7 +45619,7 @@ function buildSelectPlan(stmt, label, capabilities, orderPlans, plainGroupByPlan
45191
45619
  const clauses = [];
45192
45620
  if (column.partitionBy.length > 0) {
45193
45621
  clauses.push(`PARTITION BY ${column.partitionBy.map(
45194
- (ref) => ref.tableAlias ? `${ref.tableAlias}.${ref.field}` : ref.field
45622
+ (ref) => ref.type === "GROUPING_REF" ? `GROUPING(${ref.field.tableAlias ? `${ref.field.tableAlias}.` : ""}${ref.field.field})` : ref.tableAlias ? `${ref.tableAlias}.${ref.field}` : ref.field
45195
45623
  ).join(", ")}`);
45196
45624
  }
45197
45625
  if (column.orderBy.length > 0) {
@@ -45492,7 +45920,7 @@ function populateWithCrossJoinExplain(stmt) {
45492
45920
  if (steps.length > 0) explainCrossJoinSteps.set(select, steps);
45493
45921
  if (isConstantFalseWhere(select.where)) current = 0;
45494
45922
  else if (select.where !== null) current = null;
45495
- if (normalizeGroupingSpec(select).type !== "NONE" || select.distinct || select.having !== null || isAggregateQueryBlock(select) || select.columns.some((column) => column.type === "WINDOW_COL")) return null;
45923
+ if (normalizeGroupingSpec(select).type !== "NONE" || select.distinct || select.having !== null || isAggregateQueryBlock(select) || selectWindowColumns(select).length > 0) return null;
45496
45924
  if (current === null) return null;
45497
45925
  current = Math.max(0, current - (select.offset ?? 0));
45498
45926
  return select.limit === null ? current : Math.min(current, select.limit);
@@ -45652,7 +46080,7 @@ function collectFullScanReasons(stmt) {
45652
46080
  r.push("DISTINCT \u3042\u308A");
45653
46081
  if (hasAggregateColumns(stmt.columns))
45654
46082
  r.push("\u96C6\u8A08\u95A2\u6570\uFF08COUNT / SUM \u7B49\uFF09\u3042\u308A");
45655
- if (stmt.columns.some((c) => c.type === "WINDOW_COL"))
46083
+ if (selectWindowColumns(stmt).length > 0)
45656
46084
  r.push("\u30A6\u30A3\u30F3\u30C9\u30A6\u95A2\u6570\u3042\u308A");
45657
46085
  if (stmt.columns.some((c) => c.type === "SCALAR_SUBQUERY_COL"))
45658
46086
  r.push("SELECT \u5217\u306B\u30B9\u30AB\u30E9\u30FC\u30B5\u30D6\u30AF\u30A8\u30EA");