From 50f0638fa9ce163ca7a62d8711b440ca29df2688 Mon Sep 17 00:00:00 2001 From: Peter Debelak Date: Sat, 9 Jul 2022 15:57:15 -0500 Subject: [PATCH] Allow no alias for selects in CTEs with a column list (#3580) In cases where the CTE has a column list, we don't need an alias for columns. This checks if the select has a `common_table_expression` parent and if that parent has a `cte_column_list` child. In that case, it doesn't complain about a missing alias. Fixes #3558 --- src/sqlfluff/rules/L013.py | 15 +++++++++-- test/fixtures/rules/std_rule_cases/L013.yml | 30 +++++++++++++++++++++ 2 files changed, 43 insertions(+), 2 deletions(-) diff --git a/src/sqlfluff/rules/L013.py b/src/sqlfluff/rules/L013.py index d6f2275af9e..4941944316f 100644 --- a/src/sqlfluff/rules/L013.py +++ b/src/sqlfluff/rules/L013.py @@ -48,7 +48,8 @@ def _eval(self, context: RuleContext) -> Optional[LintResult]: elements there are. """ - segment = context.functional.segment + functional_context = context.functional + segment = functional_context.segment children = segment.children() # If we have an alias its all good if children.any(sp.is_type("alias_expression")): @@ -66,6 +67,16 @@ def _eval(self, context: RuleContext) -> Optional[LintResult]: ): return None + parent_stack = functional_context.parent_stack + + # Ignore if it is part of a CTE with column names + if ( + parent_stack.last(sp.is_type("common_table_expression")) + .children() + .any(sp.is_type("cte_column_list")) + ): + return None + select_clause_children = children.select(sp.not_(sp.is_name("star"))) is_complex_clause = _recursively_check_is_complex(select_clause_children) if not is_complex_clause: @@ -76,7 +87,7 @@ def _eval(self, context: RuleContext) -> Optional[LintResult]: # Check *how many* elements/columns there are in the select # statement. If this is the only one, then we won't # report an error. - immediate_parent = context.functional.parent_stack.last() + immediate_parent = parent_stack.last() elements = immediate_parent.children(sp.is_type("select_clause_element")) num_elements = len(elements) diff --git a/test/fixtures/rules/std_rule_cases/L013.yml b/test/fixtures/rules/std_rule_cases/L013.yml index 4662e4cc9d4..3c245573429 100644 --- a/test/fixtures/rules/std_rule_cases/L013.yml +++ b/test/fixtures/rules/std_rule_cases/L013.yml @@ -47,3 +47,33 @@ test_pass_function_emits: configs: core: dialect: exasol + +test_fail_cte_no_column_list: + fail_str: | + WITH cte AS ( + SELECT + col_a, + min(col_b) + FROM my_table + GROUP BY 1 + ) + + SELECT + a, + b + FROM cte + +test_pass_cte_column_list: + pass_str: | + WITH cte(a, b) AS ( + SELECT + col_a, + min(col_b) + FROM my_table + GROUP BY 1 + ) + + SELECT + a, + b + FROM cte