Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make BigQuery typeless STRUCTs Expressions #2435

Merged
merged 4 commits into from
Jan 23, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions src/sqlfluff/dialects/dialect_ansi.py
Original file line number Diff line number Diff line change
Expand Up @@ -1692,6 +1692,7 @@ class CaseExpressionSegment(BaseSegment):
Ref("SelectStatementSegment"),
Ref("LiteralGrammar"),
Ref("IntervalExpressionSegment"),
Ref("TypelessStructSegment"),
Ref("ColumnReferenceSegment"),
Sequence(
Ref("SimpleArrayTypeGrammar", optional=True), Ref("ArrayLiteralSegment")
Expand Down Expand Up @@ -2366,6 +2367,17 @@ class TableEndClauseSegment(BaseSegment):
match_grammar = Nothing()


@ansi_dialect.segment()
class TypelessStructSegment(BaseSegment):
"""Expression to construct a STRUCT with implicit types.

(Yes in BigQuery for example)
"""

type = "typeless_struct"
match_grammar = Nothing()


@ansi_dialect.segment()
class CreateTableStatementSegment(BaseSegment):
"""A `CREATE TABLE` statement."""
Expand Down
28 changes: 1 addition & 27 deletions src/sqlfluff/dialects/dialect_bigquery.py
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,6 @@
Ref("BareFunctionSegment"),
Ref("FunctionSegment"),
Ref("ArrayLiteralSegment"),
Ref("TypelessStructSegment"),
Ref("TupleSegment"),
Ref("BaseExpressionElementGrammar"),
),
Expand All @@ -168,14 +167,6 @@
bracket_pairs_set="angle_bracket_pairs",
),
),
# BigQuery also supports the special "Struct" construct.
BaseExpressionElementGrammar=ansi_dialect.get_grammar(
"BaseExpressionElementGrammar"
).copy(insert=[Ref("TypelessStructSegment")]),
FunctionContentsGrammar=ansi_dialect.get_grammar("FunctionContentsGrammar").copy(
insert=[Ref("TypelessStructSegment")],
before=Ref("ExpressionSegment"),
),
# BigQuery allows underscore in parameter names, and also anything if quoted in
# backticks
ParameterNameSegment=OneOf(
Expand Down Expand Up @@ -282,23 +273,6 @@ class UnorderedSelectStatementSegment(BaseSegment):
)


@bigquery_dialect.segment(replace=True)
class ArrayLiteralSegment(BaseSegment):
"""Override array literal segment to add Typeless Struct."""

type = "array_literal"
match_grammar = Bracketed(
Delimited(
OneOf(
Ref("ExpressionSegment"),
Ref("TypelessStructSegment"),
),
optional=True,
),
bracket_type="square",
)


@bigquery_dialect.segment(replace=True)
class StatementSegment(ansi_dialect.get_segment("StatementSegment")): # type: ignore
"""Overriding StatementSegment to allow for additional segment parsing."""
Expand Down Expand Up @@ -596,7 +570,7 @@ class FunctionParameterListGrammar(BaseSegment):
)


