Skip to content

Commit 36ad534

Browse files
nnamdi16georgesittas
authored andcommitted
fix(exasol)!: qualified select list with "LOCAL" (#6450)
* chore(exasol): qualified select list with "LOCAL" * chore(exasol): implementing alias referencing using local keyword for select list * chore(exasol): refactored test and simplifying implementation * chore(exasol): refactored the test and added safe checking when reading alias.node
1 parent 1b6076b commit 36ad534

File tree

2 files changed

+37
-11
lines changed

2 files changed

+37
-11
lines changed

sqlglot/dialects/exasol.py

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -75,12 +75,11 @@ def _build_nullifzero(args: t.List) -> exp.If:
7575
# https://docs.exasol.com/db/latest/sql/select.htm#:~:text=If%20you%20have,local.x%3E10
7676
def _add_local_prefix_for_aliases(expression: exp.Expression) -> exp.Expression:
7777
if isinstance(expression, exp.Select):
78-
aliases: dict[str, bool] = {}
79-
for sel in expression.selects:
80-
alias = sel.args.get("alias")
81-
82-
if isinstance(sel, exp.Alias) and alias:
83-
aliases[alias.name] = bool(alias.args.get("quoted"))
78+
aliases: dict[str, bool] = {
79+
alias.name: bool(alias.args.get("quoted"))
80+
for sel in expression.selects
81+
if isinstance(sel, exp.Alias) and (alias := sel.args.get("alias"))
82+
}
8483

8584
table = expression.find(exp.Table)
8685
table_ident = table.this if table else None
@@ -92,18 +91,33 @@ def _add_local_prefix_for_aliases(expression: exp.Expression) -> exp.Expression:
9291
):
9392
table_ident.replace(exp.to_identifier(table_ident.name.upper(), quoted=True))
9493

95-
def prefix_local(node):
94+
def prefix_local(node, visible_aliases: dict[str, bool]) -> exp.Expression:
9695
if isinstance(node, exp.Column) and not node.table:
97-
if node.name in aliases:
96+
if node.name in visible_aliases:
9897
return exp.Column(
99-
this=exp.to_identifier(node.name, quoted=aliases[node.name]),
98+
this=exp.to_identifier(node.name, quoted=visible_aliases[node.name]),
10099
table=exp.to_identifier("LOCAL", quoted=False),
101100
)
102101
return node
103102

104103
for key in ("where", "group", "having"):
105104
if arg := expression.args.get(key):
106-
expression.set(key, arg.transform(prefix_local))
105+
expression.set(key, arg.transform(lambda node: prefix_local(node, aliases)))
106+
107+
seen_aliases: dict[str, bool] = {}
108+
new_selects: list[exp.Expression] = []
109+
for sel in expression.selects:
110+
if isinstance(sel, exp.Alias):
111+
inner = sel.this.transform(lambda node: prefix_local(node, seen_aliases))
112+
sel.set("this", inner)
113+
114+
alias_node = sel.args.get("alias")
115+
116+
seen_aliases[sel.alias] = bool(alias_node and getattr(alias_node, "quoted", False))
117+
new_selects.append(sel)
118+
else:
119+
new_selects.append(sel.transform(lambda node: prefix_local(node, seen_aliases)))
120+
expression.set("expressions", new_selects)
107121

108122
return expression
109123

tests/dialects/test_exasol.py

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -682,7 +682,9 @@ def test_local_prefix_for_alias(self):
682682
self.validate_identity(
683683
'SELECT YEAR(a_date) AS "a_year" FROM MY_SUMMARY_TABLE GROUP BY LOCAL."a_year"',
684684
)
685-
self.validate_identity('SELECT a_year AS a_year FROM "LOCAL" GROUP BY "LOCAL".a_year')
685+
self.validate_identity(
686+
'SELECT a_year AS a_year FROM "LOCAL" GROUP BY "LOCAL".a_year',
687+
)
686688

687689
test_cases = [
688690
(
@@ -705,6 +707,16 @@ def test_local_prefix_for_alias(self):
705707
"SELECT YEAR(a_date) AS a_year, MONTH(a_date) AS a_month FROM my_table WHERE LOCAL.a_year > 2020 AND LOCAL.a_month < 6",
706708
"SELECT YEAR(a_date) AS a_year, MONTH(a_date) AS a_month FROM my_table WHERE a_year > 2020 AND a_month < 6",
707709
),
710+
(
711+
"Select list aliases",
712+
"SELECT YR AS THE_YEAR, ID AS YR, LOCAL.THE_YEAR + 1 AS NEXT_YEAR FROM my_table",
713+
"SELECT YR AS THE_YEAR, ID AS YR, THE_YEAR + 1 AS NEXT_YEAR FROM my_table",
714+
),
715+
(
716+
"Select list aliases without Local keyword",
717+
"SELECT YEAR(CURRENT_DATE) AS current_year, LOCAL.current_year + 1 AS next_year",
718+
"SELECT YEAR(CURRENT_DATE) AS current_year, current_year + 1 AS next_year",
719+
),
708720
]
709721
for title, exasol_sql, dbx_sql in test_cases:
710722
with self.subTest(clause=title):

0 commit comments

Comments
 (0)