@rex0220/kintone-sql-tools 3.12.0 → 3.14.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 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 === "GROUP_CONCAT") {
2130
- throw new ParseError("GROUP_CONCAT(*) \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());
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 === "GROUP_CONCAT") {
2427
- throw new ParseError("GROUP_CONCAT(*) \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());
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
- function requiresCompleteInput(stmt) {
3567
- if (isDmlType(stmt.type)) return true;
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
- return true;
3646
+ reasons.add("VALIDATE");
3647
+ break;
3571
3648
  case "SELECT":
3572
- return selectRequiresCompleteInput(stmt);
3649
+ addReasons(reasons, selectCompleteInputReasons(stmt));
3650
+ break;
3573
3651
  case "UNION":
3574
- return unionRequiresCompleteInput(stmt);
3652
+ addReasons(reasons, unionCompleteInputReasons(stmt));
3653
+ break;
3575
3654
  case "WITH":
3576
- return stmt.ctes.some(
3577
- (cte) => cte.query.type === "SELECT" && selectRequiresCompleteInput(cte.query) || cte.query.type === "UNION" && unionRequiresCompleteInput(cte.query)
3578
- ) || (stmt.query.type === "SELECT" ? selectRequiresCompleteInput(stmt.query) : unionRequiresCompleteInput(stmt.query));
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
- return stmt.query.type === "SELECT" ? selectRequiresCompleteInput(stmt.query) : stmt.query.type === "UNION" ? unionRequiresCompleteInput(stmt.query) : requiresCompleteInput(stmt.query);
3661
+ addReasons(reasons, completeInputReasons(stmt.query));
3662
+ break;
3581
3663
  default:
3582
- return false;
3664
+ break;
3583
3665
  }
3666
+ if (containsStatisticalAggregate(stmt)) reasons.add("STATISTICAL_AGGREGATE");
3667
+ return reasons;
3584
3668
  }
3585
- function unionRequiresCompleteInput(stmt) {
3586
- const left = stmt.left.type === "SELECT" ? selectRequiresCompleteInput(stmt.left) : unionRequiresCompleteInput(stmt.left);
3587
- return left || selectRequiresCompleteInput(stmt.right);
3669
+ function requiresCompleteInput(stmt) {
3670
+ return completeInputReasons(stmt).size > 0;
3588
3671
  }
3589
- function selectRequiresCompleteInput(stmt) {
3590
- if (stmt.orderBy.length > 0) return true;
3591
- if (stmt.columns.some(
3592
- (column) => column.type === "WINDOW_COL" && column.orderBy.length > 0 || column.type === "SCALAR_SUBQUERY_COL" && selectRequiresCompleteInput(column.query) || column.type === "CASE_COL" && column.expr.branches.some(
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 whereRequiresCompleteInput(where) {
3599
- if (where === null) return false;
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
- return (where.right.type === "SUBQUERY_IN_LIST" || where.right.type === "SCALAR_SUBQUERY") && selectRequiresCompleteInput(where.right.query);
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
- return whereRequiresCompleteInput(where.left) || whereRequiresCompleteInput(where.right);
3702
+ addReasons(reasons, whereCompleteInputReasons(where.left));
3703
+ addReasons(reasons, whereCompleteInputReasons(where.right));
3704
+ break;
3605
3705
  case "NOT":
3606
3706
  case "GROUP":
3607
- return whereRequiresCompleteInput(where.expr);
3707
+ addReasons(reasons, whereCompleteInputReasons(where.expr));
3708
+ break;
3608
3709
  case "EXISTS":
3609
- return selectRequiresCompleteInput(where.query);
3710
+ addReasons(reasons, selectCompleteInputReasons(where.query));
3711
+ break;
3610
3712
  case "NULL_CHECK":
3611
3713
  case "BOOLEAN":
3612
- return false;
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
- return pattern.replace(/%Y/g, y).replace(/%y/g, y.slice(2)).replace(/%m/g, mo).replace(/%c/g, String(parseInt(mo, 10))).replace(/%d/g, d).replace(/%e/g, String(parseInt(d, 10))).replace(/%H/g, h).replace(/%i/g, mi).replace(/%s/g, sec);
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 eff = distinct ? [...new Set(strValues)] : strValues;
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
- if (eff.length === 0) return 0;
9859
- const semantics = typeof comparison === "string" ? syntheticSemantics(comparison) : comparison ?? (arg.type === "FIELD_REF" ? syntheticSemantics("string") : syntheticSemantics("number"));
9860
- let result = eff[0];
9861
- for (const candidate of eff.slice(1)) {
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(rows, stmt.orderBy, optionOrders, sortKinds, effectiveOrderSemantics);
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
- const 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");
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 completeInputRequired = orderPlan?.kind === "CANONICAL_REST_TOP_N" || orderPlan?.kind === "KORDER_NATIVE" || orderPlan?.kind === "KORDER_CURSOR" ? requiresCompleteInput({ ...stmt, orderBy: [] }) : requiresCompleteInput(stmt);
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
- "ORDER BY\u306E\u6B63\u3057\u3044\u7D50\u679C\u306B\u306F\u5B8C\u5168\u306A\u5019\u88DC\u96C6\u5408\u304C\u5FC5\u8981\u3067\u3059\u3002" + (truncateWasDisabled ? "onLimit=truncate\u306F\u4F7F\u7528\u3067\u304D\u307E\u305B\u3093\u3002" : "") + error.message
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
- if (orderPlan?.requiresCompleteInput ?? requiresCompleteInput(stmt)) {
17852
- lines.push(" complete input: required (ORDER BY / window ORDER BY; onLimit=truncate disabled)");
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(", ")}`);