sqllens 1.0.0 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +0 -10
- package/README.md +95 -85
- package/THIRD-PARTY-NOTICES.md +70 -5
- package/dist/api.d.ts +5 -3
- package/dist/api.js +17 -4
- package/dist/bigquery/behavior.d.ts +2 -0
- package/dist/bigquery/behavior.js +20 -0
- package/dist/bigquery/dot-path.d.ts +0 -2
- package/dist/bigquery/dot-path.js +0 -1
- package/dist/bigquery/fold.d.ts +8 -0
- package/dist/bigquery/fold.js +39 -0
- package/dist/bigquery/index.d.ts +7 -0
- package/dist/bigquery/index.js +10 -0
- package/dist/{infer/bigquery.d.ts → bigquery/infer.d.ts} +2 -2
- package/dist/{infer/bigquery.js → bigquery/infer.js} +4 -3
- package/dist/bigquery/lower.js +35 -12
- package/dist/bigquery/signatures.generated.d.ts +6 -0
- package/dist/bigquery/signatures.generated.js +1068 -0
- package/dist/completion/atn-walk.d.ts +13 -2
- package/dist/completion/atn-walk.js +13 -10
- package/dist/completion/complete.d.ts +4 -3
- package/dist/completion/complete.js +101 -45
- package/dist/completion/config.js +66 -0
- package/dist/completion/jinja-slot.d.ts +24 -0
- package/dist/completion/jinja-slot.js +126 -0
- package/dist/completion/parser-factory.d.ts +13 -1
- package/dist/completion/parser-factory.js +48 -0
- package/dist/databricks/behavior.d.ts +2 -0
- package/dist/databricks/behavior.js +19 -0
- package/dist/databricks/fold.d.ts +8 -0
- package/dist/databricks/fold.js +27 -0
- package/dist/databricks/index.d.ts +7 -0
- package/dist/databricks/index.js +10 -0
- package/dist/databricks/infer.d.ts +6 -0
- package/dist/databricks/infer.js +638 -0
- package/dist/databricks/signatures.generated.d.ts +6 -0
- package/dist/databricks/signatures.generated.js +1745 -0
- package/dist/derived-dialects.js +19 -1
- package/dist/dialect-behavior/behavior.d.ts +26 -0
- package/dist/dialect-behavior/behavior.js +1 -0
- package/dist/dialect-behavior/carrier.d.ts +5 -0
- package/dist/dialect-behavior/carrier.js +5 -0
- package/dist/dialect-behavior/coerce-rules.d.ts +7 -0
- package/dist/dialect-behavior/coerce-rules.js +69 -0
- package/dist/dialect-behavior/public-fold.d.ts +6 -0
- package/dist/dialect-behavior/public-fold.js +9 -0
- package/dist/dialect-behavior/registry.d.ts +6 -0
- package/dist/dialect-behavior/registry.js +34 -0
- package/dist/dialect-symbols.js +22 -17
- package/dist/dialect.d.ts +2 -2
- package/dist/document/document.d.ts +1 -1
- package/dist/document/document.js +8 -7
- package/dist/duckdb/behavior.d.ts +2 -0
- package/dist/duckdb/behavior.js +21 -0
- package/dist/duckdb/fold.d.ts +8 -0
- package/dist/duckdb/fold.js +29 -0
- package/dist/duckdb/index.d.ts +7 -0
- package/dist/duckdb/index.js +10 -0
- package/dist/{infer/duckdb.d.ts → duckdb/infer.d.ts} +2 -2
- package/dist/{infer/duckdb.js → duckdb/infer.js} +4 -3
- package/dist/duckdb/lower.js +47 -15
- package/dist/duckdb/signatures.generated.d.ts +6 -0
- package/dist/duckdb/signatures.generated.js +1072 -0
- package/dist/generated/bigquery/GoogleSQLParser.js +0 -7060
- package/dist/generated/databricks/DatabricksParser.js +0 -4800
- package/dist/generated/duckdb/DuckdbParser.js +0 -9100
- package/dist/generated/minijinja/MinijinjaParser.js +0 -380
- package/dist/generated/mysql/MysqlLexer.js +7357 -0
- package/dist/generated/mysql/MysqlParser.js +78520 -0
- package/dist/generated/postgres/PostgresParser.js +0 -8530
- package/dist/generated/redshift/RedshiftParser.js +0 -10970
- package/dist/generated/snowflake/SnowflakeParser.js +0 -7320
- package/dist/generated/sqlite/SqliteLexer.js +945 -0
- package/dist/generated/sqlite/SqliteParser.js +14682 -0
- package/dist/generated/trino/TrinoParser.js +0 -3770
- package/dist/generated/tsql/TSqlParser.js +0 -8420
- package/dist/ident/fold.d.ts +24 -15
- package/dist/ident/fold.js +12 -145
- package/dist/index.d.ts +6 -2
- package/dist/index.js +14 -8
- package/dist/infer/functions.d.ts +22 -11
- package/dist/infer/functions.js +26 -888
- package/dist/infer/infer.js +16 -14
- package/dist/infer/nullability.js +3 -4
- package/dist/infer/types.d.ts +1 -1
- package/dist/infer/types.js +7 -7
- package/dist/ir/ir.d.ts +26 -17
- package/dist/ir/part-span.d.ts +16 -1
- package/dist/ir/part-span.js +38 -10
- package/dist/ir/span.js +0 -2
- package/dist/ir/walk.js +3 -3
- package/dist/lineage/hops.js +13 -10
- package/dist/lineage/lineage.js +10 -7
- package/dist/minijinja/apply-tags.d.ts +14 -7
- package/dist/minijinja/apply-tags.js +66 -121
- package/dist/minijinja/parse.js +6 -6
- package/dist/minijinja/tag-ast.d.ts +29 -36
- package/dist/minijinja/tag-ast.js +210 -90
- package/dist/mysql/behavior.d.ts +2 -0
- package/dist/mysql/behavior.js +21 -0
- package/dist/mysql/fold.d.ts +8 -0
- package/dist/mysql/fold.js +49 -0
- package/dist/mysql/index.d.ts +7 -0
- package/dist/mysql/index.js +10 -0
- package/dist/mysql/infer.d.ts +20 -0
- package/dist/mysql/infer.js +156 -0
- package/dist/mysql/lower.d.ts +13 -0
- package/dist/mysql/lower.js +1443 -0
- package/dist/mysql/parse.d.ts +10 -0
- package/dist/mysql/parse.js +70 -0
- package/dist/mysql/signatures.generated.d.ts +6 -0
- package/dist/mysql/signatures.generated.js +508 -0
- package/dist/postgres/behavior.d.ts +2 -0
- package/dist/postgres/behavior.js +19 -0
- package/dist/postgres/fold.d.ts +8 -0
- package/dist/postgres/fold.js +30 -0
- package/dist/postgres/index.d.ts +7 -0
- package/dist/postgres/index.js +10 -0
- package/dist/{infer/postgres.d.ts → postgres/infer.d.ts} +2 -2
- package/dist/{infer/postgres.js → postgres/infer.js} +4 -3
- package/dist/postgres/lower.js +2 -2
- package/dist/postgres/signatures.generated.d.ts +6 -0
- package/dist/postgres/signatures.generated.js +2973 -0
- package/dist/qualify/check-calls.js +80 -134
- package/dist/qualify/qualify.js +16 -14
- package/dist/qualify/schema-provider.js +2 -2
- package/dist/qualify/schema.js +3 -3
- package/dist/qualify/template-provider.d.ts +45 -12
- package/dist/qualify/template-provider.js +69 -38
- package/dist/redshift/behavior.d.ts +2 -0
- package/dist/redshift/behavior.js +19 -0
- package/dist/redshift/fold.d.ts +8 -0
- package/dist/redshift/fold.js +31 -0
- package/dist/redshift/index.d.ts +7 -0
- package/dist/redshift/index.js +10 -0
- package/dist/{infer/redshift.d.ts → redshift/infer.d.ts} +2 -2
- package/dist/{infer/redshift.js → redshift/infer.js} +4 -3
- package/dist/redshift/lower.js +2 -2
- package/dist/redshift/signatures.generated.d.ts +6 -0
- package/dist/redshift/signatures.generated.js +757 -0
- package/dist/references/references.js +17 -12
- package/dist/scope/like-pattern.d.ts +2 -0
- package/dist/scope/like-pattern.js +15 -0
- package/dist/scope/scope.d.ts +5 -5
- package/dist/scope/scope.js +48 -42
- package/dist/sema/resolve.js +17 -12
- package/dist/session.d.ts +2 -2
- package/dist/signature/signature.d.ts +14 -6
- package/dist/signature/signature.js +30 -22
- package/dist/signature/signatures.d.ts +14 -12
- package/dist/signature/signatures.js +42 -582
- package/dist/snowflake/behavior.d.ts +2 -0
- package/dist/snowflake/behavior.js +22 -0
- package/dist/snowflake/fold.d.ts +8 -0
- package/dist/snowflake/fold.js +25 -0
- package/dist/snowflake/index.d.ts +7 -0
- package/dist/snowflake/index.js +10 -0
- package/dist/{infer/snowflake.d.ts → snowflake/infer.d.ts} +2 -2
- package/dist/{infer/snowflake.js → snowflake/infer.js} +4 -3
- package/dist/snowflake/lower.js +59 -19
- package/dist/snowflake/signatures.generated.d.ts +6 -0
- package/dist/snowflake/signatures.generated.js +2080 -0
- package/dist/sqlite/behavior.d.ts +2 -0
- package/dist/sqlite/behavior.js +19 -0
- package/dist/sqlite/fold.d.ts +8 -0
- package/dist/sqlite/fold.js +41 -0
- package/dist/sqlite/index.d.ts +7 -0
- package/dist/sqlite/index.js +10 -0
- package/dist/sqlite/infer.d.ts +12 -0
- package/dist/sqlite/infer.js +122 -0
- package/dist/sqlite/lower.d.ts +11 -0
- package/dist/sqlite/lower.js +1093 -0
- package/dist/sqlite/parse.d.ts +10 -0
- package/dist/sqlite/parse.js +70 -0
- package/dist/sqlite/signatures.generated.d.ts +6 -0
- package/dist/sqlite/signatures.generated.js +277 -0
- package/dist/symbols/symbols.js +14 -12
- package/dist/token/classify.js +31 -0
- package/dist/token/tokenize.js +4 -0
- package/dist/trino/behavior.d.ts +2 -0
- package/dist/trino/behavior.js +21 -0
- package/dist/trino/fold.d.ts +8 -0
- package/dist/trino/fold.js +39 -0
- package/dist/trino/index.d.ts +7 -0
- package/dist/trino/index.js +10 -0
- package/dist/{infer/trino.d.ts → trino/infer.d.ts} +2 -2
- package/dist/{infer/trino.js → trino/infer.js} +4 -3
- package/dist/trino/lower.js +5 -5
- package/dist/trino/signatures.generated.d.ts +6 -0
- package/dist/trino/signatures.generated.js +968 -0
- package/dist/tsql/behavior.d.ts +2 -0
- package/dist/tsql/behavior.js +20 -0
- package/dist/tsql/fold.d.ts +8 -0
- package/dist/tsql/fold.js +34 -0
- package/dist/tsql/index.d.ts +7 -0
- package/dist/tsql/index.js +10 -0
- package/dist/tsql/infer.d.ts +16 -0
- package/dist/tsql/infer.js +289 -0
- package/dist/tsql/lower.js +4 -4
- package/dist/tsql/signatures.generated.d.ts +6 -0
- package/dist/tsql/signatures.generated.js +640 -0
- package/package.json +15 -11
- package/dist/generated/bigquery/GoogleSQLLexer.d.ts +0 -407
- package/dist/generated/bigquery/GoogleSQLParser.d.ts +0 -9558
- package/dist/generated/bigquery/GoogleSQLParserListener.d.ts +0 -7777
- package/dist/generated/bigquery/GoogleSQLParserListener.js +0 -7070
- package/dist/generated/databricks/DatabricksLexer.d.ts +0 -566
- package/dist/generated/databricks/DatabricksParser.d.ts +0 -7771
- package/dist/generated/databricks/DatabricksParserListener.d.ts +0 -5737
- package/dist/generated/databricks/DatabricksParserListener.js +0 -5256
- package/dist/generated/duckdb/DuckdbLexer.d.ts +0 -691
- package/dist/generated/duckdb/DuckdbParser.d.ts +0 -13932
- package/dist/generated/duckdb/DuckdbParserListener.d.ts +0 -10049
- package/dist/generated/duckdb/DuckdbParserListener.js +0 -9138
- package/dist/generated/minijinja/MinijinjaLexer.d.ts +0 -108
- package/dist/generated/minijinja/MinijinjaParser.d.ts +0 -604
- package/dist/generated/minijinja/MinijinjaParserListener.d.ts +0 -449
- package/dist/generated/minijinja/MinijinjaParserListener.js +0 -410
- package/dist/generated/postgres/PostgresLexer.d.ts +0 -663
- package/dist/generated/postgres/PostgresParser.d.ts +0 -12963
- package/dist/generated/postgres/PostgresParserListener.d.ts +0 -9408
- package/dist/generated/postgres/PostgresParserListener.js +0 -8554
- package/dist/generated/redshift/RedshiftLexer.d.ts +0 -954
- package/dist/generated/redshift/RedshiftParser.d.ts +0 -16939
- package/dist/generated/redshift/RedshiftParserListener.d.ts +0 -12092
- package/dist/generated/redshift/RedshiftParserListener.js +0 -10994
- package/dist/generated/snowflake/SnowflakeLexer.d.ts +0 -1046
- package/dist/generated/snowflake/SnowflakeParser.d.ts +0 -14196
- package/dist/generated/snowflake/SnowflakeParserListener.d.ts +0 -8063
- package/dist/generated/snowflake/SnowflakeParserListener.js +0 -7330
- package/dist/generated/trino/TrinoLexer.d.ts +0 -381
- package/dist/generated/trino/TrinoParser.d.ts +0 -5340
- package/dist/generated/trino/TrinoParserListener.d.ts +0 -4704
- package/dist/generated/trino/TrinoParserListener.js +0 -4326
- package/dist/generated/tsql/TSqlLexer.d.ts +0 -1278
- package/dist/generated/tsql/TSqlParser.d.ts +0 -17267
- package/dist/generated/tsql/TSqlParserListener.d.ts +0 -9697
- package/dist/generated/tsql/TSqlParserListener.js +0 -8854
- package/dist/infer/dialect.d.ts +0 -21
- package/dist/infer/dialect.js +0 -74
- package/dist/infer/literals.d.ts +0 -6
- package/dist/infer/literals.js +0 -44
- package/dist/signature/generated/tsql.d.ts +0 -3
- package/dist/signature/generated/tsql.js +0 -260
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { acceptsFor } from "../dialect-behavior/coerce-rules.js";
|
|
2
|
+
import { likePatternToRegExp } from "../scope/like-pattern.js";
|
|
3
|
+
import { SIGNATURES } from "../signature/signatures.js";
|
|
4
|
+
import { displayName, fold, foldTableName, matchesSourceKey } from "./fold.js";
|
|
5
|
+
import { sqliteLiteral, sqliteParseType, SQLITE_FUNCTION_RETURNS } from "./infer.js";
|
|
6
|
+
export const sqliteBehavior = {
|
|
7
|
+
fold,
|
|
8
|
+
displayName,
|
|
9
|
+
foldTableName,
|
|
10
|
+
matchesSourceKey,
|
|
11
|
+
likeMatch: (pattern, value) => likePatternToRegExp(pattern).test(value),
|
|
12
|
+
literal: sqliteLiteral,
|
|
13
|
+
parseType: sqliteParseType,
|
|
14
|
+
functions: SQLITE_FUNCTION_RETURNS,
|
|
15
|
+
division: "integer",
|
|
16
|
+
signatures: SIGNATURES.sqlite,
|
|
17
|
+
// SQLite implicit coercion: TEXT containing a number coerces to numeric (STR_TO_NUM=true), no bool<->num (BOOL_NUM=false).
|
|
18
|
+
accepts: (argType, paramText) => acceptsFor(sqliteParseType, true, false, argType, paramText),
|
|
19
|
+
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { type FoldRule, type IdentKind } from "../ident/fold.js";
|
|
2
|
+
export declare const SQLITE_FOLD_RULE: FoldRule;
|
|
3
|
+
/** Fold an identifier to its SQLite identity key. */
|
|
4
|
+
export declare function fold(raw: string, kind?: IdentKind): string;
|
|
5
|
+
/** Presentation twin: strip delimiters, no case change. */
|
|
6
|
+
export declare function displayName(raw: string): string;
|
|
7
|
+
export declare function foldTableName(parts: string[]): string[];
|
|
8
|
+
export declare function matchesSourceKey(key: string, rawPart: string): boolean;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
// SQLite identifier folding. The FoldRule plus its bound engine, colocated here because BOTH the
|
|
2
|
+
// upstream lower() and the downstream DialectBehavior need it (the fold rule is the one dialect concern
|
|
3
|
+
// used at two stages).
|
|
4
|
+
//
|
|
5
|
+
// sqlite.org/lang_keywords.html — verified live: SQLite recognizes three identifier-quoting
|
|
6
|
+
// delimiters, each documented only as "is an identifier" (double-quote, square-bracket, and
|
|
7
|
+
// grave-accent/backtick forms) with no case-sensitivity distinction drawn between them or
|
|
8
|
+
// against the unquoted form. SQLite's own grammar (IDENTIFIER token) treats `"x"`, `` `x` ``,
|
|
9
|
+
// `[x]` and bare `x` as the same lexical category, and SQLite's C-level identifier compare
|
|
10
|
+
// (sqlite3StrICmp) is ASCII case-insensitive regardless of how the name was spelled — the
|
|
11
|
+
// documented quirk this module's brief calls out: unlike Postgres/Snowflake, quoting an
|
|
12
|
+
// identifier does NOT make it case-sensitive in SQLite. So both unquoted AND quoted fold to
|
|
13
|
+
// lower here (same shape as redshift/duckdb/trino). SQLite's own documented fold is
|
|
14
|
+
// ASCII-only (it does not case-fold non-ASCII), but this module's shared applyCase uses JS
|
|
15
|
+
// toLowerCase() — a Unicode-wide fold — so a rare non-ASCII identifier pair (Ä vs ä) that
|
|
16
|
+
// SQLite would keep distinct conflates here: a known shared-engine limitation, consistent
|
|
17
|
+
// across every dialect in this table. Bracket delimiters have no escape mechanism (the
|
|
18
|
+
// lexer's `[`...`]` body is `~']'*` — no doubling), so a doubled `]]` inside `[...]` is not
|
|
19
|
+
// unescaped, same as this module's tsql bracket handling.
|
|
20
|
+
import { displayWith, foldWith } from "../ident/fold.js";
|
|
21
|
+
const DOUBLE_QUOTE = ['"', '"'];
|
|
22
|
+
const BACKTICK = ["`", "`"];
|
|
23
|
+
export const SQLITE_FOLD_RULE = {
|
|
24
|
+
delimiters: [DOUBLE_QUOTE, BACKTICK, ["[", "]"]],
|
|
25
|
+
unquoted: "lower",
|
|
26
|
+
quoted: "lower",
|
|
27
|
+
};
|
|
28
|
+
/** Fold an identifier to its SQLite identity key. */
|
|
29
|
+
export function fold(raw, kind = "other") {
|
|
30
|
+
return foldWith(SQLITE_FOLD_RULE, raw, kind);
|
|
31
|
+
}
|
|
32
|
+
/** Presentation twin: strip delimiters, no case change. */
|
|
33
|
+
export function displayName(raw) {
|
|
34
|
+
return displayWith(SQLITE_FOLD_RULE, raw);
|
|
35
|
+
}
|
|
36
|
+
export function foldTableName(parts) {
|
|
37
|
+
return parts.map((p) => fold(p, "table"));
|
|
38
|
+
}
|
|
39
|
+
export function matchesSourceKey(key, rawPart) {
|
|
40
|
+
return key === fold(rawPart) || key === fold(rawPart, "table");
|
|
41
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
// The complete sqlite dialect module: parse + lower (front end) and behavior (semantic knowledge).
|
|
2
|
+
// The registry wires this; to understand everything sqllens does for sqlite, read this folder.
|
|
3
|
+
import { sqliteBehavior } from "./behavior.js";
|
|
4
|
+
import { lower } from "./lower.js";
|
|
5
|
+
import { parseSqlite } from "./parse.js";
|
|
6
|
+
export const sqlite = {
|
|
7
|
+
parse: parseSqlite,
|
|
8
|
+
lower,
|
|
9
|
+
behavior: sqliteBehavior,
|
|
10
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { type Type } from "../infer/types.js";
|
|
2
|
+
import type { FnRule } from "../infer/functions.js";
|
|
3
|
+
export declare const SQLITE_ALIASES: Record<string, string>;
|
|
4
|
+
export declare function sqliteParseType(text: string): Type;
|
|
5
|
+
/** SQLite literal forms, by storage class (sqlite.org/datatype3.html has exactly five: NULL,
|
|
6
|
+
* INTEGER, REAL, TEXT, BLOB — there is no native BOOLEAN or DATE/TIME/TIMESTAMP class).
|
|
7
|
+
* TRUE/FALSE are literal aliases for the integers 1/0, not a boolean type
|
|
8
|
+
* (sqlite.org/lang_expr.html#literal_values_constants_). CURRENT_TIME/CURRENT_DATE/
|
|
9
|
+
* CURRENT_TIMESTAMP expand to a formatted TEXT value (sqlite.org/lang_createtable.html
|
|
10
|
+
* §"The DEFAULT clause"), not a date/time type. */
|
|
11
|
+
export declare function sqliteLiteral(text: string): Type;
|
|
12
|
+
export declare const SQLITE_FUNCTION_RETURNS: Record<string, FnRule>;
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import { commonType, widenSum } from "../infer/coerce.js";
|
|
2
|
+
import { parseType, scalar, UNKNOWN } from "../infer/types.js";
|
|
3
|
+
import { fold } from "./fold.js";
|
|
4
|
+
// ---------------------------------------------------------------------------
|
|
5
|
+
// SQLite inference knowledge. Literal typing (A-R4) is storage-class-faithful (sqlite.org/
|
|
6
|
+
// datatype3.html has exactly five: NULL/INTEGER/REAL/TEXT/BLOB — no native BOOLEAN or DATE/TIME/
|
|
7
|
+
// TIMESTAMP class, so this file never reaches for a `boolean` scalar). The function-return
|
|
8
|
+
// registry (R5) is worked through the core/aggregate/date/math references — lang_corefunc.html,
|
|
9
|
+
// lang_aggfunc.html, lang_datefunc.html, lang_mathfunc.html — and stays deliberately incomplete:
|
|
10
|
+
// SQLite's dynamic/flexible typing (lang_expr.html, datatype3.html) makes several documented
|
|
11
|
+
// "returns a number" functions genuinely value- or modifier-dependent (SUM/AVG/MAX/MIN's
|
|
12
|
+
// argument-shaped results, unixepoch()'s subsec-modifier int/float switch, every lang_mathfunc.html
|
|
13
|
+
// entry's undocumented storage class for its "representable integer" wording) — those stay
|
|
14
|
+
// unregistered by design, not by oversight. SQLITE_ALIASES stays empty: a CREATE TABLE column's
|
|
15
|
+
// declared type name is matched by SUBSTRING against a small pattern set to pick one of five
|
|
16
|
+
// *type affinities* (datatype3.html §3.1 "Determination Of Column Affinity"), not looked up in a
|
|
17
|
+
// fixed alias table the way other dialects' declared types are — that affinity algorithm is a
|
|
18
|
+
// distinct, not-yet-built feature, not a registration gap. Contract holds throughout: an absent
|
|
19
|
+
// rule yields `unknown`, never a guess.
|
|
20
|
+
// ---------------------------------------------------------------------------
|
|
21
|
+
export const SQLITE_ALIASES = {};
|
|
22
|
+
export function sqliteParseType(text) {
|
|
23
|
+
return parseType(text, SQLITE_ALIASES, fold);
|
|
24
|
+
}
|
|
25
|
+
const S = scalar("string");
|
|
26
|
+
const I = scalar("int");
|
|
27
|
+
const BIG = scalar("bigint");
|
|
28
|
+
const D = scalar("double");
|
|
29
|
+
const BIN = scalar("binary");
|
|
30
|
+
const fixed = (t) => () => t;
|
|
31
|
+
/** "returns argument X unchanged" (likelihood/likely/unlikely) / plain numeric passthrough (abs). */
|
|
32
|
+
const firstArg = (args) => args[0] ?? UNKNOWN;
|
|
33
|
+
/** coalesce/ifnull: "returns a copy of its first non-NULL argument" — the common type of the args
|
|
34
|
+
* (falls back to unknown, never a guess, when they don't agree). */
|
|
35
|
+
const common = (args) => commonType(args);
|
|
36
|
+
function group(rule, names) {
|
|
37
|
+
return Object.fromEntries(names.map((n) => [n, rule]));
|
|
38
|
+
}
|
|
39
|
+
/** SQLite literal forms, by storage class (sqlite.org/datatype3.html has exactly five: NULL,
|
|
40
|
+
* INTEGER, REAL, TEXT, BLOB — there is no native BOOLEAN or DATE/TIME/TIMESTAMP class).
|
|
41
|
+
* TRUE/FALSE are literal aliases for the integers 1/0, not a boolean type
|
|
42
|
+
* (sqlite.org/lang_expr.html#literal_values_constants_). CURRENT_TIME/CURRENT_DATE/
|
|
43
|
+
* CURRENT_TIMESTAMP expand to a formatted TEXT value (sqlite.org/lang_createtable.html
|
|
44
|
+
* §"The DEFAULT clause"), not a date/time type. */
|
|
45
|
+
export function sqliteLiteral(text) {
|
|
46
|
+
const t = text.trim();
|
|
47
|
+
if (/^'/.test(t))
|
|
48
|
+
return S; // STRING_LITERAL
|
|
49
|
+
if (/^x'/i.test(t))
|
|
50
|
+
return BIN; // BLOB_LITERAL — X'...'
|
|
51
|
+
if (/^null$/i.test(t))
|
|
52
|
+
return UNKNOWN;
|
|
53
|
+
if (/^(true|false)$/i.test(t))
|
|
54
|
+
return I; // integer aliases, not a boolean type
|
|
55
|
+
if (/^current_(time|date|timestamp)$/i.test(t))
|
|
56
|
+
return S;
|
|
57
|
+
if (/^[+-]?0x[0-9a-f](_?[0-9a-f])*$/i.test(t))
|
|
58
|
+
return I; // hex integer literal
|
|
59
|
+
if (/^[+-]?\d(_?\d)*$/.test(t))
|
|
60
|
+
return I; // plain integer, no '.' or exponent
|
|
61
|
+
if (/^[+-]?(\d(_?\d)*)?\.(\d(_?\d)*)?([eE][+-]?\d+)?$/.test(t) && /\d/.test(t))
|
|
62
|
+
return D; // has a '.'
|
|
63
|
+
if (/^[+-]?\d(_?\d)*[eE][+-]?\d+$/.test(t))
|
|
64
|
+
return D; // exponent form, no '.'
|
|
65
|
+
return UNKNOWN;
|
|
66
|
+
}
|
|
67
|
+
export const SQLITE_FUNCTION_RETURNS = {
|
|
68
|
+
// --- string — lang_corefunc.html: each of these is documented as unconditionally returning a
|
|
69
|
+
// string, independent of the argument's own storage class ------------------------------------
|
|
70
|
+
...group(fixed(S), [
|
|
71
|
+
"upper", // "returns a copy of input string X in which all lower-case ASCII characters are converted to their upper-case equivalent"
|
|
72
|
+
"lower", // "returns a copy of string X with all ASCII characters converted to lower case"
|
|
73
|
+
"typeof", // "returns a string that indicates the datatype of the expression X: null, integer, real, text, or blob"
|
|
74
|
+
"hex", // "returns a string which is the upper-case hexadecimal rendering of the content of that blob"
|
|
75
|
+
"quote", // "returns the text of an SQL literal which is the value of its argument suitable for inclusion into an SQL statement"
|
|
76
|
+
"ltrim", // "returns a string formed by removing any and all characters that appear in Y from the left side"
|
|
77
|
+
"rtrim", // "returns a string formed by removing any and all characters that appear in Y from the right side"
|
|
78
|
+
"trim", // "returns a string formed by removing any and all characters that appear in Y from both ends of X"
|
|
79
|
+
"replace", // "returns a string formed by substituting string Z for every occurrence of string Y in string X"
|
|
80
|
+
"soundex", // "returns a string that is the soundex encoding of the string X"
|
|
81
|
+
]),
|
|
82
|
+
// --- date/time — lang_datefunc.html: date/time/datetime/strftime/timediff all format to TEXT.
|
|
83
|
+
// unixepoch() is the one date function left OUT — its optional subsec modifier switches the
|
|
84
|
+
// return between integer and floating-point, a call-shape (not argument-type) dependency this
|
|
85
|
+
// registry has no precedent for modelling -----------------------------------------------------
|
|
86
|
+
...group(fixed(S), ["date", "time", "datetime", "strftime", "timediff"]),
|
|
87
|
+
// --- aggregate text — lang_aggfunc.html ---------------------------------------------------------
|
|
88
|
+
...group(fixed(S), ["group_concat", "string_agg"]), // "returns a string which is the concatenation of all non-NULL values of X"
|
|
89
|
+
// --- integer — lang_corefunc.html ---------------------------------------------------------------
|
|
90
|
+
...group(fixed(I), [
|
|
91
|
+
"length", // text: "number of Unicode code points"; blob: "number of bytes" — an integer either way
|
|
92
|
+
"octet_length", // "returns the number of bytes in the encoding of text string X"
|
|
93
|
+
"unicode", // "returns the numeric unicode code point corresponding to the first character of the string X"
|
|
94
|
+
"instr", // "returns the number of prior characters plus 1, or 0 if Y is nowhere found within X"
|
|
95
|
+
"sign", // "returns -1, 0, or +1" — always one of those three integers, regardless of whether X is REAL or INTEGER
|
|
96
|
+
]),
|
|
97
|
+
// --- bigint — values documented across the full 64-bit signed range --------------------------
|
|
98
|
+
count: fixed(BIG), // lang_aggfunc.html: "returns a count of the number of times that X is not NULL in a group"
|
|
99
|
+
random: fixed(BIG), // lang_corefunc.html: "returns a pseudo-random integer between -9223372036854775807 and +9223372036854775807"
|
|
100
|
+
// --- real/double ---------------------------------------------------------------------------------
|
|
101
|
+
round: fixed(D), // lang_corefunc.html: "returns a floating-point value X rounded to Y digits" — always real, even round(X) with no Y
|
|
102
|
+
total: fixed(D), // lang_aggfunc.html: "result of total() is always a floating point value" (documented always-float, unlike sum())
|
|
103
|
+
avg: fixed(D), // lang_aggfunc.html: "is always a floating point value whenever there is at least one non-NULL input" — unlike other dialects' input-typed AVG
|
|
104
|
+
julianday: fixed(D), // lang_datefunc.html: "the Julian day - the fractional number of days since noon in Greenwich..."
|
|
105
|
+
// --- blob ------------------------------------------------------------------------------------------
|
|
106
|
+
...group(fixed(BIN), [
|
|
107
|
+
"unhex", // "returns a BLOB value which is the decoding of the hexadecimal string X"
|
|
108
|
+
"zeroblob", // "returns a BLOB consisting of N bytes of 0x00"
|
|
109
|
+
"randomblob", // "return an N-byte blob containing pseudo-random bytes"
|
|
110
|
+
]),
|
|
111
|
+
// --- passthrough — lang_corefunc.html -----------------------------------------------------------
|
|
112
|
+
abs: firstArg, // "returns the absolute value of the numeric argument X" — same numeric family as its input (firstArg is the universal cross-dialect precedent for abs)
|
|
113
|
+
...group(firstArg, ["likelihood", "likely", "unlikely"]), // each: "returns argument X unchanged"
|
|
114
|
+
// --- aggregate widening ------------------------------------------------------------------------
|
|
115
|
+
// lang_aggfunc.html: "sum(X) ... Returns an integer if all inputs are integers; otherwise
|
|
116
|
+
// returns floating-point" — exactly the int-family→bigint / float→double / decimal→decimal
|
|
117
|
+
// shape widenSum already encodes (the same rule databricks/snowflake/redshift use verbatim).
|
|
118
|
+
sum: (args) => widenSum(args[0] ?? UNKNOWN),
|
|
119
|
+
// --- common-type — lang_corefunc.html: "returns a copy of its first non-NULL argument" -----------
|
|
120
|
+
coalesce: common,
|
|
121
|
+
ifnull: common,
|
|
122
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { ParserRuleContext } from "antlr4ng";
|
|
2
|
+
import type { QueryExpr } from "../ir/ir.js";
|
|
3
|
+
import { type StatementCategory } from "../ir/statement.js";
|
|
4
|
+
/** Lower a parsed SQLite file (`parse`: a `;`-separated sql_stmt_list) into the IR. A single
|
|
5
|
+
* SELECT/VALUES statement lowers fully; anything else (DDL/DML/pragma/utility, multi-statement
|
|
6
|
+
* batches, EXPLAIN) becomes a flagged non-query body — a valid parse never throws. */
|
|
7
|
+
export declare function lower(tree: ParserRuleContext): QueryExpr;
|
|
8
|
+
/** Per-statement categories for every `sql_stmt` in a parsed `parse`, in source order — the
|
|
9
|
+
* file-level view behind statementCategory (which folds >1 into "compound"). Parity with the
|
|
10
|
+
* other dialects; feeds the corpus reclassifier. */
|
|
11
|
+
export declare function statementCategories(tree: ParserRuleContext): StatementCategory[];
|