@rex0220/kintone-sql-tools 3.79.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 = {}) {
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
  }
@@ -31797,11 +32072,32 @@ function applyGroupBy(rows, groupByKeys, columns, resolveAggSortKind, resolution
31797
32072
  resolveAggSortKind,
31798
32073
  aliasEvaluationContext.evaluationContext
31799
32074
  );
32075
+ materializeAggregateDependencies(
32076
+ outRow,
32077
+ groupRows,
32078
+ having,
32079
+ resolveAggSortKind,
32080
+ aliasEvaluationContext.evaluationContext
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
+ );
31800
32096
  result.push(outRow);
31801
32097
  }
31802
32098
  return result;
31803
32099
  }
31804
- function applyGroupingSets(rows, spec, columns, resolveAggSortKind, limits = {}) {
32100
+ function applyGroupingSets(rows, spec, columns, resolveAggSortKind, limits = {}, having = null, hiddenWindows = []) {
31805
32101
  const result = [];
31806
32102
  let generatedRows = 0;
31807
32103
  const countBucket = () => {
@@ -31861,6 +32157,27 @@ function applyGroupingSets(rows, spec, columns, resolveAggSortKind, limits = {})
31861
32157
  resolveAggSortKind,
31862
32158
  limits.evaluationContext
31863
32159
  );
32160
+ materializeAggregateDependencies(
32161
+ outRow,
32162
+ groupRows,
32163
+ having,
32164
+ resolveAggSortKind,
32165
+ limits.evaluationContext
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
+ );
31864
32181
  attachGroupingRowMeta(outRow, includedCanonicalIds);
31865
32182
  result.push(outRow);
31866
32183
  }
@@ -31873,6 +32190,10 @@ function groupingItemValue(item, row) {
31873
32190
  }
31874
32191
  function materializeAggregateColumns(outRow, groupRows, columns, resolveAggSortKind, evaluationContext = {}) {
31875
32192
  for (const [columnIndex, col] of columns.entries()) {
32193
+ if (containsHiddenWindowRef(col)) {
32194
+ materializeAggregateDependencies(outRow, groupRows, col, resolveAggSortKind, evaluationContext);
32195
+ continue;
32196
+ }
31876
32197
  if (col.type === "AGGREGATE") {
31877
32198
  const syntheticKey = aggregateSyntheticName(col.func, col.distinct, col.arg);
31878
32199
  const value = String(evalAggregate(
@@ -31949,6 +32270,14 @@ function materializeAggregateColumns(outRow, groupRows, columns, resolveAggSortK
31949
32270
  }
31950
32271
  }
31951
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
+ }
31952
32281
  function caseMaterializedKey(alias, columnIndex) {
31953
32282
  return alias ?? `__ksql_case_column_${columnIndex}`;
31954
32283
  }
@@ -32165,7 +32494,7 @@ function aggArithDefaultKey(node) {
32165
32494
  }
32166
32495
  function resolveAggregateArgSemantics(arg, resolver) {
32167
32496
  if (arg.type === "FIELD_REF") return resolver?.(toAggregateFieldRef(arg.field)) ?? "string";
32168
- if (arg.type === "FIELD") return resolver?.(arg) ?? "string";
32497
+ if (arg.type === "FIELD") return arg.aggregateRef ? aggregateResultSemantics(arg.aggregateRef, resolver) : resolver?.(arg) ?? "string";
32169
32498
  if (arg.type === "NUMBER" || arg.type === "ARITH" || arg.type === "SCALAR_ARITH") return "number";
32170
32499
  if (arg.type === "STRING" || arg.type === "CONCAT_OP" || arg.type === "VARIABLE") return "string";
32171
32500
  if (arg.type === "STRING_FUNC") {
@@ -32391,14 +32720,15 @@ function buildOrderByAliasEvaluator(columns, scalarCache, resolveFieldType, reso
32391
32720
  return resolved === void 0 ? void 0 : evaluators.get(resolved)?.(row);
32392
32721
  };
32393
32722
  }
32394
- function applyWindow(rows, columns, optionOrders, sortKinds, fieldSemantics2, resolveAggSortKind, evaluationContext = {}) {
32723
+ function applyWindow(rows, columns, optionOrders, sortKinds, fieldSemantics2, resolveAggSortKind, evaluationContext = {}, hiddenWindows = []) {
32395
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 })));
32396
32726
  if (rows.length === 0 || windows.length === 0) return rows;
32397
32727
  for (let index = 0; index < rows.length; index++) rows[index] = asProcessingRow(rows[index]);
32398
32728
  for (const { column: window, columnIndex } of windows) {
32399
32729
  const partitions = /* @__PURE__ */ new Map();
32400
32730
  for (const row of rows) {
32401
- const key = JSON.stringify(window.partitionBy.map((ref) => resolveWindowField(row, ref)));
32731
+ const key = JSON.stringify(window.partitionBy.map((ref) => resolveWindowPartitionKey(row, ref)));
32402
32732
  const partition = partitions.get(key);
32403
32733
  if (partition) partition.push(row);
32404
32734
  else partitions.set(key, [row]);
@@ -32448,7 +32778,7 @@ function applyWindow(rows, columns, optionOrders, sortKinds, fieldSemantics2, re
32448
32778
  function evaluateValueWindowArg(arg, row, evaluationContext = {}) {
32449
32779
  const value = evalScalarValueExprNullable(
32450
32780
  arg,
32451
- sourceRowForEvaluation(row),
32781
+ havingEvaluationRow(row),
32452
32782
  void 0,
32453
32783
  void 0,
32454
32784
  evaluationContext
@@ -32479,7 +32809,7 @@ function applyAggregateWindow(window, columnIndex, sortedResult, resolveAggSortK
32479
32809
  const values = window.arg.type === "WILDCARD" ? null : aggregateRowValues(
32480
32810
  window.aggFunc,
32481
32811
  window.arg,
32482
- sorted.map((item) => item.row),
32812
+ sorted.map((item) => havingEvaluationRow(item.row)),
32483
32813
  evaluationContext
32484
32814
  );
32485
32815
  const comparison = window.arg.type === "WILDCARD" ? void 0 : resolveAggregateArgSemantics(window.arg, resolveAggSortKind);
@@ -32532,9 +32862,10 @@ function applyAggregateWindow(window, columnIndex, sortedResult, resolveAggSortK
32532
32862
  setMaterializedSelectValue(sorted[index].row, columnIndex, output[index], [window.alias]);
32533
32863
  }
32534
32864
  }
32535
- function resolveWindowField(row, ref) {
32865
+ function resolveWindowPartitionKey(row, ref) {
32866
+ if (ref.type === "GROUPING_REF") return evalGroupingRef(ref, row);
32536
32867
  const name = ref.tableAlias ? `${ref.tableAlias}.${ref.field}` : ref.field;
32537
- return resolveFieldRef(sourceRowForEvaluation(row), name);
32868
+ return resolveFieldRef(havingEvaluationRow(row), name);
32538
32869
  }
32539
32870
  function applyLimit(rows, limit, offset) {
32540
32871
  const start = offset ?? 0;
@@ -32542,7 +32873,8 @@ function applyLimit(rows, limit, offset) {
32542
32873
  return rows.slice(start, start + limit);
32543
32874
  }
32544
32875
  function evaluateSelectColumnValue(column, row, columnIndex, context = {}) {
32545
- const sourceRow = sourceRowForEvaluation(row);
32876
+ const hasHiddenWindow = containsHiddenWindowRef(column);
32877
+ const sourceRow = hasHiddenWindow ? havingEvaluationRow(row) : sourceRowForEvaluation(row);
32546
32878
  switch (column.type) {
32547
32879
  case "VARIABLE_COL":
32548
32880
  throw new Error(`internal error: unresolved SELECT variable @${column.name}`);
@@ -32573,9 +32905,9 @@ function evaluateSelectColumnValue(column, row, columnIndex, context = {}) {
32573
32905
  return getMaterializedSelectValue(row, columnIndex) ?? getMaterializedLookupValue(row, source) ?? getLegacyMaterializedValue(row, source) ?? "0";
32574
32906
  }
32575
32907
  case "ARITH_COL":
32576
- 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));
32577
32909
  case "CASE_COL":
32578
- 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(
32579
32911
  column.expr,
32580
32912
  sourceRow,
32581
32913
  context.resolveFieldType,
@@ -32586,7 +32918,7 @@ function evaluateSelectColumnValue(column, row, columnIndex, context = {}) {
32586
32918
  return evalGroupingRef(column.ref, row);
32587
32919
  case "STRFUNC_COL": {
32588
32920
  const source = stringFuncDefaultKey(column.expr);
32589
- 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(
32590
32922
  column.expr,
32591
32923
  sourceRow,
32592
32924
  context.resolveFieldType,
@@ -32602,7 +32934,7 @@ function evaluateSelectColumnValue(column, row, columnIndex, context = {}) {
32602
32934
  }
32603
32935
  case "SCALAR_VALUE_COL": {
32604
32936
  const source = scalarValueDefaultKey(column.expr);
32605
- 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(
32606
32938
  column.expr,
32607
32939
  sourceRow,
32608
32940
  context.resolveFieldType,
@@ -33024,9 +33356,33 @@ function mergeKnownColumns(left, right, rows) {
33024
33356
  ...Object.keys(rows[0] ?? {})
33025
33357
  ])];
33026
33358
  }
33027
- function deriveOutputOrderSemantics(columns, resolveAggSortKind) {
33359
+ function deriveOutputOrderSemantics(columns, resolveAggSortKind, hiddenWindows = []) {
33028
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);
33029
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
+ }
33030
33386
  if (!("alias" in column) || !column.alias) continue;
33031
33387
  if (column.type === "ARITH_COL" || column.type === "ARITH_AGG_COL") {
33032
33388
  result.set(column.alias, syntheticSemantics("number"));
@@ -33043,17 +33399,29 @@ function deriveOutputOrderSemantics(columns, resolveAggSortKind) {
33043
33399
  } else if (column.func === "GROUP_CONCAT") {
33044
33400
  result.set(column.alias, syntheticSemantics("string"));
33045
33401
  }
33046
- } 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") {
33047
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)));
33048
33406
  } else if (column.type === "STRFUNC_COL") {
33049
33407
  result.set(column.alias, syntheticSemantics(stringFunctionSemanticKind(
33050
33408
  column.expr,
33051
- (field) => resolveAggSortKind?.(field)
33409
+ resolveExpressionField
33052
33410
  )));
33053
33411
  }
33054
33412
  }
33055
33413
  return result;
33056
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
+ }
33057
33425
  function runFullScan(input) {
33058
33426
  const {
33059
33427
  stmt,
@@ -33076,8 +33444,17 @@ function runFullScan(input) {
33076
33444
  warnings,
33077
33445
  evaluationContext
33078
33446
  } = input;
33079
- const effectiveOrderSemantics = deriveOutputOrderSemantics(stmt.columns, aggregateSortKindResolver);
33447
+ const effectiveOrderSemantics = deriveOutputOrderSemantics(
33448
+ stmt.columns,
33449
+ aggregateSortKindResolver,
33450
+ stmt.hiddenWindows
33451
+ );
33080
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);
33081
33458
  let rows = [];
33082
33459
  const mainAlias = stmt.from.alias;
33083
33460
  const mainRecords = tables.get(mainAlias) ?? tables.get(null) ?? [];
@@ -33121,9 +33498,14 @@ function runFullScan(input) {
33121
33498
  resolvedGroupingSpec,
33122
33499
  stmt.columns,
33123
33500
  aggregateSortKindResolver,
33124
- { maxGeneratedRows: B65_MAX_GENERATED_ROWS, evaluationContext }
33501
+ { maxGeneratedRows: B65_MAX_GENERATED_ROWS, evaluationContext },
33502
+ stmt.having,
33503
+ stmt.hiddenWindows
33125
33504
  );
33126
- } else if (grouping.type === "PLAIN" || hasAggregateColumns(stmt.columns)) {
33505
+ } else if (grouping.type === "PLAIN" || hasAggregateColumns([
33506
+ ...stmt.columns,
33507
+ ...stmt.hiddenWindows ?? []
33508
+ ])) {
33127
33509
  rows = applyGroupBy(
33128
33510
  rows,
33129
33511
  grouping.type === "PLAIN" ? grouping.allItems : [],
@@ -33135,7 +33517,9 @@ function runFullScan(input) {
33135
33517
  resolveFieldType: fieldTypeResolver,
33136
33518
  resolveFieldSemantics: fieldSemanticsResolver,
33137
33519
  evaluationContext
33138
- }
33520
+ },
33521
+ stmt.having,
33522
+ stmt.hiddenWindows
33139
33523
  );
33140
33524
  }
33141
33525
  warnOnUnresolvedAggregateComparisons(stmt.columns, rows, warnings);
@@ -33155,7 +33539,8 @@ function runFullScan(input) {
33155
33539
  sortKinds,
33156
33540
  effectiveOrderSemantics,
33157
33541
  aggregateSortKindResolver,
33158
- evaluationContext
33542
+ evaluationContext,
33543
+ stmt.hiddenWindows
33159
33544
  );
33160
33545
  if (stmt.distinct) {
33161
33546
  rows = applyDistinct(
@@ -33163,7 +33548,7 @@ function runFullScan(input) {
33163
33548
  stmt.columns,
33164
33549
  scalarCache,
33165
33550
  fieldTypeResolver,
33166
- fieldSemanticsResolver,
33551
+ expressionFieldSemanticsResolver,
33167
33552
  evaluationContext
33168
33553
  );
33169
33554
  }
@@ -33177,7 +33562,7 @@ function runFullScan(input) {
33177
33562
  stmt.columns,
33178
33563
  scalarCache,
33179
33564
  fieldTypeResolver,
33180
- fieldSemanticsResolver,
33565
+ expressionFieldSemanticsResolver,
33181
33566
  evaluationContext
33182
33567
  ),
33183
33568
  evaluationContext
@@ -33189,7 +33574,7 @@ function runFullScan(input) {
33189
33574
  scalarCache,
33190
33575
  fieldTypeResolver,
33191
33576
  sourceColumns2,
33192
- fieldSemanticsResolver,
33577
+ expressionFieldSemanticsResolver,
33193
33578
  hiddenQualifiedAliases,
33194
33579
  evaluationContext
33195
33580
  );
@@ -36804,15 +37189,46 @@ async function normalizeSelectChoiceEquality(stmt, client, cacheContext, materia
36804
37189
  }
36805
37190
  return { resolver, rewrites: normalization.rewrites };
36806
37191
  }
37192
+ function selectWindowColumns(stmt) {
37193
+ return [
37194
+ ...stmt.columns.filter((column) => column.type === "WINDOW_COL"),
37195
+ ...stmt.hiddenWindows ?? []
37196
+ ];
37197
+ }
36807
37198
  function hasDefaultRangeAggregateWindow(stmt) {
36808
- return stmt.columns.some(
36809
- (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"
36810
37201
  );
36811
37202
  }
36812
37203
  function hasWindowNeedingOrderProof(stmt) {
36813
- 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
+ });
36814
37229
  }
36815
37230
  function canProveTotalWindowOrder(stmt, orderBy, resolveField2, context, generatedColumn) {
37231
+ if (sameSelectGroupOrderIsUnique(stmt, orderBy)) return true;
36816
37232
  if (generatedColumn !== void 0 && stmt.joins.length === 0 && stmt.from.cteName !== null) {
36817
37233
  return orderBy.some((item) => {
36818
37234
  if (item.key.type !== "FIELD_NAME") return false;
@@ -36935,9 +37351,7 @@ function formatWhereCapabilityFailure(result) {
36935
37351
  return details || "reason=WHERE_UNSUPPORTED";
36936
37352
  }
36937
37353
  function hasCanonicalOrder(stmt) {
36938
- return stmt.orderBy.length > 0 || stmt.columns.some(
36939
- (column) => column.type === "WINDOW_COL" && column.orderBy.length > 0
36940
- );
37354
+ return stmt.orderBy.length > 0 || selectWindowColumns(stmt).some((column) => column.orderBy.length > 0);
36941
37355
  }
36942
37356
  async function resolveDmlWhereCapability(stmt, client, cacheContext) {
36943
37357
  if (stmt.subtableCode || stmt.type === "UPDATE" && stmt.from != null) {
@@ -37395,7 +37809,7 @@ function arithHasFieldRef(node) {
37395
37809
  `InternalError: unresolved arithmetic variable @${node.name} reached SELECT planning.`
37396
37810
  );
37397
37811
  }
37398
- if (node.type === "FIELD_REF") return true;
37812
+ if (node.type === "FIELD_REF") return node.hiddenWindowRef !== true;
37399
37813
  if (node.type === "ARITH") return arithHasFieldRef(node.left) || arithHasFieldRef(node.right);
37400
37814
  if (node.type === "STRING_FUNC") return stringFuncHasFieldRef(node);
37401
37815
  return false;
@@ -37407,7 +37821,7 @@ function stringFuncArgHasFieldRef(arg) {
37407
37821
  return scalarValueHasFieldRef(arg);
37408
37822
  }
37409
37823
  function scalarValueHasFieldRef(expr) {
37410
- if (expr.type === "FIELD") return true;
37824
+ if (expr.type === "FIELD") return expr.hiddenWindowRef !== true;
37411
37825
  if (expr.type === "STRING_FUNC") return stringFuncHasFieldRef(expr);
37412
37826
  if (expr.type === "SCALAR_ARITH" || expr.type === "CONCAT_OP") {
37413
37827
  return scalarValueHasFieldRef(expr.left) || scalarValueHasFieldRef(expr.right);
@@ -37465,7 +37879,8 @@ function executeNoFromSelect(stmt, options) {
37465
37879
  void 0,
37466
37880
  void 0,
37467
37881
  void 0,
37468
- statementEvaluationContext(options)
37882
+ statementEvaluationContext(options),
37883
+ stmt.hiddenWindows
37469
37884
  );
37470
37885
  const { rows: projected, columns } = project(
37471
37886
  windowed,
@@ -37744,7 +38159,7 @@ function bindProjectedNamesForSelect(stmt, materializedTables, physicalMayHave)
37744
38159
  }
37745
38160
  for (const child of Object.values(value)) visit(child, allowSelectAlias);
37746
38161
  };
37747
- for (const column of stmt.columns) visit(column);
38162
+ for (const column of [...stmt.columns, ...stmt.hiddenWindows ?? []]) visit(column);
37748
38163
  visit(stmt.where);
37749
38164
  visit(stmt.having, true);
37750
38165
  visit(stmt.grouping);
@@ -37759,9 +38174,9 @@ function bindProjectedNamesForSelect(stmt, materializedTables, physicalMayHave)
37759
38174
  if (item.key.type === "FIELD_NAME") item.key.name = resolveText(item.key.name, true);
37760
38175
  else visit(item.key);
37761
38176
  }
37762
- for (const column of stmt.columns) {
37763
- if (column.type !== "WINDOW_COL") continue;
38177
+ for (const column of selectWindowColumns(stmt)) {
37764
38178
  for (const ref of column.partitionBy) {
38179
+ if (ref.type !== "FIELD") continue;
37765
38180
  ref.field = resolveReference(ref.field, ref.tableAlias, false);
37766
38181
  }
37767
38182
  for (const item of column.orderBy) {
@@ -38468,7 +38883,7 @@ function mergeExpressionColumnMeta(candidates) {
38468
38883
  }
38469
38884
  function inferAggregateArgMeta(arg, resolveField2) {
38470
38885
  if (arg.type === "FIELD_REF") return resolveField2(aggregateFieldRef(arg.field)) ?? unknownStringColumnMeta();
38471
- if (arg.type === "FIELD") return resolveField2(arg) ?? unknownStringColumnMeta();
38886
+ if (arg.type === "FIELD") return arg.aggregateRef ? aggregateResultColumnMeta(arg.aggregateRef, resolveField2) : resolveField2(arg) ?? unknownStringColumnMeta();
38472
38887
  if (arg.type === "NUMBER" || arg.type === "ARITH" || arg.type === "SCALAR_ARITH") return syntheticColumnMeta("number");
38473
38888
  if (arg.type === "STRING" || arg.type === "CONCAT_OP" || arg.type === "VARIABLE") return syntheticColumnMeta("string");
38474
38889
  if (arg.type === "STRING_FUNC") return stringFunctionColumnMeta(arg, resolveField2);
@@ -38476,6 +38891,15 @@ function inferAggregateArgMeta(arg, resolveField2) {
38476
38891
  if (arg.elseResult) results.push(caseResultColumnMeta(arg.elseResult, resolveField2));
38477
38892
  return mergeExpressionColumnMeta(results);
38478
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
+ }
38479
38903
  function inferWindowColumnMeta(column, resolveField2) {
38480
38904
  if (column.windowKind === "VALUE") {
38481
38905
  return inferAggregateArgMeta(column.arg, resolveField2);
@@ -38492,7 +38916,7 @@ function withDisplayName(meta, displayName) {
38492
38916
  return { ...meta ?? {}, displayName };
38493
38917
  }
38494
38918
  function selectNeedsSourceColumnMeta(stmt) {
38495
- return stmt.columns.some(
38919
+ return (stmt.hiddenWindows?.length ?? 0) > 0 || stmt.columns.some(
38496
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"))
38497
38921
  );
38498
38922
  }
@@ -38550,6 +38974,11 @@ async function inferSelectColumnMeta(stmt, outputColumns, client, cacheContext,
38550
38974
  return meta && publicSourceApp !== void 0 ? { ...meta, publicSourceApp } : meta;
38551
38975
  };
38552
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);
38553
38982
  const hasWildcard = stmt.columns.some((column) => column.type === "WILDCARD" || column.type === "PARENT_WILDCARD");
38554
38983
  if (stmt.columns.length === 1 && (stmt.columns[0].type === "WILDCARD" || stmt.columns[0].type === "PARENT_WILDCARD")) {
38555
38984
  for (const output of outputColumns) {
@@ -38592,17 +39021,17 @@ async function inferSelectColumnMeta(stmt, outputColumns, client, cacheContext,
38592
39021
  meta = syntheticColumnMeta("string");
38593
39022
  } else if (column.type === "SCALAR_VALUE_COL") {
38594
39023
  const expr = column.expr;
38595
- if (expr.type === "STRING_FUNC") meta = stringFunctionColumnMeta(expr, resolveField2);
39024
+ if (expr.type === "STRING_FUNC") meta = stringFunctionColumnMeta(expr, resolveExpressionField);
38596
39025
  else if (expr.type === "NUMBER" || expr.type === "SCALAR_ARITH") meta = syntheticColumnMeta("number");
38597
- else if (expr.type === "FIELD") meta = resolveField2(expr);
39026
+ else if (expr.type === "FIELD") meta = resolveExpressionField(expr);
38598
39027
  else meta = syntheticColumnMeta("string");
38599
39028
  } else if (column.type === "STRFUNC_COL") {
38600
- meta = stringFunctionColumnMeta(column.expr, resolveField2);
39029
+ meta = stringFunctionColumnMeta(column.expr, resolveExpressionField);
38601
39030
  } else if (column.type === "WINDOW_COL") {
38602
39031
  meta = inferWindowColumnMeta(column, resolveField2);
38603
39032
  } else if (column.type === "CASE_COL") {
38604
- const results = column.expr.branches.map((branch) => caseResultColumnMeta(branch.result, resolveField2));
38605
- 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));
38606
39035
  meta = mergeExpressionColumnMeta(results);
38607
39036
  } else if (column.type === "SCALAR_SUBQUERY_COL") {
38608
39037
  meta = unknownStringColumnMeta();
@@ -40261,7 +40690,7 @@ async function getSortKindMapByApp(appId, client, cacheContext) {
40261
40690
  function orderByFieldNames(stmt) {
40262
40691
  const items = [
40263
40692
  ...stmt.orderBy,
40264
- ...stmt.columns.flatMap((column) => column.type === "WINDOW_COL" ? column.orderBy : [])
40693
+ ...selectWindowColumns(stmt).flatMap((column) => column.orderBy)
40265
40694
  ];
40266
40695
  return [...new Set(items.flatMap(
40267
40696
  (item) => item.key.type === "FIELD_NAME" ? [item.key.name] : []
@@ -40311,6 +40740,11 @@ async function buildOrderSemanticsForSelect(stmt, client, cacheContext, material
40311
40740
  return matches.length === 1 ? matches[0] : void 0;
40312
40741
  };
40313
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);
40314
40748
  for (const column of stmt.columns) {
40315
40749
  if (!("alias" in column) || !column.alias) continue;
40316
40750
  let meta;
@@ -40321,12 +40755,18 @@ async function buildOrderSemanticsForSelect(stmt, client, cacheContext, material
40321
40755
  meta = inferWindowColumnMeta(column, resolveField2);
40322
40756
  } else if (column.type === "GROUPING_COL") {
40323
40757
  meta = syntheticColumnMeta("number");
40324
- } else if (column.type === "LITERAL_COL" || column.type === "SCALAR_VALUE_COL") meta = syntheticColumnMeta("string");
40325
- 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);
40326
40766
  else if (column.type === "SCALAR_SUBQUERY_COL") meta = unknownStringColumnMeta();
40327
40767
  else if (column.type === "CASE_COL") {
40328
- const candidates = column.expr.branches.map((branch) => caseResultColumnMeta(branch.result, resolveField2));
40329
- 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));
40330
40770
  meta = mergeExpressionColumnMeta(candidates);
40331
40771
  } else if (column.type === "AGGREGATE") {
40332
40772
  if (column.func === "MIN" || column.func === "MAX" || column.func === "MODE") {
@@ -40337,10 +40777,16 @@ async function buildOrderSemanticsForSelect(stmt, client, cacheContext, material
40337
40777
  }
40338
40778
  if (meta?.semantics) aliasSemantics.set(column.alias, meta.semantics);
40339
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
+ }
40340
40786
  const result = /* @__PURE__ */ new Map();
40341
40787
  for (const name of names) {
40342
40788
  const resolvedAlias = resolveProjectedName(name, aliasSemantics.keys());
40343
- 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;
40344
40790
  if (!base) {
40345
40791
  const ref = aggregateFieldRef(name);
40346
40792
  if (ref.tableAlias === null && ambiguousFields.has(ref.field)) {
@@ -40363,9 +40809,7 @@ async function buildOrderSemanticsForSelect(stmt, client, cacheContext, material
40363
40809
  return result;
40364
40810
  }
40365
40811
  async function buildOrderByMetaForSelect(stmt, client, cacheContext, materializedTables) {
40366
- const hasWindowOrderBy = stmt.columns.some(
40367
- (column) => column.type === "WINDOW_COL" && column.orderBy.length > 0
40368
- );
40812
+ const hasWindowOrderBy = selectWindowColumns(stmt).some((column) => column.orderBy.length > 0);
40369
40813
  if (stmt.orderBy.length === 0 && !hasWindowOrderBy) {
40370
40814
  return { optionOrders: /* @__PURE__ */ new Map(), sortKinds: /* @__PURE__ */ new Map(), semantics: /* @__PURE__ */ new Map() };
40371
40815
  }
@@ -43590,7 +44034,7 @@ async function buildExplainWhereAnalysis(query, client, cacheContext, maxRecords
43590
44034
  if (isConstantFalseWhere(select.where)) currentRows = 0;
43591
44035
  else if (select.where !== null) currentRows = null;
43592
44036
  const grouping = normalizeGroupingSpec(select);
43593
- 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) {
43594
44038
  currentRows = null;
43595
44039
  }
43596
44040
  if (currentRows !== null) {
@@ -43779,7 +44223,7 @@ async function buildExplainWhereAnalysis(query, client, cacheContext, maxRecords
43779
44223
  }
43780
44224
  const physicalApps = [select.from, ...select.joins.map((join3) => join3.table)].filter((table) => table.cteName === null).map((table) => table.appId);
43781
44225
  const needsWhereSchema = whereNeedsFieldMetadata(select.where);
43782
- 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)) {
43783
44227
  physicalApps.forEach((appId) => fieldApps.add(appId));
43784
44228
  }
43785
44229
  const { resolver, rewrites } = await normalizeSelectChoiceEquality(
@@ -43859,7 +44303,7 @@ async function buildExplainWhereAnalysis(query, client, cacheContext, maxRecords
43859
44303
  joinKeyPlans.set(joinAlias, { plan, queries, additionalQuery, additionalRelation });
43860
44304
  }
43861
44305
  if (joinKeyPlans.size > 0) explainJoinKeyPrefilters.set(select, joinKeyPlans);
43862
- 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)) {
43863
44307
  const meta = await buildOrderByMetaForSelect(select, tracedClient, cacheContext);
43864
44308
  if (select.orderMode !== "KINTONE_NATIVE") {
43865
44309
  for (const semantics of meta.semantics.values()) {
@@ -45175,7 +45619,7 @@ function buildSelectPlan(stmt, label, capabilities, orderPlans, plainGroupByPlan
45175
45619
  const clauses = [];
45176
45620
  if (column.partitionBy.length > 0) {
45177
45621
  clauses.push(`PARTITION BY ${column.partitionBy.map(
45178
- (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
45179
45623
  ).join(", ")}`);
45180
45624
  }
45181
45625
  if (column.orderBy.length > 0) {
@@ -45476,7 +45920,7 @@ function populateWithCrossJoinExplain(stmt) {
45476
45920
  if (steps.length > 0) explainCrossJoinSteps.set(select, steps);
45477
45921
  if (isConstantFalseWhere(select.where)) current = 0;
45478
45922
  else if (select.where !== null) current = null;
45479
- 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;
45480
45924
  if (current === null) return null;
45481
45925
  current = Math.max(0, current - (select.offset ?? 0));
45482
45926
  return select.limit === null ? current : Math.min(current, select.limit);
@@ -45636,7 +46080,7 @@ function collectFullScanReasons(stmt) {
45636
46080
  r.push("DISTINCT \u3042\u308A");
45637
46081
  if (hasAggregateColumns(stmt.columns))
45638
46082
  r.push("\u96C6\u8A08\u95A2\u6570\uFF08COUNT / SUM \u7B49\uFF09\u3042\u308A");
45639
- if (stmt.columns.some((c) => c.type === "WINDOW_COL"))
46083
+ if (selectWindowColumns(stmt).length > 0)
45640
46084
  r.push("\u30A6\u30A3\u30F3\u30C9\u30A6\u95A2\u6570\u3042\u308A");
45641
46085
  if (stmt.columns.some((c) => c.type === "SCALAR_SUBQUERY_COL"))
45642
46086
  r.push("SELECT \u5217\u306B\u30B9\u30AB\u30E9\u30FC\u30B5\u30D6\u30AF\u30A8\u30EA");