sqlglotc 30.22.0__tar.gz → 30.24.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.24.0}/PKG-INFO +2 -2
- {sqlglotc-30.22.0 → sqlglotc-30.24.0}/setup.py +17 -0
- {sqlglotc-30.22.0 → sqlglotc-30.24.0}/sqlglot/anonymize.py +1 -0
- {sqlglotc-30.22.0 → sqlglotc-30.24.0}/sqlglot/expressions/array.py +1 -5
- {sqlglotc-30.22.0 → sqlglotc-30.24.0}/sqlglot/expressions/builders.py +54 -5
- {sqlglotc-30.22.0 → sqlglotc-30.24.0}/sqlglot/expressions/constraints.py +1 -0
- {sqlglotc-30.22.0 → sqlglotc-30.24.0}/sqlglot/expressions/core.py +13 -3
- {sqlglotc-30.22.0 → sqlglotc-30.24.0}/sqlglot/expressions/ddl.py +2 -0
- {sqlglotc-30.22.0 → sqlglotc-30.24.0}/sqlglot/expressions/json.py +1 -0
- {sqlglotc-30.22.0 → sqlglotc-30.24.0}/sqlglot/expressions/properties.py +17 -0
- {sqlglotc-30.22.0 → sqlglotc-30.24.0}/sqlglot/expressions/query.py +17 -0
- {sqlglotc-30.22.0 → sqlglotc-30.24.0}/sqlglot/generator.py +44 -2
- {sqlglotc-30.22.0 → sqlglotc-30.24.0}/sqlglot/generators/athena.py +5 -1
- {sqlglotc-30.22.0 → sqlglotc-30.24.0}/sqlglot/generators/bigquery.py +142 -1
- {sqlglotc-30.22.0 → sqlglotc-30.24.0}/sqlglot/generators/clickhouse.py +35 -2
- {sqlglotc-30.22.0 → sqlglotc-30.24.0}/sqlglot/generators/doris.py +6 -0
- {sqlglotc-30.22.0 → sqlglotc-30.24.0}/sqlglot/generators/duckdb.py +45 -42
- {sqlglotc-30.22.0 → sqlglotc-30.24.0}/sqlglot/generators/fabric.py +5 -0
- {sqlglotc-30.22.0 → sqlglotc-30.24.0}/sqlglot/generators/hive.py +4 -0
- {sqlglotc-30.22.0 → sqlglotc-30.24.0}/sqlglot/generators/mysql.py +3 -0
- {sqlglotc-30.22.0 → sqlglotc-30.24.0}/sqlglot/generators/oracle.py +22 -0
- {sqlglotc-30.22.0 → sqlglotc-30.24.0}/sqlglot/generators/postgres.py +8 -3
- {sqlglotc-30.22.0 → sqlglotc-30.24.0}/sqlglot/generators/presto.py +16 -8
- {sqlglotc-30.22.0 → sqlglotc-30.24.0}/sqlglot/generators/snowflake.py +15 -7
- {sqlglotc-30.22.0 → sqlglotc-30.24.0}/sqlglot/generators/spark2.py +24 -2
- {sqlglotc-30.22.0 → sqlglotc-30.24.0}/sqlglot/generators/starrocks.py +56 -4
- {sqlglotc-30.22.0 → sqlglotc-30.24.0}/sqlglot/generators/teradata.py +30 -1
- {sqlglotc-30.22.0 → sqlglotc-30.24.0}/sqlglot/helper.py +17 -0
- {sqlglotc-30.22.0 → sqlglotc-30.24.0}/sqlglot/optimizer/annotate_types.py +24 -16
- {sqlglotc-30.22.0 → sqlglotc-30.24.0}/sqlglot/optimizer/qualify_columns.py +36 -12
- {sqlglotc-30.22.0 → sqlglotc-30.24.0}/sqlglot/optimizer/qualify_tables.py +4 -1
- {sqlglotc-30.22.0 → sqlglotc-30.24.0}/sqlglot/optimizer/scope.py +8 -7
- {sqlglotc-30.22.0 → sqlglotc-30.24.0}/sqlglot/optimizer/simplify.py +23 -5
- {sqlglotc-30.22.0 → sqlglotc-30.24.0}/sqlglot/parser.py +177 -44
- {sqlglotc-30.22.0 → sqlglotc-30.24.0}/sqlglot/parsers/athena.py +8 -0
- {sqlglotc-30.22.0 → sqlglotc-30.24.0}/sqlglot/parsers/clickhouse.py +11 -1
- {sqlglotc-30.22.0 → sqlglotc-30.24.0}/sqlglot/parsers/doris.py +40 -0
- {sqlglotc-30.22.0 → sqlglotc-30.24.0}/sqlglot/parsers/dremio.py +3 -0
- {sqlglotc-30.22.0 → sqlglotc-30.24.0}/sqlglot/parsers/drill.py +3 -0
- {sqlglotc-30.22.0 → sqlglotc-30.24.0}/sqlglot/parsers/duckdb.py +41 -8
- {sqlglotc-30.22.0 → sqlglotc-30.24.0}/sqlglot/parsers/hive.py +13 -0
- {sqlglotc-30.22.0 → sqlglotc-30.24.0}/sqlglot/parsers/mysql.py +84 -3
- {sqlglotc-30.22.0 → sqlglotc-30.24.0}/sqlglot/parsers/oracle.py +80 -3
- {sqlglotc-30.22.0 → sqlglotc-30.24.0}/sqlglot/parsers/postgres.py +4 -1
- {sqlglotc-30.22.0 → sqlglotc-30.24.0}/sqlglot/parsers/presto.py +2 -0
- {sqlglotc-30.22.0 → sqlglotc-30.24.0}/sqlglot/parsers/prql.py +2 -8
- {sqlglotc-30.22.0 → sqlglotc-30.24.0}/sqlglot/parsers/redshift.py +3 -1
- {sqlglotc-30.22.0 → sqlglotc-30.24.0}/sqlglot/parsers/singlestore.py +3 -0
- {sqlglotc-30.22.0 → sqlglotc-30.24.0}/sqlglot/parsers/snowflake.py +4 -4
- {sqlglotc-30.22.0 → sqlglotc-30.24.0}/sqlglot/parsers/spark2.py +11 -5
- {sqlglotc-30.22.0 → sqlglotc-30.24.0}/sqlglot/parsers/sqlite.py +14 -1
- {sqlglotc-30.22.0 → sqlglotc-30.24.0}/sqlglot/parsers/starrocks.py +145 -11
- {sqlglotc-30.22.0 → sqlglotc-30.24.0}/sqlglot/parsers/teradata.py +59 -0
- {sqlglotc-30.22.0 → sqlglotc-30.24.0}/sqlglot/parsers/trino.py +6 -1
- {sqlglotc-30.22.0 → sqlglotc-30.24.0}/sqlglot/tokenizer_core.py +4 -1
- {sqlglotc-30.22.0 → sqlglotc-30.24.0/sqlglotc.egg-info}/PKG-INFO +2 -2
- {sqlglotc-30.22.0 → sqlglotc-30.24.0}/sqlglotc.egg-info/requires.txt +1 -1
- sqlglotc-30.24.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.24.0}/MANIFEST.in +0 -0
- {sqlglotc-30.22.0 → sqlglotc-30.24.0}/pyproject.toml +0 -0
- {sqlglotc-30.22.0 → sqlglotc-30.24.0}/setup.cfg +0 -0
- {sqlglotc-30.22.0 → sqlglotc-30.24.0}/sqlglot/errors.py +0 -0
- {sqlglotc-30.22.0 → sqlglotc-30.24.0}/sqlglot/executor/table.py +0 -0
- {sqlglotc-30.22.0 → sqlglotc-30.24.0}/sqlglot/expressions/aggregate.py +0 -0
- {sqlglotc-30.22.0 → sqlglotc-30.24.0}/sqlglot/expressions/datatypes.py +0 -0
- {sqlglotc-30.22.0 → sqlglotc-30.24.0}/sqlglot/expressions/dml.py +0 -0
- {sqlglotc-30.22.0 → sqlglotc-30.24.0}/sqlglot/expressions/functions.py +0 -0
- {sqlglotc-30.22.0 → sqlglotc-30.24.0}/sqlglot/expressions/math.py +0 -0
- {sqlglotc-30.22.0 → sqlglotc-30.24.0}/sqlglot/expressions/string.py +0 -0
- {sqlglotc-30.22.0 → sqlglotc-30.24.0}/sqlglot/expressions/temporal.py +0 -0
- {sqlglotc-30.22.0 → sqlglotc-30.24.0}/sqlglot/generators/databricks.py +0 -0
- {sqlglotc-30.22.0 → sqlglotc-30.24.0}/sqlglot/generators/dax.py +0 -0
- {sqlglotc-30.22.0 → sqlglotc-30.24.0}/sqlglot/generators/dremio.py +0 -0
- {sqlglotc-30.22.0 → sqlglotc-30.24.0}/sqlglot/generators/drill.py +0 -0
- {sqlglotc-30.22.0 → sqlglotc-30.24.0}/sqlglot/generators/druid.py +0 -0
- {sqlglotc-30.22.0 → sqlglotc-30.24.0}/sqlglot/generators/dune.py +0 -0
- {sqlglotc-30.22.0 → sqlglotc-30.24.0}/sqlglot/generators/exasol.py +0 -0
- {sqlglotc-30.22.0 → sqlglotc-30.24.0}/sqlglot/generators/materialize.py +0 -0
- {sqlglotc-30.22.0 → sqlglotc-30.24.0}/sqlglot/generators/prql.py +0 -0
- {sqlglotc-30.22.0 → sqlglotc-30.24.0}/sqlglot/generators/python.py +0 -0
- {sqlglotc-30.22.0 → sqlglotc-30.24.0}/sqlglot/generators/redshift.py +0 -0
- {sqlglotc-30.22.0 → sqlglotc-30.24.0}/sqlglot/generators/risingwave.py +0 -0
- {sqlglotc-30.22.0 → sqlglotc-30.24.0}/sqlglot/generators/singlestore.py +0 -0
- {sqlglotc-30.22.0 → sqlglotc-30.24.0}/sqlglot/generators/solr.py +0 -0
- {sqlglotc-30.22.0 → sqlglotc-30.24.0}/sqlglot/generators/spark.py +0 -0
- {sqlglotc-30.22.0 → sqlglotc-30.24.0}/sqlglot/generators/sqlite.py +0 -0
- {sqlglotc-30.22.0 → sqlglotc-30.24.0}/sqlglot/generators/tableau.py +0 -0
- {sqlglotc-30.22.0 → sqlglotc-30.24.0}/sqlglot/generators/trino.py +0 -0
- {sqlglotc-30.22.0 → sqlglotc-30.24.0}/sqlglot/generators/tsql.py +0 -0
- {sqlglotc-30.22.0 → sqlglotc-30.24.0}/sqlglot/lineage.py +0 -0
- {sqlglotc-30.22.0 → sqlglotc-30.24.0}/sqlglot/optimizer/canonicalize_internal_names.py +0 -0
- {sqlglotc-30.22.0 → sqlglotc-30.24.0}/sqlglot/optimizer/isolate_table_selects.py +0 -0
- {sqlglotc-30.22.0 → sqlglotc-30.24.0}/sqlglot/optimizer/normalize_identifiers.py +0 -0
- {sqlglotc-30.22.0 → sqlglotc-30.24.0}/sqlglot/optimizer/qualify.py +0 -0
- {sqlglotc-30.22.0 → sqlglotc-30.24.0}/sqlglot/optimizer/resolver.py +0 -0
- {sqlglotc-30.22.0 → sqlglotc-30.24.0}/sqlglot/parsers/base.py +0 -0
- {sqlglotc-30.22.0 → sqlglotc-30.24.0}/sqlglot/parsers/bigquery.py +0 -0
- {sqlglotc-30.22.0 → sqlglotc-30.24.0}/sqlglot/parsers/databricks.py +0 -0
- {sqlglotc-30.22.0 → sqlglotc-30.24.0}/sqlglot/parsers/dax.py +0 -0
- {sqlglotc-30.22.0 → sqlglotc-30.24.0}/sqlglot/parsers/druid.py +0 -0
- {sqlglotc-30.22.0 → sqlglotc-30.24.0}/sqlglot/parsers/dune.py +0 -0
- {sqlglotc-30.22.0 → sqlglotc-30.24.0}/sqlglot/parsers/exasol.py +0 -0
- {sqlglotc-30.22.0 → sqlglotc-30.24.0}/sqlglot/parsers/fabric.py +0 -0
- {sqlglotc-30.22.0 → sqlglotc-30.24.0}/sqlglot/parsers/materialize.py +0 -0
- {sqlglotc-30.22.0 → sqlglotc-30.24.0}/sqlglot/parsers/risingwave.py +0 -0
- {sqlglotc-30.22.0 → sqlglotc-30.24.0}/sqlglot/parsers/solr.py +0 -0
- {sqlglotc-30.22.0 → sqlglotc-30.24.0}/sqlglot/parsers/spark.py +0 -0
- {sqlglotc-30.22.0 → sqlglotc-30.24.0}/sqlglot/parsers/tableau.py +0 -0
- {sqlglotc-30.22.0 → sqlglotc-30.24.0}/sqlglot/parsers/tsql.py +0 -0
- {sqlglotc-30.22.0 → sqlglotc-30.24.0}/sqlglot/serde.py +0 -0
- {sqlglotc-30.22.0 → sqlglotc-30.24.0}/sqlglot/time.py +0 -0
- {sqlglotc-30.22.0 → sqlglotc-30.24.0}/sqlglot/trie.py +0 -0
- {sqlglotc-30.22.0 → sqlglotc-30.24.0}/sqlglotc.egg-info/SOURCES.txt +0 -0
- {sqlglotc-30.22.0 → sqlglotc-30.24.0}/sqlglotc.egg-info/dependency_links.txt +0 -0
- {sqlglotc-30.22.0 → sqlglotc-30.24.0}/sqlglotc.egg-info/scm_file_list.json +0 -0
- {sqlglotc-30.22.0 → sqlglotc-30.24.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.24.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.24.0
|
|
11
11
|
Provides-Extra: dev
|
|
12
12
|
Requires-Dist: setuptools>=61.0; extra == "dev"
|
|
13
13
|
Requires-Dist: setuptools_scm; extra == "dev"
|
|
@@ -90,6 +90,16 @@ def _source_paths():
|
|
|
90
90
|
|
|
91
91
|
|
|
92
92
|
class build_ext(_build_ext):
|
|
93
|
+
def _remove_obsolete_extensions(self, directory, expected):
|
|
94
|
+
if self.dry_run:
|
|
95
|
+
return
|
|
96
|
+
expected = {os.path.abspath(path) for path in expected}
|
|
97
|
+
for root, _, files in os.walk(directory):
|
|
98
|
+
for filename in files:
|
|
99
|
+
path = os.path.join(root, filename)
|
|
100
|
+
if filename.endswith((".so", ".pyd")) and os.path.abspath(path) not in expected:
|
|
101
|
+
self.execute(os.remove, (path,), f"removing obsolete extension {path}")
|
|
102
|
+
|
|
93
103
|
def finalize_options(self):
|
|
94
104
|
super().finalize_options()
|
|
95
105
|
# Compile in parallel by default; builds driven by pip (wheel/sdist installs)
|
|
@@ -97,8 +107,13 @@ class build_ext(_build_ext):
|
|
|
97
107
|
if self.parallel is None:
|
|
98
108
|
self.parallel = os.cpu_count() or 1
|
|
99
109
|
|
|
110
|
+
def build_extensions(self):
|
|
111
|
+
self._remove_obsolete_extensions(self.build_lib, self.get_outputs())
|
|
112
|
+
super().build_extensions()
|
|
113
|
+
|
|
100
114
|
def copy_extensions_to_source(self):
|
|
101
115
|
"""For editable installs, put sqlglot.* .so files in the sqlglot source dir."""
|
|
116
|
+
expected = []
|
|
102
117
|
for ext in self.extensions:
|
|
103
118
|
fullname = self.get_ext_fullname(ext.name)
|
|
104
119
|
filename = self.get_ext_filename(fullname)
|
|
@@ -112,7 +127,9 @@ class build_ext(_build_ext):
|
|
|
112
127
|
# Place the mypyc runtime helper (e.g., HASH__mypyc) inside sqlglot/.
|
|
113
128
|
# sqlglot/__init__.py bootstraps it into sys.modules for editable installs.
|
|
114
129
|
dst = os.path.join(SQLGLOT_SRC, os.path.basename(filename))
|
|
130
|
+
expected.append(dst)
|
|
115
131
|
self.copy_file(src, dst, level=self.verbose)
|
|
132
|
+
self._remove_obsolete_extensions(SQLGLOT_SRC, expected)
|
|
116
133
|
|
|
117
134
|
|
|
118
135
|
class sdist(_sdist):
|
|
@@ -98,17 +98,13 @@ class ArraySlice(Expression, Func):
|
|
|
98
98
|
|
|
99
99
|
|
|
100
100
|
class ArraySort(Expression, Func):
|
|
101
|
-
arg_types = {"this": True, "expression": False}
|
|
101
|
+
arg_types = {"this": True, "expression": False, "asc": False, "nulls_first": False}
|
|
102
102
|
|
|
103
103
|
|
|
104
104
|
class Shuffle(Expression, Func):
|
|
105
105
|
pass
|
|
106
106
|
|
|
107
107
|
|
|
108
|
-
class SortArray(Expression, Func):
|
|
109
|
-
arg_types = {"this": True, "asc": False, "nulls_first": False}
|
|
110
|
-
|
|
111
|
-
|
|
112
108
|
# Array predicates / search
|
|
113
109
|
|
|
114
110
|
|
|
@@ -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):
|
|
@@ -1934,6 +1938,10 @@ class WindowSpec(Expression):
|
|
|
1934
1938
|
}
|
|
1935
1939
|
|
|
1936
1940
|
|
|
1941
|
+
class PartitionByExcluding(Expression):
|
|
1942
|
+
arg_types = {"expressions": True}
|
|
1943
|
+
|
|
1944
|
+
|
|
1937
1945
|
class PreWhere(Expression):
|
|
1938
1946
|
pass
|
|
1939
1947
|
|
|
@@ -2016,6 +2024,10 @@ class DropPartition(Expression):
|
|
|
2016
2024
|
arg_types = {"expressions": True, "exists": False}
|
|
2017
2025
|
|
|
2018
2026
|
|
|
2027
|
+
class ReplaceColumns(Expression):
|
|
2028
|
+
arg_types = {"expressions": True}
|
|
2029
|
+
|
|
2030
|
+
|
|
2019
2031
|
class ReplacePartition(Expression):
|
|
2020
2032
|
arg_types = {"expression": True, "source": True}
|
|
2021
2033
|
|
|
@@ -2047,14 +2059,17 @@ class JSONPathPart(Expression):
|
|
|
2047
2059
|
|
|
2048
2060
|
class JSONPathFilter(JSONPathPart):
|
|
2049
2061
|
arg_types = {"this": True}
|
|
2062
|
+
_hash_raw_args = True
|
|
2050
2063
|
|
|
2051
2064
|
|
|
2052
2065
|
class JSONPathKey(JSONPathPart):
|
|
2053
2066
|
arg_types = {"this": True, "quoted": False}
|
|
2067
|
+
_hash_raw_args = True
|
|
2054
2068
|
|
|
2055
2069
|
|
|
2056
2070
|
class JSONPathRecursive(JSONPathPart):
|
|
2057
2071
|
arg_types = {"this": False}
|
|
2072
|
+
_hash_raw_args = True
|
|
2058
2073
|
|
|
2059
2074
|
|
|
2060
2075
|
class JSONPathRoot(JSONPathPart):
|
|
@@ -2063,6 +2078,7 @@ class JSONPathRoot(JSONPathPart):
|
|
|
2063
2078
|
|
|
2064
2079
|
class JSONPathScript(JSONPathPart):
|
|
2065
2080
|
arg_types = {"this": True}
|
|
2081
|
+
_hash_raw_args = True
|
|
2066
2082
|
|
|
2067
2083
|
|
|
2068
2084
|
class JSONPathSlice(JSONPathPart):
|
|
@@ -2079,6 +2095,7 @@ class JSONPathSubscript(JSONPathPart):
|
|
|
2079
2095
|
|
|
2080
2096
|
class JSONPathUnion(JSONPathPart):
|
|
2081
2097
|
arg_types = {"expressions": True}
|
|
2098
|
+
_hash_raw_args = True
|
|
2082
2099
|
|
|
2083
2100
|
|
|
2084
2101
|
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,
|
|
@@ -2174,6 +2178,7 @@ class Generator:
|
|
|
2174
2178
|
property_name = exp.Properties.PROPERTY_TO_NAME.get(property_cls)
|
|
2175
2179
|
if not property_name:
|
|
2176
2180
|
self.unsupported(f"Unsupported property {expression.key}")
|
|
2181
|
+
return ""
|
|
2177
2182
|
|
|
2178
2183
|
return f"{property_name}={self.sql(expression, 'this')}"
|
|
2179
2184
|
|
|
@@ -2315,6 +2320,10 @@ class Generator:
|
|
|
2315
2320
|
override = " OVERRIDE" if expression.args.get("override") else ""
|
|
2316
2321
|
return f"LOCKING {kind}{this}{for_or_in} {lock_type}{override}"
|
|
2317
2322
|
|
|
2323
|
+
def lockingstatement_sql(self, expression: exp.LockingStatement) -> str:
|
|
2324
|
+
self.unsupported("LOCKING request modifier is not supported")
|
|
2325
|
+
return self.sql(expression, "expression")
|
|
2326
|
+
|
|
2318
2327
|
def withdataproperty_sql(self, expression: exp.WithDataProperty) -> str:
|
|
2319
2328
|
data_sql = f"WITH {'NO ' if expression.args.get('no') else ''}DATA"
|
|
2320
2329
|
statistics = expression.args.get("statistics")
|
|
@@ -2557,6 +2566,10 @@ class Generator:
|
|
|
2557
2566
|
expression: exp.TableSample,
|
|
2558
2567
|
tablesample_keyword: str | None = None,
|
|
2559
2568
|
) -> str:
|
|
2569
|
+
if expression.expressions:
|
|
2570
|
+
self.unsupported("Multiple sample sets are not supported")
|
|
2571
|
+
return ""
|
|
2572
|
+
|
|
2560
2573
|
method = self.sql(expression, "method")
|
|
2561
2574
|
method = f"{method} " if method and self.TABLESAMPLE_WITH_METHOD else ""
|
|
2562
2575
|
numerator = self.sql(expression, "bucket_numerator")
|
|
@@ -3634,6 +3647,9 @@ class Generator:
|
|
|
3634
3647
|
partition = self.expressions(expression, key="partition_by", flat=True)
|
|
3635
3648
|
return f"PARTITION BY {partition}" if partition else ""
|
|
3636
3649
|
|
|
3650
|
+
def partitionbyexcluding_sql(self, expression: exp.PartitionByExcluding) -> str:
|
|
3651
|
+
return f"EXCLUDING {self.expressions(expression, flat=True)}"
|
|
3652
|
+
|
|
3637
3653
|
def windowspec_sql(self, expression: exp.WindowSpec) -> str:
|
|
3638
3654
|
kind = self.sql(expression, "kind")
|
|
3639
3655
|
start = csv(self.sql(expression, "start"), self.sql(expression, "start_side"), sep=" ")
|
|
@@ -3840,6 +3856,8 @@ class Generator:
|
|
|
3840
3856
|
return f"CHECK ({this})"
|
|
3841
3857
|
|
|
3842
3858
|
def foreignkey_sql(self, expression: exp.ForeignKey) -> str:
|
|
3859
|
+
this = self.sql(expression, "this")
|
|
3860
|
+
this = f" {this}" if this else ""
|
|
3843
3861
|
expressions = self.expressions(expression, flat=True)
|
|
3844
3862
|
expressions = f" ({expressions})" if expressions else ""
|
|
3845
3863
|
reference = self.sql(expression, "reference")
|
|
@@ -3850,7 +3868,7 @@ class Generator:
|
|
|
3850
3868
|
update = f" ON UPDATE {update}" if update else ""
|
|
3851
3869
|
options = self.expressions(expression, key="options", flat=True, sep=" ")
|
|
3852
3870
|
options = f" {options}" if options else ""
|
|
3853
|
-
return f"FOREIGN KEY{expressions}{reference}{delete}{update}{options}"
|
|
3871
|
+
return f"FOREIGN KEY{this}{expressions}{reference}{delete}{update}{options}"
|
|
3854
3872
|
|
|
3855
3873
|
def primarykey_sql(self, expression: exp.PrimaryKey) -> str:
|
|
3856
3874
|
this = self.sql(expression, "this")
|
|
@@ -4511,6 +4529,9 @@ class Generator:
|
|
|
4511
4529
|
def addconstraint_sql(self, expression: exp.AddConstraint) -> str:
|
|
4512
4530
|
return f"ADD {self.expressions(expression, indent=False)}"
|
|
4513
4531
|
|
|
4532
|
+
def replacecolumns_sql(self, expression: exp.ReplaceColumns) -> str:
|
|
4533
|
+
return f"REPLACE COLUMNS ({self.expressions(expression, flat=True)})"
|
|
4534
|
+
|
|
4514
4535
|
def addpartition_sql(self, expression: exp.AddPartition) -> str:
|
|
4515
4536
|
exists = "IF NOT EXISTS " if expression.args.get("exists") else ""
|
|
4516
4537
|
location = self.sql(expression, "location")
|
|
@@ -4688,6 +4709,8 @@ class Generator:
|
|
|
4688
4709
|
return self._like_sql(expression)
|
|
4689
4710
|
|
|
4690
4711
|
def match_sql(self, expression: exp.Match) -> str:
|
|
4712
|
+
if expression.args.get("kind") or expression.args.get("analyzer"):
|
|
4713
|
+
self.unsupported("MATCH variants and USING ANALYZER are not supported in this dialect")
|
|
4691
4714
|
return self.binary(expression, "MATCH")
|
|
4692
4715
|
|
|
4693
4716
|
def similarto_sql(self, expression: exp.SimilarTo) -> str:
|
|
@@ -4763,14 +4786,22 @@ class Generator:
|
|
|
4763
4786
|
sqls: list[str] = []
|
|
4764
4787
|
stack: list[None | str | exp.Expr] = [expression]
|
|
4765
4788
|
binary_type = type(expression)
|
|
4789
|
+
is_is = binary_type is exp.Is and op in ("IS", "IS NOT")
|
|
4790
|
+
negate = expression.args.get("negate")
|
|
4766
4791
|
|
|
4767
4792
|
while stack:
|
|
4768
4793
|
node = stack.pop()
|
|
4769
4794
|
|
|
4770
|
-
if type(node) is binary_type
|
|
4795
|
+
if type(node) is binary_type and (
|
|
4796
|
+
node is expression
|
|
4797
|
+
or (is_is and not isinstance(node.expression, exp.Boolean))
|
|
4798
|
+
or node.args.get("negate") == negate
|
|
4799
|
+
):
|
|
4771
4800
|
op_func = node.args.get("operator")
|
|
4772
4801
|
if op_func:
|
|
4773
4802
|
op = f"OPERATOR({self.sql(op_func)})"
|
|
4803
|
+
elif is_is:
|
|
4804
|
+
op = "IS NOT" if node.args.get("negate") else "IS"
|
|
4774
4805
|
|
|
4775
4806
|
stack.append(node.args.get("expression"))
|
|
4776
4807
|
stack.append(f" {self.maybe_comment(op, comments=node.comments)} ")
|
|
@@ -5043,6 +5074,9 @@ class Generator:
|
|
|
5043
5074
|
def dictsubproperty_sql(self, expression: exp.DictSubProperty) -> str:
|
|
5044
5075
|
return f"{self.sql(expression, 'this')} {self.sql(expression, 'value')}"
|
|
5045
5076
|
|
|
5077
|
+
def aggregatekeyproperty_sql(self, expression: exp.AggregateKeyProperty) -> str:
|
|
5078
|
+
return f"AGGREGATE KEY ({self.expressions(expression, flat=True)})"
|
|
5079
|
+
|
|
5046
5080
|
def duplicatekeyproperty_sql(self, expression: exp.DuplicateKeyProperty) -> str:
|
|
5047
5081
|
return f"DUPLICATE KEY ({self.expressions(expression, flat=True)})"
|
|
5048
5082
|
|
|
@@ -5281,6 +5315,7 @@ class Generator:
|
|
|
5281
5315
|
expression_sql = self.sql(expression, "expression")
|
|
5282
5316
|
return f"FOR {this} DO {expression_sql}"
|
|
5283
5317
|
|
|
5318
|
+
@unsupported_args("partition_start", "partition_end", "force", "mode")
|
|
5284
5319
|
def refresh_sql(self, expression: exp.Refresh) -> str:
|
|
5285
5320
|
this = self.sql(expression, "this")
|
|
5286
5321
|
kind = "" if isinstance(expression.this, exp.Literal) else f"{expression.text('kind')} "
|
|
@@ -6041,6 +6076,13 @@ class Generator:
|
|
|
6041
6076
|
exp.TimestampDiff(this=expression.this, expression=start_ts, unit=exp.var("SECONDS"))
|
|
6042
6077
|
)
|
|
6043
6078
|
|
|
6079
|
+
def arraysort_sql(self, expression: exp.ArraySort) -> str:
|
|
6080
|
+
asc = expression.args.get("asc")
|
|
6081
|
+
nulls_first = expression.args.get("nulls_first")
|
|
6082
|
+
if (asc and asc != exp.true()) or (nulls_first and nulls_first != exp.false()):
|
|
6083
|
+
self.unsupported("ARRAY_SORT only sorts ascending with NULLs last")
|
|
6084
|
+
return self.func("ARRAY_SORT", expression.this, expression.expression)
|
|
6085
|
+
|
|
6044
6086
|
def arraysize_sql(self, expression: exp.ArraySize) -> str:
|
|
6045
6087
|
dim = expression.expression
|
|
6046
6088
|
|
|
@@ -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"
|