drizzle-cube
Version:
Drizzle ORM-first semantic layer with Cube.js compatibility. Type-safe analytics and dashboards with SQL injection protection.
22,959 lines • 531 kB
JavaScript
const y = /* @__PURE__ */ Symbol.for("drizzle:entityKind");
function h(T, E) {
if (!T || typeof T != "object")
return !1;
if (T instanceof E)
return !0;
if (!Object.prototype.hasOwnProperty.call(E, y))
throw new Error(
`Class "${E.name ?? "<unknown>"}" doesn't look like a Drizzle entity. If this is incorrect and the class is provided by Drizzle, please report this as a bug.`
);
let e = Object.getPrototypeOf(T).constructor;
if (e)
for (; e; ) {
if (y in e && e[y] === E[y])
return !0;
e = Object.getPrototypeOf(e);
}
return !1;
}
class sE {
constructor(E, e) {
this.table = E, this.config = e, this.name = e.name, this.keyAsName = e.keyAsName, this.notNull = e.notNull, this.default = e.default, this.defaultFn = e.defaultFn, this.onUpdateFn = e.onUpdateFn, this.hasDefault = e.hasDefault, this.primary = e.primaryKey, this.isUnique = e.isUnique, this.uniqueName = e.uniqueName, this.uniqueType = e.uniqueType, this.dataType = e.dataType, this.columnType = e.columnType, this.generated = e.generated, this.generatedIdentity = e.generatedIdentity;
}
static [y] = "Column";
name;
keyAsName;
primary;
notNull;
default;
defaultFn;
onUpdateFn;
hasDefault;
isUnique;
uniqueName;
uniqueType;
dataType;
columnType;
enumValues = void 0;
generated = void 0;
generatedIdentity = void 0;
config;
mapFromDriverValue(E) {
return E;
}
mapToDriverValue(E) {
return E;
}
// ** @internal */
shouldDisableInsert() {
return this.config.generated !== void 0 && this.config.generated.type !== "byDefault";
}
}
const UE = /* @__PURE__ */ Symbol.for("drizzle:Name"), Ce = /* @__PURE__ */ Symbol.for("drizzle:isPgEnum");
function YT(T) {
return !!T && typeof T == "function" && Ce in T && T[Ce] === !0;
}
class IT {
static [y] = "Subquery";
constructor(E, e, R, A = !1, t = []) {
this._ = {
brand: "Subquery",
sql: E,
selectedFields: e,
alias: R,
isWith: A,
usedTables: t
};
}
// getSQL(): SQL<unknown> {
// return new SQL([this]);
// }
}
const VT = {
startActiveSpan(T, E) {
return E();
}
}, AE = /* @__PURE__ */ Symbol.for("drizzle:ViewBaseConfig"), dE = /* @__PURE__ */ Symbol.for("drizzle:Schema"), oe = /* @__PURE__ */ Symbol.for("drizzle:Columns"), Le = /* @__PURE__ */ Symbol.for("drizzle:ExtraConfigColumns"), mE = /* @__PURE__ */ Symbol.for("drizzle:OriginalName"), GE = /* @__PURE__ */ Symbol.for("drizzle:BaseName"), oE = /* @__PURE__ */ Symbol.for("drizzle:IsAlias"), _e = /* @__PURE__ */ Symbol.for("drizzle:ExtraConfigBuilder"), bT = /* @__PURE__ */ Symbol.for("drizzle:IsDrizzleTable");
class $ {
static [y] = "Table";
/** @internal */
static Symbol = {
Name: UE,
Schema: dE,
OriginalName: mE,
Columns: oe,
ExtraConfigColumns: Le,
BaseName: GE,
IsAlias: oE,
ExtraConfigBuilder: _e
};
/**
* @internal
* Can be changed if the table is aliased.
*/
[UE];
/**
* @internal
* Used to store the original name of the table, before any aliasing.
*/
[mE];
/** @internal */
[dE];
/** @internal */
[oe];
/** @internal */
[Le];
/**
* @internal
* Used to store the table name before the transformation via the `tableCreator` functions.
*/
[GE];
/** @internal */
[oE] = !1;
/** @internal */
[bT] = !0;
/** @internal */
[_e] = void 0;
constructor(E, e, R) {
this[UE] = this[mE] = E, this[dE] = e, this[GE] = R;
}
}
function OT(T) {
return T != null && typeof T.getSQL == "function";
}
function gT(T) {
const E = { sql: "", params: [] };
for (const e of T)
E.sql += e.sql, E.params.push(...e.params), e.typings?.length && (E.typings || (E.typings = []), E.typings.push(...e.typings));
return E;
}
class b {
static [y] = "StringChunk";
value;
constructor(E) {
this.value = Array.isArray(E) ? E : [E];
}
getSQL() {
return new p([this]);
}
}
class p {
constructor(E) {
this.queryChunks = E;
for (const e of E)
if (h(e, $)) {
const R = e[$.Symbol.Schema];
this.usedTables.push(
R === void 0 ? e[$.Symbol.Name] : R + "." + e[$.Symbol.Name]
);
}
}
static [y] = "SQL";
/** @internal */
decoder = nT;
shouldInlineParams = !1;
/** @internal */
usedTables = [];
append(E) {
return this.queryChunks.push(...E.queryChunks), this;
}
toQuery(E) {
return VT.startActiveSpan("drizzle.buildSQL", (e) => {
const R = this.buildQueryFromSourceParams(this.queryChunks, E);
return e?.setAttributes({
"drizzle.query.text": R.sql,
"drizzle.query.params": JSON.stringify(R.params)
}), R;
});
}
buildQueryFromSourceParams(E, e) {
const R = Object.assign({}, e, {
inlineParams: e.inlineParams || this.shouldInlineParams,
paramStartIndex: e.paramStartIndex || { value: 0 }
}), {
casing: A,
escapeName: t,
escapeParam: s,
prepareTyping: I,
inlineParams: r,
paramStartIndex: S
} = R;
return gT(E.map((N) => {
if (h(N, b))
return { sql: N.value.join(""), params: [] };
if (h(N, Te))
return { sql: t(N.value), params: [] };
if (N === void 0)
return { sql: "", params: [] };
if (Array.isArray(N)) {
const O = [new b("(")];
for (const [i, a] of N.entries())
O.push(a), i < N.length - 1 && O.push(new b(", "));
return O.push(new b(")")), this.buildQueryFromSourceParams(O, R);
}
if (h(N, p))
return this.buildQueryFromSourceParams(N.queryChunks, {
...R,
inlineParams: r || N.shouldInlineParams
});
if (h(N, $)) {
const O = N[$.Symbol.Schema], i = N[$.Symbol.Name];
return {
sql: O === void 0 || N[oE] ? t(i) : t(O) + "." + t(i),
params: []
};
}
if (h(N, sE)) {
const O = A.getColumnCasing(N);
if (e.invokeSource === "indexes")
return { sql: t(O), params: [] };
const i = N.table[$.Symbol.Schema];
return {
sql: N.table[oE] || i === void 0 ? t(N.table[$.Symbol.Name]) + "." + t(O) : t(i) + "." + t(N.table[$.Symbol.Name]) + "." + t(O),
params: []
};
}
if (h(N, iT)) {
const O = N[AE].schema, i = N[AE].name;
return {
sql: O === void 0 || N[AE].isAlias ? t(i) : t(O) + "." + t(i),
params: []
};
}
if (h(N, LE)) {
if (h(N.value, _E))
return { sql: s(S.value++, N), params: [N], typings: ["none"] };
const O = N.value === null ? null : N.encoder.mapToDriverValue(N.value);
if (h(O, p))
return this.buildQueryFromSourceParams([O], R);
if (r)
return { sql: this.mapInlineParam(O, R), params: [] };
let i = ["none"];
return I && (i = [I(N.encoder)]), { sql: s(S.value++, O), params: [O], typings: i };
}
return h(N, _E) ? { sql: s(S.value++, N), params: [N], typings: ["none"] } : h(N, p.Aliased) && N.fieldAlias !== void 0 ? { sql: t(N.fieldAlias), params: [] } : h(N, IT) ? N._.isWith ? { sql: t(N._.alias), params: [] } : this.buildQueryFromSourceParams([
new b("("),
N._.sql,
new b(") "),
new Te(N._.alias)
], R) : YT(N) ? N.schema ? { sql: t(N.schema) + "." + t(N.enumName), params: [] } : { sql: t(N.enumName), params: [] } : OT(N) ? N.shouldOmitSQLParens?.() ? this.buildQueryFromSourceParams([N.getSQL()], R) : this.buildQueryFromSourceParams([
new b("("),
N.getSQL(),
new b(")")
], R) : r ? { sql: this.mapInlineParam(N, R), params: [] } : { sql: s(S.value++, N), params: [N], typings: ["none"] };
}));
}
mapInlineParam(E, { escapeString: e }) {
if (E === null)
return "null";
if (typeof E == "number" || typeof E == "boolean")
return E.toString();
if (typeof E == "string")
return e(E);
if (typeof E == "object") {
const R = E.toString();
return e(R === "[object Object]" ? JSON.stringify(E) : R);
}
throw new Error("Unexpected param value: " + E);
}
getSQL() {
return this;
}
as(E) {
return E === void 0 ? this : new p.Aliased(this, E);
}
mapWith(E) {
return this.decoder = typeof E == "function" ? { mapFromDriverValue: E } : E, this;
}
inlineParams() {
return this.shouldInlineParams = !0, this;
}
/**
* This method is used to conditionally include a part of the query.
*
* @param condition - Condition to check
* @returns itself if the condition is `true`, otherwise `undefined`
*/
if(E) {
return E ? this : void 0;
}
}
class Te {
constructor(E) {
this.value = E;
}
static [y] = "Name";
brand;
getSQL() {
return new p([this]);
}
}
function WT(T) {
return typeof T == "object" && T !== null && "mapToDriverValue" in T && typeof T.mapToDriverValue == "function";
}
const nT = {
mapFromDriverValue: (T) => T
}, rT = {
mapToDriverValue: (T) => T
};
({
...nT,
...rT
});
class LE {
/**
* @param value - Parameter value
* @param encoder - Encoder to convert the value to a driver parameter
*/
constructor(E, e = rT) {
this.value = E, this.encoder = e;
}
static [y] = "Param";
brand;
getSQL() {
return new p([this]);
}
}
function n(T, ...E) {
const e = [];
(E.length > 0 || T.length > 0 && T[0] !== "") && e.push(new b(T[0]));
for (const [R, A] of E.entries())
e.push(A, new b(T[R + 1]));
return new p(e);
}
((T) => {
function E() {
return new p([]);
}
T.empty = E;
function e(r) {
return new p(r);
}
T.fromList = e;
function R(r) {
return new p([new b(r)]);
}
T.raw = R;
function A(r, S) {
const N = [];
for (const [O, i] of r.entries())
O > 0 && S !== void 0 && N.push(S), N.push(i);
return new p(N);
}
T.join = A;
function t(r) {
return new Te(r);
}
T.identifier = t;
function s(r) {
return new _E(r);
}
T.placeholder = s;
function I(r, S) {
return new LE(r, S);
}
T.param = I;
})(n || (n = {}));
((T) => {
class E {
constructor(R, A) {
this.sql = R, this.fieldAlias = A;
}
static [y] = "SQL.Aliased";
/** @internal */
isSelectionField = !1;
getSQL() {
return this.sql;
}
/** @internal */
clone() {
return new E(this.sql, this.fieldAlias);
}
}
T.Aliased = E;
})(p || (p = {}));
class _E {
constructor(E) {
this.name = E;
}
static [y] = "Placeholder";
getSQL() {
return new p([this]);
}
}
const yT = /* @__PURE__ */ Symbol.for("drizzle:IsDrizzleView");
class iT {
static [y] = "View";
/** @internal */
[AE];
/** @internal */
[yT] = !0;
constructor({ name: E, schema: e, selectedFields: R, query: A }) {
this[AE] = {
name: E,
originalName: E,
schema: e,
selectedFields: R,
query: A,
isExisting: !A,
isAlias: !1
};
}
getSQL() {
return new p([this]);
}
}
sE.prototype.getSQL = function() {
return new p([this]);
};
$.prototype.getSQL = function() {
return new p([this]);
};
IT.prototype.getSQL = function() {
return new p([this]);
};
function g(T, E) {
return WT(E) && !OT(T) && !h(T, LE) && !h(T, _E) && !h(T, sE) && !h(T, $) && !h(T, iT) ? new LE(T, E) : T;
}
const Z = (T, E) => n`${T} = ${g(E, T)}`, De = (T, E) => n`${T} <> ${g(E, T)}`;
function F(...T) {
const E = T.filter(
(e) => e !== void 0
);
if (E.length !== 0)
return E.length === 1 ? new p(E) : new p([
new b("("),
n.join(E, new b(" and ")),
new b(")")
]);
}
function IE(...T) {
const E = T.filter(
(e) => e !== void 0
);
if (E.length !== 0)
return E.length === 1 ? new p(E) : new p([
new b("("),
n.join(E, new b(" or ")),
new b(")")
]);
}
const pE = (T, E) => n`${T} > ${g(E, T)}`, EE = (T, E) => n`${T} >= ${g(E, T)}`, fE = (T, E) => n`${T} < ${g(E, T)}`, eE = (T, E) => n`${T} <= ${g(E, T)}`;
function BE(T, E) {
return Array.isArray(E) ? E.length === 0 ? n`false` : n`${T} in ${E.map((e) => g(e, T))}` : n`${T} in ${g(E, T)}`;
}
function Pe(T, E) {
return Array.isArray(E) ? E.length === 0 ? n`true` : n`${T} not in ${E.map((e) => g(e, T))}` : n`${T} not in ${g(E, T)}`;
}
function le(T) {
return n`${T} is null`;
}
function ce(T) {
return n`${T} is not null`;
}
function XT(T, E) {
if (Array.isArray(E)) {
if (E.length === 0)
throw new Error("arrayContains requires at least one value");
const e = n`${g(E, T)}`;
return n`${T} @> ${e}`;
}
return n`${T} @> ${g(E, T)}`;
}
function $T(T, E) {
if (Array.isArray(E)) {
if (E.length === 0)
throw new Error("arrayContained requires at least one value");
const e = n`${g(E, T)}`;
return n`${T} <@ ${e}`;
}
return n`${T} <@ ${g(E, T)}`;
}
function KT(T, E) {
if (Array.isArray(E)) {
if (E.length === 0)
throw new Error("arrayOverlaps requires at least one value");
const e = n`${g(E, T)}`;
return n`${T} && ${e}`;
}
return n`${T} && ${g(E, T)}`;
}
function Me(T) {
return n`${T} asc`;
}
function wT(T) {
return n`${T} desc`;
}
function Re(T) {
return n`count(${T || n.raw("*")})`.mapWith(Number);
}
function JT(T) {
return n`count(distinct ${T})`.mapWith(Number);
}
function w(T) {
return n`sum(${T})`.mapWith(String);
}
function OE(T) {
return n`max(${T})`.mapWith(h(T, sE) ? T : String);
}
function nE(T) {
return n`min(${T})`.mapWith(h(T, sE) ? T : String);
}
class Ie {
/**
* Default implementation returns template unchanged
* Override in specific adapters for database-specific preprocessing
*/
preprocessCalculatedTemplate(E) {
return E;
}
/**
* Helper method to build pattern for string matching
* Can be overridden by specific adapters if needed
*/
buildPattern(E, e) {
switch (E) {
case "contains":
case "notContains":
return `%${e}%`;
case "startsWith":
return `${e}%`;
case "endsWith":
return `%${e}`;
default:
return e;
}
}
}
class vT extends Ie {
getEngineType() {
return "postgres";
}
/**
* Build PostgreSQL time dimension using DATE_TRUNC function
* Extracted from executor.ts:649-670 and multi-cube-builder.ts:306-320
*/
buildTimeDimension(E, e) {
switch (E) {
case "year":
return n`DATE_TRUNC('year', ${e}::timestamp)`;
case "quarter":
return n`DATE_TRUNC('quarter', ${e}::timestamp)`;
case "month":
return n`DATE_TRUNC('month', ${e}::timestamp)`;
case "week":
return n`DATE_TRUNC('week', ${e}::timestamp)`;
case "day":
return n`DATE_TRUNC('day', ${e}::timestamp)::timestamp`;
case "hour":
return n`DATE_TRUNC('hour', ${e}::timestamp)`;
case "minute":
return n`DATE_TRUNC('minute', ${e}::timestamp)`;
case "second":
return n`DATE_TRUNC('second', ${e}::timestamp)`;
default:
return e;
}
}
/**
* Build PostgreSQL string matching conditions using ILIKE (case-insensitive)
* Extracted from executor.ts:807-813 and multi-cube-builder.ts:468-474
*/
buildStringCondition(E, e, R) {
switch (e) {
case "contains":
return n`${E} ILIKE ${`%${R}%`}`;
case "notContains":
return n`${E} NOT ILIKE ${`%${R}%`}`;
case "startsWith":
return n`${E} ILIKE ${`${R}%`}`;
case "endsWith":
return n`${E} ILIKE ${`%${R}`}`;
case "like":
return n`${E} LIKE ${R}`;
case "notLike":
return n`${E} NOT LIKE ${R}`;
case "ilike":
return n`${E} ILIKE ${R}`;
case "regex":
return n`${E} ~* ${R}`;
case "notRegex":
return n`${E} !~* ${R}`;
default:
throw new Error(`Unsupported string operator: ${e}`);
}
}
/**
* Build PostgreSQL type casting using :: syntax
* Extracted from various locations where ::timestamp was used
*/
castToType(E, e) {
switch (e) {
case "timestamp":
return n`${E}::timestamp`;
case "decimal":
return n`${E}::decimal`;
case "integer":
return n`${E}::integer`;
default:
throw new Error(`Unsupported cast type: ${e}`);
}
}
/**
* Build PostgreSQL AVG aggregation with COALESCE for NULL handling
* PostgreSQL AVG returns NULL for empty sets, so we use COALESCE for consistent behavior
* Extracted from multi-cube-builder.ts:284
*/
buildAvg(E) {
return n`COALESCE(AVG(${E}), 0)`;
}
/**
* Build PostgreSQL CASE WHEN conditional expression
*/
buildCaseWhen(E, e) {
const R = E.map((A) => n`WHEN ${A.when} THEN ${A.then}`).reduce((A, t) => n`${A} ${t}`);
return e !== void 0 ? n`CASE ${R} ELSE ${e} END` : n`CASE ${R} END`;
}
/**
* Build PostgreSQL boolean literal
* PostgreSQL uses TRUE/FALSE keywords
*/
buildBooleanLiteral(E) {
return E ? n`TRUE` : n`FALSE`;
}
/**
* Convert filter values - PostgreSQL uses native types
* No conversion needed for PostgreSQL
*/
convertFilterValue(E) {
return E;
}
/**
* Prepare date value for PostgreSQL
* PostgreSQL accepts Date objects directly
*/
prepareDateValue(E) {
return E;
}
/**
* PostgreSQL stores timestamps as native timestamp types
*/
isTimestampInteger() {
return !1;
}
/**
* PostgreSQL time dimensions already return proper values
* No conversion needed
*/
convertTimeDimensionResult(E) {
return E;
}
// ============================================
// Statistical & Window Function Methods
// ============================================
/**
* PostgreSQL has full support for statistical and window functions
*/
getCapabilities() {
return {
supportsStddev: !0,
supportsVariance: !0,
supportsPercentile: !0,
supportsWindowFunctions: !0,
supportsFrameClause: !0
};
}
/**
* Build PostgreSQL STDDEV aggregation
* Uses STDDEV_POP for population, STDDEV_SAMP for sample
*/
buildStddev(E, e = !1) {
const R = e ? "STDDEV_SAMP" : "STDDEV_POP";
return n`COALESCE(${n.raw(R)}(${E}), 0)`;
}
/**
* Build PostgreSQL VARIANCE aggregation
* Uses VAR_POP for population, VAR_SAMP for sample
*/
buildVariance(E, e = !1) {
const R = e ? "VAR_SAMP" : "VAR_POP";
return n`COALESCE(${n.raw(R)}(${E}), 0)`;
}
/**
* Build PostgreSQL PERCENTILE_CONT aggregation
* Uses ordered-set aggregate function
*/
buildPercentile(E, e) {
const R = e / 100;
return n`PERCENTILE_CONT(${R}) WITHIN GROUP (ORDER BY ${E})`;
}
/**
* Build PostgreSQL window function expression
* PostgreSQL has full window function support
*/
buildWindowFunction(E, e, R, A, t) {
const s = R && R.length > 0 ? n`PARTITION BY ${n.join(R, n`, `)}` : n``, I = A && A.length > 0 ? n`ORDER BY ${n.join(A.map(
(i) => i.direction === "desc" ? n`${i.field} DESC` : n`${i.field} ASC`
), n`, `)}` : n``;
let r = n``;
if (t?.frame) {
const { type: i, start: a, end: C } = t.frame, _ = i.toUpperCase(), P = a === "unbounded" ? "UNBOUNDED PRECEDING" : typeof a == "number" ? `${a} PRECEDING` : "CURRENT ROW", c = C === "unbounded" ? "UNBOUNDED FOLLOWING" : C === "current" ? "CURRENT ROW" : typeof C == "number" ? `${C} FOLLOWING` : "CURRENT ROW";
r = n`${n.raw(_)} BETWEEN ${n.raw(P)} AND ${n.raw(c)}`;
}
const S = [];
R && R.length > 0 && S.push(s), A && A.length > 0 && S.push(I), t?.frame && S.push(r);
const N = S.length > 0 ? n.join(S, n` `) : n``, O = n`OVER (${N})`;
switch (E) {
case "lag":
return n`LAG(${e}, ${t?.offset ?? 1}${t?.defaultValue !== void 0 ? n`, ${t.defaultValue}` : n``}) ${O}`;
case "lead":
return n`LEAD(${e}, ${t?.offset ?? 1}${t?.defaultValue !== void 0 ? n`, ${t.defaultValue}` : n``}) ${O}`;
case "rank":
return n`RANK() ${O}`;
case "denseRank":
return n`DENSE_RANK() ${O}`;
case "rowNumber":
return n`ROW_NUMBER() ${O}`;
case "ntile":
return n`NTILE(${t?.nTile ?? 4}) ${O}`;
case "firstValue":
return n`FIRST_VALUE(${e}) ${O}`;
case "lastValue":
return n`LAST_VALUE(${e}) ${O}`;
case "movingAvg":
return n`AVG(${e}) ${O}`;
case "movingSum":
return n`SUM(${e}) ${O}`;
default:
throw new Error(`Unsupported window function: ${E}`);
}
}
}
class aT extends Ie {
getEngineType() {
return "mysql";
}
/**
* Build MySQL time dimension using DATE_FORMAT function
* MySQL equivalent to PostgreSQL's DATE_TRUNC
*/
buildTimeDimension(E, e) {
const R = {
year: "%Y-01-01 00:00:00",
quarter: "%Y-%q-01 00:00:00",
// %q gives quarter (1,2,3,4), but we need to map this properly
month: "%Y-%m-01 00:00:00",
week: "%Y-%u-01 00:00:00",
// %u gives week of year
day: "%Y-%m-%d 00:00:00",
hour: "%Y-%m-%d %H:00:00",
minute: "%Y-%m-%d %H:%i:00",
second: "%Y-%m-%d %H:%i:%s"
};
switch (E) {
case "quarter":
return n`DATE_ADD(MAKEDATE(YEAR(${e}), 1), INTERVAL (QUARTER(${e}) - 1) * 3 MONTH)`;
case "week":
return n`DATE_SUB(${e}, INTERVAL WEEKDAY(${e}) DAY)`;
default: {
const A = R[E];
return A ? n`STR_TO_DATE(DATE_FORMAT(${e}, ${A}), '%Y-%m-%d %H:%i:%s')` : e;
}
}
}
/**
* Build MySQL string matching conditions using LIKE
* MySQL LIKE is case-insensitive by default (depending on collation)
* For guaranteed case-insensitive matching, we use LOWER() functions
*/
buildStringCondition(E, e, R) {
switch (e) {
case "contains":
return n`LOWER(${E}) LIKE ${`%${R.toLowerCase()}%`}`;
case "notContains":
return n`LOWER(${E}) NOT LIKE ${`%${R.toLowerCase()}%`}`;
case "startsWith":
return n`LOWER(${E}) LIKE ${`${R.toLowerCase()}%`}`;
case "endsWith":
return n`LOWER(${E}) LIKE ${`%${R.toLowerCase()}`}`;
case "like":
return n`${E} LIKE ${R}`;
case "notLike":
return n`${E} NOT LIKE ${R}`;
case "ilike":
return n`LOWER(${E}) LIKE ${R.toLowerCase()}`;
case "regex":
return n`${E} REGEXP ${R}`;
case "notRegex":
return n`${E} NOT REGEXP ${R}`;
default:
throw new Error(`Unsupported string operator: ${e}`);
}
}
/**
* Build MySQL type casting using CAST() function
* MySQL equivalent to PostgreSQL's :: casting syntax
*/
castToType(E, e) {
switch (e) {
case "timestamp":
return n`CAST(${E} AS DATETIME)`;
case "decimal":
return n`CAST(${E} AS DECIMAL(10,2))`;
case "integer":
return n`CAST(${E} AS SIGNED INTEGER)`;
default:
throw new Error(`Unsupported cast type: ${e}`);
}
}
/**
* Build MySQL AVG aggregation with IFNULL for NULL handling
* MySQL AVG returns NULL for empty sets, using IFNULL for consistency
*/
buildAvg(E) {
return n`IFNULL(AVG(${E}), 0)`;
}
/**
* Build MySQL CASE WHEN conditional expression
*/
buildCaseWhen(E, e) {
const R = E.map((A) => n`WHEN ${A.when} THEN ${A.then}`).reduce((A, t) => n`${A} ${t}`);
return e !== void 0 ? n`CASE ${R} ELSE ${e} END` : n`CASE ${R} END`;
}
/**
* Build MySQL boolean literal
* MySQL uses TRUE/FALSE keywords (equivalent to 1/0)
*/
buildBooleanLiteral(E) {
return E ? n`TRUE` : n`FALSE`;
}
/**
* Convert filter values - MySQL uses native types
* No conversion needed for MySQL
*/
convertFilterValue(E) {
return E;
}
/**
* Prepare date value for MySQL
* MySQL accepts Date objects directly
*/
prepareDateValue(E) {
return E;
}
/**
* MySQL stores timestamps as native timestamp types
*/
isTimestampInteger() {
return !1;
}
/**
* MySQL time dimensions already return proper values
* No conversion needed
*/
convertTimeDimensionResult(E) {
return E;
}
// ============================================
// Statistical & Window Function Methods
// ============================================
/**
* MySQL 8.0+ has support for statistical and window functions
* but not PERCENTILE_CONT
*/
getCapabilities() {
return {
supportsStddev: !0,
supportsVariance: !0,
supportsPercentile: !1,
// MySQL doesn't have PERCENTILE_CONT
supportsWindowFunctions: !0,
supportsFrameClause: !0
};
}
/**
* Build MySQL STDDEV aggregation
* Uses STDDEV_POP for population, STDDEV_SAMP for sample
*/
buildStddev(E, e = !1) {
const R = e ? "STDDEV_SAMP" : "STDDEV_POP";
return n`IFNULL(${n.raw(R)}(${E}), 0)`;
}
/**
* Build MySQL VARIANCE aggregation
* Uses VAR_POP for population, VAR_SAMP for sample
*/
buildVariance(E, e = !1) {
const R = e ? "VAR_SAMP" : "VAR_POP";
return n`IFNULL(${n.raw(R)}(${E}), 0)`;
}
/**
* MySQL does not support PERCENTILE_CONT
* Returns null for graceful degradation
*/
buildPercentile(E, e) {
return null;
}
/**
* Build MySQL window function expression
* MySQL 8.0+ has full window function support
*/
buildWindowFunction(E, e, R, A, t) {
const s = R && R.length > 0 ? n`PARTITION BY ${n.join(R, n`, `)}` : n``, I = A && A.length > 0 ? n`ORDER BY ${n.join(A.map(
(i) => i.direction === "desc" ? n`${i.field} DESC` : n`${i.field} ASC`
), n`, `)}` : n``;
let r = n``;
if (t?.frame) {
const { type: i, start: a, end: C } = t.frame, _ = i.toUpperCase(), P = a === "unbounded" ? "UNBOUNDED PRECEDING" : typeof a == "number" ? `${a} PRECEDING` : "CURRENT ROW", c = C === "unbounded" ? "UNBOUNDED FOLLOWING" : C === "current" ? "CURRENT ROW" : typeof C == "number" ? `${C} FOLLOWING` : "CURRENT ROW";
r = n`${n.raw(_)} BETWEEN ${n.raw(P)} AND ${n.raw(c)}`;
}
const S = [];
R && R.length > 0 && S.push(s), A && A.length > 0 && S.push(I), t?.frame && S.push(r);
const N = S.length > 0 ? n.join(S, n` `) : n``, O = n`OVER (${N})`;
switch (E) {
case "lag":
return n`LAG(${e}, ${t?.offset ?? 1}${t?.defaultValue !== void 0 ? n`, ${t.defaultValue}` : n``}) ${O}`;
case "lead":
return n`LEAD(${e}, ${t?.offset ?? 1}${t?.defaultValue !== void 0 ? n`, ${t.defaultValue}` : n``}) ${O}`;
case "rank":
return n`RANK() ${O}`;
case "denseRank":
return n`DENSE_RANK() ${O}`;
case "rowNumber":
return n`ROW_NUMBER() ${O}`;
case "ntile":
return n`NTILE(${t?.nTile ?? 4}) ${O}`;
case "firstValue":
return n`FIRST_VALUE(${e}) ${O}`;
case "lastValue":
return n`LAST_VALUE(${e}) ${O}`;
case "movingAvg":
return n`AVG(${e}) ${O}`;
case "movingSum":
return n`SUM(${e}) ${O}`;
default:
throw new Error(`Unsupported window function: ${E}`);
}
}
}
class xT extends Ie {
getEngineType() {
return "sqlite";
}
/**
* Build SQLite time dimension using date/datetime functions with modifiers
* For integer timestamp columns (milliseconds), first convert to datetime
* SQLite doesn't have DATE_TRUNC like PostgreSQL, so we use strftime and date modifiers
* Returns datetime strings for consistency with other databases
*/
buildTimeDimension(E, e) {
switch (E) {
case "year":
return n`datetime(${e}, 'unixepoch', 'start of year')`;
case "quarter": {
const R = n`datetime(${e}, 'unixepoch')`;
return n`datetime(${R}, 'start of year',
'+' || (((CAST(strftime('%m', ${R}) AS INTEGER) - 1) / 3) * 3) || ' months')`;
}
case "month":
return n`datetime(${e}, 'unixepoch', 'start of month')`;
case "week":
return n`date(datetime(${e}, 'unixepoch'), 'weekday 1', '-6 days')`;
case "day":
return n`datetime(${e}, 'unixepoch', 'start of day')`;
case "hour": {
const R = n`datetime(${e}, 'unixepoch')`;
return n`datetime(strftime('%Y-%m-%d %H:00:00', ${R}))`;
}
case "minute": {
const R = n`datetime(${e}, 'unixepoch')`;
return n`datetime(strftime('%Y-%m-%d %H:%M:00', ${R}))`;
}
case "second": {
const R = n`datetime(${e}, 'unixepoch')`;
return n`datetime(strftime('%Y-%m-%d %H:%M:%S', ${R}))`;
}
default:
return n`datetime(${e}, 'unixepoch')`;
}
}
/**
* Build SQLite string matching conditions using LOWER() + LIKE for case-insensitive matching
* SQLite LIKE is case-insensitive by default, but LOWER() ensures consistency
*/
buildStringCondition(E, e, R) {
switch (e) {
case "contains":
return n`LOWER(${E}) LIKE ${`%${R.toLowerCase()}%`}`;
case "notContains":
return n`LOWER(${E}) NOT LIKE ${`%${R.toLowerCase()}%`}`;
case "startsWith":
return n`LOWER(${E}) LIKE ${`${R.toLowerCase()}%`}`;
case "endsWith":
return n`LOWER(${E}) LIKE ${`%${R.toLowerCase()}`}`;
case "like":
return n`${E} LIKE ${R}`;
case "notLike":
return n`${E} NOT LIKE ${R}`;
case "ilike":
return n`LOWER(${E}) LIKE ${R.toLowerCase()}`;
case "regex":
return n`${E} GLOB ${R}`;
case "notRegex":
return n`${E} NOT GLOB ${R}`;
default:
throw new Error(`Unsupported string operator: ${e}`);
}
}
/**
* Build SQLite type casting using CAST() function
* SQLite has dynamic typing but supports CAST for consistency
*/
castToType(E, e) {
switch (e) {
case "timestamp":
return n`datetime(${E} / 1000, 'unixepoch')`;
case "decimal":
return n`CAST(${E} AS REAL)`;
case "integer":
return n`CAST(${E} AS INTEGER)`;
default:
throw new Error(`Unsupported cast type: ${e}`);
}
}
/**
* Build SQLite AVG aggregation with IFNULL for NULL handling
* SQLite AVG returns NULL for empty sets, using IFNULL for consistency
*/
buildAvg(E) {
return n`IFNULL(AVG(${E}), 0)`;
}
/**
* Build SQLite CASE WHEN conditional expression
*/
buildCaseWhen(E, e) {
const R = E.map((A) => A.then && typeof A.then == "object" && (A.then.queryChunks || A.then._ || A.then.sql) ? n`WHEN ${A.when} THEN ${n.raw("(")}${A.then}${n.raw(")")}` : n`WHEN ${A.when} THEN ${A.then}`).reduce((A, t) => n`${A} ${t}`);
return e !== void 0 ? e && typeof e == "object" && (e.queryChunks || e._ || e.sql) ? n`CASE ${R} ELSE ${n.raw("(")}${e}${n.raw(")")} END` : n`CASE ${R} ELSE ${e} END` : n`CASE ${R} END`;
}
/**
* Build SQLite boolean literal
* SQLite uses 1/0 for true/false
*/
buildBooleanLiteral(E) {
return E ? n`1` : n`0`;
}
/**
* Preprocess calculated measure templates for SQLite-specific handling
*
* SQLite performs integer division by default (5/2 = 2 instead of 2.5).
* This method wraps division operands with CAST to REAL to ensure float division.
*
* Pattern matched: {measure1} / {measure2} or {measure1} / NULLIF({measure2}, 0)
* Transforms to: CAST({measure1} AS REAL) / ...
*
* @param calculatedSql - Template string with {member} references
* @returns Preprocessed template with CAST for division operations
*/
preprocessCalculatedTemplate(E) {
const e = /(\{[^}]+\})\s*\/\s*/g;
return E.replace(e, (R, A) => `${A.replace(/\{([^}]+)\}/, "CAST({$1} AS REAL)")} / `);
}
/**
* Convert filter values to SQLite-compatible types
* SQLite doesn't support boolean types - convert boolean to integer (1/0)
* Convert Date objects to milliseconds for integer timestamp columns
*/
convertFilterValue(E) {
return typeof E == "boolean" ? E ? 1 : 0 : E instanceof Date ? E.getTime() : Array.isArray(E) ? E.map((e) => this.convertFilterValue(e)) : E;
}
/**
* Prepare date value for SQLite integer timestamp storage
* Convert Date objects to milliseconds (Unix timestamp * 1000)
*/
prepareDateValue(E) {
if (!(E instanceof Date)) {
if (typeof E == "number") return E;
if (typeof E == "string") return new Date(E).getTime();
throw new Error(`prepareDateValue expects a Date object, got ${typeof E}`);
}
return E.getTime();
}
/**
* SQLite stores timestamps as integers (milliseconds)
*/
isTimestampInteger() {
return !0;
}
/**
* Convert SQLite time dimension results back to Date objects
* SQLite time dimensions return datetime strings, but clients expect Date objects
*/
convertTimeDimensionResult(E) {
return E;
}
// ============================================
// Statistical & Window Function Methods
// ============================================
/**
* SQLite has limited statistical support (no native STDDEV/VARIANCE/PERCENTILE)
* but supports window functions since SQLite 3.25
*/
getCapabilities() {
return {
supportsStddev: !1,
// Requires extension
supportsVariance: !1,
// Requires extension
supportsPercentile: !1,
// Requires extension
supportsWindowFunctions: !0,
// SQLite 3.25+
supportsFrameClause: !0
};
}
/**
* SQLite does not have native STDDEV
* Returns null for graceful degradation
*/
buildStddev(E, e = !1) {
return null;
}
/**
* SQLite does not have native VARIANCE
* Returns null for graceful degradation
*/
buildVariance(E, e = !1) {
return null;
}
/**
* SQLite does not have native PERCENTILE
* Returns null for graceful degradation
*/
buildPercentile(E, e) {
return null;
}
/**
* Build SQLite window function expression
* SQLite 3.25+ supports window functions
*/
buildWindowFunction(E, e, R, A, t) {
const s = R && R.length > 0 ? n`PARTITION BY ${n.join(R, n`, `)}` : n``, I = A && A.length > 0 ? n`ORDER BY ${n.join(A.map(
(i) => i.direction === "desc" ? n`${i.field} DESC` : n`${i.field} ASC`
), n`, `)}` : n``;
let r = n``;
if (t?.frame) {
const { type: i, start: a, end: C } = t.frame, _ = i.toUpperCase(), P = a === "unbounded" ? "UNBOUNDED PRECEDING" : typeof a == "number" ? `${a} PRECEDING` : "CURRENT ROW", c = C === "unbounded" ? "UNBOUNDED FOLLOWING" : C === "current" ? "CURRENT ROW" : typeof C == "number" ? `${C} FOLLOWING` : "CURRENT ROW";
r = n`${n.raw(_)} BETWEEN ${n.raw(P)} AND ${n.raw(c)}`;
}
const S = [];
R && R.length > 0 && S.push(s), A && A.length > 0 && S.push(I), t?.frame && S.push(r);
const N = S.length > 0 ? n.join(S, n` `) : n``, O = n`OVER (${N})`;
switch (E) {
case "lag":
return n`LAG(${e}, ${t?.offset ?? 1}${t?.defaultValue !== void 0 ? n`, ${t.defaultValue}` : n``}) ${O}`;
case "lead":
return n`LEAD(${e}, ${t?.offset ?? 1}${t?.defaultValue !== void 0 ? n`, ${t.defaultValue}` : n``}) ${O}`;
case "rank":
return n`RANK() ${O}`;
case "denseRank":
return n`DENSE_RANK() ${O}`;
case "rowNumber":
return n`ROW_NUMBER() ${O}`;
case "ntile":
return n`NTILE(${t?.nTile ?? 4}) ${O}`;
case "firstValue":
return n`FIRST_VALUE(${e}) ${O}`;
case "lastValue":
return n`LAST_VALUE(${e}) ${O}`;
case "movingAvg":
return n`AVG(${e}) ${O}`;
case "movingSum":
return n`SUM(${e}) ${O}`;
default:
throw new Error(`Unsupported window function: ${E}`);
}
}
}
class QT extends aT {
getEngineType() {
return "singlestore";
}
// SingleStore inherits most MySQL functionality
// Override methods here only if SingleStore-specific behavior is needed
// Note: SingleStore has some known limitations:
// - ORDER BY and LIMIT cannot be chained together in some contexts
// - Nested selects with aggregation functions are not supported
// - Serial column type only assures uniqueness (tests may need ORDER BY)
// These limitations are typically handled at the query building level
// rather than in the adapter, but can be addressed here if needed
}
function ZT(T) {
switch (T) {
case "postgres":
return new vT();
case "mysql":
return new aT();
case "sqlite":
return new xT();
case "singlestore":
return new QT();
default:
throw new Error(`Unsupported database engine: ${T}`);
}
}
class Oe {
constructor(E, e, R) {
this.db = E, this.schema = e;
const A = R || this.getEngineType();
this.databaseAdapter = ZT(A);
}
databaseAdapter;
}
class jT extends Oe {
async execute(E, e) {
if (E && typeof E == "object" && typeof E.execute == "function") {
const A = await E.execute();
return Array.isArray(A) ? A.map((t) => this.convertNumericFields(t, e)) : A;
}
if (!this.db.execute)
throw new Error("PostgreSQL database instance must have an execute method");
const R = await this.db.execute(E);
return Array.isArray(R) ? R.map((A) => this.convertNumericFields(A, e)) : R;
}
/**
* Convert numeric string fields to numbers (only for measure fields)
*/
convertNumericFields(E, e) {
if (!E || typeof E != "object") return E;
const R = {};
for (const [A, t] of Object.entries(E))
e && e.includes(A) ? R[A] = this.coerceToNumber(t) : R[A] = t;
return R;
}
/**
* Coerce a value to a number if it represents a numeric type
*/
coerceToNumber(E) {
if (E == null || typeof E == "number") return E;
if (typeof E == "bigint") return Number(E);
if (E && typeof E == "object") {
if (typeof E.toString == "function") {
const e = E.toString();
if (/^-?\d+(\.\d+)?$/.test(e))
return e.includes(".") ? parseFloat(e) : parseInt(e, 10);
}
if (E.constructor?.name === "Numeric" || E.constructor?.name === "Decimal" || "digits" in E || "sign" in E) {
const e = E.toString();
return parseFloat(e);
}
return E;
}
if (typeof E == "string") {
if (/^-?\d+(\.\d+)?$/.test(E))
return E.includes(".") ? parseFloat(E) : parseInt(E, 10);
if (!isNaN(parseFloat(E)) && isFinite(parseFloat(E)))
return parseFloat(E);
}
return E;
}
getEngineType() {
return "postgres";
}
}
function ue(T, E) {
return new jT(T, E, "postgres");
}
class CT extends Oe {
async execute(E, e) {
if (E && typeof E == "object" && typeof E.execute == "function") {
const A = await E.execute();
return Array.isArray(A) ? A.map((t) => this.convertNumericFields(t, e)) : A;
}
if (!this.db.execute)
throw new Error("MySQL database instance must have an execute method");
const R = await this.db.execute(E);
return Array.isArray(R) ? R.map((A) => this.convertNumericFields(A, e)) : R;
}
/**
* Convert numeric string fields to numbers (measure fields + numeric dimensions)
*/
convertNumericFields(E, e) {
if (!E || typeof E != "object") return E;
const R = {};
for (const [A, t] of Object.entries(E))
e && e.includes(A) ? R[A] = this.coerceToNumber(t) : R[A] = t;
return R;
}
/**
* Coerce a value to a number if it represents a numeric type
*/
coerceToNumber(E) {
if (E == null || typeof E == "number") return E;
if (typeof E == "string") {
if (/^-?\d+(\.\d+)?$/.test(E))
return E.includes(".") ? parseFloat(E) : parseInt(E, 10);
if (!isNaN(parseFloat(E)) && isFinite(parseFloat(E)))
return parseFloat(E);
}
return E;
}
getEngineType() {
return "mysql";
}
}
function qT(T, E) {
return new CT(T, E, "mysql");
}
class kT extends Oe {
async execute(E, e) {
if (E && typeof E == "object" && typeof E.execute == "function") {
const R = await E.execute();
return Array.isArray(R) ? R.map((A) => this.convertNumericFields(A, e)) : R;
}
try {
if (this.db.all) {
const R = this.db.all(E);
return Array.isArray(R) ? R.map((A) => this.convertNumericFields(A, e)) : R;
} else {
if (this.db.run)
return this.db.run(E);
throw new Error("SQLite database instance must have an all() or run() method");
}
} catch (R) {
throw new Error(`SQLite execution failed: ${R instanceof Error ? R.message : "Unknown error"}`);
}
}
/**
* Convert numeric string fields to numbers (only for measure fields)
*/
convertNumericFields(E, e) {
if (!E || typeof E != "object") return E;
const R = {};
for (const [A, t] of Object.entries(E))
e && e.includes(A) ? R[A] = this.coerceToNumber(t) : R[A] = t;
return R;
}
/**
* Coerce a value to a number if it represents a numeric type
*/
coerceToNumber(E) {
if (E == null || typeof E == "number") return E;
if (typeof E == "string") {
if (/^-?\d+(\.\d+)?$/.test(E))
return E.includes(".") ? parseFloat(E) : parseInt(E, 10);
if (!isNaN(parseFloat(E)) && isFinite(parseFloat(E)))
return parseFloat(E);
}
return E;
}
getEngineType() {
return "sqlite";
}
}
function Ue(T, E) {
return new kT(T, E, "sqlite");
}
class zT extends CT {
getEngineType() {
return "singlestore";
}
// SingleStore-specific optimizations can be added here if needed
// For now, we inherit all behavior from MySQLExecutor since
// SingleStore is largely MySQL-compatible
}
function ER(T, E) {
return new zT(T, E);
}
function de(T, E, e) {
if (e)
switch (e) {
case "postgres":
return ue(T, E);
case "mysql":
return qT(T, E);
case "sqlite":
return Ue(T, E);
case "singlestore":
return ER(T, E);
}
if (T.all && T.run)
return Ue(T, E);
if (T.execute)
return ue(T, E);
throw new Error("Unable to determine database engine type. Please specify engineType parameter.");
}
function DE(T) {
return typeof T == "function" ? T() : T;
}
function Ae(T, E) {
if (E) return E;
switch (T) {
case "belongsTo":
return "inner";
// FK should exist
case "hasOne":
return "left";
// Parent may have no child
case "hasMany":
return "left";
// Parent may have no children
case "belongsToMany":
return "left";
// Many-to-many through junction table
default:
return "left";
}
}
function te(T) {
return T && typeof T == "object" ? n`${n`${T}`}` : T;
}
function W(T, E) {
const e = typeof T == "function" ? T(E) : T;
return te(e);
}
function eR(T, E) {
if (T.relationship !== "belongsToMany" || !T.through)
throw new Error("expandBelongsToManyJoin can only be called on belongsToMany relationships with through configuration");
const { table: e, sourceKey: R, targetKey: A, securitySql: t } = T.through, s = [];
for (const N of R) {
const O = N.as || Z;
s.push(O(N.source, N.target));
}
const I = [];
for (const N of A) {
const O = N.as || Z;
I.push(O(N.source, N.target));
}
let r;
if (t) {
const N = t(E);
r = Array.isArray(N) ? N : [N];
}
const S = Ae("belongsToMany", T.sqlJoinType);
return {
junctionJoins: [
{
joinType: S,
table: e,
condition: F(...s)
},
{
joinType: S,
table: e,
// This will be replaced with target cube table in query planner
condition: F(...I)
}
],
junctionSecurityConditions: r
};
}
function PE(T) {
if ("and" in T)
return `and:[${T.and.map(PE).sort().join(",")}]`;
if ("or" in T)
return `or:[${T.or.map(PE).sort().join(",")}]`;
const E = T, e = JSON.stringify(
Array.isArray(E.values) ? [...E.values].sort() : E.values
), R = E.dateRange ? `:dr:${JSON.stringify(E.dateRange)}` : "";
return `${E.member}:${E.operator}:${e}${R}`;
}
function oT(T, E) {
return `timeDim:${T}:${JSON.stringify(E)}`;
}
class me {
cache = /* @__PURE__ */ new Map();
stats = { hits: 0, misses: 0 };
/**
* Get cached SQL or build and cache it
*
* @param key - The cache key (use getFilterKey or getTimeDimensionFilterKey)
* @param builder - Function to build the SQL if not cached
* @returns The cached or freshly built SQL, or null if builder returns null
*/
getOrBuild(E, e) {
const R = this.cache.get(E);
if (R !== void 0)
return this.stats.hits++, R;
const A = e();
return A && this.cache.set(E, A), this.stats.misses++, A;
}
/**
* Check if a key exists in the cache without affecting stats
*/
has(E) {
return this.cache.has(E);
}
/**
* Get cached SQL without building (returns undefined if not cached)
*/
get(E) {
const e = this.cache.get(E);
return e !== void 0 && this.stats.hits++, e;
}
/**
* Pre-populate cache with multiple filters
* Useful for batch initialization at query start
*/
preload(E) {
for (const { key: e, sql: R } of E)
this.cache.has(e) || this.cache.set(e, R);
}
/**
* Store a single entry in the cache
*/
set(E, e) {
this.cache.set(E, e);
}
/**
* Get cache statistics for debugging
*/
getStats() {
return { ...this.stats, cacheSize: this.cache.size };
}
/**
* Clear the cache (normally not needed as cache is per-query)
*/
clear() {
this.cache.clear(), this.stats = { hits: 0, misses: 0 };
}
}
function se(T) {
const E = [];
for (const e of T)
"and" in e && e.and ? E.push(...se(e.and)) : "or" in e && e.or ? E.push(...se(e.or)) : "member" in e && E.push(e);
return E;
}
function TR(T, E, e = {}) {
const R = e.keyPrefix ?? "drizzle-cube:", A = RR(T), t = Ge(JSON.stringify(A));
let s = `${R}query:${t}`;
if (e.includeSecurityContext !== !1) {
const I = e.securityContextSerializer ? e.securityContextSerializer(E) : JSON.stringify(lE(E)), r = Ge(I);
s += `:ctx:${r}`;
}
return s;
}
function RR(T) {
return {
measures: T.measures ? [...T.measures].sort() : void 0,
dimensions: T.dimensions ? [...T.dimensions].sort() : void 0,
filters: T.filters ? Se(T.filters) : void 0,
timeDimensions: T.timeDimensions ? AR(T.timeDimensions) : void 0,
limit: T.limit,
offset: T.offset,
order: T.order ? lE(T.order) : void 0,
fillMissingDatesValue: T.fillMissingDatesValue
};
}
function Se(T) {
return [...T].map((E) => {
if ("and" in E && E.and)
return { and: Se(E.and) };
if ("or" in E && E.or)
return { or: Se(E.or) };
const e = E;
return {
...e,
values: e.values ? [...e.values].sort() : e.values
};
}).sort((E, e) => JSON.stringify(E).localeCompare(JSON.stringify(e)));
}
function AR(T) {
return [...T].map((E) => ({
dimension: E.dimension,
granularity: E.granularity,
dateRange: E.dateRange,
fillMissingDates: E.fillMissingDates,
compareDateRange: E.compareDateRange ? [...E.compareDateRange].sort((e, R) => {
const A = Array.isArray(e) ? e.join("-") : e, t = Array.isArray(R) ? R.join("-") : R;
return A.localeCompare(t);
}) : void 0
})).sort((E, e) => E.dimension.localeCompare(e.dimension));
}
function lE(T) {
return T === null || typeof T != "object" ? T : Array.isArray(T) ? T.map(lE) : Object.keys(T).sort().reduce((E, e) => (E[e] = lE(
T[e]
), E), {});
}
function Ge(T) {
let E = 2166136261;
for (let e = 0; e < T.length; e++)
E ^= T.charCodeAt(e), E = E * 16777619 >>> 0;
return E.toString(16).padStart(8, "0");
}
class LT {
constructor(E) {
this.databaseAdapter = E;
}
/**
* Build time dimension expression with granularity using database adapter
*/
buildTimeDimensionExpression(E, e, R) {
const A = W(E, R);
return e ? this.databaseAdapter.buildTimeDimension(e, A) : A instanceof p ? A : n`${A}`;
}
/**
* Build date range condition for time dimensions
*/
buildDateRangeCondition(E, e) {
if (!e) return null;
if (Array.isArray(e) && e.length >= 2) {
const R = this.normalizeDate(e[0]);
let A = this.normalizeDate(e[1]);
if (!R || !A) return null;
if (typeof e[1] == "string" && /^\d{4}-\d{2}-\d{2}$/.test(e[1].trim())) {
const t = typeof A == "number" ? new Date(A * (this.databaseAdapter.getEngineType() === "sqlite" ? 1e3 : 1)) : new Date(A), s = new Date(t);
s.setUTCHours(23, 59, 59, 999), this.databaseAdapter.isTimestampInteger() ? A = this.databaseAdapter.getEngineType() === "sqlite" ? Math.floor(s.getTime() / 1e3) : s.getTime() : A = s.toISOString();
}
return F(
EE(E, R),
eE(E, A)
);
}
if (typeof e == "string") {
const R = this.parseRelativeDateRange(e);
if (R) {
let N, O;
return this.databaseAdapter.isTimestampInteger() ? this.databaseAdapter.getEngineType() === "sqlite" ? (N = Math.floor(R.start.getTime() / 1e3), O = Math.floor(R.end.getTime() / 1e3)) : (N = R.start.getTime(), O = R.end.getTime()) : (N = R.start.toISOString(), O = R.end.toISOString()), F(
EE(E, N),
eE(E, O)
);
}
const A = this.normalizeDate(e);
if (!A) return null;
const t = typeof A == "number" ? new Date(A * (this.databaseAdapter.getEngineType() === "sqlite" ? 1e3 : 1)) : new Date(A), s = new Date(t);
s.setUTCHours(0, 0, 0, 0);
const I = new Date(t);
I.setUTCHours(23, 59, 59, 999);
let r, S;
return this.databaseAdapter.isTimestampInteger() ? this.databaseAdapter.getEngineType() === "sqlite" ? (r = Math.floor(s.getTime() / 1e3), S = Math.floor(I.getTime() / 1e3)) : (r = s.getTime(), S = I.getTime()) : (r = s.toISOString(), S = I.toISOString()), F(
EE(E, r),
eE(E, S)
);
}
return null;
}
/**
* Parse relative date range expressions like "today", "yesterday", "last 7 days", "this month", etc.
* Handles all 14 DATE_RANGE_OPTIONS from the client
*/
parseRelativeDateRange(E) {
const e = /* @__PURE__ */ new Date(), R = E.toLowerCase().trim(), A = e.getUTCFullYear(), t = e.getUTCMonth(), s = e.getUTCDate(), I = e.getUTCDay();
if (R === "today") {
const i = new Date(e);
i.setUTCHours(0, 0, 0, 0);
const a = new Date(e);
return a.setUTCHours(23, 59, 59, 999), { start: i, end: a };
}
if (R === "yesterday") {
const i = new Date(e);
i.setUTCDate(s - 1), i.setUTCHours(0, 0, 0, 0);
const a = new Date(e);
return a.setUTCDate(s - 1), a.setUTCHours(23, 59, 59, 999), { start: i, end: a };
}
if (R === "this week") {
const i = I === 0 ? -6 : 1 - I, a = new Date(e);
a.setUTCDate(s + i), a.setUTCHours(0, 0, 0, 0);
const C = new Date(a);
return C.setUTCDate(a.getUTCDate() + 6), C.setUTCHours(23, 59, 59, 999), { start: a, end: C };
}
if (R === "this month") {
const i = new Date(Date.UTC(A, t, 1, 0, 0, 0, 0)), a = new Date(Date.UTC(A, t + 1, 0, 23, 59, 59, 999));
return { start: i, end: a };
}
if (R === "this quarter") {
const i = Math.floor(t / 3), a = new Date(Date.UTC(A, i * 3, 1, 0, 0, 0, 0)), C = new Date(Date.UTC(A, i * 3 + 3, 0, 23, 59, 59, 999));
return { start: a, end: C };
}
if (R === "this year") {
const i = new Date(Date.UTC(A, 0, 1, 0, 0, 0, 0)), a = new Date(Date.UTC(A, 11, 31, 23, 59, 59, 999));
return { start: i, end: a };
}
const r = R.match(/^last\s+(\d+)\s+days?$/);
if (r) {
const i = parseInt(r[1], 10), a = new Date(e);
a.setUTCDate(s - i + 1), a.setUTCHours(0, 0, 0, 0);
const C = new Date(e);
return C.setUTCHours(23, 59, 59, 999), { start: a, end: C };
}
const S = R.match(/^last\s+(\d+)\s+weeks?$/);
if (S) {
const a = parseInt(S[1], 10) * 7, C = new Date(e);
C.setUTCDate(s - a + 1), C.setUTCHours(0, 0, 0, 0);
const _ = new Date(e);
return _.setUTCHours(23, 59, 59, 999), { start: C, end: _ };
}
if (R === "last week") {
const i = I === 0 ? -13 : -6 - I, a = new Date(e);
a.setUTCDate(s + i), a.setUTCHours(0, 0, 0, 0);
const C = new Date(a);
return C.setUTCDate(a.getUTCDate() + 6), C.setUTCHours(23, 59, 59, 999), { start: a, end: C };
}
if (R === "last month") {
const i = new Date(Date.UTC(A, t - 1, 1, 0, 0, 0, 0)), a = new Date(Date.UTC(A, t, 0, 23, 59, 59, 999));
return { start: i, end: a };
}
if (R === "last quarter") {
const i = Math.floor(t / 3), a = i === 0 ? 3 : i - 1, C = i === 0 ? A - 1 : A, _ = new Date(Date.UTC(C, a * 3, 1, 0, 0, 0, 0)), P = new Date(Date.UTC(C, a * 3 + 3, 0, 23, 59, 59, 999));
return { start: _, end: P };
}
if (R === "last year") {
const i = new Date(Date.UTC(A - 1, 0, 1, 0, 0, 0, 0)), a = new Date(Date.UTC(A - 1, 11, 31, 23, 59, 59, 999));
return { start: i, end: a };
}
if (R === "last 12 months") {
const i = new Date(Date.UTC(A, t - 11, 1, 0, 0, 0, 0)), a = new Date(e);
return a.setUTCHours(23, 59, 59, 999), { start: i, end: a };
}
const N = R.match(/^last\s+(\d+)\s+months?$/);
if (N) {
const i = parseInt(N[1], 10), a = new Date(Date.UTC(A, t - i + 1, 1, 0, 0, 0, 0)), C = new Date(e);
return C.setUTCHours(23, 59, 59, 999), { start: a, end: C };
}
const O = R.match(/^last\s+(\d+)\s+years?$/);
if (O) {
const i = parseInt(O[1], 10), a = new Date(Date.UTC(A - i, 0, 1, 0, 0, 0, 0)), C = new Date(e);
return C.setUTCHours(23, 59, 59, 999), { start: a, end: C };
}
return null;
}
/**
* Normalize date values to handle strings, numbers, and Date objects
* Returns ISO string for PostgreSQL/MySQL, Unix timestamp for SQLite, or null
* Ensures dates are in the correct format for each database engine
*/
normalizeDate(E) {
if (!E) return null;
if (E instanceof Date)
return isNaN(E.getTime()) ? null : this.databaseAdapter.isTimestampInteger() ? this.databaseAdapter.getEngineType() === "sqlite" ? Math.floor(E.getTime() / 1e3) : E.getTime() : E.toISOString();
if (typeof E == "number") {
const R = E < 1e10 ? E * 1e3 : E, A = new Date(R);
return isNaN(A.getTime()) ? null : this.databaseAdapter.isTimestampInteger() ? this.databaseAdapter.getEngineType() === "sqlite" ? Math.floor(R / 1e3) : R : A.toISOString();
}
if (typeof E == "string") {
if (/^\d{4}-\d{2}-\d{2}$/.test(E.trim())) {
const A = /* @__PURE__ */ new Date(E + "T00:00:00Z");
return isNaN(A.getTime()) ? null : this.databaseAdapter.isTimestampInteger() ? this.databaseAdapter.getEngineType() === "sqlite" ? Math.floor(A.getTime() / 1e3) : A.getTime() : A.toISOString();
}
const R = new Date(E);
return isNaN(R.getTime()) ? null : this.databaseAdapter.isTimestampInteger() ? this.databaseAdapter.getEngineType() === "sqlite" ? Math.floor(R.getTime() / 1e3) : R.getTime() : R.toISOString();
}
const e = new Date(E);
return isNaN(e.getTime()) ? null : this.databaseAdapter.isTimestampInteger() ? this.databaseAdapter.getEngineType() === "sqlite" ? Math.floor(e.getTime() / 1e3) : e.getTime() : e.toISOString();
}
}
class tR {
constructor(E, e) {
this.databaseAdapter = E, this.dateTimeBuilder = e;
}
/**
* Build filter condition using Drizzle operators
*/
buildFilterCondition(E, e, R, A, t) {
if (t !== void 0) {
if (e !== "inDateRange")
throw new Error(
`dateRange can only be used with 'inDateRange' operator, but got '${e}'. Use explicit date values in the 'values' array for other date operators.`
);
if (A && A.type !== "time")
throw new Error(
`dateRange can only be used on time dimensions, but field '${A.name || "unknown"}' has type '${A.type}'`
);
return this.dateTimeBuilder.buildDateRangeCondition(E, t);
}
if (!R || R.length === 0)
return e === "equals" ? this.databaseAdapter.buildBooleanLiteral(!1) : null;
const s = R.filter((r) => !(r == null || r === "" || typeof r == "string" && r.includes("\0"))).map(this.databaseAdapter.convertFilterValue);
if (s.length === 0 && !["set", "notSet"].includes(e))
return e === "equals" ? this.databaseAdapter.buildBooleanLiteral(!1) : null;
const I = s[0];
switch (e) {
case "equals":
if (s.length > 1) {
if (A?.type === "time") {
const r = s.map((S) => this.dateTimeBuilder.normalizeDate(S) || S);
return BE(E, r);
}
return BE(E, s);
} else if (s.length === 1) {
const r = A?.type === "time" && this.dateTimeBuilder.normalizeDate(I) || I;
return Z(E, r);
}
return this.databaseAdapter.buildBooleanLiteral(!1);
case "notEquals":
return s.length > 1 ? Pe(E, s) : s.length === 1 ? De(E, I) : null;
case "contains":
return this.databaseAdapter.buildStringCondition(E, "contains", I);
case "notContains":
return this.databaseAdapter.buildStringCondition(E, "notContains", I);
case "startsWith":
return this.databaseAdapter.buildStringCondition(E, "startsWith", I);
case "endsWith":
return this.databaseAdapter.buildStringCondition(E, "endsWith", I);
case "gt":
return pE(E, I);
case "gte":
return EE(E, I);
case "lt":
return fE(E, I);
case "lte":
return eE(E, I);
case "set":
return ce(E);
case "notSet":
return le(E);
case "inDateRange":
if (s.length >= 2) {
const r = this.dateTimeBuilder.normalizeDate(s[0]);
let S = this.dateTimeBuilder.normalizeDate(s[1]);
if (r && S) {
const N = R[1];
if (typeof N == "string" && /^\d{4}-\d{2}-\d{2}$/.test(N.trim())) {
const O = typeof S == "number" ? new Date(S * (this.databaseAdapter.getEngineType() === "sqlite" ? 1e3 : 1)) : new Date(S), i = new Date(O);
i.setUTCHours(23, 59, 59, 999), this.databaseAdapter.isTimestampInteger() ? S = this.databaseAdapter.getEngineType() === "sqlite" ? Math.floor(i.getTime() / 1e3) : i.getTime() : S = i.toISOString();
}
return F(
EE(E, r),
eE(E, S)
);
}
}
return null;
case "beforeDate": {
const r = this.dateTimeBuilder.normalizeDate(I);
return r ? fE(E, r) : null;
}
case "afterDate": {
const r = this.dateTimeBuilder.normalizeDate(I);
return r ? pE(E, r) : null;
}
case "between":
return s.length >= 2 ? F(
EE(E, s[0]),
eE(E, s[1])
) : null;
case "notBetween":
return s.length >= 2 ? IE(
fE(E, s[0]),
pE(E, s[1])
) : null;
case "in":
return s.length > 0 ? BE(E, s) : null;
case "notIn":
return s.length > 0 ? Pe(E, s) : null;
case "like":
return this.databaseAdapter.buildStringCondition(E, "like", I);
case "notLike":
return this.databaseAdapter.buildStringCondition(E, "notLike", I);
case "ilike":
return this.databaseAdapter.buildStringCondition(E, "ilike", I);
case "regex":
return this.databaseAdapter.buildStringCondition(E, "regex", I);
case "notRegex":
return this.databaseAdapter.buildStringCondition(E, "notRegex", I);
case "isEmpty":
return IE(
le(E),
Z(E, "")
);
case "isNotEmpty":
return F(
ce(E),
De(E, "")
);
// PostgreSQL array operators - silent no-op for other databases
// These use Drizzle's built-in array operator functions
case "arrayContains":
return this.databaseAdapter.getEngineType() === "postgres" ? XT(E, s) : null;
case "arrayOverlaps":
return this.databaseAdapter.getEngineType() === "postgres" ? KT(E, s) : null;
case "arrayContained":
return this.databaseAdapter.getEngineType() === "postgres" ? $T(E, s) : null;
default:
return null;
}
}
/**
* Build a logical filter (AND/OR) - used by executor for cache preloading
* This handles nested filter structures and builds combined SQL
*/
buildLogicalFilter(E, e, R) {
if ("and" in E && E.and) {
const A = E.and.map((t) => this.buildSingleFilter(t, e, R)).filter((t) => t !== null);
return A.length > 0 ? A.length === 1 ? A[0] : F(...A) : null;
}
if ("or" in E && E.or) {
const A = E.or.map((t) => this.buildSingleFilter(t, e, R)).filter((t) => t !== null);
return A.length > 0 ? A.length === 1 ? A[0] : IE(...A) : null;
}
return null;
}
/**
* Build SQL for a single filter condition (simple or logical)
* Used for cache preloading to build filters independently of query context
*/
buildSingleFilter(E, e, R) {
if ("and" in E || "or" in E)
return this.buildLogicalFilter(E, e, R);
const A = E, [t, s] = A.member.split("."), I = e.get(t);
if (!I) return null;
const r = I.dimensions?.[s];
if (!r) return null;
const S = W(r.sql, R);
return this.buildFilterCondition(
S,
A.operator,
A.values,
r,
A.dateRange
);
}
}
class Q {
dependencyGraph;
cubes;
constructor(E) {
this.cubes = E instanceof Map ? E : /* @__PURE__ */ new Map([[E.name, E]]), this.dependencyGraph = /* @__PURE__ */ new Map();
}
/**
* Extract {member} references from calculatedSql template
* Supports both {measure} and {Cube.measure} syntax
*
* @param calculatedSql - Template string with {member} references
* @returns Array of dependency information
*/
extractDependencies(E) {
const e = /\{([^}]+)\}/g, R = E.matchAll(e), A = [];
for (const t of R) {
const s = t[1].trim();
if (s.includes(".")) {
const [I, r] = s.split(".");
A.push({
measureName: s,
cubeName: I.trim(),
fieldName: r.trim()
});
} else
A.push({
measureName: s,
cubeName: null,
fieldName: s
});
}
return A;
}
/**
* Build dependency graph for all calculated measures in a cube
*
* @param cube - The cube containing measures
*/
buildGraph(E) {
for (const [e, R] of Object.entries(E.measures))
if (R.type === "calculated" && R.calculatedSql) {
const A = `${E.name}.${e}`, t = this.extractDependencies(R.calculatedSql), s = /* @__PURE__ */ new Set();
for (const I of t) {
const S = `${I.cubeName || E.name}.${I.fieldName}`;
s.add(S);
}
this.dependencyGraph.set(A, {
id: A,
dependencies: s,
inDegree: 0
});
}
this.calculateInDegrees();
}
/**
* Build dependency graph for multiple cubes
*
* @param cubes - Map of cubes to analyze
*/
buildGraphForMultipleCubes(E) {
for (const e of E.values())
this.buildGraph(e);
}
/**
* Calculate in-degree for each node (number of measures depending on it)
*/
calculateInDegrees() {
for (const E of this.dependencyGraph.values())
E.inDegree = 0;
for (const E of this.dependencyGraph.values())
for (const e of E.dependencies) {
const R = this.dependencyGraph.get(e);
R && R.inDegree++;
}
}
/**
* Perform topological sort using Kahn's algorithm
* Returns measures in dependency order (dependencies first)
*
* @param measureNames - List of measure names to sort
* @returns Sorted array of measure names
* @throws Error if circular dependency detected
*/
topologicalSort(E) {
const e = /* @__PURE__ */ new Map(), R = [], A = [];
for (const t of E) {
const s = this.dependencyGraph.get(t);
s && e.set(t, {
id: s.id,
dependencies: new Set(s.dependencies),
inDegree: 0
// Will recalculate below
});
}
for (const t of e.values()) {
let s = 0;
for (const I of t.dependencies)
e.has(I) && s++;
t.inDegree = s;
}
for (const [t, s] of e)
s.inDegree === 0 && R.push(t);
for (; R.length > 0; ) {
const t = R.shift();
A.push(t);
for (const [s, I] of e)
I.dependencies.has(t) && (I.inDegree--, I.inDegree === 0 && R.push(s));
}
if (A.length < e.size) {
const t = this.detectCycle();
throw new Error(
`Circular dependency detected in calculated measures: ${t ? t.join(" -> ") : "unknown cycle"}`
);
}
return A;
}
/**
* Detect circular dependencies using DFS
* Returns the cycle path if found, null otherwise
*
* @returns Array representing the cycle, or null
*/
detectCycle() {
const E = /* @__PURE__ */ new Set(), e = /* @__PURE__ */ new Set(), R = [];
for (const A of this.dependencyGraph.keys())
if (!E.has(A)) {
const t = this.dfs(A, E, e, R);
if (t)
return t;
}
return null;
}
/**
* DFS helper for cycle detection
*/
dfs(E, e, R, A) {
e.add(E), R.add(E), A.push(E);
const t = this.dependencyGraph.get(E);
if (!t)
return A.pop(), R.delete(E), null;
for (const s of t.dependencies)
if (e.has(s)) {
if (R.has(s)) {
const I = A.indexOf(s);
return [...A.slice(I), s];
}
} else {
const I = this.dfs(s, e, R, A);
if (I)
return I;
}
return A.pop(), R.delete(E), null;
}
/**
* Get all dependencies for a specific measure (direct and transitive)
*
* @param measureName - Full measure name (e.g., "Cube.measure")
* @returns Set of all dependency measure names
*/
getAllDependencies(E) {
const e = /* @__PURE__ */ new Set(), R = /* @__PURE__ */ new Set(), A = (t) => {
if (R.has(t)) return;
R.add(t);
const s = this.dependencyGraph.get(t);
if (s)
for (const I of s.dependencies)
e.add(I), A(I);
};
return A(E), e;
}
/**
* Validate that all dependencies exist
*
* @param cube - The cube to validate
* @throws Error if dependencies are missing
*/
validateDependencies(E) {
for (const [e, R] of Object.entries(E.measures))
if (R.type === "calculated" && R.calculatedSql) {
const A = this.extractDependencies(R.calculatedSql);
for (const t of A) {
const s = t.cubeName || E.name, I = this.cubes.get(s);
if (!I)
throw new Error(
`Calculated measure '${E.name}.${e}' references unknown cube '${s}'`
);
if (!I.measures[t.fieldName])
throw new Error(
`Calculated measure '${E.name}.${e}' references unknown measure '${t.measureName}'`
);
if (s === E.name && t.fieldName === e)
throw new Error(
`Calculated measure '${E.name}.${e}' cannot reference itself`
);
}
}
}
/**
* Auto-populate dependencies array for calculated measures
* Updates the measure objects with detected dependencies
*
* @param cube - The cube to update
*/
populateDependencies(E) {
for (const [, e] of Object.entries(E.measures))
if (e.type === "calculated" && e.calculatedSql && !e.dependencies) {
const R = this.extractDependencies(e.calculatedSql);
e.dependencies = R.map((A) => A.measureName);
}
}
/**
* Check if a measure is a calculated measure
*
* @param measure - The measure to check
* @returns True if the measure is calculated
*/
static isCalculatedMeasure(E) {
return E.type === "calculated" && !!E.calculatedSql;
}
}
function sR(T, E) {
const { cube: e, allCubes: R, resolvedMeasures: A } = E, t = ne(T), s = /* @__PURE__ */ new Map();
for (const O of t) {
const { originalRef: i, cubeName: a, fieldName: C } = O, _ = a || e.name;
if (!R.get(_))
throw new Error(
`Cannot substitute {${i}}: cube '${_}' not found`
);
const c = `${_}.${C}`, L = A.get(c);
if (!L)
throw new Error(
`Cannot substitute {${i}}: measure '${c}' not resolved yet. Ensure measures are resolved in dependency order.`
);
const u = L(), M = n`${u}`;
s.set(i, M);
}
const I = [], r = [];
let S = 0;
for (const O of t) {
const i = `{${O.originalRef}}`, a = T.indexOf(i, S);
if (a >= 0) {
I.push(T.substring(S, a));
const C = s.get(O.originalRef);
C && r.push(C), S = a + i.length;
}
}
if (I.push(T.substring(S)), r.length === 0)
return n.raw(T);
const N = [];
for (let O = 0; O < I.length; O++)
I[O] && N.push(new b(I[O])), O < r.length && N.push(r[O]);
return n.join(N, n.raw(""));
}
function ne(T) {
const E = /\{([^}]+)\}/g, e = T.matchAll(E), R = [];
for (const A of e) {
const t = A[1].trim();
if (t.includes(".")) {
const [s, I] = t.split(".").map((r) => r.trim());
R.push({
originalRef: t,
cubeName: s,
fieldName: I
});
} else
R.push({
originalRef: t,
cubeName: null,
fieldName: t
});
}
return R;
}
function SR(T) {
const E = [];
let e = 0;
for (let s = 0; s < T.length; s++)
if (T[s] === "{")
e++;
else if (T[s] === "}" && (e--, e < 0)) {
E.push(`Unmatched closing brace at position ${s}`);
break;
}
e > 0 && E.push("Unmatched opening brace in template"), /\{\s*\}/.test(T) && E.push("Empty member reference {} found in template"), /\{[^}]*\{/.test(T) && E.push("Nested braces are not allowed in member references");
const t = ne(T);
for (const s of t) {
const I = s.cubeName ? `${s.cubeName}.${s.fieldName}` : s.fieldName;
/^[a-zA-Z_][a-zA-Z0-9_.]*$/.test(I) || E.push(
`Invalid member reference {${s.originalRef}}: must start with letter or underscore, and contain only letters, numbers, underscores, and dots`
), I.split(".").length > 2 && E.push(
`Invalid member reference {${s.originalRef}}: only one dot allowed (Cube.measure format)`
);
}
return {
isValid: E.length === 0,
errors: E
};
}
function hE(T, E) {
const e = ne(T), R = /* @__PURE__ */ new Set();
for (const A of e) {
const s = `${A.cubeName || E}.${A.fieldName}`;
R.add(s);
}
return Array.from(R);
}
class B {
constructor(E) {
this.databaseAdapter = E;
}
/**
* Build resolvedMeasures map for a set of measures
* This centralizes the logic for building both regular and calculated measures
* in dependency order, avoiding duplication across main queries and CTEs
*
* @param measureNames - Array of measure names to resolve (e.g., ["Employees.count", "Employees.activePercentage"])
* @param cubeMap - Map of all cubes involved in the query
* @param context - Query context with database and security context
* @param customMeasureBuilder - Optional function to override how individual measures are built
* @returns Map of measure names to SQL builder functions
*/
buildResolvedMeasures(E, e, R, A) {
const t = /* @__PURE__ */ new Map(), s = [], I = [], r = new Set(E), S = new Q(e);
for (const N of e.values())
S.buildGraph(N);
for (const N of E) {
const [O, i] = N.split("."), a = e.get(O);
if (a && a.measures && a.measures[i]) {
const C = a.measures[i];
if (B.isPostAggregationWindow(C)) {
const _ = B.getWindowBaseMeasure(C, O);
_ && r.add(_);
continue;
}
Q.isCalculatedMeasure(C) ? (I.push(N), hE(C.calculatedSql, O).forEach((c) => r.add(c)), S.getAllDependencies(N).forEach((c) => {
const [L, u] = c.split("."), M = e.get(L);
if (M && M.measures[u]) {
const d = M.measures[u];
Q.isCalculatedMeasure(d) && hE(d.calculatedSql, L).forEach((f) => r.add(f));
}
})) : s.push(N);
}
}
for (const N of r) {
const [O, i] = N.split("."), a = e.get(O);
if (a && a.measures && a.measures[i]) {
const C = a.measures[i];
if (B.isPostAggregationWindow(C))
continue;
Q.isCalculatedMeasure(C) ? I.includes(N) || I.push(N) : s.includes(N) || s.push(N);
}
}
for (const N of s) {
const [O, i] = N.split("."), a = e.get(O), C = a.measures[i];
if (A) {
const _ = A(N, C, a);
t.set(N, () => _);
} else
t.set(N, () => this.buildMeasureExpression(C, R, a));
}
if (I.length > 0) {
const N = S.topologicalSort(I);
for (const O of N) {
const [i, a] = O.split("."), C = e.get(i), _ = C.measures[a];
t.set(O, () => this.buildCalculatedMeasure(
_,
C,
e,
t,
R
));
}
}
return t;
}
/**
* Build calculated measure expression by substituting {member} references
* with resolved SQL expressions
*/
buildCalculatedMeasure(E, e, R, A, t) {
if (!E.calculatedSql)
throw new Error(
`Calculated measure '${e.name}.${E.name}' missing calculatedSql property`
);
const s = this.databaseAdapter.preprocessCalculatedTemplate(E.calculatedSql);
return sR(s, {
cube: e,
allCubes: R,
resolvedMeasures: A
});
}
/**
* Build resolved measures map for a calculated measure from CTE columns
* This handles re-aggregating pre-aggregated CTE columns for calculated measures
*
* IMPORTANT: For calculated measures in CTEs, we cannot sum/avg pre-computed ratios.
* We must recalculate from the base measures that were pre-aggregated in the CTE.
*
* @param measure - The calculated measure to build
* @param cube - The cube containing this measure
* @param cteInfo - CTE metadata (alias, measures, cube reference)
* @param allCubes - Map of all cubes in the query
* @param context - Query context
* @returns SQL expression for the calculated measure using CTE column references
*/
buildCTECalculatedMeasure(E, e, R, A, t) {
if (!E.calculatedSql)
throw new Error(
`Calculated measure '${e.name}.${E.name || "unknown"}' missing calculatedSql property`
);
const s = /* @__PURE__ */ new Map(), I = hE(E.calculatedSql, e.name);
for (const r of I) {
const [S, N] = r.split("."), O = A.get(S);
if (O && O.measures[N]) {
const i = O.measures[N];
if (R.measures.includes(r)) {
const a = n`${n.identifier(R.cteAlias)}.${n.identifier(N)}`;
let C;
switch (i.type) {
case "count":
case "countDistinct":
case "sum":
C = w(a);
break;
case "avg":
C = this.databaseAdapter.buildAvg(a);
break;
case "min":
C = nE(a);
break;
case "max":
C = OE(a);
break;
case "number":
C = w(a);
break;
default:
C = w(a);
}
s.set(r, () => C);
}
}
}
return this.buildCalculatedMeasure(
E,
e,
A,
s,
t
);
}
/**
* Build measure expression for HAVING clause, handling CTE references correctly
*/
buildHavingMeasureExpression(E, e, R, A, t) {
if (t && t.preAggregationCTEs) {
const s = t.preAggregationCTEs.find((I) => I.cube.name === E);
if (s && s.measures.includes(`${E}.${e}`))
if (R.type === "calculated" && R.calculatedSql) {
const I = t.primaryCube.name === E ? t.primaryCube : t.joinCubes?.find((S) => S.cube.name === E)?.cube;
if (!I)
throw new Error(`Cube ${E} not found in query plan`);
const r = /* @__PURE__ */ new Map([[t.primaryCube.name, t.primaryCube]]);
if (t.joinCubes)
for (const S of t.joinCubes)
r.set(S.cube.name, S.cube);
return this.buildCTECalculatedMeasure(
R,
I,
s,
r,
A
);
} else {
const I = n`${n.identifier(s.cteAlias)}.${n.identifier(e)}`;
switch (R.type) {
case "count":
case "countDistinct":
case "sum":
return w(I);
case "avg":
return this.databaseAdapter.buildAvg(I);
case "min":
return nE(I);
case "max":
return OE(I);
case "number":
return w(I);
default:
return w(I);
}
}
}
return this.buildMeasureExpression(R, A);
}
/**
* Build measure expression with aggregation and filters
* Note: This should NOT be called for calculated measures
*
* @param measure - The measure definition
* @param context - Query context with security context and database info
* @param cube - Optional cube reference for resolving dimension references (window functions)
*/
buildMeasureExpression(E, e, R) {
if (E.type === "calculated")
throw new Error(
`Cannot build calculated measure '${E.name}' directly. Use buildCalculatedMeasure instead.`
);
if (B.isPostAggregationWindow(E))
throw new Error(
`Post-aggregation window measure '${E.name}' should be built via buildPostAggregationWindowExpression, not buildMeasureExpression.`
);
if (!E.sql)
throw new Error(
`Measure '${E.name}' of type '${E.type}' is missing required 'sql' property. Only calculated measures and post-aggregation window functions can omit 'sql'.`
);
let A = W(E.sql, e);
if (E.filters && E.filters.length > 0) {
const t = E.filters.map((s) => {
const I = s(e);
return I ? n`(${I})` : void 0;
}).filter(Boolean);
if (t.length > 0) {
const s = t.length === 1 ? t[0] : F(...t);
A = this.databaseAdapter.buildCaseWhen([
{ when: s, then: A }
]);
}
}
switch (E.type) {
case "count":
return Re(A);
case "countDistinct":
return JT(A);
case "sum":
return w(A);
case "avg":
return this.databaseAdapter.buildAvg(A);
case "min":
return nE(A);
case "max":
return OE(A);
case "number":
return A;
// Statistical functions (Phase 1)
case "stddev":
case "stddevSamp": {
const t = E.type === "stddevSamp" || E.statisticalConfig?.useSample, s = this.databaseAdapter.buildStddev(A, t);
return s === null ? (console.warn(`[drizzle-cube] ${E.type} not supported on ${this.databaseAdapter.getEngineType()}, returning NULL`), n`MAX(NULL)`) : s;
}
case "variance":
case "varianceSamp": {
const t = E.type === "varianceSamp" || E.statisticalConfig?.useSample, s = this.databaseAdapter.buildVariance(A, t);
return s === null ? (console.warn(`[drizzle-cube] ${E.type} not supported on ${this.databaseAdapter.getEngineType()}, returning NULL`), n`MAX(NULL)`) : s;
}
case "percentile":
case "median":
case "p95":
case "p99": {
let t;
switch (E.type) {
case "median":
t = 50;
break;
case "p95":
t = 95;
break;
case "p99":
t = 99;
break;
default:
t = E.statisticalConfig?.percentile ?? 50;
}
const s = this.databaseAdapter.buildPercentile(A, t);
return s === null ? (console.warn(`[drizzle-cube] ${E.type} not supported on ${this.databaseAdapter.getEngineType()}, returning NULL`), n`MAX(NULL)`) : s;
}
// Window functions (Phase 2) - now with dimension resolution
case "lag":
case "lead":
case "rank":
case "denseRank":
case "rowNumber":
case "ntile":
case "firstValue":
case "lastValue":
case "movingAvg":
case "movingSum": {
const t = E.windowConfig || {};
let s;
if (t.partitionBy && t.partitionBy.length > 0 && R) {
const S = t.partitionBy.map((N) => {
const O = N.includes(".") ? N.split(".")[1] : N, i = R.dimensions?.[O];
return i ? W(i.sql, e) : (console.warn(`[drizzle-cube] Window function partition dimension '${N}' not found in cube '${R.name}'`), null);
}).filter((N) => N !== null);
S.length > 0 && (s = S);
}
let I;
if (t.orderBy && t.orderBy.length > 0 && R) {
const S = t.orderBy.map((N) => {
const O = N.field.includes(".") ? N.field.split(".")[1] : N.field, i = R.dimensions?.[O];
if (i)
return {
field: W(i.sql, e),
direction: N.direction
};
const a = R.measures?.[O];
return a && a.sql ? {
field: W(a.sql, e),
direction: N.direction
} : (console.warn(`[drizzle-cube] Window function order field '${N.field}' not found in cube '${R.name}'`), null);
}).filter((N) => N !== null);
S.length > 0 && (I = S);
}
const r = this.databaseAdapter.buildWindowFunction(
E.type,
["rank", "denseRank", "rowNumber"].includes(E.type) ? null : A,
s,
I,
{
offset: t.offset,
defaultValue: t.defaultValue,
nTile: t.nTile,
frame: t.frame
}
);
return r === null ? (console.warn(`[drizzle-cube] ${E.type} not supported on ${this.databaseAdapter.getEngineType()}, returning NULL`), n`NULL`) : r;
}
default:
return Re(A);
}
}
/**
* List of measure types that are window functions
* Window functions require special handling in CTEs:
* - No GROUP BY in the CTE
* - No re-aggregation in outer query
* - Return individual rows, not grouped results
*/
static WINDOW_FUNCTION_TYPES = [
"lag",
"lead",
"rank",
"denseRank",
"rowNumber",
"ntile",
"firstValue",
"lastValue",
"movingAvg",
"movingSum"
];
/**
* Check if a measure type is a window function
* @param measureType - The measure type string
* @returns true if this is a window function type
*/
static isWindowFunction(E) {
return B.WINDOW_FUNCTION_TYPES.includes(E);
}
/**
* Categorize measures into window functions and regular aggregates
* Used by query planner to create separate CTEs for each category
*
* @param measureNames - Array of measure names (e.g., ["Productivity.rank", "Productivity.totalLines"])
* @param cubeMap - Map of cubes to look up measure definitions
* @returns Object with windowMeasures and aggregateMeasures arrays
*/
static categorizeMeasures(E, e) {
const R = [], A = [];
for (const t of E) {
const [s, I] = t.split("."), r = e.get(s);
if (r?.measures?.[I]) {
const S = r.measures[I];
B.isWindowFunction(S.type) ? R.push(t) : A.push(t);
}
}
return { windowMeasures: R, aggregateMeasures: A };
}
/**
* Check if a query contains any window function measures
* @param measureNames - Array of measure names
* @param cubeMap - Map of cubes
* @returns true if any measure is a window function
*/
static hasWindowFunctions(E, e) {
const { windowMeasures: R } = B.categorizeMeasures(E, e);
return R.length > 0;
}
// ============================================================================
// Post-Aggregation Window Functions
// ============================================================================
/**
* Check if a measure is a post-aggregation window function.
* Post-aggregation windows have a `measure` reference in their windowConfig,
* indicating they should operate on aggregated data rather than raw rows.
*
* @param measure - The measure definition
* @returns true if this is a post-aggregation window function
*/
static isPostAggregationWindow(E) {
return B.isWindowFunction(E.type) && E.windowConfig?.measure !== void 0;
}
/**
* Get the base measure reference for a post-aggregation window function.
* Resolves simple names (e.g., 'totalRevenue') to fully qualified names ('Sales.totalRevenue').
*
* @param measure - The measure definition
* @param cubeName - The name of the cube containing this measure
* @returns Fully qualified base measure name, or null if not a post-agg window
*/
static getWindowBaseMeasure(E, e) {
if (!E.windowConfig?.measure)
return null;
const R = E.windowConfig.measure;
return R.includes(".") ? R : `${e}.${R}`;
}
/**
* Get the default operation for a window function type.
* - lag/lead default to 'difference' (compare current vs previous/next)
* - rank/rowNumber/ntile/firstValue/lastValue default to 'raw'
* - movingAvg/movingSum default to 'raw'
*
* @param windowType - The window function type
* @returns Default operation for the window type
*/
static getDefaultWindowOperation(E) {
switch (E) {
case "lag":
case "lead":
return "difference";
default:
return "raw";
}
}
/**
* Categorize measures for post-aggregation window function handling.
* Separates measures into:
* - aggregateMeasures: Regular aggregates (count, sum, avg, etc.)
* - postAggWindowMeasures: Window functions that reference a base measure
* - requiredBaseMeasures: Base measures needed by window functions (auto-added to query)
*
* @param measureNames - Array of measure names from the query
* @param cubeMap - Map of cubes to look up measure definitions
* @returns Categorized measures with base measure dependencies
*/
static categorizeForPostAggregation(E, e) {
const R = [], A = [], t = /* @__PURE__ */ new Set();
for (const s of E) {
const [I, r] = s.split("."), S = e.get(I);
if (S?.measures?.[r]) {
const N = S.measures[r];
if (B.isPostAggregationWindow(N)) {
A.push(s);
const O = B.getWindowBaseMeasure(N, I);
O && t.add(O);
} else B.isWindowFunction(N.type) || R.push(s);
}
}
return { aggregateMeasures: R, postAggWindowMeasures: A, requiredBaseMeasures: t };
}
/**
* Check if any measures in the query are post-aggregation window functions.
*
* @param measureNames - Array of measure names
* @param cubeMap - Map of cubes
* @returns true if any measure is a post-aggregation window function
*/
static hasPostAggregationWindows(E, e) {
const { postAggWindowMeasures: R } = B.categorizeForPostAggregation(
E,
e
);
return R.length > 0;
}
}
class NR {
constructor(E) {
this.dateTimeBuilder = E;
}
/**
* Check if a measure type is a window function
*/
isWindowFunctionType(E) {
return [
"lag",
"lead",
"rank",
"denseRank",
"rowNumber",
"ntile",
"firstValue",
"lastValue",
"movingAvg",
"movingSum"
].includes(E);
}
/**
* Check if a measure type is an aggregate function (requires GROUP BY)
*
* Note: 'number' is included because users commonly define measures with raw SQL
* aggregations (e.g., sql`COUNT(DISTINCT ...)`) and set type: 'number' for the output.
* These measures still require GROUP BY when used with time dimensions.
*/
isAggregateFunctionType(E) {
return [
"count",
"countDistinct",
"sum",
"avg",
"min",
"max",
"stddev",
"stddevSamp",
"variance",
"varianceSamp",
"median",
"p95",
"p99",
"percentile",
"number"
].includes(E);
}
/**
* Build GROUP BY fields from dimensions and time dimensions
* Works for both single and multi-cube queries
*
* NOTE: GROUP BY is only added when there are AGGREGATE measures.
* Window functions do not require GROUP BY and operate on individual rows.
*/
buildGroupByFields(E, e, R, A) {
const t = [], s = E instanceof Map ? E : /* @__PURE__ */ new Map([[E.name, E]]);
let I = !1;
for (const r of e.measures || []) {
const [S, N] = r.split("."), O = s.get(S);
if (O && O.measures && O.measures[N]) {
const i = O.measures[N];
if (this.isAggregateFunctionType(i.type) || i.type === "calculated") {
I = !0;
break;
}
if (B.isPostAggregationWindow(i)) {
const a = B.getWindowBaseMeasure(i, S);
if (a) {
const [C, _] = a.split("."), c = s.get(C)?.measures?.[_];
if (c && this.isAggregateFunctionType(c.type)) {
I = !0;
break;
}
}
}
}
}
if (!I)
return [];
if (e.dimensions)
for (const r of e.dimensions) {
const [S, N] = r.split("."), O = s.get(S);
if (O && O.dimensions && O.dimensions[N])
if (A?.preAggregationCTEs?.some((a) => a.cube.name === S)) {
const a = A.preAggregationCTEs.find((_) => _.cube.name === S), C = a.joinKeys.find((_) => _.targetColumn === N);
if (C && C.sourceColumnObj)
t.push(C.sourceColumnObj);
else {
const _ = n`${n.identifier(a.cteAlias)}.${n.identifier(N)}`;
t.push(_);
}
} else {
const a = O.dimensions[N], C = W(a.sql, R);
t.push(C);
}
}
if (e.timeDimensions)
for (const r of e.timeDimensions) {
const [S, N] = r.dimension.split("."), O = s.get(S);
if (O && O.dimensions && O.dimensions[N])
if (A?.preAggregationCTEs?.some((a) => a.cube.name === S)) {
const a = A.preAggregationCTEs.find((_) => _.cube.name === S), C = a.joinKeys.find((_) => _.targetColumn === N);
if (C && C.sourceColumnObj) {
const _ = this.dateTimeBuilder.buildTimeDimensionExpression(
C.sourceColumnObj,
r.granularity,
R
);
t.push(_);
} else {
const _ = n`${n.identifier(a.cteAlias)}.${n.identifier(N)}`;
t.push(_);
}
} else {
const a = O.dimensions[N], C = this.dateTimeBuilder.buildTimeDimensionExpression(
a.sql,
r.granularity,
R
);
t.push(C);
}
}
return t;
}
}
class IR {
dateTimeBuilder;
filterBuilder;
groupByBuilder;
measureBuilder;
constructor(E) {
this.dateTimeBuilder = new LT(E), this.filterBuilder = new tR(E, this.dateTimeBuilder), this.groupByBuilder = new NR(this.dateTimeBuilder), this.measureBuilder = new B(E);
}
/**
* Build resolvedMeasures map for a set of measures
* Delegates to MeasureBuilder
*/
buildResolvedMeasures(E, e, R, A) {
return this.measureBuilder.buildResolvedMeasures(E, e, R, A);
}
/**
* Build dynamic selections for measures, dimensions, and time dimensions
* Works for both single and multi-cube queries
* Handles calculated measures with dependency resolution
*/
buildSelections(E, e, R) {
const A = {}, t = E instanceof Map ? E : /* @__PURE__ */ new Map([[E.name, E]]);
if (e.dimensions)
for (const s of e.dimensions) {
const [I, r] = s.split("."), S = t.get(I);
if (S && S.dimensions && S.dimensions[r]) {
const N = S.dimensions[r], O = W(N.sql, R);
A[s] = n`${O}`.as(s);
}
}
if (e.measures) {
const s = this.buildResolvedMeasures(
e.measures,
t,
R
);
for (const I of e.measures) {
const r = s.get(I);
if (r) {
const S = r();
A[I] = n`${S}`.as(I);
}
}
}
if (e.timeDimensions)
for (const s of e.timeDimensions) {
const [I, r] = s.dimension.split("."), S = t.get(I);
if (S && S.dimensions && S.dimensions[r]) {
const N = S.dimensions[r], O = this.buildTimeDimensionExpression(
N.sql,
s.granularity,
R
);
A[s.dimension] = n`${O}`.as(s.dimension);
}
}
return Object.keys(A).length === 0 && (A.count = Re()), A;
}
/**
* Build calculated measure expression by substituting {member} references
* Delegates to MeasureBuilder
*/
buildCalculatedMeasure(E, e, R, A, t) {
return this.measureBuilder.buildCalculatedMeasure(E, e, R, A, t);
}
/**
* Build resolved measures map for a calculated measure from CTE columns
* Delegates to MeasureBuilder
*/
buildCTECalculatedMeasure(E, e, R, A, t) {
return this.measureBuilder.buildCTECalculatedMeasure(E, e, R, A, t);
}
/**
* Build measure expression for HAVING clause, handling CTE references correctly
* Delegates to MeasureBuilder
*/
buildHavingMeasureExpression(E, e, R, A, t) {
return this.measureBuilder.buildHavingMeasureExpression(E, e, R, A, t);
}
/**
* Build measure expression with aggregation and filters
* Delegates to MeasureBuilder
*/
buildMeasureExpression(E, e, R) {
return this.measureBuilder.buildMeasureExpression(E, e, R);
}
/**
* Build time dimension expression with granularity using database adapter
* Delegates to DateTimeBuilder
*/
buildTimeDimensionExpression(E, e, R) {
return this.dateTimeBuilder.buildTimeDimensionExpression(E, e, R);
}
/**
* Build WHERE conditions from semantic query filters (dimensions only)
* Works for both single and multi-cube queries
* @param preBuiltFilters - Optional map of cube name to pre-built filter SQL for parameter deduplication
*/
buildWhereConditions(E, e, R, A, t) {
const s = [], I = E instanceof Map ? E : /* @__PURE__ */ new Map([[E.name, E]]), r = /* @__PURE__ */ new Set();
if (e.filters && e.filters.length > 0)
for (const S of e.filters) {
if (t && "member" in S) {
const [O] = S.member.split(".");
if (I.has(O) && t.has(O) && !r.has(O)) {
const a = t.get(O);
s.push(...a), r.add(O);
continue;
} else if (r.has(O))
continue;
}
const N = this.processFilter(S, I, R, "where", A);
N && s.push(N);
}
if (e.timeDimensions)
for (const S of e.timeDimensions) {
const [N, O] = S.dimension.split("."), i = I.get(N);
if (i && i.dimensions[O] && S.dateRange) {
if (A?.preAggregationCTEs && A.preAggregationCTEs.some((c) => c.cube.name === N))
continue;
if (R.filterCache) {
const P = oT(S.dimension, S.dateRange), c = R.filterCache.get(P);
if (c) {
s.push(c);
continue;
}
}
const a = i.dimensions[O], C = W(a.sql, R), _ = this.buildDateRangeCondition(C, S.dateRange);
_ && s.push(_);
}
}
return s;
}
/**
* Build HAVING conditions from semantic query filters (measures only)
* Works for both single and multi-cube queries
*/
buildHavingConditions(E, e, R, A) {
const t = [], s = E instanceof Map ? E : /* @__PURE__ */ new Map([[E.name, E]]);
if (e.filters && e.filters.length > 0)
for (const I of e.filters) {
const r = this.processFilter(I, s, R, "having", A);
r && t.push(r);
}
return t;
}
/**
* Process a single filter (basic or logical)
* @param filterType - 'where' for dimension filters, 'having' for measure filters
*/
processFilter(E, e, R, A, t) {
if ("and" in E || "or" in E) {
const a = E;
if (a.and) {
const C = a.and.map((_) => this.processFilter(_, e, R, A, t)).filter((_) => _ !== null);
return C.length > 0 ? F(...C) : null;
}
if (a.or) {
const C = a.or.map((_) => this.processFilter(_, e, R, A, t)).filter((_) => _ !== null);
return C.length > 0 ? IE(...C) : null;
}
}
const s = E, [I, r] = s.member.split("."), S = e.get(I);
if (!S) return null;
const N = S.dimensions[r], O = S.measures[r], i = N || O;
if (!i) return null;
if (A === "where" && N) {
if (t?.preAggregationCTEs && t.preAggregationCTEs.some((P) => P.cube.name === I))
return null;
const a = ["arrayContains", "arrayOverlaps", "arrayContained"].includes(s.operator);
if (!a && R.filterCache) {
const _ = PE(E), P = R.filterCache.get(_);
if (P)
return P;
}
const C = a ? typeof N.sql == "function" ? N.sql(R) : N.sql : W(N.sql, R);
return this.buildFilterCondition(
C,
s.operator,
s.values,
i,
s.dateRange
);
} else {
if (A === "where" && O)
return null;
if (A === "having" && O) {
const a = this.buildHavingMeasureExpression(I, r, O, R, t);
return this.buildFilterCondition(
a,
s.operator,
s.values,
i,
s.dateRange
);
}
}
return null;
}
/**
* Build filter condition using Drizzle operators
* Delegates to FilterBuilder
*/
buildFilterCondition(E, e, R, A, t) {
return this.filterBuilder.buildFilterCondition(E, e, R, A, t);
}
/**
* Build date range condition for time dimensions
* Delegates to DateTimeBuilder
*/
buildDateRangeCondition(E, e) {
return this.dateTimeBuilder.buildDateRangeCondition(E, e);
}
/**
* Build GROUP BY fields from dimensions and time dimensions
* Delegates to GroupByBuilder
*/
buildGroupByFields(E, e, R, A) {
return this.groupByBuilder.buildGroupByFields(E, e, R, A);
}
/**
* Build ORDER BY clause with automatic time dimension sorting
*/
buildOrderBy(E, e) {
const R = [], A = e || [
...E.measures || [],
...E.dimensions || [],
...E.timeDimensions?.map((t) => t.dimension) || []
];
if (E.order && Object.keys(E.order).length > 0)
for (const [t, s] of Object.entries(E.order)) {
if (!A.includes(t))
throw new Error(`Cannot order by '${t}': field is not selected in the query`);
const I = s === "desc" ? wT(n.identifier(t)) : Me(n.identifier(t));
R.push(I);
}
if (E.timeDimensions && E.timeDimensions.length > 0) {
const t = new Set(Object.keys(E.order || {})), s = [...E.timeDimensions].sort(
(I, r) => I.dimension.localeCompare(r.dimension)
);
for (const I of s)
t.has(I.dimension) || R.push(Me(n.identifier(I.dimension)));
}
return R;
}
/**
* Collect numeric field names (measures + numeric dimensions) for type conversion
* Works for both single and multi-cube queries
*/
collectNumericFields(E, e) {
const R = [], A = E instanceof Map ? E : /* @__PURE__ */ new Map([[E.name, E]]);
if (e.measures && R.push(...e.measures), e.dimensions)
for (const t of e.dimensions) {
const [s, I] = t.split("."), r = A.get(s);
if (r) {
const S = r.dimensions[I];
S && S.type === "number" && R.push(t);
}
}
return R;
}
/**
* Apply LIMIT and OFFSET to a query with validation
* If offset is provided without limit, add a reasonable default limit
*/
applyLimitAndOffset(E, e) {
let R = e.limit;
e.offset !== void 0 && e.offset > 0 && R === void 0 && (R = 50);
let A = E;
if (R !== void 0) {
if (R < 0)
throw new Error("Limit must be non-negative");
A = A.limit(R);
}
if (e.offset !== void 0) {
if (e.offset < 0)
throw new Error("Offset must be non-negative");
A = A.offset(e.offset);
}
return A;
}
/**
* Public wrapper for buildFilterCondition - used by executor for cache preloading
* This allows pre-building filter SQL before query construction
*/
buildFilterConditionPublic(E, e, R, A, t) {
return this.buildFilterCondition(E, e, R, A, t);
}
/**
* Build a logical filter (AND/OR) - used by executor for cache preloading
* This handles nested filter structures and builds combined SQL
* Delegates to FilterBuilder
*/
buildLogicalFilter(E, e, R) {
return this.filterBuilder.buildLogicalFilter(E, e, R);
}
}
class nR {
cubes;
connectivityCache = /* @__PURE__ */ new Map();
/**
* @param cubes Map of cube name to cube definition
*/
constructor(E) {
this.cubes = E;
}
/**
* Find the shortest join path from source cube to target cube
* Uses BFS algorithm for optimal path discovery
*
* @param fromCube Source cube name
* @param toCube Target cube name
* @param alreadyProcessed Set of cubes to exclude from path finding
* @returns Array of join steps or null if no path exists
*/
findPath(E, e, R = /* @__PURE__ */ new Set()) {
if (E === e)
return [];
const A = this.getCacheKey(E, e, R), t = this.getFromCache(A);
if (t !== void 0)
return t;
const s = [
{ cube: E, path: [] }
], I = /* @__PURE__ */ new Set([E, ...R]);
for (; s.length > 0; ) {
const { cube: r, path: S } = s.shift(), N = this.cubes.get(r);
if (N?.joins)
for (const [, O] of Object.entries(N.joins)) {
const a = DE(O.targetCube).name;
if (I.has(a))
continue;
const C = [
...S,
{
fromCube: r,
toCube: a,
joinDef: O
}
];
if (a === e)
return this.setInCache(A, C), C;
I.add(a), s.push({ cube: a, path: C });
}
}
return this.setInCache(A, null), null;
}
/**
* Check if a cube can reach all other cubes in the list via joins
*
* @param fromCube Starting cube name
* @param allCubes List of all cubes that must be reachable
* @returns true if all cubes are reachable
*/
canReachAll(E, e) {
const R = e.filter((A) => A !== E);
for (const A of R) {
const t = this.findPath(E, A, /* @__PURE__ */ new Set());
if (!t || t.length === 0)
return !1;
}
return !0;
}
/**
* Build SQL join condition from join definition
*
* @param joinDef The cube join definition
* @param sourceAlias Optional alias for source table (null uses actual column)
* @param targetAlias Optional alias for target table (null uses actual column)
* @returns SQL condition for the join
*/
buildJoinCondition(E, e, R) {
const A = [];
for (const t of E.on) {
const s = e ? n`${n.identifier(e)}.${n.identifier(t.source.name)}` : te(t.source), I = R ? n`${n.identifier(R)}.${n.identifier(t.target.name)}` : te(t.target), r = t.as || Z;
A.push(r(s, I));
}
return F(...A);
}
/**
* Get all reachable cubes from a starting cube
* Useful for analyzing cube connectivity
*
* @param fromCube Starting cube name
* @returns Set of all reachable cube names
*/
getReachableCubes(E) {
const e = /* @__PURE__ */ new Set([E]), R = [E];
for (; R.length > 0; ) {
const A = R.shift(), t = this.cubes.get(A);
if (t?.joins)
for (const [, s] of Object.entries(t.joins)) {
const r = DE(s.targetCube).name;
e.has(r) || (e.add(r), R.push(r));
}
}
return e;
}
// Private cache management
getCacheKey(E, e, R) {
const A = Array.from(R).sort().join(",");
return `${E}:${e}:${A}`;
}
getFromCache(E) {
const e = this.connectivityCache.get(E);
if (e)
return e.path;
}
setInCache(E, e) {
this.connectivityCache.set(E, { path: e });
}
}
class _T {
// Cache resolver per cubes map to avoid repeated instantiation
resolverCache = /* @__PURE__ */ new WeakMap();
/**
* Get or create a JoinPathResolver for the given cubes map
*/
getResolver(E) {
let e = this.resolverCache.get(E);
return e || (e = new nR(E), this.resolverCache.set(E, e)), e;
}
/**
* Analyze a semantic query to determine which cubes are involved
*/
analyzeCubeUsage(E) {
const e = /* @__PURE__ */ new Set();
if (E.measures)
for (const R of E.measures) {
const [A] = R.split(".");
e.add(A);
}
if (E.dimensions)
for (const R of E.dimensions) {
const [A] = R.split(".");
e.add(A);
}
if (E.timeDimensions)
for (const R of E.timeDimensions) {
const [A] = R.dimension.split(".");
e.add(A);
}
if (E.filters)
for (const R of E.filters)
this.extractCubeNamesFromFilter(R, e);
return e;
}
/**
* Recursively extract cube names from filters (handles logical filters)
*/
extractCubeNamesFromFilter(E, e) {
if ("and" in E || "or" in E) {
const R = E.and || E.or || [];
for (const A of R)
this.extractCubeNamesFromFilter(A, e);
return;
}
if ("member" in E) {
const [R] = E.member.split(".");
R && e.add(R);
}
}
/**
* Extract measures referenced in filters (for CTE inclusion)
*/
extractMeasuresFromFilters(E, e) {
const R = [];
if (!E.filters)
return R;
for (const A of E.filters)
this.extractMeasuresFromFilter(A, e, R);
return R;
}
/**
* Recursively extract measures from filters for a specific cube
* Only includes filter members that are actually measures (not dimensions)
*/
extractMeasuresFromFilter(E, e, R) {
if ("and" in E || "or" in E) {
const A = E.and || E.or || [];
for (const t of A)
this.extractMeasuresFromFilter(t, e, R);
return;
}
if ("member" in E) {
const A = E.member, [t, s] = A.split(".");
t === e.name && e.measures && e.measures[s] && R.push(A);
}
}
/**
* Create a unified query plan that works for both single and multi-cube queries
*/
createQueryPlan(E, e, R) {
const A = this.analyzeCubeUsage(e), t = Array.from(A);
if (t.length === 0)
throw new Error("No cubes found in query");
const s = this.choosePrimaryCube(t, e, E), I = E.get(s);
if (!I)
throw new Error(`Primary cube '${s}' not found`);
if (t.length === 1)
return {
primaryCube: I,
joinCubes: [],
// Empty for single cube
selections: {},
// Will be built by QueryBuilder
whereConditions: [],
// Will be built by QueryBuilder
groupByFields: []
// Will be built by QueryBuilder
};
const r = this.buildJoinPlan(E, I, t, R), S = this.planPreAggregationCTEs(E, I, r, e);
return {
primaryCube: I,
joinCubes: r,
selections: {},
// Will be built by QueryBuilder
whereConditions: [],
// Will be built by QueryBuilder
groupByFields: [],
// Will be built by QueryBuilder
preAggregationCTEs: S
};
}
/**
* Choose the primary cube based on query analysis
* Uses a consistent strategy to avoid measure order dependencies
*
* Delegates to analyzePrimaryCubeSelection() for the actual logic,
* ensuring a single source of truth for primary cube selection.
*/
choosePrimaryCube(E, e, R) {
return E.length === 1 ? E[0] : R ? this.analyzePrimaryCubeSelection(E, e, R).selectedCube : [...E].sort()[0];
}
/**
* Build join plan for multi-cube query
* Supports both direct joins and transitive joins through intermediate cubes
*/
buildJoinPlan(E, e, R, A) {
const t = this.getResolver(E), s = [], I = /* @__PURE__ */ new Set([e.name]), r = R.filter((S) => S !== e.name);
for (const S of r) {
if (I.has(S))
continue;
const N = t.findPath(e.name, S, I);
if (!N || N.length === 0)
throw new Error(`No join path found from '${e.name}' to '${S}'`);
for (const { toCube: O, joinDef: i } of N) {
if (I.has(O))
continue;
const a = E.get(O);
if (!a)
throw new Error(`Cube '${O}' not found`);
if (i.relationship === "belongsToMany" && i.through) {
const C = eR(i, A.securityContext);
s.push({
cube: a,
alias: `${O.toLowerCase()}_cube`,
joinType: C.junctionJoins[1].joinType,
// Use the target join type
joinCondition: C.junctionJoins[1].condition,
// Target join condition
junctionTable: {
table: i.through.table,
alias: `junction_${O.toLowerCase()}`,
joinType: C.junctionJoins[0].joinType,
joinCondition: C.junctionJoins[0].condition,
securitySql: i.through.securitySql
}
});
} else {
const C = t.buildJoinCondition(
i,
null,
// No source alias needed - use the actual column
null
// No target alias needed - use the actual column
), _ = Ae(i.relationship, i.sqlJoinType);
s.push({
cube: a,
alias: `${O.toLowerCase()}_cube`,
joinType: _,
joinCondition: C
});
}
I.add(O);
}
}
return s;
}
/**
* Plan pre-aggregation CTEs for hasMany relationships to prevent fan-out
* Note: belongsToMany relationships handle fan-out differently through their junction table structure
* and don't require CTEs - the two-hop join with the junction table provides natural grouping
*/
planPreAggregationCTEs(E, e, R, A) {
const t = [];
if (!A.measures || A.measures.length === 0)
return t;
for (const s of R) {
const I = this.findHasManyJoinDef(e, s.cube.name);
if (!I)
continue;
const r = A.measures ? A.measures.filter(
(c) => c.startsWith(s.cube.name + ".")
) : [], S = this.extractMeasuresFromFilters(A, s.cube), N = [.../* @__PURE__ */ new Set([...r, ...S])];
if (N.length === 0)
continue;
const O = I.on.map((c) => ({
sourceColumn: c.source.name,
targetColumn: c.target.name,
sourceColumnObj: c.source,
targetColumnObj: c.target
})), i = this.findPropagatingFilters(A, s.cube, E), a = /* @__PURE__ */ new Map([[s.cube.name, s.cube]]), { aggregateMeasures: C, requiredBaseMeasures: _ } = B.categorizeForPostAggregation(
N,
a
), P = [.../* @__PURE__ */ new Set([
...C,
...Array.from(_).filter((c) => c.startsWith(s.cube.name + "."))
])];
if (P.length > 0) {
const c = this.expandCalculatedMeasureDependencies(
s.cube,
P
);
t.push({
cube: s.cube,
alias: s.alias,
cteAlias: `${s.cube.name.toLowerCase()}_agg`,
joinKeys: O,
measures: c,
propagatingFilters: i.length > 0 ? i : void 0,
cteType: "aggregate"
});
}
}
return t;
}
/**
* Expand calculated measures to include their dependencies
*/
expandCalculatedMeasureDependencies(E, e) {
const R = /* @__PURE__ */ new Set(), A = [...e];
for (; A.length > 0; ) {
const t = A.pop();
if (R.has(t))
continue;
R.add(t);
const [, s] = t.split(".");
if (!E.measures || !E.measures[s])
continue;
const I = E.measures[s];
if (I.type === "calculated" && I.calculatedSql) {
const r = this.extractDependenciesFromTemplate(I.calculatedSql, E.name);
for (const S of r)
R.has(S) || A.push(S);
}
}
return Array.from(R);
}
/**
* Extract measure references from calculatedSql template
*/
extractDependenciesFromTemplate(E, e) {
const R = /\{([^}]+)\}/g, A = E.matchAll(R), t = [];
for (const s of A) {
const I = s[1].trim();
I.includes(".") ? t.push(I) : t.push(`${e}.${I}`);
}
return t;
}
/**
* Find hasMany join definition from primary cube to target cube
*/
findHasManyJoinDef(E, e) {
if (!E.joins)
return null;
for (const [, R] of Object.entries(E.joins))
if (DE(R.targetCube).name === e && R.relationship === "hasMany")
return R;
return null;
}
/**
* Find filters that need to propagate from related cubes to a CTE cube.
* When cube A has filters and a hasMany relationship to cube B (the CTE cube),
* A's filters should propagate into B's CTE via a subquery.
*
* Example: Employees.createdAt filter should propagate to Productivity CTE
* via: employee_id IN (SELECT id FROM employees WHERE created_at >= $date)
*/
findPropagatingFilters(E, e, R) {
const A = [];
if (!E.filters) return A;
const t = /* @__PURE__ */ new Set();
if (this.extractFilterCubeNamesToSet(E.filters, t), E.timeDimensions) {
for (const s of E.timeDimensions)
if (s.dateRange) {
const [I] = s.dimension.split(".");
I && t.add(I);
}
}
for (const s of t) {
if (s === e.name) continue;
const I = R.get(s);
if (I?.joins) {
for (const [, r] of Object.entries(I.joins))
if (DE(r.targetCube).name === e.name && r.relationship === "hasMany") {
const N = this.extractFiltersForCube(E.filters, s), O = this.extractTimeDimensionFiltersForCube(E, s), i = [...N, ...O];
i.length > 0 && r.on.length > 0 && A.push({
sourceCube: I,
filters: i,
// Map all join keys for composite key support
// source = filterCube PK (e.g., employees.id)
// target = cteCube FK (e.g., productivity.employeeId)
joinConditions: r.on.map((a) => ({
source: a.source,
target: a.target
}))
});
}
}
}
return A;
}
/**
* Extract cube names from filters into a Set (helper for findPropagatingFilters)
*/
extractFilterCubeNamesToSet(E, e) {
for (const R of E) {
if ("and" in R || "or" in R) {
const A = R.and || R.or || [];
this.extractFilterCubeNamesToSet(A, e);
continue;
}
if ("member" in R) {
const [A] = R.member.split(".");
A && e.add(A);
}
}
}
/**
* Extract filters for a specific cube from the filter array
*
* Logic for preserving filter semantics:
* - AND: Safe to extract only matching branches (AND of fewer conditions is more permissive)
* - OR: Must include ALL branches or skip entirely (partial OR changes semantics)
* If any branch belongs to another cube, skip the entire OR to be safe
* since we can't evaluate the other cube's conditions
*/
extractFiltersForCube(E, e) {
const R = [];
for (const A of E) {
if ("and" in A) {
const t = this.extractFiltersForCube(A.and || [], e);
t.length > 0 && R.push({ and: t });
continue;
}
if ("or" in A) {
const t = A.or || [];
if (this.allFiltersFromCube(t, e)) {
const I = this.extractFiltersForCube(t, e);
I.length > 0 && R.push({ or: I });
}
continue;
}
if ("member" in A) {
const [t] = A.member.split(".");
t === e && R.push(A);
}
}
return R;
}
/**
* Check if all simple filters in a filter array belong to the specified cube
* Recursively checks nested AND/OR filters
*/
allFiltersFromCube(E, e) {
for (const R of E) {
if ("and" in R) {
if (!this.allFiltersFromCube(R.and || [], e))
return !1;
continue;
}
if ("or" in R) {
if (!this.allFiltersFromCube(R.or || [], e))
return !1;
continue;
}
if ("member" in R) {
const [A] = R.member.split(".");
if (A !== e)
return !1;
}
}
return !0;
}
/**
* Extract time dimension date range filters as regular filters for a specific cube
*/
extractTimeDimensionFiltersForCube(E, e) {
const R = [];
if (!E.timeDimensions) return R;
for (const A of E.timeDimensions) {
const [t] = A.dimension.split(".");
t === e && A.dateRange && R.push({
member: A.dimension,
operator: "inDateRange",
values: Array.isArray(A.dateRange) ? A.dateRange : [A.dateRange]
});
}
return R;
}
/**
* Analyze query planning decisions without building the full query
* Returns detailed metadata about how the query plan would be constructed
* Used for debugging and transparency in the playground UI
*/
analyzeQueryPlan(E, e, R) {
const A = this.analyzeCubeUsage(e), t = Array.from(A);
if (t.length === 0)
return {
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
cubeCount: 0,
cubesInvolved: [],
primaryCube: {
selectedCube: "",
reason: "single_cube",
explanation: "No cubes found in query"
},
joinPaths: [],
preAggregations: [],
querySummary: {
queryType: "single_cube",
joinCount: 0,
cteCount: 0,
hasPreAggregation: !1
},
warnings: ["No cubes found in query - add measures or dimensions"]
};
const s = this.analyzePrimaryCubeSelection(t, e, E), I = s.selectedCube, r = {
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
cubeCount: t.length,
cubesInvolved: t.sort(),
primaryCube: s,
joinPaths: [],
preAggregations: [],
querySummary: {
queryType: "single_cube",
joinCount: 0,
cteCount: 0,
hasPreAggregation: !1
},
warnings: []
};
if (t.length > 1) {
const S = t.filter((_) => _ !== I);
for (const _ of S)
r.joinPaths.push(
this.analyzeJoinPath(E, I, _)
);
const N = E.get(I);
N && (r.preAggregations = this.analyzePreAggregations(
E,
N,
S,
e
));
const O = r.joinPaths.filter((_) => _.pathFound), i = r.joinPaths.filter((_) => !_.pathFound);
r.querySummary.joinCount = O.length, r.querySummary.cteCount = r.preAggregations.length, r.querySummary.hasPreAggregation = r.preAggregations.length > 0;
const a = /* @__PURE__ */ new Map();
for (const _ of t) {
const P = E.get(_);
P && a.set(_, P);
}
const C = B.hasPostAggregationWindows(
e.measures || [],
a
);
r.querySummary.hasWindowFunctions = C, r.preAggregations.length > 0 ? r.querySummary.queryType = "multi_cube_cte" : r.querySummary.queryType = "multi_cube_join";
for (const _ of i)
r.warnings.push(
`No join path found to cube '${_.targetCube}'. Check that joins are defined correctly.`
);
C && r.warnings.push(
"Query contains post-aggregation window functions which will be applied to aggregated results."
);
}
return r;
}
/**
* Analyze why a particular cube was chosen as primary
*/
analyzePrimaryCubeSelection(E, e, R) {
if (E.length === 1)
return {
selectedCube: E[0],
reason: "single_cube",
explanation: "Only one cube is used in this query"
};
const A = [], t = (e.dimensions || []).map((N) => N.split(".")[0]), s = /* @__PURE__ */ new Map();
for (const N of t)
s.set(N, (s.get(N) || 0) + 1);
const I = this.getResolver(R);
for (const N of E) {
const O = R.get(N), i = s.get(N) || 0, a = O?.joins ? Object.keys(O.joins).length : 0, C = I.canReachAll(N, E);
A.push({
cubeName: N,
dimensionCount: i,
joinCount: a,
canReachAll: C
});
}
if (e.dimensions && e.dimensions.length > 0) {
const N = Math.max(...A.map((O) => O.dimensionCount));
if (N > 0) {
const O = A.filter((i) => i.dimensionCount === N).sort((i, a) => i.cubeName.localeCompare(a.cubeName));
for (const i of O)
if (i.canReachAll)
return {
selectedCube: i.cubeName,
reason: "most_dimensions",
explanation: `Selected because it has ${i.dimensionCount} dimension${i.dimensionCount !== 1 ? "s" : ""} in the query (defines the analytical grain)`,
candidates: A
};
}
}
const r = A.filter((N) => N.canReachAll);
if (r.length > 0) {
const N = Math.max(...r.map((i) => i.joinCount)), O = r.filter((i) => i.joinCount === N).sort((i, a) => i.cubeName.localeCompare(a.cubeName))[0];
return {
selectedCube: O.cubeName,
reason: "most_connected",
explanation: `Selected because it has ${O.joinCount} join relationship${O.joinCount !== 1 ? "s" : ""} and can reach all other cubes`,
candidates: A
};
}
return {
selectedCube: [...E].sort()[0],
reason: "alphabetical_fallback",
explanation: "Selected alphabetically as fallback (no cube could reach all others)",
candidates: A
};
}
/**
* Analyze the join path between two cubes with detailed step information
*
* Uses JoinPathResolver.findPath() for the actual path finding,
* then converts the result to human-readable analysis format.
*/
analyzeJoinPath(E, e, R) {
const t = this.getResolver(E).findPath(e, R), s = [e];
if (t)
for (const r of t)
s.push(r.toCube);
if (!t || t.length === 0)
return {
targetCube: R,
pathFound: !1,
error: `No join path found from '${e}' to '${R}'. Ensure the target cube has a relationship defined (belongsTo, hasOne, hasMany, or belongsToMany).`,
visitedCubes: s
};
const I = t.map((r) => {
const S = Ae(r.joinDef.relationship, r.joinDef.sqlJoinType), N = r.joinDef.on.map((i) => ({
sourceColumn: i.source.name,
targetColumn: i.target.name
})), O = {
fromCube: r.fromCube,
toCube: r.toCube,
relationship: r.joinDef.relationship,
joinType: S,
joinColumns: N
};
if (r.joinDef.relationship === "belongsToMany" && r.joinDef.through) {
const i = r.joinDef.through;
O.junctionTable = {
tableName: i.table[/* @__PURE__ */ Symbol.for("drizzle:Name")] || "junction_table",
sourceColumns: i.sourceKey.map((a) => a.target.name),
targetColumns: i.targetKey.map((a) => a.source.name)
};
}
return O;
});
return {
targetCube: R,
pathFound: !0,
path: I,
pathLength: I.length,
visitedCubes: s
};
}
/**
* Analyze pre-aggregation requirements for hasMany relationships
* This mirrors the logic in planPreAggregationCTEs to ensure analysis matches execution
*/
analyzePreAggregations(E, e, R, A) {
const t = [];
if (!A.measures || A.measures.length === 0)
return t;
for (const s of R) {
const I = this.findHasManyJoinDef(e, s);
if (!I)
continue;
const r = E.get(s);
if (!r)
continue;
const S = A.measures.filter(
(L) => L.startsWith(s + ".")
), N = this.extractMeasuresFromFilters(A, r), O = [.../* @__PURE__ */ new Set([...S, ...N])];
if (O.length === 0)
continue;
const i = I.on.map((L) => ({
sourceColumn: L.source.name,
targetColumn: L.target.name
})), a = /* @__PURE__ */ new Map([[s, r]]), { aggregateMeasures: C, postAggWindowMeasures: _, requiredBaseMeasures: P } = B.categorizeForPostAggregation(
O,
a
), c = [.../* @__PURE__ */ new Set([
...C,
...Array.from(P).filter((L) => L.startsWith(s + "."))
])];
if (c.length > 0) {
const L = _.length > 0;
t.push({
cubeName: s,
cteAlias: `${s.toLowerCase()}_agg`,
reason: L ? `hasMany relationship from ${e.name} - requires pre-aggregation; includes base measures for post-aggregation window functions` : `hasMany relationship from ${e.name} - requires pre-aggregation to prevent row duplication (fan-out)`,
measures: c,
joinKeys: i,
cteType: "aggregate"
});
}
}
return t;
}
}
class rR {
constructor(E) {
this.queryBuilder = E;
}
/**
* Build pre-aggregation CTE for hasMany relationships
*
* Creates a CTE that:
* 1. Selects join keys and aggregated measures
* 2. Applies security context filtering
* 3. Groups by join keys and requested dimensions
* 4. Handles propagating filters from related cubes
*/
buildPreAggregationCTE(E, e, R, A, t) {
const s = E.cube, I = s.sql(R), r = {};
for (const L of E.joinKeys)
if (L.targetColumnObj) {
r[L.targetColumn] = L.targetColumnObj;
for (const [u, M] of Object.entries(s.dimensions || {}))
M.sql === L.targetColumnObj && u !== L.targetColumn && (r[u] = n`${L.targetColumnObj}`.as(u));
}
const S = s.name, N = /* @__PURE__ */ new Map([[S, s]]), O = this.queryBuilder.buildResolvedMeasures(
E.measures,
N,
R
);
for (const L of E.measures) {
const [, u] = L.split("."), M = O.get(L);
if (M) {
const d = M();
r[u] = n`${d}`.as(u);
}
}
if (e.dimensions)
for (const L of e.dimensions) {
const [u, M] = L.split(".");
if (u === S && s.dimensions && s.dimensions[M]) {
const d = s.dimensions[M], G = this.queryBuilder.buildMeasureExpression({ sql: d.sql, type: "number" }, R);
r[M] = n`${G}`.as(M);
}
}
if (e.timeDimensions)
for (const L of e.timeDimensions) {
const [u, M] = L.dimension.split(".");
if (u === S && s.dimensions && s.dimensions[M]) {
const d = s.dimensions[M], G = this.queryBuilder.buildTimeDimensionExpression(d.sql, L.granularity, R);
r[M] = n`${G}`.as(M);
}
}
if (Object.keys(r).length === 0)
return null;
let i = R.db.select(r).from(I.from);
const a = A ? {
...A,
preAggregationCTEs: A.preAggregationCTEs?.filter((L) => L.cube.name !== s.name)
} : void 0, C = this.queryBuilder.buildWhereConditions(s, e, R, a, t), _ = [];
if (e.timeDimensions)
for (const L of e.timeDimensions) {
const [u, M] = L.dimension.split(".");
if (u === S && s.dimensions && s.dimensions[M] && L.dateRange) {
const d = s.dimensions[M], G = this.queryBuilder.buildMeasureExpression({ sql: d.sql, type: "number" }, R), f = this.queryBuilder.buildDateRangeCondition(G, L.dateRange);
f && _.push(f);
}
}
if (e.filters) {
for (const L of e.filters)
if (!("and" in L) && !("or" in L) && "member" in L && "operator" in L) {
const u = L, [M, d] = u.member.split(".");
if (M === S && s.dimensions && s.dimensions[d]) {
const G = s.dimensions[d];
if (u.operator === "inDateRange") {
const f = this.queryBuilder.buildMeasureExpression({ sql: G.sql, type: "number" }, R), X = this.queryBuilder.buildDateRangeCondition(f, u.values);
X && _.push(X);
}
}
}
}
if (E.propagatingFilters && E.propagatingFilters.length > 0)
for (const L of E.propagatingFilters) {
const u = this.buildPropagatingFilterSubquery(
L,
R
);
u && _.push(u);
}
const P = [];
if (I.where && P.push(I.where), P.push(...C, ..._), P.length > 0) {
const L = P.length === 1 ? P[0] : F(...P);
i = i.where(L);
}
const c = [];
for (const L of E.joinKeys)
L.targetColumnObj && c.push(L.targetColumnObj);
if (e.dimensions)
for (const L of e.dimensions) {
const [u, M] = L.split(".");
if (u === S && s.dimensions && s.dimensions[M]) {
const d = s.dimensions[M], G = W(d.sql, R);
c.push(G);
}
}
if (e.timeDimensions)
for (const L of e.timeDimensions) {
const [u, M] = L.dimension.split(".");
if (u === S && s.dimensions && s.dimensions[M]) {
const d = s.dimensions[M], G = this.queryBuilder.buildTimeDimensionExpression(d.sql, L.granularity, R);
c.push(G);
}
}
return c.length > 0 && (i = i.groupBy(...c)), R.db.$with(E.cteAlias).as(i);
}
/**
* Build join condition for CTE
*
* Creates the ON clause for joining a CTE to the main query.
* Uses stored column objects for type-safe joins.
*/
buildCTEJoinCondition(E, e, R) {
const A = R.preAggregationCTEs?.find((s) => s.cube.name === E.cube.name);
if (!A)
throw new Error(`CTE info not found for cube ${E.cube.name}`);
const t = [];
for (const s of A.joinKeys) {
const I = s.sourceColumnObj || n.identifier(s.sourceColumn), r = n`${n.identifier(e)}.${n.identifier(s.targetColumn)}`;
t.push(Z(I, r));
}
return t.length === 1 ? t[0] : F(...t);
}
/**
* Build a subquery filter for propagating filters from related cubes.
*
* This generates: cteCube.FK IN (SELECT sourceCube.PK FROM sourceCube WHERE filters...)
*
* Example: For Productivity CTE with Employees.createdAt filter:
* employee_id IN (SELECT id FROM employees WHERE organisation_id = $1 AND created_at >= $date)
*
* For composite keys, uses EXISTS instead of IN for better database compatibility:
* EXISTS (SELECT 1 FROM source WHERE source.pk1 = cte.fk1 AND source.pk2 = cte.fk2 AND <filters>)
*/
buildPropagatingFilterSubquery(E, e) {
const R = E.sourceCube, A = R.sql(e), t = [];
if (A.where && t.push(A.where), E.preBuiltFilterSQL)
t.push(E.preBuiltFilterSQL);
else {
const r = {
filters: E.filters
}, S = /* @__PURE__ */ new Map([[R.name, R]]), N = this.queryBuilder.buildWhereConditions(
S,
r,
e
);
t.push(...N);
}
if (t.length === 0)
return null;
const s = t.length === 1 ? t[0] : F(...t), I = E.joinConditions;
if (I.length === 1) {
const { source: r, target: S } = I[0], N = e.db.select({ pk: r }).from(A.from).where(s);
return n`${S} IN ${N}`;
} else {
const r = I.map((O) => Z(O.source, O.target)), S = F(
...r,
s
), N = e.db.select({ one: n`1` }).from(A.from).where(S);
return n`EXISTS ${N}`;
}
}
}
function iR(T, E, e) {
const R = [];
let A = pe(new Date(T), e);
const t = pe(new Date(E), e), s = 1e4;
for (; A <= t && R.length < s; )
R.push(new Date(A)), A = aR(A, e);
return R;
}
function pe(T, E) {
const e = new Date(T);
switch (E) {
case "second":
e.setUTCMilliseconds(0);
break;
case "minute":
e.setUTCSeconds(0, 0);
break;
case "hour":
e.setUTCMinutes(0, 0, 0);
break;
case "day":
e.setUTCHours(0, 0, 0, 0);
break;
case "week": {
const R = e.getUTCDay(), A = R === 0 ? 6 : R - 1;
e.setUTCDate(e.getUTCDate() - A), e.setUTCHours(0, 0, 0, 0);
break;
}
case "month":
e.setUTCDate(1), e.setUTCHours(0, 0, 0, 0);
break;
case "quarter": {
const R = Math.floor(e.getUTCMonth() / 3) * 3;
e.setUTCMonth(R, 1), e.setUTCHours(0, 0, 0, 0);
break;
}
case "year":
e.setUTCMonth(0, 1), e.setUTCHours(0, 0, 0, 0);
break;
}
return e;
}
function aR(T, E) {
const e = new Date(T);
switch (E) {
case "second":
e.setUTCSeconds(e.getUTCSeconds() + 1);
break;
case "minute":
e.setUTCMinutes(e.getUTCMinutes() + 1);
break;
case "hour":
e.setUTCHours(e.getUTCHours() + 1);
break;
case "day":
e.setUTCDate(e.getUTCDate() + 1);
break;
case "week":
e.setUTCDate(e.getUTCDate() + 7);
break;
case "month":
e.setUTCMonth(e.getUTCMonth() + 1);
break;
case "quarter":
e.setUTCMonth(e.getUTCMonth() + 3);
break;
case "year":
e.setUTCFullYear(e.getUTCFullYear() + 1);
break;
}
return e;
}
function CR(T) {
if (T instanceof Date)
return T.toISOString();
if (typeof T == "string") {
const E = new Date(T);
if (!isNaN(E.getTime()))
return E.toISOString();
}
return String(T);
}
function oR(T, E) {
return E.length === 0 ? "__all__" : E.map((e) => String(T[e] ?? "")).join("|||");
}
function LR(T, E) {
const { timeDimensionKey: e, granularity: R, dateRange: A, fillValue: t, measures: s, dimensions: I } = E, r = iR(A[0], A[1], R);
if (r.length === 0)
return T;
const S = /* @__PURE__ */ new Map();
for (const O of T) {
const i = oR(O, I), a = CR(O[e]);
S.has(i) || S.set(i, /* @__PURE__ */ new Map()), S.get(i).set(a, O);
}
S.size === 0 && I.length === 0 && S.set("__all__", /* @__PURE__ */ new Map());
const N = [];
for (const [O, i] of S) {
const a = i.size > 0 ? i.values().next().value : null;
for (const C of r) {
const _ = C.toISOString(), P = i.get(_);
if (P)
N.push(P);
else {
const c = {
[e]: _
};
if (a)
for (const L of I)
c[L] = a[L];
for (const L of s)
c[L] = t;
N.push(c);
}
}
}
return N;
}
function _R(T) {
if (!T)
return null;
if (Array.isArray(T)) {
if (T.length < 2)
return null;
const e = new Date(T[0]), R = new Date(T[1]);
return isNaN(e.getTime()) || isNaN(R.getTime()) ? null : [e, R];
}
const E = new Date(T);
return isNaN(E.getTime()) ? null : [E, E];
}
function fe(T, E, e) {
if (!E.timeDimensions || E.timeDimensions.length === 0)
return T;
const R = E.timeDimensions.filter((r) => {
const S = r.fillMissingDates !== !1, N = r.granularity && r.dateRange;
return S && N;
});
if (R.length === 0)
return T;
const A = E.fillMissingDatesValue === void 0 ? 0 : E.fillMissingDatesValue, t = new Set(E.timeDimensions.map((r) => r.dimension)), s = (E.dimensions || []).filter((r) => !t.has(r));
let I = T;
for (const r of R) {
const S = _R(r.dateRange);
if (!S)
continue;
const N = {
timeDimensionKey: r.dimension,
granularity: r.granularity,
dateRange: S,
fillValue: A,
measures: e,
dimensions: s
};
I = LR(I, N);
}
return I;
}
class DR {
dateTimeBuilder;
constructor(E) {
this.dateTimeBuilder = new LT(E);
}
/**
* Check if a query contains compareDateRange
*/
hasComparison(E) {
return E.timeDimensions?.some(
(e) => e.compareDateRange && e.compareDateRange.length >= 2
) ?? !1;
}
/**
* Get the time dimension with compareDateRange
*/
getComparisonTimeDimension(E) {
return E.timeDimensions?.find(
(e) => e.compareDateRange && e.compareDateRange.length >= 2
);
}
/**
* Normalize compareDateRange entries to concrete date ranges
* Handles both relative strings ('last 30 days') and explicit arrays (['2024-01-01', '2024-01-31'])
*/
normalizePeriods(E) {
const e = [];
for (let R = 0; R < E.length; R++) {
const A = E[R];
let t, s, I;
if (typeof A == "string") {
const r = this.dateTimeBuilder.parseRelativeDateRange(A);
if (r)
t = r.start, s = r.end, I = A;
else {
const S = new Date(A);
if (!isNaN(S.getTime()))
t = new Date(S), t.setUTCHours(0, 0, 0, 0), s = new Date(S), s.setUTCHours(23, 59, 59, 999), I = A;
else
continue;
}
} else {
if (t = new Date(A[0]), s = new Date(A[1]), isNaN(t.getTime()) || isNaN(s.getTime()))
continue;
/^\d{4}-\d{2}-\d{2}$/.test(A[1]) && s.setUTCHours(23, 59, 59, 999), I = `${A[0]} - ${A[1]}`;
}
e.push({
start: t,
end: s,
label: I,
index: R
});
}
return e;
}
/**
* Create sub-query for a specific period
* Replaces compareDateRange with a concrete dateRange for that period
*/
createPeriodQuery(E, e) {
return {
...E,
timeDimensions: E.timeDimensions?.map((R) => R.compareDateRange ? {
...R,
dateRange: [
e.start.toISOString(),
e.end.toISOString()
],
// Remove compareDateRange to prevent recursion
compareDateRange: void 0
} : R)
};
}
/**
* Calculate the day-of-period index for a date
* Used for aligning data points across periods in overlay mode
*/
calculatePeriodDayIndex(E, e, R) {
const A = typeof E == "string" ? new Date(E) : E, t = e.getTime(), s = A.getTime();
switch (R) {
case "second":
return Math.floor((s - t) / 1e3);
case "minute":
return Math.floor((s - t) / (1e3 * 60));
case "hour":
return Math.floor((s - t) / (1e3 * 60 * 60));
case "day":
return Math.floor((s - t) / (1e3 * 60 * 60 * 24));
case "week":
return Math.floor((s - t) / (1e3 * 60 * 60 * 24 * 7));
case "month": {
const I = e.getUTCFullYear(), r = e.getUTCMonth(), S = A.getUTCFullYear(), N = A.getUTCMonth();
return (S - I) * 12 + (N - r);
}
case "quarter": {
const I = e.getUTCFullYear(), r = Math.floor(e.getUTCMonth() / 3), S = A.getUTCFullYear(), N = Math.floor(A.getUTCMonth() / 3);
return (S - I) * 4 + (N - r);
}
case "year":
return A.getUTCFullYear() - e.getUTCFullYear();
default:
return Math.floor((s - t) / (1e3 * 60 * 60 * 24));
}
}
/**
* Add period metadata to result rows
*/
addPeriodMetadata(E, e, R, A) {
return E.map((t) => {
const s = t[R];
let I = 0;
if (s) {
const r = typeof s == "string" ? new Date(s) : s instanceof Date ? s : null;
r && !isNaN(r.getTime()) && (I = this.calculatePeriodDayIndex(
r,
e.start,
A
));
}
return {
...t,
__period: e.label,
__periodIndex: e.index,
__periodDayIndex: I
};
});
}
/**
* Merge results from multiple period queries
* Adds period metadata and creates combined result with annotation
*/
mergeComparisonResults(E, e, R) {
const A = [];
let t = {
measures: {},
dimensions: {},
segments: {},
timeDimensions: {}
};
const s = E.map((r) => r.period);
for (const { result: r, period: S } of E) {
const N = this.addPeriodMetadata(
r.data,
S,
e.dimension,
R
);
A.push(...N), t = {
measures: { ...t.measures, ...r.annotation.measures },
dimensions: { ...t.dimensions, ...r.annotation.dimensions },
segments: { ...t.segments, ...r.annotation.segments },
timeDimensions: { ...t.timeDimensions, ...r.annotation.timeDimensions }
};
}
const I = {
ranges: s.map((r) => [
r.start.toISOString().split("T")[0],
r.end.toISOString().split("T")[0]
]),
labels: s.map((r) => r.label),
timeDimension: e.dimension,
granularity: R
};
return {
data: A,
annotation: {
...t,
periods: I
}
};
}
/**
* Sort merged results by period index and then by time dimension
* Ensures consistent ordering for client-side processing
*/
sortComparisonResults(E, e) {
return [...E].sort((R, A) => {
const t = R.__periodIndex - A.__periodIndex;
if (t !== 0) return t;
const s = R[e], I = A[e];
return typeof s == "string" && typeof I == "string" ? new Date(s).getTime() - new Date(I).getTime() : 0;
});
}
}
class HE {
constructor(E, e) {
if (this.dbExecutor = E, this.databaseAdapter = E.databaseAdapter, !this.databaseAdapter)
throw new Error("DatabaseExecutor must have a databaseAdapter property");
this.queryBuilder = new IR(this.databaseAdapter), this.queryPlanner = new _T(), this.cteBuilder = new rR(this.queryBuilder), this.comparisonQueryBuilder = new DR(this.databaseAdapter), this.cacheConfig = e;
}
queryBuilder;
queryPlanner;
cteBuilder;
databaseAdapter;
comparisonQueryBuilder;
cacheConfig;
/**
* Unified query execution method that handles both single and multi-cube queries
*/
async execute(E, e, R) {
try {
const A = HT(E, e);
if (!A.isValid)
throw new Error(`Query validation failed: ${A.errors.join(", ")}`);
let t;
if (this.cacheConfig?.enabled !== !1 && this.cacheConfig?.provider) {
t = TR(e, R, this.cacheConfig);
try {
const c = Date.now(), L = await this.cacheConfig.provider.get(t);
if (L)
return this.cacheConfig.onCacheEvent?.({
type: "hit",
key: t,
durationMs: Date.now() - c
}), {
...L.value,
cache: L.metadata ? {
hit: !0,
cachedAt: new Date(L.metadata.cachedAt).toISOString(),
ttlMs: L.metadata.ttlMs,
ttlRemainingMs: L.metadata.ttlRemainingMs
} : {
hit: !0,
cachedAt: (/* @__PURE__ */ new Date()).toISOString(),
ttlMs: 0,
ttlRemainingMs: 0
}
};
this.cacheConfig.onCacheEvent?.({
type: "miss",
key: t,
durationMs: Date.now() - c
});
} catch (c) {
this.cacheConfig.onError?.(c, "get");
}
}
if (this.comparisonQueryBuilder.hasComparison(e))
return this.executeComparisonQueryWithCache(E, e, R, t);
const s = new me(), I = {
db: this.dbExecutor.db,
schema: this.dbExecutor.schema,
securityContext: R,
filterCache: s
};
this.preloadFilterCache(e, s, E, I);
const r = this.queryPlanner.createQueryPlan(E, e, I);
this.validateSecurityContext(r, I);
const S = this.buildUnifiedQuery(r, e, I), N = this.queryBuilder.collectNumericFields(E, e), O = await this.dbExecutor.execute(S, N), i = Array.isArray(O) ? O.map((c) => {
const L = { ...c };
if (e.timeDimensions) {
for (const u of e.timeDimensions)
if (u.dimension in L) {
let M = L[u.dimension];
if (typeof M == "string" && M.match(/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/)) {
const d = M.replace(" ", "T"), G = !d.endsWith("Z") && !d.includes("+") ? d + "Z" : d;
M = new Date(G);
}
M = this.databaseAdapter.convertTimeDimensionResult(M), L[u.dimension] = M;
}
}
return L;
}) : [O], a = e.measures || [], C = fe(i, e, a), _ = this.generateAnnotations(r, e), P = {
data: C,
annotation: _
};
if (t && this.cacheConfig?.provider)
try {
const c = Date.now();
await this.cacheConfig.provider.set(
t,
P,
this.cacheConfig.defaultTtlMs ?? 3e5
), this.cacheConfig.onCacheEvent?.({
type: "set",
key: t,
durationMs: Date.now() - c
});
} catch (c) {
this.cacheConfig.onError?.(c, "set");
}
return P;
} catch (A) {
if (A instanceof Error) {
let t = A;
for (; t.cause instanceof Error; )
t = t.cause;
let s = t.message;
const I = t;
throw I.code && (s += ` [${I.code}]`), I.detail && (s += ` Detail: ${I.detail}`), I.hint && (s += ` Hint: ${I.hint}`), A.message = `Query execution failed: ${s}`, A;
}
throw new Error("Query execution failed: Unknown error");
}
}
/**
* Legacy interface for single cube queries
*/
async executeQuery(E, e, R) {
const A = /* @__PURE__ */ new Map();
return A.set(E.name, E), this.execute(A, e, R);
}
/**
* Execute a comparison query with caching support
* Wraps executeComparisonQuery with cache set logic
*/
async executeComparisonQueryWithCache(E, e, R, A) {
const t = await this.executeComparisonQuery(E, e, R);
if (A && this.cacheConfig?.provider)
try {
const s = Date.now();
await this.cacheConfig.provider.set(
A,
t,
this.cacheConfig.defaultTtlMs ?? 3e5
), this.cacheConfig.onCacheEvent?.({
type: "set",
key: A,
durationMs: Date.now() - s
});
} catch (s) {
this.cacheConfig.onError?.(s, "set");
}
return t;
}
/**
* Execute a comparison query with multiple date periods
* Expands compareDateRange into multiple sub-queries and merges results
*/
async executeComparisonQuery(E, e, R) {
const A = this.comparisonQueryBuilder.getComparisonTimeDimension(e);
if (!A || !A.compareDateRange)
throw new Error("No compareDateRange found in query");
const t = this.comparisonQueryBuilder.normalizePeriods(
A.compareDateRange
);
if (t.length < 2)
throw new Error("compareDateRange requires at least 2 periods");
const s = A.granularity || "day", I = t.map(async (N) => {
const O = this.comparisonQueryBuilder.createPeriodQuery(e, N);
return { result: await this.executeStandardQuery(E, O, R), period: N };
}), r = await Promise.all(I), S = this.comparisonQueryBuilder.mergeComparisonResults(
r,
A,
s
);
return S.data = this.comparisonQueryBuilder.sortComparisonResults(
S.data,
A.dimension
), S;
}
/**
* Standard query execution (non-comparison)
* This is the core execution logic extracted for use by comparison queries
*/
async executeStandardQuery(E, e, R) {
const A = new me(), t = {
db: this.dbExecutor.db,
schema: this.dbExecutor.schema,
securityContext: R,
filterCache: A
};
this.preloadFilterCache(e, A, E, t);
const s = this.queryPlanner.createQueryPlan(E, e, t), I = this.buildUnifiedQuery(s, e, t), r = this.queryBuilder.collectNumericFields(E, e), S = await this.dbExecutor.execute(I, r), N = Array.isArray(S) ? S.map((C) => {
const _ = { ...C };
if (e.timeDimensions) {
for (const P of e.timeDimensions)
if (P.dimension in _) {
let c = _[P.dimension];
if (typeof c == "string" && c.match(/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/)) {
const L = c.replace(" ", "T"), u = !L.endsWith("Z") && !L.includes("+") ? L + "Z" : L;
c = new Date(u);
}
c = this.databaseAdapter.convertTimeDimensionResult(c), _[P.dimension] = c;
}
}
return _;
}) : [S], O = e.measures || [], i = fe(N, e, O), a = this.generateAnnotations(s, e);
return {
data: i,
annotation: a
};
}
/**
* Validate that all cubes in the query plan have proper security filtering.
* Emits a warning if a cube's sql() function doesn't return a WHERE clause.
*
* Security is critical in multi-tenant applications - this validation helps
* detect cubes that may leak data across tenants.
*/
validateSecurityContext(E, e) {
const R = typeof process < "u" ? process.env?.NODE_ENV : void 0, A = typeof process < "u" ? process.env?.DRIZZLE_CUBE_WARN_SECURITY : void 0;
if (R !== "development" && !A)
return;
const t = [E.primaryCube];
for (const I of E.joinCubes || [])
t.push(I.cube);
for (const I of E.preAggregationCTEs || [])
t.push(I.cube);
const s = /* @__PURE__ */ new Set();
for (const I of t)
if (!s.has(I.name)) {
s.add(I.name);
try {
I.sql(e).where || console.warn(
`[drizzle-cube] WARNING: Cube '${I.name}' may not have proper security filtering. The sql() function returned no 'where' clause. Ensure it returns a filter like: { from: table, where: eq(table.organisationId, ctx.securityContext.organisationId) }`
);
} catch {
}
}
}
/**
* Build unified query that works for both single and multi-cube queries
*/
buildUnifiedQuery(E, e, R) {
const A = /* @__PURE__ */ new Map();
if (E.preAggregationCTEs && E.preAggregationCTEs.length > 0) {
for (const P of E.preAggregationCTEs)
if (P.propagatingFilters && P.propagatingFilters.length > 0)
for (const c of P.propagatingFilters) {
const L = c.sourceCube.name;
if (!A.has(L)) {
const M = {
filters: c.filters
}, d = /* @__PURE__ */ new Map([[L, c.sourceCube]]), G = this.queryBuilder.buildWhereConditions(
d,
M,
R
);
A.set(L, G);
}
const u = A.get(L);
u && u.length > 0 && (c.preBuiltFilterSQL = u.length === 1 ? u[0] : F(...u));
}
}
const t = [], s = /* @__PURE__ */ new Map();
if (E.preAggregationCTEs && E.preAggregationCTEs.length > 0)
for (const P of E.preAggregationCTEs) {
const c = this.cteBuilder.buildPreAggregationCTE(P, e, R, E, A);
c && (t.push(c), s.set(P.cube.name, P.cteAlias));
}
const I = E.primaryCube.sql(R), S = { ...this.queryBuilder.buildSelections(
E.joinCubes.length > 0 ? this.getCubesFromPlan(E) : E.primaryCube,
// Single cube
e,
R
) };
if (E.preAggregationCTEs)
for (const P of E.preAggregationCTEs) {
const c = P.cube.name;
for (const L of P.measures)
if (S[L]) {
const [, u] = L.split("."), M = this.getCubesFromPlan(E).get(c);
if (M && M.measures && M.measures[u]) {
const d = M.measures[u], G = n`${n.identifier(P.cteAlias)}.${n.identifier(u)}`;
let f;
if (d.type === "calculated" && d.calculatedSql) {
const X = this.getCubesFromPlan(E);
f = this.queryBuilder.buildCTECalculatedMeasure(
d,
M,
P,
X,
R
);
} else
switch (d.type) {
case "count":
case "countDistinct":
case "sum":
f = w(G);
break;
case "avg":
f = this.databaseAdapter.buildAvg(G);
break;
case "min":
f = nE(G);
break;
case "max":
f = OE(G);
break;
case "number":
f = w(G);
break;
default:
f = w(G);
}
S[L] = n`${f}`.as(L);
}
}
for (const L in S) {
const [u, M] = L.split(".");
if (u === c) {
const d = this.getCubesFromPlan(E).get(c), G = d && d.dimensions?.[M], f = L.startsWith(c + ".");
if (G || f) {
let X = P.joinKeys.find((v) => v.targetColumn === M);
if (!X && d?.dimensions?.[M]) {
const v = d.dimensions[M].sql;
X = P.joinKeys.find((uE) => uE.targetColumnObj === v);
}
X ? S[L] = n`${n.identifier(P.cteAlias)}.${n.identifier(M)}`.as(L) : f && d?.dimensions?.[M] && (S[L] = n`${n.identifier(P.cteAlias)}.${n.identifier(M)}`.as(L));
}
}
}
}
if (e.measures) {
const P = this.getCubesFromPlan(E);
for (const c of e.measures) {
const [L, u] = c.split("."), M = P.get(L);
if (M?.measures?.[u]) {
const d = M.measures[u];
if (B.isPostAggregationWindow(d)) {
const G = B.getWindowBaseMeasure(d, L);
if (G) {
const [f, X] = G.split("."), v = P.get(f);
if (v?.measures?.[X]) {
const uE = v.measures[X], ie = E.preAggregationCTEs?.find(
(NE) => NE.cube?.name === f && NE.measures?.includes(G)
);
let SE;
if (ie) {
const NE = n`${n.identifier(ie.cteAlias)}.${n.identifier(X)}`;
SE = n`sum(${NE})`;
} else
SE = this.queryBuilder.buildMeasureExpression(uE, R, v);
S[G] || (S[G] = n`${SE}`.as(G));
const ae = this.buildPostAggregationWindowExpression(
d,
SE,
e,
R,
M,
E
);
ae && (S[c] = n`${ae}`.as(c));
}
}
}
}
}
}
const N = [];
let O = R.db.select(S).from(I.from);
if (t.length > 0 && (O = R.db.with(...t).select(S).from(I.from)), I.joins)
for (const P of I.joins)
switch (P.type || "left") {
case "left":
O = O.leftJoin(P.table, P.on);
break;
case "inner":
O = O.innerJoin(P.table, P.on);
break;
case "right":
O = O.rightJoin(P.table, P.on);
break;
case "full":
O = O.fullJoin(P.table, P.on);
break;
}
if (E.joinCubes && E.joinCubes.length > 0)
for (const P of E.joinCubes) {
const c = s.get(P.cube.name);
if (P.junctionTable) {
const M = P.junctionTable, d = [];
if (M.securitySql) {
const G = M.securitySql(R.securityContext);
Array.isArray(G) ? d.push(...G) : d.push(G);
}
try {
switch (M.joinType || "left") {
case "left":
O = O.leftJoin(M.table, M.joinCondition);
break;
case "inner":
O = O.innerJoin(M.table, M.joinCondition);
break;
case "right":
O = O.rightJoin(M.table, M.joinCondition);
break;
case "full":
O = O.fullJoin(M.table, M.joinCondition);
break;
}
d.length > 0 && N.push(...d);
} catch {
}
}
let L, u;
c ? (L = n`${n.identifier(c)}`, u = this.cteBuilder.buildCTEJoinCondition(P, c, E)) : (L = P.cube.sql(R).from, u = P.joinCondition);
try {
switch (P.joinType || "left") {
case "left":
O = O.leftJoin(L, u);
break;
case "inner":
O = O.innerJoin(L, u);
break;
case "right":
O = O.rightJoin(L, u);
break;
case "full":
O = O.fullJoin(L, u);
break;
}
} catch {
}
}
if (I.where && N.push(I.where), E.joinCubes && E.joinCubes.length > 0)
for (const P of E.joinCubes) {
if (s.get(P.cube.name))
continue;
const L = P.cube.sql(R);
L.where && N.push(L.where);
}
const i = this.queryBuilder.buildWhereConditions(
E.joinCubes.length > 0 ? this.getCubesFromPlan(E) : E.primaryCube,
// Single cube
e,
R,
E,
// Pass the queryPlan to handle CTE scenarios
A
// Reuse pre-built filters for parameter deduplication
);
if (i.length > 0 && N.push(...i), N.length > 0) {
const P = N.length === 1 ? N[0] : F(...N);
O = O.where(P);
}
const a = this.queryBuilder.buildGroupByFields(
E.joinCubes.length > 0 ? this.getCubesFromPlan(E) : E.primaryCube,
// Single cube
e,
R,
E
// Pass the queryPlan to handle CTE scenarios
);
a.length > 0 && (O = O.groupBy(...a));
const C = this.queryBuilder.buildHavingConditions(
E.joinCubes.length > 0 ? this.getCubesFromPlan(E) : E.primaryCube,
// Single cube
e,
R,
E
// Pass the queryPlan to handle CTE scenarios
);
if (C.length > 0) {
const P = C.length === 1 ? C[0] : F(...C);
O = O.having(P);
}
const _ = this.queryBuilder.buildOrderBy(e);
return _.length > 0 && (O = O.orderBy(..._)), O = this.queryBuilder.applyLimitAndOffset(O, e), O;
}
/**
* Convert query plan to cube map for QueryBuilder methods
*/
getCubesFromPlan(E) {
const e = /* @__PURE__ */ new Map();
if (e.set(E.primaryCube.name, E.primaryCube), E.joinCubes)
for (const R of E.joinCubes)
e.set(R.cube.name, R.cube);
return e;
}
/**
* Generate raw SQL for debugging (without execution) - unified approach
*/
async generateSQL(E, e, R) {
const A = /* @__PURE__ */ new Map();
return A.set(E.name, E), this.generateUnifiedSQL(A, e, R);
}
/**
* Generate raw SQL for multi-cube queries without execution - unified approach
*/
async generateMultiCubeSQL(E, e, R) {
return this.generateUnifiedSQL(E, e, R);
}
/**
* Generate SQL using unified approach (works for both single and multi-cube)
*/
async generateUnifiedSQL(E, e, R) {
const A = {
db: this.dbExecutor.db,
schema: this.dbExecutor.schema,
securityContext: R
}, t = this.queryPlanner.createQueryPlan(E, e, A), I = this.buildUnifiedQuery(t, e, A).toSQL();
return {
sql: I.sql,
params: I.params
};
}
/**
* Generate annotations for UI metadata - unified approach
*/
generateAnnotations(E, e) {
const R = {}, A = {}, t = {}, s = [E.primaryCube].filter(Boolean);
if (E.joinCubes && E.joinCubes.length > 0 && s.push(...E.joinCubes.map((I) => I.cube).filter(Boolean)), e.measures)
for (const I of e.measures) {
const [r, S] = I.split("."), N = s.find((O) => O?.name === r);
if (N && N.measures[S]) {
const O = N.measures[S];
R[I] = {
title: O.title || S,
shortTitle: O.title || S,
type: O.type
};
}
}
if (e.dimensions)
for (const I of e.dimensions) {
const [r, S] = I.split("."), N = s.find((O) => O?.name === r);
if (N && N.dimensions?.[S]) {
const O = N.dimensions[S];
A[I] = {
title: O.title || S,
shortTitle: O.title || S,
type: O.type
};
}
}
if (e.timeDimensions)
for (const I of e.timeDimensions) {
const [r, S] = I.dimension.split("."), N = s.find((O) => O?.name === r);
if (N && N.dimensions?.[S]) {
const O = N.dimensions[S];
t[I.dimension] = {
title: O.title || S,
shortTitle: O.title || S,
type: O.type,
granularity: I.granularity
};
}
}
return {
measures: R,
dimensions: A,
segments: {},
timeDimensions: t
};
}
/**
* Pre-build filter SQL and store in cache for reuse across CTEs and main query
* This enables parameter deduplication - the same filter values are shared
* rather than appearing as separate parameters in different parts of the query
*/
preloadFilterCache(E, e, R, A) {
if (E.filters && E.filters.length > 0) {
const t = se(E.filters);
for (const s of t) {
const I = PE(s);
if (e.has(I)) continue;
const [r, S] = s.member.split("."), N = R.get(r);
if (!N) continue;
const O = N.dimensions?.[S];
if (!O || ["arrayContains", "arrayOverlaps", "arrayContained"].includes(s.operator))
continue;
const a = W(O.sql, A), C = this.queryBuilder.buildFilterConditionPublic(
a,
s.operator,
s.values,
O,
s.dateRange
);
C && e.set(I, C);
}
}
if (E.timeDimensions) {
for (const t of E.timeDimensions)
if (t.dateRange) {
const s = oT(t.dimension, t.dateRange);
if (e.has(s)) continue;
const [I, r] = t.dimension.split("."), S = R.get(I);
if (!S) continue;
const N = S.dimensions?.[r];
if (!N) continue;
const O = W(N.sql, A), i = this.queryBuilder.buildDateRangeCondition(O, t.dateRange);
i && e.set(s, i);
}
}
}
/**
* Build post-aggregation window function expression
*
* Post-aggregation windows operate on already-aggregated data:
* 1. The base measure is aggregated (e.g., SUM(revenue))
* 2. The window function is applied (e.g., LAG(...) OVER ORDER BY date)
* 3. An optional operation is applied (e.g., current - previous)
*
* @param measure - The window function measure definition
* @param baseMeasureExpr - The aggregated base measure expression
* @param query - The semantic query (for dimension context)
* @param context - Query context
* @param cube - The cube containing this measure
* @returns SQL expression for the window function
*/
buildPostAggregationWindowExpression(E, e, R, A, t, s) {
const I = E.windowConfig || {}, r = (a, C) => {
if (!s?.preAggregationCTEs) return null;
const _ = s.preAggregationCTEs.find((P) => P.cube?.name === a);
return _ && _.cteAlias ? n`${n.identifier(_.cteAlias)}.${n.identifier(C)}` : null;
};
let S;
if (I.orderBy && I.orderBy.length > 0)
S = I.orderBy.map((a) => {
const C = a.field.includes(".") ? a.field.split(".")[1] : a.field;
if (R.timeDimensions)
for (const c of R.timeDimensions) {
const [L, u] = c.dimension.split(".");
if (u === C) {
const M = r(L, C);
if (M)
return {
field: M,
direction: a.direction
};
const d = t.dimensions?.[u];
if (d)
return {
field: this.queryBuilder.buildTimeDimensionExpression(
d.sql,
c.granularity,
A
),
direction: a.direction
};
}
}
const _ = t.dimensions?.[C];
if (_)
return {
field: W(_.sql, A),
direction: a.direction
};
const P = I.measure?.includes(".") ? I.measure.split(".")[1] : I.measure;
return C === P || a.field === I.measure ? {
field: e,
direction: a.direction
} : null;
}).filter((a) => a !== null);
else if (R.timeDimensions && R.timeDimensions.length > 0) {
const a = R.timeDimensions[0], [C, _] = a.dimension.split("."), P = r(C, _);
if (P)
S = [{
field: P,
direction: "asc"
}];
else {
const c = t.name === C ? t : void 0;
if (c?.dimensions?.[_]) {
const L = c.dimensions[_];
S = [{
field: this.queryBuilder.buildTimeDimensionExpression(
L.sql,
a.granularity,
A
),
direction: "asc"
}];
}
}
}
let N;
I.partitionBy && I.partitionBy.length > 0 && (N = I.partitionBy.map((a) => {
const C = a.includes(".") ? a.split(".")[1] : a, _ = t.dimensions?.[C];
return _ ? W(_.sql, A) : null;
}).filter((a) => a !== null));
const O = this.databaseAdapter.buildWindowFunction(
E.type,
e,
N,
S,
{
offset: I.offset,
defaultValue: I.defaultValue,
nTile: I.nTile,
frame: I.frame
}
);
if (!O)
return null;
switch (I.operation || B.getDefaultWindowOperation(E.type)) {
case "difference":
return n`${e} - ${O}`;
case "ratio":
return n`${e} / NULLIF(${O}, 0)`;
case "percentChange":
return n`((${e} - ${O}) / NULLIF(${O}, 0)) * 100`;
default:
return O;
}
}
}
const o = (T) => T.flatMap(PR), PR = (T) => rE(cR(T)).map(lR), lR = (T) => T.replace(/ +/g, " ").trim(), cR = (T) => ({
type: "mandatory_block",
items: re(T, 0)[0]
}), re = (T, E, e) => {
const R = [];
for (; T[E]; ) {
const [A, t] = MR(T, E);
if (R.push(A), E = t, T[E] === "|")
E++;
else if (T[E] === "}" || T[E] === "]") {
if (e !== T[E])
throw new Error(`Unbalanced parenthesis in: ${T}`);
return E++, [R, E];
} else if (E === T.length) {
if (e)
throw new Error(`Unbalanced parenthesis in: ${T}`);
return [R, E];
} else
throw new Error(`Unexpected "${T[E]}"`);
}
return [R, E];
}, MR = (T, E) => {
const e = [];
for (; ; ) {
const [R, A] = uR(T, E);
if (R)
e.push(R), E = A;
else
break;
}
return e.length === 1 ? [e[0], E] : [{ type: "concatenation", items: e }, E];
}, uR = (T, E) => {
if (T[E] === "{")
return UR(T, E + 1);
if (T[E] === "[")
return dR(T, E + 1);
{
let e = "";
for (; T[E] && /[A-Za-z0-9_ ]/.test(T[E]); )
e += T[E], E++;
return [e, E];
}
}, UR = (T, E) => {
const [e, R] = re(T, E, "}");
return [{ type: "mandatory_block", items: e }, R];
}, dR = (T, E) => {
const [e, R] = re(T, E, "]");
return [{ type: "optional_block", items: e }, R];
}, rE = (T) => {
if (typeof T == "string")
return [T];
if (T.type === "concatenation")
return T.items.map(rE).reduce(mR, [""]);
if (T.type === "mandatory_block")
return T.items.flatMap(rE);
if (T.type === "optional_block")
return ["", ...T.items.flatMap(rE)];
throw new Error(`Unknown node type: ${T}`);
}, mR = (T, E) => {
const e = [];
for (const R of T)
for (const A of E)
e.push(R + A);
return e;
};
var l;
(function(T) {
T.QUOTED_IDENTIFIER = "QUOTED_IDENTIFIER", T.IDENTIFIER = "IDENTIFIER", T.STRING = "STRING", T.VARIABLE = "VARIABLE", T.RESERVED_DATA_TYPE = "RESERVED_DATA_TYPE", T.RESERVED_PARAMETERIZED_DATA_TYPE = "RESERVED_PARAMETERIZED_DATA_TYPE", T.RESERVED_KEYWORD = "RESERVED_KEYWORD", T.RESERVED_FUNCTION_NAME = "RESERVED_FUNCTION_NAME", T.RESERVED_KEYWORD_PHRASE = "RESERVED_KEYWORD_PHRASE", T.RESERVED_DATA_TYPE_PHRASE = "RESERVED_DATA_TYPE_PHRASE", T.RESERVED_SET_OPERATION = "RESERVED_SET_OPERATION", T.RESERVED_CLAUSE = "RESERVED_CLAUSE", T.RESERVED_SELECT = "RESERVED_SELECT", T.RESERVED_JOIN = "RESERVED_JOIN", T.ARRAY_IDENTIFIER = "ARRAY_IDENTIFIER", T.ARRAY_KEYWORD = "ARRAY_KEYWORD", T.CASE = "CASE", T.END = "END", T.WHEN = "WHEN", T.ELSE = "ELSE", T.THEN = "THEN", T.LIMIT = "LIMIT", T.BETWEEN = "BETWEEN", T.AND = "AND", T.OR = "OR", T.XOR = "XOR", T.OPERATOR = "OPERATOR", T.COMMA = "COMMA", T.ASTERISK = "ASTERISK", T.PROPERTY_ACCESS_OPERATOR = "PROPERTY_ACCESS_OPERATOR", T.OPEN_PAREN = "OPEN_PAREN", T.CLOSE_PAREN = "CLOSE_PAREN", T.LINE_COMMENT = "LINE_COMMENT", T.BLOCK_COMMENT = "BLOCK_COMMENT", T.DISABLE_COMMENT = "DISABLE_COMMENT", T.NUMBER = "NUMBER", T.NAMED_PARAMETER = "NAMED_PARAMETER", T.QUOTED_PARAMETER = "QUOTED_PARAMETER", T.NUMBERED_PARAMETER = "NUMBERED_PARAMETER", T.POSITIONAL_PARAMETER = "POSITIONAL_PARAMETER", T.CUSTOM_PARAMETER = "CUSTOM_PARAMETER", T.DELIMITER = "DELIMITER", T.EOF = "EOF";
})(l = l || (l = {}));
const DT = (T) => ({
type: l.EOF,
raw: "«EOF»",
text: "«EOF»",
start: T
}), TE = DT(1 / 0), k = (T) => (E) => E.type === T.type && E.text === T.text, j = {
ARRAY: k({ text: "ARRAY", type: l.RESERVED_DATA_TYPE }),
BY: k({ text: "BY", type: l.RESERVED_KEYWORD }),
SET: k({ text: "SET", type: l.RESERVED_CLAUSE }),
STRUCT: k({ text: "STRUCT", type: l.RESERVED_DATA_TYPE }),
WINDOW: k({ text: "WINDOW", type: l.RESERVED_CLAUSE }),
VALUES: k({ text: "VALUES", type: l.RESERVED_CLAUSE })
}, PT = (T) => T === l.RESERVED_DATA_TYPE || T === l.RESERVED_KEYWORD || T === l.RESERVED_FUNCTION_NAME || T === l.RESERVED_KEYWORD_PHRASE || T === l.RESERVED_DATA_TYPE_PHRASE || T === l.RESERVED_CLAUSE || T === l.RESERVED_SELECT || T === l.RESERVED_SET_OPERATION || T === l.RESERVED_JOIN || T === l.ARRAY_KEYWORD || T === l.CASE || T === l.END || T === l.WHEN || T === l.ELSE || T === l.THEN || T === l.LIMIT || T === l.BETWEEN || T === l.AND || T === l.OR || T === l.XOR, GR = (T) => T === l.AND || T === l.OR || T === l.XOR, pR = [
// https://cloud.google.com/bigquery/docs/reference/standard-sql/aead_encryption_functions
"KEYS.NEW_KEYSET",
"KEYS.ADD_KEY_FROM_RAW_BYTES",
"AEAD.DECRYPT_BYTES",
"AEAD.DECRYPT_STRING",
"AEAD.ENCRYPT",
"KEYS.KEYSET_CHAIN",
"KEYS.KEYSET_FROM_JSON",
"KEYS.KEYSET_TO_JSON",
"KEYS.ROTATE_KEYSET",
"KEYS.KEYSET_LENGTH",
// https://cloud.google.com/bigquery/docs/reference/standard-sql/aggregate_analytic_functions
"ANY_VALUE",
"ARRAY_AGG",
"AVG",
"CORR",
"COUNT",
"COUNTIF",
"COVAR_POP",
"COVAR_SAMP",
"MAX",
"MIN",
"ST_CLUSTERDBSCAN",
"STDDEV_POP",
"STDDEV_SAMP",
"STRING_AGG",
"SUM",
"VAR_POP",
"VAR_SAMP",
// https://cloud.google.com/bigquery/docs/reference/standard-sql/aggregate_functions
"ANY_VALUE",
"ARRAY_AGG",
"ARRAY_CONCAT_AGG",
"AVG",
"BIT_AND",
"BIT_OR",
"BIT_XOR",
"COUNT",
"COUNTIF",
"LOGICAL_AND",
"LOGICAL_OR",
"MAX",
"MIN",
"STRING_AGG",
"SUM",
// https://cloud.google.com/bigquery/docs/reference/standard-sql/approximate_aggregate_functions
"APPROX_COUNT_DISTINCT",
"APPROX_QUANTILES",
"APPROX_TOP_COUNT",
"APPROX_TOP_SUM",
// https://cloud.google.com/bigquery/docs/reference/standard-sql/array_functions
// 'ARRAY',
"ARRAY_CONCAT",
"ARRAY_LENGTH",
"ARRAY_TO_STRING",
"GENERATE_ARRAY",
"GENERATE_DATE_ARRAY",
"GENERATE_TIMESTAMP_ARRAY",
"ARRAY_REVERSE",
"OFFSET",
"SAFE_OFFSET",
"ORDINAL",
"SAFE_ORDINAL",
// https://cloud.google.com/bigquery/docs/reference/standard-sql/bit_functions
"BIT_COUNT",
// https://cloud.google.com/bigquery/docs/reference/standard-sql/conversion_functions
// 'CASE',
"PARSE_BIGNUMERIC",
"PARSE_NUMERIC",
"SAFE_CAST",
// https://cloud.google.com/bigquery/docs/reference/standard-sql/date_functions
"CURRENT_DATE",
"EXTRACT",
"DATE",
"DATE_ADD",
"DATE_SUB",
"DATE_DIFF",
"DATE_TRUNC",
"DATE_FROM_UNIX_DATE",
"FORMAT_DATE",
"LAST_DAY",
"PARSE_DATE",
"UNIX_DATE",
// https://cloud.google.com/bigquery/docs/reference/standard-sql/datetime_functions
"CURRENT_DATETIME",
"DATETIME",
"EXTRACT",
"DATETIME_ADD",
"DATETIME_SUB",
"DATETIME_DIFF",
"DATETIME_TRUNC",
"FORMAT_DATETIME",
"LAST_DAY",
"PARSE_DATETIME",
// https://cloud.google.com/bigquery/docs/reference/standard-sql/debugging_functions
"ERROR",
// https://cloud.google.com/bigquery/docs/reference/standard-sql/federated_query_functions
"EXTERNAL_QUERY",
// https://cloud.google.com/bigquery/docs/reference/standard-sql/geography_functions
"S2_CELLIDFROMPOINT",
"S2_COVERINGCELLIDS",
"ST_ANGLE",
"ST_AREA",
"ST_ASBINARY",
"ST_ASGEOJSON",
"ST_ASTEXT",
"ST_AZIMUTH",
"ST_BOUNDARY",
"ST_BOUNDINGBOX",
"ST_BUFFER",
"ST_BUFFERWITHTOLERANCE",
"ST_CENTROID",
"ST_CENTROID_AGG",
"ST_CLOSESTPOINT",
"ST_CLUSTERDBSCAN",
"ST_CONTAINS",
"ST_CONVEXHULL",
"ST_COVEREDBY",
"ST_COVERS",
"ST_DIFFERENCE",
"ST_DIMENSION",
"ST_DISJOINT",
"ST_DISTANCE",
"ST_DUMP",
"ST_DWITHIN",
"ST_ENDPOINT",
"ST_EQUALS",
"ST_EXTENT",
"ST_EXTERIORRING",
"ST_GEOGFROM",
"ST_GEOGFROMGEOJSON",
"ST_GEOGFROMTEXT",
"ST_GEOGFROMWKB",
"ST_GEOGPOINT",
"ST_GEOGPOINTFROMGEOHASH",
"ST_GEOHASH",
"ST_GEOMETRYTYPE",
"ST_INTERIORRINGS",
"ST_INTERSECTION",
"ST_INTERSECTS",
"ST_INTERSECTSBOX",
"ST_ISCOLLECTION",
"ST_ISEMPTY",
"ST_LENGTH",
"ST_MAKELINE",
"ST_MAKEPOLYGON",
"ST_MAKEPOLYGONORIENTED",
"ST_MAXDISTANCE",
"ST_NPOINTS",
"ST_NUMGEOMETRIES",
"ST_NUMPOINTS",
"ST_PERIMETER",
"ST_POINTN",
"ST_SIMPLIFY",
"ST_SNAPTOGRID",
"ST_STARTPOINT",
"ST_TOUCHES",
"ST_UNION",
"ST_UNION_AGG",
"ST_WITHIN",
"ST_X",
"ST_Y",
// https://cloud.google.com/bigquery/docs/reference/standard-sql/hash_functions
"FARM_FINGERPRINT",
"MD5",
"SHA1",
"SHA256",
"SHA512",
// https://cloud.google.com/bigquery/docs/reference/standard-sql/hll_functions
"HLL_COUNT.INIT",
"HLL_COUNT.MERGE",
"HLL_COUNT.MERGE_PARTIAL",
"HLL_COUNT.EXTRACT",
// https://cloud.google.com/bigquery/docs/reference/standard-sql/interval_functions
"MAKE_INTERVAL",
"EXTRACT",
"JUSTIFY_DAYS",
"JUSTIFY_HOURS",
"JUSTIFY_INTERVAL",
// https://cloud.google.com/bigquery/docs/reference/standard-sql/json_functions
"JSON_EXTRACT",
"JSON_QUERY",
"JSON_EXTRACT_SCALAR",
"JSON_VALUE",
"JSON_EXTRACT_ARRAY",
"JSON_QUERY_ARRAY",
"JSON_EXTRACT_STRING_ARRAY",
"JSON_VALUE_ARRAY",
"TO_JSON_STRING",
// https://cloud.google.com/bigquery/docs/reference/standard-sql/mathematical_functions
"ABS",
"SIGN",
"IS_INF",
"IS_NAN",
"IEEE_DIVIDE",
"RAND",
"SQRT",
"POW",
"POWER",
"EXP",
"LN",
"LOG",
"LOG10",
"GREATEST",
"LEAST",
"DIV",
"SAFE_DIVIDE",
"SAFE_MULTIPLY",
"SAFE_NEGATE",
"SAFE_ADD",
"SAFE_SUBTRACT",
"MOD",
"ROUND",
"TRUNC",
"CEIL",
"CEILING",
"FLOOR",
"COS",
"COSH",
"ACOS",
"ACOSH",
"SIN",
"SINH",
"ASIN",
"ASINH",
"TAN",
"TANH",
"ATAN",
"ATANH",
"ATAN2",
"RANGE_BUCKET",
// https://cloud.google.com/bigquery/docs/reference/standard-sql/navigation_functions
"FIRST_VALUE",
"LAST_VALUE",
"NTH_VALUE",
"LEAD",
"LAG",
"PERCENTILE_CONT",
"PERCENTILE_DISC",
// https://cloud.google.com/bigquery/docs/reference/standard-sql/net_functions
"NET.IP_FROM_STRING",
"NET.SAFE_IP_FROM_STRING",
"NET.IP_TO_STRING",
"NET.IP_NET_MASK",
"NET.IP_TRUNC",
"NET.IPV4_FROM_INT64",
"NET.IPV4_TO_INT64",
"NET.HOST",
"NET.PUBLIC_SUFFIX",
"NET.REG_DOMAIN",
// https://cloud.google.com/bigquery/docs/reference/standard-sql/numbering_functions
"RANK",
"DENSE_RANK",
"PERCENT_RANK",
"CUME_DIST",
"NTILE",
"ROW_NUMBER",
// https://cloud.google.com/bigquery/docs/reference/standard-sql/security_functions
"SESSION_USER",
// https://cloud.google.com/bigquery/docs/reference/standard-sql/statistical_aggregate_functions
"CORR",
"COVAR_POP",
"COVAR_SAMP",
"STDDEV_POP",
"STDDEV_SAMP",
"STDDEV",
"VAR_POP",
"VAR_SAMP",
"VARIANCE",
// https://cloud.google.com/bigquery/docs/reference/standard-sql/string_functions
"ASCII",
"BYTE_LENGTH",
"CHAR_LENGTH",
"CHARACTER_LENGTH",
"CHR",
"CODE_POINTS_TO_BYTES",
"CODE_POINTS_TO_STRING",
"CONCAT",
"CONTAINS_SUBSTR",
"ENDS_WITH",
"FORMAT",
"FROM_BASE32",
"FROM_BASE64",
"FROM_HEX",
"INITCAP",
"INSTR",
"LEFT",
"LENGTH",
"LPAD",
"LOWER",
"LTRIM",
"NORMALIZE",
"NORMALIZE_AND_CASEFOLD",
"OCTET_LENGTH",
"REGEXP_CONTAINS",
"REGEXP_EXTRACT",
"REGEXP_EXTRACT_ALL",
"REGEXP_INSTR",
"REGEXP_REPLACE",
"REGEXP_SUBSTR",
"REPLACE",
"REPEAT",
"REVERSE",
"RIGHT",
"RPAD",
"RTRIM",
"SAFE_CONVERT_BYTES_TO_STRING",
"SOUNDEX",
"SPLIT",
"STARTS_WITH",
"STRPOS",
"SUBSTR",
"SUBSTRING",
"TO_BASE32",
"TO_BASE64",
"TO_CODE_POINTS",
"TO_HEX",
"TRANSLATE",
"TRIM",
"UNICODE",
"UPPER",
// https://cloud.google.com/bigquery/docs/reference/standard-sql/time_functions
"CURRENT_TIME",
"TIME",
"EXTRACT",
"TIME_ADD",
"TIME_SUB",
"TIME_DIFF",
"TIME_TRUNC",
"FORMAT_TIME",
"PARSE_TIME",
// https://cloud.google.com/bigquery/docs/reference/standard-sql/timestamp_functions
"CURRENT_TIMESTAMP",
"EXTRACT",
"STRING",
"TIMESTAMP",
"TIMESTAMP_ADD",
"TIMESTAMP_SUB",
"TIMESTAMP_DIFF",
"TIMESTAMP_TRUNC",
"FORMAT_TIMESTAMP",
"PARSE_TIMESTAMP",
"TIMESTAMP_SECONDS",
"TIMESTAMP_MILLIS",
"TIMESTAMP_MICROS",
"UNIX_SECONDS",
"UNIX_MILLIS",
"UNIX_MICROS",
// https://cloud.google.com/bigquery/docs/reference/standard-sql/uuid_functions
"GENERATE_UUID",
// https://cloud.google.com/bigquery/docs/reference/standard-sql/conditional_expressions
"COALESCE",
"IF",
"IFNULL",
"NULLIF",
// https://cloud.google.com/bigquery/docs/reference/legacy-sql
// legacyAggregate
"AVG",
"BIT_AND",
"BIT_OR",
"BIT_XOR",
"CORR",
"COUNT",
"COVAR_POP",
"COVAR_SAMP",
"EXACT_COUNT_DISTINCT",
"FIRST",
"GROUP_CONCAT",
"GROUP_CONCAT_UNQUOTED",
"LAST",
"MAX",
"MIN",
"NEST",
"NTH",
"QUANTILES",
"STDDEV",
"STDDEV_POP",
"STDDEV_SAMP",
"SUM",
"TOP",
"UNIQUE",
"VARIANCE",
"VAR_POP",
"VAR_SAMP",
// legacyBitwise
"BIT_COUNT",
// legacyCasting
"BOOLEAN",
"BYTES",
"CAST",
"FLOAT",
"HEX_STRING",
"INTEGER",
"STRING",
// legacyComparison
// expr 'IN',
"COALESCE",
"GREATEST",
"IFNULL",
"IS_INF",
"IS_NAN",
"IS_EXPLICITLY_DEFINED",
"LEAST",
"NVL",
// legacyDatetime
"CURRENT_DATE",
"CURRENT_TIME",
"CURRENT_TIMESTAMP",
"DATE",
"DATE_ADD",
"DATEDIFF",
"DAY",
"DAYOFWEEK",
"DAYOFYEAR",
"FORMAT_UTC_USEC",
"HOUR",
"MINUTE",
"MONTH",
"MSEC_TO_TIMESTAMP",
"NOW",
"PARSE_UTC_USEC",
"QUARTER",
"SEC_TO_TIMESTAMP",
"SECOND",
"STRFTIME_UTC_USEC",
"TIME",
"TIMESTAMP",
"TIMESTAMP_TO_MSEC",
"TIMESTAMP_TO_SEC",
"TIMESTAMP_TO_USEC",
"USEC_TO_TIMESTAMP",
"UTC_USEC_TO_DAY",
"UTC_USEC_TO_HOUR",
"UTC_USEC_TO_MONTH",
"UTC_USEC_TO_WEEK",
"UTC_USEC_TO_YEAR",
"WEEK",
"YEAR",
// legacyIp
"FORMAT_IP",
"PARSE_IP",
"FORMAT_PACKED_IP",
"PARSE_PACKED_IP",
// legacyJson
"JSON_EXTRACT",
"JSON_EXTRACT_SCALAR",
// legacyMath
"ABS",
"ACOS",
"ACOSH",
"ASIN",
"ASINH",
"ATAN",
"ATANH",
"ATAN2",
"CEIL",
"COS",
"COSH",
"DEGREES",
"EXP",
"FLOOR",
"LN",
"LOG",
"LOG2",
"LOG10",
"PI",
"POW",
"RADIANS",
"RAND",
"ROUND",
"SIN",
"SINH",
"SQRT",
"TAN",
"TANH",
// legacyRegex
"REGEXP_MATCH",
"REGEXP_EXTRACT",
"REGEXP_REPLACE",
// legacyString
"CONCAT",
// expr CONTAINS 'str'
"INSTR",
"LEFT",
"LENGTH",
"LOWER",
"LPAD",
"LTRIM",
"REPLACE",
"RIGHT",
"RPAD",
"RTRIM",
"SPLIT",
"SUBSTR",
"UPPER",
// legacyTableWildcard
"TABLE_DATE_RANGE",
"TABLE_DATE_RANGE_STRICT",
"TABLE_QUERY",
// legacyUrl
"HOST",
"DOMAIN",
"TLD",
// legacyWindow
"AVG",
"COUNT",
"MAX",
"MIN",
"STDDEV",
"SUM",
"CUME_DIST",
"DENSE_RANK",
"FIRST_VALUE",
"LAG",
"LAST_VALUE",
"LEAD",
"NTH_VALUE",
"NTILE",
"PERCENT_RANK",
"PERCENTILE_CONT",
"PERCENTILE_DISC",
"RANK",
"RATIO_TO_REPORT",
"ROW_NUMBER",
// legacyMisc
"CURRENT_USER",
"EVERY",
"FROM_BASE64",
"HASH",
"FARM_FINGERPRINT",
"IF",
"POSITION",
"SHA1",
"SOME",
"TO_BASE64",
// other
"BQ.JOBS.CANCEL",
"BQ.REFRESH_MATERIALIZED_VIEW",
// ddl
"OPTIONS",
// pivot
"PIVOT",
"UNPIVOT"
], fR = [
// https://cloud.google.com/bigquery/docs/reference/standard-sql/lexical#reserved_keywords
"ALL",
"AND",
"ANY",
"AS",
"ASC",
"ASSERT_ROWS_MODIFIED",
"AT",
"BETWEEN",
"BY",
"CASE",
"CAST",
"COLLATE",
"CONTAINS",
"CREATE",
"CROSS",
"CUBE",
"CURRENT",
"DEFAULT",
"DEFINE",
"DESC",
"DISTINCT",
"ELSE",
"END",
"ENUM",
"ESCAPE",
"EXCEPT",
"EXCLUDE",
"EXISTS",
"EXTRACT",
"FALSE",
"FETCH",
"FOLLOWING",
"FOR",
"FROM",
"FULL",
"GROUP",
"GROUPING",
"GROUPS",
"HASH",
"HAVING",
"IF",
"IGNORE",
"IN",
"INNER",
"INTERSECT",
"INTO",
"IS",
"JOIN",
"LATERAL",
"LEFT",
"LIMIT",
"LOOKUP",
"MERGE",
"NATURAL",
"NEW",
"NO",
"NOT",
"NULL",
"NULLS",
"OF",
"ON",
"OR",
"ORDER",
"OUTER",
"OVER",
"PARTITION",
"PRECEDING",
"PROTO",
"RANGE",
"RECURSIVE",
"RESPECT",
"RIGHT",
"ROLLUP",
"ROWS",
"SELECT",
"SET",
"SOME",
"TABLE",
"TABLESAMPLE",
"THEN",
"TO",
"TREAT",
"TRUE",
"UNBOUNDED",
"UNION",
"UNNEST",
"USING",
"WHEN",
"WHERE",
"WINDOW",
"WITH",
"WITHIN",
// misc
"SAFE",
// https://cloud.google.com/bigquery/docs/reference/standard-sql/data-definition-language
"LIKE",
"COPY",
"CLONE",
"IN",
"OUT",
"INOUT",
"RETURNS",
"LANGUAGE",
"CASCADE",
"RESTRICT",
"DETERMINISTIC"
], BR = [
// https://cloud.google.com/bigquery/docs/reference/standard-sql/data-types
"ARRAY",
"BOOL",
"BYTES",
"DATE",
"DATETIME",
"GEOGRAPHY",
"INTERVAL",
"INT64",
"INT",
"SMALLINT",
"INTEGER",
"BIGINT",
"TINYINT",
"BYTEINT",
"NUMERIC",
"DECIMAL",
"BIGNUMERIC",
"BIGDECIMAL",
"FLOAT64",
"STRING",
"STRUCT",
"TIME",
"TIMEZONE"
], hR = o(["SELECT [ALL | DISTINCT] [AS STRUCT | AS VALUE]"]), HR = o([
// Queries: https://cloud.google.com/bigquery/docs/reference/standard-sql/query-syntax
"WITH [RECURSIVE]",
"FROM",
"WHERE",
"GROUP BY",
"HAVING",
"QUALIFY",
"WINDOW",
"PARTITION BY",
"ORDER BY",
"LIMIT",
"OFFSET",
"OMIT RECORD IF",
// Data modification: https://cloud.google.com/bigquery/docs/reference/standard-sql/dml-syntax
// - insert:
"INSERT [INTO]",
"VALUES",
// - update:
"SET",
// - merge:
"MERGE [INTO]",
"WHEN [NOT] MATCHED [BY SOURCE | BY TARGET] [THEN]",
"UPDATE SET",
"CLUSTER BY",
"FOR SYSTEM_TIME AS OF",
"WITH CONNECTION",
"WITH PARTITION COLUMNS",
"REMOTE WITH CONNECTION"
]), Be = o([
"CREATE [OR REPLACE] [TEMP|TEMPORARY|SNAPSHOT|EXTERNAL] TABLE [IF NOT EXISTS]"
]), FE = o([
// - create:
// https://cloud.google.com/bigquery/docs/reference/standard-sql/data-definition-language
"CREATE [OR REPLACE] [MATERIALIZED] VIEW [IF NOT EXISTS]",
// - update:
"UPDATE",
// - delete:
"DELETE [FROM]",
// - drop table:
"DROP [SNAPSHOT | EXTERNAL] TABLE [IF EXISTS]",
// - alter table:
"ALTER TABLE [IF EXISTS]",
"ADD COLUMN [IF NOT EXISTS]",
"DROP COLUMN [IF EXISTS]",
"RENAME TO",
"ALTER COLUMN [IF EXISTS]",
"SET DEFAULT COLLATE",
"SET OPTIONS",
"DROP NOT NULL",
"SET DATA TYPE",
// - alter schema
"ALTER SCHEMA [IF EXISTS]",
// - alter view
"ALTER [MATERIALIZED] VIEW [IF EXISTS]",
// - alter bi_capacity
"ALTER BI_CAPACITY",
// - truncate:
"TRUNCATE TABLE",
// - create schema
"CREATE SCHEMA [IF NOT EXISTS]",
"DEFAULT COLLATE",
// stored procedures
"CREATE [OR REPLACE] [TEMP|TEMPORARY|TABLE] FUNCTION [IF NOT EXISTS]",
"CREATE [OR REPLACE] PROCEDURE [IF NOT EXISTS]",
// row access policy
"CREATE [OR REPLACE] ROW ACCESS POLICY [IF NOT EXISTS]",
"GRANT TO",
"FILTER USING",
// capacity
"CREATE CAPACITY",
"AS JSON",
// reservation
"CREATE RESERVATION",
// assignment
"CREATE ASSIGNMENT",
// search index
"CREATE SEARCH INDEX [IF NOT EXISTS]",
// drop
"DROP SCHEMA [IF EXISTS]",
"DROP [MATERIALIZED] VIEW [IF EXISTS]",
"DROP [TABLE] FUNCTION [IF EXISTS]",
"DROP PROCEDURE [IF EXISTS]",
"DROP ROW ACCESS POLICY",
"DROP ALL ROW ACCESS POLICIES",
"DROP CAPACITY [IF EXISTS]",
"DROP RESERVATION [IF EXISTS]",
"DROP ASSIGNMENT [IF EXISTS]",
"DROP SEARCH INDEX [IF EXISTS]",
"DROP [IF EXISTS]",
// DCL, https://cloud.google.com/bigquery/docs/reference/standard-sql/data-control-language
"GRANT",
"REVOKE",
// Script, https://cloud.google.com/bigquery/docs/reference/standard-sql/scripting
"DECLARE",
"EXECUTE IMMEDIATE",
"LOOP",
"END LOOP",
"REPEAT",
"END REPEAT",
"WHILE",
"END WHILE",
"BREAK",
"LEAVE",
"CONTINUE",
"ITERATE",
"FOR",
"END FOR",
"BEGIN",
"BEGIN TRANSACTION",
"COMMIT TRANSACTION",
"ROLLBACK TRANSACTION",
"RAISE",
"RETURN",
"CALL",
// Debug, https://cloud.google.com/bigquery/docs/reference/standard-sql/debugging-statements
"ASSERT",
// Other, https://cloud.google.com/bigquery/docs/reference/standard-sql/other-statements
"EXPORT DATA"
]), FR = o([
"UNION {ALL | DISTINCT}",
"EXCEPT DISTINCT",
"INTERSECT DISTINCT"
]), YR = o([
"JOIN",
"{LEFT | RIGHT | FULL} [OUTER] JOIN",
"{INNER | CROSS} JOIN"
]), VR = o([
// https://cloud.google.com/bigquery/docs/reference/standard-sql/query-syntax#tablesample_operator
"TABLESAMPLE SYSTEM",
// From DDL: https://cloud.google.com/bigquery/docs/reference/standard-sql/data-definition-language
"ANY TYPE",
"ALL COLUMNS",
"NOT DETERMINISTIC",
// inside window definitions
"{ROWS | RANGE} BETWEEN",
// comparison operator
"IS [NOT] DISTINCT FROM"
]), bR = o([]), gR = {
name: "bigquery",
tokenizerOptions: {
reservedSelect: hR,
reservedClauses: [...HR, ...FE, ...Be],
reservedSetOperations: FR,
reservedJoins: YR,
reservedKeywordPhrases: VR,
reservedDataTypePhrases: bR,
reservedKeywords: fR,
reservedDataTypes: BR,
reservedFunctionNames: pR,
extraParens: ["[]"],
stringTypes: [
// The triple-quoted strings are listed first, so they get matched first.
// Otherwise the first two quotes of """ will get matched as an empty "" string.
{ quote: '""".."""', prefixes: ["R", "B", "RB", "BR"] },
{ quote: "'''..'''", prefixes: ["R", "B", "RB", "BR"] },
'""-bs',
"''-bs",
{ quote: '""-raw', prefixes: ["R", "B", "RB", "BR"], requirePrefix: !0 },
{ quote: "''-raw", prefixes: ["R", "B", "RB", "BR"], requirePrefix: !0 }
],
identTypes: ["``"],
identChars: { dashes: !0 },
paramTypes: { positional: !0, named: ["@"], quoted: ["@"] },
variableTypes: [{ regex: String.raw`@@\w+` }],
lineCommentTypes: ["--", "#"],
operators: ["&", "|", "^", "~", ">>", "<<", "||", "=>"],
postProcess: WR
},
formatOptions: {
onelineClauses: [...Be, ...FE],
tabularOnelineClauses: FE
}
};
function WR(T) {
return yR(XR(T));
}
function yR(T) {
let E = TE;
return T.map((e) => e.text === "OFFSET" && E.text === "[" ? (E = e, Object.assign(Object.assign({}, e), { type: l.RESERVED_FUNCTION_NAME })) : (E = e, e));
}
function XR(T) {
var E;
const e = [];
for (let R = 0; R < T.length; R++) {
const A = T[R];
if ((j.ARRAY(A) || j.STRUCT(A)) && ((E = T[R + 1]) === null || E === void 0 ? void 0 : E.text) === "<") {
const t = $R(T, R + 1), s = T.slice(R, t + 1);
e.push({
type: l.IDENTIFIER,
raw: s.map(he("raw")).join(""),
text: s.map(he("text")).join(""),
start: A.start
}), R = t;
} else
e.push(A);
}
return e;
}
const he = (T) => (E) => E.type === l.IDENTIFIER || E.type === l.COMMA ? E[T] + " " : E[T];
function $R(T, E) {
let e = 0;
for (let R = E; R < T.length; R++) {
const A = T[R];
if (A.text === "<" ? e++ : A.text === ">" ? e-- : A.text === ">>" && (e -= 2), e === 0)
return R;
}
return T.length - 1;
}
const KR = [
// https://www.ibm.com/docs/en/db2/11.5?topic=bif-aggregate-functions
"ARRAY_AGG",
"AVG",
"CORRELATION",
"COUNT",
"COUNT_BIG",
"COVARIANCE",
"COVARIANCE_SAMP",
"CUME_DIST",
"GROUPING",
"LISTAGG",
"MAX",
"MEDIAN",
"MIN",
"PERCENTILE_CONT",
"PERCENTILE_DISC",
"PERCENT_RANK",
"REGR_AVGX",
"REGR_AVGY",
"REGR_COUNT",
"REGR_INTERCEPT",
"REGR_ICPT",
"REGR_R2",
"REGR_SLOPE",
"REGR_SXX",
"REGR_SXY",
"REGR_SYY",
"STDDEV",
"STDDEV_SAMP",
"SUM",
"VARIANCE",
"VARIANCE_SAMP",
"XMLAGG",
"XMLGROUP",
// https://www.ibm.com/docs/en/db2/11.5?topic=bif-scalar-functions
"ABS",
"ABSVAL",
"ACOS",
"ADD_DAYS",
"ADD_HOURS",
"ADD_MINUTES",
"ADD_MONTHS",
"ADD_SECONDS",
"ADD_YEARS",
"AGE",
"ARRAY_DELETE",
"ARRAY_FIRST",
"ARRAY_LAST",
"ARRAY_NEXT",
"ARRAY_PRIOR",
"ASCII",
"ASCII_STR",
"ASIN",
"ATAN",
"ATAN2",
"ATANH",
"BITAND",
"BITANDNOT",
"BITOR",
"BITXOR",
"BITNOT",
"BPCHAR",
"BSON_TO_JSON",
"BTRIM",
"CARDINALITY",
"CEILING",
"CEIL",
"CHARACTER_LENGTH",
"CHR",
"COALESCE",
"COLLATION_KEY",
"COLLATION_KEY_BIT",
"COMPARE_DECFLOAT",
"CONCAT",
"COS",
"COSH",
"COT",
"CURSOR_ROWCOUNT",
"DATAPARTITIONNUM",
"DATE_PART",
"DATE_TRUNC",
"DAY",
"DAYNAME",
"DAYOFMONTH",
"DAYOFWEEK",
"DAYOFWEEK_ISO",
"DAYOFYEAR",
"DAYS",
"DAYS_BETWEEN",
"DAYS_TO_END_OF_MONTH",
"DBPARTITIONNUM",
"DECFLOAT",
"DECFLOAT_FORMAT",
"DECODE",
"DECRYPT_BIN",
"DECRYPT_CHAR",
"DEGREES",
"DEREF",
"DIFFERENCE",
"DIGITS",
"DOUBLE_PRECISION",
"EMPTY_BLOB",
"EMPTY_CLOB",
"EMPTY_DBCLOB",
"EMPTY_NCLOB",
"ENCRYPT",
"EVENT_MON_STATE",
"EXP",
"EXTRACT",
"FIRST_DAY",
"FLOOR",
"FROM_UTC_TIMESTAMP",
"GENERATE_UNIQUE",
"GETHINT",
"GREATEST",
"HASH",
"HASH4",
"HASH8",
"HASHEDVALUE",
"HEX",
"HEXTORAW",
"HOUR",
"HOURS_BETWEEN",
"IDENTITY_VAL_LOCAL",
"IFNULL",
"INITCAP",
"INSERT",
"INSTR",
"INSTR2",
"INSTR4",
"INSTRB",
"INTNAND",
"INTNOR",
"INTNXOR",
"INTNNOT",
"ISNULL",
"JSON_ARRAY",
"JSON_OBJECT",
"JSON_QUERY",
"JSON_TO_BSON",
"JSON_VALUE",
"JULIAN_DAY",
"LAST_DAY",
"LCASE",
"LEAST",
"LEFT",
"LENGTH",
"LENGTH2",
"LENGTH4",
"LENGTHB",
"LN",
"LOCATE",
"LOCATE_IN_STRING",
"LOG10",
"LONG_VARCHAR",
"LONG_VARGRAPHIC",
"LOWER",
"LPAD",
"LTRIM",
"MAX",
"MAX_CARDINALITY",
"MICROSECOND",
"MIDNIGHT_SECONDS",
"MIN",
"MINUTE",
"MINUTES_BETWEEN",
"MOD",
"MONTH",
"MONTHNAME",
"MONTHS_BETWEEN",
"MULTIPLY_ALT",
"NEXT_DAY",
"NEXT_MONTH",
"NEXT_QUARTER",
"NEXT_WEEK",
"NEXT_YEAR",
"NORMALIZE_DECFLOAT",
"NOW",
"NULLIF",
"NVL",
"NVL2",
"OCTET_LENGTH",
"OVERLAY",
"PARAMETER",
"POSITION",
"POSSTR",
"POW",
"POWER",
"QUANTIZE",
"QUARTER",
"QUOTE_IDENT",
"QUOTE_LITERAL",
"RADIANS",
"RAISE_ERROR",
"RAND",
"RANDOM",
"RAWTOHEX",
"REC2XML",
"REGEXP_COUNT",
"REGEXP_EXTRACT",
"REGEXP_INSTR",
"REGEXP_LIKE",
"REGEXP_MATCH_COUNT",
"REGEXP_REPLACE",
"REGEXP_SUBSTR",
"REPEAT",
"REPLACE",
"RID",
"RID_BIT",
"RIGHT",
"ROUND",
"ROUND_TIMESTAMP",
"RPAD",
"RTRIM",
"SECLABEL",
"SECLABEL_BY_NAME",
"SECLABEL_TO_CHAR",
"SECOND",
"SECONDS_BETWEEN",
"SIGN",
"SIN",
"SINH",
"SOUNDEX",
"SPACE",
"SQRT",
"STRIP",
"STRLEFT",
"STRPOS",
"STRRIGHT",
"SUBSTR",
"SUBSTR2",
"SUBSTR4",
"SUBSTRB",
"SUBSTRING",
"TABLE_NAME",
"TABLE_SCHEMA",
"TAN",
"TANH",
"THIS_MONTH",
"THIS_QUARTER",
"THIS_WEEK",
"THIS_YEAR",
"TIMESTAMP_FORMAT",
"TIMESTAMP_ISO",
"TIMESTAMPDIFF",
"TIMEZONE",
"TO_CHAR",
"TO_CLOB",
"TO_DATE",
"TO_HEX",
"TO_MULTI_BYTE",
"TO_NCHAR",
"TO_NCLOB",
"TO_NUMBER",
"TO_SINGLE_BYTE",
"TO_TIMESTAMP",
"TO_UTC_TIMESTAMP",
"TOTALORDER",
"TRANSLATE",
"TRIM",
"TRIM_ARRAY",
"TRUNC_TIMESTAMP",
"TRUNCATE",
"TRUNC",
"TYPE_ID",
"TYPE_NAME",
"TYPE_SCHEMA",
"UCASE",
"UNICODE_STR",
"UPPER",
"VALUE",
"VARCHAR_BIT_FORMAT",
"VARCHAR_FORMAT",
"VARCHAR_FORMAT_BIT",
"VERIFY_GROUP_FOR_USER",
"VERIFY_ROLE_FOR_USER",
"VERIFY_TRUSTED_CONTEXT_ROLE_FOR_USER",
"WEEK",
"WEEK_ISO",
"WEEKS_BETWEEN",
"WIDTH_BUCKET",
"XMLATTRIBUTES",
"XMLCOMMENT",
"XMLCONCAT",
"XMLDOCUMENT",
"XMLELEMENT",
"XMLFOREST",
"XMLNAMESPACES",
"XMLPARSE",
"XMLPI",
"XMLQUERY",
"XMLROW",
"XMLSERIALIZE",
"XMLTEXT",
"XMLVALIDATE",
"XMLXSROBJECTID",
"XSLTRANSFORM",
"YEAR",
"YEARS_BETWEEN",
"YMD_BETWEEN",
// https://www.ibm.com/docs/en/db2/11.5?topic=bif-table-functions
"BASE_TABLE",
"JSON_TABLE",
"UNNEST",
"XMLTABLE",
// https://www.ibm.com/docs/en/db2/11.5?topic=expressions-olap-specification
// Additional function names not already present in the aggregate functions list
"RANK",
"DENSE_RANK",
"NTILE",
"LAG",
"LEAD",
"ROW_NUMBER",
"FIRST_VALUE",
"LAST_VALUE",
"NTH_VALUE",
"RATIO_TO_REPORT",
// Type casting
"CAST"
], wR = [
// https://www.ibm.com/docs/en/db2/11.5?topic=sql-reserved-schema-names-reserved-words
"ACTIVATE",
"ADD",
"AFTER",
"ALIAS",
"ALL",
"ALLOCATE",
"ALLOW",
"ALTER",
"AND",
"ANY",
"AS",
"ASENSITIVE",
"ASSOCIATE",
"ASUTIME",
"AT",
"ATTRIBUTES",
"AUDIT",
"AUTHORIZATION",
"AUX",
"AUXILIARY",
"BEFORE",
"BEGIN",
"BETWEEN",
"BINARY",
"BUFFERPOOL",
"BY",
"CACHE",
"CALL",
"CALLED",
"CAPTURE",
"CARDINALITY",
"CASCADED",
"CASE",
"CAST",
"CHECK",
"CLONE",
"CLOSE",
"CLUSTER",
"COLLECTION",
"COLLID",
"COLUMN",
"COMMENT",
"COMMIT",
"CONCAT",
"CONDITION",
"CONNECT",
"CONNECTION",
"CONSTRAINT",
"CONTAINS",
"CONTINUE",
"COUNT",
"COUNT_BIG",
"CREATE",
"CROSS",
"CURRENT",
"CURRENT_DATE",
"CURRENT_LC_CTYPE",
"CURRENT_PATH",
"CURRENT_SCHEMA",
"CURRENT_SERVER",
"CURRENT_TIME",
"CURRENT_TIMESTAMP",
"CURRENT_TIMEZONE",
"CURRENT_USER",
"CURSOR",
"CYCLE",
"DATA",
"DATABASE",
"DATAPARTITIONNAME",
"DATAPARTITIONNUM",
"DAY",
"DAYS",
"DB2GENERAL",
"DB2GENRL",
"DB2SQL",
"DBINFO",
"DBPARTITIONNAME",
"DBPARTITIONNUM",
"DEALLOCATE",
"DECLARE",
"DEFAULT",
"DEFAULTS",
"DEFINITION",
"DELETE",
"DENSERANK",
"DENSE_RANK",
"DESCRIBE",
"DESCRIPTOR",
"DETERMINISTIC",
"DIAGNOSTICS",
"DISABLE",
"DISALLOW",
"DISCONNECT",
"DISTINCT",
"DO",
"DOCUMENT",
"DROP",
"DSSIZE",
"DYNAMIC",
"EACH",
"EDITPROC",
"ELSE",
"ELSEIF",
"ENABLE",
"ENCODING",
"ENCRYPTION",
"END",
"END-EXEC",
"ENDING",
"ERASE",
"ESCAPE",
"EVERY",
"EXCEPT",
"EXCEPTION",
"EXCLUDING",
"EXCLUSIVE",
"EXECUTE",
"EXISTS",
"EXIT",
"EXPLAIN",
"EXTENDED",
"EXTERNAL",
"EXTRACT",
"FENCED",
"FETCH",
"FIELDPROC",
"FILE",
"FINAL",
"FIRST1",
"FOR",
"FOREIGN",
"FREE",
"FROM",
"FULL",
"FUNCTION",
"GENERAL",
"GENERATED",
"GET",
"GLOBAL",
"GO",
"GOTO",
"GRANT",
"GRAPHIC",
"GROUP",
"HANDLER",
"HASH",
"HASHED_VALUE",
"HAVING",
"HINT",
"HOLD",
"HOUR",
"HOURS",
"IDENTITY",
"IF",
"IMMEDIATE",
"IMPORT",
"IN",
"INCLUDING",
"INCLUSIVE",
"INCREMENT",
"INDEX",
"INDICATOR",
"INDICATORS",
"INF",
"INFINITY",
"INHERIT",
"INNER",
"INOUT",
"INSENSITIVE",
"INSERT",
"INTEGRITY",
"INTERSECT",
"INTO",
"IS",
"ISNULL",
"ISOBID",
"ISOLATION",
"ITERATE",
"JAR",
"JAVA",
"JOIN",
"KEEP",
"KEY",
"LABEL",
"LANGUAGE",
"LAST3",
"LATERAL",
"LC_CTYPE",
"LEAVE",
"LEFT",
"LIKE",
"LIMIT",
"LINKTYPE",
"LOCAL",
"LOCALDATE",
"LOCALE",
"LOCALTIME",
"LOCALTIMESTAMP",
"LOCATOR",
"LOCATORS",
"LOCK",
"LOCKMAX",
"LOCKSIZE",
"LOOP",
"MAINTAINED",
"MATERIALIZED",
"MAXVALUE",
"MICROSECOND",
"MICROSECONDS",
"MINUTE",
"MINUTES",
"MINVALUE",
"MODE",
"MODIFIES",
"MONTH",
"MONTHS",
"NAN",
"NEW",
"NEW_TABLE",
"NEXTVAL",
"NO",
"NOCACHE",
"NOCYCLE",
"NODENAME",
"NODENUMBER",
"NOMAXVALUE",
"NOMINVALUE",
"NONE",
"NOORDER",
"NORMALIZED",
"NOT2",
"NOTNULL",
"NULL",
"NULLS",
"NUMPARTS",
"OBID",
"OF",
"OFF",
"OFFSET",
"OLD",
"OLD_TABLE",
"ON",
"OPEN",
"OPTIMIZATION",
"OPTIMIZE",
"OPTION",
"OR",
"ORDER",
"OUT",
"OUTER",
"OVER",
"OVERRIDING",
"PACKAGE",
"PADDED",
"PAGESIZE",
"PARAMETER",
"PART",
"PARTITION",
"PARTITIONED",
"PARTITIONING",
"PARTITIONS",
"PASSWORD",
"PATH",
"PERCENT",
"PIECESIZE",
"PLAN",
"POSITION",
"PRECISION",
"PREPARE",
"PREVVAL",
"PRIMARY",
"PRIQTY",
"PRIVILEGES",
"PROCEDURE",
"PROGRAM",
"PSID",
"PUBLIC",
"QUERY",
"QUERYNO",
"RANGE",
"RANK",
"READ",
"READS",
"RECOVERY",
"REFERENCES",
"REFERENCING",
"REFRESH",
"RELEASE",
"RENAME",
"REPEAT",
"RESET",
"RESIGNAL",
"RESTART",
"RESTRICT",
"RESULT",
"RESULT_SET_LOCATOR",
"RETURN",
"RETURNS",
"REVOKE",
"RIGHT",
"ROLE",
"ROLLBACK",
"ROUND_CEILING",
"ROUND_DOWN",
"ROUND_FLOOR",
"ROUND_HALF_DOWN",
"ROUND_HALF_EVEN",
"ROUND_HALF_UP",
"ROUND_UP",
"ROUTINE",
"ROW",
"ROWNUMBER",
"ROWS",
"ROWSET",
"ROW_NUMBER",
"RRN",
"RUN",
"SAVEPOINT",
"SCHEMA",
"SCRATCHPAD",
"SCROLL",
"SEARCH",
"SECOND",
"SECONDS",
"SECQTY",
"SECURITY",
"SELECT",
"SENSITIVE",
"SEQUENCE",
"SESSION",
"SESSION_USER",
"SET",
"SIGNAL",
"SIMPLE",
"SNAN",
"SOME",
"SOURCE",
"SPECIFIC",
"SQL",
"SQLID",
"STACKED",
"STANDARD",
"START",
"STARTING",
"STATEMENT",
"STATIC",
"STATMENT",
"STAY",
"STOGROUP",
"STORES",
"STYLE",
"SUBSTRING",
"SUMMARY",
"SYNONYM",
"SYSFUN",
"SYSIBM",
"SYSPROC",
"SYSTEM",
"SYSTEM_USER",
"TABLE",
"TABLESPACE",
"THEN",
"TO",
"TRANSACTION",
"TRIGGER",
"TRIM",
"TRUNCATE",
"TYPE",
"UNDO",
"UNION",
"UNIQUE",
"UNTIL",
"UPDATE",
"USAGE",
"USER",
"USING",
"VALIDPROC",
"VALUE",
"VALUES",
"VARIABLE",
"VARIANT",
"VCAT",
"VERSION",
"VIEW",
"VOLATILE",
"VOLUMES",
"WHEN",
"WHENEVER",
"WHERE",
"WHILE",
"WITH",
"WITHOUT",
"WLM",
"WRITE",
"XMLELEMENT",
"XMLEXISTS",
"XMLNAMESPACES",
"YEAR",
"YEARS"
], JR = [
// https://www.ibm.com/docs/en/db2-for-zos/12?topic=columns-data-types
"ARRAY",
"BIGINT",
"BINARY",
"BLOB",
"BOOLEAN",
"CCSID",
"CHAR",
"CHARACTER",
"CLOB",
"DATE",
"DATETIME",
"DBCLOB",
"DEC",
"DECIMAL",
"DOUBLE",
"DOUBLE PRECISION",
"FLOAT",
"FLOAT4",
"FLOAT8",
"GRAPHIC",
"INT",
"INT2",
"INT4",
"INT8",
"INTEGER",
"INTERVAL",
"LONG VARCHAR",
"LONG VARGRAPHIC",
"NCHAR",
"NCHR",
"NCLOB",
"NVARCHAR",
"NUMERIC",
"SMALLINT",
"REAL",
"TIME",
"TIMESTAMP",
"VARBINARY",
"VARCHAR",
"VARGRAPHIC"
], vR = o(["SELECT [ALL | DISTINCT]"]), xR = o([
// queries
"WITH",
"FROM",
"WHERE",
"GROUP BY",
"HAVING",
"PARTITION BY",
"ORDER BY [INPUT SEQUENCE]",
"LIMIT",
"OFFSET",
"FETCH NEXT",
"FOR UPDATE [OF]",
"FOR {READ | FETCH} ONLY",
"FOR {RR | CS | UR | RS} [USE AND KEEP {SHARE | UPDATE | EXCLUSIVE} LOCKS]",
"WAIT FOR OUTCOME",
"SKIP LOCKED DATA",
"INTO",
// Data modification
// - insert:
"INSERT INTO",
"VALUES",
// - update:
"SET",
// - merge:
"MERGE INTO",
"WHEN [NOT] MATCHED [THEN]",
"UPDATE SET",
"INSERT"
]), He = o([
"CREATE [GLOBAL TEMPORARY | EXTERNAL] TABLE [IF NOT EXISTS]"
]), YE = o([
// - create:
"CREATE [OR REPLACE] VIEW",
// - update:
"UPDATE",
"WHERE CURRENT OF",
"WITH {RR | RS | CS | UR}",
// - delete:
"DELETE FROM",
// - drop table:
"DROP TABLE [IF EXISTS]",
// alter table:
"ALTER TABLE",
"ADD [COLUMN]",
"DROP [COLUMN]",
"RENAME COLUMN",
"ALTER [COLUMN]",
"SET DATA TYPE",
"SET NOT NULL",
"DROP {DEFAULT | GENERATED | NOT NULL}",
// - truncate:
"TRUNCATE [TABLE]",
// https://www.ibm.com/docs/en/db2/11.5?topic=s-statements
"ALLOCATE",
"ALTER AUDIT POLICY",
"ALTER BUFFERPOOL",
"ALTER DATABASE PARTITION GROUP",
"ALTER DATABASE",
"ALTER EVENT MONITOR",
"ALTER FUNCTION",
"ALTER HISTOGRAM TEMPLATE",
"ALTER INDEX",
"ALTER MASK",
"ALTER METHOD",
"ALTER MODULE",
"ALTER NICKNAME",
"ALTER PACKAGE",
"ALTER PERMISSION",
"ALTER PROCEDURE",
"ALTER SCHEMA",
"ALTER SECURITY LABEL COMPONENT",
"ALTER SECURITY POLICY",
"ALTER SEQUENCE",
"ALTER SERVER",
"ALTER SERVICE CLASS",
"ALTER STOGROUP",
"ALTER TABLESPACE",
"ALTER THRESHOLD",
"ALTER TRIGGER",
"ALTER TRUSTED CONTEXT",
"ALTER TYPE",
"ALTER USAGE LIST",
"ALTER USER MAPPING",
"ALTER VIEW",
"ALTER WORK ACTION SET",
"ALTER WORK CLASS SET",
"ALTER WORKLOAD",
"ALTER WRAPPER",
"ALTER XSROBJECT",
"ALTER STOGROUP",
"ALTER TABLESPACE",
"ALTER TRIGGER",
"ALTER TRUSTED CONTEXT",
"ALTER VIEW",
"ASSOCIATE [RESULT SET] {LOCATOR | LOCATORS}",
"AUDIT",
"BEGIN DECLARE SECTION",
"CALL",
"CLOSE",
"COMMENT ON",
"COMMIT [WORK]",
"CONNECT",
"CREATE [OR REPLACE] [PUBLIC] ALIAS",
"CREATE AUDIT POLICY",
"CREATE BUFFERPOOL",
"CREATE DATABASE PARTITION GROUP",
"CREATE EVENT MONITOR",
"CREATE [OR REPLACE] FUNCTION",
"CREATE FUNCTION MAPPING",
"CREATE HISTOGRAM TEMPLATE",
"CREATE [UNIQUE] INDEX",
"CREATE INDEX EXTENSION",
"CREATE [OR REPLACE] MASK",
"CREATE [SPECIFIC] METHOD",
"CREATE [OR REPLACE] MODULE",
"CREATE [OR REPLACE] NICKNAME",
"CREATE [OR REPLACE] PERMISSION",
"CREATE [OR REPLACE] PROCEDURE",
"CREATE ROLE",
"CREATE SCHEMA",
"CREATE SECURITY LABEL [COMPONENT]",
"CREATE SECURITY POLICY",
"CREATE [OR REPLACE] SEQUENCE",
"CREATE SERVICE CLASS",
"CREATE SERVER",
"CREATE STOGROUP",
"CREATE SYNONYM",
"CREATE [LARGE | REGULAR | {SYSTEM | USER} TEMPORARY] TABLESPACE",
"CREATE THRESHOLD",
"CREATE {TRANSFORM | TRANSFORMS} FOR",
"CREATE [OR REPLACE] TRIGGER",
"CREATE TRUSTED CONTEXT",
"CREATE [OR REPLACE] TYPE",
"CREATE TYPE MAPPING",
"CREATE USAGE LIST",
"CREATE USER MAPPING FOR",
"CREATE [OR REPLACE] VARIABLE",
"CREATE WORK ACTION SET",
"CREATE WORK CLASS SET",
"CREATE WORKLOAD",
"CREATE WRAPPER",
"DECLARE",
"DECLARE GLOBAL TEMPORARY TABLE",
"DESCRIBE [INPUT | OUTPUT]",
"DISCONNECT",
"DROP [PUBLIC] ALIAS",
"DROP AUDIT POLICY",
"DROP BUFFERPOOL",
"DROP DATABASE PARTITION GROUP",
"DROP EVENT MONITOR",
"DROP [SPECIFIC] FUNCTION",
"DROP FUNCTION MAPPING",
"DROP HISTOGRAM TEMPLATE",
"DROP INDEX [EXTENSION]",
"DROP MASK",
"DROP [SPECIFIC] METHOD",
"DROP MODULE",
"DROP NICKNAME",
"DROP PACKAGE",
"DROP PERMISSION",
"DROP [SPECIFIC] PROCEDURE",
"DROP ROLE",
"DROP SCHEMA",
"DROP SECURITY LABEL [COMPONENT]",
"DROP SECURITY POLICY",
"DROP SEQUENCE",
"DROP SERVER",
"DROP SERVICE CLASS",
"DROP STOGROUP",
"DROP TABLE HIERARCHY",
"DROP {TABLESPACE | TABLESPACES}",
"DROP {TRANSFORM | TRANSFORMS}",
"DROP THRESHOLD",
"DROP TRIGGER",
"DROP TRUSTED CONTEXT",
"DROP TYPE [MAPPING]",
"DROP USAGE LIST",
"DROP USER MAPPING FOR",
"DROP VARIABLE",
"DROP VIEW [HIERARCHY]",
"DROP WORK {ACTION | CLASS} SET",
"DROP WORKLOAD",
"DROP WRAPPER",
"DROP XSROBJECT",
"END DECLARE SECTION",
"EXECUTE [IMMEDIATE]",
"EXPLAIN {PLAN [SECTION] | ALL}",
"FETCH [FROM]",
"FLUSH {BUFFERPOOL | BUFFERPOOLS} ALL",
"FLUSH EVENT MONITOR",
"FLUSH FEDERATED CACHE",
"FLUSH OPTIMIZATION PROFILE CACHE",
"FLUSH PACKAGE CACHE [DYNAMIC]",
"FLUSH AUTHENTICATION CACHE [FOR ALL]",
"FREE LOCATOR",
"GET DIAGNOSTICS",
"GOTO",
"GRANT",
"INCLUDE",
"ITERATE",
"LEAVE",
"LOCK TABLE",
"LOOP",
"OPEN",
"PIPE",
"PREPARE",
"REFRESH TABLE",
"RELEASE",
"RELEASE [TO] SAVEPOINT",
"RENAME [TABLE | INDEX | STOGROUP | TABLESPACE]",
"REPEAT",
"RESIGNAL",
"RETURN",
"REVOKE",
"ROLLBACK [WORK] [TO SAVEPOINT]",
"SAVEPOINT",
"SET COMPILATION ENVIRONMENT",
"SET CONNECTION",
"SET CURRENT",
"SET ENCRYPTION PASSWORD",
"SET EVENT MONITOR STATE",
"SET INTEGRITY",
"SET PASSTHRU",
"SET PATH",
"SET ROLE",
"SET SCHEMA",
"SET SERVER OPTION",
"SET {SESSION AUTHORIZATION | SESSION_USER}",
"SET USAGE LIST",
"SIGNAL",
"TRANSFER OWNERSHIP OF",
"WHENEVER {NOT FOUND | SQLERROR | SQLWARNING}",
"WHILE"
]), QR = o(["UNION [ALL]", "EXCEPT [ALL]", "INTERSECT [ALL]"]), ZR = o([
"JOIN",
"{LEFT | RIGHT | FULL} [OUTER] JOIN",
"{INNER | CROSS} JOIN"
]), jR = o([
"ON DELETE",
"ON UPDATE",
"SET NULL",
"{ROWS | RANGE} BETWEEN"
]), qR = o([]), kR = {
name: "db2",
tokenizerOptions: {
reservedSelect: vR,
reservedClauses: [...xR, ...He, ...YE],
reservedSetOperations: QR,
reservedJoins: ZR,
reservedKeywordPhrases: jR,
reservedDataTypePhrases: qR,
reservedKeywords: wR,
reservedDataTypes: JR,
reservedFunctionNames: KR,
extraParens: ["[]"],
stringTypes: [
{ quote: "''-qq", prefixes: ["G", "N", "U&"] },
{ quote: "''-raw", prefixes: ["X", "BX", "GX", "UX"], requirePrefix: !0 }
],
identTypes: ['""-qq'],
identChars: { first: "@#$", rest: "@#$" },
paramTypes: { positional: !0, named: [":"] },
paramChars: { first: "@#$", rest: "@#$" },
operators: [
"**",
"%",
"|",
"&",
"^",
"~",
"¬=",
"¬>",
"¬<",
"!>",
"!<",
"^=",
"^>",
"^<",
"||",
"->",
"=>"
]
},
formatOptions: {
onelineClauses: [...He, ...YE],
tabularOnelineClauses: YE
}
}, zR = [
// https://www.ibm.com/docs/en/i/7.5?topic=functions-aggregate
// TODO: 'ANY', - conflicts with test for ANY predicate in 'operators.ys'!!
"ARRAY_AGG",
"AVG",
"CORR",
"CORRELATION",
"COUNT",
"COUNT_BIG",
"COVAR_POP",
"COVARIANCE",
"COVAR",
"COVAR_SAMP",
"COVARIANCE_SAMP",
"EVERY",
"GROUPING",
"JSON_ARRAYAGG",
"JSON_OBJECTAGG",
"LISTAGG",
"MAX",
"MEDIAN",
"MIN",
"PERCENTILE_CONT",
"PERCENTILE_DISC",
// https://www.ibm.com/docs/en/i/7.5?topic=functions-regression'
"REGR_AVGX",
"REGR_AVGY",
"REGR_COUNT",
"REGR_INTERCEPT",
"REGR_R2",
"REGR_SLOPE",
"REGR_SXX",
"REGR_SXY",
"REGR_SYY",
"SOME",
"STDDEV_POP",
"STDDEV",
"STDDEV_SAMP",
"SUM",
"VAR_POP",
"VARIANCE",
"VAR",
"VAR_SAMP",
"VARIANCE_SAMP",
"XMLAGG",
"XMLGROUP",
// https://www.ibm.com/docs/en/i/7.5?topic=functions-scalar
"ABS",
"ABSVAL",
"ACOS",
"ADD_DAYS",
"ADD_HOURS",
"ADD_MINUTES",
"ADD_MONTHS",
"ADD_SECONDS",
"ADD_YEARS",
"ANTILOG",
"ARRAY_MAX_CARDINALITY",
"ARRAY_TRIM",
"ASCII",
"ASIN",
"ATAN",
"ATAN2",
"ATANH",
"BASE64_DECODE",
"BASE64_ENCODE",
"BIT_LENGTH",
"BITAND",
"BITANDNOT",
"BITNOT",
"BITOR",
"BITXOR",
"BSON_TO_JSON",
"CARDINALITY",
"CEIL",
"CEILING",
"CHAR_LENGTH",
"CHARACTER_LENGTH",
"CHR",
"COALESCE",
"COMPARE_DECFLOAT",
"CONCAT",
"CONTAINS",
"COS",
"COSH",
"COT",
"CURDATE",
"CURTIME",
"DATABASE",
"DATAPARTITIONNAME",
"DATAPARTITIONNUM",
"DAY",
"DAYNAME",
"DAYOFMONTH",
"DAYOFWEEK_ISO",
"DAYOFWEEK",
"DAYOFYEAR",
"DAYS",
"DBPARTITIONNAME",
"DBPARTITIONNUM",
"DECFLOAT_FORMAT",
"DECFLOAT_SORTKEY",
"DECRYPT_BINARY",
"DECRYPT_BIT",
"DECRYPT_CHAR",
"DECRYPT_DB",
"DEGREES",
"DIFFERENCE",
"DIGITS",
"DLCOMMENT",
"DLLINKTYPE",
"DLURLCOMPLETE",
"DLURLPATH",
"DLURLPATHONLY",
"DLURLSCHEME",
"DLURLSERVER",
"DLVALUE",
"DOUBLE_PRECISION",
"DOUBLE",
"ENCRPYT",
"ENCRYPT_AES",
"ENCRYPT_AES256",
"ENCRYPT_RC2",
"ENCRYPT_TDES",
"EXP",
"EXTRACT",
"FIRST_DAY",
"FLOOR",
"GENERATE_UNIQUE",
"GET_BLOB_FROM_FILE",
"GET_CLOB_FROM_FILE",
"GET_DBCLOB_FROM_FILE",
"GET_XML_FILE",
"GETHINT",
"GREATEST",
"HASH_MD5",
"HASH_ROW",
"HASH_SHA1",
"HASH_SHA256",
"HASH_SHA512",
"HASH_VALUES",
"HASHED_VALUE",
"HEX",
"HEXTORAW",
"HOUR",
"HTML_ENTITY_DECODE",
"HTML_ENTITY_ENCODE",
"HTTP_DELETE_BLOB",
"HTTP_DELETE",
"HTTP_GET_BLOB",
"HTTP_GET",
"HTTP_PATCH_BLOB",
"HTTP_PATCH",
"HTTP_POST_BLOB",
"HTTP_POST",
"HTTP_PUT_BLOB",
"HTTP_PUT",
"IDENTITY_VAL_LOCAL",
"IFNULL",
"INSERT",
"INSTR",
"INTERPRET",
"ISFALSE",
"ISNOTFALSE",
"ISNOTTRUE",
"ISTRUE",
"JSON_ARRAY",
"JSON_OBJECT",
"JSON_QUERY",
"JSON_TO_BSON",
"JSON_UPDATE",
"JSON_VALUE",
"JULIAN_DAY",
"LAND",
"LAST_DAY",
"LCASE",
"LEAST",
"LEFT",
"LENGTH",
"LN",
"LNOT",
"LOCATE_IN_STRING",
"LOCATE",
"LOG10",
"LOR",
"LOWER",
"LPAD",
"LTRIM",
"MAX_CARDINALITY",
"MAX",
"MICROSECOND",
"MIDNIGHT_SECONDS",
"MIN",
"MINUTE",
"MOD",
"MONTH",
"MONTHNAME",
"MONTHS_BETWEEN",
"MQREAD",
"MQREADCLOB",
"MQRECEIVE",
"MQRECEIVECLOB",
"MQSEND",
"MULTIPLY_ALT",
"NEXT_DAY",
"NORMALIZE_DECFLOAT",
"NOW",
"NULLIF",
"NVL",
"OCTET_LENGTH",
"OVERLAY",
"PI",
"POSITION",
"POSSTR",
"POW",
"POWER",
"QUANTIZE",
"QUARTER",
"RADIANS",
"RAISE_ERROR",
"RANDOM",
"RAND",
"REGEXP_COUNT",
"REGEXP_INSTR",
"REGEXP_REPLACE",
"REGEXP_SUBSTR",
"REPEAT",
"REPLACE",
"RID",
"RIGHT",
"ROUND_TIMESTAMP",
"ROUND",
"RPAD",
"RRN",
"RTRIM",
"SCORE",
"SECOND",
"SIGN",
"SIN",
"SINH",
"SOUNDEX",
"SPACE",
"SQRT",
"STRIP",
"STRLEFT",
"STRPOS",
"STRRIGHT",
"SUBSTR",
"SUBSTRING",
"TABLE_NAME",
"TABLE_SCHEMA",
"TAN",
"TANH",
"TIMESTAMP_FORMAT",
"TIMESTAMP_ISO",
"TIMESTAMPDIFF_BIG",
"TIMESTAMPDIFF",
"TO_CHAR",
"TO_CLOB",
"TO_DATE",
"TO_NUMBER",
"TO_TIMESTAMP",
"TOTALORDER",
"TRANSLATE",
"TRIM_ARRAY",
"TRIM",
"TRUNC_TIMESTAMP",
"TRUNC",
"TRUNCATE",
"UCASE",
"UPPER",
"URL_DECODE",
"URL_ENCODE",
"VALUE",
"VARBINARY_FORMAT",
"VARCHAR_BIT_FORMAT",
"VARCHAR_FORMAT_BINARY",
"VARCHAR_FORMAT",
"VERIFY_GROUP_FOR_USER",
"WEEK_ISO",
"WEEK",
"WRAP",
"XMLATTRIBUTES",
"XMLCOMMENT",
"XMLCONCAT",
"XMLDOCUMENT",
"XMLELEMENT",
"XMLFOREST",
"XMLNAMESPACES",
"XMLPARSE",
"XMLPI",
"XMLROW",
"XMLSERIALIZE",
"XMLTEXT",
"XMLVALIDATE",
"XOR",
"XSLTRANSFORM",
"YEAR",
"ZONED",
// https://www.ibm.com/docs/en/i/7.5?topic=functions-table
"BASE_TABLE",
"HTTP_DELETE_BLOB_VERBOSE",
"HTTP_DELETE_VERBOSE",
"HTTP_GET_BLOB_VERBOSE",
"HTTP_GET_VERBOSE",
"HTTP_PATCH_BLOB_VERBOSE",
"HTTP_PATCH_VERBOSE",
"HTTP_POST_BLOB_VERBOSE",
"HTTP_POST_VERBOSE",
"HTTP_PUT_BLOB_VERBOSE",
"HTTP_PUT_VERBOSE",
"JSON_TABLE",
"MQREADALL",
"MQREADALLCLOB",
"MQRECEIVEALL",
"MQRECEIVEALLCLOB",
"XMLTABLE",
// https://www.ibm.com/docs/en/db2-for-zos/11?topic=functions-row
"UNPACK",
// https://www.ibm.com/docs/en/i/7.5?topic=expressions-olap-specifications
"CUME_DIST",
"DENSE_RANK",
"FIRST_VALUE",
"LAG",
"LAST_VALUE",
"LEAD",
"NTH_VALUE",
"NTILE",
"PERCENT_RANK",
"RANK",
"RATIO_TO_REPORT",
"ROW_NUMBER",
// Type casting
"CAST"
], EA = [
// https://www.ibm.com/docs/en/i/7.5?topic=words-reserved
// TODO: This list likely contains all keywords, not only the reserved ones,
// try to filter it down to just the reserved keywords.
"ABSENT",
"ACCORDING",
"ACCTNG",
"ACTION",
"ACTIVATE",
"ADD",
"ALIAS",
"ALL",
"ALLOCATE",
"ALLOW",
"ALTER",
"AND",
"ANY",
"APPEND",
"APPLNAME",
"ARRAY",
"ARRAY_AGG",
"ARRAY_TRIM",
"AS",
"ASC",
"ASENSITIVE",
"ASSOCIATE",
"ATOMIC",
"ATTACH",
"ATTRIBUTES",
"AUTHORIZATION",
"AUTONOMOUS",
"BEFORE",
"BEGIN",
"BETWEEN",
"BIND",
"BSON",
"BUFFERPOOL",
"BY",
"CACHE",
"CALL",
"CALLED",
"CARDINALITY",
"CASE",
"CAST",
"CHECK",
"CL",
"CLOSE",
"CLUSTER",
"COLLECT",
"COLLECTION",
"COLUMN",
"COMMENT",
"COMMIT",
"COMPACT",
"COMPARISONS",
"COMPRESS",
"CONCAT",
"CONCURRENT",
"CONDITION",
"CONNECT",
"CONNECT_BY_ROOT",
"CONNECTION",
"CONSTANT",
"CONSTRAINT",
"CONTAINS",
"CONTENT",
"CONTINUE",
"COPY",
"COUNT",
"COUNT_BIG",
"CREATE",
"CREATEIN",
"CROSS",
"CUBE",
"CUME_DIST",
"CURRENT",
"CURRENT_DATE",
"CURRENT_PATH",
"CURRENT_SCHEMA",
"CURRENT_SERVER",
"CURRENT_TIME",
"CURRENT_TIMESTAMP",
"CURRENT_TIMEZONE",
"CURRENT_USER",
"CURSOR",
"CYCLE",
"DATABASE",
"DATAPARTITIONNAME",
"DATAPARTITIONNUM",
"DAY",
"DAYS",
"DB2GENERAL",
"DB2GENRL",
"DB2SQL",
"DBINFO",
"DBPARTITIONNAME",
"DBPARTITIONNUM",
"DEACTIVATE",
"DEALLOCATE",
"DECLARE",
"DEFAULT",
"DEFAULTS",
"DEFER",
"DEFINE",
"DEFINITION",
"DELETE",
"DELETING",
"DENSE_RANK",
"DENSERANK",
"DESC",
"DESCRIBE",
"DESCRIPTOR",
"DETACH",
"DETERMINISTIC",
"DIAGNOSTICS",
"DISABLE",
"DISALLOW",
"DISCONNECT",
"DISTINCT",
"DO",
"DOCUMENT",
"DROP",
"DYNAMIC",
"EACH",
"ELSE",
"ELSEIF",
"EMPTY",
"ENABLE",
"ENCODING",
"ENCRYPTION",
"END",
"END-EXEC",
"ENDING",
"ENFORCED",
"ERROR",
"ESCAPE",
"EVERY",
"EXCEPT",
"EXCEPTION",
"EXCLUDING",
"EXCLUSIVE",
"EXECUTE",
"EXISTS",
"EXIT",
"EXTEND",
"EXTERNAL",
"EXTRACT",
"FALSE",
"FENCED",
"FETCH",
"FIELDPROC",
"FILE",
"FINAL",
"FIRST_VALUE",
"FOR",
"FOREIGN",
"FORMAT",
"FREE",
"FREEPAGE",
"FROM",
"FULL",
"FUNCTION",
"GBPCACHE",
"GENERAL",
"GENERATED",
"GET",
"GLOBAL",
"GO",
"GOTO",
"GRANT",
"GROUP",
"HANDLER",
"HASH",
"HASH_ROW",
"HASHED_VALUE",
"HAVING",
"HINT",
"HOLD",
"HOUR",
"HOURS",
// 'ID', Not actually a reserved keyword
"IDENTITY",
"IF",
"IGNORE",
"IMMEDIATE",
"IMPLICITLY",
"IN",
"INCLUDE",
"INCLUDING",
"INCLUSIVE",
"INCREMENT",
"INDEX",
"INDEXBP",
"INDICATOR",
"INF",
"INFINITY",
"INHERIT",
"INLINE",
"INNER",
"INOUT",
"INSENSITIVE",
"INSERT",
"INSERTING",
"INTEGRITY",
"INTERPRET",
"INTERSECT",
"INTO",
"IS",
"ISNULL",
"ISOLATION",
"ITERATE",
"JAVA",
"JOIN",
"JSON",
"JSON_ARRAY",
"JSON_ARRAYAGG",
"JSON_EXISTS",
"JSON_OBJECT",
"JSON_OBJECTAGG",
"JSON_QUERY",
"JSON_TABLE",
"JSON_VALUE",
"KEEP",
"KEY",
"KEYS",
"LABEL",
"LAG",
"LANGUAGE",
"LAST_VALUE",
"LATERAL",
"LEAD",
"LEAVE",
"LEFT",
"LEVEL2",
"LIKE",
"LIMIT",
"LINKTYPE",
"LISTAGG",
"LOCAL",
"LOCALDATE",
"LOCALTIME",
"LOCALTIMESTAMP",
"LOCATION",
"LOCATOR",
"LOCK",
"LOCKSIZE",
"LOG",
"LOGGED",
"LOOP",
"MAINTAINED",
"MASK",
"MATCHED",
"MATERIALIZED",
"MAXVALUE",
"MERGE",
"MICROSECOND",
"MICROSECONDS",
"MINPCTUSED",
"MINUTE",
"MINUTES",
"MINVALUE",
"MIRROR",
"MIXED",
"MODE",
"MODIFIES",
"MONTH",
"MONTHS",
"NAMESPACE",
"NAN",
"NATIONAL",
"NCHAR",
"NCLOB",
"NESTED",
"NEW",
"NEW_TABLE",
"NEXTVAL",
"NO",
"NOCACHE",
"NOCYCLE",
"NODENAME",
"NODENUMBER",
"NOMAXVALUE",
"NOMINVALUE",
"NONE",
"NOORDER",
"NORMALIZED",
"NOT",
"NOTNULL",
"NTH_VALUE",
"NTILE",
"NULL",
"NULLS",
"NVARCHAR",
"OBID",
"OBJECT",
"OF",
"OFF",
"OFFSET",
"OLD",
"OLD_TABLE",
"OMIT",
"ON",
"ONLY",
"OPEN",
"OPTIMIZE",
"OPTION",
"OR",
"ORDER",
"ORDINALITY",
"ORGANIZE",
"OUT",
"OUTER",
"OVER",
"OVERLAY",
"OVERRIDING",
"PACKAGE",
"PADDED",
"PAGE",
"PAGESIZE",
"PARAMETER",
"PART",
"PARTITION",
"PARTITIONED",
"PARTITIONING",
"PARTITIONS",
"PASSING",
"PASSWORD",
"PATH",
"PCTFREE",
"PERCENT_RANK",
"PERCENTILE_CONT",
"PERCENTILE_DISC",
"PERIOD",
"PERMISSION",
"PIECESIZE",
"PIPE",
"PLAN",
"POSITION",
"PREPARE",
"PREVVAL",
"PRIMARY",
"PRIOR",
"PRIQTY",
"PRIVILEGES",
"PROCEDURE",
"PROGRAM",
"PROGRAMID",
"QUERY",
"RANGE",
"RANK",
"RATIO_TO_REPORT",
"RCDFMT",
"READ",
"READS",
"RECOVERY",
"REFERENCES",
"REFERENCING",
"REFRESH",
"REGEXP_LIKE",
"RELEASE",
"RENAME",
"REPEAT",
"RESET",
"RESIGNAL",
"RESTART",
"RESULT",
"RESULT_SET_LOCATOR",
"RETURN",
"RETURNING",
"RETURNS",
"REVOKE",
"RID",
"RIGHT",
"ROLLBACK",
"ROLLUP",
"ROUTINE",
"ROW",
"ROW_NUMBER",
"ROWNUMBER",
"ROWS",
"RRN",
"RUN",
"SAVEPOINT",
"SBCS",
"SCALAR",
"SCHEMA",
"SCRATCHPAD",
"SCROLL",
"SEARCH",
"SECOND",
"SECONDS",
"SECQTY",
"SECURED",
"SELECT",
"SENSITIVE",
"SEQUENCE",
"SESSION",
"SESSION_USER",
"SET",
"SIGNAL",
"SIMPLE",
"SKIP",
"SNAN",
"SOME",
"SOURCE",
"SPECIFIC",
"SQL",
"SQLID",
"SQLIND_DEFAULT",
"SQLIND_UNASSIGNED",
"STACKED",
"START",
"STARTING",
"STATEMENT",
"STATIC",
"STOGROUP",
"SUBSTRING",
"SUMMARY",
"SYNONYM",
"SYSTEM_TIME",
"SYSTEM_USER",
"TABLE",
"TABLESPACE",
"TABLESPACES",
"TAG",
"THEN",
"THREADSAFE",
"TO",
"TRANSACTION",
"TRANSFER",
"TRIGGER",
"TRIM",
"TRIM_ARRAY",
"TRUE",
"TRUNCATE",
"TRY_CAST",
"TYPE",
"UNDO",
"UNION",
"UNIQUE",
"UNIT",
"UNKNOWN",
"UNNEST",
"UNTIL",
"UPDATE",
"UPDATING",
"URI",
"USAGE",
"USE",
"USER",
"USERID",
"USING",
"VALUE",
"VALUES",
"VARIABLE",
"VARIANT",
"VCAT",
"VERSION",
"VERSIONING",
"VIEW",
"VOLATILE",
"WAIT",
"WHEN",
"WHENEVER",
"WHERE",
"WHILE",
"WITH",
"WITHIN",
"WITHOUT",
"WRAPPED",
"WRAPPER",
"WRITE",
"WRKSTNNAME",
"XMLAGG",
"XMLATTRIBUTES",
"XMLCAST",
"XMLCOMMENT",
"XMLCONCAT",
"XMLDOCUMENT",
"XMLELEMENT",
"XMLFOREST",
"XMLGROUP",
"XMLNAMESPACES",
"XMLPARSE",
"XMLPI",
"XMLROW",
"XMLSERIALIZE",
"XMLTABLE",
"XMLTEXT",
"XMLVALIDATE",
"XSLTRANSFORM",
"XSROBJECT",
"YEAR",
"YEARS",
"YES",
"ZONE"
], eA = [
// https://www.ibm.com/docs/en/i/7.2?topic=iaodsd-odbc-data-types-how-they-correspond-db2-i-database-types
"ARRAY",
"BIGINT",
"BINARY",
"BIT",
"BLOB",
"BOOLEAN",
"CCSID",
"CHAR",
"CHARACTER",
"CLOB",
"DATA",
"DATALINK",
"DATE",
"DBCLOB",
"DECFLOAT",
"DECIMAL",
"DEC",
"DOUBLE",
"DOUBLE PRECISION",
"FLOAT",
"GRAPHIC",
"INT",
"INTEGER",
"LONG",
"NUMERIC",
"REAL",
"ROWID",
"SMALLINT",
"TIME",
"TIMESTAMP",
"VARBINARY",
"VARCHAR",
"VARGRAPHIC",
"XML"
], TA = o(["SELECT [ALL | DISTINCT]"]), RA = o([
// queries
"WITH [RECURSIVE]",
"INTO",
"FROM",
"WHERE",
"GROUP BY",
"HAVING",
"PARTITION BY",
"ORDER [SIBLINGS] BY [INPUT SEQUENCE]",
"LIMIT",
"OFFSET",
"FETCH {FIRST | NEXT}",
"FOR UPDATE [OF]",
"FOR READ ONLY",
"OPTIMIZE FOR",
// Data modification
// - insert:
"INSERT INTO",
"VALUES",
// - update:
"SET",
// - merge:
"MERGE INTO",
"WHEN [NOT] MATCHED [THEN]",
"UPDATE SET",
"DELETE",
"INSERT",
// Data definition - table
"FOR SYSTEM NAME"
]), Fe = o(["CREATE [OR REPLACE] TABLE"]), VE = o([
// - create:
"CREATE [OR REPLACE] [RECURSIVE] VIEW",
// - update:
"UPDATE",
"WHERE CURRENT OF",
"WITH {NC | RR | RS | CS | UR}",
// - delete:
"DELETE FROM",
// - drop table:
"DROP TABLE",
// alter table:
"ALTER TABLE",
"ADD [COLUMN]",
"ALTER [COLUMN]",
"DROP [COLUMN]",
"SET DATA TYPE",
"SET {GENERATED ALWAYS | GENERATED BY DEFAULT}",
"SET NOT NULL",
"SET {NOT HIDDEN | IMPLICITLY HIDDEN}",
"SET FIELDPROC",
"DROP {DEFAULT | NOT NULL | GENERATED | IDENTITY | ROW CHANGE TIMESTAMP | FIELDPROC}",
// - truncate:
"TRUNCATE [TABLE]",
// other
"SET [CURRENT] SCHEMA",
"SET CURRENT_SCHEMA",
// https://www.ibm.com/docs/en/i/7.5?topic=reference-statements
"ALLOCATE CURSOR",
"ALLOCATE [SQL] DESCRIPTOR [LOCAL | GLOBAL] SQL",
"ALTER [SPECIFIC] {FUNCTION | PROCEDURE}",
"ALTER {MASK | PERMISSION | SEQUENCE | TRIGGER}",
"ASSOCIATE [RESULT SET] {LOCATOR | LOCATORS}",
"BEGIN DECLARE SECTION",
"CALL",
"CLOSE",
"COMMENT ON {ALIAS | COLUMN | CONSTRAINT | INDEX | MASK | PACKAGE | PARAMETER | PERMISSION | SEQUENCE | TABLE | TRIGGER | VARIABLE | XSROBJECT}",
"COMMENT ON [SPECIFIC] {FUNCTION | PROCEDURE | ROUTINE}",
"COMMENT ON PARAMETER SPECIFIC {FUNCTION | PROCEDURE | ROUTINE}",
"COMMENT ON [TABLE FUNCTION] RETURN COLUMN",
"COMMENT ON [TABLE FUNCTION] RETURN COLUMN SPECIFIC [PROCEDURE | ROUTINE]",
"COMMIT [WORK] [HOLD]",
"CONNECT [TO | RESET] USER",
"CREATE [OR REPLACE] {ALIAS | FUNCTION | MASK | PERMISSION | PROCEDURE | SEQUENCE | TRIGGER | VARIABLE}",
"CREATE [ENCODED VECTOR] INDEX",
"CREATE UNIQUE [WHERE NOT NULL] INDEX",
"CREATE SCHEMA",
"CREATE TYPE",
"DEALLOCATE [SQL] DESCRIPTOR [LOCAL | GLOBAL]",
"DECLARE CURSOR",
"DECLARE GLOBAL TEMPORARY TABLE",
"DECLARE",
"DESCRIBE CURSOR",
"DESCRIBE INPUT",
"DESCRIBE [OUTPUT]",
"DESCRIBE {PROCEDURE | ROUTINE}",
"DESCRIBE TABLE",
"DISCONNECT ALL [SQL]",
"DISCONNECT [CURRENT]",
"DROP {ALIAS | INDEX | MASK | PACKAGE | PERMISSION | SCHEMA | SEQUENCE | TABLE | TYPE | VARIABLE | XSROBJECT} [IF EXISTS]",
"DROP [SPECIFIC] {FUNCTION | PROCEDURE | ROUTINE} [IF EXISTS]",
"END DECLARE SECTION",
"EXECUTE [IMMEDIATE]",
// 'FETCH {NEXT | PRIOR | FIRST | LAST | BEFORE | AFTER | CURRENT} [FROM]',
"FREE LOCATOR",
"GET [SQL] DESCRIPTOR [LOCAL | GLOBAL]",
"GET [CURRENT | STACKED] DIAGNOSTICS",
"GRANT {ALL [PRIVILEGES] | ALTER | EXECUTE} ON {FUNCTION | PROCEDURE | ROUTINE | PACKAGE | SCHEMA | SEQUENCE | TABLE | TYPE | VARIABLE | XSROBJECT}",
"HOLD LOCATOR",
"INCLUDE",
"LABEL ON {ALIAS | COLUMN | CONSTRAINT | INDEX | MASK | PACKAGE | PERMISSION | SEQUENCE | TABLE | TRIGGER | VARIABLE | XSROBJECT}",
"LABEL ON [SPECIFIC] {FUNCTION | PROCEDURE | ROUTINE}",
"LOCK TABLE",
"OPEN",
"PREPARE",
"REFRESH TABLE",
"RELEASE",
"RELEASE [TO] SAVEPOINT",
"RENAME [TABLE | INDEX] TO",
"REVOKE {ALL [PRIVILEGES] | ALTER | EXECUTE} ON {FUNCTION | PROCEDURE | ROUTINE | PACKAGE | SCHEMA | SEQUENCE | TABLE | TYPE | VARIABLE | XSROBJECT}",
"ROLLBACK [WORK] [HOLD | TO SAVEPOINT]",
"SAVEPOINT",
"SET CONNECTION",
"SET CURRENT {DEBUG MODE | DECFLOAT ROUNDING MODE | DEGREE | IMPLICIT XMLPARSE OPTION | TEMPORAL SYSTEM_TIME}",
"SET [SQL] DESCRIPTOR [LOCAL | GLOBAL]",
"SET ENCRYPTION PASSWORD",
"SET OPTION",
"SET {[CURRENT [FUNCTION]] PATH | CURRENT_PATH}",
"SET RESULT SETS [WITH RETURN [TO CALLER | TO CLIENT]]",
"SET SESSION AUTHORIZATION",
"SET SESSION_USER",
"SET TRANSACTION",
"SIGNAL SQLSTATE [VALUE]",
"TAG",
"TRANSFER OWNERSHIP OF",
"WHENEVER {NOT FOUND | SQLERROR | SQLWARNING}"
]), AA = o(["UNION [ALL]", "EXCEPT [ALL]", "INTERSECT [ALL]"]), tA = o([
"JOIN",
"{LEFT | RIGHT | FULL} [OUTER] JOIN",
"[LEFT | RIGHT] EXCEPTION JOIN",
"{INNER | CROSS} JOIN"
]), sA = o([
"ON DELETE",
"ON UPDATE",
"SET NULL",
"{ROWS | RANGE} BETWEEN"
]), SA = o([]), NA = {
name: "db2i",
tokenizerOptions: {
reservedSelect: TA,
reservedClauses: [...RA, ...Fe, ...VE],
reservedSetOperations: AA,
reservedJoins: tA,
reservedKeywordPhrases: sA,
reservedDataTypePhrases: SA,
reservedKeywords: EA,
reservedDataTypes: eA,
reservedFunctionNames: zR,
nestedBlockComments: !0,
extraParens: ["[]"],
stringTypes: [
{ quote: "''-qq", prefixes: ["G", "N"] },
{ quote: "''-raw", prefixes: ["X", "BX", "GX", "UX"], requirePrefix: !0 }
],
identTypes: ['""-qq'],
identChars: { first: "@#$", rest: "@#$" },
paramTypes: { positional: !0, named: [":"] },
paramChars: { first: "@#$", rest: "@#$" },
operators: ["**", "¬=", "¬>", "¬<", "!>", "!<", "||", "=>"]
},
formatOptions: {
onelineClauses: [...Fe, ...VE],
tabularOnelineClauses: VE
}
}, IA = [
// Functions from DuckDB (excluding those that start with an underscore):
// SELECT DISTINCT upper(function_name) AS function_name
// FROM duckdb_functions()
// WHERE function_name SIMILAR TO '^[a-z].*'
// ORDER BY function_name
"ABS",
"ACOS",
"ADD",
"ADD_PARQUET_KEY",
"AGE",
"AGGREGATE",
"ALIAS",
"ALL_PROFILING_OUTPUT",
"ANY_VALUE",
"APPLY",
"APPROX_COUNT_DISTINCT",
"APPROX_QUANTILE",
"ARBITRARY",
"ARGMAX",
"ARGMIN",
"ARG_MAX",
"ARG_MAX_NULL",
"ARG_MIN",
"ARG_MIN_NULL",
"ARRAY_AGG",
"ARRAY_AGGR",
"ARRAY_AGGREGATE",
"ARRAY_APPEND",
"ARRAY_APPLY",
"ARRAY_CAT",
"ARRAY_CONCAT",
"ARRAY_CONTAINS",
"ARRAY_COSINE_SIMILARITY",
"ARRAY_CROSS_PRODUCT",
"ARRAY_DISTANCE",
"ARRAY_DISTINCT",
"ARRAY_DOT_PRODUCT",
"ARRAY_EXTRACT",
"ARRAY_FILTER",
"ARRAY_GRADE_UP",
"ARRAY_HAS",
"ARRAY_HAS_ALL",
"ARRAY_HAS_ANY",
"ARRAY_INDEXOF",
"ARRAY_INNER_PRODUCT",
"ARRAY_INTERSECT",
"ARRAY_LENGTH",
"ARRAY_POP_BACK",
"ARRAY_POP_FRONT",
"ARRAY_POSITION",
"ARRAY_PREPEND",
"ARRAY_PUSH_BACK",
"ARRAY_PUSH_FRONT",
"ARRAY_REDUCE",
"ARRAY_RESIZE",
"ARRAY_REVERSE",
"ARRAY_REVERSE_SORT",
"ARRAY_SELECT",
"ARRAY_SLICE",
"ARRAY_SORT",
"ARRAY_TO_JSON",
"ARRAY_TO_STRING",
"ARRAY_TRANSFORM",
"ARRAY_UNIQUE",
"ARRAY_VALUE",
"ARRAY_WHERE",
"ARRAY_ZIP",
"ARROW_SCAN",
"ARROW_SCAN_DUMB",
"ASCII",
"ASIN",
"ATAN",
"ATAN2",
"AVG",
"BASE64",
"BIN",
"BITSTRING",
"BITSTRING_AGG",
"BIT_AND",
"BIT_COUNT",
"BIT_LENGTH",
"BIT_OR",
"BIT_POSITION",
"BIT_XOR",
"BOOL_AND",
"BOOL_OR",
"CARDINALITY",
"CBRT",
"CEIL",
"CEILING",
"CENTURY",
"CHECKPOINT",
"CHR",
"COLLATIONS",
"COL_DESCRIPTION",
"COMBINE",
"CONCAT",
"CONCAT_WS",
"CONSTANT_OR_NULL",
"CONTAINS",
"COPY_DATABASE",
"CORR",
"COS",
"COT",
"COUNT",
"COUNT_IF",
"COUNT_STAR",
"COVAR_POP",
"COVAR_SAMP",
"CREATE_SORT_KEY",
"CURRENT_CATALOG",
"CURRENT_DATABASE",
"CURRENT_DATE",
"CURRENT_LOCALTIME",
"CURRENT_LOCALTIMESTAMP",
"CURRENT_QUERY",
"CURRENT_ROLE",
"CURRENT_SCHEMA",
"CURRENT_SCHEMAS",
"CURRENT_SETTING",
"CURRENT_USER",
"CURRVAL",
"DAMERAU_LEVENSHTEIN",
"DATABASE_LIST",
"DATABASE_SIZE",
"DATEDIFF",
"DATEPART",
"DATESUB",
"DATETRUNC",
"DATE_ADD",
"DATE_DIFF",
"DATE_PART",
"DATE_SUB",
"DATE_TRUNC",
"DAY",
"DAYNAME",
"DAYOFMONTH",
"DAYOFWEEK",
"DAYOFYEAR",
"DECADE",
"DECODE",
"DEGREES",
"DISABLE_CHECKPOINT_ON_SHUTDOWN",
"DISABLE_OBJECT_CACHE",
"DISABLE_OPTIMIZER",
"DISABLE_PRINT_PROGRESS_BAR",
"DISABLE_PROFILE",
"DISABLE_PROFILING",
"DISABLE_PROGRESS_BAR",
"DISABLE_VERIFICATION",
"DISABLE_VERIFY_EXTERNAL",
"DISABLE_VERIFY_FETCH_ROW",
"DISABLE_VERIFY_PARALLELISM",
"DISABLE_VERIFY_SERIALIZER",
"DIVIDE",
"DUCKDB_COLUMNS",
"DUCKDB_CONSTRAINTS",
"DUCKDB_DATABASES",
"DUCKDB_DEPENDENCIES",
"DUCKDB_EXTENSIONS",
"DUCKDB_FUNCTIONS",
"DUCKDB_INDEXES",
"DUCKDB_KEYWORDS",
"DUCKDB_MEMORY",
"DUCKDB_OPTIMIZERS",
"DUCKDB_SCHEMAS",
"DUCKDB_SECRETS",
"DUCKDB_SEQUENCES",
"DUCKDB_SETTINGS",
"DUCKDB_TABLES",
"DUCKDB_TEMPORARY_FILES",
"DUCKDB_TYPES",
"DUCKDB_VIEWS",
"EDIT",
"EDITDIST3",
"ELEMENT_AT",
"ENABLE_CHECKPOINT_ON_SHUTDOWN",
"ENABLE_OBJECT_CACHE",
"ENABLE_OPTIMIZER",
"ENABLE_PRINT_PROGRESS_BAR",
"ENABLE_PROFILE",
"ENABLE_PROFILING",
"ENABLE_PROGRESS_BAR",
"ENABLE_VERIFICATION",
"ENCODE",
"ENDS_WITH",
"ENTROPY",
"ENUM_CODE",
"ENUM_FIRST",
"ENUM_LAST",
"ENUM_RANGE",
"ENUM_RANGE_BOUNDARY",
"EPOCH",
"EPOCH_MS",
"EPOCH_NS",
"EPOCH_US",
"ERA",
"ERROR",
"EVEN",
"EXP",
"FACTORIAL",
"FAVG",
"FDIV",
"FILTER",
"FINALIZE",
"FIRST",
"FLATTEN",
"FLOOR",
"FMOD",
"FORCE_CHECKPOINT",
"FORMAT",
"FORMATREADABLEDECIMALSIZE",
"FORMATREADABLESIZE",
"FORMAT_BYTES",
"FORMAT_PG_TYPE",
"FORMAT_TYPE",
"FROM_BASE64",
"FROM_BINARY",
"FROM_HEX",
"FROM_JSON",
"FROM_JSON_STRICT",
"FSUM",
"FUNCTIONS",
"GAMMA",
"GCD",
"GENERATE_SERIES",
"GENERATE_SUBSCRIPTS",
"GEN_RANDOM_UUID",
"GEOMEAN",
"GEOMETRIC_MEAN",
"GETENV",
"GET_BIT",
"GET_BLOCK_SIZE",
"GET_CURRENT_TIME",
"GET_CURRENT_TIMESTAMP",
"GLOB",
"GRADE_UP",
"GREATEST",
"GREATEST_COMMON_DIVISOR",
"GROUP_CONCAT",
"HAMMING",
"HASH",
"HAS_ANY_COLUMN_PRIVILEGE",
"HAS_COLUMN_PRIVILEGE",
"HAS_DATABASE_PRIVILEGE",
"HAS_FOREIGN_DATA_WRAPPER_PRIVILEGE",
"HAS_FUNCTION_PRIVILEGE",
"HAS_LANGUAGE_PRIVILEGE",
"HAS_SCHEMA_PRIVILEGE",
"HAS_SEQUENCE_PRIVILEGE",
"HAS_SERVER_PRIVILEGE",
"HAS_TABLESPACE_PRIVILEGE",
"HAS_TABLE_PRIVILEGE",
"HEX",
"HISTOGRAM",
"HOUR",
"ICU_CALENDAR_NAMES",
"ICU_SORT_KEY",
"ILIKE_ESCAPE",
"IMPORT_DATABASE",
"INDEX_SCAN",
"INET_CLIENT_ADDR",
"INET_CLIENT_PORT",
"INET_SERVER_ADDR",
"INET_SERVER_PORT",
"INSTR",
"IN_SEARCH_PATH",
"ISFINITE",
"ISINF",
"ISNAN",
"ISODOW",
"ISOYEAR",
"JACCARD",
"JARO_SIMILARITY",
"JARO_WINKLER_SIMILARITY",
// 'JSON',
"JSON_ARRAY",
"JSON_ARRAY_LENGTH",
"JSON_CONTAINS",
"JSON_DESERIALIZE_SQL",
"JSON_EXECUTE_SERIALIZED_SQL",
"JSON_EXTRACT",
"JSON_EXTRACT_PATH",
"JSON_EXTRACT_PATH_TEXT",
"JSON_EXTRACT_STRING",
"JSON_GROUP_ARRAY",
"JSON_GROUP_OBJECT",
"JSON_GROUP_STRUCTURE",
"JSON_KEYS",
"JSON_MERGE_PATCH",
"JSON_OBJECT",
"JSON_QUOTE",
"JSON_SERIALIZE_PLAN",
"JSON_SERIALIZE_SQL",
"JSON_STRUCTURE",
"JSON_TRANSFORM",
"JSON_TRANSFORM_STRICT",
"JSON_TYPE",
"JSON_VALID",
"JULIAN",
"KAHAN_SUM",
"KURTOSIS",
"KURTOSIS_POP",
"LAST",
"LAST_DAY",
"LCASE",
"LCM",
"LEAST",
"LEAST_COMMON_MULTIPLE",
"LEFT",
"LEFT_GRAPHEME",
"LEN",
"LENGTH",
"LENGTH_GRAPHEME",
"LEVENSHTEIN",
"LGAMMA",
"LIKE_ESCAPE",
"LIST",
"LISTAGG",
"LIST_AGGR",
"LIST_AGGREGATE",
"LIST_ANY_VALUE",
"LIST_APPEND",
"LIST_APPLY",
"LIST_APPROX_COUNT_DISTINCT",
"LIST_AVG",
"LIST_BIT_AND",
"LIST_BIT_OR",
"LIST_BIT_XOR",
"LIST_BOOL_AND",
"LIST_BOOL_OR",
"LIST_CAT",
"LIST_CONCAT",
"LIST_CONTAINS",
"LIST_COSINE_SIMILARITY",
"LIST_COUNT",
"LIST_DISTANCE",
"LIST_DISTINCT",
"LIST_DOT_PRODUCT",
"LIST_ELEMENT",
"LIST_ENTROPY",
"LIST_EXTRACT",
"LIST_FILTER",
"LIST_FIRST",
"LIST_GRADE_UP",
"LIST_HAS",
"LIST_HAS_ALL",
"LIST_HAS_ANY",
"LIST_HISTOGRAM",
"LIST_INDEXOF",
"LIST_INNER_PRODUCT",
"LIST_INTERSECT",
"LIST_KURTOSIS",
"LIST_KURTOSIS_POP",
"LIST_LAST",
"LIST_MAD",
"LIST_MAX",
"LIST_MEDIAN",
"LIST_MIN",
"LIST_MODE",
"LIST_PACK",
"LIST_POSITION",
"LIST_PREPEND",
"LIST_PRODUCT",
"LIST_REDUCE",
"LIST_RESIZE",
"LIST_REVERSE",
"LIST_REVERSE_SORT",
"LIST_SELECT",
"LIST_SEM",
"LIST_SKEWNESS",
"LIST_SLICE",
"LIST_SORT",
"LIST_STDDEV_POP",
"LIST_STDDEV_SAMP",
"LIST_STRING_AGG",
"LIST_SUM",
"LIST_TRANSFORM",
"LIST_UNIQUE",
"LIST_VALUE",
"LIST_VAR_POP",
"LIST_VAR_SAMP",
"LIST_WHERE",
"LIST_ZIP",
"LN",
"LOG",
"LOG10",
"LOG2",
"LOWER",
"LPAD",
"LSMODE",
"LTRIM",
"MAD",
"MAKE_DATE",
"MAKE_TIME",
"MAKE_TIMESTAMP",
"MAKE_TIMESTAMPTZ",
"MAP",
"MAP_CONCAT",
"MAP_ENTRIES",
"MAP_EXTRACT",
"MAP_FROM_ENTRIES",
"MAP_KEYS",
"MAP_VALUES",
"MAX",
"MAX_BY",
"MD5",
"MD5_NUMBER",
"MD5_NUMBER_LOWER",
"MD5_NUMBER_UPPER",
"MEAN",
"MEDIAN",
"METADATA_INFO",
"MICROSECOND",
"MILLENNIUM",
"MILLISECOND",
"MIN",
"MINUTE",
"MIN_BY",
"MISMATCHES",
"MOD",
"MODE",
"MONTH",
"MONTHNAME",
"MULTIPLY",
"NEXTAFTER",
"NEXTVAL",
"NFC_NORMALIZE",
"NOT_ILIKE_ESCAPE",
"NOT_LIKE_ESCAPE",
"NOW",
"NULLIF",
"OBJ_DESCRIPTION",
"OCTET_LENGTH",
"ORD",
"PARQUET_FILE_METADATA",
"PARQUET_KV_METADATA",
"PARQUET_METADATA",
"PARQUET_SCAN",
"PARQUET_SCHEMA",
"PARSE_DIRNAME",
"PARSE_DIRPATH",
"PARSE_FILENAME",
"PARSE_PATH",
"PG_COLLATION_IS_VISIBLE",
"PG_CONF_LOAD_TIME",
"PG_CONVERSION_IS_VISIBLE",
"PG_FUNCTION_IS_VISIBLE",
"PG_GET_CONSTRAINTDEF",
"PG_GET_EXPR",
"PG_GET_VIEWDEF",
"PG_HAS_ROLE",
"PG_IS_OTHER_TEMP_SCHEMA",
"PG_MY_TEMP_SCHEMA",
"PG_OPCLASS_IS_VISIBLE",
"PG_OPERATOR_IS_VISIBLE",
"PG_OPFAMILY_IS_VISIBLE",
"PG_POSTMASTER_START_TIME",
"PG_SIZE_PRETTY",
"PG_TABLE_IS_VISIBLE",
"PG_TIMEZONE_NAMES",
"PG_TS_CONFIG_IS_VISIBLE",
"PG_TS_DICT_IS_VISIBLE",
"PG_TS_PARSER_IS_VISIBLE",
"PG_TS_TEMPLATE_IS_VISIBLE",
"PG_TYPEOF",
"PG_TYPE_IS_VISIBLE",
"PI",
"PLATFORM",
"POSITION",
"POW",
"POWER",
"PRAGMA_COLLATIONS",
"PRAGMA_DATABASE_SIZE",
"PRAGMA_METADATA_INFO",
"PRAGMA_PLATFORM",
"PRAGMA_SHOW",
"PRAGMA_STORAGE_INFO",
"PRAGMA_TABLE_INFO",
"PRAGMA_USER_AGENT",
"PRAGMA_VERSION",
"PREFIX",
"PRINTF",
"PRODUCT",
"QUANTILE",
"QUANTILE_CONT",
"QUANTILE_DISC",
"QUARTER",
"RADIANS",
"RANDOM",
"RANGE",
"READFILE",
"READ_BLOB",
"READ_CSV",
"READ_CSV_AUTO",
"READ_JSON",
"READ_JSON_AUTO",
"READ_JSON_OBJECTS",
"READ_JSON_OBJECTS_AUTO",
"READ_NDJSON",
"READ_NDJSON_AUTO",
"READ_NDJSON_OBJECTS",
"READ_PARQUET",
"READ_TEXT",
"REDUCE",
"REGEXP_ESCAPE",
"REGEXP_EXTRACT",
"REGEXP_EXTRACT_ALL",
"REGEXP_FULL_MATCH",
"REGEXP_MATCHES",
"REGEXP_REPLACE",
"REGEXP_SPLIT_TO_ARRAY",
"REGEXP_SPLIT_TO_TABLE",
"REGR_AVGX",
"REGR_AVGY",
"REGR_COUNT",
"REGR_INTERCEPT",
"REGR_R2",
"REGR_SLOPE",
"REGR_SXX",
"REGR_SXY",
"REGR_SYY",
"REPEAT",
"REPEAT_ROW",
"REPLACE",
"RESERVOIR_QUANTILE",
"REVERSE",
"RIGHT",
"RIGHT_GRAPHEME",
"ROUND",
"ROUNDBANKERS",
"ROUND_EVEN",
"ROW",
"ROW_TO_JSON",
"RPAD",
"RTRIM",
"SECOND",
"SEM",
"SEQ_SCAN",
"SESSION_USER",
"SETSEED",
"SET_BIT",
"SHA256",
"SHA3",
"SHELL_ADD_SCHEMA",
"SHELL_ESCAPE_CRNL",
"SHELL_IDQUOTE",
"SHELL_MODULE_SCHEMA",
"SHELL_PUTSNL",
"SHOBJ_DESCRIPTION",
"SHOW",
"SHOW_DATABASES",
"SHOW_TABLES",
"SHOW_TABLES_EXPANDED",
"SIGN",
"SIGNBIT",
"SIN",
"SKEWNESS",
"SNIFF_CSV",
"SPLIT",
"SPLIT_PART",
"SQL_AUTO_COMPLETE",
"SQRT",
"STARTS_WITH",
"STATS",
"STDDEV",
"STDDEV_POP",
"STDDEV_SAMP",
"STORAGE_INFO",
"STRFTIME",
"STRING_AGG",
"STRING_SPLIT",
"STRING_SPLIT_REGEX",
"STRING_TO_ARRAY",
"STRIP_ACCENTS",
"STRLEN",
"STRPOS",
"STRPTIME",
"STRUCT_EXTRACT",
"STRUCT_INSERT",
"STRUCT_PACK",
"STR_SPLIT",
"STR_SPLIT_REGEX",
"SUBSTR",
"SUBSTRING",
"SUBSTRING_GRAPHEME",
"SUBTRACT",
"SUFFIX",
"SUM",
"SUMKAHAN",
"SUMMARY",
"SUM_NO_OVERFLOW",
"TABLE_INFO",
"TAN",
"TEST_ALL_TYPES",
"TEST_VECTOR_TYPES",
"TIMEZONE",
"TIMEZONE_HOUR",
"TIMEZONE_MINUTE",
"TIME_BUCKET",
"TODAY",
"TO_BASE",
"TO_BASE64",
"TO_BINARY",
"TO_CENTURIES",
"TO_DAYS",
"TO_DECADES",
"TO_HEX",
"TO_HOURS",
"TO_JSON",
"TO_MICROSECONDS",
"TO_MILLENNIA",
"TO_MILLISECONDS",
"TO_MINUTES",
"TO_MONTHS",
"TO_SECONDS",
"TO_TIMESTAMP",
"TO_WEEKS",
"TO_YEARS",
"TRANSACTION_TIMESTAMP",
"TRANSLATE",
"TRIM",
"TRUNC",
"TRY_STRPTIME",
"TXID_CURRENT",
"TYPEOF",
"UCASE",
"UNBIN",
"UNHEX",
"UNICODE",
"UNION_EXTRACT",
"UNION_TAG",
"UNION_VALUE",
"UNNEST",
"UNPIVOT_LIST",
"UPPER",
"USER",
"USER_AGENT",
"UUID",
"VARIANCE",
"VAR_POP",
"VAR_SAMP",
"VECTOR_TYPE",
"VERIFY_EXTERNAL",
"VERIFY_FETCH_ROW",
"VERIFY_PARALLELISM",
"VERIFY_SERIALIZER",
"VERSION",
"WEEK",
"WEEKDAY",
"WEEKOFYEAR",
"WHICH_SECRET",
"WRITEFILE",
"XOR",
"YEAR",
"YEARWEEK",
// Keywords that also need to be listed as functions
"CAST",
"COALESCE",
// 'NULL', we really prefer treating it as keyword
"RANK",
"ROW_NUMBER"
], OA = [
// Keywords from DuckDB:
// SELECT upper(keyword_name)
// FROM duckdb_keywords()
// WHERE keyword_category = 'reserved'
// ORDER BY keyword_name
"ALL",
"ANALYSE",
"ANALYZE",
"AND",
"ANY",
"AS",
"ASC",
"ATTACH",
"ASYMMETRIC",
"BOTH",
"CASE",
"CAST",
"CHECK",
"COLLATE",
"COLUMN",
"CONSTRAINT",
"CREATE",
"DEFAULT",
"DEFERRABLE",
"DESC",
"DESCRIBE",
"DETACH",
"DISTINCT",
"DO",
"ELSE",
"END",
"EXCEPT",
"FALSE",
"FETCH",
"FOR",
"FOREIGN",
"FROM",
"GRANT",
"GROUP",
"HAVING",
"IN",
"INITIALLY",
"INTERSECT",
"INTO",
"IS",
"LATERAL",
"LEADING",
"LIMIT",
"NOT",
"NULL",
"OFFSET",
"ON",
"ONLY",
"OR",
"ORDER",
"PIVOT",
"PIVOT_LONGER",
"PIVOT_WIDER",
"PLACING",
"PRIMARY",
"REFERENCES",
"RETURNING",
"SELECT",
"SHOW",
"SOME",
"SUMMARIZE",
"SYMMETRIC",
"TABLE",
"THEN",
"TO",
"TRAILING",
"TRUE",
"UNION",
"UNIQUE",
"UNPIVOT",
"USING",
"VARIADIC",
"WHEN",
"WHERE",
"WINDOW",
"WITH"
], nA = [
// Types from DuckDB:
// SELECT DISTINCT upper(type_name)
// FROM duckdb_types()
// ORDER BY type_name
"ARRAY",
"BIGINT",
"BINARY",
"BIT",
"BITSTRING",
"BLOB",
"BOOL",
"BOOLEAN",
"BPCHAR",
"BYTEA",
"CHAR",
"DATE",
"DATETIME",
"DEC",
"DECIMAL",
"DOUBLE",
"ENUM",
"FLOAT",
"FLOAT4",
"FLOAT8",
"GUID",
"HUGEINT",
"INET",
"INT",
"INT1",
"INT128",
"INT16",
"INT2",
"INT32",
"INT4",
"INT64",
"INT8",
"INTEGER",
"INTEGRAL",
"INTERVAL",
"JSON",
"LIST",
"LOGICAL",
"LONG",
"MAP",
// 'NULL' is a keyword
"NUMERIC",
"NVARCHAR",
"OID",
"REAL",
"ROW",
"SHORT",
"SIGNED",
"SMALLINT",
"STRING",
"STRUCT",
"TEXT",
"TIME",
"TIMESTAMP_MS",
"TIMESTAMP_NS",
"TIMESTAMP_S",
"TIMESTAMP_US",
"TIMESTAMP",
"TIMESTAMPTZ",
"TIMETZ",
"TINYINT",
"UBIGINT",
"UHUGEINT",
"UINT128",
"UINT16",
"UINT32",
"UINT64",
"UINT8",
"UINTEGER",
"UNION",
"USMALLINT",
"UTINYINT",
"UUID",
"VARBINARY",
"VARCHAR"
], rA = o(["SELECT [ALL | DISTINCT]"]), iA = o([
// queries
"WITH [RECURSIVE]",
"FROM",
"WHERE",
"GROUP BY [ALL]",
"HAVING",
"WINDOW",
"PARTITION BY",
"ORDER BY [ALL]",
"LIMIT",
"OFFSET",
// 'USING' (conflicts with 'USING' in JOIN)
"USING SAMPLE",
"QUALIFY",
// Data manipulation
// - insert:
"INSERT [OR REPLACE] INTO",
"VALUES",
"DEFAULT VALUES",
// - update:
"SET",
// other:
"RETURNING"
]), Ye = o([
"CREATE [OR REPLACE] [TEMPORARY | TEMP] TABLE [IF NOT EXISTS]"
]), bE = o([
// TABLE
// - update:
"UPDATE",
// - insert:
"ON CONFLICT",
// - delete:
"DELETE FROM",
// - drop table:
"DROP TABLE [IF EXISTS]",
// - truncate
"TRUNCATE",
// - alter table:
"ALTER TABLE",
"ADD [COLUMN] [IF NOT EXISTS]",
"ADD PRIMARY KEY",
"DROP [COLUMN] [IF EXISTS]",
"ALTER [COLUMN]",
"RENAME [COLUMN]",
"RENAME TO",
"SET [DATA] TYPE",
"{SET | DROP} DEFAULT",
"{SET | DROP} NOT NULL",
// MACRO / FUNCTION
"CREATE [OR REPLACE] [TEMPORARY | TEMP] {MACRO | FUNCTION}",
"DROP MACRO [TABLE] [IF EXISTS]",
"DROP FUNCTION [IF EXISTS]",
// INDEX
"CREATE [UNIQUE] INDEX [IF NOT EXISTS]",
"DROP INDEX [IF EXISTS]",
// SCHEMA
"CREATE [OR REPLACE] SCHEMA [IF NOT EXISTS]",
"DROP SCHEMA [IF EXISTS]",
// SECRET
"CREATE [OR REPLACE] [PERSISTENT | TEMPORARY] SECRET [IF NOT EXISTS]",
"DROP [PERSISTENT | TEMPORARY] SECRET [IF EXISTS]",
// SEQUENCE
"CREATE [OR REPLACE] [TEMPORARY | TEMP] SEQUENCE",
"DROP SEQUENCE [IF EXISTS]",
// VIEW
"CREATE [OR REPLACE] [TEMPORARY | TEMP] VIEW [IF NOT EXISTS]",
"DROP VIEW [IF EXISTS]",
"ALTER VIEW",
// TYPE
"CREATE TYPE",
"DROP TYPE [IF EXISTS]",
// other
"ANALYZE",
"ATTACH [DATABASE] [IF NOT EXISTS]",
"DETACH [DATABASE] [IF EXISTS]",
"CALL",
"[FORCE] CHECKPOINT",
"COMMENT ON [TABLE | COLUMN | VIEW | INDEX | SEQUENCE | TYPE | MACRO | MACRO TABLE]",
"COPY [FROM DATABASE]",
"DESCRIBE",
"EXPORT DATABASE",
"IMPORT DATABASE",
"INSTALL",
"LOAD",
"PIVOT",
"PIVOT_WIDER",
"UNPIVOT",
"EXPLAIN [ANALYZE]",
// plain SET conflicts with SET clause in UPDATE
"SET {LOCAL | SESSION | GLOBAL}",
"RESET [LOCAL | SESSION | GLOBAL]",
"{SET | RESET} VARIABLE",
"SUMMARIZE",
"BEGIN TRANSACTION",
"ROLLBACK",
"COMMIT",
"ABORT",
"USE",
"VACUUM [ANALYZE]",
// prepared statements
"PREPARE",
"EXECUTE",
"DEALLOCATE [PREPARE]"
]), aA = o([
"UNION [ALL | BY NAME]",
"EXCEPT [ALL]",
"INTERSECT [ALL]"
]), CA = o([
"JOIN",
"{LEFT | RIGHT | FULL} [OUTER] JOIN",
"{INNER | CROSS} JOIN",
"{NATURAL | ASOF} [INNER] JOIN",
"{NATURAL | ASOF} {LEFT | RIGHT | FULL} [OUTER] JOIN",
"POSITIONAL JOIN",
"ANTI JOIN",
"SEMI JOIN"
]), oA = o([
"{ROWS | RANGE | GROUPS} BETWEEN",
"SIMILAR TO",
"IS [NOT] DISTINCT FROM"
]), LA = o(["TIMESTAMP WITH TIME ZONE"]), _A = {
name: "duckdb",
tokenizerOptions: {
reservedSelect: rA,
reservedClauses: [...iA, ...Ye, ...bE],
reservedSetOperations: aA,
reservedJoins: CA,
reservedKeywordPhrases: oA,
reservedDataTypePhrases: LA,
supportsXor: !0,
reservedKeywords: OA,
reservedDataTypes: nA,
reservedFunctionNames: IA,
nestedBlockComments: !0,
extraParens: ["[]", "{}"],
underscoresInNumbers: !0,
stringTypes: [
"$$",
"''-qq",
{ quote: "''-qq-bs", prefixes: ["E"], requirePrefix: !0 },
{ quote: "''-raw", prefixes: ["B", "X"], requirePrefix: !0 }
],
identTypes: ['""-qq'],
identChars: { rest: "$" },
// TODO: named params $foo currently conflict with $$-quoted strings
paramTypes: { positional: !0, numbered: ["$"], quoted: ["$"] },
operators: [
// Arithmetic:
"//",
"%",
"**",
"^",
"!",
// Bitwise:
"&",
"|",
"~",
"<<",
">>",
// Cast:
"::",
// Comparison:
"==",
// Lambda & JSON:
"->",
// JSON:
"->>",
// key-value separator:
":",
// Named function params:
":=",
"=>",
// Pattern matching:
"~~",
"!~~",
"~~*",
"!~~*",
"~~~",
// Regular expressions:
"~",
"!~",
"~*",
"!~*",
// String:
"^@",
"||",
// INET extension:
">>=",
"<<="
]
},
formatOptions: {
alwaysDenseOperators: ["::"],
onelineClauses: [...Ye, ...bE],
tabularOnelineClauses: bE
}
}, DA = [
// https://cwiki.apache.org/confluence/display/Hive/LanguageManual+UDF
// math
"ABS",
"ACOS",
"ASIN",
"ATAN",
"BIN",
"BROUND",
"CBRT",
"CEIL",
"CEILING",
"CONV",
"COS",
"DEGREES",
// 'E',
"EXP",
"FACTORIAL",
"FLOOR",
"GREATEST",
"HEX",
"LEAST",
"LN",
"LOG",
"LOG10",
"LOG2",
"NEGATIVE",
"PI",
"PMOD",
"POSITIVE",
"POW",
"POWER",
"RADIANS",
"RAND",
"ROUND",
"SHIFTLEFT",
"SHIFTRIGHT",
"SHIFTRIGHTUNSIGNED",
"SIGN",
"SIN",
"SQRT",
"TAN",
"UNHEX",
"WIDTH_BUCKET",
// array
"ARRAY_CONTAINS",
"MAP_KEYS",
"MAP_VALUES",
"SIZE",
"SORT_ARRAY",
// conversion
"BINARY",
"CAST",
// date
"ADD_MONTHS",
"DATE",
"DATE_ADD",
"DATE_FORMAT",
"DATE_SUB",
"DATEDIFF",
"DAY",
"DAYNAME",
"DAYOFMONTH",
"DAYOFYEAR",
"EXTRACT",
"FROM_UNIXTIME",
"FROM_UTC_TIMESTAMP",
"HOUR",
"LAST_DAY",
"MINUTE",
"MONTH",
"MONTHS_BETWEEN",
"NEXT_DAY",
"QUARTER",
"SECOND",
"TIMESTAMP",
"TO_DATE",
"TO_UTC_TIMESTAMP",
"TRUNC",
"UNIX_TIMESTAMP",
"WEEKOFYEAR",
"YEAR",
// conditional
"ASSERT_TRUE",
"COALESCE",
"IF",
"ISNOTNULL",
"ISNULL",
"NULLIF",
"NVL",
// string
"ASCII",
"BASE64",
"CHARACTER_LENGTH",
"CHR",
"CONCAT",
"CONCAT_WS",
"CONTEXT_NGRAMS",
"DECODE",
"ELT",
"ENCODE",
"FIELD",
"FIND_IN_SET",
"FORMAT_NUMBER",
"GET_JSON_OBJECT",
"IN_FILE",
"INITCAP",
"INSTR",
"LCASE",
"LENGTH",
"LEVENSHTEIN",
"LOCATE",
"LOWER",
"LPAD",
"LTRIM",
"NGRAMS",
"OCTET_LENGTH",
"PARSE_URL",
"PRINTF",
"QUOTE",
"REGEXP_EXTRACT",
"REGEXP_REPLACE",
"REPEAT",
"REVERSE",
"RPAD",
"RTRIM",
"SENTENCES",
"SOUNDEX",
"SPACE",
"SPLIT",
"STR_TO_MAP",
"SUBSTR",
"SUBSTRING",
"TRANSLATE",
"TRIM",
"UCASE",
"UNBASE64",
"UPPER",
// masking
"MASK",
"MASK_FIRST_N",
"MASK_HASH",
"MASK_LAST_N",
"MASK_SHOW_FIRST_N",
"MASK_SHOW_LAST_N",
// misc
"AES_DECRYPT",
"AES_ENCRYPT",
"CRC32",
"CURRENT_DATABASE",
"CURRENT_USER",
"HASH",
"JAVA_METHOD",
"LOGGED_IN_USER",
"MD5",
"REFLECT",
"SHA",
"SHA1",
"SHA2",
"SURROGATE_KEY",
"VERSION",
// aggregate
"AVG",
"COLLECT_LIST",
"COLLECT_SET",
"CORR",
"COUNT",
"COVAR_POP",
"COVAR_SAMP",
"HISTOGRAM_NUMERIC",
"MAX",
"MIN",
"NTILE",
"PERCENTILE",
"PERCENTILE_APPROX",
"REGR_AVGX",
"REGR_AVGY",
"REGR_COUNT",
"REGR_INTERCEPT",
"REGR_R2",
"REGR_SLOPE",
"REGR_SXX",
"REGR_SXY",
"REGR_SYY",
"STDDEV_POP",
"STDDEV_SAMP",
"SUM",
"VAR_POP",
"VAR_SAMP",
"VARIANCE",
// table
"EXPLODE",
"INLINE",
"JSON_TUPLE",
"PARSE_URL_TUPLE",
"POSEXPLODE",
"STACK",
// https://cwiki.apache.org/confluence/display/Hive/LanguageManual+WindowingAndAnalytics
"LEAD",
"LAG",
"FIRST_VALUE",
"LAST_VALUE",
"RANK",
"ROW_NUMBER",
"DENSE_RANK",
"CUME_DIST",
"PERCENT_RANK",
"NTILE"
], PA = [
// https://cwiki.apache.org/confluence/display/hive/languagemanual+ddl
// Non-reserved keywords have proscribed meanings in. HiveQL, but can still be used as table or column names
"ADD",
"ADMIN",
"AFTER",
"ANALYZE",
"ARCHIVE",
"ASC",
"BEFORE",
"BUCKET",
"BUCKETS",
"CASCADE",
"CHANGE",
"CLUSTER",
"CLUSTERED",
"CLUSTERSTATUS",
"COLLECTION",
"COLUMNS",
"COMMENT",
"COMPACT",
"COMPACTIONS",
"COMPUTE",
"CONCATENATE",
"CONTINUE",
"DATA",
"DATABASES",
"DATETIME",
"DAY",
"DBPROPERTIES",
"DEFERRED",
"DEFINED",
"DELIMITED",
"DEPENDENCY",
"DESC",
"DIRECTORIES",
"DIRECTORY",
"DISABLE",
"DISTRIBUTE",
"ELEM_TYPE",
"ENABLE",
"ESCAPED",
"EXCLUSIVE",
"EXPLAIN",
"EXPORT",
"FIELDS",
"FILE",
"FILEFORMAT",
"FIRST",
"FORMAT",
"FORMATTED",
"FUNCTIONS",
"HOLD_DDLTIME",
"HOUR",
"IDXPROPERTIES",
"IGNORE",
"INDEX",
"INDEXES",
"INPATH",
"INPUTDRIVER",
"INPUTFORMAT",
"ITEMS",
"JAR",
"KEYS",
"KEY_TYPE",
"LIMIT",
"LINES",
"LOAD",
"LOCATION",
"LOCK",
"LOCKS",
"LOGICAL",
"LONG",
"MAPJOIN",
"MATERIALIZED",
"METADATA",
"MINUS",
"MINUTE",
"MONTH",
"MSCK",
"NOSCAN",
"NO_DROP",
"OFFLINE",
"OPTION",
"OUTPUTDRIVER",
"OUTPUTFORMAT",
"OVERWRITE",
"OWNER",
"PARTITIONED",
"PARTITIONS",
"PLUS",
"PRETTY",
"PRINCIPALS",
"PROTECTION",
"PURGE",
"READ",
"READONLY",
"REBUILD",
"RECORDREADER",
"RECORDWRITER",
"RELOAD",
"RENAME",
"REPAIR",
"REPLACE",
"REPLICATION",
"RESTRICT",
"REWRITE",
"ROLE",
"ROLES",
"SCHEMA",
"SCHEMAS",
"SECOND",
"SEMI",
"SERDE",
"SERDEPROPERTIES",
"SERVER",
"SETS",
"SHARED",
"SHOW",
"SHOW_DATABASE",
"SKEWED",
"SORT",
"SORTED",
"SSL",
"STATISTICS",
"STORED",
"STREAMTABLE",
"STRING",
"TABLES",
"TBLPROPERTIES",
"TEMPORARY",
"TERMINATED",
"TINYINT",
"TOUCH",
"TRANSACTIONS",
"UNARCHIVE",
"UNDO",
"UNIONTYPE",
"UNLOCK",
"UNSET",
"UNSIGNED",
"URI",
"USE",
"UTC",
"UTCTIMESTAMP",
"VALUE_TYPE",
"VIEW",
"WHILE",
"YEAR",
"AUTOCOMMIT",
"ISOLATION",
"LEVEL",
"OFFSET",
"SNAPSHOT",
"TRANSACTION",
"WORK",
"WRITE",
"ABORT",
"KEY",
"LAST",
"NORELY",
"NOVALIDATE",
"NULLS",
"RELY",
"VALIDATE",
"DETAIL",
"DOW",
"EXPRESSION",
"OPERATOR",
"QUARTER",
"SUMMARY",
"VECTORIZATION",
"WEEK",
"YEARS",
"MONTHS",
"WEEKS",
"DAYS",
"HOURS",
"MINUTES",
"SECONDS",
"TIMESTAMPTZ",
"ZONE",
// reserved
"ALL",
"ALTER",
"AND",
"AS",
"AUTHORIZATION",
"BETWEEN",
"BOTH",
"BY",
"CASE",
"CAST",
"COLUMN",
"CONF",
"CREATE",
"CROSS",
"CUBE",
"CURRENT",
"CURRENT_DATE",
"CURRENT_TIMESTAMP",
"CURSOR",
"DATABASE",
"DELETE",
"DESCRIBE",
"DISTINCT",
"DROP",
"ELSE",
"END",
"EXCHANGE",
"EXISTS",
"EXTENDED",
"EXTERNAL",
"FALSE",
"FETCH",
"FOLLOWING",
"FOR",
"FROM",
"FULL",
"FUNCTION",
"GRANT",
"GROUP",
"GROUPING",
"HAVING",
"IF",
"IMPORT",
"IN",
"INNER",
"INSERT",
"INTERSECT",
"INTO",
"IS",
"JOIN",
"LATERAL",
"LEFT",
"LESS",
"LIKE",
"LOCAL",
"MACRO",
"MORE",
"NONE",
"NOT",
"NULL",
"OF",
"ON",
"OR",
"ORDER",
"OUT",
"OUTER",
"OVER",
"PARTIALSCAN",
"PARTITION",
"PERCENT",
"PRECEDING",
"PRESERVE",
"PROCEDURE",
"RANGE",
"READS",
"REDUCE",
"REVOKE",
"RIGHT",
"ROLLUP",
"ROW",
"ROWS",
"SELECT",
"SET",
"TABLE",
"TABLESAMPLE",
"THEN",
"TO",
"TRANSFORM",
"TRIGGER",
"TRUE",
"TRUNCATE",
"UNBOUNDED",
"UNION",
"UNIQUEJOIN",
"UPDATE",
"USER",
"USING",
"UTC_TMESTAMP",
"VALUES",
"WHEN",
"WHERE",
"WINDOW",
"WITH",
"COMMIT",
"ONLY",
"REGEXP",
"RLIKE",
"ROLLBACK",
"START",
"CACHE",
"CONSTRAINT",
"FOREIGN",
"PRIMARY",
"REFERENCES",
"DAYOFWEEK",
"EXTRACT",
"FLOOR",
"VIEWS",
"TIME",
"SYNC",
// fileTypes
"TEXTFILE",
"SEQUENCEFILE",
"ORC",
"CSV",
"TSV",
"PARQUET",
"AVRO",
"RCFILE",
"JSONFILE",
"INPUTFORMAT",
"OUTPUTFORMAT"
], lA = [
// https://cwiki.apache.org/confluence/display/Hive/LanguageManual+Types
"ARRAY",
"BIGINT",
"BINARY",
"BOOLEAN",
"CHAR",
"DATE",
"DECIMAL",
"DOUBLE",
"FLOAT",
"INT",
"INTEGER",
"INTERVAL",
"MAP",
"NUMERIC",
"PRECISION",
"SMALLINT",
"STRUCT",
"TIMESTAMP",
"VARCHAR"
], cA = o(["SELECT [ALL | DISTINCT]"]), MA = o([
// queries
"WITH",
"FROM",
"WHERE",
"GROUP BY",
"HAVING",
"WINDOW",
"PARTITION BY",
"ORDER BY",
"SORT BY",
"CLUSTER BY",
"DISTRIBUTE BY",
"LIMIT",
// Data manipulation
// - insert:
// Hive does not actually support plain INSERT INTO, only INSERT INTO TABLE
// but it's a nuisance to not support it, as all other dialects do.
"INSERT INTO [TABLE]",
"VALUES",
// - update:
"SET",
// - merge:
"MERGE INTO",
"WHEN [NOT] MATCHED [THEN]",
"UPDATE SET",
"INSERT [VALUES]",
// - insert overwrite directory:
// https://cwiki.apache.org/confluence/display/Hive/LanguageManual+DML#LanguageManualDML-Writingdataintothefilesystemfromqueries
"INSERT OVERWRITE [LOCAL] DIRECTORY",
// - load:
// https://cwiki.apache.org/confluence/display/Hive/LanguageManual+DML#LanguageManualDML-Loadingfilesintotables
"LOAD DATA [LOCAL] INPATH",
"[OVERWRITE] INTO TABLE"
]), Ve = o([
"CREATE [TEMPORARY] [EXTERNAL] TABLE [IF NOT EXISTS]"
]), gE = o([
// - create:
"CREATE [MATERIALIZED] VIEW [IF NOT EXISTS]",
// - update:
"UPDATE",
// - delete:
"DELETE FROM",
// - drop table:
"DROP TABLE [IF EXISTS]",
// - alter table:
"ALTER TABLE",
"RENAME TO",
// - truncate:
"TRUNCATE [TABLE]",
// other
"ALTER",
"CREATE",
"USE",
"DESCRIBE",
"DROP",
"FETCH",
"SHOW",
"STORED AS",
"STORED BY",
"ROW FORMAT"
]), uA = o(["UNION [ALL | DISTINCT]"]), UA = o([
"JOIN",
"{LEFT | RIGHT | FULL} [OUTER] JOIN",
"{INNER | CROSS} JOIN",
// non-standard joins
"LEFT SEMI JOIN"
]), dA = o(["{ROWS | RANGE} BETWEEN"]), mA = o([]), GA = {
name: "hive",
tokenizerOptions: {
reservedSelect: cA,
reservedClauses: [...MA, ...Ve, ...gE],
reservedSetOperations: uA,
reservedJoins: UA,
reservedKeywordPhrases: dA,
reservedDataTypePhrases: mA,
reservedKeywords: PA,
reservedDataTypes: lA,
reservedFunctionNames: DA,
extraParens: ["[]"],
stringTypes: ['""-bs', "''-bs"],
identTypes: ["``"],
variableTypes: [{ quote: "{}", prefixes: ["$"], requirePrefix: !0 }],
operators: ["%", "~", "^", "|", "&", "<=>", "==", "!", "||"]
},
formatOptions: {
onelineClauses: [...Ve, ...gE],
tabularOnelineClauses: gE
}
};
function ME(T) {
return T.map((E, e) => {
const R = T[e + 1] || TE;
if (j.SET(E) && R.text === "(")
return Object.assign(Object.assign({}, E), { type: l.RESERVED_FUNCTION_NAME });
const A = T[e - 1] || TE;
return j.VALUES(E) && A.text === "=" ? Object.assign(Object.assign({}, E), { type: l.RESERVED_FUNCTION_NAME }) : E;
});
}
const pA = [
// https://mariadb.com/kb/en/reserved-words/
"ACCESSIBLE",
"ADD",
"ALL",
"ALTER",
"ANALYZE",
"AND",
"AS",
"ASC",
"ASENSITIVE",
"BEFORE",
"BETWEEN",
"BOTH",
"BY",
"CALL",
"CASCADE",
"CASE",
"CHANGE",
"CHECK",
"COLLATE",
"COLUMN",
"CONDITION",
"CONSTRAINT",
"CONTINUE",
"CONVERT",
"CREATE",
"CROSS",
"CURRENT_DATE",
"CURRENT_ROLE",
"CURRENT_TIME",
"CURRENT_TIMESTAMP",
"CURRENT_USER",
"CURSOR",
"DATABASE",
"DATABASES",
"DAY_HOUR",
"DAY_MICROSECOND",
"DAY_MINUTE",
"DAY_SECOND",
"DECLARE",
"DEFAULT",
"DELAYED",
"DELETE",
"DELETE_DOMAIN_ID",
"DESC",
"DESCRIBE",
"DETERMINISTIC",
"DISTINCT",
"DISTINCTROW",
"DIV",
"DO_DOMAIN_IDS",
"DROP",
"DUAL",
"EACH",
"ELSE",
"ELSEIF",
"ENCLOSED",
"ESCAPED",
"EXCEPT",
"EXISTS",
"EXIT",
"EXPLAIN",
"FALSE",
"FETCH",
"FOR",
"FORCE",
"FOREIGN",
"FROM",
"FULLTEXT",
"GENERAL",
"GRANT",
"GROUP",
"HAVING",
"HIGH_PRIORITY",
"HOUR_MICROSECOND",
"HOUR_MINUTE",
"HOUR_SECOND",
"IF",
"IGNORE",
"IGNORE_DOMAIN_IDS",
"IGNORE_SERVER_IDS",
"IN",
"INDEX",
"INFILE",
"INNER",
"INOUT",
"INSENSITIVE",
"INSERT",
"INTERSECT",
"INTERVAL",
"INTO",
"IS",
"ITERATE",
"JOIN",
"KEY",
"KEYS",
"KILL",
"LEADING",
"LEAVE",
"LEFT",
"LIKE",
"LIMIT",
"LINEAR",
"LINES",
"LOAD",
"LOCALTIME",
"LOCALTIMESTAMP",
"LOCK",
"LOOP",
"LOW_PRIORITY",
"MASTER_HEARTBEAT_PERIOD",
"MASTER_SSL_VERIFY_SERVER_CERT",
"MATCH",
"MAXVALUE",
"MINUTE_MICROSECOND",
"MINUTE_SECOND",
"MOD",
"MODIFIES",
"NATURAL",
"NOT",
"NO_WRITE_TO_BINLOG",
"NULL",
"OFFSET",
"ON",
"OPTIMIZE",
"OPTION",
"OPTIONALLY",
"OR",
"ORDER",
"OUT",
"OUTER",
"OUTFILE",
"OVER",
"PAGE_CHECKSUM",
"PARSE_VCOL_EXPR",
"PARTITION",
"POSITION",
"PRIMARY",
"PROCEDURE",
"PURGE",
"RANGE",
"READ",
"READS",
"READ_WRITE",
"RECURSIVE",
"REF_SYSTEM_ID",
"REFERENCES",
"REGEXP",
"RELEASE",
"RENAME",
"REPEAT",
"REPLACE",
"REQUIRE",
"RESIGNAL",
"RESTRICT",
"RETURN",
"RETURNING",
"REVOKE",
"RIGHT",
"RLIKE",
"ROW_NUMBER",
"ROWS",
"SCHEMA",
"SCHEMAS",
"SECOND_MICROSECOND",
"SELECT",
"SENSITIVE",
"SEPARATOR",
"SET",
"SHOW",
"SIGNAL",
"SLOW",
"SPATIAL",
"SPECIFIC",
"SQL",
"SQLEXCEPTION",
"SQLSTATE",
"SQLWARNING",
"SQL_BIG_RESULT",
"SQL_CALC_FOUND_ROWS",
"SQL_SMALL_RESULT",
"SSL",
"STARTING",
"STATS_AUTO_RECALC",
"STATS_PERSISTENT",
"STATS_SAMPLE_PAGES",
"STRAIGHT_JOIN",
"TABLE",
"TERMINATED",
"THEN",
"TO",
"TRAILING",
"TRIGGER",
"TRUE",
"UNDO",
"UNION",
"UNIQUE",
"UNLOCK",
"UNSIGNED",
"UPDATE",
"USAGE",
"USE",
"USING",
"UTC_DATE",
"UTC_TIME",
"UTC_TIMESTAMP",
"VALUES",
"WHEN",
"WHERE",
"WHILE",
"WINDOW",
"WITH",
"WRITE",
"XOR",
"YEAR_MONTH",
"ZEROFILL"
], fA = [
// https://mariadb.com/kb/en/data-types/
"BIGINT",
"BINARY",
"BIT",
"BLOB",
"CHAR BYTE",
"CHAR",
"CHARACTER",
"DATETIME",
"DEC",
"DECIMAL",
"DOUBLE PRECISION",
"DOUBLE",
"ENUM",
"FIXED",
"FLOAT",
"FLOAT4",
"FLOAT8",
"INT",
"INT1",
"INT2",
"INT3",
"INT4",
"INT8",
"INTEGER",
"LONG",
"LONGBLOB",
"LONGTEXT",
"MEDIUMBLOB",
"MEDIUMINT",
"MEDIUMTEXT",
"MIDDLEINT",
"NATIONAL CHAR",
"NATIONAL VARCHAR",
"NUMERIC",
"PRECISION",
"REAL",
"SMALLINT",
"TEXT",
"TIMESTAMP",
"TINYBLOB",
"TINYINT",
"TINYTEXT",
"VARBINARY",
"VARCHAR",
"VARCHARACTER",
"VARYING",
"YEAR"
// 'NUMBER', // ?? In oracle mode only
// 'SET' // handled as special-case in postProcess
], BA = [
// https://mariadb.com/kb/en/information-schema-sql_functions-table/
"ADDDATE",
"ADD_MONTHS",
"BIT_AND",
"BIT_OR",
"BIT_XOR",
"CAST",
"COUNT",
"CUME_DIST",
"CURDATE",
"CURTIME",
"DATE_ADD",
"DATE_SUB",
"DATE_FORMAT",
"DECODE",
"DENSE_RANK",
"EXTRACT",
"FIRST_VALUE",
"GROUP_CONCAT",
"JSON_ARRAYAGG",
"JSON_OBJECTAGG",
"LAG",
"LEAD",
"MAX",
"MEDIAN",
"MID",
"MIN",
"NOW",
"NTH_VALUE",
"NTILE",
"POSITION",
"PERCENT_RANK",
"PERCENTILE_CONT",
"PERCENTILE_DISC",
"RANK",
"ROW_NUMBER",
"SESSION_USER",
"STD",
"STDDEV",
"STDDEV_POP",
"STDDEV_SAMP",
"SUBDATE",
"SUBSTR",
"SUBSTRING",
"SUM",
"SYSTEM_USER",
"TRIM",
"TRIM_ORACLE",
"VARIANCE",
"VAR_POP",
"VAR_SAMP",
"ABS",
"ACOS",
"ADDTIME",
"AES_DECRYPT",
"AES_ENCRYPT",
"ASIN",
"ATAN",
"ATAN2",
"BENCHMARK",
"BIN",
"BINLOG_GTID_POS",
"BIT_COUNT",
"BIT_LENGTH",
"CEIL",
"CEILING",
"CHARACTER_LENGTH",
"CHAR_LENGTH",
"CHR",
"COERCIBILITY",
"COLUMN_CHECK",
"COLUMN_EXISTS",
"COLUMN_LIST",
"COLUMN_JSON",
"COMPRESS",
"CONCAT",
"CONCAT_OPERATOR_ORACLE",
"CONCAT_WS",
"CONNECTION_ID",
"CONV",
"CONVERT_TZ",
"COS",
"COT",
"CRC32",
"DATEDIFF",
"DAYNAME",
"DAYOFMONTH",
"DAYOFWEEK",
"DAYOFYEAR",
"DEGREES",
"DECODE_HISTOGRAM",
"DECODE_ORACLE",
"DES_DECRYPT",
"DES_ENCRYPT",
"ELT",
"ENCODE",
"ENCRYPT",
"EXP",
"EXPORT_SET",
"EXTRACTVALUE",
"FIELD",
"FIND_IN_SET",
"FLOOR",
"FORMAT",
"FOUND_ROWS",
"FROM_BASE64",
"FROM_DAYS",
"FROM_UNIXTIME",
"GET_LOCK",
"GREATEST",
"HEX",
"IFNULL",
"INSTR",
"ISNULL",
"IS_FREE_LOCK",
"IS_USED_LOCK",
"JSON_ARRAY",
"JSON_ARRAY_APPEND",
"JSON_ARRAY_INSERT",
"JSON_COMPACT",
"JSON_CONTAINS",
"JSON_CONTAINS_PATH",
"JSON_DEPTH",
"JSON_DETAILED",
"JSON_EXISTS",
"JSON_EXTRACT",
"JSON_INSERT",
"JSON_KEYS",
"JSON_LENGTH",
"JSON_LOOSE",
"JSON_MERGE",
"JSON_MERGE_PATCH",
"JSON_MERGE_PRESERVE",
"JSON_QUERY",
"JSON_QUOTE",
"JSON_OBJECT",
"JSON_REMOVE",
"JSON_REPLACE",
"JSON_SET",
"JSON_SEARCH",
"JSON_TYPE",
"JSON_UNQUOTE",
"JSON_VALID",
"JSON_VALUE",
"LAST_DAY",
"LAST_INSERT_ID",
"LCASE",
"LEAST",
"LENGTH",
"LENGTHB",
"LN",
"LOAD_FILE",
"LOCATE",
"LOG",
"LOG10",
"LOG2",
"LOWER",
"LPAD",
"LPAD_ORACLE",
"LTRIM",
"LTRIM_ORACLE",
"MAKEDATE",
"MAKETIME",
"MAKE_SET",
"MASTER_GTID_WAIT",
"MASTER_POS_WAIT",
"MD5",
"MONTHNAME",
"NAME_CONST",
"NVL",
"NVL2",
"OCT",
"OCTET_LENGTH",
"ORD",
"PERIOD_ADD",
"PERIOD_DIFF",
"PI",
"POW",
"POWER",
"QUOTE",
"REGEXP_INSTR",
"REGEXP_REPLACE",
"REGEXP_SUBSTR",
"RADIANS",
"RAND",
"RELEASE_ALL_LOCKS",
"RELEASE_LOCK",
"REPLACE_ORACLE",
"REVERSE",
"ROUND",
"RPAD",
"RPAD_ORACLE",
"RTRIM",
"RTRIM_ORACLE",
"SEC_TO_TIME",
"SHA",
"SHA1",
"SHA2",
"SIGN",
"SIN",
"SLEEP",
"SOUNDEX",
"SPACE",
"SQRT",
"STRCMP",
"STR_TO_DATE",
"SUBSTR_ORACLE",
"SUBSTRING_INDEX",
"SUBTIME",
"SYS_GUID",
"TAN",
"TIMEDIFF",
"TIME_FORMAT",
"TIME_TO_SEC",
"TO_BASE64",
"TO_CHAR",
"TO_DAYS",
"TO_SECONDS",
"UCASE",
"UNCOMPRESS",
"UNCOMPRESSED_LENGTH",
"UNHEX",
"UNIX_TIMESTAMP",
"UPDATEXML",
"UPPER",
"UUID",
"UUID_SHORT",
"VERSION",
"WEEKDAY",
"WEEKOFYEAR",
"WSREP_LAST_WRITTEN_GTID",
"WSREP_LAST_SEEN_GTID",
"WSREP_SYNC_WAIT_UPTO_GTID",
"YEARWEEK",
// CASE expression shorthands
"COALESCE",
"NULLIF"
], hA = o(["SELECT [ALL | DISTINCT | DISTINCTROW]"]), HA = o([
// queries
"WITH [RECURSIVE]",
"FROM",
"WHERE",
"GROUP BY",
"HAVING",
"PARTITION BY",
"ORDER BY",
"LIMIT",
"OFFSET",
"FETCH {FIRST | NEXT}",
// Data manipulation
// - insert:
"INSERT [LOW_PRIORITY | DELAYED | HIGH_PRIORITY] [IGNORE] [INTO]",
"REPLACE [LOW_PRIORITY | DELAYED] [INTO]",
"VALUES",
"ON DUPLICATE KEY UPDATE",
// - update:
"SET",
// other
"RETURNING"
]), be = o([
"CREATE [OR REPLACE] [TEMPORARY] TABLE [IF NOT EXISTS]"
]), WE = o([
// - create:
"CREATE [OR REPLACE] [SQL SECURITY DEFINER | SQL SECURITY INVOKER] VIEW [IF NOT EXISTS]",
// - update:
"UPDATE [LOW_PRIORITY] [IGNORE]",
// - delete:
"DELETE [LOW_PRIORITY] [QUICK] [IGNORE] FROM",
// - drop table:
"DROP [TEMPORARY] TABLE [IF EXISTS]",
// - alter table:
"ALTER [ONLINE] [IGNORE] TABLE [IF EXISTS]",
"ADD [COLUMN] [IF NOT EXISTS]",
"{CHANGE | MODIFY} [COLUMN] [IF EXISTS]",
"DROP [COLUMN] [IF EXISTS]",
"RENAME [TO]",
"RENAME COLUMN",
"ALTER [COLUMN]",
"{SET | DROP} DEFAULT",
"SET {VISIBLE | INVISIBLE}",
// - truncate:
"TRUNCATE [TABLE]",
// https://mariadb.com/docs/reference/mdb/sql-statements/
"ALTER DATABASE",
"ALTER DATABASE COMMENT",
"ALTER EVENT",
"ALTER FUNCTION",
"ALTER PROCEDURE",
"ALTER SCHEMA",
"ALTER SCHEMA COMMENT",
"ALTER SEQUENCE",
"ALTER SERVER",
"ALTER USER",
"ALTER VIEW",
"ANALYZE",
"ANALYZE TABLE",
"BACKUP LOCK",
"BACKUP STAGE",
"BACKUP UNLOCK",
"BEGIN",
"BINLOG",
"CACHE INDEX",
"CALL",
"CHANGE MASTER TO",
"CHECK TABLE",
"CHECK VIEW",
"CHECKSUM TABLE",
"COMMIT",
"CREATE AGGREGATE FUNCTION",
"CREATE DATABASE",
"CREATE EVENT",
"CREATE FUNCTION",
"CREATE INDEX",
"CREATE PROCEDURE",
"CREATE ROLE",
"CREATE SEQUENCE",
"CREATE SERVER",
"CREATE SPATIAL INDEX",
"CREATE TRIGGER",
"CREATE UNIQUE INDEX",
"CREATE USER",
"DEALLOCATE PREPARE",
"DESCRIBE",
"DROP DATABASE",
"DROP EVENT",
"DROP FUNCTION",
"DROP INDEX",
"DROP PREPARE",
"DROP PROCEDURE",
"DROP ROLE",
"DROP SEQUENCE",
"DROP SERVER",
"DROP TRIGGER",
"DROP USER",
"DROP VIEW",
"EXECUTE",
"EXPLAIN",
"FLUSH",
"GET DIAGNOSTICS",
"GET DIAGNOSTICS CONDITION",
"GRANT",
"HANDLER",
"HELP",
"INSTALL PLUGIN",
"INSTALL SONAME",
"KILL",
"LOAD DATA INFILE",
"LOAD INDEX INTO CACHE",
"LOAD XML INFILE",
"LOCK TABLE",
"OPTIMIZE TABLE",
"PREPARE",
"PURGE BINARY LOGS",
"PURGE MASTER LOGS",
"RELEASE SAVEPOINT",
"RENAME TABLE",
"RENAME USER",
"REPAIR TABLE",
"REPAIR VIEW",
"RESET MASTER",
"RESET QUERY CACHE",
"RESET REPLICA",
"RESET SLAVE",
"RESIGNAL",
"REVOKE",
"ROLLBACK",
"SAVEPOINT",
"SET CHARACTER SET",
"SET DEFAULT ROLE",
"SET GLOBAL TRANSACTION",
"SET NAMES",
"SET PASSWORD",
"SET ROLE",
"SET STATEMENT",
"SET TRANSACTION",
"SHOW",
"SHOW ALL REPLICAS STATUS",
"SHOW ALL SLAVES STATUS",
"SHOW AUTHORS",
"SHOW BINARY LOGS",
"SHOW BINLOG EVENTS",
"SHOW BINLOG STATUS",
"SHOW CHARACTER SET",
"SHOW CLIENT_STATISTICS",
"SHOW COLLATION",
"SHOW COLUMNS",
"SHOW CONTRIBUTORS",
"SHOW CREATE DATABASE",
"SHOW CREATE EVENT",
"SHOW CREATE FUNCTION",
"SHOW CREATE PACKAGE",
"SHOW CREATE PACKAGE BODY",
"SHOW CREATE PROCEDURE",
"SHOW CREATE SEQUENCE",
"SHOW CREATE TABLE",
"SHOW CREATE TRIGGER",
"SHOW CREATE USER",
"SHOW CREATE VIEW",
"SHOW DATABASES",
"SHOW ENGINE",
"SHOW ENGINE INNODB STATUS",
"SHOW ENGINES",
"SHOW ERRORS",
"SHOW EVENTS",
"SHOW EXPLAIN",
"SHOW FUNCTION CODE",
"SHOW FUNCTION STATUS",
"SHOW GRANTS",
"SHOW INDEX",
"SHOW INDEXES",
"SHOW INDEX_STATISTICS",
"SHOW KEYS",
"SHOW LOCALES",
"SHOW MASTER LOGS",
"SHOW MASTER STATUS",
"SHOW OPEN TABLES",
"SHOW PACKAGE BODY CODE",
"SHOW PACKAGE BODY STATUS",
"SHOW PACKAGE STATUS",
"SHOW PLUGINS",
"SHOW PLUGINS SONAME",
"SHOW PRIVILEGES",
"SHOW PROCEDURE CODE",
"SHOW PROCEDURE STATUS",
"SHOW PROCESSLIST",
"SHOW PROFILE",
"SHOW PROFILES",
"SHOW QUERY_RESPONSE_TIME",
"SHOW RELAYLOG EVENTS",
"SHOW REPLICA",
"SHOW REPLICA HOSTS",
"SHOW REPLICA STATUS",
"SHOW SCHEMAS",
"SHOW SLAVE",
"SHOW SLAVE HOSTS",
"SHOW SLAVE STATUS",
"SHOW STATUS",
"SHOW STORAGE ENGINES",
"SHOW TABLE STATUS",
"SHOW TABLES",
"SHOW TRIGGERS",
"SHOW USER_STATISTICS",
"SHOW VARIABLES",
"SHOW WARNINGS",
"SHOW WSREP_MEMBERSHIP",
"SHOW WSREP_STATUS",
"SHUTDOWN",
"SIGNAL",
"START ALL REPLICAS",
"START ALL SLAVES",
"START REPLICA",
"START SLAVE",
"START TRANSACTION",
"STOP ALL REPLICAS",
"STOP ALL SLAVES",
"STOP REPLICA",
"STOP SLAVE",
"UNINSTALL PLUGIN",
"UNINSTALL SONAME",
"UNLOCK TABLE",
"USE",
"XA BEGIN",
"XA COMMIT",
"XA END",
"XA PREPARE",
"XA RECOVER",
"XA ROLLBACK",
"XA START"
]), FA = o([
"UNION [ALL | DISTINCT]",
"EXCEPT [ALL | DISTINCT]",
"INTERSECT [ALL | DISTINCT]",
"MINUS [ALL | DISTINCT]"
]), YA = o([
"JOIN",
"{LEFT | RIGHT} [OUTER] JOIN",
"{INNER | CROSS} JOIN",
"NATURAL JOIN",
"NATURAL {LEFT | RIGHT} [OUTER] JOIN",
// non-standard joins
"STRAIGHT_JOIN"
]), VA = o([
"ON {UPDATE | DELETE} [SET NULL | SET DEFAULT]",
"CHARACTER SET",
"{ROWS | RANGE} BETWEEN",
"IDENTIFIED BY"
]), bA = o([]), gA = {
name: "mariadb",
tokenizerOptions: {
reservedSelect: hA,
reservedClauses: [...HA, ...be, ...WE],
reservedSetOperations: FA,
reservedJoins: YA,
reservedKeywordPhrases: VA,
reservedDataTypePhrases: bA,
supportsXor: !0,
reservedKeywords: pA,
reservedDataTypes: fA,
reservedFunctionNames: BA,
// TODO: support _ char set prefixes such as _utf8, _latin1, _binary, _utf8mb4, etc.
stringTypes: [
'""-qq-bs',
"''-qq-bs",
{ quote: "''-raw", prefixes: ["B", "X"], requirePrefix: !0 }
],
identTypes: ["``"],
identChars: { first: "$", rest: "$", allowFirstCharNumber: !0 },
variableTypes: [
{ regex: "@@?[A-Za-z0-9_.$]+" },
{ quote: '""-qq-bs', prefixes: ["@"], requirePrefix: !0 },
{ quote: "''-qq-bs", prefixes: ["@"], requirePrefix: !0 },
{ quote: "``", prefixes: ["@"], requirePrefix: !0 }
],
paramTypes: { positional: !0 },
lineCommentTypes: ["--", "#"],
operators: [
"%",
":=",
"&",
"|",
"^",
"~",
"<<",
">>",
"<=>",
"&&",
"||",
"!",
"*.*"
// Not actually an operator
],
postProcess: ME
},
formatOptions: {
onelineClauses: [...be, ...WE],
tabularOnelineClauses: WE
}
}, WA = [
// https://dev.mysql.com/doc/refman/8.0/en/keywords.html
"ACCESSIBLE",
"ADD",
"ALL",
"ALTER",
"ANALYZE",
"AND",
"AS",
"ASC",
"ASENSITIVE",
"BEFORE",
"BETWEEN",
"BOTH",
"BY",
"CALL",
"CASCADE",
"CASE",
"CHANGE",
"CHECK",
"COLLATE",
"COLUMN",
"CONDITION",
"CONSTRAINT",
"CONTINUE",
"CONVERT",
"CREATE",
"CROSS",
"CUBE",
"CUME_DIST",
"CURRENT_DATE",
"CURRENT_TIME",
"CURRENT_TIMESTAMP",
"CURRENT_USER",
"CURSOR",
"DATABASE",
"DATABASES",
"DAY_HOUR",
"DAY_MICROSECOND",
"DAY_MINUTE",
"DAY_SECOND",
"DECLARE",
"DEFAULT",
"DELAYED",
"DELETE",
"DENSE_RANK",
"DESC",
"DESCRIBE",
"DETERMINISTIC",
"DISTINCT",
"DISTINCTROW",
"DIV",
"DROP",
"DUAL",
"EACH",
"ELSE",
"ELSEIF",
"EMPTY",
"ENCLOSED",
"ESCAPED",
"EXCEPT",
"EXISTS",
"EXIT",
"EXPLAIN",
"FALSE",
"FETCH",
"FIRST_VALUE",
"FOR",
"FORCE",
"FOREIGN",
"FROM",
"FULLTEXT",
"FUNCTION",
"GENERATED",
"GET",
"GRANT",
"GROUP",
"GROUPING",
"GROUPS",
"HAVING",
"HIGH_PRIORITY",
"HOUR_MICROSECOND",
"HOUR_MINUTE",
"HOUR_SECOND",
"IF",
"IGNORE",
"IN",
"INDEX",
"INFILE",
"INNER",
"INOUT",
"INSENSITIVE",
"INSERT",
"IN",
"INTERSECT",
"INTERVAL",
"INTO",
"IO_AFTER_GTIDS",
"IO_BEFORE_GTIDS",
"IS",
"ITERATE",
"JOIN",
"JSON_TABLE",
"KEY",
"KEYS",
"KILL",
"LAG",
"LAST_VALUE",
"LATERAL",
"LEAD",
"LEADING",
"LEAVE",
"LEFT",
"LIKE",
"LIMIT",
"LINEAR",
"LINES",
"LOAD",
"LOCALTIME",
"LOCALTIMESTAMP",
"LOCK",
"LONG",
"LOOP",
"LOW_PRIORITY",
"MASTER_BIND",
"MASTER_SSL_VERIFY_SERVER_CERT",
"MATCH",
"MAXVALUE",
"MINUTE_MICROSECOND",
"MINUTE_SECOND",
"MOD",
"MODIFIES",
"NATURAL",
"NOT",
"NO_WRITE_TO_BINLOG",
"NTH_VALUE",
"NTILE",
"NULL",
"OF",
"ON",
"OPTIMIZE",
"OPTIMIZER_COSTS",
"OPTION",
"OPTIONALLY",
"OR",
"ORDER",
"OUT",
"OUTER",
"OUTFILE",
"OVER",
"PARTITION",
"PERCENT_RANK",
"PRIMARY",
"PROCEDURE",
"PURGE",
"RANGE",
"RANK",
"READ",
"READS",
"READ_WRITE",
"RECURSIVE",
"REFERENCES",
"REGEXP",
"RELEASE",
"RENAME",
"REPEAT",
"REPLACE",
"REQUIRE",
"RESIGNAL",
"RESTRICT",
"RETURN",
"REVOKE",
"RIGHT",
"RLIKE",
"ROW",
"ROWS",
"ROW_NUMBER",
"SCHEMA",
"SCHEMAS",
"SECOND_MICROSECOND",
"SELECT",
"SENSITIVE",
"SEPARATOR",
"SET",
"SHOW",
"SIGNAL",
"SPATIAL",
"SPECIFIC",
"SQL",
"SQLEXCEPTION",
"SQLSTATE",
"SQLWARNING",
"SQL_BIG_RESULT",
"SQL_CALC_FOUND_ROWS",
"SQL_SMALL_RESULT",
"SSL",
"STARTING",
"STORED",
"STRAIGHT_JOIN",
"SYSTEM",
"TABLE",
"TERMINATED",
"THEN",
"TO",
"TRAILING",
"TRIGGER",
"TRUE",
"UNDO",
"UNION",
"UNIQUE",
"UNLOCK",
"UNSIGNED",
"UPDATE",
"USAGE",
"USE",
"USING",
"UTC_DATE",
"UTC_TIME",
"UTC_TIMESTAMP",
"VALUES",
"VIRTUAL",
"WHEN",
"WHERE",
"WHILE",
"WINDOW",
"WITH",
"WRITE",
"XOR",
"YEAR_MONTH",
"ZEROFILL"
// (R)
], yA = [
// https://dev.mysql.com/doc/refman/8.0/en/data-types.html
"BIGINT",
"BINARY",
"BIT",
"BLOB",
"BOOL",
"BOOLEAN",
"CHAR",
"CHARACTER",
"DATE",
"DATETIME",
"DEC",
"DECIMAL",
"DOUBLE PRECISION",
"DOUBLE",
"ENUM",
"FIXED",
"FLOAT",
"FLOAT4",
"FLOAT8",
"INT",
"INT1",
"INT2",
"INT3",
"INT4",
"INT8",
"INTEGER",
"LONGBLOB",
"LONGTEXT",
"MEDIUMBLOB",
"MEDIUMINT",
"MEDIUMTEXT",
"MIDDLEINT",
"NATIONAL CHAR",
"NATIONAL VARCHAR",
"NUMERIC",
"PRECISION",
"REAL",
"SMALLINT",
"TEXT",
"TIME",
"TIMESTAMP",
"TINYBLOB",
"TINYINT",
"TINYTEXT",
"VARBINARY",
"VARCHAR",
"VARCHARACTER",
"VARYING",
"YEAR"
// 'SET' // handled as special-case in postProcess
], XA = [
// https://dev.mysql.com/doc/refman/8.0/en/built-in-function-reference.html
"ABS",
"ACOS",
"ADDDATE",
"ADDTIME",
"AES_DECRYPT",
"AES_ENCRYPT",
// 'AND',
"ANY_VALUE",
"ASCII",
"ASIN",
"ATAN",
"ATAN2",
"AVG",
"BENCHMARK",
"BIN",
"BIN_TO_UUID",
"BINARY",
"BIT_AND",
"BIT_COUNT",
"BIT_LENGTH",
"BIT_OR",
"BIT_XOR",
"CAN_ACCESS_COLUMN",
"CAN_ACCESS_DATABASE",
"CAN_ACCESS_TABLE",
"CAN_ACCESS_USER",
"CAN_ACCESS_VIEW",
"CAST",
"CEIL",
"CEILING",
"CHAR",
"CHAR_LENGTH",
"CHARACTER_LENGTH",
"CHARSET",
"COALESCE",
"COERCIBILITY",
"COLLATION",
"COMPRESS",
"CONCAT",
"CONCAT_WS",
"CONNECTION_ID",
"CONV",
"CONVERT",
"CONVERT_TZ",
"COS",
"COT",
"COUNT",
"CRC32",
"CUME_DIST",
"CURDATE",
"CURRENT_DATE",
"CURRENT_ROLE",
"CURRENT_TIME",
"CURRENT_TIMESTAMP",
"CURRENT_USER",
"CURTIME",
"DATABASE",
"DATE",
"DATE_ADD",
"DATE_FORMAT",
"DATE_SUB",
"DATEDIFF",
"DAY",
"DAYNAME",
"DAYOFMONTH",
"DAYOFWEEK",
"DAYOFYEAR",
"DEFAULT",
"DEGREES",
"DENSE_RANK",
"DIV",
"ELT",
"EXP",
"EXPORT_SET",
"EXTRACT",
"EXTRACTVALUE",
"FIELD",
"FIND_IN_SET",
"FIRST_VALUE",
"FLOOR",
"FORMAT",
"FORMAT_BYTES",
"FORMAT_PICO_TIME",
"FOUND_ROWS",
"FROM_BASE64",
"FROM_DAYS",
"FROM_UNIXTIME",
"GEOMCOLLECTION",
"GEOMETRYCOLLECTION",
"GET_DD_COLUMN_PRIVILEGES",
"GET_DD_CREATE_OPTIONS",
"GET_DD_INDEX_SUB_PART_LENGTH",
"GET_FORMAT",
"GET_LOCK",
"GREATEST",
"GROUP_CONCAT",
"GROUPING",
"GTID_SUBSET",
"GTID_SUBTRACT",
"HEX",
"HOUR",
"ICU_VERSION",
"IF",
"IFNULL",
// 'IN',
"INET_ATON",
"INET_NTOA",
"INET6_ATON",
"INET6_NTOA",
"INSERT",
"INSTR",
"INTERNAL_AUTO_INCREMENT",
"INTERNAL_AVG_ROW_LENGTH",
"INTERNAL_CHECK_TIME",
"INTERNAL_CHECKSUM",
"INTERNAL_DATA_FREE",
"INTERNAL_DATA_LENGTH",
"INTERNAL_DD_CHAR_LENGTH",
"INTERNAL_GET_COMMENT_OR_ERROR",
"INTERNAL_GET_ENABLED_ROLE_JSON",
"INTERNAL_GET_HOSTNAME",
"INTERNAL_GET_USERNAME",
"INTERNAL_GET_VIEW_WARNING_OR_ERROR",
"INTERNAL_INDEX_COLUMN_CARDINALITY",
"INTERNAL_INDEX_LENGTH",
"INTERNAL_IS_ENABLED_ROLE",
"INTERNAL_IS_MANDATORY_ROLE",
"INTERNAL_KEYS_DISABLED",
"INTERNAL_MAX_DATA_LENGTH",
"INTERNAL_TABLE_ROWS",
"INTERNAL_UPDATE_TIME",
"INTERVAL",
"IS",
"IS_FREE_LOCK",
"IS_IPV4",
"IS_IPV4_COMPAT",
"IS_IPV4_MAPPED",
"IS_IPV6",
"IS NOT",
"IS NOT NULL",
"IS NULL",
"IS_USED_LOCK",
"IS_UUID",
"ISNULL",
"JSON_ARRAY",
"JSON_ARRAY_APPEND",
"JSON_ARRAY_INSERT",
"JSON_ARRAYAGG",
"JSON_CONTAINS",
"JSON_CONTAINS_PATH",
"JSON_DEPTH",
"JSON_EXTRACT",
"JSON_INSERT",
"JSON_KEYS",
"JSON_LENGTH",
"JSON_MERGE",
"JSON_MERGE_PATCH",
"JSON_MERGE_PRESERVE",
"JSON_OBJECT",
"JSON_OBJECTAGG",
"JSON_OVERLAPS",
"JSON_PRETTY",
"JSON_QUOTE",
"JSON_REMOVE",
"JSON_REPLACE",
"JSON_SCHEMA_VALID",
"JSON_SCHEMA_VALIDATION_REPORT",
"JSON_SEARCH",
"JSON_SET",
"JSON_STORAGE_FREE",
"JSON_STORAGE_SIZE",
"JSON_TABLE",
"JSON_TYPE",
"JSON_UNQUOTE",
"JSON_VALID",
"JSON_VALUE",
"LAG",
"LAST_DAY",
"LAST_INSERT_ID",
"LAST_VALUE",
"LCASE",
"LEAD",
"LEAST",
"LEFT",
"LENGTH",
"LIKE",
"LINESTRING",
"LN",
"LOAD_FILE",
"LOCALTIME",
"LOCALTIMESTAMP",
"LOCATE",
"LOG",
"LOG10",
"LOG2",
"LOWER",
"LPAD",
"LTRIM",
"MAKE_SET",
"MAKEDATE",
"MAKETIME",
"MASTER_POS_WAIT",
"MATCH",
"MAX",
"MBRCONTAINS",
"MBRCOVEREDBY",
"MBRCOVERS",
"MBRDISJOINT",
"MBREQUALS",
"MBRINTERSECTS",
"MBROVERLAPS",
"MBRTOUCHES",
"MBRWITHIN",
"MD5",
"MEMBER OF",
"MICROSECOND",
"MID",
"MIN",
"MINUTE",
"MOD",
"MONTH",
"MONTHNAME",
"MULTILINESTRING",
"MULTIPOINT",
"MULTIPOLYGON",
"NAME_CONST",
"NOT",
"NOT IN",
"NOT LIKE",
"NOT REGEXP",
"NOW",
"NTH_VALUE",
"NTILE",
"NULLIF",
"OCT",
"OCTET_LENGTH",
// 'OR',
"ORD",
"PERCENT_RANK",
"PERIOD_ADD",
"PERIOD_DIFF",
"PI",
"POINT",
"POLYGON",
"POSITION",
"POW",
"POWER",
"PS_CURRENT_THREAD_ID",
"PS_THREAD_ID",
"QUARTER",
"QUOTE",
"RADIANS",
"RAND",
"RANDOM_BYTES",
"RANK",
"REGEXP",
"REGEXP_INSTR",
"REGEXP_LIKE",
"REGEXP_REPLACE",
"REGEXP_SUBSTR",
"RELEASE_ALL_LOCKS",
"RELEASE_LOCK",
"REPEAT",
"REPLACE",
"REVERSE",
"RIGHT",
"RLIKE",
"ROLES_GRAPHML",
"ROUND",
"ROW_COUNT",
"ROW_NUMBER",
"RPAD",
"RTRIM",
"SCHEMA",
"SEC_TO_TIME",
"SECOND",
"SESSION_USER",
"SHA1",
"SHA2",
"SIGN",
"SIN",
"SLEEP",
"SOUNDEX",
"SOUNDS LIKE",
"SOURCE_POS_WAIT",
"SPACE",
"SQRT",
"ST_AREA",
"ST_ASBINARY",
"ST_ASGEOJSON",
"ST_ASTEXT",
"ST_BUFFER",
"ST_BUFFER_STRATEGY",
"ST_CENTROID",
"ST_COLLECT",
"ST_CONTAINS",
"ST_CONVEXHULL",
"ST_CROSSES",
"ST_DIFFERENCE",
"ST_DIMENSION",
"ST_DISJOINT",
"ST_DISTANCE",
"ST_DISTANCE_SPHERE",
"ST_ENDPOINT",
"ST_ENVELOPE",
"ST_EQUALS",
"ST_EXTERIORRING",
"ST_FRECHETDISTANCE",
"ST_GEOHASH",
"ST_GEOMCOLLFROMTEXT",
"ST_GEOMCOLLFROMWKB",
"ST_GEOMETRYN",
"ST_GEOMETRYTYPE",
"ST_GEOMFROMGEOJSON",
"ST_GEOMFROMTEXT",
"ST_GEOMFROMWKB",
"ST_HAUSDORFFDISTANCE",
"ST_INTERIORRINGN",
"ST_INTERSECTION",
"ST_INTERSECTS",
"ST_ISCLOSED",
"ST_ISEMPTY",
"ST_ISSIMPLE",
"ST_ISVALID",
"ST_LATFROMGEOHASH",
"ST_LATITUDE",
"ST_LENGTH",
"ST_LINEFROMTEXT",
"ST_LINEFROMWKB",
"ST_LINEINTERPOLATEPOINT",
"ST_LINEINTERPOLATEPOINTS",
"ST_LONGFROMGEOHASH",
"ST_LONGITUDE",
"ST_MAKEENVELOPE",
"ST_MLINEFROMTEXT",
"ST_MLINEFROMWKB",
"ST_MPOINTFROMTEXT",
"ST_MPOINTFROMWKB",
"ST_MPOLYFROMTEXT",
"ST_MPOLYFROMWKB",
"ST_NUMGEOMETRIES",
"ST_NUMINTERIORRING",
"ST_NUMPOINTS",
"ST_OVERLAPS",
"ST_POINTATDISTANCE",
"ST_POINTFROMGEOHASH",
"ST_POINTFROMTEXT",
"ST_POINTFROMWKB",
"ST_POINTN",
"ST_POLYFROMTEXT",
"ST_POLYFROMWKB",
"ST_SIMPLIFY",
"ST_SRID",
"ST_STARTPOINT",
"ST_SWAPXY",
"ST_SYMDIFFERENCE",
"ST_TOUCHES",
"ST_TRANSFORM",
"ST_UNION",
"ST_VALIDATE",
"ST_WITHIN",
"ST_X",
"ST_Y",
"STATEMENT_DIGEST",
"STATEMENT_DIGEST_TEXT",
"STD",
"STDDEV",
"STDDEV_POP",
"STDDEV_SAMP",
"STR_TO_DATE",
"STRCMP",
"SUBDATE",
"SUBSTR",
"SUBSTRING",
"SUBSTRING_INDEX",
"SUBTIME",
"SUM",
"SYSDATE",
"SYSTEM_USER",
"TAN",
"TIME",
"TIME_FORMAT",
"TIME_TO_SEC",
"TIMEDIFF",
"TIMESTAMP",
"TIMESTAMPADD",
"TIMESTAMPDIFF",
"TO_BASE64",
"TO_DAYS",
"TO_SECONDS",
"TRIM",
"TRUNCATE",
"UCASE",
"UNCOMPRESS",
"UNCOMPRESSED_LENGTH",
"UNHEX",
"UNIX_TIMESTAMP",
"UPDATEXML",
"UPPER",
// 'USER',
"UTC_DATE",
"UTC_TIME",
"UTC_TIMESTAMP",
"UUID",
"UUID_SHORT",
"UUID_TO_BIN",
"VALIDATE_PASSWORD_STRENGTH",
"VALUES",
"VAR_POP",
"VAR_SAMP",
"VARIANCE",
"VERSION",
"WAIT_FOR_EXECUTED_GTID_SET",
"WAIT_UNTIL_SQL_THREAD_AFTER_GTIDS",
"WEEK",
"WEEKDAY",
"WEEKOFYEAR",
"WEIGHT_STRING",
// 'XOR',
"YEAR",
"YEARWEEK"
], $A = o(["SELECT [ALL | DISTINCT | DISTINCTROW]"]), KA = o([
// queries
"WITH [RECURSIVE]",
"FROM",
"WHERE",
"GROUP BY",
"HAVING",
"WINDOW",
"PARTITION BY",
"ORDER BY",
"LIMIT",
"OFFSET",
// Data manipulation
// - insert:
"INSERT [LOW_PRIORITY | DELAYED | HIGH_PRIORITY] [IGNORE] [INTO]",
"REPLACE [LOW_PRIORITY | DELAYED] [INTO]",
"VALUES",
"ON DUPLICATE KEY UPDATE",
// - update:
"SET"
]), ge = o(["CREATE [TEMPORARY] TABLE [IF NOT EXISTS]"]), yE = o([
// - create:
"CREATE [OR REPLACE] [SQL SECURITY DEFINER | SQL SECURITY INVOKER] VIEW [IF NOT EXISTS]",
// - update:
"UPDATE [LOW_PRIORITY] [IGNORE]",
// - delete:
"DELETE [LOW_PRIORITY] [QUICK] [IGNORE] FROM",
// - drop table:
"DROP [TEMPORARY] TABLE [IF EXISTS]",
// - alter table:
"ALTER TABLE",
"ADD [COLUMN]",
"{CHANGE | MODIFY} [COLUMN]",
"DROP [COLUMN]",
"RENAME [TO | AS]",
"RENAME COLUMN",
"ALTER [COLUMN]",
"{SET | DROP} DEFAULT",
// - truncate:
"TRUNCATE [TABLE]",
// https://dev.mysql.com/doc/refman/8.0/en/sql-statements.html
"ALTER DATABASE",
"ALTER EVENT",
"ALTER FUNCTION",
"ALTER INSTANCE",
"ALTER LOGFILE GROUP",
"ALTER PROCEDURE",
"ALTER RESOURCE GROUP",
"ALTER SERVER",
"ALTER TABLESPACE",
"ALTER USER",
"ALTER VIEW",
"ANALYZE TABLE",
"BINLOG",
"CACHE INDEX",
"CALL",
"CHANGE MASTER TO",
"CHANGE REPLICATION FILTER",
"CHANGE REPLICATION SOURCE TO",
"CHECK TABLE",
"CHECKSUM TABLE",
"CLONE",
"COMMIT",
"CREATE DATABASE",
"CREATE EVENT",
"CREATE FUNCTION",
"CREATE FUNCTION",
"CREATE INDEX",
"CREATE LOGFILE GROUP",
"CREATE PROCEDURE",
"CREATE RESOURCE GROUP",
"CREATE ROLE",
"CREATE SERVER",
"CREATE SPATIAL REFERENCE SYSTEM",
"CREATE TABLESPACE",
"CREATE TRIGGER",
"CREATE USER",
"DEALLOCATE PREPARE",
"DESCRIBE",
"DROP DATABASE",
"DROP EVENT",
"DROP FUNCTION",
"DROP FUNCTION",
"DROP INDEX",
"DROP LOGFILE GROUP",
"DROP PROCEDURE",
"DROP RESOURCE GROUP",
"DROP ROLE",
"DROP SERVER",
"DROP SPATIAL REFERENCE SYSTEM",
"DROP TABLESPACE",
"DROP TRIGGER",
"DROP USER",
"DROP VIEW",
"EXECUTE",
"EXPLAIN",
"FLUSH",
"GRANT",
"HANDLER",
"HELP",
"IMPORT TABLE",
"INSTALL COMPONENT",
"INSTALL PLUGIN",
"KILL",
"LOAD DATA",
"LOAD INDEX INTO CACHE",
"LOAD XML",
"LOCK INSTANCE FOR BACKUP",
"LOCK TABLES",
"MASTER_POS_WAIT",
"OPTIMIZE TABLE",
"PREPARE",
"PURGE BINARY LOGS",
"RELEASE SAVEPOINT",
"RENAME TABLE",
"RENAME USER",
"REPAIR TABLE",
"RESET",
"RESET MASTER",
"RESET PERSIST",
"RESET REPLICA",
"RESET SLAVE",
"RESTART",
"REVOKE",
"ROLLBACK",
"ROLLBACK TO SAVEPOINT",
"SAVEPOINT",
"SET CHARACTER SET",
"SET DEFAULT ROLE",
"SET NAMES",
"SET PASSWORD",
"SET RESOURCE GROUP",
"SET ROLE",
"SET TRANSACTION",
"SHOW",
"SHOW BINARY LOGS",
"SHOW BINLOG EVENTS",
"SHOW CHARACTER SET",
"SHOW COLLATION",
"SHOW COLUMNS",
"SHOW CREATE DATABASE",
"SHOW CREATE EVENT",
"SHOW CREATE FUNCTION",
"SHOW CREATE PROCEDURE",
"SHOW CREATE TABLE",
"SHOW CREATE TRIGGER",
"SHOW CREATE USER",
"SHOW CREATE VIEW",
"SHOW DATABASES",
"SHOW ENGINE",
"SHOW ENGINES",
"SHOW ERRORS",
"SHOW EVENTS",
"SHOW FUNCTION CODE",
"SHOW FUNCTION STATUS",
"SHOW GRANTS",
"SHOW INDEX",
"SHOW MASTER STATUS",
"SHOW OPEN TABLES",
"SHOW PLUGINS",
"SHOW PRIVILEGES",
"SHOW PROCEDURE CODE",
"SHOW PROCEDURE STATUS",
"SHOW PROCESSLIST",
"SHOW PROFILE",
"SHOW PROFILES",
"SHOW RELAYLOG EVENTS",
"SHOW REPLICA STATUS",
"SHOW REPLICAS",
"SHOW SLAVE",
"SHOW SLAVE HOSTS",
"SHOW STATUS",
"SHOW TABLE STATUS",
"SHOW TABLES",
"SHOW TRIGGERS",
"SHOW VARIABLES",
"SHOW WARNINGS",
"SHUTDOWN",
"SOURCE_POS_WAIT",
"START GROUP_REPLICATION",
"START REPLICA",
"START SLAVE",
"START TRANSACTION",
"STOP GROUP_REPLICATION",
"STOP REPLICA",
"STOP SLAVE",
"TABLE",
"UNINSTALL COMPONENT",
"UNINSTALL PLUGIN",
"UNLOCK INSTANCE",
"UNLOCK TABLES",
"USE",
"XA",
// flow control
// 'IF',
"ITERATE",
"LEAVE",
"LOOP",
"REPEAT",
"RETURN",
"WHILE"
]), wA = o(["UNION [ALL | DISTINCT]"]), JA = o([
"JOIN",
"{LEFT | RIGHT} [OUTER] JOIN",
"{INNER | CROSS} JOIN",
"NATURAL [INNER] JOIN",
"NATURAL {LEFT | RIGHT} [OUTER] JOIN",
// non-standard joins
"STRAIGHT_JOIN"
]), vA = o([
"ON {UPDATE | DELETE} [SET NULL]",
"CHARACTER SET",
"{ROWS | RANGE} BETWEEN",
"IDENTIFIED BY"
]), xA = o([]), QA = {
name: "mysql",
tokenizerOptions: {
reservedSelect: $A,
reservedClauses: [...KA, ...ge, ...yE],
reservedSetOperations: wA,
reservedJoins: JA,
reservedKeywordPhrases: vA,
reservedDataTypePhrases: xA,
supportsXor: !0,
reservedKeywords: WA,
reservedDataTypes: yA,
reservedFunctionNames: XA,
// TODO: support _ char set prefixes such as _utf8, _latin1, _binary, _utf8mb4, etc.
stringTypes: [
'""-qq-bs',
{ quote: "''-qq-bs", prefixes: ["N"] },
{ quote: "''-raw", prefixes: ["B", "X"], requirePrefix: !0 }
],
identTypes: ["``"],
identChars: { first: "$", rest: "$", allowFirstCharNumber: !0 },
variableTypes: [
{ regex: "@@?[A-Za-z0-9_.$]+" },
{ quote: '""-qq-bs', prefixes: ["@"], requirePrefix: !0 },
{ quote: "''-qq-bs", prefixes: ["@"], requirePrefix: !0 },
{ quote: "``", prefixes: ["@"], requirePrefix: !0 }
],
paramTypes: { positional: !0 },
lineCommentTypes: ["--", "#"],
operators: [
"%",
":=",
"&",
"|",
"^",
"~",
"<<",
">>",
"<=>",
"->",
"->>",
"&&",
"||",
"!",
"*.*"
// Not actually an operator
],
postProcess: ME
},
formatOptions: {
onelineClauses: [...ge, ...yE],
tabularOnelineClauses: yE
}
}, ZA = [
// https://docs.pingcap.com/tidb/stable/keywords
"ADD",
"ALL",
"ALTER",
"ANALYZE",
"AND",
"ARRAY",
"AS",
"ASC",
"BETWEEN",
"BOTH",
"BY",
"CALL",
"CASCADE",
"CASE",
"CHANGE",
"CHECK",
"COLLATE",
"COLUMN",
"CONSTRAINT",
"CONTINUE",
"CONVERT",
"CREATE",
"CROSS",
"CURRENT_DATE",
"CURRENT_ROLE",
"CURRENT_TIME",
"CURRENT_TIMESTAMP",
"CURRENT_USER",
"CURSOR",
"DATABASE",
"DATABASES",
"DAY_HOUR",
"DAY_MICROSECOND",
"DAY_MINUTE",
"DAY_SECOND",
"DEFAULT",
"DELAYED",
"DELETE",
"DESC",
"DESCRIBE",
"DISTINCT",
"DISTINCTROW",
"DIV",
"DOUBLE",
"DROP",
"DUAL",
"ELSE",
"ELSEIF",
"ENCLOSED",
"ESCAPED",
"EXCEPT",
"EXISTS",
"EXIT",
"EXPLAIN",
"FALSE",
"FETCH",
"FOR",
"FORCE",
"FOREIGN",
"FROM",
"FULLTEXT",
"GENERATED",
"GRANT",
"GROUP",
"GROUPS",
"HAVING",
"HIGH_PRIORITY",
"HOUR_MICROSECOND",
"HOUR_MINUTE",
"HOUR_SECOND",
"IF",
"IGNORE",
"ILIKE",
"IN",
"INDEX",
"INFILE",
"INNER",
"INOUT",
"INSERT",
"INTERSECT",
"INTERVAL",
"INTO",
"IS",
"ITERATE",
"JOIN",
"KEY",
"KEYS",
"KILL",
"LEADING",
"LEAVE",
"LEFT",
"LIKE",
"LIMIT",
"LINEAR",
"LINES",
"LOAD",
"LOCALTIME",
"LOCALTIMESTAMP",
"LOCK",
"LONG",
"LOW_PRIORITY",
"MATCH",
"MAXVALUE",
"MINUTE_MICROSECOND",
"MINUTE_SECOND",
"MOD",
"NATURAL",
"NOT",
"NO_WRITE_TO_BINLOG",
"NULL",
"OF",
"ON",
"OPTIMIZE",
"OPTION",
"OPTIONALLY",
"OR",
"ORDER",
"OUT",
"OUTER",
"OUTFILE",
"OVER",
"PARTITION",
"PRIMARY",
"PROCEDURE",
"RANGE",
"READ",
"RECURSIVE",
"REFERENCES",
"REGEXP",
"RELEASE",
"RENAME",
"REPEAT",
"REPLACE",
"REQUIRE",
"RESTRICT",
"REVOKE",
"RIGHT",
"RLIKE",
"ROW",
"ROWS",
"SECOND_MICROSECOND",
"SELECT",
"SET",
"SHOW",
"SPATIAL",
"SQL",
"SQLEXCEPTION",
"SQLSTATE",
"SQLWARNING",
"SQL_BIG_RESULT",
"SQL_CALC_FOUND_ROWS",
"SQL_SMALL_RESULT",
"SSL",
"STARTING",
"STATS_EXTENDED",
"STORED",
"STRAIGHT_JOIN",
"TABLE",
"TABLESAMPLE",
"TERMINATED",
"THEN",
"TO",
"TRAILING",
"TRIGGER",
"TRUE",
"TiDB_CURRENT_TSO",
"UNION",
"UNIQUE",
"UNLOCK",
"UNSIGNED",
"UNTIL",
"UPDATE",
"USAGE",
"USE",
"USING",
"UTC_DATE",
"UTC_TIME",
"UTC_TIMESTAMP",
"VALUES",
"VIRTUAL",
"WHEN",
"WHERE",
"WHILE",
"WINDOW",
"WITH",
"WRITE",
"XOR",
"YEAR_MONTH",
"ZEROFILL"
// (R)
], jA = [
// https://docs.pingcap.com/tidb/stable/data-type-overview
"BIGINT",
"BINARY",
"BIT",
"BLOB",
"BOOL",
"BOOLEAN",
"CHAR",
"CHARACTER",
"DATE",
"DATETIME",
"DEC",
"DECIMAL",
"DOUBLE PRECISION",
"DOUBLE",
"ENUM",
"FIXED",
"INT",
"INT1",
"INT2",
"INT3",
"INT4",
"INT8",
"INTEGER",
"LONGBLOB",
"LONGTEXT",
"MEDIUMBLOB",
"MEDIUMINT",
"MIDDLEINT",
"NATIONAL CHAR",
"NATIONAL VARCHAR",
"NUMERIC",
"PRECISION",
"SMALLINT",
"TEXT",
"TIME",
"TIMESTAMP",
"TINYBLOB",
"TINYINT",
"TINYTEXT",
"VARBINARY",
"VARCHAR",
"VARCHARACTER",
"VARYING",
"YEAR"
// 'SET' // handled as special-case in postProcess
], qA = [
// https://docs.pingcap.com/tidb/stable/sql-statement-show-builtins
// https://docs.pingcap.com/tidb/stable/functions-and-operators-overview
// + MySQL aggregate functions: https://dev.mysql.com/doc/refman/8.0/en/aggregate-functions.html
// + MySQL window functions: https://dev.mysql.com/doc/refman/8.0/en/window-functions-usage.html
"ABS",
"ACOS",
"ADDDATE",
"ADDTIME",
"AES_DECRYPT",
"AES_ENCRYPT",
// 'AND',
"ANY_VALUE",
"ASCII",
"ASIN",
"ATAN",
"ATAN2",
"AVG",
"BENCHMARK",
"BIN",
"BIN_TO_UUID",
"BIT_AND",
"BIT_COUNT",
"BIT_LENGTH",
"BIT_OR",
"BIT_XOR",
"BITAND",
"BITNEG",
"BITOR",
"BITXOR",
"CASE",
"CAST",
"CEIL",
"CEILING",
"CHAR_FUNC",
"CHAR_LENGTH",
"CHARACTER_LENGTH",
"CHARSET",
"COALESCE",
"COERCIBILITY",
"COLLATION",
"COMPRESS",
"CONCAT",
"CONCAT_WS",
"CONNECTION_ID",
"CONV",
"CONVERT",
"CONVERT_TZ",
"COS",
"COT",
"COUNT",
"CRC32",
"CUME_DIST",
"CURDATE",
"CURRENT_DATE",
"CURRENT_RESOURCE_GROUP",
"CURRENT_ROLE",
"CURRENT_TIME",
"CURRENT_TIMESTAMP",
"CURRENT_USER",
"CURTIME",
"DATABASE",
"DATE",
"DATE_ADD",
"DATE_FORMAT",
"DATE_SUB",
"DATEDIFF",
"DAY",
"DAYNAME",
"DAYOFMONTH",
"DAYOFWEEK",
"DAYOFYEAR",
"DECODE",
"DEFAULT_FUNC",
"DEGREES",
"DENSE_RANK",
"DES_DECRYPT",
"DES_ENCRYPT",
"DIV",
"ELT",
"ENCODE",
"ENCRYPT",
"EQ",
"EXP",
"EXPORT_SET",
"EXTRACT",
"FIELD",
"FIND_IN_SET",
"FIRST_VALUE",
"FLOOR",
"FORMAT",
"FORMAT_BYTES",
"FORMAT_NANO_TIME",
"FOUND_ROWS",
"FROM_BASE64",
"FROM_DAYS",
"FROM_UNIXTIME",
"GE",
"GET_FORMAT",
"GET_LOCK",
"GETPARAM",
"GREATEST",
"GROUP_CONCAT",
"GROUPING",
"GT",
"HEX",
"HOUR",
"IF",
"IFNULL",
"ILIKE",
// 'IN',
"INET6_ATON",
"INET6_NTOA",
"INET_ATON",
"INET_NTOA",
"INSERT_FUNC",
"INSTR",
"INTDIV",
"INTERVAL",
"IS_FREE_LOCK",
"IS_IPV4",
"IS_IPV4_COMPAT",
"IS_IPV4_MAPPED",
"IS_IPV6",
"IS_USED_LOCK",
"IS_UUID",
"ISFALSE",
"ISNULL",
"ISTRUE",
"JSON_ARRAY",
"JSON_ARRAYAGG",
"JSON_ARRAY_APPEND",
"JSON_ARRAY_INSERT",
"JSON_CONTAINS",
"JSON_CONTAINS_PATH",
"JSON_DEPTH",
"JSON_EXTRACT",
"JSON_INSERT",
"JSON_KEYS",
"JSON_LENGTH",
"JSON_MEMBEROF",
"JSON_MERGE",
"JSON_MERGE_PATCH",
"JSON_MERGE_PRESERVE",
"JSON_OBJECT",
"JSON_OBJECTAGG",
"JSON_OVERLAPS",
"JSON_PRETTY",
"JSON_QUOTE",
"JSON_REMOVE",
"JSON_REPLACE",
"JSON_SEARCH",
"JSON_SET",
"JSON_STORAGE_FREE",
"JSON_STORAGE_SIZE",
"JSON_TYPE",
"JSON_UNQUOTE",
"JSON_VALID",
"LAG",
"LAST_DAY",
"LAST_INSERT_ID",
"LAST_VALUE",
"LASTVAL",
"LCASE",
"LE",
"LEAD",
"LEAST",
"LEFT",
"LEFTSHIFT",
"LENGTH",
"LIKE",
"LN",
"LOAD_FILE",
"LOCALTIME",
"LOCALTIMESTAMP",
"LOCATE",
"LOG",
"LOG10",
"LOG2",
"LOWER",
"LPAD",
"LT",
"LTRIM",
"MAKE_SET",
"MAKEDATE",
"MAKETIME",
"MASTER_POS_WAIT",
"MAX",
"MD5",
"MICROSECOND",
"MID",
"MIN",
"MINUS",
"MINUTE",
"MOD",
"MONTH",
"MONTHNAME",
"MUL",
"NAME_CONST",
"NE",
"NEXTVAL",
"NOT",
"NOW",
"NTH_VALUE",
"NTILE",
"NULLEQ",
"OCT",
"OCTET_LENGTH",
"OLD_PASSWORD",
// 'OR',
"ORD",
"PASSWORD_FUNC",
"PERCENT_RANK",
"PERIOD_ADD",
"PERIOD_DIFF",
"PI",
"PLUS",
"POSITION",
"POW",
"POWER",
"QUARTER",
"QUOTE",
"RADIANS",
"RAND",
"RANDOM_BYTES",
"RANK",
"REGEXP",
"REGEXP_INSTR",
"REGEXP_LIKE",
"REGEXP_REPLACE",
"REGEXP_SUBSTR",
"RELEASE_ALL_LOCKS",
"RELEASE_LOCK",
"REPEAT",
"REPLACE",
"REVERSE",
"RIGHT",
"RIGHTSHIFT",
"ROUND",
"ROW_COUNT",
"ROW_NUMBER",
"RPAD",
"RTRIM",
"SCHEMA",
"SEC_TO_TIME",
"SECOND",
"SESSION_USER",
"SETVAL",
"SETVAR",
"SHA",
"SHA1",
"SHA2",
"SIGN",
"SIN",
"SLEEP",
"SM3",
"SPACE",
"SQRT",
"STD",
"STDDEV",
"STDDEV_POP",
"STDDEV_SAMP",
"STR_TO_DATE",
"STRCMP",
"SUBDATE",
"SUBSTR",
"SUBSTRING",
"SUBSTRING_INDEX",
"SUBTIME",
"SUM",
"SYSDATE",
"SYSTEM_USER",
"TAN",
"TIDB_BOUNDED_STALENESS",
"TIDB_CURRENT_TSO",
"TIDB_DECODE_BINARY_PLAN",
"TIDB_DECODE_KEY",
"TIDB_DECODE_PLAN",
"TIDB_DECODE_SQL_DIGESTS",
"TIDB_ENCODE_SQL_DIGEST",
"TIDB_IS_DDL_OWNER",
"TIDB_PARSE_TSO",
"TIDB_PARSE_TSO_LOGICAL",
"TIDB_ROW_CHECKSUM",
"TIDB_SHARD",
"TIDB_VERSION",
"TIME",
"TIME_FORMAT",
"TIME_TO_SEC",
"TIMEDIFF",
"TIMESTAMP",
"TIMESTAMPADD",
"TIMESTAMPDIFF",
"TO_BASE64",
"TO_DAYS",
"TO_SECONDS",
"TRANSLATE",
"TRIM",
"TRUNCATE",
"UCASE",
"UNARYMINUS",
"UNCOMPRESS",
"UNCOMPRESSED_LENGTH",
"UNHEX",
"UNIX_TIMESTAMP",
"UPPER",
// 'USER',
"UTC_DATE",
"UTC_TIME",
"UTC_TIMESTAMP",
"UUID",
"UUID_SHORT",
"UUID_TO_BIN",
"VALIDATE_PASSWORD_STRENGTH",
"VAR_POP",
"VAR_SAMP",
"VARIANCE",
"VERSION",
"VITESS_HASH",
"WEEK",
"WEEKDAY",
"WEEKOFYEAR",
"WEIGHT_STRING",
// 'XOR',
"YEAR",
"YEARWEEK"
], kA = o(["SELECT [ALL | DISTINCT | DISTINCTROW]"]), zA = o([
// queries
"WITH [RECURSIVE]",
"FROM",
"WHERE",
"GROUP BY",
"HAVING",
"WINDOW",
"PARTITION BY",
"ORDER BY",
"LIMIT",
"OFFSET",
// Data manipulation
// - insert:
"INSERT [LOW_PRIORITY | DELAYED | HIGH_PRIORITY] [IGNORE] [INTO]",
"REPLACE [LOW_PRIORITY | DELAYED] [INTO]",
"VALUES",
"ON DUPLICATE KEY UPDATE",
// - update:
"SET"
]), We = o(["CREATE [TEMPORARY] TABLE [IF NOT EXISTS]"]), XE = o([
// https://docs.pingcap.com/tidb/stable/sql-statement-create-view
"CREATE [OR REPLACE] [SQL SECURITY DEFINER | SQL SECURITY INVOKER] VIEW [IF NOT EXISTS]",
// https://docs.pingcap.com/tidb/stable/sql-statement-update
"UPDATE [LOW_PRIORITY] [IGNORE]",
// https://docs.pingcap.com/tidb/stable/sql-statement-delete
"DELETE [LOW_PRIORITY] [QUICK] [IGNORE] FROM",
// https://docs.pingcap.com/tidb/stable/sql-statement-drop-table
"DROP [TEMPORARY] TABLE [IF EXISTS]",
// https://docs.pingcap.com/tidb/stable/sql-statement-alter-table
"ALTER TABLE",
"ADD [COLUMN]",
"{CHANGE | MODIFY} [COLUMN]",
"DROP [COLUMN]",
"RENAME [TO | AS]",
"RENAME COLUMN",
"ALTER [COLUMN]",
"{SET | DROP} DEFAULT",
// https://docs.pingcap.com/tidb/stable/sql-statement-truncate
"TRUNCATE [TABLE]",
// https://docs.pingcap.com/tidb/stable/sql-statement-alter-database
"ALTER DATABASE",
// https://docs.pingcap.com/tidb/stable/sql-statement-alter-instance
"ALTER INSTANCE",
"ALTER RESOURCE GROUP",
"ALTER SEQUENCE",
// https://docs.pingcap.com/tidb/stable/sql-statement-alter-user
"ALTER USER",
"ALTER VIEW",
"ANALYZE TABLE",
"CHECK TABLE",
"CHECKSUM TABLE",
"COMMIT",
"CREATE DATABASE",
"CREATE INDEX",
"CREATE RESOURCE GROUP",
"CREATE ROLE",
"CREATE SEQUENCE",
"CREATE USER",
"DEALLOCATE PREPARE",
"DESCRIBE",
"DROP DATABASE",
"DROP INDEX",
"DROP RESOURCE GROUP",
"DROP ROLE",
"DROP TABLESPACE",
"DROP USER",
"DROP VIEW",
"EXPLAIN",
"FLUSH",
// https://docs.pingcap.com/tidb/stable/sql-statement-grant-privileges
"GRANT",
"IMPORT TABLE",
"INSTALL COMPONENT",
"INSTALL PLUGIN",
"KILL",
"LOAD DATA",
"LOCK INSTANCE FOR BACKUP",
"LOCK TABLES",
"OPTIMIZE TABLE",
"PREPARE",
"RELEASE SAVEPOINT",
"RENAME TABLE",
"RENAME USER",
"REPAIR TABLE",
"RESET",
"REVOKE",
"ROLLBACK",
"ROLLBACK TO SAVEPOINT",
"SAVEPOINT",
"SET CHARACTER SET",
"SET DEFAULT ROLE",
"SET NAMES",
"SET PASSWORD",
"SET RESOURCE GROUP",
"SET ROLE",
"SET TRANSACTION",
"SHOW",
"SHOW BINARY LOGS",
"SHOW BINLOG EVENTS",
"SHOW CHARACTER SET",
"SHOW COLLATION",
"SHOW COLUMNS",
"SHOW CREATE DATABASE",
"SHOW CREATE TABLE",
"SHOW CREATE USER",
"SHOW CREATE VIEW",
"SHOW DATABASES",
"SHOW ENGINE",
"SHOW ENGINES",
"SHOW ERRORS",
"SHOW EVENTS",
"SHOW GRANTS",
"SHOW INDEX",
"SHOW MASTER STATUS",
"SHOW OPEN TABLES",
"SHOW PLUGINS",
"SHOW PRIVILEGES",
"SHOW PROCESSLIST",
"SHOW PROFILE",
"SHOW PROFILES",
"SHOW STATUS",
"SHOW TABLE STATUS",
"SHOW TABLES",
"SHOW TRIGGERS",
"SHOW VARIABLES",
"SHOW WARNINGS",
// https://docs.pingcap.com/tidb/stable/sql-statement-table
"TABLE",
"UNINSTALL COMPONENT",
"UNINSTALL PLUGIN",
"UNLOCK INSTANCE",
"UNLOCK TABLES",
// https://docs.pingcap.com/tidb/stable/sql-statement-use
"USE"
]), Et = o(["UNION [ALL | DISTINCT]"]), et = o([
"JOIN",
"{LEFT | RIGHT} [OUTER] JOIN",
"{INNER | CROSS} JOIN",
"NATURAL [INNER] JOIN",
"NATURAL {LEFT | RIGHT} [OUTER] JOIN",
// non-standard joins
"STRAIGHT_JOIN"
]), Tt = o([
"ON {UPDATE | DELETE} [SET NULL]",
"CHARACTER SET",
"{ROWS | RANGE} BETWEEN",
"IDENTIFIED BY"
]), Rt = o([]), At = {
name: "tidb",
tokenizerOptions: {
reservedSelect: kA,
reservedClauses: [...zA, ...We, ...XE],
reservedSetOperations: Et,
reservedJoins: et,
reservedKeywordPhrases: Tt,
reservedDataTypePhrases: Rt,
supportsXor: !0,
reservedKeywords: ZA,
reservedDataTypes: jA,
reservedFunctionNames: qA,
// TODO: support _ char set prefixes such as _utf8, _latin1, _binary, _utf8mb4, etc.
stringTypes: [
'""-qq-bs',
{ quote: "''-qq-bs", prefixes: ["N"] },
{ quote: "''-raw", prefixes: ["B", "X"], requirePrefix: !0 }
],
identTypes: ["``"],
identChars: { first: "$", rest: "$", allowFirstCharNumber: !0 },
variableTypes: [
{ regex: "@@?[A-Za-z0-9_.$]+" },
{ quote: '""-qq-bs', prefixes: ["@"], requirePrefix: !0 },
{ quote: "''-qq-bs", prefixes: ["@"], requirePrefix: !0 },
{ quote: "``", prefixes: ["@"], requirePrefix: !0 }
],
paramTypes: { positional: !0 },
lineCommentTypes: ["--", "#"],
operators: [
"%",
":=",
"&",
"|",
"^",
"~",
"<<",
">>",
"<=>",
"->",
"->>",
"&&",
"||",
"!",
"*.*"
// Not actually an operator
],
postProcess: ME
},
formatOptions: {
onelineClauses: [...We, ...XE],
tabularOnelineClauses: XE
}
}, tt = [
// https://docs.couchbase.com/server/current/n1ql/n1ql-language-reference/functions.html
"ABORT",
"ABS",
"ACOS",
"ADVISOR",
"ARRAY_AGG",
"ARRAY_AGG",
"ARRAY_APPEND",
"ARRAY_AVG",
"ARRAY_BINARY_SEARCH",
"ARRAY_CONCAT",
"ARRAY_CONTAINS",
"ARRAY_COUNT",
"ARRAY_DISTINCT",
"ARRAY_EXCEPT",
"ARRAY_FLATTEN",
"ARRAY_IFNULL",
"ARRAY_INSERT",
"ARRAY_INTERSECT",
"ARRAY_LENGTH",
"ARRAY_MAX",
"ARRAY_MIN",
"ARRAY_MOVE",
"ARRAY_POSITION",
"ARRAY_PREPEND",
"ARRAY_PUT",
"ARRAY_RANGE",
"ARRAY_REMOVE",
"ARRAY_REPEAT",
"ARRAY_REPLACE",
"ARRAY_REVERSE",
"ARRAY_SORT",
"ARRAY_STAR",
"ARRAY_SUM",
"ARRAY_SYMDIFF",
"ARRAY_SYMDIFF1",
"ARRAY_SYMDIFFN",
"ARRAY_UNION",
"ASIN",
"ATAN",
"ATAN2",
"AVG",
"BASE64",
"BASE64_DECODE",
"BASE64_ENCODE",
"BITAND ",
"BITCLEAR ",
"BITNOT ",
"BITOR ",
"BITSET ",
"BITSHIFT ",
"BITTEST ",
"BITXOR ",
"CEIL",
"CLOCK_LOCAL",
"CLOCK_MILLIS",
"CLOCK_STR",
"CLOCK_TZ",
"CLOCK_UTC",
"COALESCE",
"CONCAT",
"CONCAT2",
"CONTAINS",
"CONTAINS_TOKEN",
"CONTAINS_TOKEN_LIKE",
"CONTAINS_TOKEN_REGEXP",
"COS",
"COUNT",
"COUNT",
"COUNTN",
"CUME_DIST",
"CURL",
"DATE_ADD_MILLIS",
"DATE_ADD_STR",
"DATE_DIFF_MILLIS",
"DATE_DIFF_STR",
"DATE_FORMAT_STR",
"DATE_PART_MILLIS",
"DATE_PART_STR",
"DATE_RANGE_MILLIS",
"DATE_RANGE_STR",
"DATE_TRUNC_MILLIS",
"DATE_TRUNC_STR",
"DECODE",
"DECODE_JSON",
"DEGREES",
"DENSE_RANK",
"DURATION_TO_STR",
// 'E',
"ENCODED_SIZE",
"ENCODE_JSON",
"EXP",
"FIRST_VALUE",
"FLOOR",
"GREATEST",
"HAS_TOKEN",
"IFINF",
"IFMISSING",
"IFMISSINGORNULL",
"IFNAN",
"IFNANORINF",
"IFNULL",
"INITCAP",
"ISARRAY",
"ISATOM",
"ISBITSET",
"ISBOOLEAN",
"ISNUMBER",
"ISOBJECT",
"ISSTRING",
"LAG",
"LAST_VALUE",
"LEAD",
"LEAST",
"LENGTH",
"LN",
"LOG",
"LOWER",
"LTRIM",
"MAX",
"MEAN",
"MEDIAN",
"META",
"MILLIS",
"MILLIS_TO_LOCAL",
"MILLIS_TO_STR",
"MILLIS_TO_TZ",
"MILLIS_TO_UTC",
"MILLIS_TO_ZONE_NAME",
"MIN",
"MISSINGIF",
"NANIF",
"NEGINFIF",
"NOW_LOCAL",
"NOW_MILLIS",
"NOW_STR",
"NOW_TZ",
"NOW_UTC",
"NTH_VALUE",
"NTILE",
"NULLIF",
"NVL",
"NVL2",
"OBJECT_ADD",
"OBJECT_CONCAT",
"OBJECT_INNER_PAIRS",
"OBJECT_INNER_VALUES",
"OBJECT_LENGTH",
"OBJECT_NAMES",
"OBJECT_PAIRS",
"OBJECT_PUT",
"OBJECT_REMOVE",
"OBJECT_RENAME",
"OBJECT_REPLACE",
"OBJECT_UNWRAP",
"OBJECT_VALUES",
"PAIRS",
"PERCENT_RANK",
"PI",
"POLY_LENGTH",
"POSINFIF",
"POSITION",
"POWER",
"RADIANS",
"RANDOM",
"RANK",
"RATIO_TO_REPORT",
"REGEXP_CONTAINS",
"REGEXP_LIKE",
"REGEXP_MATCHES",
"REGEXP_POSITION",
"REGEXP_REPLACE",
"REGEXP_SPLIT",
"REGEX_CONTAINS",
"REGEX_LIKE",
"REGEX_MATCHES",
"REGEX_POSITION",
"REGEX_REPLACE",
"REGEX_SPLIT",
"REPEAT",
"REPLACE",
"REVERSE",
"ROUND",
"ROW_NUMBER",
"RTRIM",
"SEARCH",
"SEARCH_META",
"SEARCH_SCORE",
"SIGN",
"SIN",
"SPLIT",
"SQRT",
"STDDEV",
"STDDEV_POP",
"STDDEV_SAMP",
"STR_TO_DURATION",
"STR_TO_MILLIS",
"STR_TO_TZ",
"STR_TO_UTC",
"STR_TO_ZONE_NAME",
"SUBSTR",
"SUFFIXES",
"SUM",
"TAN",
"TITLE",
"TOARRAY",
"TOATOM",
"TOBOOLEAN",
"TOKENS",
"TOKENS",
"TONUMBER",
"TOOBJECT",
"TOSTRING",
"TRIM",
"TRUNC",
// 'TYPE', // disabled
"UPPER",
"UUID",
"VARIANCE",
"VARIANCE_POP",
"VARIANCE_SAMP",
"VAR_POP",
"VAR_SAMP",
"WEEKDAY_MILLIS",
"WEEKDAY_STR",
// type casting
// not implemented in N1QL, but added here now for the sake of tests
// https://docs.couchbase.com/server/current/analytics/3_query.html#Vs_SQL-92
"CAST"
], st = [
// https://docs.couchbase.com/server/current/n1ql/n1ql-language-reference/reservedwords.html
"ADVISE",
"ALL",
"ALTER",
"ANALYZE",
"AND",
"ANY",
"ARRAY",
"AS",
"ASC",
"AT",
"BEGIN",
"BETWEEN",
"BINARY",
"BOOLEAN",
"BREAK",
"BUCKET",
"BUILD",
"BY",
"CALL",
"CASE",
"CAST",
"CLUSTER",
"COLLATE",
"COLLECTION",
"COMMIT",
"COMMITTED",
"CONNECT",
"CONTINUE",
"CORRELATED",
"COVER",
"CREATE",
"CURRENT",
"DATABASE",
"DATASET",
"DATASTORE",
"DECLARE",
"DECREMENT",
"DELETE",
"DERIVED",
"DESC",
"DESCRIBE",
"DISTINCT",
"DO",
"DROP",
"EACH",
"ELEMENT",
"ELSE",
"END",
"EVERY",
"EXCEPT",
"EXCLUDE",
"EXECUTE",
"EXISTS",
"EXPLAIN",
"FALSE",
"FETCH",
"FILTER",
"FIRST",
"FLATTEN",
"FLUSH",
"FOLLOWING",
"FOR",
"FORCE",
"FROM",
"FTS",
"FUNCTION",
"GOLANG",
"GRANT",
"GROUP",
"GROUPS",
"GSI",
"HASH",
"HAVING",
"IF",
"IGNORE",
"ILIKE",
"IN",
"INCLUDE",
"INCREMENT",
"INDEX",
"INFER",
"INLINE",
"INNER",
"INSERT",
"INTERSECT",
"INTO",
"IS",
"ISOLATION",
"JAVASCRIPT",
"JOIN",
"KEY",
"KEYS",
"KEYSPACE",
"KNOWN",
"LANGUAGE",
"LAST",
"LEFT",
"LET",
"LETTING",
"LEVEL",
"LIKE",
"LIMIT",
"LSM",
"MAP",
"MAPPING",
"MATCHED",
"MATERIALIZED",
"MERGE",
"MINUS",
"MISSING",
"NAMESPACE",
"NEST",
"NL",
"NO",
"NOT",
"NTH_VALUE",
"NULL",
"NULLS",
"NUMBER",
"OBJECT",
"OFFSET",
"ON",
"OPTION",
"OPTIONS",
"OR",
"ORDER",
"OTHERS",
"OUTER",
"OVER",
"PARSE",
"PARTITION",
"PASSWORD",
"PATH",
"POOL",
"PRECEDING",
"PREPARE",
"PRIMARY",
"PRIVATE",
"PRIVILEGE",
"PROBE",
"PROCEDURE",
"PUBLIC",
"RANGE",
"RAW",
"REALM",
"REDUCE",
"RENAME",
"RESPECT",
"RETURN",
"RETURNING",
"REVOKE",
"RIGHT",
"ROLE",
"ROLLBACK",
"ROW",
"ROWS",
"SATISFIES",
"SAVEPOINT",
"SCHEMA",
"SCOPE",
"SELECT",
"SELF",
"SEMI",
"SET",
"SHOW",
"SOME",
"START",
"STATISTICS",
"STRING",
"SYSTEM",
"THEN",
"TIES",
"TO",
"TRAN",
"TRANSACTION",
"TRIGGER",
"TRUE",
"TRUNCATE",
"UNBOUNDED",
"UNDER",
"UNION",
"UNIQUE",
"UNKNOWN",
"UNNEST",
"UNSET",
"UPDATE",
"UPSERT",
"USE",
"USER",
"USING",
"VALIDATE",
"VALUE",
"VALUED",
"VALUES",
"VIA",
"VIEW",
"WHEN",
"WHERE",
"WHILE",
"WINDOW",
"WITH",
"WITHIN",
"WORK",
"XOR"
], St = [
// N1QL does not support any way of declaring types for columns.
// It does not support the CREATE TABLE statement nor the CAST() expression.
//
// It does have several keywords like ARRAY and OBJECT, which seem to refer to types,
// but they are used as operators. It also reserves several words like STRING and NUMBER,
// which it actually doesn't use.
//
// https://docs.couchbase.com/server/current/n1ql/n1ql-language-reference/datatypes.html
], Nt = o(["SELECT [ALL | DISTINCT]"]), It = o([
// queries
"WITH",
"FROM",
"WHERE",
"GROUP BY",
"HAVING",
"WINDOW",
"PARTITION BY",
"ORDER BY",
"LIMIT",
"OFFSET",
// Data manipulation
// - insert:
"INSERT INTO",
"VALUES",
// - update:
"SET",
// - merge:
"MERGE INTO",
"WHEN [NOT] MATCHED THEN",
"UPDATE SET",
"INSERT",
// other
"NEST",
"UNNEST",
"RETURNING"
]), ye = o([
// - update:
"UPDATE",
// - delete:
"DELETE FROM",
// - set schema:
"SET SCHEMA",
// https://docs.couchbase.com/server/current/n1ql/n1ql-language-reference/reservedwords.html
"ADVISE",
"ALTER INDEX",
"BEGIN TRANSACTION",
"BUILD INDEX",
"COMMIT TRANSACTION",
"CREATE COLLECTION",
"CREATE FUNCTION",
"CREATE INDEX",
"CREATE PRIMARY INDEX",
"CREATE SCOPE",
"DROP COLLECTION",
"DROP FUNCTION",
"DROP INDEX",
"DROP PRIMARY INDEX",
"DROP SCOPE",
"EXECUTE",
"EXECUTE FUNCTION",
"EXPLAIN",
"GRANT",
"INFER",
"PREPARE",
"REVOKE",
"ROLLBACK TRANSACTION",
"SAVEPOINT",
"SET TRANSACTION",
"UPDATE STATISTICS",
"UPSERT",
// other
"LET",
"SET CURRENT SCHEMA",
"SHOW",
"USE [PRIMARY] KEYS"
]), Ot = o(["UNION [ALL]", "EXCEPT [ALL]", "INTERSECT [ALL]"]), nt = o(["JOIN", "{LEFT | RIGHT} [OUTER] JOIN", "INNER JOIN"]), rt = o(["{ROWS | RANGE | GROUPS} BETWEEN"]), it = o([]), at = {
name: "n1ql",
tokenizerOptions: {
reservedSelect: Nt,
reservedClauses: [...It, ...ye],
reservedSetOperations: Ot,
reservedJoins: nt,
reservedKeywordPhrases: rt,
reservedDataTypePhrases: it,
supportsXor: !0,
reservedKeywords: st,
reservedDataTypes: St,
reservedFunctionNames: tt,
// NOTE: single quotes are actually not supported in N1QL,
// but we support them anyway as all other SQL dialects do,
// which simplifies writing tests that are shared between all dialects.
stringTypes: ['""-bs', "''-bs"],
identTypes: ["``"],
extraParens: ["[]", "{}"],
paramTypes: { positional: !0, numbered: ["$"], named: ["$"] },
lineCommentTypes: ["#", "--"],
operators: ["%", "==", ":", "||"]
},
formatOptions: {
onelineClauses: ye
}
}, Ct = [
// https://docs.oracle.com/cd/B19306_01/appdev.102/b14261/reservewords.htm
// 'A',
"ADD",
"AGENT",
"AGGREGATE",
"ALL",
"ALTER",
"AND",
"ANY",
"ARROW",
"AS",
"ASC",
"AT",
"ATTRIBUTE",
"AUTHID",
"AVG",
"BEGIN",
"BETWEEN",
"BLOCK",
"BODY",
"BOTH",
"BOUND",
"BULK",
"BY",
"BYTE",
// 'C',
"CALL",
"CALLING",
"CASCADE",
"CASE",
"CHARSET",
"CHARSETFORM",
"CHARSETID",
"CHECK",
"CLOSE",
"CLUSTER",
"CLUSTERS",
"COLAUTH",
"COLLECT",
"COLUMNS",
"COMMENT",
"COMMIT",
"COMMITTED",
"COMPILED",
"COMPRESS",
"CONNECT",
"CONSTANT",
"CONSTRUCTOR",
"CONTEXT",
"CONVERT",
"COUNT",
"CRASH",
"CREATE",
"CURRENT",
"CURSOR",
"CUSTOMDATUM",
"DANGLING",
"DATA",
"DAY",
"DECLARE",
"DEFAULT",
"DEFINE",
"DELETE",
"DESC",
"DETERMINISTIC",
"DISTINCT",
"DROP",
"DURATION",
"ELEMENT",
"ELSE",
"ELSIF",
"EMPTY",
"END",
"ESCAPE",
"EXCEPT",
"EXCEPTION",
"EXCEPTIONS",
"EXCLUSIVE",
"EXECUTE",
"EXISTS",
"EXIT",
"EXTERNAL",
"FETCH",
"FINAL",
"FIXED",
"FOR",
"FORALL",
"FORCE",
"FORM",
"FROM",
"FUNCTION",
"GENERAL",
"GOTO",
"GRANT",
"GROUP",
"HASH",
"HAVING",
"HEAP",
"HIDDEN",
"HOUR",
"IDENTIFIED",
"IF",
"IMMEDIATE",
"IN",
"INCLUDING",
"INDEX",
"INDEXES",
"INDICATOR",
"INDICES",
"INFINITE",
"INSERT",
"INSTANTIABLE",
"INTERFACE",
"INTERSECT",
"INTERVAL",
"INTO",
"INVALIDATE",
"IS",
"ISOLATION",
"JAVA",
"LANGUAGE",
"LARGE",
"LEADING",
"LENGTH",
"LEVEL",
"LIBRARY",
"LIKE",
"LIKE2",
"LIKE4",
"LIKEC",
"LIMIT",
"LIMITED",
"LOCAL",
"LOCK",
"LOOP",
"MAP",
"MAX",
"MAXLEN",
"MEMBER",
"MERGE",
"MIN",
"MINUS",
"MINUTE",
"MOD",
"MODE",
"MODIFY",
"MONTH",
"MULTISET",
"NAME",
"NAN",
"NATIONAL",
"NATIVE",
"NEW",
"NOCOMPRESS",
"NOCOPY",
"NOT",
"NOWAIT",
"NULL",
"OBJECT",
"OCICOLL",
"OCIDATE",
"OCIDATETIME",
"OCIDURATION",
"OCIINTERVAL",
"OCILOBLOCATOR",
"OCINUMBER",
"OCIRAW",
"OCIREF",
"OCIREFCURSOR",
"OCIROWID",
"OCISTRING",
"OCITYPE",
"OF",
"ON",
"ONLY",
"OPAQUE",
"OPEN",
"OPERATOR",
"OPTION",
"OR",
"ORACLE",
"ORADATA",
"ORDER",
"OVERLAPS",
"ORGANIZATION",
"ORLANY",
"ORLVARY",
"OTHERS",
"OUT",
"OVERRIDING",
"PACKAGE",
"PARALLEL_ENABLE",
"PARAMETER",
"PARAMETERS",
"PARTITION",
"PASCAL",
"PIPE",
"PIPELINED",
"PRAGMA",
"PRIOR",
"PRIVATE",
"PROCEDURE",
"PUBLIC",
"RAISE",
"RANGE",
"READ",
"RECORD",
"REF",
"REFERENCE",
"REM",
"REMAINDER",
"RENAME",
"RESOURCE",
"RESULT",
"RETURN",
"RETURNING",
"REVERSE",
"REVOKE",
"ROLLBACK",
"ROW",
"SAMPLE",
"SAVE",
"SAVEPOINT",
"SB1",
"SB2",
"SB4",
"SECOND",
"SEGMENT",
"SELECT",
"SELF",
"SEPARATE",
"SEQUENCE",
"SERIALIZABLE",
"SET",
"SHARE",
"SHORT",
"SIZE",
"SIZE_T",
"SOME",
"SPARSE",
"SQL",
"SQLCODE",
"SQLDATA",
"SQLNAME",
"SQLSTATE",
"STANDARD",
"START",
"STATIC",
"STDDEV",
"STORED",
"STRING",
"STRUCT",
"STYLE",
"SUBMULTISET",
"SUBPARTITION",
"SUBSTITUTABLE",
"SUBTYPE",
"SUM",
"SYNONYM",
"TABAUTH",
"TABLE",
"TDO",
"THE",
"THEN",
"TIME",
"TIMEZONE_ABBR",
"TIMEZONE_HOUR",
"TIMEZONE_MINUTE",
"TIMEZONE_REGION",
"TO",
"TRAILING",
"TRANSAC",
"TRANSACTIONAL",
"TRUSTED",
"TYPE",
"UB1",
"UB2",
"UB4",
"UNDER",
"UNION",
"UNIQUE",
"UNSIGNED",
"UNTRUSTED",
"UPDATE",
"USE",
"USING",
"VALIST",
"VALUE",
"VALUES",
"VARIABLE",
"VARIANCE",
"VARRAY",
"VIEW",
"VIEWS",
"VOID",
"WHEN",
"WHERE",
"WHILE",
"WITH",
"WORK",
"WRAPPED",
"WRITE",
"YEAR",
"ZONE"
], ot = [
// https://www.ibm.com/docs/en/db2/10.5?topic=plsql-data-types
"ARRAY",
"BFILE_BASE",
"BINARY",
"BLOB_BASE",
"CHAR VARYING",
"CHAR_BASE",
"CHAR",
"CHARACTER VARYING",
"CHARACTER",
"CLOB_BASE",
"DATE_BASE",
"DATE",
"DECIMAL",
"DOUBLE",
"FLOAT",
"INT",
"INTERVAL DAY",
"INTERVAL YEAR",
"LONG",
"NATIONAL CHAR VARYING",
"NATIONAL CHAR",
"NATIONAL CHARACTER VARYING",
"NATIONAL CHARACTER",
"NCHAR VARYING",
"NCHAR",
"NCHAR",
"NUMBER_BASE",
"NUMBER",
"NUMBERIC",
"NVARCHAR",
"PRECISION",
"RAW",
"TIMESTAMP",
"UROWID",
"VARCHAR",
"VARCHAR2"
], Lt = [
// https://docs.oracle.com/cd/B19306_01/server.102/b14200/functions001.htm
// numeric
"ABS",
"ACOS",
"ASIN",
"ATAN",
"ATAN2",
"BITAND",
"CEIL",
"COS",
"COSH",
"EXP",
"FLOOR",
"LN",
"LOG",
"MOD",
"NANVL",
"POWER",
"REMAINDER",
"ROUND",
"SIGN",
"SIN",
"SINH",
"SQRT",
"TAN",
"TANH",
"TRUNC",
"WIDTH_BUCKET",
// character
"CHR",
"CONCAT",
"INITCAP",
"LOWER",
"LPAD",
"LTRIM",
"NLS_INITCAP",
"NLS_LOWER",
"NLSSORT",
"NLS_UPPER",
"REGEXP_REPLACE",
"REGEXP_SUBSTR",
"REPLACE",
"RPAD",
"RTRIM",
"SOUNDEX",
"SUBSTR",
"TRANSLATE",
"TREAT",
"TRIM",
"UPPER",
"NLS_CHARSET_DECL_LEN",
"NLS_CHARSET_ID",
"NLS_CHARSET_NAME",
"ASCII",
"INSTR",
"LENGTH",
"REGEXP_INSTR",
// datetime
"ADD_MONTHS",
"CURRENT_DATE",
"CURRENT_TIMESTAMP",
"DBTIMEZONE",
"EXTRACT",
"FROM_TZ",
"LAST_DAY",
"LOCALTIMESTAMP",
"MONTHS_BETWEEN",
"NEW_TIME",
"NEXT_DAY",
"NUMTODSINTERVAL",
"NUMTOYMINTERVAL",
"ROUND",
"SESSIONTIMEZONE",
"SYS_EXTRACT_UTC",
"SYSDATE",
"SYSTIMESTAMP",
"TO_CHAR",
"TO_TIMESTAMP",
"TO_TIMESTAMP_TZ",
"TO_DSINTERVAL",
"TO_YMINTERVAL",
"TRUNC",
"TZ_OFFSET",
// comparison
"GREATEST",
"LEAST",
// conversion
"ASCIISTR",
"BIN_TO_NUM",
"CAST",
"CHARTOROWID",
"COMPOSE",
"CONVERT",
"DECOMPOSE",
"HEXTORAW",
"NUMTODSINTERVAL",
"NUMTOYMINTERVAL",
"RAWTOHEX",
"RAWTONHEX",
"ROWIDTOCHAR",
"ROWIDTONCHAR",
"SCN_TO_TIMESTAMP",
"TIMESTAMP_TO_SCN",
"TO_BINARY_DOUBLE",
"TO_BINARY_FLOAT",
"TO_CHAR",
"TO_CLOB",
"TO_DATE",
"TO_DSINTERVAL",
"TO_LOB",
"TO_MULTI_BYTE",
"TO_NCHAR",
"TO_NCLOB",
"TO_NUMBER",
"TO_DSINTERVAL",
"TO_SINGLE_BYTE",
"TO_TIMESTAMP",
"TO_TIMESTAMP_TZ",
"TO_YMINTERVAL",
"TO_YMINTERVAL",
"TRANSLATE",
"UNISTR",
// largeObject
"BFILENAME",
"EMPTY_BLOB,",
"EMPTY_CLOB",
// collection
"CARDINALITY",
"COLLECT",
"POWERMULTISET",
"POWERMULTISET_BY_CARDINALITY",
"SET",
// hierarchical
"SYS_CONNECT_BY_PATH",
// dataMining
"CLUSTER_ID",
"CLUSTER_PROBABILITY",
"CLUSTER_SET",
"FEATURE_ID",
"FEATURE_SET",
"FEATURE_VALUE",
"PREDICTION",
"PREDICTION_COST",
"PREDICTION_DETAILS",
"PREDICTION_PROBABILITY",
"PREDICTION_SET",
// xml
"APPENDCHILDXML",
"DELETEXML",
"DEPTH",
"EXTRACT",
"EXISTSNODE",
"EXTRACTVALUE",
"INSERTCHILDXML",
"INSERTXMLBEFORE",
"PATH",
"SYS_DBURIGEN",
"SYS_XMLAGG",
"SYS_XMLGEN",
"UPDATEXML",
"XMLAGG",
"XMLCDATA",
"XMLCOLATTVAL",
"XMLCOMMENT",
"XMLCONCAT",
"XMLFOREST",
"XMLPARSE",
"XMLPI",
"XMLQUERY",
"XMLROOT",
"XMLSEQUENCE",
"XMLSERIALIZE",
"XMLTABLE",
"XMLTRANSFORM",
// encoding
"DECODE",
"DUMP",
"ORA_HASH",
"VSIZE",
// nullRelated
"COALESCE",
"LNNVL",
"NULLIF",
"NVL",
"NVL2",
// env
"SYS_CONTEXT",
"SYS_GUID",
"SYS_TYPEID",
"UID",
"USER",
"USERENV",
// aggregate
"AVG",
"COLLECT",
"CORR",
"CORR_S",
"CORR_K",
"COUNT",
"COVAR_POP",
"COVAR_SAMP",
"CUME_DIST",
"DENSE_RANK",
"FIRST",
"GROUP_ID",
"GROUPING",
"GROUPING_ID",
"LAST",
"MAX",
"MEDIAN",
"MIN",
"PERCENTILE_CONT",
"PERCENTILE_DISC",
"PERCENT_RANK",
"RANK",
"REGR_SLOPE",
"REGR_INTERCEPT",
"REGR_COUNT",
"REGR_R2",
"REGR_AVGX",
"REGR_AVGY",
"REGR_SXX",
"REGR_SYY",
"REGR_SXY",
"STATS_BINOMIAL_TEST",
"STATS_CROSSTAB",
"STATS_F_TEST",
"STATS_KS_TEST",
"STATS_MODE",
"STATS_MW_TEST",
"STATS_ONE_WAY_ANOVA",
"STATS_T_TEST_ONE",
"STATS_T_TEST_PAIRED",
"STATS_T_TEST_INDEP",
"STATS_T_TEST_INDEPU",
"STATS_WSR_TEST",
"STDDEV",
"STDDEV_POP",
"STDDEV_SAMP",
"SUM",
"VAR_POP",
"VAR_SAMP",
"VARIANCE",
// Windowing functions (minus the ones already listed in aggregates)
// window
"FIRST_VALUE",
"LAG",
"LAST_VALUE",
"LEAD",
"NTILE",
"RATIO_TO_REPORT",
"ROW_NUMBER",
// objectReference
"DEREF",
"MAKE_REF",
"REF",
"REFTOHEX",
"VALUE",
// model
"CV",
"ITERATION_NUMBER",
"PRESENTNNV",
"PRESENTV",
"PREVIOUS"
], _t = o(["SELECT [ALL | DISTINCT | UNIQUE]"]), Dt = o([
// queries
"WITH",
"FROM",
"WHERE",
"GROUP BY",
"HAVING",
"PARTITION BY",
"ORDER [SIBLINGS] BY",
"OFFSET",
"FETCH {FIRST | NEXT}",
"FOR UPDATE [OF]",
// Data manipulation
// - insert:
"INSERT [INTO | ALL INTO]",
"VALUES",
// - update:
"SET",
// - merge:
"MERGE [INTO]",
"WHEN [NOT] MATCHED [THEN]",
"UPDATE SET",
// other
"RETURNING"
]), Xe = o([
"CREATE [GLOBAL TEMPORARY | PRIVATE TEMPORARY | SHARDED | DUPLICATED | IMMUTABLE BLOCKCHAIN | BLOCKCHAIN | IMMUTABLE] TABLE"
]), $E = o([
// - create:
"CREATE [OR REPLACE] [NO FORCE | FORCE] [EDITIONING | EDITIONABLE | EDITIONABLE EDITIONING | NONEDITIONABLE] VIEW",
"CREATE MATERIALIZED VIEW",
// - update:
"UPDATE [ONLY]",
// - delete:
"DELETE FROM [ONLY]",
// - drop table:
"DROP TABLE",
// - alter table:
"ALTER TABLE",
"ADD",
"DROP {COLUMN | UNUSED COLUMNS | COLUMNS CONTINUE}",
"MODIFY",
"RENAME TO",
"RENAME COLUMN",
// - truncate:
"TRUNCATE TABLE",
// other
"SET SCHEMA",
"BEGIN",
"CONNECT BY",
"DECLARE",
"EXCEPT",
"EXCEPTION",
"LOOP",
"START WITH"
]), Pt = o(["UNION [ALL]", "MINUS", "INTERSECT"]), lt = o([
"JOIN",
"{LEFT | RIGHT | FULL} [OUTER] JOIN",
"{INNER | CROSS} JOIN",
"NATURAL [INNER] JOIN",
"NATURAL {LEFT | RIGHT | FULL} [OUTER] JOIN",
// non-standard joins
"{CROSS | OUTER} APPLY"
]), ct = o([
"ON {UPDATE | DELETE} [SET NULL]",
"ON COMMIT",
"{ROWS | RANGE} BETWEEN"
]), Mt = o([]), ut = {
name: "plsql",
tokenizerOptions: {
reservedSelect: _t,
reservedClauses: [...Dt, ...Xe, ...$E],
reservedSetOperations: Pt,
reservedJoins: lt,
reservedKeywordPhrases: ct,
reservedDataTypePhrases: Mt,
supportsXor: !0,
reservedKeywords: Ct,
reservedDataTypes: ot,
reservedFunctionNames: Lt,
stringTypes: [
{ quote: "''-qq", prefixes: ["N"] },
{ quote: "q''", prefixes: ["N"] }
],
// PL/SQL doesn't actually support escaping of quotes in identifiers,
// but for the sake of simpler testing we'll support this anyway
// as all other SQL dialects with "identifiers" do.
identTypes: ['""-qq'],
identChars: { rest: "$#" },
variableTypes: [{ regex: "&{1,2}[A-Za-z][A-Za-z0-9_$#]*" }],
paramTypes: { numbered: [":"], named: [":"] },
operators: [
"**",
":=",
"%",
"~=",
"^=",
// '..', // Conflicts with float followed by dot (so "2..3" gets parsed as ["2.", ".", "3"])
">>",
"<<",
"=>",
"@",
"||"
],
postProcess: Ut
},
formatOptions: {
alwaysDenseOperators: ["@"],
onelineClauses: [...Xe, ...$E],
tabularOnelineClauses: $E
}
};
function Ut(T) {
let E = TE;
return T.map((e) => j.SET(e) && j.BY(E) ? Object.assign(Object.assign({}, e), { type: l.RESERVED_KEYWORD }) : (PT(e.type) && (E = e), e));
}
const dt = [
// https://www.postgresql.org/docs/14/functions.html
//
// https://www.postgresql.org/docs/14/functions-math.html
"ABS",
"ACOS",
"ACOSD",
"ACOSH",
"ASIN",
"ASIND",
"ASINH",
"ATAN",
"ATAN2",
"ATAN2D",
"ATAND",
"ATANH",
"CBRT",
"CEIL",
"CEILING",
"COS",
"COSD",
"COSH",
"COT",
"COTD",
"DEGREES",
"DIV",
"EXP",
"FACTORIAL",
"FLOOR",
"GCD",
"LCM",
"LN",
"LOG",
"LOG10",
"MIN_SCALE",
"MOD",
"PI",
"POWER",
"RADIANS",
"RANDOM",
"ROUND",
"SCALE",
"SETSEED",
"SIGN",
"SIN",
"SIND",
"SINH",
"SQRT",
"TAN",
"TAND",
"TANH",
"TRIM_SCALE",
"TRUNC",
"WIDTH_BUCKET",
// https://www.postgresql.org/docs/14/functions-string.html
"ABS",
"ASCII",
"BIT_LENGTH",
"BTRIM",
"CHARACTER_LENGTH",
"CHAR_LENGTH",
"CHR",
"CONCAT",
"CONCAT_WS",
"FORMAT",
"INITCAP",
"LEFT",
"LENGTH",
"LOWER",
"LPAD",
"LTRIM",
"MD5",
"NORMALIZE",
"OCTET_LENGTH",
"OVERLAY",
"PARSE_IDENT",
"PG_CLIENT_ENCODING",
"POSITION",
"QUOTE_IDENT",
"QUOTE_LITERAL",
"QUOTE_NULLABLE",
"REGEXP_MATCH",
"REGEXP_MATCHES",
"REGEXP_REPLACE",
"REGEXP_SPLIT_TO_ARRAY",
"REGEXP_SPLIT_TO_TABLE",
"REPEAT",
"REPLACE",
"REVERSE",
"RIGHT",
"RPAD",
"RTRIM",
"SPLIT_PART",
"SPRINTF",
"STARTS_WITH",
"STRING_AGG",
"STRING_TO_ARRAY",
"STRING_TO_TABLE",
"STRPOS",
"SUBSTR",
"SUBSTRING",
"TO_ASCII",
"TO_HEX",
"TRANSLATE",
"TRIM",
"UNISTR",
"UPPER",
// https://www.postgresql.org/docs/14/functions-binarystring.html
"BIT_COUNT",
"BIT_LENGTH",
"BTRIM",
"CONVERT",
"CONVERT_FROM",
"CONVERT_TO",
"DECODE",
"ENCODE",
"GET_BIT",
"GET_BYTE",
"LENGTH",
"LTRIM",
"MD5",
"OCTET_LENGTH",
"OVERLAY",
"POSITION",
"RTRIM",
"SET_BIT",
"SET_BYTE",
"SHA224",
"SHA256",
"SHA384",
"SHA512",
"STRING_AGG",
"SUBSTR",
"SUBSTRING",
"TRIM",
// https://www.postgresql.org/docs/14/functions-bitstring.html
"BIT_COUNT",
"BIT_LENGTH",
"GET_BIT",
"LENGTH",
"OCTET_LENGTH",
"OVERLAY",
"POSITION",
"SET_BIT",
"SUBSTRING",
// https://www.postgresql.org/docs/14/functions-matching.html
"REGEXP_MATCH",
"REGEXP_MATCHES",
"REGEXP_REPLACE",
"REGEXP_SPLIT_TO_ARRAY",
"REGEXP_SPLIT_TO_TABLE",
// https://www.postgresql.org/docs/14/functions-formatting.html
"TO_CHAR",
"TO_DATE",
"TO_NUMBER",
"TO_TIMESTAMP",
// https://www.postgresql.org/docs/14/functions-datetime.html
// 'AGE',
"CLOCK_TIMESTAMP",
"CURRENT_DATE",
"CURRENT_TIME",
"CURRENT_TIMESTAMP",
"DATE_BIN",
"DATE_PART",
"DATE_TRUNC",
"EXTRACT",
"ISFINITE",
"JUSTIFY_DAYS",
"JUSTIFY_HOURS",
"JUSTIFY_INTERVAL",
"LOCALTIME",
"LOCALTIMESTAMP",
"MAKE_DATE",
"MAKE_INTERVAL",
"MAKE_TIME",
"MAKE_TIMESTAMP",
"MAKE_TIMESTAMPTZ",
"NOW",
"PG_SLEEP",
"PG_SLEEP_FOR",
"PG_SLEEP_UNTIL",
"STATEMENT_TIMESTAMP",
"TIMEOFDAY",
"TO_TIMESTAMP",
"TRANSACTION_TIMESTAMP",
// https://www.postgresql.org/docs/14/functions-enum.html
"ENUM_FIRST",
"ENUM_LAST",
"ENUM_RANGE",
// https://www.postgresql.org/docs/14/functions-geometry.html
"AREA",
"BOUND_BOX",
"BOX",
"CENTER",
"CIRCLE",
"DIAGONAL",
"DIAMETER",
"HEIGHT",
"ISCLOSED",
"ISOPEN",
"LENGTH",
"LINE",
"LSEG",
"NPOINTS",
"PATH",
"PCLOSE",
"POINT",
"POLYGON",
"POPEN",
"RADIUS",
"SLOPE",
"WIDTH",
// https://www.postgresql.org/docs/14/functions-net.html
"ABBREV",
"BROADCAST",
"FAMILY",
"HOST",
"HOSTMASK",
"INET_MERGE",
"INET_SAME_FAMILY",
"MACADDR8_SET7BIT",
"MASKLEN",
"NETMASK",
"NETWORK",
"SET_MASKLEN",
// 'TEXT', // excluded because it's also a data type name
"TRUNC",
// https://www.postgresql.org/docs/14/functions-textsearch.html
"ARRAY_TO_TSVECTOR",
"GET_CURRENT_TS_CONFIG",
"JSONB_TO_TSVECTOR",
"JSON_TO_TSVECTOR",
"LENGTH",
"NUMNODE",
"PHRASETO_TSQUERY",
"PLAINTO_TSQUERY",
"QUERYTREE",
"SETWEIGHT",
"STRIP",
"TO_TSQUERY",
"TO_TSVECTOR",
"TSQUERY_PHRASE",
"TSVECTOR_TO_ARRAY",
"TS_DEBUG",
"TS_DELETE",
"TS_FILTER",
"TS_HEADLINE",
"TS_LEXIZE",
"TS_PARSE",
"TS_RANK",
"TS_RANK_CD",
"TS_REWRITE",
"TS_STAT",
"TS_TOKEN_TYPE",
"WEBSEARCH_TO_TSQUERY",
// https://www.postgresql.org/docs/18/functions-uuid.html
"GEN_RANDOM_UUID",
"UUIDV4",
"UUIDV7",
"UUID_EXTRACT_TIMESTAMP",
"UUID_EXTRACT_VERSION",
// https://www.postgresql.org/docs/14/functions-xml.html
"CURSOR_TO_XML",
"CURSOR_TO_XMLSCHEMA",
"DATABASE_TO_XML",
"DATABASE_TO_XMLSCHEMA",
"DATABASE_TO_XML_AND_XMLSCHEMA",
"NEXTVAL",
"QUERY_TO_XML",
"QUERY_TO_XMLSCHEMA",
"QUERY_TO_XML_AND_XMLSCHEMA",
"SCHEMA_TO_XML",
"SCHEMA_TO_XMLSCHEMA",
"SCHEMA_TO_XML_AND_XMLSCHEMA",
"STRING",
"TABLE_TO_XML",
"TABLE_TO_XMLSCHEMA",
"TABLE_TO_XML_AND_XMLSCHEMA",
"XMLAGG",
"XMLCOMMENT",
"XMLCONCAT",
"XMLELEMENT",
"XMLEXISTS",
"XMLFOREST",
"XMLPARSE",
"XMLPI",
"XMLROOT",
"XMLSERIALIZE",
"XMLTABLE",
"XML_IS_WELL_FORMED",
"XML_IS_WELL_FORMED_CONTENT",
"XML_IS_WELL_FORMED_DOCUMENT",
"XPATH",
"XPATH_EXISTS",
// https://www.postgresql.org/docs/14/functions-json.html
"ARRAY_TO_JSON",
"JSONB_AGG",
"JSONB_ARRAY_ELEMENTS",
"JSONB_ARRAY_ELEMENTS_TEXT",
"JSONB_ARRAY_LENGTH",
"JSONB_BUILD_ARRAY",
"JSONB_BUILD_OBJECT",
"JSONB_EACH",
"JSONB_EACH_TEXT",
"JSONB_EXTRACT_PATH",
"JSONB_EXTRACT_PATH_TEXT",
"JSONB_INSERT",
"JSONB_OBJECT",
"JSONB_OBJECT_AGG",
"JSONB_OBJECT_KEYS",
"JSONB_PATH_EXISTS",
"JSONB_PATH_EXISTS_TZ",
"JSONB_PATH_MATCH",
"JSONB_PATH_MATCH_TZ",
"JSONB_PATH_QUERY",
"JSONB_PATH_QUERY_ARRAY",
"JSONB_PATH_QUERY_ARRAY_TZ",
"JSONB_PATH_QUERY_FIRST",
"JSONB_PATH_QUERY_FIRST_TZ",
"JSONB_PATH_QUERY_TZ",
"JSONB_POPULATE_RECORD",
"JSONB_POPULATE_RECORDSET",
"JSONB_PRETTY",
"JSONB_SET",
"JSONB_SET_LAX",
"JSONB_STRIP_NULLS",
"JSONB_TO_RECORD",
"JSONB_TO_RECORDSET",
"JSONB_TYPEOF",
"JSON_AGG",
"JSON_ARRAY_ELEMENTS",
"JSON_ARRAY_ELEMENTS_TEXT",
"JSON_ARRAY_LENGTH",
"JSON_BUILD_ARRAY",
"JSON_BUILD_OBJECT",
"JSON_EACH",
"JSON_EACH_TEXT",
"JSON_EXTRACT_PATH",
"JSON_EXTRACT_PATH_TEXT",
"JSON_OBJECT",
"JSON_OBJECT_AGG",
"JSON_OBJECT_KEYS",
"JSON_POPULATE_RECORD",
"JSON_POPULATE_RECORDSET",
"JSON_STRIP_NULLS",
"JSON_TO_RECORD",
"JSON_TO_RECORDSET",
"JSON_TYPEOF",
"ROW_TO_JSON",
"TO_JSON",
"TO_JSONB",
"TO_TIMESTAMP",
// https://www.postgresql.org/docs/14/functions-sequence.html
"CURRVAL",
"LASTVAL",
"NEXTVAL",
"SETVAL",
// https://www.postgresql.org/docs/14/functions-conditional.html
// 'CASE',
"COALESCE",
"GREATEST",
"LEAST",
"NULLIF",
// https://www.postgresql.org/docs/14/functions-array.html
"ARRAY_AGG",
"ARRAY_APPEND",
"ARRAY_CAT",
"ARRAY_DIMS",
"ARRAY_FILL",
"ARRAY_LENGTH",
"ARRAY_LOWER",
"ARRAY_NDIMS",
"ARRAY_POSITION",
"ARRAY_POSITIONS",
"ARRAY_PREPEND",
"ARRAY_REMOVE",
"ARRAY_REPLACE",
"ARRAY_TO_STRING",
"ARRAY_UPPER",
"CARDINALITY",
"STRING_TO_ARRAY",
"TRIM_ARRAY",
"UNNEST",
// https://www.postgresql.org/docs/14/functions-range.html
"ISEMPTY",
"LOWER",
"LOWER_INC",
"LOWER_INF",
"MULTIRANGE",
"RANGE_MERGE",
"UPPER",
"UPPER_INC",
"UPPER_INF",
// https://www.postgresql.org/docs/14/functions-aggregate.html
// 'ANY',
"ARRAY_AGG",
"AVG",
"BIT_AND",
"BIT_OR",
"BIT_XOR",
"BOOL_AND",
"BOOL_OR",
"COALESCE",
"CORR",
"COUNT",
"COVAR_POP",
"COVAR_SAMP",
"CUME_DIST",
"DENSE_RANK",
"EVERY",
"GROUPING",
"JSONB_AGG",
"JSONB_OBJECT_AGG",
"JSON_AGG",
"JSON_OBJECT_AGG",
"MAX",
"MIN",
"MODE",
"PERCENTILE_CONT",
"PERCENTILE_DISC",
"PERCENT_RANK",
"RANGE_AGG",
"RANGE_INTERSECT_AGG",
"RANK",
"REGR_AVGX",
"REGR_AVGY",
"REGR_COUNT",
"REGR_INTERCEPT",
"REGR_R2",
"REGR_SLOPE",
"REGR_SXX",
"REGR_SXY",
"REGR_SYY",
// 'SOME',
"STDDEV",
"STDDEV_POP",
"STDDEV_SAMP",
"STRING_AGG",
"SUM",
"TO_JSON",
"TO_JSONB",
"VARIANCE",
"VAR_POP",
"VAR_SAMP",
"XMLAGG",
// https://www.postgresql.org/docs/14/functions-window.html
"CUME_DIST",
"DENSE_RANK",
"FIRST_VALUE",
"LAG",
"LAST_VALUE",
"LEAD",
"NTH_VALUE",
"NTILE",
"PERCENT_RANK",
"RANK",
"ROW_NUMBER",
// https://www.postgresql.org/docs/14/functions-srf.html
"GENERATE_SERIES",
"GENERATE_SUBSCRIPTS",
// https://www.postgresql.org/docs/14/functions-info.html
"ACLDEFAULT",
"ACLEXPLODE",
"COL_DESCRIPTION",
"CURRENT_CATALOG",
"CURRENT_DATABASE",
"CURRENT_QUERY",
"CURRENT_ROLE",
"CURRENT_SCHEMA",
"CURRENT_SCHEMAS",
"CURRENT_USER",
"FORMAT_TYPE",
"HAS_ANY_COLUMN_PRIVILEGE",
"HAS_COLUMN_PRIVILEGE",
"HAS_DATABASE_PRIVILEGE",
"HAS_FOREIGN_DATA_WRAPPER_PRIVILEGE",
"HAS_FUNCTION_PRIVILEGE",
"HAS_LANGUAGE_PRIVILEGE",
"HAS_SCHEMA_PRIVILEGE",
"HAS_SEQUENCE_PRIVILEGE",
"HAS_SERVER_PRIVILEGE",
"HAS_TABLESPACE_PRIVILEGE",
"HAS_TABLE_PRIVILEGE",
"HAS_TYPE_PRIVILEGE",
"INET_CLIENT_ADDR",
"INET_CLIENT_PORT",
"INET_SERVER_ADDR",
"INET_SERVER_PORT",
"MAKEACLITEM",
"OBJ_DESCRIPTION",
"PG_BACKEND_PID",
"PG_BLOCKING_PIDS",
"PG_COLLATION_IS_VISIBLE",
"PG_CONF_LOAD_TIME",
"PG_CONTROL_CHECKPOINT",
"PG_CONTROL_INIT",
"PG_CONTROL_SYSTEM",
"PG_CONVERSION_IS_VISIBLE",
"PG_CURRENT_LOGFILE",
"PG_CURRENT_SNAPSHOT",
"PG_CURRENT_XACT_ID",
"PG_CURRENT_XACT_ID_IF_ASSIGNED",
"PG_DESCRIBE_OBJECT",
"PG_FUNCTION_IS_VISIBLE",
"PG_GET_CATALOG_FOREIGN_KEYS",
"PG_GET_CONSTRAINTDEF",
"PG_GET_EXPR",
"PG_GET_FUNCTIONDEF",
"PG_GET_FUNCTION_ARGUMENTS",
"PG_GET_FUNCTION_IDENTITY_ARGUMENTS",
"PG_GET_FUNCTION_RESULT",
"PG_GET_INDEXDEF",
"PG_GET_KEYWORDS",
"PG_GET_OBJECT_ADDRESS",
"PG_GET_OWNED_SEQUENCE",
"PG_GET_RULEDEF",
"PG_GET_SERIAL_SEQUENCE",
"PG_GET_STATISTICSOBJDEF",
"PG_GET_TRIGGERDEF",
"PG_GET_USERBYID",
"PG_GET_VIEWDEF",
"PG_HAS_ROLE",
"PG_IDENTIFY_OBJECT",
"PG_IDENTIFY_OBJECT_AS_ADDRESS",
"PG_INDEXAM_HAS_PROPERTY",
"PG_INDEX_COLUMN_HAS_PROPERTY",
"PG_INDEX_HAS_PROPERTY",
"PG_IS_OTHER_TEMP_SCHEMA",
"PG_JIT_AVAILABLE",
"PG_LAST_COMMITTED_XACT",
"PG_LISTENING_CHANNELS",
"PG_MY_TEMP_SCHEMA",
"PG_NOTIFICATION_QUEUE_USAGE",
"PG_OPCLASS_IS_VISIBLE",
"PG_OPERATOR_IS_VISIBLE",
"PG_OPFAMILY_IS_VISIBLE",
"PG_OPTIONS_TO_TABLE",
"PG_POSTMASTER_START_TIME",
"PG_SAFE_SNAPSHOT_BLOCKING_PIDS",
"PG_SNAPSHOT_XIP",
"PG_SNAPSHOT_XMAX",
"PG_SNAPSHOT_XMIN",
"PG_STATISTICS_OBJ_IS_VISIBLE",
"PG_TABLESPACE_DATABASES",
"PG_TABLESPACE_LOCATION",
"PG_TABLE_IS_VISIBLE",
"PG_TRIGGER_DEPTH",
"PG_TS_CONFIG_IS_VISIBLE",
"PG_TS_DICT_IS_VISIBLE",
"PG_TS_PARSER_IS_VISIBLE",
"PG_TS_TEMPLATE_IS_VISIBLE",
"PG_TYPEOF",
"PG_TYPE_IS_VISIBLE",
"PG_VISIBLE_IN_SNAPSHOT",
"PG_XACT_COMMIT_TIMESTAMP",
"PG_XACT_COMMIT_TIMESTAMP_ORIGIN",
"PG_XACT_STATUS",
"PQSERVERVERSION",
"ROW_SECURITY_ACTIVE",
"SESSION_USER",
"SHOBJ_DESCRIPTION",
"TO_REGCLASS",
"TO_REGCOLLATION",
"TO_REGNAMESPACE",
"TO_REGOPER",
"TO_REGOPERATOR",
"TO_REGPROC",
"TO_REGPROCEDURE",
"TO_REGROLE",
"TO_REGTYPE",
"TXID_CURRENT",
"TXID_CURRENT_IF_ASSIGNED",
"TXID_CURRENT_SNAPSHOT",
"TXID_SNAPSHOT_XIP",
"TXID_SNAPSHOT_XMAX",
"TXID_SNAPSHOT_XMIN",
"TXID_STATUS",
"TXID_VISIBLE_IN_SNAPSHOT",
"USER",
"VERSION",
// https://www.postgresql.org/docs/14/functions-admin.html
"BRIN_DESUMMARIZE_RANGE",
"BRIN_SUMMARIZE_NEW_VALUES",
"BRIN_SUMMARIZE_RANGE",
"CONVERT_FROM",
"CURRENT_SETTING",
"GIN_CLEAN_PENDING_LIST",
"PG_ADVISORY_LOCK",
"PG_ADVISORY_LOCK_SHARED",
"PG_ADVISORY_UNLOCK",
"PG_ADVISORY_UNLOCK_ALL",
"PG_ADVISORY_UNLOCK_SHARED",
"PG_ADVISORY_XACT_LOCK",
"PG_ADVISORY_XACT_LOCK_SHARED",
"PG_BACKUP_START_TIME",
"PG_CANCEL_BACKEND",
"PG_COLLATION_ACTUAL_VERSION",
"PG_COLUMN_COMPRESSION",
"PG_COLUMN_SIZE",
"PG_COPY_LOGICAL_REPLICATION_SLOT",
"PG_COPY_PHYSICAL_REPLICATION_SLOT",
"PG_CREATE_LOGICAL_REPLICATION_SLOT",
"PG_CREATE_PHYSICAL_REPLICATION_SLOT",
"PG_CREATE_RESTORE_POINT",
"PG_CURRENT_WAL_FLUSH_LSN",
"PG_CURRENT_WAL_INSERT_LSN",
"PG_CURRENT_WAL_LSN",
"PG_DATABASE_SIZE",
"PG_DROP_REPLICATION_SLOT",
"PG_EXPORT_SNAPSHOT",
"PG_FILENODE_RELATION",
"PG_GET_WAL_REPLAY_PAUSE_STATE",
"PG_IMPORT_SYSTEM_COLLATIONS",
"PG_INDEXES_SIZE",
"PG_IS_IN_BACKUP",
"PG_IS_IN_RECOVERY",
"PG_IS_WAL_REPLAY_PAUSED",
"PG_LAST_WAL_RECEIVE_LSN",
"PG_LAST_WAL_REPLAY_LSN",
"PG_LAST_XACT_REPLAY_TIMESTAMP",
"PG_LOGICAL_EMIT_MESSAGE",
"PG_LOGICAL_SLOT_GET_BINARY_CHANGES",
"PG_LOGICAL_SLOT_GET_CHANGES",
"PG_LOGICAL_SLOT_PEEK_BINARY_CHANGES",
"PG_LOGICAL_SLOT_PEEK_CHANGES",
"PG_LOG_BACKEND_MEMORY_CONTEXTS",
"PG_LS_ARCHIVE_STATUSDIR",
"PG_LS_DIR",
"PG_LS_LOGDIR",
"PG_LS_TMPDIR",
"PG_LS_WALDIR",
"PG_PARTITION_ANCESTORS",
"PG_PARTITION_ROOT",
"PG_PARTITION_TREE",
"PG_PROMOTE",
"PG_READ_BINARY_FILE",
"PG_READ_FILE",
"PG_RELATION_FILENODE",
"PG_RELATION_FILEPATH",
"PG_RELATION_SIZE",
"PG_RELOAD_CONF",
"PG_REPLICATION_ORIGIN_ADVANCE",
"PG_REPLICATION_ORIGIN_CREATE",
"PG_REPLICATION_ORIGIN_DROP",
"PG_REPLICATION_ORIGIN_OID",
"PG_REPLICATION_ORIGIN_PROGRESS",
"PG_REPLICATION_ORIGIN_SESSION_IS_SETUP",
"PG_REPLICATION_ORIGIN_SESSION_PROGRESS",
"PG_REPLICATION_ORIGIN_SESSION_RESET",
"PG_REPLICATION_ORIGIN_SESSION_SETUP",
"PG_REPLICATION_ORIGIN_XACT_RESET",
"PG_REPLICATION_ORIGIN_XACT_SETUP",
"PG_REPLICATION_SLOT_ADVANCE",
"PG_ROTATE_LOGFILE",
"PG_SIZE_BYTES",
"PG_SIZE_PRETTY",
"PG_START_BACKUP",
"PG_STAT_FILE",
"PG_STOP_BACKUP",
"PG_SWITCH_WAL",
"PG_TABLESPACE_SIZE",
"PG_TABLE_SIZE",
"PG_TERMINATE_BACKEND",
"PG_TOTAL_RELATION_SIZE",
"PG_TRY_ADVISORY_LOCK",
"PG_TRY_ADVISORY_LOCK_SHARED",
"PG_TRY_ADVISORY_XACT_LOCK",
"PG_TRY_ADVISORY_XACT_LOCK_SHARED",
"PG_WALFILE_NAME",
"PG_WALFILE_NAME_OFFSET",
"PG_WAL_LSN_DIFF",
"PG_WAL_REPLAY_PAUSE",
"PG_WAL_REPLAY_RESUME",
"SET_CONFIG",
// https://www.postgresql.org/docs/14/functions-trigger.html
"SUPPRESS_REDUNDANT_UPDATES_TRIGGER",
"TSVECTOR_UPDATE_TRIGGER",
"TSVECTOR_UPDATE_TRIGGER_COLUMN",
// https://www.postgresql.org/docs/14/functions-event-triggers.html
"PG_EVENT_TRIGGER_DDL_COMMANDS",
"PG_EVENT_TRIGGER_DROPPED_OBJECTS",
"PG_EVENT_TRIGGER_TABLE_REWRITE_OID",
"PG_EVENT_TRIGGER_TABLE_REWRITE_REASON",
"PG_GET_OBJECT_ADDRESS",
// https://www.postgresql.org/docs/14/functions-statistics.html
"PG_MCV_LIST_ITEMS",
// cast
"CAST"
], mt = [
// https://www.postgresql.org/docs/14/sql-keywords-appendix.html
"ALL",
"ANALYSE",
"ANALYZE",
"AND",
"ANY",
"AS",
"ASC",
"ASYMMETRIC",
"AUTHORIZATION",
"BETWEEN",
"BINARY",
"BOTH",
"CASE",
"CAST",
"CHECK",
"COLLATE",
"COLLATION",
"COLUMN",
"CONCURRENTLY",
"CONSTRAINT",
"CREATE",
"CROSS",
"CURRENT_CATALOG",
"CURRENT_DATE",
"CURRENT_ROLE",
"CURRENT_SCHEMA",
"CURRENT_TIME",
"CURRENT_TIMESTAMP",
"CURRENT_USER",
"DAY",
"DEFAULT",
"DEFERRABLE",
"DESC",
"DISTINCT",
"DO",
"ELSE",
"END",
"EXCEPT",
"EXISTS",
"FALSE",
"FETCH",
"FILTER",
"FOR",
"FOREIGN",
"FREEZE",
"FROM",
"FULL",
"GRANT",
"GROUP",
"HAVING",
"HOUR",
"ILIKE",
"IN",
"INITIALLY",
"INNER",
"INOUT",
"INTERSECT",
"INTO",
"IS",
"ISNULL",
"JOIN",
"LATERAL",
"LEADING",
"LEFT",
"LIKE",
"LIMIT",
"LOCALTIME",
"LOCALTIMESTAMP",
"MINUTE",
"MONTH",
"NATURAL",
"NOT",
"NOTNULL",
"NULL",
"NULLIF",
"OFFSET",
"ON",
"ONLY",
"OR",
"ORDER",
"OUT",
"OUTER",
"OVER",
"OVERLAPS",
"PLACING",
"PRIMARY",
"REFERENCES",
"RETURNING",
"RIGHT",
"ROW",
"SECOND",
"SELECT",
"SESSION_USER",
"SIMILAR",
"SOME",
"SYMMETRIC",
"TABLE",
"TABLESAMPLE",
"THEN",
"TO",
"TRAILING",
"TRUE",
"UNION",
"UNIQUE",
"USER",
"USING",
"VALUES",
"VARIADIC",
"VERBOSE",
"WHEN",
"WHERE",
"WINDOW",
"WITH",
"WITHIN",
"WITHOUT",
"YEAR"
// requires AS
], Gt = [
// https://www.postgresql.org/docs/current/datatype.html
"ARRAY",
"BIGINT",
"BIT",
"BIT VARYING",
"BOOL",
"BOOLEAN",
"CHAR",
"CHARACTER",
"CHARACTER VARYING",
"DECIMAL",
"DEC",
"DOUBLE",
"ENUM",
"FLOAT",
"INT",
"INTEGER",
"INTERVAL",
"NCHAR",
"NUMERIC",
"JSON",
"JSONB",
"PRECISION",
"REAL",
"SMALLINT",
"TEXT",
"TIME",
"TIMESTAMP",
"TIMESTAMPTZ",
"UUID",
"VARCHAR",
"XML",
"ZONE"
], pt = o(["SELECT [ALL | DISTINCT]"]), ft = o([
// queries
"WITH [RECURSIVE]",
"FROM",
"WHERE",
"GROUP BY [ALL | DISTINCT]",
"HAVING",
"WINDOW",
"PARTITION BY",
"ORDER BY",
"LIMIT",
"OFFSET",
"FETCH {FIRST | NEXT}",
"FOR {UPDATE | NO KEY UPDATE | SHARE | KEY SHARE} [OF]",
// Data manipulation
// - insert:
"INSERT INTO",
"VALUES",
"DEFAULT VALUES",
// - update:
"SET",
// other
"RETURNING"
]), $e = o([
"CREATE [GLOBAL | LOCAL] [TEMPORARY | TEMP | UNLOGGED] TABLE [IF NOT EXISTS]"
]), KE = o([
// - create
"CREATE [OR REPLACE] [TEMP | TEMPORARY] [RECURSIVE] VIEW",
"CREATE [MATERIALIZED] VIEW [IF NOT EXISTS]",
// - update:
"UPDATE [ONLY]",
"WHERE CURRENT OF",
// - insert:
"ON CONFLICT",
// - delete:
"DELETE FROM [ONLY]",
// - drop table:
"DROP TABLE [IF EXISTS]",
// - alter table:
"ALTER TABLE [IF EXISTS] [ONLY]",
"ALTER TABLE ALL IN TABLESPACE",
"RENAME [COLUMN]",
"RENAME TO",
"ADD [COLUMN] [IF NOT EXISTS]",
"DROP [COLUMN] [IF EXISTS]",
"ALTER [COLUMN]",
"SET DATA TYPE",
"{SET | DROP} DEFAULT",
"{SET | DROP} NOT NULL",
// - truncate:
"TRUNCATE [TABLE] [ONLY]",
// other
"SET SCHEMA",
"AFTER",
// https://www.postgresql.org/docs/14/sql-commands.html
"ABORT",
"ALTER AGGREGATE",
"ALTER COLLATION",
"ALTER CONVERSION",
"ALTER DATABASE",
"ALTER DEFAULT PRIVILEGES",
"ALTER DOMAIN",
"ALTER EVENT TRIGGER",
"ALTER EXTENSION",
"ALTER FOREIGN DATA WRAPPER",
"ALTER FOREIGN TABLE",
"ALTER FUNCTION",
"ALTER GROUP",
"ALTER INDEX",
"ALTER LANGUAGE",
"ALTER LARGE OBJECT",
"ALTER MATERIALIZED VIEW",
"ALTER OPERATOR",
"ALTER OPERATOR CLASS",
"ALTER OPERATOR FAMILY",
"ALTER POLICY",
"ALTER PROCEDURE",
"ALTER PUBLICATION",
"ALTER ROLE",
"ALTER ROUTINE",
"ALTER RULE",
"ALTER SCHEMA",
"ALTER SEQUENCE",
"ALTER SERVER",
"ALTER STATISTICS",
"ALTER SUBSCRIPTION",
"ALTER SYSTEM",
"ALTER TABLESPACE",
"ALTER TEXT SEARCH CONFIGURATION",
"ALTER TEXT SEARCH DICTIONARY",
"ALTER TEXT SEARCH PARSER",
"ALTER TEXT SEARCH TEMPLATE",
"ALTER TRIGGER",
"ALTER TYPE",
"ALTER USER",
"ALTER USER MAPPING",
"ALTER VIEW",
"ANALYZE",
"BEGIN",
"CALL",
"CHECKPOINT",
"CLOSE",
"CLUSTER",
"COMMENT ON",
"COMMIT",
"COMMIT PREPARED",
"COPY",
"CREATE ACCESS METHOD",
"CREATE [OR REPLACE] AGGREGATE",
"CREATE CAST",
"CREATE COLLATION",
"CREATE [DEFAULT] CONVERSION",
"CREATE DATABASE",
"CREATE DOMAIN",
"CREATE EVENT TRIGGER",
"CREATE EXTENSION",
"CREATE FOREIGN DATA WRAPPER",
"CREATE FOREIGN TABLE",
"CREATE [OR REPLACE] FUNCTION",
"CREATE GROUP",
"CREATE [UNIQUE] INDEX",
"CREATE [OR REPLACE] [TRUSTED] [PROCEDURAL] LANGUAGE",
"CREATE OPERATOR",
"CREATE OPERATOR CLASS",
"CREATE OPERATOR FAMILY",
"CREATE POLICY",
"CREATE [OR REPLACE] PROCEDURE",
"CREATE PUBLICATION",
"CREATE ROLE",
"CREATE [OR REPLACE] RULE",
"CREATE SCHEMA [AUTHORIZATION]",
"CREATE [TEMPORARY | TEMP | UNLOGGED] SEQUENCE",
"CREATE SERVER",
"CREATE STATISTICS",
"CREATE SUBSCRIPTION",
"CREATE TABLESPACE",
"CREATE TEXT SEARCH CONFIGURATION",
"CREATE TEXT SEARCH DICTIONARY",
"CREATE TEXT SEARCH PARSER",
"CREATE TEXT SEARCH TEMPLATE",
"CREATE [OR REPLACE] TRANSFORM",
"CREATE [OR REPLACE] [CONSTRAINT] TRIGGER",
"CREATE TYPE",
"CREATE USER",
"CREATE USER MAPPING",
"DEALLOCATE",
"DECLARE",
"DISCARD",
"DROP ACCESS METHOD",
"DROP AGGREGATE",
"DROP CAST",
"DROP COLLATION",
"DROP CONVERSION",
"DROP DATABASE",
"DROP DOMAIN",
"DROP EVENT TRIGGER",
"DROP EXTENSION",
"DROP FOREIGN DATA WRAPPER",
"DROP FOREIGN TABLE",
"DROP FUNCTION",
"DROP GROUP",
"DROP IDENTITY",
"DROP INDEX",
"DROP LANGUAGE",
"DROP MATERIALIZED VIEW [IF EXISTS]",
"DROP OPERATOR",
"DROP OPERATOR CLASS",
"DROP OPERATOR FAMILY",
"DROP OWNED",
"DROP POLICY",
"DROP PROCEDURE",
"DROP PUBLICATION",
"DROP ROLE",
"DROP ROUTINE",
"DROP RULE",
"DROP SCHEMA",
"DROP SEQUENCE",
"DROP SERVER",
"DROP STATISTICS",
"DROP SUBSCRIPTION",
"DROP TABLESPACE",
"DROP TEXT SEARCH CONFIGURATION",
"DROP TEXT SEARCH DICTIONARY",
"DROP TEXT SEARCH PARSER",
"DROP TEXT SEARCH TEMPLATE",
"DROP TRANSFORM",
"DROP TRIGGER",
"DROP TYPE",
"DROP USER",
"DROP USER MAPPING",
"DROP VIEW",
"EXECUTE",
"EXPLAIN",
"FETCH",
"GRANT",
"IMPORT FOREIGN SCHEMA",
"LISTEN",
"LOAD",
"LOCK",
"MOVE",
"NOTIFY",
"OVERRIDING SYSTEM VALUE",
"PREPARE",
"PREPARE TRANSACTION",
"REASSIGN OWNED",
"REFRESH MATERIALIZED VIEW",
"REINDEX",
"RELEASE SAVEPOINT",
"RESET [ALL|ROLE|SESSION AUTHORIZATION]",
"REVOKE",
"ROLLBACK",
"ROLLBACK PREPARED",
"ROLLBACK TO SAVEPOINT",
"SAVEPOINT",
"SECURITY LABEL",
"SELECT INTO",
"SET CONSTRAINTS",
"SET ROLE",
"SET SESSION AUTHORIZATION",
"SET TRANSACTION",
"SHOW",
"START TRANSACTION",
"UNLISTEN",
"VACUUM"
]), Bt = o([
"UNION [ALL | DISTINCT]",
"EXCEPT [ALL | DISTINCT]",
"INTERSECT [ALL | DISTINCT]"
]), ht = o([
"JOIN",
"{LEFT | RIGHT | FULL} [OUTER] JOIN",
"{INNER | CROSS} JOIN",
"NATURAL [INNER] JOIN",
"NATURAL {LEFT | RIGHT | FULL} [OUTER] JOIN"
]), Ht = o([
"PRIMARY KEY",
"GENERATED {ALWAYS | BY DEFAULT} AS IDENTITY",
"ON {UPDATE | DELETE} [NO ACTION | RESTRICT | CASCADE | SET NULL | SET DEFAULT]",
"DO {NOTHING | UPDATE}",
"AS MATERIALIZED",
"{ROWS | RANGE | GROUPS} BETWEEN",
// comparison operator
"IS [NOT] DISTINCT FROM",
"NULLS {FIRST | LAST}",
"WITH ORDINALITY"
]), Ft = o([
// https://www.postgresql.org/docs/current/datatype-datetime.html
"[TIMESTAMP | TIME] {WITH | WITHOUT} TIME ZONE"
]), Yt = {
name: "postgresql",
tokenizerOptions: {
reservedSelect: pt,
reservedClauses: [...ft, ...$e, ...KE],
reservedSetOperations: Bt,
reservedJoins: ht,
reservedKeywordPhrases: Ht,
reservedDataTypePhrases: Ft,
reservedKeywords: mt,
reservedDataTypes: Gt,
reservedFunctionNames: dt,
nestedBlockComments: !0,
extraParens: ["[]"],
underscoresInNumbers: !0,
stringTypes: [
"$$",
{ quote: "''-qq", prefixes: ["U&"] },
{ quote: "''-qq-bs", prefixes: ["E"], requirePrefix: !0 },
{ quote: "''-raw", prefixes: ["B", "X"], requirePrefix: !0 }
],
identTypes: [{ quote: '""-qq', prefixes: ["U&"] }],
identChars: { rest: "$" },
paramTypes: { numbered: ["$"] },
operators: [
// Arithmetic
"%",
"^",
"|/",
"||/",
"@",
// Assignment
":=",
// Bitwise
"&",
"|",
"#",
"~",
"<<",
">>",
// Byte comparison
"~>~",
"~<~",
"~>=~",
"~<=~",
// Geometric
"@-@",
"@@",
"##",
"<->",
"&&",
"&<",
"&>",
"<<|",
"&<|",
"|>>",
"|&>",
"<^",
"^>",
"?#",
"?-",
"?|",
"?-|",
"?||",
"@>",
"<@",
"~=",
// JSON
"?",
"@?",
"?&",
"->",
"->>",
"#>",
"#>>",
"#-",
// Named function params
"=>",
// Network address
">>=",
"<<=",
// Pattern matching
"~~",
"~~*",
"!~~",
"!~~*",
// POSIX RegExp
"~",
"~*",
"!~",
"!~*",
// Range/multirange
"-|-",
// String concatenation
"||",
// Text search
"@@@",
"!!",
"^@",
// Trigram/trigraph
"<%",
"%>",
"<<%",
"%>>",
"<<->",
"<->>",
"<<<->",
"<->>>",
// Type cast
"::",
":",
// Custom operators defined by pgvector extension
// https://github.com/pgvector/pgvector#querying
"<#>",
"<=>",
"<+>",
"<~>",
"<%>"
],
operatorKeyword: !0
},
formatOptions: {
alwaysDenseOperators: ["::", ":"],
onelineClauses: [...$e, ...KE],
tabularOnelineClauses: KE
}
}, Vt = [
// https://docs.aws.amazon.com/redshift/latest/dg/c_Aggregate_Functions.html
"ANY_VALUE",
"APPROXIMATE PERCENTILE_DISC",
"AVG",
"COUNT",
"LISTAGG",
"MAX",
"MEDIAN",
"MIN",
"PERCENTILE_CONT",
"STDDEV_SAMP",
"STDDEV_POP",
"SUM",
"VAR_SAMP",
"VAR_POP",
// https://docs.aws.amazon.com/redshift/latest/dg/c_Array_Functions.html
// 'array',
"array_concat",
"array_flatten",
"get_array_length",
"split_to_array",
"subarray",
// https://docs.aws.amazon.com/redshift/latest/dg/c_bitwise_aggregate_functions.html
"BIT_AND",
"BIT_OR",
"BOOL_AND",
"BOOL_OR",
// https://docs.aws.amazon.com/redshift/latest/dg/c_conditional_expressions.html
"COALESCE",
"DECODE",
"GREATEST",
"LEAST",
"NVL",
"NVL2",
"NULLIF",
// https://docs.aws.amazon.com/redshift/latest/dg/Date_functions_header.html
"ADD_MONTHS",
"AT TIME ZONE",
"CONVERT_TIMEZONE",
"CURRENT_DATE",
"CURRENT_TIME",
"CURRENT_TIMESTAMP",
"DATE_CMP",
"DATE_CMP_TIMESTAMP",
"DATE_CMP_TIMESTAMPTZ",
"DATE_PART_YEAR",
"DATEADD",
"DATEDIFF",
"DATE_PART",
"DATE_TRUNC",
"EXTRACT",
"GETDATE",
"INTERVAL_CMP",
"LAST_DAY",
"MONTHS_BETWEEN",
"NEXT_DAY",
"SYSDATE",
"TIMEOFDAY",
"TIMESTAMP_CMP",
"TIMESTAMP_CMP_DATE",
"TIMESTAMP_CMP_TIMESTAMPTZ",
"TIMESTAMPTZ_CMP",
"TIMESTAMPTZ_CMP_DATE",
"TIMESTAMPTZ_CMP_TIMESTAMP",
"TIMEZONE",
"TO_TIMESTAMP",
"TRUNC",
// https://docs.aws.amazon.com/redshift/latest/dg/geospatial-functions.html
"AddBBox",
"DropBBox",
"GeometryType",
"ST_AddPoint",
"ST_Angle",
"ST_Area",
"ST_AsBinary",
"ST_AsEWKB",
"ST_AsEWKT",
"ST_AsGeoJSON",
"ST_AsText",
"ST_Azimuth",
"ST_Boundary",
"ST_Collect",
"ST_Contains",
"ST_ContainsProperly",
"ST_ConvexHull",
"ST_CoveredBy",
"ST_Covers",
"ST_Crosses",
"ST_Dimension",
"ST_Disjoint",
"ST_Distance",
"ST_DistanceSphere",
"ST_DWithin",
"ST_EndPoint",
"ST_Envelope",
"ST_Equals",
"ST_ExteriorRing",
"ST_Force2D",
"ST_Force3D",
"ST_Force3DM",
"ST_Force3DZ",
"ST_Force4D",
"ST_GeometryN",
"ST_GeometryType",
"ST_GeomFromEWKB",
"ST_GeomFromEWKT",
"ST_GeomFromText",
"ST_GeomFromWKB",
"ST_InteriorRingN",
"ST_Intersects",
"ST_IsPolygonCCW",
"ST_IsPolygonCW",
"ST_IsClosed",
"ST_IsCollection",
"ST_IsEmpty",
"ST_IsSimple",
"ST_IsValid",
"ST_Length",
"ST_LengthSphere",
"ST_Length2D",
"ST_LineFromMultiPoint",
"ST_LineInterpolatePoint",
"ST_M",
"ST_MakeEnvelope",
"ST_MakeLine",
"ST_MakePoint",
"ST_MakePolygon",
"ST_MemSize",
"ST_MMax",
"ST_MMin",
"ST_Multi",
"ST_NDims",
"ST_NPoints",
"ST_NRings",
"ST_NumGeometries",
"ST_NumInteriorRings",
"ST_NumPoints",
"ST_Perimeter",
"ST_Perimeter2D",
"ST_Point",
"ST_PointN",
"ST_Points",
"ST_Polygon",
"ST_RemovePoint",
"ST_Reverse",
"ST_SetPoint",
"ST_SetSRID",
"ST_Simplify",
"ST_SRID",
"ST_StartPoint",
"ST_Touches",
"ST_Within",
"ST_X",
"ST_XMax",
"ST_XMin",
"ST_Y",
"ST_YMax",
"ST_YMin",
"ST_Z",
"ST_ZMax",
"ST_ZMin",
"SupportsBBox",
// https://docs.aws.amazon.com/redshift/latest/dg/hash-functions.html
"CHECKSUM",
"FUNC_SHA1",
"FNV_HASH",
"MD5",
"SHA",
"SHA1",
"SHA2",
// https://docs.aws.amazon.com/redshift/latest/dg/hyperloglog-functions.html
"HLL",
"HLL_CREATE_SKETCH",
"HLL_CARDINALITY",
"HLL_COMBINE",
// https://docs.aws.amazon.com/redshift/latest/dg/json-functions.html
"IS_VALID_JSON",
"IS_VALID_JSON_ARRAY",
"JSON_ARRAY_LENGTH",
"JSON_EXTRACT_ARRAY_ELEMENT_TEXT",
"JSON_EXTRACT_PATH_TEXT",
"JSON_PARSE",
"JSON_SERIALIZE",
// https://docs.aws.amazon.com/redshift/latest/dg/Math_functions.html
"ABS",
"ACOS",
"ASIN",
"ATAN",
"ATAN2",
"CBRT",
"CEILING",
"CEIL",
"COS",
"COT",
"DEGREES",
"DEXP",
"DLOG1",
"DLOG10",
"EXP",
"FLOOR",
"LN",
"LOG",
"MOD",
"PI",
"POWER",
"RADIANS",
"RANDOM",
"ROUND",
"SIN",
"SIGN",
"SQRT",
"TAN",
"TO_HEX",
"TRUNC",
// https://docs.aws.amazon.com/redshift/latest/dg/ml-function.html
"EXPLAIN_MODEL",
// https://docs.aws.amazon.com/redshift/latest/dg/String_functions_header.html
"ASCII",
"BPCHARCMP",
"BTRIM",
"BTTEXT_PATTERN_CMP",
"CHAR_LENGTH",
"CHARACTER_LENGTH",
"CHARINDEX",
"CHR",
"COLLATE",
"CONCAT",
"CRC32",
"DIFFERENCE",
"INITCAP",
"LEFT",
"RIGHT",
"LEN",
"LENGTH",
"LOWER",
"LPAD",
"RPAD",
"LTRIM",
"OCTETINDEX",
"OCTET_LENGTH",
"POSITION",
"QUOTE_IDENT",
"QUOTE_LITERAL",
"REGEXP_COUNT",
"REGEXP_INSTR",
"REGEXP_REPLACE",
"REGEXP_SUBSTR",
"REPEAT",
"REPLACE",
"REPLICATE",
"REVERSE",
"RTRIM",
"SOUNDEX",
"SPLIT_PART",
"STRPOS",
"STRTOL",
"SUBSTRING",
"TEXTLEN",
"TRANSLATE",
"TRIM",
"UPPER",
// https://docs.aws.amazon.com/redshift/latest/dg/c_Type_Info_Functions.html
"decimal_precision",
"decimal_scale",
"is_array",
"is_bigint",
"is_boolean",
"is_char",
"is_decimal",
"is_float",
"is_integer",
"is_object",
"is_scalar",
"is_smallint",
"is_varchar",
"json_typeof",
// https://docs.aws.amazon.com/redshift/latest/dg/c_Window_functions.html
"AVG",
"COUNT",
"CUME_DIST",
"DENSE_RANK",
"FIRST_VALUE",
"LAST_VALUE",
"LAG",
"LEAD",
"LISTAGG",
"MAX",
"MEDIAN",
"MIN",
"NTH_VALUE",
"NTILE",
"PERCENT_RANK",
"PERCENTILE_CONT",
"PERCENTILE_DISC",
"RANK",
"RATIO_TO_REPORT",
"ROW_NUMBER",
"STDDEV_SAMP",
"STDDEV_POP",
"SUM",
"VAR_SAMP",
"VAR_POP",
// https://docs.aws.amazon.com/redshift/latest/dg/r_Data_type_formatting.html
"CAST",
"CONVERT",
"TO_CHAR",
"TO_DATE",
"TO_NUMBER",
"TEXT_TO_INT_ALT",
"TEXT_TO_NUMERIC_ALT",
// https://docs.aws.amazon.com/redshift/latest/dg/r_System_administration_functions.html
"CHANGE_QUERY_PRIORITY",
"CHANGE_SESSION_PRIORITY",
"CHANGE_USER_PRIORITY",
"CURRENT_SETTING",
"PG_CANCEL_BACKEND",
"PG_TERMINATE_BACKEND",
"REBOOT_CLUSTER",
"SET_CONFIG",
// https://docs.aws.amazon.com/redshift/latest/dg/r_System_information_functions.html
"CURRENT_AWS_ACCOUNT",
"CURRENT_DATABASE",
"CURRENT_NAMESPACE",
"CURRENT_SCHEMA",
"CURRENT_SCHEMAS",
"CURRENT_USER",
"CURRENT_USER_ID",
"HAS_ASSUMEROLE_PRIVILEGE",
"HAS_DATABASE_PRIVILEGE",
"HAS_SCHEMA_PRIVILEGE",
"HAS_TABLE_PRIVILEGE",
"PG_BACKEND_PID",
"PG_GET_COLS",
"PG_GET_GRANTEE_BY_IAM_ROLE",
"PG_GET_IAM_ROLE_BY_USER",
"PG_GET_LATE_BINDING_VIEW_COLS",
"PG_LAST_COPY_COUNT",
"PG_LAST_COPY_ID",
"PG_LAST_UNLOAD_ID",
"PG_LAST_QUERY_ID",
"PG_LAST_UNLOAD_COUNT",
"SESSION_USER",
"SLICE_NUM",
"USER",
"VERSION"
], bt = [
// https://docs.aws.amazon.com/redshift/latest/dg/r_pg_keywords.html
"AES128",
"AES256",
"ALL",
"ALLOWOVERWRITE",
"ANY",
"AS",
"ASC",
"AUTHORIZATION",
"BACKUP",
"BETWEEN",
"BINARY",
"BOTH",
"CHECK",
"COLUMN",
"CONSTRAINT",
"CREATE",
"CROSS",
"DEFAULT",
"DEFERRABLE",
"DEFLATE",
"DEFRAG",
"DESC",
"DISABLE",
"DISTINCT",
"DO",
"ENABLE",
"ENCODE",
"ENCRYPT",
"ENCRYPTION",
"EXPLICIT",
"FALSE",
"FOR",
"FOREIGN",
"FREEZE",
"FROM",
"FULL",
"GLOBALDICT256",
"GLOBALDICT64K",
"GROUP",
"IDENTITY",
"IGNORE",
"ILIKE",
"IN",
"INITIALLY",
"INNER",
"INTO",
"IS",
"ISNULL",
"LANGUAGE",
"LEADING",
"LIKE",
"LIMIT",
"LOCALTIME",
"LOCALTIMESTAMP",
"LUN",
"LUNS",
"MINUS",
"NATURAL",
"NEW",
"NOT",
"NOTNULL",
"NULL",
"NULLS",
"OFF",
"OFFLINE",
"OFFSET",
"OID",
"OLD",
"ON",
"ONLY",
"OPEN",
"ORDER",
"OUTER",
"OVERLAPS",
"PARALLEL",
"PARTITION",
"PERCENT",
"PERMISSIONS",
"PLACING",
"PRIMARY",
"RECOVER",
"REFERENCES",
"REJECTLOG",
"RESORT",
"RESPECT",
"RESTORE",
"SIMILAR",
"SNAPSHOT",
"SOME",
"SYSTEM",
"TABLE",
"TAG",
"TDES",
"THEN",
"TIMESTAMP",
"TO",
"TOP",
"TRAILING",
"TRUE",
"UNIQUE",
"USING",
"VERBOSE",
"WALLET",
"WITHOUT",
// https://docs.aws.amazon.com/redshift/latest/dg/copy-parameters-data-conversion.html
"ACCEPTANYDATE",
"ACCEPTINVCHARS",
"BLANKSASNULL",
"DATEFORMAT",
"EMPTYASNULL",
"ENCODING",
"ESCAPE",
"EXPLICIT_IDS",
"FILLRECORD",
"IGNOREBLANKLINES",
"IGNOREHEADER",
"REMOVEQUOTES",
"ROUNDEC",
"TIMEFORMAT",
"TRIMBLANKS",
"TRUNCATECOLUMNS",
// https://docs.aws.amazon.com/redshift/latest/dg/copy-parameters-data-load.html
"COMPROWS",
"COMPUPDATE",
"MAXERROR",
"NOLOAD",
"STATUPDATE",
// https://docs.aws.amazon.com/redshift/latest/dg/copy-parameters-data-format.html
"FORMAT",
"CSV",
"DELIMITER",
"FIXEDWIDTH",
"SHAPEFILE",
"AVRO",
"JSON",
"PARQUET",
"ORC",
// https://docs.aws.amazon.com/redshift/latest/dg/copy-parameters-authorization.html
"ACCESS_KEY_ID",
"CREDENTIALS",
"ENCRYPTED",
"IAM_ROLE",
"MASTER_SYMMETRIC_KEY",
"SECRET_ACCESS_KEY",
"SESSION_TOKEN",
// https://docs.aws.amazon.com/redshift/latest/dg/copy-parameters-file-compression.html
"BZIP2",
"GZIP",
"LZOP",
"ZSTD",
// https://docs.aws.amazon.com/redshift/latest/dg/r_COPY-alphabetical-parm-list.html
"MANIFEST",
"READRATIO",
"REGION",
"SSH",
// https://docs.aws.amazon.com/redshift/latest/dg/c_Compression_encodings.html
"RAW",
"AZ64",
"BYTEDICT",
"DELTA",
"DELTA32K",
"LZO",
"MOSTLY8",
"MOSTLY16",
"MOSTLY32",
"RUNLENGTH",
"TEXT255",
"TEXT32K",
// misc
// CREATE EXTERNAL SCHEMA (https://docs.aws.amazon.com/redshift/latest/dg/r_CREATE_EXTERNAL_SCHEMA.html)
"CATALOG_ROLE",
"SECRET_ARN",
"EXTERNAL",
// https://docs.aws.amazon.com/redshift/latest/dg/c_choosing_dist_sort.html
"AUTO",
"EVEN",
"KEY",
"PREDICATE",
// unknown
"COMPRESSION"
/**
* Other keywords not included:
* STL: https://docs.aws.amazon.com/redshift/latest/dg/c_intro_STL_tables.html
* SVCS: https://docs.aws.amazon.com/redshift/latest/dg/svcs_views.html
* SVL: https://docs.aws.amazon.com/redshift/latest/dg/svl_views.html
* SVV: https://docs.aws.amazon.com/redshift/latest/dg/svv_views.html
*/
], gt = [
// https://docs.aws.amazon.com/redshift/latest/dg/r_Character_types.html#r_Character_types-text-and-bpchar-types
"ARRAY",
"BIGINT",
"BPCHAR",
"CHAR",
"CHARACTER VARYING",
"CHARACTER",
"DECIMAL",
"INT",
"INT2",
"INT4",
"INT8",
"INTEGER",
"NCHAR",
"NUMERIC",
"NVARCHAR",
"SMALLINT",
"TEXT",
"VARBYTE",
"VARCHAR"
], Wt = o(["SELECT [ALL | DISTINCT]"]), yt = o([
// queries
"WITH [RECURSIVE]",
"FROM",
"WHERE",
"GROUP BY",
"HAVING",
"QUALIFY",
"PARTITION BY",
"ORDER BY",
"LIMIT",
"OFFSET",
// Data manipulation
// - insert:
"INSERT INTO",
"VALUES",
// - update:
"SET"
]), Ke = o([
"CREATE [TEMPORARY | TEMP | LOCAL TEMPORARY | LOCAL TEMP] TABLE [IF NOT EXISTS]"
]), wE = o([
// - create:
"CREATE [OR REPLACE | MATERIALIZED] VIEW",
// - update:
"UPDATE",
// - delete:
"DELETE [FROM]",
// - drop table:
"DROP TABLE [IF EXISTS]",
// - alter table:
"ALTER TABLE",
"ALTER TABLE APPEND",
"ADD [COLUMN]",
"DROP [COLUMN]",
"RENAME TO",
"RENAME COLUMN",
"ALTER COLUMN",
"TYPE",
"ENCODE",
// - truncate:
"TRUNCATE [TABLE]",
// https://docs.aws.amazon.com/redshift/latest/dg/c_SQL_commands.html
"ABORT",
"ALTER DATABASE",
"ALTER DATASHARE",
"ALTER DEFAULT PRIVILEGES",
"ALTER GROUP",
"ALTER MATERIALIZED VIEW",
"ALTER PROCEDURE",
"ALTER SCHEMA",
"ALTER USER",
"ANALYSE",
"ANALYZE",
"ANALYSE COMPRESSION",
"ANALYZE COMPRESSION",
"BEGIN",
"CALL",
"CANCEL",
"CLOSE",
"COMMIT",
"COPY",
"CREATE DATABASE",
"CREATE DATASHARE",
"CREATE EXTERNAL FUNCTION",
"CREATE EXTERNAL SCHEMA",
"CREATE EXTERNAL TABLE",
"CREATE FUNCTION",
"CREATE GROUP",
"CREATE LIBRARY",
"CREATE MODEL",
"CREATE PROCEDURE",
"CREATE SCHEMA",
"CREATE USER",
"DEALLOCATE",
"DECLARE",
"DESC DATASHARE",
"DROP DATABASE",
"DROP DATASHARE",
"DROP FUNCTION",
"DROP GROUP",
"DROP LIBRARY",
"DROP MODEL",
"DROP MATERIALIZED VIEW",
"DROP PROCEDURE",
"DROP SCHEMA",
"DROP USER",
"DROP VIEW",
"DROP",
"EXECUTE",
"EXPLAIN",
"FETCH",
"GRANT",
"LOCK",
"PREPARE",
"REFRESH MATERIALIZED VIEW",
"RESET",
"REVOKE",
"ROLLBACK",
"SELECT INTO",
"SET SESSION AUTHORIZATION",
"SET SESSION CHARACTERISTICS",
"SHOW",
"SHOW EXTERNAL TABLE",
"SHOW MODEL",
"SHOW DATASHARES",
"SHOW PROCEDURE",
"SHOW TABLE",
"SHOW VIEW",
"START TRANSACTION",
"UNLOAD",
"VACUUM"
]), Xt = o(["UNION [ALL]", "EXCEPT", "INTERSECT", "MINUS"]), $t = o([
"JOIN",
"{LEFT | RIGHT | FULL} [OUTER] JOIN",
"{INNER | CROSS} JOIN",
"NATURAL [INNER] JOIN",
"NATURAL {LEFT | RIGHT | FULL} [OUTER] JOIN"
]), Kt = o([
// https://docs.aws.amazon.com/redshift/latest/dg/copy-parameters-data-conversion.html
"NULL AS",
// https://docs.aws.amazon.com/redshift/latest/dg/r_CREATE_EXTERNAL_SCHEMA.html
"DATA CATALOG",
"HIVE METASTORE",
// in window specifications
"{ROWS | RANGE} BETWEEN"
]), wt = o([]), Jt = {
name: "redshift",
tokenizerOptions: {
reservedSelect: Wt,
reservedClauses: [...yt, ...Ke, ...wE],
reservedSetOperations: Xt,
reservedJoins: $t,
reservedKeywordPhrases: Kt,
reservedDataTypePhrases: wt,
reservedKeywords: bt,
reservedDataTypes: gt,
reservedFunctionNames: Vt,
extraParens: ["[]"],
stringTypes: ["''-qq"],
identTypes: ['""-qq'],
identChars: { first: "#" },
paramTypes: { numbered: ["$"] },
operators: [
"^",
"%",
"@",
"|/",
"||/",
"&",
"|",
// '#', conflicts with first char of identifier
"~",
"<<",
">>",
"||",
"::"
]
},
formatOptions: {
alwaysDenseOperators: ["::"],
onelineClauses: [...Ke, ...wE],
tabularOnelineClauses: wE
}
}, vt = [
// https://deepkb.com/CO_000013/en/kb/IMPORT-fbfa59f0-2bf1-31fe-bb7b-0f9efe9932c6/spark-sql-keywords
"ADD",
"AFTER",
"ALL",
"ALTER",
"ANALYZE",
"AND",
"ANTI",
"ANY",
"ARCHIVE",
"AS",
"ASC",
"AT",
"AUTHORIZATION",
"BETWEEN",
"BOTH",
"BUCKET",
"BUCKETS",
"BY",
"CACHE",
"CASCADE",
"CAST",
"CHANGE",
"CHECK",
"CLEAR",
"CLUSTER",
"CLUSTERED",
"CODEGEN",
"COLLATE",
"COLLECTION",
"COLUMN",
"COLUMNS",
"COMMENT",
"COMMIT",
"COMPACT",
"COMPACTIONS",
"COMPUTE",
"CONCATENATE",
"CONSTRAINT",
"COST",
"CREATE",
"CROSS",
"CUBE",
"CURRENT",
"CURRENT_DATE",
"CURRENT_TIME",
"CURRENT_TIMESTAMP",
"CURRENT_USER",
"DATA",
"DATABASE",
"DATABASES",
"DAY",
"DBPROPERTIES",
"DEFINED",
"DELETE",
"DELIMITED",
"DESC",
"DESCRIBE",
"DFS",
"DIRECTORIES",
"DIRECTORY",
"DISTINCT",
"DISTRIBUTE",
"DIV",
"DROP",
"ESCAPE",
"ESCAPED",
"EXCEPT",
"EXCHANGE",
"EXISTS",
"EXPORT",
"EXTENDED",
"EXTERNAL",
"EXTRACT",
"FALSE",
"FETCH",
"FIELDS",
"FILTER",
"FILEFORMAT",
"FIRST",
"FIRST_VALUE",
"FOLLOWING",
"FOR",
"FOREIGN",
"FORMAT",
"FORMATTED",
"FULL",
"FUNCTION",
"FUNCTIONS",
"GLOBAL",
"GRANT",
"GROUP",
"GROUPING",
"HOUR",
"IF",
"IGNORE",
"IMPORT",
"IN",
"INDEX",
"INDEXES",
"INNER",
"INPATH",
"INPUTFORMAT",
"INTERSECT",
"INTO",
"IS",
"ITEMS",
"KEYS",
"LAST",
"LAST_VALUE",
"LATERAL",
"LAZY",
"LEADING",
"LEFT",
"LIKE",
"LINES",
"LIST",
"LOCAL",
"LOCATION",
"LOCK",
"LOCKS",
"LOGICAL",
"MACRO",
"MATCHED",
"MERGE",
"MINUTE",
"MONTH",
"MSCK",
"NAMESPACE",
"NAMESPACES",
"NATURAL",
"NO",
"NOT",
"NULL",
"NULLS",
"OF",
"ONLY",
"OPTION",
"OPTIONS",
"OR",
"ORDER",
"OUT",
"OUTER",
"OUTPUTFORMAT",
"OVER",
"OVERLAPS",
"OVERLAY",
"OVERWRITE",
"OWNER",
"PARTITION",
"PARTITIONED",
"PARTITIONS",
"PERCENT",
"PLACING",
"POSITION",
"PRECEDING",
"PRIMARY",
"PRINCIPALS",
"PROPERTIES",
"PURGE",
"QUERY",
"RANGE",
"RECORDREADER",
"RECORDWRITER",
"RECOVER",
"REDUCE",
"REFERENCES",
"RENAME",
"REPAIR",
"REPLACE",
"RESPECT",
"RESTRICT",
"REVOKE",
"RIGHT",
"RLIKE",
"ROLE",
"ROLES",
"ROLLBACK",
"ROLLUP",
"ROW",
"ROWS",
"SCHEMA",
"SECOND",
"SELECT",
"SEMI",
"SEPARATED",
"SERDE",
"SERDEPROPERTIES",
"SESSION_USER",
"SETS",
"SHOW",
"SKEWED",
"SOME",
"SORT",
"SORTED",
"START",
"STATISTICS",
"STORED",
"STRATIFY",
"SUBSTR",
"SUBSTRING",
"TABLE",
"TABLES",
"TBLPROPERTIES",
"TEMPORARY",
"TERMINATED",
"THEN",
"TO",
"TOUCH",
"TRAILING",
"TRANSACTION",
"TRANSACTIONS",
"TRIM",
"TRUE",
"TRUNCATE",
"UNARCHIVE",
"UNBOUNDED",
"UNCACHE",
"UNIQUE",
"UNKNOWN",
"UNLOCK",
"UNSET",
"USE",
"USER",
"USING",
"VIEW",
"WINDOW",
"YEAR",
// other
"ANALYSE",
"ARRAY_ZIP",
"COALESCE",
"CONTAINS",
"CONVERT",
"DAYS",
"DAY_HOUR",
"DAY_MINUTE",
"DAY_SECOND",
"DECODE",
"DEFAULT",
"DISTINCTROW",
"ENCODE",
"EXPLODE",
"EXPLODE_OUTER",
"FIXED",
"GREATEST",
"GROUP_CONCAT",
"HOURS",
"HOUR_MINUTE",
"HOUR_SECOND",
"IFNULL",
"LEAST",
"LEVEL",
"MINUTE_SECOND",
"NULLIF",
"OFFSET",
"ON",
"OPTIMIZE",
"REGEXP",
"SEPARATOR",
"SIZE",
"TYPE",
"TYPES",
"UNSIGNED",
"VARIABLES",
"YEAR_MONTH"
], xt = [
// https://spark.apache.org/docs/latest/sql-ref-datatypes.html
"ARRAY",
"BIGINT",
"BINARY",
"BOOLEAN",
"BYTE",
"CHAR",
"DATE",
"DEC",
"DECIMAL",
"DOUBLE",
"FLOAT",
"INT",
"INTEGER",
"INTERVAL",
"LONG",
"MAP",
"NUMERIC",
"REAL",
"SHORT",
"SMALLINT",
"STRING",
"STRUCT",
"TIMESTAMP_LTZ",
"TIMESTAMP_NTZ",
"TIMESTAMP",
"TINYINT",
"VARCHAR"
// No varchar type in Spark, only STRING. Added for the sake of tests
], Qt = [
// http://spark.apache.org/docs/latest/sql-ref-functions.html
//
// http://spark.apache.org/docs/latest/sql-ref-functions-builtin.html#aggregate-functions
// 'ANY',
"APPROX_COUNT_DISTINCT",
"APPROX_PERCENTILE",
"AVG",
"BIT_AND",
"BIT_OR",
"BIT_XOR",
"BOOL_AND",
"BOOL_OR",
"COLLECT_LIST",
"COLLECT_SET",
"CORR",
"COUNT",
"COUNT",
"COUNT",
"COUNT_IF",
"COUNT_MIN_SKETCH",
"COVAR_POP",
"COVAR_SAMP",
"EVERY",
"FIRST",
"FIRST_VALUE",
"GROUPING",
"GROUPING_ID",
"KURTOSIS",
"LAST",
"LAST_VALUE",
"MAX",
"MAX_BY",
"MEAN",
"MIN",
"MIN_BY",
"PERCENTILE",
"PERCENTILE",
"PERCENTILE_APPROX",
"SKEWNESS",
// 'SOME',
"STD",
"STDDEV",
"STDDEV_POP",
"STDDEV_SAMP",
"SUM",
"VAR_POP",
"VAR_SAMP",
"VARIANCE",
// http://spark.apache.org/docs/latest/sql-ref-functions-builtin.html#window-functions
"CUME_DIST",
"DENSE_RANK",
"LAG",
"LEAD",
"NTH_VALUE",
"NTILE",
"PERCENT_RANK",
"RANK",
"ROW_NUMBER",
// http://spark.apache.org/docs/latest/sql-ref-functions-builtin.html#array-functions
"ARRAY",
"ARRAY_CONTAINS",
"ARRAY_DISTINCT",
"ARRAY_EXCEPT",
"ARRAY_INTERSECT",
"ARRAY_JOIN",
"ARRAY_MAX",
"ARRAY_MIN",
"ARRAY_POSITION",
"ARRAY_REMOVE",
"ARRAY_REPEAT",
"ARRAY_UNION",
"ARRAYS_OVERLAP",
"ARRAYS_ZIP",
"FLATTEN",
"SEQUENCE",
"SHUFFLE",
"SLICE",
"SORT_ARRAY",
// http://spark.apache.org/docs/latest/sql-ref-functions-builtin.html#map-functions
"ELEMENT_AT",
"ELEMENT_AT",
"MAP_CONCAT",
"MAP_ENTRIES",
"MAP_FROM_ARRAYS",
"MAP_FROM_ENTRIES",
"MAP_KEYS",
"MAP_VALUES",
"STR_TO_MAP",
// http://spark.apache.org/docs/latest/sql-ref-functions-builtin.html#date-and-timestamp-functions
"ADD_MONTHS",
"CURRENT_DATE",
"CURRENT_DATE",
"CURRENT_TIMESTAMP",
"CURRENT_TIMESTAMP",
"CURRENT_TIMEZONE",
"DATE_ADD",
"DATE_FORMAT",
"DATE_FROM_UNIX_DATE",
"DATE_PART",
"DATE_SUB",
"DATE_TRUNC",
"DATEDIFF",
"DAY",
"DAYOFMONTH",
"DAYOFWEEK",
"DAYOFYEAR",
"EXTRACT",
"FROM_UNIXTIME",
"FROM_UTC_TIMESTAMP",
"HOUR",
"LAST_DAY",
"MAKE_DATE",
"MAKE_DT_INTERVAL",
"MAKE_INTERVAL",
"MAKE_TIMESTAMP",
"MAKE_YM_INTERVAL",
"MINUTE",
"MONTH",
"MONTHS_BETWEEN",
"NEXT_DAY",
"NOW",
"QUARTER",
"SECOND",
"SESSION_WINDOW",
"TIMESTAMP_MICROS",
"TIMESTAMP_MILLIS",
"TIMESTAMP_SECONDS",
"TO_DATE",
"TO_TIMESTAMP",
"TO_UNIX_TIMESTAMP",
"TO_UTC_TIMESTAMP",
"TRUNC",
"UNIX_DATE",
"UNIX_MICROS",
"UNIX_MILLIS",
"UNIX_SECONDS",
"UNIX_TIMESTAMP",
"WEEKDAY",
"WEEKOFYEAR",
"WINDOW",
"YEAR",
// http://spark.apache.org/docs/latest/sql-ref-functions-builtin.html#json-functions
"FROM_JSON",
"GET_JSON_OBJECT",
"JSON_ARRAY_LENGTH",
"JSON_OBJECT_KEYS",
"JSON_TUPLE",
"SCHEMA_OF_JSON",
"TO_JSON",
// http://spark.apache.org/docs/latest/api/sql/index.html
"ABS",
"ACOS",
"ACOSH",
"AGGREGATE",
"ARRAY_SORT",
"ASCII",
"ASIN",
"ASINH",
"ASSERT_TRUE",
"ATAN",
"ATAN2",
"ATANH",
"BASE64",
"BIN",
"BIT_COUNT",
"BIT_GET",
"BIT_LENGTH",
"BROUND",
"BTRIM",
"CARDINALITY",
"CBRT",
"CEIL",
"CEILING",
"CHAR_LENGTH",
"CHARACTER_LENGTH",
"CHR",
"CONCAT",
"CONCAT_WS",
"CONV",
"COS",
"COSH",
"COT",
"CRC32",
"CURRENT_CATALOG",
"CURRENT_DATABASE",
"CURRENT_USER",
"DEGREES",
// 'E',
"ELT",
"EXP",
"EXPM1",
"FACTORIAL",
"FIND_IN_SET",
"FLOOR",
"FORALL",
"FORMAT_NUMBER",
"FORMAT_STRING",
"FROM_CSV",
"GETBIT",
"HASH",
"HEX",
"HYPOT",
"INITCAP",
"INLINE",
"INLINE_OUTER",
"INPUT_FILE_BLOCK_LENGTH",
"INPUT_FILE_BLOCK_START",
"INPUT_FILE_NAME",
"INSTR",
"ISNAN",
"ISNOTNULL",
"ISNULL",
"JAVA_METHOD",
"LCASE",
"LEFT",
"LENGTH",
"LEVENSHTEIN",
"LN",
"LOCATE",
"LOG",
"LOG10",
"LOG1P",
"LOG2",
"LOWER",
"LPAD",
"LTRIM",
"MAP_FILTER",
"MAP_ZIP_WITH",
"MD5",
"MOD",
"MONOTONICALLY_INCREASING_ID",
"NAMED_STRUCT",
"NANVL",
"NEGATIVE",
"NVL",
"NVL2",
"OCTET_LENGTH",
"OVERLAY",
"PARSE_URL",
"PI",
"PMOD",
"POSEXPLODE",
"POSEXPLODE_OUTER",
"POSITION",
"POSITIVE",
"POW",
"POWER",
"PRINTF",
"RADIANS",
"RAISE_ERROR",
"RAND",
"RANDN",
"RANDOM",
"REFLECT",
"REGEXP_EXTRACT",
"REGEXP_EXTRACT_ALL",
"REGEXP_LIKE",
"REGEXP_REPLACE",
"REPEAT",
"REPLACE",
"REVERSE",
"RIGHT",
"RINT",
"ROUND",
"RPAD",
"RTRIM",
"SCHEMA_OF_CSV",
"SENTENCES",
"SHA",
"SHA1",
"SHA2",
"SHIFTLEFT",
"SHIFTRIGHT",
"SHIFTRIGHTUNSIGNED",
"SIGN",
"SIGNUM",
"SIN",
"SINH",
"SOUNDEX",
"SPACE",
"SPARK_PARTITION_ID",
"SPLIT",
"SQRT",
"STACK",
"SUBSTR",
"SUBSTRING",
"SUBSTRING_INDEX",
"TAN",
"TANH",
"TO_CSV",
"TRANSFORM_KEYS",
"TRANSFORM_VALUES",
"TRANSLATE",
"TRIM",
"TRY_ADD",
"TRY_DIVIDE",
"TYPEOF",
"UCASE",
"UNBASE64",
"UNHEX",
"UPPER",
"UUID",
"VERSION",
"WIDTH_BUCKET",
"XPATH",
"XPATH_BOOLEAN",
"XPATH_DOUBLE",
"XPATH_FLOAT",
"XPATH_INT",
"XPATH_LONG",
"XPATH_NUMBER",
"XPATH_SHORT",
"XPATH_STRING",
"XXHASH64",
"ZIP_WITH",
// cast
"CAST",
// Shorthand functions to use in place of CASE expression
"COALESCE",
"NULLIF"
], Zt = o(["SELECT [ALL | DISTINCT]"]), jt = o([
// queries
"WITH",
"FROM",
"WHERE",
"GROUP BY",
"HAVING",
"WINDOW",
"PARTITION BY",
"ORDER BY",
"SORT BY",
"CLUSTER BY",
"DISTRIBUTE BY",
"LIMIT",
// Data manipulation
// - insert:
"INSERT [INTO | OVERWRITE] [TABLE]",
"VALUES",
// - insert overwrite directory:
// https://spark.apache.org/docs/latest/sql-ref-syntax-dml-insert-overwrite-directory.html
"INSERT OVERWRITE [LOCAL] DIRECTORY",
// - load:
// https://spark.apache.org/docs/latest/sql-ref-syntax-dml-load.html
"LOAD DATA [LOCAL] INPATH",
"[OVERWRITE] INTO TABLE"
]), we = o(["CREATE [EXTERNAL] TABLE [IF NOT EXISTS]"]), JE = o([
// - create:
"CREATE [OR REPLACE] [GLOBAL TEMPORARY | TEMPORARY] VIEW [IF NOT EXISTS]",
// - drop table:
"DROP TABLE [IF EXISTS]",
// - alter table:
"ALTER TABLE",
"ADD COLUMNS",
"DROP {COLUMN | COLUMNS}",
"RENAME TO",
"RENAME COLUMN",
"ALTER COLUMN",
// - truncate:
"TRUNCATE TABLE",
// other
"LATERAL VIEW",
"ALTER DATABASE",
"ALTER VIEW",
"CREATE DATABASE",
"CREATE FUNCTION",
"DROP DATABASE",
"DROP FUNCTION",
"DROP VIEW",
"REPAIR TABLE",
"USE DATABASE",
// Data Retrieval
"TABLESAMPLE",
"PIVOT",
"TRANSFORM",
"EXPLAIN",
// Auxiliary
"ADD FILE",
"ADD JAR",
"ANALYZE TABLE",
"CACHE TABLE",
"CLEAR CACHE",
"DESCRIBE DATABASE",
"DESCRIBE FUNCTION",
"DESCRIBE QUERY",
"DESCRIBE TABLE",
"LIST FILE",
"LIST JAR",
"REFRESH",
"REFRESH TABLE",
"REFRESH FUNCTION",
"RESET",
"SHOW COLUMNS",
"SHOW CREATE TABLE",
"SHOW DATABASES",
"SHOW FUNCTIONS",
"SHOW PARTITIONS",
"SHOW TABLE EXTENDED",
"SHOW TABLES",
"SHOW TBLPROPERTIES",
"SHOW VIEWS",
"UNCACHE TABLE"
]), qt = o([
"UNION [ALL | DISTINCT]",
"EXCEPT [ALL | DISTINCT]",
"INTERSECT [ALL | DISTINCT]"
]), kt = o([
"JOIN",
"{LEFT | RIGHT | FULL} [OUTER] JOIN",
"{INNER | CROSS} JOIN",
"NATURAL [INNER] JOIN",
"NATURAL {LEFT | RIGHT | FULL} [OUTER] JOIN",
// non-standard-joins
"[LEFT] {ANTI | SEMI} JOIN",
"NATURAL [LEFT] {ANTI | SEMI} JOIN"
]), zt = o([
"ON DELETE",
"ON UPDATE",
"CURRENT ROW",
"{ROWS | RANGE} BETWEEN"
]), Es = o([]), es = {
name: "spark",
tokenizerOptions: {
reservedSelect: Zt,
reservedClauses: [...jt, ...we, ...JE],
reservedSetOperations: qt,
reservedJoins: kt,
reservedKeywordPhrases: zt,
reservedDataTypePhrases: Es,
supportsXor: !0,
reservedKeywords: vt,
reservedDataTypes: xt,
reservedFunctionNames: Qt,
extraParens: ["[]"],
stringTypes: [
"''-bs",
'""-bs',
{ quote: "''-raw", prefixes: ["R", "X"], requirePrefix: !0 },
{ quote: '""-raw', prefixes: ["R", "X"], requirePrefix: !0 }
],
identTypes: ["``"],
identChars: { allowFirstCharNumber: !0 },
variableTypes: [{ quote: "{}", prefixes: ["$"], requirePrefix: !0 }],
operators: ["%", "~", "^", "|", "&", "<=>", "==", "!", "||", "->"],
postProcess: Ts
},
formatOptions: {
onelineClauses: [...we, ...JE],
tabularOnelineClauses: JE
}
};
function Ts(T) {
return T.map((E, e) => {
const R = T[e - 1] || TE, A = T[e + 1] || TE;
return j.WINDOW(E) && A.type === l.OPEN_PAREN ? Object.assign(Object.assign({}, E), { type: l.RESERVED_FUNCTION_NAME }) : E.text === "ITEMS" && E.type === l.RESERVED_KEYWORD && !(R.text === "COLLECTION" && A.text === "TERMINATED") ? Object.assign(Object.assign({}, E), { type: l.IDENTIFIER, text: E.raw }) : E;
});
}
const Rs = [
// https://www.sqlite.org/lang_corefunc.html
"ABS",
"CHANGES",
"CHAR",
"COALESCE",
"FORMAT",
"GLOB",
"HEX",
"IFNULL",
"IIF",
"INSTR",
"LAST_INSERT_ROWID",
"LENGTH",
"LIKE",
"LIKELIHOOD",
"LIKELY",
"LOAD_EXTENSION",
"LOWER",
"LTRIM",
"NULLIF",
"PRINTF",
"QUOTE",
"RANDOM",
"RANDOMBLOB",
"REPLACE",
"ROUND",
"RTRIM",
"SIGN",
"SOUNDEX",
"SQLITE_COMPILEOPTION_GET",
"SQLITE_COMPILEOPTION_USED",
"SQLITE_OFFSET",
"SQLITE_SOURCE_ID",
"SQLITE_VERSION",
"SUBSTR",
"SUBSTRING",
"TOTAL_CHANGES",
"TRIM",
"TYPEOF",
"UNICODE",
"UNLIKELY",
"UPPER",
"ZEROBLOB",
// https://www.sqlite.org/lang_aggfunc.html
"AVG",
"COUNT",
"GROUP_CONCAT",
"MAX",
"MIN",
"SUM",
"TOTAL",
// https://www.sqlite.org/lang_datefunc.html
"DATE",
"TIME",
"DATETIME",
"JULIANDAY",
"UNIXEPOCH",
"STRFTIME",
// https://www.sqlite.org/windowfunctions.html#biwinfunc
"row_number",
"rank",
"dense_rank",
"percent_rank",
"cume_dist",
"ntile",
"lag",
"lead",
"first_value",
"last_value",
"nth_value",
// https://www.sqlite.org/lang_mathfunc.html
"ACOS",
"ACOSH",
"ASIN",
"ASINH",
"ATAN",
"ATAN2",
"ATANH",
"CEIL",
"CEILING",
"COS",
"COSH",
"DEGREES",
"EXP",
"FLOOR",
"LN",
"LOG",
"LOG",
"LOG10",
"LOG2",
"MOD",
"PI",
"POW",
"POWER",
"RADIANS",
"SIN",
"SINH",
"SQRT",
"TAN",
"TANH",
"TRUNC",
// https://www.sqlite.org/json1.html
"JSON",
"JSON_ARRAY",
"JSON_ARRAY_LENGTH",
"JSON_ARRAY_LENGTH",
"JSON_EXTRACT",
"JSON_INSERT",
"JSON_OBJECT",
"JSON_PATCH",
"JSON_REMOVE",
"JSON_REPLACE",
"JSON_SET",
"JSON_TYPE",
"JSON_TYPE",
"JSON_VALID",
"JSON_QUOTE",
"JSON_GROUP_ARRAY",
"JSON_GROUP_OBJECT",
"JSON_EACH",
"JSON_TREE",
// cast
"CAST"
], As = [
// https://www.sqlite.org/lang_keywords.html
// Note: The keywords listed on that URL are not all reserved keywords.
// We'll need to clean up this list to only include reserved keywords.
"ABORT",
"ACTION",
"ADD",
"AFTER",
"ALL",
"ALTER",
"AND",
"ARE",
"ALWAYS",
"ANALYZE",
"AS",
"ASC",
"ATTACH",
"AUTOINCREMENT",
"BEFORE",
"BEGIN",
"BETWEEN",
"BY",
"CASCADE",
"CASE",
"CAST",
"CHECK",
"COLLATE",
"COLUMN",
"COMMIT",
"CONFLICT",
"CONSTRAINT",
"CREATE",
"CROSS",
"CURRENT",
"CURRENT_DATE",
"CURRENT_TIME",
"CURRENT_TIMESTAMP",
"DATABASE",
"DEFAULT",
"DEFERRABLE",
"DEFERRED",
"DELETE",
"DESC",
"DETACH",
"DISTINCT",
"DO",
"DROP",
"EACH",
"ELSE",
"END",
"ESCAPE",
"EXCEPT",
"EXCLUDE",
"EXCLUSIVE",
"EXISTS",
"EXPLAIN",
"FAIL",
"FILTER",
"FIRST",
"FOLLOWING",
"FOR",
"FOREIGN",
"FROM",
"FULL",
"GENERATED",
"GLOB",
"GROUP",
"HAVING",
"IF",
"IGNORE",
"IMMEDIATE",
"IN",
"INDEX",
"INDEXED",
"INITIALLY",
"INNER",
"INSERT",
"INSTEAD",
"INTERSECT",
"INTO",
"IS",
"ISNULL",
"JOIN",
"KEY",
"LAST",
"LEFT",
"LIKE",
"LIMIT",
"MATCH",
"MATERIALIZED",
"NATURAL",
"NO",
"NOT",
"NOTHING",
"NOTNULL",
"NULL",
"NULLS",
"OF",
"OFFSET",
"ON",
"ONLY",
"OPEN",
"OR",
"ORDER",
"OTHERS",
"OUTER",
"OVER",
"PARTITION",
"PLAN",
"PRAGMA",
"PRECEDING",
"PRIMARY",
"QUERY",
"RAISE",
"RANGE",
"RECURSIVE",
"REFERENCES",
"REGEXP",
"REINDEX",
"RELEASE",
"RENAME",
"REPLACE",
"RESTRICT",
"RETURNING",
"RIGHT",
"ROLLBACK",
"ROW",
"ROWS",
"SAVEPOINT",
"SELECT",
"SET",
"TABLE",
"TEMP",
"TEMPORARY",
"THEN",
"TIES",
"TO",
"TRANSACTION",
"TRIGGER",
"UNBOUNDED",
"UNION",
"UNIQUE",
"UPDATE",
"USING",
"VACUUM",
"VALUES",
"VIEW",
"VIRTUAL",
"WHEN",
"WHERE",
"WINDOW",
"WITH",
"WITHOUT"
], ts = [
// SQLite allows any word as a data type, e.g. CREATE TABLE foo (col1 madeupname(123));
// Here we just list some common ones as SQL Formatter
// is only able to detect a predefined list of data types.
// https://www.sqlite.org/stricttables.html
// https://www.sqlite.org/datatype3.html
"ANY",
"ARRAY",
"BLOB",
"CHARACTER",
"DECIMAL",
"INT",
"INTEGER",
"NATIVE CHARACTER",
"NCHAR",
"NUMERIC",
"NVARCHAR",
"REAL",
"TEXT",
"VARCHAR",
"VARYING CHARACTER"
], ss = o(["SELECT [ALL | DISTINCT]"]), Ss = o([
// queries
"WITH [RECURSIVE]",
"FROM",
"WHERE",
"GROUP BY",
"HAVING",
"WINDOW",
"PARTITION BY",
"ORDER BY",
"LIMIT",
"OFFSET",
// Data manipulation
// - insert:
"INSERT [OR ABORT | OR FAIL | OR IGNORE | OR REPLACE | OR ROLLBACK] INTO",
"REPLACE INTO",
"VALUES",
// - update:
"SET",
// other:
"RETURNING"
]), Je = o(["CREATE [TEMPORARY | TEMP] TABLE [IF NOT EXISTS]"]), vE = o([
// - create:
"CREATE [TEMPORARY | TEMP] VIEW [IF NOT EXISTS]",
// - update:
"UPDATE [OR ABORT | OR FAIL | OR IGNORE | OR REPLACE | OR ROLLBACK]",
// - insert:
"ON CONFLICT",
// - delete:
"DELETE FROM",
// - drop table:
"DROP TABLE [IF EXISTS]",
// - alter table:
"ALTER TABLE",
"ADD [COLUMN]",
"DROP [COLUMN]",
"RENAME [COLUMN]",
"RENAME TO",
// - set schema
"SET SCHEMA"
]), Ns = o(["UNION [ALL]", "EXCEPT", "INTERSECT"]), Is = o([
"JOIN",
"{LEFT | RIGHT | FULL} [OUTER] JOIN",
"{INNER | CROSS} JOIN",
"NATURAL [INNER] JOIN",
"NATURAL {LEFT | RIGHT | FULL} [OUTER] JOIN"
]), Os = o([
"ON {UPDATE | DELETE} [SET NULL | SET DEFAULT]",
"{ROWS | RANGE | GROUPS} BETWEEN",
"DO UPDATE"
]), ns = o([]), rs = {
name: "sqlite",
tokenizerOptions: {
reservedSelect: ss,
reservedClauses: [...Ss, ...Je, ...vE],
reservedSetOperations: Ns,
reservedJoins: Is,
reservedKeywordPhrases: Os,
reservedDataTypePhrases: ns,
reservedKeywords: As,
reservedDataTypes: ts,
reservedFunctionNames: Rs,
stringTypes: [
"''-qq",
{ quote: "''-raw", prefixes: ["X"], requirePrefix: !0 }
// Depending on context SQLite also supports double-quotes for strings,
// and single-quotes for identifiers.
],
identTypes: ['""-qq', "``", "[]"],
// https://www.sqlite.org/lang_expr.html#parameters
paramTypes: { positional: !0, numbered: ["?"], named: [":", "@", "$"] },
operators: ["%", "~", "&", "|", "<<", ">>", "==", "->", "->>", "||"]
},
formatOptions: {
onelineClauses: [...Je, ...vE],
tabularOnelineClauses: vE
}
}, is = [
// https://jakewheat.github.io/sql-overview/sql-2008-foundation-grammar.html#_6_9_set_function_specification
"GROUPING",
// https://jakewheat.github.io/sql-overview/sql-2008-foundation-grammar.html#_6_10_window_function
"RANK",
"DENSE_RANK",
"PERCENT_RANK",
"CUME_DIST",
"ROW_NUMBER",
// https://jakewheat.github.io/sql-overview/sql-2008-foundation-grammar.html#_6_27_numeric_value_function
"POSITION",
"OCCURRENCES_REGEX",
"POSITION_REGEX",
"EXTRACT",
"CHAR_LENGTH",
"CHARACTER_LENGTH",
"OCTET_LENGTH",
"CARDINALITY",
"ABS",
"MOD",
"LN",
"EXP",
"POWER",
"SQRT",
"FLOOR",
"CEIL",
"CEILING",
"WIDTH_BUCKET",
// https://jakewheat.github.io/sql-overview/sql-2008-foundation-grammar.html#_6_29_string_value_function
"SUBSTRING",
"SUBSTRING_REGEX",
"UPPER",
"LOWER",
"CONVERT",
"TRANSLATE",
"TRANSLATE_REGEX",
"TRIM",
"OVERLAY",
"NORMALIZE",
"SPECIFICTYPE",
// https://jakewheat.github.io/sql-overview/sql-2008-foundation-grammar.html#_6_31_datetime_value_function
"CURRENT_DATE",
"CURRENT_TIME",
"LOCALTIME",
"CURRENT_TIMESTAMP",
"LOCALTIMESTAMP",
// https://jakewheat.github.io/sql-overview/sql-2008-foundation-grammar.html#_6_38_multiset_value_function
// SET serves multiple roles: a SET() function and a SET keyword e.g. in UPDATE table SET ...
// multiset
// 'SET', (disabled for now)
// https://jakewheat.github.io/sql-overview/sql-2008-foundation-grammar.html#_10_9_aggregate_function
"COUNT",
"AVG",
"MAX",
"MIN",
"SUM",
// 'EVERY',
// 'ANY',
// 'SOME',
"STDDEV_POP",
"STDDEV_SAMP",
"VAR_SAMP",
"VAR_POP",
"COLLECT",
"FUSION",
"INTERSECTION",
"COVAR_POP",
"COVAR_SAMP",
"CORR",
"REGR_SLOPE",
"REGR_INTERCEPT",
"REGR_COUNT",
"REGR_R2",
"REGR_AVGX",
"REGR_AVGY",
"REGR_SXX",
"REGR_SYY",
"REGR_SXY",
"PERCENTILE_CONT",
"PERCENTILE_DISC",
// CAST is a pretty complex case, involving multiple forms:
// - CAST(col AS int)
// - CAST(...) WITH ...
// - CAST FROM int
// - CREATE CAST(mycol AS int) WITH ...
"CAST",
// Shorthand functions to use in place of CASE expression
"COALESCE",
"NULLIF",
// Non-standard functions that have widespread support
"ROUND",
"SIN",
"COS",
"TAN",
"ASIN",
"ACOS",
"ATAN"
], as = [
// https://jakewheat.github.io/sql-overview/sql-2008-foundation-grammar.html#reserved-word
"ALL",
"ALLOCATE",
"ALTER",
"ANY",
"ARE",
"AS",
"ASC",
"ASENSITIVE",
"ASYMMETRIC",
"AT",
"ATOMIC",
"AUTHORIZATION",
"BEGIN",
"BETWEEN",
"BOTH",
"BY",
"CALL",
"CALLED",
"CASCADED",
"CAST",
"CHECK",
"CLOSE",
"COALESCE",
"COLLATE",
"COLUMN",
"COMMIT",
"CONDITION",
"CONNECT",
"CONSTRAINT",
"CORRESPONDING",
"CREATE",
"CROSS",
"CUBE",
"CURRENT",
"CURRENT_CATALOG",
"CURRENT_DEFAULT_TRANSFORM_GROUP",
"CURRENT_PATH",
"CURRENT_ROLE",
"CURRENT_SCHEMA",
"CURRENT_TRANSFORM_GROUP_FOR_TYPE",
"CURRENT_USER",
"CURSOR",
"CYCLE",
"DEALLOCATE",
"DAY",
"DECLARE",
"DEFAULT",
"DELETE",
"DEREF",
"DESC",
"DESCRIBE",
"DETERMINISTIC",
"DISCONNECT",
"DISTINCT",
"DROP",
"DYNAMIC",
"EACH",
"ELEMENT",
"END-EXEC",
"ESCAPE",
"EVERY",
"EXCEPT",
"EXEC",
"EXECUTE",
"EXISTS",
"EXTERNAL",
"FALSE",
"FETCH",
"FILTER",
"FOR",
"FOREIGN",
"FREE",
"FROM",
"FULL",
"FUNCTION",
"GET",
"GLOBAL",
"GRANT",
"GROUP",
"HAVING",
"HOLD",
"HOUR",
"IDENTITY",
"IN",
"INDICATOR",
"INNER",
"INOUT",
"INSENSITIVE",
"INSERT",
"INTERSECT",
"INTO",
"IS",
"LANGUAGE",
"LARGE",
"LATERAL",
"LEADING",
"LEFT",
"LIKE",
"LIKE_REGEX",
"LOCAL",
"MATCH",
"MEMBER",
"MERGE",
"METHOD",
"MINUTE",
"MODIFIES",
"MODULE",
"MONTH",
"NATURAL",
"NEW",
"NO",
"NONE",
"NOT",
"NULL",
"NULLIF",
"OF",
"OLD",
"ON",
"ONLY",
"OPEN",
"ORDER",
"OUT",
"OUTER",
"OVER",
"OVERLAPS",
"PARAMETER",
"PARTITION",
"PRECISION",
"PREPARE",
"PRIMARY",
"PROCEDURE",
"RANGE",
"READS",
"REAL",
"RECURSIVE",
"REF",
"REFERENCES",
"REFERENCING",
"RELEASE",
"RESULT",
"RETURN",
"RETURNS",
"REVOKE",
"RIGHT",
"ROLLBACK",
"ROLLUP",
"ROW",
"ROWS",
"SAVEPOINT",
"SCOPE",
"SCROLL",
"SEARCH",
"SECOND",
"SELECT",
"SENSITIVE",
"SESSION_USER",
"SET",
"SIMILAR",
"SOME",
"SPECIFIC",
"SQL",
"SQLEXCEPTION",
"SQLSTATE",
"SQLWARNING",
"START",
"STATIC",
"SUBMULTISET",
"SYMMETRIC",
"SYSTEM",
"SYSTEM_USER",
"TABLE",
"TABLESAMPLE",
"THEN",
"TIMEZONE_HOUR",
"TIMEZONE_MINUTE",
"TO",
"TRAILING",
"TRANSLATION",
"TREAT",
"TRIGGER",
"TRUE",
"UESCAPE",
"UNION",
"UNIQUE",
"UNKNOWN",
"UNNEST",
"UPDATE",
"USER",
"USING",
"VALUE",
"VALUES",
"WHENEVER",
"WINDOW",
"WITHIN",
"WITHOUT",
"YEAR"
], Cs = [
// https://jakewheat.github.io/sql-overview/sql-2008-foundation-grammar.html#_6_1_data_type
"ARRAY",
"BIGINT",
"BINARY LARGE OBJECT",
"BINARY VARYING",
"BINARY",
"BLOB",
"BOOLEAN",
"CHAR LARGE OBJECT",
"CHAR VARYING",
"CHAR",
"CHARACTER LARGE OBJECT",
"CHARACTER VARYING",
"CHARACTER",
"CLOB",
"DATE",
"DEC",
"DECIMAL",
"DOUBLE",
"FLOAT",
"INT",
"INTEGER",
"INTERVAL",
"MULTISET",
"NATIONAL CHAR VARYING",
"NATIONAL CHAR",
"NATIONAL CHARACTER LARGE OBJECT",
"NATIONAL CHARACTER VARYING",
"NATIONAL CHARACTER",
"NCHAR LARGE OBJECT",
"NCHAR VARYING",
"NCHAR",
"NCLOB",
"NUMERIC",
"SMALLINT",
"TIME",
"TIMESTAMP",
"VARBINARY",
"VARCHAR"
], os = o(["SELECT [ALL | DISTINCT]"]), Ls = o([
// queries
"WITH [RECURSIVE]",
"FROM",
"WHERE",
"GROUP BY [ALL | DISTINCT]",
"HAVING",
"WINDOW",
"PARTITION BY",
"ORDER BY",
"LIMIT",
"OFFSET",
"FETCH {FIRST | NEXT}",
// Data manipulation
// - insert:
"INSERT INTO",
"VALUES",
// - update:
"SET"
]), ve = o(["CREATE [GLOBAL TEMPORARY | LOCAL TEMPORARY] TABLE"]), xE = o([
// - create:
"CREATE [RECURSIVE] VIEW",
// - update:
"UPDATE",
"WHERE CURRENT OF",
// - delete:
"DELETE FROM",
// - drop table:
"DROP TABLE",
// - alter table:
"ALTER TABLE",
"ADD COLUMN",
"DROP [COLUMN]",
"RENAME COLUMN",
"RENAME TO",
"ALTER [COLUMN]",
"{SET | DROP} DEFAULT",
"ADD SCOPE",
"DROP SCOPE {CASCADE | RESTRICT}",
"RESTART WITH",
// - truncate:
"TRUNCATE TABLE",
// other
"SET SCHEMA"
]), _s = o([
"UNION [ALL | DISTINCT]",
"EXCEPT [ALL | DISTINCT]",
"INTERSECT [ALL | DISTINCT]"
]), Ds = o([
"JOIN",
"{LEFT | RIGHT | FULL} [OUTER] JOIN",
"{INNER | CROSS} JOIN",
"NATURAL [INNER] JOIN",
"NATURAL {LEFT | RIGHT | FULL} [OUTER] JOIN"
]), Ps = o([
"ON {UPDATE | DELETE} [SET NULL | SET DEFAULT]",
"{ROWS | RANGE} BETWEEN"
]), ls = o([]), cs = {
name: "sql",
tokenizerOptions: {
reservedSelect: os,
reservedClauses: [...Ls, ...ve, ...xE],
reservedSetOperations: _s,
reservedJoins: Ds,
reservedKeywordPhrases: Ps,
reservedDataTypePhrases: ls,
reservedKeywords: as,
reservedDataTypes: Cs,
reservedFunctionNames: is,
stringTypes: [
{ quote: "''-qq-bs", prefixes: ["N", "U&"] },
{ quote: "''-raw", prefixes: ["X"], requirePrefix: !0 }
],
identTypes: ['""-qq', "``"],
paramTypes: { positional: !0 },
operators: ["||"]
},
formatOptions: {
onelineClauses: [...ve, ...xE],
tabularOnelineClauses: xE
}
}, Ms = [
// https://github.com/trinodb/trino/tree/432d2897bdef99388c1a47188743a061c4ac1f34/docs/src/main/sphinx/functions
// rg '^\.\. function::' ./docs/src/main/sphinx/functions | cut -d' ' -f 3 | cut -d '(' -f 1 | sort | uniq
// rg '\* ' ./docs/src/main/sphinx/functions/list-by-topic.rst | grep '\* :func:' | cut -d'`' -f 2
// rg '\* ' ./docs/src/main/sphinx/functions/list-by-topic.rst | grep -v '\* :func:'
// grep -e '^- ' ./docs/src/main/sphinx/functions/list.rst | grep -e '^- :func:' | cut -d'`' -f2
// grep -e '^- ' ./docs/src/main/sphinx/functions/list.rst | grep -ve '^- :func:'
"ABS",
"ACOS",
"ALL_MATCH",
"ANY_MATCH",
"APPROX_DISTINCT",
"APPROX_MOST_FREQUENT",
"APPROX_PERCENTILE",
"APPROX_SET",
"ARBITRARY",
"ARRAYS_OVERLAP",
"ARRAY_AGG",
"ARRAY_DISTINCT",
"ARRAY_EXCEPT",
"ARRAY_INTERSECT",
"ARRAY_JOIN",
"ARRAY_MAX",
"ARRAY_MIN",
"ARRAY_POSITION",
"ARRAY_REMOVE",
"ARRAY_SORT",
"ARRAY_UNION",
"ASIN",
"ATAN",
"ATAN2",
"AT_TIMEZONE",
"AVG",
"BAR",
"BETA_CDF",
"BING_TILE",
"BING_TILES_AROUND",
"BING_TILE_AT",
"BING_TILE_COORDINATES",
"BING_TILE_POLYGON",
"BING_TILE_QUADKEY",
"BING_TILE_ZOOM_LEVEL",
"BITWISE_AND",
"BITWISE_AND_AGG",
"BITWISE_LEFT_SHIFT",
"BITWISE_NOT",
"BITWISE_OR",
"BITWISE_OR_AGG",
"BITWISE_RIGHT_SHIFT",
"BITWISE_RIGHT_SHIFT_ARITHMETIC",
"BITWISE_XOR",
"BIT_COUNT",
"BOOL_AND",
"BOOL_OR",
"CARDINALITY",
"CAST",
"CBRT",
"CEIL",
"CEILING",
"CHAR2HEXINT",
"CHECKSUM",
"CHR",
"CLASSIFY",
"COALESCE",
"CODEPOINT",
"COLOR",
"COMBINATIONS",
"CONCAT",
"CONCAT_WS",
"CONTAINS",
"CONTAINS_SEQUENCE",
"CONVEX_HULL_AGG",
"CORR",
"COS",
"COSH",
"COSINE_SIMILARITY",
"COUNT",
"COUNT_IF",
"COVAR_POP",
"COVAR_SAMP",
"CRC32",
"CUME_DIST",
"CURRENT_CATALOG",
"CURRENT_DATE",
"CURRENT_GROUPS",
"CURRENT_SCHEMA",
"CURRENT_TIME",
"CURRENT_TIMESTAMP",
"CURRENT_TIMEZONE",
"CURRENT_USER",
"DATE",
"DATE_ADD",
"DATE_DIFF",
"DATE_FORMAT",
"DATE_PARSE",
"DATE_TRUNC",
"DAY",
"DAY_OF_MONTH",
"DAY_OF_WEEK",
"DAY_OF_YEAR",
"DEGREES",
"DENSE_RANK",
"DOW",
"DOY",
"E",
"ELEMENT_AT",
"EMPTY_APPROX_SET",
"EVALUATE_CLASSIFIER_PREDICTIONS",
"EVERY",
"EXP",
"EXTRACT",
"FEATURES",
"FILTER",
"FIRST_VALUE",
"FLATTEN",
"FLOOR",
"FORMAT",
"FORMAT_DATETIME",
"FORMAT_NUMBER",
"FROM_BASE",
"FROM_BASE32",
"FROM_BASE64",
"FROM_BASE64URL",
"FROM_BIG_ENDIAN_32",
"FROM_BIG_ENDIAN_64",
"FROM_ENCODED_POLYLINE",
"FROM_GEOJSON_GEOMETRY",
"FROM_HEX",
"FROM_IEEE754_32",
"FROM_IEEE754_64",
"FROM_ISO8601_DATE",
"FROM_ISO8601_TIMESTAMP",
"FROM_ISO8601_TIMESTAMP_NANOS",
"FROM_UNIXTIME",
"FROM_UNIXTIME_NANOS",
"FROM_UTF8",
"GEOMETRIC_MEAN",
"GEOMETRY_FROM_HADOOP_SHAPE",
"GEOMETRY_INVALID_REASON",
"GEOMETRY_NEAREST_POINTS",
"GEOMETRY_TO_BING_TILES",
"GEOMETRY_UNION",
"GEOMETRY_UNION_AGG",
"GREATEST",
"GREAT_CIRCLE_DISTANCE",
"HAMMING_DISTANCE",
"HASH_COUNTS",
"HISTOGRAM",
"HMAC_MD5",
"HMAC_SHA1",
"HMAC_SHA256",
"HMAC_SHA512",
"HOUR",
"HUMAN_READABLE_SECONDS",
"IF",
"INDEX",
"INFINITY",
"INTERSECTION_CARDINALITY",
"INVERSE_BETA_CDF",
"INVERSE_NORMAL_CDF",
"IS_FINITE",
"IS_INFINITE",
"IS_JSON_SCALAR",
"IS_NAN",
"JACCARD_INDEX",
"JSON_ARRAY_CONTAINS",
"JSON_ARRAY_GET",
"JSON_ARRAY_LENGTH",
"JSON_EXISTS",
"JSON_EXTRACT",
"JSON_EXTRACT_SCALAR",
"JSON_FORMAT",
"JSON_PARSE",
"JSON_QUERY",
"JSON_SIZE",
"JSON_VALUE",
"KURTOSIS",
"LAG",
"LAST_DAY_OF_MONTH",
"LAST_VALUE",
"LEAD",
"LEARN_CLASSIFIER",
"LEARN_LIBSVM_CLASSIFIER",
"LEARN_LIBSVM_REGRESSOR",
"LEARN_REGRESSOR",
"LEAST",
"LENGTH",
"LEVENSHTEIN_DISTANCE",
"LINE_INTERPOLATE_POINT",
"LINE_INTERPOLATE_POINTS",
"LINE_LOCATE_POINT",
"LISTAGG",
"LN",
"LOCALTIME",
"LOCALTIMESTAMP",
"LOG",
"LOG10",
"LOG2",
"LOWER",
"LPAD",
"LTRIM",
"LUHN_CHECK",
"MAKE_SET_DIGEST",
"MAP",
"MAP_AGG",
"MAP_CONCAT",
"MAP_ENTRIES",
"MAP_FILTER",
"MAP_FROM_ENTRIES",
"MAP_KEYS",
"MAP_UNION",
"MAP_VALUES",
"MAP_ZIP_WITH",
"MAX",
"MAX_BY",
"MD5",
"MERGE",
"MERGE_SET_DIGEST",
"MILLISECOND",
"MIN",
"MINUTE",
"MIN_BY",
"MOD",
"MONTH",
"MULTIMAP_AGG",
"MULTIMAP_FROM_ENTRIES",
"MURMUR3",
"NAN",
"NGRAMS",
"NONE_MATCH",
"NORMALIZE",
"NORMAL_CDF",
"NOW",
"NTH_VALUE",
"NTILE",
"NULLIF",
"NUMERIC_HISTOGRAM",
"OBJECTID",
"OBJECTID_TIMESTAMP",
"PARSE_DATA_SIZE",
"PARSE_DATETIME",
"PARSE_DURATION",
"PERCENT_RANK",
"PI",
"POSITION",
"POW",
"POWER",
"QDIGEST_AGG",
"QUARTER",
"RADIANS",
"RAND",
"RANDOM",
"RANK",
"REDUCE",
"REDUCE_AGG",
"REGEXP_COUNT",
"REGEXP_EXTRACT",
"REGEXP_EXTRACT_ALL",
"REGEXP_LIKE",
"REGEXP_POSITION",
"REGEXP_REPLACE",
"REGEXP_SPLIT",
"REGRESS",
"REGR_INTERCEPT",
"REGR_SLOPE",
"RENDER",
"REPEAT",
"REPLACE",
"REVERSE",
"RGB",
"ROUND",
"ROW_NUMBER",
"RPAD",
"RTRIM",
"SECOND",
"SEQUENCE",
"SHA1",
"SHA256",
"SHA512",
"SHUFFLE",
"SIGN",
"SIMPLIFY_GEOMETRY",
"SIN",
"SKEWNESS",
"SLICE",
"SOUNDEX",
"SPATIAL_PARTITIONING",
"SPATIAL_PARTITIONS",
"SPLIT",
"SPLIT_PART",
"SPLIT_TO_MAP",
"SPLIT_TO_MULTIMAP",
"SPOOKY_HASH_V2_32",
"SPOOKY_HASH_V2_64",
"SQRT",
"STARTS_WITH",
"STDDEV",
"STDDEV_POP",
"STDDEV_SAMP",
"STRPOS",
"ST_AREA",
"ST_ASBINARY",
"ST_ASTEXT",
"ST_BOUNDARY",
"ST_BUFFER",
"ST_CENTROID",
"ST_CONTAINS",
"ST_CONVEXHULL",
"ST_COORDDIM",
"ST_CROSSES",
"ST_DIFFERENCE",
"ST_DIMENSION",
"ST_DISJOINT",
"ST_DISTANCE",
"ST_ENDPOINT",
"ST_ENVELOPE",
"ST_ENVELOPEASPTS",
"ST_EQUALS",
"ST_EXTERIORRING",
"ST_GEOMETRIES",
"ST_GEOMETRYFROMTEXT",
"ST_GEOMETRYN",
"ST_GEOMETRYTYPE",
"ST_GEOMFROMBINARY",
"ST_INTERIORRINGN",
"ST_INTERIORRINGS",
"ST_INTERSECTION",
"ST_INTERSECTS",
"ST_ISCLOSED",
"ST_ISEMPTY",
"ST_ISRING",
"ST_ISSIMPLE",
"ST_ISVALID",
"ST_LENGTH",
"ST_LINEFROMTEXT",
"ST_LINESTRING",
"ST_MULTIPOINT",
"ST_NUMGEOMETRIES",
"ST_NUMINTERIORRING",
"ST_NUMPOINTS",
"ST_OVERLAPS",
"ST_POINT",
"ST_POINTN",
"ST_POINTS",
"ST_POLYGON",
"ST_RELATE",
"ST_STARTPOINT",
"ST_SYMDIFFERENCE",
"ST_TOUCHES",
"ST_UNION",
"ST_WITHIN",
"ST_X",
"ST_XMAX",
"ST_XMIN",
"ST_Y",
"ST_YMAX",
"ST_YMIN",
"SUBSTR",
"SUBSTRING",
"SUM",
"TAN",
"TANH",
"TDIGEST_AGG",
"TIMESTAMP_OBJECTID",
"TIMEZONE_HOUR",
"TIMEZONE_MINUTE",
"TO_BASE",
"TO_BASE32",
"TO_BASE64",
"TO_BASE64URL",
"TO_BIG_ENDIAN_32",
"TO_BIG_ENDIAN_64",
"TO_CHAR",
"TO_DATE",
"TO_ENCODED_POLYLINE",
"TO_GEOJSON_GEOMETRY",
"TO_GEOMETRY",
"TO_HEX",
"TO_IEEE754_32",
"TO_IEEE754_64",
"TO_ISO8601",
"TO_MILLISECONDS",
"TO_SPHERICAL_GEOGRAPHY",
"TO_TIMESTAMP",
"TO_UNIXTIME",
"TO_UTF8",
"TRANSFORM",
"TRANSFORM_KEYS",
"TRANSFORM_VALUES",
"TRANSLATE",
"TRIM",
"TRIM_ARRAY",
"TRUNCATE",
"TRY",
"TRY_CAST",
"TYPEOF",
"UPPER",
"URL_DECODE",
"URL_ENCODE",
"URL_EXTRACT_FRAGMENT",
"URL_EXTRACT_HOST",
"URL_EXTRACT_PARAMETER",
"URL_EXTRACT_PATH",
"URL_EXTRACT_PORT",
"URL_EXTRACT_PROTOCOL",
"URL_EXTRACT_QUERY",
"UUID",
"VALUES_AT_QUANTILES",
"VALUE_AT_QUANTILE",
"VARIANCE",
"VAR_POP",
"VAR_SAMP",
"VERSION",
"WEEK",
"WEEK_OF_YEAR",
"WIDTH_BUCKET",
"WILSON_INTERVAL_LOWER",
"WILSON_INTERVAL_UPPER",
"WITH_TIMEZONE",
"WORD_STEM",
"XXHASH64",
"YEAR",
"YEAR_OF_WEEK",
"YOW",
"ZIP",
"ZIP_WITH",
// https://trino.io/docs/current/sql/match-recognize.html#row-pattern-recognition-expressions
"CLASSIFIER",
"FIRST",
"LAST",
"MATCH_NUMBER",
"NEXT",
"PERMUTE",
"PREV"
], us = [
// https://github.com/trinodb/trino/blob/432d2897bdef99388c1a47188743a061c4ac1f34/core/trino-parser/src/main/antlr4/io/trino/sql/parser/SqlBase.g4#L858-L1128
"ABSENT",
"ADD",
"ADMIN",
"AFTER",
"ALL",
"ALTER",
"ANALYZE",
"AND",
"ANY",
"AS",
"ASC",
"AT",
"AUTHORIZATION",
"BERNOULLI",
"BETWEEN",
"BOTH",
"BY",
"CALL",
"CASCADE",
"CASE",
"CATALOGS",
"COLUMN",
"COLUMNS",
"COMMENT",
"COMMIT",
"COMMITTED",
"CONDITIONAL",
"CONSTRAINT",
"COPARTITION",
"CREATE",
"CROSS",
"CUBE",
"CURRENT",
"CURRENT_PATH",
"CURRENT_ROLE",
"DATA",
"DEALLOCATE",
"DEFAULT",
"DEFINE",
"DEFINER",
"DELETE",
"DENY",
"DESC",
"DESCRIBE",
"DESCRIPTOR",
"DISTINCT",
"DISTRIBUTED",
"DOUBLE",
"DROP",
"ELSE",
"EMPTY",
"ENCODING",
"END",
"ERROR",
"ESCAPE",
"EXCEPT",
"EXCLUDING",
"EXECUTE",
"EXISTS",
"EXPLAIN",
"FALSE",
"FETCH",
"FINAL",
"FIRST",
"FOLLOWING",
"FOR",
"FROM",
"FULL",
"FUNCTIONS",
"GRANT",
"GRANTED",
"GRANTS",
"GRAPHVIZ",
"GROUP",
"GROUPING",
"GROUPS",
"HAVING",
"IGNORE",
"IN",
"INCLUDING",
"INITIAL",
"INNER",
"INPUT",
"INSERT",
"INTERSECT",
"INTERVAL",
"INTO",
"INVOKER",
"IO",
"IS",
"ISOLATION",
"JOIN",
"JSON",
"JSON_ARRAY",
"JSON_OBJECT",
"KEEP",
"KEY",
"KEYS",
"LAST",
"LATERAL",
"LEADING",
"LEFT",
"LEVEL",
"LIKE",
"LIMIT",
"LOCAL",
"LOGICAL",
"MATCH",
"MATCHED",
"MATCHES",
"MATCH_RECOGNIZE",
"MATERIALIZED",
"MEASURES",
"NATURAL",
"NEXT",
"NFC",
"NFD",
"NFKC",
"NFKD",
"NO",
"NONE",
"NOT",
"NULL",
"NULLS",
"OBJECT",
"OF",
"OFFSET",
"OMIT",
"ON",
"ONE",
"ONLY",
"OPTION",
"OR",
"ORDER",
"ORDINALITY",
"OUTER",
"OUTPUT",
"OVER",
"OVERFLOW",
"PARTITION",
"PARTITIONS",
"PASSING",
"PAST",
"PATH",
"PATTERN",
"PER",
"PERMUTE",
"PRECEDING",
"PRECISION",
"PREPARE",
"PRIVILEGES",
"PROPERTIES",
"PRUNE",
"QUOTES",
"RANGE",
"READ",
"RECURSIVE",
"REFRESH",
"RENAME",
"REPEATABLE",
"RESET",
"RESPECT",
"RESTRICT",
"RETURNING",
"REVOKE",
"RIGHT",
"ROLE",
"ROLES",
"ROLLBACK",
"ROLLUP",
"ROW",
"ROWS",
"RUNNING",
"SCALAR",
"SCHEMA",
"SCHEMAS",
"SECURITY",
"SEEK",
"SELECT",
"SERIALIZABLE",
"SESSION",
"SET",
"SETS",
"SHOW",
"SKIP",
"SOME",
"START",
"STATS",
"STRING",
"SUBSET",
"SYSTEM",
"TABLE",
"TABLES",
"TABLESAMPLE",
"TEXT",
"THEN",
"TIES",
"TIME",
"TIMESTAMP",
"TO",
"TRAILING",
"TRANSACTION",
"TRUE",
"TYPE",
"UESCAPE",
"UNBOUNDED",
"UNCOMMITTED",
"UNCONDITIONAL",
"UNION",
"UNIQUE",
"UNKNOWN",
"UNMATCHED",
"UNNEST",
"UPDATE",
"USE",
"USER",
"USING",
"UTF16",
"UTF32",
"UTF8",
"VALIDATE",
"VALUE",
"VALUES",
"VERBOSE",
"VIEW",
"WHEN",
"WHERE",
"WINDOW",
"WITH",
"WITHIN",
"WITHOUT",
"WORK",
"WRAPPER",
"WRITE",
"ZONE"
], Us = [
// https://github.com/trinodb/trino/blob/432d2897bdef99388c1a47188743a061c4ac1f34/core/trino-main/src/main/java/io/trino/metadata/TypeRegistry.java#L131-L168
// or https://trino.io/docs/current/language/types.html
"BIGINT",
"INT",
"INTEGER",
"SMALLINT",
"TINYINT",
"BOOLEAN",
"DATE",
"DECIMAL",
"REAL",
"DOUBLE",
"HYPERLOGLOG",
"QDIGEST",
"TDIGEST",
"P4HYPERLOGLOG",
"INTERVAL",
"TIMESTAMP",
"TIME",
"VARBINARY",
"VARCHAR",
"CHAR",
"ROW",
"ARRAY",
"MAP",
"JSON",
"JSON2016",
"IPADDRESS",
"GEOMETRY",
"UUID",
"SETDIGEST",
"JONIREGEXP",
"RE2JREGEXP",
"LIKEPATTERN",
"COLOR",
"CODEPOINTS",
"FUNCTION",
"JSONPATH"
], ds = o(["SELECT [ALL | DISTINCT]"]), ms = o([
// queries
"WITH [RECURSIVE]",
"FROM",
"WHERE",
"GROUP BY [ALL | DISTINCT]",
"HAVING",
"WINDOW",
"PARTITION BY",
"ORDER BY",
"LIMIT",
"OFFSET",
"FETCH {FIRST | NEXT}",
// Data manipulation
// - insert:
"INSERT INTO",
"VALUES",
// - update:
"SET",
// MATCH_RECOGNIZE
"MATCH_RECOGNIZE",
"MEASURES",
"ONE ROW PER MATCH",
"ALL ROWS PER MATCH",
"AFTER MATCH",
"PATTERN",
"SUBSET",
"DEFINE"
]), xe = o(["CREATE TABLE [IF NOT EXISTS]"]), QE = o([
// - create:
"CREATE [OR REPLACE] [MATERIALIZED] VIEW",
// - update:
"UPDATE",
// - delete:
"DELETE FROM",
// - drop table:
"DROP TABLE [IF EXISTS]",
// - alter table:
"ALTER TABLE [IF EXISTS]",
"ADD COLUMN [IF NOT EXISTS]",
"DROP COLUMN [IF EXISTS]",
"RENAME COLUMN [IF EXISTS]",
"RENAME TO",
"SET AUTHORIZATION [USER | ROLE]",
"SET PROPERTIES",
"EXECUTE",
// - truncate:
"TRUNCATE TABLE",
// other
"ALTER SCHEMA",
"ALTER MATERIALIZED VIEW",
"ALTER VIEW",
"CREATE SCHEMA",
"CREATE ROLE",
"DROP SCHEMA",
"DROP MATERIALIZED VIEW",
"DROP VIEW",
"DROP ROLE",
// Auxiliary
"EXPLAIN",
"ANALYZE",
"EXPLAIN ANALYZE",
"EXPLAIN ANALYZE VERBOSE",
"USE",
"DESCRIBE INPUT",
"DESCRIBE OUTPUT",
"REFRESH MATERIALIZED VIEW",
"RESET SESSION",
"SET SESSION",
"SET PATH",
"SET TIME ZONE",
"SHOW GRANTS",
"SHOW CREATE TABLE",
"SHOW CREATE SCHEMA",
"SHOW CREATE VIEW",
"SHOW CREATE MATERIALIZED VIEW",
"SHOW TABLES",
"SHOW SCHEMAS",
"SHOW CATALOGS",
"SHOW COLUMNS",
"SHOW STATS FOR",
"SHOW ROLES",
"SHOW CURRENT ROLES",
"SHOW ROLE GRANTS",
"SHOW FUNCTIONS",
"SHOW SESSION"
]), Gs = o([
"UNION [ALL | DISTINCT]",
"EXCEPT [ALL | DISTINCT]",
"INTERSECT [ALL | DISTINCT]"
]), ps = o([
"JOIN",
"{LEFT | RIGHT | FULL} [OUTER] JOIN",
"{INNER | CROSS} JOIN",
"NATURAL [INNER] JOIN",
"NATURAL {LEFT | RIGHT | FULL} [OUTER] JOIN"
]), fs = o([
"{ROWS | RANGE | GROUPS} BETWEEN",
// comparison operator
"IS [NOT] DISTINCT FROM"
]), Bs = o([]), hs = {
name: "trino",
tokenizerOptions: {
reservedSelect: ds,
reservedClauses: [...ms, ...xe, ...QE],
reservedSetOperations: Gs,
reservedJoins: ps,
reservedKeywordPhrases: fs,
reservedDataTypePhrases: Bs,
reservedKeywords: us,
reservedDataTypes: Us,
reservedFunctionNames: Ms,
// Trino also supports {- ... -} parenthesis.
// The formatting of these currently works out as a result of { and -
// not getting a space added in-between.
// https://trino.io/docs/current/sql/match-recognize.html#row-pattern-syntax
extraParens: ["[]", "{}"],
// https://trino.io/docs/current/language/types.html#string
// https://trino.io/docs/current/language/types.html#varbinary
stringTypes: [
{ quote: "''-qq", prefixes: ["U&"] },
{ quote: "''-raw", prefixes: ["X"], requirePrefix: !0 }
],
// https://trino.io/docs/current/language/reserved.html
identTypes: ['""-qq'],
paramTypes: { positional: !0 },
operators: [
"%",
"->",
"=>",
":",
"||",
// Row pattern syntax
"|",
"^",
"$"
// '?', conflicts with positional placeholders
]
},
formatOptions: {
onelineClauses: [...xe, ...QE],
tabularOnelineClauses: QE
}
}, Hs = [
// https://docs.microsoft.com/en-us/sql/t-sql/functions/functions?view=sql-server-ver15
// aggregate
"APPROX_COUNT_DISTINCT",
"AVG",
"CHECKSUM_AGG",
"COUNT",
"COUNT_BIG",
"GROUPING",
"GROUPING_ID",
"MAX",
"MIN",
"STDEV",
"STDEVP",
"SUM",
"VAR",
"VARP",
// analytic
"CUME_DIST",
"FIRST_VALUE",
"LAG",
"LAST_VALUE",
"LEAD",
"PERCENTILE_CONT",
"PERCENTILE_DISC",
"PERCENT_RANK",
"Collation - COLLATIONPROPERTY",
"Collation - TERTIARY_WEIGHTS",
// configuration
"@@DBTS",
"@@LANGID",
"@@LANGUAGE",
"@@LOCK_TIMEOUT",
"@@MAX_CONNECTIONS",
"@@MAX_PRECISION",
"@@NESTLEVEL",
"@@OPTIONS",
"@@REMSERVER",
"@@SERVERNAME",
"@@SERVICENAME",
"@@SPID",
"@@TEXTSIZE",
"@@VERSION",
// conversion
"CAST",
"CONVERT",
"PARSE",
"TRY_CAST",
"TRY_CONVERT",
"TRY_PARSE",
// cryptographic
"ASYMKEY_ID",
"ASYMKEYPROPERTY",
"CERTPROPERTY",
"CERT_ID",
"CRYPT_GEN_RANDOM",
"DECRYPTBYASYMKEY",
"DECRYPTBYCERT",
"DECRYPTBYKEY",
"DECRYPTBYKEYAUTOASYMKEY",
"DECRYPTBYKEYAUTOCERT",
"DECRYPTBYPASSPHRASE",
"ENCRYPTBYASYMKEY",
"ENCRYPTBYCERT",
"ENCRYPTBYKEY",
"ENCRYPTBYPASSPHRASE",
"HASHBYTES",
"IS_OBJECTSIGNED",
"KEY_GUID",
"KEY_ID",
"KEY_NAME",
"SIGNBYASYMKEY",
"SIGNBYCERT",
"SYMKEYPROPERTY",
"VERIFYSIGNEDBYCERT",
"VERIFYSIGNEDBYASYMKEY",
// cursor
"@@CURSOR_ROWS",
"@@FETCH_STATUS",
"CURSOR_STATUS",
// dataType
"DATALENGTH",
"IDENT_CURRENT",
"IDENT_INCR",
"IDENT_SEED",
"IDENTITY",
"SQL_VARIANT_PROPERTY",
// datetime
"@@DATEFIRST",
"CURRENT_TIMESTAMP",
"CURRENT_TIMEZONE",
"CURRENT_TIMEZONE_ID",
"DATEADD",
"DATEDIFF",
"DATEDIFF_BIG",
"DATEFROMPARTS",
"DATENAME",
"DATEPART",
"DATETIME2FROMPARTS",
"DATETIMEFROMPARTS",
"DATETIMEOFFSETFROMPARTS",
"DAY",
"EOMONTH",
"GETDATE",
"GETUTCDATE",
"ISDATE",
"MONTH",
"SMALLDATETIMEFROMPARTS",
"SWITCHOFFSET",
"SYSDATETIME",
"SYSDATETIMEOFFSET",
"SYSUTCDATETIME",
"TIMEFROMPARTS",
"TODATETIMEOFFSET",
"YEAR",
"JSON",
"ISJSON",
"JSON_VALUE",
"JSON_QUERY",
"JSON_MODIFY",
// mathematical
"ABS",
"ACOS",
"ASIN",
"ATAN",
"ATN2",
"CEILING",
"COS",
"COT",
"DEGREES",
"EXP",
"FLOOR",
"LOG",
"LOG10",
"PI",
"POWER",
"RADIANS",
"RAND",
"ROUND",
"SIGN",
"SIN",
"SQRT",
"SQUARE",
"TAN",
"CHOOSE",
"GREATEST",
"IIF",
"LEAST",
// metadata
"@@PROCID",
"APP_NAME",
"APPLOCK_MODE",
"APPLOCK_TEST",
"ASSEMBLYPROPERTY",
"COL_LENGTH",
"COL_NAME",
"COLUMNPROPERTY",
"DATABASEPROPERTYEX",
"DB_ID",
"DB_NAME",
"FILE_ID",
"FILE_IDEX",
"FILE_NAME",
"FILEGROUP_ID",
"FILEGROUP_NAME",
"FILEGROUPPROPERTY",
"FILEPROPERTY",
"FILEPROPERTYEX",
"FULLTEXTCATALOGPROPERTY",
"FULLTEXTSERVICEPROPERTY",
"INDEX_COL",
"INDEXKEY_PROPERTY",
"INDEXPROPERTY",
"NEXT VALUE FOR",
"OBJECT_DEFINITION",
"OBJECT_ID",
"OBJECT_NAME",
"OBJECT_SCHEMA_NAME",
"OBJECTPROPERTY",
"OBJECTPROPERTYEX",
"ORIGINAL_DB_NAME",
"PARSENAME",
"SCHEMA_ID",
"SCHEMA_NAME",
"SCOPE_IDENTITY",
"SERVERPROPERTY",
"STATS_DATE",
"TYPE_ID",
"TYPE_NAME",
"TYPEPROPERTY",
// ranking
"DENSE_RANK",
"NTILE",
"RANK",
"ROW_NUMBER",
"PUBLISHINGSERVERNAME",
// security
"CERTENCODED",
"CERTPRIVATEKEY",
"CURRENT_USER",
"DATABASE_PRINCIPAL_ID",
"HAS_DBACCESS",
"HAS_PERMS_BY_NAME",
"IS_MEMBER",
"IS_ROLEMEMBER",
"IS_SRVROLEMEMBER",
"LOGINPROPERTY",
"ORIGINAL_LOGIN",
"PERMISSIONS",
"PWDENCRYPT",
"PWDCOMPARE",
"SESSION_USER",
"SESSIONPROPERTY",
"SUSER_ID",
"SUSER_NAME",
"SUSER_SID",
"SUSER_SNAME",
"SYSTEM_USER",
"USER",
"USER_ID",
"USER_NAME",
// string
"ASCII",
"CHARINDEX",
"CONCAT",
"CONCAT_WS",
"DIFFERENCE",
"FORMAT",
"LEFT",
"LEN",
"LOWER",
"LTRIM",
"PATINDEX",
"QUOTENAME",
"REPLACE",
"REPLICATE",
"REVERSE",
"RIGHT",
"RTRIM",
"SOUNDEX",
"SPACE",
"STR",
"STRING_AGG",
"STRING_ESCAPE",
"STUFF",
"SUBSTRING",
"TRANSLATE",
"TRIM",
"UNICODE",
"UPPER",
// system
"$PARTITION",
"@@ERROR",
"@@IDENTITY",
"@@PACK_RECEIVED",
"@@ROWCOUNT",
"@@TRANCOUNT",
"BINARY_CHECKSUM",
"CHECKSUM",
"COMPRESS",
"CONNECTIONPROPERTY",
"CONTEXT_INFO",
"CURRENT_REQUEST_ID",
"CURRENT_TRANSACTION_ID",
"DECOMPRESS",
"ERROR_LINE",
"ERROR_MESSAGE",
"ERROR_NUMBER",
"ERROR_PROCEDURE",
"ERROR_SEVERITY",
"ERROR_STATE",
"FORMATMESSAGE",
"GET_FILESTREAM_TRANSACTION_CONTEXT",
"GETANSINULL",
"HOST_ID",
"HOST_NAME",
"ISNULL",
"ISNUMERIC",
"MIN_ACTIVE_ROWVERSION",
"NEWID",
"NEWSEQUENTIALID",
"ROWCOUNT_BIG",
"SESSION_CONTEXT",
"XACT_STATE",
// statistical
"@@CONNECTIONS",
"@@CPU_BUSY",
"@@IDLE",
"@@IO_BUSY",
"@@PACK_SENT",
"@@PACKET_ERRORS",
"@@TIMETICKS",
"@@TOTAL_ERRORS",
"@@TOTAL_READ",
"@@TOTAL_WRITE",
"TEXTPTR",
"TEXTVALID",
// trigger
"COLUMNS_UPDATED",
"EVENTDATA",
"TRIGGER_NESTLEVEL",
"UPDATE",
// Shorthand functions to use in place of CASE expression
"COALESCE",
"NULLIF"
], Fs = [
// https://docs.microsoft.com/en-us/sql/t-sql/language-elements/reserved-keywords-transact-sql?view=sql-server-ver15
// standard
"ADD",
"ALL",
"ALTER",
"AND",
"ANY",
"AS",
"ASC",
"AUTHORIZATION",
"BACKUP",
"BEGIN",
"BETWEEN",
"BREAK",
"BROWSE",
"BULK",
"BY",
"CASCADE",
"CHECK",
"CHECKPOINT",
"CLOSE",
"CLUSTERED",
"COALESCE",
"COLLATE",
"COLUMN",
"COMMIT",
"COMPUTE",
"CONSTRAINT",
"CONTAINS",
"CONTAINSTABLE",
"CONTINUE",
"CONVERT",
"CREATE",
"CROSS",
"CURRENT",
"CURRENT_DATE",
"CURRENT_TIME",
"CURRENT_TIMESTAMP",
"CURRENT_USER",
"CURSOR",
"DATABASE",
"DBCC",
"DEALLOCATE",
"DECLARE",
"DEFAULT",
"DELETE",
"DENY",
"DESC",
"DISK",
"DISTINCT",
"DISTRIBUTED",
"DROP",
"DUMP",
"ERRLVL",
"ESCAPE",
"EXEC",
"EXECUTE",
"EXISTS",
"EXIT",
"EXTERNAL",
"FETCH",
"FILE",
"FILLFACTOR",
"FOR",
"FOREIGN",
"FREETEXT",
"FREETEXTTABLE",
"FROM",
"FULL",
"FUNCTION",
"GOTO",
"GRANT",
"GROUP",
"HAVING",
"HOLDLOCK",
"IDENTITY",
"IDENTITYCOL",
"IDENTITY_INSERT",
"IF",
"IN",
"INDEX",
"INNER",
"INSERT",
"INTERSECT",
"INTO",
"IS",
"JOIN",
"KEY",
"KILL",
"LEFT",
"LIKE",
"LINENO",
"LOAD",
"MERGE",
"NOCHECK",
"NONCLUSTERED",
"NOT",
"NULL",
"NULLIF",
"OF",
"OFF",
"OFFSETS",
"ON",
"OPEN",
"OPENDATASOURCE",
"OPENQUERY",
"OPENROWSET",
"OPENXML",
"OPTION",
"OR",
"ORDER",
"OUTER",
"OVER",
"PERCENT",
"PIVOT",
"PLAN",
"PRIMARY",
"PRINT",
"PROC",
"PROCEDURE",
"PUBLIC",
"RAISERROR",
"READ",
"READTEXT",
"RECONFIGURE",
"REFERENCES",
"REPLICATION",
"RESTORE",
"RESTRICT",
"RETURN",
"REVERT",
"REVOKE",
"RIGHT",
"ROLLBACK",
"ROWCOUNT",
"ROWGUIDCOL",
"RULE",
"SAVE",
"SCHEMA",
"SECURITYAUDIT",
"SELECT",
"SEMANTICKEYPHRASETABLE",
"SEMANTICSIMILARITYDETAILSTABLE",
"SEMANTICSIMILARITYTABLE",
"SESSION_USER",
"SET",
"SETUSER",
"SHUTDOWN",
"SOME",
"STATISTICS",
"SYSTEM_USER",
"TABLE",
"TABLESAMPLE",
"TEXTSIZE",
"THEN",
"TO",
"TOP",
"TRAN",
"TRANSACTION",
"TRIGGER",
"TRUNCATE",
"TRY_CONVERT",
"TSEQUAL",
"UNION",
"UNIQUE",
"UNPIVOT",
"UPDATE",
"UPDATETEXT",
"USE",
"USER",
"VALUES",
"VIEW",
"WAITFOR",
"WHERE",
"WHILE",
"WITH",
"WITHIN GROUP",
"WRITETEXT",
// https://learn.microsoft.com/en-us/sql/t-sql/queries/output-clause-transact-sql?view=sql-server-ver16#action
"$ACTION"
], Ys = [
// https://learn.microsoft.com/en-us/sql/t-sql/data-types/data-types-transact-sql?view=sql-server-ver15
"BINARY",
"BIT",
"CHAR",
"CHAR",
"CHARACTER",
"DATE",
"DATETIME2",
"DATETIMEOFFSET",
"DEC",
"DECIMAL",
"DOUBLE",
"FLOAT",
"INT",
"INTEGER",
"NATIONAL",
"NCHAR",
"NUMERIC",
"NVARCHAR",
"PRECISION",
"REAL",
"SMALLINT",
"TIME",
"TIMESTAMP",
"VARBINARY",
"VARCHAR"
], Vs = o(["SELECT [ALL | DISTINCT]"]), bs = o([
// queries
"WITH",
"INTO",
"FROM",
"WHERE",
"GROUP BY",
"HAVING",
"WINDOW",
"PARTITION BY",
"ORDER BY",
"OFFSET",
"FETCH {FIRST | NEXT}",
"FOR {BROWSE | XML | JSON}",
"OPTION",
// Data manipulation
// - insert:
"INSERT [INTO]",
"VALUES",
// - update:
"SET",
// - merge:
"MERGE [INTO]",
"WHEN [NOT] MATCHED [BY TARGET | BY SOURCE] [THEN]",
"UPDATE SET"
]), Qe = o(["CREATE TABLE"]), ZE = o([
// - create:
"CREATE [OR ALTER] [MATERIALIZED] VIEW",
// - update:
"UPDATE",
"WHERE CURRENT OF",
// - delete:
"DELETE [FROM]",
// - drop table:
"DROP TABLE [IF EXISTS]",
// - alter table:
"ALTER TABLE",
"ADD",
"DROP COLUMN [IF EXISTS]",
"ALTER COLUMN",
// - truncate:
"TRUNCATE TABLE",
// indexes
"CREATE [UNIQUE] [CLUSTERED] INDEX",
// databases
"CREATE DATABASE",
"ALTER DATABASE",
"DROP DATABASE [IF EXISTS]",
// functions/procedures
"CREATE [OR ALTER] [PARTITION] {FUNCTION | PROCEDURE | PROC}",
"ALTER [PARTITION] {FUNCTION | PROCEDURE | PROC}",
"DROP [PARTITION] {FUNCTION | PROCEDURE | PROC} [IF EXISTS]",
// other statements
"GO",
"USE",
// https://docs.microsoft.com/en-us/sql/t-sql/statements/statements?view=sql-server-ver15
"ADD SENSITIVITY CLASSIFICATION",
"ADD SIGNATURE",
"AGGREGATE",
"ANSI_DEFAULTS",
"ANSI_NULLS",
"ANSI_NULL_DFLT_OFF",
"ANSI_NULL_DFLT_ON",
"ANSI_PADDING",
"ANSI_WARNINGS",
"APPLICATION ROLE",
"ARITHABORT",
"ARITHIGNORE",
"ASSEMBLY",
"ASYMMETRIC KEY",
"AUTHORIZATION",
"AVAILABILITY GROUP",
"BACKUP",
"BACKUP CERTIFICATE",
"BACKUP MASTER KEY",
"BACKUP SERVICE MASTER KEY",
"BEGIN CONVERSATION TIMER",
"BEGIN DIALOG CONVERSATION",
"BROKER PRIORITY",
"BULK INSERT",
"CERTIFICATE",
"CLOSE MASTER KEY",
"CLOSE SYMMETRIC KEY",
"COLUMN ENCRYPTION KEY",
"COLUMN MASTER KEY",
"COLUMNSTORE INDEX",
"CONCAT_NULL_YIELDS_NULL",
"CONTEXT_INFO",
"CONTRACT",
"CREDENTIAL",
"CRYPTOGRAPHIC PROVIDER",
"CURSOR_CLOSE_ON_COMMIT",
"DATABASE",
"DATABASE AUDIT SPECIFICATION",
"DATABASE ENCRYPTION KEY",
"DATABASE HADR",
"DATABASE SCOPED CONFIGURATION",
"DATABASE SCOPED CREDENTIAL",
"DATABASE SET",
"DATEFIRST",
"DATEFORMAT",
"DEADLOCK_PRIORITY",
"DENY",
"DENY XML",
"DISABLE TRIGGER",
"ENABLE TRIGGER",
"END CONVERSATION",
"ENDPOINT",
"EVENT NOTIFICATION",
"EVENT SESSION",
"EXECUTE AS",
"EXTERNAL DATA SOURCE",
"EXTERNAL FILE FORMAT",
"EXTERNAL LANGUAGE",
"EXTERNAL LIBRARY",
"EXTERNAL RESOURCE POOL",
"EXTERNAL TABLE",
"FIPS_FLAGGER",
"FMTONLY",
"FORCEPLAN",
"FULLTEXT CATALOG",
"FULLTEXT INDEX",
"FULLTEXT STOPLIST",
"GET CONVERSATION GROUP",
"GET_TRANSMISSION_STATUS",
"GRANT",
"GRANT XML",
"IDENTITY_INSERT",
"IMPLICIT_TRANSACTIONS",
"INDEX",
"LANGUAGE",
"LOCK_TIMEOUT",
"LOGIN",
"MASTER KEY",
"MESSAGE TYPE",
"MOVE CONVERSATION",
"NOCOUNT",
"NOEXEC",
"NUMERIC_ROUNDABORT",
"OFFSETS",
"OPEN MASTER KEY",
"OPEN SYMMETRIC KEY",
"PARSEONLY",
"PARTITION SCHEME",
"QUERY_GOVERNOR_COST_LIMIT",
"QUEUE",
"QUOTED_IDENTIFIER",
"RECEIVE",
"REMOTE SERVICE BINDING",
"REMOTE_PROC_TRANSACTIONS",
"RESOURCE GOVERNOR",
"RESOURCE POOL",
"RESTORE",
"RESTORE FILELISTONLY",
"RESTORE HEADERONLY",
"RESTORE LABELONLY",
"RESTORE MASTER KEY",
"RESTORE REWINDONLY",
"RESTORE SERVICE MASTER KEY",
"RESTORE VERIFYONLY",
"REVERT",
"REVOKE",
"REVOKE XML",
"ROLE",
"ROUTE",
"ROWCOUNT",
"RULE",
"SCHEMA",
"SEARCH PROPERTY LIST",
"SECURITY POLICY",
"SELECTIVE XML INDEX",
"SEND",
"SENSITIVITY CLASSIFICATION",
"SEQUENCE",
"SERVER AUDIT",
"SERVER AUDIT SPECIFICATION",
"SERVER CONFIGURATION",
"SERVER ROLE",
"SERVICE",
"SERVICE MASTER KEY",
"SETUSER",
"SHOWPLAN_ALL",
"SHOWPLAN_TEXT",
"SHOWPLAN_XML",
"SIGNATURE",
"SPATIAL INDEX",
"STATISTICS",
"STATISTICS IO",
"STATISTICS PROFILE",
"STATISTICS TIME",
"STATISTICS XML",
"SYMMETRIC KEY",
"SYNONYM",
"TABLE",
"TABLE IDENTITY",
"TEXTSIZE",
"TRANSACTION ISOLATION LEVEL",
"TRIGGER",
"TYPE",
"UPDATE STATISTICS",
"USER",
"WORKLOAD GROUP",
"XACT_ABORT",
"XML INDEX",
"XML SCHEMA COLLECTION"
]), gs = o(["UNION [ALL]", "EXCEPT", "INTERSECT"]), Ws = o([
"JOIN",
"{LEFT | RIGHT | FULL} [OUTER] JOIN",
"{INNER | CROSS} JOIN",
// non-standard joins
"{CROSS | OUTER} APPLY"
]), ys = o([
"ON {UPDATE | DELETE} [SET NULL | SET DEFAULT]",
"{ROWS | RANGE} BETWEEN"
]), Xs = o([]), $s = {
name: "transactsql",
tokenizerOptions: {
reservedSelect: Vs,
reservedClauses: [...bs, ...Qe, ...ZE],
reservedSetOperations: gs,
reservedJoins: Ws,
reservedKeywordPhrases: ys,
reservedDataTypePhrases: Xs,
reservedKeywords: Fs,
reservedDataTypes: Ys,
reservedFunctionNames: Hs,
nestedBlockComments: !0,
stringTypes: [{ quote: "''-qq", prefixes: ["N"] }, "{}"],
identTypes: ['""-qq', "[]"],
identChars: { first: "#@", rest: "#@$" },
paramTypes: { named: ["@"], quoted: ["@"] },
operators: [
"%",
"&",
"|",
"^",
"~",
"!<",
"!>",
"+=",
"-=",
"*=",
"/=",
"%=",
"|=",
"&=",
"^=",
"::",
":"
],
propertyAccessOperators: [".."]
// TODO: Support for money constants
},
formatOptions: {
alwaysDenseOperators: ["::"],
onelineClauses: [...Qe, ...ZE],
tabularOnelineClauses: ZE
}
}, Ks = [
// List of all keywords taken from:
// https://docs.singlestore.com/managed-service/en/reference/sql-reference/restricted-keywords/list-of-restricted-keywords.html
// Then filtered down to reserved keywords by running
// > SELECT * AS <keyword>;
// for each keyword in that list and observing which of these produce an error.
"ADD",
"ALL",
"ALTER",
"ANALYZE",
"AND",
"AS",
"ASC",
"ASENSITIVE",
"BEFORE",
"BETWEEN",
"_BINARY",
"BOTH",
"BY",
"CALL",
"CASCADE",
"CASE",
"CHANGE",
"CHECK",
"COLLATE",
"COLUMN",
"CONDITION",
"CONSTRAINT",
"CONTINUE",
"CONVERT",
"CREATE",
"CROSS",
"CURRENT_DATE",
"CURRENT_TIME",
"CURRENT_TIMESTAMP",
"CURRENT_USER",
"CURSOR",
"DATABASE",
"DATABASES",
"DAY_HOUR",
"DAY_MICROSECOND",
"DAY_MINUTE",
"DAY_SECOND",
"DECLARE",
"DEFAULT",
"DELAYED",
"DELETE",
"DESC",
"DESCRIBE",
"DETERMINISTIC",
"DISTINCT",
"DISTINCTROW",
"DIV",
"DROP",
"DUAL",
"EACH",
"ELSE",
"ELSEIF",
"ENCLOSED",
"ESCAPED",
"EXCEPT",
"EXISTS",
"EXIT",
"EXPLAIN",
"EXTRA_JOIN",
"FALSE",
"FETCH",
"FOR",
"FORCE",
"FORCE_COMPILED_MODE",
"FORCE_INTERPRETER_MODE",
"FOREIGN",
"FROM",
"FULL",
"FULLTEXT",
"GRANT",
"GROUP",
"HAVING",
"HEARTBEAT_NO_LOGGING",
"HIGH_PRIORITY",
"HOUR_MICROSECOND",
"HOUR_MINUTE",
"HOUR_SECOND",
"IF",
"IGNORE",
"IN",
"INDEX",
"INFILE",
"INNER",
"INOUT",
"INSENSITIVE",
"INSERT",
"IN",
"_INTERNAL_DYNAMIC_TYPECAST",
"INTERSECT",
"INTERVAL",
"INTO",
"ITERATE",
"JOIN",
"KEY",
"KEYS",
"KILL",
"LEADING",
"LEAVE",
"LEFT",
"LIKE",
"LIMIT",
"LINES",
"LOAD",
"LOCALTIME",
"LOCALTIMESTAMP",
"LOCK",
"LOOP",
"LOW_PRIORITY",
"MATCH",
"MAXVALUE",
"MINUS",
"MINUTE_MICROSECOND",
"MINUTE_SECOND",
"MOD",
"MODIFIES",
"NATURAL",
"NO_QUERY_REWRITE",
"NOT",
"NO_WRITE_TO_BINLOG",
"NO_QUERY_REWRITE",
"NULL",
"ON",
"OPTIMIZE",
"OPTION",
"OPTIONALLY",
"OR",
"ORDER",
"OUT",
"OUTER",
"OUTFILE",
"OVER",
"PRIMARY",
"PROCEDURE",
"PURGE",
"RANGE",
"READ",
"READS",
"REFERENCES",
"REGEXP",
"RELEASE",
"RENAME",
"REPEAT",
"REPLACE",
"REQUIRE",
"RESTRICT",
"RETURN",
"REVOKE",
"RIGHT",
"RIGHT_ANTI_JOIN",
"RIGHT_SEMI_JOIN",
"RIGHT_STRAIGHT_JOIN",
"RLIKE",
"SCHEMA",
"SCHEMAS",
"SECOND_MICROSECOND",
"SELECT",
"SEMI_JOIN",
"SENSITIVE",
"SEPARATOR",
"SET",
"SHOW",
"SIGNAL",
"SPATIAL",
"SPECIFIC",
"SQL",
"SQL_BIG_RESULT",
"SQL_BUFFER_RESULT",
"SQL_CACHE",
"SQL_CALC_FOUND_ROWS",
"SQLEXCEPTION",
"SQL_NO_CACHE",
"SQL_NO_LOGGING",
"SQL_SMALL_RESULT",
"SQLSTATE",
"SQLWARNING",
"STRAIGHT_JOIN",
"TABLE",
"TERMINATED",
"THEN",
"TO",
"TRAILING",
"TRIGGER",
"TRUE",
"UNBOUNDED",
"UNDO",
"UNION",
"UNIQUE",
"UNLOCK",
"UPDATE",
"USAGE",
"USE",
"USING",
"UTC_DATE",
"UTC_TIME",
"UTC_TIMESTAMP",
"_UTF8",
"VALUES",
"WHEN",
"WHERE",
"WHILE",
"WINDOW",
"WITH",
"WITHIN",
"WRITE",
"XOR",
"YEAR_MONTH",
"ZEROFILL"
], ws = [
// https://docs.singlestore.com/cloud/reference/sql-reference/data-types/
"BIGINT",
"BINARY",
"BIT",
"BLOB",
"CHAR",
"CHARACTER",
"DATETIME",
"DEC",
"DECIMAL",
"DOUBLE PRECISION",
"DOUBLE",
"ENUM",
"FIXED",
"FLOAT",
"FLOAT4",
"FLOAT8",
"INT",
"INT1",
"INT2",
"INT3",
"INT4",
"INT8",
"INTEGER",
"LONG",
"LONGBLOB",
"LONGTEXT",
"MEDIUMBLOB",
"MEDIUMINT",
"MEDIUMTEXT",
"MIDDLEINT",
"NATIONAL CHAR",
"NATIONAL VARCHAR",
"NUMERIC",
"PRECISION",
"REAL",
"SMALLINT",
"TEXT",
"TIME",
"TIMESTAMP",
"TINYBLOB",
"TINYINT",
"TINYTEXT",
"UNSIGNED",
"VARBINARY",
"VARCHAR",
"VARCHARACTER",
"YEAR"
], Js = [
// https://docs.singlestore.com/managed-service/en/reference/sql-reference/vector-functions/vector-functions.html
// https://docs.singlestore.com/managed-service/en/reference/sql-reference/window-functions/window-functions.html
// https://docs.singlestore.com/managed-service/en/reference/sql-reference/string-functions/string-functions.html
// https://docs.singlestore.com/managed-service/en/reference/sql-reference/conditional-functions/conditional-functions.html
// https://docs.singlestore.com/managed-service/en/reference/sql-reference/numeric-functions/numeric-functions.html
// https://docs.singlestore.com/managed-service/en/reference/sql-reference/geospatial-functions/geospatial-functions.html
// https://docs.singlestore.com/managed-service/en/reference/sql-reference/json-functions/json-functions.html
// https://docs.singlestore.com/managed-service/en/reference/sql-reference/information-functions/information-functions.html
// https://docs.singlestore.com/managed-service/en/reference/sql-reference/aggregate-functions/aggregate-functions.html
// https://docs.singlestore.com/managed-service/en/reference/sql-reference/time-series-functions/time-series-functions.html
// https://docs.singlestore.com/managed-service/en/reference/sql-reference/identifier-generation-functions.html
// https://docs.singlestore.com/managed-service/en/reference/sql-reference/date-and-time-functions/date-and-time-functions.html
// https://docs.singlestore.com/managed-service/en/reference/sql-reference/distinct-count-estimation-functions.html
// https://docs.singlestore.com/managed-service/en/reference/sql-reference/full-text-search-functions/full-text-search-functions.html
// https://docs.singlestore.com/managed-service/en/reference/sql-reference/regular-expression-functions.html
"ABS",
"ACOS",
"ADDDATE",
"ADDTIME",
"AES_DECRYPT",
"AES_ENCRYPT",
"ANY_VALUE",
"APPROX_COUNT_DISTINCT",
"APPROX_COUNT_DISTINCT_ACCUMULATE",
"APPROX_COUNT_DISTINCT_COMBINE",
"APPROX_COUNT_DISTINCT_ESTIMATE",
"APPROX_GEOGRAPHY_INTERSECTS",
"APPROX_PERCENTILE",
"ASCII",
"ASIN",
"ATAN",
"ATAN2",
"AVG",
"BIN",
"BINARY",
"BIT_AND",
"BIT_COUNT",
"BIT_OR",
"BIT_XOR",
"CAST",
"CEIL",
"CEILING",
"CHAR",
"CHARACTER_LENGTH",
"CHAR_LENGTH",
"CHARSET",
"COALESCE",
"COERCIBILITY",
"COLLATION",
"COLLECT",
"CONCAT",
"CONCAT_WS",
"CONNECTION_ID",
"CONV",
"CONVERT",
"CONVERT_TZ",
"COS",
"COT",
"COUNT",
"CUME_DIST",
"CURDATE",
"CURRENT_DATE",
"CURRENT_ROLE",
"CURRENT_TIME",
"CURRENT_TIMESTAMP",
"CURRENT_USER",
"CURTIME",
"DATABASE",
"DATE",
"DATE_ADD",
"DATEDIFF",
"DATE_FORMAT",
"DATE_SUB",
"DATE_TRUNC",
"DAY",
"DAYNAME",
"DAYOFMONTH",
"DAYOFWEEK",
"DAYOFYEAR",
"DECODE",
"DEFAULT",
"DEGREES",
"DENSE_RANK",
"DIV",
"DOT_PRODUCT",
"ELT",
"EUCLIDEAN_DISTANCE",
"EXP",
"EXTRACT",
"FIELD",
"FIRST",
"FIRST_VALUE",
"FLOOR",
"FORMAT",
"FOUND_ROWS",
"FROM_BASE64",
"FROM_DAYS",
"FROM_UNIXTIME",
"GEOGRAPHY_AREA",
"GEOGRAPHY_CONTAINS",
"GEOGRAPHY_DISTANCE",
"GEOGRAPHY_INTERSECTS",
"GEOGRAPHY_LATITUDE",
"GEOGRAPHY_LENGTH",
"GEOGRAPHY_LONGITUDE",
"GEOGRAPHY_POINT",
"GEOGRAPHY_WITHIN_DISTANCE",
"GEOMETRY_AREA",
"GEOMETRY_CONTAINS",
"GEOMETRY_DISTANCE",
"GEOMETRY_FILTER",
"GEOMETRY_INTERSECTS",
"GEOMETRY_LENGTH",
"GEOMETRY_POINT",
"GEOMETRY_WITHIN_DISTANCE",
"GEOMETRY_X",
"GEOMETRY_Y",
"GREATEST",
"GROUPING",
"GROUP_CONCAT",
"HEX",
"HIGHLIGHT",
"HOUR",
"ICU_VERSION",
"IF",
"IFNULL",
"INET_ATON",
"INET_NTOA",
"INET6_ATON",
"INET6_NTOA",
"INITCAP",
"INSERT",
"INSTR",
"INTERVAL",
"IS",
"IS NULL",
"JSON_AGG",
"JSON_ARRAY_CONTAINS_DOUBLE",
"JSON_ARRAY_CONTAINS_JSON",
"JSON_ARRAY_CONTAINS_STRING",
"JSON_ARRAY_PUSH_DOUBLE",
"JSON_ARRAY_PUSH_JSON",
"JSON_ARRAY_PUSH_STRING",
"JSON_DELETE_KEY",
"JSON_EXTRACT_DOUBLE",
"JSON_EXTRACT_JSON",
"JSON_EXTRACT_STRING",
"JSON_EXTRACT_BIGINT",
"JSON_GET_TYPE",
"JSON_LENGTH",
"JSON_SET_DOUBLE",
"JSON_SET_JSON",
"JSON_SET_STRING",
"JSON_SPLICE_DOUBLE",
"JSON_SPLICE_JSON",
"JSON_SPLICE_STRING",
"LAG",
"LAST_DAY",
"LAST_VALUE",
"LCASE",
"LEAD",
"LEAST",
"LEFT",
"LENGTH",
"LIKE",
"LN",
"LOCALTIME",
"LOCALTIMESTAMP",
"LOCATE",
"LOG",
"LOG10",
"LOG2",
"LPAD",
"LTRIM",
"MATCH",
"MAX",
"MD5",
"MEDIAN",
"MICROSECOND",
"MIN",
"MINUTE",
"MOD",
"MONTH",
"MONTHNAME",
"MONTHS_BETWEEN",
"NOT",
"NOW",
"NTH_VALUE",
"NTILE",
"NULLIF",
"OCTET_LENGTH",
"PERCENT_RANK",
"PERCENTILE_CONT",
"PERCENTILE_DISC",
"PI",
"PIVOT",
"POSITION",
"POW",
"POWER",
"QUARTER",
"QUOTE",
"RADIANS",
"RAND",
"RANK",
"REGEXP",
"REPEAT",
"REPLACE",
"REVERSE",
"RIGHT",
"RLIKE",
"ROUND",
"ROW_COUNT",
"ROW_NUMBER",
"RPAD",
"RTRIM",
"SCALAR",
"SCHEMA",
"SEC_TO_TIME",
"SHA1",
"SHA2",
"SIGMOID",
"SIGN",
"SIN",
"SLEEP",
"SPLIT",
"SOUNDEX",
"SOUNDS LIKE",
"SOURCE_POS_WAIT",
"SPACE",
"SQRT",
"STDDEV",
"STDDEV_POP",
"STDDEV_SAMP",
"STR_TO_DATE",
"SUBDATE",
"SUBSTR",
"SUBSTRING",
"SUBSTRING_INDEX",
"SUM",
"SYS_GUID",
"TAN",
"TIME",
"TIMEDIFF",
"TIME_BUCKET",
"TIME_FORMAT",
"TIMESTAMP",
"TIMESTAMPADD",
"TIMESTAMPDIFF",
"TIME_TO_SEC",
"TO_BASE64",
"TO_CHAR",
"TO_DAYS",
"TO_JSON",
"TO_NUMBER",
"TO_SECONDS",
"TO_TIMESTAMP",
"TRIM",
"TRUNC",
"TRUNCATE",
"UCASE",
"UNHEX",
"UNIX_TIMESTAMP",
"UPDATEXML",
"UPPER",
// 'USER',
"UTC_DATE",
"UTC_TIME",
"UTC_TIMESTAMP",
"UUID",
"VALUES",
"VARIANCE",
"VAR_POP",
"VAR_SAMP",
"VECTOR_SUB",
"VERSION",
"WEEK",
"WEEKDAY",
"WEEKOFYEAR",
"YEAR"
], vs = o(["SELECT [ALL | DISTINCT | DISTINCTROW]"]), xs = o([
// queries
"WITH",
"FROM",
"WHERE",
"GROUP BY",
"HAVING",
"PARTITION BY",
"ORDER BY",
"LIMIT",
"OFFSET",
// Data manipulation
// - insert:
"INSERT [IGNORE] [INTO]",
"VALUES",
"REPLACE [INTO]",
"ON DUPLICATE KEY UPDATE",
// - update:
"SET",
// Data definition
"CREATE [OR REPLACE] [TEMPORARY] PROCEDURE [IF NOT EXISTS]",
"CREATE [OR REPLACE] [EXTERNAL] FUNCTION"
]), Ze = o([
"CREATE [ROWSTORE] [REFERENCE | TEMPORARY | GLOBAL TEMPORARY] TABLE [IF NOT EXISTS]"
]), jE = o([
// - create:
"CREATE VIEW",
// - update:
"UPDATE",
// - delete:
"DELETE [FROM]",
// - drop table:
"DROP [TEMPORARY] TABLE [IF EXISTS]",
// - alter table:
"ALTER [ONLINE] TABLE",
"ADD [COLUMN]",
"ADD [UNIQUE] {INDEX | KEY}",
"DROP [COLUMN]",
"MODIFY [COLUMN]",
"CHANGE",
"RENAME [TO | AS]",
// - truncate:
"TRUNCATE [TABLE]",
// https://docs.singlestore.com/managed-service/en/reference/sql-reference.html
"ADD AGGREGATOR",
"ADD LEAF",
"AGGREGATOR SET AS MASTER",
"ALTER DATABASE",
"ALTER PIPELINE",
"ALTER RESOURCE POOL",
"ALTER USER",
"ALTER VIEW",
"ANALYZE TABLE",
"ATTACH DATABASE",
"ATTACH LEAF",
"ATTACH LEAF ALL",
"BACKUP DATABASE",
"BINLOG",
"BOOTSTRAP AGGREGATOR",
"CACHE INDEX",
"CALL",
"CHANGE",
"CHANGE MASTER TO",
"CHANGE REPLICATION FILTER",
"CHANGE REPLICATION SOURCE TO",
"CHECK BLOB CHECKSUM",
"CHECK TABLE",
"CHECKSUM TABLE",
"CLEAR ORPHAN DATABASES",
"CLONE",
"COMMIT",
"CREATE DATABASE",
"CREATE GROUP",
"CREATE INDEX",
"CREATE LINK",
"CREATE MILESTONE",
"CREATE PIPELINE",
"CREATE RESOURCE POOL",
"CREATE ROLE",
"CREATE USER",
"DEALLOCATE PREPARE",
"DESCRIBE",
"DETACH DATABASE",
"DETACH PIPELINE",
"DROP DATABASE",
"DROP FUNCTION",
"DROP INDEX",
"DROP LINK",
"DROP PIPELINE",
"DROP PROCEDURE",
"DROP RESOURCE POOL",
"DROP ROLE",
"DROP USER",
"DROP VIEW",
"EXECUTE",
"EXPLAIN",
"FLUSH",
"FORCE",
"GRANT",
"HANDLER",
"HELP",
"KILL CONNECTION",
"KILLALL QUERIES",
"LOAD DATA",
"LOAD INDEX INTO CACHE",
"LOAD XML",
"LOCK INSTANCE FOR BACKUP",
"LOCK TABLES",
"MASTER_POS_WAIT",
"OPTIMIZE TABLE",
"PREPARE",
"PURGE BINARY LOGS",
"REBALANCE PARTITIONS",
"RELEASE SAVEPOINT",
"REMOVE AGGREGATOR",
"REMOVE LEAF",
"REPAIR TABLE",
"REPLACE",
"REPLICATE DATABASE",
"RESET",
"RESET MASTER",
"RESET PERSIST",
"RESET REPLICA",
"RESET SLAVE",
"RESTART",
"RESTORE DATABASE",
"RESTORE REDUNDANCY",
"REVOKE",
"ROLLBACK",
"ROLLBACK TO SAVEPOINT",
"SAVEPOINT",
"SET CHARACTER SET",
"SET DEFAULT ROLE",
"SET NAMES",
"SET PASSWORD",
"SET RESOURCE GROUP",
"SET ROLE",
"SET TRANSACTION",
"SHOW",
"SHOW CHARACTER SET",
"SHOW COLLATION",
"SHOW COLUMNS",
"SHOW CREATE DATABASE",
"SHOW CREATE FUNCTION",
"SHOW CREATE PIPELINE",
"SHOW CREATE PROCEDURE",
"SHOW CREATE TABLE",
"SHOW CREATE USER",
"SHOW CREATE VIEW",
"SHOW DATABASES",
"SHOW ENGINE",
"SHOW ENGINES",
"SHOW ERRORS",
"SHOW FUNCTION CODE",
"SHOW FUNCTION STATUS",
"SHOW GRANTS",
"SHOW INDEX",
"SHOW MASTER STATUS",
"SHOW OPEN TABLES",
"SHOW PLUGINS",
"SHOW PRIVILEGES",
"SHOW PROCEDURE CODE",
"SHOW PROCEDURE STATUS",
"SHOW PROCESSLIST",
"SHOW PROFILE",
"SHOW PROFILES",
"SHOW RELAYLOG EVENTS",
"SHOW REPLICA STATUS",
"SHOW REPLICAS",
"SHOW SLAVE",
"SHOW SLAVE HOSTS",
"SHOW STATUS",
"SHOW TABLE STATUS",
"SHOW TABLES",
"SHOW VARIABLES",
"SHOW WARNINGS",
"SHUTDOWN",
"SNAPSHOT DATABASE",
"SOURCE_POS_WAIT",
"START GROUP_REPLICATION",
"START PIPELINE",
"START REPLICA",
"START SLAVE",
"START TRANSACTION",
"STOP GROUP_REPLICATION",
"STOP PIPELINE",
"STOP REPLICA",
"STOP REPLICATING",
"STOP SLAVE",
"TEST PIPELINE",
"UNLOCK INSTANCE",
"UNLOCK TABLES",
"USE",
"XA",
// flow control
"ITERATE",
"LEAVE",
"LOOP",
"REPEAT",
"RETURN",
"WHILE"
]), Qs = o([
"UNION [ALL | DISTINCT]",
"EXCEPT",
"INTERSECT",
"MINUS"
]), Zs = o([
"JOIN",
"{LEFT | RIGHT | FULL} [OUTER] JOIN",
"{INNER | CROSS} JOIN",
"NATURAL {LEFT | RIGHT} [OUTER] JOIN",
// non-standard joins
"STRAIGHT_JOIN"
]), js = o([
"ON DELETE",
"ON UPDATE",
"CHARACTER SET",
"{ROWS | RANGE} BETWEEN",
"IDENTIFIED BY"
]), qs = o([]), ks = {
name: "singlestoredb",
tokenizerOptions: {
reservedSelect: vs,
reservedClauses: [...xs, ...Ze, ...jE],
reservedSetOperations: Qs,
reservedJoins: Zs,
reservedKeywordPhrases: js,
reservedDataTypePhrases: qs,
reservedKeywords: Ks,
reservedDataTypes: ws,
reservedFunctionNames: Js,
// TODO: support _binary"some string" prefix
stringTypes: [
'""-qq-bs',
"''-qq-bs",
{ quote: "''-raw", prefixes: ["B", "X"], requirePrefix: !0 }
],
identTypes: ["``"],
identChars: { first: "$", rest: "$", allowFirstCharNumber: !0 },
variableTypes: [
{ regex: "@@?[A-Za-z0-9_$]+" },
{ quote: "``", prefixes: ["@"], requirePrefix: !0 }
],
lineCommentTypes: ["--", "#"],
operators: [
":=",
"&",
"|",
"^",
"~",
"<<",
">>",
"<=>",
"&&",
"||",
"::",
"::$",
"::%",
":>",
"!:>",
"*.*"
// Not actually an operator
],
postProcess: ME
},
formatOptions: {
alwaysDenseOperators: ["::", "::$", "::%"],
onelineClauses: [...Ze, ...jE],
tabularOnelineClauses: jE
}
}, zs = [
// https://docs.snowflake.com/en/sql-reference-functions.html
//
// https://docs.snowflake.com/en/sql-reference/functions-all.html
// 1. run in console on this page: $x('//tbody/tr/*[1]//a/span/text()').map(x => x.nodeValue)
// 2. split all lines that contain ',' or '/' into multiple lines
// 3. remove all '— Deprecated' parts from the strings
// 4. delete all strings that end with '<object_type>', they are already covered in the list
// 5. remove all strings that contain '[', they are operators not functions
// 6. fix all values that contain '*'
// 7. delete operatos ':', '::', '||'
//
// Steps 1-5 can be combined by the following script in the developer console:
// $x('//tbody/tr/*[1]//a/span/text()').map(x => x.nodeValue) // Step 1
// .map(x => x.split(x.includes(',') ? ',' : '/')).flat().map(x => x.trim()) // Step 2
// .map(x => x.replace('— Deprecated', '')) // Step 3
// .filter(x => !x.endsWith('<object_type>')) // Step 4
// .filter(x => !x.includes('[')) // Step 5
"ABS",
"ACOS",
"ACOSH",
"ADD_MONTHS",
"ALL_USER_NAMES",
"ANY_VALUE",
"APPROX_COUNT_DISTINCT",
"APPROX_PERCENTILE",
"APPROX_PERCENTILE_ACCUMULATE",
"APPROX_PERCENTILE_COMBINE",
"APPROX_PERCENTILE_ESTIMATE",
"APPROX_TOP_K",
"APPROX_TOP_K_ACCUMULATE",
"APPROX_TOP_K_COMBINE",
"APPROX_TOP_K_ESTIMATE",
"APPROXIMATE_JACCARD_INDEX",
"APPROXIMATE_SIMILARITY",
"ARRAY_AGG",
"ARRAY_APPEND",
"ARRAY_CAT",
"ARRAY_COMPACT",
"ARRAY_CONSTRUCT",
"ARRAY_CONSTRUCT_COMPACT",
"ARRAY_CONTAINS",
"ARRAY_INSERT",
"ARRAY_INTERSECTION",
"ARRAY_POSITION",
"ARRAY_PREPEND",
"ARRAY_SIZE",
"ARRAY_SLICE",
"ARRAY_TO_STRING",
"ARRAY_UNION_AGG",
"ARRAY_UNIQUE_AGG",
"ARRAYS_OVERLAP",
"AS_ARRAY",
"AS_BINARY",
"AS_BOOLEAN",
"AS_CHAR",
"AS_VARCHAR",
"AS_DATE",
"AS_DECIMAL",
"AS_NUMBER",
"AS_DOUBLE",
"AS_REAL",
"AS_INTEGER",
"AS_OBJECT",
"AS_TIME",
"AS_TIMESTAMP_LTZ",
"AS_TIMESTAMP_NTZ",
"AS_TIMESTAMP_TZ",
"ASCII",
"ASIN",
"ASINH",
"ATAN",
"ATAN2",
"ATANH",
"AUTO_REFRESH_REGISTRATION_HISTORY",
"AUTOMATIC_CLUSTERING_HISTORY",
"AVG",
"BASE64_DECODE_BINARY",
"BASE64_DECODE_STRING",
"BASE64_ENCODE",
"BIT_LENGTH",
"BITAND",
"BITAND_AGG",
"BITMAP_BIT_POSITION",
"BITMAP_BUCKET_NUMBER",
"BITMAP_CONSTRUCT_AGG",
"BITMAP_COUNT",
"BITMAP_OR_AGG",
"BITNOT",
"BITOR",
"BITOR_AGG",
"BITSHIFTLEFT",
"BITSHIFTRIGHT",
"BITXOR",
"BITXOR_AGG",
"BOOLAND",
"BOOLAND_AGG",
"BOOLNOT",
"BOOLOR",
"BOOLOR_AGG",
"BOOLXOR",
"BOOLXOR_AGG",
"BUILD_SCOPED_FILE_URL",
"BUILD_STAGE_FILE_URL",
"CASE",
"CAST",
"CBRT",
"CEIL",
"CHARINDEX",
"CHECK_JSON",
"CHECK_XML",
"CHR",
"CHAR",
"COALESCE",
"COLLATE",
"COLLATION",
"COMPLETE_TASK_GRAPHS",
"COMPRESS",
"CONCAT",
"CONCAT_WS",
"CONDITIONAL_CHANGE_EVENT",
"CONDITIONAL_TRUE_EVENT",
"CONTAINS",
"CONVERT_TIMEZONE",
"COPY_HISTORY",
"CORR",
"COS",
"COSH",
"COT",
"COUNT",
"COUNT_IF",
"COVAR_POP",
"COVAR_SAMP",
"CUME_DIST",
"CURRENT_ACCOUNT",
"CURRENT_AVAILABLE_ROLES",
"CURRENT_CLIENT",
"CURRENT_DATABASE",
"CURRENT_DATE",
"CURRENT_IP_ADDRESS",
"CURRENT_REGION",
"CURRENT_ROLE",
"CURRENT_SCHEMA",
"CURRENT_SCHEMAS",
"CURRENT_SECONDARY_ROLES",
"CURRENT_SESSION",
"CURRENT_STATEMENT",
"CURRENT_TASK_GRAPHS",
"CURRENT_TIME",
"CURRENT_TIMESTAMP",
"CURRENT_TRANSACTION",
"CURRENT_USER",
"CURRENT_VERSION",
"CURRENT_WAREHOUSE",
"DATA_TRANSFER_HISTORY",
"DATABASE_REFRESH_HISTORY",
"DATABASE_REFRESH_PROGRESS",
"DATABASE_REFRESH_PROGRESS_BY_JOB",
"DATABASE_STORAGE_USAGE_HISTORY",
"DATE_FROM_PARTS",
"DATE_PART",
"DATE_TRUNC",
"DATEADD",
"DATEDIFF",
"DAYNAME",
"DECODE",
"DECOMPRESS_BINARY",
"DECOMPRESS_STRING",
"DECRYPT",
"DECRYPT_RAW",
"DEGREES",
"DENSE_RANK",
"DIV0",
"EDITDISTANCE",
"ENCRYPT",
"ENCRYPT_RAW",
"ENDSWITH",
"EQUAL_NULL",
"EXP",
"EXPLAIN_JSON",
"EXTERNAL_FUNCTIONS_HISTORY",
"EXTERNAL_TABLE_FILES",
"EXTERNAL_TABLE_FILE_REGISTRATION_HISTORY",
"EXTRACT",
"EXTRACT_SEMANTIC_CATEGORIES",
"FACTORIAL",
"FILTER",
"FIRST_VALUE",
"FLATTEN",
"FLOOR",
"GENERATE_COLUMN_DESCRIPTION",
"GENERATOR",
"GET",
"GET_ABSOLUTE_PATH",
"GET_DDL",
"GET_IGNORE_CASE",
"GET_OBJECT_REFERENCES",
"GET_PATH",
"GET_PRESIGNED_URL",
"GET_RELATIVE_PATH",
"GET_STAGE_LOCATION",
"GETBIT",
"GREATEST",
"GREATEST_IGNORE_NULLS",
"GROUPING",
"GROUPING_ID",
"HASH",
"HASH_AGG",
"HAVERSINE",
"HEX_DECODE_BINARY",
"HEX_DECODE_STRING",
"HEX_ENCODE",
"HLL",
"HLL_ACCUMULATE",
"HLL_COMBINE",
"HLL_ESTIMATE",
"HLL_EXPORT",
"HLL_IMPORT",
"HOUR",
"MINUTE",
"SECOND",
"IDENTIFIER",
"IFF",
"IFNULL",
"ILIKE",
"ILIKE ANY",
"INFER_SCHEMA",
"INITCAP",
"INSERT",
"INVOKER_ROLE",
"INVOKER_SHARE",
"IS_ARRAY",
"IS_BINARY",
"IS_BOOLEAN",
"IS_CHAR",
"IS_VARCHAR",
"IS_DATE",
"IS_DATE_VALUE",
"IS_DECIMAL",
"IS_DOUBLE",
"IS_REAL",
"IS_GRANTED_TO_INVOKER_ROLE",
"IS_INTEGER",
"IS_NULL_VALUE",
"IS_OBJECT",
"IS_ROLE_IN_SESSION",
"IS_TIME",
"IS_TIMESTAMP_LTZ",
"IS_TIMESTAMP_NTZ",
"IS_TIMESTAMP_TZ",
"JAROWINKLER_SIMILARITY",
"JSON_EXTRACT_PATH_TEXT",
"KURTOSIS",
"LAG",
"LAST_DAY",
"LAST_QUERY_ID",
"LAST_TRANSACTION",
"LAST_VALUE",
"LEAD",
"LEAST",
"LEFT",
"LENGTH",
"LEN",
"LIKE",
"LIKE ALL",
"LIKE ANY",
"LISTAGG",
"LN",
"LOCALTIME",
"LOCALTIMESTAMP",
"LOG",
"LOGIN_HISTORY",
"LOGIN_HISTORY_BY_USER",
"LOWER",
"LPAD",
"LTRIM",
"MATERIALIZED_VIEW_REFRESH_HISTORY",
"MD5",
"MD5_HEX",
"MD5_BINARY",
"MD5_NUMBER — Obsoleted",
"MD5_NUMBER_LOWER64",
"MD5_NUMBER_UPPER64",
"MEDIAN",
"MIN",
"MAX",
"MINHASH",
"MINHASH_COMBINE",
"MOD",
"MODE",
"MONTHNAME",
"MONTHS_BETWEEN",
"NEXT_DAY",
"NORMAL",
"NTH_VALUE",
"NTILE",
"NULLIF",
"NULLIFZERO",
"NVL",
"NVL2",
"OBJECT_AGG",
"OBJECT_CONSTRUCT",
"OBJECT_CONSTRUCT_KEEP_NULL",
"OBJECT_DELETE",
"OBJECT_INSERT",
"OBJECT_KEYS",
"OBJECT_PICK",
"OCTET_LENGTH",
"PARSE_IP",
"PARSE_JSON",
"PARSE_URL",
"PARSE_XML",
"PERCENT_RANK",
"PERCENTILE_CONT",
"PERCENTILE_DISC",
"PI",
"PIPE_USAGE_HISTORY",
"POLICY_CONTEXT",
"POLICY_REFERENCES",
"POSITION",
"POW",
"POWER",
"PREVIOUS_DAY",
"QUERY_ACCELERATION_HISTORY",
"QUERY_HISTORY",
"QUERY_HISTORY_BY_SESSION",
"QUERY_HISTORY_BY_USER",
"QUERY_HISTORY_BY_WAREHOUSE",
"RADIANS",
"RANDOM",
"RANDSTR",
"RANK",
"RATIO_TO_REPORT",
"REGEXP",
"REGEXP_COUNT",
"REGEXP_INSTR",
"REGEXP_LIKE",
"REGEXP_REPLACE",
"REGEXP_SUBSTR",
"REGEXP_SUBSTR_ALL",
"REGR_AVGX",
"REGR_AVGY",
"REGR_COUNT",
"REGR_INTERCEPT",
"REGR_R2",
"REGR_SLOPE",
"REGR_SXX",
"REGR_SXY",
"REGR_SYY",
"REGR_VALX",
"REGR_VALY",
"REPEAT",
"REPLACE",
"REPLICATION_GROUP_REFRESH_HISTORY",
"REPLICATION_GROUP_REFRESH_PROGRESS",
"REPLICATION_GROUP_REFRESH_PROGRESS_BY_JOB",
"REPLICATION_GROUP_USAGE_HISTORY",
"REPLICATION_USAGE_HISTORY",
"REST_EVENT_HISTORY",
"RESULT_SCAN",
"REVERSE",
"RIGHT",
"RLIKE",
"ROUND",
"ROW_NUMBER",
"RPAD",
"RTRIM",
"RTRIMMED_LENGTH",
"SEARCH_OPTIMIZATION_HISTORY",
"SEQ1",
"SEQ2",
"SEQ4",
"SEQ8",
"SERVERLESS_TASK_HISTORY",
"SHA1",
"SHA1_HEX",
"SHA1_BINARY",
"SHA2",
"SHA2_HEX",
"SHA2_BINARY",
"SIGN",
"SIN",
"SINH",
"SKEW",
"SOUNDEX",
"SPACE",
"SPLIT",
"SPLIT_PART",
"SPLIT_TO_TABLE",
"SQRT",
"SQUARE",
"ST_AREA",
"ST_ASEWKB",
"ST_ASEWKT",
"ST_ASGEOJSON",
"ST_ASWKB",
"ST_ASBINARY",
"ST_ASWKT",
"ST_ASTEXT",
"ST_AZIMUTH",
"ST_CENTROID",
"ST_COLLECT",
"ST_CONTAINS",
"ST_COVEREDBY",
"ST_COVERS",
"ST_DIFFERENCE",
"ST_DIMENSION",
"ST_DISJOINT",
"ST_DISTANCE",
"ST_DWITHIN",
"ST_ENDPOINT",
"ST_ENVELOPE",
"ST_GEOGFROMGEOHASH",
"ST_GEOGPOINTFROMGEOHASH",
"ST_GEOGRAPHYFROMWKB",
"ST_GEOGRAPHYFROMWKT",
"ST_GEOHASH",
"ST_GEOMETRYFROMWKB",
"ST_GEOMETRYFROMWKT",
"ST_HAUSDORFFDISTANCE",
"ST_INTERSECTION",
"ST_INTERSECTS",
"ST_LENGTH",
"ST_MAKEGEOMPOINT",
"ST_GEOM_POINT",
"ST_MAKELINE",
"ST_MAKEPOINT",
"ST_POINT",
"ST_MAKEPOLYGON",
"ST_POLYGON",
"ST_NPOINTS",
"ST_NUMPOINTS",
"ST_PERIMETER",
"ST_POINTN",
"ST_SETSRID",
"ST_SIMPLIFY",
"ST_SRID",
"ST_STARTPOINT",
"ST_SYMDIFFERENCE",
"ST_UNION",
"ST_WITHIN",
"ST_X",
"ST_XMAX",
"ST_XMIN",
"ST_Y",
"ST_YMAX",
"ST_YMIN",
"STAGE_DIRECTORY_FILE_REGISTRATION_HISTORY",
"STAGE_STORAGE_USAGE_HISTORY",
"STARTSWITH",
"STDDEV",
"STDDEV_POP",
"STDDEV_SAMP",
"STRIP_NULL_VALUE",
"STRTOK",
"STRTOK_SPLIT_TO_TABLE",
"STRTOK_TO_ARRAY",
"SUBSTR",
"SUBSTRING",
"SUM",
"SYSDATE",
"SYSTEM$ABORT_SESSION",
"SYSTEM$ABORT_TRANSACTION",
"SYSTEM$AUTHORIZE_PRIVATELINK",
"SYSTEM$AUTHORIZE_STAGE_PRIVATELINK_ACCESS",
"SYSTEM$BEHAVIOR_CHANGE_BUNDLE_STATUS",
"SYSTEM$CANCEL_ALL_QUERIES",
"SYSTEM$CANCEL_QUERY",
"SYSTEM$CLUSTERING_DEPTH",
"SYSTEM$CLUSTERING_INFORMATION",
"SYSTEM$CLUSTERING_RATIO ",
"SYSTEM$CURRENT_USER_TASK_NAME",
"SYSTEM$DATABASE_REFRESH_HISTORY ",
"SYSTEM$DATABASE_REFRESH_PROGRESS",
"SYSTEM$DATABASE_REFRESH_PROGRESS_BY_JOB ",
"SYSTEM$DISABLE_BEHAVIOR_CHANGE_BUNDLE",
"SYSTEM$DISABLE_DATABASE_REPLICATION",
"SYSTEM$ENABLE_BEHAVIOR_CHANGE_BUNDLE",
"SYSTEM$ESTIMATE_QUERY_ACCELERATION",
"SYSTEM$ESTIMATE_SEARCH_OPTIMIZATION_COSTS",
"SYSTEM$EXPLAIN_JSON_TO_TEXT",
"SYSTEM$EXPLAIN_PLAN_JSON",
"SYSTEM$EXTERNAL_TABLE_PIPE_STATUS",
"SYSTEM$GENERATE_SAML_CSR",
"SYSTEM$GENERATE_SCIM_ACCESS_TOKEN",
"SYSTEM$GET_AWS_SNS_IAM_POLICY",
"SYSTEM$GET_PREDECESSOR_RETURN_VALUE",
"SYSTEM$GET_PRIVATELINK",
"SYSTEM$GET_PRIVATELINK_AUTHORIZED_ENDPOINTS",
"SYSTEM$GET_PRIVATELINK_CONFIG",
"SYSTEM$GET_SNOWFLAKE_PLATFORM_INFO",
"SYSTEM$GET_TAG",
"SYSTEM$GET_TAG_ALLOWED_VALUES",
"SYSTEM$GET_TAG_ON_CURRENT_COLUMN",
"SYSTEM$GET_TAG_ON_CURRENT_TABLE",
"SYSTEM$GLOBAL_ACCOUNT_SET_PARAMETER",
"SYSTEM$LAST_CHANGE_COMMIT_TIME",
"SYSTEM$LINK_ACCOUNT_OBJECTS_BY_NAME",
"SYSTEM$MIGRATE_SAML_IDP_REGISTRATION",
"SYSTEM$PIPE_FORCE_RESUME",
"SYSTEM$PIPE_STATUS",
"SYSTEM$REVOKE_PRIVATELINK",
"SYSTEM$REVOKE_STAGE_PRIVATELINK_ACCESS",
"SYSTEM$SET_RETURN_VALUE",
"SYSTEM$SHOW_OAUTH_CLIENT_SECRETS",
"SYSTEM$STREAM_GET_TABLE_TIMESTAMP",
"SYSTEM$STREAM_HAS_DATA",
"SYSTEM$TASK_DEPENDENTS_ENABLE",
"SYSTEM$TYPEOF",
"SYSTEM$USER_TASK_CANCEL_ONGOING_EXECUTIONS",
"SYSTEM$VERIFY_EXTERNAL_OAUTH_TOKEN",
"SYSTEM$WAIT",
"SYSTEM$WHITELIST",
"SYSTEM$WHITELIST_PRIVATELINK",
"TAG_REFERENCES",
"TAG_REFERENCES_ALL_COLUMNS",
"TAG_REFERENCES_WITH_LINEAGE",
"TAN",
"TANH",
"TASK_DEPENDENTS",
"TASK_HISTORY",
"TIME_FROM_PARTS",
"TIME_SLICE",
"TIMEADD",
"TIMEDIFF",
"TIMESTAMP_FROM_PARTS",
"TIMESTAMPADD",
"TIMESTAMPDIFF",
"TO_ARRAY",
"TO_BINARY",
"TO_BOOLEAN",
"TO_CHAR",
"TO_VARCHAR",
"TO_DATE",
"DATE",
"TO_DECIMAL",
"TO_NUMBER",
"TO_NUMERIC",
"TO_DOUBLE",
"TO_GEOGRAPHY",
"TO_GEOMETRY",
"TO_JSON",
"TO_OBJECT",
"TO_TIME",
"TIME",
"TO_TIMESTAMP",
"TO_TIMESTAMP_LTZ",
"TO_TIMESTAMP_NTZ",
"TO_TIMESTAMP_TZ",
"TO_VARIANT",
"TO_XML",
"TRANSLATE",
"TRIM",
"TRUNCATE",
"TRUNC",
"TRUNC",
"TRY_BASE64_DECODE_BINARY",
"TRY_BASE64_DECODE_STRING",
"TRY_CAST",
"TRY_HEX_DECODE_BINARY",
"TRY_HEX_DECODE_STRING",
"TRY_PARSE_JSON",
"TRY_TO_BINARY",
"TRY_TO_BOOLEAN",
"TRY_TO_DATE",
"TRY_TO_DECIMAL",
"TRY_TO_NUMBER",
"TRY_TO_NUMERIC",
"TRY_TO_DOUBLE",
"TRY_TO_GEOGRAPHY",
"TRY_TO_GEOMETRY",
"TRY_TO_TIME",
"TRY_TO_TIMESTAMP",
"TRY_TO_TIMESTAMP_LTZ",
"TRY_TO_TIMESTAMP_NTZ",
"TRY_TO_TIMESTAMP_TZ",
"TYPEOF",
"UNICODE",
"UNIFORM",
"UPPER",
"UUID_STRING",
"VALIDATE",
"VALIDATE_PIPE_LOAD",
"VAR_POP",
"VAR_SAMP",
"VARIANCE",
"VARIANCE_SAMP",
"VARIANCE_POP",
"WAREHOUSE_LOAD_HISTORY",
"WAREHOUSE_METERING_HISTORY",
"WIDTH_BUCKET",
"XMLGET",
"YEAR",
"YEAROFWEEK",
"YEAROFWEEKISO",
"DAY",
"DAYOFMONTH",
"DAYOFWEEK",
"DAYOFWEEKISO",
"DAYOFYEAR",
"WEEK",
"WEEK",
"WEEKOFYEAR",
"WEEKISO",
"MONTH",
"QUARTER",
"ZEROIFNULL",
"ZIPF"
], ES = [
// https://docs.snowflake.com/en/sql-reference/reserved-keywords.html
//
// run in console on this page: $x('//tbody/tr/*[1]/p/text()').map(x => x.nodeValue)
"ACCOUNT",
"ALL",
"ALTER",
"AND",
"ANY",
"AS",
"BETWEEN",
"BY",
"CASE",
"CAST",
"CHECK",
"COLUMN",
"CONNECT",
"CONNECTION",
"CONSTRAINT",
"CREATE",
"CROSS",
"CURRENT",
"CURRENT_DATE",
"CURRENT_TIME",
"CURRENT_TIMESTAMP",
"CURRENT_USER",
"DATABASE",
"DELETE",
"DISTINCT",
"DROP",
"ELSE",
"EXISTS",
"FALSE",
"FOLLOWING",
"FOR",
"FROM",
"FULL",
"GRANT",
"GROUP",
"GSCLUSTER",
"HAVING",
"ILIKE",
"IN",
"INCREMENT",
"INNER",
"INSERT",
"INTERSECT",
"INTO",
"IS",
"ISSUE",
"JOIN",
"LATERAL",
"LEFT",
"LIKE",
"LOCALTIME",
"LOCALTIMESTAMP",
"MINUS",
"NATURAL",
"NOT",
"NULL",
"OF",
"ON",
"OR",
"ORDER",
"ORGANIZATION",
"QUALIFY",
"REGEXP",
"REVOKE",
"RIGHT",
"RLIKE",
"ROW",
"ROWS",
"SAMPLE",
"SCHEMA",
"SELECT",
"SET",
"SOME",
"START",
"TABLE",
"TABLESAMPLE",
"THEN",
"TO",
"TRIGGER",
"TRUE",
"TRY_CAST",
"UNION",
"UNIQUE",
"UPDATE",
"USING",
"VALUES",
"VIEW",
"WHEN",
"WHENEVER",
"WHERE",
"WITH",
// These are definitely keywords, but haven't found a definite list in the docs
"COMMENT"
], eS = [
"NUMBER",
"DECIMAL",
"NUMERIC",
"INT",
"INTEGER",
"BIGINT",
"SMALLINT",
"TINYINT",
"BYTEINT",
"FLOAT",
"FLOAT4",
"FLOAT8",
"DOUBLE",
"DOUBLE PRECISION",
"REAL",
"VARCHAR",
"CHAR",
"CHARACTER",
"STRING",
"TEXT",
"BINARY",
"VARBINARY",
"BOOLEAN",
"DATE",
"DATETIME",
"TIME",
"TIMESTAMP",
"TIMESTAMP_LTZ",
"TIMESTAMP_NTZ",
"TIMESTAMP",
"TIMESTAMP_TZ",
"VARIANT",
"OBJECT",
"ARRAY",
"GEOGRAPHY",
"GEOMETRY"
], TS = o(["SELECT [ALL | DISTINCT]"]), RS = o([
// queries
"WITH [RECURSIVE]",
"FROM",
"WHERE",
"GROUP BY",
"HAVING",
"PARTITION BY",
"ORDER BY",
"QUALIFY",
"LIMIT",
"OFFSET",
"FETCH [FIRST | NEXT]",
// Data manipulation
// - insert:
"INSERT [OVERWRITE] [ALL INTO | INTO | ALL | FIRST]",
"{THEN | ELSE} INTO",
"VALUES",
// - update:
"SET",
"CLUSTER BY",
"[WITH] {MASKING POLICY | TAG | ROW ACCESS POLICY}",
"COPY GRANTS",
"USING TEMPLATE",
"MERGE INTO",
"WHEN MATCHED [AND]",
"THEN {UPDATE SET | DELETE}",
"WHEN NOT MATCHED THEN INSERT"
]), je = o([
"CREATE [OR REPLACE] [VOLATILE] TABLE [IF NOT EXISTS]",
"CREATE [OR REPLACE] [LOCAL | GLOBAL] {TEMP|TEMPORARY} TABLE [IF NOT EXISTS]"
]), qE = o([
// - create:
"CREATE [OR REPLACE] [SECURE] [RECURSIVE] VIEW [IF NOT EXISTS]",
// - update:
"UPDATE",
// - delete:
"DELETE FROM",
// - drop table:
"DROP TABLE [IF EXISTS]",
// - alter table:
"ALTER TABLE [IF EXISTS]",
"RENAME TO",
"SWAP WITH",
"[SUSPEND | RESUME] RECLUSTER",
"DROP CLUSTERING KEY",
"ADD [COLUMN]",
"RENAME COLUMN",
"{ALTER | MODIFY} [COLUMN]",
"DROP [COLUMN]",
"{ADD | ALTER | MODIFY | DROP} [CONSTRAINT]",
"RENAME CONSTRAINT",
"{ADD | DROP} SEARCH OPTIMIZATION",
"{SET | UNSET} TAG",
"{ADD | DROP} ROW ACCESS POLICY",
"DROP ALL ROW ACCESS POLICIES",
"{SET | DROP} DEFAULT",
"{SET | DROP} NOT NULL",
"SET DATA TYPE",
"UNSET COMMENT",
"{SET | UNSET} MASKING POLICY",
// - truncate:
"TRUNCATE [TABLE] [IF EXISTS]",
// other
// https://docs.snowflake.com/en/sql-reference/sql-all.html
//
// 1. run in console on this page: $x('//tbody/tr/*[1]//a/span/text()').map(x => x.nodeValue)
// 2. delete all lines that contain a sting like '(.*)', they are already covered in the list
// 3. delete all lines that contain a sting like '<.*>', they are already covered in the list
// 4. delete all lines that contain '…', they are part of a regex statement that can't be covered here
// 5. Manually add 'COPY INTO'
// 6. Remove all lines that are already in `reservedClauses`
//
// Steps 1-4 can be combined by the following script in the developer console:
// $x('//tbody/tr/*[1]//a/span/text()').map(x => x.nodeValue) // Step 1
// filter(x => !x.match(/\(.*\)/) && !x.match(/…/) && !x.match(/<.*>/)) // Step 2-4
"ALTER ACCOUNT",
"ALTER API INTEGRATION",
"ALTER CONNECTION",
"ALTER DATABASE",
"ALTER EXTERNAL TABLE",
"ALTER FAILOVER GROUP",
"ALTER FILE FORMAT",
"ALTER FUNCTION",
"ALTER INTEGRATION",
"ALTER MASKING POLICY",
"ALTER MATERIALIZED VIEW",
"ALTER NETWORK POLICY",
"ALTER NOTIFICATION INTEGRATION",
"ALTER PIPE",
"ALTER PROCEDURE",
"ALTER REPLICATION GROUP",
"ALTER RESOURCE MONITOR",
"ALTER ROLE",
"ALTER ROW ACCESS POLICY",
"ALTER SCHEMA",
"ALTER SECURITY INTEGRATION",
"ALTER SEQUENCE",
"ALTER SESSION",
"ALTER SESSION POLICY",
"ALTER SHARE",
"ALTER STAGE",
"ALTER STORAGE INTEGRATION",
"ALTER STREAM",
"ALTER TAG",
"ALTER TASK",
"ALTER USER",
"ALTER VIEW",
"ALTER WAREHOUSE",
"BEGIN",
"CALL",
"COMMIT",
"COPY INTO",
"CREATE ACCOUNT",
"CREATE API INTEGRATION",
"CREATE CONNECTION",
"CREATE DATABASE",
"CREATE EXTERNAL FUNCTION",
"CREATE EXTERNAL TABLE",
"CREATE FAILOVER GROUP",
"CREATE FILE FORMAT",
"CREATE FUNCTION",
"CREATE INTEGRATION",
"CREATE MANAGED ACCOUNT",
"CREATE MASKING POLICY",
"CREATE MATERIALIZED VIEW",
"CREATE NETWORK POLICY",
"CREATE NOTIFICATION INTEGRATION",
"CREATE PIPE",
"CREATE PROCEDURE",
"CREATE REPLICATION GROUP",
"CREATE RESOURCE MONITOR",
"CREATE ROLE",
"CREATE ROW ACCESS POLICY",
"CREATE SCHEMA",
"CREATE SECURITY INTEGRATION",
"CREATE SEQUENCE",
"CREATE SESSION POLICY",
"CREATE SHARE",
"CREATE STAGE",
"CREATE STORAGE INTEGRATION",
"CREATE STREAM",
"CREATE TAG",
"CREATE TASK",
"CREATE USER",
"CREATE WAREHOUSE",
"DELETE",
"DESCRIBE DATABASE",
"DESCRIBE EXTERNAL TABLE",
"DESCRIBE FILE FORMAT",
"DESCRIBE FUNCTION",
"DESCRIBE INTEGRATION",
"DESCRIBE MASKING POLICY",
"DESCRIBE MATERIALIZED VIEW",
"DESCRIBE NETWORK POLICY",
"DESCRIBE PIPE",
"DESCRIBE PROCEDURE",
"DESCRIBE RESULT",
"DESCRIBE ROW ACCESS POLICY",
"DESCRIBE SCHEMA",
"DESCRIBE SEQUENCE",
"DESCRIBE SESSION POLICY",
"DESCRIBE SHARE",
"DESCRIBE STAGE",
"DESCRIBE STREAM",
"DESCRIBE TABLE",
"DESCRIBE TASK",
"DESCRIBE TRANSACTION",
"DESCRIBE USER",
"DESCRIBE VIEW",
"DESCRIBE WAREHOUSE",
"DROP CONNECTION",
"DROP DATABASE",
"DROP EXTERNAL TABLE",
"DROP FAILOVER GROUP",
"DROP FILE FORMAT",
"DROP FUNCTION",
"DROP INTEGRATION",
"DROP MANAGED ACCOUNT",
"DROP MASKING POLICY",
"DROP MATERIALIZED VIEW",
"DROP NETWORK POLICY",
"DROP PIPE",
"DROP PROCEDURE",
"DROP REPLICATION GROUP",
"DROP RESOURCE MONITOR",
"DROP ROLE",
"DROP ROW ACCESS POLICY",
"DROP SCHEMA",
"DROP SEQUENCE",
"DROP SESSION POLICY",
"DROP SHARE",
"DROP STAGE",
"DROP STREAM",
"DROP TAG",
"DROP TASK",
"DROP USER",
"DROP VIEW",
"DROP WAREHOUSE",
"EXECUTE IMMEDIATE",
"EXECUTE TASK",
"EXPLAIN",
"GET",
"GRANT OWNERSHIP",
"GRANT ROLE",
"INSERT",
"LIST",
"MERGE",
"PUT",
"REMOVE",
"REVOKE ROLE",
"ROLLBACK",
"SHOW COLUMNS",
"SHOW CONNECTIONS",
"SHOW DATABASES",
"SHOW DATABASES IN FAILOVER GROUP",
"SHOW DATABASES IN REPLICATION GROUP",
"SHOW DELEGATED AUTHORIZATIONS",
"SHOW EXTERNAL FUNCTIONS",
"SHOW EXTERNAL TABLES",
"SHOW FAILOVER GROUPS",
"SHOW FILE FORMATS",
"SHOW FUNCTIONS",
"SHOW GLOBAL ACCOUNTS",
"SHOW GRANTS",
"SHOW INTEGRATIONS",
"SHOW LOCKS",
"SHOW MANAGED ACCOUNTS",
"SHOW MASKING POLICIES",
"SHOW MATERIALIZED VIEWS",
"SHOW NETWORK POLICIES",
"SHOW OBJECTS",
"SHOW ORGANIZATION ACCOUNTS",
"SHOW PARAMETERS",
"SHOW PIPES",
"SHOW PRIMARY KEYS",
"SHOW PROCEDURES",
"SHOW REGIONS",
"SHOW REPLICATION ACCOUNTS",
"SHOW REPLICATION DATABASES",
"SHOW REPLICATION GROUPS",
"SHOW RESOURCE MONITORS",
"SHOW ROLES",
"SHOW ROW ACCESS POLICIES",
"SHOW SCHEMAS",
"SHOW SEQUENCES",
"SHOW SESSION POLICIES",
"SHOW SHARES",
"SHOW SHARES IN FAILOVER GROUP",
"SHOW SHARES IN REPLICATION GROUP",
"SHOW STAGES",
"SHOW STREAMS",
"SHOW TABLES",
"SHOW TAGS",
"SHOW TASKS",
"SHOW TRANSACTIONS",
"SHOW USER FUNCTIONS",
"SHOW USERS",
"SHOW VARIABLES",
"SHOW VIEWS",
"SHOW WAREHOUSES",
"TRUNCATE MATERIALIZED VIEW",
"UNDROP DATABASE",
"UNDROP SCHEMA",
"UNDROP TABLE",
"UNDROP TAG",
"UNSET",
"USE DATABASE",
"USE ROLE",
"USE SCHEMA",
"USE SECONDARY ROLES",
"USE WAREHOUSE"
]), AS = o(["UNION [ALL]", "MINUS", "EXCEPT", "INTERSECT"]), tS = o([
"[INNER] JOIN",
"[NATURAL] {LEFT | RIGHT | FULL} [OUTER] JOIN",
"{CROSS | NATURAL} JOIN"
]), sS = o([
"{ROWS | RANGE} BETWEEN",
"ON {UPDATE | DELETE} [SET NULL | SET DEFAULT]"
]), SS = o([]), NS = {
name: "snowflake",
tokenizerOptions: {
reservedSelect: TS,
reservedClauses: [...RS, ...je, ...qE],
reservedSetOperations: AS,
reservedJoins: tS,
reservedKeywordPhrases: sS,
reservedDataTypePhrases: SS,
reservedKeywords: ES,
reservedDataTypes: eS,
reservedFunctionNames: zs,
stringTypes: ["$$", "''-qq-bs"],
identTypes: ['""-qq'],
variableTypes: [
// for accessing columns at certain positons in the table
{ regex: "[$][1-9]\\d*" },
// identifier style syntax
{ regex: "[$][_a-zA-Z][_a-zA-Z0-9$]*" }
],
extraParens: ["[]"],
identChars: { rest: "$" },
lineCommentTypes: ["--", "//"],
operators: [
// Modulo
"%",
// Type cast
"::",
// String concat
"||",
// Generators: https://docs.snowflake.com/en/sql-reference/functions/generator.html#generator
"=>",
// Assignment https://docs.snowflake.com/en/sql-reference/snowflake-scripting/let
":=",
// Lambda: https://docs.snowflake.com/en/user-guide/querying-semistructured#lambda-expressions
"->"
],
propertyAccessOperators: [":"]
},
formatOptions: {
alwaysDenseOperators: ["::"],
onelineClauses: [...je, ...qE],
tabularOnelineClauses: qE
}
}, IS = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
__proto__: null,
bigquery: gR,
db2: kR,
db2i: NA,
duckdb: _A,
hive: GA,
mariadb: gA,
mysql: QA,
n1ql: at,
plsql: ut,
postgresql: Yt,
redshift: Jt,
singlestoredb: ks,
snowflake: NS,
spark: es,
sql: cs,
sqlite: rs,
tidb: At,
transactsql: $s,
trino: hs
}, Symbol.toStringTag, { value: "Module" })), tE = (T) => T[T.length - 1], lT = (T) => T.sort((E, e) => e.length - E.length || E.localeCompare(e)), iE = (T) => T.replace(/\s+/gu, " "), kE = (T) => /\n/.test(T), K = (T) => T.replace(/[.*+?^${}()|[\]\\]/gu, "\\$&"), qe = /\s+/uy, q = (T) => new RegExp(`(?:${T})`, "uy"), OS = (T) => T.split("").map((E) => / /gu.test(E) ? "\\s+" : `[${E.toUpperCase()}${E.toLowerCase()}]`).join(""), nS = (T) => T + "(?:-" + T + ")*", rS = ({ prefixes: T, requirePrefix: E }) => `(?:${T.map(OS).join("|")}${E ? "" : "|"})`, iS = (T) => new RegExp(`(?:${T.map(K).join("|")}).*?(?=\r
|\r|
|$)`, "uy"), ke = (T, E = []) => {
const e = T === "open" ? 0 : 1, R = ["()", ...E].map((A) => A[e]);
return q(R.map(K).join("|"));
}, ze = (T) => q(`${lT(T).map(K).join("|")}`), aS = ({ rest: T, dashes: E }) => T || E ? `(?![${T || ""}${E ? "-" : ""}])` : "", J = (T, E = {}) => {
if (T.length === 0)
return /^\b$/u;
const e = aS(E), R = lT(T).map(K).join("|").replace(/ /gu, "\\s+");
return new RegExp(`(?:${R})${e}\\b`, "iuy");
}, zE = (T, E) => {
if (!T.length)
return;
const e = T.map(K).join("|");
return q(`(?:${e})(?:${E})`);
}, CS = () => {
const T = {
"<": ">",
"[": "]",
"(": ")",
"{": "}"
}, E = "{left}(?:(?!{right}').)*?{right}", e = Object.entries(T).map(([s, I]) => E.replace(/{left}/g, K(s)).replace(/{right}/g, K(I))), R = K(Object.keys(T).join(""));
return `[Qq]'(?:${String.raw`(?<tag>[^\s${R}])(?:(?!\k<tag>').)*?\k<tag>`}|${e.join("|")})'`;
}, ET = {
// - backtick quoted (using `` to escape)
"``": "(?:`[^`]*`)+",
// - Transact-SQL square bracket quoted (using ]] to escape)
"[]": String.raw`(?:\[[^\]]*\])(?:\][^\]]*\])*`,
// double-quoted
'""-qq': String.raw`(?:"[^"]*")+`,
'""-bs': String.raw`(?:"[^"\\]*(?:\\.[^"\\]*)*")`,
'""-qq-bs': String.raw`(?:"[^"\\]*(?:\\.[^"\\]*)*")+`,
'""-raw': String.raw`(?:"[^"]*")`,
// single-quoted
"''-qq": String.raw`(?:'[^']*')+`,
"''-bs": String.raw`(?:'[^'\\]*(?:\\.[^'\\]*)*')`,
"''-qq-bs": String.raw`(?:'[^'\\]*(?:\\.[^'\\]*)*')+`,
"''-raw": String.raw`(?:'[^']*')`,
// PostgreSQL dollar-quoted
$$: String.raw`(?<tag>\$\w*\$)[\s\S]*?\k<tag>`,
// BigQuery '''triple-quoted''' (using \' to escape)
"'''..'''": String.raw`'''[^\\]*?(?:\\.[^\\]*?)*?'''`,
// BigQuery """triple-quoted""" (using \" to escape)
'""".."""': String.raw`"""[^\\]*?(?:\\.[^\\]*?)*?"""`,
// Hive and Spark variables: ${name}
"{}": String.raw`(?:\{[^\}]*\})`,
// Oracle q'' strings: q'<text>' q'|text|' ...
"q''": CS()
}, cT = (T) => typeof T == "string" ? ET[T] : "regex" in T ? T.regex : rS(T) + ET[T.quote], oS = (T) => q(T.map((E) => "regex" in E ? E.regex : cT(E)).join("|")), MT = (T) => T.map(cT).join("|"), eT = (T) => q(MT(T)), LS = (T = {}) => q(uT(T)), uT = ({ first: T, rest: E, dashes: e, allowFirstCharNumber: R } = {}) => {
const A = "\\p{Alphabetic}\\p{Mark}_", t = "\\p{Decimal_Number}", s = K(T ?? ""), I = K(E ?? ""), r = R ? `[${A}${t}${s}][${A}${t}${I}]*` : `[${A}${s}][${A}${t}${I}]*`;
return e ? nS(r) : r;
};
function UT(T, E) {
const e = T.slice(0, E).split(/\n/);
return { line: e.length, col: e[e.length - 1].length + 1 };
}
class _S {
constructor(E, e) {
this.rules = E, this.dialectName = e, this.input = "", this.index = 0;
}
/**
* Takes a SQL string and breaks it into tokens.
* Each token is an object with type and value.
*
* @param {string} input - The SQL string
* @returns {Token[]} output token stream
*/
tokenize(E) {
this.input = E, this.index = 0;
const e = [];
let R;
for (; this.index < this.input.length; ) {
const A = this.getWhitespace();
if (this.index < this.input.length) {
if (R = this.getNextToken(), !R)
throw this.createParseError();
e.push(Object.assign(Object.assign({}, R), { precedingWhitespace: A }));
}
}
return e;
}
createParseError() {
const E = this.input.slice(this.index, this.index + 10), { line: e, col: R } = UT(this.input, this.index);
return new Error(`Parse error: Unexpected "${E}" at line ${e} column ${R}.
${this.dialectInfo()}`);
}
dialectInfo() {
return this.dialectName === "sql" ? `This likely happens because you're using the default "sql" dialect.
If possible, please select a more specific dialect (like sqlite, postgresql, etc).` : `SQL dialect used: "${this.dialectName}".`;
}
getWhitespace() {
qe.lastIndex = this.index;
const E = qe.exec(this.input);
if (E)
return this.index += E[0].length, E[0];
}
getNextToken() {
for (const E of this.rules) {
const e = this.match(E);
if (e)
return e;
}
}
// Attempts to match token rule regex at current position in input
match(E) {
E.regex.lastIndex = this.index;
const e = E.regex.exec(this.input);
if (e) {
const R = e[0], A = {
type: E.type,
raw: R,
text: E.text ? E.text(R) : R,
start: this.index
};
return E.key && (A.key = E.key(R)), this.index += R.length, A;
}
}
}
const TT = /\/\*/uy, DS = /[\s\S]/uy, PS = /\*\//uy;
class lS {
constructor() {
this.lastIndex = 0;
}
exec(E) {
let e = "", R, A = 0;
if (R = this.matchSection(TT, E))
e += R, A++;
else
return null;
for (; A > 0; )
if (R = this.matchSection(TT, E))
e += R, A++;
else if (R = this.matchSection(PS, E))
e += R, A--;
else if (R = this.matchSection(DS, E))
e += R;
else
return null;
return [e];
}
matchSection(E, e) {
E.lastIndex = this.lastIndex;
const R = E.exec(e);
return R && (this.lastIndex += R[0].length), R ? R[0] : null;
}
}
class cS {
constructor(E, e) {
this.cfg = E, this.dialectName = e, this.rulesBeforeParams = this.buildRulesBeforeParams(E), this.rulesAfterParams = this.buildRulesAfterParams(E);
}
tokenize(E, e) {
const R = [
...this.rulesBeforeParams,
...this.buildParamRules(this.cfg, e),
...this.rulesAfterParams
], A = new _S(R, this.dialectName).tokenize(E);
return this.cfg.postProcess ? this.cfg.postProcess(A) : A;
}
// These rules can be cached as they only depend on
// the Tokenizer config options specified for each SQL dialect
buildRulesBeforeParams(E) {
var e, R, A;
return this.validRules([
{
type: l.DISABLE_COMMENT,
regex: /(\/\* *sql-formatter-disable *\*\/[\s\S]*?(?:\/\* *sql-formatter-enable *\*\/|$))/uy
},
{
type: l.BLOCK_COMMENT,
regex: E.nestedBlockComments ? new lS() : /(\/\*[^]*?\*\/)/uy
},
{
type: l.LINE_COMMENT,
regex: iS((e = E.lineCommentTypes) !== null && e !== void 0 ? e : ["--"])
},
{
type: l.QUOTED_IDENTIFIER,
regex: eT(E.identTypes)
},
{
type: l.NUMBER,
regex: E.underscoresInNumbers ? /(?:0x[0-9a-fA-F_]+|0b[01_]+|(?:-\s*)?(?:[0-9_]*\.[0-9_]+|[0-9_]+(?:\.[0-9_]*)?)(?:[eE][-+]?[0-9_]+(?:\.[0-9_]+)?)?)(?![\w\p{Alphabetic}])/uy : /(?:0x[0-9a-fA-F]+|0b[01]+|(?:-\s*)?(?:[0-9]*\.[0-9]+|[0-9]+(?:\.[0-9]*)?)(?:[eE][-+]?[0-9]+(?:\.[0-9]+)?)?)(?![\w\p{Alphabetic}])/uy
},
// RESERVED_KEYWORD_PHRASE and RESERVED_DATA_TYPE_PHRASE is matched before all other keyword tokens
// to e.g. prioritize matching "TIMESTAMP WITH TIME ZONE" phrase over "WITH" clause.
{
type: l.RESERVED_KEYWORD_PHRASE,
regex: J((R = E.reservedKeywordPhrases) !== null && R !== void 0 ? R : [], E.identChars),
text: H
},
{
type: l.RESERVED_DATA_TYPE_PHRASE,
regex: J((A = E.reservedDataTypePhrases) !== null && A !== void 0 ? A : [], E.identChars),
text: H
},
{
type: l.CASE,
regex: /CASE\b/iuy,
text: H
},
{
type: l.END,
regex: /END\b/iuy,
text: H
},
{
type: l.BETWEEN,
regex: /BETWEEN\b/iuy,
text: H
},
{
type: l.LIMIT,
regex: E.reservedClauses.includes("LIMIT") ? /LIMIT\b/iuy : void 0,
text: H
},
{
type: l.RESERVED_CLAUSE,
regex: J(E.reservedClauses, E.identChars),
text: H
},
{
type: l.RESERVED_SELECT,
regex: J(E.reservedSelect, E.identChars),
text: H
},
{
type: l.RESERVED_SET_OPERATION,
regex: J(E.reservedSetOperations, E.identChars),
text: H
},
{
type: l.WHEN,
regex: /WHEN\b/iuy,
text: H
},
{
type: l.ELSE,
regex: /ELSE\b/iuy,
text: H
},
{
type: l.THEN,
regex: /THEN\b/iuy,
text: H
},
{
type: l.RESERVED_JOIN,
regex: J(E.reservedJoins, E.identChars),
text: H
},
{
type: l.AND,
regex: /AND\b/iuy,
text: H
},
{
type: l.OR,
regex: /OR\b/iuy,
text: H
},
{
type: l.XOR,
regex: E.supportsXor ? /XOR\b/iuy : void 0,
text: H
},
...E.operatorKeyword ? [
{
type: l.OPERATOR,
regex: /OPERATOR *\([^)]+\)/iuy
}
] : [],
{
type: l.RESERVED_FUNCTION_NAME,
regex: J(E.reservedFunctionNames, E.identChars),
text: H
},
{
type: l.RESERVED_DATA_TYPE,
regex: J(E.reservedDataTypes, E.identChars),
text: H
},
{
type: l.RESERVED_KEYWORD,
regex: J(E.reservedKeywords, E.identChars),
text: H
}
]);
}
// These rules can also be cached as they only depend on
// the Tokenizer config options specified for each SQL dialect
buildRulesAfterParams(E) {
var e, R;
return this.validRules([
{
type: l.VARIABLE,
regex: E.variableTypes ? oS(E.variableTypes) : void 0
},
{ type: l.STRING, regex: eT(E.stringTypes) },
{
type: l.IDENTIFIER,
regex: LS(E.identChars)
},
{ type: l.DELIMITER, regex: /[;]/uy },
{ type: l.COMMA, regex: /[,]/y },
{
type: l.OPEN_PAREN,
regex: ke("open", E.extraParens)
},
{
type: l.CLOSE_PAREN,
regex: ke("close", E.extraParens)
},
{
type: l.OPERATOR,
regex: ze([
// standard operators
"+",
"-",
"/",
">",
"<",
"=",
"<>",
"<=",
">=",
"!=",
...(e = E.operators) !== null && e !== void 0 ? e : []
])
},
{ type: l.ASTERISK, regex: /[*]/uy },
{
type: l.PROPERTY_ACCESS_OPERATOR,
regex: ze([".", ...(R = E.propertyAccessOperators) !== null && R !== void 0 ? R : []])
}
]);
}
// These rules can't be blindly cached as the paramTypesOverrides object
// can differ on each invocation of the format() function.
buildParamRules(E, e) {
var R, A, t, s, I;
const r = {
named: e?.named || ((R = E.paramTypes) === null || R === void 0 ? void 0 : R.named) || [],
quoted: e?.quoted || ((A = E.paramTypes) === null || A === void 0 ? void 0 : A.quoted) || [],
numbered: e?.numbered || ((t = E.paramTypes) === null || t === void 0 ? void 0 : t.numbered) || [],
positional: typeof e?.positional == "boolean" ? e.positional : (s = E.paramTypes) === null || s === void 0 ? void 0 : s.positional,
custom: e?.custom || ((I = E.paramTypes) === null || I === void 0 ? void 0 : I.custom) || []
};
return this.validRules([
{
type: l.NAMED_PARAMETER,
regex: zE(r.named, uT(E.paramChars || E.identChars)),
key: (S) => S.slice(1)
},
{
type: l.QUOTED_PARAMETER,
regex: zE(r.quoted, MT(E.identTypes)),
key: (S) => (({ tokenKey: N, quoteChar: O }) => N.replace(new RegExp(K("\\" + O), "gu"), O))({
tokenKey: S.slice(2, -1),
quoteChar: S.slice(-1)
})
},
{
type: l.NUMBERED_PARAMETER,
regex: zE(r.numbered, "[0-9]+"),
key: (S) => S.slice(1)
},
{
type: l.POSITIONAL_PARAMETER,
regex: r.positional ? /[?]/y : void 0
},
...r.custom.map((S) => {
var N;
return {
type: l.CUSTOM_PARAMETER,
regex: q(S.regex),
key: (N = S.key) !== null && N !== void 0 ? N : ((O) => O)
};
})
]);
}
// filters out rules for token types whose regex is undefined
validRules(E) {
return E.filter((e) => !!e.regex);
}
}
const H = (T) => iE(T.toUpperCase()), RT = /* @__PURE__ */ new Map(), MS = (T) => {
let E = RT.get(T);
return E || (E = uS(T), RT.set(T, E)), E;
}, uS = (T) => ({
tokenizer: new cS(T.tokenizerOptions, T.name),
formatOptions: US(T.formatOptions)
}), US = (T) => {
var E;
return {
alwaysDenseOperators: T.alwaysDenseOperators || [],
onelineClauses: Object.fromEntries(T.onelineClauses.map((e) => [e, !0])),
tabularOnelineClauses: Object.fromEntries(((E = T.tabularOnelineClauses) !== null && E !== void 0 ? E : T.onelineClauses).map((e) => [e, !0]))
};
};
function dS(T) {
return T.indentStyle === "tabularLeft" || T.indentStyle === "tabularRight" ? " ".repeat(10) : T.useTabs ? " " : " ".repeat(T.tabWidth);
}
function z(T) {
return T.indentStyle === "tabularLeft" || T.indentStyle === "tabularRight";
}
class mS {
constructor(E) {
this.params = E, this.index = 0;
}
/**
* Returns param value that matches given placeholder with param key.
*/
get({ key: E, text: e }) {
return this.params ? E ? this.params[E] : this.params[this.index++] : e;
}
/**
* Returns index of current positional parameter.
*/
getPositionalParameterIndex() {
return this.index;
}
/**
* Sets index of current positional parameter.
*/
setPositionalParameterIndex(E) {
this.index = E;
}
}
function GS(T) {
return T && T.__esModule && Object.prototype.hasOwnProperty.call(T, "default") ? T.default : T;
}
var aE = { exports: {} }, pS = aE.exports, AT;
function fS() {
return AT || (AT = 1, (function(T) {
(function(E, e) {
T.exports ? T.exports = e() : E.nearley = e();
})(pS, function() {
function E(S, N, O) {
return this.id = ++E.highestId, this.name = S, this.symbols = N, this.postprocess = O, this;
}
E.highestId = 0, E.prototype.toString = function(S) {
var N = typeof S > "u" ? this.symbols.map(r).join(" ") : this.symbols.slice(0, S).map(r).join(" ") + " ● " + this.symbols.slice(S).map(r).join(" ");
return this.name + " → " + N;
};
function e(S, N, O, i) {
this.rule = S, this.dot = N, this.reference = O, this.data = [], this.wantedBy = i, this.isComplete = this.dot === S.symbols.length;
}
e.prototype.toString = function() {
return "{" + this.rule.toString(this.dot) + "}, from: " + (this.reference || 0);
}, e.prototype.nextState = function(S) {
var N = new e(this.rule, this.dot + 1, this.reference, this.wantedBy);
return N.left = this, N.right = S, N.isComplete && (N.data = N.build(), N.right = void 0), N;
}, e.prototype.build = function() {
var S = [], N = this;
do
S.push(N.right.data), N = N.left;
while (N.left);
return S.reverse(), S;
}, e.prototype.finish = function() {
this.rule.postprocess && (this.data = this.rule.postprocess(this.data, this.reference, s.fail));
};
function R(S, N) {
this.grammar = S, this.index = N, this.states = [], this.wants = {}, this.scannable = [], this.completed = {};
}
R.prototype.process = function(S) {
for (var N = this.states, O = this.wants, i = this.completed, a = 0; a < N.length; a++) {
var C = N[a];
if (C.isComplete) {
if (C.finish(), C.data !== s.fail) {
for (var _ = C.wantedBy, P = _.length; P--; ) {
var c = _[P];
this.complete(c, C);
}
if (C.reference === this.index) {
var L = C.rule.name;
(this.completed[L] = this.completed[L] || []).push(C);
}
}
} else {
var L = C.rule.symbols[C.dot];
if (typeof L != "string") {
this.scannable.push(C);
continue;
}
if (O[L]) {
if (O[L].push(C), i.hasOwnProperty(L))
for (var u = i[L], P = 0; P < u.length; P++) {
var M = u[P];
this.complete(C, M);
}
} else
O[L] = [C], this.predict(L);
}
}
}, R.prototype.predict = function(S) {
for (var N = this.grammar.byName[S] || [], O = 0; O < N.length; O++) {
var i = N[O], a = this.wants[S], C = new e(i, 0, this.index, a);
this.states.push(C);
}
}, R.prototype.complete = function(S, N) {
var O = S.nextState(N);
this.states.push(O);
};
function A(S, N) {
this.rules = S, this.start = N || this.rules[0].name;
var O = this.byName = {};
this.rules.forEach(function(i) {
O.hasOwnProperty(i.name) || (O[i.name] = []), O[i.name].push(i);
});
}
A.fromCompiled = function(i, N) {
var O = i.Lexer;
i.ParserStart && (N = i.ParserStart, i = i.ParserRules);
var i = i.map(function(C) {
return new E(C.name, C.symbols, C.postprocess);
}), a = new A(i, N);
return a.lexer = O, a;
};
function t() {
this.reset("");
}
t.prototype.reset = function(S, N) {
this.buffer = S, this.index = 0, this.line = N ? N.line : 1, this.lastLineBreak = N ? -N.col : 0;
}, t.prototype.next = function() {
if (this.index < this.buffer.length) {
var S = this.buffer[this.index++];
return S === `
` && (this.line += 1, this.lastLineBreak = this.index), { value: S };
}
}, t.prototype.save = function() {
return {
line: this.line,
col: this.index - this.lastLineBreak
};
}, t.prototype.formatError = function(S, N) {
var O = this.buffer;
if (typeof O == "string") {
var i = O.split(`
`).slice(
Math.max(0, this.line - 5),
this.line
), a = O.indexOf(`
`, this.index);
a === -1 && (a = O.length);
var C = this.index - this.lastLineBreak, _ = String(this.line).length;
return N += " at line " + this.line + " col " + C + `:
`, N += i.map(function(c, L) {
return P(this.line - i.length + L + 1, _) + " " + c;
}, this).join(`
`), N += `
` + P("", _ + C) + `^
`, N;
} else
return N + " at index " + (this.index - 1);
function P(c, L) {
var u = String(c);
return Array(L - u.length + 1).join(" ") + u;
}
};
function s(S, N, O) {
if (S instanceof A)
var i = S, O = N;
else
var i = A.fromCompiled(S, N);
this.grammar = i, this.options = {
keepHistory: !1,
lexer: i.lexer || new t()
};
for (var a in O || {})
this.options[a] = O[a];
this.lexer = this.options.lexer, this.lexerState = void 0;
var C = new R(i, 0);
this.table = [C], C.wants[i.start] = [], C.predict(i.start), C.process(), this.current = 0;
}
s.fail = {}, s.prototype.feed = function(S) {
var N = this.lexer;
N.reset(S, this.lexerState);
for (var O; ; ) {
try {
if (O = N.next(), !O)
break;
} catch (f) {
var _ = new R(this.grammar, this.current + 1);
this.table.push(_);
var i = new Error(this.reportLexerError(f));
throw i.offset = this.current, i.token = f.token, i;
}
var a = this.table[this.current];
this.options.keepHistory || delete this.table[this.current - 1];
var C = this.current + 1, _ = new R(this.grammar, C);
this.table.push(_);
for (var P = O.text !== void 0 ? O.text : O.value, c = N.constructor === t ? O.value : O, L = a.scannable, u = L.length; u--; ) {
var M = L[u], d = M.rule.symbols[M.dot];
if (d.test ? d.test(c) : d.type ? d.type === O.type : d.literal === P) {
var G = M.nextState({ data: c, token: O, isToken: !0, reference: C - 1 });
_.states.push(G);
}
}
if (_.process(), _.states.length === 0) {
var i = new Error(this.reportError(O));
throw i.offset = this.current, i.token = O, i;
}
this.options.keepHistory && (a.lexerState = N.save()), this.current++;
}
return a && (this.lexerState = N.save()), this.results = this.finish(), this;
}, s.prototype.reportLexerError = function(S) {
var N, O, i = S.token;
return i ? (N = "input " + JSON.stringify(i.text[0]) + " (lexer error)", O = this.lexer.formatError(i, "Syntax error")) : (N = "input (lexer error)", O = S.message), this.reportErrorCommon(O, N);
}, s.prototype.reportError = function(S) {
var N = (S.type ? S.type + " token: " : "") + JSON.stringify(S.value !== void 0 ? S.value : S), O = this.lexer.formatError(S, "Syntax error");
return this.reportErrorCommon(O, N);
}, s.prototype.reportErrorCommon = function(S, N) {
var O = [];
O.push(S);
var i = this.table.length - 2, a = this.table[i], C = a.states.filter(function(P) {
var c = P.rule.symbols[P.dot];
return c && typeof c != "string";
});
if (C.length === 0)
O.push("Unexpected " + N + `. I did not expect any more input. Here is the state of my parse table:
`), this.displayStateStack(a.states, O);
else {
O.push("Unexpected " + N + `. Instead, I was expecting to see one of the following:
`);
var _ = C.map(function(P) {
return this.buildFirstStateStack(P, []) || [P];
}, this);
_.forEach(function(P) {
var c = P[0], L = c.rule.symbols[c.dot], u = this.getSymbolDisplay(L);
O.push("A " + u + " based on:"), this.displayStateStack(P, O);
}, this);
}
return O.push(""), O.join(`
`);
}, s.prototype.displayStateStack = function(S, N) {
for (var O, i = 0, a = 0; a < S.length; a++) {
var C = S[a], _ = C.rule.toString(C.dot);
_ === O ? i++ : (i > 0 && N.push(" ^ " + i + " more lines identical to this"), i = 0, N.push(" " + _)), O = _;
}
}, s.prototype.getSymbolDisplay = function(S) {
return I(S);
}, s.prototype.buildFirstStateStack = function(S, N) {
if (N.indexOf(S) !== -1)
return null;
if (S.wantedBy.length === 0)
return [S];
var O = S.wantedBy[0], i = [S].concat(N), a = this.buildFirstStateStack(O, i);
return a === null ? null : [S].concat(a);
}, s.prototype.save = function() {
var S = this.table[this.current];
return S.lexerState = this.lexerState, S;
}, s.prototype.restore = function(S) {
var N = S.index;
this.current = N, this.table[N] = S, this.table.splice(N + 1), this.lexerState = S.lexerState, this.results = this.finish();
}, s.prototype.rewind = function(S) {
if (!this.options.keepHistory)
throw new Error("set option `keepHistory` to enable rewinding");
this.restore(this.table[S]);
}, s.prototype.finish = function() {
var S = [], N = this.grammar.start, O = this.table[this.table.length - 1];
return O.states.forEach(function(i) {
i.rule.name === N && i.dot === i.rule.symbols.length && i.reference === 0 && i.data !== s.fail && S.push(i);
}), S.map(function(i) {
return i.data;
});
};
function I(S) {
var N = typeof S;
if (N === "string")
return S;
if (N === "object") {
if (S.literal)
return JSON.stringify(S.literal);
if (S instanceof RegExp)
return "character matching " + S;
if (S.type)
return S.type + " token";
if (S.test)
return "token matching " + String(S.test);
throw new Error("Unknown symbol type: " + S);
}
}
function r(S) {
var N = typeof S;
if (N === "string")
return S;
if (N === "object") {
if (S.literal)
return JSON.stringify(S.literal);
if (S instanceof RegExp)
return S.toString();
if (S.type)
return "%" + S.type;
if (S.test)
return "<" + String(S.test) + ">";
throw new Error("Unknown symbol type: " + S);
}
}
return {
Parser: s,
Grammar: A,
Rule: E
};
});
})(aE)), aE.exports;
}
var BS = fS();
const hS = /* @__PURE__ */ GS(BS);
function HS(T) {
return T.map(FS).map(YS).map(VS).map(bS).map(gS);
}
const FS = (T, E, e) => {
if (PT(T.type)) {
const R = WS(e, E);
if (R && R.type === l.PROPERTY_ACCESS_OPERATOR)
return Object.assign(Object.assign({}, T), { type: l.IDENTIFIER, text: T.raw });
const A = RE(e, E);
if (A && A.type === l.PROPERTY_ACCESS_OPERATOR)
return Object.assign(Object.assign({}, T), { type: l.IDENTIFIER, text: T.raw });
}
return T;
}, YS = (T, E, e) => {
if (T.type === l.RESERVED_FUNCTION_NAME) {
const R = RE(e, E);
if (!R || !dT(R))
return Object.assign(Object.assign({}, T), { type: l.IDENTIFIER, text: T.raw });
}
return T;
}, VS = (T, E, e) => {
if (T.type === l.RESERVED_DATA_TYPE) {
const R = RE(e, E);
if (R && dT(R))
return Object.assign(Object.assign({}, T), { type: l.RESERVED_PARAMETERIZED_DATA_TYPE });
}
return T;
}, bS = (T, E, e) => {
if (T.type === l.IDENTIFIER) {
const R = RE(e, E);
if (R && mT(R))
return Object.assign(Object.assign({}, T), { type: l.ARRAY_IDENTIFIER });
}
return T;
}, gS = (T, E, e) => {
if (T.type === l.RESERVED_DATA_TYPE) {
const R = RE(e, E);
if (R && mT(R))
return Object.assign(Object.assign({}, T), { type: l.ARRAY_KEYWORD });
}
return T;
}, WS = (T, E) => RE(T, E, -1), RE = (T, E, e = 1) => {
let R = 1;
for (; T[E + R * e] && yS(T[E + R * e]); )
R++;
return T[E + R * e];
}, dT = (T) => T.type === l.OPEN_PAREN && T.text === "(", mT = (T) => T.type === l.OPEN_PAREN && T.text === "[", yS = (T) => T.type === l.BLOCK_COMMENT || T.type === l.LINE_COMMENT;
class GT {
constructor(E) {
this.tokenize = E, this.index = 0, this.tokens = [], this.input = "";
}
reset(E, e) {
this.input = E, this.index = 0, this.tokens = this.tokenize(E);
}
next() {
return this.tokens[this.index++];
}
save() {
}
formatError(E) {
const { line: e, col: R } = UT(this.input, E.start);
return `Parse error at token: ${E.text} at line ${e} column ${R}`;
}
has(E) {
return E in l;
}
}
var U;
(function(T) {
T.statement = "statement", T.clause = "clause", T.set_operation = "set_operation", T.function_call = "function_call", T.parameterized_data_type = "parameterized_data_type", T.array_subscript = "array_subscript", T.property_access = "property_access", T.parenthesis = "parenthesis", T.between_predicate = "between_predicate", T.case_expression = "case_expression", T.case_when = "case_when", T.case_else = "case_else", T.limit_clause = "limit_clause", T.all_columns_asterisk = "all_columns_asterisk", T.literal = "literal", T.identifier = "identifier", T.keyword = "keyword", T.data_type = "data_type", T.parameter = "parameter", T.operator = "operator", T.comma = "comma", T.line_comment = "line_comment", T.block_comment = "block_comment", T.disable_comment = "disable_comment";
})(U = U || (U = {}));
function Ee(T) {
return T[0];
}
const m = new GT((T) => []), x = ([[T]]) => T, Y = (T) => ({
type: U.keyword,
tokenType: T.type,
text: T.text,
raw: T.raw
}), tT = (T) => ({
type: U.data_type,
text: T.text,
raw: T.raw
}), V = (T, { leading: E, trailing: e }) => (E?.length && (T = Object.assign(Object.assign({}, T), { leadingComments: E })), e?.length && (T = Object.assign(Object.assign({}, T), { trailingComments: e })), T), XS = (T, { leading: E, trailing: e }) => {
if (E?.length) {
const [R, ...A] = T;
T = [V(R, { leading: E }), ...A];
}
if (e?.length) {
const R = T.slice(0, -1), A = T[T.length - 1];
T = [...R, V(A, { trailing: e })];
}
return T;
}, $S = {
Lexer: m,
ParserRules: [
{ name: "main$ebnf$1", symbols: [] },
{ name: "main$ebnf$1", symbols: ["main$ebnf$1", "statement"], postprocess: (T) => T[0].concat([T[1]]) },
{
name: "main",
symbols: ["main$ebnf$1"],
postprocess: ([T]) => {
const E = T[T.length - 1];
return E && !E.hasSemicolon ? E.children.length > 0 ? T : T.slice(0, -1) : T;
}
},
{ name: "statement$subexpression$1", symbols: [m.has("DELIMITER") ? { type: "DELIMITER" } : DELIMITER] },
{ name: "statement$subexpression$1", symbols: [m.has("EOF") ? { type: "EOF" } : EOF] },
{
name: "statement",
symbols: ["expressions_or_clauses", "statement$subexpression$1"],
postprocess: ([T, [E]]) => ({
type: U.statement,
children: T,
hasSemicolon: E.type === l.DELIMITER
})
},
{ name: "expressions_or_clauses$ebnf$1", symbols: [] },
{ name: "expressions_or_clauses$ebnf$1", symbols: ["expressions_or_clauses$ebnf$1", "free_form_sql"], postprocess: (T) => T[0].concat([T[1]]) },
{ name: "expressions_or_clauses$ebnf$2", symbols: [] },
{ name: "expressions_or_clauses$ebnf$2", symbols: ["expressions_or_clauses$ebnf$2", "clause"], postprocess: (T) => T[0].concat([T[1]]) },
{
name: "expressions_or_clauses",
symbols: ["expressions_or_clauses$ebnf$1", "expressions_or_clauses$ebnf$2"],
postprocess: ([T, E]) => [...T, ...E]
},
{ name: "clause$subexpression$1", symbols: ["limit_clause"] },
{ name: "clause$subexpression$1", symbols: ["select_clause"] },
{ name: "clause$subexpression$1", symbols: ["other_clause"] },
{ name: "clause$subexpression$1", symbols: ["set_operation"] },
{ name: "clause", symbols: ["clause$subexpression$1"], postprocess: x },
{ name: "limit_clause$ebnf$1$subexpression$1$ebnf$1", symbols: ["free_form_sql"] },
{ name: "limit_clause$ebnf$1$subexpression$1$ebnf$1", symbols: ["limit_clause$ebnf$1$subexpression$1$ebnf$1", "free_form_sql"], postprocess: (T) => T[0].concat([T[1]]) },
{ name: "limit_clause$ebnf$1$subexpression$1", symbols: [m.has("COMMA") ? { type: "COMMA" } : COMMA, "limit_clause$ebnf$1$subexpression$1$ebnf$1"] },
{ name: "limit_clause$ebnf$1", symbols: ["limit_clause$ebnf$1$subexpression$1"], postprocess: Ee },
{ name: "limit_clause$ebnf$1", symbols: [], postprocess: () => null },
{
name: "limit_clause",
symbols: [m.has("LIMIT") ? { type: "LIMIT" } : LIMIT, "_", "expression_chain_", "limit_clause$ebnf$1"],
postprocess: ([T, E, e, R]) => {
if (R) {
const [A, t] = R;
return {
type: U.limit_clause,
limitKw: V(Y(T), { trailing: E }),
offset: e,
count: t
};
} else
return {
type: U.limit_clause,
limitKw: V(Y(T), { trailing: E }),
count: e
};
}
},
{ name: "select_clause$subexpression$1$ebnf$1", symbols: [] },
{ name: "select_clause$subexpression$1$ebnf$1", symbols: ["select_clause$subexpression$1$ebnf$1", "free_form_sql"], postprocess: (T) => T[0].concat([T[1]]) },
{ name: "select_clause$subexpression$1", symbols: ["all_columns_asterisk", "select_clause$subexpression$1$ebnf$1"] },
{ name: "select_clause$subexpression$1$ebnf$2", symbols: [] },
{ name: "select_clause$subexpression$1$ebnf$2", symbols: ["select_clause$subexpression$1$ebnf$2", "free_form_sql"], postprocess: (T) => T[0].concat([T[1]]) },
{ name: "select_clause$subexpression$1", symbols: ["asteriskless_free_form_sql", "select_clause$subexpression$1$ebnf$2"] },
{
name: "select_clause",
symbols: [m.has("RESERVED_SELECT") ? { type: "RESERVED_SELECT" } : RESERVED_SELECT, "select_clause$subexpression$1"],
postprocess: ([T, [E, e]]) => ({
type: U.clause,
nameKw: Y(T),
children: [E, ...e]
})
},
{
name: "select_clause",
symbols: [m.has("RESERVED_SELECT") ? { type: "RESERVED_SELECT" } : RESERVED_SELECT],
postprocess: ([T]) => ({
type: U.clause,
nameKw: Y(T),
children: []
})
},
{
name: "all_columns_asterisk",
symbols: [m.has("ASTERISK") ? { type: "ASTERISK" } : ASTERISK],
postprocess: () => ({ type: U.all_columns_asterisk })
},
{ name: "other_clause$ebnf$1", symbols: [] },
{ name: "other_clause$ebnf$1", symbols: ["other_clause$ebnf$1", "free_form_sql"], postprocess: (T) => T[0].concat([T[1]]) },
{
name: "other_clause",
symbols: [m.has("RESERVED_CLAUSE") ? { type: "RESERVED_CLAUSE" } : RESERVED_CLAUSE, "other_clause$ebnf$1"],
postprocess: ([T, E]) => ({
type: U.clause,
nameKw: Y(T),
children: E
})
},
{ name: "set_operation$ebnf$1", symbols: [] },
{ name: "set_operation$ebnf$1", symbols: ["set_operation$ebnf$1", "free_form_sql"], postprocess: (T) => T[0].concat([T[1]]) },
{
name: "set_operation",
symbols: [m.has("RESERVED_SET_OPERATION") ? { type: "RESERVED_SET_OPERATION" } : RESERVED_SET_OPERATION, "set_operation$ebnf$1"],
postprocess: ([T, E]) => ({
type: U.set_operation,
nameKw: Y(T),
children: E
})
},
{ name: "expression_chain_$ebnf$1", symbols: ["expression_with_comments_"] },
{ name: "expression_chain_$ebnf$1", symbols: ["expression_chain_$ebnf$1", "expression_with_comments_"], postprocess: (T) => T[0].concat([T[1]]) },
{ name: "expression_chain_", symbols: ["expression_chain_$ebnf$1"], postprocess: Ee },
{ name: "expression_chain$ebnf$1", symbols: [] },
{ name: "expression_chain$ebnf$1", symbols: ["expression_chain$ebnf$1", "_expression_with_comments"], postprocess: (T) => T[0].concat([T[1]]) },
{
name: "expression_chain",
symbols: ["expression", "expression_chain$ebnf$1"],
postprocess: ([T, E]) => [T, ...E]
},
{ name: "andless_expression_chain$ebnf$1", symbols: [] },
{ name: "andless_expression_chain$ebnf$1", symbols: ["andless_expression_chain$ebnf$1", "_andless_expression_with_comments"], postprocess: (T) => T[0].concat([T[1]]) },
{
name: "andless_expression_chain",
symbols: ["andless_expression", "andless_expression_chain$ebnf$1"],
postprocess: ([T, E]) => [T, ...E]
},
{
name: "expression_with_comments_",
symbols: ["expression", "_"],
postprocess: ([T, E]) => V(T, { trailing: E })
},
{
name: "_expression_with_comments",
symbols: ["_", "expression"],
postprocess: ([T, E]) => V(E, { leading: T })
},
{
name: "_andless_expression_with_comments",
symbols: ["_", "andless_expression"],
postprocess: ([T, E]) => V(E, { leading: T })
},
{ name: "free_form_sql$subexpression$1", symbols: ["asteriskless_free_form_sql"] },
{ name: "free_form_sql$subexpression$1", symbols: ["asterisk"] },
{ name: "free_form_sql", symbols: ["free_form_sql$subexpression$1"], postprocess: x },
{ name: "asteriskless_free_form_sql$subexpression$1", symbols: ["asteriskless_andless_expression"] },
{ name: "asteriskless_free_form_sql$subexpression$1", symbols: ["logic_operator"] },
{ name: "asteriskless_free_form_sql$subexpression$1", symbols: ["comma"] },
{ name: "asteriskless_free_form_sql$subexpression$1", symbols: ["comment"] },
{ name: "asteriskless_free_form_sql$subexpression$1", symbols: ["other_keyword"] },
{ name: "asteriskless_free_form_sql", symbols: ["asteriskless_free_form_sql$subexpression$1"], postprocess: x },
{ name: "expression$subexpression$1", symbols: ["andless_expression"] },
{ name: "expression$subexpression$1", symbols: ["logic_operator"] },
{ name: "expression", symbols: ["expression$subexpression$1"], postprocess: x },
{ name: "andless_expression$subexpression$1", symbols: ["asteriskless_andless_expression"] },
{ name: "andless_expression$subexpression$1", symbols: ["asterisk"] },
{ name: "andless_expression", symbols: ["andless_expression$subexpression$1"], postprocess: x },
{ name: "asteriskless_andless_expression$subexpression$1", symbols: ["atomic_expression"] },
{ name: "asteriskless_andless_expression$subexpression$1", symbols: ["between_predicate"] },
{ name: "asteriskless_andless_expression$subexpression$1", symbols: ["case_expression"] },
{ name: "asteriskless_andless_expression", symbols: ["asteriskless_andless_expression$subexpression$1"], postprocess: x },
{ name: "atomic_expression$subexpression$1", symbols: ["array_subscript"] },
{ name: "atomic_expression$subexpression$1", symbols: ["function_call"] },
{ name: "atomic_expression$subexpression$1", symbols: ["property_access"] },
{ name: "atomic_expression$subexpression$1", symbols: ["parenthesis"] },
{ name: "atomic_expression$subexpression$1", symbols: ["curly_braces"] },
{ name: "atomic_expression$subexpression$1", symbols: ["square_brackets"] },
{ name: "atomic_expression$subexpression$1", symbols: ["operator"] },
{ name: "atomic_expression$subexpression$1", symbols: ["identifier"] },
{ name: "atomic_expression$subexpression$1", symbols: ["parameter"] },
{ name: "atomic_expression$subexpression$1", symbols: ["literal"] },
{ name: "atomic_expression$subexpression$1", symbols: ["data_type"] },
{ name: "atomic_expression$subexpression$1", symbols: ["keyword"] },
{ name: "atomic_expression", symbols: ["atomic_expression$subexpression$1"], postprocess: x },
{
name: "array_subscript",
symbols: [m.has("ARRAY_IDENTIFIER") ? { type: "ARRAY_IDENTIFIER" } : ARRAY_IDENTIFIER, "_", "square_brackets"],
postprocess: ([T, E, e]) => ({
type: U.array_subscript,
array: V({ type: U.identifier, quoted: !1, text: T.text }, { trailing: E }),
parenthesis: e
})
},
{
name: "array_subscript",
symbols: [m.has("ARRAY_KEYWORD") ? { type: "ARRAY_KEYWORD" } : ARRAY_KEYWORD, "_", "square_brackets"],
postprocess: ([T, E, e]) => ({
type: U.array_subscript,
array: V(Y(T), { trailing: E }),
parenthesis: e
})
},
{
name: "function_call",
symbols: [m.has("RESERVED_FUNCTION_NAME") ? { type: "RESERVED_FUNCTION_NAME" } : RESERVED_FUNCTION_NAME, "_", "parenthesis"],
postprocess: ([T, E, e]) => ({
type: U.function_call,
nameKw: V(Y(T), { trailing: E }),
parenthesis: e
})
},
{
name: "parenthesis",
symbols: [{ literal: "(" }, "expressions_or_clauses", { literal: ")" }],
postprocess: ([T, E, e]) => ({
type: U.parenthesis,
children: E,
openParen: "(",
closeParen: ")"
})
},
{ name: "curly_braces$ebnf$1", symbols: [] },
{ name: "curly_braces$ebnf$1", symbols: ["curly_braces$ebnf$1", "free_form_sql"], postprocess: (T) => T[0].concat([T[1]]) },
{
name: "curly_braces",
symbols: [{ literal: "{" }, "curly_braces$ebnf$1", { literal: "}" }],
postprocess: ([T, E, e]) => ({
type: U.parenthesis,
children: E,
openParen: "{",
closeParen: "}"
})
},
{ name: "square_brackets$ebnf$1", symbols: [] },
{ name: "square_brackets$ebnf$1", symbols: ["square_brackets$ebnf$1", "free_form_sql"], postprocess: (T) => T[0].concat([T[1]]) },
{
name: "square_brackets",
symbols: [{ literal: "[" }, "square_brackets$ebnf$1", { literal: "]" }],
postprocess: ([T, E, e]) => ({
type: U.parenthesis,
children: E,
openParen: "[",
closeParen: "]"
})
},
{ name: "property_access$subexpression$1", symbols: ["identifier"] },
{ name: "property_access$subexpression$1", symbols: ["array_subscript"] },
{ name: "property_access$subexpression$1", symbols: ["all_columns_asterisk"] },
{ name: "property_access$subexpression$1", symbols: ["parameter"] },
{
name: "property_access",
symbols: ["atomic_expression", "_", m.has("PROPERTY_ACCESS_OPERATOR") ? { type: "PROPERTY_ACCESS_OPERATOR" } : PROPERTY_ACCESS_OPERATOR, "_", "property_access$subexpression$1"],
postprocess: (
// Allowing property to be <array_subscript> is currently a hack.
// A better way would be to allow <property_access> on the left side of array_subscript,
// but we currently can't do that because of another hack that requires
// %ARRAY_IDENTIFIER on the left side of <array_subscript>.
([T, E, e, R, [A]]) => ({
type: U.property_access,
object: V(T, { trailing: E }),
operator: e.text,
property: V(A, { leading: R })
})
)
},
{
name: "between_predicate",
symbols: [m.has("BETWEEN") ? { type: "BETWEEN" } : BETWEEN, "_", "andless_expression_chain", "_", m.has("AND") ? { type: "AND" } : AND, "_", "andless_expression"],
postprocess: ([T, E, e, R, A, t, s]) => ({
type: U.between_predicate,
betweenKw: Y(T),
expr1: XS(e, { leading: E, trailing: R }),
andKw: Y(A),
expr2: [V(s, { leading: t })]
})
},
{ name: "case_expression$ebnf$1", symbols: ["expression_chain_"], postprocess: Ee },
{ name: "case_expression$ebnf$1", symbols: [], postprocess: () => null },
{ name: "case_expression$ebnf$2", symbols: [] },
{ name: "case_expression$ebnf$2", symbols: ["case_expression$ebnf$2", "case_clause"], postprocess: (T) => T[0].concat([T[1]]) },
{
name: "case_expression",
symbols: [m.has("CASE") ? { type: "CASE" } : CASE, "_", "case_expression$ebnf$1", "case_expression$ebnf$2", m.has("END") ? { type: "END" } : END],
postprocess: ([T, E, e, R, A]) => ({
type: U.case_expression,
caseKw: V(Y(T), { trailing: E }),
endKw: Y(A),
expr: e || [],
clauses: R
})
},
{
name: "case_clause",
symbols: [m.has("WHEN") ? { type: "WHEN" } : WHEN, "_", "expression_chain_", m.has("THEN") ? { type: "THEN" } : THEN, "_", "expression_chain_"],
postprocess: ([T, E, e, R, A, t]) => ({
type: U.case_when,
whenKw: V(Y(T), { trailing: E }),
thenKw: V(Y(R), { trailing: A }),
condition: e,
result: t
})
},
{
name: "case_clause",
symbols: [m.has("ELSE") ? { type: "ELSE" } : ELSE, "_", "expression_chain_"],
postprocess: ([T, E, e]) => ({
type: U.case_else,
elseKw: V(Y(T), { trailing: E }),
result: e
})
},
{ name: "comma$subexpression$1", symbols: [m.has("COMMA") ? { type: "COMMA" } : COMMA] },
{ name: "comma", symbols: ["comma$subexpression$1"], postprocess: ([[T]]) => ({ type: U.comma }) },
{ name: "asterisk$subexpression$1", symbols: [m.has("ASTERISK") ? { type: "ASTERISK" } : ASTERISK] },
{ name: "asterisk", symbols: ["asterisk$subexpression$1"], postprocess: ([[T]]) => ({ type: U.operator, text: T.text }) },
{ name: "operator$subexpression$1", symbols: [m.has("OPERATOR") ? { type: "OPERATOR" } : OPERATOR] },
{ name: "operator", symbols: ["operator$subexpression$1"], postprocess: ([[T]]) => ({ type: U.operator, text: T.text }) },
{ name: "identifier$subexpression$1", symbols: [m.has("IDENTIFIER") ? { type: "IDENTIFIER" } : IDENTIFIER] },
{ name: "identifier$subexpression$1", symbols: [m.has("QUOTED_IDENTIFIER") ? { type: "QUOTED_IDENTIFIER" } : QUOTED_IDENTIFIER] },
{ name: "identifier$subexpression$1", symbols: [m.has("VARIABLE") ? { type: "VARIABLE" } : VARIABLE] },
{ name: "identifier", symbols: ["identifier$subexpression$1"], postprocess: ([[T]]) => ({ type: U.identifier, quoted: T.type !== "IDENTIFIER", text: T.text }) },
{ name: "parameter$subexpression$1", symbols: [m.has("NAMED_PARAMETER") ? { type: "NAMED_PARAMETER" } : NAMED_PARAMETER] },
{ name: "parameter$subexpression$1", symbols: [m.has("QUOTED_PARAMETER") ? { type: "QUOTED_PARAMETER" } : QUOTED_PARAMETER] },
{ name: "parameter$subexpression$1", symbols: [m.has("NUMBERED_PARAMETER") ? { type: "NUMBERED_PARAMETER" } : NUMBERED_PARAMETER] },
{ name: "parameter$subexpression$1", symbols: [m.has("POSITIONAL_PARAMETER") ? { type: "POSITIONAL_PARAMETER" } : POSITIONAL_PARAMETER] },
{ name: "parameter$subexpression$1", symbols: [m.has("CUSTOM_PARAMETER") ? { type: "CUSTOM_PARAMETER" } : CUSTOM_PARAMETER] },
{ name: "parameter", symbols: ["parameter$subexpression$1"], postprocess: ([[T]]) => ({ type: U.parameter, key: T.key, text: T.text }) },
{ name: "literal$subexpression$1", symbols: [m.has("NUMBER") ? { type: "NUMBER" } : NUMBER] },
{ name: "literal$subexpression$1", symbols: [m.has("STRING") ? { type: "STRING" } : STRING] },
{ name: "literal", symbols: ["literal$subexpression$1"], postprocess: ([[T]]) => ({ type: U.literal, text: T.text }) },
{ name: "keyword$subexpression$1", symbols: [m.has("RESERVED_KEYWORD") ? { type: "RESERVED_KEYWORD" } : RESERVED_KEYWORD] },
{ name: "keyword$subexpression$1", symbols: [m.has("RESERVED_KEYWORD_PHRASE") ? { type: "RESERVED_KEYWORD_PHRASE" } : RESERVED_KEYWORD_PHRASE] },
{ name: "keyword$subexpression$1", symbols: [m.has("RESERVED_JOIN") ? { type: "RESERVED_JOIN" } : RESERVED_JOIN] },
{
name: "keyword",
symbols: ["keyword$subexpression$1"],
postprocess: ([[T]]) => Y(T)
},
{ name: "data_type$subexpression$1", symbols: [m.has("RESERVED_DATA_TYPE") ? { type: "RESERVED_DATA_TYPE" } : RESERVED_DATA_TYPE] },
{ name: "data_type$subexpression$1", symbols: [m.has("RESERVED_DATA_TYPE_PHRASE") ? { type: "RESERVED_DATA_TYPE_PHRASE" } : RESERVED_DATA_TYPE_PHRASE] },
{
name: "data_type",
symbols: ["data_type$subexpression$1"],
postprocess: ([[T]]) => tT(T)
},
{
name: "data_type",
symbols: [m.has("RESERVED_PARAMETERIZED_DATA_TYPE") ? { type: "RESERVED_PARAMETERIZED_DATA_TYPE" } : RESERVED_PARAMETERIZED_DATA_TYPE, "_", "parenthesis"],
postprocess: ([T, E, e]) => ({
type: U.parameterized_data_type,
dataType: V(tT(T), { trailing: E }),
parenthesis: e
})
},
{ name: "logic_operator$subexpression$1", symbols: [m.has("AND") ? { type: "AND" } : AND] },
{ name: "logic_operator$subexpression$1", symbols: [m.has("OR") ? { type: "OR" } : OR] },
{ name: "logic_operator$subexpression$1", symbols: [m.has("XOR") ? { type: "XOR" } : XOR] },
{
name: "logic_operator",
symbols: ["logic_operator$subexpression$1"],
postprocess: ([[T]]) => Y(T)
},
{ name: "other_keyword$subexpression$1", symbols: [m.has("WHEN") ? { type: "WHEN" } : WHEN] },
{ name: "other_keyword$subexpression$1", symbols: [m.has("THEN") ? { type: "THEN" } : THEN] },
{ name: "other_keyword$subexpression$1", symbols: [m.has("ELSE") ? { type: "ELSE" } : ELSE] },
{ name: "other_keyword$subexpression$1", symbols: [m.has("END") ? { type: "END" } : END] },
{
name: "other_keyword",
symbols: ["other_keyword$subexpression$1"],
postprocess: ([[T]]) => Y(T)
},
{ name: "_$ebnf$1", symbols: [] },
{ name: "_$ebnf$1", symbols: ["_$ebnf$1", "comment"], postprocess: (T) => T[0].concat([T[1]]) },
{ name: "_", symbols: ["_$ebnf$1"], postprocess: ([T]) => T },
{
name: "comment",
symbols: [m.has("LINE_COMMENT") ? { type: "LINE_COMMENT" } : LINE_COMMENT],
postprocess: ([T]) => ({
type: U.line_comment,
text: T.text,
precedingWhitespace: T.precedingWhitespace
})
},
{
name: "comment",
symbols: [m.has("BLOCK_COMMENT") ? { type: "BLOCK_COMMENT" } : BLOCK_COMMENT],
postprocess: ([T]) => ({
type: U.block_comment,
text: T.text,
precedingWhitespace: T.precedingWhitespace
})
},
{
name: "comment",
symbols: [m.has("DISABLE_COMMENT") ? { type: "DISABLE_COMMENT" } : DISABLE_COMMENT],
postprocess: ([T]) => ({
type: U.disable_comment,
text: T.text,
precedingWhitespace: T.precedingWhitespace
})
}
],
ParserStart: "main"
}, { Parser: KS, Grammar: wS } = hS;
function JS(T) {
let E = {};
const e = new GT((A) => [
...HS(T.tokenize(A, E)),
DT(A.length)
]), R = new KS(wS.fromCompiled($S), { lexer: e });
return {
parse: (A, t) => {
E = t;
const { results: s } = R.feed(A);
if (s.length === 1)
return s[0];
throw s.length === 0 ? new Error("Parse error: Invalid SQL") : new Error(`Parse error: Ambiguous grammar
${JSON.stringify(s, void 0, 2)}`);
}
};
}
var D;
(function(T) {
T[T.SPACE = 0] = "SPACE", T[T.NO_SPACE = 1] = "NO_SPACE", T[T.NO_NEWLINE = 2] = "NO_NEWLINE", T[T.NEWLINE = 3] = "NEWLINE", T[T.MANDATORY_NEWLINE = 4] = "MANDATORY_NEWLINE", T[T.INDENT = 5] = "INDENT", T[T.SINGLE_INDENT = 6] = "SINGLE_INDENT";
})(D = D || (D = {}));
class pT {
constructor(E) {
this.indentation = E, this.items = [];
}
/**
* Appends token strings and whitespace modifications to SQL string.
*/
add(...E) {
for (const e of E)
switch (e) {
case D.SPACE:
this.items.push(D.SPACE);
break;
case D.NO_SPACE:
this.trimHorizontalWhitespace();
break;
case D.NO_NEWLINE:
this.trimWhitespace();
break;
case D.NEWLINE:
this.trimHorizontalWhitespace(), this.addNewline(D.NEWLINE);
break;
case D.MANDATORY_NEWLINE:
this.trimHorizontalWhitespace(), this.addNewline(D.MANDATORY_NEWLINE);
break;
case D.INDENT:
this.addIndentation();
break;
case D.SINGLE_INDENT:
this.items.push(D.SINGLE_INDENT);
break;
default:
this.items.push(e);
}
}
trimHorizontalWhitespace() {
for (; vS(tE(this.items)); )
this.items.pop();
}
trimWhitespace() {
for (; xS(tE(this.items)); )
this.items.pop();
}
addNewline(E) {
if (this.items.length > 0)
switch (tE(this.items)) {
case D.NEWLINE:
this.items.pop(), this.items.push(E);
break;
case D.MANDATORY_NEWLINE:
break;
default:
this.items.push(E);
break;
}
}
addIndentation() {
for (let E = 0; E < this.indentation.getLevel(); E++)
this.items.push(D.SINGLE_INDENT);
}
/**
* Returns the final SQL string.
*/
toString() {
return this.items.map((E) => this.itemToString(E)).join("");
}
/**
* Returns the internal layout data
*/
getLayoutItems() {
return this.items;
}
itemToString(E) {
switch (E) {
case D.SPACE:
return " ";
case D.NEWLINE:
case D.MANDATORY_NEWLINE:
return `
`;
case D.SINGLE_INDENT:
return this.indentation.getSingleIndent();
default:
return E;
}
}
}
const vS = (T) => T === D.SPACE || T === D.SINGLE_INDENT, xS = (T) => T === D.SPACE || T === D.SINGLE_INDENT || T === D.NEWLINE;
function sT(T, E) {
if (E === "standard")
return T;
let e = [];
return T.length >= 10 && T.includes(" ") && ([T, ...e] = T.split(" ")), E === "tabularLeft" ? T = T.padEnd(9, " ") : T = T.padStart(9, " "), T + ["", ...e].join(" ");
}
function ST(T) {
return GR(T) || T === l.RESERVED_CLAUSE || T === l.RESERVED_SELECT || T === l.RESERVED_SET_OPERATION || T === l.RESERVED_JOIN || T === l.LIMIT;
}
const ee = "top-level", QS = "block-level";
class fT {
/**
* @param {string} indent A string to indent with
*/
constructor(E) {
this.indent = E, this.indentTypes = [];
}
/**
* Returns indentation string for single indentation step.
*/
getSingleIndent() {
return this.indent;
}
/**
* Returns current indentation level
*/
getLevel() {
return this.indentTypes.length;
}
/**
* Increases indentation by one top-level indent.
*/
increaseTopLevel() {
this.indentTypes.push(ee);
}
/**
* Increases indentation by one block-level indent.
*/
increaseBlockLevel() {
this.indentTypes.push(QS);
}
/**
* Decreases indentation by one top-level indent.
* Does nothing when the previous indent is not top-level.
*/
decreaseTopLevel() {
this.indentTypes.length > 0 && tE(this.indentTypes) === ee && this.indentTypes.pop();
}
/**
* Decreases indentation by one block-level indent.
* If there are top-level indents within the block-level indent,
* throws away these as well.
*/
decreaseBlockLevel() {
for (; this.indentTypes.length > 0 && this.indentTypes.pop() === ee; )
;
}
}
class ZS extends pT {
constructor(E) {
super(new fT("")), this.expressionWidth = E, this.length = 0, this.trailingSpace = !1;
}
add(...E) {
if (E.forEach((e) => this.addToLength(e)), this.length > this.expressionWidth)
throw new Ne();
super.add(...E);
}
addToLength(E) {
if (typeof E == "string")
this.length += E.length, this.trailingSpace = !1;
else {
if (E === D.MANDATORY_NEWLINE || E === D.NEWLINE)
throw new Ne();
E === D.INDENT || E === D.SINGLE_INDENT || E === D.SPACE ? this.trailingSpace || (this.length++, this.trailingSpace = !0) : (E === D.NO_NEWLINE || E === D.NO_SPACE) && this.trailingSpace && (this.trailingSpace = !1, this.length--);
}
}
}
class Ne extends Error {
}
class cE {
constructor({ cfg: E, dialectCfg: e, params: R, layout: A, inline: t = !1 }) {
this.inline = !1, this.nodes = [], this.index = -1, this.cfg = E, this.dialectCfg = e, this.inline = t, this.params = R, this.layout = A;
}
format(E) {
for (this.nodes = E, this.index = 0; this.index < this.nodes.length; this.index++)
this.formatNode(this.nodes[this.index]);
return this.layout;
}
formatNode(E) {
this.formatComments(E.leadingComments), this.formatNodeWithoutComments(E), this.formatComments(E.trailingComments);
}
formatNodeWithoutComments(E) {
switch (E.type) {
case U.function_call:
return this.formatFunctionCall(E);
case U.parameterized_data_type:
return this.formatParameterizedDataType(E);
case U.array_subscript:
return this.formatArraySubscript(E);
case U.property_access:
return this.formatPropertyAccess(E);
case U.parenthesis:
return this.formatParenthesis(E);
case U.between_predicate:
return this.formatBetweenPredicate(E);
case U.case_expression:
return this.formatCaseExpression(E);
case U.case_when:
return this.formatCaseWhen(E);
case U.case_else:
return this.formatCaseElse(E);
case U.clause:
return this.formatClause(E);
case U.set_operation:
return this.formatSetOperation(E);
case U.limit_clause:
return this.formatLimitClause(E);
case U.all_columns_asterisk:
return this.formatAllColumnsAsterisk(E);
case U.literal:
return this.formatLiteral(E);
case U.identifier:
return this.formatIdentifier(E);
case U.parameter:
return this.formatParameter(E);
case U.operator:
return this.formatOperator(E);
case U.comma:
return this.formatComma(E);
case U.line_comment:
return this.formatLineComment(E);
case U.block_comment:
return this.formatBlockComment(E);
case U.disable_comment:
return this.formatBlockComment(E);
case U.data_type:
return this.formatDataType(E);
case U.keyword:
return this.formatKeywordNode(E);
}
}
formatFunctionCall(E) {
this.withComments(E.nameKw, () => {
this.layout.add(this.showFunctionKw(E.nameKw));
}), this.formatNode(E.parenthesis);
}
formatParameterizedDataType(E) {
this.withComments(E.dataType, () => {
this.layout.add(this.showDataType(E.dataType));
}), this.formatNode(E.parenthesis);
}
formatArraySubscript(E) {
let e;
switch (E.array.type) {
case U.data_type:
e = this.showDataType(E.array);
break;
case U.keyword:
e = this.showKw(E.array);
break;
default:
e = this.showIdentifier(E.array);
break;
}
this.withComments(E.array, () => {
this.layout.add(e);
}), this.formatNode(E.parenthesis);
}
formatPropertyAccess(E) {
this.formatNode(E.object), this.layout.add(D.NO_SPACE, E.operator), this.formatNode(E.property);
}
formatParenthesis(E) {
const e = this.formatInlineExpression(E.children);
e ? (this.layout.add(E.openParen), this.layout.add(...e.getLayoutItems()), this.layout.add(D.NO_SPACE, E.closeParen, D.SPACE)) : (this.layout.add(E.openParen, D.NEWLINE), z(this.cfg) ? (this.layout.add(D.INDENT), this.layout = this.formatSubExpression(E.children)) : (this.layout.indentation.increaseBlockLevel(), this.layout.add(D.INDENT), this.layout = this.formatSubExpression(E.children), this.layout.indentation.decreaseBlockLevel()), this.layout.add(D.NEWLINE, D.INDENT, E.closeParen, D.SPACE));
}
formatBetweenPredicate(E) {
this.layout.add(this.showKw(E.betweenKw), D.SPACE), this.layout = this.formatSubExpression(E.expr1), this.layout.add(D.NO_SPACE, D.SPACE, this.showNonTabularKw(E.andKw), D.SPACE), this.layout = this.formatSubExpression(E.expr2), this.layout.add(D.SPACE);
}
formatCaseExpression(E) {
this.formatNode(E.caseKw), this.layout.indentation.increaseBlockLevel(), this.layout = this.formatSubExpression(E.expr), this.layout = this.formatSubExpression(E.clauses), this.layout.indentation.decreaseBlockLevel(), this.layout.add(D.NEWLINE, D.INDENT), this.formatNode(E.endKw);
}
formatCaseWhen(E) {
this.layout.add(D.NEWLINE, D.INDENT), this.formatNode(E.whenKw), this.layout = this.formatSubExpression(E.condition), this.formatNode(E.thenKw), this.layout = this.formatSubExpression(E.result);
}
formatCaseElse(E) {
this.layout.add(D.NEWLINE, D.INDENT), this.formatNode(E.elseKw), this.layout = this.formatSubExpression(E.result);
}
formatClause(E) {
this.isOnelineClause(E) ? this.formatClauseInOnelineStyle(E) : z(this.cfg) ? this.formatClauseInTabularStyle(E) : this.formatClauseInIndentedStyle(E);
}
isOnelineClause(E) {
return z(this.cfg) ? this.dialectCfg.tabularOnelineClauses[E.nameKw.text] : this.dialectCfg.onelineClauses[E.nameKw.text];
}
formatClauseInIndentedStyle(E) {
this.layout.add(D.NEWLINE, D.INDENT, this.showKw(E.nameKw), D.NEWLINE), this.layout.indentation.increaseTopLevel(), this.layout.add(D.INDENT), this.layout = this.formatSubExpression(E.children), this.layout.indentation.decreaseTopLevel();
}
formatClauseInOnelineStyle(E) {
this.layout.add(D.NEWLINE, D.INDENT, this.showKw(E.nameKw), D.SPACE), this.layout = this.formatSubExpression(E.children);
}
formatClauseInTabularStyle(E) {
this.layout.add(D.NEWLINE, D.INDENT, this.showKw(E.nameKw), D.SPACE), this.layout.indentation.increaseTopLevel(), this.layout = this.formatSubExpression(E.children), this.layout.indentation.decreaseTopLevel();
}
formatSetOperation(E) {
this.layout.add(D.NEWLINE, D.INDENT, this.showKw(E.nameKw), D.NEWLINE), this.layout.add(D.INDENT), this.layout = this.formatSubExpression(E.children);
}
formatLimitClause(E) {
this.withComments(E.limitKw, () => {
this.layout.add(D.NEWLINE, D.INDENT, this.showKw(E.limitKw));
}), this.layout.indentation.increaseTopLevel(), z(this.cfg) ? this.layout.add(D.SPACE) : this.layout.add(D.NEWLINE, D.INDENT), E.offset ? (this.layout = this.formatSubExpression(E.offset), this.layout.add(D.NO_SPACE, ",", D.SPACE), this.layout = this.formatSubExpression(E.count)) : this.layout = this.formatSubExpression(E.count), this.layout.indentation.decreaseTopLevel();
}
formatAllColumnsAsterisk(E) {
this.layout.add("*", D.SPACE);
}
formatLiteral(E) {
this.layout.add(E.text, D.SPACE);
}
formatIdentifier(E) {
this.layout.add(this.showIdentifier(E), D.SPACE);
}
formatParameter(E) {
this.layout.add(this.params.get(E), D.SPACE);
}
formatOperator({ text: E }) {
this.cfg.denseOperators || this.dialectCfg.alwaysDenseOperators.includes(E) ? this.layout.add(D.NO_SPACE, E) : E === ":" ? this.layout.add(D.NO_SPACE, E, D.SPACE) : this.layout.add(E, D.SPACE);
}
formatComma(E) {
this.inline ? this.layout.add(D.NO_SPACE, ",", D.SPACE) : this.layout.add(D.NO_SPACE, ",", D.NEWLINE, D.INDENT);
}
withComments(E, e) {
this.formatComments(E.leadingComments), e(), this.formatComments(E.trailingComments);
}
formatComments(E) {
E && E.forEach((e) => {
e.type === U.line_comment ? this.formatLineComment(e) : this.formatBlockComment(e);
});
}
formatLineComment(E) {
kE(E.precedingWhitespace || "") ? this.layout.add(D.NEWLINE, D.INDENT, E.text, D.MANDATORY_NEWLINE, D.INDENT) : this.layout.getLayoutItems().length > 0 ? this.layout.add(D.NO_NEWLINE, D.SPACE, E.text, D.MANDATORY_NEWLINE, D.INDENT) : this.layout.add(E.text, D.MANDATORY_NEWLINE, D.INDENT);
}
formatBlockComment(E) {
E.type === U.block_comment && this.isMultilineBlockComment(E) ? (this.splitBlockComment(E.text).forEach((e) => {
this.layout.add(D.NEWLINE, D.INDENT, e);
}), this.layout.add(D.NEWLINE, D.INDENT)) : this.layout.add(E.text, D.SPACE);
}
isMultilineBlockComment(E) {
return kE(E.text) || kE(E.precedingWhitespace || "");
}
isDocComment(E) {
const e = E.split(/\n/);
return (
// first line starts with /* or /**
/^\/\*\*?$/.test(e[0]) && // intermediate lines start with *
e.slice(1, e.length - 1).every((R) => /^\s*\*/.test(R)) && // last line ends with */
/^\s*\*\/$/.test(tE(e))
);
}
// Breaks up block comment to multiple lines.
// For example this doc-comment (dots representing leading whitespace):
//
// ..../**
// .....* Some description here
// .....* and here too
// .....*/
//
// gets broken to this array (note the leading single spaces):
//
// [ '/**',
// '.* Some description here',
// '.* and here too',
// '.*/' ]
//
// However, a normal comment (non-doc-comment) like this:
//
// ..../*
// ....Some description here
// ....*/
//
// gets broken to this array (no leading spaces):
//
// [ '/*',
// 'Some description here',
// '*/' ]
//
splitBlockComment(E) {
return this.isDocComment(E) ? E.split(/\n/).map((e) => /^\s*\*/.test(e) ? " " + e.replace(/^\s*/, "") : e) : E.split(/\n/).map((e) => e.replace(/^\s*/, ""));
}
formatSubExpression(E) {
return new cE({
cfg: this.cfg,
dialectCfg: this.dialectCfg,
params: this.params,
layout: this.layout,
inline: this.inline
}).format(E);
}
formatInlineExpression(E) {
const e = this.params.getPositionalParameterIndex();
try {
return new cE({
cfg: this.cfg,
dialectCfg: this.dialectCfg,
params: this.params,
layout: new ZS(this.cfg.expressionWidth),
inline: !0
}).format(E);
} catch (R) {
if (R instanceof Ne) {
this.params.setPositionalParameterIndex(e);
return;
} else
throw R;
}
}
formatKeywordNode(E) {
switch (E.tokenType) {
case l.RESERVED_JOIN:
return this.formatJoin(E);
case l.AND:
case l.OR:
case l.XOR:
return this.formatLogicalOperator(E);
default:
return this.formatKeyword(E);
}
}
formatJoin(E) {
z(this.cfg) ? (this.layout.indentation.decreaseTopLevel(), this.layout.add(D.NEWLINE, D.INDENT, this.showKw(E), D.SPACE), this.layout.indentation.increaseTopLevel()) : this.layout.add(D.NEWLINE, D.INDENT, this.showKw(E), D.SPACE);
}
formatKeyword(E) {
this.layout.add(this.showKw(E), D.SPACE);
}
formatLogicalOperator(E) {
this.cfg.logicalOperatorNewline === "before" ? z(this.cfg) ? (this.layout.indentation.decreaseTopLevel(), this.layout.add(D.NEWLINE, D.INDENT, this.showKw(E), D.SPACE), this.layout.indentation.increaseTopLevel()) : this.layout.add(D.NEWLINE, D.INDENT, this.showKw(E), D.SPACE) : this.layout.add(this.showKw(E), D.NEWLINE, D.INDENT);
}
formatDataType(E) {
this.layout.add(this.showDataType(E), D.SPACE);
}
showKw(E) {
return ST(E.tokenType) ? sT(this.showNonTabularKw(E), this.cfg.indentStyle) : this.showNonTabularKw(E);
}
// Like showKw(), but skips tabular formatting
showNonTabularKw(E) {
switch (this.cfg.keywordCase) {
case "preserve":
return iE(E.raw);
case "upper":
return E.text;
case "lower":
return E.text.toLowerCase();
}
}
showFunctionKw(E) {
return ST(E.tokenType) ? sT(this.showNonTabularFunctionKw(E), this.cfg.indentStyle) : this.showNonTabularFunctionKw(E);
}
// Like showFunctionKw(), but skips tabular formatting
showNonTabularFunctionKw(E) {
switch (this.cfg.functionCase) {
case "preserve":
return iE(E.raw);
case "upper":
return E.text;
case "lower":
return E.text.toLowerCase();
}
}
showIdentifier(E) {
if (E.quoted)
return E.text;
switch (this.cfg.identifierCase) {
case "preserve":
return E.text;
case "upper":
return E.text.toUpperCase();
case "lower":
return E.text.toLowerCase();
}
}
showDataType(E) {
switch (this.cfg.dataTypeCase) {
case "preserve":
return iE(E.raw);
case "upper":
return E.text;
case "lower":
return E.text.toLowerCase();
}
}
}
class jS {
constructor(E, e) {
this.dialect = E, this.cfg = e, this.params = new mS(this.cfg.params);
}
/**
* Formats an SQL query.
* @param {string} query - The SQL query string to be formatted
* @return {string} The formatter query
*/
format(E) {
const e = this.parse(E);
return this.formatAst(e).trimEnd();
}
parse(E) {
return JS(this.dialect.tokenizer).parse(E, this.cfg.paramTypes || {});
}
formatAst(E) {
return E.map((e) => this.formatStatement(e)).join(`
`.repeat(this.cfg.linesBetweenQueries + 1));
}
formatStatement(E) {
const e = new cE({
cfg: this.cfg,
dialectCfg: this.dialect.formatOptions,
params: this.params,
layout: new pT(new fT(dS(this.cfg)))
}).format(E.children);
return E.hasSemicolon && (this.cfg.newlineBeforeSemicolon ? e.add(D.NEWLINE, ";") : e.add(D.NO_NEWLINE, ";")), e.toString();
}
}
class CE extends Error {
}
function qS(T) {
const E = [
"multilineLists",
"newlineBeforeOpenParen",
"newlineBeforeCloseParen",
"aliasAs",
"commaPosition",
"tabulateAlias"
];
for (const e of E)
if (e in T)
throw new CE(`${e} config is no more supported.`);
if (T.expressionWidth <= 0)
throw new CE(`expressionWidth config must be positive number. Received ${T.expressionWidth} instead.`);
if (T.params && !kS(T.params) && console.warn('WARNING: All "params" option values should be strings.'), T.paramTypes && !zS(T.paramTypes))
throw new CE("Empty regex given in custom paramTypes. That would result in matching infinite amount of parameters.");
return T;
}
function kS(T) {
return (T instanceof Array ? T : Object.values(T)).every((e) => typeof e == "string");
}
function zS(T) {
return T.custom && Array.isArray(T.custom) ? T.custom.every((E) => E.regex !== "") : !0;
}
var EN = function(T, E) {
var e = {};
for (var R in T) Object.prototype.hasOwnProperty.call(T, R) && E.indexOf(R) < 0 && (e[R] = T[R]);
if (T != null && typeof Object.getOwnPropertySymbols == "function")
for (var A = 0, R = Object.getOwnPropertySymbols(T); A < R.length; A++)
E.indexOf(R[A]) < 0 && Object.prototype.propertyIsEnumerable.call(T, R[A]) && (e[R[A]] = T[R[A]]);
return e;
};
const BT = {
bigquery: "bigquery",
db2: "db2",
db2i: "db2i",
duckdb: "duckdb",
hive: "hive",
mariadb: "mariadb",
mysql: "mysql",
n1ql: "n1ql",
plsql: "plsql",
postgresql: "postgresql",
redshift: "redshift",
spark: "spark",
sqlite: "sqlite",
sql: "sql",
tidb: "tidb",
trino: "trino",
transactsql: "transactsql",
tsql: "transactsql",
singlestoredb: "singlestoredb",
snowflake: "snowflake"
}, eN = Object.keys(BT), TN = {
tabWidth: 2,
useTabs: !1,
keywordCase: "preserve",
identifierCase: "preserve",
dataTypeCase: "preserve",
functionCase: "preserve",
indentStyle: "standard",
logicalOperatorNewline: "before",
expressionWidth: 50,
linesBetweenQueries: 1,
denseOperators: !1,
newlineBeforeSemicolon: !1
}, RN = (T, E = {}) => {
if (typeof E.language == "string" && !eN.includes(E.language))
throw new CE(`Unsupported SQL dialect: ${E.language}`);
const e = BT[E.language || "sql"];
return AN(T, Object.assign(Object.assign({}, E), { dialect: IS[e] }));
}, AN = (T, E) => {
var { dialect: e } = E, R = EN(E, ["dialect"]);
if (typeof T != "string")
throw new Error("Invalid query argument. Expected string, instead got " + typeof T);
const A = qS(Object.assign(Object.assign({}, TN), R));
return new jS(MS(e), A).format(T);
};
function tN(T) {
let E = 0;
return E += (T.measures?.length || 0) * 1, E += (T.dimensions?.length || 0) * 1, E += (T.filters?.length || 0) * 2, E += (T.timeDimensions?.length || 0) * 3, E <= 5 ? "low" : E <= 15 ? "medium" : "high";
}
function hT(T, E) {
if ("and" in T || "or" in T) {
const e = T.and || T.or || [];
for (const R of e)
hT(R, E);
return;
}
if ("member" in T) {
const [e] = T.member.split(".");
e && E.add(e);
}
}
function sN() {
const T = Date.now(), E = Math.random().toString(36).substring(2, 9);
return `${T}-${E}`;
}
function SN(T) {
const E = T.dimensions || [], e = T.timeDimensions || [], R = T.measures || [];
return {
sortedDimensions: E,
sortedTimeDimensions: e,
timeDimensions: e,
measures: R,
leafMeasureAdditive: !0,
leafMeasures: R,
measureToLeafMeasures: {},
hasNoTimeDimensionsWithoutGranularity: !0,
allFiltersWithinSelectedDimensions: !0,
isAdditive: !0,
granularityHierarchies: {},
hasMultipliedMeasures: !1,
hasCumulativeMeasures: !1,
windowGranularity: null,
filterDimensionsSingleValueEqual: {},
ownedDimensions: E,
ownedTimeDimensionsWithRollupGranularity: [],
ownedTimeDimensionsAsIs: [],
allBackAliasMembers: {},
hasMultiStage: !1
};
}
function NN(T) {
if (T.hasExecutor()) {
const E = T.databaseExecutor;
if (E?.engineType)
return E.engineType;
}
return "postgres";
}
async function ON(T, E, e) {
const R = e.validateQuery(T);
if (!R.isValid)
throw new Error(`Query validation failed: ${R.errors.join(", ")}`);
const A = /* @__PURE__ */ new Set();
T.measures?.forEach((S) => {
const N = S.split(".")[0];
A.add(N);
}), T.dimensions?.forEach((S) => {
const N = S.split(".")[0];
A.add(N);
}), T.timeDimensions?.forEach((S) => {
const N = S.dimension.split(".")[0];
A.add(N);
}), T.filters?.forEach((S) => {
hT(S, A);
});
const t = A.size > 1;
let s;
if (t)
s = await e.generateMultiCubeSQL(T, E);
else {
const S = Array.from(A)[0];
s = await e.generateSQL(S, T, E);
}
const I = Array.from(A).map((S) => ({
cube: S,
query: {
measures: T.measures?.filter((N) => N.startsWith(S + ".")) || [],
dimensions: T.dimensions?.filter((N) => N.startsWith(S + ".")) || [],
filters: T.filters || [],
timeDimensions: T.timeDimensions || [],
order: T.order || {},
limit: T.limit,
offset: T.offset
}
}));
let r;
try {
r = e.analyzeQuery(T, E);
} catch (S) {
console.warn("Query analysis failed:", S);
}
return {
queryType: "regularQuery",
normalizedQueries: I,
queryOrder: Array.from(A),
transformedQueries: I,
pivotQuery: {
query: T,
cubes: Array.from(A)
},
sql: {
sql: [s.sql],
params: s.params || []
},
complexity: tN(T),
valid: !0,
cubesUsed: Array.from(A),
joinType: t ? "multi_cube_join" : "single_cube",
query: T,
// Query analysis for debugging and transparency
analysis: r
};
}
function IN(T, E, e) {
const R = NN(e), A = sN(), t = (/* @__PURE__ */ new Date()).toISOString(), s = SN(T);
return {
queryType: "regularQuery",
results: [{
query: T,
lastRefreshTime: t,
usedPreAggregations: {},
transformedQuery: s,
requestId: A,
annotation: E.annotation,
dataSource: "default",
dbType: R,
extDbType: R,
external: !1,
slowQuery: !1,
data: E.data,
// Include cache metadata if present (indicates cache hit with TTL info)
...E.cache && { cache: E.cache }
}],
pivotQuery: {
...T,
queryType: "regularQuery"
},
slowQuery: !1
};
}
function NT(T, E) {
try {
return RN(T, {
language: {
postgres: "postgresql",
mysql: "mysql",
sqlite: "sqlite",
singlestore: "mysql"
// SingleStore uses MySQL dialect for formatting
}[E],
tabWidth: 2,
keywordCase: "upper",
indentStyle: "standard"
});
} catch (e) {
return console.warn("SQL formatting failed:", e), T;
}
}
function nN(T, E) {
return {
sql: E.sql,
params: E.params || [],
query: T
};
}
function rN(T) {
return {
cubes: T
};
}
function iN(T, E = 500) {
return {
error: T instanceof Error ? T.message : T,
status: E
};
}
async function aN(T, E, e) {
return { results: (await Promise.allSettled(
T.map(async (t) => {
const s = await e.executeMultiCubeQuery(t, E);
return IN(t, s, e);
})
)).map((t, s) => t.status === "fulfilled" ? {
success: !0,
...t.value
} : {
success: !1,
error: t.reason instanceof Error ? t.reason.message : String(t.reason),
query: T[s]
// Include the query that failed for debugging
}) };
}
class CN {
cubes = /* @__PURE__ */ new Map();
dbExecutor;
metadataCache;
cacheConfig;
constructor(E) {
E?.databaseExecutor ? this.dbExecutor = E.databaseExecutor : E?.drizzle && (this.dbExecutor = de(
E.drizzle,
E.schema,
E.engineType
)), this.cacheConfig = E?.cache;
}
/**
* Set or update the database executor
*/
setDatabaseExecutor(E) {
this.dbExecutor = E;
}
/**
* Get the database engine type for SQL formatting
*/
getEngineType() {
return this.dbExecutor?.getEngineType();
}
/**
* Set Drizzle instance and schema directly
*/
setDrizzle(E, e, R) {
this.dbExecutor = de(E, e, R);
}
/**
* Check if database executor is configured
*/
hasExecutor() {
return !!this.dbExecutor;
}
/**
* Register a simplified cube with dynamic query building
* Validates calculated measures during registration
*/
registerCube(E) {
this.validateCalculatedMeasures(E), new Q(this.cubes).populateDependencies(E), this.cubes.set(E.name, E), this.invalidateMetadataCache();
}
/**
* Validate calculated measures in a cube
* Checks template syntax, dependency existence, and circular dependencies
*/
validateCalculatedMeasures(E) {
const e = [];
for (const [R, A] of Object.entries(E.measures))
if (A.type === "calculated") {
if (!A.calculatedSql) {
e.push(
`Calculated measure '${E.name}.${R}' must have calculatedSql property`
);
continue;
}
const t = SR(A.calculatedSql);
if (!t.isValid) {
e.push(
`Invalid calculatedSql syntax in '${E.name}.${R}': ${t.errors.join(", ")}`
);
continue;
}
const s = new Map(this.cubes);
s.set(E.name, E);
const I = new Q(s);
try {
I.validateDependencies(E);
} catch (r) {
e.push(r instanceof Error ? r.message : String(r));
}
}
if (e.length === 0) {
const R = new Map(this.cubes);
R.set(E.name, E);
const A = new Q(R);
A.buildGraph(E);
const t = A.detectCycle();
t && e.push(
`Circular dependency detected in calculated measures: ${t.join(" -> ")}`
);
}
if (e.length > 0)
throw new Error(
`Calculated measure validation failed for cube '${E.name}':
${e.join(`
`)}`
);
}
/**
* Get a cube by name
*/
getCube(E) {
return this.cubes.get(E);
}
/**
* Get all registered cubes
*/
getAllCubes() {
return Array.from(this.cubes.values());
}
/**
* Get all cubes as a Map for multi-cube queries
*/
getAllCubesMap() {
return this.cubes;
}
/**
* Unified query execution method that handles both single and multi-cube queries
*/
async execute(E, e) {
if (!this.dbExecutor)
throw new Error("Database executor not configured");
return new HE(this.dbExecutor, this.cacheConfig).execute(this.cubes, E, e);
}
/**
* Execute a multi-cube query
*/
async executeMultiCubeQuery(E, e) {
return this.execute(E, e);
}
/**
* Execute a single cube query
*/
async executeQuery(E, e, R) {
if (!this.cubes.get(E))
throw new Error(`Cube '${E}' not found`);
return this.execute(e, R);
}
/**
* Get metadata for all cubes (for API responses)
* Uses caching to improve performance for repeated requests
* Cache is invalidated when cubes are modified (registerCube, removeCube, clearCubes)
*/
getMetadata() {
return this.metadataCache ? this.metadataCache : (this.metadataCache = Array.from(this.cubes.values()).map((E) => this.generateCubeMetadata(E)), this.metadataCache);
}
/**
* Extract column name from Drizzle column reference
* Handles different column types and extracts the actual column name
*/
getColumnName(E) {
if (E && E.name || E && E.columnType && E.name)
return E.name;
if (typeof E == "string")
return E;
if (E && typeof E == "object") {
if (E._.name) return E._.name;
if (E.name) return E.name;
if (E.columnName) return E.columnName;
}
return "unknown_column";
}
/**
* Generate cube metadata for API responses from cubes
* Optimized version that minimizes object iterations
*/
generateCubeMetadata(E) {
const e = Object.keys(E.measures), R = Object.keys(E.dimensions), A = new Array(e.length), t = new Array(R.length);
for (let I = 0; I < e.length; I++) {
const r = e[I], S = E.measures[r];
A[I] = {
name: `${E.name}.${r}`,
title: S.title || r,
shortTitle: S.title || r,
type: S.type,
format: void 0,
// Measure doesn't have format field
description: S.description
};
}
for (let I = 0; I < R.length; I++) {
const r = R[I], S = E.dimensions[r];
t[I] = {
name: `${E.name}.${r}`,
title: S.title || r,
shortTitle: S.title || r,
type: S.type,
format: void 0,
// Dimension doesn't have format field
description: S.description
};
}
const s = [];
if (E.joins)
for (const [, I] of Object.entries(E.joins)) {
const r = typeof I.targetCube == "function" ? I.targetCube() : I.targetCube;
s.push({
targetCube: r.name,
relationship: I.relationship,
joinFields: I.on.map((S) => ({
sourceField: this.getColumnName(S.source),
targetField: this.getColumnName(S.target)
}))
});
}
return {
name: E.name,
title: E.title || E.name,
description: E.description,
measures: A,
dimensions: t,
segments: [],
// Add segments support later if needed
relationships: s.length > 0 ? s : void 0
};
}
/**
* Get SQL for a query without executing it (debugging)
*/
async generateSQL(E, e, R) {
const A = this.getCube(E);
if (!A)
throw new Error(`Cube '${E}' not found`);
if (!this.dbExecutor)
throw new Error("Database executor not configured");
const s = await new HE(this.dbExecutor).generateSQL(A, e, R), I = this.dbExecutor.getEngineType();
return {
sql: NT(s.sql, I),
params: s.params
};
}
/**
* Get SQL for a multi-cube query without executing it (debugging)
*/
async generateMultiCubeSQL(E, e) {
if (!this.dbExecutor)
throw new Error("Database executor not configured");
const A = await new HE(this.dbExecutor).generateMultiCubeSQL(this.cubes, E, e), t = this.dbExecutor.getEngineType();
return {
sql: NT(A.sql, t),
params: A.params
};
}
/**
* Check if a cube exists
*/
hasCube(E) {
return this.cubes.has(E);
}
/**
* Remove a cube
*/
removeCube(E) {
const e = this.cubes.delete(E);
return e && this.invalidateMetadataCache(), e;
}
/**
* Clear all cubes
*/
clearCubes() {
this.cubes.clear(), this.invalidateMetadataCache();
}
/**
* Invalidate the metadata cache
* Called whenever cubes are modified
*/
invalidateMetadataCache() {
this.metadataCache = void 0;
}
/**
* Get cube names
*/
getCubeNames() {
return Array.from(this.cubes.keys());
}
/**
* Validate a query against registered cubes
* Ensures all referenced cubes and fields exist
*/
validateQuery(E) {
return HT(this.cubes, E);
}
/**
* Analyze query planning decisions for debugging and transparency
* Returns detailed metadata about how the query would be planned
* Used by the playground UI to help users understand query structure
*/
analyzeQuery(E, e) {
if (!this.dbExecutor)
throw new Error("Database executor not configured");
const R = new _T(), A = {
db: this.dbExecutor.db,
schema: this.dbExecutor.schema,
securityContext: e
};
return R.analyzeQueryPlan(this.cubes, E, A);
}
}
function HT(T, E) {
const e = [], R = /* @__PURE__ */ new Set();
if (E.measures)
for (const A of E.measures) {
const [t, s] = A.split(".");
if (!t || !s) {
e.push(`Invalid measure format: ${A}. Expected format: 'CubeName.fieldName'`);
continue;
}
R.add(t);
const I = T.get(t);
if (!I) {
e.push(`Cube '${t}' not found (referenced in measure '${A}')`);
continue;
}
I.measures[s] || e.push(`Measure '${s}' not found on cube '${t}'`);
}
if (E.dimensions)
for (const A of E.dimensions) {
const [t, s] = A.split(".");
if (!t || !s) {
e.push(`Invalid dimension format: ${A}. Expected format: 'CubeName.fieldName'`);
continue;
}
R.add(t);
const I = T.get(t);
if (!I) {
e.push(`Cube '${t}' not found (referenced in dimension '${A}')`);
continue;
}
I.dimensions[s] || e.push(`Dimension '${s}' not found on cube '${t}'`);
}
if (E.timeDimensions)
for (const A of E.timeDimensions) {
const [t, s] = A.dimension.split(".");
if (!t || !s) {
e.push(`Invalid timeDimension format: ${A.dimension}. Expected format: 'CubeName.fieldName'`);
continue;
}
R.add(t);
const I = T.get(t);
if (!I) {
e.push(`Cube '${t}' not found (referenced in timeDimension '${A.dimension}')`);
continue;
}
I.dimensions[s] || e.push(`TimeDimension '${s}' not found on cube '${t}' (must be a dimension with time type)`);
}
if (E.filters)
for (const A of E.filters)
FT(A, T, e, R);
return R.size === 0 && e.push("Query must reference at least one cube through measures, dimensions, or filters"), {
isValid: e.length === 0,
errors: e
};
}
function FT(T, E, e, R) {
if ("and" in T || "or" in T) {
const I = T.and || T.or || [];
for (const r of I)
FT(r, E, e, R);
return;
}
if (!("member" in T)) {
e.push("Filter must have a member field");
return;
}
const [A, t] = T.member.split(".");
if (!A || !t) {
e.push(`Invalid filter member format: ${T.member}. Expected format: 'CubeName.fieldName'`);
return;
}
R.add(A);
const s = E.get(A);
if (!s) {
e.push(`Cube '${A}' not found (referenced in filter '${T.member}')`);
return;
}
!s.dimensions[t] && !s.measures[t] && e.push(`Filter field '${t}' not found on cube '${A}' (must be a dimension or measure)`);
}
export {
CN as S,
rN as a,
nN as b,
ON as c,
iN as d,
IN as f,
aN as h
};