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
@@ -1,731 +1,52 @@
1
1
  // ---------------------------------------------------------------------------
2
- // Curated per-dialect function-signature tables.
2
+ // Function-signature runtime — one generated table per dialect, each folding a curated override
3
+ // layer over the harvested doc-derived long tail at BUILD time (tools/harvest-signatures.mjs). There
4
+ // is no separate curated/harvested split left at runtime: SIGNATURES[dialect] is already the merged
5
+ // table, and each entry's `origin` field says which layer produced it.
3
6
  //
4
- // The inference registry (src/infer/dialect.ts: FnRule = (args) => Type) knows a
5
- // function's RETURN type but carries NO parameter metadata. Signature help needs
6
- // parameter NAMES and types, so this is new, separate data: a hand-authored set
7
- // of the high-frequency scalar / date / string / conversion / aggregate functions
8
- // a data engineer actually calls, with the exact parameter names + order pulled
9
- // from each dialect's official docs (cited per entry). It is intentionally bounded
10
- // (~20–40 per dialect, not the whole registry); the long tail degrades to a
11
- // name-only hint in signatureAt() (the uncurated fallback Niclas approved).
7
+ // A name maps to an ORDERED overload SET (readonly FnSignature[]), not a single shape: it is common
8
+ // for a builtin to be overloaded on argument type or arity (postgres lower(text) vs lower(anyrange),
9
+ // trino length(binary) vs length(string)), and the model represents that directly. A name with one
10
+ // documented shape is simply a one-element array; origin is uniform across one name's whole set (an
11
+ // override always replaces the entire set, never blends origins entry by entry).
12
12
  //
13
- // The arg ORDER differs per dialect — DATEADD is (datepart, number, date) in
14
- // T-SQL, (part, value, date) in Snowflake, (datepart, interval, date) in Redshift
15
- // — so each dialect's table is authored from its own docs, never copied across.
13
+ // The ten generated tables are committed at src/<dialect>/signatures.generated.ts, rebuilt by
14
+ // `node tools/harvest-signatures.mjs`, never hand-edited. The curated inputs that feed the merge
15
+ // live as plain data at tools/signature-overrides/<dialect>.mjs.
16
16
  //
17
17
  // Core module: pure data + types, no antlr, no LSP deps.
18
18
  // ---------------------------------------------------------------------------
19
- import { TSQL_HARVESTED } from "./generated/tsql.js";
20
- const p = (name, type) => (type === undefined ? { name } : { name, type });
21
- /** An OPTIONAL trailing parameter — same as `p`, but the arity checker treats it as omittable. */
22
- const o = (name, type) => type === undefined ? { name, optional: true } : { name, type, optional: true };
23
- // ---------------------------------------------------------------------------
24
- // Databricks (Spark SQL) — docs.databricks.com / spark.apache.org built-in
25
- // functions reference. Each entry cites the function's reference page name.
26
- // ---------------------------------------------------------------------------
27
- const DATABRICKS = {
28
- // date/time — Spark "Date and timestamp functions"
29
- // date_add/datediff carry a 2-arg (start_date, num_days) and a 3-arg unit form
30
- // (date_add(unit, value, expr)).
31
- date_add: { name: "date_add", params: [p("start_date", "date"), p("num_days", "int"), o("expr")] }, // date_add function
32
- date_sub: { name: "date_sub", params: [p("start_date", "date"), p("num_days", "int"), o("expr")] }, // date_sub function
33
- datediff: { name: "datediff", params: [p("endDate", "date"), p("startDate", "date"), o("endTs")] }, // datediff function
34
- date_trunc: { name: "date_trunc", params: [p("fmt", "string"), p("ts", "timestamp")] }, // date_trunc function
35
- trunc: { name: "trunc", params: [p("date", "date"), p("fmt", "string")] }, // trunc function
36
- to_date: { name: "to_date", params: [p("expr", "string"), o("fmt", "string")] }, // to_date function (fmt optional)
37
- to_timestamp: { name: "to_timestamp", params: [p("expr", "string"), o("fmt", "string")] }, // to_timestamp function (fmt optional)
38
- date_format: { name: "date_format", params: [p("expr", "date"), p("fmt", "string")] }, // date_format function
39
- add_months: { name: "add_months", params: [p("startDate", "date"), p("numMonths", "int")] }, // add_months function
40
- // string — Spark "String functions"
41
- concat: { name: "concat", params: [p("expr", "string")], variadic: true }, // concat function (variadic)
42
- concat_ws: { name: "concat_ws", params: [p("sep", "string"), p("expr", "string")], variadic: true }, // concat_ws function
43
- // len is optional (to end of string); substr's pos too (bare substr('hello') per fn-invocation ref).
44
- substring: { name: "substring", params: [p("str", "string"), p("pos", "int"), o("len", "int")] }, // substring function
45
- substr: { name: "substr", params: [p("str", "string"), o("pos", "int"), o("len", "int")] }, // substr function
46
- split: { name: "split", params: [p("str", "string"), p("regex", "string"), o("limit", "int")] }, // split function (limit optional)
47
- split_part: { name: "split_part", params: [p("str", "string"), p("delimiter", "string"), p("partNum", "int")] }, // split_part function
48
- replace: { name: "replace", params: [p("str", "string"), p("search", "string"), o("replace", "string")] }, // replace function (replace optional → '')
49
- trim: { name: "trim", params: [p("str", "string"), o("trimStr", "string")] }, // trim function (trimStr optional)
50
- lpad: { name: "lpad", params: [p("str", "string"), p("len", "int"), o("pad", "string")] }, // lpad function (pad optional)
51
- rpad: { name: "rpad", params: [p("str", "string"), p("len", "int"), o("pad", "string")] }, // rpad function (pad optional)
52
- regexp_replace: {
53
- name: "regexp_replace",
54
- params: [p("str", "string"), p("regexp", "string"), p("rep", "string"), o("position", "int")],
55
- }, // regexp_replace function
56
- regexp_extract: {
57
- name: "regexp_extract",
58
- params: [p("str", "string"), p("regexp", "string"), o("idx", "int")],
59
- }, // regexp_extract function (idx optional → 1)
60
- // conditional / null — Spark "Conditional functions"
61
- coalesce: { name: "coalesce", params: [p("expr")], variadic: true }, // coalesce function (variadic)
62
- nvl: { name: "nvl", params: [p("expr1"), p("expr2")] }, // nvl function
63
- nullif: { name: "nullif", params: [p("expr1"), p("expr2")] }, // nullif function
64
- if: { name: "if", params: [p("cond", "boolean"), p("ifTrue"), p("ifFalse")] }, // if function
65
- // numeric — Spark "Mathematical functions"
66
- round: { name: "round", params: [p("expr", "numeric"), o("targetScale", "int")] }, // round function (scale optional → 0)
67
- abs: { name: "abs", params: [p("expr", "numeric")] }, // abs function
68
- ceil: { name: "ceil", params: [p("expr", "numeric"), o("targetScale", "int")] }, // ceil function (scale optional)
69
- floor: { name: "floor", params: [p("expr", "numeric"), o("targetScale", "int")] }, // floor function (scale optional)
70
- power: { name: "power", params: [p("expr1", "double"), p("expr2", "double")] }, // power function
71
- mod: { name: "mod", params: [p("dividend", "numeric"), p("divisor", "numeric")] }, // mod function
72
- cast: { name: "cast", params: [p("expr"), p("type")] }, // cast function
73
- // aggregate — Spark "Aggregate functions"
74
- count: { name: "count", params: [p("expr")] }, // count aggregate
75
- sum: { name: "sum", params: [p("expr", "numeric")] }, // sum aggregate
76
- avg: { name: "avg", params: [p("expr", "numeric")] }, // avg aggregate
77
- min: { name: "min", params: [p("expr")] }, // min aggregate
78
- max: { name: "max", params: [p("expr")] }, // max aggregate
79
- };
80
- // ---------------------------------------------------------------------------
81
- // T-SQL (SQL Server) — learn.microsoft.com Transact-SQL function reference.
82
- // Cites the docs page per entry. Note DATEADD = (datepart, number, date).
83
- // ---------------------------------------------------------------------------
84
- const TSQL = {
85
- // date/time — "Date and Time Data Types and Functions"
86
- dateadd: { name: "DATEADD", params: [p("datepart"), p("number", "int"), p("date", "date")] }, // DATEADD (Transact-SQL)
87
- datediff: { name: "DATEDIFF", params: [p("datepart"), p("startdate", "date"), p("enddate", "date")] }, // DATEDIFF (Transact-SQL)
88
- datepart: { name: "DATEPART", params: [p("datepart"), p("date", "date")] }, // DATEPART (Transact-SQL)
89
- datename: { name: "DATENAME", params: [p("datepart"), p("date", "date")] }, // DATENAME (Transact-SQL)
90
- datefromparts: { name: "DATEFROMPARTS", params: [p("year", "int"), p("month", "int"), p("day", "int")] }, // DATEFROMPARTS (Transact-SQL)
91
- eomonth: { name: "EOMONTH", params: [p("start_date", "date"), p("month_to_add", "int")] }, // EOMONTH (Transact-SQL)
92
- // conversion — "CAST and CONVERT"
93
- convert: { name: "CONVERT", params: [p("data_type"), p("expression"), p("style", "int")] }, // CONVERT (Transact-SQL)
94
- cast: { name: "CAST", params: [p("expression"), p("data_type")] }, // CAST (Transact-SQL)
95
- try_convert: { name: "TRY_CONVERT", params: [p("data_type"), p("expression"), p("style", "int")] }, // TRY_CONVERT (Transact-SQL)
96
- // string — "String Functions"
97
- substring: { name: "SUBSTRING", params: [p("expression"), p("start", "int"), o("length", "int")] }, // SUBSTRING (Transact-SQL) (length optional in Fabric/newer)
98
- charindex: {
99
- name: "CHARINDEX",
100
- params: [p("expressionToFind"), p("expressionToSearch"), o("start_location", "int")],
101
- }, // CHARINDEX (Transact-SQL) (start_location optional)
102
- replace: { name: "REPLACE", params: [p("string_expression"), p("string_pattern"), p("string_replacement")] }, // REPLACE (Transact-SQL)
103
- left: { name: "LEFT", params: [p("character_expression"), p("integer_expression", "int")] }, // LEFT (Transact-SQL)
104
- right: { name: "RIGHT", params: [p("character_expression"), p("integer_expression", "int")] }, // RIGHT (Transact-SQL)
105
- concat: { name: "CONCAT", params: [p("string_value")], variadic: true }, // CONCAT (Transact-SQL) (variadic)
106
- concat_ws: { name: "CONCAT_WS", params: [p("separator"), p("argument")], variadic: true }, // CONCAT_WS (Transact-SQL)
107
- stuff: {
108
- name: "STUFF",
109
- params: [p("character_expression"), p("start", "int"), p("length", "int"), p("replaceWith_expression")],
110
- }, // STUFF (Transact-SQL)
111
- trim: { name: "TRIM", params: [p("string"), o("characters")] }, // TRIM (Transact-SQL) (characters optional)
112
- ltrim: { name: "LTRIM", params: [p("character_expression"), o("characters")] }, // LTRIM (Transact-SQL) (characters optional, 2022+)
113
- rtrim: { name: "RTRIM", params: [p("character_expression"), o("characters")] }, // RTRIM (Transact-SQL) (characters optional, 2022+)
114
- format: { name: "FORMAT", params: [p("value"), p("format"), o("culture")] }, // FORMAT (Transact-SQL) (culture optional)
115
- // conditional / null — "Logical Functions" / "NULLIF"
116
- isnull: { name: "ISNULL", params: [p("check_expression"), p("replacement_value")] }, // ISNULL (Transact-SQL)
117
- coalesce: { name: "COALESCE", params: [p("expression")], variadic: true }, // COALESCE (Transact-SQL) (variadic)
118
- nullif: { name: "NULLIF", params: [p("expression1"), p("expression2")] }, // NULLIF (Transact-SQL)
119
- iif: { name: "IIF", params: [p("boolean_expression", "boolean"), p("true_value"), p("false_value")] }, // IIF (Transact-SQL)
120
- // numeric — "Mathematical Functions"
121
- round: { name: "ROUND", params: [p("numeric_expression", "numeric"), p("length", "int"), o("function", "int")] }, // ROUND (Transact-SQL) (function optional)
122
- abs: { name: "ABS", params: [p("numeric_expression", "numeric")] }, // ABS (Transact-SQL)
123
- ceiling: { name: "CEILING", params: [p("numeric_expression", "numeric")] }, // CEILING (Transact-SQL)
124
- floor: { name: "FLOOR", params: [p("numeric_expression", "numeric")] }, // FLOOR (Transact-SQL)
125
- power: { name: "POWER", params: [p("float_expression", "float"), p("y")] }, // POWER (Transact-SQL)
126
- // aggregate — "Aggregate Functions"
127
- count: { name: "COUNT", params: [p("expression")] }, // COUNT (Transact-SQL)
128
- sum: { name: "SUM", params: [p("expression", "numeric")] }, // SUM (Transact-SQL)
129
- avg: { name: "AVG", params: [p("expression", "numeric")] }, // AVG (Transact-SQL)
130
- min: { name: "MIN", params: [p("expression")] }, // MIN (Transact-SQL)
131
- max: { name: "MAX", params: [p("expression")] }, // MAX (Transact-SQL)
132
- string_agg: { name: "STRING_AGG", params: [p("expression"), p("separator")] }, // STRING_AGG (Transact-SQL)
133
- };
134
- // ---------------------------------------------------------------------------
135
- // Snowflake — docs.snowflake.com SQL function reference. Cites the page per
136
- // entry. DATEADD = (date_or_time_part, value, date_or_time_expr).
137
- // ---------------------------------------------------------------------------
138
- const SNOWFLAKE = {
139
- // date/time
140
- dateadd: { name: "DATEADD", params: [p("date_or_time_part"), p("value", "integer"), p("date_or_time_expr")] }, // DATEADD
141
- datediff: { name: "DATEDIFF", params: [p("date_or_time_part"), p("date_or_time_expr1"), p("date_or_time_expr2")] }, // DATEDIFF
142
- date_part: { name: "DATE_PART", params: [p("date_or_time_part"), p("date_or_time_expr")] }, // DATE_PART
143
- date_trunc: { name: "DATE_TRUNC", params: [p("date_or_time_part"), p("date_or_time_expr")] }, // DATE_TRUNC
144
- to_date: { name: "TO_DATE", params: [p("expr"), o("format", "string")] }, // TO_DATE , DATE (format optional)
145
- to_timestamp: { name: "TO_TIMESTAMP", params: [p("expr"), o("format", "string")] }, // TO_TIMESTAMP (format optional)
146
- timestampadd: {
147
- name: "TIMESTAMPADD",
148
- params: [p("date_or_time_part"), p("value", "integer"), p("date_or_time_expr")],
149
- }, // TIMESTAMPADD
150
- last_day: { name: "LAST_DAY", params: [p("date_or_time_expr"), o("date_part")] }, // LAST_DAY (date_part optional)
151
- // string
152
- concat: { name: "CONCAT", params: [p("expr", "string")], variadic: true }, // CONCAT (variadic)
153
- concat_ws: { name: "CONCAT_WS", params: [p("separator", "string"), p("expr", "string")], variadic: true }, // CONCAT_WS
154
- substr: { name: "SUBSTR", params: [p("base_expr", "string"), p("start_pos", "integer"), o("length", "integer")] }, // SUBSTR , SUBSTRING (length optional)
155
- substring: {
156
- name: "SUBSTRING",
157
- params: [p("base_expr", "string"), p("start_pos", "integer"), o("length", "integer")],
158
- }, // SUBSTRING (length optional)
159
- split_part: {
160
- name: "SPLIT_PART",
161
- params: [p("string", "string"), p("delimiter", "string"), p("part_number", "integer")],
162
- }, // SPLIT_PART
163
- replace: { name: "REPLACE", params: [p("subject", "string"), p("pattern", "string"), o("replacement", "string")] }, // REPLACE (replacement optional → '')
164
- trim: { name: "TRIM", params: [p("expr", "string"), o("characters", "string")] }, // TRIM (characters optional)
165
- lpad: { name: "LPAD", params: [p("base", "string"), p("length", "integer"), o("pad", "string")] }, // LPAD (pad optional)
166
- rpad: { name: "RPAD", params: [p("base", "string"), p("length", "integer"), o("pad", "string")] }, // RPAD (pad optional)
167
- regexp_replace: {
168
- name: "REGEXP_REPLACE",
169
- // subject, pattern[, replacement, position, occurrence, parameters]
170
- params: [
171
- p("subject", "string"),
172
- p("pattern", "string"),
173
- o("replacement", "string"),
174
- o("position", "integer"),
175
- o("occurrence", "integer"),
176
- o("parameters", "string"),
177
- ],
178
- }, // REGEXP_REPLACE
179
- // conditional / null
180
- coalesce: { name: "COALESCE", params: [p("expr")], variadic: true }, // COALESCE (variadic)
181
- nvl: { name: "NVL", params: [p("expr1"), p("expr2")] }, // NVL
182
- ifnull: { name: "IFNULL", params: [p("expr1"), p("expr2")] }, // IFNULL
183
- nullif: { name: "NULLIF", params: [p("expr1"), p("expr2")] }, // NULLIF
184
- iff: { name: "IFF", params: [p("condition", "boolean"), p("expr1"), p("expr2")] }, // IFF
185
- decode: { name: "DECODE", params: [p("expr"), p("search"), p("result")], variadic: true }, // DECODE (variadic search/result)
186
- // numeric
187
- round: {
188
- name: "ROUND",
189
- params: [p("input_expr", "numeric"), o("scale_expr", "integer"), o("rounding_mode", "string")],
190
- }, // ROUND (scale + rounding_mode optional)
191
- abs: { name: "ABS", params: [p("expr", "numeric")] }, // ABS
192
- ceil: { name: "CEIL", params: [p("input_expr", "numeric"), o("scale_expr", "integer")] }, // CEIL (scale optional)
193
- floor: { name: "FLOOR", params: [p("input_expr", "numeric"), o("scale_expr", "integer")] }, // FLOOR (scale optional)
194
- power: { name: "POWER", params: [p("base", "numeric"), p("exponent", "numeric")] }, // POWER
195
- mod: { name: "MOD", params: [p("expr1", "numeric"), p("expr2", "numeric")] }, // MOD
196
- // aggregate
197
- count: { name: "COUNT", params: [p("expr")] }, // COUNT
198
- sum: { name: "SUM", params: [p("expr", "numeric")] }, // SUM
199
- avg: { name: "AVG", params: [p("expr", "numeric")] }, // AVG
200
- min: { name: "MIN", params: [p("expr")] }, // MIN
201
- max: { name: "MAX", params: [p("expr")] }, // MAX
202
- listagg: { name: "LISTAGG", params: [p("expr", "string"), p("delimiter", "string")] }, // LISTAGG
203
- };
204
- // ---------------------------------------------------------------------------
205
- // BigQuery (GoogleSQL) — cloud.google.com/bigquery/docs function reference.
206
- // Cites the page per entry. DATE_ADD = (date, INTERVAL int part) — modelled
207
- // here as (date_expression, interval) since the INTERVAL literal is one arg slot.
208
- // ---------------------------------------------------------------------------
209
- const BIGQUERY = {
210
- // date/time
211
- date_add: { name: "DATE_ADD", params: [p("date_expression", "DATE"), p("interval", "INTERVAL")] }, // DATE_ADD
212
- date_sub: { name: "DATE_SUB", params: [p("date_expression", "DATE"), p("interval", "INTERVAL")] }, // DATE_SUB
213
- date_diff: { name: "DATE_DIFF", params: [p("end_date", "DATE"), p("start_date", "DATE"), p("granularity")] }, // DATE_DIFF
214
- date_trunc: { name: "DATE_TRUNC", params: [p("date_expression", "DATE"), p("granularity")] }, // DATE_TRUNC
215
- timestamp_diff: {
216
- name: "TIMESTAMP_DIFF",
217
- params: [p("end_timestamp", "TIMESTAMP"), p("start_timestamp", "TIMESTAMP"), p("granularity")],
218
- }, // TIMESTAMP_DIFF
219
- parse_date: { name: "PARSE_DATE", params: [p("format_string", "STRING"), p("date_string", "STRING")] }, // PARSE_DATE
220
- format_date: { name: "FORMAT_DATE", params: [p("format_string", "STRING"), p("date_expr", "DATE")] }, // FORMAT_DATE
221
- // string
222
- concat: { name: "CONCAT", params: [p("value", "STRING")], variadic: true }, // CONCAT (variadic)
223
- substr: { name: "SUBSTR", params: [p("value", "STRING"), p("position", "INT64"), o("length", "INT64")] }, // SUBSTR (length optional)
224
- substring: { name: "SUBSTRING", params: [p("value", "STRING"), p("position", "INT64"), o("length", "INT64")] }, // SUBSTRING (length optional)
225
- split: { name: "SPLIT", params: [p("value", "STRING"), o("delimiter", "STRING")] }, // SPLIT (delimiter optional → comma)
226
- replace: {
227
- name: "REPLACE",
228
- params: [p("original_value", "STRING"), p("from_pattern", "STRING"), p("to_value", "STRING")],
229
- }, // REPLACE
230
- trim: { name: "TRIM", params: [p("value", "STRING"), o("chars_to_trim", "STRING")] }, // TRIM (chars optional)
231
- lpad: {
232
- name: "LPAD",
233
- params: [p("original_value", "STRING"), p("return_length", "INT64"), p("pattern", "STRING")],
234
- }, // LPAD
235
- rpad: {
236
- name: "RPAD",
237
- params: [p("original_value", "STRING"), p("return_length", "INT64"), p("pattern", "STRING")],
238
- }, // RPAD
239
- regexp_replace: {
240
- name: "REGEXP_REPLACE",
241
- params: [p("value", "STRING"), p("regexp", "STRING"), p("replacement", "STRING")],
242
- }, // REGEXP_REPLACE
243
- regexp_extract: { name: "REGEXP_EXTRACT", params: [p("value", "STRING"), p("regexp", "STRING")] }, // REGEXP_EXTRACT
244
- // conditional / null
245
- coalesce: { name: "COALESCE", params: [p("expr")], variadic: true }, // COALESCE (variadic)
246
- ifnull: { name: "IFNULL", params: [p("expr"), p("null_result")] }, // IFNULL
247
- nullif: { name: "NULLIF", params: [p("expr"), p("expr_to_match")] }, // NULLIF
248
- if: { name: "IF", params: [p("expr", "BOOL"), p("true_result"), p("else_result")] }, // IF
249
- safe_cast: { name: "SAFE_CAST", params: [p("expression"), p("typename")] }, // SAFE_CAST
250
- cast: { name: "CAST", params: [p("expression"), p("typename")] }, // CAST
251
- // numeric
252
- round: { name: "ROUND", params: [p("X", "FLOAT64"), o("N", "INT64"), o("rounding_mode")] }, // ROUND (N + rounding_mode optional)
253
- abs: { name: "ABS", params: [p("X", "numeric")] }, // ABS
254
- ceil: { name: "CEIL", params: [p("X", "FLOAT64")] }, // CEIL
255
- floor: { name: "FLOOR", params: [p("X", "FLOAT64")] }, // FLOOR
256
- power: { name: "POWER", params: [p("X", "FLOAT64"), p("Y", "FLOAT64")] }, // POWER
257
- mod: { name: "MOD", params: [p("X", "INT64"), p("Y", "INT64")] }, // MOD
258
- // aggregate
259
- count: { name: "COUNT", params: [p("expression")] }, // COUNT
260
- sum: { name: "SUM", params: [p("expression", "numeric")] }, // SUM
261
- avg: { name: "AVG", params: [p("expression", "numeric")] }, // AVG
262
- min: { name: "MIN", params: [p("expression")] }, // MIN
263
- max: { name: "MAX", params: [p("expression")] }, // MAX
264
- array_agg: { name: "ARRAY_AGG", params: [p("expression")] }, // ARRAY_AGG
265
- string_agg: { name: "STRING_AGG", params: [p("expression", "STRING"), p("delimiter", "STRING")] }, // STRING_AGG
266
- };
267
- // ---------------------------------------------------------------------------
268
- // Redshift — docs.aws.amazon.com/redshift SQL functions reference. Cites the
269
- // page per entry. DATEADD = (datepart, interval, date).
270
- // ---------------------------------------------------------------------------
271
- const REDSHIFT = {
272
- // date/time
273
- dateadd: { name: "DATEADD", params: [p("datepart"), p("interval", "integer"), p("date", "date")] }, // DATEADD function
274
- datediff: { name: "DATEDIFF", params: [p("datepart"), p("startdate", "date"), p("enddate", "date")] }, // DATEDIFF function
275
- date_part: { name: "DATE_PART", params: [p("datepart"), p("timestamp", "timestamp")] }, // DATE_PART function
276
- date_trunc: { name: "DATE_TRUNC", params: [p("datepart"), p("timestamp", "timestamp")] }, // DATE_TRUNC function
277
- to_date: { name: "TO_DATE", params: [p("string", "string"), p("format", "string"), o("is_strict", "boolean")] }, // TO_DATE function (is_strict optional)
278
- to_timestamp: {
279
- name: "TO_TIMESTAMP",
280
- params: [p("timestamp", "string"), p("format", "string"), o("is_strict", "boolean")],
281
- }, // TO_TIMESTAMP function (is_strict optional)
282
- // string
283
- concat: { name: "CONCAT", params: [p("string1", "string"), p("string2", "string")] }, // CONCAT function (binary)
284
- substring: {
285
- name: "SUBSTRING",
286
- params: [p("string", "string"), p("start_position", "integer"), o("number_characters", "integer")],
287
- }, // SUBSTRING function (number_characters optional)
288
- split_part: { name: "SPLIT_PART", params: [p("string", "string"), p("delimiter", "string"), p("part", "integer")] }, // SPLIT_PART function
289
- replace: { name: "REPLACE", params: [p("string", "string"), p("old_chars", "string"), p("new_chars", "string")] }, // REPLACE function
290
- trim: { name: "TRIM", params: [p("string", "string")] }, // TRIM function
291
- lpad: { name: "LPAD", params: [p("string", "string"), p("length", "integer"), o("pad", "string")] }, // LPAD function (pad optional)
292
- rpad: { name: "RPAD", params: [p("string", "string"), p("length", "integer"), o("pad", "string")] }, // RPAD function (pad optional)
293
- regexp_replace: {
294
- name: "REGEXP_REPLACE",
295
- // source_string, pattern[, replace_string, position, parameters]
296
- params: [
297
- p("source_string", "string"),
298
- p("pattern", "string"),
299
- o("replace_string", "string"),
300
- o("position", "integer"),
301
- o("parameters", "string"),
302
- ],
303
- }, // REGEXP_REPLACE function
304
- // conditional / null
305
- coalesce: { name: "COALESCE", params: [p("expression")], variadic: true }, // COALESCE / NVL (variadic)
306
- nvl: { name: "NVL", params: [p("expression")], variadic: true }, // NVL function (variadic)
307
- nvl2: { name: "NVL2", params: [p("expression"), p("not_null_return_value"), p("null_return_value")] }, // NVL2 function
308
- nullif: { name: "NULLIF", params: [p("expression1"), p("expression2")] }, // NULLIF function
309
- decode: { name: "DECODE", params: [p("expression"), p("search"), p("result")], variadic: true }, // DECODE expression (variadic)
310
- // numeric
311
- round: { name: "ROUND", params: [p("number", "numeric"), o("integer", "integer")] }, // ROUND function (integer optional → 0)
312
- abs: { name: "ABS", params: [p("number", "numeric")] }, // ABS function
313
- ceiling: { name: "CEILING", params: [p("number", "numeric")] }, // CEILING / CEIL function
314
- floor: { name: "FLOOR", params: [p("number", "numeric")] }, // FLOOR function
315
- power: { name: "POWER", params: [p("base", "numeric"), p("exponent", "numeric")] }, // POWER function
316
- mod: { name: "MOD", params: [p("number1", "numeric"), p("number2", "numeric")] }, // MOD function
317
- // aggregate
318
- count: { name: "COUNT", params: [p("expression")] }, // COUNT function
319
- sum: { name: "SUM", params: [p("expression", "numeric")] }, // SUM function
320
- avg: { name: "AVG", params: [p("expression", "numeric")] }, // AVG function
321
- min: { name: "MIN", params: [p("expression")] }, // MIN function
322
- max: { name: "MAX", params: [p("expression")] }, // MAX function
323
- listagg: { name: "LISTAGG", params: [p("aggregate_expression", "string"), p("delimiter", "string")] }, // LISTAGG function
324
- };
325
- // ---------------------------------------------------------------------------
326
- // PostgreSQL — postgresql.org/docs/18 function reference; cites the doc page/table per entry.
327
- // ---------------------------------------------------------------------------
328
- const POSTGRES = {
329
- // date/time — functions-datetime.html (Table 9.33)
330
- age: { name: "age", params: [p("timestamp", "timestamp"), p("timestamp2", "timestamp")] }, // age(timestamp, timestamp)
331
- date_trunc: { name: "date_trunc", params: [p("field", "text"), p("source", "timestamp")] }, // date_trunc(field, source)
332
- date_part: { name: "date_part", params: [p("field", "text"), p("source", "timestamp")] }, // date_part(field, source)
333
- date_bin: {
334
- name: "date_bin",
335
- params: [p("stride", "interval"), p("source", "timestamp"), p("origin", "timestamp")],
336
- }, // date_bin(stride, source, origin)
337
- make_date: { name: "make_date", params: [p("year", "int"), p("month", "int"), p("day", "int")] }, // make_date(year, month, day)
338
- make_interval: {
339
- name: "make_interval",
340
- params: [p("years", "int"), p("months", "int"), p("weeks", "int"), p("days", "int")],
341
- }, // make_interval(years, months, …)
342
- to_date: { name: "to_date", params: [p("text", "text"), p("format", "text")] }, // to_date(text, format)
343
- to_timestamp: { name: "to_timestamp", params: [p("text", "text"), p("format", "text")] }, // to_timestamp(text, format)
344
- to_char: { name: "to_char", params: [p("value"), p("format", "text")] }, // to_char(value, format)
345
- to_number: { name: "to_number", params: [p("text", "text"), p("format", "text")] }, // to_number(text, format)
346
- // string — functions-string.html (Table 9.10)
347
- concat: { name: "concat", params: [p("val")], variadic: true }, // concat(val1, val2, …)
348
- concat_ws: { name: "concat_ws", params: [p("sep", "text"), p("val")], variadic: true }, // concat_ws(sep, val…)
349
- substring: { name: "substring", params: [p("string", "text"), p("start", "int"), p("count", "int")] }, // substring(string, start, count)
350
- substr: { name: "substr", params: [p("string", "text"), p("start", "int"), p("count", "int")] }, // substr(string, start, count)
351
- split_part: { name: "split_part", params: [p("string", "text"), p("delimiter", "text"), p("n", "int")] }, // split_part(string, delimiter, n)
352
- replace: { name: "replace", params: [p("string", "text"), p("from", "text"), p("to", "text")] }, // replace(string, from, to)
353
- regexp_replace: {
354
- name: "regexp_replace",
355
- params: [p("string", "text"), p("pattern", "text"), p("replacement", "text"), p("flags", "text")],
356
- }, // regexp_replace(string, pattern, replacement [, flags])
357
- regexp_match: { name: "regexp_match", params: [p("string", "text"), p("pattern", "text"), o("flags", "text")] }, // regexp_match(string, pattern [, flags])
358
- lpad: { name: "lpad", params: [p("string", "text"), p("length", "int"), p("fill", "text")] }, // lpad(string, length, fill)
359
- rpad: { name: "rpad", params: [p("string", "text"), p("length", "int"), p("fill", "text")] }, // rpad(string, length, fill)
360
- position: { name: "position", params: [p("substring", "text"), p("string", "text")] }, // position(substring in string)
361
- strpos: { name: "strpos", params: [p("string", "text"), p("substring", "text")] }, // strpos(string, substring)
362
- left: { name: "left", params: [p("string", "text"), p("n", "int")] }, // left(string, n)
363
- right: { name: "right", params: [p("string", "text"), p("n", "int")] }, // right(string, n)
364
- format: { name: "format", params: [p("formatstr", "text"), p("formatarg")], variadic: true }, // format(formatstr, formatarg…)
365
- string_to_array: {
366
- name: "string_to_array",
367
- params: [p("string", "text"), p("delimiter", "text"), p("null_string", "text")],
368
- }, // string_to_array(string, delimiter [, null_string])
369
- // numeric — functions-math.html (Table 9.5)
370
- round: { name: "round", params: [p("v", "numeric"), o("s", "int")] }, // round(v numeric [, s int])
371
- trunc: { name: "trunc", params: [p("v", "numeric"), o("s", "int")] }, // trunc(v numeric [, s int])
372
- abs: { name: "abs", params: [p("x", "numeric")] }, // abs(x)
373
- ceil: { name: "ceil", params: [p("x", "numeric")] }, // ceil(x)
374
- floor: { name: "floor", params: [p("x", "numeric")] }, // floor(x)
375
- power: { name: "power", params: [p("a", "numeric"), p("b", "numeric")] }, // power(a, b)
376
- mod: { name: "mod", params: [p("y", "numeric"), p("x", "numeric")] }, // mod(y, x)
377
- div: { name: "div", params: [p("y", "numeric"), p("x", "numeric")] }, // div(y, x)
378
- width_bucket: {
379
- name: "width_bucket",
380
- params: [p("operand", "numeric"), p("low", "numeric"), p("high", "numeric"), p("count", "int")],
381
- }, // width_bucket(operand, low, high, count)
382
- // conditional — functions-conditional.html
383
- coalesce: { name: "coalesce", params: [p("value")], variadic: true }, // COALESCE(value…)
384
- nullif: { name: "nullif", params: [p("value1"), p("value2")] }, // NULLIF(value1, value2)
385
- greatest: { name: "greatest", params: [p("value")], variadic: true }, // GREATEST(value…)
386
- least: { name: "least", params: [p("value")], variadic: true }, // LEAST(value…)
387
- // aggregates — functions-aggregate.html (Table 9.62)
388
- count: { name: "count", params: [p("expression")] }, // count(expression)
389
- sum: { name: "sum", params: [p("expression", "numeric")] }, // sum(expression)
390
- avg: { name: "avg", params: [p("expression", "numeric")] }, // avg(expression)
391
- min: { name: "min", params: [p("expression")] }, // min(expression)
392
- max: { name: "max", params: [p("expression")] }, // max(expression)
393
- string_agg: { name: "string_agg", params: [p("value", "text"), p("delimiter", "text")] }, // string_agg(value, delimiter)
394
- array_agg: { name: "array_agg", params: [p("expression")] }, // array_agg(expression)
395
- // JSON — functions-json.html
396
- jsonb_set: {
397
- name: "jsonb_set",
398
- params: [p("target", "jsonb"), p("path", "text[]"), p("new_value", "jsonb"), p("create_if_missing", "boolean")],
399
- }, // jsonb_set(target, path, new_value [, create_if_missing])
400
- jsonb_extract_path: {
401
- name: "jsonb_extract_path",
402
- params: [p("from_json", "jsonb"), p("path_elems", "text")],
403
- variadic: true,
404
- }, // jsonb_extract_path(from_json, VARIADIC path_elems)
405
- json_build_object: { name: "json_build_object", params: [p("arg")], variadic: true }, // json_build_object(VARIADIC args)
406
- };
407
- // ---------------------------------------------------------------------------
408
- // DuckDB — duckdb.org/docs/current/sql/functions reference; cites the page per entry.
409
- // ---------------------------------------------------------------------------
410
- const DUCKDB = {
411
- // date/time — functions/date.md, timestamp.md
412
- date_part: { name: "date_part", params: [p("part", "text"), p("date", "date")] }, // date_part(part, date)
413
- date_diff: { name: "date_diff", params: [p("part", "text"), p("startdate", "date"), p("enddate", "date")] }, // date_diff(part, startdate, enddate)
414
- date_add: { name: "date_add", params: [p("date", "date"), p("interval", "interval")] }, // date_add(date, interval)
415
- date_sub: { name: "date_sub", params: [p("part", "text"), p("startdate", "date"), p("enddate", "date")] }, // date_sub(part, startdate, enddate)
416
- date_trunc: { name: "date_trunc", params: [p("part", "text"), p("date", "date")] }, // date_trunc(part, date)
417
- strftime: { name: "strftime", params: [p("date", "date"), p("format", "text")] }, // strftime(date, format)
418
- strptime: { name: "strptime", params: [p("text", "text"), p("format", "text")] }, // strptime(text, format)
419
- make_date: { name: "make_date", params: [p("year", "bigint"), p("month", "bigint"), p("day", "bigint")] }, // make_date(year, month, day)
420
- time_bucket: {
421
- name: "time_bucket",
422
- params: [p("bucket_width", "interval"), p("timestamp", "timestamp"), p("offset", "interval")],
423
- }, // time_bucket(bucket_width, timestamp[, offset])
424
- // text — functions/text.md
425
- concat: { name: "concat", params: [p("value")], variadic: true }, // concat(value, ...)
426
- concat_ws: { name: "concat_ws", params: [p("separator", "text"), p("value")], variadic: true }, // concat_ws(separator, value, ...)
427
- substring: { name: "substring", params: [p("string", "text"), p("start", "int"), p("length", "int")] }, // substring(string, start, length)
428
- split_part: { name: "split_part", params: [p("string", "text"), p("separator", "text"), p("index", "int")] }, // split_part(string, separator, index)
429
- replace: { name: "replace", params: [p("string", "text"), p("source", "text"), p("target", "text")] }, // replace(string, source, target)
430
- regexp_replace: {
431
- name: "regexp_replace",
432
- params: [p("string", "text"), p("pattern", "text"), p("replacement", "text"), p("options", "text")],
433
- }, // regexp_replace(string, pattern, replacement[, options])
434
- regexp_extract: { name: "regexp_extract", params: [p("string", "text"), p("pattern", "text"), o("group", "int")] }, // regexp_extract(string, pattern[, group])
435
- regexp_matches: {
436
- name: "regexp_matches",
437
- params: [p("string", "text"), p("pattern", "text"), o("options", "text")],
438
- }, // regexp_matches(string, pattern[, options])
439
- lpad: { name: "lpad", params: [p("string", "text"), p("count", "int"), p("character", "text")] }, // lpad(string, count, character)
440
- rpad: { name: "rpad", params: [p("string", "text"), p("count", "int"), p("character", "text")] }, // rpad(string, count, character)
441
- left: { name: "left", params: [p("string", "text"), p("count", "int")] }, // left(string, count)
442
- right: { name: "right", params: [p("string", "text"), p("count", "int")] }, // right(string, count)
443
- contains: { name: "contains", params: [p("string", "text"), p("search_string", "text")] }, // contains(string, search_string)
444
- starts_with: { name: "starts_with", params: [p("string", "text"), p("search_string", "text")] }, // starts_with(string, search_string)
445
- printf: { name: "printf", params: [p("format", "text"), p("parameter")], variadic: true }, // printf(format, parameters...)
446
- format: { name: "format", params: [p("format", "text"), p("parameter")], variadic: true }, // format(format, parameters...)
447
- // numeric — functions/numeric.md
448
- round: { name: "round", params: [p("v", "numeric"), p("s", "int")] }, // round(v, s)
449
- trunc: { name: "trunc", params: [p("x", "numeric")] }, // trunc(x)
450
- abs: { name: "abs", params: [p("x", "numeric")] }, // abs(x)
451
- ceil: { name: "ceil", params: [p("x", "numeric")] }, // ceil(x)
452
- floor: { name: "floor", params: [p("x", "numeric")] }, // floor(x)
453
- power: { name: "power", params: [p("x", "numeric"), p("y", "numeric")] }, // power(x, y)
454
- // list — functions/list.md
455
- list_transform: { name: "list_transform", params: [p("list", "list"), p("lambda")] }, // list_transform(list, lambda)
456
- list_filter: { name: "list_filter", params: [p("list", "list"), p("lambda")] }, // list_filter(list, lambda)
457
- list_reduce: { name: "list_reduce", params: [p("list", "list"), p("lambda"), o("initial_value")] }, // list_reduce(list, lambda[, initial_value])
458
- list_extract: { name: "list_extract", params: [p("list", "list"), p("index", "int")] }, // list_extract(list, index)
459
- list_contains: { name: "list_contains", params: [p("list", "list"), p("element")] }, // list_contains(list, element)
460
- array_to_string: { name: "array_to_string", params: [p("list", "list"), p("delimiter", "text")] }, // array_to_string(list, delimiter)
461
- unnest: { name: "unnest", params: [p("list", "list")] }, // unnest(list)
462
- // conditional — functions/utility.md
463
- coalesce: { name: "coalesce", params: [p("expr")], variadic: true }, // coalesce(expr, ...)
464
- nullif: { name: "nullif", params: [p("a"), p("b")] }, // nullif(a, b)
465
- ifnull: { name: "ifnull", params: [p("expr"), p("other")] }, // ifnull(expr, other)
466
- if: { name: "if", params: [p("condition", "boolean"), p("a"), p("b")] }, // if(condition, a, b)
467
- // aggregates — functions/aggregates.md
468
- count: { name: "count", params: [p("arg")] }, // count(arg)
469
- sum: { name: "sum", params: [p("arg", "numeric")] }, // sum(arg)
470
- avg: { name: "avg", params: [p("arg", "numeric")] }, // avg(arg)
471
- min: { name: "min", params: [p("arg"), p("n", "int")] }, // min(arg[, n])
472
- max: { name: "max", params: [p("arg"), p("n", "int")] }, // max(arg[, n])
473
- arg_max: { name: "arg_max", params: [p("arg"), p("val"), p("n", "int")] }, // arg_max(arg, val[, n])
474
- arg_min: { name: "arg_min", params: [p("arg"), p("val"), p("n", "int")] }, // arg_min(arg, val[, n])
475
- string_agg: { name: "string_agg", params: [p("arg", "text"), p("sep", "text")] }, // string_agg(arg, sep)
476
- quantile_cont: { name: "quantile_cont", params: [p("x", "numeric"), p("pos", "double")] }, // quantile_cont(x, pos)
477
- };
478
- // ---------------------------------------------------------------------------
479
- // Trino — trino.io/docs/current/functions reference; cites the page per entry.
480
- // ---------------------------------------------------------------------------
481
- const TRINO = {
482
- // date/time — functions/datetime.html
483
- date_trunc: { name: "date_trunc", params: [p("unit", "varchar"), p("x", "timestamp")] }, // date_trunc(unit, x)
484
- date_add: { name: "date_add", params: [p("unit", "varchar"), p("value", "bigint"), p("timestamp", "timestamp")] }, // date_add(unit, value, timestamp)
485
- date_diff: {
486
- name: "date_diff",
487
- params: [p("unit", "varchar"), p("timestamp1", "timestamp"), p("timestamp2", "timestamp")],
488
- }, // date_diff(unit, timestamp1, timestamp2)
489
- date_format: { name: "date_format", params: [p("timestamp", "timestamp"), p("format", "varchar")] }, // date_format(timestamp, format)
490
- date_parse: { name: "date_parse", params: [p("string", "varchar"), p("format", "varchar")] }, // date_parse(string, format)
491
- from_unixtime: { name: "from_unixtime", params: [p("unixtime", "double"), p("zone", "varchar")] }, // from_unixtime(unixtime[, zone])
492
- at_timezone: { name: "at_timezone", params: [p("timestamp", "timestamp"), p("zone", "varchar")] }, // at_timezone(timestamp, zone)
493
- // string — functions/string.html
494
- substr: { name: "substr", params: [p("string", "varchar"), p("start", "bigint"), p("length", "bigint")] }, // substr(string, start[, length])
495
- split: { name: "split", params: [p("string", "varchar"), p("delimiter", "varchar"), o("limit", "bigint")] }, // split(string, delimiter[, limit])
496
- split_part: {
497
- name: "split_part",
498
- params: [p("string", "varchar"), p("delimiter", "varchar"), p("index", "bigint")],
499
- }, // split_part(string, delimiter, index)
500
- strpos: { name: "strpos", params: [p("string", "varchar"), p("substring", "varchar"), p("instance", "bigint")] }, // strpos(string, substring[, instance])
501
- replace: { name: "replace", params: [p("string", "varchar"), p("search", "varchar"), p("replace", "varchar")] }, // replace(string, search[, replace])
502
- lpad: { name: "lpad", params: [p("string", "varchar"), p("size", "bigint"), p("padstring", "varchar")] }, // lpad(string, size, padstring)
503
- rpad: { name: "rpad", params: [p("string", "varchar"), p("size", "bigint"), p("padstring", "varchar")] }, // rpad(string, size, padstring)
504
- concat_ws: { name: "concat_ws", params: [p("separator", "varchar"), p("strings", "varchar...")] }, // concat_ws(separator, ...)
505
- format: { name: "format", params: [p("format", "varchar"), p("args", "any")], variadic: true }, // format(format, args...)
506
- // regexp — functions/regexp.html
507
- regexp_like: { name: "regexp_like", params: [p("string", "varchar"), p("pattern", "varchar")] }, // regexp_like(string, pattern)
508
- regexp_extract: {
509
- name: "regexp_extract",
510
- params: [p("string", "varchar"), p("pattern", "varchar"), o("group", "bigint")],
511
- }, // regexp_extract(string, pattern[, group])
512
- regexp_replace: {
513
- name: "regexp_replace",
514
- params: [p("string", "varchar"), p("pattern", "varchar"), o("replacement", "varchar")],
515
- }, // regexp_replace(string, pattern[, replacement])
516
- // json — functions/json.html
517
- json_extract: { name: "json_extract", params: [p("json", "json"), p("json_path", "varchar")] }, // json_extract(json, json_path)
518
- json_extract_scalar: { name: "json_extract_scalar", params: [p("json", "json"), p("json_path", "varchar")] }, // json_extract_scalar(json, json_path)
519
- json_parse: { name: "json_parse", params: [p("string", "varchar")] }, // json_parse(string)
520
- // array — functions/array.html
521
- element_at: { name: "element_at", params: [p("collection", "array|map"), p("key", "any")] }, // element_at(x, key)
522
- array_join: {
523
- name: "array_join",
524
- params: [p("x", "array"), p("delimiter", "varchar"), o("null_replacement", "varchar")],
525
- }, // array_join(x, delimiter[, null_replacement])
526
- sequence: { name: "sequence", params: [p("start", "bigint"), p("stop", "bigint"), p("step", "bigint")] }, // sequence(start, stop[, step])
527
- transform: { name: "transform", params: [p("array", "array"), p("function", "lambda")] }, // transform(array, function) — functions/lambda.html
528
- reduce: {
529
- name: "reduce",
530
- params: [
531
- p("array", "array"),
532
- p("initialState", "any"),
533
- p("inputFunction", "lambda"),
534
- p("outputFunction", "lambda"),
535
- ],
536
- }, // reduce(array, s0, in, out)
537
- // aggregate — functions/aggregate.html
538
- count: { name: "count", params: [p("x", "any")] }, // count(x)
539
- sum: { name: "sum", params: [p("x", "numeric")] }, // sum(x)
540
- avg: { name: "avg", params: [p("x", "numeric")] }, // avg(x)
541
- min: { name: "min", params: [p("x", "any"), p("n", "bigint")] }, // min(x[, n])
542
- max: { name: "max", params: [p("x", "any"), p("n", "bigint")] }, // max(x[, n])
543
- max_by: { name: "max_by", params: [p("x", "any"), p("y", "any"), p("n", "bigint")] }, // max_by(x, y[, n])
544
- min_by: { name: "min_by", params: [p("x", "any"), p("y", "any"), p("n", "bigint")] }, // min_by(x, y[, n])
545
- approx_percentile: { name: "approx_percentile", params: [p("x", "numeric"), p("percentile", "double")] }, // approx_percentile(x, percentile)
546
- approx_distinct: { name: "approx_distinct", params: [p("x", "any"), p("e", "double")] }, // approx_distinct(x[, e])
547
- listagg: { name: "listagg", params: [p("expression", "varchar"), p("separator", "varchar")] }, // listagg(expr[, sep]) WITHIN GROUP
548
- // conditional — functions/conditional.html
549
- coalesce: { name: "coalesce", params: [p("value", "any")], variadic: true }, // coalesce(value1, value2, ...)
550
- nullif: { name: "nullif", params: [p("value1", "any"), p("value2", "any")] }, // nullif(value1, value2)
551
- if: { name: "if", params: [p("condition", "boolean"), p("true_value", "any"), p("false_value", "any")] }, // if(cond, t[, f])
552
- };
553
- // ---------------------------------------------------------------------------
554
- // SQLite — sqlite.org/lang_corefunc.html, lang_aggfunc.html, lang_datefunc.html,
555
- // lang_mathfunc.html; cites the page per entry. min()/max()/count()/sum()/total()/avg()/
556
- // group_concat() are always lowered with the `aggregate` flag set (src/sqlite/lower.ts's
557
- // AGGREGATES set is name-based, not arg-count-based), so the arity checker in
558
- // src/qualify/check-calls.ts never applies these signatures to a call — they exist here purely
559
- // for the signature-help hint. `log(X)` / `log(B,X)` is deliberately NOT curated: the two forms
560
- // disagree on argument ORDER, not just optional trailing count, and this table's ParamSig can't
561
- // express a leading-optional/reordered overload without asserting a wrong arity for one form.
562
- // ---------------------------------------------------------------------------
563
- const SQLITE = {
564
- // date/time — lang_datefunc.html (modifier repeats; each function's own doc page shows the
565
- // same "time-value, modifier, modifier, ..." shape)
566
- date: { name: "date", params: [p("time_value", "text"), p("modifier", "text")], variadic: true }, // date(time-value, modifier, ...)
567
- time: { name: "time", params: [p("time_value", "text"), p("modifier", "text")], variadic: true }, // time(time-value, modifier, ...)
568
- datetime: { name: "datetime", params: [p("time_value", "text"), p("modifier", "text")], variadic: true }, // datetime(time-value, modifier, ...)
569
- julianday: { name: "julianday", params: [p("time_value", "text"), p("modifier", "text")], variadic: true }, // julianday(time-value, modifier, ...)
570
- unixepoch: { name: "unixepoch", params: [p("time_value", "text"), p("modifier", "text")], variadic: true }, // unixepoch(time-value, modifier, ...)
571
- strftime: {
572
- name: "strftime",
573
- params: [p("format", "text"), p("time_value", "text"), p("modifier", "text")],
574
- variadic: true,
575
- }, // strftime(format, time-value, modifier, ...)
576
- timediff: { name: "timediff", params: [p("time_value_1", "text"), p("time_value_2", "text")] }, // timediff(time-value-1, time-value-2)
577
- // string — lang_corefunc.html
578
- substr: { name: "substr", params: [p("X", "text"), p("Y", "int"), o("Z", "int")] }, // substr(X,Y,Z) / substr(X,Y)
579
- replace: { name: "replace", params: [p("X", "text"), p("Y", "text"), p("Z", "text")] }, // replace(X,Y,Z)
580
- trim: { name: "trim", params: [p("X", "text"), o("Y", "text")] }, // trim(X,Y)
581
- ltrim: { name: "ltrim", params: [p("X", "text"), o("Y", "text")] }, // ltrim(X,Y)
582
- rtrim: { name: "rtrim", params: [p("X", "text"), o("Y", "text")] }, // rtrim(X,Y)
583
- instr: { name: "instr", params: [p("X", "text"), p("Y", "text")] }, // instr(X,Y)
584
- glob: { name: "glob", params: [p("pattern", "text"), p("string", "text")] }, // glob(X,Y) ("Y GLOB X")
585
- like: { name: "like", params: [p("pattern", "text"), p("string", "text"), o("escape", "text")] }, // like(X,Y[,Z]) ("Y LIKE X [ESCAPE Z]")
586
- printf: { name: "printf", params: [p("format", "text"), p("args")], variadic: true }, // printf(FORMAT,...) — alias for format()
587
- quote: { name: "quote", params: [p("X")] }, // quote(X)
588
- soundex: { name: "soundex", params: [p("X", "text")] }, // soundex(X)
589
- // numeric — lang_corefunc.html + lang_mathfunc.html
590
- round: { name: "round", params: [p("X", "numeric"), o("Y", "int")] }, // round(X,Y) / round(X)
591
- abs: { name: "abs", params: [p("X", "numeric")] }, // abs(X)
592
- sign: { name: "sign", params: [p("X", "numeric")] }, // sign(X)
593
- hex: { name: "hex", params: [p("X", "blob")] }, // hex(X)
594
- power: { name: "power", params: [p("X", "numeric"), p("Y", "numeric")] }, // power(X,Y) — lang_mathfunc.html
595
- sqrt: { name: "sqrt", params: [p("X", "numeric")] }, // sqrt(X) — lang_mathfunc.html
596
- mod: { name: "mod", params: [p("X", "numeric"), p("Y", "numeric")] }, // mod(X,Y) — lang_mathfunc.html
597
- pi: { name: "pi", params: [] }, // pi() — lang_mathfunc.html
598
- exp: { name: "exp", params: [p("X", "numeric")] }, // exp(X) — lang_mathfunc.html
599
- ln: { name: "ln", params: [p("X", "numeric")] }, // ln(X) — lang_mathfunc.html
600
- // conditional/null — lang_corefunc.html
601
- coalesce: { name: "coalesce", params: [p("X"), p("Y")], variadic: true }, // coalesce(X,Y,...) (SQLite requires >= 2 args)
602
- ifnull: { name: "ifnull", params: [p("X"), p("Y")] }, // ifnull(X,Y)
603
- nullif: { name: "nullif", params: [p("X"), p("Y")] }, // nullif(X,Y)
604
- iif: { name: "iif", params: [p("condition", "boolean"), p("true_value"), p("false_value")], variadic: true }, // iif(B1,V1,B2,V2,...,else)
605
- // aggregate — lang_aggfunc.html (see the module note: never arity-checked, name-based aggregate flag)
606
- count: { name: "count", params: [p("X")] }, // count(X) / count(*)
607
- sum: { name: "sum", params: [p("X", "numeric")] }, // sum(X)
608
- total: { name: "total", params: [p("X", "numeric")] }, // total(X)
609
- avg: { name: "avg", params: [p("X", "numeric")] }, // avg(X)
610
- min: { name: "min", params: [p("X")], variadic: true }, // min(X) aggregate / min(X,Y,...) scalar
611
- max: { name: "max", params: [p("X")], variadic: true }, // max(X) aggregate / max(X,Y,...) scalar
612
- group_concat: { name: "group_concat", params: [p("X", "text"), o("Y", "text")] }, // group_concat(X[,Y])
613
- };
614
- // ---------------------------------------------------------------------------
615
- // MySQL — dev.mysql.com/doc/refman/8.4/en/, cites the function-reference page per entry. TRIM is
616
- // deliberately NOT curated: MySQL's grammar gives it two structurally different shapes — a bare
617
- // `TRIM(str)` (1 arg, the ordinary function-call path) and the `TRIM([{BOTH|LEADING|TRAILING}]
618
- // [remstr] FROM str)` form (a dedicated grammar production) — the same leading-optional/reordered
619
- // shape SQLite's module note calls out for log() as un-curatable without asserting a wrong arity
620
- // for one form. DATE_ADD/DATE_SUB ARE curated: MySqlParser.g4's grammar folds their whole
621
- // `INTERVAL expr unit` operand into a single expression (a dedicated `intervalExpressionAtom`), so
622
- // the call is a genuine, arity-safe 2-argument form at the functionArgs level despite the multi-
623
- // word SQL surface syntax.
624
- // ---------------------------------------------------------------------------
625
- const MYSQL = {
626
- // string — string-functions.html
627
- concat: { name: "CONCAT", params: [p("str", "string")], variadic: true }, // CONCAT(str1,str2,...)
628
- concat_ws: { name: "CONCAT_WS", params: [p("separator", "string"), p("str", "string")], variadic: true }, // CONCAT_WS(separator,str1,str2,...)
629
- substring: { name: "SUBSTRING", params: [p("str", "string"), p("pos", "int"), o("len", "int")] }, // SUBSTRING(str,pos[,len])
630
- substr: { name: "SUBSTR", params: [p("str", "string"), p("pos", "int"), o("len", "int")] }, // SUBSTR(str,pos[,len]) — documented synonym of SUBSTRING
631
- left: { name: "LEFT", params: [p("str", "string"), p("len", "int")] }, // LEFT(str,len)
632
- right: { name: "RIGHT", params: [p("str", "string"), p("len", "int")] }, // RIGHT(str,len)
633
- lpad: { name: "LPAD", params: [p("str", "string"), p("len", "int"), p("padstr", "string")] }, // LPAD(str,len,padstr)
634
- rpad: { name: "RPAD", params: [p("str", "string"), p("len", "int"), p("padstr", "string")] }, // RPAD(str,len,padstr)
635
- replace: { name: "REPLACE", params: [p("str", "string"), p("from_str", "string"), p("to_str", "string")] }, // REPLACE(str,from_str,to_str)
636
- repeat: { name: "REPEAT", params: [p("str", "string"), p("count", "int")] }, // REPEAT(str,count)
637
- locate: { name: "LOCATE", params: [p("substr", "string"), p("str", "string"), o("pos", "int")] }, // LOCATE(substr,str[,pos])
638
- instr: { name: "INSTR", params: [p("str", "string"), p("substr", "string")] }, // INSTR(str,substr)
639
- substring_index: {
640
- name: "SUBSTRING_INDEX",
641
- params: [p("str", "string"), p("delim", "string"), p("count", "int")],
642
- }, // SUBSTRING_INDEX(str,delim,count)
643
- insert: { name: "INSERT", params: [p("str", "string"), p("pos", "int"), p("len", "int"), p("newstr", "string")] }, // INSERT(str,pos,len,newstr)
644
- strcmp: { name: "STRCMP", params: [p("str1", "string"), p("str2", "string")] }, // STRCMP(str1,str2)
645
- field: { name: "FIELD", params: [p("str", "string"), p("str1", "string")], variadic: true }, // FIELD(str,str1,str2,str3,...)
646
- format: { name: "FORMAT", params: [p("X", "numeric"), p("D", "int"), o("locale", "string")] }, // FORMAT(X,D[,locale])
647
- hex: { name: "HEX", params: [p("N_or_str")] }, // HEX(N) numeric form / HEX(str) string form — polymorphic
648
- // numeric — mathematical-functions.html
649
- round: { name: "ROUND", params: [p("X", "numeric"), o("D", "int")] }, // ROUND(X) / ROUND(X,D)
650
- truncate: { name: "TRUNCATE", params: [p("X", "numeric"), p("D", "int")] }, // TRUNCATE(X,D)
651
- mod: { name: "MOD", params: [p("N", "numeric"), p("M", "numeric")] }, // MOD(N,M)
652
- pow: { name: "POW", params: [p("X", "double"), p("Y", "double")] }, // POW(X,Y)
653
- power: { name: "POWER", params: [p("X", "double"), p("Y", "double")] }, // POWER(X,Y) — documented synonym of POW
654
- sqrt: { name: "SQRT", params: [p("X", "numeric")] }, // SQRT(X)
655
- ceiling: { name: "CEILING", params: [p("X", "numeric")] }, // CEILING(X)
656
- ceil: { name: "CEIL", params: [p("X", "numeric")] }, // CEIL(X) — documented synonym of CEILING
657
- floor: { name: "FLOOR", params: [p("X", "numeric")] }, // FLOOR(X)
658
- rand: { name: "RAND", params: [o("N", "int")] }, // RAND([N])
659
- sign: { name: "SIGN", params: [p("X", "numeric")] }, // SIGN(X)
660
- abs: { name: "ABS", params: [p("X", "numeric")] }, // ABS(X)
661
- // date/time — date-and-time-functions.html
662
- date_add: { name: "DATE_ADD", params: [p("date", "date"), p("expr", "interval")] }, // DATE_ADD(date, INTERVAL expr unit)
663
- date_sub: { name: "DATE_SUB", params: [p("date", "date"), p("expr", "interval")] }, // DATE_SUB(date, INTERVAL expr unit)
664
- datediff: { name: "DATEDIFF", params: [p("expr1", "date"), p("expr2", "date")] }, // DATEDIFF(expr1,expr2)
665
- date_format: { name: "DATE_FORMAT", params: [p("date", "date"), p("format", "string")] }, // DATE_FORMAT(date,format)
666
- str_to_date: { name: "STR_TO_DATE", params: [p("str", "string"), p("format", "string")] }, // STR_TO_DATE(str,format)
667
- // flow control — flow-control-functions.html
668
- if: { name: "IF", params: [p("expr1", "boolean"), p("expr2"), p("expr3")] }, // IF(expr1,expr2,expr3)
669
- ifnull: { name: "IFNULL", params: [p("expr1"), p("expr2")] }, // IFNULL(expr1,expr2)
670
- nullif: { name: "NULLIF", params: [p("expr1"), p("expr2")] }, // NULLIF(expr1,expr2)
671
- // comparison — comparison-operators.html
672
- coalesce: { name: "COALESCE", params: [p("value")], variadic: true }, // COALESCE(value,...)
673
- greatest: { name: "GREATEST", params: [p("value1"), p("value2")], variadic: true }, // GREATEST(value1,value2,...)
674
- least: { name: "LEAST", params: [p("value1"), p("value2")], variadic: true }, // LEAST(value1,value2,...)
675
- // conversion — cast-functions.html (both CAST and CONVERT lower to a `cast` IR node, not a
676
- // `function` call, in src/mysql/lower.ts — these entries exist purely for the signature-help
677
- // token-scan, never reach the arity checker)
678
- cast: { name: "CAST", params: [p("expr"), p("type")] }, // CAST(expr AS type)
679
- convert: { name: "CONVERT", params: [p("expr"), p("type")] }, // CONVERT(expr,type)
680
- // JSON — json-search-functions.html
681
- json_extract: { name: "JSON_EXTRACT", params: [p("json_doc", "json"), p("path", "string")], variadic: true }, // JSON_EXTRACT(json_doc,path[,path]...)
682
- json_contains: {
683
- name: "JSON_CONTAINS",
684
- params: [p("target", "json"), p("candidate", "json"), o("path", "string")],
685
- }, // JSON_CONTAINS(target,candidate[,path])
686
- json_keys: { name: "JSON_KEYS", params: [p("json_doc", "json"), o("path", "string")] }, // JSON_KEYS(json_doc[,path])
687
- };
688
- /** Curated parameter signatures, per dialect, keyed by LOWERCASED function name. */
689
- export const FUNCTION_SIGNATURES = {
690
- databricks: DATABRICKS,
691
- tsql: TSQL,
692
- snowflake: SNOWFLAKE,
693
- bigquery: BIGQUERY,
694
- redshift: REDSHIFT,
695
- postgres: POSTGRES,
696
- duckdb: DUCKDB,
697
- trino: TRINO,
698
- sqlite: SQLITE,
699
- mysql: MYSQL,
700
- };
701
- // ---------------------------------------------------------------------------
702
- // Harvested signatures — the LONG-TAIL layer under the curated table. Mined from each dialect's
703
- // reference-doc syntax blocks by tools/harvest-signatures.mjs into src/signature/generated/<dialect>.ts
704
- // (committed, rebuildable, never hand-edited). Only dialects with an offline syntax-block source in
705
- // the corpus repo have a generated table today (T-SQL); the rest map to an empty table and fall
706
- // through to the name-only hint. See the harvester's header for why.
707
- // ---------------------------------------------------------------------------
708
- /** Harvested parameter signatures, per dialect, keyed by LOWERCASED function name. */
709
- export const HARVESTED_SIGNATURES = {
710
- databricks: {},
711
- tsql: TSQL_HARVESTED,
712
- snowflake: {},
713
- bigquery: {},
714
- redshift: {},
715
- postgres: {},
716
- duckdb: {},
717
- trino: {},
718
- sqlite: {},
719
- mysql: {},
720
- };
721
- /**
722
- * The signature for a lowercased function name, honoring lookup order: curated (hand-verified) wins,
723
- * then harvested (doc-derived long tail), else undefined → the caller degrades to a name-only hint.
724
- */
19
+ import { DATABRICKS_SIGNATURES } from "../databricks/signatures.generated.js";
20
+ import { TSQL_SIGNATURES } from "../tsql/signatures.generated.js";
21
+ import { SNOWFLAKE_SIGNATURES } from "../snowflake/signatures.generated.js";
22
+ import { BIGQUERY_SIGNATURES } from "../bigquery/signatures.generated.js";
23
+ import { REDSHIFT_SIGNATURES } from "../redshift/signatures.generated.js";
24
+ import { POSTGRES_SIGNATURES } from "../postgres/signatures.generated.js";
25
+ import { DUCKDB_SIGNATURES } from "../duckdb/signatures.generated.js";
26
+ import { TRINO_SIGNATURES } from "../trino/signatures.generated.js";
27
+ import { SQLITE_SIGNATURES } from "../sqlite/signatures.generated.js";
28
+ import { MYSQL_SIGNATURES } from "../mysql/signatures.generated.js";
29
+ /** The merged function-signature table, per dialect, keyed by lowercased function name. Each name maps
30
+ * to an ordered overload SET, not a single shape. Each table is generated (curated overrides folded
31
+ * over the harvested long tail); see the module header. */
32
+ export const SIGNATURES = {
33
+ databricks: DATABRICKS_SIGNATURES,
34
+ tsql: TSQL_SIGNATURES,
35
+ snowflake: SNOWFLAKE_SIGNATURES,
36
+ bigquery: BIGQUERY_SIGNATURES,
37
+ redshift: REDSHIFT_SIGNATURES,
38
+ postgres: POSTGRES_SIGNATURES,
39
+ duckdb: DUCKDB_SIGNATURES,
40
+ trino: TRINO_SIGNATURES,
41
+ sqlite: SQLITE_SIGNATURES,
42
+ mysql: MYSQL_SIGNATURES,
43
+ };
44
+ /** The overload set for a lowercased function name, or undefined when neither layer knows it: the
45
+ * caller then degrades to a name-only hint. */
725
46
  export function lookupSignature(dialect, lowerName) {
726
- return FUNCTION_SIGNATURES[dialect][lowerName] ?? HARVESTED_SIGNATURES[dialect][lowerName];
47
+ return SIGNATURES[dialect][lowerName];
727
48
  }
728
- /** Whether either signature layer knows this lowercased name (membership check for functionName()). */
49
+ /** Whether the merged table knows this lowercased name (membership check for functionName()). */
729
50
  export function hasSignature(dialect, lowerName) {
730
- return lowerName in FUNCTION_SIGNATURES[dialect] || lowerName in HARVESTED_SIGNATURES[dialect];
51
+ return lowerName in SIGNATURES[dialect];
731
52
  }