sqllens 1.1.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.
Files changed (234) hide show
  1. package/README.md +2 -74
  2. package/THIRD-PARTY-NOTICES.md +50 -5
  3. package/dist/api.d.ts +5 -3
  4. package/dist/api.js +11 -4
  5. package/dist/bigquery/behavior.d.ts +2 -0
  6. package/dist/bigquery/behavior.js +20 -0
  7. package/dist/bigquery/dot-path.d.ts +0 -2
  8. package/dist/bigquery/dot-path.js +0 -1
  9. package/dist/bigquery/fold.d.ts +8 -0
  10. package/dist/bigquery/fold.js +39 -0
  11. package/dist/bigquery/index.d.ts +7 -0
  12. package/dist/bigquery/index.js +10 -0
  13. package/dist/{infer/bigquery.d.ts → bigquery/infer.d.ts} +2 -2
  14. package/dist/{infer/bigquery.js → bigquery/infer.js} +4 -3
  15. package/dist/bigquery/lower.js +35 -12
  16. package/dist/bigquery/signatures.generated.d.ts +6 -0
  17. package/dist/bigquery/signatures.generated.js +1068 -0
  18. package/dist/completion/atn-walk.d.ts +13 -2
  19. package/dist/completion/atn-walk.js +13 -10
  20. package/dist/completion/complete.d.ts +4 -3
  21. package/dist/completion/complete.js +101 -45
  22. package/dist/completion/jinja-slot.d.ts +24 -0
  23. package/dist/completion/jinja-slot.js +126 -0
  24. package/dist/completion/parser-factory.d.ts +13 -1
  25. package/dist/completion/parser-factory.js +12 -0
  26. package/dist/databricks/behavior.d.ts +2 -0
  27. package/dist/databricks/behavior.js +19 -0
  28. package/dist/databricks/fold.d.ts +8 -0
  29. package/dist/databricks/fold.js +27 -0
  30. package/dist/databricks/index.d.ts +7 -0
  31. package/dist/databricks/index.js +10 -0
  32. package/dist/databricks/infer.d.ts +6 -0
  33. package/dist/databricks/infer.js +638 -0
  34. package/dist/databricks/signatures.generated.d.ts +6 -0
  35. package/dist/databricks/signatures.generated.js +1745 -0
  36. package/dist/dialect-behavior/behavior.d.ts +26 -0
  37. package/dist/dialect-behavior/behavior.js +1 -0
  38. package/dist/dialect-behavior/carrier.d.ts +5 -0
  39. package/dist/dialect-behavior/carrier.js +5 -0
  40. package/dist/dialect-behavior/coerce-rules.d.ts +7 -0
  41. package/dist/dialect-behavior/coerce-rules.js +69 -0
  42. package/dist/dialect-behavior/public-fold.d.ts +6 -0
  43. package/dist/dialect-behavior/public-fold.js +9 -0
  44. package/dist/dialect-behavior/registry.d.ts +6 -0
  45. package/dist/dialect-behavior/registry.js +34 -0
  46. package/dist/dialect-symbols.js +16 -19
  47. package/dist/document/document.d.ts +1 -1
  48. package/dist/document/document.js +8 -7
  49. package/dist/duckdb/behavior.d.ts +2 -0
  50. package/dist/duckdb/behavior.js +21 -0
  51. package/dist/duckdb/fold.d.ts +8 -0
  52. package/dist/duckdb/fold.js +29 -0
  53. package/dist/duckdb/index.d.ts +7 -0
  54. package/dist/duckdb/index.js +10 -0
  55. package/dist/{infer/duckdb.d.ts → duckdb/infer.d.ts} +2 -2
  56. package/dist/{infer/duckdb.js → duckdb/infer.js} +4 -3
  57. package/dist/duckdb/lower.js +47 -15
  58. package/dist/duckdb/signatures.generated.d.ts +6 -0
  59. package/dist/duckdb/signatures.generated.js +1072 -0
  60. package/dist/generated/bigquery/GoogleSQLParser.js +0 -7060
  61. package/dist/generated/databricks/DatabricksParser.js +0 -4800
  62. package/dist/generated/duckdb/DuckdbParser.js +0 -9100
  63. package/dist/generated/minijinja/MinijinjaParser.js +0 -380
  64. package/dist/generated/mysql/MysqlParser.js +0 -6330
  65. package/dist/generated/postgres/PostgresParser.js +0 -8530
  66. package/dist/generated/redshift/RedshiftParser.js +0 -10970
  67. package/dist/generated/snowflake/SnowflakeParser.js +0 -7320
  68. package/dist/generated/sqlite/SqliteParser.js +0 -1150
  69. package/dist/generated/trino/TrinoParser.js +0 -3770
  70. package/dist/generated/tsql/TSqlParser.js +0 -8420
  71. package/dist/ident/fold.d.ts +24 -15
  72. package/dist/ident/fold.js +12 -194
  73. package/dist/index.d.ts +2 -2
  74. package/dist/index.js +10 -8
  75. package/dist/infer/functions.d.ts +22 -11
  76. package/dist/infer/functions.js +26 -888
  77. package/dist/infer/infer.js +16 -14
  78. package/dist/infer/nullability.js +3 -4
  79. package/dist/infer/types.d.ts +1 -1
  80. package/dist/infer/types.js +7 -7
  81. package/dist/ir/ir.d.ts +26 -17
  82. package/dist/ir/span.js +0 -2
  83. package/dist/ir/walk.js +3 -3
  84. package/dist/lineage/hops.js +13 -10
  85. package/dist/lineage/lineage.js +10 -7
  86. package/dist/minijinja/apply-tags.d.ts +14 -7
  87. package/dist/minijinja/apply-tags.js +66 -121
  88. package/dist/minijinja/parse.js +5 -5
  89. package/dist/minijinja/tag-ast.d.ts +29 -36
  90. package/dist/minijinja/tag-ast.js +210 -90
  91. package/dist/mysql/behavior.d.ts +2 -0
  92. package/dist/mysql/behavior.js +21 -0
  93. package/dist/mysql/fold.d.ts +8 -0
  94. package/dist/mysql/fold.js +49 -0
  95. package/dist/mysql/index.d.ts +7 -0
  96. package/dist/mysql/index.js +10 -0
  97. package/dist/{infer/mysql.d.ts → mysql/infer.d.ts} +2 -2
  98. package/dist/{infer/mysql.js → mysql/infer.js} +3 -2
  99. package/dist/mysql/signatures.generated.d.ts +6 -0
  100. package/dist/mysql/signatures.generated.js +508 -0
  101. package/dist/postgres/behavior.d.ts +2 -0
  102. package/dist/postgres/behavior.js +19 -0
  103. package/dist/postgres/fold.d.ts +8 -0
  104. package/dist/postgres/fold.js +30 -0
  105. package/dist/postgres/index.d.ts +7 -0
  106. package/dist/postgres/index.js +10 -0
  107. package/dist/{infer/postgres.d.ts → postgres/infer.d.ts} +2 -2
  108. package/dist/{infer/postgres.js → postgres/infer.js} +4 -3
  109. package/dist/postgres/lower.js +2 -2
  110. package/dist/postgres/signatures.generated.d.ts +6 -0
  111. package/dist/postgres/signatures.generated.js +2973 -0
  112. package/dist/qualify/check-calls.js +80 -161
  113. package/dist/qualify/qualify.js +16 -14
  114. package/dist/qualify/schema-provider.js +2 -2
  115. package/dist/qualify/schema.js +3 -3
  116. package/dist/qualify/template-provider.d.ts +45 -12
  117. package/dist/qualify/template-provider.js +69 -38
  118. package/dist/redshift/behavior.d.ts +2 -0
  119. package/dist/redshift/behavior.js +19 -0
  120. package/dist/redshift/fold.d.ts +8 -0
  121. package/dist/redshift/fold.js +31 -0
  122. package/dist/redshift/index.d.ts +7 -0
  123. package/dist/redshift/index.js +10 -0
  124. package/dist/{infer/redshift.d.ts → redshift/infer.d.ts} +2 -2
  125. package/dist/{infer/redshift.js → redshift/infer.js} +4 -3
  126. package/dist/redshift/lower.js +2 -2
  127. package/dist/redshift/signatures.generated.d.ts +6 -0
  128. package/dist/redshift/signatures.generated.js +757 -0
  129. package/dist/references/references.js +17 -12
  130. package/dist/scope/like-pattern.d.ts +2 -0
  131. package/dist/scope/like-pattern.js +15 -0
  132. package/dist/scope/scope.d.ts +5 -5
  133. package/dist/scope/scope.js +48 -42
  134. package/dist/sema/resolve.js +17 -12
  135. package/dist/session.d.ts +2 -2
  136. package/dist/signature/signature.d.ts +14 -6
  137. package/dist/signature/signature.js +30 -22
  138. package/dist/signature/signatures.d.ts +14 -12
  139. package/dist/signature/signatures.js +42 -721
  140. package/dist/snowflake/behavior.d.ts +2 -0
  141. package/dist/snowflake/behavior.js +22 -0
  142. package/dist/snowflake/fold.d.ts +8 -0
  143. package/dist/snowflake/fold.js +25 -0
  144. package/dist/snowflake/index.d.ts +7 -0
  145. package/dist/snowflake/index.js +10 -0
  146. package/dist/{infer/snowflake.d.ts → snowflake/infer.d.ts} +2 -2
  147. package/dist/{infer/snowflake.js → snowflake/infer.js} +4 -3
  148. package/dist/snowflake/lower.js +59 -19
  149. package/dist/snowflake/signatures.generated.d.ts +6 -0
  150. package/dist/snowflake/signatures.generated.js +2080 -0
  151. package/dist/sqlite/behavior.d.ts +2 -0
  152. package/dist/sqlite/behavior.js +19 -0
  153. package/dist/sqlite/fold.d.ts +8 -0
  154. package/dist/sqlite/fold.js +41 -0
  155. package/dist/sqlite/index.d.ts +7 -0
  156. package/dist/sqlite/index.js +10 -0
  157. package/dist/{infer/sqlite.d.ts → sqlite/infer.d.ts} +2 -2
  158. package/dist/{infer/sqlite.js → sqlite/infer.js} +4 -3
  159. package/dist/sqlite/signatures.generated.d.ts +6 -0
  160. package/dist/sqlite/signatures.generated.js +277 -0
  161. package/dist/symbols/symbols.js +14 -12
  162. package/dist/trino/behavior.d.ts +2 -0
  163. package/dist/trino/behavior.js +21 -0
  164. package/dist/trino/fold.d.ts +8 -0
  165. package/dist/trino/fold.js +39 -0
  166. package/dist/trino/index.d.ts +7 -0
  167. package/dist/trino/index.js +10 -0
  168. package/dist/{infer/trino.d.ts → trino/infer.d.ts} +2 -2
  169. package/dist/{infer/trino.js → trino/infer.js} +4 -3
  170. package/dist/trino/lower.js +5 -5
  171. package/dist/trino/signatures.generated.d.ts +6 -0
  172. package/dist/trino/signatures.generated.js +968 -0
  173. package/dist/tsql/behavior.d.ts +2 -0
  174. package/dist/tsql/behavior.js +20 -0
  175. package/dist/tsql/fold.d.ts +8 -0
  176. package/dist/tsql/fold.js +34 -0
  177. package/dist/tsql/index.d.ts +7 -0
  178. package/dist/tsql/index.js +10 -0
  179. package/dist/tsql/infer.d.ts +16 -0
  180. package/dist/tsql/infer.js +289 -0
  181. package/dist/tsql/lower.js +4 -4
  182. package/dist/tsql/signatures.generated.d.ts +6 -0
  183. package/dist/tsql/signatures.generated.js +640 -0
  184. package/package.json +5 -10
  185. package/dist/generated/bigquery/GoogleSQLLexer.d.ts +0 -407
  186. package/dist/generated/bigquery/GoogleSQLParser.d.ts +0 -9558
  187. package/dist/generated/bigquery/GoogleSQLParserListener.d.ts +0 -7777
  188. package/dist/generated/bigquery/GoogleSQLParserListener.js +0 -7070
  189. package/dist/generated/databricks/DatabricksLexer.d.ts +0 -566
  190. package/dist/generated/databricks/DatabricksParser.d.ts +0 -7771
  191. package/dist/generated/databricks/DatabricksParserListener.d.ts +0 -5737
  192. package/dist/generated/databricks/DatabricksParserListener.js +0 -5256
  193. package/dist/generated/duckdb/DuckdbLexer.d.ts +0 -691
  194. package/dist/generated/duckdb/DuckdbParser.d.ts +0 -13932
  195. package/dist/generated/duckdb/DuckdbParserListener.d.ts +0 -10049
  196. package/dist/generated/duckdb/DuckdbParserListener.js +0 -9138
  197. package/dist/generated/minijinja/MinijinjaLexer.d.ts +0 -108
  198. package/dist/generated/minijinja/MinijinjaParser.d.ts +0 -604
  199. package/dist/generated/minijinja/MinijinjaParserListener.d.ts +0 -449
  200. package/dist/generated/minijinja/MinijinjaParserListener.js +0 -410
  201. package/dist/generated/mysql/MysqlLexer.d.ts +0 -1198
  202. package/dist/generated/mysql/MysqlParser.d.ts +0 -10992
  203. package/dist/generated/mysql/MysqlParserListener.d.ts +0 -7592
  204. package/dist/generated/mysql/MysqlParserListener.js +0 -6958
  205. package/dist/generated/postgres/PostgresLexer.d.ts +0 -663
  206. package/dist/generated/postgres/PostgresParser.d.ts +0 -12963
  207. package/dist/generated/postgres/PostgresParserListener.d.ts +0 -9408
  208. package/dist/generated/postgres/PostgresParserListener.js +0 -8554
  209. package/dist/generated/redshift/RedshiftLexer.d.ts +0 -954
  210. package/dist/generated/redshift/RedshiftParser.d.ts +0 -16939
  211. package/dist/generated/redshift/RedshiftParserListener.d.ts +0 -12092
  212. package/dist/generated/redshift/RedshiftParserListener.js +0 -10994
  213. package/dist/generated/snowflake/SnowflakeLexer.d.ts +0 -1046
  214. package/dist/generated/snowflake/SnowflakeParser.d.ts +0 -14196
  215. package/dist/generated/snowflake/SnowflakeParserListener.d.ts +0 -8063
  216. package/dist/generated/snowflake/SnowflakeParserListener.js +0 -7330
  217. package/dist/generated/sqlite/SqliteLexer.d.ts +0 -210
  218. package/dist/generated/sqlite/SqliteParser.d.ts +0 -2115
  219. package/dist/generated/sqlite/SqliteParserListener.d.ts +0 -1276
  220. package/dist/generated/sqlite/SqliteParserListener.js +0 -1160
  221. package/dist/generated/trino/TrinoLexer.d.ts +0 -381
  222. package/dist/generated/trino/TrinoParser.d.ts +0 -5340
  223. package/dist/generated/trino/TrinoParserListener.d.ts +0 -4704
  224. package/dist/generated/trino/TrinoParserListener.js +0 -4326
  225. package/dist/generated/tsql/TSqlLexer.d.ts +0 -1278
  226. package/dist/generated/tsql/TSqlParser.d.ts +0 -17267
  227. package/dist/generated/tsql/TSqlParserListener.d.ts +0 -9697
  228. package/dist/generated/tsql/TSqlParserListener.js +0 -8854
  229. package/dist/infer/dialect.d.ts +0 -21
  230. package/dist/infer/dialect.js +0 -100
  231. package/dist/infer/literals.d.ts +0 -6
  232. package/dist/infer/literals.js +0 -44
  233. package/dist/signature/generated/tsql.d.ts +0 -3
  234. package/dist/signature/generated/tsql.js +0 -260
@@ -0,0 +1,2 @@
1
+ import type { DialectBehavior } from "../dialect-behavior/behavior.js";
2
+ export declare const sqliteBehavior: DialectBehavior;
@@ -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,7 @@
1
+ import { lower } from "./lower.js";
2
+ import { parseSqlite } from "./parse.js";
3
+ export declare const sqlite: {
4
+ parse: typeof parseSqlite;
5
+ lower: typeof lower;
6
+ behavior: import("../dialect-behavior/behavior.js").DialectBehavior;
7
+ };
@@ -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
+ };
@@ -1,5 +1,5 @@
1
- import { type Type } from "./types.js";
2
- import type { FnRule } from "./functions.js";
1
+ import { type Type } from "../infer/types.js";
2
+ import type { FnRule } from "../infer/functions.js";
3
3
  export declare const SQLITE_ALIASES: Record<string, string>;
4
4
  export declare function sqliteParseType(text: string): Type;
5
5
  /** SQLite literal forms, by storage class (sqlite.org/datatype3.html has exactly five: NULL,
@@ -1,5 +1,6 @@
1
- import { commonType, widenSum } from "./coerce.js";
2
- import { parseType, scalar, UNKNOWN } from "./types.js";
1
+ import { commonType, widenSum } from "../infer/coerce.js";
2
+ import { parseType, scalar, UNKNOWN } from "../infer/types.js";
3
+ import { fold } from "./fold.js";
3
4
  // ---------------------------------------------------------------------------
4
5
  // SQLite inference knowledge. Literal typing (A-R4) is storage-class-faithful (sqlite.org/
5
6
  // datatype3.html has exactly five: NULL/INTEGER/REAL/TEXT/BLOB — no native BOOLEAN or DATE/TIME/
@@ -19,7 +20,7 @@ import { parseType, scalar, UNKNOWN } from "./types.js";
19
20
  // ---------------------------------------------------------------------------
20
21
  export const SQLITE_ALIASES = {};
21
22
  export function sqliteParseType(text) {
22
- return parseType(text, SQLITE_ALIASES, "sqlite");
23
+ return parseType(text, SQLITE_ALIASES, fold);
23
24
  }
24
25
  const S = scalar("string");
25
26
  const I = scalar("int");
@@ -0,0 +1,6 @@
1
+ import type { FnSignature } from "../signature/signatures.js";
2
+ /** The merged function-signature table for sqlite: curated overrides folded over the harvested
3
+ * doc-derived long tail (overrides win by key, replacing the whole overload set), keyed by
4
+ * lowercased name. Each name maps to an ORDERED overload set - a name with one documented shape
5
+ * is a one-element array. `origin` says which layer produced the set. */
6
+ export declare const SQLITE_SIGNATURES: Record<string, FnSignature[]>;
@@ -0,0 +1,277 @@
1
+ /** The merged function-signature table for sqlite: curated overrides folded over the harvested
2
+ * doc-derived long tail (overrides win by key, replacing the whole overload set), keyed by
3
+ * lowercased name. Each name maps to an ORDERED overload set - a name with one documented shape
4
+ * is a one-element array. `origin` says which layer produced the set. */
5
+ export const SQLITE_SIGNATURES = {
6
+ abs: [{ name: "abs", params: [{ name: "X" }], origin: "harvested" }], // lang_corefunc/1.txt
7
+ acos: [{ name: "acos", params: [{ name: "X" }], origin: "harvested" }], // lang_mathfunc/1.txt
8
+ acosh: [{ name: "acosh", params: [{ name: "X" }], origin: "harvested" }], // lang_mathfunc/2.txt
9
+ asin: [{ name: "asin", params: [{ name: "X" }], origin: "harvested" }], // lang_mathfunc/3.txt
10
+ asinh: [{ name: "asinh", params: [{ name: "X" }], origin: "harvested" }], // lang_mathfunc/4.txt
11
+ atan: [{ name: "atan", params: [{ name: "X" }], origin: "harvested" }], // lang_mathfunc/5.txt
12
+ atan2: [{ name: "atan2", params: [{ name: "Y" }, { name: "X" }], origin: "harvested" }], // lang_mathfunc/6.txt
13
+ atanh: [{ name: "atanh", params: [{ name: "X" }], origin: "harvested" }], // lang_mathfunc/7.txt
14
+ avg: [{ name: "avg", params: [{ name: "X" }], origin: "harvested" }], // lang_aggfunc/1.txt
15
+ ceil: [{ name: "ceil", params: [{ name: "X" }], origin: "harvested" }], // lang_mathfunc/8.txt
16
+ ceiling: [{ name: "ceiling", params: [{ name: "X" }], origin: "harvested" }], // lang_mathfunc/9.txt
17
+ changes: [{ name: "changes", params: [], origin: "harvested" }], // lang_corefunc/2.txt
18
+ coalesce: [{ name: "coalesce", params: [{ name: "X" }, { name: "Y" }], variadic: true, origin: "harvested" }], // lang_corefunc/4.txt
19
+ concat: [{ name: "concat", params: [{ name: "X" }], variadic: true, origin: "harvested" }], // lang_corefunc/5.txt
20
+ concat_ws: [{ name: "concat_ws", params: [{ name: "SEP" }, { name: "X" }], variadic: true, origin: "harvested" }], // lang_corefunc/6.txt
21
+ cos: [{ name: "cos", params: [{ name: "X" }], origin: "harvested" }], // lang_mathfunc/10.txt
22
+ cosh: [{ name: "cosh", params: [{ name: "X" }], origin: "harvested" }], // lang_mathfunc/11.txt
23
+ count: [{ name: "count", params: [{ name: "X" }], origin: "harvested" }], // lang_aggfunc/3.txt
24
+ cume_dist: [{ name: "cume_dist", params: [], origin: "harvested" }], // windowfunctions/5.txt
25
+ date: [
26
+ {
27
+ name: "date",
28
+ params: [
29
+ { name: "time_value", type: "text" },
30
+ { name: "modifier", type: "text" },
31
+ ],
32
+ variadic: true,
33
+ origin: "curated",
34
+ },
35
+ ], // curated: date(time-value, modifier, ...)
36
+ datetime: [
37
+ {
38
+ name: "datetime",
39
+ params: [
40
+ { name: "time_value", type: "text" },
41
+ { name: "modifier", type: "text" },
42
+ ],
43
+ variadic: true,
44
+ origin: "curated",
45
+ },
46
+ ], // curated: datetime(time-value, modifier, ...)
47
+ degrees: [{ name: "degrees", params: [{ name: "X" }], origin: "harvested" }], // lang_mathfunc/12.txt
48
+ dense_rank: [{ name: "dense_rank", params: [], origin: "harvested" }], // windowfunctions/3.txt
49
+ exp: [{ name: "exp", params: [{ name: "X" }], origin: "harvested" }], // lang_mathfunc/13.txt
50
+ first_value: [{ name: "first_value", params: [{ name: "expr" }], origin: "harvested" }], // windowfunctions/13.txt
51
+ floor: [{ name: "floor", params: [{ name: "X" }], origin: "harvested" }], // lang_mathfunc/14.txt
52
+ format: [{ name: "format", params: [{ name: "FORMAT" }], variadic: true, origin: "harvested" }], // lang_corefunc/7.txt
53
+ glob: [
54
+ {
55
+ name: "glob",
56
+ params: [
57
+ { name: "pattern", type: "text" },
58
+ { name: "string", type: "text" },
59
+ ],
60
+ origin: "curated",
61
+ },
62
+ ], // curated: glob(X,Y) ("Y GLOB X")
63
+ group_concat: [
64
+ { name: "group_concat", params: [{ name: "X" }, { name: "Y", optional: true }], origin: "harvested" },
65
+ ], // lang_aggfunc/5.txt
66
+ hex: [{ name: "hex", params: [{ name: "X" }], origin: "harvested" }], // lang_corefunc/9.txt
67
+ if: [{ name: "if", params: [{ name: "B1" }, { name: "V1" }], variadic: true, origin: "harvested" }], // lang_corefunc/10.txt
68
+ ifnull: [{ name: "ifnull", params: [{ name: "X" }, { name: "Y" }], origin: "harvested" }], // lang_corefunc/11.txt
69
+ iif: [
70
+ {
71
+ name: "iif",
72
+ params: [{ name: "condition", type: "boolean" }, { name: "true_value" }, { name: "false_value" }],
73
+ variadic: true,
74
+ origin: "curated",
75
+ },
76
+ ], // curated: iif(B1,V1,B2,V2,...,else)
77
+ instr: [{ name: "instr", params: [{ name: "X" }, { name: "Y" }], origin: "harvested" }], // lang_corefunc/13.txt
78
+ json: [{ name: "json", params: [{ name: "X" }], origin: "harvested" }], // json1/1.txt
79
+ json_array_length: [
80
+ { name: "json_array_length", params: [{ name: "X" }, { name: "P", optional: true }], origin: "harvested" },
81
+ ], // json1/4.txt
82
+ json_each: [{ name: "json_each", params: [{ name: "X" }, { name: "P", optional: true }], origin: "harvested" }], // json1/20.txt
83
+ json_error_position: [{ name: "json_error_position", params: [{ name: "X" }], origin: "harvested" }], // json1/5.txt
84
+ json_extract: [
85
+ {
86
+ name: "json_extract",
87
+ params: [{ name: "X" }, { name: "P1" }, { name: "P2" }],
88
+ variadic: true,
89
+ origin: "harvested",
90
+ },
91
+ ], // json1/6.txt
92
+ json_group_array: [{ name: "json_group_array", params: [{ name: "X" }], origin: "harvested" }], // json1/14.txt
93
+ json_group_object: [
94
+ { name: "json_group_object", params: [{ name: "NAME" }, { name: "VALUE" }], origin: "harvested" },
95
+ ], // json1/15.txt
96
+ json_patch: [{ name: "json_patch", params: [{ name: "T" }, { name: "P" }], origin: "harvested" }], // json1/7.txt
97
+ json_quote: [{ name: "json_quote", params: [{ name: "X" }], origin: "harvested" }], // json1/13.txt
98
+ json_remove: [
99
+ {
100
+ name: "json_remove",
101
+ params: [{ name: "X" }, { name: "P", optional: true }],
102
+ variadic: true,
103
+ origin: "harvested",
104
+ },
105
+ ], // json1/8.txt
106
+ json_tree: [{ name: "json_tree", params: [{ name: "X" }, { name: "P", optional: true }], origin: "harvested" }], // json1/22.txt
107
+ json_type: [{ name: "json_type", params: [{ name: "X" }, { name: "P", optional: true }], origin: "harvested" }], // json1/11.txt
108
+ json_valid: [{ name: "json_valid", params: [{ name: "X" }, { name: "Y" }], origin: "harvested" }], // json1/12.txt
109
+ jsonb: [{ name: "jsonb", params: [{ name: "X" }], origin: "harvested" }], // json1/2.txt
110
+ jsonb_each: [{ name: "jsonb_each", params: [{ name: "X" }, { name: "P", optional: true }], origin: "harvested" }], // json1/21.txt
111
+ jsonb_tree: [{ name: "jsonb_tree", params: [{ name: "X" }, { name: "P", optional: true }], origin: "harvested" }], // json1/23.txt
112
+ julianday: [
113
+ {
114
+ name: "julianday",
115
+ params: [
116
+ { name: "time_value", type: "text" },
117
+ { name: "modifier", type: "text" },
118
+ ],
119
+ variadic: true,
120
+ origin: "curated",
121
+ },
122
+ ], // curated: julianday(time-value, modifier, ...)
123
+ lag: [
124
+ {
125
+ name: "lag",
126
+ params: [{ name: "expr" }, { name: "offset", optional: true }, { name: "default", optional: true }],
127
+ origin: "harvested",
128
+ },
129
+ ], // windowfunctions/9.txt
130
+ last_insert_rowid: [{ name: "last_insert_rowid", params: [], origin: "harvested" }], // lang_corefunc/14.txt
131
+ last_value: [{ name: "last_value", params: [{ name: "expr" }], origin: "harvested" }], // windowfunctions/14.txt
132
+ lead: [
133
+ {
134
+ name: "lead",
135
+ params: [{ name: "expr" }, { name: "offset", optional: true }, { name: "default", optional: true }],
136
+ origin: "harvested",
137
+ },
138
+ ], // windowfunctions/12.txt
139
+ length: [{ name: "length", params: [{ name: "X" }], origin: "harvested" }], // lang_corefunc/15.txt
140
+ like: [
141
+ {
142
+ name: "like",
143
+ params: [
144
+ { name: "pattern", type: "text" },
145
+ { name: "string", type: "text" },
146
+ { name: "escape", type: "text", optional: true },
147
+ ],
148
+ origin: "curated",
149
+ },
150
+ ], // curated: like(X,Y[,Z]) ("Y LIKE X [ESCAPE Z]")
151
+ likelihood: [{ name: "likelihood", params: [{ name: "X" }, { name: "Y" }], origin: "harvested" }], // lang_corefunc/18.txt
152
+ likely: [{ name: "likely", params: [{ name: "X" }], origin: "harvested" }], // lang_corefunc/19.txt
153
+ ln: [{ name: "ln", params: [{ name: "X" }], origin: "harvested" }], // lang_mathfunc/15.txt
154
+ load_extension: [
155
+ { name: "load_extension", params: [{ name: "X" }, { name: "Y", optional: true }], origin: "harvested" },
156
+ ], // lang_corefunc/21.txt
157
+ log: [
158
+ { name: "log", params: [{ name: "B" }, { name: "X" }], origin: "harvested" },
159
+ { name: "log", params: [{ name: "X" }], origin: "harvested" },
160
+ ], // lang_mathfunc/16.txt, lang_mathfunc/17.txt
161
+ log10: [{ name: "log10", params: [{ name: "X" }], origin: "harvested" }], // lang_mathfunc/18.txt
162
+ log2: [{ name: "log2", params: [{ name: "X" }], origin: "harvested" }], // lang_mathfunc/19.txt
163
+ lower: [{ name: "lower", params: [{ name: "X" }], origin: "harvested" }], // lang_corefunc/22.txt
164
+ ltrim: [{ name: "ltrim", params: [{ name: "X" }, { name: "Y", optional: true }], origin: "harvested" }], // lang_corefunc/24.txt
165
+ max: [{ name: "max", params: [{ name: "X" }, { name: "Y", optional: true }], variadic: true, origin: "harvested" }], // lang_corefunc/25.txt
166
+ median: [{ name: "median", params: [{ name: "X" }], origin: "harvested" }], // lang_aggfunc/7.txt
167
+ min: [{ name: "min", params: [{ name: "X" }, { name: "Y", optional: true }], variadic: true, origin: "harvested" }], // lang_corefunc/26.txt
168
+ mod: [{ name: "mod", params: [{ name: "X" }, { name: "Y" }], origin: "harvested" }], // lang_mathfunc/20.txt
169
+ nth_value: [{ name: "nth_value", params: [{ name: "expr" }, { name: "N" }], origin: "harvested" }], // windowfunctions/15.txt
170
+ ntile: [{ name: "ntile", params: [{ name: "N" }], origin: "harvested" }], // windowfunctions/6.txt
171
+ nullif: [{ name: "nullif", params: [{ name: "X" }, { name: "Y" }], origin: "harvested" }], // lang_corefunc/27.txt
172
+ octet_length: [{ name: "octet_length", params: [{ name: "X" }], origin: "harvested" }], // lang_corefunc/28.txt
173
+ percent_rank: [{ name: "percent_rank", params: [], origin: "harvested" }], // windowfunctions/4.txt
174
+ percentile: [{ name: "percentile", params: [{ name: "Y" }, { name: "P" }], origin: "harvested" }], // lang_aggfunc/9.txt
175
+ percentile_cont: [{ name: "percentile_cont", params: [{ name: "Y" }, { name: "P" }], origin: "harvested" }], // lang_aggfunc/10.txt
176
+ percentile_disc: [{ name: "percentile_disc", params: [{ name: "Y" }, { name: "P" }], origin: "harvested" }], // lang_aggfunc/11.txt
177
+ pi: [{ name: "pi", params: [], origin: "harvested" }], // lang_mathfunc/21.txt
178
+ pow: [{ name: "pow", params: [{ name: "X" }, { name: "Y" }], origin: "harvested" }], // lang_mathfunc/22.txt
179
+ power: [{ name: "power", params: [{ name: "X" }, { name: "Y" }], origin: "harvested" }], // lang_mathfunc/23.txt
180
+ printf: [
181
+ {
182
+ name: "printf",
183
+ params: [{ name: "format", type: "text" }, { name: "args" }],
184
+ variadic: true,
185
+ origin: "curated",
186
+ },
187
+ ], // curated: printf(FORMAT,...) - alias for format()
188
+ quote: [{ name: "quote", params: [{ name: "X" }], origin: "harvested" }], // lang_corefunc/30.txt
189
+ radians: [{ name: "radians", params: [{ name: "X" }], origin: "harvested" }], // lang_mathfunc/24.txt
190
+ random: [{ name: "random", params: [], origin: "harvested" }], // lang_corefunc/31.txt
191
+ randomblob: [{ name: "randomblob", params: [{ name: "N" }], origin: "harvested" }], // lang_corefunc/32.txt
192
+ rank: [{ name: "rank", params: [], origin: "harvested" }], // windowfunctions/2.txt
193
+ replace: [{ name: "replace", params: [{ name: "X" }, { name: "Y" }, { name: "Z" }], origin: "harvested" }], // lang_corefunc/33.txt
194
+ round: [{ name: "round", params: [{ name: "X" }, { name: "Y", optional: true }], origin: "harvested" }], // lang_corefunc/35.txt
195
+ row_number: [{ name: "row_number", params: [], origin: "harvested" }], // windowfunctions/1.txt
196
+ rtrim: [{ name: "rtrim", params: [{ name: "X" }, { name: "Y", optional: true }], origin: "harvested" }], // lang_corefunc/37.txt
197
+ sign: [{ name: "sign", params: [{ name: "X" }], origin: "harvested" }], // lang_corefunc/38.txt
198
+ sin: [{ name: "sin", params: [{ name: "X" }], origin: "harvested" }], // lang_mathfunc/25.txt
199
+ sinh: [{ name: "sinh", params: [{ name: "X" }], origin: "harvested" }], // lang_mathfunc/26.txt
200
+ soundex: [{ name: "soundex", params: [{ name: "X" }], origin: "harvested" }], // lang_corefunc/39.txt
201
+ sqlite_compileoption_get: [{ name: "sqlite_compileoption_get", params: [{ name: "N" }], origin: "harvested" }], // lang_corefunc/40.txt
202
+ sqlite_compileoption_used: [{ name: "sqlite_compileoption_used", params: [{ name: "X" }], origin: "harvested" }], // lang_corefunc/41.txt
203
+ sqlite_offset: [{ name: "sqlite_offset", params: [{ name: "X" }], origin: "harvested" }], // lang_corefunc/42.txt
204
+ sqlite_source_id: [{ name: "sqlite_source_id", params: [], origin: "harvested" }], // lang_corefunc/43.txt
205
+ sqlite_version: [{ name: "sqlite_version", params: [], origin: "harvested" }], // lang_corefunc/44.txt
206
+ sqrt: [{ name: "sqrt", params: [{ name: "X" }], origin: "harvested" }], // lang_mathfunc/27.txt
207
+ strftime: [
208
+ {
209
+ name: "strftime",
210
+ params: [
211
+ { name: "format", type: "text" },
212
+ { name: "time_value", type: "text" },
213
+ { name: "modifier", type: "text" },
214
+ ],
215
+ variadic: true,
216
+ origin: "curated",
217
+ },
218
+ ], // curated: strftime(format, time-value, modifier, ...)
219
+ string_agg: [{ name: "string_agg", params: [{ name: "X" }, { name: "Y" }], origin: "harvested" }], // lang_aggfunc/12.txt
220
+ substr: [
221
+ { name: "substr", params: [{ name: "X" }, { name: "Y" }, { name: "Z", optional: true }], origin: "harvested" },
222
+ ], // lang_corefunc/46.txt
223
+ substring: [
224
+ {
225
+ name: "substring",
226
+ params: [{ name: "X" }, { name: "Y" }, { name: "Z", optional: true }],
227
+ origin: "harvested",
228
+ },
229
+ ], // lang_corefunc/48.txt
230
+ sum: [{ name: "sum", params: [{ name: "X" }], origin: "harvested" }], // lang_aggfunc/13.txt
231
+ tan: [{ name: "tan", params: [{ name: "X" }], origin: "harvested" }], // lang_mathfunc/28.txt
232
+ tanh: [{ name: "tanh", params: [{ name: "X" }], origin: "harvested" }], // lang_mathfunc/29.txt
233
+ time: [
234
+ {
235
+ name: "time",
236
+ params: [
237
+ { name: "time_value", type: "text" },
238
+ { name: "modifier", type: "text" },
239
+ ],
240
+ variadic: true,
241
+ origin: "curated",
242
+ },
243
+ ], // curated: time(time-value, modifier, ...)
244
+ timediff: [
245
+ {
246
+ name: "timediff",
247
+ params: [
248
+ { name: "time_value_1", type: "text" },
249
+ { name: "time_value_2", type: "text" },
250
+ ],
251
+ origin: "curated",
252
+ },
253
+ ], // curated: timediff(time-value-1, time-value-2)
254
+ total: [{ name: "total", params: [{ name: "X" }], origin: "harvested" }], // lang_aggfunc/14.txt
255
+ total_changes: [{ name: "total_changes", params: [], origin: "harvested" }], // lang_corefunc/49.txt
256
+ trim: [{ name: "trim", params: [{ name: "X" }, { name: "Y", optional: true }], origin: "harvested" }], // lang_corefunc/51.txt
257
+ trunc: [{ name: "trunc", params: [{ name: "X" }], origin: "harvested" }], // lang_mathfunc/30.txt
258
+ typeof: [{ name: "typeof", params: [{ name: "X" }], origin: "harvested" }], // lang_corefunc/52.txt
259
+ unhex: [{ name: "unhex", params: [{ name: "X" }, { name: "Y", optional: true }], origin: "harvested" }], // lang_corefunc/54.txt
260
+ unicode: [{ name: "unicode", params: [{ name: "X" }], origin: "harvested" }], // lang_corefunc/55.txt
261
+ unistr: [{ name: "unistr", params: [{ name: "X" }], origin: "harvested" }], // lang_corefunc/56.txt
262
+ unistr_quote: [{ name: "unistr_quote", params: [{ name: "X" }], origin: "harvested" }], // lang_corefunc/57.txt
263
+ unixepoch: [
264
+ {
265
+ name: "unixepoch",
266
+ params: [
267
+ { name: "time_value", type: "text" },
268
+ { name: "modifier", type: "text" },
269
+ ],
270
+ variadic: true,
271
+ origin: "curated",
272
+ },
273
+ ], // curated: unixepoch(time-value, modifier, ...)
274
+ unlikely: [{ name: "unlikely", params: [{ name: "X" }], origin: "harvested" }], // lang_corefunc/58.txt
275
+ upper: [{ name: "upper", params: [{ name: "X" }], origin: "harvested" }], // lang_corefunc/59.txt
276
+ zeroblob: [{ name: "zeroblob", params: [{ name: "N" }], origin: "harvested" }], // lang_corefunc/60.txt
277
+ };
@@ -1,4 +1,5 @@
1
- import { displayName, foldIdentifier } from "../ident/fold.js";
1
+ import { behaviorOf } from "../dialect-behavior/carrier.js";
2
+ import { resolveBehavior } from "../dialect-behavior/registry.js";
2
3
  import { endPosition } from "../ir/span.js";
