sqlglotc 30.8.0__tar.gz → 30.11.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.8.0/sqlglotc.egg-info → sqlglotc-30.11.0}/PKG-INFO +4 -2
- {sqlglotc-30.8.0 → sqlglotc-30.11.0}/pyproject.toml +3 -3
- {sqlglotc-30.8.0 → sqlglotc-30.11.0}/setup.py +33 -0
- {sqlglotc-30.8.0 → sqlglotc-30.11.0}/sqlglot/expressions/aggregate.py +1 -1
- {sqlglotc-30.8.0 → sqlglotc-30.11.0}/sqlglot/expressions/builders.py +6 -1
- {sqlglotc-30.8.0 → sqlglotc-30.11.0}/sqlglot/expressions/core.py +41 -12
- {sqlglotc-30.8.0 → sqlglotc-30.11.0}/sqlglot/expressions/datatypes.py +17 -5
- {sqlglotc-30.8.0 → sqlglotc-30.11.0}/sqlglot/expressions/ddl.py +8 -0
- {sqlglotc-30.8.0 → sqlglotc-30.11.0}/sqlglot/expressions/dml.py +1 -0
- {sqlglotc-30.8.0 → sqlglotc-30.11.0}/sqlglot/expressions/functions.py +10 -1
- {sqlglotc-30.8.0 → sqlglotc-30.11.0}/sqlglot/expressions/properties.py +4 -0
- {sqlglotc-30.8.0 → sqlglotc-30.11.0}/sqlglot/expressions/query.py +12 -4
- {sqlglotc-30.8.0 → sqlglotc-30.11.0}/sqlglot/expressions/string.py +1 -0
- {sqlglotc-30.8.0 → sqlglotc-30.11.0}/sqlglot/generator.py +168 -15
- {sqlglotc-30.8.0 → sqlglotc-30.11.0}/sqlglot/generators/bigquery.py +9 -3
- {sqlglotc-30.8.0 → sqlglotc-30.11.0}/sqlglot/generators/clickhouse.py +1 -1
- {sqlglotc-30.8.0 → sqlglotc-30.11.0}/sqlglot/generators/databricks.py +14 -12
- {sqlglotc-30.8.0 → sqlglotc-30.11.0}/sqlglot/generators/duckdb.py +60 -0
- {sqlglotc-30.8.0 → sqlglotc-30.11.0}/sqlglot/generators/exasol.py +6 -0
- {sqlglotc-30.8.0 → sqlglotc-30.11.0}/sqlglot/generators/mysql.py +37 -0
- {sqlglotc-30.8.0 → sqlglotc-30.11.0}/sqlglot/generators/oracle.py +10 -2
- {sqlglotc-30.8.0 → sqlglotc-30.11.0}/sqlglot/generators/presto.py +2 -6
- {sqlglotc-30.8.0 → sqlglotc-30.11.0}/sqlglot/generators/snowflake.py +0 -3
- {sqlglotc-30.8.0 → sqlglotc-30.11.0}/sqlglot/generators/sqlite.py +39 -10
- {sqlglotc-30.8.0 → sqlglotc-30.11.0}/sqlglot/generators/starrocks.py +5 -2
- {sqlglotc-30.8.0 → sqlglotc-30.11.0}/sqlglot/generators/tsql.py +27 -7
- {sqlglotc-30.8.0 → sqlglotc-30.11.0}/sqlglot/lineage.py +124 -20
- {sqlglotc-30.8.0 → sqlglotc-30.11.0}/sqlglot/optimizer/annotate_types.py +14 -4
- {sqlglotc-30.8.0 → sqlglotc-30.11.0}/sqlglot/optimizer/normalize_identifiers.py +4 -3
- {sqlglotc-30.8.0 → sqlglotc-30.11.0}/sqlglot/optimizer/qualify_columns.py +25 -13
- {sqlglotc-30.8.0 → sqlglotc-30.11.0}/sqlglot/optimizer/resolver.py +6 -4
- {sqlglotc-30.8.0 → sqlglotc-30.11.0}/sqlglot/optimizer/scope.py +32 -8
- {sqlglotc-30.8.0 → sqlglotc-30.11.0}/sqlglot/optimizer/simplify.py +50 -15
- {sqlglotc-30.8.0 → sqlglotc-30.11.0}/sqlglot/parser.py +134 -23
- {sqlglotc-30.8.0 → sqlglotc-30.11.0}/sqlglot/parsers/bigquery.py +33 -6
- {sqlglotc-30.8.0 → sqlglotc-30.11.0}/sqlglot/parsers/clickhouse.py +9 -3
- {sqlglotc-30.8.0 → sqlglotc-30.11.0}/sqlglot/parsers/databricks.py +5 -0
- {sqlglotc-30.8.0 → sqlglotc-30.11.0}/sqlglot/parsers/duckdb.py +1 -0
- {sqlglotc-30.8.0 → sqlglotc-30.11.0}/sqlglot/parsers/oracle.py +21 -0
- {sqlglotc-30.8.0 → sqlglotc-30.11.0}/sqlglot/parsers/snowflake.py +16 -1
- {sqlglotc-30.8.0 → sqlglotc-30.11.0}/sqlglot/parsers/spark2.py +1 -0
- {sqlglotc-30.8.0 → sqlglotc-30.11.0}/sqlglot/parsers/tsql.py +72 -10
- {sqlglotc-30.8.0 → sqlglotc-30.11.0}/sqlglot/serde.py +1 -1
- {sqlglotc-30.8.0 → sqlglotc-30.11.0}/sqlglot/tokenizer_core.py +1 -0
- {sqlglotc-30.8.0 → sqlglotc-30.11.0/sqlglotc.egg-info}/PKG-INFO +4 -2
- sqlglotc-30.11.0/sqlglotc.egg-info/requires.txt +6 -0
- sqlglotc-30.8.0/sqlglotc.egg-info/requires.txt +0 -5
- {sqlglotc-30.8.0 → sqlglotc-30.11.0}/MANIFEST.in +0 -0
- {sqlglotc-30.8.0 → sqlglotc-30.11.0}/setup.cfg +0 -0
- {sqlglotc-30.8.0 → sqlglotc-30.11.0}/sqlglot/errors.py +0 -0
- {sqlglotc-30.8.0 → sqlglotc-30.11.0}/sqlglot/executor/table.py +0 -0
- {sqlglotc-30.8.0 → sqlglotc-30.11.0}/sqlglot/expressions/array.py +0 -0
- {sqlglotc-30.8.0 → sqlglotc-30.11.0}/sqlglot/expressions/constraints.py +0 -0
- {sqlglotc-30.8.0 → sqlglotc-30.11.0}/sqlglot/expressions/json.py +0 -0
- {sqlglotc-30.8.0 → sqlglotc-30.11.0}/sqlglot/expressions/math.py +0 -0
- {sqlglotc-30.8.0 → sqlglotc-30.11.0}/sqlglot/expressions/temporal.py +0 -0
- {sqlglotc-30.8.0 → sqlglotc-30.11.0}/sqlglot/generators/athena.py +0 -0
- {sqlglotc-30.8.0 → sqlglotc-30.11.0}/sqlglot/generators/doris.py +0 -0
- {sqlglotc-30.8.0 → sqlglotc-30.11.0}/sqlglot/generators/dremio.py +0 -0
- {sqlglotc-30.8.0 → sqlglotc-30.11.0}/sqlglot/generators/drill.py +0 -0
- {sqlglotc-30.8.0 → sqlglotc-30.11.0}/sqlglot/generators/druid.py +0 -0
- {sqlglotc-30.8.0 → sqlglotc-30.11.0}/sqlglot/generators/dune.py +0 -0
- {sqlglotc-30.8.0 → sqlglotc-30.11.0}/sqlglot/generators/fabric.py +0 -0
- {sqlglotc-30.8.0 → sqlglotc-30.11.0}/sqlglot/generators/hive.py +0 -0
- {sqlglotc-30.8.0 → sqlglotc-30.11.0}/sqlglot/generators/materialize.py +0 -0
- {sqlglotc-30.8.0 → sqlglotc-30.11.0}/sqlglot/generators/postgres.py +0 -0
- {sqlglotc-30.8.0 → sqlglotc-30.11.0}/sqlglot/generators/prql.py +0 -0
- {sqlglotc-30.8.0 → sqlglotc-30.11.0}/sqlglot/generators/python.py +0 -0
- {sqlglotc-30.8.0 → sqlglotc-30.11.0}/sqlglot/generators/redshift.py +0 -0
- {sqlglotc-30.8.0 → sqlglotc-30.11.0}/sqlglot/generators/risingwave.py +0 -0
- {sqlglotc-30.8.0 → sqlglotc-30.11.0}/sqlglot/generators/singlestore.py +0 -0
- {sqlglotc-30.8.0 → sqlglotc-30.11.0}/sqlglot/generators/solr.py +0 -0
- {sqlglotc-30.8.0 → sqlglotc-30.11.0}/sqlglot/generators/spark.py +0 -0
- {sqlglotc-30.8.0 → sqlglotc-30.11.0}/sqlglot/generators/spark2.py +0 -0
- {sqlglotc-30.8.0 → sqlglotc-30.11.0}/sqlglot/generators/tableau.py +0 -0
- {sqlglotc-30.8.0 → sqlglotc-30.11.0}/sqlglot/generators/teradata.py +0 -0
- {sqlglotc-30.8.0 → sqlglotc-30.11.0}/sqlglot/generators/trino.py +0 -0
- {sqlglotc-30.8.0 → sqlglotc-30.11.0}/sqlglot/helper.py +0 -0
- {sqlglotc-30.8.0 → sqlglotc-30.11.0}/sqlglot/optimizer/canonicalize_internal_names.py +0 -0
- {sqlglotc-30.8.0 → sqlglotc-30.11.0}/sqlglot/optimizer/isolate_table_selects.py +0 -0
- {sqlglotc-30.8.0 → sqlglotc-30.11.0}/sqlglot/optimizer/qualify.py +0 -0
- {sqlglotc-30.8.0 → sqlglotc-30.11.0}/sqlglot/optimizer/qualify_tables.py +0 -0
- {sqlglotc-30.8.0 → sqlglotc-30.11.0}/sqlglot/parsers/athena.py +0 -0
- {sqlglotc-30.8.0 → sqlglotc-30.11.0}/sqlglot/parsers/base.py +0 -0
- {sqlglotc-30.8.0 → sqlglotc-30.11.0}/sqlglot/parsers/doris.py +0 -0
- {sqlglotc-30.8.0 → sqlglotc-30.11.0}/sqlglot/parsers/dremio.py +0 -0
- {sqlglotc-30.8.0 → sqlglotc-30.11.0}/sqlglot/parsers/drill.py +0 -0
- {sqlglotc-30.8.0 → sqlglotc-30.11.0}/sqlglot/parsers/druid.py +0 -0
- {sqlglotc-30.8.0 → sqlglotc-30.11.0}/sqlglot/parsers/dune.py +0 -0
- {sqlglotc-30.8.0 → sqlglotc-30.11.0}/sqlglot/parsers/exasol.py +0 -0
- {sqlglotc-30.8.0 → sqlglotc-30.11.0}/sqlglot/parsers/fabric.py +0 -0
- {sqlglotc-30.8.0 → sqlglotc-30.11.0}/sqlglot/parsers/hive.py +0 -0
- {sqlglotc-30.8.0 → sqlglotc-30.11.0}/sqlglot/parsers/materialize.py +0 -0
- {sqlglotc-30.8.0 → sqlglotc-30.11.0}/sqlglot/parsers/mysql.py +0 -0
- {sqlglotc-30.8.0 → sqlglotc-30.11.0}/sqlglot/parsers/postgres.py +0 -0
- {sqlglotc-30.8.0 → sqlglotc-30.11.0}/sqlglot/parsers/presto.py +0 -0
- {sqlglotc-30.8.0 → sqlglotc-30.11.0}/sqlglot/parsers/prql.py +0 -0
- {sqlglotc-30.8.0 → sqlglotc-30.11.0}/sqlglot/parsers/redshift.py +0 -0
- {sqlglotc-30.8.0 → sqlglotc-30.11.0}/sqlglot/parsers/risingwave.py +0 -0
- {sqlglotc-30.8.0 → sqlglotc-30.11.0}/sqlglot/parsers/singlestore.py +0 -0
- {sqlglotc-30.8.0 → sqlglotc-30.11.0}/sqlglot/parsers/solr.py +0 -0
- {sqlglotc-30.8.0 → sqlglotc-30.11.0}/sqlglot/parsers/spark.py +0 -0
- {sqlglotc-30.8.0 → sqlglotc-30.11.0}/sqlglot/parsers/sqlite.py +0 -0
- {sqlglotc-30.8.0 → sqlglotc-30.11.0}/sqlglot/parsers/starrocks.py +0 -0
- {sqlglotc-30.8.0 → sqlglotc-30.11.0}/sqlglot/parsers/tableau.py +0 -0
- {sqlglotc-30.8.0 → sqlglotc-30.11.0}/sqlglot/parsers/teradata.py +0 -0
- {sqlglotc-30.8.0 → sqlglotc-30.11.0}/sqlglot/parsers/trino.py +0 -0
- {sqlglotc-30.8.0 → sqlglotc-30.11.0}/sqlglot/schema.py +0 -0
- {sqlglotc-30.8.0 → sqlglotc-30.11.0}/sqlglot/time.py +0 -0
- {sqlglotc-30.8.0 → sqlglotc-30.11.0}/sqlglot/trie.py +0 -0
- {sqlglotc-30.8.0 → sqlglotc-30.11.0}/sqlglotc.egg-info/SOURCES.txt +0 -0
- {sqlglotc-30.8.0 → sqlglotc-30.11.0}/sqlglotc.egg-info/dependency_links.txt +0 -0
- {sqlglotc-30.8.0 → sqlglotc-30.11.0}/sqlglotc.egg-info/top_level.txt +0 -0
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: sqlglotc
|
|
3
|
-
Version: 30.
|
|
3
|
+
Version: 30.11.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.11.0
|
|
10
11
|
Provides-Extra: dev
|
|
11
12
|
Requires-Dist: setuptools>=61.0; extra == "dev"
|
|
12
13
|
Requires-Dist: setuptools_scm; extra == "dev"
|
|
13
|
-
Requires-Dist: sqlglot-mypy>=1.
|
|
14
|
+
Requires-Dist: sqlglot-mypy>=2.1.0.post2; extra == "dev"
|
|
15
|
+
Dynamic: requires-dist
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "sqlglotc"
|
|
3
|
-
dynamic = ["version"]
|
|
3
|
+
dynamic = ["version", "dependencies"]
|
|
4
4
|
description = "mypyc-compiled extensions for sqlglot"
|
|
5
5
|
authors = [{ name = "Toby Mao", email = "toby.mao@gmail.com" }]
|
|
6
6
|
license = "MIT"
|
|
7
7
|
requires-python = ">= 3.10"
|
|
8
8
|
|
|
9
9
|
[project.optional-dependencies]
|
|
10
|
-
dev = ["setuptools >= 61.0", "setuptools_scm", "sqlglot-mypy >= 1.
|
|
10
|
+
dev = ["setuptools >= 61.0", "setuptools_scm", "sqlglot-mypy >= 2.1.0.post2"]
|
|
11
11
|
|
|
12
12
|
[project.urls]
|
|
13
13
|
Homepage = "https://sqlglot.com/"
|
|
@@ -17,7 +17,7 @@ Repository = "https://github.com/tobymao/sqlglot"
|
|
|
17
17
|
requires = [
|
|
18
18
|
"setuptools >= 61.0",
|
|
19
19
|
"setuptools_scm",
|
|
20
|
-
"sqlglot-mypy >= 1.
|
|
20
|
+
"sqlglot-mypy >= 2.1.0.post2",
|
|
21
21
|
"types-python-dateutil",
|
|
22
22
|
"sqlglot",
|
|
23
23
|
]
|
|
@@ -128,9 +128,42 @@ class sdist(_sdist):
|
|
|
128
128
|
shutil.rmtree(local_sqlglot, ignore_errors=True)
|
|
129
129
|
|
|
130
130
|
|
|
131
|
+
def _sqlglot_requirement():
|
|
132
|
+
"""Pin sqlglot to the matching version so resolvers keep the two packages in lockstep."""
|
|
133
|
+
try:
|
|
134
|
+
pkg_info = os.path.join(os.path.dirname(os.path.abspath(__file__)), "PKG-INFO")
|
|
135
|
+
if os.path.isfile(pkg_info):
|
|
136
|
+
# Building from an sdist: no git metadata; the released version is frozen in PKG-INFO.
|
|
137
|
+
with open(pkg_info, encoding="utf-8") as fd:
|
|
138
|
+
version = next(
|
|
139
|
+
(line.split(":", 1)[1].strip() for line in fd if line.startswith("Version:")),
|
|
140
|
+
"",
|
|
141
|
+
)
|
|
142
|
+
else:
|
|
143
|
+
from setuptools_scm import get_version
|
|
144
|
+
|
|
145
|
+
version = get_version(
|
|
146
|
+
root="..",
|
|
147
|
+
relative_to=__file__,
|
|
148
|
+
local_scheme="no-local-version",
|
|
149
|
+
fallback_version="0.0.0",
|
|
150
|
+
)
|
|
151
|
+
except Exception as e:
|
|
152
|
+
print(f"sqlglotc: failed to determine the sqlglot version to pin: {e}")
|
|
153
|
+
version = ""
|
|
154
|
+
|
|
155
|
+
# Dev and fallback (no git metadata) builds have no matching sqlglot release on PyPI;
|
|
156
|
+
# depend on sqlglot unpinned since the extensions can't be imported without it.
|
|
157
|
+
if version in ("", "0.0.0") or ".dev" in version:
|
|
158
|
+
return ["sqlglot"]
|
|
159
|
+
|
|
160
|
+
return [f"sqlglot=={version}"]
|
|
161
|
+
|
|
162
|
+
|
|
131
163
|
setup(
|
|
132
164
|
name="sqlglotc",
|
|
133
165
|
packages=[],
|
|
166
|
+
install_requires=_sqlglot_requirement(),
|
|
134
167
|
ext_modules=mypycify(
|
|
135
168
|
_source_paths(), opt_level=os.environ.get("MYPYC_OPT", "2"), separate=True, verbose=True
|
|
136
169
|
),
|
|
@@ -319,6 +319,11 @@ def parse_identifier(name: str | Identifier, dialect: DialectType = None) -> Ide
|
|
|
319
319
|
Returns:
|
|
320
320
|
The identifier ast node.
|
|
321
321
|
"""
|
|
322
|
+
if isinstance(name, str) and SAFE_IDENTIFIER_RE.match(name):
|
|
323
|
+
# Simple names parse to a single unquoted identifier in all dialects, so we can
|
|
324
|
+
# avoid the tokenizer/parser round-trip for them.
|
|
325
|
+
return Identifier(this=name, quoted=False)
|
|
326
|
+
|
|
322
327
|
try:
|
|
323
328
|
expression = maybe_parse(name, dialect=dialect, into=Identifier)
|
|
324
329
|
except (ParseError, TokenError):
|
|
@@ -822,7 +827,7 @@ def replace_tables(
|
|
|
822
827
|
mapping = {normalize_table_name(k, dialect=dialect): v for k, v in mapping.items()}
|
|
823
828
|
|
|
824
829
|
def _replace_tables(node: Expr) -> Expr:
|
|
825
|
-
if isinstance(node, Table) and node.
|
|
830
|
+
if isinstance(node, Table) and node.meta_get("replace") is not False:
|
|
826
831
|
original = normalize_table_name(node, dialect=dialect)
|
|
827
832
|
new_name = mapping.get(original)
|
|
828
833
|
|
|
@@ -88,6 +88,7 @@ class Expr:
|
|
|
88
88
|
_hash_raw_args: t.ClassVar[bool] = False
|
|
89
89
|
is_subquery: t.ClassVar[bool] = False
|
|
90
90
|
is_cast: t.ClassVar[bool] = False
|
|
91
|
+
is_data_type: t.ClassVar[bool] = False
|
|
91
92
|
|
|
92
93
|
args: dict[str, t.Any]
|
|
93
94
|
parent: Expr | None
|
|
@@ -239,6 +240,9 @@ class Expr:
|
|
|
239
240
|
def meta(self) -> dict[str, t.Any]:
|
|
240
241
|
raise NotImplementedError
|
|
241
242
|
|
|
243
|
+
def meta_get(self, key: str, default: t.Any = None) -> t.Any:
|
|
244
|
+
raise NotImplementedError
|
|
245
|
+
|
|
242
246
|
def __deepcopy__(self, memo: t.Any) -> Expr:
|
|
243
247
|
raise NotImplementedError
|
|
244
248
|
|
|
@@ -837,26 +841,35 @@ class Expression(Expr):
|
|
|
837
841
|
def __hash__(self) -> int:
|
|
838
842
|
if self._hash is None:
|
|
839
843
|
nodes: list[Expr] = []
|
|
840
|
-
|
|
841
|
-
queue.append(self)
|
|
844
|
+
stack: list[Expr] = [self]
|
|
842
845
|
|
|
843
|
-
|
|
844
|
-
|
|
846
|
+
# Collect nodes, finding child expressions inline instead of via the
|
|
847
|
+
# iter_expressions generator (whose per-node generator object dominates the
|
|
848
|
+
# hash's cost). reversed(nodes) is a valid post-order regardless of DFS/BFS.
|
|
849
|
+
while stack:
|
|
850
|
+
node = stack.pop()
|
|
845
851
|
nodes.append(node)
|
|
846
852
|
|
|
847
|
-
for
|
|
848
|
-
if
|
|
849
|
-
|
|
853
|
+
for v in node.args.values():
|
|
854
|
+
if isinstance(v, Expr):
|
|
855
|
+
if v._hash is None:
|
|
856
|
+
stack.append(v)
|
|
857
|
+
elif type(v) is list:
|
|
858
|
+
for x in v:
|
|
859
|
+
if isinstance(x, Expr) and x._hash is None:
|
|
860
|
+
stack.append(x)
|
|
850
861
|
|
|
851
862
|
for node in reversed(nodes):
|
|
852
863
|
hash_ = hash(node.key)
|
|
853
864
|
|
|
854
865
|
if node._hash_raw_args:
|
|
855
|
-
for k
|
|
866
|
+
for k in sorted(node.args):
|
|
867
|
+
v = node.args[k]
|
|
856
868
|
if v:
|
|
857
869
|
hash_ = hash((hash_, k, v))
|
|
858
870
|
else:
|
|
859
|
-
for k
|
|
871
|
+
for k in sorted(node.args):
|
|
872
|
+
v = node.args[k]
|
|
860
873
|
vt = type(v)
|
|
861
874
|
|
|
862
875
|
if vt is list:
|
|
@@ -953,6 +966,8 @@ class Expression(Expr):
|
|
|
953
966
|
|
|
954
967
|
@property
|
|
955
968
|
def type(self) -> DataType | None:
|
|
969
|
+
if self.is_data_type:
|
|
970
|
+
return self # type: ignore[return-value]
|
|
956
971
|
if self.is_cast:
|
|
957
972
|
return self._type or self.to # type: ignore[attr-defined]
|
|
958
973
|
return self._type
|
|
@@ -978,6 +993,11 @@ class Expression(Expr):
|
|
|
978
993
|
self._meta = {}
|
|
979
994
|
return self._meta
|
|
980
995
|
|
|
996
|
+
def meta_get(self, key: str, default: t.Any = None) -> t.Any:
|
|
997
|
+
"""Reads a meta value without allocating the meta dict (unlike the `meta` property)."""
|
|
998
|
+
meta = self._meta
|
|
999
|
+
return meta.get(key, default) if meta is not None else default
|
|
1000
|
+
|
|
981
1001
|
def __deepcopy__(self, memo: t.Any) -> Expr:
|
|
982
1002
|
root = self.__class__()
|
|
983
1003
|
stack: list[tuple[Expr, Expr]] = [(self, root)]
|
|
@@ -1039,6 +1059,11 @@ class Expression(Expr):
|
|
|
1039
1059
|
return comments
|
|
1040
1060
|
|
|
1041
1061
|
def append(self, arg_key: str, value: t.Any) -> None:
|
|
1062
|
+
node: Expr | None = self
|
|
1063
|
+
while node and node._hash is not None:
|
|
1064
|
+
node._hash = None
|
|
1065
|
+
node = node.parent
|
|
1066
|
+
|
|
1042
1067
|
if type(self.args.get(arg_key)) is not list:
|
|
1043
1068
|
self.args[arg_key] = []
|
|
1044
1069
|
self._set_parent(arg_key, value)
|
|
@@ -2118,6 +2143,10 @@ class Distance(Expression, Binary):
|
|
|
2118
2143
|
pass
|
|
2119
2144
|
|
|
2120
2145
|
|
|
2146
|
+
class DistanceNd(Expression, Binary):
|
|
2147
|
+
pass
|
|
2148
|
+
|
|
2149
|
+
|
|
2121
2150
|
class Escape(Expression, Binary):
|
|
2122
2151
|
pass
|
|
2123
2152
|
|
|
@@ -2269,8 +2298,7 @@ class Or(Expression, Connector, Func):
|
|
|
2269
2298
|
|
|
2270
2299
|
|
|
2271
2300
|
class Xor(Expression, Connector, Func):
|
|
2272
|
-
arg_types = {"this":
|
|
2273
|
-
is_var_len_args = True
|
|
2301
|
+
arg_types = {"this": True, "expression": True, "round_input": False}
|
|
2274
2302
|
|
|
2275
2303
|
|
|
2276
2304
|
class Pow(Expression, Binary, Func):
|
|
@@ -2428,6 +2456,7 @@ QUERY_MODIFIERS = {
|
|
|
2428
2456
|
"settings": False,
|
|
2429
2457
|
"format": False,
|
|
2430
2458
|
"options": False,
|
|
2459
|
+
"for_": False,
|
|
2431
2460
|
}
|
|
2432
2461
|
|
|
2433
2462
|
|
|
@@ -2534,7 +2563,7 @@ def _to_s(node: t.Any, verbose: bool = False, level: int = 0, repr_str: bool = F
|
|
|
2534
2563
|
if isinstance(node, Expr):
|
|
2535
2564
|
args = {k: v for k, v in node.args.items() if (v is not None and v != []) or verbose}
|
|
2536
2565
|
|
|
2537
|
-
if (node.type or verbose) and
|
|
2566
|
+
if (node.type or verbose) and not node.is_data_type:
|
|
2538
2567
|
args["_type"] = node.type
|
|
2539
2568
|
if node.comments or verbose:
|
|
2540
2569
|
args["_comments"] = node.comments
|
|
@@ -8,6 +8,7 @@ from enum import auto
|
|
|
8
8
|
from sqlglot.helper import AutoName
|
|
9
9
|
from sqlglot.errors import ErrorLevel, ParseError
|
|
10
10
|
from sqlglot.expressions.core import (
|
|
11
|
+
Expr,
|
|
11
12
|
Expression,
|
|
12
13
|
_TimeUnit,
|
|
13
14
|
Identifier,
|
|
@@ -17,13 +18,18 @@ from sqlglot.expressions.core import (
|
|
|
17
18
|
from builtins import type as Type
|
|
18
19
|
|
|
19
20
|
if t.TYPE_CHECKING:
|
|
21
|
+
from sqlglot._typing import DataTypeArgs
|
|
20
22
|
from sqlglot.dialects.dialect import DialectType
|
|
21
|
-
from typing_extensions import Self
|
|
23
|
+
from typing_extensions import Self, Unpack
|
|
22
24
|
|
|
23
25
|
|
|
24
26
|
class DataTypeParam(Expression):
|
|
25
27
|
arg_types = {"this": True, "expression": False}
|
|
26
28
|
|
|
29
|
+
@property
|
|
30
|
+
def this(self) -> Expr:
|
|
31
|
+
return self.args["this"]
|
|
32
|
+
|
|
27
33
|
@property
|
|
28
34
|
def name(self) -> str:
|
|
29
35
|
return self.this.name
|
|
@@ -181,6 +187,8 @@ class DataType(Expression):
|
|
|
181
187
|
"collate": False,
|
|
182
188
|
}
|
|
183
189
|
|
|
190
|
+
is_data_type: t.ClassVar[bool] = True
|
|
191
|
+
|
|
184
192
|
Type: t.ClassVar[Type[DType]] = DType
|
|
185
193
|
|
|
186
194
|
STRUCT_TYPES: t.ClassVar[set[DType]] = {
|
|
@@ -331,7 +339,7 @@ class DataType(Expression):
|
|
|
331
339
|
dialect: DialectType = None,
|
|
332
340
|
udt: bool = False,
|
|
333
341
|
copy: bool = True,
|
|
334
|
-
**kwargs:
|
|
342
|
+
**kwargs: Unpack[DataTypeArgs],
|
|
335
343
|
) -> Self:
|
|
336
344
|
"""
|
|
337
345
|
Constructs a DataType object.
|
|
@@ -364,7 +372,11 @@ class DataType(Expression):
|
|
|
364
372
|
|
|
365
373
|
@classmethod
|
|
366
374
|
def from_str(
|
|
367
|
-
cls,
|
|
375
|
+
cls,
|
|
376
|
+
dtype: str,
|
|
377
|
+
dialect: DialectType = None,
|
|
378
|
+
udt: bool = False,
|
|
379
|
+
**kwargs: Unpack[DataTypeArgs],
|
|
368
380
|
) -> Self:
|
|
369
381
|
"""
|
|
370
382
|
Constructs a `DataType` object from a `str` representation.
|
|
@@ -405,10 +417,10 @@ class DataType(Expression):
|
|
|
405
417
|
Returns:
|
|
406
418
|
True, if and only if there is a type in `dtypes` which is equal to this DataType.
|
|
407
419
|
"""
|
|
408
|
-
self_is_nullable = self.args.get("nullable")
|
|
420
|
+
self_is_nullable: bool | None = self.args.get("nullable")
|
|
409
421
|
for dtype in dtypes:
|
|
410
422
|
other_type = DataType.build(dtype, copy=False, udt=True)
|
|
411
|
-
other_is_nullable = other_type.args.get("nullable")
|
|
423
|
+
other_is_nullable: bool | None = other_type.args.get("nullable")
|
|
412
424
|
if (
|
|
413
425
|
other_type.expressions
|
|
414
426
|
or (check_nullable and (self_is_nullable or other_is_nullable))
|
|
@@ -226,6 +226,14 @@ class UserDefinedFunction(Expression):
|
|
|
226
226
|
arg_types = {"this": True, "expressions": False, "wrapped": False}
|
|
227
227
|
|
|
228
228
|
|
|
229
|
+
class MacroOverloads(Expression):
|
|
230
|
+
arg_types = {"expressions": True}
|
|
231
|
+
|
|
232
|
+
|
|
233
|
+
class MacroOverload(Expression):
|
|
234
|
+
arg_types = {"this": True, "expressions": False, "is_table": False}
|
|
235
|
+
|
|
236
|
+
|
|
229
237
|
class CharacterSet(Expression):
|
|
230
238
|
arg_types = {"this": True, "default": False}
|
|
231
239
|
|
|
@@ -70,7 +70,12 @@ class Cast(Expression, Func):
|
|
|
70
70
|
|
|
71
71
|
|
|
72
72
|
class TryCast(Cast):
|
|
73
|
-
arg_types = {
|
|
73
|
+
arg_types = {
|
|
74
|
+
**Cast.arg_types,
|
|
75
|
+
"requires_string": False,
|
|
76
|
+
"null_on_text_overflow": False,
|
|
77
|
+
"probe_date_format": False,
|
|
78
|
+
}
|
|
74
79
|
|
|
75
80
|
|
|
76
81
|
class JSONCast(Cast):
|
|
@@ -436,6 +441,10 @@ class XMLElement(Expression, Func):
|
|
|
436
441
|
arg_types = {"this": True, "expressions": False, "evalname": False}
|
|
437
442
|
|
|
438
443
|
|
|
444
|
+
class GetIgnoreCase(Expression, Func):
|
|
445
|
+
arg_types = {"this": True, "expression": True}
|
|
446
|
+
|
|
447
|
+
|
|
439
448
|
class XMLGet(Expression, Func):
|
|
440
449
|
_sql_names = ["XMLGET"]
|
|
441
450
|
arg_types = {"this": True, "expression": True, "instance": False}
|
|
@@ -75,6 +75,10 @@ class ChecksumProperty(Property):
|
|
|
75
75
|
arg_types = {"on": False, "default": False}
|
|
76
76
|
|
|
77
77
|
|
|
78
|
+
class ClusterProperty(Property):
|
|
79
|
+
arg_types = {"this": False, "expressions": False}
|
|
80
|
+
|
|
81
|
+
|
|
78
82
|
class CollateProperty(Property):
|
|
79
83
|
arg_types = {"this": True, "default": False}
|
|
80
84
|
|
|
@@ -859,8 +859,8 @@ class SkipJSONColumn(Expression):
|
|
|
859
859
|
arg_types = {"regexp": False, "expression": True}
|
|
860
860
|
|
|
861
861
|
|
|
862
|
-
class Cluster(
|
|
863
|
-
|
|
862
|
+
class Cluster(Expression):
|
|
863
|
+
arg_types = {"expressions": True}
|
|
864
864
|
|
|
865
865
|
|
|
866
866
|
class Distribute(Order):
|
|
@@ -915,6 +915,11 @@ class QueryOption(Expression):
|
|
|
915
915
|
arg_types = {"this": True, "expression": False}
|
|
916
916
|
|
|
917
917
|
|
|
918
|
+
# FOR { XML | JSON } query modifier; `kind` is the discriminant ("XML" or "JSON").
|
|
919
|
+
class ForClause(Expression):
|
|
920
|
+
arg_types = {"kind": True, "expressions": False}
|
|
921
|
+
|
|
922
|
+
|
|
918
923
|
class WithTableHint(Expression):
|
|
919
924
|
arg_types = {"expressions": True}
|
|
920
925
|
|
|
@@ -1266,8 +1271,8 @@ class Select(Expression, Query):
|
|
|
1266
1271
|
Set the CLUSTER BY expression.
|
|
1267
1272
|
|
|
1268
1273
|
Example:
|
|
1269
|
-
>>> Select().from_("tbl").select("x").cluster_by("x
|
|
1270
|
-
'SELECT x FROM tbl CLUSTER BY x
|
|
1274
|
+
>>> Select().from_("tbl").select("x").cluster_by("x").sql(dialect="hive")
|
|
1275
|
+
'SELECT x FROM tbl CLUSTER BY x'
|
|
1271
1276
|
|
|
1272
1277
|
Args:
|
|
1273
1278
|
*expressions: the SQL code strings to parse.
|
|
@@ -1753,6 +1758,9 @@ class Pivot(Expression):
|
|
|
1753
1758
|
"default_on_null": False,
|
|
1754
1759
|
"into": False,
|
|
1755
1760
|
"with_": False,
|
|
1761
|
+
"identify_pivot_strings": False,
|
|
1762
|
+
"prefixed_pivot_columns": False,
|
|
1763
|
+
"pivot_column_naming": False,
|
|
1756
1764
|
}
|
|
1757
1765
|
|
|
1758
1766
|
@property
|