diff --git a/pkg/binlog-filter/filter.go b/pkg/binlog-filter/filter.go index 6ec81c0cf..58d6e4813 100644 --- a/pkg/binlog-filter/filter.go +++ b/pkg/binlog-filter/filter.go @@ -55,6 +55,7 @@ const ( CreateDatabase EventType = "create database" DropDatabase EventType = "drop database" + AlterDatabase EventType = "alter database" CreateTable EventType = "create table" DropTable EventType = "drop table" TruncateTable EventType = "truncate table" @@ -63,9 +64,16 @@ const ( DropIndex EventType = "drop index" CreateView EventType = "create view" DropView EventType = "drop view" - AlertTable EventType = "alter table" + AlterTable EventType = "alter table" + + CreateSchema EventType = "create schema" // alias of CreateDatabase + DropSchema EventType = "drop schema" // alias of DropDatabase + AlterSchema EventType = "alter schema" // alias of AlterDatabase + AddIndex EventType = "add index" // alias of CreateIndex // if need, add more AlertTableOption = "alert table option" + // NullEvent is used to represents unsupported ddl event type when we + // convert a ast.StmtNode or a string to EventType. NullEvent EventType = "" ) @@ -74,13 +82,16 @@ func ClassifyEvent(event EventType) (EventType, error) { switch event { case InsertEvent, UpdateEvent, DeleteEvent: return dml, nil - case CreateDatabase, DropDatabase, CreateTable, DropTable, TruncateTable, RenameTable, - CreateIndex, DropIndex, CreateView, DropView, AlertTable: + case CreateDatabase, DropDatabase, CreateTable, + DropTable, TruncateTable, RenameTable, + CreateIndex, DropIndex, CreateView, + DropView, AlterTable, + CreateSchema, DropSchema, AddIndex: return ddl, nil case NullEvent: return NullEvent, nil default: - return NoneEvent, errors.NotValidf("event type %s", event) + return NullEvent, errors.NotValidf("event type %s", event) } } @@ -115,11 +126,13 @@ func (b *BinlogEventRule) Valid() error { return errors.Errorf("action of binlog event rule %+v should not be empty", b) } - // TODO: check validity of dml/ddl event. for i := range b.Events { - b.Events[i] = EventType(strings.ToLower(string(b.Events[i]))) + et, err := toEventType(string(b.Events[i])) + if err != nil { + return errors.NotValidf("event type %s", b.Events[i]) + } + b.Events[i] = et } - return nil } diff --git a/pkg/binlog-filter/filter_test.go b/pkg/binlog-filter/filter_test.go index 69db26eb6..1cc004723 100644 --- a/pkg/binlog-filter/filter_test.go +++ b/pkg/binlog-filter/filter_test.go @@ -17,6 +17,7 @@ import ( "testing" . "github.com/pingcap/check" + "github.com/pingcap/errors" selector "github.com/pingcap/tidb-tools/pkg/table-rule-selector" ) @@ -125,6 +126,7 @@ func (t *testFilterSuite) TestFilter(c *C) { // mismatched action, err := filter.Filter("xxx_a", "", InsertEvent, "") + c.Assert(err, IsNil) c.Assert(action, Equals, Do) // invalid rule @@ -245,3 +247,41 @@ func (t *testFilterSuite) TestGlobalFilter(c *C) { c.Assert(action, Equals, cs.action) } } + +func (t *testFilterSuite) TestToEventType(c *C) { + cases := []struct { + eventStr string + event EventType + err error + }{ + {"", NullEvent, nil}, + {"insert", InsertEvent, nil}, + {"Insert", InsertEvent, nil}, + {"update", UpdateEvent, nil}, + {"UPDATE", UpdateEvent, nil}, + {"delete", DeleteEvent, nil}, + {"create", NullEvent, errors.NotValidf("event type %s", "create")}, + {"create schema", CreateDatabase, nil}, + {"create SCHEMA", CreateDatabase, nil}, + {"create database", CreateDatabase, nil}, + {"drop schema", DropDatabase, nil}, + {"drop Schema", DropDatabase, nil}, + {"drop database", DropDatabase, nil}, + {"alter database", AlterDatabase, nil}, + {"alter schema", AlterDatabase, nil}, + {"add index", CreateIndex, nil}, + {"create index", CreateIndex, nil}, + {"xxx", NullEvent, errors.NotValidf("event type %s", "xxx")}, + {"I don't know", NullEvent, errors.NotValidf("event type %s", "I don't know")}, + } + + for _, cs := range cases { + event, err := toEventType(cs.eventStr) + c.Assert(cs.event, Equals, event) + if err != nil { + c.Assert(cs.err.Error(), Equals, err.Error()) + } else { + c.Assert(cs.err, IsNil) + } + } +} diff --git a/pkg/binlog-filter/util.go b/pkg/binlog-filter/util.go index b60919e26..939750a82 100644 --- a/pkg/binlog-filter/util.go +++ b/pkg/binlog-filter/util.go @@ -13,7 +13,12 @@ package filter -import "github.com/pingcap/tidb/parser/ast" +import ( + "strings" + + "github.com/pingcap/errors" + "github.com/pingcap/tidb/parser/ast" +) // AstToDDLEvent returns filter.DDLEvent func AstToDDLEvent(node ast.StmtNode) EventType { @@ -38,10 +43,52 @@ func AstToDDLEvent(node ast.StmtNode) EventType { case *ast.DropIndexStmt: return DropIndex case *ast.AlterTableStmt: - return AlertTable + return AlterTable case *ast.CreateViewStmt: return CreateView + case *ast.AlterDatabaseStmt: + return AlterDatabase } return NullEvent } + +// toEventType converts event type string to EventType and check if it is valid. +func toEventType(es string) (EventType, error) { + event := EventType(strings.ToLower(es)) + switch event { + case AllEvent, + AllDDL, + AllDML, + NullEvent, + NoneEvent, + NoneDDL, + NoneDML, + InsertEvent, + UpdateEvent, + DeleteEvent, + CreateDatabase, + DropDatabase, + AlterDatabase, + CreateTable, + DropTable, + TruncateTable, + RenameTable, + CreateIndex, + DropIndex, + CreateView, + DropView, + AlterTable: + return event, nil + case CreateSchema: // alias of CreateDatabase + return CreateDatabase, nil + case DropSchema: // alias of DropDatabase + return DropDatabase, nil + case AddIndex: // alias of CreateIndex + return CreateIndex, nil + case AlterSchema: + return AlterDatabase, nil + default: + return NullEvent, errors.NotValidf("event type %s", es) + } +}