From 44f9e9a1072788972b221637f0092d9010bf1f5a Mon Sep 17 00:00:00 2001 From: JohnnyThree Date: Thu, 7 May 2020 17:23:53 +0800 Subject: [PATCH] support drop vindex Signed-off-by: JohnnyThree --- go/vt/sqlparser/analyzer.go | 2 +- go/vt/topotools/vschema_ddl.go | 19 ++++++ .../vtgate/plan_executor_vschema_ddl_test.go | 68 +++++++++++++++++++ 3 files changed, 88 insertions(+), 1 deletion(-) diff --git a/go/vt/sqlparser/analyzer.go b/go/vt/sqlparser/analyzer.go index 11e6260af18..bbc90ac6edc 100644 --- a/go/vt/sqlparser/analyzer.go +++ b/go/vt/sqlparser/analyzer.go @@ -232,7 +232,7 @@ func IsDMLStatement(stmt Statement) bool { //IsVschemaDDL returns true if the query is an Vschema alter ddl. func IsVschemaDDL(ddl *DDL) bool { switch ddl.Action { - case CreateVindexStr, AddVschemaTableStr, DropVschemaTableStr, AddColVindexStr, DropColVindexStr, AddSequenceStr, AddAutoIncStr: + case CreateVindexStr, DropVindexStr, AddVschemaTableStr, DropVschemaTableStr, AddColVindexStr, DropColVindexStr, AddSequenceStr, AddAutoIncStr: return true } return false diff --git a/go/vt/topotools/vschema_ddl.go b/go/vt/topotools/vschema_ddl.go index 54858aa1f8c..a557cbc2d2c 100644 --- a/go/vt/topotools/vschema_ddl.go +++ b/go/vt/topotools/vschema_ddl.go @@ -71,6 +71,25 @@ func ApplyVSchemaDDL(ksName string, ks *vschemapb.Keyspace, ddl *sqlparser.DDL) return ks, nil + case sqlparser.DropVindexStr: + name := ddl.VindexSpec.Name.String() + if _, ok := ks.Vindexes[name]; !ok { + return nil, vterrors.Errorf(vtrpcpb.Code_INTERNAL, "vindex %s does not exists in keyspace %s", name, ksName) + } + + for tableName, table := range ks.Tables { + // Make sure there isn't a vindex with the same name left on the table. + for _, vindex := range table.ColumnVindexes { + if vindex.Name == name { + return nil, vterrors.Errorf(vtrpcpb.Code_INTERNAL, "can not drop vindex cause %s still defined on table %s", name, tableName) + } + } + } + + delete(ks.Vindexes, name) + + return ks, nil + case sqlparser.AddVschemaTableStr: if ks.Sharded { return nil, vterrors.Errorf(vtrpcpb.Code_INTERNAL, "add vschema table: unsupported on sharded keyspace %s", ksName) diff --git a/go/vt/vtgate/plan_executor_vschema_ddl_test.go b/go/vt/vtgate/plan_executor_vschema_ddl_test.go index cd3d6655236..ec3b3c8d6e7 100644 --- a/go/vt/vtgate/plan_executor_vschema_ddl_test.go +++ b/go/vt/vtgate/plan_executor_vschema_ddl_test.go @@ -196,6 +196,74 @@ func TestPlanExecutorCreateVindexDDL(t *testing.T) { } } +func TestPlanExecutorDropVindexDDL(t *testing.T) { + *vschemaacl.AuthorizedDDLUsers = "%" + defer func() { + *vschemaacl.AuthorizedDDLUsers = "" + }() + executor, _, _, _ := createExecutorEnvUsing(planAllTheThings) + ks := "TestExecutor" + + vschemaUpdates := make(chan *vschemapb.SrvVSchema, 4) + executor.serv.WatchSrvVSchema(context.Background(), "aa", func(vschema *vschemapb.SrvVSchema, err error) { + vschemaUpdates <- vschema + }) + + vschema := <-vschemaUpdates + _, ok := vschema.Keyspaces[ks].Vindexes["test_vindex"] + if ok { + t.Fatalf("test_vindex should not exist in original vschema") + } + + session := NewSafeSession(&vtgatepb.Session{TargetString: ks}) + stmt := "alter vschema drop vindex test_vindex" + _, err := executor.Execute(context.Background(), "TestExecute", session, stmt, nil) + wantErr := "vindex test_vindex does not exists in keyspace TestExecutor" + if err == nil || err.Error() != wantErr { + t.Errorf("want error %v got %v", wantErr, err) + } + + stmt = "alter vschema drop vindex TestExecutor.test_vindex" + _, err = executor.Execute(context.Background(), "TestExecute", session, stmt, nil) + wantErr = "vindex test_vindex does not exists in keyspace TestExecutor" + if err == nil || err.Error() != wantErr { + t.Errorf("want error %v got %v", wantErr, err) + } + + //add one vindex that has never been used by the tables + stmt = "alter vschema create vindex test_vindex using hash" + _, err = executor.Execute(context.Background(), "TestExecute", session, stmt, nil) + require.NoError(t, err) + + _, vindex := waitForVindex(t, ks, "test_vindex", vschemaUpdates, executor) + if vindex == nil || vindex.Type != "hash" { + t.Errorf("updated vschema did not contain test_vindex") + } + + //drop an existing vindex that has never been used by the tables + stmt = "alter vschema drop vindex TestExecutor.test_vindex" + _, err = executor.Execute(context.Background(), "TestExecute", session, stmt, nil) + require.NoError(t, err) + vschema = <-vschemaUpdates + _, ok = vschema.Keyspaces[ks].Vindexes["test_vindex"] + if ok { + t.Fatalf("test_vindex should not exist after droping it") + } + + //drop an existing vindex that is used by at least one table + stmt = "alter vschema drop vindex TestExecutor.keyspace_id" + _, err = executor.Execute(context.Background(), "TestExecute", session, stmt, nil) + wantErr = "can not drop vindex cause keyspace_id still defined on table ksid_table" + if err == nil || err.Error() != wantErr { + t.Errorf("drop vindex still defined: %v, want %s", err, wantErr) + } + select { + case <-vschemaUpdates: + t.Error("vschema should not be updated on error") + default: + } +} + func TestPlanExecutorAddDropVschemaTableDDL(t *testing.T) { *vschemaacl.AuthorizedDDLUsers = "%" defer func() {