@dbsp/nql 1.0.1 → 1.0.3
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/index.d.ts +2 -0
- package/dist/index.js +54 -15
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -438,6 +438,8 @@ interface NqlCompilerOptions {
|
|
|
438
438
|
readonly recursiveKeywords?: readonly string[];
|
|
439
439
|
/** BATCH-001: Named parameters for ANY(:param) expressions */
|
|
440
440
|
readonly params?: Readonly<Record<string, unknown>>;
|
|
441
|
+
/** Maximum number of items allowed in an ANY(:param) array. Defaults to MAX_ANY_ITEMS (10000). */
|
|
442
|
+
readonly maxAnyItems?: number;
|
|
441
443
|
}
|
|
442
444
|
|
|
443
445
|
/**
|
package/dist/index.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { isRankingWindowFunction } from '@dbsp/types';
|
|
1
2
|
import { createToken, Lexer, CstParser } from 'chevrotain';
|
|
2
3
|
|
|
3
4
|
// src/errors/types.ts
|
|
@@ -787,6 +788,7 @@ function getISOWeekCount(year) {
|
|
|
787
788
|
}
|
|
788
789
|
|
|
789
790
|
// src/compiler/compile-expression.ts
|
|
791
|
+
var MAX_ANY_ITEMS = 1e4;
|
|
790
792
|
function compileLogical(expr, ctx, fns, aliasContext, outerAliases) {
|
|
791
793
|
if (expr.type === "binary") {
|
|
792
794
|
const binary = expr;
|
|
@@ -961,7 +963,19 @@ function compileMembership(expr, ctx, fns, aliasContext, outerAliases) {
|
|
|
961
963
|
}
|
|
962
964
|
validateWhereField(ctx, field2, aliasContext, anyExpr.column);
|
|
963
965
|
const rawValues = ctx.params[anyExpr.paramName];
|
|
964
|
-
|
|
966
|
+
if (!Array.isArray(rawValues)) {
|
|
967
|
+
throw new NqlSemanticException(
|
|
968
|
+
NqlErrorCodes.SEM_INVALID_SYNTAX,
|
|
969
|
+
`ANY(:${anyExpr.paramName}) requires an array argument but received ${rawValues === void 0 ? "undefined (parameter not bound)" : typeof rawValues}`
|
|
970
|
+
);
|
|
971
|
+
}
|
|
972
|
+
if (rawValues.length > ctx.maxAnyItems) {
|
|
973
|
+
throw new NqlSemanticException(
|
|
974
|
+
NqlErrorCodes.SEM_INVALID_SYNTAX,
|
|
975
|
+
`ANY(:${anyExpr.paramName}) array length ${rawValues.length} exceeds maximum of ${ctx.maxAnyItems}`
|
|
976
|
+
);
|
|
977
|
+
}
|
|
978
|
+
const values2 = rawValues;
|
|
965
979
|
return { kind: "any", field: field2, values: values2 };
|
|
966
980
|
}
|
|
967
981
|
const inExpr = expr;
|
|
@@ -995,7 +1009,6 @@ function compileMembership(expr, ctx, fns, aliasContext, outerAliases) {
|
|
|
995
1009
|
const result2 = {
|
|
996
1010
|
kind: "in",
|
|
997
1011
|
field,
|
|
998
|
-
values: [],
|
|
999
1012
|
subquery
|
|
1000
1013
|
};
|
|
1001
1014
|
if (inExpr.negated) {
|
|
@@ -1438,8 +1451,9 @@ function resolveBindingsInWhere(where, bindings) {
|
|
|
1438
1451
|
if (!bindings || bindings.size === 0) return where;
|
|
1439
1452
|
if (where.kind === "in") {
|
|
1440
1453
|
const inWhere = where;
|
|
1441
|
-
|
|
1442
|
-
|
|
1454
|
+
const inValues = inWhere.subquery ? void 0 : inWhere.values;
|
|
1455
|
+
if (inValues && inValues.length === 1) {
|
|
1456
|
+
const val = inValues[0];
|
|
1443
1457
|
if (val && typeof val === "object" && "$ref" in val) {
|
|
1444
1458
|
const ref = val.$ref;
|
|
1445
1459
|
if (bindings.has(ref)) {
|
|
@@ -1459,7 +1473,6 @@ function resolveBindingsInWhere(where, bindings) {
|
|
|
1459
1473
|
return {
|
|
1460
1474
|
kind: "in",
|
|
1461
1475
|
field: inWhere.field,
|
|
1462
|
-
values: [],
|
|
1463
1476
|
subquery: cteRef
|
|
1464
1477
|
};
|
|
1465
1478
|
}
|
|
@@ -1494,8 +1507,6 @@ function extractBindName(stmt) {
|
|
|
1494
1507
|
}
|
|
1495
1508
|
return void 0;
|
|
1496
1509
|
}
|
|
1497
|
-
|
|
1498
|
-
// src/compiler/compile-select.ts
|
|
1499
1510
|
function compileSelectClause(clause, ctx, fns) {
|
|
1500
1511
|
if (clause.items.length === 1 && clause.items[0]?.type === "star") {
|
|
1501
1512
|
return { type: "all" };
|
|
@@ -1620,17 +1631,36 @@ function compileSelectExpression(item, ctx, fns) {
|
|
|
1620
1631
|
}
|
|
1621
1632
|
return { field: f, direction: o.direction };
|
|
1622
1633
|
}) : void 0;
|
|
1634
|
+
const over = {
|
|
1635
|
+
...partitionBy && { partitionBy },
|
|
1636
|
+
...orderBy && { orderBy }
|
|
1637
|
+
};
|
|
1638
|
+
const alias = exprItem.alias ?? fn;
|
|
1639
|
+
if (isRankingWindowFunction(fn)) {
|
|
1640
|
+
return {
|
|
1641
|
+
kind: "window",
|
|
1642
|
+
function: fn,
|
|
1643
|
+
alias,
|
|
1644
|
+
over
|
|
1645
|
+
};
|
|
1646
|
+
}
|
|
1647
|
+
if (fn === "lag" || fn === "lead") {
|
|
1648
|
+
return {
|
|
1649
|
+
kind: "window",
|
|
1650
|
+
function: fn,
|
|
1651
|
+
field: field ?? "",
|
|
1652
|
+
alias,
|
|
1653
|
+
...offset !== void 0 && { offset },
|
|
1654
|
+
...defaultValue !== void 0 && { defaultValue },
|
|
1655
|
+
over
|
|
1656
|
+
};
|
|
1657
|
+
}
|
|
1623
1658
|
return {
|
|
1624
1659
|
kind: "window",
|
|
1625
1660
|
function: fn,
|
|
1626
1661
|
...field !== void 0 && { field },
|
|
1627
|
-
alias
|
|
1628
|
-
|
|
1629
|
-
...defaultValue !== void 0 && { defaultValue },
|
|
1630
|
-
over: {
|
|
1631
|
-
...partitionBy && { partitionBy },
|
|
1632
|
-
...orderBy && { orderBy }
|
|
1633
|
-
}
|
|
1662
|
+
alias,
|
|
1663
|
+
over
|
|
1634
1664
|
};
|
|
1635
1665
|
}
|
|
1636
1666
|
if (expr.type === "subquery") {
|
|
@@ -1900,13 +1930,22 @@ var NqlCompiler = class {
|
|
|
1900
1930
|
const recursive = options?.recursiveKeywords ?? DEFAULT_RECURSIVE_KEYWORDS;
|
|
1901
1931
|
const recursiveKeywords = new Set(recursive.map((k) => k.toLowerCase()));
|
|
1902
1932
|
const validator = schema ? new ColumnValidator(schema) : null;
|
|
1933
|
+
const maxAnyItemsRaw = options?.maxAnyItems;
|
|
1934
|
+
if (maxAnyItemsRaw !== void 0) {
|
|
1935
|
+
if (!Number.isSafeInteger(maxAnyItemsRaw) || maxAnyItemsRaw <= 0) {
|
|
1936
|
+
throw new Error(
|
|
1937
|
+
`Invalid maxAnyItems: ${maxAnyItemsRaw}. Must be a positive integer.`
|
|
1938
|
+
);
|
|
1939
|
+
}
|
|
1940
|
+
}
|
|
1903
1941
|
this.ctx = {
|
|
1904
1942
|
currentFromTable: void 0,
|
|
1905
1943
|
currentRelationTarget: void 0,
|
|
1906
1944
|
pseudoColumnKeywords,
|
|
1907
1945
|
recursiveKeywords,
|
|
1908
1946
|
validator,
|
|
1909
|
-
params: options?.params ?? {}
|
|
1947
|
+
params: options?.params ?? {},
|
|
1948
|
+
maxAnyItems: maxAnyItemsRaw ?? MAX_ANY_ITEMS
|
|
1910
1949
|
};
|
|
1911
1950
|
this.fns = {
|
|
1912
1951
|
compileQuery: (query, ctx) => compileQuery(query, ctx, this.fns),
|