Skip to content

Commit

Permalink
Snowflake: Added AlterTableStatement specific for Snowflake (#2267)
Browse files Browse the repository at this point in the history
  • Loading branch information
wong-codaio committed Jan 17, 2022
1 parent 6815d91 commit 0ea874b
Show file tree
Hide file tree
Showing 6 changed files with 317 additions and 136 deletions.
98 changes: 86 additions & 12 deletions src/sqlfluff/dialects/dialect_snowflake.py
Original file line number Diff line number Diff line change
Expand Up @@ -548,7 +548,6 @@ class StatementSegment(ansi_dialect.get_segment("StatementSegment")): # type: i
Ref("SetAssignmentStatementSegment"),
Ref("CallStoredProcedureSegment"),
Ref("MergeStatementSegment"),
Ref("AlterTableColumnStatementSegment"),
Ref("CopyIntoTableStatementSegment"),
Ref("AlterWarehouseStatementSegment"),
Ref("CreateExternalTableSegment"),
Expand Down Expand Up @@ -890,25 +889,78 @@ class SelectClauseModifierSegment(BaseSegment):
)


@snowflake_dialect.segment()
class AlterTableColumnStatementSegment(BaseSegment):
"""An `ALTER TABLE .. ALTER COLUMN` statement.
https://docs.snowflake.com/en/sql-reference/sql/alter-table-column.html
@snowflake_dialect.segment(replace=True)
class AlterTableStatementSegment(BaseSegment):
"""An `ALTER TABLE` statement.
https://docs.snowflake.com/en/sql-reference/sql/alter-table.html
If possible, please keep the order below the same as Snowflake's doc:
"""

type = "alter_table_column_statement"
type = "alter_table_statement"

match_grammar = Sequence(
"ALTER",
"TABLE",
Ref("TableReferenceSegment"),
OneOf(
# Rename
Sequence(
"DROP",
Ref.keyword("COLUMN", optional=True),
Ref("SingleIdentifierGrammar"),
"RENAME",
"TO",
Ref("TableReferenceSegment"),
),
# Swap With
Sequence(
"SWAP",
"WITH",
Ref("TableReferenceSegment"),
),
# @TODO: clusteringAction
Ref("AlterTableTableColumnActionSegment"),
# @TODO: constraintAction
# @TODO: extTableColumnAction
# @TODO: searchOptimizationAction
# SET Table options
# @TODO: Restrict the list of parameters supported per Snowflake doc.
Sequence(
Ref.keyword("SET"),
OneOf(
Ref("ParameterNameSegment"),
Ref.keyword("COMMENT"),
),
Ref("EqualsSegment", optional=True),
OneOf(
Ref("LiteralGrammar"),
Ref("NakedIdentifierSegment"),
Ref("QuotedLiteralSegment"),
),
),
# @TODO: Set/unset TAG
# @TODO: Unset table options
# @TODO: Add/drop row access policies
),
)


@snowflake_dialect.segment()
class AlterTableTableColumnActionSegment(BaseSegment):
"""ALTER TABLE `tableColumnAction` per defined in Snowflake's grammar.
https://docs.snowflake.com/en/sql-reference/sql/alter-table.html
https://docs.snowflake.com/en/sql-reference/sql/alter-table-column.html
If possible, please match the order of this sequence with what's defined in Snowflake's
tableColumnAction grammar.
"""

type = "alter_table_table_column_action"

match_grammar = Sequence(
OneOf(
# @TODO: Add Column
# @TODO: Rename column
# Alter/Modify column(s)
Sequence(
OneOf("ALTER", "MODIFY"),
OptionallyBracketed(
Expand All @@ -917,7 +969,7 @@ class AlterTableColumnStatementSegment(BaseSegment):
# Add things
Sequence(
Ref.keyword("COLUMN", optional=True),
Ref("SingleIdentifierGrammar"),
Ref("ColumnReferenceSegment"),
OneOf(
Sequence("DROP", "DEFAULT"),
Sequence(
Expand Down Expand Up @@ -945,16 +997,38 @@ class AlterTableColumnStatementSegment(BaseSegment):
),
Sequence(
"COLUMN",
Ref("SingleIdentifierGrammar"),
Ref("ColumnReferenceSegment"),
OneOf("SET", "UNSET"),
"MASKING",
"POLICY",
Ref("FunctionNameIdentifierSegment", optional=True),
),
# @TODO: Set/Unset TAG support
),
),
),
),
# Drop column
Sequence(
"DROP",
Ref.keyword("COLUMN", optional=True),
Ref("ColumnReferenceSegment"),
),
# @TODO: Drop columns
# vvvvv COPIED FROM ANSI vvvvv
# @TODO: Removed these once `tableColumnAction` is properly supported.
Sequence(
OneOf("ADD", "MODIFY"),
Ref.keyword("COLUMN", optional=True),
Ref("ColumnDefinitionSegment"),
OneOf(
Sequence(OneOf("FIRST", "AFTER"), Ref("ColumnReferenceSegment")),
# Bracketed Version of the same
Ref("BracketedColumnReferenceListGrammar"),
optional=True,
),
),
# ^^^^^ COPIED FROM ANSI ^^^^^
),
)

Expand Down
9 changes: 9 additions & 0 deletions test/fixtures/dialects/snowflake/snowflake_alter_table.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
ALTER TABLE my_old_table RENAME TO my_new_table;

ALTER TABLE my_existing_table SWAP WITH my_another_table;

ALTER TABLE my_table SET DATA_RETENTION_TIME_IN_DAYS = 30;

ALTER TABLE my_table SET DEFAULT_DDL_COLLATION = 'en-ci';

ALTER TABLE my_table SET COMMENT = 'my table comment';
65 changes: 65 additions & 0 deletions test/fixtures/dialects/snowflake/snowflake_alter_table.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# YML test files are auto-generated from SQL files and should not be edited by
# hand. To help enforce this, the "hash" field in the file must match a hash
# 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: bc4f7d830f87054dbf6d7b40125a08cda4fbfe4ee52186811a821493f955ad45
file:
- statement:
alter_table_statement:
- keyword: ALTER
- keyword: TABLE
- table_reference:
identifier: my_old_table
- keyword: RENAME
- keyword: TO
- table_reference:
identifier: my_new_table
- statement_terminator: ;
- statement:
alter_table_statement:
- keyword: ALTER
- keyword: TABLE
- table_reference:
identifier: my_existing_table
- keyword: SWAP
- keyword: WITH
- table_reference:
identifier: my_another_table
- statement_terminator: ;
- statement:
alter_table_statement:
- keyword: ALTER
- keyword: TABLE
- table_reference:
identifier: my_table
- keyword: SET
- parameter: DATA_RETENTION_TIME_IN_DAYS
- comparison_operator:
raw_comparison_operator: '='
- literal: '30'
- statement_terminator: ;
- statement:
alter_table_statement:
- keyword: ALTER
- keyword: TABLE
- table_reference:
identifier: my_table
- keyword: SET
- parameter: DEFAULT_DDL_COLLATION
- comparison_operator:
raw_comparison_operator: '='
- literal: "'en-ci'"
- statement_terminator: ;
- statement:
alter_table_statement:
- keyword: ALTER
- keyword: TABLE
- table_reference:
identifier: my_table
- keyword: SET
- parameter: COMMENT
- comparison_operator:
raw_comparison_operator: '='
- literal: "'my table comment'"
- statement_terminator: ;
23 changes: 13 additions & 10 deletions test/fixtures/dialects/snowflake/snowflake_alter_table_column.sql
Original file line number Diff line number Diff line change
@@ -1,32 +1,35 @@
-- SET/DROP column properties
-- Single column
alter table t1 alter column c1 drop not null;
alter table t1 alter c5 comment '50 character column';

-- Multiple columns/properties
alter table t1 modify c2 drop default, c3 set default seq5.nextval ;

alter table t1 alter c4 set data type varchar(50), column c4 drop default;

alter table t1 alter c5 comment '50 character column';

-- SET Masking Policy
-- Single column
ALTER TABLE xxxx.example_table MODIFY COLUMN employeeCode SET MASKING POLICY example_MASKING_POLICY;

alter table empl_info modify column empl_id set masking policy mask_empl_id;

-- multiple columns

-- Multiple columns
alter table empl_info modify
column empl_id set masking policy mask_empl_id
, column empl_dob set masking policy mask_empl_dob
;

-- single column

-- UNSET masking policy
-- Single column
alter table empl_info modify column empl_id unset masking policy;

-- multiple columns

-- Multiple columns
alter table empl_info modify
column empl_id unset masking policy
, column empl_dob unset masking policy
;

alter table test_table column test_column;
alter table test_schema.test_table column test_column;
-- DROP COLUMN
ALTER TABLE empl_info DROP COLUMN my_column;
ALTER TABLE some_schema.empl_info DROP COLUMN my_column;
Loading

0 comments on commit 0ea874b

Please sign in to comment.