Merging upstream version 25.5.1.
Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
parent
298e7a8147
commit
029b9c2c73
136 changed files with 80990 additions and 72541 deletions
|
@ -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}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue