Merging upstream version 7.1.3.
Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
parent
964bd62de9
commit
e6b3d2fe54
42 changed files with 1430 additions and 253 deletions
|
@ -1,3 +1,4 @@
|
|||
import datetime
|
||||
import numbers
|
||||
import re
|
||||
from collections import deque
|
||||
|
@ -508,7 +509,7 @@ class DerivedTable(Expression):
|
|||
return [select.alias_or_name for select in self.selects]
|
||||
|
||||
|
||||
class Unionable:
|
||||
class Unionable(Expression):
|
||||
def union(self, expression, distinct=True, dialect=None, **opts):
|
||||
"""
|
||||
Builds a UNION expression.
|
||||
|
@ -614,6 +615,10 @@ class Create(Expression):
|
|||
}
|
||||
|
||||
|
||||
class Describe(Expression):
|
||||
pass
|
||||
|
||||
|
||||
class UserDefinedFunction(Expression):
|
||||
arg_types = {"this": True, "expressions": False}
|
||||
|
||||
|
@ -741,6 +746,11 @@ class Check(Expression):
|
|||
pass
|
||||
|
||||
|
||||
class Directory(Expression):
|
||||
# https://spark.apache.org/docs/3.0.0-preview/sql-ref-syntax-dml-insert-overwrite-directory-hive.html
|
||||
arg_types = {"this": True, "local": False, "row_format": False}
|
||||
|
||||
|
||||
class ForeignKey(Expression):
|
||||
arg_types = {
|
||||
"expressions": True,
|
||||
|
@ -804,6 +814,18 @@ class Introducer(Expression):
|
|||
arg_types = {"this": True, "expression": True}
|
||||
|
||||
|
||||
class LoadData(Expression):
|
||||
arg_types = {
|
||||
"this": True,
|
||||
"local": False,
|
||||
"overwrite": False,
|
||||
"inpath": True,
|
||||
"partition": False,
|
||||
"input_format": False,
|
||||
"serde": False,
|
||||
}
|
||||
|
||||
|
||||
class Partition(Expression):
|
||||
pass
|
||||
|
||||
|
@ -1037,6 +1059,18 @@ class Reference(Expression):
|
|||
arg_types = {"this": True, "expressions": True}
|
||||
|
||||
|
||||
class RowFormat(Expression):
|
||||
# https://cwiki.apache.org/confluence/display/hive/languagemanual+dml
|
||||
arg_types = {
|
||||
"fields": False,
|
||||
"escaped": False,
|
||||
"collection_items": False,
|
||||
"map_keys": False,
|
||||
"lines": False,
|
||||
"null": False,
|
||||
}
|
||||
|
||||
|
||||
class Tuple(Expression):
|
||||
arg_types = {"expressions": False}
|
||||
|
||||
|
@ -1071,6 +1105,14 @@ class Subqueryable(Unionable):
|
|||
return []
|
||||
return with_.expressions
|
||||
|
||||
@property
|
||||
def selects(self):
|
||||
raise NotImplementedError("Subqueryable objects must implement `selects`")
|
||||
|
||||
@property
|
||||
def named_selects(self):
|
||||
raise NotImplementedError("Subqueryable objects must implement `named_selects`")
|
||||
|
||||
def with_(
|
||||
self,
|
||||
alias,
|
||||
|
@ -1158,7 +1200,7 @@ class Table(Expression):
|
|||
}
|
||||
|
||||
|
||||
class Union(Subqueryable, Expression):
|
||||
class Union(Subqueryable):
|
||||
arg_types = {
|
||||
"with": False,
|
||||
"this": True,
|
||||
|
@ -1169,7 +1211,11 @@ class Union(Subqueryable, Expression):
|
|||
|
||||
@property
|
||||
def named_selects(self):
|
||||
return self.args["this"].unnest().named_selects
|
||||
return self.this.unnest().named_selects
|
||||
|
||||
@property
|
||||
def selects(self):
|
||||
return self.this.unnest().selects
|
||||
|
||||
@property
|
||||
def left(self):
|
||||
|
@ -1222,7 +1268,7 @@ class Schema(Expression):
|
|||
arg_types = {"this": False, "expressions": True}
|
||||
|
||||
|
||||
class Select(Subqueryable, Expression):
|
||||
class Select(Subqueryable):
|
||||
arg_types = {
|
||||
"with": False,
|
||||
"expressions": False,
|
||||
|
@ -2075,7 +2121,7 @@ class Bracket(Condition):
|
|||
|
||||
|
||||
class Distinct(Expression):
|
||||
arg_types = {"this": False, "on": False}
|
||||
arg_types = {"expressions": False, "on": False}
|
||||
|
||||
|
||||
class In(Predicate):
|
||||
|
@ -2233,6 +2279,14 @@ class Case(Func):
|
|||
class Cast(Func):
|
||||
arg_types = {"this": True, "to": True}
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
return self.this.name
|
||||
|
||||
@property
|
||||
def to(self):
|
||||
return self.args["to"]
|
||||
|
||||
|
||||
class TryCast(Cast):
|
||||
pass
|
||||
|
@ -2666,7 +2720,7 @@ def _norm_args(expression):
|
|||
else:
|
||||
arg = _norm_arg(arg)
|
||||
|
||||
if arg is not None:
|
||||
if arg is not None and arg is not False:
|
||||
args[k] = arg
|
||||
|
||||
return args
|
||||
|
@ -3012,6 +3066,30 @@ def update(table, properties, where=None, from_=None, dialect=None, **opts):
|
|||
return update
|
||||
|
||||
|
||||
def delete(table, where=None, dialect=None, **opts):
|
||||
"""
|
||||
Builds a delete statement.
|
||||
|
||||
Example:
|
||||
>>> delete("my_table", where="id > 1").sql()
|
||||
'DELETE FROM my_table WHERE id > 1'
|
||||
|
||||
Args:
|
||||
where (str|Condition): sql conditional parsed into a WHERE statement
|
||||
dialect (str): the dialect used to parse the input expressions.
|
||||
**opts: other options to use to parse the input expressions.
|
||||
|
||||
Returns:
|
||||
Delete: the syntax tree for the DELETE statement.
|
||||
"""
|
||||
return Delete(
|
||||
this=maybe_parse(table, into=Table, dialect=dialect, **opts),
|
||||
where=Where(this=where)
|
||||
if isinstance(where, Condition)
|
||||
else maybe_parse(where, into=Where, dialect=dialect, prefix="WHERE", **opts),
|
||||
)
|
||||
|
||||
|
||||
def condition(expression, dialect=None, **opts):
|
||||
"""
|
||||
Initialize a logical condition expression.
|
||||
|
@ -3131,6 +3209,25 @@ def to_identifier(alias, quoted=None):
|
|||
return identifier
|
||||
|
||||
|
||||
def to_table(sql_path, **kwargs):
|
||||
"""
|
||||
Create a table expression from a `[catalog].[schema].[table]` sql path. Catalog and schema are optional.
|
||||
Example:
|
||||
>>> to_table('catalog.db.table_name').sql()
|
||||
'catalog.db.table_name'
|
||||
|
||||
Args:
|
||||
sql_path(str): `[catalog].[schema].[table]` string
|
||||
Returns:
|
||||
Table: A table expression
|
||||
"""
|
||||
table_parts = sql_path.split(".")
|
||||
catalog, db, table_name = [
|
||||
to_identifier(x) if x is not None else x for x in [None] * (3 - len(table_parts)) + table_parts
|
||||
]
|
||||
return Table(this=table_name, db=db, catalog=catalog, **kwargs)
|
||||
|
||||
|
||||
def alias_(expression, alias, table=False, dialect=None, quoted=None, **opts):
|
||||
"""
|
||||
Create an Alias expression.
|
||||
|
@ -3216,6 +3313,28 @@ def table_(table, db=None, catalog=None, quoted=None):
|
|||
)
|
||||
|
||||
|
||||
def values(values, alias=None):
|
||||
"""Build VALUES statement.
|
||||
|
||||
Example:
|
||||
>>> values([(1, '2')]).sql()
|
||||
"VALUES (1, '2')"
|
||||
|
||||
Args:
|
||||
values (list[tuple[str | Expression]]): values statements that will be converted to SQL
|
||||
alias (str): optional alias
|
||||
dialect (str): the dialect used to parse the input expression.
|
||||
**opts: other options to use to parse the input expressions.
|
||||
|
||||
Returns:
|
||||
Values: the Values expression object
|
||||
"""
|
||||
return Values(
|
||||
expressions=[convert(tup) for tup in values],
|
||||
alias=to_identifier(alias) if alias else None,
|
||||
)
|
||||
|
||||
|
||||
def convert(value):
|
||||
"""Convert a python value into an expression object.
|
||||
|
||||
|
@ -3246,6 +3365,12 @@ def convert(value):
|
|||
keys=[convert(k) for k in value.keys()],
|
||||
values=[convert(v) for v in value.values()],
|
||||
)
|
||||
if isinstance(value, datetime.datetime):
|
||||
datetime_literal = Literal.string(value.strftime("%Y-%m-%d %H:%M:%S"))
|
||||
return TimeStrToTime(this=datetime_literal)
|
||||
if isinstance(value, datetime.date):
|
||||
date_literal = Literal.string(value.strftime("%Y-%m-%d"))
|
||||
return DateStrToDate(this=date_literal)
|
||||
raise ValueError(f"Cannot convert {value}")
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue