Skip to content

Commit 41c6d24

Browse files
authored
feat(optimizer)!: Alias expanded USING STRUCT fields (#4474)
* feat(optimizer): Alias expanded USING STRUCT fields * Typo
1 parent a34bcde commit 41c6d24

File tree

2 files changed

+15
-2
lines changed

2 files changed

+15
-2
lines changed

sqlglot/optimizer/qualify_columns.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -220,11 +220,16 @@ def _update_source_columns(source_name: str) -> None:
220220
if not column.table and column.name in column_tables:
221221
tables = column_tables[column.name]
222222
coalesce_args = [exp.column(column.name, table=table) for table in tables]
223-
replacement = exp.func("coalesce", *coalesce_args)
223+
replacement: exp.Expression = exp.func("coalesce", *coalesce_args)
224224

225-
# Ensure selects keep their output name
226225
if isinstance(column.parent, exp.Select):
226+
# Ensure the USING column keeps its name if it's projected
227227
replacement = alias(replacement, alias=column.name, copy=False)
228+
elif isinstance(column.parent, exp.Struct):
229+
# Ensure the USING column keeps its name if it's an anonymous STRUCT field
230+
replacement = exp.PropertyEQ(
231+
this=exp.to_identifier(column.name), expression=replacement
232+
)
228233

229234
scope.replace(column, replacement)
230235

tests/fixtures/optimizer/qualify_columns.sql

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -532,6 +532,14 @@ WITH t1 AS (SELECT 'x' AS id, CAST('2024-01-01' AS DATE) AS foo, 000 AS value),
532532
WITH t1 AS (SELECT 'x' AS id, CAST('2024-01-01' AS DATE) AS foo, 000 AS value), t2 AS (SELECT 'x' AS id, CAST('2024-02-02' AS DATE) AS foo, 123 AS value), t3 AS (SELECT 'x' AS id, CAST('2024-02-02' AS DATE) AS foo, 456 AS value), t4 AS (SELECT 'x' AS id, CAST('2024-03-03' AS DATE) AS foo, 789 AS value) SELECT * FROM t1 FULL OUTER JOIN t2 USING (id, foo) FULL OUTER JOIN t3 USING (id, foo) FULL OUTER JOIN t4 USING (id, foo);
533533
WITH t1 AS (SELECT 'x' AS id, CAST('2024-01-01' AS DATE) AS foo, 000 AS value), t2 AS (SELECT 'x' AS id, CAST('2024-02-02' AS DATE) AS foo, 123 AS value), t3 AS (SELECT 'x' AS id, CAST('2024-02-02' AS DATE) AS foo, 456 AS value), t4 AS (SELECT 'x' AS id, CAST('2024-03-03' AS DATE) AS foo, 789 AS value) SELECT COALESCE(t1.id, t2.id, t3.id, t4.id) AS id, COALESCE(t1.foo, t2.foo, t3.foo, t4.foo) AS foo, t1.value AS value, t2.value AS value, t3.value AS value, t4.value AS value FROM t1 AS t1 FULL OUTER JOIN t2 AS t2 ON t1.id = t2.id AND t1.foo = t2.foo FULL OUTER JOIN t3 AS t3 ON COALESCE(t1.id, t2.id) = t3.id AND COALESCE(t1.foo, t2.foo) = t3.foo FULL OUTER JOIN t4 AS t4 ON COALESCE(t1.id, t2.id, t3.id) = t4.id AND COALESCE(t1.foo, t2.foo, t3.foo) = t4.foo;
534534

535+
# title: Name anonymous STRUCT fields if replacing USING columns
536+
WITH t1 AS (SELECT 1 AS id), t2 AS (SELECT 2 AS id) SELECT STRUCT(id) AS my_field FROM t1 JOIN t2 USING (id);
537+
WITH t1 AS (SELECT 1 AS id), t2 AS (SELECT 2 AS id) SELECT STRUCT(COALESCE(t1.id, t2.id) AS id) AS my_field FROM t1 AS t1 JOIN t2 AS t2 ON t1.id = t2.id;
538+
539+
# title: Do not rename aliased STRUCT fields if replacing USING columns
540+
WITH t1 AS (SELECT 1 AS id), t2 AS (SELECT 2 AS id) SELECT STRUCT(id AS col) AS my_field FROM t1 JOIN t2 USING (id);
541+
WITH t1 AS (SELECT 1 AS id), t2 AS (SELECT 2 AS id) SELECT STRUCT(COALESCE(t1.id, t2.id) AS col) AS my_field FROM t1 AS t1 JOIN t2 AS t2 ON t1.id = t2.id;
542+
535543
--------------------------------------
536544
-- Hint with table reference
537545
--------------------------------------

0 commit comments

Comments
 (0)