Adding upstream version 25.16.1.
Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
parent
a500eebbbb
commit
1341bc6477
110 changed files with 75353 additions and 68092 deletions
|
@ -122,12 +122,6 @@ def _regexpilike_sql(self: Snowflake.Generator, expression: exp.RegexpILike) ->
|
|||
)
|
||||
|
||||
|
||||
def _build_convert_timezone(args: t.List) -> t.Union[exp.Anonymous, exp.AtTimeZone]:
|
||||
if len(args) == 3:
|
||||
return exp.Anonymous(this="CONVERT_TIMEZONE", expressions=args)
|
||||
return exp.AtTimeZone(this=seq_get(args, 1), zone=seq_get(args, 0))
|
||||
|
||||
|
||||
def _build_regexp_replace(args: t.List) -> exp.RegexpReplace:
|
||||
regexp_replace = exp.RegexpReplace.from_arg_list(args)
|
||||
|
||||
|
@ -186,6 +180,47 @@ def _flatten_structured_types_unless_iceberg(expression: exp.Expression) -> exp.
|
|||
return expression
|
||||
|
||||
|
||||
def _unnest_generate_date_array(expression: exp.Expression) -> exp.Expression:
|
||||
if isinstance(expression, exp.Select):
|
||||
for unnest in expression.find_all(exp.Unnest):
|
||||
if (
|
||||
isinstance(unnest.parent, (exp.From, exp.Join))
|
||||
and len(unnest.expressions) == 1
|
||||
and isinstance(unnest.expressions[0], exp.GenerateDateArray)
|
||||
):
|
||||
generate_date_array = unnest.expressions[0]
|
||||
start = generate_date_array.args.get("start")
|
||||
end = generate_date_array.args.get("end")
|
||||
step = generate_date_array.args.get("step")
|
||||
|
||||
if not start or not end or not isinstance(step, exp.Interval) or step.name != "1":
|
||||
continue
|
||||
|
||||
unit = step.args.get("unit")
|
||||
|
||||
unnest_alias = unnest.args.get("alias")
|
||||
if unnest_alias:
|
||||
unnest_alias = unnest_alias.copy()
|
||||
sequence_value_name = seq_get(unnest_alias.columns, 0) or "value"
|
||||
else:
|
||||
sequence_value_name = "value"
|
||||
|
||||
# We'll add the next sequence value to the starting date and project the result
|
||||
date_add = _build_date_time_add(exp.DateAdd)(
|
||||
[unit, exp.cast(sequence_value_name, "int"), exp.cast(start, "date")]
|
||||
).as_(sequence_value_name)
|
||||
|
||||
# We use DATEDIFF to compute the number of sequence values needed
|
||||
number_sequence = Snowflake.Parser.FUNCTIONS["ARRAY_GENERATE_RANGE"](
|
||||
[exp.Literal.number(0), _build_datediff([unit, start, end]) + 1]
|
||||
)
|
||||
|
||||
unnest.set("expressions", [number_sequence])
|
||||
unnest.replace(exp.select(date_add).from_(unnest.copy()).subquery(unnest_alias))
|
||||
|
||||
return expression
|
||||
|
||||
|
||||
class Snowflake(Dialect):
|
||||
# https://docs.snowflake.com/en/sql-reference/identifiers-syntax
|
||||
NORMALIZATION_STRATEGY = NormalizationStrategy.UPPERCASE
|
||||
|
@ -255,7 +290,7 @@ class Snowflake(Dialect):
|
|||
**parser.Parser.FUNCTIONS,
|
||||
"APPROX_PERCENTILE": exp.ApproxQuantile.from_arg_list,
|
||||
"ARRAYAGG": exp.ArrayAgg.from_arg_list,
|
||||
"ARRAY_CONSTRUCT": exp.Array.from_arg_list,
|
||||
"ARRAY_CONSTRUCT": lambda args: exp.Array(expressions=args),
|
||||
"ARRAY_CONTAINS": lambda args: exp.ArrayContains(
|
||||
this=seq_get(args, 1), expression=seq_get(args, 0)
|
||||
),
|
||||
|
@ -268,7 +303,6 @@ class Snowflake(Dialect):
|
|||
"BITXOR": binary_from_function(exp.BitwiseXor),
|
||||
"BIT_XOR": binary_from_function(exp.BitwiseXor),
|
||||
"BOOLXOR": binary_from_function(exp.Xor),
|
||||
"CONVERT_TIMEZONE": _build_convert_timezone,
|
||||
"DATE": _build_datetime("DATE", exp.DataType.Type.DATE),
|
||||
"DATE_TRUNC": _date_trunc_to_time,
|
||||
"DATEADD": _build_date_time_add(exp.DateAdd),
|
||||
|
@ -413,6 +447,26 @@ class Snowflake(Dialect):
|
|||
),
|
||||
}
|
||||
|
||||
def _negate_range(
|
||||
self, this: t.Optional[exp.Expression] = None
|
||||
) -> t.Optional[exp.Expression]:
|
||||
if not this:
|
||||
return this
|
||||
|
||||
query = this.args.get("query")
|
||||
if isinstance(this, exp.In) and isinstance(query, exp.Query):
|
||||
# Snowflake treats `value NOT IN (subquery)` as `VALUE <> ALL (subquery)`, so
|
||||
# we do this conversion here to avoid parsing it into `NOT value IN (subquery)`
|
||||
# which can produce different results (most likely a SnowFlake bug).
|
||||
#
|
||||
# https://docs.snowflake.com/en/sql-reference/functions/in
|
||||
# Context: https://github.com/tobymao/sqlglot/issues/3890
|
||||
return self.expression(
|
||||
exp.NEQ, this=this.this, expression=exp.All(this=query.unnest())
|
||||
)
|
||||
|
||||
return self.expression(exp.Not, this=this)
|
||||
|
||||
def _parse_with_constraint(self) -> t.Optional[exp.Expression]:
|
||||
if self._prev.token_type != TokenType.WITH:
|
||||
self._retreat(self._index - 1)
|
||||
|
@ -638,6 +692,7 @@ class Snowflake(Dialect):
|
|||
HEX_STRINGS = [("x'", "'"), ("X'", "'")]
|
||||
RAW_STRINGS = ["$$"]
|
||||
COMMENTS = ["--", "//", ("/*", "*/")]
|
||||
NESTED_COMMENTS = False
|
||||
|
||||
KEYWORDS = {
|
||||
**tokens.Tokenizer.KEYWORDS,
|
||||
|
@ -692,6 +747,9 @@ class Snowflake(Dialect):
|
|||
COPY_PARAMS_ARE_WRAPPED = False
|
||||
COPY_PARAMS_EQ_REQUIRED = True
|
||||
STAR_EXCEPT = "EXCLUDE"
|
||||
SUPPORTS_EXPLODING_PROJECTIONS = False
|
||||
ARRAY_CONCAT_IS_VAR_LEN = False
|
||||
SUPPORTS_CONVERT_TIMEZONE = True
|
||||
|
||||
TRANSFORMS = {
|
||||
**generator.Generator.TRANSFORMS,
|
||||
|
@ -699,7 +757,7 @@ class Snowflake(Dialect):
|
|||
exp.ArgMax: rename_func("MAX_BY"),
|
||||
exp.ArgMin: rename_func("MIN_BY"),
|
||||
exp.Array: inline_array_sql,
|
||||
exp.ArrayConcat: rename_func("ARRAY_CAT"),
|
||||
exp.ArrayConcat: lambda self, e: self.arrayconcat_sql(e, name="ARRAY_CAT"),
|
||||
exp.ArrayContains: lambda self, e: self.func("ARRAY_CONTAINS", e.expression, e.this),
|
||||
exp.AtTimeZone: lambda self, e: self.func(
|
||||
"CONVERT_TIMEZONE", e.args.get("zone"), e.this
|
||||
|
@ -751,6 +809,7 @@ class Snowflake(Dialect):
|
|||
transforms.eliminate_distinct_on,
|
||||
transforms.explode_to_unnest(),
|
||||
transforms.eliminate_semi_and_anti_joins,
|
||||
_unnest_generate_date_array,
|
||||
]
|
||||
),
|
||||
exp.SHA: rename_func("SHA1"),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue