@rex0220/kintone-sql-tools 3.42.0 → 3.44.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +0 -2
- package/dist-cli/ksql.js +1089 -790
- package/dist-engine/index.cjs +12 -12
- package/dist-engine/index.mjs +12 -12
- package/dist-engine/ksql-engine.umd.js +12 -12
- package/dist-engine/meta/bundle-baseline.json +10 -10
- package/dist-engine/meta/cjs.json +84 -46
- package/dist-engine/meta/esm.json +84 -46
- package/dist-engine/meta/umd.json +84 -46
- package/dist-mcp/ksql-mcp.js +886 -584
- package/dist-mcpb/ksql-mcp.mcpb +0 -0
- package/package.json +1 -1
package/dist-mcp/ksql-mcp.js
CHANGED
|
@@ -30555,6 +30555,7 @@ function arithLabel(node, topLevel = false) {
|
|
|
30555
30555
|
function fieldValueLabel(value) {
|
|
30556
30556
|
if (value.type === "FIELD") return value.tableAlias ? `${value.tableAlias}.${value.field}` : value.field;
|
|
30557
30557
|
if (value.type === "FUNC_FIELD") return stringFuncLabel(value.expr);
|
|
30558
|
+
if (value.type === "AGG_FIELD") return aggregateOperandLabel(value.expr);
|
|
30558
30559
|
if (value.type === "ARITH_FIELD") return arithLabel(value.expr);
|
|
30559
30560
|
if (value.type === "GROUPING_FIELD") {
|
|
30560
30561
|
const field = value.ref.field;
|
|
@@ -30608,6 +30609,8 @@ function whereLabel(expr) {
|
|
|
30608
30609
|
}
|
|
30609
30610
|
function caseResultLabel(result) {
|
|
30610
30611
|
if (result.type === "ARRAY") return `[${result.elements.map((entry) => quote(entry.value)).join(",")}]`;
|
|
30612
|
+
if (result.type === "AGG_REF") return aggregateSyntheticName(result.func, result.distinct, result.arg);
|
|
30613
|
+
if (result.type === "AGG_ARITH") return aggregateOperandLabel(result);
|
|
30611
30614
|
if (result.type === "FIELD_REF" || result.type === "ARITH") return arithLabel(result);
|
|
30612
30615
|
return scalarValueLabel(result);
|
|
30613
30616
|
}
|
|
@@ -30911,8 +30914,9 @@ function needsSpaceBetween(prev, cur) {
|
|
|
30911
30914
|
return true;
|
|
30912
30915
|
}
|
|
30913
30916
|
var ParseError = class extends Error {
|
|
30914
|
-
constructor(
|
|
30915
|
-
super(`${
|
|
30917
|
+
constructor(rawMessage, token) {
|
|
30918
|
+
super(`${rawMessage}\uFF08\u4F4D\u7F6E ${token.pos}\u3001\u30C8\u30FC\u30AF\u30F3: \u300C${token.value}\u300D\uFF09`);
|
|
30919
|
+
this.rawMessage = rawMessage;
|
|
30916
30920
|
this.token = token;
|
|
30917
30921
|
this.name = "ParseError";
|
|
30918
30922
|
}
|
|
@@ -31951,8 +31955,17 @@ var Parser = class {
|
|
|
31951
31955
|
if (column.type === "AGGREGATE" || column.type === "ARITH_AGG_COL") return true;
|
|
31952
31956
|
if (column.type === "STRFUNC_COL") return column.expr.args.some((arg) => this.stringFuncArgHasAggregate(arg));
|
|
31953
31957
|
if (column.type === "SCALAR_VALUE_COL") return this.scalarValueHasAggregate(column.expr);
|
|
31958
|
+
if (column.type === "CASE_COL") return this.nodeHasAggregate(column.expr);
|
|
31954
31959
|
return false;
|
|
31955
31960
|
}
|
|
31961
|
+
nodeHasAggregate(node) {
|
|
31962
|
+
if (node === null || typeof node !== "object") return false;
|
|
31963
|
+
if (Array.isArray(node)) return node.some((value2) => this.nodeHasAggregate(value2));
|
|
31964
|
+
const value = node;
|
|
31965
|
+
if (value["type"] === "AGG_REF" || value["type"] === "AGG_ARITH") return true;
|
|
31966
|
+
if (value["type"] === "SELECT" || value["type"] === "SCALAR_SUBQUERY") return false;
|
|
31967
|
+
return Object.values(value).some((child) => this.nodeHasAggregate(child));
|
|
31968
|
+
}
|
|
31956
31969
|
stringFuncArgHasAggregate(arg) {
|
|
31957
31970
|
if (arg.type === "AGG_REF" || arg.type === "AGG_ARITH") return true;
|
|
31958
31971
|
return this.scalarValueHasAggregate(arg);
|
|
@@ -31963,11 +31976,7 @@ var Parser = class {
|
|
|
31963
31976
|
return this.scalarValueHasAggregate(expr.left) || this.scalarValueHasAggregate(expr.right);
|
|
31964
31977
|
}
|
|
31965
31978
|
if (expr.type === "CASE_WHEN") {
|
|
31966
|
-
|
|
31967
|
-
return results.some((result) => {
|
|
31968
|
-
if (result.type === "ARRAY" || result.type === "FIELD_REF" || result.type === "ARITH") return false;
|
|
31969
|
-
return this.scalarValueHasAggregate(result);
|
|
31970
|
-
});
|
|
31979
|
+
return this.nodeHasAggregate(expr);
|
|
31971
31980
|
}
|
|
31972
31981
|
return false;
|
|
31973
31982
|
}
|
|
@@ -32224,9 +32233,9 @@ var Parser = class {
|
|
|
32224
32233
|
this.expect("(" /* LPAREN */);
|
|
32225
32234
|
const condition = this.parseCaseCondition(allowGroupingCondition);
|
|
32226
32235
|
this.expect("," /* COMMA */);
|
|
32227
|
-
const thenResult = this.parseCaseResult();
|
|
32236
|
+
const thenResult = this.parseCaseResult(allowGroupingCondition);
|
|
32228
32237
|
this.expect("," /* COMMA */);
|
|
32229
|
-
const elseResult = this.parseCaseResult();
|
|
32238
|
+
const elseResult = this.parseCaseResult(allowGroupingCondition);
|
|
32230
32239
|
this.expect(")" /* RPAREN */);
|
|
32231
32240
|
return {
|
|
32232
32241
|
type: "CASE_WHEN",
|
|
@@ -32241,7 +32250,7 @@ var Parser = class {
|
|
|
32241
32250
|
this.advance();
|
|
32242
32251
|
const condition = this.parseCaseCondition(allowGroupingCondition);
|
|
32243
32252
|
this.expect("THEN" /* THEN */);
|
|
32244
|
-
const result = this.parseCaseResult();
|
|
32253
|
+
const result = this.parseCaseResult(allowGroupingCondition);
|
|
32245
32254
|
branches.push({ condition, result });
|
|
32246
32255
|
}
|
|
32247
32256
|
if (branches.length === 0) {
|
|
@@ -32249,7 +32258,7 @@ var Parser = class {
|
|
|
32249
32258
|
}
|
|
32250
32259
|
let elseResult = null;
|
|
32251
32260
|
if (this.consume("ELSE" /* ELSE */)) {
|
|
32252
|
-
elseResult = this.parseCaseResult();
|
|
32261
|
+
elseResult = this.parseCaseResult(allowGroupingCondition);
|
|
32253
32262
|
}
|
|
32254
32263
|
this.expect("END" /* END */);
|
|
32255
32264
|
return { type: "CASE_WHEN", branches, elseResult };
|
|
@@ -32259,7 +32268,7 @@ var Parser = class {
|
|
|
32259
32268
|
return this.parseWhereExpr("SELECT_CASE");
|
|
32260
32269
|
}
|
|
32261
32270
|
/** THEN / ELSE の結果値。`||` を含む場合だけ新スカラー文法へ渡す。 */
|
|
32262
|
-
parseCaseResult() {
|
|
32271
|
+
parseCaseResult(allowAggregateResult = false) {
|
|
32263
32272
|
const tok = this.peek();
|
|
32264
32273
|
if (this.insideAggregateArg > 0 && this.tryAggregateFunc() !== null) {
|
|
32265
32274
|
throw new ParseError("\u96C6\u8A08\u95A2\u6570\u306E\u5F15\u6570\u5185\u306B\u96C6\u8A08\u95A2\u6570\u306F\u4F7F\u7528\u3067\u304D\u307E\u305B\u3093", tok);
|
|
@@ -32267,6 +32276,10 @@ var Parser = class {
|
|
|
32267
32276
|
if (tok.kind === "[" /* LBRACKET */) {
|
|
32268
32277
|
return this.parseArrayLiteral();
|
|
32269
32278
|
}
|
|
32279
|
+
const aggregateFunc = this.tryAggregateFunc();
|
|
32280
|
+
if (aggregateFunc !== null && allowAggregateResult) {
|
|
32281
|
+
return this.continueAggArith(this.parseAggregateRef(aggregateFunc));
|
|
32282
|
+
}
|
|
32270
32283
|
if (this.hasTopLevelTokenBeforeValueEnd("||" /* CONCAT_OP */)) {
|
|
32271
32284
|
return this.parseScalarValueExpr({ allowAggregateArgs: true });
|
|
32272
32285
|
}
|
|
@@ -32298,16 +32311,33 @@ var Parser = class {
|
|
|
32298
32311
|
const byKind = PARSER_SCALAR_FUNCTION_TOKEN_MAP[this.peek().kind] ?? null;
|
|
32299
32312
|
if (byKind !== null && byKind !== "LEFT" && byKind !== "RIGHT") return byKind;
|
|
32300
32313
|
if (this.peek().kind === "IDENT" /* IDENT */) {
|
|
32301
|
-
const
|
|
32314
|
+
const nameToken = this.peek();
|
|
32315
|
+
const name = nameToken.value.toUpperCase();
|
|
32302
32316
|
if (PARSER_IDENT_SCALAR_FUNCTIONS.includes(name)) {
|
|
32303
32317
|
if (this.peekAt(1).kind === "(" /* LPAREN */) {
|
|
32304
32318
|
return name;
|
|
32305
32319
|
}
|
|
32306
32320
|
}
|
|
32321
|
+
if (this.peekAt(1).kind === "(" /* LPAREN */) {
|
|
32322
|
+
const hint = name === "DATE_SUB" ? "\u3002\u65E5\u4ED8\u3092\u6E1B\u7B97\u3059\u308B\u306B\u306F DATE_ADD \u306E\u52A0\u7B97\u5024\u3078\u8CA0\u6570\u3092\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044" : "";
|
|
32323
|
+
throw new ParseError(`\u300C${nameToken.value}\u300D\u3068\u3044\u3046\u95A2\u6570\u306F\u3042\u308A\u307E\u305B\u3093${hint}`, nameToken);
|
|
32324
|
+
}
|
|
32307
32325
|
}
|
|
32308
32326
|
return null;
|
|
32309
32327
|
}
|
|
32310
32328
|
parseStringFuncExpr() {
|
|
32329
|
+
const nameToken = this.peek();
|
|
32330
|
+
const func = this.tryStringFuncName();
|
|
32331
|
+
try {
|
|
32332
|
+
return this.parseStringFuncExprBody();
|
|
32333
|
+
} catch (error51) {
|
|
32334
|
+
if (!(error51 instanceof ParseError)) throw error51;
|
|
32335
|
+
const displayName = nameToken.value.toUpperCase();
|
|
32336
|
+
const guidance = func === "DATE_ADD" ? `${displayName} \u306E\u69CB\u6587\u306F DATE_ADD(\u5217, n, '\u5358\u4F4D') \u3067\u3059\u3002` : `${displayName} \u306E\u5F15\u6570\u69CB\u6587\u304C\u4E0D\u6B63\u3067\u3059\u3002`;
|
|
32337
|
+
throw new ParseError(`${guidance}${error51.rawMessage}`, error51.token);
|
|
32338
|
+
}
|
|
32339
|
+
}
|
|
32340
|
+
parseStringFuncExprBody() {
|
|
32311
32341
|
const tokenKind = this.peek().kind;
|
|
32312
32342
|
const func = this.tryStringFuncName();
|
|
32313
32343
|
this.advance();
|
|
@@ -32773,8 +32803,19 @@ var Parser = class {
|
|
|
32773
32803
|
throw new ParseError("\u96C6\u8A08\u95A2\u6570\u306E\u5F15\u6570\u5185\u306B\u96C6\u8A08\u95A2\u6570\u306F\u4F7F\u7528\u3067\u304D\u307E\u305B\u3093", this.peek());
|
|
32774
32804
|
}
|
|
32775
32805
|
const ref = this.parseAggregateRef(aggFunc);
|
|
32806
|
+
if (this.isArithOp(this.peek().kind)) {
|
|
32807
|
+
return {
|
|
32808
|
+
type: "AGG_FIELD",
|
|
32809
|
+
expr: this.continueAggArith(ref)
|
|
32810
|
+
};
|
|
32811
|
+
}
|
|
32776
32812
|
const syntheticName = aggregateSyntheticName(ref.func, ref.distinct, ref.arg);
|
|
32777
|
-
return {
|
|
32813
|
+
return {
|
|
32814
|
+
type: "FIELD",
|
|
32815
|
+
tableAlias: null,
|
|
32816
|
+
field: syntheticName,
|
|
32817
|
+
...this.groupingFieldContext === "SELECT_CASE" || this.groupingFieldContext === "HAVING" ? { aggregateRef: ref } : {}
|
|
32818
|
+
};
|
|
32778
32819
|
}
|
|
32779
32820
|
if (this.peek().kind === "CASE" /* CASE */) {
|
|
32780
32821
|
const expr = this.parseCaseWhenExpr();
|
|
@@ -34977,6 +35018,9 @@ function convertField(field) {
|
|
|
34977
35018
|
`WHERE \u53E5\u306E\u95A2\u6570\uFF08${field.expr.func}\uFF09\u306F kintone \u30AF\u30A8\u30EA\u306B\u5909\u63DB\u3067\u304D\u307E\u305B\u3093`
|
|
34978
35019
|
);
|
|
34979
35020
|
}
|
|
35021
|
+
if (field.type === "AGG_FIELD") {
|
|
35022
|
+
throw new KintoneQueryError("HAVING \u53E5\u306E\u96C6\u8A08\u7B97\u8853\u5F0F\u306F kintone \u30AF\u30A8\u30EA\u306B\u5909\u63DB\u3067\u304D\u307E\u305B\u3093");
|
|
35023
|
+
}
|
|
34980
35024
|
if (field.type === "ARITH_FIELD") {
|
|
34981
35025
|
throw new KintoneQueryError("WHERE \u53E5\u306E\u7B97\u8853\u5F0F\u306F kintone \u30AF\u30A8\u30EA\u306B\u5909\u63DB\u3067\u304D\u307E\u305B\u3093");
|
|
34982
35026
|
}
|
|
@@ -35115,189 +35159,464 @@ var KintoneQueryError = class extends Error {
|
|
|
35115
35159
|
}
|
|
35116
35160
|
};
|
|
35117
35161
|
|
|
35118
|
-
// src/
|
|
35119
|
-
|
|
35120
|
-
|
|
35121
|
-
|
|
35122
|
-
|
|
35123
|
-
|
|
35124
|
-
|
|
35125
|
-
|
|
35126
|
-
|
|
35127
|
-
|
|
35128
|
-
|
|
35129
|
-
|
|
35130
|
-
|
|
35131
|
-
)
|
|
35132
|
-
|
|
35133
|
-
if (stmt.orderBy.some((o) => o.key.type !== "FIELD_NAME")) return "FULL_SCAN";
|
|
35134
|
-
return "SIMPLE";
|
|
35162
|
+
// src/core/groupingValidation.ts
|
|
35163
|
+
init_define_KSQL_DOCS();
|
|
35164
|
+
|
|
35165
|
+
// src/engine/groupingRowMeta.ts
|
|
35166
|
+
init_define_KSQL_DOCS();
|
|
35167
|
+
var groupingRowMetaKey = /* @__PURE__ */ Symbol("ksql.groupingRowMeta");
|
|
35168
|
+
var groupingRefCanonicalIds = /* @__PURE__ */ new WeakMap();
|
|
35169
|
+
function attachGroupingRowMeta(row, includedCanonicalIds) {
|
|
35170
|
+
Object.defineProperty(row, groupingRowMetaKey, {
|
|
35171
|
+
value: { includedCanonicalIds },
|
|
35172
|
+
enumerable: false,
|
|
35173
|
+
configurable: false,
|
|
35174
|
+
writable: false
|
|
35175
|
+
});
|
|
35176
|
+
return row;
|
|
35135
35177
|
}
|
|
35136
|
-
function
|
|
35137
|
-
|
|
35138
|
-
switch (where.type) {
|
|
35139
|
-
case "BOOLEAN":
|
|
35140
|
-
return true;
|
|
35141
|
-
case "BINARY":
|
|
35142
|
-
return isFunc(where.left) || where.right.type === "ARITH_VALUE" || where.right.type === "CASE_VALUE" || where.right.type === "SUBQUERY_IN_LIST" || where.right.type === "SCALAR_SUBQUERY" || isLike(where);
|
|
35143
|
-
case "NULL_CHECK":
|
|
35144
|
-
return isFunc(where.field);
|
|
35145
|
-
case "LOGICAL":
|
|
35146
|
-
return whereRequiresJsEval(where.left) || whereRequiresJsEval(where.right);
|
|
35147
|
-
case "NOT":
|
|
35148
|
-
case "GROUP":
|
|
35149
|
-
return whereRequiresJsEval(where.expr);
|
|
35150
|
-
case "EXISTS":
|
|
35151
|
-
return true;
|
|
35152
|
-
}
|
|
35178
|
+
function getGroupingRowMeta(row) {
|
|
35179
|
+
return row[groupingRowMetaKey];
|
|
35153
35180
|
}
|
|
35154
|
-
function
|
|
35155
|
-
return
|
|
35181
|
+
function readGroupingMembership(row) {
|
|
35182
|
+
return getGroupingRowMeta(row)?.includedCanonicalIds;
|
|
35156
35183
|
}
|
|
35157
|
-
function
|
|
35158
|
-
|
|
35159
|
-
const hasPagination = stmt.limit !== null || stmt.offset !== null;
|
|
35160
|
-
const shouldInjectDefaultOrder = hasPagination && stmt.orderBy.length === 0;
|
|
35161
|
-
if (stmt.where !== null) {
|
|
35162
|
-
queryParts.push(whereToKintone(stmt.where));
|
|
35163
|
-
}
|
|
35164
|
-
if (stmt.orderBy.length > 0) {
|
|
35165
|
-
const orderStr = stmt.orderBy.map(convertOrderBy).join(", ");
|
|
35166
|
-
queryParts.push(`order by ${orderStr}`);
|
|
35167
|
-
} else if (shouldInjectDefaultOrder) {
|
|
35168
|
-
queryParts.push("order by $id asc");
|
|
35169
|
-
}
|
|
35170
|
-
if (stmt.limit !== null) {
|
|
35171
|
-
queryParts.push(`limit ${stmt.limit}`);
|
|
35172
|
-
}
|
|
35173
|
-
if (stmt.offset !== null) {
|
|
35174
|
-
queryParts.push(`offset ${stmt.offset}`);
|
|
35175
|
-
}
|
|
35176
|
-
return {
|
|
35177
|
-
app: stmt.from.appId,
|
|
35178
|
-
query: queryParts.join(" "),
|
|
35179
|
-
fields: extractFields(stmt.columns),
|
|
35180
|
-
totalCount: false
|
|
35181
|
-
};
|
|
35184
|
+
function bindGroupingRefCanonicalId(ref, canonicalId) {
|
|
35185
|
+
groupingRefCanonicalIds.set(ref, canonicalId);
|
|
35182
35186
|
}
|
|
35183
|
-
function
|
|
35184
|
-
const
|
|
35185
|
-
if (
|
|
35186
|
-
|
|
35187
|
+
function evalGroupingRef(ref, row) {
|
|
35188
|
+
const membership = readGroupingMembership(row);
|
|
35189
|
+
if (!membership) {
|
|
35190
|
+
throw new Error("internal error: GROUPING() evaluation requires B65 grouping row membership.");
|
|
35187
35191
|
}
|
|
35188
|
-
|
|
35189
|
-
|
|
35190
|
-
|
|
35191
|
-
fields: []
|
|
35192
|
-
// 全件取得なので全フィールドを取得する
|
|
35193
|
-
};
|
|
35194
|
-
}
|
|
35195
|
-
function selectToFetchAllFields(stmt, targetTable, plainGroupByPlan) {
|
|
35196
|
-
const plan = collectRequiredFieldsByTable(stmt, plainGroupByPlan);
|
|
35197
|
-
const target = plan.get(targetTable);
|
|
35198
|
-
if (!target) return [];
|
|
35199
|
-
if (target.allFields) return [];
|
|
35200
|
-
const fields = new Set(target.fields);
|
|
35201
|
-
if (target.table.subtableCode) {
|
|
35202
|
-
fields.add(target.table.subtableCode);
|
|
35192
|
+
const canonicalId = groupingRefCanonicalIds.get(ref);
|
|
35193
|
+
if (!canonicalId) {
|
|
35194
|
+
throw new Error("internal error: GROUPING() reference was not resolved during B65 planning.");
|
|
35203
35195
|
}
|
|
35204
|
-
|
|
35205
|
-
return [...fields];
|
|
35196
|
+
return membership.has(canonicalId) ? "0" : "1";
|
|
35206
35197
|
}
|
|
35207
|
-
|
|
35208
|
-
|
|
35209
|
-
|
|
35210
|
-
|
|
35198
|
+
|
|
35199
|
+
// src/core/groupingValidation.ts
|
|
35200
|
+
var enforceGroupingPlanningCandidateLimits = (facts) => {
|
|
35201
|
+
if (facts.expandedSetCount > B65_MAX_GROUPING_SETS) {
|
|
35202
|
+
throw new Error(
|
|
35203
|
+
`ArgumentError: B65 expanded grouping set count ${facts.expandedSetCount} exceeds limit ${B65_MAX_GROUPING_SETS} (reason=GROUPING_SET_LIMIT_EXCEEDED).`
|
|
35204
|
+
);
|
|
35211
35205
|
}
|
|
35212
|
-
|
|
35213
|
-
|
|
35214
|
-
|
|
35215
|
-
|
|
35216
|
-
(c) => c.type === "WILDCARD" || c.type === "AGGREGATE" || c.type === "ARITH_AGG_COL" || c.type === "CASE_COL" || c.type === "SCALAR_SUBQUERY_COL"
|
|
35217
|
-
);
|
|
35218
|
-
if (hasWildcard) return [];
|
|
35219
|
-
const fields = [];
|
|
35220
|
-
for (const col of columns) {
|
|
35221
|
-
if (col.type === "FIELD") {
|
|
35222
|
-
fields.push(normalizeSimpleFieldRef(col.field));
|
|
35223
|
-
} else if (col.type === "ARITH_COL") {
|
|
35224
|
-
collectArithNode(col.expr, fields);
|
|
35225
|
-
} else if (col.type === "STRFUNC_COL") {
|
|
35226
|
-
collectStringFuncFields(col.expr, fields);
|
|
35227
|
-
} else if (col.type === "SCALAR_VALUE_COL") {
|
|
35228
|
-
collectScalarValueFields(col.expr, fields);
|
|
35229
|
-
}
|
|
35206
|
+
if (facts.canonicalItemCount > B65_MAX_GROUPING_ITEMS) {
|
|
35207
|
+
throw new Error(
|
|
35208
|
+
`ArgumentError: B65 canonical grouping item count ${facts.canonicalItemCount} exceeds limit ${B65_MAX_GROUPING_ITEMS} (reason=GROUPING_ITEM_LIMIT_EXCEEDED).`
|
|
35209
|
+
);
|
|
35230
35210
|
}
|
|
35231
|
-
|
|
35232
|
-
|
|
35233
|
-
|
|
35234
|
-
collectArithNode(expr.left, out);
|
|
35235
|
-
collectArithNode(expr.right, out);
|
|
35236
|
-
}
|
|
35237
|
-
function collectArithNode(node, out) {
|
|
35238
|
-
if (node.type === "VARIABLE") throw new Error(
|
|
35239
|
-
`InternalError: unresolved arithmetic variable @${node.name} reached SELECT field collection.`
|
|
35240
|
-
);
|
|
35241
|
-
if (node.type === "FIELD_REF") out.push(normalizeSimpleFieldRef(node.field));
|
|
35242
|
-
else if (node.type === "ARITH") collectArithFields(node, out);
|
|
35243
|
-
else if (node.type === "STRING_FUNC") collectStringFuncFields(node, out);
|
|
35244
|
-
}
|
|
35245
|
-
function normalizeSimpleFieldRef(field) {
|
|
35246
|
-
const dot = field.indexOf(".");
|
|
35247
|
-
if (dot <= 0) return field;
|
|
35248
|
-
const unqualified = field.slice(dot + 1);
|
|
35249
|
-
return unqualified || field;
|
|
35211
|
+
};
|
|
35212
|
+
function displayField(field) {
|
|
35213
|
+
return field.tableAlias ? `${field.tableAlias}.${field.field}` : field.field;
|
|
35250
35214
|
}
|
|
35251
|
-
function
|
|
35252
|
-
|
|
35253
|
-
|
|
35254
|
-
}
|
|
35215
|
+
function refFromName(name) {
|
|
35216
|
+
const dot = name.indexOf(".");
|
|
35217
|
+
return dot > 0 ? { type: "FIELD", tableAlias: name.slice(0, dot), field: name.slice(dot + 1) } : { type: "FIELD", tableAlias: null, field: name };
|
|
35255
35218
|
}
|
|
35256
|
-
function
|
|
35257
|
-
if (
|
|
35258
|
-
|
|
35219
|
+
function collectGroupingRefs(node, out) {
|
|
35220
|
+
if (node === null || typeof node !== "object") return;
|
|
35221
|
+
if (Array.isArray(node)) {
|
|
35222
|
+
node.forEach((item) => collectGroupingRefs(item, out));
|
|
35259
35223
|
return;
|
|
35260
35224
|
}
|
|
35261
|
-
|
|
35262
|
-
|
|
35263
|
-
|
|
35264
|
-
|
|
35265
|
-
out.push(normalizeSimpleFieldRef(expr.tableAlias ? `${expr.tableAlias}.${expr.field}` : expr.field));
|
|
35225
|
+
const value = node;
|
|
35226
|
+
if (value["type"] === "SELECT" || value["type"] === "SCALAR_SUBQUERY") return;
|
|
35227
|
+
if (value["type"] === "GROUPING_REF") {
|
|
35228
|
+
out.push(value);
|
|
35266
35229
|
return;
|
|
35267
35230
|
}
|
|
35268
|
-
|
|
35269
|
-
|
|
35231
|
+
Object.values(value).forEach((item) => collectGroupingRefs(item, out));
|
|
35232
|
+
}
|
|
35233
|
+
function collectAggregateArgumentGroupingRefs(node, out) {
|
|
35234
|
+
if (node === null || typeof node !== "object") return;
|
|
35235
|
+
if (Array.isArray(node)) {
|
|
35236
|
+
node.forEach((item) => collectAggregateArgumentGroupingRefs(item, out));
|
|
35270
35237
|
return;
|
|
35271
35238
|
}
|
|
35272
|
-
|
|
35273
|
-
|
|
35274
|
-
|
|
35239
|
+
const value = node;
|
|
35240
|
+
if (value["type"] === "SELECT" || value["type"] === "SCALAR_SUBQUERY") return;
|
|
35241
|
+
if (value["type"] === "AGGREGATE" || value["type"] === "AGG_REF") {
|
|
35242
|
+
collectGroupingRefs(value["arg"], out);
|
|
35275
35243
|
return;
|
|
35276
35244
|
}
|
|
35277
|
-
|
|
35278
|
-
for (const branch of expr.branches) collectCaseResultScalarFields(branch.result, out);
|
|
35279
|
-
if (expr.elseResult) collectCaseResultScalarFields(expr.elseResult, out);
|
|
35280
|
-
}
|
|
35245
|
+
Object.values(value).forEach((item) => collectAggregateArgumentGroupingRefs(item, out));
|
|
35281
35246
|
}
|
|
35282
|
-
function
|
|
35283
|
-
if (
|
|
35284
|
-
if (
|
|
35285
|
-
|
|
35247
|
+
function collectNonAggregateFieldRefs(node, out) {
|
|
35248
|
+
if (node === null || typeof node !== "object") return;
|
|
35249
|
+
if (Array.isArray(node)) {
|
|
35250
|
+
node.forEach((item) => collectNonAggregateFieldRefs(item, out));
|
|
35286
35251
|
return;
|
|
35287
35252
|
}
|
|
35288
|
-
|
|
35289
|
-
|
|
35290
|
-
|
|
35291
|
-
if (
|
|
35292
|
-
|
|
35253
|
+
const value = node;
|
|
35254
|
+
const type = value["type"];
|
|
35255
|
+
if (type === "SELECT" || type === "SCALAR_SUBQUERY" || type === "GROUPING_REF" || type === "AGG_REF" || type === "AGG_ARITH") return;
|
|
35256
|
+
if (type === "FIELD" && value["aggregateRef"] !== void 0) return;
|
|
35257
|
+
if (type === "FIELD" && typeof value["field"] === "string") {
|
|
35258
|
+
out.push({
|
|
35259
|
+
type: "FIELD",
|
|
35260
|
+
tableAlias: typeof value["tableAlias"] === "string" ? value["tableAlias"] : null,
|
|
35261
|
+
field: value["field"]
|
|
35262
|
+
});
|
|
35293
35263
|
return;
|
|
35294
35264
|
}
|
|
35295
|
-
if (
|
|
35296
|
-
|
|
35297
|
-
|
|
35265
|
+
if (type === "FIELD_REF" && typeof value["field"] === "string") {
|
|
35266
|
+
out.push(refFromName(value["field"]));
|
|
35267
|
+
return;
|
|
35298
35268
|
}
|
|
35269
|
+
Object.values(value).forEach((item) => collectNonAggregateFieldRefs(item, out));
|
|
35299
35270
|
}
|
|
35300
|
-
function
|
|
35271
|
+
function containsAggregate2(node) {
|
|
35272
|
+
if (node === null || typeof node !== "object") return false;
|
|
35273
|
+
if (Array.isArray(node)) return node.some(containsAggregate2);
|
|
35274
|
+
const value = node;
|
|
35275
|
+
if (value["type"] === "AGG_REF" || value["type"] === "AGG_ARITH") return true;
|
|
35276
|
+
if (value["type"] === "SELECT" || value["type"] === "SCALAR_SUBQUERY") return false;
|
|
35277
|
+
return Object.values(value).some(containsAggregate2);
|
|
35278
|
+
}
|
|
35279
|
+
function isAggregateMaterializedAlias(column) {
|
|
35280
|
+
if (!("alias" in column) || column.alias === null) return false;
|
|
35281
|
+
if (column.type === "AGGREGATE" || column.type === "ARITH_AGG_COL") return true;
|
|
35282
|
+
if (column.type === "STRFUNC_COL" || column.type === "SCALAR_VALUE_COL" || column.type === "CASE_COL") {
|
|
35283
|
+
return containsAggregate2(column);
|
|
35284
|
+
}
|
|
35285
|
+
return false;
|
|
35286
|
+
}
|
|
35287
|
+
function outputAliases(columns) {
|
|
35288
|
+
return new Set(columns.flatMap(
|
|
35289
|
+
(column) => "alias" in column && typeof column.alias === "string" ? [column.alias] : []
|
|
35290
|
+
));
|
|
35291
|
+
}
|
|
35292
|
+
function isAggregateSyntheticReference(ref) {
|
|
35293
|
+
return ref.tableAlias === null && /^(COUNT|SUM|AVG|MAX|MIN|GROUP_CONCAT|STDDEV_POP|STDDEV_SAMP|VAR_POP|VAR_SAMP|MEDIAN|MODE)\(/.test(ref.field);
|
|
35294
|
+
}
|
|
35295
|
+
function validateGroupingRefMembership(ref, resolve3, canonicalItems) {
|
|
35296
|
+
const resolved = resolve3(ref.field);
|
|
35297
|
+
if (!resolved.physical) {
|
|
35298
|
+
throw new Error(`ArgumentError: B65 grouping reference ${displayField(ref.field)} must resolve to a physical APP field.`);
|
|
35299
|
+
}
|
|
35300
|
+
if (!canonicalItems.has(resolved.canonicalId)) {
|
|
35301
|
+
throw new Error(
|
|
35302
|
+
`ArgumentError: B65 GROUPING argument ${displayField(ref.field)} is not present in grouping allItems (reason=B65_GROUPING_ARG_NOT_ITEM).`
|
|
35303
|
+
);
|
|
35304
|
+
}
|
|
35305
|
+
bindGroupingRefCanonicalId(ref, resolved.canonicalId);
|
|
35306
|
+
}
|
|
35307
|
+
function validateDependency(ref, resolve3, canonicalItems, context) {
|
|
35308
|
+
const resolved = resolve3(ref);
|
|
35309
|
+
if (!resolved.physical || !canonicalItems.has(resolved.canonicalId)) {
|
|
35310
|
+
throw new Error(
|
|
35311
|
+
`ArgumentError: B65 non-aggregate field ${displayField(ref)} in ${context} is not a grouping item (reason=B65_NON_GROUPED_DEPENDENCY).`
|
|
35312
|
+
);
|
|
35313
|
+
}
|
|
35314
|
+
}
|
|
35315
|
+
function keyDependencies(key) {
|
|
35316
|
+
if (key.type === "GROUPING_KEY") return [];
|
|
35317
|
+
if (key.type === "FIELD_NAME") return [refFromName(key.name)];
|
|
35318
|
+
const refs = [];
|
|
35319
|
+
collectNonAggregateFieldRefs(key, refs);
|
|
35320
|
+
return refs;
|
|
35321
|
+
}
|
|
35322
|
+
function validateGroupingStatic(stmt) {
|
|
35323
|
+
const normalized = normalizeGroupingSpec(stmt);
|
|
35324
|
+
const groupingRefs = [];
|
|
35325
|
+
for (const column of stmt.columns) {
|
|
35326
|
+
if (column.type !== "WINDOW_COL") collectGroupingRefs(column, groupingRefs);
|
|
35327
|
+
}
|
|
35328
|
+
collectGroupingRefs(stmt.having, groupingRefs);
|
|
35329
|
+
collectGroupingRefs(stmt.orderBy, groupingRefs);
|
|
35330
|
+
const forbiddenGroupingRefs = [];
|
|
35331
|
+
collectGroupingRefs(stmt.where, forbiddenGroupingRefs);
|
|
35332
|
+
collectGroupingRefs(stmt.joins, forbiddenGroupingRefs);
|
|
35333
|
+
collectAggregateArgumentGroupingRefs(stmt.columns, forbiddenGroupingRefs);
|
|
35334
|
+
collectAggregateArgumentGroupingRefs(stmt.having, forbiddenGroupingRefs);
|
|
35335
|
+
for (const column of stmt.columns) {
|
|
35336
|
+
if (column.type === "WINDOW_COL") collectGroupingRefs(column, forbiddenGroupingRefs);
|
|
35337
|
+
}
|
|
35338
|
+
if (forbiddenGroupingRefs.length > 0) {
|
|
35339
|
+
throw new Error(
|
|
35340
|
+
"ArgumentError: B65 GROUPING() is not allowed in WHERE, JOIN, window, aggregate arguments, or DML expressions."
|
|
35341
|
+
);
|
|
35342
|
+
}
|
|
35343
|
+
if (normalized.type !== "GROUPING_SETS") {
|
|
35344
|
+
if (groupingRefs.length > 0) {
|
|
35345
|
+
throw new Error("ArgumentError: B65 GROUPING() requires GROUP BY ROLLUP or GROUPING SETS.");
|
|
35346
|
+
}
|
|
35347
|
+
return;
|
|
35348
|
+
}
|
|
35349
|
+
if (stmt.orderMode === "KINTONE_NATIVE") {
|
|
35350
|
+
throw new Error("ArgumentError: B65 KORDER BY is not supported in Phase1.");
|
|
35351
|
+
}
|
|
35352
|
+
if (stmt.columns.some((column) => column.type === "WINDOW_COL")) {
|
|
35353
|
+
throw new Error("ArgumentError: B65 window functions are not supported in Phase1.");
|
|
35354
|
+
}
|
|
35355
|
+
if (stmt.columns.some(
|
|
35356
|
+
(column) => column.type === "WILDCARD" || column.type === "PARENT_WILDCARD"
|
|
35357
|
+
)) {
|
|
35358
|
+
throw new Error("ArgumentError: B65 wildcard projection is not supported in Phase1.");
|
|
35359
|
+
}
|
|
35360
|
+
}
|
|
35361
|
+
function validateGroupingPlanning(stmt, resolve3, planningGuardHook = () => void 0) {
|
|
35362
|
+
validateGroupingStatic(stmt);
|
|
35363
|
+
const normalized = normalizeGroupingSpec(stmt);
|
|
35364
|
+
const groupingRefs = [];
|
|
35365
|
+
for (const column of stmt.columns) {
|
|
35366
|
+
if (column.type !== "WINDOW_COL") collectGroupingRefs(column, groupingRefs);
|
|
35367
|
+
}
|
|
35368
|
+
collectGroupingRefs(stmt.having, groupingRefs);
|
|
35369
|
+
collectGroupingRefs(stmt.orderBy, groupingRefs);
|
|
35370
|
+
if (normalized.type !== "GROUPING_SETS") {
|
|
35371
|
+
return null;
|
|
35372
|
+
}
|
|
35373
|
+
const resolvedSpec = resolveGroupingSpec(stmt, resolve3);
|
|
35374
|
+
const canonicalItems = /* @__PURE__ */ new Set();
|
|
35375
|
+
const resolvedItems = [];
|
|
35376
|
+
for (const item of resolvedSpec.allItems) {
|
|
35377
|
+
const resolved = item;
|
|
35378
|
+
if (!resolved.physical) {
|
|
35379
|
+
throw new Error(`ArgumentError: B65 grouping item ${displayField(item.field)} must resolve to a physical APP field.`);
|
|
35380
|
+
}
|
|
35381
|
+
if (!canonicalItems.has(resolved.canonicalId)) {
|
|
35382
|
+
canonicalItems.add(resolved.canonicalId);
|
|
35383
|
+
resolvedItems.push(resolved);
|
|
35384
|
+
}
|
|
35385
|
+
}
|
|
35386
|
+
planningGuardHook({
|
|
35387
|
+
expandedSetCount: normalized.sets.length,
|
|
35388
|
+
canonicalItemCount: canonicalItems.size
|
|
35389
|
+
});
|
|
35390
|
+
for (const ref of groupingRefs) {
|
|
35391
|
+
validateGroupingRefMembership(ref, resolve3, canonicalItems);
|
|
35392
|
+
}
|
|
35393
|
+
const aliases = outputAliases(stmt.columns);
|
|
35394
|
+
for (const column of stmt.columns) {
|
|
35395
|
+
if (column.type === "GROUPING_COL" || column.type === "AGGREGATE" || column.type === "ARITH_AGG_COL" || column.type === "LITERAL_COL" || column.type === "VARIABLE_COL" || column.type === "SCALAR_SUBQUERY_COL") continue;
|
|
35396
|
+
const refs = [];
|
|
35397
|
+
if (column.type === "FIELD") refs.push(refFromName(column.field));
|
|
35398
|
+
else collectNonAggregateFieldRefs(column, refs);
|
|
35399
|
+
for (const ref of refs) validateDependency(ref, resolve3, canonicalItems, "SELECT");
|
|
35400
|
+
}
|
|
35401
|
+
if (stmt.having) {
|
|
35402
|
+
const refs = [];
|
|
35403
|
+
collectNonAggregateFieldRefs(stmt.having, refs);
|
|
35404
|
+
for (const ref of refs) {
|
|
35405
|
+
if (ref.tableAlias === null && aliases.has(ref.field) || isAggregateSyntheticReference(ref)) continue;
|
|
35406
|
+
validateDependency(ref, resolve3, canonicalItems, "HAVING");
|
|
35407
|
+
}
|
|
35408
|
+
}
|
|
35409
|
+
for (const order of stmt.orderBy) {
|
|
35410
|
+
for (const ref of keyDependencies(order.key)) {
|
|
35411
|
+
if (ref.tableAlias === null && aliases.has(ref.field) || isAggregateSyntheticReference(ref)) continue;
|
|
35412
|
+
validateDependency(ref, resolve3, canonicalItems, "ORDER BY");
|
|
35413
|
+
}
|
|
35414
|
+
}
|
|
35415
|
+
const collisionKeys = /* @__PURE__ */ new Set();
|
|
35416
|
+
for (const item of resolvedItems) {
|
|
35417
|
+
collisionKeys.add(item.directKey);
|
|
35418
|
+
if (item.unqualifiedBridgeKey !== null) collisionKeys.add(item.unqualifiedBridgeKey);
|
|
35419
|
+
}
|
|
35420
|
+
for (const column of stmt.columns) {
|
|
35421
|
+
if (!isAggregateMaterializedAlias(column)) continue;
|
|
35422
|
+
const alias = "alias" in column ? column.alias : null;
|
|
35423
|
+
if (alias === null) continue;
|
|
35424
|
+
if (collisionKeys.has(alias)) {
|
|
35425
|
+
throw new Error(
|
|
35426
|
+
`ArgumentError: B65 aggregate alias ${alias} collides with a grouping runtime key (reason=B65_AGGREGATE_ALIAS_COLLISION).`
|
|
35427
|
+
);
|
|
35428
|
+
}
|
|
35429
|
+
}
|
|
35430
|
+
return resolvedSpec;
|
|
35431
|
+
}
|
|
35432
|
+
|
|
35433
|
+
// src/converter/selectToKintone.ts
|
|
35434
|
+
function hasWindowColumns(columns) {
|
|
35435
|
+
return columns.some((column) => column.type === "WINDOW_COL");
|
|
35436
|
+
}
|
|
35437
|
+
function resolveSelectMode(stmt) {
|
|
35438
|
+
if (stmt.from.subtableCode) return "FULL_SCAN";
|
|
35439
|
+
if (stmt.joins.some((j) => j.table.subtableCode)) return "FULL_SCAN";
|
|
35440
|
+
if (stmt.joins.length > 0) return "FULL_SCAN";
|
|
35441
|
+
if (normalizeGroupingSpec(stmt).type !== "NONE") return "FULL_SCAN";
|
|
35442
|
+
if (stmt.distinct) return "FULL_SCAN";
|
|
35443
|
+
if (hasWindowColumns(stmt.columns)) return "FULL_SCAN";
|
|
35444
|
+
if (stmt.columns.some(
|
|
35445
|
+
(c) => c.type === "AGGREGATE" || c.type === "ARITH_AGG_COL" || c.type === "SCALAR_SUBQUERY_COL" || c.type === "CASE_COL" && containsAggregate2(c.expr) || c.type === "STRFUNC_COL" && hasAggregateInStringFuncExpr(c.expr) || c.type === "SCALAR_VALUE_COL" && scalarValueHasAggregate(c.expr)
|
|
35446
|
+
)) return "FULL_SCAN";
|
|
35447
|
+
if (whereRequiresJsEval(stmt.where)) return "FULL_SCAN";
|
|
35448
|
+
if (stmt.orderBy.some((o) => o.key.type !== "FIELD_NAME")) return "FULL_SCAN";
|
|
35449
|
+
return "SIMPLE";
|
|
35450
|
+
}
|
|
35451
|
+
function whereRequiresJsEval(where) {
|
|
35452
|
+
if (where === null) return false;
|
|
35453
|
+
switch (where.type) {
|
|
35454
|
+
case "BOOLEAN":
|
|
35455
|
+
return true;
|
|
35456
|
+
case "BINARY":
|
|
35457
|
+
return isFunc(where.left) || where.right.type === "ARITH_VALUE" || where.right.type === "CASE_VALUE" || where.right.type === "SUBQUERY_IN_LIST" || where.right.type === "SCALAR_SUBQUERY" || isLike(where);
|
|
35458
|
+
case "NULL_CHECK":
|
|
35459
|
+
return isFunc(where.field);
|
|
35460
|
+
case "LOGICAL":
|
|
35461
|
+
return whereRequiresJsEval(where.left) || whereRequiresJsEval(where.right);
|
|
35462
|
+
case "NOT":
|
|
35463
|
+
case "GROUP":
|
|
35464
|
+
return whereRequiresJsEval(where.expr);
|
|
35465
|
+
case "EXISTS":
|
|
35466
|
+
return true;
|
|
35467
|
+
}
|
|
35468
|
+
}
|
|
35469
|
+
function isFunc(fv) {
|
|
35470
|
+
return fv.type === "FUNC_FIELD" || fv.type === "ARITH_FIELD" || fv.type === "CASE_FIELD";
|
|
35471
|
+
}
|
|
35472
|
+
function selectToKintoneParams(stmt) {
|
|
35473
|
+
const queryParts = [];
|
|
35474
|
+
const hasPagination = stmt.limit !== null || stmt.offset !== null;
|
|
35475
|
+
const shouldInjectDefaultOrder = hasPagination && stmt.orderBy.length === 0;
|
|
35476
|
+
if (stmt.where !== null) {
|
|
35477
|
+
queryParts.push(whereToKintone(stmt.where));
|
|
35478
|
+
}
|
|
35479
|
+
if (stmt.orderBy.length > 0) {
|
|
35480
|
+
const orderStr = stmt.orderBy.map(convertOrderBy).join(", ");
|
|
35481
|
+
queryParts.push(`order by ${orderStr}`);
|
|
35482
|
+
} else if (shouldInjectDefaultOrder) {
|
|
35483
|
+
queryParts.push("order by $id asc");
|
|
35484
|
+
}
|
|
35485
|
+
if (stmt.limit !== null) {
|
|
35486
|
+
queryParts.push(`limit ${stmt.limit}`);
|
|
35487
|
+
}
|
|
35488
|
+
if (stmt.offset !== null) {
|
|
35489
|
+
queryParts.push(`offset ${stmt.offset}`);
|
|
35490
|
+
}
|
|
35491
|
+
return {
|
|
35492
|
+
app: stmt.from.appId,
|
|
35493
|
+
query: queryParts.join(" "),
|
|
35494
|
+
fields: extractFields(stmt.columns),
|
|
35495
|
+
totalCount: false
|
|
35496
|
+
};
|
|
35497
|
+
}
|
|
35498
|
+
function selectToFetchAllParams(stmt, appId) {
|
|
35499
|
+
const queryParts = [];
|
|
35500
|
+
if (stmt.where !== null && stmt.joins.length === 0 && !whereRequiresJsEval(stmt.where)) {
|
|
35501
|
+
queryParts.push(whereToKintone(stmt.where));
|
|
35502
|
+
}
|
|
35503
|
+
return {
|
|
35504
|
+
app: appId,
|
|
35505
|
+
query: queryParts.join(" "),
|
|
35506
|
+
fields: []
|
|
35507
|
+
// 全件取得なので全フィールドを取得する
|
|
35508
|
+
};
|
|
35509
|
+
}
|
|
35510
|
+
function selectToFetchAllFields(stmt, targetTable, plainGroupByPlan) {
|
|
35511
|
+
const plan = collectRequiredFieldsByTable(stmt, plainGroupByPlan);
|
|
35512
|
+
const target = plan.get(targetTable);
|
|
35513
|
+
if (!target) return [];
|
|
35514
|
+
if (target.allFields) return [];
|
|
35515
|
+
const fields = new Set(target.fields);
|
|
35516
|
+
if (target.table.subtableCode) {
|
|
35517
|
+
fields.add(target.table.subtableCode);
|
|
35518
|
+
}
|
|
35519
|
+
if (fields.size === 0) fields.add("$id");
|
|
35520
|
+
return [...fields];
|
|
35521
|
+
}
|
|
35522
|
+
function convertOrderBy(item) {
|
|
35523
|
+
const dir = item.direction === "ASC" ? "asc" : "desc";
|
|
35524
|
+
if (item.key.type !== "FIELD_NAME") {
|
|
35525
|
+
throw new Error("ORDER BY \u5F0F\u306F kintone \u30AF\u30A8\u30EA\u306B\u5909\u63DB\u3067\u304D\u307E\u305B\u3093\uFF08FULL_SCAN \u304C\u5FC5\u8981\u3067\u3059\uFF09");
|
|
35526
|
+
}
|
|
35527
|
+
return `${item.key.name} ${dir}`;
|
|
35528
|
+
}
|
|
35529
|
+
function extractFields(columns) {
|
|
35530
|
+
const hasWildcard = columns.some(
|
|
35531
|
+
(c) => c.type === "WILDCARD" || c.type === "AGGREGATE" || c.type === "ARITH_AGG_COL" || c.type === "CASE_COL" || c.type === "SCALAR_SUBQUERY_COL"
|
|
35532
|
+
);
|
|
35533
|
+
if (hasWildcard) return [];
|
|
35534
|
+
const fields = [];
|
|
35535
|
+
for (const col of columns) {
|
|
35536
|
+
if (col.type === "FIELD") {
|
|
35537
|
+
fields.push(normalizeSimpleFieldRef(col.field));
|
|
35538
|
+
} else if (col.type === "ARITH_COL") {
|
|
35539
|
+
collectArithNode(col.expr, fields);
|
|
35540
|
+
} else if (col.type === "STRFUNC_COL") {
|
|
35541
|
+
collectStringFuncFields(col.expr, fields);
|
|
35542
|
+
} else if (col.type === "SCALAR_VALUE_COL") {
|
|
35543
|
+
collectScalarValueFields(col.expr, fields);
|
|
35544
|
+
}
|
|
35545
|
+
}
|
|
35546
|
+
return [...new Set(fields)];
|
|
35547
|
+
}
|
|
35548
|
+
function collectArithFields(expr, out) {
|
|
35549
|
+
collectArithNode(expr.left, out);
|
|
35550
|
+
collectArithNode(expr.right, out);
|
|
35551
|
+
}
|
|
35552
|
+
function collectArithNode(node, out) {
|
|
35553
|
+
if (node.type === "VARIABLE") throw new Error(
|
|
35554
|
+
`InternalError: unresolved arithmetic variable @${node.name} reached SELECT field collection.`
|
|
35555
|
+
);
|
|
35556
|
+
if (node.type === "FIELD_REF") out.push(normalizeSimpleFieldRef(node.field));
|
|
35557
|
+
else if (node.type === "ARITH") collectArithFields(node, out);
|
|
35558
|
+
else if (node.type === "STRING_FUNC") collectStringFuncFields(node, out);
|
|
35559
|
+
}
|
|
35560
|
+
function normalizeSimpleFieldRef(field) {
|
|
35561
|
+
const dot = field.indexOf(".");
|
|
35562
|
+
if (dot <= 0) return field;
|
|
35563
|
+
const unqualified = field.slice(dot + 1);
|
|
35564
|
+
return unqualified || field;
|
|
35565
|
+
}
|
|
35566
|
+
function collectStringFuncFields(expr, out) {
|
|
35567
|
+
for (const arg of expr.args) {
|
|
35568
|
+
collectStringFuncArgFields(arg, out);
|
|
35569
|
+
}
|
|
35570
|
+
}
|
|
35571
|
+
function collectStringFuncArgFields(arg, out) {
|
|
35572
|
+
if (arg.type === "AGG_REF" || arg.type === "AGG_ARITH") {
|
|
35573
|
+
collectAggOperandFields(arg, out);
|
|
35574
|
+
return;
|
|
35575
|
+
}
|
|
35576
|
+
collectScalarValueFields(arg, out);
|
|
35577
|
+
}
|
|
35578
|
+
function collectScalarValueFields(expr, out) {
|
|
35579
|
+
if (expr.type === "FIELD") {
|
|
35580
|
+
out.push(normalizeSimpleFieldRef(expr.tableAlias ? `${expr.tableAlias}.${expr.field}` : expr.field));
|
|
35581
|
+
return;
|
|
35582
|
+
}
|
|
35583
|
+
if (expr.type === "STRING_FUNC") {
|
|
35584
|
+
collectStringFuncFields(expr, out);
|
|
35585
|
+
return;
|
|
35586
|
+
}
|
|
35587
|
+
if (expr.type === "SCALAR_ARITH" || expr.type === "CONCAT_OP") {
|
|
35588
|
+
collectScalarValueFields(expr.left, out);
|
|
35589
|
+
collectScalarValueFields(expr.right, out);
|
|
35590
|
+
return;
|
|
35591
|
+
}
|
|
35592
|
+
if (expr.type === "CASE_WHEN") {
|
|
35593
|
+
for (const branch of expr.branches) collectCaseResultScalarFields(branch.result, out);
|
|
35594
|
+
if (expr.elseResult) collectCaseResultScalarFields(expr.elseResult, out);
|
|
35595
|
+
}
|
|
35596
|
+
}
|
|
35597
|
+
function collectCaseResultScalarFields(result, out) {
|
|
35598
|
+
if (result.type === "ARRAY") return;
|
|
35599
|
+
if (result.type === "AGG_REF" || result.type === "AGG_ARITH") {
|
|
35600
|
+
collectAggOperandFields(result, out);
|
|
35601
|
+
return;
|
|
35602
|
+
}
|
|
35603
|
+
if (result.type === "FIELD_REF" || result.type === "ARITH") {
|
|
35604
|
+
collectArithNode(result, out);
|
|
35605
|
+
return;
|
|
35606
|
+
}
|
|
35607
|
+
collectScalarValueFields(result, out);
|
|
35608
|
+
}
|
|
35609
|
+
function collectAggOperandFields(node, out) {
|
|
35610
|
+
if (node.type === "AGG_REF") {
|
|
35611
|
+
if (node.arg.type !== "WILDCARD") collectAggregateArgFields(node.arg, out);
|
|
35612
|
+
return;
|
|
35613
|
+
}
|
|
35614
|
+
if (node.type === "AGG_ARITH") {
|
|
35615
|
+
collectAggOperandFields(node.left, out);
|
|
35616
|
+
collectAggOperandFields(node.right, out);
|
|
35617
|
+
}
|
|
35618
|
+
}
|
|
35619
|
+
function collectAggregateArgFields(node, out) {
|
|
35301
35620
|
if (node.type === "FIELD_REF" || node.type === "ARITH") collectArithNode(node, out);
|
|
35302
35621
|
else collectScalarValueFields(node, out);
|
|
35303
35622
|
}
|
|
@@ -35318,6 +35637,7 @@ function scalarValueHasAggregate(expr) {
|
|
|
35318
35637
|
return false;
|
|
35319
35638
|
}
|
|
35320
35639
|
function caseResultHasAggregate(result) {
|
|
35640
|
+
if (result.type === "AGG_REF" || result.type === "AGG_ARITH") return true;
|
|
35321
35641
|
if (result.type === "ARRAY" || result.type === "FIELD_REF" || result.type === "ARITH") return false;
|
|
35322
35642
|
return scalarValueHasAggregate(result);
|
|
35323
35643
|
}
|
|
@@ -35526,6 +35846,10 @@ function collectRequiredFieldsByTable(stmt, plainGroupByPlan, sourceAware) {
|
|
|
35526
35846
|
};
|
|
35527
35847
|
const walkCaseResult = (result, phase = "select") => {
|
|
35528
35848
|
if (result.type === "ARRAY") return;
|
|
35849
|
+
if (result.type === "AGG_REF" || result.type === "AGG_ARITH") {
|
|
35850
|
+
walkAgg(result, phase);
|
|
35851
|
+
return;
|
|
35852
|
+
}
|
|
35529
35853
|
if (result.type === "FIELD_REF" || result.type === "ARITH") {
|
|
35530
35854
|
walkArith(result, phase);
|
|
35531
35855
|
return;
|
|
@@ -35541,6 +35865,10 @@ function collectRequiredFieldsByTable(stmt, plainGroupByPlan, sourceAware) {
|
|
|
35541
35865
|
};
|
|
35542
35866
|
const walkFieldValue = (fv, phase = "select") => {
|
|
35543
35867
|
if (fv.type === "FIELD") {
|
|
35868
|
+
if (fv.aggregateRef) {
|
|
35869
|
+
walkAgg(fv.aggregateRef, phase);
|
|
35870
|
+
return;
|
|
35871
|
+
}
|
|
35544
35872
|
addFieldRef(fv.field, fv.tableAlias, phase);
|
|
35545
35873
|
return;
|
|
35546
35874
|
}
|
|
@@ -35548,6 +35876,10 @@ function collectRequiredFieldsByTable(stmt, plainGroupByPlan, sourceAware) {
|
|
|
35548
35876
|
walkStringFunc(fv.expr, phase);
|
|
35549
35877
|
return;
|
|
35550
35878
|
}
|
|
35879
|
+
if (fv.type === "AGG_FIELD") {
|
|
35880
|
+
walkAgg(fv.expr, phase);
|
|
35881
|
+
return;
|
|
35882
|
+
}
|
|
35551
35883
|
if (fv.type === "ARITH_FIELD") {
|
|
35552
35884
|
walkArith(fv.expr, phase);
|
|
35553
35885
|
return;
|
|
@@ -36292,410 +36624,225 @@ function validateOwnKlikeExpressions(stmt) {
|
|
|
36292
36624
|
}
|
|
36293
36625
|
function validateNestedSelects(node) {
|
|
36294
36626
|
walkObjects(node, (obj) => {
|
|
36295
|
-
if (obj.type === "SELECT") validateSelect(obj);
|
|
36296
|
-
}, true);
|
|
36297
|
-
}
|
|
36298
|
-
function containsKlike(node) {
|
|
36299
|
-
let found = false;
|
|
36300
|
-
walkObjects(node, (obj) => {
|
|
36301
|
-
if (obj.type === "BINARY" && (obj.op === "KLIKE" || obj.op === "NOT_KLIKE")) found = true;
|
|
36302
|
-
});
|
|
36303
|
-
return found;
|
|
36304
|
-
}
|
|
36305
|
-
function containsKlikeOutsideWhereAndNestedSelects(node, allowedWhere) {
|
|
36306
|
-
let found = false;
|
|
36307
|
-
const visit = (value) => {
|
|
36308
|
-
if (found || value === allowedWhere || value === null || typeof value !== "object") return;
|
|
36309
|
-
if (Array.isArray(value)) {
|
|
36310
|
-
for (const item of value) visit(item);
|
|
36311
|
-
return;
|
|
36312
|
-
}
|
|
36313
|
-
const obj = value;
|
|
36314
|
-
if (obj.type === "SELECT") return;
|
|
36315
|
-
if (obj.type === "BINARY" && (obj.op === "KLIKE" || obj.op === "NOT_KLIKE")) {
|
|
36316
|
-
found = true;
|
|
36317
|
-
return;
|
|
36318
|
-
}
|
|
36319
|
-
for (const child of Object.values(obj)) visit(child);
|
|
36320
|
-
};
|
|
36321
|
-
visit(node);
|
|
36322
|
-
return found;
|
|
36323
|
-
}
|
|
36324
|
-
function isDescendantOf(root, target) {
|
|
36325
|
-
if (root === null) return false;
|
|
36326
|
-
if (root === target) return true;
|
|
36327
|
-
switch (root.type) {
|
|
36328
|
-
case "LOGICAL":
|
|
36329
|
-
return isDescendantOf(root.left, target) || isDescendantOf(root.right, target);
|
|
36330
|
-
case "NOT":
|
|
36331
|
-
case "GROUP":
|
|
36332
|
-
return isDescendantOf(root.expr, target);
|
|
36333
|
-
case "BINARY":
|
|
36334
|
-
case "NULL_CHECK":
|
|
36335
|
-
case "EXISTS":
|
|
36336
|
-
return false;
|
|
36337
|
-
case "BOOLEAN":
|
|
36338
|
-
return false;
|
|
36339
|
-
}
|
|
36340
|
-
}
|
|
36341
|
-
function walkWithoutNestedSelects(node, visitWhere) {
|
|
36342
|
-
if (Array.isArray(node)) {
|
|
36343
|
-
for (const value of node) walkWithoutNestedSelects(value, visitWhere);
|
|
36344
|
-
return;
|
|
36345
|
-
}
|
|
36346
|
-
if (node === null || typeof node !== "object") return;
|
|
36347
|
-
const obj = node;
|
|
36348
|
-
if (obj.type === "BINARY" || obj.type === "NULL_CHECK" || obj.type === "LOGICAL" || obj.type === "NOT" || obj.type === "GROUP" || obj.type === "EXISTS") {
|
|
36349
|
-
visitWhere(obj);
|
|
36350
|
-
}
|
|
36351
|
-
for (const value of Object.values(obj)) {
|
|
36352
|
-
if (value !== node && isSelectObject(value)) continue;
|
|
36353
|
-
walkWithoutNestedSelects(value, visitWhere);
|
|
36354
|
-
}
|
|
36355
|
-
}
|
|
36356
|
-
function walkObjects(node, visit, skipRoot = false) {
|
|
36357
|
-
if (Array.isArray(node)) {
|
|
36358
|
-
for (const value of node) walkObjects(value, visit);
|
|
36359
|
-
return;
|
|
36360
|
-
}
|
|
36361
|
-
if (node === null || typeof node !== "object") return;
|
|
36362
|
-
const obj = node;
|
|
36363
|
-
if (!skipRoot) visit(obj);
|
|
36364
|
-
for (const value of Object.values(obj)) walkObjects(value, visit);
|
|
36365
|
-
}
|
|
36366
|
-
function isSelectObject(value) {
|
|
36367
|
-
return value !== null && typeof value === "object" && value.type === "SELECT";
|
|
36368
|
-
}
|
|
36369
|
-
|
|
36370
|
-
// src/core/primaryOrganizationDmlValidation.ts
|
|
36371
|
-
init_define_KSQL_DOCS();
|
|
36372
|
-
var PrimaryOrganizationDmlValidationError = class extends Error {
|
|
36373
|
-
constructor() {
|
|
36374
|
-
super(
|
|
36375
|
-
"ArgumentError: PRIMARY_ORGANIZATION() \u306F DML \u306E WHERE \u3067\u306F\u4F7F\u7528\u3067\u304D\u307E\u305B\u3093"
|
|
36376
|
-
);
|
|
36377
|
-
this.name = "ArgumentError";
|
|
36378
|
-
}
|
|
36379
|
-
};
|
|
36380
|
-
function validatePrimaryOrganizationDmlStatement(stmt) {
|
|
36381
|
-
const target = stmt.type === "EXPLAIN" ? stmt.query : stmt;
|
|
36382
|
-
switch (target.type) {
|
|
36383
|
-
case "UPDATE":
|
|
36384
|
-
case "DELETE":
|
|
36385
|
-
case "UPSERT":
|
|
36386
|
-
case "UPSERT_SELECT":
|
|
36387
|
-
case "INSERT_SELECT":
|
|
36388
|
-
if (hasPrimaryOrganizationInWhere(target)) {
|
|
36389
|
-
throw new PrimaryOrganizationDmlValidationError();
|
|
36390
|
-
}
|
|
36391
|
-
return;
|
|
36392
|
-
default:
|
|
36393
|
-
return;
|
|
36394
|
-
}
|
|
36627
|
+
if (obj.type === "SELECT") validateSelect(obj);
|
|
36628
|
+
}, true);
|
|
36395
36629
|
}
|
|
36396
|
-
function
|
|
36630
|
+
function containsKlike(node) {
|
|
36397
36631
|
let found = false;
|
|
36398
|
-
|
|
36399
|
-
if (
|
|
36400
|
-
if (containsPrimaryOrganization(obj.where)) found = true;
|
|
36632
|
+
walkObjects(node, (obj) => {
|
|
36633
|
+
if (obj.type === "BINARY" && (obj.op === "KLIKE" || obj.op === "NOT_KLIKE")) found = true;
|
|
36401
36634
|
});
|
|
36402
36635
|
return found;
|
|
36403
36636
|
}
|
|
36404
|
-
function
|
|
36637
|
+
function containsKlikeOutsideWhereAndNestedSelects(node, allowedWhere) {
|
|
36405
36638
|
let found = false;
|
|
36406
|
-
|
|
36407
|
-
if (
|
|
36639
|
+
const visit = (value) => {
|
|
36640
|
+
if (found || value === allowedWhere || value === null || typeof value !== "object") return;
|
|
36641
|
+
if (Array.isArray(value)) {
|
|
36642
|
+
for (const item of value) visit(item);
|
|
36643
|
+
return;
|
|
36644
|
+
}
|
|
36645
|
+
const obj = value;
|
|
36646
|
+
if (obj.type === "SELECT") return;
|
|
36647
|
+
if (obj.type === "BINARY" && (obj.op === "KLIKE" || obj.op === "NOT_KLIKE")) {
|
|
36408
36648
|
found = true;
|
|
36649
|
+
return;
|
|
36409
36650
|
}
|
|
36410
|
-
|
|
36651
|
+
for (const child of Object.values(obj)) visit(child);
|
|
36652
|
+
};
|
|
36653
|
+
visit(node);
|
|
36411
36654
|
return found;
|
|
36412
36655
|
}
|
|
36413
|
-
function
|
|
36414
|
-
if (
|
|
36415
|
-
|
|
36416
|
-
|
|
36417
|
-
|
|
36418
|
-
|
|
36419
|
-
|
|
36420
|
-
|
|
36421
|
-
|
|
36422
|
-
|
|
36423
|
-
|
|
36424
|
-
|
|
36425
|
-
|
|
36426
|
-
|
|
36427
|
-
|
|
36428
|
-
validateKlikeStatement(stmt);
|
|
36429
|
-
}
|
|
36430
|
-
|
|
36431
|
-
// src/core/groupingValidation.ts
|
|
36432
|
-
init_define_KSQL_DOCS();
|
|
36433
|
-
|
|
36434
|
-
// src/engine/groupingRowMeta.ts
|
|
36435
|
-
init_define_KSQL_DOCS();
|
|
36436
|
-
var groupingRowMetaKey = /* @__PURE__ */ Symbol("ksql.groupingRowMeta");
|
|
36437
|
-
var groupingRefCanonicalIds = /* @__PURE__ */ new WeakMap();
|
|
36438
|
-
function attachGroupingRowMeta(row, includedCanonicalIds) {
|
|
36439
|
-
Object.defineProperty(row, groupingRowMetaKey, {
|
|
36440
|
-
value: { includedCanonicalIds },
|
|
36441
|
-
enumerable: false,
|
|
36442
|
-
configurable: false,
|
|
36443
|
-
writable: false
|
|
36444
|
-
});
|
|
36445
|
-
return row;
|
|
36446
|
-
}
|
|
36447
|
-
function getGroupingRowMeta(row) {
|
|
36448
|
-
return row[groupingRowMetaKey];
|
|
36449
|
-
}
|
|
36450
|
-
function readGroupingMembership(row) {
|
|
36451
|
-
return getGroupingRowMeta(row)?.includedCanonicalIds;
|
|
36452
|
-
}
|
|
36453
|
-
function bindGroupingRefCanonicalId(ref, canonicalId) {
|
|
36454
|
-
groupingRefCanonicalIds.set(ref, canonicalId);
|
|
36455
|
-
}
|
|
36456
|
-
function evalGroupingRef(ref, row) {
|
|
36457
|
-
const membership = readGroupingMembership(row);
|
|
36458
|
-
if (!membership) {
|
|
36459
|
-
throw new Error("internal error: GROUPING() evaluation requires B65 grouping row membership.");
|
|
36460
|
-
}
|
|
36461
|
-
const canonicalId = groupingRefCanonicalIds.get(ref);
|
|
36462
|
-
if (!canonicalId) {
|
|
36463
|
-
throw new Error("internal error: GROUPING() reference was not resolved during B65 planning.");
|
|
36464
|
-
}
|
|
36465
|
-
return membership.has(canonicalId) ? "0" : "1";
|
|
36466
|
-
}
|
|
36467
|
-
|
|
36468
|
-
// src/core/groupingValidation.ts
|
|
36469
|
-
var enforceGroupingPlanningCandidateLimits = (facts) => {
|
|
36470
|
-
if (facts.expandedSetCount > B65_MAX_GROUPING_SETS) {
|
|
36471
|
-
throw new Error(
|
|
36472
|
-
`ArgumentError: B65 expanded grouping set count ${facts.expandedSetCount} exceeds limit ${B65_MAX_GROUPING_SETS} (reason=GROUPING_SET_LIMIT_EXCEEDED).`
|
|
36473
|
-
);
|
|
36474
|
-
}
|
|
36475
|
-
if (facts.canonicalItemCount > B65_MAX_GROUPING_ITEMS) {
|
|
36476
|
-
throw new Error(
|
|
36477
|
-
`ArgumentError: B65 canonical grouping item count ${facts.canonicalItemCount} exceeds limit ${B65_MAX_GROUPING_ITEMS} (reason=GROUPING_ITEM_LIMIT_EXCEEDED).`
|
|
36478
|
-
);
|
|
36656
|
+
function isDescendantOf(root, target) {
|
|
36657
|
+
if (root === null) return false;
|
|
36658
|
+
if (root === target) return true;
|
|
36659
|
+
switch (root.type) {
|
|
36660
|
+
case "LOGICAL":
|
|
36661
|
+
return isDescendantOf(root.left, target) || isDescendantOf(root.right, target);
|
|
36662
|
+
case "NOT":
|
|
36663
|
+
case "GROUP":
|
|
36664
|
+
return isDescendantOf(root.expr, target);
|
|
36665
|
+
case "BINARY":
|
|
36666
|
+
case "NULL_CHECK":
|
|
36667
|
+
case "EXISTS":
|
|
36668
|
+
return false;
|
|
36669
|
+
case "BOOLEAN":
|
|
36670
|
+
return false;
|
|
36479
36671
|
}
|
|
36480
|
-
};
|
|
36481
|
-
function displayField(field) {
|
|
36482
|
-
return field.tableAlias ? `${field.tableAlias}.${field.field}` : field.field;
|
|
36483
|
-
}
|
|
36484
|
-
function refFromName(name) {
|
|
36485
|
-
const dot = name.indexOf(".");
|
|
36486
|
-
return dot > 0 ? { type: "FIELD", tableAlias: name.slice(0, dot), field: name.slice(dot + 1) } : { type: "FIELD", tableAlias: null, field: name };
|
|
36487
36672
|
}
|
|
36488
|
-
function
|
|
36489
|
-
if (node === null || typeof node !== "object") return;
|
|
36673
|
+
function walkWithoutNestedSelects(node, visitWhere) {
|
|
36490
36674
|
if (Array.isArray(node)) {
|
|
36491
|
-
node
|
|
36492
|
-
return;
|
|
36493
|
-
}
|
|
36494
|
-
const value = node;
|
|
36495
|
-
if (value["type"] === "SELECT" || value["type"] === "SCALAR_SUBQUERY") return;
|
|
36496
|
-
if (value["type"] === "GROUPING_REF") {
|
|
36497
|
-
out.push(value);
|
|
36675
|
+
for (const value of node) walkWithoutNestedSelects(value, visitWhere);
|
|
36498
36676
|
return;
|
|
36499
36677
|
}
|
|
36500
|
-
Object.values(value).forEach((item) => collectGroupingRefs(item, out));
|
|
36501
|
-
}
|
|
36502
|
-
function collectAggregateArgumentGroupingRefs(node, out) {
|
|
36503
36678
|
if (node === null || typeof node !== "object") return;
|
|
36504
|
-
|
|
36505
|
-
|
|
36506
|
-
|
|
36679
|
+
const obj = node;
|
|
36680
|
+
if (obj.type === "BINARY" || obj.type === "NULL_CHECK" || obj.type === "LOGICAL" || obj.type === "NOT" || obj.type === "GROUP" || obj.type === "EXISTS") {
|
|
36681
|
+
visitWhere(obj);
|
|
36507
36682
|
}
|
|
36508
|
-
const value
|
|
36509
|
-
|
|
36510
|
-
|
|
36511
|
-
collectGroupingRefs(value["arg"], out);
|
|
36512
|
-
return;
|
|
36683
|
+
for (const value of Object.values(obj)) {
|
|
36684
|
+
if (value !== node && isSelectObject(value)) continue;
|
|
36685
|
+
walkWithoutNestedSelects(value, visitWhere);
|
|
36513
36686
|
}
|
|
36514
|
-
Object.values(value).forEach((item) => collectAggregateArgumentGroupingRefs(item, out));
|
|
36515
36687
|
}
|
|
36516
|
-
function
|
|
36517
|
-
if (node === null || typeof node !== "object") return;
|
|
36688
|
+
function walkObjects(node, visit, skipRoot = false) {
|
|
36518
36689
|
if (Array.isArray(node)) {
|
|
36519
|
-
node
|
|
36520
|
-
return;
|
|
36521
|
-
}
|
|
36522
|
-
const value = node;
|
|
36523
|
-
const type = value["type"];
|
|
36524
|
-
if (type === "SELECT" || type === "SCALAR_SUBQUERY" || type === "GROUPING_REF" || type === "AGG_REF" || type === "AGG_ARITH") return;
|
|
36525
|
-
if (type === "FIELD" && typeof value["field"] === "string") {
|
|
36526
|
-
out.push({
|
|
36527
|
-
type: "FIELD",
|
|
36528
|
-
tableAlias: typeof value["tableAlias"] === "string" ? value["tableAlias"] : null,
|
|
36529
|
-
field: value["field"]
|
|
36530
|
-
});
|
|
36531
|
-
return;
|
|
36532
|
-
}
|
|
36533
|
-
if (type === "FIELD_REF" && typeof value["field"] === "string") {
|
|
36534
|
-
out.push(refFromName(value["field"]));
|
|
36535
|
-
return;
|
|
36536
|
-
}
|
|
36537
|
-
Object.values(value).forEach((item) => collectNonAggregateFieldRefs(item, out));
|
|
36538
|
-
}
|
|
36539
|
-
function containsAggregate2(node) {
|
|
36540
|
-
if (node === null || typeof node !== "object") return false;
|
|
36541
|
-
if (Array.isArray(node)) return node.some(containsAggregate2);
|
|
36542
|
-
const value = node;
|
|
36543
|
-
if (value["type"] === "AGG_REF" || value["type"] === "AGG_ARITH") return true;
|
|
36544
|
-
if (value["type"] === "SELECT" || value["type"] === "SCALAR_SUBQUERY") return false;
|
|
36545
|
-
return Object.values(value).some(containsAggregate2);
|
|
36546
|
-
}
|
|
36547
|
-
function isAggregateMaterializedAlias(column) {
|
|
36548
|
-
if (!("alias" in column) || column.alias === null) return false;
|
|
36549
|
-
if (column.type === "AGGREGATE" || column.type === "ARITH_AGG_COL") return true;
|
|
36550
|
-
if (column.type === "STRFUNC_COL" || column.type === "SCALAR_VALUE_COL") {
|
|
36551
|
-
return containsAggregate2(column);
|
|
36552
|
-
}
|
|
36553
|
-
return false;
|
|
36554
|
-
}
|
|
36555
|
-
function outputAliases(columns) {
|
|
36556
|
-
return new Set(columns.flatMap(
|
|
36557
|
-
(column) => "alias" in column && typeof column.alias === "string" ? [column.alias] : []
|
|
36558
|
-
));
|
|
36559
|
-
}
|
|
36560
|
-
function isAggregateSyntheticReference(ref) {
|
|
36561
|
-
return ref.tableAlias === null && /^(COUNT|SUM|AVG|MAX|MIN|GROUP_CONCAT|STDDEV_POP|STDDEV_SAMP|VAR_POP|VAR_SAMP|MEDIAN|MODE)\(/.test(ref.field);
|
|
36562
|
-
}
|
|
36563
|
-
function validateGroupingRefMembership(ref, resolve3, canonicalItems) {
|
|
36564
|
-
const resolved = resolve3(ref.field);
|
|
36565
|
-
if (!resolved.physical) {
|
|
36566
|
-
throw new Error(`ArgumentError: B65 grouping reference ${displayField(ref.field)} must resolve to a physical APP field.`);
|
|
36567
|
-
}
|
|
36568
|
-
if (!canonicalItems.has(resolved.canonicalId)) {
|
|
36569
|
-
throw new Error(
|
|
36570
|
-
`ArgumentError: B65 GROUPING argument ${displayField(ref.field)} is not present in grouping allItems (reason=B65_GROUPING_ARG_NOT_ITEM).`
|
|
36571
|
-
);
|
|
36572
|
-
}
|
|
36573
|
-
bindGroupingRefCanonicalId(ref, resolved.canonicalId);
|
|
36574
|
-
}
|
|
36575
|
-
function validateDependency(ref, resolve3, canonicalItems, context) {
|
|
36576
|
-
const resolved = resolve3(ref);
|
|
36577
|
-
if (!resolved.physical || !canonicalItems.has(resolved.canonicalId)) {
|
|
36578
|
-
throw new Error(
|
|
36579
|
-
`ArgumentError: B65 non-aggregate field ${displayField(ref)} in ${context} is not a grouping item (reason=B65_NON_GROUPED_DEPENDENCY).`
|
|
36580
|
-
);
|
|
36581
|
-
}
|
|
36582
|
-
}
|
|
36583
|
-
function keyDependencies(key) {
|
|
36584
|
-
if (key.type === "GROUPING_KEY") return [];
|
|
36585
|
-
if (key.type === "FIELD_NAME") return [refFromName(key.name)];
|
|
36586
|
-
const refs = [];
|
|
36587
|
-
collectNonAggregateFieldRefs(key, refs);
|
|
36588
|
-
return refs;
|
|
36589
|
-
}
|
|
36590
|
-
function validateGroupingStatic(stmt) {
|
|
36591
|
-
const normalized = normalizeGroupingSpec(stmt);
|
|
36592
|
-
const groupingRefs = [];
|
|
36593
|
-
for (const column of stmt.columns) {
|
|
36594
|
-
if (column.type !== "WINDOW_COL") collectGroupingRefs(column, groupingRefs);
|
|
36595
|
-
}
|
|
36596
|
-
collectGroupingRefs(stmt.having, groupingRefs);
|
|
36597
|
-
collectGroupingRefs(stmt.orderBy, groupingRefs);
|
|
36598
|
-
const forbiddenGroupingRefs = [];
|
|
36599
|
-
collectGroupingRefs(stmt.where, forbiddenGroupingRefs);
|
|
36600
|
-
collectGroupingRefs(stmt.joins, forbiddenGroupingRefs);
|
|
36601
|
-
collectAggregateArgumentGroupingRefs(stmt.columns, forbiddenGroupingRefs);
|
|
36602
|
-
collectAggregateArgumentGroupingRefs(stmt.having, forbiddenGroupingRefs);
|
|
36603
|
-
for (const column of stmt.columns) {
|
|
36604
|
-
if (column.type === "WINDOW_COL") collectGroupingRefs(column, forbiddenGroupingRefs);
|
|
36605
|
-
}
|
|
36606
|
-
if (forbiddenGroupingRefs.length > 0) {
|
|
36607
|
-
throw new Error(
|
|
36608
|
-
"ArgumentError: B65 GROUPING() is not allowed in WHERE, JOIN, window, aggregate arguments, or DML expressions."
|
|
36609
|
-
);
|
|
36610
|
-
}
|
|
36611
|
-
if (normalized.type !== "GROUPING_SETS") {
|
|
36612
|
-
if (groupingRefs.length > 0) {
|
|
36613
|
-
throw new Error("ArgumentError: B65 GROUPING() requires GROUP BY ROLLUP or GROUPING SETS.");
|
|
36614
|
-
}
|
|
36690
|
+
for (const value of node) walkObjects(value, visit);
|
|
36615
36691
|
return;
|
|
36616
36692
|
}
|
|
36617
|
-
if (
|
|
36618
|
-
|
|
36619
|
-
|
|
36620
|
-
|
|
36621
|
-
throw new Error("ArgumentError: B65 window functions are not supported in Phase1.");
|
|
36622
|
-
}
|
|
36623
|
-
if (stmt.columns.some(
|
|
36624
|
-
(column) => column.type === "WILDCARD" || column.type === "PARENT_WILDCARD"
|
|
36625
|
-
)) {
|
|
36626
|
-
throw new Error("ArgumentError: B65 wildcard projection is not supported in Phase1.");
|
|
36627
|
-
}
|
|
36693
|
+
if (node === null || typeof node !== "object") return;
|
|
36694
|
+
const obj = node;
|
|
36695
|
+
if (!skipRoot) visit(obj);
|
|
36696
|
+
for (const value of Object.values(obj)) walkObjects(value, visit);
|
|
36628
36697
|
}
|
|
36629
|
-
function
|
|
36630
|
-
|
|
36631
|
-
|
|
36632
|
-
|
|
36633
|
-
|
|
36634
|
-
|
|
36698
|
+
function isSelectObject(value) {
|
|
36699
|
+
return value !== null && typeof value === "object" && value.type === "SELECT";
|
|
36700
|
+
}
|
|
36701
|
+
|
|
36702
|
+
// src/core/primaryOrganizationDmlValidation.ts
|
|
36703
|
+
init_define_KSQL_DOCS();
|
|
36704
|
+
var PrimaryOrganizationDmlValidationError = class extends Error {
|
|
36705
|
+
constructor() {
|
|
36706
|
+
super(
|
|
36707
|
+
"ArgumentError: PRIMARY_ORGANIZATION() \u306F DML \u306E WHERE \u3067\u306F\u4F7F\u7528\u3067\u304D\u307E\u305B\u3093"
|
|
36708
|
+
);
|
|
36709
|
+
this.name = "ArgumentError";
|
|
36635
36710
|
}
|
|
36636
|
-
|
|
36637
|
-
|
|
36638
|
-
|
|
36639
|
-
|
|
36711
|
+
};
|
|
36712
|
+
function validatePrimaryOrganizationDmlStatement(stmt) {
|
|
36713
|
+
const target = stmt.type === "EXPLAIN" ? stmt.query : stmt;
|
|
36714
|
+
switch (target.type) {
|
|
36715
|
+
case "UPDATE":
|
|
36716
|
+
case "DELETE":
|
|
36717
|
+
case "UPSERT":
|
|
36718
|
+
case "UPSERT_SELECT":
|
|
36719
|
+
case "INSERT_SELECT":
|
|
36720
|
+
if (hasPrimaryOrganizationInWhere(target)) {
|
|
36721
|
+
throw new PrimaryOrganizationDmlValidationError();
|
|
36722
|
+
}
|
|
36723
|
+
return;
|
|
36724
|
+
default:
|
|
36725
|
+
return;
|
|
36640
36726
|
}
|
|
36641
|
-
|
|
36642
|
-
|
|
36643
|
-
|
|
36644
|
-
|
|
36645
|
-
|
|
36646
|
-
if (
|
|
36647
|
-
|
|
36648
|
-
|
|
36649
|
-
|
|
36650
|
-
|
|
36651
|
-
|
|
36727
|
+
}
|
|
36728
|
+
function hasPrimaryOrganizationInWhere(node) {
|
|
36729
|
+
let found = false;
|
|
36730
|
+
walkObjects2(node, (obj) => {
|
|
36731
|
+
if (found || !Object.prototype.hasOwnProperty.call(obj, "where")) return;
|
|
36732
|
+
if (containsPrimaryOrganization(obj.where)) found = true;
|
|
36733
|
+
});
|
|
36734
|
+
return found;
|
|
36735
|
+
}
|
|
36736
|
+
function containsPrimaryOrganization(node) {
|
|
36737
|
+
let found = false;
|
|
36738
|
+
walkObjects2(node, (obj) => {
|
|
36739
|
+
if (obj.type === "KINTONE_FUNC" && obj.name === "PRIMARY_ORGANIZATION") {
|
|
36740
|
+
found = true;
|
|
36652
36741
|
}
|
|
36653
|
-
}
|
|
36654
|
-
planningGuardHook({
|
|
36655
|
-
expandedSetCount: normalized.sets.length,
|
|
36656
|
-
canonicalItemCount: canonicalItems.size
|
|
36657
36742
|
});
|
|
36658
|
-
|
|
36659
|
-
|
|
36660
|
-
|
|
36661
|
-
|
|
36662
|
-
|
|
36663
|
-
|
|
36664
|
-
const refs = [];
|
|
36665
|
-
if (column.type === "FIELD") refs.push(refFromName(column.field));
|
|
36666
|
-
else collectNonAggregateFieldRefs(column, refs);
|
|
36667
|
-
for (const ref of refs) validateDependency(ref, resolve3, canonicalItems, "SELECT");
|
|
36743
|
+
return found;
|
|
36744
|
+
}
|
|
36745
|
+
function walkObjects2(node, visit) {
|
|
36746
|
+
if (Array.isArray(node)) {
|
|
36747
|
+
for (const value of node) walkObjects2(value, visit);
|
|
36748
|
+
return;
|
|
36668
36749
|
}
|
|
36669
|
-
if (
|
|
36670
|
-
|
|
36671
|
-
|
|
36672
|
-
|
|
36673
|
-
|
|
36674
|
-
|
|
36675
|
-
|
|
36750
|
+
if (node === null || typeof node !== "object") return;
|
|
36751
|
+
const obj = node;
|
|
36752
|
+
visit(obj);
|
|
36753
|
+
for (const value of Object.values(obj)) walkObjects2(value, visit);
|
|
36754
|
+
}
|
|
36755
|
+
|
|
36756
|
+
// src/core/statementValidation.ts
|
|
36757
|
+
init_define_KSQL_DOCS();
|
|
36758
|
+
|
|
36759
|
+
// src/core/functionArity.ts
|
|
36760
|
+
init_define_KSQL_DOCS();
|
|
36761
|
+
function assertArity(func, args, min, max = Number.POSITIVE_INFINITY) {
|
|
36762
|
+
if (args.length >= min && args.length <= max) return;
|
|
36763
|
+
const expected = min === max ? String(min) : max === Number.POSITIVE_INFINITY ? `${min} or more` : `${min} to ${max}`;
|
|
36764
|
+
throw new Error(`ArgumentError: ${func} expects ${expected} argument(s).`);
|
|
36765
|
+
}
|
|
36766
|
+
function assertStringFunctionArity(func, args) {
|
|
36767
|
+
switch (func) {
|
|
36768
|
+
case "UPPER":
|
|
36769
|
+
case "LOWER":
|
|
36770
|
+
case "TRIM":
|
|
36771
|
+
case "LTRIM":
|
|
36772
|
+
case "RTRIM":
|
|
36773
|
+
case "LENGTH":
|
|
36774
|
+
case "LENGTH_CHAR":
|
|
36775
|
+
case "YEAR":
|
|
36776
|
+
case "MONTH":
|
|
36777
|
+
case "DAY":
|
|
36778
|
+
case "DAYOFWEEK":
|
|
36779
|
+
case "QUARTER":
|
|
36780
|
+
case "WEEK":
|
|
36781
|
+
case "LAST_DAY":
|
|
36782
|
+
case "ABS":
|
|
36783
|
+
case "SQRT":
|
|
36784
|
+
return assertArity(func, args, 1, 1);
|
|
36785
|
+
case "SUBSTRING":
|
|
36786
|
+
case "LPAD":
|
|
36787
|
+
case "RPAD":
|
|
36788
|
+
case "REGEXP_LIKE":
|
|
36789
|
+
case "REGEXP_SUBSTR":
|
|
36790
|
+
return assertArity(func, args, 2, 3);
|
|
36791
|
+
case "LEFT":
|
|
36792
|
+
case "RIGHT":
|
|
36793
|
+
case "INSTR":
|
|
36794
|
+
case "ISNULL":
|
|
36795
|
+
case "NULLIF":
|
|
36796
|
+
case "MOD":
|
|
36797
|
+
case "POWER":
|
|
36798
|
+
case "FORMAT":
|
|
36799
|
+
case "CAST":
|
|
36800
|
+
case "DATE_FORMAT":
|
|
36801
|
+
case "DATEDIFF":
|
|
36802
|
+
return assertArity(func, args, 2, 2);
|
|
36803
|
+
case "CONCAT":
|
|
36804
|
+
case "COALESCE":
|
|
36805
|
+
case "GREATEST":
|
|
36806
|
+
case "LEAST":
|
|
36807
|
+
return assertArity(func, args, 2);
|
|
36808
|
+
case "REPLACE":
|
|
36809
|
+
case "TRANSLATE":
|
|
36810
|
+
case "DATE_ADD":
|
|
36811
|
+
return assertArity(func, args, 3, 3);
|
|
36812
|
+
case "REGEXP_REPLACE":
|
|
36813
|
+
return assertArity(func, args, 3, 5);
|
|
36814
|
+
case "ROUND":
|
|
36815
|
+
case "FLOOR":
|
|
36816
|
+
case "CEIL":
|
|
36817
|
+
case "TRUNCATE":
|
|
36818
|
+
return assertArity(func, args, 1, 2);
|
|
36819
|
+
case "CURRENT_DATE":
|
|
36820
|
+
case "CURRENT_TIMESTAMP":
|
|
36821
|
+
return assertArity(func, args, 0, 0);
|
|
36676
36822
|
}
|
|
36677
|
-
|
|
36678
|
-
|
|
36679
|
-
|
|
36680
|
-
|
|
36823
|
+
}
|
|
36824
|
+
|
|
36825
|
+
// src/core/statementValidation.ts
|
|
36826
|
+
function validateStatementStatic(stmt) {
|
|
36827
|
+
validateStringFunctionArities(stmt);
|
|
36828
|
+
validatePrimaryOrganizationDmlStatement(stmt);
|
|
36829
|
+
validateKlikeStatement(stmt);
|
|
36830
|
+
}
|
|
36831
|
+
function validateStringFunctionArities(stmt) {
|
|
36832
|
+
const visit = (value) => {
|
|
36833
|
+
if (value === null || typeof value !== "object") return;
|
|
36834
|
+
if (Array.isArray(value)) {
|
|
36835
|
+
value.forEach(visit);
|
|
36836
|
+
return;
|
|
36681
36837
|
}
|
|
36682
|
-
|
|
36683
|
-
|
|
36684
|
-
|
|
36685
|
-
|
|
36686
|
-
if (item.unqualifiedBridgeKey !== null) collisionKeys.add(item.unqualifiedBridgeKey);
|
|
36687
|
-
}
|
|
36688
|
-
for (const column of stmt.columns) {
|
|
36689
|
-
if (!isAggregateMaterializedAlias(column)) continue;
|
|
36690
|
-
const alias = "alias" in column ? column.alias : null;
|
|
36691
|
-
if (alias === null) continue;
|
|
36692
|
-
if (collisionKeys.has(alias)) {
|
|
36693
|
-
throw new Error(
|
|
36694
|
-
`ArgumentError: B65 aggregate alias ${alias} collides with a grouping runtime key (reason=B65_AGGREGATE_ALIAS_COLLISION).`
|
|
36695
|
-
);
|
|
36838
|
+
const node = value;
|
|
36839
|
+
if (node.type === "STRING_FUNC") {
|
|
36840
|
+
const expr = node;
|
|
36841
|
+
assertStringFunctionArity(expr.func, expr.args);
|
|
36696
36842
|
}
|
|
36697
|
-
|
|
36698
|
-
|
|
36843
|
+
Object.values(node).forEach(visit);
|
|
36844
|
+
};
|
|
36845
|
+
visit(stmt);
|
|
36699
36846
|
}
|
|
36700
36847
|
|
|
36701
36848
|
// src/core/batch.ts
|
|
@@ -37474,6 +37621,7 @@ function replaceNthMatch(input, globalRe, replacement, n) {
|
|
|
37474
37621
|
});
|
|
37475
37622
|
}
|
|
37476
37623
|
function evalStringFunc(expr, row, resolveFieldType, resolveFieldSemantics2) {
|
|
37624
|
+
assertStringFunctionArity(expr.func, expr.args);
|
|
37477
37625
|
const args = expr.args.map((a) => evalStringFuncArg(a, row, resolveFieldType, resolveFieldSemantics2));
|
|
37478
37626
|
switch (expr.func) {
|
|
37479
37627
|
case "UPPER":
|
|
@@ -37489,7 +37637,6 @@ function evalStringFunc(expr, row, resolveFieldType, resolveFieldSemantics2) {
|
|
|
37489
37637
|
case "LENGTH":
|
|
37490
37638
|
return String((args[0] ?? "").length);
|
|
37491
37639
|
case "LENGTH_CHAR":
|
|
37492
|
-
assertArity("LENGTH_CHAR", args, 1, 1);
|
|
37493
37640
|
return String([...args[0] ?? ""].length);
|
|
37494
37641
|
case "SUBSTRING": {
|
|
37495
37642
|
const str = args[0] ?? "";
|
|
@@ -37498,23 +37645,19 @@ function evalStringFunc(expr, row, resolveFieldType, resolveFieldSemantics2) {
|
|
|
37498
37645
|
return sliceSafeRange(str, start, len !== void 0 ? start + len : str.length);
|
|
37499
37646
|
}
|
|
37500
37647
|
case "LEFT": {
|
|
37501
|
-
assertArity("LEFT", args, 2, 2);
|
|
37502
37648
|
const str = args[0];
|
|
37503
37649
|
const n = Math.trunc(Number(args[1]));
|
|
37504
37650
|
return Number.isNaN(n) || n <= 0 ? "" : sliceSafePrefix(str, n);
|
|
37505
37651
|
}
|
|
37506
37652
|
case "RIGHT": {
|
|
37507
|
-
assertArity("RIGHT", args, 2, 2);
|
|
37508
37653
|
const str = args[0];
|
|
37509
37654
|
const n = Math.trunc(Number(args[1]));
|
|
37510
37655
|
return Number.isNaN(n) || n <= 0 ? "" : sliceSafeSuffix(str, n);
|
|
37511
37656
|
}
|
|
37512
37657
|
case "INSTR":
|
|
37513
|
-
assertArity("INSTR", args, 2, 2);
|
|
37514
37658
|
return String(args[0].indexOf(args[1]) + 1);
|
|
37515
37659
|
case "LPAD":
|
|
37516
37660
|
case "RPAD": {
|
|
37517
|
-
assertArity(expr.func, args, 2, 3);
|
|
37518
37661
|
const str = args[0];
|
|
37519
37662
|
const n = Math.trunc(Number(args[1]));
|
|
37520
37663
|
if (Number.isNaN(n) || n <= 0) return "";
|
|
@@ -37526,7 +37669,6 @@ function evalStringFunc(expr, row, resolveFieldType, resolveFieldSemantics2) {
|
|
|
37526
37669
|
}
|
|
37527
37670
|
case "GREATEST":
|
|
37528
37671
|
case "LEAST":
|
|
37529
|
-
assertArity(expr.func, args, 2);
|
|
37530
37672
|
return selectScalarExtreme(args, expr.func === "GREATEST" ? "greatest" : "least");
|
|
37531
37673
|
case "CONCAT":
|
|
37532
37674
|
return args.join("");
|
|
@@ -37537,22 +37679,18 @@ function evalStringFunc(expr, row, resolveFieldType, resolveFieldSemantics2) {
|
|
|
37537
37679
|
return from === "" ? str : str.split(from).join(to);
|
|
37538
37680
|
}
|
|
37539
37681
|
case "REGEXP_LIKE": {
|
|
37540
|
-
assertArity("REGEXP_LIKE", args, 2, 3);
|
|
37541
37682
|
return compileRegexp(args[1], args[2] ?? "").test(args[0]) ? "1" : "0";
|
|
37542
37683
|
}
|
|
37543
37684
|
case "REGEXP_REPLACE": {
|
|
37544
|
-
assertArity("REGEXP_REPLACE", args, 3, 5);
|
|
37545
37685
|
assertRegexpReplacement(args[2]);
|
|
37546
37686
|
const occurrence = parseRegexpOccurrence(args[4]);
|
|
37547
37687
|
const regexp = compileRegexp(args[1], args[3] ?? "", true);
|
|
37548
37688
|
return occurrence === 0 ? args[0].replace(regexp, args[2]) : replaceNthMatch(args[0], regexp, args[2], occurrence);
|
|
37549
37689
|
}
|
|
37550
37690
|
case "REGEXP_SUBSTR": {
|
|
37551
|
-
assertArity("REGEXP_SUBSTR", args, 2, 3);
|
|
37552
37691
|
return compileRegexp(args[1], args[2] ?? "").exec(args[0])?.[0] ?? "";
|
|
37553
37692
|
}
|
|
37554
37693
|
case "TRANSLATE": {
|
|
37555
|
-
assertArity("TRANSLATE", args, 3, 3);
|
|
37556
37694
|
const from = [...args[1]];
|
|
37557
37695
|
const to = [...args[2]];
|
|
37558
37696
|
if (from.length !== to.length) {
|
|
@@ -37579,7 +37717,6 @@ function evalStringFunc(expr, row, resolveFieldType, resolveFieldSemantics2) {
|
|
|
37579
37717
|
case "CEIL":
|
|
37580
37718
|
return applyRoundOp("ceil", Number(args[0] ?? "0"), Number(args[1] ?? "0"));
|
|
37581
37719
|
case "TRUNCATE":
|
|
37582
|
-
assertArity("TRUNCATE", args, 1, 2);
|
|
37583
37720
|
return applyRoundOp("trunc", Number(args[0]), Number(args[1] ?? "0"));
|
|
37584
37721
|
case "CAST": {
|
|
37585
37722
|
const val = args[0] ?? "";
|
|
@@ -37608,13 +37745,10 @@ function evalStringFunc(expr, row, resolveFieldType, resolveFieldSemantics2) {
|
|
|
37608
37745
|
return d.length >= 10 ? String(parseInt(d.slice(8, 10), 10)) : "";
|
|
37609
37746
|
}
|
|
37610
37747
|
case "DAYOFWEEK":
|
|
37611
|
-
assertArity(expr.func, args, 1, 1);
|
|
37612
37748
|
return isValidYmd(args[0]) ? String(dayOfWeekIndex(args[0]) + 1) : "";
|
|
37613
37749
|
case "QUARTER":
|
|
37614
|
-
assertArity(expr.func, args, 1, 1);
|
|
37615
37750
|
return isValidYmd(args[0]) ? String(Math.ceil(Number(args[0].slice(5, 7)) / 3)) : "";
|
|
37616
37751
|
case "WEEK":
|
|
37617
|
-
assertArity(expr.func, args, 1, 1);
|
|
37618
37752
|
return isValidYmd(args[0]) ? String(isoWeekNumber(args[0])) : "";
|
|
37619
37753
|
case "DATE_FORMAT":
|
|
37620
37754
|
return applyDateFormat(args[0] ?? "", args[1] ?? "");
|
|
@@ -37623,7 +37757,6 @@ function evalStringFunc(expr, row, resolveFieldType, resolveFieldSemantics2) {
|
|
|
37623
37757
|
case "DATE_ADD":
|
|
37624
37758
|
return applyDateAdd(args[0] ?? "", Number(args[1] ?? "0"), (args[2] ?? "DAY").toUpperCase());
|
|
37625
37759
|
case "LAST_DAY":
|
|
37626
|
-
assertArity("LAST_DAY", args, 1, 1);
|
|
37627
37760
|
return applyLastDay(args[0]);
|
|
37628
37761
|
case "ABS":
|
|
37629
37762
|
return String(Math.abs(Number(args[0] ?? "0")));
|
|
@@ -37647,11 +37780,6 @@ function evalStringFunc(expr, row, resolveFieldType, resolveFieldSemantics2) {
|
|
|
37647
37780
|
return (/* @__PURE__ */ new Date()).toISOString();
|
|
37648
37781
|
}
|
|
37649
37782
|
}
|
|
37650
|
-
function assertArity(func, args, min, max = Number.POSITIVE_INFINITY) {
|
|
37651
|
-
if (args.length >= min && args.length <= max) return;
|
|
37652
|
-
const expected = min === max ? String(min) : max === Number.POSITIVE_INFINITY ? `${min} or more` : `${min} to ${max}`;
|
|
37653
|
-
throw new Error(`ArgumentError: ${func} expects ${expected} argument(s).`);
|
|
37654
|
-
}
|
|
37655
37783
|
function parseDateParts(s) {
|
|
37656
37784
|
return {
|
|
37657
37785
|
y: s.slice(0, 4) || "0000",
|
|
@@ -37812,10 +37940,32 @@ function formatWithComma(num, digits) {
|
|
|
37812
37940
|
return decStr ? `${intFmt}.${decStr}` : intFmt;
|
|
37813
37941
|
}
|
|
37814
37942
|
function evalStringFuncArg(arg, row, resolveFieldType, resolveFieldSemantics2) {
|
|
37815
|
-
if (arg.type === "AGG_REF" || arg.type === "AGG_ARITH")
|
|
37943
|
+
if (arg.type === "AGG_REF" || arg.type === "AGG_ARITH") {
|
|
37944
|
+
return String(evalMaterializedAggregateOperand(arg, row));
|
|
37945
|
+
}
|
|
37816
37946
|
if (arg.type === "NUMBER") return numberLiteralText(arg);
|
|
37817
37947
|
return String(evalScalarValueExpr(arg, row, resolveFieldType, resolveFieldSemantics2));
|
|
37818
37948
|
}
|
|
37949
|
+
function evalMaterializedAggregateOperand(node, row) {
|
|
37950
|
+
if (node.type === "NUMBER") return node.value;
|
|
37951
|
+
if (node.type === "AGG_REF") {
|
|
37952
|
+
return row[aggregateSyntheticName(node.func, node.distinct, node.arg)] ?? "";
|
|
37953
|
+
}
|
|
37954
|
+
const left = Number(evalMaterializedAggregateOperand(node.left, row));
|
|
37955
|
+
const right = Number(evalMaterializedAggregateOperand(node.right, row));
|
|
37956
|
+
switch (node.op) {
|
|
37957
|
+
case "+":
|
|
37958
|
+
return left + right;
|
|
37959
|
+
case "-":
|
|
37960
|
+
return left - right;
|
|
37961
|
+
case "*":
|
|
37962
|
+
return left * right;
|
|
37963
|
+
case "/":
|
|
37964
|
+
return right !== 0 ? left / right : NaN;
|
|
37965
|
+
case "%":
|
|
37966
|
+
return right !== 0 ? left % right : NaN;
|
|
37967
|
+
}
|
|
37968
|
+
}
|
|
37819
37969
|
function resolveFieldRef(row, field) {
|
|
37820
37970
|
const direct = row[field];
|
|
37821
37971
|
if (direct !== void 0) return direct;
|
|
@@ -37910,7 +38060,7 @@ function semanticsForLeft(left, fieldType, resolveSemantics) {
|
|
|
37910
38060
|
if (left.type === "FIELD") {
|
|
37911
38061
|
return resolveSemantics?.(left) ?? (fieldType ? resolveFieldSemantics({ fieldType }) : syntheticSemantics("string"));
|
|
37912
38062
|
}
|
|
37913
|
-
if (left.type === "ARITH_FIELD") return syntheticSemantics("number");
|
|
38063
|
+
if (left.type === "ARITH_FIELD" || left.type === "AGG_FIELD") return syntheticSemantics("number");
|
|
37914
38064
|
if (left.type === "FUNC_FIELD") {
|
|
37915
38065
|
return syntheticSemantics(NUMERIC_STRING_FUNCTIONS.has(left.expr.func) ? "number" : "string");
|
|
37916
38066
|
}
|
|
@@ -38003,6 +38153,7 @@ function evalLogical(expr, row, resolveFieldType, appliedKlikes, resolveFieldSem
|
|
|
38003
38153
|
}
|
|
38004
38154
|
function resolveField(field, row, resolveFieldType, resolveFieldSemantics2) {
|
|
38005
38155
|
if (field.type === "FUNC_FIELD") return evalStringFunc(field.expr, row);
|
|
38156
|
+
if (field.type === "AGG_FIELD") return String(evalMaterializedAggregateOperand(field.expr, row));
|
|
38006
38157
|
if (field.type === "ARITH_FIELD") return String(evalArithExpr(field.expr, row));
|
|
38007
38158
|
if (field.type === "CASE_FIELD") return evalCaseWhen(field.expr, row, resolveFieldType, resolveFieldSemantics2);
|
|
38008
38159
|
if (field.type === "GROUPING_FIELD") return evalGroupingRef(field.ref, row);
|
|
@@ -38060,12 +38211,20 @@ function evalCaseWhenNullable(expr, row, resolveFieldType, resolveFieldSemantics
|
|
|
38060
38211
|
}
|
|
38061
38212
|
function evalCaseResultNullable(result, row, resolveFieldType, resolveFieldSemantics2) {
|
|
38062
38213
|
if (result.type === "ARRAY") return result.elements.map((entry) => entry.value).join(",");
|
|
38214
|
+
if (result.type === "AGG_REF") {
|
|
38215
|
+
return row[aggregateSyntheticName(result.func, result.distinct, result.arg)] ?? "";
|
|
38216
|
+
}
|
|
38217
|
+
if (result.type === "AGG_ARITH") return row[aggregateOperandLabel(result)] ?? "";
|
|
38063
38218
|
if (result.type === "FIELD_REF") return row[result.field] ?? "";
|
|
38064
38219
|
if (result.type === "ARITH") return evalArithExpr(result, row);
|
|
38065
38220
|
return evalScalarValueExprNullable(result, row, resolveFieldType, resolveFieldSemantics2);
|
|
38066
38221
|
}
|
|
38067
38222
|
function evalCaseResult(result, row, resolveFieldType, resolveFieldSemantics2) {
|
|
38068
38223
|
if (result.type === "ARRAY") return result.elements.map((e) => e.value).join(",");
|
|
38224
|
+
if (result.type === "AGG_REF") {
|
|
38225
|
+
return row[aggregateSyntheticName(result.func, result.distinct, result.arg)] ?? "";
|
|
38226
|
+
}
|
|
38227
|
+
if (result.type === "AGG_ARITH") return row[aggregateOperandLabel(result)] ?? "";
|
|
38069
38228
|
if (result.type === "FIELD_REF") {
|
|
38070
38229
|
return row[result.field] ?? "";
|
|
38071
38230
|
}
|
|
@@ -38331,6 +38490,10 @@ function collectAggregateArgFields2(node, out) {
|
|
|
38331
38490
|
}
|
|
38332
38491
|
function collectCaseResultFields(result, out) {
|
|
38333
38492
|
if (result.type === "ARRAY") return;
|
|
38493
|
+
if (result.type === "AGG_REF" || result.type === "AGG_ARITH") {
|
|
38494
|
+
collectAggOperandFields2(result, out);
|
|
38495
|
+
return;
|
|
38496
|
+
}
|
|
38334
38497
|
if (result.type === "FIELD_REF" || result.type === "ARITH") {
|
|
38335
38498
|
collectArithNode2(result, out);
|
|
38336
38499
|
return;
|
|
@@ -38552,6 +38715,9 @@ function evalCaseResultValue(result, row, fieldType) {
|
|
|
38552
38715
|
if (result.type === "ARRAY") {
|
|
38553
38716
|
return convertArray(result.elements.map((e) => e.value), fieldType);
|
|
38554
38717
|
}
|
|
38718
|
+
if (result.type === "AGG_REF" || result.type === "AGG_ARITH") {
|
|
38719
|
+
throw new Error("InternalError: aggregate CASE result reached DML evaluation.");
|
|
38720
|
+
}
|
|
38555
38721
|
if (result.type === "STRING") {
|
|
38556
38722
|
return convertString2(result.value, fieldType);
|
|
38557
38723
|
}
|
|
@@ -42787,7 +42953,7 @@ function applyFilter(rows, where, resolveFieldType, appliedKlikes, resolveFieldS
|
|
|
42787
42953
|
}
|
|
42788
42954
|
function hasAggregateColumns(columns) {
|
|
42789
42955
|
return columns.some(
|
|
42790
|
-
(c) => c.type === "AGGREGATE" || c.type === "ARITH_AGG_COL" || c.type === "STRFUNC_COL" && hasAggregateInStringFuncExpr2(c.expr) || c.type === "SCALAR_VALUE_COL" && scalarValueHasAggregate2(c.expr)
|
|
42956
|
+
(c) => c.type === "AGGREGATE" || c.type === "ARITH_AGG_COL" || c.type === "CASE_COL" && containsAggregate2(c.expr) || c.type === "STRFUNC_COL" && hasAggregateInStringFuncExpr2(c.expr) || c.type === "SCALAR_VALUE_COL" && scalarValueHasAggregate2(c.expr)
|
|
42791
42957
|
);
|
|
42792
42958
|
}
|
|
42793
42959
|
function applyGroupBy(rows, groupByKeys, columns, resolveAggSortKind, resolutionPlan, aliasEvaluationContext = {}) {
|
|
@@ -42892,26 +43058,72 @@ function groupingItemValue(item, row) {
|
|
|
42892
43058
|
return row[item.directKey] ?? (item.unqualifiedBridgeKey === null ? void 0 : row[item.unqualifiedBridgeKey]) ?? "";
|
|
42893
43059
|
}
|
|
42894
43060
|
function materializeAggregateColumns(outRow, groupRows, columns, resolveAggSortKind) {
|
|
42895
|
-
for (const col of columns) {
|
|
43061
|
+
for (const [columnIndex, col] of columns.entries()) {
|
|
42896
43062
|
if (col.type === "AGGREGATE") {
|
|
42897
43063
|
const syntheticKey = aggregateSyntheticName(col.func, col.distinct, col.arg);
|
|
42898
43064
|
const value = String(evalAggregate(col.func, col.distinct, col.arg, col.separator, groupRows, resolveAggSortKind));
|
|
42899
43065
|
outRow[col.alias ?? syntheticKey] = value;
|
|
42900
43066
|
if (col.alias) outRow[syntheticKey] = value;
|
|
42901
43067
|
} else if (col.type === "ARITH_AGG_COL") {
|
|
43068
|
+
materializeAggregateDependencies(outRow, groupRows, col.expr, resolveAggSortKind);
|
|
42902
43069
|
const outputKey = col.alias ?? aggArithDefaultKey(col.expr);
|
|
42903
43070
|
outRow[outputKey] = String(evalAggArithExpr(col.expr, groupRows, resolveAggSortKind));
|
|
42904
43071
|
} else if (col.type === "STRFUNC_COL" && hasAggregateInStringFuncExpr2(col.expr)) {
|
|
43072
|
+
materializeAggregateDependencies(outRow, groupRows, col.expr, resolveAggSortKind);
|
|
42905
43073
|
const outputKey = col.alias ?? stringFuncDefaultKey(col.expr);
|
|
42906
43074
|
const resolvedExpr = resolveAggInStringFuncExpr(col.expr, groupRows, resolveAggSortKind);
|
|
42907
43075
|
outRow[outputKey] = evalStringFunc(resolvedExpr, outRow);
|
|
42908
43076
|
} else if (col.type === "SCALAR_VALUE_COL" && scalarValueHasAggregate2(col.expr)) {
|
|
43077
|
+
materializeAggregateDependencies(outRow, groupRows, col.expr, resolveAggSortKind);
|
|
42909
43078
|
const outputKey = col.alias ?? scalarValueDefaultKey(col.expr);
|
|
42910
43079
|
const resolvedExpr = resolveAggInScalarValue(col.expr, groupRows, resolveAggSortKind);
|
|
42911
43080
|
outRow[outputKey] = String(evalScalarValueExpr(resolvedExpr, outRow));
|
|
43081
|
+
} else if (col.type === "CASE_COL" && containsAggregate2(col.expr)) {
|
|
43082
|
+
materializeAggregateDependencies(outRow, groupRows, col.expr, resolveAggSortKind);
|
|
43083
|
+
const resolvedExpr = resolveAggInCaseExpr(col.expr, groupRows, resolveAggSortKind);
|
|
43084
|
+
const resolveAggregateSemantics = (field) => field.aggregateRef ? aggregateResultSemantics(field.aggregateRef, resolveAggSortKind) : void 0;
|
|
43085
|
+
outRow[caseMaterializedKey(col.alias, columnIndex)] = evalCaseWhen(
|
|
43086
|
+
resolvedExpr,
|
|
43087
|
+
outRow,
|
|
43088
|
+
void 0,
|
|
43089
|
+
resolveAggregateSemantics
|
|
43090
|
+
);
|
|
42912
43091
|
}
|
|
42913
43092
|
}
|
|
42914
43093
|
}
|
|
43094
|
+
function caseMaterializedKey(alias, columnIndex) {
|
|
43095
|
+
return alias ?? `__ksql_case_column_${columnIndex}`;
|
|
43096
|
+
}
|
|
43097
|
+
function collectAggregateRefs(node, out) {
|
|
43098
|
+
if (node === null || typeof node !== "object") return;
|
|
43099
|
+
if (Array.isArray(node)) {
|
|
43100
|
+
node.forEach((value2) => collectAggregateRefs(value2, out));
|
|
43101
|
+
return;
|
|
43102
|
+
}
|
|
43103
|
+
const value = node;
|
|
43104
|
+
if (value["type"] === "AGG_REF") {
|
|
43105
|
+
out.push(value);
|
|
43106
|
+
return;
|
|
43107
|
+
}
|
|
43108
|
+
if (value["type"] === "SELECT" || value["type"] === "SCALAR_SUBQUERY") return;
|
|
43109
|
+
Object.values(value).forEach((child) => collectAggregateRefs(child, out));
|
|
43110
|
+
}
|
|
43111
|
+
function materializeAggregateDependencies(outRow, rows, node, resolveAggSortKind) {
|
|
43112
|
+
const refs = [];
|
|
43113
|
+
collectAggregateRefs(node, refs);
|
|
43114
|
+
for (const ref of refs) {
|
|
43115
|
+
const key = aggregateSyntheticName(ref.func, ref.distinct, ref.arg);
|
|
43116
|
+
if (outRow[key] !== void 0) continue;
|
|
43117
|
+
outRow[key] = String(evalAggregate(
|
|
43118
|
+
ref.func,
|
|
43119
|
+
ref.distinct,
|
|
43120
|
+
ref.arg,
|
|
43121
|
+
ref.separator,
|
|
43122
|
+
rows,
|
|
43123
|
+
resolveAggSortKind
|
|
43124
|
+
));
|
|
43125
|
+
}
|
|
43126
|
+
}
|
|
42915
43127
|
function evalGroupByKey(key, row, resolution, columns, aliasEvaluationContext) {
|
|
42916
43128
|
if (key.type === "FIELD_NAME") {
|
|
42917
43129
|
if (!resolution) return row[key.name] ?? "";
|
|
@@ -42952,7 +43164,7 @@ function evalAggregate(func, distinct, arg, separator, rows, resolveAggSortKind)
|
|
|
42952
43164
|
const raw = row[arg.field];
|
|
42953
43165
|
if (raw === void 0 || raw === "" && func !== "MIN" && func !== "MAX") continue;
|
|
42954
43166
|
strVal = raw;
|
|
42955
|
-
} else if (arg.type === "ARITH" || arg.type === "NUMBER"
|
|
43167
|
+
} else if (arg.type === "ARITH" || arg.type === "NUMBER") {
|
|
42956
43168
|
const n = evalArithExpr(arg, row);
|
|
42957
43169
|
if (isNaN(n)) continue;
|
|
42958
43170
|
strVal = String(n);
|
|
@@ -43084,6 +43296,16 @@ function resolveAggregateArgSemantics(arg, resolver) {
|
|
|
43084
43296
|
const first = results[0];
|
|
43085
43297
|
return results.every((result) => JSON.stringify(result) === JSON.stringify(first)) ? first : kinds[0];
|
|
43086
43298
|
}
|
|
43299
|
+
function aggregateResultSemantics(ref, resolver) {
|
|
43300
|
+
if (ref.func === "COUNT" || ref.func === "SUM" || ref.func === "AVG" || ref.func === "STDDEV_POP" || ref.func === "STDDEV_SAMP" || ref.func === "VAR_POP" || ref.func === "VAR_SAMP" || ref.func === "MEDIAN") {
|
|
43301
|
+
return syntheticSemantics("number");
|
|
43302
|
+
}
|
|
43303
|
+
if (ref.func === "GROUP_CONCAT" || ref.func === "MODE") {
|
|
43304
|
+
return syntheticSemantics("string");
|
|
43305
|
+
}
|
|
43306
|
+
const semantics = ref.arg.type === "WILDCARD" ? "string" : resolveAggregateArgSemantics(ref.arg, resolver) ?? "string";
|
|
43307
|
+
return typeof semantics === "string" ? syntheticSemantics(semantics) : semantics;
|
|
43308
|
+
}
|
|
43087
43309
|
function applyHaving(rows, having, resolveFieldType, resolveFieldSemantics2) {
|
|
43088
43310
|
if (having === null) return rows;
|
|
43089
43311
|
return rows.filter((row) => evalWhere(having, row, resolveFieldType, void 0, resolveFieldSemantics2));
|
|
@@ -43243,7 +43465,7 @@ function buildOrderByAliasEvaluator(columns, scalarCache, resolveFieldType, reso
|
|
|
43243
43465
|
break;
|
|
43244
43466
|
}
|
|
43245
43467
|
case "CASE_COL":
|
|
43246
|
-
evaluators.set(alias, (row) => evalCaseWhen(column.expr, row, resolveFieldType, resolveFieldSemantics2));
|
|
43468
|
+
evaluators.set(alias, (row) => containsAggregate2(column.expr) ? row[alias] ?? "" : evalCaseWhen(column.expr, row, resolveFieldType, resolveFieldSemantics2));
|
|
43247
43469
|
break;
|
|
43248
43470
|
case "SCALAR_VALUE_COL": {
|
|
43249
43471
|
const source = scalarValueDefaultKey(column.expr);
|
|
@@ -43332,7 +43554,7 @@ function evaluateSelectColumnValue(column, row, columnIndex, context = {}) {
|
|
|
43332
43554
|
case "ARITH_COL":
|
|
43333
43555
|
return String(evalArithExpr(column.expr, row));
|
|
43334
43556
|
case "CASE_COL":
|
|
43335
|
-
return evalCaseWhen(
|
|
43557
|
+
return containsAggregate2(column.expr) ? row[caseMaterializedKey(column.alias, columnIndex)] ?? "" : evalCaseWhen(
|
|
43336
43558
|
column.expr,
|
|
43337
43559
|
row,
|
|
43338
43560
|
context.resolveFieldType,
|
|
@@ -43397,13 +43619,14 @@ function project(rows, columns, scalarCache, resolveFieldType, sourceColumns2, r
|
|
|
43397
43619
|
return { rows: projected2, columns: cols };
|
|
43398
43620
|
}
|
|
43399
43621
|
const defaultFieldKeys = buildDefaultFieldOutputKeys(columns);
|
|
43622
|
+
const defaultCaseKeys = buildDefaultCaseOutputKeys(columns);
|
|
43400
43623
|
const hasWildcard = columns.some(
|
|
43401
43624
|
(col) => col.type === "WILDCARD" || col.type === "PARENT_WILDCARD"
|
|
43402
43625
|
);
|
|
43403
|
-
const outputKeys = hasWildcard ? null : computeOutputKeys(columns, defaultFieldKeys);
|
|
43626
|
+
const outputKeys = hasWildcard ? null : computeOutputKeys(columns, defaultFieldKeys, defaultCaseKeys);
|
|
43404
43627
|
const orderedKeys = outputKeys ?? [];
|
|
43405
43628
|
if (hasWildcard && rows.length === 0) {
|
|
43406
|
-
return { rows: [], columns: computeExplicitOutputKeys(columns, defaultFieldKeys) };
|
|
43629
|
+
return { rows: [], columns: computeExplicitOutputKeys(columns, defaultFieldKeys, defaultCaseKeys) };
|
|
43407
43630
|
}
|
|
43408
43631
|
const projected = rows.map((row, rowIdx) => {
|
|
43409
43632
|
const out = {};
|
|
@@ -43470,7 +43693,7 @@ function project(rows, columns, scalarCache, resolveFieldType, sourceColumns2, r
|
|
|
43470
43693
|
break;
|
|
43471
43694
|
}
|
|
43472
43695
|
case "CASE_COL": {
|
|
43473
|
-
const key = outputKeys?.[colIdx] ?? col.alias ?? "case";
|
|
43696
|
+
const key = outputKeys?.[colIdx] ?? col.alias ?? defaultCaseKeys.get(colIdx) ?? "case";
|
|
43474
43697
|
out[key] = value;
|
|
43475
43698
|
if (outputKeys === null && rowIdx === 0) orderedKeys.push(key);
|
|
43476
43699
|
break;
|
|
@@ -43511,15 +43734,15 @@ function project(rows, columns, scalarCache, resolveFieldType, sourceColumns2, r
|
|
|
43511
43734
|
});
|
|
43512
43735
|
return { rows: projected, columns: orderedKeys };
|
|
43513
43736
|
}
|
|
43514
|
-
function computeOutputKeys(columns, defaultFieldKeys) {
|
|
43515
|
-
return columns.map((col, colIdx) => computeOutputKey(col, colIdx, defaultFieldKeys));
|
|
43737
|
+
function computeOutputKeys(columns, defaultFieldKeys, defaultCaseKeys) {
|
|
43738
|
+
return columns.map((col, colIdx) => computeOutputKey(col, colIdx, defaultFieldKeys, defaultCaseKeys));
|
|
43516
43739
|
}
|
|
43517
|
-
function computeExplicitOutputKeys(columns, defaultFieldKeys) {
|
|
43740
|
+
function computeExplicitOutputKeys(columns, defaultFieldKeys, defaultCaseKeys) {
|
|
43518
43741
|
const keys = [];
|
|
43519
43742
|
const seen = /* @__PURE__ */ new Set();
|
|
43520
43743
|
for (const [colIdx, col] of columns.entries()) {
|
|
43521
43744
|
if (col.type === "WILDCARD" || col.type === "PARENT_WILDCARD") continue;
|
|
43522
|
-
const key = computeOutputKey(col, colIdx, defaultFieldKeys);
|
|
43745
|
+
const key = computeOutputKey(col, colIdx, defaultFieldKeys, defaultCaseKeys);
|
|
43523
43746
|
if (!seen.has(key)) {
|
|
43524
43747
|
seen.add(key);
|
|
43525
43748
|
keys.push(key);
|
|
@@ -43527,7 +43750,7 @@ function computeExplicitOutputKeys(columns, defaultFieldKeys) {
|
|
|
43527
43750
|
}
|
|
43528
43751
|
return keys;
|
|
43529
43752
|
}
|
|
43530
|
-
function computeOutputKey(col, colIdx, defaultFieldKeys) {
|
|
43753
|
+
function computeOutputKey(col, colIdx, defaultFieldKeys, defaultCaseKeys) {
|
|
43531
43754
|
switch (col.type) {
|
|
43532
43755
|
case "VARIABLE_COL":
|
|
43533
43756
|
throw new Error(`internal error: unresolved SELECT variable @${col.name}`);
|
|
@@ -43542,7 +43765,7 @@ function computeOutputKey(col, colIdx, defaultFieldKeys) {
|
|
|
43542
43765
|
case "ARITH_COL":
|
|
43543
43766
|
return col.alias ?? arithColDefaultKey(col.expr);
|
|
43544
43767
|
case "CASE_COL":
|
|
43545
|
-
return col.alias ?? "case";
|
|
43768
|
+
return col.alias ?? defaultCaseKeys.get(colIdx) ?? "case";
|
|
43546
43769
|
case "STRFUNC_COL":
|
|
43547
43770
|
return col.alias ?? stringFuncDefaultKey(col.expr);
|
|
43548
43771
|
case "SCALAR_VALUE_COL":
|
|
@@ -43558,6 +43781,24 @@ function computeOutputKey(col, colIdx, defaultFieldKeys) {
|
|
|
43558
43781
|
throw new Error("internal: computeOutputKey received a wildcard column");
|
|
43559
43782
|
}
|
|
43560
43783
|
}
|
|
43784
|
+
function buildDefaultCaseOutputKeys(columns) {
|
|
43785
|
+
const used = new Set(columns.flatMap(
|
|
43786
|
+
(column) => "alias" in column && column.alias !== null ? [column.alias] : []
|
|
43787
|
+
));
|
|
43788
|
+
const keys = /* @__PURE__ */ new Map();
|
|
43789
|
+
let suffix = 1;
|
|
43790
|
+
for (const [columnIndex, column] of columns.entries()) {
|
|
43791
|
+
if (column.type !== "CASE_COL" || column.alias !== null) continue;
|
|
43792
|
+
let key;
|
|
43793
|
+
do {
|
|
43794
|
+
key = suffix === 1 ? "case" : `case_${suffix}`;
|
|
43795
|
+
suffix++;
|
|
43796
|
+
} while (used.has(key));
|
|
43797
|
+
used.add(key);
|
|
43798
|
+
keys.set(columnIndex, key);
|
|
43799
|
+
}
|
|
43800
|
+
return keys;
|
|
43801
|
+
}
|
|
43561
43802
|
function buildDefaultFieldOutputKeys(columns) {
|
|
43562
43803
|
const qualifierCollisionCount = /* @__PURE__ */ new Map();
|
|
43563
43804
|
for (const col of columns) {
|
|
@@ -43647,6 +43888,7 @@ function scalarValueHasAggregate2(expr) {
|
|
|
43647
43888
|
return false;
|
|
43648
43889
|
}
|
|
43649
43890
|
function caseResultHasAggregate2(result) {
|
|
43891
|
+
if (result.type === "AGG_REF" || result.type === "AGG_ARITH") return true;
|
|
43650
43892
|
if (result.type === "ARRAY" || result.type === "FIELD_REF" || result.type === "ARITH") return false;
|
|
43651
43893
|
return scalarValueHasAggregate2(result);
|
|
43652
43894
|
}
|
|
@@ -43669,6 +43911,7 @@ function resolveAggInStringFuncArg(arg, rows, resolveAggSortKind) {
|
|
|
43669
43911
|
}
|
|
43670
43912
|
function resolveAggInScalarValue(expr, rows, resolveAggSortKind) {
|
|
43671
43913
|
if (expr.type === "STRING_FUNC") return resolveAggInStringFuncExpr(expr, rows, resolveAggSortKind);
|
|
43914
|
+
if (expr.type === "CASE_WHEN") return resolveAggInCaseExpr(expr, rows, resolveAggSortKind);
|
|
43672
43915
|
if (expr.type === "SCALAR_ARITH" || expr.type === "CONCAT_OP") {
|
|
43673
43916
|
return {
|
|
43674
43917
|
...expr,
|
|
@@ -43678,6 +43921,35 @@ function resolveAggInScalarValue(expr, rows, resolveAggSortKind) {
|
|
|
43678
43921
|
}
|
|
43679
43922
|
return expr;
|
|
43680
43923
|
}
|
|
43924
|
+
function resolveAggInCaseResult(result, rows, resolveAggSortKind) {
|
|
43925
|
+
if (result.type === "AGG_REF") {
|
|
43926
|
+
const value = evalAggregate(
|
|
43927
|
+
result.func,
|
|
43928
|
+
result.distinct,
|
|
43929
|
+
result.arg,
|
|
43930
|
+
result.separator,
|
|
43931
|
+
rows,
|
|
43932
|
+
resolveAggSortKind
|
|
43933
|
+
);
|
|
43934
|
+
return typeof value === "number" ? { type: "NUMBER", value, raw: String(value) } : { type: "STRING", value };
|
|
43935
|
+
}
|
|
43936
|
+
if (result.type === "AGG_ARITH") {
|
|
43937
|
+
const value = evalAggArithExpr(result, rows, resolveAggSortKind);
|
|
43938
|
+
return { type: "NUMBER", value, raw: String(value) };
|
|
43939
|
+
}
|
|
43940
|
+
if (result.type === "ARRAY" || result.type === "FIELD_REF" || result.type === "ARITH") return result;
|
|
43941
|
+
return resolveAggInScalarValue(result, rows, resolveAggSortKind);
|
|
43942
|
+
}
|
|
43943
|
+
function resolveAggInCaseExpr(expr, rows, resolveAggSortKind) {
|
|
43944
|
+
return {
|
|
43945
|
+
...expr,
|
|
43946
|
+
branches: expr.branches.map((branch) => ({
|
|
43947
|
+
...branch,
|
|
43948
|
+
result: resolveAggInCaseResult(branch.result, rows, resolveAggSortKind)
|
|
43949
|
+
})),
|
|
43950
|
+
elseResult: expr.elseResult === null ? null : resolveAggInCaseResult(expr.elseResult, rows, resolveAggSortKind)
|
|
43951
|
+
};
|
|
43952
|
+
}
|
|
43681
43953
|
function resolveAggInStringFuncExpr(expr, rows, resolveAggSortKind) {
|
|
43682
43954
|
return {
|
|
43683
43955
|
type: "STRING_FUNC",
|
|
@@ -43800,7 +44072,8 @@ function runFullScan(input) {
|
|
|
43800
44072
|
}
|
|
43801
44073
|
);
|
|
43802
44074
|
}
|
|
43803
|
-
|
|
44075
|
+
const resolveHavingSemantics = (field) => field.aggregateRef ? aggregateResultSemantics(field.aggregateRef, aggregateSortKindResolver) : havingFieldSemanticsResolver?.(field);
|
|
44076
|
+
rows = applyHaving(rows, stmt.having, havingFieldTypeResolver, resolveHavingSemantics);
|
|
43804
44077
|
rows = applyWindow(rows, stmt.columns, optionOrders, sortKinds, effectiveOrderSemantics);
|
|
43805
44078
|
if (stmt.distinct) {
|
|
43806
44079
|
rows = applyDistinct(
|
|
@@ -47367,7 +47640,7 @@ function scalarValueHasFieldRef(expr) {
|
|
|
47367
47640
|
}
|
|
47368
47641
|
if (expr.type === "CASE_WHEN") {
|
|
47369
47642
|
const results = [...expr.branches.map((branch) => branch.result), ...expr.elseResult ? [expr.elseResult] : []];
|
|
47370
|
-
return results.some((result) => result.type !== "ARRAY" && (result.type === "FIELD_REF" || result.type === "ARITH" ? arithHasFieldRef(result) : scalarValueHasFieldRef(result)));
|
|
47643
|
+
return results.some((result) => result.type !== "ARRAY" && (result.type === "FIELD_REF" || result.type === "ARITH" ? arithHasFieldRef(result) : result.type === "AGG_REF" || result.type === "AGG_ARITH" ? true : scalarValueHasFieldRef(result)));
|
|
47371
47644
|
}
|
|
47372
47645
|
return false;
|
|
47373
47646
|
}
|
|
@@ -47919,7 +48192,8 @@ function collectAggregateArgFieldRefs(arg, out) {
|
|
|
47919
48192
|
}
|
|
47920
48193
|
if (arg.type === "CASE_WHEN") {
|
|
47921
48194
|
for (const result of [...arg.branches.map((branch) => branch.result), ...arg.elseResult ? [arg.elseResult] : []]) {
|
|
47922
|
-
if (result.type
|
|
48195
|
+
if (result.type === "AGG_REF" || result.type === "AGG_ARITH") collectAggregateOperandRefs(result, out);
|
|
48196
|
+
else if (result.type !== "ARRAY") collectAggregateArgFieldRefs(result, out);
|
|
47923
48197
|
}
|
|
47924
48198
|
}
|
|
47925
48199
|
}
|
|
@@ -47956,10 +48230,29 @@ function collectScalarAggregateRefs(expr, out) {
|
|
|
47956
48230
|
const results = [...expr.branches.map((branch) => branch.result), ...expr.elseResult ? [expr.elseResult] : []];
|
|
47957
48231
|
for (const result of results) {
|
|
47958
48232
|
if (result.type === "STRING_FUNC") collectStringFuncAggregateRefs(result, out);
|
|
48233
|
+
else if (result.type === "AGG_REF" || result.type === "AGG_ARITH") collectAggregateOperandRefs(result, out);
|
|
47959
48234
|
else if (result.type !== "ARRAY" && result.type !== "FIELD_REF" && result.type !== "ARITH") collectScalarAggregateRefs(result, out);
|
|
47960
48235
|
}
|
|
47961
48236
|
}
|
|
47962
48237
|
}
|
|
48238
|
+
function collectCaseAggregateRefs(expr, out) {
|
|
48239
|
+
const visit = (node) => {
|
|
48240
|
+
if (node === null || typeof node !== "object") return;
|
|
48241
|
+
if (Array.isArray(node)) {
|
|
48242
|
+
node.forEach(visit);
|
|
48243
|
+
return;
|
|
48244
|
+
}
|
|
48245
|
+
const value = node;
|
|
48246
|
+
if (value["type"] === "AGG_REF") {
|
|
48247
|
+
const aggregate = value;
|
|
48248
|
+
collectAggregateRef(aggregate.func, aggregate.arg, out);
|
|
48249
|
+
return;
|
|
48250
|
+
}
|
|
48251
|
+
if (value["type"] === "SELECT" || value["type"] === "SCALAR_SUBQUERY") return;
|
|
48252
|
+
Object.values(value).forEach(visit);
|
|
48253
|
+
};
|
|
48254
|
+
visit(expr);
|
|
48255
|
+
}
|
|
47963
48256
|
function collectSelectAggregateSortRefs(columns) {
|
|
47964
48257
|
const refs = [];
|
|
47965
48258
|
for (const column of columns) {
|
|
@@ -47971,6 +48264,8 @@ function collectSelectAggregateSortRefs(columns) {
|
|
|
47971
48264
|
collectStringFuncAggregateRefs(column.expr, refs);
|
|
47972
48265
|
} else if (column.type === "SCALAR_VALUE_COL") {
|
|
47973
48266
|
collectScalarAggregateRefs(column.expr, refs);
|
|
48267
|
+
} else if (column.type === "CASE_COL") {
|
|
48268
|
+
collectCaseAggregateRefs(column.expr, refs);
|
|
47974
48269
|
}
|
|
47975
48270
|
}
|
|
47976
48271
|
return refs;
|
|
@@ -48148,6 +48443,13 @@ function stringFunctionColumnMeta(expr) {
|
|
|
48148
48443
|
function caseResultColumnMeta(result, resolveField2) {
|
|
48149
48444
|
if (result.type === "STRING") return syntheticColumnMeta("string");
|
|
48150
48445
|
if (result.type === "ARRAY") return unsupportedColumnMeta();
|
|
48446
|
+
if (result.type === "AGG_REF") {
|
|
48447
|
+
if (result.func === "MIN" || result.func === "MAX" || result.func === "MODE") {
|
|
48448
|
+
return result.arg.type === "WILDCARD" ? unknownStringColumnMeta() : inferAggregateArgMeta(result.arg, resolveField2);
|
|
48449
|
+
}
|
|
48450
|
+
return result.func === "GROUP_CONCAT" ? syntheticColumnMeta("string") : syntheticColumnMeta("number");
|
|
48451
|
+
}
|
|
48452
|
+
if (result.type === "AGG_ARITH") return syntheticColumnMeta("number");
|
|
48151
48453
|
if (result.type === "NUMBER" || result.type === "ARITH" || result.type === "SCALAR_ARITH") return syntheticColumnMeta("number");
|
|
48152
48454
|
if (result.type === "STRING_FUNC") return stringFunctionColumnMeta(result);
|
|
48153
48455
|
if (result.type === "FIELD_REF") return resolveField2(aggregateFieldRef(result.field)) ?? unknownStringColumnMeta();
|
|
@@ -57424,7 +57726,7 @@ Nested JSON/CSV subtable mutation is fail-closed on MCP: use VALIDATE ONLY/EXPLA
|
|
|
57424
57726
|
JSON child IDs are rejected and replacement renumbers all rows.
|
|
57425
57727
|
`);
|
|
57426
57728
|
}
|
|
57427
|
-
var SERVER_VERSION = true ? "3.
|
|
57729
|
+
var SERVER_VERSION = true ? "3.44.0" : "0.0.0-dev";
|
|
57428
57730
|
var FUNCTION_CATALOG_PARAGRAPH = `Complete function catalog \u2014 Scalar: ${KSQL_FUNCTION_CATALOG.scalar.join(" ")}. Aggregate: ${KSQL_FUNCTION_CATALOG.aggregate.join(" ")}. Variance and standard-deviation aggregates use explicit POP/SAMP names; unqualified STDDEV and VARIANCE are unsupported. Window: ${KSQL_FUNCTION_CATALOG.window.join(" ")} (OVER and AS alias required). Contextual: ${KSQL_FUNCTION_CATALOG.contextual.join(" ")} (kintone predicates; WHERE server-only/fail-closed; INNER JOIN direct-APP exact pushdown supported; local LOGINUSER is empty on all surfaces). Aliases: ${KSQL_FUNCTION_CATALOG.aliases.join(" ")}. Syntax: ${KSQL_FUNCTION_CATALOG.syntax.join(" ")}. This list is complete; functions from other dialects such as IFNULL do not exist. Use ksql_docs for arguments and constraints.`;
|
|
57429
57731
|
var KSQL_MCP_INSTRUCTIONS = `kSQL MCP server version ${SERVER_VERSION}.
|
|
57430
57732
|
|