@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 +555 -111
- package/dist-engine/index.cjs +16 -16
- package/dist-engine/index.mjs +16 -16
- package/dist-engine/ksql-engine.umd.js +16 -16
- package/dist-engine/meta/bundle-baseline.json +7 -7
- package/dist-engine/meta/cjs.json +20 -20
- package/dist-engine/meta/esm.json +20 -20
- package/dist-engine/meta/umd.json +20 -20
- package/dist-flow/index.cjs +14 -14
- package/dist-flow/index.mjs +14 -14
- package/dist-flow/meta/cjs.json +20 -20
- package/dist-flow/meta/esm.json +20 -20
- package/dist-flow/types/ast.d.ts +10 -3
- package/dist-mcp/ksql-mcp.js +558 -114
- package/dist-mcpb/ksql-mcp.mcpb +0 -0
- package/package.json +1 -1
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
|
|
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
|
-
|
|
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
|
-
|
|
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(
|
|
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
|
|
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
|
-
|
|
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(
|
|
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
|
-
|
|
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(
|
|
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.
|
|
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(
|
|
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(
|
|
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")
|
|
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
|
-
|
|
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
|
-
|
|
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)
|
|
24103
|
-
|
|
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) =>
|
|
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
|
-
|
|
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
|
|
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(
|
|
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
|
|
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 === "
|
|
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
|
-
|
|
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(
|
|
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(
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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.
|
|
36809
|
-
(column) => column.
|
|
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.
|
|
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.
|
|
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
|
|
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,
|
|
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 =
|
|
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,
|
|
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,
|
|
38605
|
-
if (column.expr.elseResult) results.push(caseResultColumnMeta(column.expr.elseResult,
|
|
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.
|
|
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"
|
|
40325
|
-
else if (column.type === "
|
|
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,
|
|
40329
|
-
if (column.expr.elseResult) candidates.push(caseResultColumnMeta(column.expr.elseResult,
|
|
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.
|
|
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
|
|
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.
|
|
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.
|
|
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
|
|
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
|
|
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");
|