@@ -519,7 +519,7 @@ func getSchemaID(tableMap map[int64]*BasicTableInfo, tableID int64) int64 {
519519// schemaName should be "Name.O"
520520func findSchemaIDByName (databaseMap map [int64 ]* BasicDatabaseInfo , schemaName string ) (int64 , bool ) {
521521 for id , info := range databaseMap {
522- if info .Name == schemaName {
522+ if strings . EqualFold ( info .Name , schemaName ) {
523523 return id , true
524524 }
525525 }
@@ -529,7 +529,7 @@ func findSchemaIDByName(databaseMap map[int64]*BasicDatabaseInfo, schemaName str
529529// tableName should be "Name.O"
530530func findTableIDByName (tableMap map [int64 ]* BasicTableInfo , schemaID int64 , tableName string ) (int64 , bool ) {
531531 for id , info := range tableMap {
532- if info .SchemaID == schemaID && info .Name == tableName {
532+ if info .SchemaID == schemaID && strings . EqualFold ( info .Name , tableName ) {
533533 return id , true
534534 }
535535 }
@@ -599,7 +599,7 @@ func buildPersistedDDLEventForDropView(args buildPersistedDDLEventFuncArgs) Pers
599599 // We don't store the relationship: view_id -> table_name, get table name from args.job
600600 event .TableName = args .job .TableName
601601 // The query in job maybe "DROP VIEW test1.view1, test2.view2", we need rebuild it here.
602- event .Query = fmt .Sprintf ("DROP VIEW `%s`.`%s` " , event .SchemaName , event .TableName )
602+ event .Query = fmt .Sprintf ("DROP VIEW %s " , common . QuoteSchema ( event .SchemaName , event .TableName ) )
603603 return event
604604}
605605
@@ -661,7 +661,7 @@ func buildPersistedDDLEventForDropTable(args buildPersistedDDLEventFuncArgs) Per
661661 event .SchemaName = getSchemaName (args .databaseMap , event .SchemaID )
662662 event .TableName = getTableName (args .tableMap , event .TableID )
663663 // The query in job maybe "DROP TABLE test1.table1, test2.table2", we need rebuild it here.
664- event .Query = fmt .Sprintf ("DROP TABLE `%s`.`%s` " , event .SchemaName , event .TableName )
664+ event .Query = fmt .Sprintf ("DROP TABLE %s " , common . QuoteSchema ( event .SchemaName , event .TableName ) )
665665 return event
666666}
667667
@@ -722,6 +722,11 @@ func buildPersistedDDLEventForRenameTable(args buildPersistedDDLEventFuncArgs) P
722722 //
723723 // InvolvingSchemaInfo returns the schema info involved in the job.
724724 // The value should be stored in lower case.
725+ //
726+ // InvolvingSchemaInfo may store normalized lower-case names,
727+ // while the original query can keep user-provided identifier case.
728+ // Prefer names parsed from the original query whenever possible.
729+ // See https://github.com/pingcap/ticdc/pull/2218 for background.
725730 oldSchemaName := args .job .InvolvingSchemaInfo [0 ].Database
726731 oldTableName := args .job .InvolvingSchemaInfo [0 ].Table
727732 stmt , err := parser .New ().ParseOneStmt (args .job .Query , "" , "" )
@@ -743,9 +748,9 @@ func buildPersistedDDLEventForRenameTable(args buildPersistedDDLEventFuncArgs) P
743748 log .Error ("unknown stmt type" , zap .String ("query" , args .job .Query ), zap .Any ("stmt" , stmt ))
744749 }
745750 }
746- event .Query = fmt .Sprintf ("RENAME TABLE `%s`.`%s` TO `%s`.`%s` " ,
747- oldSchemaName , oldTableName ,
748- event .SchemaName , event .TableName )
751+ event .Query = fmt .Sprintf ("RENAME TABLE %s TO %s " ,
752+ common . QuoteSchema ( oldSchemaName , oldTableName ) ,
753+ common . QuoteSchema ( event .SchemaName , event .TableName ) )
749754 }
750755 return event
751756}
@@ -786,8 +791,10 @@ func buildPersistedDDLEventForExchangePartition(args buildPersistedDDLEventFuncA
786791 // Note that partition name should be parsed from original query, not the upperQuery.
787792 partName := strings .TrimSpace (event .Query [idx1 :idx2 ])
788793 partName = strings .Replace (partName , "`" , "" , - 1 )
789- event .Query = fmt .Sprintf ("ALTER TABLE `%s`.`%s` EXCHANGE PARTITION `%s` WITH TABLE `%s`.`%s`" ,
790- event .ExtraSchemaName , event .ExtraTableName , partName , event .SchemaName , event .TableName )
794+ event .Query = fmt .Sprintf ("ALTER TABLE %s EXCHANGE PARTITION %s WITH TABLE %s" ,
795+ common .QuoteSchema (event .ExtraSchemaName , event .ExtraTableName ),
796+ common .QuoteName (partName ),
797+ common .QuoteSchema (event .SchemaName , event .TableName ))
791798
792799 if strings .HasSuffix (upperQuery , "WITHOUT VALIDATION" ) {
793800 event .Query += " WITHOUT VALIDATION"
@@ -799,6 +806,41 @@ func buildPersistedDDLEventForExchangePartition(args buildPersistedDDLEventFuncA
799806 return event
800807}
801808
809+ type renameTableQueryInfo struct {
810+ oldSchemaName string
811+ oldTableName string
812+ newSchemaName string
813+ newTableName string
814+ }
815+
816+ func parseRenameTablesQueryInfos (query string ) ([]renameTableQueryInfo , bool ) {
817+ if query == "" {
818+ return nil , false
819+ }
820+ stmt , err := parser .New ().ParseOneStmt (query , "" , "" )
821+ if err != nil {
822+ log .Warn ("parse rename tables query failed" ,
823+ zap .String ("query" , query ),
824+ zap .Error (err ))
825+ return nil , false
826+ }
827+ renameStmt , ok := stmt .(* ast.RenameTableStmt )
828+ if ! ok {
829+ return nil , false
830+ }
831+
832+ queryInfos := make ([]renameTableQueryInfo , 0 , len (renameStmt .TableToTables ))
833+ for _ , tableToTable := range renameStmt .TableToTables {
834+ queryInfos = append (queryInfos , renameTableQueryInfo {
835+ oldSchemaName : tableToTable .OldTable .Schema .O ,
836+ oldTableName : tableToTable .OldTable .Name .O ,
837+ newSchemaName : tableToTable .NewTable .Schema .O ,
838+ newTableName : tableToTable .NewTable .Name .O ,
839+ })
840+ }
841+ return queryInfos , true
842+ }
843+
802844func buildPersistedDDLEventForRenameTables (args buildPersistedDDLEventFuncArgs ) PersistedDDLEvent {
803845 // TODO: does rename tables has the same problem(finished ts is not the real commit ts) with rename table?
804846 event := buildPersistedDDLEventCommon (args )
@@ -808,25 +850,71 @@ func buildPersistedDDLEventForRenameTables(args buildPersistedDDLEventFuncArgs)
808850 zap .String ("query" , args .job .Query ),
809851 zap .Error (err ))
810852 }
811- if len (renameArgs .RenameTableInfos ) != len (args .job .BinlogInfo .MultipleTableInfos ) {
853+ renameTableInfos := renameArgs .RenameTableInfos
854+ multipleTableInfos := args .job .BinlogInfo .MultipleTableInfos
855+ if len (renameTableInfos ) != len (multipleTableInfos ) {
812856 log .Panic ("should not happen" ,
813- zap .Int ("renameArgsLen" , len (renameArgs .RenameTableInfos )),
814- zap .Int ("multipleTableInfosLen" , len (args .job .BinlogInfo .MultipleTableInfos )))
857+ zap .Int ("renameArgsLen" , len (renameTableInfos )),
858+ zap .Int ("multipleTableInfosLen" , len (multipleTableInfos )),
859+ zap .String ("query" , args .job .Query ))
860+ }
861+
862+ // RenameTableInfos may store normalized lower-case names,
863+ // while the original query can keep user-provided identifier case.
864+ // Prefer names parsed from the original query whenever possible.
865+ // See https://github.com/pingcap/ticdc/pull/2218 for background.
866+ queryInfos , queryParsed := parseRenameTablesQueryInfos (args .job .Query )
867+ if queryParsed && len (queryInfos ) != len (renameTableInfos ) {
868+ log .Panic ("rename tables query info length is inconsistent with args" ,
869+ zap .Int ("queryInfosLen" , len (queryInfos )),
870+ zap .Int ("renameArgsLen" , len (renameTableInfos )),
871+ zap .String ("query" , args .job .Query ))
872+ }
873+
874+ // TiDB <= v8.1 may emit empty old table names for RENAME TABLES args.
875+ // See https://github.com/pingcap/tidb/pull/64421 for the upstream fix.
876+ if ! queryParsed && renameTableInfos [0 ].OldTableName .O == "" {
877+ // TODO: return error instead of falling back to args once builder supports error propagation.
878+ log .Warn ("rename tables args miss old table name and query is unavailable, keep args as-is" ,
879+ zap .Int ("tableCount" , len (renameTableInfos )),
880+ zap .String ("query" , args .job .Query ))
815881 }
816882
817883 var querys []string
818- for _ , info := range renameArgs .RenameTableInfos {
819- event .ExtraSchemaIDs = append (event .ExtraSchemaIDs , info .OldSchemaID )
820- event .ExtraSchemaNames = append (event .ExtraSchemaNames , info .OldSchemaName .O )
821- event .ExtraTableNames = append (event .ExtraTableNames , info .OldTableName .O )
884+ for i , info := range renameTableInfos {
885+ oldSchemaID := info .OldSchemaID
886+ oldSchemaName := info .OldSchemaName .O
887+ oldTableName := info .OldTableName .O
888+ newSchemaName := getSchemaName (args .databaseMap , info .NewSchemaID )
889+ newTableName := info .NewTableName .O
890+ if queryParsed {
891+ queryInfo := queryInfos [i ]
892+ if queryInfo .oldSchemaName != "" {
893+ oldSchemaName = queryInfo .oldSchemaName
894+ }
895+ if queryInfo .oldTableName != "" {
896+ oldTableName = queryInfo .oldTableName
897+ }
898+ if queryInfo .newSchemaName != "" {
899+ newSchemaName = queryInfo .newSchemaName
900+ }
901+ if queryInfo .newTableName != "" {
902+ newTableName = queryInfo .newTableName
903+ }
904+ }
905+
906+ event .ExtraSchemaIDs = append (event .ExtraSchemaIDs , oldSchemaID )
907+ event .ExtraSchemaNames = append (event .ExtraSchemaNames , oldSchemaName )
908+ event .ExtraTableNames = append (event .ExtraTableNames , oldTableName )
822909 event .SchemaIDs = append (event .SchemaIDs , info .NewSchemaID )
823- SchemaName := getSchemaName (args .databaseMap , info .NewSchemaID )
824- event .SchemaNames = append (event .SchemaNames , SchemaName )
825- querys = append (querys , fmt .Sprintf ("RENAME TABLE `%s`.`%s` TO `%s`.`%s`;" , info .OldSchemaName .O , info .OldTableName .O , SchemaName , info .NewTableName .O ))
910+ event .SchemaNames = append (event .SchemaNames , newSchemaName )
911+ querys = append (querys , fmt .Sprintf ("RENAME TABLE %s TO %s;" ,
912+ common .QuoteSchema (oldSchemaName , oldTableName ),
913+ common .QuoteSchema (newSchemaName , newTableName )))
826914 }
827915
828916 event .Query = strings .Join (querys , "" )
829- event .MultipleTableInfos = args . job . BinlogInfo . MultipleTableInfos
917+ event .MultipleTableInfos = multipleTableInfos
830918 // we have to reverse MultipleTableInfos to get correct schema name
831919 // see https://github.com/pingcap/tidb/issues/63710
832920 //
0 commit comments