Variable ALLOWED_SQL_FUNCTIONSConst
ALLOWED_SQL_FUNCTIONS: {
aggregates: readonly [
"COUNT",
"COUNT_BIG",
"SUM",
"AVG",
"MIN",
"MAX",
"STDEV",
"STDEVP",
"VAR",
"VARP",
"STRING_AGG",
"CHECKSUM_AGG",
"ARRAY_AGG",
"JSONB_AGG",
"JSON_AGG",
"BOOL_AND",
"BOOL_OR",
"EVERY",
"PERCENTILE_CONT",
"PERCENTILE_DISC",
"MODE",
];
conditional: readonly ["CASE", "WHEN", "THEN", "ELSE", "END"];
conversion: readonly [
"CAST",
"CONVERT",
"TRY_CAST",
"TRY_CONVERT",
"FORMAT",
"TO_CHAR",
"TO_DATE",
"TO_NUMBER",
"TO_TIMESTAMP",
];
date: readonly [
"DATEPART",
"DATEDIFF",
"DATEADD",
"YEAR",
"MONTH",
"DAY",
"HOUR",
"MINUTE",
"SECOND",
"GETDATE",
"GETUTCDATE",
"SYSDATETIME",
"EOMONTH",
"NOW",
"CURRENT_DATE",
"CURRENT_TIME",
"CURRENT_TIMESTAMP",
"LOCALTIMESTAMP",
"DATE_TRUNC",
"DATE_PART",
"EXTRACT",
"AGE",
"TO_DATE",
"TO_TIMESTAMP",
"MAKE_DATE",
"MAKE_TIMESTAMP",
"JUSTIFY_DAYS",
];
logical: readonly [
"AND",
"OR",
"NOT",
"IS",
"NULL",
"LIKE",
"BETWEEN",
"IN",
"ILIKE",
"SIMILAR",
"ANY",
"ALL",
"SOME",
"EXISTS",
];
math: readonly [
"ABS",
"CEILING",
"FLOOR",
"ROUND",
"POWER",
"SQRT",
"LOG",
"LOG10",
"EXP",
"SIGN",
"RAND",
"CEIL",
"RANDOM",
"TRUNC",
"MOD",
"DIV",
"GREATEST",
"LEAST",
"WIDTH_BUCKET",
];
nullHandling: readonly [
"ISNULL",
"COALESCE",
"NULLIF",
"IIF",
"GREATEST",
"LEAST",
];
ordering: readonly [
"ASC",
"ASCENDING",
"DESC",
"DESCENDING",
"OVER",
"PARTITION",
"BY",
"ORDER",
"ROWS",
"RANGE",
"UNBOUNDED",
"PRECEDING",
"FOLLOWING",
"CURRENT",
"ROW",
"NULLS",
"FIRST",
"LAST",
"FILTER",
"WITHIN",
"GROUPING",
];
string: readonly [
"LEN",
"LENGTH",
"UPPER",
"LOWER",
"LTRIM",
"RTRIM",
"TRIM",
"LEFT",
"RIGHT",
"SUBSTRING",
"CHARINDEX",
"REPLACE",
"CONCAT",
"STUFF",
"POSITION",
"STRPOS",
"SPLIT_PART",
"INITCAP",
"LPAD",
"RPAD",
"REPEAT",
"REVERSE",
"TRANSLATE",
"REGEXP_REPLACE",
"REGEXP_MATCHES",
"REGEXP_SUBSTR",
"TO_CHAR",
"MD5",
"ASCII",
"CHR",
];
} = ...
Type Declaration
Readonlyaggregates: readonly [
"COUNT",
"COUNT_BIG",
"SUM",
"AVG",
"MIN",
"MAX",
"STDEV",
"STDEVP",
"VAR",
"VARP",
"STRING_AGG",
"CHECKSUM_AGG",
"ARRAY_AGG",
"JSONB_AGG",
"JSON_AGG",
"BOOL_AND",
"BOOL_OR",
"EVERY",
"PERCENTILE_CONT",
"PERCENTILE_DISC",
"MODE",
]
Readonlyconditional: readonly ["CASE", "WHEN", "THEN", "ELSE", "END"]
Readonlyconversion: readonly [
"CAST",
"CONVERT",
"TRY_CAST",
"TRY_CONVERT",
"FORMAT",
"TO_CHAR",
"TO_DATE",
"TO_NUMBER",
"TO_TIMESTAMP",
]
Readonlydate: readonly [
"DATEPART",
"DATEDIFF",
"DATEADD",
"YEAR",
"MONTH",
"DAY",
"HOUR",
"MINUTE",
"SECOND",
"GETDATE",
"GETUTCDATE",
"SYSDATETIME",
"EOMONTH",
"NOW",
"CURRENT_DATE",
"CURRENT_TIME",
"CURRENT_TIMESTAMP",
"LOCALTIMESTAMP",
"DATE_TRUNC",
"DATE_PART",
"EXTRACT",
"AGE",
"TO_DATE",
"TO_TIMESTAMP",
"MAKE_DATE",
"MAKE_TIMESTAMP",
"JUSTIFY_DAYS",
]
Readonlylogical: readonly [
"AND",
"OR",
"NOT",
"IS",
"NULL",
"LIKE",
"BETWEEN",
"IN",
"ILIKE",
"SIMILAR",
"ANY",
"ALL",
"SOME",
"EXISTS",
]
Readonlymath: readonly [
"ABS",
"CEILING",
"FLOOR",
"ROUND",
"POWER",
"SQRT",
"LOG",
"LOG10",
"EXP",
"SIGN",
"RAND",
"CEIL",
"RANDOM",
"TRUNC",
"MOD",
"DIV",
"GREATEST",
"LEAST",
"WIDTH_BUCKET",
]
ReadonlynullHandling: readonly ["ISNULL", "COALESCE", "NULLIF", "IIF", "GREATEST", "LEAST"]
Readonlyordering: readonly [
"ASC",
"ASCENDING",
"DESC",
"DESCENDING",
"OVER",
"PARTITION",
"BY",
"ORDER",
"ROWS",
"RANGE",
"UNBOUNDED",
"PRECEDING",
"FOLLOWING",
"CURRENT",
"ROW",
"NULLS",
"FIRST",
"LAST",
"FILTER",
"WITHIN",
"GROUPING",
]
Readonlystring: readonly [
"LEN",
"LENGTH",
"UPPER",
"LOWER",
"LTRIM",
"RTRIM",
"TRIM",
"LEFT",
"RIGHT",
"SUBSTRING",
"CHARINDEX",
"REPLACE",
"CONCAT",
"STUFF",
"POSITION",
"STRPOS",
"SPLIT_PART",
"INITCAP",
"LPAD",
"RPAD",
"REPEAT",
"REVERSE",
"TRANSLATE",
"REGEXP_REPLACE",
"REGEXP_MATCHES",
"REGEXP_SUBSTR",
"TO_CHAR",
"MD5",
"ASCII",
"CHR",
]
Safe SQL functions allowed in expressions, organized by category.
WHY THIS IS A UNION RATHER THAN A PER-DIALECT TABLE
This is a deny-by-default SAFETY list, not a dialect grammar. Its job is to stop a user-supplied expression from smuggling in something that is not a read-only scalar/aggregate call — it is not, and must not become, a per-platform parser. So it carries the union of every supported dialect's read-only vocabulary, and
checkFunctionNamesconsults the flattened union.Keying the buckets off
ResolvePlatformKeyis the alternative, and it costs more than it buys: a PostgreSQL name that reaches a SQL Server tenant is rejected by the SQL Server parser on its own —DATE_TRUNC(...)simply never parses there. The union therefore cannot widen the blast radius past what the target server will already accept, whereas a dialect switch here would add a second independent place for the dialect to be resolved, and so a second place for it to be wrong.Before this list held the PostgreSQL names, a perfectly ordinary PG filter such as
DATE_TRUNC('month', CreatedAt)was rejected outright with "Function 'DATE_TRUNC' is not allowed" on every PostgreSQL tenant.Every name here is read-only by construction. Anything that writes, escalates, or reaches outside the statement stays on DANGEROUS_SQL_KEYWORDS, which is checked FIRST (step 2 of
validate) — a name added here can never unblock one that is denied there.