@rex0220/kintone-sql-tools 3.80.0 → 3.82.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 +539 -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 +542 -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 = {}, having = null) {
|
|
32026
|
+
function applyGroupBy(rows, groupByKeys, columns, resolveAggSortKind, resolutionPlan, aliasEvaluationContext = {}, having = null, hiddenWindows = []) {
|
|
31752
32027
|
if (resolutionPlan && resolutionPlan.items.length !== groupByKeys.length) {
|
|
31753
32028
|
throw new Error("InternalError: plain GROUP BY resolution plan length does not match group keys.");
|
|
31754
32029
|
}
|
|
@@ -31804,11 +32079,25 @@ function applyGroupBy(rows, groupByKeys, columns, resolveAggSortKind, resolution
|
|
|
31804
32079
|
resolveAggSortKind,
|
|
31805
32080
|
aliasEvaluationContext.evaluationContext
|
|
31806
32081
|
);
|
|
32082
|
+
materializeAggregateDependencies(
|
|
32083
|
+
outRow,
|
|
32084
|
+
groupRows,
|
|
32085
|
+
columns.filter((column) => column.type === "WINDOW_COL"),
|
|
32086
|
+
resolveAggSortKind,
|
|
32087
|
+
aliasEvaluationContext.evaluationContext
|
|
32088
|
+
);
|
|
32089
|
+
materializeAggregateDependencies(
|
|
32090
|
+
outRow,
|
|
32091
|
+
groupRows,
|
|
32092
|
+
hiddenWindows,
|
|
32093
|
+
resolveAggSortKind,
|
|
32094
|
+
aliasEvaluationContext.evaluationContext
|
|
32095
|
+
);
|
|
31807
32096
|
result.push(outRow);
|
|
31808
32097
|
}
|
|
31809
32098
|
return result;
|
|
31810
32099
|
}
|
|
31811
|
-
function applyGroupingSets(rows, spec, columns, resolveAggSortKind, limits = {}, having = null) {
|
|
32100
|
+
function applyGroupingSets(rows, spec, columns, resolveAggSortKind, limits = {}, having = null, hiddenWindows = []) {
|
|
31812
32101
|
const result = [];
|
|
31813
32102
|
let generatedRows = 0;
|
|
31814
32103
|
const countBucket = () => {
|
|
@@ -31875,6 +32164,20 @@ function applyGroupingSets(rows, spec, columns, resolveAggSortKind, limits = {},
|
|
|
31875
32164
|
resolveAggSortKind,
|
|
31876
32165
|
limits.evaluationContext
|
|
31877
32166
|
);
|
|
32167
|
+
materializeAggregateDependencies(
|
|
32168
|
+
outRow,
|
|
32169
|
+
groupRows,
|
|
32170
|
+
hiddenWindows,
|
|
32171
|
+
resolveAggSortKind,
|
|
32172
|
+
limits.evaluationContext
|
|
32173
|
+
);
|
|
32174
|
+
materializeAggregateDependencies(
|
|
32175
|
+
outRow,
|
|
32176
|
+
groupRows,
|
|
32177
|
+
columns.filter((column) => column.type === "WINDOW_COL"),
|
|
32178
|
+
resolveAggSortKind,
|
|
32179
|
+
limits.evaluationContext
|
|
32180
|
+
);
|
|
31878
32181
|
attachGroupingRowMeta(outRow, includedCanonicalIds);
|
|
31879
32182
|
result.push(outRow);
|
|
31880
32183
|
}
|
|
@@ -31887,6 +32190,10 @@ function groupingItemValue(item, row) {
|
|
|
31887
32190
|
}
|
|
31888
32191
|
function materializeAggregateColumns(outRow, groupRows, columns, resolveAggSortKind, evaluationContext = {}) {
|
|
31889
32192
|
for (const [columnIndex, col] of columns.entries()) {
|
|
32193
|
+
if (containsHiddenWindowRef(col)) {
|
|
32194
|
+
materializeAggregateDependencies(outRow, groupRows, col, resolveAggSortKind, evaluationContext);
|
|
32195
|
+
continue;
|
|
32196
|
+
}
|
|
31890
32197
|
if (col.type === "AGGREGATE") {
|
|
31891
32198
|
const syntheticKey = aggregateSyntheticName(col.func, col.distinct, col.arg);
|
|
31892
32199
|
const value = String(evalAggregate(
|
|
@@ -31963,6 +32270,14 @@ function materializeAggregateColumns(outRow, groupRows, columns, resolveAggSortK
|
|
|
31963
32270
|
}
|
|
31964
32271
|
}
|
|
31965
32272
|
}
|
|
32273
|
+
function containsHiddenWindowRef(node) {
|
|
32274
|
+
if (node === null || typeof node !== "object") return false;
|
|
32275
|
+
if (Array.isArray(node)) return node.some(containsHiddenWindowRef);
|
|
32276
|
+
const value = node;
|
|
32277
|
+
if (value["hiddenWindowRef"] === true) return true;
|
|
32278
|
+
if (value["type"] === "SELECT" || value["type"] === "SCALAR_SUBQUERY") return false;
|
|
32279
|
+
return Object.values(value).some(containsHiddenWindowRef);
|
|
32280
|
+
}
|
|
31966
32281
|
function caseMaterializedKey(alias, columnIndex) {
|
|
31967
32282
|
return alias ?? `__ksql_case_column_${columnIndex}`;
|
|
31968
32283
|
}
|
|
@@ -32179,7 +32494,7 @@ function aggArithDefaultKey(node) {
|
|
|
32179
32494
|
}
|
|
32180
32495
|
function resolveAggregateArgSemantics(arg, resolver) {
|
|
32181
32496
|
if (arg.type === "FIELD_REF") return resolver?.(toAggregateFieldRef(arg.field)) ?? "string";
|
|
32182
|
-
if (arg.type === "FIELD") return resolver?.(arg) ?? "string";
|
|
32497
|
+
if (arg.type === "FIELD") return arg.aggregateRef ? aggregateResultSemantics(arg.aggregateRef, resolver) : resolver?.(arg) ?? "string";
|
|
32183
32498
|
if (arg.type === "NUMBER" || arg.type === "ARITH" || arg.type === "SCALAR_ARITH") return "number";
|
|
32184
32499
|
if (arg.type === "STRING" || arg.type === "CONCAT_OP" || arg.type === "VARIABLE") return "string";
|
|
32185
32500
|
if (arg.type === "STRING_FUNC") {
|
|
@@ -32405,14 +32720,15 @@ function buildOrderByAliasEvaluator(columns, scalarCache, resolveFieldType, reso
|
|
|
32405
32720
|
return resolved === void 0 ? void 0 : evaluators.get(resolved)?.(row);
|
|
32406
32721
|
};
|
|
32407
32722
|
}
|
|
32408
|
-
function applyWindow(rows, columns, optionOrders, sortKinds, fieldSemantics2, resolveAggSortKind, evaluationContext = {}) {
|
|
32723
|
+
function applyWindow(rows, columns, optionOrders, sortKinds, fieldSemantics2, resolveAggSortKind, evaluationContext = {}, hiddenWindows = []) {
|
|
32409
32724
|
const windows = columns.map((column, columnIndex) => ({ column, columnIndex })).filter((item) => item.column.type === "WINDOW_COL");
|
|
32725
|
+
windows.push(...hiddenWindows.map((column) => ({ column, columnIndex: null })));
|
|
32410
32726
|
if (rows.length === 0 || windows.length === 0) return rows;
|
|
32411
32727
|
for (let index = 0; index < rows.length; index++) rows[index] = asProcessingRow(rows[index]);
|
|
32412
32728
|
for (const { column: window, columnIndex } of windows) {
|
|
32413
32729
|
const partitions = /* @__PURE__ */ new Map();
|
|
32414
32730
|
for (const row of rows) {
|
|
32415
|
-
const key = JSON.stringify(window.partitionBy.map((ref) =>
|
|
32731
|
+
const key = JSON.stringify(window.partitionBy.map((ref) => resolveWindowPartitionKey(row, ref)));
|
|
32416
32732
|
const partition = partitions.get(key);
|
|
32417
32733
|
if (partition) partition.push(row);
|
|
32418
32734
|
else partitions.set(key, [row]);
|
|
@@ -32462,7 +32778,7 @@ function applyWindow(rows, columns, optionOrders, sortKinds, fieldSemantics2, re
|
|
|
32462
32778
|
function evaluateValueWindowArg(arg, row, evaluationContext = {}) {
|
|
32463
32779
|
const value = evalScalarValueExprNullable(
|
|
32464
32780
|
arg,
|
|
32465
|
-
|
|
32781
|
+
havingEvaluationRow(row),
|
|
32466
32782
|
void 0,
|
|
32467
32783
|
void 0,
|
|
32468
32784
|
evaluationContext
|
|
@@ -32493,7 +32809,7 @@ function applyAggregateWindow(window, columnIndex, sortedResult, resolveAggSortK
|
|
|
32493
32809
|
const values = window.arg.type === "WILDCARD" ? null : aggregateRowValues(
|
|
32494
32810
|
window.aggFunc,
|
|
32495
32811
|
window.arg,
|
|
32496
|
-
sorted.map((item) => item.row),
|
|
32812
|
+
sorted.map((item) => havingEvaluationRow(item.row)),
|
|
32497
32813
|
evaluationContext
|
|
32498
32814
|
);
|
|
32499
32815
|
const comparison = window.arg.type === "WILDCARD" ? void 0 : resolveAggregateArgSemantics(window.arg, resolveAggSortKind);
|
|
@@ -32546,9 +32862,10 @@ function applyAggregateWindow(window, columnIndex, sortedResult, resolveAggSortK
|
|
|
32546
32862
|
setMaterializedSelectValue(sorted[index].row, columnIndex, output[index], [window.alias]);
|
|
32547
32863
|
}
|
|
32548
32864
|
}
|
|
32549
|
-
function
|
|
32865
|
+
function resolveWindowPartitionKey(row, ref) {
|
|
32866
|
+
if (ref.type === "GROUPING_REF") return evalGroupingRef(ref, row);
|
|
32550
32867
|
const name = ref.tableAlias ? `${ref.tableAlias}.${ref.field}` : ref.field;
|
|
32551
|
-
return resolveFieldRef(
|
|
32868
|
+
return resolveFieldRef(havingEvaluationRow(row), name);
|
|
32552
32869
|
}
|
|
32553
32870
|
function applyLimit(rows, limit, offset) {
|
|
32554
32871
|
const start = offset ?? 0;
|
|
@@ -32556,7 +32873,8 @@ function applyLimit(rows, limit, offset) {
|
|
|
32556
32873
|
return rows.slice(start, start + limit);
|
|
32557
32874
|
}
|
|
32558
32875
|
function evaluateSelectColumnValue(column, row, columnIndex, context = {}) {
|
|
32559
|
-
const
|
|
32876
|
+
const hasHiddenWindow = containsHiddenWindowRef(column);
|
|
32877
|
+
const sourceRow = hasHiddenWindow ? havingEvaluationRow(row) : sourceRowForEvaluation(row);
|
|
32560
32878
|
switch (column.type) {
|
|
32561
32879
|
case "VARIABLE_COL":
|
|
32562
32880
|
throw new Error(`internal error: unresolved SELECT variable @${column.name}`);
|
|
@@ -32587,9 +32905,9 @@ function evaluateSelectColumnValue(column, row, columnIndex, context = {}) {
|
|
|
32587
32905
|
return getMaterializedSelectValue(row, columnIndex) ?? getMaterializedLookupValue(row, source) ?? getLegacyMaterializedValue(row, source) ?? "0";
|
|
32588
32906
|
}
|
|
32589
32907
|
case "ARITH_COL":
|
|
32590
|
-
return containsAggregate2(column.expr) ? getMaterializedSelectValue(row, columnIndex) ?? getMaterializedLookupValue(row, column.alias ?? arithColDefaultKey(column.expr)) ?? "" : String(evalArithExpr(column.expr, sourceRow, context.evaluationContext));
|
|
32908
|
+
return containsAggregate2(column.expr) && !hasHiddenWindow ? getMaterializedSelectValue(row, columnIndex) ?? getMaterializedLookupValue(row, column.alias ?? arithColDefaultKey(column.expr)) ?? "" : String(evalArithExpr(column.expr, sourceRow, context.evaluationContext));
|
|
32591
32909
|
case "CASE_COL":
|
|
32592
|
-
return containsAggregate2(column.expr) ? getMaterializedSelectValue(row, columnIndex) ?? getMaterializedLookupValue(row, caseMaterializedKey(column.alias, columnIndex)) ?? getLegacyMaterializedValue(row, caseMaterializedKey(column.alias, columnIndex)) ?? "" : evalCaseWhen(
|
|
32910
|
+
return containsAggregate2(column.expr) && !hasHiddenWindow ? getMaterializedSelectValue(row, columnIndex) ?? getMaterializedLookupValue(row, caseMaterializedKey(column.alias, columnIndex)) ?? getLegacyMaterializedValue(row, caseMaterializedKey(column.alias, columnIndex)) ?? "" : evalCaseWhen(
|
|
32593
32911
|
column.expr,
|
|
32594
32912
|
sourceRow,
|
|
32595
32913
|
context.resolveFieldType,
|
|
@@ -32600,7 +32918,7 @@ function evaluateSelectColumnValue(column, row, columnIndex, context = {}) {
|
|
|
32600
32918
|
return evalGroupingRef(column.ref, row);
|
|
32601
32919
|
case "STRFUNC_COL": {
|
|
32602
32920
|
const source = stringFuncDefaultKey(column.expr);
|
|
32603
|
-
return hasAggregateInStringFuncExpr2(column.expr) ? getMaterializedSelectValue(row, columnIndex) ?? getMaterializedLookupValue(row, column.alias ?? source) ?? getMaterializedLookupValue(row, source) ?? getLegacyMaterializedValue(row, column.alias ?? source) ?? getLegacyMaterializedValue(row, source) ?? evalStringFunc(
|
|
32921
|
+
return hasAggregateInStringFuncExpr2(column.expr) && !hasHiddenWindow ? getMaterializedSelectValue(row, columnIndex) ?? getMaterializedLookupValue(row, column.alias ?? source) ?? getMaterializedLookupValue(row, source) ?? getLegacyMaterializedValue(row, column.alias ?? source) ?? getLegacyMaterializedValue(row, source) ?? evalStringFunc(
|
|
32604
32922
|
column.expr,
|
|
32605
32923
|
sourceRow,
|
|
32606
32924
|
context.resolveFieldType,
|
|
@@ -32616,7 +32934,7 @@ function evaluateSelectColumnValue(column, row, columnIndex, context = {}) {
|
|
|
32616
32934
|
}
|
|
32617
32935
|
case "SCALAR_VALUE_COL": {
|
|
32618
32936
|
const source = scalarValueDefaultKey(column.expr);
|
|
32619
|
-
return scalarValueHasAggregate2(column.expr) ? getMaterializedSelectValue(row, columnIndex) ?? getMaterializedLookupValue(row, column.alias ?? source) ?? getMaterializedLookupValue(row, source) ?? getLegacyMaterializedValue(row, column.alias ?? source) ?? getLegacyMaterializedValue(row, source) ?? "" : String(evalScalarValueExpr(
|
|
32937
|
+
return scalarValueHasAggregate2(column.expr) && !hasHiddenWindow ? getMaterializedSelectValue(row, columnIndex) ?? getMaterializedLookupValue(row, column.alias ?? source) ?? getMaterializedLookupValue(row, source) ?? getLegacyMaterializedValue(row, column.alias ?? source) ?? getLegacyMaterializedValue(row, source) ?? "" : String(evalScalarValueExpr(
|
|
32620
32938
|
column.expr,
|
|
32621
32939
|
sourceRow,
|
|
32622
32940
|
context.resolveFieldType,
|
|
@@ -33038,9 +33356,33 @@ function mergeKnownColumns(left, right, rows) {
|
|
|
33038
33356
|
...Object.keys(rows[0] ?? {})
|
|
33039
33357
|
])];
|
|
33040
33358
|
}
|
|
33041
|
-
function deriveOutputOrderSemantics(columns, resolveAggSortKind) {
|
|
33359
|
+
function deriveOutputOrderSemantics(columns, resolveAggSortKind, hiddenWindows = []) {
|
|
33042
33360
|
const result = /* @__PURE__ */ new Map();
|
|
33361
|
+
const hiddenSemantics = new Map(hiddenWindows.map((window) => [
|
|
33362
|
+
window.alias,
|
|
33363
|
+
windowResultSemantics(window, resolveAggSortKind)
|
|
33364
|
+
]));
|
|
33365
|
+
const resolveExpressionField = (field) => hiddenSemantics.get(field.field) ?? resolveAggSortKind?.(field);
|
|
33043
33366
|
for (const column of columns) {
|
|
33367
|
+
if (column.type === "AGGREGATE") {
|
|
33368
|
+
result.set(
|
|
33369
|
+
aggregateSyntheticName(column.func, column.distinct, column.arg),
|
|
33370
|
+
aggregateResultSemantics({
|
|
33371
|
+
type: "AGG_REF",
|
|
33372
|
+
func: column.func,
|
|
33373
|
+
distinct: column.distinct,
|
|
33374
|
+
arg: column.arg,
|
|
33375
|
+
...column.separator !== void 0 ? { separator: column.separator } : {}
|
|
33376
|
+
}, resolveAggSortKind)
|
|
33377
|
+
);
|
|
33378
|
+
}
|
|
33379
|
+
if (column.type === "WINDOW_COL") {
|
|
33380
|
+
for (const item of column.orderBy) {
|
|
33381
|
+
if (item.key.type === "FIELD_NAME" && item.key.aggregateRef) {
|
|
33382
|
+
result.set(item.key.name, aggregateResultSemantics(item.key.aggregateRef, resolveAggSortKind));
|
|
33383
|
+
}
|
|
33384
|
+
}
|
|
33385
|
+
}
|
|
33044
33386
|
if (!("alias" in column) || !column.alias) continue;
|
|
33045
33387
|
if (column.type === "ARITH_COL" || column.type === "ARITH_AGG_COL") {
|
|
33046
33388
|
result.set(column.alias, syntheticSemantics("number"));
|
|
@@ -33057,17 +33399,29 @@ function deriveOutputOrderSemantics(columns, resolveAggSortKind) {
|
|
|
33057
33399
|
} else if (column.func === "GROUP_CONCAT") {
|
|
33058
33400
|
result.set(column.alias, syntheticSemantics("string"));
|
|
33059
33401
|
}
|
|
33060
|
-
} else if (column.type === "LITERAL_COL" || column.type === "
|
|
33402
|
+
} else if (column.type === "LITERAL_COL" || column.type === "SCALAR_SUBQUERY_COL") {
|
|
33061
33403
|
result.set(column.alias, syntheticSemantics("string"));
|
|
33404
|
+
} else if (column.type === "CASE_COL" || column.type === "SCALAR_VALUE_COL") {
|
|
33405
|
+
result.set(column.alias, syntheticSemantics(expressionSemanticKind(column.expr, resolveExpressionField)));
|
|
33062
33406
|
} else if (column.type === "STRFUNC_COL") {
|
|
33063
33407
|
result.set(column.alias, syntheticSemantics(stringFunctionSemanticKind(
|
|
33064
33408
|
column.expr,
|
|
33065
|
-
|
|
33409
|
+
resolveExpressionField
|
|
33066
33410
|
)));
|
|
33067
33411
|
}
|
|
33068
33412
|
}
|
|
33069
33413
|
return result;
|
|
33070
33414
|
}
|
|
33415
|
+
function windowResultSemantics(window, resolveAggSortKind) {
|
|
33416
|
+
if (isRankingWindow(window) || isAggregateWindow(window) && (window.aggFunc === "COUNT" || window.aggFunc === "SUM" || window.aggFunc === "AVG")) {
|
|
33417
|
+
return syntheticSemantics("number");
|
|
33418
|
+
}
|
|
33419
|
+
if ((isAggregateWindow(window) || isValueWindow(window)) && window.arg.type !== "WILDCARD") {
|
|
33420
|
+
const semantics = resolveAggregateArgSemantics(window.arg, resolveAggSortKind) ?? "string";
|
|
33421
|
+
return typeof semantics === "string" ? syntheticSemantics(semantics) : semantics;
|
|
33422
|
+
}
|
|
33423
|
+
return syntheticSemantics("string");
|
|
33424
|
+
}
|
|
33071
33425
|
function runFullScan(input) {
|
|
33072
33426
|
const {
|
|
33073
33427
|
stmt,
|
|
@@ -33090,8 +33444,17 @@ function runFullScan(input) {
|
|
|
33090
33444
|
warnings,
|
|
33091
33445
|
evaluationContext
|
|
33092
33446
|
} = input;
|
|
33093
|
-
const effectiveOrderSemantics = deriveOutputOrderSemantics(
|
|
33447
|
+
const effectiveOrderSemantics = deriveOutputOrderSemantics(
|
|
33448
|
+
stmt.columns,
|
|
33449
|
+
aggregateSortKindResolver,
|
|
33450
|
+
stmt.hiddenWindows
|
|
33451
|
+
);
|
|
33094
33452
|
for (const [key, value] of orderSemantics ?? []) effectiveOrderSemantics.set(key, value);
|
|
33453
|
+
const hiddenWindowSemantics = new Map((stmt.hiddenWindows ?? []).map((window) => [
|
|
33454
|
+
window.alias,
|
|
33455
|
+
windowResultSemantics(window, aggregateSortKindResolver)
|
|
33456
|
+
]));
|
|
33457
|
+
const expressionFieldSemanticsResolver = (field) => hiddenWindowSemantics.get(field.field) ?? fieldSemanticsResolver?.(field);
|
|
33095
33458
|
let rows = [];
|
|
33096
33459
|
const mainAlias = stmt.from.alias;
|
|
33097
33460
|
const mainRecords = tables.get(mainAlias) ?? tables.get(null) ?? [];
|
|
@@ -33136,9 +33499,13 @@ function runFullScan(input) {
|
|
|
33136
33499
|
stmt.columns,
|
|
33137
33500
|
aggregateSortKindResolver,
|
|
33138
33501
|
{ maxGeneratedRows: B65_MAX_GENERATED_ROWS, evaluationContext },
|
|
33139
|
-
stmt.having
|
|
33502
|
+
stmt.having,
|
|
33503
|
+
stmt.hiddenWindows
|
|
33140
33504
|
);
|
|
33141
|
-
} else if (grouping.type === "PLAIN" || hasAggregateColumns(
|
|
33505
|
+
} else if (grouping.type === "PLAIN" || hasAggregateColumns([
|
|
33506
|
+
...stmt.columns,
|
|
33507
|
+
...stmt.hiddenWindows ?? []
|
|
33508
|
+
])) {
|
|
33142
33509
|
rows = applyGroupBy(
|
|
33143
33510
|
rows,
|
|
33144
33511
|
grouping.type === "PLAIN" ? grouping.allItems : [],
|
|
@@ -33151,7 +33518,8 @@ function runFullScan(input) {
|
|
|
33151
33518
|
resolveFieldSemantics: fieldSemanticsResolver,
|
|
33152
33519
|
evaluationContext
|
|
33153
33520
|
},
|
|
33154
|
-
stmt.having
|
|
33521
|
+
stmt.having,
|
|
33522
|
+
stmt.hiddenWindows
|
|
33155
33523
|
);
|
|
33156
33524
|
}
|
|
33157
33525
|
warnOnUnresolvedAggregateComparisons(stmt.columns, rows, warnings);
|
|
@@ -33171,7 +33539,8 @@ function runFullScan(input) {
|
|
|
33171
33539
|
sortKinds,
|
|
33172
33540
|
effectiveOrderSemantics,
|
|
33173
33541
|
aggregateSortKindResolver,
|
|
33174
|
-
evaluationContext
|
|
33542
|
+
evaluationContext,
|
|
33543
|
+
stmt.hiddenWindows
|
|
33175
33544
|
);
|
|
33176
33545
|
if (stmt.distinct) {
|
|
33177
33546
|
rows = applyDistinct(
|
|
@@ -33179,7 +33548,7 @@ function runFullScan(input) {
|
|
|
33179
33548
|
stmt.columns,
|
|
33180
33549
|
scalarCache,
|
|
33181
33550
|
fieldTypeResolver,
|
|
33182
|
-
|
|
33551
|
+
expressionFieldSemanticsResolver,
|
|
33183
33552
|
evaluationContext
|
|
33184
33553
|
);
|
|
33185
33554
|
}
|
|
@@ -33193,7 +33562,7 @@ function runFullScan(input) {
|
|
|
33193
33562
|
stmt.columns,
|
|
33194
33563
|
scalarCache,
|
|
33195
33564
|
fieldTypeResolver,
|
|
33196
|
-
|
|
33565
|
+
expressionFieldSemanticsResolver,
|
|
33197
33566
|
evaluationContext
|
|
33198
33567
|
),
|
|
33199
33568
|
evaluationContext
|
|
@@ -33205,7 +33574,7 @@ function runFullScan(input) {
|
|
|
33205
33574
|
scalarCache,
|
|
33206
33575
|
fieldTypeResolver,
|
|
33207
33576
|
sourceColumns2,
|
|
33208
|
-
|
|
33577
|
+
expressionFieldSemanticsResolver,
|
|
33209
33578
|
hiddenQualifiedAliases,
|
|
33210
33579
|
evaluationContext
|
|
33211
33580
|
);
|
|
@@ -36820,15 +37189,46 @@ async function normalizeSelectChoiceEquality(stmt, client, cacheContext, materia
|
|
|
36820
37189
|
}
|
|
36821
37190
|
return { resolver, rewrites: normalization.rewrites };
|
|
36822
37191
|
}
|
|
37192
|
+
function selectWindowColumns(stmt) {
|
|
37193
|
+
return [
|
|
37194
|
+
...stmt.columns.filter((column) => column.type === "WINDOW_COL"),
|
|
37195
|
+
...stmt.hiddenWindows ?? []
|
|
37196
|
+
];
|
|
37197
|
+
}
|
|
36823
37198
|
function hasDefaultRangeAggregateWindow(stmt) {
|
|
36824
|
-
return stmt.
|
|
36825
|
-
(column) => column.
|
|
37199
|
+
return selectWindowColumns(stmt).some(
|
|
37200
|
+
(column) => column.windowKind === "AGGREGATE" && column.orderBy.length > 0 && column.frame?.source === "DEFAULT"
|
|
36826
37201
|
);
|
|
36827
37202
|
}
|
|
36828
37203
|
function hasWindowNeedingOrderProof(stmt) {
|
|
36829
|
-
return hasDefaultRangeAggregateWindow(stmt) || stmt.
|
|
37204
|
+
return hasDefaultRangeAggregateWindow(stmt) || selectWindowColumns(stmt).some((column) => column.windowKind === "VALUE");
|
|
37205
|
+
}
|
|
37206
|
+
function sameSelectGroupOrderIsUnique(stmt, orderBy) {
|
|
37207
|
+
const grouping = normalizeGroupingSpec(stmt);
|
|
37208
|
+
if (grouping.type !== "PLAIN" || grouping.allItems.length === 0) return false;
|
|
37209
|
+
return grouping.allItems.every((groupKey) => {
|
|
37210
|
+
if (orderBy.some((item) => {
|
|
37211
|
+
if (groupKey.type === "FIELD_NAME" && item.key.type === "FIELD_NAME") {
|
|
37212
|
+
return item.key.name === groupKey.name;
|
|
37213
|
+
}
|
|
37214
|
+
return groupKey.type === item.key.type && JSON.stringify(groupKey) === JSON.stringify(item.key);
|
|
37215
|
+
})) return true;
|
|
37216
|
+
return stmt.columns.some((column) => {
|
|
37217
|
+
if (!("alias" in column) || column.alias === null) return false;
|
|
37218
|
+
if (!orderBy.some((item) => item.key.type === "FIELD_NAME" && item.key.name === column.alias)) return false;
|
|
37219
|
+
if (groupKey.type === "FIELD_NAME" && column.type === "FIELD") return column.field === groupKey.name;
|
|
37220
|
+
if (groupKey.type === "ARITH_KEY" && column.type === "ARITH_COL") {
|
|
37221
|
+
return JSON.stringify(groupKey.expr) === JSON.stringify(column.expr);
|
|
37222
|
+
}
|
|
37223
|
+
if (groupKey.type === "FUNC_KEY" && column.type === "STRFUNC_COL") {
|
|
37224
|
+
return JSON.stringify(groupKey.expr) === JSON.stringify(column.expr);
|
|
37225
|
+
}
|
|
37226
|
+
return false;
|
|
37227
|
+
});
|
|
37228
|
+
});
|
|
36830
37229
|
}
|
|
36831
37230
|
function canProveTotalWindowOrder(stmt, orderBy, resolveField2, context, generatedColumn) {
|
|
37231
|
+
if (sameSelectGroupOrderIsUnique(stmt, orderBy)) return true;
|
|
36832
37232
|
if (generatedColumn !== void 0 && stmt.joins.length === 0 && stmt.from.cteName !== null) {
|
|
36833
37233
|
return orderBy.some((item) => {
|
|
36834
37234
|
if (item.key.type !== "FIELD_NAME") return false;
|
|
@@ -36951,9 +37351,7 @@ function formatWhereCapabilityFailure(result) {
|
|
|
36951
37351
|
return details || "reason=WHERE_UNSUPPORTED";
|
|
36952
37352
|
}
|
|
36953
37353
|
function hasCanonicalOrder(stmt) {
|
|
36954
|
-
return stmt.orderBy.length > 0 || stmt.
|
|
36955
|
-
(column) => column.type === "WINDOW_COL" && column.orderBy.length > 0
|
|
36956
|
-
);
|
|
37354
|
+
return stmt.orderBy.length > 0 || selectWindowColumns(stmt).some((column) => column.orderBy.length > 0);
|
|
36957
37355
|
}
|
|
36958
37356
|
async function resolveDmlWhereCapability(stmt, client, cacheContext) {
|
|
36959
37357
|
if (stmt.subtableCode || stmt.type === "UPDATE" && stmt.from != null) {
|
|
@@ -37411,7 +37809,7 @@ function arithHasFieldRef(node) {
|
|
|
37411
37809
|
`InternalError: unresolved arithmetic variable @${node.name} reached SELECT planning.`
|
|
37412
37810
|
);
|
|
37413
37811
|
}
|
|
37414
|
-
if (node.type === "FIELD_REF") return true;
|
|
37812
|
+
if (node.type === "FIELD_REF") return node.hiddenWindowRef !== true;
|
|
37415
37813
|
if (node.type === "ARITH") return arithHasFieldRef(node.left) || arithHasFieldRef(node.right);
|
|
37416
37814
|
if (node.type === "STRING_FUNC") return stringFuncHasFieldRef(node);
|
|
37417
37815
|
return false;
|
|
@@ -37423,7 +37821,7 @@ function stringFuncArgHasFieldRef(arg) {
|
|
|
37423
37821
|
return scalarValueHasFieldRef(arg);
|
|
37424
37822
|
}
|
|
37425
37823
|
function scalarValueHasFieldRef(expr) {
|
|
37426
|
-
if (expr.type === "FIELD") return true;
|
|
37824
|
+
if (expr.type === "FIELD") return expr.hiddenWindowRef !== true;
|
|
37427
37825
|
if (expr.type === "STRING_FUNC") return stringFuncHasFieldRef(expr);
|
|
37428
37826
|
if (expr.type === "SCALAR_ARITH" || expr.type === "CONCAT_OP") {
|
|
37429
37827
|
return scalarValueHasFieldRef(expr.left) || scalarValueHasFieldRef(expr.right);
|
|
@@ -37481,7 +37879,8 @@ function executeNoFromSelect(stmt, options) {
|
|
|
37481
37879
|
void 0,
|
|
37482
37880
|
void 0,
|
|
37483
37881
|
void 0,
|
|
37484
|
-
statementEvaluationContext(options)
|
|
37882
|
+
statementEvaluationContext(options),
|
|
37883
|
+
stmt.hiddenWindows
|
|
37485
37884
|
);
|
|
37486
37885
|
const { rows: projected, columns } = project(
|
|
37487
37886
|
windowed,
|
|
@@ -37760,7 +38159,7 @@ function bindProjectedNamesForSelect(stmt, materializedTables, physicalMayHave)
|
|
|
37760
38159
|
}
|
|
37761
38160
|
for (const child of Object.values(value)) visit(child, allowSelectAlias);
|
|
37762
38161
|
};
|
|
37763
|
-
for (const column of stmt.columns) visit(column);
|
|
38162
|
+
for (const column of [...stmt.columns, ...stmt.hiddenWindows ?? []]) visit(column);
|
|
37764
38163
|
visit(stmt.where);
|
|
37765
38164
|
visit(stmt.having, true);
|
|
37766
38165
|
visit(stmt.grouping);
|
|
@@ -37775,9 +38174,9 @@ function bindProjectedNamesForSelect(stmt, materializedTables, physicalMayHave)
|
|
|
37775
38174
|
if (item.key.type === "FIELD_NAME") item.key.name = resolveText(item.key.name, true);
|
|
37776
38175
|
else visit(item.key);
|
|
37777
38176
|
}
|
|
37778
|
-
for (const column of stmt
|
|
37779
|
-
if (column.type !== "WINDOW_COL") continue;
|
|
38177
|
+
for (const column of selectWindowColumns(stmt)) {
|
|
37780
38178
|
for (const ref of column.partitionBy) {
|
|
38179
|
+
if (ref.type !== "FIELD") continue;
|
|
37781
38180
|
ref.field = resolveReference(ref.field, ref.tableAlias, false);
|
|
37782
38181
|
}
|
|
37783
38182
|
for (const item of column.orderBy) {
|
|
@@ -38484,7 +38883,7 @@ function mergeExpressionColumnMeta(candidates) {
|
|
|
38484
38883
|
}
|
|
38485
38884
|
function inferAggregateArgMeta(arg, resolveField2) {
|
|
38486
38885
|
if (arg.type === "FIELD_REF") return resolveField2(aggregateFieldRef(arg.field)) ?? unknownStringColumnMeta();
|
|
38487
|
-
if (arg.type === "FIELD") return resolveField2(arg) ?? unknownStringColumnMeta();
|
|
38886
|
+
if (arg.type === "FIELD") return arg.aggregateRef ? aggregateResultColumnMeta(arg.aggregateRef, resolveField2) : resolveField2(arg) ?? unknownStringColumnMeta();
|
|
38488
38887
|
if (arg.type === "NUMBER" || arg.type === "ARITH" || arg.type === "SCALAR_ARITH") return syntheticColumnMeta("number");
|
|
38489
38888
|
if (arg.type === "STRING" || arg.type === "CONCAT_OP" || arg.type === "VARIABLE") return syntheticColumnMeta("string");
|
|
38490
38889
|
if (arg.type === "STRING_FUNC") return stringFunctionColumnMeta(arg, resolveField2);
|
|
@@ -38492,6 +38891,15 @@ function inferAggregateArgMeta(arg, resolveField2) {
|
|
|
38492
38891
|
if (arg.elseResult) results.push(caseResultColumnMeta(arg.elseResult, resolveField2));
|
|
38493
38892
|
return mergeExpressionColumnMeta(results);
|
|
38494
38893
|
}
|
|
38894
|
+
function aggregateResultColumnMeta(ref, resolveField2) {
|
|
38895
|
+
if (ref.func === "COUNT" || ref.func === "SUM" || ref.func === "AVG" || ref.func === "STDDEV_POP" || ref.func === "STDDEV_SAMP" || ref.func === "VAR_POP" || ref.func === "VAR_SAMP" || ref.func === "MEDIAN") {
|
|
38896
|
+
return syntheticColumnMeta("number");
|
|
38897
|
+
}
|
|
38898
|
+
if (ref.func === "GROUP_CONCAT" || ref.func === "MODE" || ref.arg.type === "WILDCARD") {
|
|
38899
|
+
return syntheticColumnMeta("string");
|
|
38900
|
+
}
|
|
38901
|
+
return inferAggregateArgMeta(ref.arg, resolveField2);
|
|
38902
|
+
}
|
|
38495
38903
|
function inferWindowColumnMeta(column, resolveField2) {
|
|
38496
38904
|
if (column.windowKind === "VALUE") {
|
|
38497
38905
|
return inferAggregateArgMeta(column.arg, resolveField2);
|
|
@@ -38508,7 +38916,7 @@ function withDisplayName(meta, displayName) {
|
|
|
38508
38916
|
return { ...meta ?? {}, displayName };
|
|
38509
38917
|
}
|
|
38510
38918
|
function selectNeedsSourceColumnMeta(stmt) {
|
|
38511
|
-
return stmt.columns.some(
|
|
38919
|
+
return (stmt.hiddenWindows?.length ?? 0) > 0 || stmt.columns.some(
|
|
38512
38920
|
(column) => column.type === "FIELD" || column.type === "WILDCARD" || column.type === "PARENT_WILDCARD" || column.type === "CASE_COL" || column.type === "AGGREGATE" && (column.func === "MIN" || column.func === "MAX" || column.func === "MODE") || column.type === "WINDOW_COL" && (column.windowKind === "VALUE" || column.windowKind === "AGGREGATE" && (column.aggFunc === "MIN" || column.aggFunc === "MAX"))
|
|
38513
38921
|
);
|
|
38514
38922
|
}
|
|
@@ -38566,6 +38974,11 @@ async function inferSelectColumnMeta(stmt, outputColumns, client, cacheContext,
|
|
|
38566
38974
|
return meta && publicSourceApp !== void 0 ? { ...meta, publicSourceApp } : meta;
|
|
38567
38975
|
};
|
|
38568
38976
|
const inferred = /* @__PURE__ */ new Map();
|
|
38977
|
+
const hiddenWindowMeta = new Map((stmt.hiddenWindows ?? []).map((window) => [
|
|
38978
|
+
window.alias,
|
|
38979
|
+
inferWindowColumnMeta(window, resolveField2)
|
|
38980
|
+
]));
|
|
38981
|
+
const resolveExpressionField = (ref) => ref.hiddenWindowRef ? hiddenWindowMeta.get(ref.field) : resolveField2(ref);
|
|
38569
38982
|
const hasWildcard = stmt.columns.some((column) => column.type === "WILDCARD" || column.type === "PARENT_WILDCARD");
|
|
38570
38983
|
if (stmt.columns.length === 1 && (stmt.columns[0].type === "WILDCARD" || stmt.columns[0].type === "PARENT_WILDCARD")) {
|
|
38571
38984
|
for (const output of outputColumns) {
|
|
@@ -38608,17 +39021,17 @@ async function inferSelectColumnMeta(stmt, outputColumns, client, cacheContext,
|
|
|
38608
39021
|
meta = syntheticColumnMeta("string");
|
|
38609
39022
|
} else if (column.type === "SCALAR_VALUE_COL") {
|
|
38610
39023
|
const expr = column.expr;
|
|
38611
|
-
if (expr.type === "STRING_FUNC") meta = stringFunctionColumnMeta(expr,
|
|
39024
|
+
if (expr.type === "STRING_FUNC") meta = stringFunctionColumnMeta(expr, resolveExpressionField);
|
|
38612
39025
|
else if (expr.type === "NUMBER" || expr.type === "SCALAR_ARITH") meta = syntheticColumnMeta("number");
|
|
38613
|
-
else if (expr.type === "FIELD") meta =
|
|
39026
|
+
else if (expr.type === "FIELD") meta = resolveExpressionField(expr);
|
|
38614
39027
|
else meta = syntheticColumnMeta("string");
|
|
38615
39028
|
} else if (column.type === "STRFUNC_COL") {
|
|
38616
|
-
meta = stringFunctionColumnMeta(column.expr,
|
|
39029
|
+
meta = stringFunctionColumnMeta(column.expr, resolveExpressionField);
|
|
38617
39030
|
} else if (column.type === "WINDOW_COL") {
|
|
38618
39031
|
meta = inferWindowColumnMeta(column, resolveField2);
|
|
38619
39032
|
} else if (column.type === "CASE_COL") {
|
|
38620
|
-
const results = column.expr.branches.map((branch) => caseResultColumnMeta(branch.result,
|
|
38621
|
-
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));
|
|
38622
39035
|
meta = mergeExpressionColumnMeta(results);
|
|
38623
39036
|
} else if (column.type === "SCALAR_SUBQUERY_COL") {
|
|
38624
39037
|
meta = unknownStringColumnMeta();
|
|
@@ -40277,7 +40690,7 @@ async function getSortKindMapByApp(appId, client, cacheContext) {
|
|
|
40277
40690
|
function orderByFieldNames(stmt) {
|
|
40278
40691
|
const items = [
|
|
40279
40692
|
...stmt.orderBy,
|
|
40280
|
-
...stmt.
|
|
40693
|
+
...selectWindowColumns(stmt).flatMap((column) => column.orderBy)
|
|
40281
40694
|
];
|
|
40282
40695
|
return [...new Set(items.flatMap(
|
|
40283
40696
|
(item) => item.key.type === "FIELD_NAME" ? [item.key.name] : []
|
|
@@ -40327,6 +40740,11 @@ async function buildOrderSemanticsForSelect(stmt, client, cacheContext, material
|
|
|
40327
40740
|
return matches.length === 1 ? matches[0] : void 0;
|
|
40328
40741
|
};
|
|
40329
40742
|
const aliasSemantics = /* @__PURE__ */ new Map();
|
|
40743
|
+
const hiddenWindowMeta = new Map((stmt.hiddenWindows ?? []).map((window) => [
|
|
40744
|
+
window.alias,
|
|
40745
|
+
inferWindowColumnMeta(window, resolveField2)
|
|
40746
|
+
]));
|
|
40747
|
+
const resolveExpressionField = (ref) => ref.hiddenWindowRef ? hiddenWindowMeta.get(ref.field) : resolveField2(ref);
|
|
40330
40748
|
for (const column of stmt.columns) {
|
|
40331
40749
|
if (!("alias" in column) || !column.alias) continue;
|
|
40332
40750
|
let meta;
|
|
@@ -40337,12 +40755,18 @@ async function buildOrderSemanticsForSelect(stmt, client, cacheContext, material
|
|
|
40337
40755
|
meta = inferWindowColumnMeta(column, resolveField2);
|
|
40338
40756
|
} else if (column.type === "GROUPING_COL") {
|
|
40339
40757
|
meta = syntheticColumnMeta("number");
|
|
40340
|
-
} else if (column.type === "LITERAL_COL"
|
|
40341
|
-
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);
|
|
40342
40766
|
else if (column.type === "SCALAR_SUBQUERY_COL") meta = unknownStringColumnMeta();
|
|
40343
40767
|
else if (column.type === "CASE_COL") {
|
|
40344
|
-
const candidates = column.expr.branches.map((branch) => caseResultColumnMeta(branch.result,
|
|
40345
|
-
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));
|
|
40346
40770
|
meta = mergeExpressionColumnMeta(candidates);
|
|
40347
40771
|
} else if (column.type === "AGGREGATE") {
|
|
40348
40772
|
if (column.func === "MIN" || column.func === "MAX" || column.func === "MODE") {
|
|
@@ -40353,10 +40777,16 @@ async function buildOrderSemanticsForSelect(stmt, client, cacheContext, material
|
|
|
40353
40777
|
}
|
|
40354
40778
|
if (meta?.semantics) aliasSemantics.set(column.alias, meta.semantics);
|
|
40355
40779
|
}
|
|
40780
|
+
const aggregateOrderRefs = /* @__PURE__ */ new Map();
|
|
40781
|
+
for (const item of selectWindowColumns(stmt).flatMap((column) => column.orderBy)) {
|
|
40782
|
+
if (item.key.type === "FIELD_NAME" && item.key.aggregateRef) {
|
|
40783
|
+
aggregateOrderRefs.set(item.key.name, item.key.aggregateRef);
|
|
40784
|
+
}
|
|
40785
|
+
}
|
|
40356
40786
|
const result = /* @__PURE__ */ new Map();
|
|
40357
40787
|
for (const name of names) {
|
|
40358
40788
|
const resolvedAlias = resolveProjectedName(name, aliasSemantics.keys());
|
|
40359
|
-
const base = (resolvedAlias === void 0 ? void 0 : aliasSemantics.get(resolvedAlias)) ?? resolveField2(aggregateFieldRef(name))?.semantics;
|
|
40789
|
+
const base = (resolvedAlias === void 0 ? void 0 : aliasSemantics.get(resolvedAlias)) ?? (aggregateOrderRefs.has(name) ? aggregateResultColumnMeta(aggregateOrderRefs.get(name), resolveField2).semantics : void 0) ?? resolveField2(aggregateFieldRef(name))?.semantics;
|
|
40360
40790
|
if (!base) {
|
|
40361
40791
|
const ref = aggregateFieldRef(name);
|
|
40362
40792
|
if (ref.tableAlias === null && ambiguousFields.has(ref.field)) {
|
|
@@ -40379,9 +40809,7 @@ async function buildOrderSemanticsForSelect(stmt, client, cacheContext, material
|
|
|
40379
40809
|
return result;
|
|
40380
40810
|
}
|
|
40381
40811
|
async function buildOrderByMetaForSelect(stmt, client, cacheContext, materializedTables) {
|
|
40382
|
-
const hasWindowOrderBy = stmt.
|
|
40383
|
-
(column) => column.type === "WINDOW_COL" && column.orderBy.length > 0
|
|
40384
|
-
);
|
|
40812
|
+
const hasWindowOrderBy = selectWindowColumns(stmt).some((column) => column.orderBy.length > 0);
|
|
40385
40813
|
if (stmt.orderBy.length === 0 && !hasWindowOrderBy) {
|
|
40386
40814
|
return { optionOrders: /* @__PURE__ */ new Map(), sortKinds: /* @__PURE__ */ new Map(), semantics: /* @__PURE__ */ new Map() };
|
|
40387
40815
|
}
|
|
@@ -43606,7 +44034,7 @@ async function buildExplainWhereAnalysis(query, client, cacheContext, maxRecords
|
|
|
43606
44034
|
if (isConstantFalseWhere(select.where)) currentRows = 0;
|
|
43607
44035
|
else if (select.where !== null) currentRows = null;
|
|
43608
44036
|
const grouping = normalizeGroupingSpec(select);
|
|
43609
|
-
if (grouping.type !== "NONE" || select.distinct || select.having !== null || isAggregateQueryBlock(select) || select
|
|
44037
|
+
if (grouping.type !== "NONE" || select.distinct || select.having !== null || isAggregateQueryBlock(select) || selectWindowColumns(select).length > 0) {
|
|
43610
44038
|
currentRows = null;
|
|
43611
44039
|
}
|
|
43612
44040
|
if (currentRows !== null) {
|
|
@@ -43795,7 +44223,7 @@ async function buildExplainWhereAnalysis(query, client, cacheContext, maxRecords
|
|
|
43795
44223
|
}
|
|
43796
44224
|
const physicalApps = [select.from, ...select.joins.map((join3) => join3.table)].filter((table) => table.cteName === null).map((table) => table.appId);
|
|
43797
44225
|
const needsWhereSchema = whereNeedsFieldMetadata(select.where);
|
|
43798
|
-
if (needsWhereSchema || select.orderBy.length > 0 || select.
|
|
44226
|
+
if (needsWhereSchema || select.orderBy.length > 0 || selectWindowColumns(select).some((column) => column.orderBy.length > 0)) {
|
|
43799
44227
|
physicalApps.forEach((appId) => fieldApps.add(appId));
|
|
43800
44228
|
}
|
|
43801
44229
|
const { resolver, rewrites } = await normalizeSelectChoiceEquality(
|
|
@@ -43875,7 +44303,7 @@ async function buildExplainWhereAnalysis(query, client, cacheContext, maxRecords
|
|
|
43875
44303
|
joinKeyPlans.set(joinAlias, { plan, queries, additionalQuery, additionalRelation });
|
|
43876
44304
|
}
|
|
43877
44305
|
if (joinKeyPlans.size > 0) explainJoinKeyPrefilters.set(select, joinKeyPlans);
|
|
43878
|
-
if (select.orderBy.length > 0 || select.
|
|
44306
|
+
if (select.orderBy.length > 0 || selectWindowColumns(select).some((column) => column.orderBy.length > 0)) {
|
|
43879
44307
|
const meta = await buildOrderByMetaForSelect(select, tracedClient, cacheContext);
|
|
43880
44308
|
if (select.orderMode !== "KINTONE_NATIVE") {
|
|
43881
44309
|
for (const semantics of meta.semantics.values()) {
|
|
@@ -45191,7 +45619,7 @@ function buildSelectPlan(stmt, label, capabilities, orderPlans, plainGroupByPlan
|
|
|
45191
45619
|
const clauses = [];
|
|
45192
45620
|
if (column.partitionBy.length > 0) {
|
|
45193
45621
|
clauses.push(`PARTITION BY ${column.partitionBy.map(
|
|
45194
|
-
(ref) => ref.tableAlias ? `${ref.tableAlias}.${ref.field}` : ref.field
|
|
45622
|
+
(ref) => ref.type === "GROUPING_REF" ? `GROUPING(${ref.field.tableAlias ? `${ref.field.tableAlias}.` : ""}${ref.field.field})` : ref.tableAlias ? `${ref.tableAlias}.${ref.field}` : ref.field
|
|
45195
45623
|
).join(", ")}`);
|
|
45196
45624
|
}
|
|
45197
45625
|
if (column.orderBy.length > 0) {
|
|
@@ -45492,7 +45920,7 @@ function populateWithCrossJoinExplain(stmt) {
|
|
|
45492
45920
|
if (steps.length > 0) explainCrossJoinSteps.set(select, steps);
|
|
45493
45921
|
if (isConstantFalseWhere(select.where)) current = 0;
|
|
45494
45922
|
else if (select.where !== null) current = null;
|
|
45495
|
-
if (normalizeGroupingSpec(select).type !== "NONE" || select.distinct || select.having !== null || isAggregateQueryBlock(select) || select
|
|
45923
|
+
if (normalizeGroupingSpec(select).type !== "NONE" || select.distinct || select.having !== null || isAggregateQueryBlock(select) || selectWindowColumns(select).length > 0) return null;
|
|
45496
45924
|
if (current === null) return null;
|
|
45497
45925
|
current = Math.max(0, current - (select.offset ?? 0));
|
|
45498
45926
|
return select.limit === null ? current : Math.min(current, select.limit);
|
|
@@ -45652,7 +46080,7 @@ function collectFullScanReasons(stmt) {
|
|
|
45652
46080
|
r.push("DISTINCT \u3042\u308A");
|
|
45653
46081
|
if (hasAggregateColumns(stmt.columns))
|
|
45654
46082
|
r.push("\u96C6\u8A08\u95A2\u6570\uFF08COUNT / SUM \u7B49\uFF09\u3042\u308A");
|
|
45655
|
-
if (stmt
|
|
46083
|
+
if (selectWindowColumns(stmt).length > 0)
|
|
45656
46084
|
r.push("\u30A6\u30A3\u30F3\u30C9\u30A6\u95A2\u6570\u3042\u308A");
|
|
45657
46085
|
if (stmt.columns.some((c) => c.type === "SCALAR_SUBQUERY_COL"))
|
|
45658
46086
|
r.push("SELECT \u5217\u306B\u30B9\u30AB\u30E9\u30FC\u30B5\u30D6\u30AF\u30A8\u30EA");
|