@bigquery_dialect.segment()
@bigquery_dialect.segment(replace=True)
class TypelessStructSegment(BaseSegment):
"""Expression to construct a STRUCT with implicit types.

Expand Down
36 changes: 19 additions & 17 deletions test/fixtures/dialects/bigquery/declare_variable.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
# computed by SQLFluff when running the tests. Please run
# `python test/generate_parse_fixture_yml.py` to generate them after adding or
# altering SQL files.
_hash: 20ea3ed015513907c7b58b9f037cae3464decb55739f78fe5570bf4f4cbff70d
_hash: b072399d5f83df444e0434bdf9c0b46373debdfb3916e86cc0cb4c1f5118157d
file:
- statement:
declare_segment:
Expand Down Expand Up @@ -126,28 +126,30 @@ file:
data_type_identifier: string
- end_angle_bracket: '>'
- keyword: default
- typeless_struct:
keyword: struct
bracketed:
- start_bracket: (
- literal: "'one'"
- comma: ','
- literal: "'two'"
- end_bracket: )
- expression:
typeless_struct:
keyword: struct
bracketed:
- start_bracket: (
- literal: "'one'"
- comma: ','
- literal: "'two'"
- end_bracket: )
- statement_terminator: ;
- statement:
declare_segment:
- keyword: declare
- identifier: str3
- keyword: default
- typeless_struct:
keyword: struct
bracketed:
- start_bracket: (
- literal: "'one'"
- comma: ','
- literal: "'two'"
- end_bracket: )
- expression:
typeless_struct:
keyword: struct
bracketed:
- start_bracket: (
- literal: "'one'"
- comma: ','
- literal: "'two'"
- end_bracket: )
- statement_terminator: ;
- statement:
declare_segment:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
# computed by SQLFluff when running the tests. Please run
# `python test/generate_parse_fixture_yml.py` to generate them after adding or
# altering SQL files.
_hash: 04e1c92046585ea1c067f6c5bfa3c7425fb9518690fb50b45d97c6dadb776d33
_hash: c47530d353648a4c2b721741e4cd0bc53e351fc10fb4626208198855367c5071
file:
statement:
select_statement:
Expand Down Expand Up @@ -91,34 +91,35 @@ file:
expression:
array_literal:
start_square_bracket: '['
typeless_struct:
keyword: STRUCT
bracketed:
- start_bracket: (
- literal: '"Rudisha"'
- alias_expression:
keyword: AS
identifier: name
- comma: ','
- expression:
array_literal:
- start_square_bracket: '['
- expression:
literal: '23.4'
- comma: ','
- expression:
literal: '26.3'
- comma: ','
- expression:
literal: '26.4'
- comma: ','
- expression:
literal: '26.1'
- end_square_bracket: ']'
- alias_expression:
keyword: AS
identifier: splits
- end_bracket: )
expression:
typeless_struct:
keyword: STRUCT
bracketed:
- start_bracket: (
- literal: '"Rudisha"'
- alias_expression:
keyword: AS
identifier: name
- comma: ','
- expression:
array_literal:
- start_square_bracket: '['
- expression:
literal: '23.4'
- comma: ','
- expression:
literal: '26.3'
- comma: ','
- expression:
literal: '26.4'
- comma: ','
- expression:
literal: '26.1'
- end_square_bracket: ']'
- alias_expression:
keyword: AS
identifier: splits
- end_bracket: )
end_square_bracket: ']'
alias_expression:
keyword: AS
Expand Down
43 changes: 22 additions & 21 deletions test/fixtures/dialects/bigquery/select_struct.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
# computed by SQLFluff when running the tests. Please run
# `python test/generate_parse_fixture_yml.py` to generate them after adding or
# altering SQL files.
_hash: 958734aacebc6a6c2e7883beca9c39f2491fbbbc1d121987c1fddc014306e7cc
_hash: 342882573eb2a6a05bd83f11250c9b8bcc24239f0be3a2dd853b5e6f2f006c54
file:
- statement:
select_statement:
Expand Down Expand Up @@ -85,26 +85,27 @@ file:
select_clause:
keyword: select
select_clause_element:
typeless_struct:
keyword: struct
bracketed:
- start_bracket: (
- column_reference:
- identifier: bar
- dot: .
- identifier: bar_id
- alias_expression:
keyword: as
identifier: id
- comma: ','
- column_reference:
- identifier: bar
- dot: .
- identifier: bar_name
- alias_expression:
keyword: as
identifier: bar
- end_bracket: )
expression:
typeless_struct:
keyword: struct
bracketed:
- start_bracket: (
- column_reference:
- identifier: bar
- dot: .
- identifier: bar_id
- alias_expression:
keyword: as
identifier: id
- comma: ','
- column_reference:
- identifier: bar
- dot: .
- identifier: bar_name
- alias_expression:
keyword: as
identifier: bar
- end_bracket: )
alias_expression:
keyword: as
identifier: bar
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,30 +3,32 @@
# computed by SQLFluff when running the tests. Please run
# `python test/generate_parse_fixture_yml.py` to generate them after adding or
# altering SQL files.
_hash: b0a15006dcb0e8923a1437a02e82b14d9eb3753c6c9be8d835a2c00652a14e22
_hash: 9c3f1a9ff8303f1c1714ef240d1d9d1b793ff895f8575dca49322892e7325e13
file:
- statement:
select_statement:
select_clause:
keyword: SELECT
select_clause_element:
typeless_struct:
keyword: STRUCT
bracketed:
start_bracket: (
typeless_struct:
keyword: STRUCT
bracketed:
start_bracket: (
literal: '1'
alias_expression:
keyword: AS
identifier: b
end_bracket: )
alias_expression:
keyword: AS
identifier: a
end_bracket: )
expression:
typeless_struct:
keyword: STRUCT
bracketed:
start_bracket: (
expression:
typeless_struct:
keyword: STRUCT
bracketed:
start_bracket: (
literal: '1'
alias_expression:
keyword: AS
identifier: b
end_bracket: )
alias_expression:
keyword: AS
identifier: a
end_bracket: )
alias_expression:
keyword: AS
identifier: foo
Expand All @@ -41,22 +43,23 @@ file:
function_name_identifier: ARRAY_AGG
bracketed:
start_bracket: (
typeless_struct:
keyword: STRUCT
bracketed:
- start_bracket: (
- column_reference:
identifier: a
- alias_expression:
keyword: AS
identifier: a
- comma: ','
- column_reference:
identifier: b
- alias_expression:
keyword: AS
identifier: b
- end_bracket: )
expression:
typeless_struct:
keyword: STRUCT
bracketed:
- start_bracket: (
- column_reference:
identifier: a
- alias_expression:
keyword: AS
identifier: a
- comma: ','
- column_reference:
identifier: b
- alias_expression:
keyword: AS
identifier: b
- end_bracket: )
end_bracket: )
from_clause:
keyword: FROM
Expand Down
14 changes: 14 additions & 0 deletions test/fixtures/dialects/bigquery/typeless_struct.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@

SELECT IF(
TRUE,
STRUCT('hello' AS greeting, 'world' AS subject),
STRUCT('hi' AS greeting, 'there' AS subject)
) AS salute
FROM (SELECT 1);

SELECT
CASE
WHEN a.xxx != b.xxx THEN STRUCT(a.xxx AS M, b.xxx AS N)
END AS xxx
FROM A
JOIN B ON B.id = A.id;
Loading