@rex0220/kintone-sql-tools 3.58.0 → 3.60.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
@@ -1169,6 +1169,12 @@ var Parser = class {
1169
1169
  if (upper === "DROP") return this.parseDropTempTable();
1170
1170
  if (upper === "DECLARE") return this.parseDeclareVariable();
1171
1171
  if (upper === "VALIDATE") return this.parseValidate();
1172
+ if (upper === "GENERATE_SERIES") {
1173
+ throw new ParseError(
1174
+ "GENERATE_SERIES \u306F WITH \u306E CTE \u672C\u4F53\u306B\u66F8\u3044\u3066\u304F\u3060\u3055\u3044\u3002\u4F8B: WITH s AS (GENERATE_SERIES(1, 5)) SELECT generate_series FROM s",
1175
+ tok
1176
+ );
1177
+ }
1172
1178
  if (upper === "IMPORT") {
1173
1179
  if (!this.capabilities.import) {
1174
1180
  throw new ParseError("IMPORT is not supported (capability is disabled).", tok);
@@ -1928,6 +1934,8 @@ var Parser = class {
1928
1934
  query2 = this.parseShow();
1929
1935
  } else if (inner === "DESCRIBE" /* DESCRIBE */ || inner === "DESC" /* DESC */) {
1930
1936
  query2 = this.parseDescribe();
1937
+ } else if (inner === "IDENT" /* IDENT */ && this.peek().value.toUpperCase() === "GENERATE_SERIES") {
1938
+ query2 = this.parseGenerateSeries();
1931
1939
  } else {
1932
1940
  query2 = this.tryParseUnionChain(this.parseSelect());
1933
1941
  }
@@ -1939,6 +1947,43 @@ var Parser = class {
1939
1947
  this.cteNames.clear();
1940
1948
  return { type: "WITH", ctes, query };
1941
1949
  }
1950
+ parseGenerateSeries() {
1951
+ const name = this.advance();
1952
+ if (name.kind !== "IDENT" /* IDENT */ || name.value.toUpperCase() !== "GENERATE_SERIES") {
1953
+ throw new ParseError("GENERATE_SERIES \u304C\u5FC5\u8981\u3067\u3059", name);
1954
+ }
1955
+ this.expect("(" /* LPAREN */);
1956
+ const args = [];
1957
+ if (this.peek().kind !== ")" /* RPAREN */) {
1958
+ do {
1959
+ const tok = this.peek();
1960
+ if (tok.kind === "STRING" /* STRING */) {
1961
+ this.advance();
1962
+ args.push({ type: "STRING", value: tok.value });
1963
+ continue;
1964
+ }
1965
+ if (tok.kind === "VARIABLE" /* VARIABLE */) {
1966
+ this.advance();
1967
+ args.push({ type: "VARIABLE", name: tok.value.slice(1).toLowerCase() });
1968
+ continue;
1969
+ }
1970
+ let sign = "";
1971
+ if (tok.kind === "+" /* PLUS */ || tok.kind === "-" /* MINUS */) {
1972
+ sign = tok.kind === "-" /* MINUS */ ? "-" : "+";
1973
+ this.advance();
1974
+ }
1975
+ const number = this.peek();
1976
+ if (number.kind !== "NUMBER" /* NUMBER */) {
1977
+ throw new ParseError("GENERATE_SERIES \u306E\u5F15\u6570\u306B\u306F\u6570\u5024\u3001\u6587\u5B57\u5217\u3001\u307E\u305F\u306F\u30D0\u30C3\u30C1\u5909\u6570\u3092\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044", number);
1978
+ }
1979
+ this.advance();
1980
+ args.push(makeNumberLiteral(`${sign}${number.value}`));
1981
+ } while (this.consume("," /* COMMA */));
1982
+ }
1983
+ this.expect(")" /* RPAREN */);
1984
+ const columnAlias = this.consume("AS" /* AS */) ? this.parseIdentifier() : "generate_series";
1985
+ return { type: "GENERATE_SERIES", args, columnAlias };
1986
+ }
1942
1987
  // ----------------------------------------------------------
1943
1988
  // UNION / UNION ALL チェーン
1944
1989
  // ----------------------------------------------------------
@@ -2923,6 +2968,12 @@ var Parser = class {
2923
2968
  // ----------------------------------------------------------
2924
2969
  parseTableRef() {
2925
2970
  const nameTok = this.peek();
2971
+ if (nameTok.kind === "IDENT" /* IDENT */ && nameTok.value.toUpperCase() === "GENERATE_SERIES" && this.peekAt(1).kind === "(" /* LPAREN */) {
2972
+ throw new ParseError(
2973
+ "GENERATE_SERIES \u306F WITH \u306E CTE \u672C\u4F53\u306B\u66F8\u3044\u3066\u304F\u3060\u3055\u3044\u3002\u4F8B: WITH s AS (GENERATE_SERIES(1, 5)) SELECT generate_series FROM s",
2974
+ nameTok
2975
+ );
2976
+ }
2926
2977
  const name = this.parseTableName();
2927
2978
  if (nameTok.kind === "IDENT" /* IDENT */ && name.startsWith("#")) {
2928
2979
  this.tempTableRefs.push(this.prev());
@@ -3136,7 +3187,7 @@ var Parser = class {
3136
3187
  return { type: "BINARY", op: "KLIKE", left: field, right: pattern };
3137
3188
  }
3138
3189
  const op = this.parseCompareOp();
3139
- const right = this.parseWhereSqlValue();
3190
+ const right = this.parseWhereSqlValue(op !== "LIKE");
3140
3191
  return { type: "BINARY", op, left: field, right };
3141
3192
  }
3142
3193
  parseCompareOp() {
@@ -3259,8 +3310,13 @@ var Parser = class {
3259
3310
  return { type: "FIELD", tableAlias: qi.tableAlias, field: qi.field };
3260
3311
  }
3261
3312
  // 右辺の値
3262
- parseWhereSqlValue() {
3313
+ parseWhereSqlValue(allowUnaryPlusNumberLiteral = true) {
3263
3314
  const tok = this.peek();
3315
+ if (allowUnaryPlusNumberLiteral && tok.kind === "+" /* PLUS */) {
3316
+ this.advance();
3317
+ const number = this.expect("NUMBER" /* NUMBER */, "\u5358\u9805 + \u306E\u76F4\u5F8C\u306B\u306F\u6570\u5024\u30EA\u30C6\u30E9\u30EB\u304C\u5FC5\u8981\u3067\u3059");
3318
+ return makeNumberLiteral(`+${number.value}`);
3319
+ }
3264
3320
  if (this.allowRelativeDateFunctions && tok.kind === "IDENT" /* IDENT */ && this.peekAt(1).kind === "(" /* LPAREN */ && isRelativeDateFunctionName(tok.value.toUpperCase())) {
3265
3321
  return this.parseRelativeDateFunction();
3266
3322
  }
@@ -4698,7 +4754,9 @@ function completeInputReasons(stmt) {
4698
4754
  break;
4699
4755
  case "WITH":
4700
4756
  for (const cte of stmt.ctes) {
4701
- addReasons(reasons, completeInputReasons(cte.query));
4757
+ if (cte.query.type !== "GENERATE_SERIES") {
4758
+ addReasons(reasons, completeInputReasons(cte.query));
4759
+ }
4702
4760
  }
4703
4761
  addReasons(reasons, completeInputReasons(stmt.query));
4704
4762
  break;
@@ -7649,11 +7707,231 @@ function assertStringFunctionArity(func, args) {
7649
7707
  }
7650
7708
  }
7651
7709
 
7710
+ // src/core/generateSeries.ts
7711
+ var GENERATE_SERIES_MAX_ROWS = 1e4;
7712
+ var argumentError = (message) => new Error(`ArgumentError: ${message}`);
7713
+ var isVariable = (arg) => arg.type === "VARIABLE";
7714
+ var isResolvedVariable = (arg) => arg?.type === "STRING" && arg.fromVariable === true;
7715
+ function literalValue(arg) {
7716
+ return arg.type === "NUMBER" ? Number(numberLiteralText(arg)) : arg.value;
7717
+ }
7718
+ function dateParts(value) {
7719
+ const match = /^(\d{4})-(\d{2})-(\d{2})$/.exec(value);
7720
+ if (!match) return null;
7721
+ const year = Number(match[1]);
7722
+ const month = Number(match[2]);
7723
+ const day = Number(match[3]);
7724
+ if (year < 1 || year > 9999 || month < 1 || month > 12 || day < 1 || day > 31) return null;
7725
+ const date = /* @__PURE__ */ new Date(0);
7726
+ date.setUTCHours(0, 0, 0, 0);
7727
+ date.setUTCFullYear(year, month - 1, day);
7728
+ return date.getUTCFullYear() === year && date.getUTCMonth() === month - 1 && date.getUTCDate() === day ? { year, month, day } : null;
7729
+ }
7730
+ function dateOrdinal(value) {
7731
+ const parts = dateParts(value);
7732
+ const date = /* @__PURE__ */ new Date(0);
7733
+ date.setUTCHours(0, 0, 0, 0);
7734
+ date.setUTCFullYear(parts.year, parts.month - 1, parts.day);
7735
+ return Math.trunc(date.getTime() / 864e5);
7736
+ }
7737
+ function dateFromOrdinal(ordinal) {
7738
+ const date = new Date(ordinal * 864e5);
7739
+ const year = date.getUTCFullYear();
7740
+ if (year < 1 || year > 9999) {
7741
+ throw argumentError("GENERATE_SERIES \u306E\u65E5\u4ED8\u5F15\u6570\u306B\u306F\u5B9F\u5728\u3059\u308B YYYY-MM-DD \u5F62\u5F0F\u306E DATE \u3092\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044\u3002");
7742
+ }
7743
+ return `${String(year).padStart(4, "0")}-${String(date.getUTCMonth() + 1).padStart(2, "0")}-${String(date.getUTCDate()).padStart(2, "0")}`;
7744
+ }
7745
+ function parseDateStep(value) {
7746
+ const trimmed = value.trim();
7747
+ const match = /^([+-]?\d+)\s+(day|days)$/i.exec(trimmed);
7748
+ if (!match) {
7749
+ if (/^[+-]?\d+\s+\S+$/i.test(trimmed)) {
7750
+ throw argumentError("GENERATE_SERIES \u306E\u65E5\u4ED8 step \u306F day \u307E\u305F\u306F days \u306E\u307F\u5BFE\u5FDC\u3057\u3066\u3044\u307E\u3059\u3002");
7751
+ }
7752
+ throw argumentError("GENERATE_SERIES \u306E step \u304C\u7CFB\u5217\u306E\u578B\u3068\u4E00\u81F4\u3057\u307E\u305B\u3093\u3002\u6574\u6570\u7CFB\u5217\u306B\u306F\u6574\u6570\u3001DATE \u7CFB\u5217\u306B\u306F day \u5358\u4F4D\u3092\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044\u3002");
7753
+ }
7754
+ const step = Number(match[1]);
7755
+ if (!Number.isSafeInteger(step)) {
7756
+ throw argumentError("GENERATE_SERIES \u306E\u6570\u5024\u7CFB\u5217\u306F\u6574\u6570\u306E start\u3001stop\u3001step \u306E\u307F\u3092\u53D7\u3051\u4ED8\u3051\u307E\u3059\u3002");
7757
+ }
7758
+ if (step === 0) throw argumentError("GENERATE_SERIES \u306E\u65E5\u4ED8 step \u306B 0 day \u306F\u6307\u5B9A\u3067\u304D\u307E\u305B\u3093\u3002");
7759
+ return step;
7760
+ }
7761
+ function integerValue(value) {
7762
+ if (typeof value === "number") return Number.isSafeInteger(value) ? value : null;
7763
+ if (!/^[+-]?\d+$/.test(value)) return null;
7764
+ const parsed = Number(value);
7765
+ return Number.isSafeInteger(parsed) ? parsed : null;
7766
+ }
7767
+ function integerNumberLiteral(arg) {
7768
+ const decimal = parseExactDecimal(arg.raw ?? String(arg.value));
7769
+ if (decimal === null || decimal.scale > 0) return null;
7770
+ if (decimal.sign === 0) return 0;
7771
+ const digits = decimal.coefficient.length - decimal.scale;
7772
+ if (digits > 16) return null;
7773
+ const magnitude = `${decimal.coefficient}${"0".repeat(-decimal.scale)}`;
7774
+ if (magnitude.length === 16 && magnitude > "9007199254740991") return null;
7775
+ const value = Number(magnitude) * decimal.sign;
7776
+ return Number.isSafeInteger(value) ? value : null;
7777
+ }
7778
+ function isUnsupportedTemporal(value) {
7779
+ return typeof value === "string" && (/^\d{4}-\d{2}-\d{2}T/.test(value) || /^\d{2}:\d{2}(?::\d{2})?$/.test(value));
7780
+ }
7781
+ function countRows(start, stop, step) {
7782
+ if (start === stop) return 1;
7783
+ if (start < stop && step < 0 || start > stop && step > 0) return 0;
7784
+ const distance = step > 0 ? BigInt(stop) - BigInt(start) : BigInt(start) - BigInt(stop);
7785
+ return Number(distance / BigInt(Math.abs(step)) + 1n);
7786
+ }
7787
+ function planResolved(stmt) {
7788
+ if (stmt.args.length < 2 || stmt.args.length > 3) {
7789
+ throw argumentError("GENERATE_SERIES \u306F start\u3001stop \u3068\u7701\u7565\u53EF\u80FD\u306A step \u306E2\u500B\u307E\u305F\u306F3\u500B\u306E\u5F15\u6570\u3092\u53D7\u3051\u4ED8\u3051\u307E\u3059\u3002");
7790
+ }
7791
+ const values = stmt.args.map((arg) => literalValue(arg));
7792
+ ["start", "stop", "step"].forEach((name, index) => {
7793
+ if (values[index] === "") throw argumentError(`GENERATE_SERIES \u306E ${name} \u306B\u7A7A\u6587\u5B57\u306F\u6307\u5B9A\u3067\u304D\u307E\u305B\u3093\u3002`);
7794
+ });
7795
+ const [startRaw, stopRaw, stepRaw] = values;
7796
+ const [startArg, stopArg, stepArg] = stmt.args;
7797
+ const startDate = typeof startRaw === "string" ? dateParts(startRaw) : null;
7798
+ const stopDate = typeof stopRaw === "string" ? dateParts(stopRaw) : null;
7799
+ const dateLikeStart = typeof startRaw === "string" && /^\d{4}-/.test(startRaw);
7800
+ const dateLikeStop = typeof stopRaw === "string" && /^\d{4}-/.test(stopRaw);
7801
+ if ([startRaw, stopRaw].some(isUnsupportedTemporal)) {
7802
+ throw argumentError("GENERATE_SERIES \u306F Phase 1 \u3067\u306F\u6574\u6570\u3068 DATE \u306E\u307F\u5BFE\u5FDC\u3057\u3066\u3044\u307E\u3059\u3002DATETIME \u3068 TIME \u306F\u4F7F\u7528\u3067\u304D\u307E\u305B\u3093\u3002");
7803
+ }
7804
+ if (startDate || stopDate || dateLikeStart || dateLikeStop || typeof startRaw === "string" && typeof stopRaw === "string" && !(isResolvedVariable(startArg) && isResolvedVariable(stopArg) && integerValue(startRaw) !== null && integerValue(stopRaw) !== null)) {
7805
+ if (!startDate || !stopDate) {
7806
+ if (startDate && typeof stopRaw !== "string" || stopDate && typeof startRaw !== "string") {
7807
+ throw argumentError("GENERATE_SERIES \u306E start \u3068 stop \u306F\u3001\u4E21\u65B9\u3092\u6574\u6570\u307E\u305F\u306F\u4E21\u65B9\u3092 DATE \u306B\u3057\u3066\u304F\u3060\u3055\u3044\u3002");
7808
+ }
7809
+ throw argumentError("GENERATE_SERIES \u306E\u65E5\u4ED8\u5F15\u6570\u306B\u306F\u5B9F\u5728\u3059\u308B YYYY-MM-DD \u5F62\u5F0F\u306E DATE \u3092\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044\u3002");
7810
+ }
7811
+ if (stepRaw !== void 0 && typeof stepRaw !== "string") {
7812
+ throw argumentError("GENERATE_SERIES \u306E step \u304C\u7CFB\u5217\u306E\u578B\u3068\u4E00\u81F4\u3057\u307E\u305B\u3093\u3002\u6574\u6570\u7CFB\u5217\u306B\u306F\u6574\u6570\u3001DATE \u7CFB\u5217\u306B\u306F day \u5358\u4F4D\u3092\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044\u3002");
7813
+ }
7814
+ const step2 = stepRaw === void 0 ? 1 : parseDateStep(stepRaw);
7815
+ const start2 = startRaw;
7816
+ const stop2 = stopRaw;
7817
+ return { kind: "DATE", start: start2, stop: stop2, step: step2, rowCount: countRows(dateOrdinal(start2), dateOrdinal(stop2), step2) };
7818
+ }
7819
+ const startInteger = startArg.type === "NUMBER" ? integerNumberLiteral(startArg) : isResolvedVariable(startArg) ? integerValue(startRaw) : null;
7820
+ const stopInteger = stopArg.type === "NUMBER" ? integerNumberLiteral(stopArg) : isResolvedVariable(stopArg) ? integerValue(stopRaw) : null;
7821
+ if (startInteger === null || stopInteger === null) {
7822
+ if ((startArg.type === "NUMBER" || isResolvedVariable(startArg)) && (stopArg.type === "NUMBER" || isResolvedVariable(stopArg))) {
7823
+ throw argumentError("GENERATE_SERIES \u306E\u6570\u5024\u7CFB\u5217\u306F\u6574\u6570\u306E start\u3001stop\u3001step \u306E\u307F\u3092\u53D7\u3051\u4ED8\u3051\u307E\u3059\u3002");
7824
+ }
7825
+ throw argumentError("GENERATE_SERIES \u306E start \u3068 stop \u306F\u3001\u4E21\u65B9\u3092\u6574\u6570\u307E\u305F\u306F\u4E21\u65B9\u3092 DATE \u306B\u3057\u3066\u304F\u3060\u3055\u3044\u3002");
7826
+ }
7827
+ const resolvedStep = stepRaw === void 0 ? 1 : stepArg?.type === "NUMBER" ? integerNumberLiteral(stepArg) : isResolvedVariable(stepArg) ? integerValue(stepRaw) : null;
7828
+ if (resolvedStep === null) {
7829
+ if (stepArg?.type === "NUMBER" || isResolvedVariable(stepArg)) {
7830
+ throw argumentError("GENERATE_SERIES \u306E\u6570\u5024\u7CFB\u5217\u306F\u6574\u6570\u306E start\u3001stop\u3001step \u306E\u307F\u3092\u53D7\u3051\u4ED8\u3051\u307E\u3059\u3002");
7831
+ }
7832
+ throw argumentError("GENERATE_SERIES \u306E step \u304C\u7CFB\u5217\u306E\u578B\u3068\u4E00\u81F4\u3057\u307E\u305B\u3093\u3002\u6574\u6570\u7CFB\u5217\u306B\u306F\u6574\u6570\u3001DATE \u7CFB\u5217\u306B\u306F day \u5358\u4F4D\u3092\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044\u3002");
7833
+ }
7834
+ const start = startInteger;
7835
+ const stop = stopInteger;
7836
+ const step = resolvedStep;
7837
+ if (step === 0) throw argumentError("GENERATE_SERIES \u306E step \u306B 0 \u306F\u6307\u5B9A\u3067\u304D\u307E\u305B\u3093\u3002");
7838
+ return { kind: "INTEGER", start, stop, step, rowCount: countRows(start, stop, step) };
7839
+ }
7840
+ function validateGenerateSeriesStatement(stmt) {
7841
+ if (stmt.args.length < 2 || stmt.args.length > 3) {
7842
+ throw argumentError("GENERATE_SERIES \u306F start\u3001stop \u3068\u7701\u7565\u53EF\u80FD\u306A step \u306E2\u500B\u307E\u305F\u306F3\u500B\u306E\u5F15\u6570\u3092\u53D7\u3051\u4ED8\u3051\u307E\u3059\u3002");
7843
+ }
7844
+ if (stmt.args.some(isVariable)) {
7845
+ ["start", "stop", "step"].forEach((name, index) => {
7846
+ const arg = stmt.args[index];
7847
+ if (arg?.type === "STRING" && arg.value === "") {
7848
+ throw argumentError(`GENERATE_SERIES \u306E ${name} \u306B\u7A7A\u6587\u5B57\u306F\u6307\u5B9A\u3067\u304D\u307E\u305B\u3093\u3002`);
7849
+ }
7850
+ if (arg?.type === "NUMBER" && integerNumberLiteral(arg) === null) {
7851
+ throw argumentError("GENERATE_SERIES \u306E\u6570\u5024\u7CFB\u5217\u306F\u6574\u6570\u306E start\u3001stop\u3001step \u306E\u307F\u3092\u53D7\u3051\u4ED8\u3051\u307E\u3059\u3002");
7852
+ }
7853
+ if (index < 2 && arg?.type === "STRING") {
7854
+ if (isUnsupportedTemporal(arg.value)) {
7855
+ throw argumentError("GENERATE_SERIES \u306F Phase 1 \u3067\u306F\u6574\u6570\u3068 DATE \u306E\u307F\u5BFE\u5FDC\u3057\u3066\u3044\u307E\u3059\u3002DATETIME \u3068 TIME \u306F\u4F7F\u7528\u3067\u304D\u307E\u305B\u3093\u3002");
7856
+ }
7857
+ if (/^\d{4}-/.test(arg.value) && dateParts(arg.value) === null) {
7858
+ throw argumentError("GENERATE_SERIES \u306E\u65E5\u4ED8\u5F15\u6570\u306B\u306F\u5B9F\u5728\u3059\u308B YYYY-MM-DD \u5F62\u5F0F\u306E DATE \u3092\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044\u3002");
7859
+ }
7860
+ }
7861
+ });
7862
+ const step = stmt.args[2];
7863
+ if (step?.type === "NUMBER") {
7864
+ const value = integerNumberLiteral(step);
7865
+ if (value === null) throw argumentError("GENERATE_SERIES \u306E\u6570\u5024\u7CFB\u5217\u306F\u6574\u6570\u306E start\u3001stop\u3001step \u306E\u307F\u3092\u53D7\u3051\u4ED8\u3051\u307E\u3059\u3002");
7866
+ if (value === 0) throw argumentError("GENERATE_SERIES \u306E step \u306B 0 \u306F\u6307\u5B9A\u3067\u304D\u307E\u305B\u3093\u3002");
7867
+ } else if (step?.type === "STRING") {
7868
+ parseDateStep(step.value);
7869
+ }
7870
+ return null;
7871
+ }
7872
+ const plan = planResolved(stmt);
7873
+ if (plan.rowCount > GENERATE_SERIES_MAX_ROWS) {
7874
+ throw argumentError(`GENERATE_SERIES \u306E\u751F\u6210\u4EF6\u6570 ${plan.rowCount} \u884C\u304C\u4E0A\u9650 ${GENERATE_SERIES_MAX_ROWS} \u884C\u3092\u8D85\u3048\u3066\u3044\u307E\u3059\u3002`);
7875
+ }
7876
+ return plan.rowCount;
7877
+ }
7878
+ function validateGenerateSeriesInStatement(node) {
7879
+ const visit = (value) => {
7880
+ if (value === null || typeof value !== "object") return;
7881
+ if (Array.isArray(value)) {
7882
+ value.forEach(visit);
7883
+ return;
7884
+ }
7885
+ const obj = value;
7886
+ if (obj.type === "WITH") {
7887
+ let total = 0;
7888
+ let complete = true;
7889
+ for (const cte of obj.ctes) {
7890
+ if (cte.query.type === "GENERATE_SERIES") {
7891
+ const count = validateGenerateSeriesStatement(cte.query);
7892
+ if (count === null) complete = false;
7893
+ else total += count;
7894
+ } else visit(cte.query);
7895
+ }
7896
+ if (complete && total > GENERATE_SERIES_MAX_ROWS) {
7897
+ throw argumentError(`\u3053\u306E WITH \u6587\u306E GENERATE_SERIES \u751F\u6210\u4EF6\u6570\u5408\u8A08 ${total} \u884C\u304C\u4E0A\u9650 ${GENERATE_SERIES_MAX_ROWS} \u884C\u3092\u8D85\u3048\u3066\u3044\u307E\u3059\u3002`);
7898
+ }
7899
+ visit(obj.query);
7900
+ return;
7901
+ }
7902
+ Object.values(obj).forEach(visit);
7903
+ };
7904
+ visit(node);
7905
+ }
7906
+ function resolveGenerateSeries(stmt) {
7907
+ const plan = planResolved(stmt);
7908
+ if (plan.rowCount > GENERATE_SERIES_MAX_ROWS) {
7909
+ throw argumentError(`GENERATE_SERIES \u306E\u751F\u6210\u4EF6\u6570 ${plan.rowCount} \u884C\u304C\u4E0A\u9650 ${GENERATE_SERIES_MAX_ROWS} \u884C\u3092\u8D85\u3048\u3066\u3044\u307E\u3059\u3002`);
7910
+ }
7911
+ const values = [];
7912
+ if (plan.kind === "INTEGER") {
7913
+ let current = plan.start;
7914
+ for (let index = 0; index < plan.rowCount; index++) {
7915
+ values.push(String(current));
7916
+ if (index + 1 < plan.rowCount) {
7917
+ const next = current + plan.step;
7918
+ if (!Number.isSafeInteger(next)) throw argumentError("GENERATE_SERIES \u306E\u6570\u5024\u7CFB\u5217\u306F\u6574\u6570\u306E start\u3001stop\u3001step \u306E\u307F\u3092\u53D7\u3051\u4ED8\u3051\u307E\u3059\u3002");
7919
+ current = next;
7920
+ }
7921
+ }
7922
+ } else {
7923
+ const startOrdinal = dateOrdinal(plan.start);
7924
+ for (let index = 0; index < plan.rowCount; index++) values.push(dateFromOrdinal(startOrdinal + index * plan.step));
7925
+ }
7926
+ return { ...plan, values };
7927
+ }
7928
+
7652
7929
  // src/core/statementValidation.ts
7653
7930
  function validateStatementStatic(stmt) {
7654
7931
  validateStringFunctionArities(stmt);
7655
7932
  validatePrimaryOrganizationDmlStatement(stmt);
7656
7933
  validateKlikeStatement(stmt);
7934
+ validateGenerateSeriesInStatement(stmt);
7657
7935
  }
7658
7936
  function validateStringFunctionArities(stmt) {
7659
7937
  const visit = (value) => {
@@ -12057,7 +12335,8 @@ var NATIVE_OPERATORS = /* @__PURE__ */ new Map([
12057
12335
  ["USER_SELECT", /* @__PURE__ */ new Set(["in", "not in"])],
12058
12336
  ["ORGANIZATION_SELECT", /* @__PURE__ */ new Set(["in", "not in"])],
12059
12337
  ["GROUP_SELECT", /* @__PURE__ */ new Set(["in", "not in"])],
12060
- ["STATUS", new Set(EQUALITY_IN)]
12338
+ ["STATUS", new Set(EQUALITY_IN)],
12339
+ ["STATUS_ASSIGNEE", /* @__PURE__ */ new Set(["in", "not in"])]
12061
12340
  ]);
12062
12341
  var LOCAL_VALID_OPERATORS = /* @__PURE__ */ new Map([
12063
12342
  ["CREATOR", /* @__PURE__ */ new Set(["in", "not in"])],
@@ -12511,6 +12790,44 @@ function requireExactFunctionPushdown(result) {
12511
12790
  );
12512
12791
  }
12513
12792
 
12793
+ // src/core/optimization/joinDateTimeLiteralPolicy.ts
12794
+ function isCanonicalJoinDate(value) {
12795
+ const match = /^(\d{4})-(\d{2})-(\d{2})$/.exec(value);
12796
+ if (!match) return false;
12797
+ const year = Number(match[1]);
12798
+ const month = Number(match[2]);
12799
+ const day = Number(match[3]);
12800
+ if (year < 1 || year > 9999) return false;
12801
+ const date = /* @__PURE__ */ new Date(0);
12802
+ date.setUTCFullYear(year, month - 1, day);
12803
+ date.setUTCHours(0, 0, 0, 0);
12804
+ return date.getUTCFullYear() === year && date.getUTCMonth() === month - 1 && date.getUTCDate() === day;
12805
+ }
12806
+ function isCanonicalJoinTime(value) {
12807
+ const match = /^(\d{2}):(\d{2})$/.exec(value);
12808
+ return match !== null && Number(match[1]) <= 23 && Number(match[2]) <= 59;
12809
+ }
12810
+ function isCanonicalJoinDateTime(value) {
12811
+ const match = /^(\d{4}-\d{2}-\d{2})T(\d{2}):(\d{2}):(\d{2})Z$/.exec(value);
12812
+ if (!match || !isCanonicalJoinDate(match[1])) return false;
12813
+ return Number(match[2]) <= 23 && Number(match[3]) <= 59 && Number(match[4]) <= 59;
12814
+ }
12815
+
12816
+ // src/core/optimization/joinNumberLiteralPolicy.ts
12817
+ function isJoinNumberLiteralSupported(literal) {
12818
+ const source = literal.raw ?? String(literal.value);
12819
+ const decimal = parseExactDecimal(source);
12820
+ if (decimal === null) return false;
12821
+ if (decimal.sign === 0) return numberLiteralText(literal) === "0";
12822
+ const fractionDigits = Math.max(decimal.scale, 0);
12823
+ const integerDigits = Math.max(decimal.coefficient.length - decimal.scale, 0);
12824
+ if (fractionDigits > 10 || integerDigits + fractionDigits > 30) {
12825
+ return false;
12826
+ }
12827
+ const canonical = formatPlainDecimal(decimal);
12828
+ return numberLiteralText(literal) === canonical;
12829
+ }
12830
+
12514
12831
  // src/core/optimization/joinPredicatePushdown.ts
12515
12832
  var SELECTION_TYPES = /* @__PURE__ */ new Set([
12516
12833
  "DROP_DOWN",
@@ -12519,6 +12836,14 @@ var SELECTION_TYPES = /* @__PURE__ */ new Set([
12519
12836
  "MULTI_SELECT",
12520
12837
  "STATUS"
12521
12838
  ]);
12839
+ var USER_CODE_TYPES = /* @__PURE__ */ new Set([
12840
+ "CREATOR",
12841
+ "MODIFIER",
12842
+ "USER_SELECT",
12843
+ "ORGANIZATION_SELECT",
12844
+ "GROUP_SELECT",
12845
+ "STATUS_ASSIGNEE"
12846
+ ]);
12522
12847
  var KLIKE_TYPES = /* @__PURE__ */ new Set([
12523
12848
  "SINGLE_LINE_TEXT",
12524
12849
  "LINK",
@@ -12526,7 +12851,7 @@ var KLIKE_TYPES = /* @__PURE__ */ new Set([
12526
12851
  "RICH_TEXT",
12527
12852
  "FILE"
12528
12853
  ]);
12529
- var DATETIME_EQUALITY_TYPES = /* @__PURE__ */ new Set([
12854
+ var DATETIME_TYPES = /* @__PURE__ */ new Set([
12530
12855
  "DATETIME",
12531
12856
  "CREATED_TIME",
12532
12857
  "UPDATED_TIME"
@@ -13122,21 +13447,45 @@ function classifySupportedLeaf(predicate, owner, fieldType) {
13122
13447
  return isPositiveSafeInteger(predicate.right) && (predicate.op === "=" || predicate.op === "<" || predicate.op === ">" || predicate.op === "<=" || predicate.op === ">=") ? "exact" : "unsafe";
13123
13448
  }
13124
13449
  if (fieldType === "RECORD_NUMBER") {
13125
- return "unsafe";
13450
+ return classifySupersetScalarOrListLiteral(predicate);
13126
13451
  }
13127
13452
  if (fieldType === "NUMBER") {
13128
- if (predicate.right.type !== "NUMBER") return "unsafe";
13129
- if (predicate.op === "=") return "superset";
13130
- return (predicate.op === "<" || predicate.op === ">") && isSafeIntegerLiteral(predicate.right) ? "superset" : "unsafe";
13453
+ if ((predicate.op === "IN" || predicate.op === "NOT_IN") && predicate.right.type === "IN_LIST" && predicate.right.values.length > 0 && predicate.right.values.every(
13454
+ (value) => value.type === "NUMBER" && isJoinNumberLiteralSupported(value)
13455
+ )) {
13456
+ return "exact";
13457
+ }
13458
+ if ((predicate.op === "=" || predicate.op === "!=" || predicate.op === "<>" || predicate.op === "<" || predicate.op === ">" || predicate.op === "<=" || predicate.op === ">=") && predicate.right.type === "NUMBER" && isJoinNumberLiteralSupported(predicate.right)) {
13459
+ return "exact";
13460
+ }
13461
+ return "unsafe";
13131
13462
  }
13132
- if (fieldType === "SINGLE_LINE_TEXT") {
13133
- return predicate.op === "=" && predicate.right.type === "STRING" && predicate.right.value !== "" ? "superset" : "unsafe";
13463
+ if (fieldType === "CALC") {
13464
+ return classifySupersetScalarOrListLiteral(predicate);
13134
13465
  }
13135
- if (fieldType === "DATE" || fieldType === "TIME" || DATETIME_EQUALITY_TYPES.has(fieldType)) {
13136
- if (predicate.op !== "=" || predicate.right.type !== "STRING") return "unsafe";
13137
- if (fieldType === "DATE") return isCanonicalDate(predicate.right.value) ? "superset" : "unsafe";
13138
- if (fieldType === "TIME") return isCanonicalTime(predicate.right.value) ? "superset" : "unsafe";
13139
- return isCanonicalDateTime(predicate.right.value) ? "superset" : "unsafe";
13466
+ if (USER_CODE_TYPES.has(fieldType)) {
13467
+ if (predicate.op !== "IN" && predicate.op !== "NOT_IN" || predicate.right.type !== "IN_LIST" || predicate.right.values.length === 0) return "unsafe";
13468
+ return predicate.right.values.every(
13469
+ (value) => value.type === "STRING" && value.value !== ""
13470
+ ) ? "exact" : "unsafe";
13471
+ }
13472
+ if (fieldType === "SINGLE_LINE_TEXT" || fieldType === "LINK") {
13473
+ if ((predicate.op === "IN" || predicate.op === "NOT_IN") && predicate.right.type === "IN_LIST" && predicate.right.values.length > 0 && predicate.right.values.every(
13474
+ (value) => value.type === "STRING" && value.value !== ""
13475
+ )) {
13476
+ return "exact";
13477
+ }
13478
+ return (predicate.op === "=" || predicate.op === "!=" || predicate.op === "<>") && predicate.right.type === "STRING" && predicate.right.value !== "" ? "exact" : "unsafe";
13479
+ }
13480
+ if (fieldType === "DATE" || fieldType === "TIME" || DATETIME_TYPES.has(fieldType)) {
13481
+ if (predicate.op !== "=" && predicate.op !== "!=" && predicate.op !== "<>" && predicate.op !== "<" && predicate.op !== ">" && predicate.op !== "<=" && predicate.op !== ">=" || predicate.right.type !== "STRING") return "unsafe";
13482
+ if (fieldType === "DATE") {
13483
+ return isCanonicalJoinDate(predicate.right.value) ? "exact" : "unsafe";
13484
+ }
13485
+ if (fieldType === "TIME") {
13486
+ return isCanonicalJoinTime(predicate.right.value) ? "exact" : "unsafe";
13487
+ }
13488
+ return isCanonicalJoinDateTime(predicate.right.value) ? "exact" : "unsafe";
13140
13489
  }
13141
13490
  if (SELECTION_TYPES.has(fieldType)) {
13142
13491
  if (predicate.op !== "IN" && predicate.op !== "NOT_IN" || predicate.right.type !== "IN_LIST" || predicate.right.values.length === 0) return "unsafe";
@@ -13148,6 +13497,19 @@ function classifySupportedLeaf(predicate, owner, fieldType) {
13148
13497
  }
13149
13498
  return "unsafe";
13150
13499
  }
13500
+ function classifySupersetScalarOrListLiteral(predicate) {
13501
+ const supportedLiteral = (value) => value.type === "NUMBER" && isJoinNumberLiteralSupported(value) || value.type === "STRING" && value.value !== "";
13502
+ if ((predicate.op === "IN" || predicate.op === "NOT_IN") && predicate.right.type === "IN_LIST") {
13503
+ const values = predicate.right.values;
13504
+ if (values.length > 0 && values.every(supportedLiteral) && values.every((value) => value.type === values[0].type)) {
13505
+ return "superset";
13506
+ }
13507
+ }
13508
+ if ((predicate.op === "=" || predicate.op === "!=" || predicate.op === "<>" || predicate.op === "<" || predicate.op === ">" || predicate.op === "<=" || predicate.op === ">=") && supportedLiteral(predicate.right)) {
13509
+ return "superset";
13510
+ }
13511
+ return "unsafe";
13512
+ }
13151
13513
  function owned(source, fieldCode) {
13152
13514
  return Object.freeze({
13153
13515
  status: "OWNED",
@@ -13172,24 +13534,6 @@ function isPositiveSafeInteger(value) {
13172
13534
  function isSafeIntegerLiteral(value) {
13173
13535
  return /^-?\d+$/.test(numberLiteralText(value)) && Number.isSafeInteger(value.value);
13174
13536
  }
13175
- function isCanonicalDate(value) {
13176
- const match = /^(\d{4})-(\d{2})-(\d{2})$/.exec(value);
13177
- if (!match) return false;
13178
- const year = Number(match[1]);
13179
- const month = Number(match[2]);
13180
- const day = Number(match[3]);
13181
- const date = new Date(Date.UTC(year, month - 1, day));
13182
- return date.getUTCFullYear() === year && date.getUTCMonth() === month - 1 && date.getUTCDate() === day;
13183
- }
13184
- function isCanonicalTime(value) {
13185
- const match = /^(\d{2}):(\d{2})$/.exec(value);
13186
- return match !== null && Number(match[1]) <= 23 && Number(match[2]) <= 59;
13187
- }
13188
- function isCanonicalDateTime(value) {
13189
- const match = /^(\d{4}-\d{2}-\d{2})T(\d{2}):(\d{2}):(\d{2})Z$/.exec(value);
13190
- if (!match || !isCanonicalDate(match[1])) return false;
13191
- return Number(match[2]) <= 23 && Number(match[3]) <= 59 && Number(match[4]) <= 59;
13192
- }
13193
13537
  function collectKlikes2(where, out) {
13194
13538
  if (where === null) return;
13195
13539
  if (isKlike(where)) {
@@ -17767,7 +18111,7 @@ function resolveBatchVariableReferencesInternal(node, variables, numericArithmet
17767
18111
  type: "NUMBER",
17768
18112
  value: value.value,
17769
18113
  raw: numericArithmeticOperand === "AGG_ARITH" ? `@${obj["name"]}` : value.raw ?? String(value.value)
17770
- } : { type: "STRING", value: value.value };
18114
+ } : { type: "STRING", value: value.value, fromVariable: true };
17771
18115
  }
17772
18116
  if (obj["type"] === "VARIABLE_COL" && typeof obj["name"] === "string" && typeof obj["alias"] === "string") {
17773
18117
  const value = variables.get(obj["name"]);
@@ -18083,10 +18427,16 @@ function hasDefaultRangeAggregateWindow(stmt) {
18083
18427
  function hasWindowNeedingOrderProof(stmt) {
18084
18428
  return hasDefaultRangeAggregateWindow(stmt) || stmt.columns.some((column) => column.type === "WINDOW_COL" && column.windowKind === "VALUE");
18085
18429
  }
18086
- function canProveTotalWindowOrder(stmt, orderBy, resolveField2, context) {
18087
- if (context !== "DIRECT" || stmt.joins.length > 0 || stmt.from.cteName !== null || stmt.from.subtableCode != null) {
18088
- return false;
18430
+ function canProveTotalWindowOrder(stmt, orderBy, resolveField2, context, generatedColumn) {
18431
+ if (generatedColumn !== void 0 && stmt.joins.length === 0 && stmt.from.cteName !== null) {
18432
+ return orderBy.some((item) => {
18433
+ if (item.key.type !== "FIELD_NAME") return false;
18434
+ const ref = aggregateFieldRef(item.key.name);
18435
+ if (ref.field !== generatedColumn) return false;
18436
+ return ref.tableAlias === null || ref.tableAlias === effectiveTableAlias(stmt.from);
18437
+ });
18089
18438
  }
18439
+ if (context !== "DIRECT" || stmt.joins.length > 0 || stmt.from.cteName !== null || stmt.from.subtableCode != null) return false;
18090
18440
  return orderBy.some((item) => {
18091
18441
  if (item.key.type !== "FIELD_NAME") return false;
18092
18442
  const ref = aggregateFieldRef(item.key.name);
@@ -18099,18 +18449,18 @@ function tieBreakAdvice(context, kind) {
18099
18449
  }
18100
18450
  return kind === "RANGE" ? "ORDER BY \u306B\u30EC\u30B3\u30FC\u30C9\u756A\u53F7\u306A\u3069\u306E\u30BF\u30A4\u30D6\u30EC\u30FC\u30AF\u30AD\u30FC\u3092\u8DB3\u3057\u3066\u304F\u3060\u3055\u3044\u3002" : "\u30EC\u30B3\u30FC\u30C9\u756A\u53F7\u7B49\u3092 ORDER BY \u306B\u8FFD\u52A0\u3057\u3066\u304F\u3060\u3055\u3044\u3002";
18101
18451
  }
18102
- function collectDefaultRangeWindowWarnings(stmt, resolveField2, context) {
18452
+ function collectDefaultRangeWindowWarnings(stmt, resolveField2, context, generatedColumn) {
18103
18453
  const warnings = [];
18104
18454
  for (const column of stmt.columns) {
18105
18455
  if (column.type !== "WINDOW_COL" || column.windowKind !== "AGGREGATE" || column.orderBy.length === 0 || column.frame?.source !== "DEFAULT") continue;
18106
- if (canProveTotalWindowOrder(stmt, column.orderBy, resolveField2, context)) continue;
18456
+ if (canProveTotalWindowOrder(stmt, column.orderBy, resolveField2, context, generatedColumn)) continue;
18107
18457
  warnings.push(
18108
18458
  `${column.alias} \u306F\u65E2\u5B9A\u30D5\u30EC\u30FC\u30E0\uFF08RANGE\uFF09\u3067\u8A55\u4FA1\u3055\u308C\u307E\u3059\u3002ORDER BY \u306E\u5024\u304C\u540C\u3058\u884C\u306F\u3059\u3079\u3066\u540C\u3058\u5024\u306B\u306A\u308A\u307E\u3059\u3002\u884C\u3054\u3068\u306E\u5024\u304C\u5FC5\u8981\u306A\u3089 ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW \u3092\u660E\u793A\u3059\u308B\u304B\u3001` + tieBreakAdvice(context, "RANGE")
18109
18459
  );
18110
18460
  }
18111
18461
  for (const column of stmt.columns) {
18112
18462
  if (column.type !== "WINDOW_COL" || column.windowKind !== "VALUE") continue;
18113
- if (canProveTotalWindowOrder(stmt, column.orderBy, resolveField2, context)) continue;
18463
+ if (canProveTotalWindowOrder(stmt, column.orderBy, resolveField2, context, generatedColumn)) continue;
18114
18464
  warnings.push(
18115
18465
  `${column.alias} \u306E ORDER BY \u306F\u5168\u9806\u5E8F\u3067\u306A\u3044\u305F\u3081\u3001\u540C\u9806\u5185\u306E\u524D\u5F8C\u95A2\u4FC2\u306F\u672A\u898F\u5B9A\u3067\u3059\u3002` + tieBreakAdvice(context, "VALUE")
18116
18466
  );
@@ -20041,6 +20391,8 @@ async function executeWith(stmt, client, options, cacheContext, seed, captureCol
20041
20391
  result2 = await executeShowApps(client);
20042
20392
  } else if (cte.query.type === "DESCRIBE") {
20043
20393
  result2 = await executeDescribe(cte.query, client, cacheContext);
20394
+ } else if (cte.query.type === "GENERATE_SERIES") {
20395
+ result2 = executeGenerateSeries(cte.query);
20044
20396
  } else {
20045
20397
  result2 = await executeQueryWithCte(cte.query, client, options, cteCache, cacheContext, true);
20046
20398
  }
@@ -20048,7 +20400,8 @@ async function executeWith(stmt, client, options, cacheContext, seed, captureCol
20048
20400
  cteCache.set(cte.name, {
20049
20401
  rows: result2.rows,
20050
20402
  columns: result2.columns,
20051
- columnMeta: materializedMetaBySelectResult.get(result2)
20403
+ columnMeta: materializedMetaBySelectResult.get(result2),
20404
+ ...cte.query.type === "GENERATE_SERIES" ? { uniqueGeneratedColumn: cte.query.columnAlias } : {}
20052
20405
  });
20053
20406
  }
20054
20407
  const result = await executeQueryWithCte(
@@ -20061,6 +20414,27 @@ async function executeWith(stmt, client, options, cacheContext, seed, captureCol
20061
20414
  );
20062
20415
  return mergeSelectWarnings(result, [...warnings]);
20063
20416
  }
20417
+ function executeGenerateSeries(stmt) {
20418
+ const series = resolveGenerateSeries(stmt);
20419
+ const result = {
20420
+ type: "SELECT",
20421
+ columns: [stmt.columnAlias],
20422
+ rows: series.values.map((value) => ({ [stmt.columnAlias]: value })),
20423
+ rowCount: series.rowCount,
20424
+ warnings: []
20425
+ };
20426
+ const meta = series.kind === "INTEGER" ? {
20427
+ sortKind: "number",
20428
+ fieldType: "NUMBER",
20429
+ semantics: resolveFieldSemantics({ fieldType: "NUMBER" })
20430
+ } : {
20431
+ sortKind: "string",
20432
+ fieldType: "DATE",
20433
+ semantics: resolveFieldSemantics({ fieldType: "DATE" })
20434
+ };
20435
+ materializedMetaBySelectResult.set(result, /* @__PURE__ */ new Map([[stmt.columnAlias, meta]]));
20436
+ return result;
20437
+ }
20064
20438
  async function executeQueryWithCte(query, client, options, cteCache, cacheContext, captureColumnMeta = false, b86PreflightComplete = false) {
20065
20439
  if (!b86PreflightComplete) {
20066
20440
  await preflightB86QueryWithCte(query, client, cteCache, cacheContext);
@@ -20167,7 +20541,8 @@ async function executeFullScanWithCte(stmt, client, options, cteCache, cacheCont
20167
20541
  const defaultRangeWarnings = collectDefaultRangeWindowWarnings(
20168
20542
  stmt,
20169
20543
  choiceAndWindowResolver,
20170
- "DERIVED"
20544
+ "DERIVED",
20545
+ stmt.joins.length === 0 && stmt.from.cteName !== null ? cteCache.get(stmt.from.cteName)?.uniqueGeneratedColumn : void 0
20171
20546
  );
20172
20547
  const maxRecords = options.maxRecords ?? 1e4;
20173
20548
  const warnings = /* @__PURE__ */ new Set();
@@ -23840,6 +24215,9 @@ async function buildExplainWhereAnalysis(query, client, cacheContext, maxRecords
23840
24215
  }
23841
24216
  if (typed["type"] === "SHOW_APPS") return [...SHOW_APPS_COLUMNS];
23842
24217
  if (typed["type"] === "DESCRIBE") return [...DESCRIBE_COLUMNS];
24218
+ if (typed["type"] === "GENERATE_SERIES") {
24219
+ return [node.columnAlias];
24220
+ }
23843
24221
  throw new Error("ArgumentError: EXPLAIN could not determine the relation output schema.");
23844
24222
  };
23845
24223
  const preflightExplainRelations = async (node) => {
@@ -25133,6 +25511,22 @@ function buildWithPlan(stmt, capabilities, orderPlans, plainGroupByPlans, collec
25133
25511
  "cte"
25134
25512
  ));
25135
25513
  lines.push("");
25514
+ } else if (cte.query.type === "GENERATE_SERIES") {
25515
+ const series = resolveGenerateSeries(cte.query);
25516
+ const step = series.kind === "DATE" ? `${series.step} ${Math.abs(series.step) === 1 ? "day" : "days"}` : String(series.step);
25517
+ lines.push(
25518
+ `[cte: ${cte.name}]`,
25519
+ " source: GENERATE_SERIES",
25520
+ ` column: ${cte.query.columnAlias}`,
25521
+ ` series type: ${series.kind}`,
25522
+ ` start: ${series.start}`,
25523
+ ` stop: ${series.stop}`,
25524
+ ` step: ${step}`,
25525
+ ` rows: ${series.rowCount}`,
25526
+ ` row guard: ${series.rowCount} / ${GENERATE_SERIES_MAX_ROWS}`,
25527
+ " records API: none",
25528
+ ""
25529
+ );
25136
25530
  }
25137
25531
  }
25138
25532
  if (stmt.query.type === "SELECT" || stmt.query.type === "UNION") {
@@ -26083,19 +26477,19 @@ function normalizeSqlAppProfiles(sql, defaultProfile = "dev", resolutionContext)
26083
26477
  var PHYSICAL_APP_KEY_RE = /^APP\d+$/i;
26084
26478
  var NUMERIC_APP_KEY_RE = /^\d+$/;
26085
26479
  var LOGICAL_SQL_KEY_RE = /^LAPP_/i;
26086
- function argumentError(message) {
26480
+ function argumentError2(message) {
26087
26481
  return new Error(`ArgumentError: ${message}`);
26088
26482
  }
26089
26483
  function normalizeLogicalApps(profileName, value) {
26090
26484
  if (value === void 0) return void 0;
26091
26485
  if (value === null || typeof value !== "object" || Array.isArray(value)) {
26092
- throw argumentError(`logicalApps for profile "${profileName}" must be an object.`);
26486
+ throw argumentError2(`logicalApps for profile "${profileName}" must be an object.`);
26093
26487
  }
26094
26488
  const normalized = {};
26095
26489
  const physicalIdOwners = /* @__PURE__ */ new Map();
26096
26490
  for (const [rawName, rawAppId] of Object.entries(value)) {
26097
26491
  if (PHYSICAL_APP_KEY_RE.test(rawName) || NUMERIC_APP_KEY_RE.test(rawName) || LOGICAL_SQL_KEY_RE.test(rawName)) {
26098
- throw argumentError(
26492
+ throw argumentError2(
26099
26493
  `logical app key "${rawName}" in profile "${profileName}" must be a logical name without APP, numeric, or LAPP_ syntax.`
26100
26494
  );
26101
26495
  }
@@ -26103,23 +26497,23 @@ function normalizeLogicalApps(profileName, value) {
26103
26497
  try {
26104
26498
  logicalName = canonicalizeLogicalAppName(rawName);
26105
26499
  } catch {
26106
- throw argumentError(
26500
+ throw argumentError2(
26107
26501
  `logical app key "${rawName}" in profile "${profileName}" must match the logical app name rules.`
26108
26502
  );
26109
26503
  }
26110
26504
  if (Object.prototype.hasOwnProperty.call(normalized, logicalName)) {
26111
- throw argumentError(
26505
+ throw argumentError2(
26112
26506
  `logical app name "${logicalName}" is duplicated after case normalization in profile "${profileName}".`
26113
26507
  );
26114
26508
  }
26115
26509
  if (typeof rawAppId !== "number" || !Number.isSafeInteger(rawAppId) || rawAppId <= 0) {
26116
- throw argumentError(
26510
+ throw argumentError2(
26117
26511
  `physical app ID for logical app "${logicalName}" in profile "${profileName}" must be a positive safe integer.`
26118
26512
  );
26119
26513
  }
26120
26514
  const existingName = physicalIdOwners.get(rawAppId);
26121
26515
  if (existingName !== void 0) {
26122
- throw argumentError(
26516
+ throw argumentError2(
26123
26517
  `logical apps "${existingName}" and "${logicalName}" in profile "${profileName}" map to the same physical app ID ${rawAppId}; physical app aliases are not supported yet.`
26124
26518
  );
26125
26519
  }
@@ -26130,31 +26524,31 @@ function normalizeLogicalApps(profileName, value) {
26130
26524
  }
26131
26525
  function validateKsqlConfig(config) {
26132
26526
  if (config === null || typeof config !== "object" || Array.isArray(config)) {
26133
- throw argumentError("config must be an object.");
26527
+ throw argumentError2("config must be an object.");
26134
26528
  }
26135
26529
  if (config.profiles === void 0) return config;
26136
26530
  if (config.profiles === null || typeof config.profiles !== "object" || Array.isArray(config.profiles)) {
26137
- throw argumentError("profiles must be an object.");
26531
+ throw argumentError2("profiles must be an object.");
26138
26532
  }
26139
26533
  for (const [profileName, profile] of Object.entries(config.profiles)) {
26140
26534
  if (profile === null || typeof profile !== "object" || Array.isArray(profile)) {
26141
- throw argumentError(`profile "${profileName}" must be an object.`);
26535
+ throw argumentError2(`profile "${profileName}" must be an object.`);
26142
26536
  }
26143
26537
  if (profile.allowPhysicalAppRefs !== void 0 && typeof profile.allowPhysicalAppRefs !== "boolean") {
26144
- throw argumentError(`allowPhysicalAppRefs for profile "${profileName}" must be boolean.`);
26538
+ throw argumentError2(`allowPhysicalAppRefs for profile "${profileName}" must be boolean.`);
26145
26539
  }
26146
26540
  const logicalApps = normalizeLogicalApps(profileName, profile.logicalApps);
26147
26541
  if (logicalApps !== void 0) profile.logicalApps = logicalApps;
26148
26542
  if (profile.query?.cursorMaxActive !== void 0) {
26149
26543
  const value = profile.query.cursorMaxActive;
26150
26544
  if (!Number.isSafeInteger(value) || value < 1 || value > 5) {
26151
- throw argumentError(`query.cursorMaxActive for profile "${profileName}" must be an integer from 1 to 5.`);
26545
+ throw argumentError2(`query.cursorMaxActive for profile "${profileName}" must be an integer from 1 to 5.`);
26152
26546
  }
26153
26547
  }
26154
26548
  if (profile.query?.dmlMaxSubtableRows !== void 0) {
26155
26549
  const value = profile.query.dmlMaxSubtableRows;
26156
26550
  if (!Number.isSafeInteger(value) || value <= 0) {
26157
- throw argumentError(`query.dmlMaxSubtableRows for profile "${profileName}" must be a positive safe integer.`);
26551
+ throw argumentError2(`query.dmlMaxSubtableRows for profile "${profileName}" must be a positive safe integer.`);
26158
26552
  }
26159
26553
  }
26160
26554
  }
@@ -26174,7 +26568,7 @@ function createAppResolutionContext(config, defaultProfile) {
26174
26568
  function requireProfile(profileName) {
26175
26569
  const profile = profiles[profileName];
26176
26570
  if (!profile && profileName === defaultProfile) return implicitDefaultProfile;
26177
- if (!profile) throw argumentError(`profile "${profileName}" is not defined.`);
26571
+ if (!profile) throw argumentError2(`profile "${profileName}" is not defined.`);
26178
26572
  return profile;
26179
26573
  }
26180
26574
  return {
@@ -26184,11 +26578,11 @@ function createAppResolutionContext(config, defaultProfile) {
26184
26578
  try {
26185
26579
  logicalName = canonicalizeLogicalAppName(name);
26186
26580
  } catch {
26187
- throw argumentError(`logical app name "${name}" must match the logical app name rules.`);
26581
+ throw argumentError2(`logical app name "${name}" must match the logical app name rules.`);
26188
26582
  }
26189
26583
  const appId = requireProfile(profileName).logicalApps?.[logicalName];
26190
26584
  if (appId === void 0) {
26191
- throw argumentError(`logical app LAPP_${logicalName}@${profileName} is not defined.`);
26585
+ throw argumentError2(`logical app LAPP_${logicalName}@${profileName} is not defined.`);
26192
26586
  }
26193
26587
  return appId;
26194
26588
  },
@@ -26196,7 +26590,7 @@ function createAppResolutionContext(config, defaultProfile) {
26196
26590
  const profileName = profile || defaultProfile;
26197
26591
  if (!profiles[profileName]) return;
26198
26592
  if (requireProfile(profileName).allowPhysicalAppRefs === false) {
26199
- throw argumentError(
26593
+ throw argumentError2(
26200
26594
  `physical app references are not allowed for profile "${profileName}"; use LAPP_<NAME>.`
26201
26595
  );
26202
26596
  }