@rex0220/kintone-sql-tools 3.37.1 → 3.39.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist-cli/ksql.js +201 -60
- package/dist-engine/index.cjs +9 -9
- package/dist-engine/index.mjs +10 -10
- package/dist-engine/ksql-engine.umd.js +10 -10
- package/dist-engine/meta/bundle-baseline.json +7 -7
- package/dist-engine/meta/cjs.json +12 -12
- package/dist-engine/meta/esm.json +12 -12
- package/dist-engine/meta/umd.json +12 -12
- package/dist-engine/publicTypes.d.ts +1 -0
- package/dist-mcp/ksql-mcp.js +203 -62
- package/dist-mcpb/ksql-mcp.mcpb +0 -0
- package/package.json +1 -1
package/dist-cli/ksql.js
CHANGED
|
@@ -1175,13 +1175,38 @@ var Parser = class {
|
|
|
1175
1175
|
parseDeclareVariable() {
|
|
1176
1176
|
this.advance();
|
|
1177
1177
|
const variable = this.expect("VARIABLE" /* VARIABLE */, "DECLARE \u306E\u5F8C\u306B\u306F\u5909\u6570\u540D\uFF08\u4F8B: @name\uFF09\u304C\u5FC5\u8981\u3067\u3059");
|
|
1178
|
+
const relativeDate = this.peek().kind === "IDENT" /* IDENT */ && this.peek().value.toUpperCase() === "RELATIVE_DATE";
|
|
1179
|
+
if (relativeDate) this.advance();
|
|
1178
1180
|
this.expect("=" /* EQ */);
|
|
1181
|
+
if (relativeDate) {
|
|
1182
|
+
return {
|
|
1183
|
+
type: "DECLARE_VARIABLE",
|
|
1184
|
+
name: variable.value.slice(1).toLowerCase(),
|
|
1185
|
+
annotation: "RELATIVE_DATE",
|
|
1186
|
+
default: this.parseRelativeDateVariableToken()
|
|
1187
|
+
};
|
|
1188
|
+
}
|
|
1179
1189
|
const expr = this.parseScalarExpr("DECLARE", false);
|
|
1180
1190
|
if (expr.type === "SCALAR_SUBQUERY") {
|
|
1181
1191
|
throw new ParseError("DECLARE \u306E\u65E2\u5B9A\u5024\u306B\u30B9\u30AB\u30E9\u30FC\u30B5\u30D6\u30AF\u30A8\u30EA\u306F\u4F7F\u7528\u3067\u304D\u307E\u305B\u3093", this.peek());
|
|
1182
1192
|
}
|
|
1183
1193
|
return { type: "DECLARE_VARIABLE", name: variable.value.slice(1).toLowerCase(), default: expr };
|
|
1184
1194
|
}
|
|
1195
|
+
/** RELATIVE_DATE 宣言専用。WHERE と同じ関数パーサーを使い、日付系14個だけを許可する。 */
|
|
1196
|
+
parseRelativeDateVariableToken() {
|
|
1197
|
+
const tok = this.peek();
|
|
1198
|
+
const contextualFunction = PARSER_CONTEXTUAL_FUNCTION_TOKEN_MAP[tok.kind];
|
|
1199
|
+
if (contextualFunction === "TODAY" || contextualFunction === "NOW") {
|
|
1200
|
+
return this.parseSqlValue();
|
|
1201
|
+
}
|
|
1202
|
+
if (tok.kind === "IDENT" /* IDENT */ && this.peekAt(1).kind === "(" /* LPAREN */ && isRelativeDateFunctionName(tok.value.toUpperCase())) {
|
|
1203
|
+
return this.parseRelativeDateFunction();
|
|
1204
|
+
}
|
|
1205
|
+
throw new ParseError(
|
|
1206
|
+
"RELATIVE_DATE \u306E\u65E2\u5B9A\u5024\u306B\u306F\u30B5\u30DD\u30FC\u30C8\u5BFE\u8C61\u306E\u76F8\u5BFE\u65E5\u4ED8\u95A2\u6570\u30C8\u30FC\u30AF\u30F3\u304C\u5FC5\u8981\u3067\u3059",
|
|
1207
|
+
tok
|
|
1208
|
+
);
|
|
1209
|
+
}
|
|
1185
1210
|
/** SET / DECLARE RHS 専用。既存式パーサーで構文を読み、フィールド参照を明示的に拒否する。 */
|
|
1186
1211
|
parseScalarExpr(context, allowScalarSubquery) {
|
|
1187
1212
|
const tok = this.peek();
|
|
@@ -1925,24 +1950,25 @@ var Parser = class {
|
|
|
1925
1950
|
}
|
|
1926
1951
|
if (this.isGroupingFunctionStart()) {
|
|
1927
1952
|
const ref = this.parseGroupingRef();
|
|
1928
|
-
const
|
|
1929
|
-
return { type: "GROUPING_COL", ref, alias:
|
|
1953
|
+
const parsedAlias2 = this.consume("AS" /* AS */) ? this.parseAliasName() : null;
|
|
1954
|
+
return this.withAliasDisplay({ type: "GROUPING_COL", ref, alias: parsedAlias2?.alias ?? null }, parsedAlias2);
|
|
1930
1955
|
}
|
|
1931
1956
|
if (this.tryAggregateFunc() === null && this.hasTopLevelTokenBeforeValueEnd("||" /* CONCAT_OP */)) {
|
|
1932
1957
|
const expr = this.parseScalarValueExpr({ allowAggregateArgs: true });
|
|
1933
|
-
const
|
|
1934
|
-
return { type: "SCALAR_VALUE_COL", expr, alias:
|
|
1958
|
+
const parsedAlias2 = this.consume("AS" /* AS */) ? this.parseAliasName() : null;
|
|
1959
|
+
return this.withAliasDisplay({ type: "SCALAR_VALUE_COL", expr, alias: parsedAlias2?.alias ?? null }, parsedAlias2);
|
|
1935
1960
|
}
|
|
1936
1961
|
if (this.peek().kind === "VARIABLE" /* VARIABLE */) {
|
|
1937
1962
|
const variable = this.advance();
|
|
1938
1963
|
if (!this.consume("AS" /* AS */)) {
|
|
1939
1964
|
throw new ParseError("SELECT \u5217\u306E\u30D0\u30C3\u30C1\u5909\u6570\u306B\u306F AS alias \u304C\u5FC5\u8981\u3067\u3059", this.peek());
|
|
1940
1965
|
}
|
|
1941
|
-
|
|
1966
|
+
const parsedAlias2 = this.parseAliasName();
|
|
1967
|
+
return this.withAliasDisplay({
|
|
1942
1968
|
type: "VARIABLE_COL",
|
|
1943
1969
|
name: variable.value.slice(1).toLowerCase(),
|
|
1944
|
-
alias:
|
|
1945
|
-
};
|
|
1970
|
+
alias: parsedAlias2.alias
|
|
1971
|
+
}, parsedAlias2);
|
|
1946
1972
|
}
|
|
1947
1973
|
const windowFunc = this.tryWindowFunc();
|
|
1948
1974
|
if (windowFunc !== null) {
|
|
@@ -1950,58 +1976,58 @@ var Parser = class {
|
|
|
1950
1976
|
}
|
|
1951
1977
|
if (this.peek().kind === "CASE" /* CASE */) {
|
|
1952
1978
|
const expr = this.parseCaseWhenExpr(true);
|
|
1953
|
-
const
|
|
1954
|
-
return { type: "CASE_COL", expr, alias:
|
|
1979
|
+
const parsedAlias2 = this.consume("AS" /* AS */) ? this.parseAliasName() : null;
|
|
1980
|
+
return this.withAliasDisplay({ type: "CASE_COL", expr, alias: parsedAlias2?.alias ?? null }, parsedAlias2);
|
|
1955
1981
|
}
|
|
1956
1982
|
if (this.peek().kind === "IF" /* IF */) {
|
|
1957
1983
|
const expr = this.parseIfExpr(true);
|
|
1958
|
-
const
|
|
1959
|
-
return { type: "CASE_COL", expr, alias:
|
|
1984
|
+
const parsedAlias2 = this.consume("AS" /* AS */) ? this.parseAliasName() : null;
|
|
1985
|
+
return this.withAliasDisplay({ type: "CASE_COL", expr, alias: parsedAlias2?.alias ?? null }, parsedAlias2);
|
|
1960
1986
|
}
|
|
1961
1987
|
if (this.tryStringFuncName() !== null) {
|
|
1962
1988
|
const funcExpr = this.parseStringFuncExpr();
|
|
1963
1989
|
if (this.isArithOp(this.peek().kind)) {
|
|
1964
1990
|
const node = this.parseSelectArith(() => this.continueArith(funcExpr));
|
|
1965
|
-
const
|
|
1966
|
-
return { type: "ARITH_COL", expr: node, alias:
|
|
1991
|
+
const parsedAlias3 = this.consume("AS" /* AS */) ? this.parseAliasName() : null;
|
|
1992
|
+
return this.withAliasDisplay({ type: "ARITH_COL", expr: node, alias: parsedAlias3?.alias ?? null }, parsedAlias3);
|
|
1967
1993
|
}
|
|
1968
|
-
const
|
|
1969
|
-
return { type: "STRFUNC_COL", expr: funcExpr, alias:
|
|
1994
|
+
const parsedAlias2 = this.consume("AS" /* AS */) ? this.parseAliasName() : null;
|
|
1995
|
+
return this.withAliasDisplay({ type: "STRFUNC_COL", expr: funcExpr, alias: parsedAlias2?.alias ?? null }, parsedAlias2);
|
|
1970
1996
|
}
|
|
1971
1997
|
const aggFunc = this.tryAggregateFunc();
|
|
1972
1998
|
if (aggFunc !== null) {
|
|
1973
1999
|
const ref = this.parseAggregateRef(aggFunc);
|
|
1974
2000
|
if (this.isArithOp(this.peek().kind)) {
|
|
1975
2001
|
const expr = this.continueAggArith(ref);
|
|
1976
|
-
const
|
|
1977
|
-
return { type: "ARITH_AGG_COL", expr, alias:
|
|
2002
|
+
const parsedAlias3 = this.consume("AS" /* AS */) ? this.parseAliasName() : null;
|
|
2003
|
+
return this.withAliasDisplay({ type: "ARITH_AGG_COL", expr, alias: parsedAlias3?.alias ?? null }, parsedAlias3);
|
|
1978
2004
|
}
|
|
1979
|
-
const
|
|
1980
|
-
return {
|
|
2005
|
+
const parsedAlias2 = this.consume("AS" /* AS */) ? this.parseAliasName() : null;
|
|
2006
|
+
return this.withAliasDisplay({
|
|
1981
2007
|
type: "AGGREGATE",
|
|
1982
2008
|
func: ref.func,
|
|
1983
2009
|
distinct: ref.distinct,
|
|
1984
2010
|
arg: ref.arg,
|
|
1985
2011
|
...ref.separator !== void 0 ? { separator: ref.separator } : {},
|
|
1986
|
-
alias:
|
|
1987
|
-
};
|
|
2012
|
+
alias: parsedAlias2?.alias ?? null
|
|
2013
|
+
}, parsedAlias2);
|
|
1988
2014
|
}
|
|
1989
2015
|
if (this.peek().kind === "(" /* LPAREN */ && this.peekAt(1).kind === "SELECT" /* SELECT */) {
|
|
1990
2016
|
this.advance();
|
|
1991
2017
|
const query = this.parseSelect();
|
|
1992
2018
|
this.expect(")" /* RPAREN */);
|
|
1993
|
-
const
|
|
1994
|
-
return { type: "SCALAR_SUBQUERY_COL", query, alias:
|
|
2019
|
+
const parsedAlias2 = this.consume("AS" /* AS */) ? this.parseAliasName() : null;
|
|
2020
|
+
return this.withAliasDisplay({ type: "SCALAR_SUBQUERY_COL", query, alias: parsedAlias2?.alias ?? null }, parsedAlias2);
|
|
1995
2021
|
}
|
|
1996
2022
|
if (this.peek().kind === "STRING" /* STRING */) {
|
|
1997
2023
|
const value = this.expect("STRING" /* STRING */).value;
|
|
1998
|
-
const
|
|
1999
|
-
return { type: "LITERAL_COL", value, alias:
|
|
2024
|
+
const parsedAlias2 = this.consume("AS" /* AS */) ? this.parseAliasName() : null;
|
|
2025
|
+
return this.withAliasDisplay({ type: "LITERAL_COL", value, alias: parsedAlias2?.alias ?? null }, parsedAlias2);
|
|
2000
2026
|
}
|
|
2001
2027
|
if (this.peek().kind === "(" /* LPAREN */ || this.peek().kind === "NUMBER" /* NUMBER */) {
|
|
2002
2028
|
const node = this.parseSelectArith(() => this.parseArithAddSub());
|
|
2003
|
-
const
|
|
2004
|
-
return { type: "ARITH_COL", expr: node, alias:
|
|
2029
|
+
const parsedAlias2 = this.consume("AS" /* AS */) ? this.parseAliasName() : null;
|
|
2030
|
+
return this.withAliasDisplay({ type: "ARITH_COL", expr: node, alias: parsedAlias2?.alias ?? null }, parsedAlias2);
|
|
2005
2031
|
}
|
|
2006
2032
|
const field = this.parseColumnFieldRef();
|
|
2007
2033
|
if (field === "_p.*") {
|
|
@@ -2013,11 +2039,11 @@ var Parser = class {
|
|
|
2013
2039
|
if (this.isArithOp(this.peek().kind)) {
|
|
2014
2040
|
const left = { type: "FIELD_REF", field };
|
|
2015
2041
|
const node = this.parseSelectArith(() => this.continueArith(left));
|
|
2016
|
-
const
|
|
2017
|
-
return { type: "ARITH_COL", expr: node, alias:
|
|
2042
|
+
const parsedAlias2 = this.consume("AS" /* AS */) ? this.parseAliasName() : null;
|
|
2043
|
+
return this.withAliasDisplay({ type: "ARITH_COL", expr: node, alias: parsedAlias2?.alias ?? null }, parsedAlias2);
|
|
2018
2044
|
}
|
|
2019
|
-
const
|
|
2020
|
-
return { type: "FIELD", field, alias };
|
|
2045
|
+
const parsedAlias = this.consume("AS" /* AS */) ? this.parseAliasName() : null;
|
|
2046
|
+
return this.withAliasDisplay({ type: "FIELD", field, alias: parsedAlias?.alias ?? null }, parsedAlias);
|
|
2021
2047
|
}
|
|
2022
2048
|
tryWindowFunc() {
|
|
2023
2049
|
return PARSER_WINDOW_FUNCTION_TOKEN_MAP[this.peek().kind] ?? null;
|
|
@@ -2045,8 +2071,8 @@ var Parser = class {
|
|
|
2045
2071
|
if (!this.consume("AS" /* AS */)) {
|
|
2046
2072
|
throw new ParseError("\u30A6\u30A3\u30F3\u30C9\u30A6\u95A2\u6570\u306B\u306F AS alias \u304C\u5FC5\u8981\u3067\u3059", this.peek());
|
|
2047
2073
|
}
|
|
2048
|
-
const
|
|
2049
|
-
return { type: "WINDOW_COL", func, partitionBy, orderBy, alias };
|
|
2074
|
+
const parsedAlias = this.parseAliasName();
|
|
2075
|
+
return this.withAliasDisplay({ type: "WINDOW_COL", func, partitionBy, orderBy, alias: parsedAlias.alias }, parsedAlias);
|
|
2050
2076
|
}
|
|
2051
2077
|
selectColumnHasAggregate(column) {
|
|
2052
2078
|
if (column.type === "AGGREGATE" || column.type === "ARITH_AGG_COL") return true;
|
|
@@ -4195,10 +4221,24 @@ var Parser = class {
|
|
|
4195
4221
|
}
|
|
4196
4222
|
if (tok.kind === "IDENT" /* IDENT */ || tok.kind === "BIDENT" /* BIDENT */ || KEYWORDS.has(tok.value.toUpperCase())) {
|
|
4197
4223
|
this.advance();
|
|
4198
|
-
return
|
|
4224
|
+
return {
|
|
4225
|
+
alias: tok.value.toLowerCase(),
|
|
4226
|
+
// alias は小文字で統一
|
|
4227
|
+
display: tok.value
|
|
4228
|
+
};
|
|
4199
4229
|
}
|
|
4200
4230
|
throw new ParseError("\u30A8\u30A4\u30EA\u30A2\u30B9\u540D\u304C\u5FC5\u8981\u3067\u3059", tok);
|
|
4201
4231
|
}
|
|
4232
|
+
/** 互換 snapshot を変えず、SELECT 列 AST に表示表記を保持する。 */
|
|
4233
|
+
withAliasDisplay(column, parsedAlias) {
|
|
4234
|
+
if (parsedAlias !== null) {
|
|
4235
|
+
Object.defineProperty(column, "aliasDisplay", {
|
|
4236
|
+
value: parsedAlias.display,
|
|
4237
|
+
enumerable: false
|
|
4238
|
+
});
|
|
4239
|
+
}
|
|
4240
|
+
return column;
|
|
4241
|
+
}
|
|
4202
4242
|
/** フィールド名または修飾フィールド名(alias.field)を解析する */
|
|
4203
4243
|
parseFieldPath() {
|
|
4204
4244
|
const first = this.parseIdentifier();
|
|
@@ -6792,9 +6832,10 @@ function collectRefs(node, tempRefs, appIds) {
|
|
|
6792
6832
|
for (const v of Object.values(obj)) collectRefs(v, tempRefs, appIds);
|
|
6793
6833
|
}
|
|
6794
6834
|
}
|
|
6795
|
-
|
|
6835
|
+
var RELATIVE_DATE_COMPARISON_OPS = /* @__PURE__ */ new Set(["=", "!=", "<>", ">", "<", ">=", "<="]);
|
|
6836
|
+
function collectVariableRefs(node, refs, inWhere = false) {
|
|
6796
6837
|
if (Array.isArray(node)) {
|
|
6797
|
-
for (const v of node) collectVariableRefs(v, refs);
|
|
6838
|
+
for (const v of node) collectVariableRefs(v, refs, inWhere);
|
|
6798
6839
|
return;
|
|
6799
6840
|
}
|
|
6800
6841
|
if (node !== null && typeof node === "object") {
|
|
@@ -6803,13 +6844,27 @@ function collectVariableRefs(node, refs) {
|
|
|
6803
6844
|
if ((type === "VARIABLE" || type === "VARIABLE_COL" || type === "VARIABLE_IN_LIST") && typeof obj["name"] === "string") {
|
|
6804
6845
|
refs.push({
|
|
6805
6846
|
name: obj["name"],
|
|
6806
|
-
kind: type === "VARIABLE" ? "scalar" : type === "VARIABLE_COL" ? "select-column" : "array-in-list"
|
|
6847
|
+
kind: type === "VARIABLE" ? "scalar" : type === "VARIABLE_COL" ? "select-column" : "array-in-list",
|
|
6848
|
+
relativeDateAllowed: inWhere
|
|
6807
6849
|
});
|
|
6808
6850
|
return;
|
|
6809
6851
|
}
|
|
6810
|
-
|
|
6852
|
+
const preservesWhereContext = type === "BINARY" || type === "LOGICAL" || type === "NOT" || type === "GROUP" || type === "NULL_CHECK" || type === "BOOLEAN";
|
|
6853
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
6854
|
+
const directVariable = value !== null && typeof value === "object" && value["type"] === "VARIABLE";
|
|
6855
|
+
const directComparisonRight = inWhere && type === "BINARY" && key === "right" && directVariable && RELATIVE_DATE_COMPARISON_OPS.has(String(obj["op"]));
|
|
6856
|
+
collectVariableRefs(
|
|
6857
|
+
value,
|
|
6858
|
+
refs,
|
|
6859
|
+
key === "where" ? true : type === "BINARY" && key === "right" && directVariable ? directComparisonRight : preservesWhereContext ? inWhere : false
|
|
6860
|
+
);
|
|
6861
|
+
}
|
|
6811
6862
|
}
|
|
6812
6863
|
}
|
|
6864
|
+
function isRelativeDateDmlUse(stmt) {
|
|
6865
|
+
const target = stmt.type === "EXPLAIN" ? stmt.query : stmt;
|
|
6866
|
+
return isDmlType(target.type) || target.type === "VALIDATE";
|
|
6867
|
+
}
|
|
6813
6868
|
function validateGroupingStaticQueries(node) {
|
|
6814
6869
|
if (Array.isArray(node)) {
|
|
6815
6870
|
for (const value of node) validateGroupingStaticQueries(value);
|
|
@@ -6904,6 +6959,18 @@ function analyzeBatch(statements) {
|
|
|
6904
6959
|
index
|
|
6905
6960
|
);
|
|
6906
6961
|
}
|
|
6962
|
+
if (def.relativeDate && isRelativeDateDmlUse(stmt)) {
|
|
6963
|
+
throw new BatchAnalysisError(
|
|
6964
|
+
`ArgumentError: RELATIVE_DATE variable @${use.name} cannot be used in DML or VALIDATE statements.`,
|
|
6965
|
+
index
|
|
6966
|
+
);
|
|
6967
|
+
}
|
|
6968
|
+
if (def.relativeDate && !use.relativeDateAllowed) {
|
|
6969
|
+
throw new BatchAnalysisError(
|
|
6970
|
+
`ArgumentError: RELATIVE_DATE variable @${use.name} can only be used as a WHERE comparison right operand or BETWEEN boundary.`,
|
|
6971
|
+
index
|
|
6972
|
+
);
|
|
6973
|
+
}
|
|
6907
6974
|
if (!referencedThisStatement.has(use.name)) {
|
|
6908
6975
|
def.referencedBy.push(index);
|
|
6909
6976
|
referencedThisStatement.add(use.name);
|
|
@@ -6916,6 +6983,7 @@ function analyzeBatch(statements) {
|
|
|
6916
6983
|
variableDefs.set(stmt.name, {
|
|
6917
6984
|
index,
|
|
6918
6985
|
kind: stmt.type === "SET_VARIABLE" && stmt.expr.type === "ARRAY" ? "array" : "scalar",
|
|
6986
|
+
relativeDate: stmt.type === "DECLARE_VARIABLE" && stmt.annotation === "RELATIVE_DATE",
|
|
6919
6987
|
referencedBy: []
|
|
6920
6988
|
});
|
|
6921
6989
|
variableOrder.push(stmt.name);
|
|
@@ -16089,7 +16157,7 @@ function materializedColumnMetaEqual(left, right) {
|
|
|
16089
16157
|
if (!left || !right || left.size !== right.size) return false;
|
|
16090
16158
|
for (const [column, meta] of left) {
|
|
16091
16159
|
const candidate = right.get(column);
|
|
16092
|
-
if (!candidate || candidate.sortKind !== meta.sortKind || candidate.fieldType !== meta.fieldType || !fieldSemanticsEqual(candidate.semantics, meta.semantics)) return false;
|
|
16160
|
+
if (!candidate || candidate.displayName !== meta.displayName || candidate.sortKind !== meta.sortKind || candidate.fieldType !== meta.fieldType || !fieldSemanticsEqual(candidate.semantics, meta.semantics)) return false;
|
|
16093
16161
|
}
|
|
16094
16162
|
return true;
|
|
16095
16163
|
}
|
|
@@ -16108,6 +16176,7 @@ async function executeBatch(sql, client, options = {}) {
|
|
|
16108
16176
|
throw new Error("UnsupportedError: APPLY mutation requires allowApplyMutation=true");
|
|
16109
16177
|
}
|
|
16110
16178
|
const injectedVariables = validateDeclaredBatchVariables(statements, options.variables);
|
|
16179
|
+
const relativeDateVariables = prepareRelativeDateVariables(statements, injectedVariables);
|
|
16111
16180
|
const batchOptions = { ...options, variables: injectedVariables };
|
|
16112
16181
|
if (options.continueOnError && analysis.containsDml) {
|
|
16113
16182
|
throw new Error("ArgumentError: continueOnError is not allowed for batches containing DML.");
|
|
@@ -16179,7 +16248,16 @@ async function executeBatch(sql, client, options = {}) {
|
|
|
16179
16248
|
);
|
|
16180
16249
|
const cursorScope = wrapClientWithCursorScope(statementClient);
|
|
16181
16250
|
const outcome = await runWithDeadline(
|
|
16182
|
-
executeBatchStatement(
|
|
16251
|
+
executeBatchStatement(
|
|
16252
|
+
statements[i],
|
|
16253
|
+
info,
|
|
16254
|
+
cursorScope.client,
|
|
16255
|
+
stmtOptions,
|
|
16256
|
+
cacheContext,
|
|
16257
|
+
tempTables,
|
|
16258
|
+
variables,
|
|
16259
|
+
relativeDateVariables
|
|
16260
|
+
),
|
|
16183
16261
|
remaining,
|
|
16184
16262
|
cursorScope.closeActive
|
|
16185
16263
|
);
|
|
@@ -16224,7 +16302,7 @@ function statementHasApplyMutation(statement) {
|
|
|
16224
16302
|
}
|
|
16225
16303
|
return statement.type === "UPSERT" && statement.validateOnly !== true && Boolean(statement.onInsertApplyBlocks?.length || statement.onUpdateApplyBlocks?.length);
|
|
16226
16304
|
}
|
|
16227
|
-
async function executeBatchStatement(stmt, info, client, options, cacheContext, tempTables, variables) {
|
|
16305
|
+
async function executeBatchStatement(stmt, info, client, options, cacheContext, tempTables, variables, relativeDateVariables) {
|
|
16228
16306
|
if (stmt.type === "SET_VARIABLE") {
|
|
16229
16307
|
const resolvedStmt2 = resolveBatchVariableReferences(stmt, variables);
|
|
16230
16308
|
validateStatementStatic(resolvedStmt2);
|
|
@@ -16269,6 +16347,13 @@ async function executeBatchStatement(stmt, info, client, options, cacheContext,
|
|
|
16269
16347
|
return {};
|
|
16270
16348
|
}
|
|
16271
16349
|
if (stmt.type === "DECLARE_VARIABLE") {
|
|
16350
|
+
if (stmt.annotation === "RELATIVE_DATE") {
|
|
16351
|
+
variables.set(stmt.name, {
|
|
16352
|
+
type: "relative-date",
|
|
16353
|
+
value: relativeDateVariables.get(stmt.name)
|
|
16354
|
+
});
|
|
16355
|
+
return {};
|
|
16356
|
+
}
|
|
16272
16357
|
const injected = options.variables ?? {};
|
|
16273
16358
|
if (Object.prototype.hasOwnProperty.call(injected, stmt.name)) {
|
|
16274
16359
|
variables.set(stmt.name, { type: "string", value: injected[stmt.name] });
|
|
@@ -16368,7 +16453,16 @@ async function executeBatchStatement(stmt, info, client, options, cacheContext,
|
|
|
16368
16453
|
}
|
|
16369
16454
|
if (info.tempTablesReferenced.length > 0) {
|
|
16370
16455
|
if (resolvedStmt.type === "SELECT" || resolvedStmt.type === "UNION") {
|
|
16371
|
-
return {
|
|
16456
|
+
return {
|
|
16457
|
+
result: await executeQueryWithCte(
|
|
16458
|
+
resolvedStmt,
|
|
16459
|
+
client,
|
|
16460
|
+
options,
|
|
16461
|
+
tempTables,
|
|
16462
|
+
cacheContext,
|
|
16463
|
+
options.captureColumnMeta === true
|
|
16464
|
+
)
|
|
16465
|
+
};
|
|
16372
16466
|
}
|
|
16373
16467
|
if (resolvedStmt.type === "WITH") {
|
|
16374
16468
|
return { result: await executeWith(resolvedStmt, client, options, cacheContext, tempTables) };
|
|
@@ -16483,6 +16577,32 @@ function parseSqlBatch(sql, enableImport = false) {
|
|
|
16483
16577
|
const tokens = new Lexer(sql).tokenize();
|
|
16484
16578
|
return new Parser(tokens, { import: enableImport }).parseStatements();
|
|
16485
16579
|
}
|
|
16580
|
+
function parseRelativeDateVariableValue(name, value) {
|
|
16581
|
+
try {
|
|
16582
|
+
const statements = parseSqlBatch(`DECLARE @__b111 RELATIVE_DATE = ${value}`);
|
|
16583
|
+
const declaration = statements[0];
|
|
16584
|
+
if (statements.length !== 1 || declaration?.type !== "DECLARE_VARIABLE" || declaration.annotation !== "RELATIVE_DATE") {
|
|
16585
|
+
throw new Error("token was not consumed as one RELATIVE_DATE declaration");
|
|
16586
|
+
}
|
|
16587
|
+
return declaration.default;
|
|
16588
|
+
} catch (error) {
|
|
16589
|
+
const detail = error instanceof Error ? ` ${error.message}` : "";
|
|
16590
|
+
throw new Error(
|
|
16591
|
+
`ArgumentError: RELATIVE_DATE variable @${name} requires one supported relative-date function token.${detail}`
|
|
16592
|
+
);
|
|
16593
|
+
}
|
|
16594
|
+
}
|
|
16595
|
+
function prepareRelativeDateVariables(statements, injectedVariables) {
|
|
16596
|
+
const prepared = /* @__PURE__ */ new Map();
|
|
16597
|
+
for (const stmt of statements) {
|
|
16598
|
+
if (stmt.type !== "DECLARE_VARIABLE" || stmt.annotation !== "RELATIVE_DATE") continue;
|
|
16599
|
+
prepared.set(
|
|
16600
|
+
stmt.name,
|
|
16601
|
+
Object.prototype.hasOwnProperty.call(injectedVariables, stmt.name) ? parseRelativeDateVariableValue(stmt.name, injectedVariables[stmt.name]) : stmt.default
|
|
16602
|
+
);
|
|
16603
|
+
}
|
|
16604
|
+
return prepared;
|
|
16605
|
+
}
|
|
16486
16606
|
function evaluateScalarExpr(expr) {
|
|
16487
16607
|
switch (expr.type) {
|
|
16488
16608
|
case "STRING":
|
|
@@ -16519,7 +16639,8 @@ function resolveBatchVariableReferencesInternal(node, variables, numericArithmet
|
|
|
16519
16639
|
if (value.type === "array") {
|
|
16520
16640
|
throw new Error(`ParseError: array variable @${obj["name"]} can only be used as IN @${obj["name"]}.`);
|
|
16521
16641
|
}
|
|
16522
|
-
if (
|
|
16642
|
+
if (value.type === "relative-date") return value.value;
|
|
16643
|
+
if (numericArithmeticOperand && value.type !== "number" && !(value.type === "string" && value.placeholder === true)) {
|
|
16523
16644
|
throw new Error(
|
|
16524
16645
|
`ArgumentError: variable @${obj["name"]} is not numeric and cannot be used in arithmetic.`
|
|
16525
16646
|
);
|
|
@@ -16530,7 +16651,11 @@ function resolveBatchVariableReferencesInternal(node, variables, numericArithmet
|
|
|
16530
16651
|
const value = variables.get(obj["name"]);
|
|
16531
16652
|
if (value === void 0) throw new Error(`ParseError: variable @${obj["name"]} is not defined in this batch.`);
|
|
16532
16653
|
if (value.type === "array") throw new Error(`ParseError: array variable @${obj["name"]} cannot be used as a SELECT column.`);
|
|
16533
|
-
|
|
16654
|
+
if (value.type === "relative-date") {
|
|
16655
|
+
throw new Error(`InternalError: RELATIVE_DATE variable @${obj["name"]} reached a SELECT column.`);
|
|
16656
|
+
}
|
|
16657
|
+
const aliasDisplay = typeof obj["aliasDisplay"] === "string" ? { aliasDisplay: obj["aliasDisplay"] } : {};
|
|
16658
|
+
return value.type === "number" ? { type: "ARITH_COL", expr: { type: "NUMBER", value: value.value, raw: value.raw ?? String(value.value) }, alias: obj["alias"], ...aliasDisplay } : { type: "LITERAL_COL", value: value.value, alias: obj["alias"], ...aliasDisplay };
|
|
16534
16659
|
}
|
|
16535
16660
|
if (obj["type"] === "VARIABLE_IN_LIST") return obj;
|
|
16536
16661
|
const resolved = Object.fromEntries(
|
|
@@ -16543,6 +16668,9 @@ function resolveBatchVariableReferencesInternal(node, variables, numericArithmet
|
|
|
16543
16668
|
)
|
|
16544
16669
|
])
|
|
16545
16670
|
);
|
|
16671
|
+
if (typeof obj["aliasDisplay"] === "string") {
|
|
16672
|
+
resolved["aliasDisplay"] = obj["aliasDisplay"];
|
|
16673
|
+
}
|
|
16546
16674
|
if (resolved["type"] === "BINARY") {
|
|
16547
16675
|
const right = resolved["right"];
|
|
16548
16676
|
if (right?.["type"] === "VARIABLE_IN_LIST" && typeof right["name"] === "string") {
|
|
@@ -18068,6 +18196,9 @@ function inferAggregateArgMeta(arg, resolveField2) {
|
|
|
18068
18196
|
if (arg.elseResult) results.push(caseResultColumnMeta(arg.elseResult, resolveField2));
|
|
18069
18197
|
return mergeExpressionColumnMeta(results);
|
|
18070
18198
|
}
|
|
18199
|
+
function withDisplayName(meta, displayName) {
|
|
18200
|
+
return { ...meta ?? {}, displayName };
|
|
18201
|
+
}
|
|
18071
18202
|
function selectNeedsSourceColumnMeta(stmt) {
|
|
18072
18203
|
return stmt.columns.some(
|
|
18073
18204
|
(column) => column.type === "FIELD" || column.type === "WILDCARD" || column.type === "PARENT_WILDCARD" || column.type === "CASE_COL" || column.type === "AGGREGATE" && (column.func === "MIN" || column.func === "MAX" || column.func === "MODE")
|
|
@@ -18132,7 +18263,7 @@ async function inferSelectColumnMeta(stmt, outputColumns, client, cacheContext,
|
|
|
18132
18263
|
for (const output of outputColumns) {
|
|
18133
18264
|
const ref = aggregateFieldRef(output);
|
|
18134
18265
|
const meta = withPublicSource(resolveField2(ref), ref);
|
|
18135
|
-
|
|
18266
|
+
inferred.set(output, withDisplayName(meta, meta?.displayName ?? output));
|
|
18136
18267
|
}
|
|
18137
18268
|
return inferred;
|
|
18138
18269
|
}
|
|
@@ -18140,7 +18271,7 @@ async function inferSelectColumnMeta(stmt, outputColumns, client, cacheContext,
|
|
|
18140
18271
|
for (const output of outputColumns) {
|
|
18141
18272
|
const ref = aggregateFieldRef(output);
|
|
18142
18273
|
const meta = withPublicSource(resolveField2(ref), ref);
|
|
18143
|
-
|
|
18274
|
+
inferred.set(output, withDisplayName(meta, meta?.displayName ?? output));
|
|
18144
18275
|
}
|
|
18145
18276
|
}
|
|
18146
18277
|
const explicitColumns = stmt.columns.filter(
|
|
@@ -18184,7 +18315,7 @@ async function inferSelectColumnMeta(stmt, outputColumns, client, cacheContext,
|
|
|
18184
18315
|
} else if (column.type === "SCALAR_SUBQUERY_COL") {
|
|
18185
18316
|
meta = unknownStringColumnMeta();
|
|
18186
18317
|
}
|
|
18187
|
-
|
|
18318
|
+
inferred.set(output, withDisplayName(meta, column.aliasDisplay ?? output));
|
|
18188
18319
|
});
|
|
18189
18320
|
return inferred;
|
|
18190
18321
|
}
|
|
@@ -18196,15 +18327,14 @@ function mergeUnionColumnMeta(left, right) {
|
|
|
18196
18327
|
const a = leftMeta?.get(column);
|
|
18197
18328
|
const rightColumn = right.columns[index];
|
|
18198
18329
|
const b = rightColumn === void 0 ? void 0 : rightMeta?.get(rightColumn);
|
|
18330
|
+
let meta;
|
|
18199
18331
|
if (a && b) {
|
|
18200
18332
|
const combined = mergeExpressionColumnMeta([a, b]);
|
|
18201
18333
|
const publicSourceApp = a.publicSourceApp === b.publicSourceApp ? a.publicSourceApp : void 0;
|
|
18202
18334
|
const { publicSourceApp: _discarded, ...withoutPublicSource } = combined;
|
|
18203
|
-
|
|
18204
|
-
|
|
18205
|
-
|
|
18206
|
-
);
|
|
18207
|
-
} else if (a || b) merged.set(column, unknownStringColumnMeta());
|
|
18335
|
+
meta = publicSourceApp === void 0 ? withoutPublicSource : { ...withoutPublicSource, publicSourceApp };
|
|
18336
|
+
} else meta = unknownStringColumnMeta();
|
|
18337
|
+
merged.set(column, withDisplayName(meta, a?.displayName ?? column));
|
|
18208
18338
|
});
|
|
18209
18339
|
return merged;
|
|
18210
18340
|
}
|
|
@@ -22643,7 +22773,8 @@ async function buildBatchExplainPlans(sql, client, injectedVariables, cacheConte
|
|
|
22643
22773
|
try {
|
|
22644
22774
|
const statements = parseSqlBatch(sql, enableImport);
|
|
22645
22775
|
const analysis = analyzeBatch(statements);
|
|
22646
|
-
validateDeclaredBatchVariables(statements, injectedVariables);
|
|
22776
|
+
const normalizedInjectedVariables = validateDeclaredBatchVariables(statements, injectedVariables);
|
|
22777
|
+
const relativeDateVariables = prepareRelativeDateVariables(statements, normalizedInjectedVariables);
|
|
22647
22778
|
const variables = /* @__PURE__ */ new Map();
|
|
22648
22779
|
const plans = [];
|
|
22649
22780
|
for (let i = 0; i < statements.length; i++) {
|
|
@@ -22676,7 +22807,7 @@ async function buildBatchExplainPlans(sql, client, injectedVariables, cacheConte
|
|
|
22676
22807
|
plan: statementPlan.length === 0 ? metadataPlan : [statementPlan[0], ...metadataPlan, ...statementPlan.slice(1)]
|
|
22677
22808
|
});
|
|
22678
22809
|
if (stmt.type === "SET_VARIABLE" || stmt.type === "DECLARE_VARIABLE") {
|
|
22679
|
-
variables.set(stmt.name, stmt.type === "SET_VARIABLE" && stmt.expr.type === "ARRAY" ? { type: "array", elements: stmt.expr.elements.map((element) => ({ type: "string", value: element.value })) } : { type: "string", value: `@${stmt.name}`, placeholder: true });
|
|
22810
|
+
variables.set(stmt.name, stmt.type === "DECLARE_VARIABLE" && stmt.annotation === "RELATIVE_DATE" ? { type: "relative-date", value: relativeDateVariables.get(stmt.name) } : stmt.type === "SET_VARIABLE" && stmt.expr.type === "ARRAY" ? { type: "array", elements: stmt.expr.elements.map((element) => ({ type: "string", value: element.value })) } : { type: "string", value: `@${stmt.name}`, placeholder: true });
|
|
22680
22811
|
}
|
|
22681
22812
|
}
|
|
22682
22813
|
return { statementCount: statements.length, statements: plans };
|
|
@@ -22715,6 +22846,12 @@ function buildBatchStatementPlan(stmt, info, capabilities, orderPlans, dmlMaxRow
|
|
|
22715
22846
|
];
|
|
22716
22847
|
}
|
|
22717
22848
|
if (stmt.type === "DECLARE_VARIABLE") {
|
|
22849
|
+
if (stmt.annotation === "RELATIVE_DATE") {
|
|
22850
|
+
return [
|
|
22851
|
+
`DECLARE @${stmt.name} RELATIVE_DATE = <relative-date token>`,
|
|
22852
|
+
" value: \u5916\u90E8\u6CE8\u5165\u304C\u3042\u308C\u3070\u63A1\u7528\u3001\u306A\u3051\u308C\u3070\u65E2\u5B9A\u30C8\u30FC\u30AF\u30F3\u3092\u4F7F\u7528\uFF08\u5024\u306F\u975E\u516C\u958B\uFF09"
|
|
22853
|
+
];
|
|
22854
|
+
}
|
|
22718
22855
|
return [
|
|
22719
22856
|
`DECLARE @${stmt.name} = <default scalar expression>`,
|
|
22720
22857
|
" value: \u5916\u90E8\u6CE8\u5165\u304C\u3042\u308C\u3070\u63A1\u7528\u3001\u306A\u3051\u308C\u3070\u65E2\u5B9A\u5024\u3092\u5B9F\u884C\u6642\u306B1\u56DE\u8A55\u4FA1\uFF08\u5024\u306F\u975E\u516C\u958B\uFF09"
|
|
@@ -25344,13 +25481,17 @@ function restoreSqlDiagnosticValue(value, bindings, options = {}) {
|
|
|
25344
25481
|
return `${dmlTarget[1]}${target}`;
|
|
25345
25482
|
}
|
|
25346
25483
|
}
|
|
25347
|
-
|
|
25348
|
-
|
|
25349
|
-
|
|
25484
|
+
if (bindings.size === 0) return value;
|
|
25485
|
+
const mappedIds = [...bindings.keys()].sort((a, b) => String(b).length - String(a).length);
|
|
25486
|
+
const internalApp = new RegExp(
|
|
25487
|
+
`APP(${mappedIds.join("|")})(?!\\d)(\\s+AS\\s+[^\\s()]+)?(?:\\s+\\(\\1\\))?`,
|
|
25488
|
+
"g"
|
|
25489
|
+
);
|
|
25490
|
+
return value.replace(internalApp, (_match, mappedIdText, alias) => {
|
|
25491
|
+
const binding = bindings.get(Number(mappedIdText));
|
|
25350
25492
|
const display = binding.source === "logical" ? displayMode === "physical" ? `LAPP_${binding.logicalName} -> APP${binding.appId}` : `LAPP_${binding.logicalName}@${binding.profile}` : displayMode === "physical" ? `APP${binding.appId}` : `APP${binding.appId}@${binding.profile}`;
|
|
25351
|
-
|
|
25352
|
-
}
|
|
25353
|
-
return restored;
|
|
25493
|
+
return `${display}${alias ?? ""}`;
|
|
25494
|
+
});
|
|
25354
25495
|
}
|
|
25355
25496
|
if (Array.isArray(value)) {
|
|
25356
25497
|
return value.map((item) => restoreSqlDiagnosticValue(item, bindings, options));
|