diff --git a/src/sqlfluff/dialects/dialect_mysql.py b/src/sqlfluff/dialects/dialect_mysql.py index f17fd35a839..0d07b503102 100644 --- a/src/sqlfluff/dialects/dialect_mysql.py +++ b/src/sqlfluff/dialects/dialect_mysql.py @@ -315,6 +315,34 @@ class AliasExpressionSegment(BaseSegment): Dedent, ) +# Mainly adapted from the sparksql implementation +class GeneratedColumnDefinitionSegment(BaseSegment): + """A generated column definition. + + e.g. email_domain CHAR(100) AS (SUBSTRING_INDEX(email, '@', -1)) + https://dev.mysql.com/doc/refman/8.0/en/create-table-generated-columns.html + """ + type = "generated_column_definition" + + match_grammar: Matchable = Sequence( + Ref("SingleIdentifierGrammar"), # Column name + Ref("DatatypeSegment"), # Column type + Bracketed(Anything(), optional=True), # For types like VARCHAR(100) + Sequence( + Sequence("GENERATED", "ALWAYS", optional=True), + "AS", + Bracketed( + OneOf( + Ref("FunctionSegment"), + Ref("BareFunctionSegment"), + ), + ), + OneOf("VIRTUAL", "STORED", optional=True) + ), + AnyNumberOf( + Ref("ColumnConstraintSegment", optional=True), + ), + ) class ColumnDefinitionSegment(BaseSegment): """A column definition, e.g. for CREATE TABLE or ALTER TABLE.""" @@ -380,6 +408,8 @@ class CreateTableStatementSegment(ansi.CreateTableStatementSegment): https://dev.mysql.com/doc/refman/8.0/en/create-table.html """ + # TODO check if here is the right place to add the new option of the + # generated column definition match_grammar = ansi.CreateTableStatementSegment.match_grammar.copy( insert=[ AnyNumberOf( diff --git a/test/fixtures/dialects/mysql/create_table_generated_columns.sql b/test/fixtures/dialects/mysql/create_table_generated_columns.sql new file mode 100644 index 00000000000..07b96010d03 --- /dev/null +++ b/test/fixtures/dialects/mysql/create_table_generated_columns.sql @@ -0,0 +1,7 @@ + +CREATE TABLE emails ( + email CHAR(100) NOT NULL, + email_domain CHAR(100) AS (SUBSTRING_INDEX(email, '@', -1)), + email_domain2 CHAR(100) GENERATED ALWAYS AS (SUBSTRING_INDEX(email, '@', -1)) STORED, + email_domain3 CHAR(100) GENERATED ALWAYS AS (SUBSTRING_INDEX(email, '@', -1)) VIRTUAL +); \ No newline at end of file