3
4
  import { inferType } from "../infer/infer.js";
4
5
  import { originsOf } from "../lineage/lineage.js";
@@ -39,7 +40,7 @@ function walk(scope, frame, out, schema, sourceSyms, expandStarOf) {
39
40
  // CTE declarations, and each CTE body as its own frame. The map key is the FOLDED identity;
40
41
  // the symbol (and frame label) shows the display form of the declared name.
41
42
  for (const [, cteRef] of scope.ctes) {
42
- const name = displayName(cteRef.def.name, scope.dialect);
43
+ const name = behaviorOf(scope).displayName(cteRef.def.name);
43
44
  out.push({
44
45
  kind: "cte",
45
46
  modifiers: ["declaration"],
@@ -81,7 +82,7 @@ function walk(scope, frame, out, schema, sourceSyms, expandStarOf) {
81
82
  if (alias)
82
83
  out.push(alias);
83
84
  if (src.kind === "subquery") {
84
- walk(src.scope, src.source.alias ? displayName(src.source.alias, scope.dialect) : "_subquery_", out, schema, sourceSyms, expandStarOf);
85
+ walk(src.scope, src.source.alias ? behaviorOf(scope).displayName(src.source.alias) : "_subquery_", out, schema, sourceSyms, expandStarOf);
85
86
  walked.add(src.scope);
86
87
  }
87
88
  else if (src.kind === "graphtable") {
@@ -219,12 +220,12 @@ function emitColumns(scope, frame, out, schema, sourceSyms, expandStarOf) {
219
220
  if (p.name === undefined)
220
221
  continue;
221
222
  const last = p.expr.kind === "column" ? p.expr.parts[p.expr.parts.length - 1] : undefined;
222
- const echo = last !== undefined && foldIdentifier(last, scope.dialect) === foldIdentifier(p.name, scope.dialect);
223
+ const echo = last !== undefined && behaviorOf(scope).fold(last) === behaviorOf(scope).fold(p.name);
223
224
  if (!echo) {
224
225
  out.push({
225
226
  kind: "column",
226
227
  modifiers: ["declaration", "output"],
227
- name: displayName(p.name, scope.dialect),
228
+ name: behaviorOf(scope).displayName(p.name),
228
229
  span: spanOf(p.aliasCst ?? p.cst),
229
230
  frame,
230
231
  type: typeOrUndefined(inferType(p.expr, scope, schema)),
@@ -252,7 +253,7 @@ function emitColumns(scope, frame, out, schema, sourceSyms, expandStarOf) {
252
253
  out.push({
253
254
  kind: "column",
254
255
  modifiers,
255
- name: ref.parts.map((p) => displayName(p, scope.dialect)).join("."),
256
+ name: ref.parts.map((p) => behaviorOf(scope).displayName(p)).join("."),
256
257
  span: spanOf(ref.cst),
257
258
  frame,
258
259
  definition: columnDefinition(res),
@@ -351,7 +352,7 @@ function aliasSymbol(src, frame, dialect) {
351
352
  ? {
352
353
  kind: "alias",
353
354
  modifiers: ["declaration"],
354
- name: displayName(src.source.alias, dialect),
355
+ name: resolveBehavior(dialect).displayName(src.source.alias),
355
356
  span: spanOf(src.source.aliasCst ?? src.source.cst),
356
357
  frame,
357
358
  }
@@ -363,7 +364,7 @@ function aliasSymbol(src, frame, dialect) {
363
364
  return {
364
365
  kind: "alias",
365
366
  modifiers: ["declaration"],
366
- name: displayName(s.alias, dialect),
367
+ name: resolveBehavior(dialect).displayName(s.alias),
367
368
  span: spanOf(s.aliasCst ?? s.cst),
368
369
  frame,
369
370
  };
@@ -388,20 +389,21 @@ function projectionSpan(scope, column, aliases) {
388
389
  if (scope.body.kind !== "select")
389
390
  return undefined;
390
391
  const projs = scope.body.projections;
391
- const c = foldIdentifier(column, scope.dialect);
392
+ const b = behaviorOf(scope);
393
+ const c = b.fold(column);
392
394
  let p;
393
395
  if (aliases) {
394
- const i = aliases.findIndex((a) => foldIdentifier(a, scope.dialect) === c);
396
+ const i = aliases.findIndex((a) => b.fold(a) === c);
395
397
  p = i >= 0 ? projs[i] : undefined;
396
398
  }
397
399
  else {
398
- p = projs.find((pp) => pp.name !== undefined && foldIdentifier(pp.name, scope.dialect) === c);
400
+ p = projs.find((pp) => pp.name !== undefined && b.fold(pp.name) === c);
399
401
  }
400
402
  return p ? spanOf(p.aliasCst ?? p.cst) : undefined;
401
403
  }
402
404
  function relationSymbol(src, frame, dialect) {
403
405
  const ref = ["reference"];
404
- const show = (n) => displayName(n, dialect);
406
+ const show = (n) => resolveBehavior(dialect).displayName(n);
405
407
  // The implicit pipe-stage relation is skipped by the caller; handled here only for exhaustiveness.
406
408
  if (src.kind === "relation") {
407
409
  return { kind: "subquery", modifiers: ref, name: "", span: spanOf(src.scope.body.cst), frame };
@@ -0,0 +1,2 @@
1
+ import type { DialectBehavior } from "../dialect-behavior/behavior.js";
2
+ export declare const trinoBehavior: DialectBehavior;
@@ -0,0 +1,21 @@
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 { trinoLiteral, trinoParseType, TRINO_FUNCTION_RETURNS } from "./infer.js";
6
+ // Trino implicit coercion: no VARCHAR<->numeric, no bool<->numeric — trino does NOT implicitly coerce.
7
+ const STR_TO_NUM = false;
8
+ const BOOL_NUM = false;
9
+ export const trinoBehavior = {
10
+ fold,
11
+ displayName,
12
+ foldTableName,
13
+ matchesSourceKey,
14
+ likeMatch: (pattern, value) => likePatternToRegExp(pattern).test(value),
15
+ literal: trinoLiteral,
16
+ parseType: trinoParseType,
17
+ functions: TRINO_FUNCTION_RETURNS,
18
+ division: "integer",
19
+ signatures: SIGNATURES.trino,
20
+ accepts: (argType, paramText) => acceptsFor(trinoParseType, STR_TO_NUM, BOOL_NUM, argType, paramText),
21
+ };
@@ -0,0 +1,8 @@
1
+ import { type FoldRule, type IdentKind } from "../ident/fold.js";
2
+ export declare const TRINO_FOLD_RULE: FoldRule;
3
+ /** Fold an identifier to its Trino 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,39 @@
1
+ // Trino 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
+ // trino.io/docs/current/language/reserved.html — verified live: "Identifiers with other
5
+ // characters must be delimited with double quotes (\"). ... Escape a \" with another preceding
6
+ // double quote in a delimited identifier." and, blanket, "Identifiers are not treated as case
7
+ // sensitive" — no quoted/unquoted distinction is drawn, and no backtick delimiter is documented
8
+ // (adjusted from the originally proposed "backtick tolerated" — dropped, unconfirmed by the
9
+ // live page). The fold DIRECTION (lower here) is this module's choice, not vendor-documented —
10
+ // the live docs only commit to uniform case-insensitivity across quoted/unquoted, which lower-
11
+ // folding both forms reproduces; chosen for consistency with the other case-insensitive-quoted
12
+ // dialects (redshift/duckdb) and this module's undefined-dialect default. NOTE: Trino's own
13
+ // engine source is internally inconsistent with this blanket docs claim — trino-parser's
14
+ // Identifier.getCanonicalValue() canonicalizes unquoted to UPPER and preserves quoted verbatim
15
+ // (ANSI-style, would make quoted case-sensitive), while trino-main's Field field-matching does
16
+ // a blanket case-insensitive compare regardless of quoting. Encoding the documented behavior
17
+ // per this module's citation policy; flagged as a discrepancy, not resolved against a live
18
+ // engine.
19
+ import { displayWith, foldWith } from "../ident/fold.js";
20
+ const DOUBLE_QUOTE = ['"', '"'];
21
+ export const TRINO_FOLD_RULE = {
22
+ delimiters: [DOUBLE_QUOTE],
23
+ unquoted: "lower",
24
+ quoted: "lower",
25
+ };
26
+ /** Fold an identifier to its Trino identity key. */
27
+ export function fold(raw, kind = "other") {
28
+ return foldWith(TRINO_FOLD_RULE, raw, kind);
29
+ }
30
+ /** Presentation twin: strip delimiters, no case change. */
31
+ export function displayName(raw) {
32
+ return displayWith(TRINO_FOLD_RULE, raw);
33
+ }
34
+ export function foldTableName(parts) {
35
+ return parts.map((p) => fold(p, "table"));
36
+ }
37
+ export function matchesSourceKey(key, rawPart) {
38
+ return key === fold(rawPart) || key === fold(rawPart, "table");
39
+ }
@@ -0,0 +1,7 @@
1
+ import { lower } from "./lower.js";
2
+ import { parseTrino } from "./parse.js";
3
+ export declare const trino: {
4
+ parse: typeof parseTrino;
5
+ lower: typeof lower;
6
+ behavior: import("../dialect-behavior/behavior.js").DialectBehavior;
7
+ };
@@ -0,0 +1,10 @@
1
+ // The complete trino dialect module: parse + lower (front end) and behavior (semantic knowledge).
2
+ // The registry wires this; to understand everything sqllens does for trino, read this folder.
3
+ import { trinoBehavior } from "./behavior.js";
4
+ import { lower } from "./lower.js";
5
+ import { parseTrino } from "./parse.js";
6
+ export const trino = {
7
+ parse: parseTrino,
8
+ lower,
9
+ behavior: trinoBehavior,
10
+ };
@@ -1,5 +1,5 @@
1
- import { type Type } from "./types.js";
2
- import type { FnRule } from "./functions.js";
1
+ import { type Type } from "../infer/types.js";
2
+ import type { FnRule } from "../infer/functions.js";
3
3
  export declare const TRINO_ALIASES: Record<string, string>;
4
4
  export declare function trinoParseType(text: string): Type;
5
5
  /** Trino literal forms — language/types.html: integers are INTEGER/BIGINT by range (int here),
@@ -1,5 +1,6 @@
1
- import { parseType, scalar, UNKNOWN } from "./types.js";
2
- import { commonType } from "./coerce.js";
1
+ import { parseType, scalar, UNKNOWN } from "../infer/types.js";
2
+ import { commonType } from "../infer/coerce.js";
3
+ import { fold } from "./fold.js";
3
4
  // ---------------------------------------------------------------------------
4
5
  // Trino inference knowledge. Scalar-name aliases map Trino's type vocabulary onto the shared
5
6
  // canonical names (trino.io/docs/current/language/types.html); `/` on integers is INTEGER
@@ -29,7 +30,7 @@ export const TRINO_ALIASES = {
29
30
  tdigest: "binary",
30
31
  };
31
32
  export function trinoParseType(text) {
32
- return parseType(text, TRINO_ALIASES, "trino");
33
+ return parseType(text, TRINO_ALIASES, fold);
33
34
  }
34
35
  const S = scalar("string");
35
36
  const I = scalar("int");