sqlglot 27.27.0__py3-none-any.whl → 28.4.0__py3-none-any.whl
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.
- sqlglot/__init__.py +1 -0
- sqlglot/__main__.py +6 -4
- sqlglot/_version.py +2 -2
- sqlglot/dialects/bigquery.py +118 -279
- sqlglot/dialects/clickhouse.py +73 -5
- sqlglot/dialects/databricks.py +38 -1
- sqlglot/dialects/dialect.py +354 -275
- sqlglot/dialects/dremio.py +4 -1
- sqlglot/dialects/duckdb.py +754 -25
- sqlglot/dialects/exasol.py +243 -10
- sqlglot/dialects/hive.py +8 -8
- sqlglot/dialects/mysql.py +14 -4
- sqlglot/dialects/oracle.py +29 -0
- sqlglot/dialects/postgres.py +60 -26
- sqlglot/dialects/presto.py +47 -16
- sqlglot/dialects/redshift.py +16 -0
- sqlglot/dialects/risingwave.py +3 -0
- sqlglot/dialects/singlestore.py +12 -3
- sqlglot/dialects/snowflake.py +239 -218
- sqlglot/dialects/spark.py +15 -4
- sqlglot/dialects/spark2.py +11 -48
- sqlglot/dialects/sqlite.py +10 -0
- sqlglot/dialects/starrocks.py +3 -0
- sqlglot/dialects/teradata.py +5 -8
- sqlglot/dialects/trino.py +6 -0
- sqlglot/dialects/tsql.py +61 -22
- sqlglot/diff.py +4 -2
- sqlglot/errors.py +69 -0
- sqlglot/executor/__init__.py +5 -10
- sqlglot/executor/python.py +1 -29
- sqlglot/expressions.py +637 -100
- sqlglot/generator.py +160 -43
- sqlglot/helper.py +2 -44
- sqlglot/lineage.py +10 -4
- sqlglot/optimizer/annotate_types.py +247 -140
- sqlglot/optimizer/canonicalize.py +6 -1
- sqlglot/optimizer/eliminate_joins.py +1 -1
- sqlglot/optimizer/eliminate_subqueries.py +2 -2
- sqlglot/optimizer/merge_subqueries.py +5 -5
- sqlglot/optimizer/normalize.py +20 -13
- sqlglot/optimizer/normalize_identifiers.py +17 -3
- sqlglot/optimizer/optimizer.py +4 -0
- sqlglot/optimizer/pushdown_predicates.py +1 -1
- sqlglot/optimizer/qualify.py +18 -10
- sqlglot/optimizer/qualify_columns.py +122 -275
- sqlglot/optimizer/qualify_tables.py +128 -76
- sqlglot/optimizer/resolver.py +374 -0
- sqlglot/optimizer/scope.py +27 -16
- sqlglot/optimizer/simplify.py +1075 -959
- sqlglot/optimizer/unnest_subqueries.py +12 -2
- sqlglot/parser.py +296 -170
- sqlglot/planner.py +2 -2
- sqlglot/schema.py +15 -4
- sqlglot/tokens.py +42 -7
- sqlglot/transforms.py +77 -22
- sqlglot/typing/__init__.py +316 -0
- sqlglot/typing/bigquery.py +376 -0
- sqlglot/typing/hive.py +12 -0
- sqlglot/typing/presto.py +24 -0
- sqlglot/typing/snowflake.py +505 -0
- sqlglot/typing/spark2.py +58 -0
- sqlglot/typing/tsql.py +9 -0
- {sqlglot-27.27.0.dist-info → sqlglot-28.4.0.dist-info}/METADATA +2 -2
- sqlglot-28.4.0.dist-info/RECORD +92 -0
- sqlglot-27.27.0.dist-info/RECORD +0 -84
- {sqlglot-27.27.0.dist-info → sqlglot-28.4.0.dist-info}/WHEEL +0 -0
- {sqlglot-27.27.0.dist-info → sqlglot-28.4.0.dist-info}/licenses/LICENSE +0 -0
- {sqlglot-27.27.0.dist-info → sqlglot-28.4.0.dist-info}/top_level.txt +0 -0
sqlglot/optimizer/scope.py
CHANGED
|
@@ -98,6 +98,7 @@ class Scope:
|
|
|
98
98
|
self._selected_sources = None
|
|
99
99
|
self._columns = None
|
|
100
100
|
self._external_columns = None
|
|
101
|
+
self._local_columns = None
|
|
101
102
|
self._join_hints = None
|
|
102
103
|
self._pivots = None
|
|
103
104
|
self._references = None
|
|
@@ -137,7 +138,7 @@ class Scope:
|
|
|
137
138
|
|
|
138
139
|
if isinstance(node, exp.Dot) and node.is_star:
|
|
139
140
|
self._stars.append(node)
|
|
140
|
-
elif isinstance(node, exp.Column):
|
|
141
|
+
elif isinstance(node, exp.Column) and not isinstance(node, exp.Pseudocolumn):
|
|
141
142
|
if isinstance(node.this, exp.Star):
|
|
142
143
|
self._stars.append(node)
|
|
143
144
|
else:
|
|
@@ -156,7 +157,7 @@ class Scope:
|
|
|
156
157
|
self._ctes.append(node)
|
|
157
158
|
elif _is_derived_table(node) and _is_from_or_join(node):
|
|
158
159
|
self._derived_tables.append(node)
|
|
159
|
-
elif isinstance(node, exp.UNWRAPPED_QUERIES):
|
|
160
|
+
elif isinstance(node, exp.UNWRAPPED_QUERIES) and not _is_from_or_join(node):
|
|
160
161
|
self._subqueries.append(node)
|
|
161
162
|
elif isinstance(node, exp.TableColumn):
|
|
162
163
|
self._table_columns.append(node)
|
|
@@ -308,7 +309,7 @@ class Scope:
|
|
|
308
309
|
or column.name not in named_selects
|
|
309
310
|
)
|
|
310
311
|
)
|
|
311
|
-
or (isinstance(ancestor, exp.Star) and not column.arg_key == "
|
|
312
|
+
or (isinstance(ancestor, exp.Star) and not column.arg_key == "except_")
|
|
312
313
|
):
|
|
313
314
|
self._columns.append(column)
|
|
314
315
|
|
|
@@ -372,8 +373,7 @@ class Scope:
|
|
|
372
373
|
Columns that appear to reference sources in outer scopes.
|
|
373
374
|
|
|
374
375
|
Returns:
|
|
375
|
-
list[exp.Column]: Column instances that don't reference
|
|
376
|
-
sources in the current scope.
|
|
376
|
+
list[exp.Column]: Column instances that don't reference sources in the current scope.
|
|
377
377
|
"""
|
|
378
378
|
if self._external_columns is None:
|
|
379
379
|
if isinstance(self.expression, exp.SetOperation):
|
|
@@ -383,12 +383,25 @@ class Scope:
|
|
|
383
383
|
self._external_columns = [
|
|
384
384
|
c
|
|
385
385
|
for c in self.columns
|
|
386
|
-
if c.table not in self.
|
|
387
|
-
and c.table not in self.semi_or_anti_join_tables
|
|
386
|
+
if c.table not in self.sources and c.table not in self.semi_or_anti_join_tables
|
|
388
387
|
]
|
|
389
388
|
|
|
390
389
|
return self._external_columns
|
|
391
390
|
|
|
391
|
+
@property
|
|
392
|
+
def local_columns(self):
|
|
393
|
+
"""
|
|
394
|
+
Columns in this scope that are not external.
|
|
395
|
+
|
|
396
|
+
Returns:
|
|
397
|
+
list[exp.Column]: Column instances that reference sources in the current scope.
|
|
398
|
+
"""
|
|
399
|
+
if self._local_columns is None:
|
|
400
|
+
external_columns = set(self.external_columns)
|
|
401
|
+
self._local_columns = [c for c in self.columns if c not in external_columns]
|
|
402
|
+
|
|
403
|
+
return self._local_columns
|
|
404
|
+
|
|
392
405
|
@property
|
|
393
406
|
def unqualified_columns(self):
|
|
394
407
|
"""
|
|
@@ -472,8 +485,9 @@ class Scope:
|
|
|
472
485
|
|
|
473
486
|
def rename_source(self, old_name, new_name):
|
|
474
487
|
"""Rename a source in this scope"""
|
|
475
|
-
|
|
476
|
-
self.sources
|
|
488
|
+
old_name = old_name or ""
|
|
489
|
+
if old_name in self.sources:
|
|
490
|
+
self.sources[new_name] = self.sources.pop(old_name)
|
|
477
491
|
|
|
478
492
|
def add_source(self, name, source):
|
|
479
493
|
"""Add a source to this scope"""
|
|
@@ -663,7 +677,7 @@ def _traverse_ctes(scope):
|
|
|
663
677
|
|
|
664
678
|
# if the scope is a recursive cte, it must be in the form of base_case UNION recursive.
|
|
665
679
|
# thus the recursive scope is the first section of the union.
|
|
666
|
-
with_ = scope.expression.args.get("
|
|
680
|
+
with_ = scope.expression.args.get("with_")
|
|
667
681
|
if with_ and with_.recursive:
|
|
668
682
|
union = cte.this
|
|
669
683
|
|
|
@@ -720,7 +734,7 @@ def _traverse_tables(scope):
|
|
|
720
734
|
|
|
721
735
|
# Traverse FROMs, JOINs, and LATERALs in the order they are defined
|
|
722
736
|
expressions = []
|
|
723
|
-
from_ = scope.expression.args.get("
|
|
737
|
+
from_ = scope.expression.args.get("from_")
|
|
724
738
|
if from_:
|
|
725
739
|
expressions.append(from_.this)
|
|
726
740
|
|
|
@@ -821,7 +835,7 @@ def _traverse_udtfs(scope):
|
|
|
821
835
|
|
|
822
836
|
sources = {}
|
|
823
837
|
for expression in expressions:
|
|
824
|
-
if
|
|
838
|
+
if isinstance(expression, exp.Subquery):
|
|
825
839
|
top = None
|
|
826
840
|
for child_scope in _traverse_scope(
|
|
827
841
|
scope.branch(
|
|
@@ -870,10 +884,7 @@ def walk_in_scope(expression, bfs=True, prune=None):
|
|
|
870
884
|
|
|
871
885
|
if (
|
|
872
886
|
isinstance(node, exp.CTE)
|
|
873
|
-
or (
|
|
874
|
-
isinstance(node.parent, (exp.From, exp.Join, exp.Subquery))
|
|
875
|
-
and _is_derived_table(node)
|
|
876
|
-
)
|
|
887
|
+
or (isinstance(node.parent, (exp.From, exp.Join)) and _is_derived_table(node))
|
|
877
888
|
or (isinstance(node.parent, exp.UDTF) and isinstance(node, exp.Query))
|
|
878
889
|
or isinstance(node, exp.UNWRAPPED_QUERIES)
|
|
879
890
|
):
|