diff --git a/parser/ast.go b/parser/ast.go index 28725b4..e4d43e1 100644 --- a/parser/ast.go +++ b/parser/ast.go @@ -505,6 +505,32 @@ func (a *AlterTableRenameColumn) String(level int) string { return builder.String() } +type AlterTableModifyTTL struct { + ModifyPos Pos + StatementEnd Pos + TTL *TTLExpr +} + +func (a *AlterTableModifyTTL) Pos() Pos { + return a.ModifyPos +} + +func (a *AlterTableModifyTTL) End() Pos { + return a.StatementEnd +} + +func (a *AlterTableModifyTTL) AlterType() string { + return "MODIFY_TTL" +} + +func (a *AlterTableModifyTTL) String(level int) string { + var builder strings.Builder + builder.WriteString("MODIFY ") + builder.WriteString("TTL ") + builder.WriteString(a.TTL.String(level)) + return builder.String() +} + type AlterTableModifyColumn struct { ModifyPos Pos StatementEnd Pos diff --git a/parser/parser_alter.go b/parser/parser_alter.go index 29602b2..36a215f 100644 --- a/parser/parser_alter.go +++ b/parser/parser_alter.go @@ -530,6 +530,17 @@ func (p *Parser) parseAlterTableModify(pos Pos) (AlterTableExpr, error) { switch { case p.matchKeyword(KeywordColumn): return p.parseAlterTableModifyColumn(pos) + case p.matchKeyword(KeywordTtl): + _ = p.lexer.consumeToken() + ttlExpr, err := p.parseTTLExpr(p.Pos()) + if err != nil { + return nil, err + } + return &AlterTableModifyTTL{ + ModifyPos: pos, + StatementEnd: ttlExpr.End(), + TTL: ttlExpr, + }, nil default: return nil, fmt.Errorf("expected keyword: COLUMN, but got %q", p.last().String) diff --git a/parser/testdata/dml/alter_table_with_modify_remove_ttl.sql b/parser/testdata/dml/alter_table_with_modify_remove_ttl.sql new file mode 100644 index 0000000..f69525e --- /dev/null +++ b/parser/testdata/dml/alter_table_with_modify_remove_ttl.sql @@ -0,0 +1 @@ +ALTER TABLE infra.flow_processed_emails_local ON CLUSTER default_cluster REMOVE TTL; \ No newline at end of file diff --git a/parser/testdata/dml/alter_table_with_modify_ttl.sql b/parser/testdata/dml/alter_table_with_modify_ttl.sql new file mode 100644 index 0000000..ed3b9de --- /dev/null +++ b/parser/testdata/dml/alter_table_with_modify_ttl.sql @@ -0,0 +1 @@ +ALTER TABLE infra.flow_processed_emails_local ON CLUSTER default_cluster MODIFY TTL created_at + INTERVAL 3 YEAR; \ No newline at end of file diff --git a/parser/testdata/dml/format/alter_table_with_modify_remove_ttl.sql b/parser/testdata/dml/format/alter_table_with_modify_remove_ttl.sql new file mode 100644 index 0000000..aa7f352 --- /dev/null +++ b/parser/testdata/dml/format/alter_table_with_modify_remove_ttl.sql @@ -0,0 +1,7 @@ +-- Origin SQL: +ALTER TABLE infra.flow_processed_emails_local ON CLUSTER default_cluster REMOVE TTL; + +-- Format SQL: +ALTER TABLE infra.flow_processed_emails_local +ON CLUSTER default_cluster +REMOVE TTL; diff --git a/parser/testdata/dml/format/alter_table_with_modify_ttl.sql b/parser/testdata/dml/format/alter_table_with_modify_ttl.sql new file mode 100644 index 0000000..16c6b9b --- /dev/null +++ b/parser/testdata/dml/format/alter_table_with_modify_ttl.sql @@ -0,0 +1,7 @@ +-- Origin SQL: +ALTER TABLE infra.flow_processed_emails_local ON CLUSTER default_cluster MODIFY TTL created_at + INTERVAL 3 YEAR; + +-- Format SQL: +ALTER TABLE infra.flow_processed_emails_local +ON CLUSTER default_cluster +MODIFY TTL created_at + INTERVAL 3 YEAR; diff --git a/parser/testdata/dml/output/alter_table_with_modify_remove_ttl.sql.golden.json b/parser/testdata/dml/output/alter_table_with_modify_remove_ttl.sql.golden.json new file mode 100644 index 0000000..eeaccb8 --- /dev/null +++ b/parser/testdata/dml/output/alter_table_with_modify_remove_ttl.sql.golden.json @@ -0,0 +1,35 @@ +[ + { + "AlterPos": 0, + "StatementEnd": 83, + "TableIdentifier": { + "Database": { + "Name": "infra", + "Unquoted": false, + "NamePos": 12, + "NameEnd": 17 + }, + "Table": { + "Name": "flow_processed_emails_local", + "Unquoted": false, + "NamePos": 18, + "NameEnd": 45 + } + }, + "OnCluster": { + "OnPos": 46, + "Expr": { + "Name": "default_cluster", + "Unquoted": false, + "NamePos": 57, + "NameEnd": 72 + } + }, + "AlterExprs": [ + { + "RemovePos": 73, + "StatementEnd": 83 + } + ] + } +] \ No newline at end of file diff --git a/parser/testdata/dml/output/alter_table_with_modify_ttl.sql.golden.json b/parser/testdata/dml/output/alter_table_with_modify_ttl.sql.golden.json new file mode 100644 index 0000000..726b8f3 --- /dev/null +++ b/parser/testdata/dml/output/alter_table_with_modify_ttl.sql.golden.json @@ -0,0 +1,64 @@ +[ + { + "AlterPos": 0, + "StatementEnd": 112, + "TableIdentifier": { + "Database": { + "Name": "infra", + "Unquoted": false, + "NamePos": 12, + "NameEnd": 17 + }, + "Table": { + "Name": "flow_processed_emails_local", + "Unquoted": false, + "NamePos": 18, + "NameEnd": 45 + } + }, + "OnCluster": { + "OnPos": 46, + "Expr": { + "Name": "default_cluster", + "Unquoted": false, + "NamePos": 57, + "NameEnd": 72 + } + }, + "AlterExprs": [ + { + "ModifyPos": 73, + "StatementEnd": 112, + "TTL": { + "TTLPos": 84, + "Expr": { + "LeftExpr": { + "Name": "created_at", + "Unquoted": false, + "NamePos": 84, + "NameEnd": 94 + }, + "Operation": "+", + "RightExpr": { + "IntervalPos": 97, + "Expr": { + "NumPos": 106, + "NumEnd": 107, + "Literal": "3", + "Base": 10 + }, + "Unit": { + "Name": "YEAR", + "Unquoted": false, + "NamePos": 108, + "NameEnd": 112 + } + }, + "HasGlobal": false, + "HasNot": false + } + } + } + ] + } +] \ No newline at end of file