Skip to content

Commit

Permalink
Improve parser and schemadiff support for ALTER TABLE
Browse files Browse the repository at this point in the history
The parser logic for ALTER TABLE was not allowing for the INSTANT
algorithm. This doesn't implement anything for instant DDL, but it
specifically only allows parsing it.

Additionally, the new VISIBLE / INVISIBLE property on columns can be set
using an `ALTER TABLE ALTER COLUMN`, so this is also added to the parser
as well.

Lastly, this makes schemadiff work with such an ALTER TABLE statement.
It doesn't generate these itself at this point, but implementing support
for handling it is simple to add so this was done as well.

Signed-off-by: Dirkjan Bussink <d.bussink@gmail.com>
  • Loading branch information
dbussink committed May 15, 2022
1 parent f56ac88 commit 491fff9
Show file tree
Hide file tree
Showing 14 changed files with 7,624 additions and 7,350 deletions.
20 changes: 19 additions & 1 deletion go/vt/schemadiff/table.go
Original file line number Diff line number Diff line change
Expand Up @@ -1172,7 +1172,7 @@ func (c *CreateTableEntity) diffColumns(alterTable *sqlparser.AlterTable,
// check diff between before/after columns:
modifyColumnDiff := t1ColEntity.ColumnDiff(t2ColEntity, hints)
if modifyColumnDiff == nil {
// even if there's no apparent change, there can still be implciit changes
// even if there's no apparent change, there can still be implicit changes
// it is possible that the table charset is changed. the column may be some col1 TEXT NOT NULL, possibly in both varsions 1 and 2,
// but implicitly the column has changed its characters set. So we need to explicitly ass a MODIFY COLUMN statement, so that
// MySQL rebuilds it.
Expand Down Expand Up @@ -1492,6 +1492,24 @@ func (c *CreateTableEntity) apply(diff *AlterTableEntityDiff) error {
if !found {
return errors.Wrap(ErrApplyColumnNotFound, opt.NewColDefinition.Name.String())
}
case *sqlparser.AlterColumn:
// we expect the column to exist
found := false
for _, col := range c.TableSpec.Columns {
if col.Name.String() == opt.Column.Name.String() {
found = true
if opt.DropDefault {
col.Type.Options.Default = nil
} else if opt.DefaultVal != nil {
col.Type.Options.Default = opt.DefaultVal
}
col.Type.Options.Invisible = opt.Invisible
break
}
}
if !found {
return errors.Wrap(ErrApplyColumnNotFound, opt.Column.Name.String())
}
case sqlparser.TableOptions:
// Apply table options. Options that have their DEFAULT value are actually remvoed.
for _, option := range opt {
Expand Down
24 changes: 24 additions & 0 deletions go/vt/schemadiff/table_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1041,6 +1041,30 @@ func TestValidate(t *testing.T) {
alter: "alter table t add column i int",
expectErr: ErrApplyDuplicatePartition,
},
{
name: "change to visible with alter column",
from: "create table t (id int, i int invisible, primary key (id))",
alter: "alter table t alter column i set visible",
to: "create table t (id int, i int, primary key (id))",
},
{
name: "change to invisible with alter column",
from: "create table t (id int, i int, primary key (id))",
alter: "alter table t alter column i set invisible",
to: "create table t (id int, i int invisible, primary key (id))",
},
{
name: "remove default with alter column",
from: "create table t (id int, i int default 0, primary key (id))",
alter: "alter table t alter column i drop default",
to: "create table t (id int, i int, primary key (id))",
},
{
name: "change default with alter column",
from: "create table t (id int, i int, primary key (id))",
alter: "alter table t alter column i set default 0",
to: "create table t (id int, i int default 0, primary key (id))",
},
}
hints := DiffHints{}
for _, ts := range tt {
Expand Down
3 changes: 2 additions & 1 deletion go/vt/sqlparser/ast.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,11 +128,12 @@ type (
// AlgorithmValue is the algorithm specified in the alter table command
AlgorithmValue string

// AlterColumn is used to add or drop defaults to columns in alter table command
// AlterColumn is used to add or drop defaults & visibility to columns in alter table command
AlterColumn struct {
Column *ColName
DropDefault bool
DefaultVal Expr
Invisible *bool
}

// With contains the lists of common table expression and specifies if it is recursive or not
Expand Down
19 changes: 10 additions & 9 deletions go/vt/sqlparser/ast_clone.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

25 changes: 13 additions & 12 deletions go/vt/sqlparser/ast_equals.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 11 additions & 4 deletions go/vt/sqlparser/ast_format.go
Original file line number Diff line number Diff line change
Expand Up @@ -1916,11 +1916,18 @@ func (node AlgorithmValue) Format(buf *TrackedBuffer) {

// Format formats the node
func (node *AlterColumn) Format(buf *TrackedBuffer) {
buf.astPrintf(node, "alter column %v", node.Column)
if node.DropDefault {
buf.astPrintf(node, "alter column %v drop default", node.Column)
} else {
buf.astPrintf(node, "alter column %v set default", node.Column)
buf.astPrintf(node, " %v", node.DefaultVal)
buf.astPrintf(node, " drop default")
} else if node.DefaultVal != nil {
buf.astPrintf(node, " set default %v", node.DefaultVal)
}
if node.Invisible != nil {
if *node.Invisible {
buf.astPrintf(node, " set invisible")
} else {
buf.astPrintf(node, " set visible")
}
}
}

Expand Down
18 changes: 11 additions & 7 deletions go/vt/sqlparser/ast_format_fast.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion go/vt/sqlparser/cached_size.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions go/vt/sqlparser/keywords.go
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,7 @@ var keywords = []keyword{
{"insensitive", UNUSED},
{"insert", INSERT},
{"insert_method", INSERT_METHOD},
{"instant", INSTANT},
{"invisible", INVISIBLE},
{"int", INT},
{"int1", UNUSED},
Expand Down
4 changes: 4 additions & 0 deletions go/vt/sqlparser/parse_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1134,6 +1134,8 @@ var (
}, {
input: "alter table a alter x set default NULL, alter column x2 set default 's', alter x3 drop default",
output: "alter table a alter column x set default null, alter column x2 set default 's', alter column x3 drop default",
}, {
input: "alter table a alter column x set visible, alter column x2 set invisible",
}, {
input: "alter table a add spatial key foo (column1)",
}, {
Expand Down Expand Up @@ -1171,6 +1173,8 @@ var (
input: "alter table a convert to character set utf32",
}, {
input: "alter table `By` add column foo int, algorithm = default",
}, {
input: "alter table `By` add column foo int, algorithm = instant",
}, {
input: "alter table a rename b",
}, {
Expand Down
Loading

0 comments on commit 491fff9

Please sign in to comment.