sqlglotc 30.22.0__tar.gz → 30.23.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.22.0/sqlglotc.egg-info → sqlglotc-30.23.0}/PKG-INFO +2 -2
- {sqlglotc-30.22.0 → sqlglotc-30.23.0}/sqlglot/anonymize.py +1 -0
- {sqlglotc-30.22.0 → sqlglotc-30.23.0}/sqlglot/expressions/builders.py +54 -5
- {sqlglotc-30.22.0 → sqlglotc-30.23.0}/sqlglot/expressions/constraints.py +1 -0
- {sqlglotc-30.22.0 → sqlglotc-30.23.0}/sqlglot/expressions/core.py +13 -3
- {sqlglotc-30.22.0 → sqlglotc-30.23.0}/sqlglot/expressions/ddl.py +2 -0
- {sqlglotc-30.22.0 → sqlglotc-30.23.0}/sqlglot/expressions/json.py +1 -0
- {sqlglotc-30.22.0 → sqlglotc-30.23.0}/sqlglot/expressions/properties.py +17 -0
- {sqlglotc-30.22.0 → sqlglotc-30.23.0}/sqlglot/expressions/query.py +9 -0
- {sqlglotc-30.22.0 → sqlglotc-30.23.0}/sqlglot/generator.py +13 -1
- {sqlglotc-30.22.0 → sqlglotc-30.23.0}/sqlglot/generators/athena.py +5 -1
- {sqlglotc-30.22.0 → sqlglotc-30.23.0}/sqlglot/generators/clickhouse.py +33 -1
- {sqlglotc-30.22.0 → sqlglotc-30.23.0}/sqlglot/generators/doris.py +6 -0
- {sqlglotc-30.22.0 → sqlglotc-30.23.0}/sqlglot/generators/duckdb.py +9 -2
- {sqlglotc-30.22.0 → sqlglotc-30.23.0}/sqlglot/generators/oracle.py +22 -0
- {sqlglotc-30.22.0 → sqlglotc-30.23.0}/sqlglot/generators/presto.py +2 -1
- {sqlglotc-30.22.0 → sqlglotc-30.23.0}/sqlglot/generators/spark2.py +2 -1
- {sqlglotc-30.22.0 → sqlglotc-30.23.0}/sqlglot/generators/starrocks.py +21 -0
- {sqlglotc-30.22.0 → sqlglotc-30.23.0}/sqlglot/generators/teradata.py +19 -0
- {sqlglotc-30.22.0 → sqlglotc-30.23.0}/sqlglot/optimizer/qualify_columns.py +3 -3
- {sqlglotc-30.22.0 → sqlglotc-30.23.0}/sqlglot/optimizer/qualify_tables.py +4 -1
- {sqlglotc-30.22.0 → sqlglotc-30.23.0}/sqlglot/parser.py +32 -12
- {sqlglotc-30.22.0 → sqlglotc-30.23.0}/sqlglot/parsers/athena.py +8 -0
- {sqlglotc-30.22.0 → sqlglotc-30.23.0}/sqlglot/parsers/clickhouse.py +5 -1
- {sqlglotc-30.22.0 → sqlglotc-30.23.0}/sqlglot/parsers/doris.py +40 -0
- {sqlglotc-30.22.0 → sqlglotc-30.23.0}/sqlglot/parsers/duckdb.py +7 -0
- {sqlglotc-30.22.0 → sqlglotc-30.23.0}/sqlglot/parsers/mysql.py +13 -0
- {sqlglotc-30.22.0 → sqlglotc-30.23.0}/sqlglot/parsers/oracle.py +77 -2
- {sqlglotc-30.22.0 → sqlglotc-30.23.0}/sqlglot/parsers/postgres.py +1 -0
- {sqlglotc-30.22.0 → sqlglotc-30.23.0}/sqlglot/parsers/spark2.py +7 -4
- {sqlglotc-30.22.0 → sqlglotc-30.23.0}/sqlglot/parsers/starrocks.py +72 -1
- {sqlglotc-30.22.0 → sqlglotc-30.23.0}/sqlglot/parsers/teradata.py +44 -0
- {sqlglotc-30.22.0 → sqlglotc-30.23.0}/sqlglot/tokenizer_core.py +3 -1
- {sqlglotc-30.22.0 → sqlglotc-30.23.0/sqlglotc.egg-info}/PKG-INFO +2 -2
- {sqlglotc-30.22.0 → sqlglotc-30.23.0}/sqlglotc.egg-info/requires.txt +1 -1
- sqlglotc-30.23.0/sqlglotc.egg-info/scm_version.json +8 -0
- sqlglotc-30.22.0/sqlglotc.egg-info/scm_version.json +0 -8
- {sqlglotc-30.22.0 → sqlglotc-30.23.0}/MANIFEST.in +0 -0
- {sqlglotc-30.22.0 → sqlglotc-30.23.0}/pyproject.toml +0 -0
- {sqlglotc-30.22.0 → sqlglotc-30.23.0}/setup.cfg +0 -0
- {sqlglotc-30.22.0 → sqlglotc-30.23.0}/setup.py +0 -0
- {sqlglotc-30.22.0 → sqlglotc-30.23.0}/sqlglot/errors.py +0 -0
- {sqlglotc-30.22.0 → sqlglotc-30.23.0}/sqlglot/executor/table.py +0 -0
- {sqlglotc-30.22.0 → sqlglotc-30.23.0}/sqlglot/expressions/aggregate.py +0 -0
- {sqlglotc-30.22.0 → sqlglotc-30.23.0}/sqlglot/expressions/array.py +0 -0
- {sqlglotc-30.22.0 → sqlglotc-30.23.0}/sqlglot/expressions/datatypes.py +0 -0
- {sqlglotc-30.22.0 → sqlglotc-30.23.0}/sqlglot/expressions/dml.py +0 -0
- {sqlglotc-30.22.0 → sqlglotc-30.23.0}/sqlglot/expressions/functions.py +0 -0
- {sqlglotc-30.22.0 → sqlglotc-30.23.0}/sqlglot/expressions/math.py +0 -0
- {sqlglotc-30.22.0 → sqlglotc-30.23.0}/sqlglot/expressions/string.py +0 -0
- {sqlglotc-30.22.0 → sqlglotc-30.23.0}/sqlglot/expressions/temporal.py +0 -0
- {sqlglotc-30.22.0 → sqlglotc-30.23.0}/sqlglot/generators/bigquery.py +0 -0
- {sqlglotc-30.22.0 → sqlglotc-30.23.0}/sqlglot/generators/databricks.py +0 -0
- {sqlglotc-30.22.0 → sqlglotc-30.23.0}/sqlglot/generators/dax.py +0 -0
- {sqlglotc-30.22.0 → sqlglotc-30.23.0}/sqlglot/generators/dremio.py +0 -0
- {sqlglotc-30.22.0 → sqlglotc-30.23.0}/sqlglot/generators/drill.py +0 -0
- {sqlglotc-30.22.0 → sqlglotc-30.23.0}/sqlglot/generators/druid.py +0 -0
- {sqlglotc-30.22.0 → sqlglotc-30.23.0}/sqlglot/generators/dune.py +0 -0
- {sqlglotc-30.22.0 → sqlglotc-30.23.0}/sqlglot/generators/exasol.py +0 -0
- {sqlglotc-30.22.0 → sqlglotc-30.23.0}/sqlglot/generators/fabric.py +0 -0
- {sqlglotc-30.22.0 → sqlglotc-30.23.0}/sqlglot/generators/hive.py +0 -0
- {sqlglotc-30.22.0 → sqlglotc-30.23.0}/sqlglot/generators/materialize.py +0 -0
- {sqlglotc-30.22.0 → sqlglotc-30.23.0}/sqlglot/generators/mysql.py +0 -0
- {sqlglotc-30.22.0 → sqlglotc-30.23.0}/sqlglot/generators/postgres.py +0 -0
- {sqlglotc-30.22.0 → sqlglotc-30.23.0}/sqlglot/generators/prql.py +0 -0
- {sqlglotc-30.22.0 → sqlglotc-30.23.0}/sqlglot/generators/python.py +0 -0
- {sqlglotc-30.22.0 → sqlglotc-30.23.0}/sqlglot/generators/redshift.py +0 -0
- {sqlglotc-30.22.0 → sqlglotc-30.23.0}/sqlglot/generators/risingwave.py +0 -0
- {sqlglotc-30.22.0 → sqlglotc-30.23.0}/sqlglot/generators/singlestore.py +0 -0
- {sqlglotc-30.22.0 → sqlglotc-30.23.0}/sqlglot/generators/snowflake.py +0 -0
- {sqlglotc-30.22.0 → sqlglotc-30.23.0}/sqlglot/generators/solr.py +0 -0
- {sqlglotc-30.22.0 → sqlglotc-30.23.0}/sqlglot/generators/spark.py +0 -0
- {sqlglotc-30.22.0 → sqlglotc-30.23.0}/sqlglot/generators/sqlite.py +0 -0
- {sqlglotc-30.22.0 → sqlglotc-30.23.0}/sqlglot/generators/tableau.py +0 -0
- {sqlglotc-30.22.0 → sqlglotc-30.23.0}/sqlglot/generators/trino.py +0 -0
- {sqlglotc-30.22.0 → sqlglotc-30.23.0}/sqlglot/generators/tsql.py +0 -0
- {sqlglotc-30.22.0 → sqlglotc-30.23.0}/sqlglot/helper.py +0 -0
- {sqlglotc-30.22.0 → sqlglotc-30.23.0}/sqlglot/lineage.py +0 -0
- {sqlglotc-30.22.0 → sqlglotc-30.23.0}/sqlglot/optimizer/annotate_types.py +0 -0
- {sqlglotc-30.22.0 → sqlglotc-30.23.0}/sqlglot/optimizer/canonicalize_internal_names.py +0 -0
- {sqlglotc-30.22.0 → sqlglotc-30.23.0}/sqlglot/optimizer/isolate_table_selects.py +0 -0
- {sqlglotc-30.22.0 → sqlglotc-30.23.0}/sqlglot/optimizer/normalize_identifiers.py +0 -0
- {sqlglotc-30.22.0 → sqlglotc-30.23.0}/sqlglot/optimizer/qualify.py +0 -0
- {sqlglotc-30.22.0 → sqlglotc-30.23.0}/sqlglot/optimizer/resolver.py +0 -0
- {sqlglotc-30.22.0 → sqlglotc-30.23.0}/sqlglot/optimizer/scope.py +0 -0
- {sqlglotc-30.22.0 → sqlglotc-30.23.0}/sqlglot/optimizer/simplify.py +0 -0
- {sqlglotc-30.22.0 → sqlglotc-30.23.0}/sqlglot/parsers/base.py +0 -0
- {sqlglotc-30.22.0 → sqlglotc-30.23.0}/sqlglot/parsers/bigquery.py +0 -0
- {sqlglotc-30.22.0 → sqlglotc-30.23.0}/sqlglot/parsers/databricks.py +0 -0
- {sqlglotc-30.22.0 → sqlglotc-30.23.0}/sqlglot/parsers/dax.py +0 -0
- {sqlglotc-30.22.0 → sqlglotc-30.23.0}/sqlglot/parsers/dremio.py +0 -0
- {sqlglotc-30.22.0 → sqlglotc-30.23.0}/sqlglot/parsers/drill.py +0 -0
- {sqlglotc-30.22.0 → sqlglotc-30.23.0}/sqlglot/parsers/druid.py +0 -0
- {sqlglotc-30.22.0 → sqlglotc-30.23.0}/sqlglot/parsers/dune.py +0 -0
- {sqlglotc-30.22.0 → sqlglotc-30.23.0}/sqlglot/parsers/exasol.py +0 -0
- {sqlglotc-30.22.0 → sqlglotc-30.23.0}/sqlglot/parsers/fabric.py +0 -0
- {sqlglotc-30.22.0 → sqlglotc-30.23.0}/sqlglot/parsers/hive.py +0 -0
- {sqlglotc-30.22.0 → sqlglotc-30.23.0}/sqlglot/parsers/materialize.py +0 -0
- {sqlglotc-30.22.0 → sqlglotc-30.23.0}/sqlglot/parsers/presto.py +0 -0
- {sqlglotc-30.22.0 → sqlglotc-30.23.0}/sqlglot/parsers/prql.py +0 -0
- {sqlglotc-30.22.0 → sqlglotc-30.23.0}/sqlglot/parsers/redshift.py +0 -0
- {sqlglotc-30.22.0 → sqlglotc-30.23.0}/sqlglot/parsers/risingwave.py +0 -0
- {sqlglotc-30.22.0 → sqlglotc-30.23.0}/sqlglot/parsers/singlestore.py +0 -0
- {sqlglotc-30.22.0 → sqlglotc-30.23.0}/sqlglot/parsers/snowflake.py +0 -0
- {sqlglotc-30.22.0 → sqlglotc-30.23.0}/sqlglot/parsers/solr.py +0 -0
- {sqlglotc-30.22.0 → sqlglotc-30.23.0}/sqlglot/parsers/spark.py +0 -0
- {sqlglotc-30.22.0 → sqlglotc-30.23.0}/sqlglot/parsers/sqlite.py +0 -0
- {sqlglotc-30.22.0 → sqlglotc-30.23.0}/sqlglot/parsers/tableau.py +0 -0
- {sqlglotc-30.22.0 → sqlglotc-30.23.0}/sqlglot/parsers/trino.py +0 -0
- {sqlglotc-30.22.0 → sqlglotc-30.23.0}/sqlglot/parsers/tsql.py +0 -0
- {sqlglotc-30.22.0 → sqlglotc-30.23.0}/sqlglot/serde.py +0 -0
- {sqlglotc-30.22.0 → sqlglotc-30.23.0}/sqlglot/time.py +0 -0
- {sqlglotc-30.22.0 → sqlglotc-30.23.0}/sqlglot/trie.py +0 -0
- {sqlglotc-30.22.0 → sqlglotc-30.23.0}/sqlglotc.egg-info/SOURCES.txt +0 -0
- {sqlglotc-30.22.0 → sqlglotc-30.23.0}/sqlglotc.egg-info/dependency_links.txt +0 -0
- {sqlglotc-30.22.0 → sqlglotc-30.23.0}/sqlglotc.egg-info/scm_file_list.json +0 -0
- {sqlglotc-30.22.0 → sqlglotc-30.23.0}/sqlglotc.egg-info/top_level.txt +0 -0
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: sqlglotc
|
|
3
|
-
Version: 30.
|
|
3
|
+
Version: 30.23.0
|
|
4
4
|
Summary: mypyc-compiled extensions for sqlglot
|
|
5
5
|
Author-email: Toby Mao <toby.mao@gmail.com>
|
|
6
6
|
License-Expression: MIT
|
|
7
7
|
Project-URL: Homepage, https://sqlglot.com/
|
|
8
8
|
Project-URL: Repository, https://github.com/tobymao/sqlglot
|
|
9
9
|
Requires-Python: >=3.10
|
|
10
|
-
Requires-Dist: sqlglot==30.
|
|
10
|
+
Requires-Dist: sqlglot==30.23.0
|
|
11
11
|
Provides-Extra: dev
|
|
12
12
|
Requires-Dist: setuptools>=61.0; extra == "dev"
|
|
13
13
|
Requires-Dist: setuptools_scm; extra == "dev"
|
|
@@ -10,14 +10,25 @@ from sqlglot.errors import ParseError, TokenError
|
|
|
10
10
|
from sqlglot.expressions.core import (
|
|
11
11
|
Alias,
|
|
12
12
|
Anonymous,
|
|
13
|
+
AtTimeZone,
|
|
14
|
+
Between,
|
|
15
|
+
Binary,
|
|
16
|
+
BitwiseNot,
|
|
13
17
|
Boolean,
|
|
18
|
+
Bracket,
|
|
14
19
|
Column,
|
|
15
20
|
Condition,
|
|
21
|
+
Dot,
|
|
16
22
|
EQ,
|
|
17
23
|
Expr,
|
|
24
|
+
Func,
|
|
18
25
|
Identifier,
|
|
26
|
+
In,
|
|
19
27
|
Literal,
|
|
28
|
+
Neg,
|
|
29
|
+
Not,
|
|
20
30
|
Null,
|
|
31
|
+
Paren,
|
|
21
32
|
Placeholder,
|
|
22
33
|
TABLE_PARTS,
|
|
23
34
|
Var,
|
|
@@ -36,6 +47,8 @@ from sqlglot.expressions.query import (
|
|
|
36
47
|
From,
|
|
37
48
|
Schema,
|
|
38
49
|
Select,
|
|
50
|
+
SetOperation,
|
|
51
|
+
Subquery,
|
|
39
52
|
Table,
|
|
40
53
|
TableAlias,
|
|
41
54
|
Tuple,
|
|
@@ -44,7 +57,7 @@ from sqlglot.expressions.query import (
|
|
|
44
57
|
With,
|
|
45
58
|
Query,
|
|
46
59
|
)
|
|
47
|
-
from sqlglot.expressions.ddl import Alter, AlterRename, RenameColumn
|
|
60
|
+
from sqlglot.expressions.ddl import Alter, AlterRename, Create, RenameColumn
|
|
48
61
|
from sqlglot.expressions.dml import Delete, Insert, Merge, Update, When, Whens
|
|
49
62
|
from sqlglot.expressions.functions import Case, Cast
|
|
50
63
|
from sqlglot.expressions.array import Array
|
|
@@ -53,11 +66,10 @@ from sqlglot.expressions.array import Array
|
|
|
53
66
|
if t.TYPE_CHECKING:
|
|
54
67
|
from collections.abc import Sequence, Iterable, Iterator
|
|
55
68
|
from sqlglot.dialects.dialect import DialectType
|
|
56
|
-
from sqlglot.expressions.core import ExpOrStr
|
|
69
|
+
from sqlglot.expressions.core import ExpOrStr
|
|
57
70
|
from sqlglot.expressions.datatypes import DATA_TYPE
|
|
58
71
|
from sqlglot._typing import ParserArgs, ParserNoDialectArgs, E, P
|
|
59
72
|
from typing_extensions import Unpack, Concatenate
|
|
60
|
-
from sqlglot.expressions.core import Dot
|
|
61
73
|
|
|
62
74
|
|
|
63
75
|
def select(
|
|
@@ -849,6 +861,43 @@ def replace_tables(
|
|
|
849
861
|
return expression.transform(_replace_tables, copy=copy) # type: ignore
|
|
850
862
|
|
|
851
863
|
|
|
864
|
+
OPERATORS = (AtTimeZone, Between, Binary, BitwiseNot, In, Neg, Not)
|
|
865
|
+
|
|
866
|
+
|
|
867
|
+
def _is_operand(placeholder: Placeholder) -> bool:
|
|
868
|
+
parent = placeholder.parent
|
|
869
|
+
if isinstance(parent, (Bracket, In)):
|
|
870
|
+
return placeholder.arg_key == "this"
|
|
871
|
+
return isinstance(parent, OPERATORS)
|
|
872
|
+
|
|
873
|
+
|
|
874
|
+
def _takes_query(placeholder: Placeholder) -> bool:
|
|
875
|
+
parent = placeholder.parent
|
|
876
|
+
if isinstance(parent, In):
|
|
877
|
+
return placeholder.arg_key == "expressions" and len(parent.expressions) == 1
|
|
878
|
+
if isinstance(parent, Func):
|
|
879
|
+
return len(list(parent.iter_expressions())) == 1
|
|
880
|
+
if isinstance(parent, Table):
|
|
881
|
+
return isinstance(parent.parent, (Create, Subquery))
|
|
882
|
+
return not parent or isinstance(parent, (CTE, Paren, SetOperation))
|
|
883
|
+
|
|
884
|
+
|
|
885
|
+
def _replace_placeholder(placeholder: Placeholder, expression: Expr) -> Expr:
|
|
886
|
+
if (
|
|
887
|
+
isinstance(expression, Query)
|
|
888
|
+
and not isinstance(expression, Subquery)
|
|
889
|
+
and not _takes_query(placeholder)
|
|
890
|
+
):
|
|
891
|
+
return expression.subquery(copy=False)
|
|
892
|
+
if (
|
|
893
|
+
_is_operand(placeholder)
|
|
894
|
+
and isinstance(expression, OPERATORS)
|
|
895
|
+
and not isinstance(expression, Dot)
|
|
896
|
+
):
|
|
897
|
+
return Paren(this=expression)
|
|
898
|
+
return expression
|
|
899
|
+
|
|
900
|
+
|
|
852
901
|
def replace_placeholders(expression: Expr, *args: object, **kwargs: t.Any) -> Expr:
|
|
853
902
|
"""Replace placeholders in an expression.
|
|
854
903
|
|
|
@@ -874,10 +923,10 @@ def replace_placeholders(expression: Expr, *args: object, **kwargs: t.Any) -> Ex
|
|
|
874
923
|
if node.this:
|
|
875
924
|
new_name = kwargs.get(node.this)
|
|
876
925
|
if new_name is not None:
|
|
877
|
-
return convert(new_name)
|
|
926
|
+
return _replace_placeholder(node, convert(new_name))
|
|
878
927
|
else:
|
|
879
928
|
try:
|
|
880
|
-
return convert(next(args))
|
|
929
|
+
return _replace_placeholder(node, convert(next(args)))
|
|
881
930
|
except StopIteration:
|
|
882
931
|
pass
|
|
883
932
|
return node
|
|
@@ -867,7 +867,7 @@ class Expression(Expr):
|
|
|
867
867
|
for k in sorted(node.args):
|
|
868
868
|
v = node.args[k]
|
|
869
869
|
if v:
|
|
870
|
-
hash_ = hash((hash_, k, v))
|
|
870
|
+
hash_ = hash((hash_, k, tuple(v) if type(v) is list else v))
|
|
871
871
|
else:
|
|
872
872
|
for k in sorted(node.args):
|
|
873
873
|
v = node.args[k]
|
|
@@ -1595,7 +1595,14 @@ class Uncache(Expression):
|
|
|
1595
1595
|
|
|
1596
1596
|
|
|
1597
1597
|
class Refresh(Expression):
|
|
1598
|
-
arg_types = {
|
|
1598
|
+
arg_types = {
|
|
1599
|
+
"this": True,
|
|
1600
|
+
"kind": True,
|
|
1601
|
+
"partition_start": False,
|
|
1602
|
+
"partition_end": False,
|
|
1603
|
+
"force": False,
|
|
1604
|
+
"mode": False,
|
|
1605
|
+
}
|
|
1599
1606
|
|
|
1600
1607
|
|
|
1601
1608
|
class LockingStatement(Expression):
|
|
@@ -1859,6 +1866,7 @@ class SessionParameter(Expression, Condition):
|
|
|
1859
1866
|
|
|
1860
1867
|
class Placeholder(Expression, Condition):
|
|
1861
1868
|
arg_types = {"this": False, "kind": False, "widget": False, "jdbc": False}
|
|
1869
|
+
_hash_raw_args = True
|
|
1862
1870
|
|
|
1863
1871
|
@property
|
|
1864
1872
|
def name(self) -> str:
|
|
@@ -1994,6 +2002,7 @@ class Typeof(Expression, Func):
|
|
|
1994
2002
|
|
|
1995
2003
|
class ParameterizedAgg(Expression, AggFunc):
|
|
1996
2004
|
arg_types = {"this": True, "expressions": True, "params": True}
|
|
2005
|
+
_hash_raw_args = True
|
|
1997
2006
|
|
|
1998
2007
|
|
|
1999
2008
|
class Anonymous(Expression, Func):
|
|
@@ -2008,6 +2017,7 @@ class Anonymous(Expression, Func):
|
|
|
2008
2017
|
class AnonymousAggFunc(Expression, AggFunc):
|
|
2009
2018
|
arg_types = {"this": True, "expressions": False}
|
|
2010
2019
|
is_var_len_args = True
|
|
2020
|
+
_hash_raw_args = True
|
|
2011
2021
|
|
|
2012
2022
|
|
|
2013
2023
|
class CombinedAggFunc(AnonymousAggFunc):
|
|
@@ -2211,7 +2221,7 @@ class Like(Expression, Binary, Predicate):
|
|
|
2211
2221
|
|
|
2212
2222
|
|
|
2213
2223
|
class Match(Expression, Binary, Predicate):
|
|
2214
|
-
|
|
2224
|
+
arg_types = {"this": True, "expression": True, "kind": False, "analyzer": False}
|
|
2215
2225
|
|
|
2216
2226
|
|
|
2217
2227
|
class LT(Expression, Binary, Predicate):
|
|
@@ -176,6 +176,7 @@ class Set(Expression):
|
|
|
176
176
|
|
|
177
177
|
class Heredoc(Expression):
|
|
178
178
|
arg_types = {"this": True, "tag": False}
|
|
179
|
+
_hash_raw_args = True
|
|
179
180
|
|
|
180
181
|
|
|
181
182
|
class SetItem(Expression):
|
|
@@ -382,6 +383,7 @@ class Undrop(Expression):
|
|
|
382
383
|
|
|
383
384
|
class Command(Expression):
|
|
384
385
|
arg_types = {"this": True, "expression": False}
|
|
386
|
+
_hash_raw_args = True
|
|
385
387
|
|
|
386
388
|
|
|
387
389
|
class Transaction(Expression):
|
|
@@ -25,6 +25,10 @@ class AllowedValuesProperty(Expression):
|
|
|
25
25
|
arg_types = {"expressions": True}
|
|
26
26
|
|
|
27
27
|
|
|
28
|
+
class AggregateKeyProperty(Property):
|
|
29
|
+
arg_types = {"expressions": True}
|
|
30
|
+
|
|
31
|
+
|
|
28
32
|
class AlgorithmProperty(Property):
|
|
29
33
|
arg_types = {"this": True}
|
|
30
34
|
|
|
@@ -123,6 +127,7 @@ class DatabaseProperty(Property):
|
|
|
123
127
|
|
|
124
128
|
class DefinerProperty(Property):
|
|
125
129
|
arg_types = {"this": True}
|
|
130
|
+
_hash_raw_args = True
|
|
126
131
|
|
|
127
132
|
|
|
128
133
|
class DistKeyProperty(Property):
|
|
@@ -390,6 +395,10 @@ class PartitionedOfProperty(Property):
|
|
|
390
395
|
arg_types = {"this": True, "expression": True}
|
|
391
396
|
|
|
392
397
|
|
|
398
|
+
class PhysicalProperty(Property):
|
|
399
|
+
arg_types = {"this": True, "value": False}
|
|
400
|
+
|
|
401
|
+
|
|
393
402
|
class StreamingTableProperty(Property):
|
|
394
403
|
arg_types = {}
|
|
395
404
|
|
|
@@ -497,6 +506,10 @@ class StorageHandlerProperty(Property):
|
|
|
497
506
|
arg_types = {"this": True}
|
|
498
507
|
|
|
499
508
|
|
|
509
|
+
class StorageProperty(Property):
|
|
510
|
+
arg_types = {"expressions": True}
|
|
511
|
+
|
|
512
|
+
|
|
500
513
|
class UsingProperty(Property):
|
|
501
514
|
# kind: JAR, FILE, or ARCHIVE; this: the resource path (string literal)
|
|
502
515
|
arg_types = {"this": True, "kind": True}
|
|
@@ -522,6 +535,10 @@ class Tags(Property, ColumnConstraintKind):
|
|
|
522
535
|
arg_types = {"expressions": True}
|
|
523
536
|
|
|
524
537
|
|
|
538
|
+
class TableSpaceProperty(Property):
|
|
539
|
+
arg_types = {"this": True}
|
|
540
|
+
|
|
541
|
+
|
|
525
542
|
class PropertiesLocation(AutoName):
|
|
526
543
|
POST_CREATE = auto()
|
|
527
544
|
POST_NAME = auto()
|
|
@@ -500,14 +500,17 @@ class HexString(Expression, Condition):
|
|
|
500
500
|
class ByteString(Expression, Condition):
|
|
501
501
|
arg_types = {"this": True, "is_bytes": False}
|
|
502
502
|
is_primitive = True
|
|
503
|
+
_hash_raw_args = True
|
|
503
504
|
|
|
504
505
|
|
|
505
506
|
class RawString(Expression, Condition):
|
|
506
507
|
is_primitive = True
|
|
508
|
+
_hash_raw_args = True
|
|
507
509
|
|
|
508
510
|
|
|
509
511
|
class UnicodeString(Expression, Condition):
|
|
510
512
|
arg_types = {"this": True, "escape": False}
|
|
513
|
+
_hash_raw_args = True
|
|
511
514
|
|
|
512
515
|
|
|
513
516
|
class ColumnPosition(Expression):
|
|
@@ -599,6 +602,7 @@ class Introducer(Expression):
|
|
|
599
602
|
|
|
600
603
|
class National(Expression):
|
|
601
604
|
is_primitive = True
|
|
605
|
+
_hash_raw_args = True
|
|
602
606
|
|
|
603
607
|
|
|
604
608
|
class Partition(Expression):
|
|
@@ -2047,14 +2051,17 @@ class JSONPathPart(Expression):
|
|
|
2047
2051
|
|
|
2048
2052
|
class JSONPathFilter(JSONPathPart):
|
|
2049
2053
|
arg_types = {"this": True}
|
|
2054
|
+
_hash_raw_args = True
|
|
2050
2055
|
|
|
2051
2056
|
|
|
2052
2057
|
class JSONPathKey(JSONPathPart):
|
|
2053
2058
|
arg_types = {"this": True, "quoted": False}
|
|
2059
|
+
_hash_raw_args = True
|
|
2054
2060
|
|
|
2055
2061
|
|
|
2056
2062
|
class JSONPathRecursive(JSONPathPart):
|
|
2057
2063
|
arg_types = {"this": False}
|
|
2064
|
+
_hash_raw_args = True
|
|
2058
2065
|
|
|
2059
2066
|
|
|
2060
2067
|
class JSONPathRoot(JSONPathPart):
|
|
@@ -2063,6 +2070,7 @@ class JSONPathRoot(JSONPathPart):
|
|
|
2063
2070
|
|
|
2064
2071
|
class JSONPathScript(JSONPathPart):
|
|
2065
2072
|
arg_types = {"this": True}
|
|
2073
|
+
_hash_raw_args = True
|
|
2066
2074
|
|
|
2067
2075
|
|
|
2068
2076
|
class JSONPathSlice(JSONPathPart):
|
|
@@ -2079,6 +2087,7 @@ class JSONPathSubscript(JSONPathPart):
|
|
|
2079
2087
|
|
|
2080
2088
|
class JSONPathUnion(JSONPathPart):
|
|
2081
2089
|
arg_types = {"expressions": True}
|
|
2090
|
+
_hash_raw_args = True
|
|
2082
2091
|
|
|
2083
2092
|
|
|
2084
2093
|
class JSONPathWildcard(JSONPathPart):
|
|
@@ -706,6 +706,7 @@ class Generator:
|
|
|
706
706
|
EXPRESSION_PRECEDES_PROPERTIES_CREATABLES: t.ClassVar[set[str]] = set()
|
|
707
707
|
|
|
708
708
|
PROPERTIES_LOCATION: t.ClassVar = {
|
|
709
|
+
exp.AggregateKeyProperty: exp.Properties.Location.POST_SCHEMA,
|
|
709
710
|
exp.AllowedValuesProperty: exp.Properties.Location.POST_SCHEMA,
|
|
710
711
|
exp.AlgorithmProperty: exp.Properties.Location.POST_CREATE,
|
|
711
712
|
exp.ApiProperty: exp.Properties.Location.POST_CREATE,
|
|
@@ -773,6 +774,7 @@ class Generator:
|
|
|
773
774
|
exp.OutputModelProperty: exp.Properties.Location.POST_SCHEMA,
|
|
774
775
|
exp.PartitionedByProperty: exp.Properties.Location.POST_WITH,
|
|
775
776
|
exp.PartitionedOfProperty: exp.Properties.Location.POST_SCHEMA,
|
|
777
|
+
exp.PhysicalProperty: exp.Properties.Location.UNSUPPORTED,
|
|
776
778
|
exp.PrimaryKey: exp.Properties.Location.POST_SCHEMA,
|
|
777
779
|
exp.Property: exp.Properties.Location.POST_WITH,
|
|
778
780
|
exp.RefreshTriggerProperty: exp.Properties.Location.POST_SCHEMA,
|
|
@@ -800,9 +802,11 @@ class Generator:
|
|
|
800
802
|
exp.SqlSecurityProperty: exp.Properties.Location.POST_SCHEMA,
|
|
801
803
|
exp.StabilityProperty: exp.Properties.Location.POST_SCHEMA,
|
|
802
804
|
exp.StorageHandlerProperty: exp.Properties.Location.POST_SCHEMA,
|
|
805
|
+
exp.StorageProperty: exp.Properties.Location.UNSUPPORTED,
|
|
803
806
|
exp.StreamingTableProperty: exp.Properties.Location.POST_CREATE,
|
|
804
807
|
exp.StrictProperty: exp.Properties.Location.POST_SCHEMA,
|
|
805
808
|
exp.Tags: exp.Properties.Location.POST_WITH,
|
|
809
|
+
exp.TableSpaceProperty: exp.Properties.Location.UNSUPPORTED,
|
|
806
810
|
exp.TemporaryProperty: exp.Properties.Location.POST_CREATE,
|
|
807
811
|
exp.ToTableProperty: exp.Properties.Location.POST_SCHEMA,
|
|
808
812
|
exp.TransientProperty: exp.Properties.Location.POST_CREATE,
|
|
@@ -3840,6 +3844,8 @@ class Generator:
|
|
|
3840
3844
|
return f"CHECK ({this})"
|
|
3841
3845
|
|
|
3842
3846
|
def foreignkey_sql(self, expression: exp.ForeignKey) -> str:
|
|
3847
|
+
this = self.sql(expression, "this")
|
|
3848
|
+
this = f" {this}" if this else ""
|
|
3843
3849
|
expressions = self.expressions(expression, flat=True)
|
|
3844
3850
|
expressions = f" ({expressions})" if expressions else ""
|
|
3845
3851
|
reference = self.sql(expression, "reference")
|
|
@@ -3850,7 +3856,7 @@ class Generator:
|
|
|
3850
3856
|
update = f" ON UPDATE {update}" if update else ""
|
|
3851
3857
|
options = self.expressions(expression, key="options", flat=True, sep=" ")
|
|
3852
3858
|
options = f" {options}" if options else ""
|
|
3853
|
-
return f"FOREIGN KEY{expressions}{reference}{delete}{update}{options}"
|
|
3859
|
+
return f"FOREIGN KEY{this}{expressions}{reference}{delete}{update}{options}"
|
|
3854
3860
|
|
|
3855
3861
|
def primarykey_sql(self, expression: exp.PrimaryKey) -> str:
|
|
3856
3862
|
this = self.sql(expression, "this")
|
|
@@ -4688,6 +4694,8 @@ class Generator:
|
|
|
4688
4694
|
return self._like_sql(expression)
|
|
4689
4695
|
|
|
4690
4696
|
def match_sql(self, expression: exp.Match) -> str:
|
|
4697
|
+
if expression.args.get("kind") or expression.args.get("analyzer"):
|
|
4698
|
+
self.unsupported("MATCH variants and USING ANALYZER are not supported in this dialect")
|
|
4691
4699
|
return self.binary(expression, "MATCH")
|
|
4692
4700
|
|
|
4693
4701
|
def similarto_sql(self, expression: exp.SimilarTo) -> str:
|
|
@@ -5043,6 +5051,9 @@ class Generator:
|
|
|
5043
5051
|
def dictsubproperty_sql(self, expression: exp.DictSubProperty) -> str:
|
|
5044
5052
|
return f"{self.sql(expression, 'this')} {self.sql(expression, 'value')}"
|
|
5045
5053
|
|
|
5054
|
+
def aggregatekeyproperty_sql(self, expression: exp.AggregateKeyProperty) -> str:
|
|
5055
|
+
return f"AGGREGATE KEY ({self.expressions(expression, flat=True)})"
|
|
5056
|
+
|
|
5046
5057
|
def duplicatekeyproperty_sql(self, expression: exp.DuplicateKeyProperty) -> str:
|
|
5047
5058
|
return f"DUPLICATE KEY ({self.expressions(expression, flat=True)})"
|
|
5048
5059
|
|
|
@@ -5281,6 +5292,7 @@ class Generator:
|
|
|
5281
5292
|
expression_sql = self.sql(expression, "expression")
|
|
5282
5293
|
return f"FOR {this} DO {expression_sql}"
|
|
5283
5294
|
|
|
5295
|
+
@unsupported_args("partition_start", "partition_end", "force", "mode")
|
|
5284
5296
|
def refresh_sql(self, expression: exp.Refresh) -> str:
|
|
5285
5297
|
this = self.sql(expression, "this")
|
|
5286
5298
|
kind = "" if isinstance(expression.this, exp.Literal) else f"{expression.text('kind')} "
|
|
@@ -54,7 +54,11 @@ def _generate_as_hive(expression: exp.Expr) -> bool:
|
|
|
54
54
|
|
|
55
55
|
# Any CREATE TABLE other than CREATE TABLE ... As <query> is Hive
|
|
56
56
|
if not isinstance(expression.expression, exp.Query):
|
|
57
|
-
|
|
57
|
+
# CTAS with a leading USING EXTERNAL FUNCTION clause is Trino
|
|
58
|
+
return not (
|
|
59
|
+
isinstance(expression.expression, exp.Command)
|
|
60
|
+
and expression.expression.text("this").upper() == "USING"
|
|
61
|
+
)
|
|
58
62
|
else:
|
|
59
63
|
# CREATE VIEW is Trino, but CREATE SCHEMA, CREATE DATABASE, etc, is Hive
|
|
60
64
|
return expression.kind != "VIEW"
|
|
@@ -326,7 +326,7 @@ class ClickHouseGenerator(generator.Generator):
|
|
|
326
326
|
exp.IsNan: rename_func("isNaN"),
|
|
327
327
|
exp.JarowinklerSimilarity: jarowinkler_similarity("jaroWinklerSimilarity"),
|
|
328
328
|
exp.JSONCast: _json_cast_sql,
|
|
329
|
-
exp.JSONExtract: json_extract_segments("
|
|
329
|
+
exp.JSONExtract: json_extract_segments("JSONExtractRaw", quoted_index=False),
|
|
330
330
|
exp.JSONExtractScalar: json_extract_segments("JSONExtractString", quoted_index=False),
|
|
331
331
|
exp.JSONPathKey: json_path_key_only_name,
|
|
332
332
|
exp.JSONPathRoot: lambda *_: "",
|
|
@@ -503,6 +503,14 @@ class ClickHouseGenerator(generator.Generator):
|
|
|
503
503
|
if isinstance(this, exp.StrToDate) and expression.to == exp.DType.DATETIME.into_expr():
|
|
504
504
|
return self.sql(this)
|
|
505
505
|
|
|
506
|
+
this = this.unnest()
|
|
507
|
+
if (
|
|
508
|
+
isinstance(this, exp.JSONExtract)
|
|
509
|
+
and this.args.get("requires_json")
|
|
510
|
+
and expression.to.is_type(*exp.DataType.TEXT_TYPES)
|
|
511
|
+
):
|
|
512
|
+
return self.func("JSONExtract", this, exp.Literal.string("Nullable(String)"))
|
|
513
|
+
|
|
506
514
|
return super().cast_sql(expression, safe_prefix=safe_prefix)
|
|
507
515
|
|
|
508
516
|
def trycast_sql(self, expression: exp.TryCast) -> str:
|
|
@@ -543,6 +551,30 @@ class ClickHouseGenerator(generator.Generator):
|
|
|
543
551
|
def neq_sql(self, expression: exp.NEQ) -> str:
|
|
544
552
|
return self._any_to_has(expression, super().neq_sql, "NOT ")
|
|
545
553
|
|
|
554
|
+
def regexpcount_sql(self, expression: exp.RegexpCount) -> str:
|
|
555
|
+
this = expression.this
|
|
556
|
+
pattern = expression.expression
|
|
557
|
+
position = expression.args.get("position")
|
|
558
|
+
parameters = expression.args.get("parameters")
|
|
559
|
+
|
|
560
|
+
if position:
|
|
561
|
+
# SUBSTRING counts bytes in ClickHouse, the position counts characters
|
|
562
|
+
this = self.func("substringUTF8", this, position)
|
|
563
|
+
|
|
564
|
+
if parameters:
|
|
565
|
+
flags = parameters.name if parameters.is_string else ""
|
|
566
|
+
if not parameters.is_string or set(flags) - set("cims"):
|
|
567
|
+
self.unsupported("Only literal 'c', 'i', 'm' and 's' regexp flags are supported")
|
|
568
|
+
# "c" (case-sensitive) is the default, and the last of "c" and "i" wins
|
|
569
|
+
if flags.rfind("c") > flags.rfind("i"):
|
|
570
|
+
flags = flags.replace("i", "")
|
|
571
|
+
flags = "".join(f for f in flags if f in "ims")
|
|
572
|
+
if flags:
|
|
573
|
+
# countMatches has no flags argument, so they are embedded in the pattern
|
|
574
|
+
pattern = self.func("CONCAT", exp.Literal.string(f"(?{flags})"), pattern)
|
|
575
|
+
|
|
576
|
+
return self.func("countMatches", this, pattern)
|
|
577
|
+
|
|
546
578
|
def regexpilike_sql(self, expression: exp.RegexpILike) -> str:
|
|
547
579
|
# Manually add a flag to make the search case-insensitive
|
|
548
580
|
regex = self.func("CONCAT", "'(?i)'", expression.expression)
|
|
@@ -23,6 +23,12 @@ def _lag_lead_sql(self, expression: exp.Lag | exp.Lead) -> str:
|
|
|
23
23
|
|
|
24
24
|
|
|
25
25
|
class DorisGenerator(MySQLGenerator):
|
|
26
|
+
def match_sql(self, expression: exp.Match) -> str:
|
|
27
|
+
kind = expression.text("kind")
|
|
28
|
+
sql = self.binary(expression, f"MATCH_{kind}" if kind else "MATCH")
|
|
29
|
+
analyzer = self.sql(expression, "analyzer")
|
|
30
|
+
return f"{sql} USING ANALYZER {analyzer}" if analyzer else sql
|
|
31
|
+
|
|
26
32
|
LAST_DAY_SUPPORTS_DATE_PART = False
|
|
27
33
|
SUPPORTS_ALTER_COLUMN_NULLABILITY = False
|
|
28
34
|
VARCHAR_REQUIRES_SIZE = False
|
|
@@ -388,6 +388,10 @@ def _array_insert_sql(self: DuckDBGenerator, expression: exp.ArrayInsert) -> str
|
|
|
388
388
|
|
|
389
389
|
pos_value = position.to_py()
|
|
390
390
|
|
|
391
|
+
# 1-based -1 appends (Spark/Databricks); the 0-based normalization below
|
|
392
|
+
# would otherwise map it onto the prepend branch.
|
|
393
|
+
append = index_offset == 1 and pos_value == -1
|
|
394
|
+
|
|
391
395
|
# Normalize one-based indexing to zero-based for slice calculations
|
|
392
396
|
# Spark (1-based) -> Snowflake (0-based):
|
|
393
397
|
# Positive: pos=1 -> pos=0 (subtract 1)
|
|
@@ -399,7 +403,10 @@ def _array_insert_sql(self: DuckDBGenerator, expression: exp.ArrayInsert) -> str
|
|
|
399
403
|
pos_value = pos_value + index_offset
|
|
400
404
|
|
|
401
405
|
# Build the appropriate list_concat expression based on position
|
|
402
|
-
if
|
|
406
|
+
if append:
|
|
407
|
+
# append at end
|
|
408
|
+
concat_exprs = [this, element_array]
|
|
409
|
+
elif pos_value == 0:
|
|
403
410
|
# insert at beginning
|
|
404
411
|
concat_exprs = [element_array, this]
|
|
405
412
|
elif pos_value > 0:
|
|
@@ -4164,7 +4171,7 @@ class DuckDBGenerator(generator.Generator):
|
|
|
4164
4171
|
this=exp.Transform(
|
|
4165
4172
|
this=expression.this,
|
|
4166
4173
|
expression=exp.Lambda(
|
|
4167
|
-
this=exp.Coalesce(this=x, expressions=[null]),
|
|
4174
|
+
this=exp.Coalesce(this=exp.cast(x, "TEXT"), expressions=[null]),
|
|
4168
4175
|
expressions=[x],
|
|
4169
4176
|
),
|
|
4170
4177
|
),
|
|
@@ -106,13 +106,24 @@ class OracleGenerator(generator.Generator):
|
|
|
106
106
|
exp.UtcTimestamp: rename_func("UTC_TIMESTAMP"),
|
|
107
107
|
exp.UtcTime: rename_func("UTC_TIME"),
|
|
108
108
|
exp.Systimestamp: lambda self, e: "SYSTIMESTAMP",
|
|
109
|
+
exp.TableSpaceProperty: lambda self, e: f"TABLESPACE {self.sql(e, 'this')}",
|
|
109
110
|
}
|
|
110
111
|
|
|
111
112
|
PROPERTIES_LOCATION = {
|
|
112
113
|
**generator.Generator.PROPERTIES_LOCATION,
|
|
113
114
|
exp.VolatileProperty: exp.Properties.Location.UNSUPPORTED,
|
|
115
|
+
exp.TableSpaceProperty: exp.Properties.Location.POST_SCHEMA,
|
|
116
|
+
exp.PhysicalProperty: exp.Properties.Location.POST_SCHEMA,
|
|
117
|
+
exp.StorageProperty: exp.Properties.Location.POST_SCHEMA,
|
|
114
118
|
}
|
|
115
119
|
|
|
120
|
+
def physicalproperty_sql(self, expression: exp.PhysicalProperty) -> str:
|
|
121
|
+
value = self.sql(expression, "value")
|
|
122
|
+
return f"{expression.name}{f' {value}' if value else ''}"
|
|
123
|
+
|
|
124
|
+
def storageproperty_sql(self, expression: exp.StorageProperty) -> str:
|
|
125
|
+
return f"STORAGE ({self.expressions(expression, sep=' ', flat=True)})"
|
|
126
|
+
|
|
116
127
|
def currenttimestamp_sql(self, expression: exp.CurrentTimestamp) -> str:
|
|
117
128
|
if expression.args.get("sysdate"):
|
|
118
129
|
return "SYSDATE"
|
|
@@ -120,6 +131,17 @@ class OracleGenerator(generator.Generator):
|
|
|
120
131
|
this = expression.this
|
|
121
132
|
return self.func("CURRENT_TIMESTAMP", this) if this else "CURRENT_TIMESTAMP"
|
|
122
133
|
|
|
134
|
+
def version_sql(self, expression: exp.Version) -> str:
|
|
135
|
+
if expression.text("kind") == "AS OF":
|
|
136
|
+
value = expression.expression
|
|
137
|
+
value_sql = (
|
|
138
|
+
self.func("TO_TIMESTAMP", value, exp.Literal.string("YYYY-MM-DD HH24:MI:SS.FF6"))
|
|
139
|
+
if expression.name == "TIMESTAMP" and value.is_string
|
|
140
|
+
else self.sql(value)
|
|
141
|
+
)
|
|
142
|
+
return f"AS OF {expression.name} {value_sql}"
|
|
143
|
+
return super().version_sql(expression)
|
|
144
|
+
|
|
123
145
|
def offset_sql(self, expression: exp.Offset) -> str:
|
|
124
146
|
return f"{super().offset_sql(expression)} ROWS"
|
|
125
147
|
|
|
@@ -4,6 +4,7 @@ import typing as t
|
|
|
4
4
|
|
|
5
5
|
from sqlglot import exp, generator, transforms
|
|
6
6
|
from sqlglot.dialects.dialect import (
|
|
7
|
+
array_slice_to_slice_sql,
|
|
7
8
|
bool_xor_sql,
|
|
8
9
|
bracket_to_element_at_sql,
|
|
9
10
|
datestrtodate_sql,
|
|
@@ -324,7 +325,7 @@ class PrestoGenerator(generator.Generator):
|
|
|
324
325
|
exp.ArrayContains: rename_func("CONTAINS"),
|
|
325
326
|
exp.ArrayToString: rename_func("ARRAY_JOIN"),
|
|
326
327
|
exp.ArrayUniqueAgg: rename_func("SET_AGG"),
|
|
327
|
-
exp.ArraySlice:
|
|
328
|
+
exp.ArraySlice: array_slice_to_slice_sql,
|
|
328
329
|
exp.AtTimeZone: rename_func("AT_TIMEZONE"),
|
|
329
330
|
exp.BitwiseAnd: lambda self, e: self.func("BITWISE_AND", e.this, e.expression),
|
|
330
331
|
exp.BitwiseLeftShift: rename_func("BITWISE_LEFT_SHIFT"),
|
|
@@ -4,6 +4,7 @@ import typing as t
|
|
|
4
4
|
|
|
5
5
|
from sqlglot import exp, transforms
|
|
6
6
|
from sqlglot.dialects.dialect import (
|
|
7
|
+
array_slice_to_slice_sql,
|
|
7
8
|
bracket_to_element_at_sql,
|
|
8
9
|
is_parse_json,
|
|
9
10
|
rename_func,
|
|
@@ -139,7 +140,7 @@ class Spark2Generator(HiveGenerator):
|
|
|
139
140
|
f"AGGREGATE({self.sql(e, 'this')}, 0, (acc, x) -> acc + x, acc -> acc)"
|
|
140
141
|
),
|
|
141
142
|
exp.ArrayToString: rename_func("ARRAY_JOIN"),
|
|
142
|
-
exp.ArraySlice:
|
|
143
|
+
exp.ArraySlice: array_slice_to_slice_sql,
|
|
143
144
|
exp.AtTimeZone: lambda self, e: self.func(
|
|
144
145
|
"FROM_UTC_TIMESTAMP", e.this, e.args.get("zone")
|
|
145
146
|
),
|
|
@@ -79,6 +79,7 @@ class StarRocksGenerator(MySQLGenerator):
|
|
|
79
79
|
|
|
80
80
|
TYPE_MAPPING = {
|
|
81
81
|
**MySQLGenerator.TYPE_MAPPING,
|
|
82
|
+
exp.DType.HLLSKETCH: "HLL",
|
|
82
83
|
exp.DType.INT128: "LARGEINT",
|
|
83
84
|
exp.DType.TEXT: "STRING",
|
|
84
85
|
exp.DType.TIMESTAMP: "DATETIME",
|
|
@@ -379,3 +380,23 @@ class StarRocksGenerator(MySQLGenerator):
|
|
|
379
380
|
every = f" EVERY (INTERVAL {every} {unit})" if every and unit else ""
|
|
380
381
|
|
|
381
382
|
return f"REFRESH{method}{kind}{starts}{every}"
|
|
383
|
+
|
|
384
|
+
def refresh_sql(self, expression: exp.Refresh) -> str:
|
|
385
|
+
this = self.sql(expression, "this")
|
|
386
|
+
kind = "" if isinstance(expression.this, exp.Literal) else f"{expression.text('kind')} "
|
|
387
|
+
partition_start = self.sql(expression, "partition_start")
|
|
388
|
+
partition_end = self.sql(expression, "partition_end")
|
|
389
|
+
partition = (
|
|
390
|
+
f" PARTITION START ({partition_start}) END ({partition_end})" if partition_start else ""
|
|
391
|
+
)
|
|
392
|
+
force = " FORCE" if expression.args.get("force") else ""
|
|
393
|
+
mode = self.sql(expression, "mode")
|
|
394
|
+
mode = f" WITH {mode} MODE" if mode else ""
|
|
395
|
+
|
|
396
|
+
return f"REFRESH {kind}{this}{partition}{force}{mode}"
|
|
397
|
+
|
|
398
|
+
def timeslice_sql(self, expression: exp.TimeSlice) -> str:
|
|
399
|
+
interval = exp.Interval(this=expression.expression, unit=expression.unit)
|
|
400
|
+
kind = expression.text("kind").upper()
|
|
401
|
+
boundary = exp.var("CEIL" if kind == "END" else "FLOOR") if kind else None
|
|
402
|
+
return self.func("TIME_SLICE", expression.this, interval, boundary)
|
|
@@ -10,6 +10,7 @@ from sqlglot.dialects.dialect import (
|
|
|
10
10
|
strposition_sql,
|
|
11
11
|
to_number_with_nls_param,
|
|
12
12
|
)
|
|
13
|
+
from sqlglot.parsers.teradata import is_window_aggregate
|
|
13
14
|
from collections import defaultdict
|
|
14
15
|
|
|
15
16
|
|
|
@@ -117,6 +118,24 @@ class TeradataGenerator(generator.Generator):
|
|
|
117
118
|
) -> str:
|
|
118
119
|
return f"{self.sql(expression, 'this')} SAMPLE {self.expressions(expression)}"
|
|
119
120
|
|
|
121
|
+
def window_sql(self, expression: exp.Window) -> str:
|
|
122
|
+
spec = expression.args.get("spec")
|
|
123
|
+
|
|
124
|
+
if (
|
|
125
|
+
spec
|
|
126
|
+
and expression.args.get("order")
|
|
127
|
+
and is_window_aggregate(expression)
|
|
128
|
+
and spec.text("kind").upper() == "ROWS"
|
|
129
|
+
and spec.text("start").upper() == "UNBOUNDED"
|
|
130
|
+
and spec.text("start_side").upper() == "PRECEDING"
|
|
131
|
+
and spec.text("end").upper() == "UNBOUNDED"
|
|
132
|
+
and spec.text("end_side").upper() == "FOLLOWING"
|
|
133
|
+
):
|
|
134
|
+
# This is the default frame of window aggregates with ORDER BY in Teradata
|
|
135
|
+
expression.set("spec", None)
|
|
136
|
+
|
|
137
|
+
return super().window_sql(expression)
|
|
138
|
+
|
|
120
139
|
def partitionedbyproperty_sql(self, expression: exp.PartitionedByProperty) -> str:
|
|
121
140
|
return f"PARTITION BY {self.sql(expression, 'this')}"
|
|
122
141
|
|