From 2783cac6ba0b905a48f77f883daf82ad10b06215 Mon Sep 17 00:00:00 2001 From: Robin Tang Date: Thu, 19 Dec 2024 13:01:22 -0800 Subject: [PATCH 1/2] More MySQL Improvements (#621) --- lib/antlr/parse.go | 2 ++ lib/mysql/schema/schema.go | 8 +++++--- lib/mysql/schema/schema_test.go | 7 +++++++ sources/mysql/streaming/ddl/ddl.go | 6 +++++- 4 files changed, 19 insertions(+), 4 deletions(-) diff --git a/lib/antlr/parse.go b/lib/antlr/parse.go index 7ab31cef..6446f5c5 100644 --- a/lib/antlr/parse.go +++ b/lib/antlr/parse.go @@ -86,6 +86,8 @@ func visit(tree antlr.Tree) ([]Event, error) { case *generated.RenameTableContext: return processRenameTable(ctx) case + *generated.CreateEventContext, + *generated.DropEventContext, *generated.EmptyStatement_Context, *generated.TruncateTableContext, *generated.AdministrationStatementContext, diff --git a/lib/mysql/schema/schema.go b/lib/mysql/schema/schema.go index 69113b7d..f2aab05f 100644 --- a/lib/mysql/schema/schema.go +++ b/lib/mysql/schema/schema.go @@ -131,9 +131,11 @@ func ParseColumnDataType(originalS string, optionalSQLMode []string) (DataType, s = s[:collateIdx] } - if charSetIdx := strings.Index(s, " character set"); charSetIdx != -1 { - // Strip character set - s = s[:charSetIdx] + for _, charSetPermutation := range []string{" character set", " charset"} { + if charSetIdx := strings.Index(s, charSetPermutation); charSetIdx != -1 { + // Strip character set + s = s[:charSetIdx] + } } parenIndex := strings.Index(s, "(") diff --git a/lib/mysql/schema/schema_test.go b/lib/mysql/schema/schema_test.go index 53dc4d76..82febcb0 100644 --- a/lib/mysql/schema/schema_test.go +++ b/lib/mysql/schema/schema_test.go @@ -116,6 +116,13 @@ func TestParseColumnDataType(t *testing.T) { assert.Equal(t, Varchar, dataType) assert.Equal(t, &Opts{Size: typing.ToPtr(255)}, opts) } + { + // Using charset instead + dataType, opts, err := ParseColumnDataType(`varchar(255) CHARSET utf8mb3 COLLATE utf8mb3_unicode_ci`, nil) + assert.NoError(t, err) + assert.Equal(t, Varchar, dataType) + assert.Equal(t, &Opts{Size: typing.ToPtr(255)}, opts) + } } { // Decimal diff --git a/sources/mysql/streaming/ddl/ddl.go b/sources/mysql/streaming/ddl/ddl.go index 81c26b64..c346517f 100644 --- a/sources/mysql/streaming/ddl/ddl.go +++ b/sources/mysql/streaming/ddl/ddl.go @@ -55,7 +55,11 @@ func (s *SchemaAdapter) ApplyDDL(unixTs int64, query string) error { } func (s *SchemaAdapter) applyDDL(unixTs int64, result antlr.Event) error { - if _, ok := result.(antlr.CreateTableEvent); ok { + switch result.(type) { + case antlr.DropTableEvent: + delete(s.adapters, result.GetTable()) + return nil + case antlr.CreateTableEvent: var cols []Column for _, col := range result.GetColumns() { cols = append(cols, Column{ From 3ba635ed368c8faccfad671653556b43e2422a4c Mon Sep 17 00:00:00 2001 From: Robin Tang Date: Thu, 19 Dec 2024 13:16:42 -0800 Subject: [PATCH 2/2] [DDL] Rename table and Copy table to use `getTableNameFromNode` (#622) --- lib/antlr/create_table.go | 4 ++-- lib/antlr/create_table_test.go | 33 +++++++++++++++++++++++---------- lib/antlr/rename_table.go | 7 ++++++- lib/antlr/rename_table_test.go | 6 +++--- lib/antlr/util.go | 1 + 5 files changed, 35 insertions(+), 16 deletions(-) diff --git a/lib/antlr/create_table.go b/lib/antlr/create_table.go index 9628fe18..3de1f93b 100644 --- a/lib/antlr/create_table.go +++ b/lib/antlr/create_table.go @@ -109,12 +109,12 @@ func processCopyTable(ctx *generated.CopyCreateTableContext) (Event, error) { return nil, fmt.Errorf("expected exactly 2 table names, got %d", len(tableNames)) } - tableName, err := getTextFromSingleNodeBranch(tableNames[0]) + tableName, err := getTableNameFromNode(tableNames[0]) if err != nil { return nil, err } - copiedFromTableName, err := getTextFromSingleNodeBranch(tableNames[1]) + copiedFromTableName, err := getTableNameFromNode(tableNames[1]) if err != nil { return nil, err } diff --git a/lib/antlr/create_table_test.go b/lib/antlr/create_table_test.go index 32e4d6e4..e2aa770d 100644 --- a/lib/antlr/create_table_test.go +++ b/lib/antlr/create_table_test.go @@ -9,16 +9,10 @@ import ( func TestCreateTable(t *testing.T) { { - // Create table LIKE - sameQueries := []string{ - "CREATE TABLE table_name LIKE other_table;", - "create table table_name (like other_table);", - } - - for _, query := range sameQueries { - events, err := Parse(query) + { + // Create table LIKE by specifying schema + events, err := Parse("CREATE TABLE db_name.table_name LIKE db_name.other_table;") assert.NoError(t, err) - assert.Len(t, events, 1) createTableEvent, isOk := events[0].(CopyTableEvent) assert.True(t, isOk) @@ -27,7 +21,26 @@ func TestCreateTable(t *testing.T) { assert.Len(t, createTableEvent.GetColumns(), 0) assert.Equal(t, "other_table", createTableEvent.GetCopyFromTableName()) } - + { + // Create table LIKE + sameQueries := []string{ + "CREATE TABLE table_name LIKE other_table;", + "create table table_name (like other_table);", + } + + for _, query := range sameQueries { + events, err := Parse(query) + assert.NoError(t, err) + assert.Len(t, events, 1) + + createTableEvent, isOk := events[0].(CopyTableEvent) + assert.True(t, isOk) + + assert.Equal(t, "table_name", createTableEvent.GetTable()) + assert.Len(t, createTableEvent.GetColumns(), 0) + assert.Equal(t, "other_table", createTableEvent.GetCopyFromTableName()) + } + } } { // Create table with column as CHARACTER SET and collation specified at the column level diff --git a/lib/antlr/rename_table.go b/lib/antlr/rename_table.go index b6f3450f..d82d3005 100644 --- a/lib/antlr/rename_table.go +++ b/lib/antlr/rename_table.go @@ -13,7 +13,12 @@ func processRenameTable(ctx *generated.RenameTableContext) ([]Event, error) { case *generated.RenameTableClauseContext: var allTableNames []string for _, tableName := range castedChild.AllTableName() { - allTableNames = append(allTableNames, tableName.GetText()) + parsedTableName, err := getTableNameFromNode(tableName) + if err != nil { + return nil, fmt.Errorf("failed to get table name: %w", err) + } + + allTableNames = append(allTableNames, parsedTableName) } // Must be at least two table names diff --git a/lib/antlr/rename_table_test.go b/lib/antlr/rename_table_test.go index afae455c..fc36e845 100644 --- a/lib/antlr/rename_table_test.go +++ b/lib/antlr/rename_table_test.go @@ -20,15 +20,15 @@ func TestRenameTable(t *testing.T) { } { // Another one table variant - events, err := Parse(`RENAME TABLE current_db.tbl_name TO other_db.tbl_name;`) + events, err := Parse(`RENAME TABLE current_db.tbl_name TO current_db.tbl_name;`) assert.NoError(t, err) assert.Len(t, events, 1) renameTableEvent, isOk := events[0].(RenameTableEvent) assert.True(t, isOk) - assert.Equal(t, "current_db.tbl_name", renameTableEvent.GetTable()) - assert.Equal(t, "other_db.tbl_name", renameTableEvent.GetNewTableName()) + assert.Equal(t, "tbl_name", renameTableEvent.GetTable()) + assert.Equal(t, "tbl_name", renameTableEvent.GetNewTableName()) } { // Multiple tables diff --git a/lib/antlr/util.go b/lib/antlr/util.go index 8b427f54..e4aec220 100644 --- a/lib/antlr/util.go +++ b/lib/antlr/util.go @@ -41,6 +41,7 @@ func getTextFromSingleNodeBranch(tree antlr.Tree) (string, error) { return getTextFromSingleNodeBranch(tree.GetChild(0)) } +// TODO: Extend this function to return the schema (if present) func getTableNameFromNode(ctx generated.ITableNameContext) (string, error) { children := ctx.GetChildren() if len(children) != 1 {