@rex0220/kintone-sql-tools 3.12.0 → 3.13.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 +424 -84
- package/dist-mcp/ksql-mcp.js +445 -89
- package/dist-mcpb/ksql-mcp.mcpb +0 -0
- package/package.json +1 -1
package/dist-cli/ksql.js
CHANGED
|
@@ -93,6 +93,12 @@ var KEYWORDS = /* @__PURE__ */ new Map([
|
|
|
93
93
|
["MAX", "MAX" /* MAX */],
|
|
94
94
|
["MIN", "MIN" /* MIN */],
|
|
95
95
|
["GROUP_CONCAT", "GROUP_CONCAT" /* GROUP_CONCAT */],
|
|
96
|
+
["STDDEV_POP", "STDDEV_POP" /* STDDEV_POP */],
|
|
97
|
+
["STDDEV_SAMP", "STDDEV_SAMP" /* STDDEV_SAMP */],
|
|
98
|
+
["VAR_POP", "VAR_POP" /* VAR_POP */],
|
|
99
|
+
["VAR_SAMP", "VAR_SAMP" /* VAR_SAMP */],
|
|
100
|
+
["MEDIAN", "MEDIAN" /* MEDIAN */],
|
|
101
|
+
["MODE", "MODE" /* MODE */],
|
|
96
102
|
["ROW_NUMBER", "ROW_NUMBER" /* ROW_NUMBER */],
|
|
97
103
|
["RANK", "RANK" /* RANK */],
|
|
98
104
|
["DENSE_RANK", "DENSE_RANK" /* DENSE_RANK */],
|
|
@@ -155,6 +161,9 @@ var KEYWORDS = /* @__PURE__ */ new Map([
|
|
|
155
161
|
["YEAR", "YEAR" /* YEAR */],
|
|
156
162
|
["MONTH", "MONTH" /* MONTH */],
|
|
157
163
|
["DAY", "DAY" /* DAY */],
|
|
164
|
+
["DAYOFWEEK", "DAYOFWEEK" /* DAYOFWEEK */],
|
|
165
|
+
["QUARTER", "QUARTER" /* QUARTER */],
|
|
166
|
+
["WEEK", "WEEK" /* WEEK */],
|
|
158
167
|
["DATE_FORMAT", "DATE_FORMAT" /* DATE_FORMAT */],
|
|
159
168
|
["DATEDIFF", "DATEDIFF" /* DATEDIFF */],
|
|
160
169
|
["DATE_ADD", "DATE_ADD" /* DATE_ADD */],
|
|
@@ -620,6 +629,9 @@ var PARSER_SCALAR_FUNCTION_TOKEN_MAP = Object.freeze({
|
|
|
620
629
|
["YEAR" /* YEAR */]: "YEAR",
|
|
621
630
|
["MONTH" /* MONTH */]: "MONTH",
|
|
622
631
|
["DAY" /* DAY */]: "DAY",
|
|
632
|
+
["DAYOFWEEK" /* DAYOFWEEK */]: "DAYOFWEEK",
|
|
633
|
+
["QUARTER" /* QUARTER */]: "QUARTER",
|
|
634
|
+
["WEEK" /* WEEK */]: "WEEK",
|
|
623
635
|
["DATE_FORMAT" /* DATE_FORMAT */]: "DATE_FORMAT",
|
|
624
636
|
["DATEDIFF" /* DATEDIFF */]: "DATEDIFF",
|
|
625
637
|
["DATE_ADD" /* DATE_ADD */]: "DATE_ADD",
|
|
@@ -635,8 +647,30 @@ var PARSER_AGGREGATE_FUNCTION_TOKEN_MAP = Object.freeze({
|
|
|
635
647
|
["AVG" /* AVG */]: "AVG",
|
|
636
648
|
["MAX" /* MAX */]: "MAX",
|
|
637
649
|
["MIN" /* MIN */]: "MIN",
|
|
638
|
-
["GROUP_CONCAT" /* GROUP_CONCAT */]: "GROUP_CONCAT"
|
|
650
|
+
["GROUP_CONCAT" /* GROUP_CONCAT */]: "GROUP_CONCAT",
|
|
651
|
+
["STDDEV_POP" /* STDDEV_POP */]: "STDDEV_POP",
|
|
652
|
+
["STDDEV_SAMP" /* STDDEV_SAMP */]: "STDDEV_SAMP",
|
|
653
|
+
["VAR_POP" /* VAR_POP */]: "VAR_POP",
|
|
654
|
+
["VAR_SAMP" /* VAR_SAMP */]: "VAR_SAMP",
|
|
655
|
+
["MEDIAN" /* MEDIAN */]: "MEDIAN",
|
|
656
|
+
["MODE" /* MODE */]: "MODE"
|
|
639
657
|
});
|
|
658
|
+
var PARSER_AGGREGATE_FUNCTIONS = Object.freeze(
|
|
659
|
+
Object.values(PARSER_AGGREGATE_FUNCTION_TOKEN_MAP).filter(
|
|
660
|
+
(func) => func !== void 0
|
|
661
|
+
)
|
|
662
|
+
);
|
|
663
|
+
var PARSER_AGGREGATE_WILDCARD_FUNCTIONS = Object.freeze([
|
|
664
|
+
"COUNT",
|
|
665
|
+
"SUM",
|
|
666
|
+
"AVG",
|
|
667
|
+
"MAX",
|
|
668
|
+
"MIN"
|
|
669
|
+
]);
|
|
670
|
+
var PARSER_AGGREGATE_WILDCARD_FUNCTION_SET = new Set(PARSER_AGGREGATE_WILDCARD_FUNCTIONS);
|
|
671
|
+
function aggregateAcceptsWildcard(func) {
|
|
672
|
+
return PARSER_AGGREGATE_WILDCARD_FUNCTION_SET.has(func);
|
|
673
|
+
}
|
|
640
674
|
var PARSER_WINDOW_FUNCTION_TOKEN_MAP = Object.freeze({
|
|
641
675
|
["ROW_NUMBER" /* ROW_NUMBER */]: "ROW_NUMBER",
|
|
642
676
|
["RANK" /* RANK */]: "RANK",
|
|
@@ -666,6 +700,13 @@ var FUNC_CALL_PREFIX_KINDS = /* @__PURE__ */ new Set([
|
|
|
666
700
|
"AVG" /* AVG */,
|
|
667
701
|
"MAX" /* MAX */,
|
|
668
702
|
"MIN" /* MIN */,
|
|
703
|
+
"GROUP_CONCAT" /* GROUP_CONCAT */,
|
|
704
|
+
"STDDEV_POP" /* STDDEV_POP */,
|
|
705
|
+
"STDDEV_SAMP" /* STDDEV_SAMP */,
|
|
706
|
+
"VAR_POP" /* VAR_POP */,
|
|
707
|
+
"VAR_SAMP" /* VAR_SAMP */,
|
|
708
|
+
"MEDIAN" /* MEDIAN */,
|
|
709
|
+
"MODE" /* MODE */,
|
|
669
710
|
"ROW_NUMBER" /* ROW_NUMBER */,
|
|
670
711
|
"RANK" /* RANK */,
|
|
671
712
|
"DENSE_RANK" /* DENSE_RANK */,
|
|
@@ -714,6 +755,9 @@ var FUNC_CALL_PREFIX_KINDS = /* @__PURE__ */ new Set([
|
|
|
714
755
|
"YEAR" /* YEAR */,
|
|
715
756
|
"MONTH" /* MONTH */,
|
|
716
757
|
"DAY" /* DAY */,
|
|
758
|
+
"DAYOFWEEK" /* DAYOFWEEK */,
|
|
759
|
+
"QUARTER" /* QUARTER */,
|
|
760
|
+
"WEEK" /* WEEK */,
|
|
717
761
|
"DATE_FORMAT" /* DATE_FORMAT */,
|
|
718
762
|
"DATEDIFF" /* DATEDIFF */,
|
|
719
763
|
"DATE_ADD" /* DATE_ADD */,
|
|
@@ -2124,10 +2168,14 @@ var Parser = class {
|
|
|
2124
2168
|
this.advance();
|
|
2125
2169
|
this.expect("(" /* LPAREN */);
|
|
2126
2170
|
const distinct = this.consume("DISTINCT" /* DISTINCT */);
|
|
2171
|
+
const distinctToken = distinct ? this.prev() : null;
|
|
2172
|
+
if (func === "MODE" && distinctToken) {
|
|
2173
|
+
throw new ParseError("MODE \u3067\u306F DISTINCT \u306F\u4F7F\u7528\u3067\u304D\u307E\u305B\u3093", distinctToken);
|
|
2174
|
+
}
|
|
2127
2175
|
let arg;
|
|
2128
2176
|
if (this.consume("*" /* STAR */)) {
|
|
2129
|
-
if (func
|
|
2130
|
-
throw new ParseError(
|
|
2177
|
+
if (!aggregateAcceptsWildcard(func)) {
|
|
2178
|
+
throw new ParseError(`${func}(*) \u306F\u4F7F\u7528\u3067\u304D\u307E\u305B\u3093\u3002\u30D5\u30A3\u30FC\u30EB\u30C9\u307E\u305F\u306F\u5F0F\u3092\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044`, this.prev());
|
|
2131
2179
|
}
|
|
2132
2180
|
arg = { type: "WILDCARD" };
|
|
2133
2181
|
} else {
|
|
@@ -2421,10 +2469,14 @@ var Parser = class {
|
|
|
2421
2469
|
this.advance();
|
|
2422
2470
|
this.expect("(" /* LPAREN */);
|
|
2423
2471
|
const distinct = this.consume("DISTINCT" /* DISTINCT */);
|
|
2472
|
+
const distinctToken = distinct ? this.prev() : null;
|
|
2473
|
+
if (aggFunc === "MODE" && distinctToken) {
|
|
2474
|
+
throw new ParseError("MODE \u3067\u306F DISTINCT \u306F\u4F7F\u7528\u3067\u304D\u307E\u305B\u3093", distinctToken);
|
|
2475
|
+
}
|
|
2424
2476
|
let argStr;
|
|
2425
2477
|
if (this.consume("*" /* STAR */)) {
|
|
2426
|
-
if (aggFunc
|
|
2427
|
-
throw new ParseError(
|
|
2478
|
+
if (!aggregateAcceptsWildcard(aggFunc)) {
|
|
2479
|
+
throw new ParseError(`${aggFunc}(*) \u306F\u4F7F\u7528\u3067\u304D\u307E\u305B\u3093\u3002\u30D5\u30A3\u30FC\u30EB\u30C9\u307E\u305F\u306F\u5F0F\u3092\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044`, this.prev());
|
|
2428
2480
|
}
|
|
2429
2481
|
argStr = "*";
|
|
2430
2482
|
} else {
|
|
@@ -3563,54 +3615,105 @@ function writesKintone(stmt) {
|
|
|
3563
3615
|
function isReadOnlyStatement(stmt) {
|
|
3564
3616
|
return !writesKintone(stmt) && (isReadOnlyType(stmt.type) || isDmlType(stmt.type));
|
|
3565
3617
|
}
|
|
3566
|
-
|
|
3567
|
-
|
|
3618
|
+
var STATISTICAL_AGGREGATES = /* @__PURE__ */ new Set([
|
|
3619
|
+
"STDDEV_POP",
|
|
3620
|
+
"STDDEV_SAMP",
|
|
3621
|
+
"VAR_POP",
|
|
3622
|
+
"VAR_SAMP",
|
|
3623
|
+
"MEDIAN",
|
|
3624
|
+
"MODE"
|
|
3625
|
+
]);
|
|
3626
|
+
function addReasons(target, source) {
|
|
3627
|
+
for (const reason of source) target.add(reason);
|
|
3628
|
+
}
|
|
3629
|
+
function containsStatisticalAggregate(value, seen = /* @__PURE__ */ new Set()) {
|
|
3630
|
+
if (value === null || typeof value !== "object") return false;
|
|
3631
|
+
if (seen.has(value)) return false;
|
|
3632
|
+
seen.add(value);
|
|
3633
|
+
const record = value;
|
|
3634
|
+
if ((record.type === "AGGREGATE" || record.type === "AGG_REF") && typeof record.func === "string" && STATISTICAL_AGGREGATES.has(record.func)) return true;
|
|
3635
|
+
if (record.type === "FIELD" && typeof record.field === "string" && /^(STDDEV_POP|STDDEV_SAMP|VAR_POP|VAR_SAMP|MEDIAN|MODE)\(/i.test(record.field)) return true;
|
|
3636
|
+
return Object.values(record).some((child) => Array.isArray(child) ? child.some((entry) => containsStatisticalAggregate(entry, seen)) : containsStatisticalAggregate(child, seen));
|
|
3637
|
+
}
|
|
3638
|
+
function completeInputReasons(stmt) {
|
|
3639
|
+
const reasons = /* @__PURE__ */ new Set();
|
|
3640
|
+
if (isDmlType(stmt.type)) {
|
|
3641
|
+
reasons.add("DML");
|
|
3642
|
+
return reasons;
|
|
3643
|
+
}
|
|
3568
3644
|
switch (stmt.type) {
|
|
3569
3645
|
case "VALIDATE":
|
|
3570
|
-
|
|
3646
|
+
reasons.add("VALIDATE");
|
|
3647
|
+
break;
|
|
3571
3648
|
case "SELECT":
|
|
3572
|
-
|
|
3649
|
+
addReasons(reasons, selectCompleteInputReasons(stmt));
|
|
3650
|
+
break;
|
|
3573
3651
|
case "UNION":
|
|
3574
|
-
|
|
3652
|
+
addReasons(reasons, unionCompleteInputReasons(stmt));
|
|
3653
|
+
break;
|
|
3575
3654
|
case "WITH":
|
|
3576
|
-
|
|
3577
|
-
(
|
|
3578
|
-
|
|
3655
|
+
for (const cte of stmt.ctes) {
|
|
3656
|
+
addReasons(reasons, completeInputReasons(cte.query));
|
|
3657
|
+
}
|
|
3658
|
+
addReasons(reasons, completeInputReasons(stmt.query));
|
|
3659
|
+
break;
|
|
3579
3660
|
case "CREATE_TEMP_TABLE":
|
|
3580
|
-
|
|
3661
|
+
addReasons(reasons, completeInputReasons(stmt.query));
|
|
3662
|
+
break;
|
|
3581
3663
|
default:
|
|
3582
|
-
|
|
3664
|
+
break;
|
|
3583
3665
|
}
|
|
3666
|
+
if (containsStatisticalAggregate(stmt)) reasons.add("STATISTICAL_AGGREGATE");
|
|
3667
|
+
return reasons;
|
|
3584
3668
|
}
|
|
3585
|
-
function
|
|
3586
|
-
|
|
3587
|
-
return left || selectRequiresCompleteInput(stmt.right);
|
|
3669
|
+
function requiresCompleteInput(stmt) {
|
|
3670
|
+
return completeInputReasons(stmt).size > 0;
|
|
3588
3671
|
}
|
|
3589
|
-
function
|
|
3590
|
-
|
|
3591
|
-
|
|
3592
|
-
|
|
3593
|
-
(branch) => whereRequiresCompleteInput(branch.condition)
|
|
3594
|
-
)
|
|
3595
|
-
)) return true;
|
|
3596
|
-
return whereRequiresCompleteInput(stmt.where) || whereRequiresCompleteInput(stmt.having);
|
|
3672
|
+
function unionCompleteInputReasons(stmt) {
|
|
3673
|
+
const reasons = stmt.left.type === "SELECT" ? selectCompleteInputReasons(stmt.left) : unionCompleteInputReasons(stmt.left);
|
|
3674
|
+
addReasons(reasons, selectCompleteInputReasons(stmt.right));
|
|
3675
|
+
return reasons;
|
|
3597
3676
|
}
|
|
3598
|
-
function
|
|
3599
|
-
|
|
3677
|
+
function selectCompleteInputReasons(stmt) {
|
|
3678
|
+
const reasons = /* @__PURE__ */ new Set();
|
|
3679
|
+
if (stmt.orderBy.length > 0) reasons.add("LOCAL_ORDER");
|
|
3680
|
+
for (const column of stmt.columns) {
|
|
3681
|
+
if (column.type === "WINDOW_COL" && column.orderBy.length > 0) reasons.add("WINDOW_ORDER");
|
|
3682
|
+
if (column.type === "SCALAR_SUBQUERY_COL") addReasons(reasons, selectCompleteInputReasons(column.query));
|
|
3683
|
+
if (column.type === "CASE_COL") {
|
|
3684
|
+
for (const branch of column.expr.branches) addReasons(reasons, whereCompleteInputReasons(branch.condition));
|
|
3685
|
+
}
|
|
3686
|
+
}
|
|
3687
|
+
addReasons(reasons, whereCompleteInputReasons(stmt.where));
|
|
3688
|
+
addReasons(reasons, whereCompleteInputReasons(stmt.having));
|
|
3689
|
+
if (containsStatisticalAggregate(stmt)) reasons.add("STATISTICAL_AGGREGATE");
|
|
3690
|
+
return reasons;
|
|
3691
|
+
}
|
|
3692
|
+
function whereCompleteInputReasons(where) {
|
|
3693
|
+
const reasons = /* @__PURE__ */ new Set();
|
|
3694
|
+
if (where === null) return reasons;
|
|
3600
3695
|
switch (where.type) {
|
|
3601
3696
|
case "BINARY":
|
|
3602
|
-
|
|
3697
|
+
if (where.right.type === "SUBQUERY_IN_LIST" || where.right.type === "SCALAR_SUBQUERY") {
|
|
3698
|
+
addReasons(reasons, selectCompleteInputReasons(where.right.query));
|
|
3699
|
+
}
|
|
3700
|
+
break;
|
|
3603
3701
|
case "LOGICAL":
|
|
3604
|
-
|
|
3702
|
+
addReasons(reasons, whereCompleteInputReasons(where.left));
|
|
3703
|
+
addReasons(reasons, whereCompleteInputReasons(where.right));
|
|
3704
|
+
break;
|
|
3605
3705
|
case "NOT":
|
|
3606
3706
|
case "GROUP":
|
|
3607
|
-
|
|
3707
|
+
addReasons(reasons, whereCompleteInputReasons(where.expr));
|
|
3708
|
+
break;
|
|
3608
3709
|
case "EXISTS":
|
|
3609
|
-
|
|
3710
|
+
addReasons(reasons, selectCompleteInputReasons(where.query));
|
|
3711
|
+
break;
|
|
3610
3712
|
case "NULL_CHECK":
|
|
3611
3713
|
case "BOOLEAN":
|
|
3612
|
-
|
|
3714
|
+
break;
|
|
3613
3715
|
}
|
|
3716
|
+
return reasons;
|
|
3614
3717
|
}
|
|
3615
3718
|
function hasWhereClause(stmt) {
|
|
3616
3719
|
if (!stmt || typeof stmt !== "object") return false;
|
|
@@ -4936,7 +5039,7 @@ function scalarValueLabel(expr) {
|
|
|
4936
5039
|
}
|
|
4937
5040
|
}
|
|
4938
5041
|
function isAggregateSyntheticName(name) {
|
|
4939
|
-
return /^(COUNT|SUM|AVG|MAX|MIN|GROUP_CONCAT)\(/i.test(name);
|
|
5042
|
+
return /^(COUNT|SUM|AVG|MAX|MIN|GROUP_CONCAT|STDDEV_POP|STDDEV_SAMP|VAR_POP|VAR_SAMP|MEDIAN|MODE)\(/i.test(name);
|
|
4940
5043
|
}
|
|
4941
5044
|
|
|
4942
5045
|
// src/core/cteInlining.ts
|
|
@@ -5917,7 +6020,7 @@ function evalArithExpr(expr, row) {
|
|
|
5917
6020
|
return r !== 0 ? l % r : NaN;
|
|
5918
6021
|
}
|
|
5919
6022
|
}
|
|
5920
|
-
function evalScalarValueExpr(expr, row) {
|
|
6023
|
+
function evalScalarValueExpr(expr, row, resolveFieldType, resolveFieldSemantics2) {
|
|
5921
6024
|
switch (expr.type) {
|
|
5922
6025
|
case "STRING":
|
|
5923
6026
|
return expr.value;
|
|
@@ -5928,19 +6031,19 @@ function evalScalarValueExpr(expr, row) {
|
|
|
5928
6031
|
case "VARIABLE":
|
|
5929
6032
|
throw new Error(`ArgumentError: unresolved variable @${expr.name} reached scalar evaluator.`);
|
|
5930
6033
|
case "STRING_FUNC":
|
|
5931
|
-
return evalStringFunc(expr, row);
|
|
6034
|
+
return evalStringFunc(expr, row, resolveFieldType, resolveFieldSemantics2);
|
|
5932
6035
|
case "CASE_WHEN":
|
|
5933
|
-
return evalCaseWhen(expr, row);
|
|
6036
|
+
return evalCaseWhen(expr, row, resolveFieldType, resolveFieldSemantics2);
|
|
5934
6037
|
case "CONCAT_OP": {
|
|
5935
6038
|
return evalStringFunc({
|
|
5936
6039
|
type: "STRING_FUNC",
|
|
5937
6040
|
func: "CONCAT",
|
|
5938
6041
|
args: [expr.left, expr.right]
|
|
5939
|
-
}, row);
|
|
6042
|
+
}, row, resolveFieldType, resolveFieldSemantics2);
|
|
5940
6043
|
}
|
|
5941
6044
|
case "SCALAR_ARITH": {
|
|
5942
|
-
const left = Number(evalScalarValueExpr(expr.left, row));
|
|
5943
|
-
const right = Number(evalScalarValueExpr(expr.right, row));
|
|
6045
|
+
const left = Number(evalScalarValueExpr(expr.left, row, resolveFieldType, resolveFieldSemantics2));
|
|
6046
|
+
const right = Number(evalScalarValueExpr(expr.right, row, resolveFieldType, resolveFieldSemantics2));
|
|
5944
6047
|
switch (expr.op) {
|
|
5945
6048
|
case "+":
|
|
5946
6049
|
return left + right;
|
|
@@ -6105,8 +6208,8 @@ function replaceNthMatch(input, globalRe, replacement, n) {
|
|
|
6105
6208
|
return expandRegexpReplacement(replacement, match, captures, namedGroups);
|
|
6106
6209
|
});
|
|
6107
6210
|
}
|
|
6108
|
-
function evalStringFunc(expr, row) {
|
|
6109
|
-
const args = expr.args.map((a) => evalStringFuncArg(a, row));
|
|
6211
|
+
function evalStringFunc(expr, row, resolveFieldType, resolveFieldSemantics2) {
|
|
6212
|
+
const args = expr.args.map((a) => evalStringFuncArg(a, row, resolveFieldType, resolveFieldSemantics2));
|
|
6110
6213
|
switch (expr.func) {
|
|
6111
6214
|
case "UPPER":
|
|
6112
6215
|
return (args[0] ?? "").toUpperCase();
|
|
@@ -6239,6 +6342,15 @@ function evalStringFunc(expr, row) {
|
|
|
6239
6342
|
const d = args[0] ?? "";
|
|
6240
6343
|
return d.length >= 10 ? String(parseInt(d.slice(8, 10), 10)) : "";
|
|
6241
6344
|
}
|
|
6345
|
+
case "DAYOFWEEK":
|
|
6346
|
+
assertArity(expr.func, args, 1, 1);
|
|
6347
|
+
return isValidYmd(args[0]) ? String(dayOfWeekIndex(args[0]) + 1) : "";
|
|
6348
|
+
case "QUARTER":
|
|
6349
|
+
assertArity(expr.func, args, 1, 1);
|
|
6350
|
+
return isValidYmd(args[0]) ? String(Math.ceil(Number(args[0].slice(5, 7)) / 3)) : "";
|
|
6351
|
+
case "WEEK":
|
|
6352
|
+
assertArity(expr.func, args, 1, 1);
|
|
6353
|
+
return isValidYmd(args[0]) ? String(isoWeekNumber(args[0])) : "";
|
|
6242
6354
|
case "DATE_FORMAT":
|
|
6243
6355
|
return applyDateFormat(args[0] ?? "", args[1] ?? "");
|
|
6244
6356
|
case "DATEDIFF":
|
|
@@ -6285,10 +6397,78 @@ function parseDateParts(s) {
|
|
|
6285
6397
|
sec: s.length >= 19 ? s.slice(17, 19) : "00"
|
|
6286
6398
|
};
|
|
6287
6399
|
}
|
|
6400
|
+
function ymdUtcDate(dateStr) {
|
|
6401
|
+
const date = /* @__PURE__ */ new Date(0);
|
|
6402
|
+
date.setUTCHours(0, 0, 0, 0);
|
|
6403
|
+
date.setUTCFullYear(
|
|
6404
|
+
Number(dateStr.slice(0, 4)),
|
|
6405
|
+
Number(dateStr.slice(5, 7)) - 1,
|
|
6406
|
+
Number(dateStr.slice(8, 10))
|
|
6407
|
+
);
|
|
6408
|
+
return date;
|
|
6409
|
+
}
|
|
6410
|
+
function isValidYmd(dateStr) {
|
|
6411
|
+
const ymd = dateStr.slice(0, 10);
|
|
6412
|
+
if (!/^\d{4}-\d{2}-\d{2}$/.test(ymd)) return false;
|
|
6413
|
+
const date = ymdUtcDate(ymd);
|
|
6414
|
+
return date.getUTCFullYear() === Number(ymd.slice(0, 4)) && date.getUTCMonth() + 1 === Number(ymd.slice(5, 7)) && date.getUTCDate() === Number(ymd.slice(8, 10));
|
|
6415
|
+
}
|
|
6416
|
+
function dayOfWeekIndex(dateStr) {
|
|
6417
|
+
return ymdUtcDate(dateStr).getUTCDay();
|
|
6418
|
+
}
|
|
6419
|
+
function isoWeekThursday(dateStr) {
|
|
6420
|
+
const date = ymdUtcDate(dateStr);
|
|
6421
|
+
const isoDay = date.getUTCDay() || 7;
|
|
6422
|
+
date.setUTCDate(date.getUTCDate() + 4 - isoDay);
|
|
6423
|
+
return date;
|
|
6424
|
+
}
|
|
6425
|
+
function isoWeekYear(dateStr) {
|
|
6426
|
+
return isoWeekThursday(dateStr).getUTCFullYear();
|
|
6427
|
+
}
|
|
6428
|
+
function isoWeekNumber(dateStr) {
|
|
6429
|
+
const thursday = isoWeekThursday(dateStr);
|
|
6430
|
+
const year = thursday.getUTCFullYear();
|
|
6431
|
+
const jan4 = ymdUtcDate(`${String(year).padStart(4, "0")}-01-04`);
|
|
6432
|
+
const jan4IsoDay = jan4.getUTCDay() || 7;
|
|
6433
|
+
jan4.setUTCDate(jan4.getUTCDate() + 4 - jan4IsoDay);
|
|
6434
|
+
return 1 + Math.round((thursday.getTime() - jan4.getTime()) / (7 * 864e5));
|
|
6435
|
+
}
|
|
6288
6436
|
function applyDateFormat(dateStr, pattern) {
|
|
6289
6437
|
if (!dateStr || dateStr.length < 10) return "";
|
|
6290
6438
|
const { y, mo, d, h, mi, sec } = parseDateParts(dateStr);
|
|
6291
|
-
|
|
6439
|
+
const validYmd = isValidYmd(dateStr);
|
|
6440
|
+
return pattern.replace(/%[YymcdeHiswavG]/g, (specifier) => {
|
|
6441
|
+
switch (specifier) {
|
|
6442
|
+
case "%Y":
|
|
6443
|
+
return y;
|
|
6444
|
+
case "%y":
|
|
6445
|
+
return y.slice(2);
|
|
6446
|
+
case "%m":
|
|
6447
|
+
return mo;
|
|
6448
|
+
case "%c":
|
|
6449
|
+
return String(parseInt(mo, 10));
|
|
6450
|
+
case "%d":
|
|
6451
|
+
return d;
|
|
6452
|
+
case "%e":
|
|
6453
|
+
return String(parseInt(d, 10));
|
|
6454
|
+
case "%H":
|
|
6455
|
+
return h;
|
|
6456
|
+
case "%i":
|
|
6457
|
+
return mi;
|
|
6458
|
+
case "%s":
|
|
6459
|
+
return sec;
|
|
6460
|
+
case "%w":
|
|
6461
|
+
return validYmd ? String(dayOfWeekIndex(dateStr)) : "";
|
|
6462
|
+
case "%a":
|
|
6463
|
+
return validYmd ? ["\u65E5", "\u6708", "\u706B", "\u6C34", "\u6728", "\u91D1", "\u571F"][dayOfWeekIndex(dateStr)] : "";
|
|
6464
|
+
case "%v":
|
|
6465
|
+
return validYmd ? String(isoWeekNumber(dateStr)).padStart(2, "0") : "";
|
|
6466
|
+
case "%G":
|
|
6467
|
+
return validYmd ? String(isoWeekYear(dateStr)).padStart(4, "0") : "";
|
|
6468
|
+
default:
|
|
6469
|
+
return specifier;
|
|
6470
|
+
}
|
|
6471
|
+
});
|
|
6292
6472
|
}
|
|
6293
6473
|
function applyDateDiff(date1, date2) {
|
|
6294
6474
|
if (date1.length < 10 || date2.length < 10) return "0";
|
|
@@ -6357,10 +6537,10 @@ function formatWithComma(num, digits) {
|
|
|
6357
6537
|
const intFmt = intStr.replace(/\B(?=(\d{3})+(?!\d))/g, ",");
|
|
6358
6538
|
return decStr ? `${intFmt}.${decStr}` : intFmt;
|
|
6359
6539
|
}
|
|
6360
|
-
function evalStringFuncArg(arg, row) {
|
|
6540
|
+
function evalStringFuncArg(arg, row, resolveFieldType, resolveFieldSemantics2) {
|
|
6361
6541
|
if (arg.type === "AGG_REF" || arg.type === "AGG_ARITH") return "";
|
|
6362
6542
|
if (arg.type === "NUMBER") return numberLiteralText(arg);
|
|
6363
|
-
return String(evalScalarValueExpr(arg, row));
|
|
6543
|
+
return String(evalScalarValueExpr(arg, row, resolveFieldType, resolveFieldSemantics2));
|
|
6364
6544
|
}
|
|
6365
6545
|
function resolveFieldRef(row, field) {
|
|
6366
6546
|
const direct = row[field];
|
|
@@ -6447,7 +6627,10 @@ var NUMERIC_STRING_FUNCTIONS = /* @__PURE__ */ new Set([
|
|
|
6447
6627
|
"ABS",
|
|
6448
6628
|
"MOD",
|
|
6449
6629
|
"POWER",
|
|
6450
|
-
"SQRT"
|
|
6630
|
+
"SQRT",
|
|
6631
|
+
"DAYOFWEEK",
|
|
6632
|
+
"QUARTER",
|
|
6633
|
+
"WEEK"
|
|
6451
6634
|
]);
|
|
6452
6635
|
function semanticsForLeft(left, fieldType, resolveSemantics) {
|
|
6453
6636
|
if (left.type === "FIELD") {
|
|
@@ -6577,15 +6760,15 @@ function resolveValue(value, row, resolveFieldType, resolveFieldSemantics2) {
|
|
|
6577
6760
|
function evalCaseWhen(expr, row, resolveFieldType, resolveFieldSemantics2) {
|
|
6578
6761
|
for (const branch of expr.branches) {
|
|
6579
6762
|
if (evalWhere(branch.condition, row, resolveFieldType, void 0, resolveFieldSemantics2)) {
|
|
6580
|
-
return evalCaseResult(branch.result, row);
|
|
6763
|
+
return evalCaseResult(branch.result, row, resolveFieldType, resolveFieldSemantics2);
|
|
6581
6764
|
}
|
|
6582
6765
|
}
|
|
6583
6766
|
if (expr.elseResult !== null) {
|
|
6584
|
-
return evalCaseResult(expr.elseResult, row);
|
|
6767
|
+
return evalCaseResult(expr.elseResult, row, resolveFieldType, resolveFieldSemantics2);
|
|
6585
6768
|
}
|
|
6586
6769
|
return "";
|
|
6587
6770
|
}
|
|
6588
|
-
function evalCaseResult(result, row) {
|
|
6771
|
+
function evalCaseResult(result, row, resolveFieldType, resolveFieldSemantics2) {
|
|
6589
6772
|
if (result.type === "ARRAY") return result.elements.map((e) => e.value).join(",");
|
|
6590
6773
|
if (result.type === "FIELD_REF") {
|
|
6591
6774
|
return row[result.field] ?? "";
|
|
@@ -6593,7 +6776,7 @@ function evalCaseResult(result, row) {
|
|
|
6593
6776
|
if (result.type === "ARITH") {
|
|
6594
6777
|
return String(evalArithExpr(result, row));
|
|
6595
6778
|
}
|
|
6596
|
-
return String(evalScalarValueExpr(result, row));
|
|
6779
|
+
return String(evalScalarValueExpr(result, row, resolveFieldType, resolveFieldSemantics2));
|
|
6597
6780
|
}
|
|
6598
6781
|
function resolveKintoneFunc(name) {
|
|
6599
6782
|
const now = /* @__PURE__ */ new Date();
|
|
@@ -6666,7 +6849,7 @@ function collectRefs2(root) {
|
|
|
6666
6849
|
for (const value of Object.values(obj)) visit(value);
|
|
6667
6850
|
};
|
|
6668
6851
|
const add = (tableAlias, field) => {
|
|
6669
|
-
if (/^(COUNT|SUM|AVG|MIN|MAX|GROUP_CONCAT)\(/i.test(field)) {
|
|
6852
|
+
if (/^(COUNT|SUM|AVG|MIN|MAX|GROUP_CONCAT|STDDEV_POP|STDDEV_SAMP|VAR_POP|VAR_SAMP|MEDIAN|MODE)\(/i.test(field)) {
|
|
6670
6853
|
throw customCheckParseError("CHECK \u306B\u96C6\u7D04\u95A2\u6570\u306F\u4F7F\u7528\u3067\u304D\u307E\u305B\u3093");
|
|
6671
6854
|
}
|
|
6672
6855
|
const key = `${tableAlias ?? ""}\0${field}`;
|
|
@@ -9482,6 +9665,9 @@ var REST_LIMIT_MAX = 500;
|
|
|
9482
9665
|
function fieldSemantics(item, semantics) {
|
|
9483
9666
|
return item.key.type === "FIELD_NAME" ? semantics.get(item.key.name) : void 0;
|
|
9484
9667
|
}
|
|
9668
|
+
function hasSelectOutputAlias(stmt, name) {
|
|
9669
|
+
return stmt.columns.some((column) => "alias" in column && column.alias === name);
|
|
9670
|
+
}
|
|
9485
9671
|
function planCanonicalOrder(input) {
|
|
9486
9672
|
const { stmt } = input;
|
|
9487
9673
|
const reasons = [];
|
|
@@ -9509,7 +9695,7 @@ function planCanonicalOrder(input) {
|
|
|
9509
9695
|
throw new Error(`ArgumentError: ORDER BY key has no canonical comparison contract (reason=${reason}).`);
|
|
9510
9696
|
}
|
|
9511
9697
|
const allRestEquivalent = stmt.orderBy.length > 0 && windowOrderBy.length === 0 && stmt.orderBy.every(
|
|
9512
|
-
(item) => item.key.type === "FIELD_NAME" && item.key.name === "$id"
|
|
9698
|
+
(item) => item.key.type === "FIELD_NAME" && item.key.name === "$id" && !hasSelectOutputAlias(stmt, item.key.name)
|
|
9513
9699
|
);
|
|
9514
9700
|
if (!allRestEquivalent) reasons.push("ORDER_KEY_NOT_REST_EQUIVALENT");
|
|
9515
9701
|
if (input.whereCapability !== "EXACT_PUSHDOWN") reasons.push("WHERE_NOT_EXACT");
|
|
@@ -9558,6 +9744,9 @@ var KORDER_NATIVE_FIELD_TYPES = /* @__PURE__ */ new Set([
|
|
|
9558
9744
|
"CREATOR",
|
|
9559
9745
|
"MODIFIER"
|
|
9560
9746
|
]);
|
|
9747
|
+
function hasSelectOutputAlias2(stmt, name) {
|
|
9748
|
+
return stmt.columns.some((column) => "alias" in column && column.alias === name);
|
|
9749
|
+
}
|
|
9561
9750
|
function planKorder(input) {
|
|
9562
9751
|
const { stmt } = input;
|
|
9563
9752
|
const reasons = [];
|
|
@@ -9579,6 +9768,10 @@ function planKorder(input) {
|
|
|
9579
9768
|
reasons.push(`KORDER_KEY_UNRESOLVED(field=${name})`);
|
|
9580
9769
|
continue;
|
|
9581
9770
|
}
|
|
9771
|
+
if (hasSelectOutputAlias2(stmt, name)) {
|
|
9772
|
+
reasons.push(`KORDER_KEY_NOT_DIRECT_FIELD(field=${name})`);
|
|
9773
|
+
continue;
|
|
9774
|
+
}
|
|
9582
9775
|
if (name === "$id") continue;
|
|
9583
9776
|
if (!semantics.source || semantics.source.fieldCode !== name) {
|
|
9584
9777
|
reasons.push(`KORDER_KEY_NOT_DIRECT_FIELD(field=${name})`);
|
|
@@ -9850,26 +10043,81 @@ function evalAggregate(func, distinct, arg, separator, rows, resolveAggSortKind)
|
|
|
9850
10043
|
}
|
|
9851
10044
|
strValues.push(strVal);
|
|
9852
10045
|
}
|
|
9853
|
-
const
|
|
10046
|
+
const statistical = func === "STDDEV_POP" || func === "STDDEV_SAMP" || func === "VAR_POP" || func === "VAR_SAMP" || func === "MEDIAN";
|
|
10047
|
+
const numericValues = statistical ? strValues.map((value) => {
|
|
10048
|
+
const numeric = Number(value);
|
|
10049
|
+
if (!Number.isFinite(numeric)) {
|
|
10050
|
+
throw new Error(`ArgumentError: ${func} \u306E\u5F15\u6570\u306B\u975E\u6570\u5024\u307E\u305F\u306F\u975E\u6709\u9650\u306E\u5024\u304C\u3042\u308A\u307E\u3059: ${value}`);
|
|
10051
|
+
}
|
|
10052
|
+
return numeric;
|
|
10053
|
+
}) : null;
|
|
10054
|
+
const eff = distinct ? statistical ? [...new Set(numericValues)] : [...new Set(strValues)] : statistical ? numericValues : strValues;
|
|
9854
10055
|
if (func === "COUNT") return eff.length;
|
|
9855
10056
|
if (func === "GROUP_CONCAT") return eff.join(separator ?? ",");
|
|
9856
|
-
const comparison = (func === "MIN" || func === "MAX") && arg.type === "FIELD_REF" ? resolveAggSortKind?.(toAggregateFieldRef(arg.field)) : void 0;
|
|
10057
|
+
const comparison = (func === "MIN" || func === "MAX" || func === "MODE") && arg.type === "FIELD_REF" ? resolveAggSortKind?.(toAggregateFieldRef(arg.field)) : void 0;
|
|
10058
|
+
const semantics = typeof comparison === "string" ? syntheticSemantics(comparison) : comparison ?? (arg.type === "FIELD_REF" ? syntheticSemantics("string") : syntheticSemantics("number"));
|
|
10059
|
+
if (func === "MODE") {
|
|
10060
|
+
if (strValues.length === 0) return "";
|
|
10061
|
+
const frequencies = /* @__PURE__ */ new Map();
|
|
10062
|
+
for (const value of strValues) frequencies.set(value, (frequencies.get(value) ?? 0) + 1);
|
|
10063
|
+
let result = "";
|
|
10064
|
+
let maxFrequency = 0;
|
|
10065
|
+
for (const [candidate, frequency] of frequencies) {
|
|
10066
|
+
if (frequency > maxFrequency) {
|
|
10067
|
+
result = candidate;
|
|
10068
|
+
maxFrequency = frequency;
|
|
10069
|
+
continue;
|
|
10070
|
+
}
|
|
10071
|
+
if (frequency !== maxFrequency) continue;
|
|
10072
|
+
const canonical = compareCanonicalValues(candidate, result, semantics);
|
|
10073
|
+
if (canonical < 0 || canonical === 0 && compareCodePointStrings(candidate, result) < 0) {
|
|
10074
|
+
result = candidate;
|
|
10075
|
+
}
|
|
10076
|
+
}
|
|
10077
|
+
return result;
|
|
10078
|
+
}
|
|
9857
10079
|
if (func === "MIN" || func === "MAX") {
|
|
9858
|
-
|
|
9859
|
-
|
|
9860
|
-
let result =
|
|
9861
|
-
for (const candidate of
|
|
10080
|
+
const comparableValues = eff;
|
|
10081
|
+
if (comparableValues.length === 0) return 0;
|
|
10082
|
+
let result = comparableValues[0];
|
|
10083
|
+
for (const candidate of comparableValues.slice(1)) {
|
|
9862
10084
|
const cmp = compareCanonicalValues(candidate, result, semantics);
|
|
9863
10085
|
if (func === "MAX" && cmp > 0 || func === "MIN" && cmp < 0) result = candidate;
|
|
9864
10086
|
}
|
|
9865
10087
|
return result;
|
|
9866
10088
|
}
|
|
9867
|
-
const nums = eff.map(Number);
|
|
10089
|
+
const nums = statistical ? eff : eff.map(Number);
|
|
9868
10090
|
switch (func) {
|
|
9869
10091
|
case "SUM":
|
|
9870
10092
|
return nums.reduce((a, b) => a + b, 0);
|
|
9871
10093
|
case "AVG":
|
|
9872
10094
|
return nums.length === 0 ? 0 : nums.reduce((a, b) => a + b, 0) / nums.length;
|
|
10095
|
+
case "MEDIAN": {
|
|
10096
|
+
if (nums.length === 0) return "";
|
|
10097
|
+
const sorted = [...nums].sort((a, b) => a - b);
|
|
10098
|
+
const middle = Math.floor(sorted.length / 2);
|
|
10099
|
+
return sorted.length % 2 === 1 ? sorted[middle] : (sorted[middle - 1] + sorted[middle]) / 2;
|
|
10100
|
+
}
|
|
10101
|
+
case "VAR_POP":
|
|
10102
|
+
case "VAR_SAMP":
|
|
10103
|
+
case "STDDEV_POP":
|
|
10104
|
+
case "STDDEV_SAMP": {
|
|
10105
|
+
const sample = func === "VAR_SAMP" || func === "STDDEV_SAMP";
|
|
10106
|
+
if (nums.length === 0 || sample && nums.length < 2) return "";
|
|
10107
|
+
const origin = nums[0];
|
|
10108
|
+
let count = 0;
|
|
10109
|
+
let mean = 0;
|
|
10110
|
+
let m2 = 0;
|
|
10111
|
+
for (const rawValue of nums) {
|
|
10112
|
+
const value = rawValue - origin;
|
|
10113
|
+
count++;
|
|
10114
|
+
const delta = value - mean;
|
|
10115
|
+
mean += delta / count;
|
|
10116
|
+
m2 += delta * (value - mean);
|
|
10117
|
+
}
|
|
10118
|
+
const variance = Math.max(0, m2 / (sample ? count - 1 : count));
|
|
10119
|
+
return func === "STDDEV_POP" || func === "STDDEV_SAMP" ? Math.sqrt(variance) : variance;
|
|
10120
|
+
}
|
|
9873
10121
|
}
|
|
9874
10122
|
}
|
|
9875
10123
|
function toAggregateFieldRef(field) {
|
|
@@ -9961,11 +10209,11 @@ function buildDistinctKeyBuilder(rows, columns) {
|
|
|
9961
10209
|
return JSON.stringify(values);
|
|
9962
10210
|
};
|
|
9963
10211
|
}
|
|
9964
|
-
function applyOrderBy(rows, orderBy, optionOrders, sortKinds, fieldSemantics2) {
|
|
10212
|
+
function applyOrderBy(rows, orderBy, optionOrders, sortKinds, fieldSemantics2, aliasEvaluator) {
|
|
9965
10213
|
if (orderBy.length === 0) return rows;
|
|
9966
|
-
return sortDecoratedRows(rows, orderBy, optionOrders, sortKinds, fieldSemantics2).rows.map((item) => item.row);
|
|
10214
|
+
return sortDecoratedRows(rows, orderBy, optionOrders, sortKinds, fieldSemantics2, aliasEvaluator).rows.map((item) => item.row);
|
|
9967
10215
|
}
|
|
9968
|
-
function sortDecoratedRows(rows, orderBy, optionOrders, sortKinds, fieldSemantics2) {
|
|
10216
|
+
function sortDecoratedRows(rows, orderBy, optionOrders, sortKinds, fieldSemantics2, aliasEvaluator) {
|
|
9969
10217
|
const keyMeta = orderBy.map(({ key }) => {
|
|
9970
10218
|
if (key.type === "ARITH_KEY") return { semantics: syntheticSemantics("number") };
|
|
9971
10219
|
if (key.type === "FUNC_KEY") {
|
|
@@ -9990,7 +10238,7 @@ function sortDecoratedRows(rows, orderBy, optionOrders, sortKinds, fieldSemantic
|
|
|
9990
10238
|
const decorated = rows.map((row) => ({
|
|
9991
10239
|
row,
|
|
9992
10240
|
keys: orderBy.map(({ key }, i) => {
|
|
9993
|
-
const s = evalOrderKey(key, row);
|
|
10241
|
+
const s = evalOrderKey(key, row, aliasEvaluator);
|
|
9994
10242
|
return { s };
|
|
9995
10243
|
})
|
|
9996
10244
|
}));
|
|
@@ -10023,18 +10271,71 @@ var NUMERIC_ORDER_FUNCTIONS = /* @__PURE__ */ new Set([
|
|
|
10023
10271
|
"ABS",
|
|
10024
10272
|
"MOD",
|
|
10025
10273
|
"POWER",
|
|
10026
|
-
"SQRT"
|
|
10274
|
+
"SQRT",
|
|
10275
|
+
"DAYOFWEEK",
|
|
10276
|
+
"QUARTER",
|
|
10277
|
+
"WEEK"
|
|
10027
10278
|
]);
|
|
10028
|
-
function evalOrderKey(key, row) {
|
|
10279
|
+
function evalOrderKey(key, row, aliasEvaluator) {
|
|
10029
10280
|
switch (key.type) {
|
|
10030
10281
|
case "FIELD_NAME":
|
|
10031
|
-
return row[key.name] ?? "";
|
|
10282
|
+
return aliasEvaluator?.(key.name, row) ?? row[key.name] ?? "";
|
|
10032
10283
|
case "ARITH_KEY":
|
|
10033
10284
|
return String(evalArithExpr(key.expr, row));
|
|
10034
10285
|
case "FUNC_KEY":
|
|
10035
10286
|
return evalStringFunc(key.expr, row);
|
|
10036
10287
|
}
|
|
10037
10288
|
}
|
|
10289
|
+
function buildOrderByAliasEvaluator(columns, scalarCache, resolveFieldType, resolveFieldSemantics2) {
|
|
10290
|
+
const evaluators = /* @__PURE__ */ new Map();
|
|
10291
|
+
for (const [columnIndex, column] of columns.entries()) {
|
|
10292
|
+
if (!("alias" in column) || column.alias === null) continue;
|
|
10293
|
+
const alias = column.alias;
|
|
10294
|
+
switch (column.type) {
|
|
10295
|
+
case "FIELD":
|
|
10296
|
+
evaluators.set(alias, (row) => resolveFieldRef(row, column.field));
|
|
10297
|
+
break;
|
|
10298
|
+
case "LITERAL_COL":
|
|
10299
|
+
evaluators.set(alias, () => column.value);
|
|
10300
|
+
break;
|
|
10301
|
+
case "AGGREGATE": {
|
|
10302
|
+
const source = aggregateSyntheticName2(column.func, column.distinct, column.arg);
|
|
10303
|
+
evaluators.set(alias, (row) => row[alias] ?? row[source] ?? "0");
|
|
10304
|
+
break;
|
|
10305
|
+
}
|
|
10306
|
+
case "ARITH_AGG_COL": {
|
|
10307
|
+
const source = aggArithDefaultKey(column.expr);
|
|
10308
|
+
evaluators.set(alias, (row) => row[alias] ?? row[source] ?? "0");
|
|
10309
|
+
break;
|
|
10310
|
+
}
|
|
10311
|
+
case "WINDOW_COL":
|
|
10312
|
+
evaluators.set(alias, (row) => row[alias] ?? "");
|
|
10313
|
+
break;
|
|
10314
|
+
case "ARITH_COL":
|
|
10315
|
+
evaluators.set(alias, (row) => String(evalArithExpr(column.expr, row)));
|
|
10316
|
+
break;
|
|
10317
|
+
case "STRFUNC_COL": {
|
|
10318
|
+
const source = stringFuncDefaultKey(column.expr);
|
|
10319
|
+
evaluators.set(alias, (row) => hasAggregateInStringFuncExpr2(column.expr) ? row[alias] ?? row[source] ?? evalStringFunc(column.expr, row, resolveFieldType, resolveFieldSemantics2) : evalStringFunc(column.expr, row, resolveFieldType, resolveFieldSemantics2));
|
|
10320
|
+
break;
|
|
10321
|
+
}
|
|
10322
|
+
case "CASE_COL":
|
|
10323
|
+
evaluators.set(alias, (row) => evalCaseWhen(column.expr, row, resolveFieldType, resolveFieldSemantics2));
|
|
10324
|
+
break;
|
|
10325
|
+
case "SCALAR_VALUE_COL": {
|
|
10326
|
+
const source = scalarValueDefaultKey(column.expr);
|
|
10327
|
+
evaluators.set(alias, (row) => scalarValueHasAggregate2(column.expr) ? row[alias] ?? row[source] ?? "" : String(evalScalarValueExpr(column.expr, row, resolveFieldType, resolveFieldSemantics2)));
|
|
10328
|
+
break;
|
|
10329
|
+
}
|
|
10330
|
+
case "SCALAR_SUBQUERY_COL":
|
|
10331
|
+
evaluators.set(alias, () => scalarCache?.get(columnIndex) ?? "");
|
|
10332
|
+
break;
|
|
10333
|
+
case "VARIABLE_COL":
|
|
10334
|
+
break;
|
|
10335
|
+
}
|
|
10336
|
+
}
|
|
10337
|
+
return (name, row) => evaluators.get(name)?.(row);
|
|
10338
|
+
}
|
|
10038
10339
|
function applyWindow(rows, columns, optionOrders, sortKinds, fieldSemantics2) {
|
|
10039
10340
|
const windows = columns.filter((column) => column.type === "WINDOW_COL");
|
|
10040
10341
|
if (rows.length === 0 || windows.length === 0) return rows;
|
|
@@ -10152,9 +10453,9 @@ function project(rows, columns, scalarCache, resolveFieldType, sourceColumns, re
|
|
|
10152
10453
|
const key = outputKeys?.[colIdx] ?? col.alias ?? stringFuncDefaultKey(col.expr);
|
|
10153
10454
|
if (hasAggregateInStringFuncExpr2(col.expr)) {
|
|
10154
10455
|
const srcKey = stringFuncDefaultKey(col.expr);
|
|
10155
|
-
out[key] = row[col.alias ?? srcKey] ?? row[srcKey] ?? evalStringFunc(col.expr, row);
|
|
10456
|
+
out[key] = row[col.alias ?? srcKey] ?? row[srcKey] ?? evalStringFunc(col.expr, row, resolveFieldType, resolveFieldSemantics2);
|
|
10156
10457
|
} else {
|
|
10157
|
-
out[key] = evalStringFunc(col.expr, row);
|
|
10458
|
+
out[key] = evalStringFunc(col.expr, row, resolveFieldType, resolveFieldSemantics2);
|
|
10158
10459
|
}
|
|
10159
10460
|
if (outputKeys === null && rowIdx === 0) orderedKeys.push(key);
|
|
10160
10461
|
break;
|
|
@@ -10162,7 +10463,7 @@ function project(rows, columns, scalarCache, resolveFieldType, sourceColumns, re
|
|
|
10162
10463
|
case "SCALAR_VALUE_COL": {
|
|
10163
10464
|
const key = outputKeys?.[colIdx] ?? col.alias ?? scalarValueDefaultKey(col.expr);
|
|
10164
10465
|
const srcKey = scalarValueDefaultKey(col.expr);
|
|
10165
|
-
out[key] = scalarValueHasAggregate2(col.expr) ? row[col.alias ?? srcKey] ?? row[srcKey] ?? "" : String(evalScalarValueExpr(col.expr, row));
|
|
10466
|
+
out[key] = scalarValueHasAggregate2(col.expr) ? row[col.alias ?? srcKey] ?? row[srcKey] ?? "" : String(evalScalarValueExpr(col.expr, row, resolveFieldType, resolveFieldSemantics2));
|
|
10166
10467
|
if (outputKeys === null && rowIdx === 0) orderedKeys.push(key);
|
|
10167
10468
|
break;
|
|
10168
10469
|
}
|
|
@@ -10381,7 +10682,7 @@ function deriveOutputOrderSemantics(columns) {
|
|
|
10381
10682
|
if (column.type === "ARITH_COL" || column.type === "ARITH_AGG_COL" || column.type === "WINDOW_COL") {
|
|
10382
10683
|
result.set(column.alias, syntheticSemantics("number"));
|
|
10383
10684
|
} else if (column.type === "AGGREGATE") {
|
|
10384
|
-
if (column.func === "COUNT" || column.func === "SUM" || column.func === "AVG") {
|
|
10685
|
+
if (column.func === "COUNT" || column.func === "SUM" || column.func === "AVG" || column.func === "STDDEV_POP" || column.func === "STDDEV_SAMP" || column.func === "VAR_POP" || column.func === "VAR_SAMP" || column.func === "MEDIAN") {
|
|
10385
10686
|
result.set(column.alias, syntheticSemantics("number"));
|
|
10386
10687
|
} else if (column.func === "GROUP_CONCAT") {
|
|
10387
10688
|
result.set(column.alias, syntheticSemantics("string"));
|
|
@@ -10447,7 +10748,14 @@ function runFullScan(input) {
|
|
|
10447
10748
|
if (stmt.distinct) {
|
|
10448
10749
|
rows = applyDistinct(rows, stmt.columns);
|
|
10449
10750
|
}
|
|
10450
|
-
rows = applyOrderBy(
|
|
10751
|
+
rows = applyOrderBy(
|
|
10752
|
+
rows,
|
|
10753
|
+
stmt.orderBy,
|
|
10754
|
+
optionOrders,
|
|
10755
|
+
sortKinds,
|
|
10756
|
+
effectiveOrderSemantics,
|
|
10757
|
+
buildOrderByAliasEvaluator(stmt.columns, scalarCache, fieldTypeResolver, fieldSemanticsResolver)
|
|
10758
|
+
);
|
|
10451
10759
|
rows = applyLimit(rows, stmt.limit, stmt.offset);
|
|
10452
10760
|
return project(
|
|
10453
10761
|
rows,
|
|
@@ -12268,7 +12576,17 @@ async function executeBatchStatement(stmt, info, client, options, cacheContext,
|
|
|
12268
12576
|
tempTables
|
|
12269
12577
|
);
|
|
12270
12578
|
const first = resolvedStmt2.expr.query.columns[0];
|
|
12271
|
-
|
|
12579
|
+
let numeric = first?.type === "ARITH_COL" || first?.type === "ARITH_AGG_COL" || first?.type === "WINDOW_COL" || first?.type === "AGGREGATE" && (first.func === "COUNT" || first.func === "SUM" || first.func === "AVG" || first.func === "STDDEV_POP" || first.func === "STDDEV_SAMP" || first.func === "VAR_POP" || first.func === "VAR_SAMP" || first.func === "MEDIAN");
|
|
12580
|
+
if (first?.type === "AGGREGATE" && first.func === "MODE") {
|
|
12581
|
+
const meta = (await inferSelectColumnMeta(
|
|
12582
|
+
resolvedStmt2.expr.query,
|
|
12583
|
+
["__scalar__"],
|
|
12584
|
+
client,
|
|
12585
|
+
cacheContext,
|
|
12586
|
+
tempTables
|
|
12587
|
+
)).get("__scalar__");
|
|
12588
|
+
numeric = meta?.semantics?.compareMode === "number" || meta?.sortKind === "number";
|
|
12589
|
+
}
|
|
12272
12590
|
const numberValue = numeric ? Number(value) : Number.NaN;
|
|
12273
12591
|
variables.set(stmt.name, numeric && Number.isFinite(numberValue) ? { type: "number", value: numberValue, raw: value } : { type: "string", value });
|
|
12274
12592
|
} catch (e) {
|
|
@@ -12803,7 +13121,7 @@ function buildHavingFieldSemanticsResolver(stmt, rowResolver) {
|
|
|
12803
13121
|
else if (column.type === "ARITH_COL" || column.type === "ARITH_AGG_COL" || column.type === "WINDOW_COL") {
|
|
12804
13122
|
semantics = syntheticSemantics("number");
|
|
12805
13123
|
} else if (column.type === "AGGREGATE") {
|
|
12806
|
-
if (column.func === "MIN" || column.func === "MAX") {
|
|
13124
|
+
if (column.func === "MIN" || column.func === "MAX" || column.func === "MODE") {
|
|
12807
13125
|
semantics = column.arg.type === "FIELD_REF" ? rowResolver(aggregateFieldRef(column.arg.field)) : syntheticSemantics("number");
|
|
12808
13126
|
} else {
|
|
12809
13127
|
semantics = column.func === "GROUP_CONCAT" ? syntheticSemantics("string") : syntheticSemantics("number");
|
|
@@ -12886,7 +13204,8 @@ async function executeSelect(stmt, client, options, cacheContext, cteCache, capt
|
|
|
12886
13204
|
client,
|
|
12887
13205
|
cacheContext
|
|
12888
13206
|
);
|
|
12889
|
-
const
|
|
13207
|
+
const completeReasons = orderPlan?.kind === "CANONICAL_REST_TOP_N" || orderPlan?.kind === "KORDER_NATIVE" || orderPlan?.kind === "KORDER_CURSOR" ? completeInputReasons({ ...stmt, orderBy: [] }) : completeInputReasons(stmt);
|
|
13208
|
+
const completeInputRequired = completeReasons.size > 0;
|
|
12890
13209
|
const truncateWasDisabled = completeInputRequired && options.onLimitReached === "truncate";
|
|
12891
13210
|
const effectiveOptions = truncateWasDisabled ? { ...options, onLimitReached: "error" } : options;
|
|
12892
13211
|
try {
|
|
@@ -12906,7 +13225,7 @@ async function executeSelect(stmt, client, options, cacheContext, cteCache, capt
|
|
|
12906
13225
|
} catch (error) {
|
|
12907
13226
|
if (completeInputRequired && error instanceof FetchAllLimitError) {
|
|
12908
13227
|
throw new FetchAllLimitError(
|
|
12909
|
-
|
|
13228
|
+
completeInputErrorPrefix(completeReasons) + (truncateWasDisabled ? "onLimit=truncate\u306F\u4F7F\u7528\u3067\u304D\u307E\u305B\u3093\u3002" : "") + error.message
|
|
12910
13229
|
);
|
|
12911
13230
|
}
|
|
12912
13231
|
throw error;
|
|
@@ -12916,6 +13235,11 @@ async function executeSelect(stmt, client, options, cacheContext, cteCache, capt
|
|
|
12916
13235
|
}
|
|
12917
13236
|
return result;
|
|
12918
13237
|
}
|
|
13238
|
+
function completeInputErrorPrefix(reasons) {
|
|
13239
|
+
const reasonList = [...reasons].join(", ");
|
|
13240
|
+
const subject = reasons.size === 1 && reasons.has("STATISTICAL_AGGREGATE") ? "\u7D71\u8A08\u96C6\u7D04\u306E\u6B63\u3057\u3044\u7D50\u679C" : "ORDER BY\u306E\u6B63\u3057\u3044\u7D50\u679C";
|
|
13241
|
+
return `${subject}\u306B\u306F\u5B8C\u5168\u306A\u5019\u88DC\u96C6\u5408\u304C\u5FC5\u8981\u3067\u3059\u3002complete input reason: ${reasonList}\u3002`;
|
|
13242
|
+
}
|
|
12919
13243
|
function isConstantFalseWhere(where) {
|
|
12920
13244
|
return where?.type === "BOOLEAN" && where.value === false;
|
|
12921
13245
|
}
|
|
@@ -13055,7 +13379,13 @@ async function executeSimpleSelect(stmt, client, options, cacheContext, orderPla
|
|
|
13055
13379
|
stmt.orderBy,
|
|
13056
13380
|
orderMeta.optionOrders,
|
|
13057
13381
|
orderMeta.sortKinds,
|
|
13058
|
-
orderMeta.semantics
|
|
13382
|
+
orderMeta.semantics,
|
|
13383
|
+
buildOrderByAliasEvaluator(
|
|
13384
|
+
stmt.columns,
|
|
13385
|
+
void 0,
|
|
13386
|
+
fieldTypeResolvers.row,
|
|
13387
|
+
projectionSemanticsResolver
|
|
13388
|
+
)
|
|
13059
13389
|
);
|
|
13060
13390
|
rows = applyLimit(rows, stmt.limit, stmt.offset);
|
|
13061
13391
|
}
|
|
@@ -13241,7 +13571,7 @@ function aggregateFieldRef(field) {
|
|
|
13241
13571
|
return dot > 0 ? { type: "FIELD", tableAlias: field.slice(0, dot), field: field.slice(dot + 1) } : { type: "FIELD", tableAlias: null, field };
|
|
13242
13572
|
}
|
|
13243
13573
|
function collectAggregateRef(func, arg, out) {
|
|
13244
|
-
if ((func === "MIN" || func === "MAX") && arg.type === "FIELD_REF" && arg.field) {
|
|
13574
|
+
if ((func === "MIN" || func === "MAX" || func === "MODE") && arg.type === "FIELD_REF" && arg.field) {
|
|
13245
13575
|
out.push(aggregateFieldRef(arg.field));
|
|
13246
13576
|
}
|
|
13247
13577
|
}
|
|
@@ -13454,7 +13784,10 @@ var NUMBER_RETURNING_STRING_FUNCTIONS = /* @__PURE__ */ new Set([
|
|
|
13454
13784
|
"ABS",
|
|
13455
13785
|
"MOD",
|
|
13456
13786
|
"POWER",
|
|
13457
|
-
"SQRT"
|
|
13787
|
+
"SQRT",
|
|
13788
|
+
"DAYOFWEEK",
|
|
13789
|
+
"QUARTER",
|
|
13790
|
+
"WEEK"
|
|
13458
13791
|
]);
|
|
13459
13792
|
function stringFunctionColumnMeta(expr) {
|
|
13460
13793
|
if (expr.func === "CAST") {
|
|
@@ -13495,7 +13828,7 @@ function mergeExpressionColumnMeta(candidates) {
|
|
|
13495
13828
|
}
|
|
13496
13829
|
function selectNeedsSourceColumnMeta(stmt) {
|
|
13497
13830
|
return stmt.columns.some(
|
|
13498
|
-
(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.arg.type === "FIELD_REF"
|
|
13831
|
+
(column) => column.type === "FIELD" || column.type === "WILDCARD" || column.type === "PARENT_WILDCARD" || column.type === "CASE_COL" || column.type === "AGGREGATE" && (column.func === "MIN" || column.func === "MAX" || column.func === "MODE") && column.arg.type === "FIELD_REF"
|
|
13499
13832
|
);
|
|
13500
13833
|
}
|
|
13501
13834
|
async function inferSelectColumnMeta(stmt, outputColumns, client, cacheContext, materializedTables) {
|
|
@@ -13564,11 +13897,13 @@ async function inferSelectColumnMeta(stmt, outputColumns, client, cacheContext,
|
|
|
13564
13897
|
} else if (column.type === "AGGREGATE") {
|
|
13565
13898
|
if (column.func === "GROUP_CONCAT") {
|
|
13566
13899
|
meta = syntheticColumnMeta("string");
|
|
13567
|
-
} else if (column.func === "COUNT" || column.func === "SUM" || column.func === "AVG") {
|
|
13900
|
+
} else if (column.func === "COUNT" || column.func === "SUM" || column.func === "AVG" || column.func === "STDDEV_POP" || column.func === "STDDEV_SAMP" || column.func === "VAR_POP" || column.func === "VAR_SAMP" || column.func === "MEDIAN") {
|
|
13568
13901
|
meta = syntheticColumnMeta("number");
|
|
13569
|
-
} else if ((column.func === "MIN" || column.func === "MAX") && column.arg.type === "FIELD_REF") {
|
|
13902
|
+
} else if ((column.func === "MIN" || column.func === "MAX" || column.func === "MODE") && column.arg.type === "FIELD_REF") {
|
|
13570
13903
|
const source = resolveField2(aggregateFieldRef(column.arg.field));
|
|
13571
13904
|
if (source) meta = source;
|
|
13905
|
+
} else if (column.func === "MODE") {
|
|
13906
|
+
meta = syntheticColumnMeta("number");
|
|
13572
13907
|
}
|
|
13573
13908
|
} else if (column.type === "ARITH_AGG_COL" || column.type === "ARITH_COL") {
|
|
13574
13909
|
meta = syntheticColumnMeta("number");
|
|
@@ -14333,7 +14668,7 @@ async function buildOrderSemanticsForSelect(stmt, client, cacheContext, material
|
|
|
14333
14668
|
if (column.expr.elseResult) candidates.push(caseResultColumnMeta(column.expr.elseResult, resolveField2));
|
|
14334
14669
|
meta = mergeExpressionColumnMeta(candidates);
|
|
14335
14670
|
} else if (column.type === "AGGREGATE") {
|
|
14336
|
-
if (column.func === "MIN" || column.func === "MAX") {
|
|
14671
|
+
if (column.func === "MIN" || column.func === "MAX" || column.func === "MODE") {
|
|
14337
14672
|
meta = column.arg.type === "FIELD_REF" ? resolveField2(aggregateFieldRef(column.arg.field)) : syntheticColumnMeta("number");
|
|
14338
14673
|
} else {
|
|
14339
14674
|
meta = column.func === "GROUP_CONCAT" ? syntheticColumnMeta("string") : syntheticColumnMeta("number");
|
|
@@ -17848,8 +18183,13 @@ function buildSelectPlan(stmt, label, capabilities, orderPlans) {
|
|
|
17848
18183
|
lines.push(` scan rows: ${orderPlan.scanRows}`);
|
|
17849
18184
|
}
|
|
17850
18185
|
}
|
|
17851
|
-
|
|
17852
|
-
|
|
18186
|
+
const explainedStmt = orderPlan && !orderPlan.requiresCompleteInput ? { ...stmt, orderBy: [] } : stmt;
|
|
18187
|
+
const completeReasons = completeInputReasons(explainedStmt);
|
|
18188
|
+
if (orderPlan?.requiresCompleteInput) completeReasons.add("LOCAL_ORDER");
|
|
18189
|
+
if (completeReasons.size > 0) {
|
|
18190
|
+
lines.push(" complete input: required (onLimit=truncate disabled)");
|
|
18191
|
+
lines.push(` complete input reason: ${[...completeReasons].join(", ")}`);
|
|
18192
|
+
lines.push(" onLimit=truncate: disabled");
|
|
17853
18193
|
}
|
|
17854
18194
|
if (mode === "FULL_SCAN" && reasons.length > 0) {
|
|
17855
18195
|
lines.push(` reason: ${reasons.join(", ")}`);
|