Skip to content

Commit

Permalink
ApplySchema: Allow ALTER DATABASE.
Browse files Browse the repository at this point in the history
This allows using vtctl ApplySchema to execute ALTER DATABASE across all
shards of a keyspace.

Signed-off-by: Anthony Yeh <enisoc@planetscale.com>
  • Loading branch information
enisoc committed Jan 20, 2020
1 parent 1d60870 commit b23afc0
Show file tree
Hide file tree
Showing 7 changed files with 2,712 additions and 2,657 deletions.
8 changes: 8 additions & 0 deletions go/test/endtoend/vtgate/schema/schema_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ func TestMain(m *testing.M) {
func TestSchemaChange(t *testing.T) {
testWithInitialSchema(t)
testWithAlterSchema(t)
testWithAlterDatabase(t)
testWithDropCreateSchema(t)
testSchemaChangePreflightErrorPartially(t)
testDropNonExistentTables(t)
Expand Down Expand Up @@ -135,6 +136,13 @@ func testWithAlterSchema(t *testing.T) {
matchSchema(t, clusterInstance.Keyspaces[0].Shards[0].Vttablets[0].VttabletProcess.TabletPath, clusterInstance.Keyspaces[0].Shards[1].Vttablets[0].VttabletProcess.TabletPath)
}

// testWithAlterDatabase tests that ALTER DATABASE is accepted by the validator.
func testWithAlterDatabase(t *testing.T) {
sql := "create database alter_database_test; alter database alter_database_test default character set = utf8mb4; drop database alter_database_test"
err := clusterInstance.VtctlclientProcess.ApplySchema(keyspaceName, sql)
assert.NoError(t, err)
}

// testWithDropCreateSchema , we should be able to drop and create same schema
//Tests that a DROP and CREATE table will pass PreflightSchema check.
//
Expand Down
25 changes: 15 additions & 10 deletions go/vt/schemamanager/tablet_executor.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,9 @@ func (exec *TabletExecutor) Validate(ctx context.Context, sqls []string) error {
return fmt.Errorf("executor is closed")
}

parsedDDLs, err := exec.parseDDLs(sqls)
// We ignore DATABASE-level DDLs here because detectBigSchemaChanges doesn't
// look at them anyway.
parsedDDLs, _, err := exec.parseDDLs(sqls)
if err != nil {
return err
}
Expand All @@ -114,23 +116,26 @@ func (exec *TabletExecutor) Validate(ctx context.Context, sqls []string) error {
return err
}

func (exec *TabletExecutor) parseDDLs(sqls []string) ([]*sqlparser.DDL, error) {
parsedDDLs := make([]*sqlparser.DDL, 0, len(sqls))
func (exec *TabletExecutor) parseDDLs(sqls []string) ([]*sqlparser.DDL, []*sqlparser.DBDDL, error) {
parsedDDLs := make([]*sqlparser.DDL, 0)
parsedDBDDLs := make([]*sqlparser.DBDDL, 0)
for _, sql := range sqls {
stat, err := sqlparser.Parse(sql)
if err != nil {
return nil, fmt.Errorf("failed to parse sql: %s, got error: %v", sql, err)
return nil, nil, fmt.Errorf("failed to parse sql: %s, got error: %v", sql, err)
}
ddl, ok := stat.(*sqlparser.DDL)
if !ok {
switch ddl := stat.(type) {
case *sqlparser.DDL:
parsedDDLs = append(parsedDDLs, ddl)
case *sqlparser.DBDDL:
parsedDBDDLs = append(parsedDBDDLs, ddl)
default:
if len(exec.tablets) != 1 {
return nil, fmt.Errorf("non-ddl statements can only be executed for single shard keyspaces: %s", sql)
return nil, nil, fmt.Errorf("non-ddl statements can only be executed for single shard keyspaces: %s", sql)
}
continue
}
parsedDDLs = append(parsedDDLs, ddl)
}
return parsedDDLs, nil
return parsedDDLs, parsedDBDDLs, nil
}

// a schema change that satisfies any following condition is considered
Expand Down
2 changes: 2 additions & 0 deletions go/vt/schemamanager/tablet_executor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,8 @@ func TestTabletExecutorValidate(t *testing.T) {
sqls := []string{
"ALTER TABLE test_table ADD COLUMN new_id bigint(20)",
"CREATE TABLE test_table_02 (pk int)",
"ALTER DATABASE db_name DEFAULT CHARACTER SET = utf8mb4",
"ALTER SCHEMA db_name CHARACTER SET = utf8mb4",
}

if err := executor.Validate(ctx, sqls); err == nil {
Expand Down
4 changes: 2 additions & 2 deletions go/vt/sqlparser/ast.go
Original file line number Diff line number Diff line change
Expand Up @@ -688,7 +688,7 @@ func (node *Set) walkSubtree(visit Visit) error {
)
}

// DBDDL represents a CREATE, DROP database statement.
// DBDDL represents a CREATE, DROP, or ALTER database statement.
type DBDDL struct {
Action string
DBName string
Expand All @@ -700,7 +700,7 @@ type DBDDL struct {
// Format formats the node.
func (node *DBDDL) Format(buf *TrackedBuffer) {
switch node.Action {
case CreateStr:
case CreateStr, AlterStr:
buf.WriteString(fmt.Sprintf("%s database %s", node.Action, node.DBName))
case DropStr:
exists := ""
Expand Down
24 changes: 24 additions & 0 deletions go/vt/sqlparser/parse_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -958,6 +958,30 @@ var (
}, {
input: "alter table a drop id",
output: "alter table a",
}, {
input: "alter database d default character set = charset",
output: "alter database d",
}, {
input: "alter database d character set = charset",
output: "alter database d",
}, {
input: "alter database d default collate = collation",
output: "alter database d",
}, {
input: "alter database d collate = collation",
output: "alter database d",
}, {
input: "alter schema d default character set = charset",
output: "alter database d",
}, {
input: "alter schema d character set = charset",
output: "alter database d",
}, {
input: "alter schema d default collate = collation",
output: "alter database d",
}, {
input: "alter schema d collate = collation",
output: "alter database d",
}, {
input: "create table a",
}, {
Expand Down
Loading

0 comments on commit b23afc0

Please sign in to comment.