1
0
Fork 0

Merging upstream version 25.5.1.

Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
Daniel Baumann 2025-02-13 21:41:14 +01:00
parent 298e7a8147
commit 029b9c2c73
Signed by: daniel
GPG key ID: FBB4F0E80A80222F
136 changed files with 80990 additions and 72541 deletions

View file

@ -20,6 +20,7 @@ import textwrap
import typing as t
from collections import deque
from copy import deepcopy
from decimal import Decimal
from enum import auto
from functools import reduce
@ -29,7 +30,6 @@ from sqlglot.helper import (
camel_to_snake_case,
ensure_collection,
ensure_list,
is_int,
seq_get,
subclasses,
)
@ -40,6 +40,7 @@ if t.TYPE_CHECKING:
from sqlglot.dialects.dialect import DialectType
Q = t.TypeVar("Q", bound="Query")
S = t.TypeVar("S", bound="SetOperation")
class _Expression(type):
@ -174,23 +175,22 @@ class Expression(metaclass=_Expression):
"""
Checks whether a Literal expression is a number.
"""
return isinstance(self, Literal) and not self.args["is_string"]
return (isinstance(self, Literal) and not self.args["is_string"]) or (
isinstance(self, Neg) and self.this.is_number
)
@property
def is_negative(self) -> bool:
def to_py(self) -> t.Any:
"""
Checks whether an expression is negative.
Handles both exp.Neg and Literal numbers with "-" which come from optimizer.simplify.
Returns a Python object equivalent of the SQL node.
"""
return isinstance(self, Neg) or (self.is_number and self.this.startswith("-"))
raise ValueError(f"{self} cannot be converted to a Python object.")
@property
def is_int(self) -> bool:
"""
Checks whether a Literal expression is an integer.
Checks whether an expression is an integer.
"""
return self.is_number and is_int(self.name)
return self.is_number and isinstance(self.to_py(), int)
@property
def is_star(self) -> bool:
@ -2002,6 +2002,10 @@ class Check(Expression):
pass
class Changes(Expression):
arg_types = {"information": True, "at_before": False, "end": False}
# https://docs.snowflake.com/en/sql-reference/constructs/connect-by
class Connect(Expression):
arg_types = {"start": False, "connect": True, "nocycle": False}
@ -2127,6 +2131,7 @@ class IndexParameters(Expression):
"partition_by": False,
"tablespace": False,
"where": False,
"on": False,
}
@ -2281,6 +2286,14 @@ class Literal(Condition):
def output_name(self) -> str:
return self.name
def to_py(self) -> int | str | Decimal:
if self.is_number:
try:
return int(self.this)
except ValueError:
return Decimal(self.this)
return self.this
class Join(Expression):
arg_types = {
@ -2639,6 +2652,10 @@ class DictRange(Property):
arg_types = {"this": True, "min": True, "max": True}
class DynamicProperty(Property):
arg_types = {}
# Clickhouse CREATE ... ON CLUSTER modifier
# https://clickhouse.com/docs/en/sql-reference/distributed-ddl
class OnCluster(Property):
@ -2805,6 +2822,10 @@ class TemporaryProperty(Property):
arg_types = {"this": False}
class SecureProperty(Property):
arg_types = {}
class TransformModelProperty(Property):
arg_types = {"expressions": True}
@ -2834,6 +2855,10 @@ class WithJournalTableProperty(Property):
arg_types = {"this": True}
class WithSchemaBindingProperty(Property):
arg_types = {"this": True}
class WithSystemVersioningProperty(Property):
arg_types = {
"on": False,
@ -3017,6 +3042,7 @@ class Table(Expression):
"when": False,
"only": False,
"partition": False,
"changes": False,
}
@property
@ -3065,7 +3091,7 @@ class Table(Expression):
return col
class Union(Query):
class SetOperation(Query):
arg_types = {
"with": False,
"this": True,
@ -3076,13 +3102,13 @@ class Union(Query):
}
def select(
self,
self: S,
*expressions: t.Optional[ExpOrStr],
append: bool = True,
dialect: DialectType = None,
copy: bool = True,
**opts,
) -> Union:
) -> S:
this = maybe_copy(self, copy)
this.this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
this.expression.unnest().select(
@ -3111,11 +3137,15 @@ class Union(Query):
return self.expression
class Except(Union):
class Union(SetOperation):
pass
class Intersect(Union):
class Except(SetOperation):
pass
class Intersect(SetOperation):
pass
@ -3727,7 +3757,7 @@ class Select(Query):
return self.expressions
UNWRAPPED_QUERIES = (Select, Union)
UNWRAPPED_QUERIES = (Select, SetOperation)
class Subquery(DerivedTable, Query):
@ -3893,9 +3923,13 @@ class Null(Condition):
def name(self) -> str:
return "NULL"
def to_py(self) -> Lit[None]:
return None
class Boolean(Condition):
pass
def to_py(self) -> bool:
return self.this
class DataTypeParam(Expression):
@ -4019,6 +4053,7 @@ class DataType(Expression):
VARBINARY = auto()
VARCHAR = auto()
VARIANT = auto()
VECTOR = auto()
XML = auto()
YEAR = auto()
TDIGEST = auto()
@ -4473,7 +4508,10 @@ class Paren(Unary):
class Neg(Unary):
pass
def to_py(self) -> int | Decimal:
if self.is_number:
return self.this.to_py() * -1
return super().to_py()
class Alias(Expression):
@ -5065,6 +5103,12 @@ class DateTrunc(Func):
return self.args["unit"]
# https://cloud.google.com/bigquery/docs/reference/standard-sql/datetime_functions#datetime
# expression can either be time_expr or time_zone
class Datetime(Func):
arg_types = {"this": True, "expression": False}
class DatetimeAdd(Func, IntervalOp):
arg_types = {"this": True, "expression": True, "unit": False}
@ -5115,7 +5159,7 @@ class Extract(Func):
class Timestamp(Func):
arg_types = {"this": False, "expression": False, "with_tz": False}
arg_types = {"this": False, "zone": False, "with_tz": False}
class TimestampAdd(Func, TimeUnit):
@ -5441,12 +5485,18 @@ class OpenJSON(Func):
arg_types = {"this": True, "path": False, "expressions": False}
class JSONBContains(Binary):
class JSONBContains(Binary, Func):
_sql_names = ["JSONB_CONTAINS"]
class JSONExtract(Binary, Func):
arg_types = {"this": True, "expression": True, "only_json_types": False, "expressions": False}
arg_types = {
"this": True,
"expression": True,
"only_json_types": False,
"expressions": False,
"variant_extract": False,
}
_sql_names = ["JSON_EXTRACT"]
is_var_len_args = True
@ -5485,9 +5535,9 @@ class JSONArrayContains(Binary, Predicate, Func):
class ParseJSON(Func):
# BigQuery, Snowflake have PARSE_JSON, Presto has JSON_PARSE
# Snowflake also has TRY_PARSE_JSON, which is represented using `safe`
_sql_names = ["PARSE_JSON", "JSON_PARSE"]
arg_types = {"this": True, "expressions": False}
is_var_len_args = True
arg_types = {"this": True, "expression": False, "safe": False}
class Least(Func):
@ -5504,6 +5554,7 @@ class Right(Func):
class Length(Func):
arg_types = {"this": True, "binary": False}
_sql_names = ["LENGTH", "LEN"]
@ -5560,6 +5611,11 @@ class MapFromEntries(Func):
pass
# https://learn.microsoft.com/en-us/sql/t-sql/language-elements/scope-resolution-operator-transact-sql?view=sql-server-ver16
class ScopeResolution(Expression):
arg_types = {"this": False, "expression": True}
class StarMap(Func):
pass
@ -5642,9 +5698,11 @@ class Quarter(Func):
pass
# https://docs.teradata.com/r/Enterprise_IntelliFlex_VMware/SQL-Functions-Expressions-and-Predicates/Arithmetic-Trigonometric-Hyperbolic-Operators/Functions/RANDOM/RANDOM-Function-Syntax
# teradata lower and upper bounds
class Rand(Func):
_sql_names = ["RAND", "RANDOM"]
arg_types = {"this": False}
arg_types = {"this": False, "lower": False, "upper": False}
class Randn(Func):
@ -5765,11 +5823,11 @@ class StrPosition(Func):
class StrToDate(Func):
arg_types = {"this": True, "format": False}
arg_types = {"this": True, "format": False, "safe": False}
class StrToTime(Func):
arg_types = {"this": True, "format": True, "zone": False}
arg_types = {"this": True, "format": True, "zone": False, "safe": False}
# Spark allows unix_timestamp()
@ -5833,6 +5891,11 @@ class StddevSamp(AggFunc):
pass
# https://cloud.google.com/bigquery/docs/reference/standard-sql/time_functions#time
class Time(Func):
arg_types = {"this": False, "zone": False}
class TimeToStr(Func):
arg_types = {"this": True, "format": True, "culture": False, "timezone": False}