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.
- package/README.md +2 -74
- package/THIRD-PARTY-NOTICES.md +50 -5
- package/dist/api.d.ts +5 -3
- package/dist/api.js +11 -4
- package/dist/bigquery/behavior.d.ts +2 -0
- package/dist/bigquery/behavior.js +20 -0
- package/dist/bigquery/dot-path.d.ts +0 -2
- package/dist/bigquery/dot-path.js +0 -1
- package/dist/bigquery/fold.d.ts +8 -0
- package/dist/bigquery/fold.js +39 -0
- package/dist/bigquery/index.d.ts +7 -0
- package/dist/bigquery/index.js +10 -0
- package/dist/{infer/bigquery.d.ts → bigquery/infer.d.ts} +2 -2
- package/dist/{infer/bigquery.js → bigquery/infer.js} +4 -3
- package/dist/bigquery/lower.js +35 -12
- package/dist/bigquery/signatures.generated.d.ts +6 -0
- package/dist/bigquery/signatures.generated.js +1068 -0
- package/dist/completion/atn-walk.d.ts +13 -2
- package/dist/completion/atn-walk.js +13 -10
- package/dist/completion/complete.d.ts +4 -3
- package/dist/completion/complete.js +101 -45
- package/dist/completion/jinja-slot.d.ts +24 -0
- package/dist/completion/jinja-slot.js +126 -0
- package/dist/completion/parser-factory.d.ts +13 -1
- package/dist/completion/parser-factory.js +12 -0
- package/dist/databricks/behavior.d.ts +2 -0
- package/dist/databricks/behavior.js +19 -0
- package/dist/databricks/fold.d.ts +8 -0
- package/dist/databricks/fold.js +27 -0
- package/dist/databricks/index.d.ts +7 -0
- package/dist/databricks/index.js +10 -0
- package/dist/databricks/infer.d.ts +6 -0
- package/dist/databricks/infer.js +638 -0
- package/dist/databricks/signatures.generated.d.ts +6 -0
- package/dist/databricks/signatures.generated.js +1745 -0
- package/dist/dialect-behavior/behavior.d.ts +26 -0
- package/dist/dialect-behavior/behavior.js +1 -0
- package/dist/dialect-behavior/carrier.d.ts +5 -0
- package/dist/dialect-behavior/carrier.js +5 -0
- package/dist/dialect-behavior/coerce-rules.d.ts +7 -0
- package/dist/dialect-behavior/coerce-rules.js +69 -0
- package/dist/dialect-behavior/public-fold.d.ts +6 -0
- package/dist/dialect-behavior/public-fold.js +9 -0
- package/dist/dialect-behavior/registry.d.ts +6 -0
- package/dist/dialect-behavior/registry.js +34 -0
- package/dist/dialect-symbols.js +16 -19
- package/dist/document/document.d.ts +1 -1
- package/dist/document/document.js +8 -7
- package/dist/duckdb/behavior.d.ts +2 -0
- package/dist/duckdb/behavior.js +21 -0
- package/dist/duckdb/fold.d.ts +8 -0
- package/dist/duckdb/fold.js +29 -0
- package/dist/duckdb/index.d.ts +7 -0
- package/dist/duckdb/index.js +10 -0
- package/dist/{infer/duckdb.d.ts → duckdb/infer.d.ts} +2 -2
- package/dist/{infer/duckdb.js → duckdb/infer.js} +4 -3
- package/dist/duckdb/lower.js +47 -15
- package/dist/duckdb/signatures.generated.d.ts +6 -0
- package/dist/duckdb/signatures.generated.js +1072 -0
- package/dist/generated/bigquery/GoogleSQLParser.js +0 -7060
- package/dist/generated/databricks/DatabricksParser.js +0 -4800
- package/dist/generated/duckdb/DuckdbParser.js +0 -9100
- package/dist/generated/minijinja/MinijinjaParser.js +0 -380
- package/dist/generated/mysql/MysqlParser.js +0 -6330
- package/dist/generated/postgres/PostgresParser.js +0 -8530
- package/dist/generated/redshift/RedshiftParser.js +0 -10970
- package/dist/generated/snowflake/SnowflakeParser.js +0 -7320
- package/dist/generated/sqlite/SqliteParser.js +0 -1150
- package/dist/generated/trino/TrinoParser.js +0 -3770
- package/dist/generated/tsql/TSqlParser.js +0 -8420
- package/dist/ident/fold.d.ts +24 -15
- package/dist/ident/fold.js +12 -194
- package/dist/index.d.ts +2 -2
- package/dist/index.js +10 -8
- package/dist/infer/functions.d.ts +22 -11
- package/dist/infer/functions.js +26 -888
- package/dist/infer/infer.js +16 -14
- package/dist/infer/nullability.js +3 -4
- package/dist/infer/types.d.ts +1 -1
- package/dist/infer/types.js +7 -7
- package/dist/ir/ir.d.ts +26 -17
- package/dist/ir/span.js +0 -2
- package/dist/ir/walk.js +3 -3
- package/dist/lineage/hops.js +13 -10
- package/dist/lineage/lineage.js +10 -7
- package/dist/minijinja/apply-tags.d.ts +14 -7
- package/dist/minijinja/apply-tags.js +66 -121
- package/dist/minijinja/parse.js +5 -5
- package/dist/minijinja/tag-ast.d.ts +29 -36
- package/dist/minijinja/tag-ast.js +210 -90
- package/dist/mysql/behavior.d.ts +2 -0
- package/dist/mysql/behavior.js +21 -0
- package/dist/mysql/fold.d.ts +8 -0
- package/dist/mysql/fold.js +49 -0
- package/dist/mysql/index.d.ts +7 -0
- package/dist/mysql/index.js +10 -0
- package/dist/{infer/mysql.d.ts → mysql/infer.d.ts} +2 -2
- package/dist/{infer/mysql.js → mysql/infer.js} +3 -2
- package/dist/mysql/signatures.generated.d.ts +6 -0
- package/dist/mysql/signatures.generated.js +508 -0
- package/dist/postgres/behavior.d.ts +2 -0
- package/dist/postgres/behavior.js +19 -0
- package/dist/postgres/fold.d.ts +8 -0
- package/dist/postgres/fold.js +30 -0
- package/dist/postgres/index.d.ts +7 -0
- package/dist/postgres/index.js +10 -0
- package/dist/{infer/postgres.d.ts → postgres/infer.d.ts} +2 -2
- package/dist/{infer/postgres.js → postgres/infer.js} +4 -3
- package/dist/postgres/lower.js +2 -2
- package/dist/postgres/signatures.generated.d.ts +6 -0
- package/dist/postgres/signatures.generated.js +2973 -0
- package/dist/qualify/check-calls.js +80 -161
- package/dist/qualify/qualify.js +16 -14
- package/dist/qualify/schema-provider.js +2 -2
- package/dist/qualify/schema.js +3 -3
- package/dist/qualify/template-provider.d.ts +45 -12
- package/dist/qualify/template-provider.js +69 -38
- package/dist/redshift/behavior.d.ts +2 -0
- package/dist/redshift/behavior.js +19 -0
- package/dist/redshift/fold.d.ts +8 -0
- package/dist/redshift/fold.js +31 -0
- package/dist/redshift/index.d.ts +7 -0
- package/dist/redshift/index.js +10 -0
- package/dist/{infer/redshift.d.ts → redshift/infer.d.ts} +2 -2
- package/dist/{infer/redshift.js → redshift/infer.js} +4 -3
- package/dist/redshift/lower.js +2 -2
- package/dist/redshift/signatures.generated.d.ts +6 -0
- package/dist/redshift/signatures.generated.js +757 -0
- package/dist/references/references.js +17 -12
- package/dist/scope/like-pattern.d.ts +2 -0
- package/dist/scope/like-pattern.js +15 -0
- package/dist/scope/scope.d.ts +5 -5
- package/dist/scope/scope.js +48 -42
- package/dist/sema/resolve.js +17 -12
- package/dist/session.d.ts +2 -2
- package/dist/signature/signature.d.ts +14 -6
- package/dist/signature/signature.js +30 -22
- package/dist/signature/signatures.d.ts +14 -12
- package/dist/signature/signatures.js +42 -721
- package/dist/snowflake/behavior.d.ts +2 -0
- package/dist/snowflake/behavior.js +22 -0
- package/dist/snowflake/fold.d.ts +8 -0
- package/dist/snowflake/fold.js +25 -0
- package/dist/snowflake/index.d.ts +7 -0
- package/dist/snowflake/index.js +10 -0
- package/dist/{infer/snowflake.d.ts → snowflake/infer.d.ts} +2 -2
- package/dist/{infer/snowflake.js → snowflake/infer.js} +4 -3
- package/dist/snowflake/lower.js +59 -19
- package/dist/snowflake/signatures.generated.d.ts +6 -0
- package/dist/snowflake/signatures.generated.js +2080 -0
- package/dist/sqlite/behavior.d.ts +2 -0
- package/dist/sqlite/behavior.js +19 -0
- package/dist/sqlite/fold.d.ts +8 -0
- package/dist/sqlite/fold.js +41 -0
- package/dist/sqlite/index.d.ts +7 -0
- package/dist/sqlite/index.js +10 -0
- package/dist/{infer/sqlite.d.ts → sqlite/infer.d.ts} +2 -2
- package/dist/{infer/sqlite.js → sqlite/infer.js} +4 -3
- package/dist/sqlite/signatures.generated.d.ts +6 -0
- package/dist/sqlite/signatures.generated.js +277 -0
- package/dist/symbols/symbols.js +14 -12
- package/dist/trino/behavior.d.ts +2 -0
- package/dist/trino/behavior.js +21 -0
- package/dist/trino/fold.d.ts +8 -0
- package/dist/trino/fold.js +39 -0
- package/dist/trino/index.d.ts +7 -0
- package/dist/trino/index.js +10 -0
- package/dist/{infer/trino.d.ts → trino/infer.d.ts} +2 -2
- package/dist/{infer/trino.js → trino/infer.js} +4 -3
- package/dist/trino/lower.js +5 -5
- package/dist/trino/signatures.generated.d.ts +6 -0
- package/dist/trino/signatures.generated.js +968 -0
- package/dist/tsql/behavior.d.ts +2 -0
- package/dist/tsql/behavior.js +20 -0
- package/dist/tsql/fold.d.ts +8 -0
- package/dist/tsql/fold.js +34 -0
- package/dist/tsql/index.d.ts +7 -0
- package/dist/tsql/index.js +10 -0
- package/dist/tsql/infer.d.ts +16 -0
- package/dist/tsql/infer.js +289 -0
- package/dist/tsql/lower.js +4 -4
- package/dist/tsql/signatures.generated.d.ts +6 -0
- package/dist/tsql/signatures.generated.js +640 -0
- package/package.json +5 -10
- package/dist/generated/bigquery/GoogleSQLLexer.d.ts +0 -407
- package/dist/generated/bigquery/GoogleSQLParser.d.ts +0 -9558
- package/dist/generated/bigquery/GoogleSQLParserListener.d.ts +0 -7777
- package/dist/generated/bigquery/GoogleSQLParserListener.js +0 -7070
- package/dist/generated/databricks/DatabricksLexer.d.ts +0 -566
- package/dist/generated/databricks/DatabricksParser.d.ts +0 -7771
- package/dist/generated/databricks/DatabricksParserListener.d.ts +0 -5737
- package/dist/generated/databricks/DatabricksParserListener.js +0 -5256
- package/dist/generated/duckdb/DuckdbLexer.d.ts +0 -691
- package/dist/generated/duckdb/DuckdbParser.d.ts +0 -13932
- package/dist/generated/duckdb/DuckdbParserListener.d.ts +0 -10049
- package/dist/generated/duckdb/DuckdbParserListener.js +0 -9138
- package/dist/generated/minijinja/MinijinjaLexer.d.ts +0 -108
- package/dist/generated/minijinja/MinijinjaParser.d.ts +0 -604
- package/dist/generated/minijinja/MinijinjaParserListener.d.ts +0 -449
- package/dist/generated/minijinja/MinijinjaParserListener.js +0 -410
- package/dist/generated/mysql/MysqlLexer.d.ts +0 -1198
- package/dist/generated/mysql/MysqlParser.d.ts +0 -10992
- package/dist/generated/mysql/MysqlParserListener.d.ts +0 -7592
- package/dist/generated/mysql/MysqlParserListener.js +0 -6958
- package/dist/generated/postgres/PostgresLexer.d.ts +0 -663
- package/dist/generated/postgres/PostgresParser.d.ts +0 -12963
- package/dist/generated/postgres/PostgresParserListener.d.ts +0 -9408
- package/dist/generated/postgres/PostgresParserListener.js +0 -8554
- package/dist/generated/redshift/RedshiftLexer.d.ts +0 -954
- package/dist/generated/redshift/RedshiftParser.d.ts +0 -16939
- package/dist/generated/redshift/RedshiftParserListener.d.ts +0 -12092
- package/dist/generated/redshift/RedshiftParserListener.js +0 -10994
- package/dist/generated/snowflake/SnowflakeLexer.d.ts +0 -1046
- package/dist/generated/snowflake/SnowflakeParser.d.ts +0 -14196
- package/dist/generated/snowflake/SnowflakeParserListener.d.ts +0 -8063
- package/dist/generated/snowflake/SnowflakeParserListener.js +0 -7330
- package/dist/generated/sqlite/SqliteLexer.d.ts +0 -210
- package/dist/generated/sqlite/SqliteParser.d.ts +0 -2115
- package/dist/generated/sqlite/SqliteParserListener.d.ts +0 -1276
- package/dist/generated/sqlite/SqliteParserListener.js +0 -1160
- package/dist/generated/trino/TrinoLexer.d.ts +0 -381
- package/dist/generated/trino/TrinoParser.d.ts +0 -5340
- package/dist/generated/trino/TrinoParserListener.d.ts +0 -4704
- package/dist/generated/trino/TrinoParserListener.js +0 -4326
- package/dist/generated/tsql/TSqlLexer.d.ts +0 -1278
- package/dist/generated/tsql/TSqlParser.d.ts +0 -17267
- package/dist/generated/tsql/TSqlParserListener.d.ts +0 -9697
- package/dist/generated/tsql/TSqlParserListener.js +0 -8854
- package/dist/infer/dialect.d.ts +0 -21
- package/dist/infer/dialect.js +0 -100
- package/dist/infer/literals.d.ts +0 -6
- package/dist/infer/literals.js +0 -44
- package/dist/signature/generated/tsql.d.ts +0 -3
- package/dist/signature/generated/tsql.js +0 -260
|
@@ -0,0 +1,22 @@
|
|
|
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 { snowflakeLiteral, snowflakeParseType, SNOWFLAKE_FUNCTION_RETURNS, snowflakeSpecial } from "./infer.js";
|
|
6
|
+
// Snowflake implicit coercion: VARCHAR containing a number coerces to NUMBER (str->num), no bool<->num.
|
|
7
|
+
const STR_TO_NUM = true;
|
|
8
|
+
const BOOL_NUM = false;
|
|
9
|
+
export const snowflakeBehavior = {
|
|
10
|
+
fold,
|
|
11
|
+
displayName,
|
|
12
|
+
foldTableName,
|
|
13
|
+
matchesSourceKey,
|
|
14
|
+
likeMatch: (pattern, value) => likePatternToRegExp(pattern).test(value),
|
|
15
|
+
literal: snowflakeLiteral,
|
|
16
|
+
parseType: snowflakeParseType,
|
|
17
|
+
functions: SNOWFLAKE_FUNCTION_RETURNS,
|
|
18
|
+
division: "decimal", // Snowflake: 10/3 -> 3.333333, a scaled NUMBER unless a float is involved
|
|
19
|
+
special: snowflakeSpecial,
|
|
20
|
+
signatures: SIGNATURES.snowflake,
|
|
21
|
+
accepts: (argType, paramText) => acceptsFor(snowflakeParseType, STR_TO_NUM, BOOL_NUM, argType, paramText),
|
|
22
|
+
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { type FoldRule, type IdentKind } from "../ident/fold.js";
|
|
2
|
+
export declare const SNOWFLAKE_FOLD_RULE: FoldRule;
|
|
3
|
+
/** Fold an identifier to its Snowflake 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,25 @@
|
|
|
1
|
+
// Snowflake 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). Snowflake unquoted identifiers fold to UPPER; quoted identifiers preserve case
|
|
4
|
+
// (docs.snowflake.com/en/sql-reference/identifiers-syntax); double-quote is the delimiter, doubled to escape.
|
|
5
|
+
import { displayWith, foldWith } from "../ident/fold.js";
|
|
6
|
+
const DOUBLE_QUOTE = ['"', '"'];
|
|
7
|
+
export const SNOWFLAKE_FOLD_RULE = {
|
|
8
|
+
delimiters: [DOUBLE_QUOTE],
|
|
9
|
+
unquoted: "upper",
|
|
10
|
+
quoted: "preserve",
|
|
11
|
+
};
|
|
12
|
+
/** Fold an identifier to its Snowflake identity key. */
|
|
13
|
+
export function fold(raw, kind = "other") {
|
|
14
|
+
return foldWith(SNOWFLAKE_FOLD_RULE, raw, kind);
|
|
15
|
+
}
|
|
16
|
+
/** Presentation twin: strip delimiters, no case change. */
|
|
17
|
+
export function displayName(raw) {
|
|
18
|
+
return displayWith(SNOWFLAKE_FOLD_RULE, raw);
|
|
19
|
+
}
|
|
20
|
+
export function foldTableName(parts) {
|
|
21
|
+
return parts.map((p) => fold(p, "table"));
|
|
22
|
+
}
|
|
23
|
+
export function matchesSourceKey(key, rawPart) {
|
|
24
|
+
return key === fold(rawPart) || key === fold(rawPart, "table");
|
|
25
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
// The complete snowflake dialect module: parse + lower (front end) and behavior (semantic knowledge).
|
|
2
|
+
// The registry wires this; to understand everything sqllens does for snowflake, read this folder.
|
|
3
|
+
import { snowflakeBehavior } from "./behavior.js";
|
|
4
|
+
import { lower } from "./lower.js";
|
|
5
|
+
import { parseSnowflake } from "./parse.js";
|
|
6
|
+
export const snowflake = {
|
|
7
|
+
parse: parseSnowflake,
|
|
8
|
+
lower,
|
|
9
|
+
behavior: snowflakeBehavior,
|
|
10
|
+
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Expr } from "../ir/ir.js";
|
|
2
|
-
import type { FnRule } from "
|
|
3
|
-
import { type Type } from "
|
|
2
|
+
import type { FnRule } from "../infer/functions.js";
|
|
3
|
+
import { type Type } from "../infer/types.js";
|
|
4
4
|
export declare const SNOWFLAKE_FUNCTION_RETURNS: Record<string, FnRule>;
|
|
5
5
|
/** Snowflake literal forms: '…' / $$…$$ → string; integers are NUMBER(38,0) (int
|
|
6
6
|
* canonically); non-integers are NUMBER (decimal); 1e3 is approximate (double). */
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { commonType, widenSum } from "
|
|
2
|
-
import { parseType, scalar, UNKNOWN } from "
|
|
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
|
// Snowflake inference knowledge — function return types, literal forms, and scalar-type
|
|
4
5
|
// aliases — from the SQL function reference (docs.snowflake.com/en/sql-reference/functions).
|
|
5
6
|
// Same contract as the other dialects: a rule is absent (→ unknown) only when the documented
|
|
@@ -557,7 +558,7 @@ export const SNOWFLAKE_ALIASES = {
|
|
|
557
558
|
bool: "boolean",
|
|
558
559
|
};
|
|
559
560
|
export function snowflakeParseType(text) {
|
|
560
|
-
return parseType(text, SNOWFLAKE_ALIASES,
|
|
561
|
+
return parseType(text, SNOWFLAKE_ALIASES, fold);
|
|
561
562
|
}
|
|
562
563
|
/** Pre-registry hook for calls a plain FnRule can't key. `<seq>.NEXTVAL` carries the sequence as a
|
|
563
564
|
* (variable) qualifier, so no registry key can enumerate it; NEXTVAL always returns NUMBER(38,0)
|
package/dist/snowflake/lower.js
CHANGED
|
@@ -3,7 +3,7 @@ import { SnowflakeParser as P } from "../generated/snowflake/SnowflakeParser.js"
|
|
|
3
3
|
import { keywordCategory, swallowedCategories, swallowedStatements } from "../ir/statement.js";
|
|
4
4
|
import { partSpansOf } from "../ir/part-span.js";
|
|
5
5
|
import { freezeIR } from "../ir/freeze.js";
|
|
6
|
-
import { displayName } from "
|
|
6
|
+
import { displayName } from "./fold.js";
|
|
7
7
|
// ---------------------------------------------------------------------------
|
|
8
8
|
// Lowering — Snowflake (grammars-v4 sql/snowflake fork) CST -> the shared,
|
|
9
9
|
// dialect-neutral IR (src/ir/ir.ts). The semantic layer runs on the IR
|
|
@@ -958,15 +958,16 @@ function lowerExpr(node) {
|
|
|
958
958
|
// expr ! method ( args ) — class-instance method call
|
|
959
959
|
if (hasDirectToken(node, P.BANG)) {
|
|
960
960
|
const method = directChildrenOfRule(node, P.RULE_id_)[0];
|
|
961
|
-
const
|
|
962
|
-
|
|
963
|
-
...directChildrenOfRule(node, P.RULE_param_assoc_list).flatMap(paramAssocValues),
|
|
964
|
-
];
|
|
961
|
+
const positional = exprListExprs(node).map(lowerExpr);
|
|
962
|
+
const paramAssoc = directChildrenOfRule(node, P.RULE_param_assoc_list).flatMap(paramAssocValues);
|
|
965
963
|
const base = exprs[0] ? lowerExpr(exprs[0]) : otherExpr(node);
|
|
964
|
+
const args = [base, ...positional, ...paramAssoc.map((v) => v.arg)];
|
|
965
|
+
const argNames = [undefined, ...positional.map(() => undefined), ...paramAssoc.map((v) => v.name)];
|
|
966
966
|
return {
|
|
967
967
|
kind: "function",
|
|
968
968
|
name: method ? method.getText() : "",
|
|
969
|
-
args
|
|
969
|
+
args,
|
|
970
|
+
...(argNames.some((n) => n !== undefined) ? { argNames } : {}),
|
|
970
971
|
aggregate: false,
|
|
971
972
|
distinct: false,
|
|
972
973
|
cst: node,
|
|
@@ -1236,7 +1237,7 @@ function lowerFunctionCall(node) {
|
|
|
1236
1237
|
const agg = directChildrenOfRule(node, P.RULE_aggregate_function)[0];
|
|
1237
1238
|
if (agg) {
|
|
1238
1239
|
const id = directChildrenOfRule(agg, P.RULE_id_)[0];
|
|
1239
|
-
const name = (id ? displayName(id.getText()
|
|
1240
|
+
const name = (id ? displayName(id.getText()) : (leftmostToken(agg) ?? "")).toLowerCase();
|
|
1240
1241
|
const args = [
|
|
1241
1242
|
...exprListExprs(agg).map(lowerExpr),
|
|
1242
1243
|
...directChildrenOfRule(agg, P.RULE_expr).map(lowerExpr),
|
|
@@ -1252,40 +1253,79 @@ function lowerFunctionCall(node) {
|
|
|
1252
1253
|
cst: node,
|
|
1253
1254
|
};
|
|
1254
1255
|
}
|
|
1256
|
+
// EXTRACT LR_BRACKET (id_ | string) (FROM | COMMA) expr RR_BRACKET: the date-part operand is an
|
|
1257
|
+
// id_/string child, not an expr, so the generic collection below drops it and every
|
|
1258
|
+
// EXTRACT(part FROM ts) call under-counts to one argument (a wrong-arity false positive on valid
|
|
1259
|
+
// SQL once the arity checker trusts the generated signatures). Lowered as a literal, never a
|
|
1260
|
+
// column ref: a date part must not join name resolution.
|
|
1261
|
+
if (hasTokenShallow(node, P.EXTRACT)) {
|
|
1262
|
+
const part = directChildrenOfRule(node, P.RULE_id_)[0] ?? directChildrenOfRule(node, P.RULE_string)[0];
|
|
1263
|
+
const partArgs = part ? [{ kind: "literal", text: part.getText(), cst: part }] : [];
|
|
1264
|
+
return {
|
|
1265
|
+
kind: "function",
|
|
1266
|
+
name: "extract",
|
|
1267
|
+
args: [...partArgs, ...directChildrenOfRule(node, P.RULE_expr).map(lowerExpr)],
|
|
1268
|
+
aggregate: false,
|
|
1269
|
+
distinct: false,
|
|
1270
|
+
cst: node,
|
|
1271
|
+
};
|
|
1272
|
+
}
|
|
1255
1273
|
const name = functionName(node);
|
|
1256
|
-
const
|
|
1274
|
+
const positional = [
|
|
1257
1275
|
...exprListExprs(node).map(lowerExpr),
|
|
1258
1276
|
...directChildrenOfRule(node, P.RULE_expr).map(lowerExpr),
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1277
|
+
];
|
|
1278
|
+
const paramAssoc = directChildrenOfRule(node, P.RULE_param_assoc_list).flatMap(paramAssocValues);
|
|
1279
|
+
// the object_name(func_arg_list) alternative — positional exprs and named-arg values
|
|
1280
|
+
// (STAR / stage / spread / TYPE args carry no expr payload and add nothing here).
|
|
1281
|
+
// Also the SLL-surgery wave's home for plain f(args) calls (2026-07-03).
|
|
1282
|
+
const funcArg = directChildrenOfRule(node, P.RULE_func_arg_list).flatMap(funcArgValues);
|
|
1283
|
+
const args = [...positional, ...paramAssoc.map((v) => v.arg), ...funcArg.map((v) => v.arg)];
|
|
1284
|
+
const argNames = [
|
|
1285
|
+
...positional.map(() => undefined),
|
|
1286
|
+
...paramAssoc.map((v) => v.name),
|
|
1287
|
+
...funcArg.map((v) => v.name),
|
|
1264
1288
|
];
|
|
1265
1289
|
return {
|
|
1266
1290
|
kind: "function",
|
|
1267
1291
|
name: name.toLowerCase(),
|
|
1268
1292
|
args,
|
|
1293
|
+
// Named-argument invocation `fn(name => value)`: the per-arg names make the call
|
|
1294
|
+
// conservation-visible and let the arity checker's named-arg bypass fire (a named call's
|
|
1295
|
+
// positional count says nothing about the documented positional signature).
|
|
1296
|
+
...(argNames.some((n) => n !== undefined) ? { argNames } : {}),
|
|
1269
1297
|
aggregate: AGGREGATES.has(name.toLowerCase()),
|
|
1270
1298
|
distinct: hasTokenShallow(node, P.DISTINCT),
|
|
1271
1299
|
cst: node,
|
|
1272
1300
|
};
|
|
1273
1301
|
}
|
|
1302
|
+
/** One func_arg's lowered value plus its `name =>` parameter name (undefined for a plain positional
|
|
1303
|
+
* expr). STAR / stage / spread / TYPE / TABLE(...) args carry no expr payload and are skipped. */
|
|
1274
1304
|
function funcArgValues(list) {
|
|
1275
1305
|
return directChildrenOfRule(list, P.RULE_func_arg).flatMap((fa) => {
|
|
1276
1306
|
const e = directChildrenOfRule(fa, P.RULE_expr)[0];
|
|
1277
1307
|
if (e)
|
|
1278
|
-
return [lowerExpr(e)];
|
|
1308
|
+
return [{ arg: lowerExpr(e), name: undefined }];
|
|
1279
1309
|
const pa = directChildrenOfRule(fa, P.RULE_param_assoc)[0];
|
|
1280
|
-
const
|
|
1281
|
-
return
|
|
1310
|
+
const one = pa ? oneParamAssoc(pa) : undefined;
|
|
1311
|
+
return one ? [one] : [];
|
|
1282
1312
|
});
|
|
1283
1313
|
}
|
|
1314
|
+
/** param_assoc_list: every param_assoc child, each lowered via oneParamAssoc. */
|
|
1284
1315
|
function paramAssocValues(list) {
|
|
1285
1316
|
return directChildrenOfRule(list, P.RULE_param_assoc)
|
|
1286
|
-
.map(
|
|
1287
|
-
.filter((
|
|
1288
|
-
|
|
1317
|
+
.map(oneParamAssoc)
|
|
1318
|
+
.filter((v) => v !== undefined);
|
|
1319
|
+
}
|
|
1320
|
+
/** param_assoc: `(id_ | FILE_FORMAT | PATTERN | LIMIT) ASSOC expr`; the name is the id_ rule when
|
|
1321
|
+
* present, else the leading keyword token itself. */
|
|
1322
|
+
function oneParamAssoc(pa) {
|
|
1323
|
+
const e = directChildrenOfRule(pa, P.RULE_expr)[0];
|
|
1324
|
+
if (!e)
|
|
1325
|
+
return undefined;
|
|
1326
|
+
const id = directChildrenOfRule(pa, P.RULE_id_)[0];
|
|
1327
|
+
const name = id ? id.getText() : leftmostToken(pa);
|
|
1328
|
+
return { arg: lowerExpr(e), name };
|
|
1289
1329
|
}
|
|
1290
1330
|
function functionName(node) {
|
|
1291
1331
|
const obj = directChildrenOfRule(node, P.RULE_object_name)[0];
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { FnSignature } from "../signature/signatures.js";
|
|
2
|
+
/** The merged function-signature table for snowflake: 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 SNOWFLAKE_SIGNATURES: Record<string, FnSignature[]>;
|