sqlglotc 30.3.0__tar.gz → 30.4.0__tar.gz
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.
- {sqlglotc-30.3.0 → sqlglotc-30.4.0}/PKG-INFO +1 -1
- {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/generator.py +11 -0
- {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/generators/duckdb.py +49 -0
- {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/generators/snowflake.py +1 -0
- {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/parser.py +5 -1
- {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglotc.egg-info/PKG-INFO +1 -1
- {sqlglotc-30.3.0 → sqlglotc-30.4.0}/MANIFEST.in +0 -0
- {sqlglotc-30.3.0 → sqlglotc-30.4.0}/pyproject.toml +0 -0
- {sqlglotc-30.3.0 → sqlglotc-30.4.0}/setup.cfg +0 -0
- {sqlglotc-30.3.0 → sqlglotc-30.4.0}/setup.py +0 -0
- {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/errors.py +0 -0
- {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/executor/table.py +0 -0
- {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/expressions/aggregate.py +0 -0
- {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/expressions/array.py +0 -0
- {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/expressions/builders.py +0 -0
- {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/expressions/constraints.py +0 -0
- {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/expressions/core.py +0 -0
- {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/expressions/datatypes.py +0 -0
- {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/expressions/ddl.py +0 -0
- {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/expressions/dml.py +0 -0
- {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/expressions/functions.py +0 -0
- {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/expressions/json.py +0 -0
- {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/expressions/math.py +0 -0
- {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/expressions/properties.py +0 -0
- {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/expressions/query.py +0 -0
- {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/expressions/string.py +0 -0
- {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/expressions/temporal.py +0 -0
- {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/generators/athena.py +0 -0
- {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/generators/bigquery.py +0 -0
- {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/generators/clickhouse.py +0 -0
- {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/generators/databricks.py +0 -0
- {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/generators/doris.py +0 -0
- {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/generators/dremio.py +0 -0
- {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/generators/drill.py +0 -0
- {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/generators/druid.py +0 -0
- {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/generators/dune.py +0 -0
- {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/generators/exasol.py +0 -0
- {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/generators/fabric.py +0 -0
- {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/generators/hive.py +0 -0
- {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/generators/materialize.py +0 -0
- {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/generators/mysql.py +0 -0
- {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/generators/oracle.py +0 -0
- {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/generators/postgres.py +0 -0
- {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/generators/presto.py +0 -0
- {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/generators/prql.py +0 -0
- {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/generators/redshift.py +0 -0
- {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/generators/risingwave.py +0 -0
- {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/generators/singlestore.py +0 -0
- {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/generators/solr.py +0 -0
- {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/generators/spark.py +0 -0
- {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/generators/spark2.py +0 -0
- {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/generators/sqlite.py +0 -0
- {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/generators/starrocks.py +0 -0
- {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/generators/tableau.py +0 -0
- {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/generators/teradata.py +0 -0
- {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/generators/trino.py +0 -0
- {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/generators/tsql.py +0 -0
- {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/helper.py +0 -0
- {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/optimizer/annotate_types.py +0 -0
- {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/optimizer/isolate_table_selects.py +0 -0
- {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/optimizer/normalize_identifiers.py +0 -0
- {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/optimizer/qualify.py +0 -0
- {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/optimizer/qualify_columns.py +0 -0
- {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/optimizer/qualify_tables.py +0 -0
- {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/optimizer/resolver.py +0 -0
- {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/optimizer/scope.py +0 -0
- {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/optimizer/simplify.py +0 -0
- {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/parsers/athena.py +0 -0
- {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/parsers/base.py +0 -0
- {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/parsers/bigquery.py +0 -0
- {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/parsers/clickhouse.py +0 -0
- {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/parsers/databricks.py +0 -0
- {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/parsers/doris.py +0 -0
- {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/parsers/dremio.py +0 -0
- {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/parsers/drill.py +0 -0
- {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/parsers/druid.py +0 -0
- {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/parsers/duckdb.py +0 -0
- {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/parsers/dune.py +0 -0
- {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/parsers/exasol.py +0 -0
- {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/parsers/fabric.py +0 -0
- {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/parsers/hive.py +0 -0
- {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/parsers/materialize.py +0 -0
- {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/parsers/mysql.py +0 -0
- {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/parsers/oracle.py +0 -0
- {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/parsers/postgres.py +0 -0
- {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/parsers/presto.py +0 -0
- {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/parsers/prql.py +0 -0
- {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/parsers/redshift.py +0 -0
- {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/parsers/risingwave.py +0 -0
- {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/parsers/singlestore.py +0 -0
- {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/parsers/snowflake.py +0 -0
- {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/parsers/solr.py +0 -0
- {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/parsers/spark.py +0 -0
- {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/parsers/spark2.py +0 -0
- {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/parsers/sqlite.py +0 -0
- {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/parsers/starrocks.py +0 -0
- {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/parsers/tableau.py +0 -0
- {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/parsers/teradata.py +0 -0
- {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/parsers/trino.py +0 -0
- {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/parsers/tsql.py +0 -0
- {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/schema.py +0 -0
- {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/serde.py +0 -0
- {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/time.py +0 -0
- {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/tokenizer_core.py +0 -0
- {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/trie.py +0 -0
- {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglotc.egg-info/SOURCES.txt +0 -0
- {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglotc.egg-info/dependency_links.txt +0 -0
- {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglotc.egg-info/requires.txt +0 -0
- {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglotc.egg-info/top_level.txt +0 -0
|
@@ -3416,6 +3416,17 @@ class Generator:
|
|
|
3416
3416
|
return self.func("CONCAT", *expressions)
|
|
3417
3417
|
|
|
3418
3418
|
def concatws_sql(self, expression: exp.ConcatWs) -> str:
|
|
3419
|
+
if self.dialect.CONCAT_COALESCE and not expression.args.get("coalesce"):
|
|
3420
|
+
# Dialect's CONCAT_WS function coalesces NULLs to empty strings, but the expression does not.
|
|
3421
|
+
# Wrap the entire call in a CASE expression that returns NULL if any input IS NULL.
|
|
3422
|
+
all_args = expression.expressions
|
|
3423
|
+
expression.set("coalesce", True)
|
|
3424
|
+
return self.sql(
|
|
3425
|
+
exp.case()
|
|
3426
|
+
.when(exp.or_(*(arg.is_(exp.null()) for arg in all_args)), exp.null())
|
|
3427
|
+
.else_(expression)
|
|
3428
|
+
)
|
|
3429
|
+
|
|
3419
3430
|
return self.func(
|
|
3420
3431
|
"CONCAT_WS", seq_get(expression.expressions, 0), *self.convert_concat_args(expression)
|
|
3421
3432
|
)
|
|
@@ -82,6 +82,13 @@ WEEK_START_DAY_TO_DOW = {
|
|
|
82
82
|
|
|
83
83
|
MAX_BIT_POSITION = exp.Literal.number(32768)
|
|
84
84
|
|
|
85
|
+
# cs/as/ps are Snowflake defaults; DuckDB already behaves the same way, so they are safe to drop.
|
|
86
|
+
# Note: "as" is also a reserved keyword in DuckDB, making it impossible to pass through.
|
|
87
|
+
_SNOWFLAKE_COLLATION_DEFAULTS = frozenset({"cs", "as", "ps"})
|
|
88
|
+
_SNOWFLAKE_COLLATION_UNSUPPORTED = frozenset(
|
|
89
|
+
{"ci", "ai", "upper", "lower", "utf8", "bin", "pi", "fl", "fu", "trim", "ltrim", "rtrim"}
|
|
90
|
+
)
|
|
91
|
+
|
|
85
92
|
# Window functions that support IGNORE/RESPECT NULLS in DuckDB
|
|
86
93
|
_IGNORE_RESPECT_NULLS_WINDOW_FUNCTIONS = (
|
|
87
94
|
exp.FirstValue,
|
|
@@ -2997,6 +3004,30 @@ class DuckDBGenerator(generator.Generator):
|
|
|
2997
3004
|
self.unsupported("COLLATION function is not supported by DuckDB")
|
|
2998
3005
|
return self.function_fallback_sql(expression)
|
|
2999
3006
|
|
|
3007
|
+
def collate_sql(self, expression: exp.Collate) -> str:
|
|
3008
|
+
if not expression.expression.is_string:
|
|
3009
|
+
return super().collate_sql(expression)
|
|
3010
|
+
|
|
3011
|
+
raw = expression.expression.name
|
|
3012
|
+
if not raw:
|
|
3013
|
+
return self.sql(expression.this)
|
|
3014
|
+
|
|
3015
|
+
parts = []
|
|
3016
|
+
for part in raw.split("-"):
|
|
3017
|
+
lower = part.lower()
|
|
3018
|
+
if lower not in _SNOWFLAKE_COLLATION_DEFAULTS:
|
|
3019
|
+
if lower in _SNOWFLAKE_COLLATION_UNSUPPORTED:
|
|
3020
|
+
self.unsupported(
|
|
3021
|
+
f"Snowflake collation specifier '{part}' has no DuckDB equivalent"
|
|
3022
|
+
)
|
|
3023
|
+
parts.append(lower)
|
|
3024
|
+
|
|
3025
|
+
if not parts:
|
|
3026
|
+
return self.sql(expression.this)
|
|
3027
|
+
return super().collate_sql(
|
|
3028
|
+
exp.Collate(this=expression.this, expression=exp.var(".".join(parts)))
|
|
3029
|
+
)
|
|
3030
|
+
|
|
3000
3031
|
def _validate_regexp_flags(self, flags: exp.Expr | None, supported_flags: str) -> str | None:
|
|
3001
3032
|
"""
|
|
3002
3033
|
Validate and filter regexp flags for DuckDB compatibility.
|
|
@@ -3362,6 +3393,9 @@ class DuckDBGenerator(generator.Generator):
|
|
|
3362
3393
|
def right_sql(self, expression: exp.Right) -> str:
|
|
3363
3394
|
return self._left_right_sql(expression, "RIGHT")
|
|
3364
3395
|
|
|
3396
|
+
def rtrimmedlength_sql(self, expression: exp.RtrimmedLength) -> str:
|
|
3397
|
+
return self.func("LENGTH", exp.Trim(this=expression.this, position="TRAILING"))
|
|
3398
|
+
|
|
3365
3399
|
def rand_sql(self, expression: exp.Rand) -> str:
|
|
3366
3400
|
seed = expression.this
|
|
3367
3401
|
if seed is not None:
|
|
@@ -3733,6 +3767,21 @@ class DuckDBGenerator(generator.Generator):
|
|
|
3733
3767
|
|
|
3734
3768
|
return self.func("ARRAY_TO_STRING", expression.this, expression.expression)
|
|
3735
3769
|
|
|
3770
|
+
def concatws_sql(self, expression: exp.ConcatWs) -> str:
|
|
3771
|
+
# DuckDB-specific: handle binary types using DPipe (||) operator
|
|
3772
|
+
separator = seq_get(expression.expressions, 0)
|
|
3773
|
+
args = expression.expressions[1:]
|
|
3774
|
+
|
|
3775
|
+
if any(_is_binary(arg) for arg in [separator, *args]):
|
|
3776
|
+
result = args[0]
|
|
3777
|
+
for arg in args[1:]:
|
|
3778
|
+
result = exp.DPipe(
|
|
3779
|
+
this=exp.DPipe(this=result, expression=separator), expression=arg
|
|
3780
|
+
)
|
|
3781
|
+
return self.sql(result)
|
|
3782
|
+
|
|
3783
|
+
return super().concatws_sql(expression)
|
|
3784
|
+
|
|
3736
3785
|
def _regexp_extract_sql(self, expression: exp.RegexpExtract | exp.RegexpExtractAll) -> str:
|
|
3737
3786
|
this = expression.this
|
|
3738
3787
|
group = expression.args.get("group")
|
|
@@ -481,6 +481,7 @@ class SnowflakeGenerator(generator.Generator):
|
|
|
481
481
|
),
|
|
482
482
|
exp.CosineDistance: rename_func("VECTOR_COSINE_SIMILARITY"),
|
|
483
483
|
exp.EuclideanDistance: rename_func("VECTOR_L2_DISTANCE"),
|
|
484
|
+
exp.HandlerProperty: lambda self, e: f"HANDLER = {self.sql(e, 'this')}",
|
|
484
485
|
exp.FileFormatProperty: lambda self, e: (
|
|
485
486
|
f"FILE_FORMAT=({self.expressions(e, 'expressions', sep=' ')})"
|
|
486
487
|
),
|
|
@@ -5399,7 +5399,11 @@ class Parser:
|
|
|
5399
5399
|
comments = self._prev_comments
|
|
5400
5400
|
if top:
|
|
5401
5401
|
limit_paren = self._match(TokenType.L_PAREN)
|
|
5402
|
-
expression =
|
|
5402
|
+
expression = (
|
|
5403
|
+
self._parse_term() or self._parse_select()
|
|
5404
|
+
if limit_paren
|
|
5405
|
+
else self._parse_number()
|
|
5406
|
+
)
|
|
5403
5407
|
|
|
5404
5408
|
if limit_paren:
|
|
5405
5409
|
self._match_r_paren()
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|