diff --git a/pkg/check/table_structure.go b/pkg/check/table_structure.go index 276044a77..796168819 100644 --- a/pkg/check/table_structure.go +++ b/pkg/check/table_structure.go @@ -58,19 +58,17 @@ func (o *incompatibilityOption) String() string { // In generally we need to check definitions of columns, constraints and table options. // Because of the early TiDB engineering design, we did not have a complete list of check items, which are all based on experience now. type TablesChecker struct { - db *sql.DB - dbinfo *dbutil.DBConfig - tables map[string][]string // schema => []table; if []table is empty, query tables from db - enableANSIQuotes bool + db *sql.DB + dbinfo *dbutil.DBConfig + tables map[string][]string // schema => []table; if []table is empty, query tables from db } // NewTablesChecker returns a Checker -func NewTablesChecker(db *sql.DB, dbinfo *dbutil.DBConfig, tables map[string][]string, enableANSIQuotes bool) Checker { +func NewTablesChecker(db *sql.DB, dbinfo *dbutil.DBConfig, tables map[string][]string) Checker { return &TablesChecker{ - db: db, - dbinfo: dbinfo, - tables: tables, - enableANSIQuotes: enableANSIQuotes, + db: db, + dbinfo: dbinfo, + tables: tables, } } @@ -165,11 +163,7 @@ func (c *TablesChecker) Name() string { } func (c *TablesChecker) checkCreateSQL(statement string) []*incompatibilityOption { - sqlMode := "" - if c.enableANSIQuotes { - sqlMode = "ANSI_QUOTES" - } - parser2, err := dbutil.GetParser(sqlMode) + parser2, err := dbutil.GetParserForDB(c.db) if err != nil { return []*incompatibilityOption{ { @@ -295,18 +289,16 @@ type ShardingTablesCheck struct { tables map[string]map[string][]string // instance => {schema: [table1, table2, ...]} mapping map[string]*column.Mapping checkAutoIncrementPrimaryKey bool - enableANSIQuotes bool } // NewShardingTablesCheck returns a Checker -func NewShardingTablesCheck(name string, dbs map[string]*sql.DB, tables map[string]map[string][]string, mapping map[string]*column.Mapping, checkAutoIncrementPrimaryKey bool, enableANSIQuotes bool) Checker { +func NewShardingTablesCheck(name string, dbs map[string]*sql.DB, tables map[string]map[string][]string, mapping map[string]*column.Mapping, checkAutoIncrementPrimaryKey bool) Checker { return &ShardingTablesCheck{ name: name, dbs: dbs, tables: tables, mapping: mapping, checkAutoIncrementPrimaryKey: checkAutoIncrementPrimaryKey, - enableANSIQuotes: enableANSIQuotes, } } @@ -324,17 +316,6 @@ func (c *ShardingTablesCheck) Check(ctx context.Context) *Result { tableName string ) - sqlMode := "" - if c.enableANSIQuotes { - sqlMode = "ANSI_QUOTES" - } - parser2, err := dbutil.GetParser(sqlMode) - if err != nil { - markCheckError(r, err) - r.Extra = fmt.Sprintf("fail to get parser") - return r - } - for instance, schemas := range c.tables { db, ok := c.dbs[instance] if !ok { @@ -342,6 +323,13 @@ func (c *ShardingTablesCheck) Check(ctx context.Context) *Result { return r } + parser2, err := dbutil.GetParserForDB(db) + if err != nil { + markCheckError(r, err) + r.Extra = fmt.Sprintf("fail to get parser for instance %s on sharding %s", instance, c.name) + return r + } + for schema, tables := range schemas { for _, table := range tables { statement, err := dbutil.GetCreateTableSQL(ctx, db, schema, table) @@ -355,7 +343,7 @@ func (c *ShardingTablesCheck) Check(ctx context.Context) *Result { return r } - info, err := dbutil.GetTableInfoBySQL(statement, sqlMode) + info, err := dbutil.GetTableInfoBySQL(statement, parser2) if err != nil { markCheckError(r, err) r.Extra = fmt.Sprintf("instance %s on sharding %s", instance, c.name) diff --git a/pkg/dbutil/common.go b/pkg/dbutil/common.go index 15bfdfa98..5f1d016dd 100644 --- a/pkg/dbutil/common.go +++ b/pkg/dbutil/common.go @@ -72,8 +72,6 @@ type DBConfig struct { Schema string `toml:"schema" json:"schema"` Snapshot string `toml:"snapshot" json:"snapshot"` - - SQLMode string `toml:"sql-mode" json:"sql-mode"` } // String returns native format of database configuration @@ -606,6 +604,52 @@ func GetDBVersion(ctx context.Context, db *sql.DB) (string, error) { return "", ErrVersionNotFound } +// GetSessionVariable gets server's session variable, although argument is *sql.DB, (session) system variables may be +// set through DSN +func GetSessionVariable(db *sql.DB, variable string) (value string, err error) { + query := fmt.Sprintf("SHOW VARIABLES LIKE '%s'", variable) + rows, err := db.Query(query) + + if err != nil { + return "", errors.Trace(err) + } + defer rows.Close() + + // Show an example. + /* + mysql> SHOW VARIABLES LIKE "binlog_format"; + +---------------+-------+ + | Variable_name | Value | + +---------------+-------+ + | binlog_format | ROW | + +---------------+-------+ + */ + + for rows.Next() { + err = rows.Scan(&variable, &value) + if err != nil { + return "", errors.Trace(err) + } + } + + if rows.Err() != nil { + return "", errors.Trace(err) + } + + return value, nil +} + +// GetSQLMode returns sql_mode. +func GetSQLMode(db *sql.DB) (tmysql.SQLMode, error) { + sqlMode, err := GetSessionVariable(db, "sql_mode") + if err != nil { + return tmysql.ModeNone, err + } + + mode, err := tmysql.GetSQLMode(sqlMode) + return mode, errors.Trace(err) +} + // IsTiDB returns true if this database is tidb func IsTiDB(ctx context.Context, db *sql.DB) (bool, error) { version, err := GetDBVersion(ctx, db) @@ -766,8 +810,8 @@ func DeleteRows(ctx context.Context, db *sql.DB, schemaName string, tableName st return DeleteRows(ctx, db, schemaName, tableName, where, args) } -// GetParser gets parser according to sql mode -func GetParser(sqlModeStr string) (*parser.Parser, error) { +// getParser gets parser according to sql mode +func getParser(sqlModeStr string) (*parser.Parser, error) { if len(sqlModeStr) == 0 { return parser.New(), nil } @@ -780,3 +824,15 @@ func GetParser(sqlModeStr string) (*parser.Parser, error) { parser2.SetSQLMode(sqlMode) return parser2, nil } + +// GetParserForDB discovers ANSI_QUOTES in db's session variables and returns a proper parser +func GetParserForDB(db *sql.DB) (*parser.Parser, error) { + mode, err := GetSQLMode(db) + if err != nil { + return nil, err + } + + parser2 := parser.New() + parser2.SetSQLMode(mode) + return parser2, nil +} diff --git a/pkg/dbutil/common_test.go b/pkg/dbutil/common_test.go index a756809c7..848cfc224 100644 --- a/pkg/dbutil/common_test.go +++ b/pkg/dbutil/common_test.go @@ -170,7 +170,7 @@ func (s *testDBSuite) TestGetParser(c *C) { } for _, testCase := range testCases { - parser, err := GetParser(testCase.sqlModeStr) + parser, err := getParser(testCase.sqlModeStr) if testCase.hasErr { c.Assert(err, NotNil) } else { diff --git a/pkg/dbutil/index_test.go b/pkg/dbutil/index_test.go index 68d40074b..278167429 100644 --- a/pkg/dbutil/index_test.go +++ b/pkg/dbutil/index_test.go @@ -15,6 +15,7 @@ package dbutil import ( . "github.com/pingcap/check" + "github.com/pingcap/parser" ) func (*testDBSuite) TestIndex(c *C) { @@ -81,7 +82,7 @@ func (*testDBSuite) TestIndex(c *C) { } for _, testCase := range testCases { - tableInfo, err := GetTableInfoBySQL(testCase.sql, "") + tableInfo, err := GetTableInfoBySQL(testCase.sql, parser.New()) c.Assert(err, IsNil) indices := FindAllIndex(tableInfo) diff --git a/pkg/dbutil/table.go b/pkg/dbutil/table.go index a5e4b4c92..84a702cc0 100644 --- a/pkg/dbutil/table.go +++ b/pkg/dbutil/table.go @@ -20,6 +20,7 @@ import ( "strings" "github.com/pingcap/errors" + "github.com/pingcap/parser" "github.com/pingcap/parser/ast" "github.com/pingcap/parser/model" "github.com/pingcap/tidb/ddl" @@ -28,22 +29,21 @@ import ( ) // GetTableInfo returns table information. -func GetTableInfo(ctx context.Context, db *sql.DB, schemaName string, tableName string, sqlMode string) (*model.TableInfo, error) { +func GetTableInfo(ctx context.Context, db *sql.DB, schemaName string, tableName string) (*model.TableInfo, error) { createTableSQL, err := GetCreateTableSQL(ctx, db, schemaName, tableName) if err != nil { return nil, errors.Trace(err) } - return GetTableInfoBySQL(createTableSQL, sqlMode) -} - -// GetTableInfoBySQL returns table information by given create table sql. -func GetTableInfoBySQL(createTableSQL string, sqlMode string) (table *model.TableInfo, err error) { - parser2, err := GetParser(sqlMode) + parser2, err := GetParserForDB(db) if err != nil { return nil, errors.Trace(err) } + return GetTableInfoBySQL(createTableSQL, parser2) +} +// GetTableInfoBySQL returns table information by given create table sql. +func GetTableInfoBySQL(createTableSQL string, parser2 *parser.Parser) (table *model.TableInfo, err error) { stmt, err := parser2.ParseOneStmt(createTableSQL, "", "") if err != nil { return nil, errors.Trace(err) diff --git a/pkg/dbutil/table_test.go b/pkg/dbutil/table_test.go index 57a6c2cbd..30fa5bf92 100644 --- a/pkg/dbutil/table_test.go +++ b/pkg/dbutil/table_test.go @@ -17,6 +17,7 @@ import ( "testing" . "github.com/pingcap/check" + "github.com/pingcap/parser" "github.com/pingcap/parser/mysql" ) @@ -78,7 +79,7 @@ func (*testDBSuite) TestTable(c *C) { } for _, testCase := range testCases { - tableInfo, err := GetTableInfoBySQL(testCase.sql, "") + tableInfo, err := GetTableInfoBySQL(testCase.sql, parser.New()) c.Assert(err, IsNil) for i, column := range tableInfo.Columns { c.Assert(testCase.columns[i], Equals, column.Name.O) @@ -95,15 +96,17 @@ func (*testDBSuite) TestTable(c *C) { func (*testDBSuite) TestTableStructEqual(c *C) { createTableSQL1 := "CREATE TABLE `test`.`atest` (`id` int(24), `name` varchar(24), `birthday` datetime, `update_time` time, `money` decimal(20,2), primary key(`id`))" - tableInfo1, err := GetTableInfoBySQL(createTableSQL1, "") + tableInfo1, err := GetTableInfoBySQL(createTableSQL1, parser.New()) c.Assert(err, IsNil) createTableSQL2 := "CREATE TABLE `test`.`atest` (`id` int(24) NOT NULL, `name` varchar(24), `birthday` datetime, `update_time` time, `money` decimal(20,2), primary key(`id`))" - tableInfo2, err := GetTableInfoBySQL(createTableSQL2, "") + tableInfo2, err := GetTableInfoBySQL(createTableSQL2, parser.New()) c.Assert(err, IsNil) createTableSQL3 := `CREATE TABLE "test"."atest" ("id" int(24), "name" varchar(24), "birthday" datetime, "update_time" time, "money" decimal(20,2), unique key("id"))` - tableInfo3, err := GetTableInfoBySQL(createTableSQL3, "ANSI_QUOTES") + p := parser.New() + p.SetSQLMode(mysql.ModeANSIQuotes) + tableInfo3, err := GetTableInfoBySQL(createTableSQL3, p) c.Assert(err, IsNil) equal, _ := EqualTableInfo(tableInfo1, tableInfo2) diff --git a/pkg/diff/chunk_test.go b/pkg/diff/chunk_test.go index 72d4a785f..c37ca25fc 100644 --- a/pkg/diff/chunk_test.go +++ b/pkg/diff/chunk_test.go @@ -71,7 +71,7 @@ func (*testChunkSuite) TestSplitRange(c *C) { // only work on tidb, so don't assert err here _, _ = conn.ExecContext(ctx, "ANALYZE TABLE `test`.`test_chunk`") - tableInfo, err := dbutil.GetTableInfo(ctx, conn, "test", "test_chunk", "") + tableInfo, err := dbutil.GetTableInfo(ctx, conn, "test", "test_chunk") c.Assert(err, IsNil) tableInstance := &TableInstance{ diff --git a/pkg/diff/diff.go b/pkg/diff/diff.go index 124384730..ed3d2db90 100644 --- a/pkg/diff/diff.go +++ b/pkg/diff/diff.go @@ -48,7 +48,6 @@ type TableInstance struct { Table string `json:"table"` InstanceID string `json:"instance-id"` info *model.TableInfo - SQLMode string `json:"sql-mode"` } // TableDiff saves config for diff table @@ -212,14 +211,14 @@ func (t *TableDiff) adjustConfig() { } func (t *TableDiff) getTableInfo(ctx context.Context) error { - tableInfo, err := dbutil.GetTableInfo(ctx, t.TargetTable.Conn, t.TargetTable.Schema, t.TargetTable.Table, t.TargetTable.SQLMode) + tableInfo, err := dbutil.GetTableInfo(ctx, t.TargetTable.Conn, t.TargetTable.Schema, t.TargetTable.Table) if err != nil { return errors.Trace(err) } t.TargetTable.info = ignoreColumns(tableInfo, t.IgnoreColumns) for _, sourceTable := range t.SourceTables { - tableInfo, err := dbutil.GetTableInfo(ctx, sourceTable.Conn, sourceTable.Schema, sourceTable.Table, sourceTable.SQLMode) + tableInfo, err := dbutil.GetTableInfo(ctx, sourceTable.Conn, sourceTable.Schema, sourceTable.Table) if err != nil { return errors.Trace(err) } diff --git a/pkg/diff/diff_test.go b/pkg/diff/diff_test.go index 86e5522b9..8367809eb 100644 --- a/pkg/diff/diff_test.go +++ b/pkg/diff/diff_test.go @@ -23,6 +23,7 @@ import ( _ "github.com/go-sql-driver/mysql" . "github.com/pingcap/check" "github.com/pingcap/failpoint" + "github.com/pingcap/parser" "github.com/pingcap/tidb-tools/pkg/dbutil" "github.com/pingcap/tidb-tools/pkg/importer" ) @@ -37,7 +38,7 @@ type testDiffSuite struct{} func (*testDiffSuite) TestGenerateSQLs(c *C) { createTableSQL := "CREATE TABLE `diff_test`.`atest` (`id` int(24), `name` varchar(24), `birthday` datetime, `update_time` time, `money` decimal(20,2), `id_gen` int(11) GENERATED ALWAYS AS ((`id` + 1)) VIRTUAL, primary key(`id`, `name`))" - tableInfo, err := dbutil.GetTableInfoBySQL(createTableSQL, "") + tableInfo, err := dbutil.GetTableInfoBySQL(createTableSQL, parser.New()) c.Assert(err, IsNil) rowsData := map[string]*dbutil.ColumnData{ @@ -56,7 +57,7 @@ func (*testDiffSuite) TestGenerateSQLs(c *C) { // test the unique key createTableSQL2 := "CREATE TABLE `diff_test`.`atest` (`id` int(24), `name` varchar(24), `birthday` datetime, `update_time` time, `money` decimal(20,2), unique key(`id`, `name`))" - tableInfo2, err := dbutil.GetTableInfoBySQL(createTableSQL2, "") + tableInfo2, err := dbutil.GetTableInfoBySQL(createTableSQL2, parser.New()) c.Assert(err, IsNil) replaceSQL = generateDML("replace", rowsData, tableInfo2, "diff_test") deleteSQL = generateDML("delete", rowsData, tableInfo2, "diff_test") @@ -188,10 +189,10 @@ func testStructEqual(ctx context.Context, conn *sql.DB, c *C) { _, err = conn.ExecContext(ctx, testCase.createTargetTable) c.Assert(err, IsNil) - sourceInfo, err := dbutil.GetTableInfoBySQL(testCase.createSourceTable, "") + sourceInfo, err := dbutil.GetTableInfoBySQL(testCase.createSourceTable, parser.New()) c.Assert(err, IsNil) - targetInfo, err := dbutil.GetTableInfoBySQL(testCase.createTargetTable, "") + targetInfo, err := dbutil.GetTableInfoBySQL(testCase.createTargetTable, parser.New()) c.Assert(err, IsNil) tableDiff := createTableDiff(conn, "diff_test", []string{sourceInfo.Name.O}, targetInfo.Name.O) diff --git a/pkg/diff/merge_test.go b/pkg/diff/merge_test.go index e83cf3967..f4d7824bc 100644 --- a/pkg/diff/merge_test.go +++ b/pkg/diff/merge_test.go @@ -17,6 +17,7 @@ import ( "container/heap" . "github.com/pingcap/check" + "github.com/pingcap/parser" "github.com/pingcap/tidb-tools/pkg/dbutil" ) @@ -26,7 +27,7 @@ type testMergerSuite struct{} func (s *testMergerSuite) TestMerge(c *C) { createTableSQL := "create table test.test(id int(24), name varchar(24), age int(24), primary key(id, name));" - tableInfo, err := dbutil.GetTableInfoBySQL(createTableSQL, "") + tableInfo, err := dbutil.GetTableInfoBySQL(createTableSQL, parser.New()) c.Assert(err, IsNil) _, orderKeyCols := dbutil.SelectUniqueOrderKey(tableInfo) diff --git a/pkg/diff/spliter_test.go b/pkg/diff/spliter_test.go index d0e51ef4b..4d9095584 100644 --- a/pkg/diff/spliter_test.go +++ b/pkg/diff/spliter_test.go @@ -18,6 +18,7 @@ import ( sqlmock "github.com/DATA-DOG/go-sqlmock" . "github.com/pingcap/check" + "github.com/pingcap/parser" "github.com/pingcap/tidb-tools/pkg/dbutil" ) @@ -113,7 +114,7 @@ func (s *testSpliterSuite) TestSplitRangeByRandom(c *C) { } for i, testCase := range testCases { - tableInfo, err := dbutil.GetTableInfoBySQL(testCase.createTableSQL, "") + tableInfo, err := dbutil.GetTableInfoBySQL(testCase.createTableSQL, parser.New()) c.Assert(err, IsNil) splitCols, err := getSplitFields(tableInfo, nil) @@ -200,7 +201,7 @@ func (s *testSpliterSuite) TestRandomSpliter(c *C) { } for i, testCase := range testCases { - tableInfo, err := dbutil.GetTableInfoBySQL(testCase.createTableSQL, "") + tableInfo, err := dbutil.GetTableInfoBySQL(testCase.createTableSQL, parser.New()) c.Assert(err, IsNil) tableInstance := &TableInstance{ @@ -252,7 +253,7 @@ func (s *testSpliterSuite) TestBucketSpliter(c *C) { c.Assert(err, IsNil) createTableSQL := "create table `test`.`test`(`a` int, `b` varchar(10), `c` float, `d` datetime, primary key(`a`, `b`))" - tableInfo, err := dbutil.GetTableInfoBySQL(createTableSQL, "") + tableInfo, err := dbutil.GetTableInfoBySQL(createTableSQL, parser.New()) c.Assert(err, IsNil) testCases := []struct { diff --git a/pkg/diff/util_test.go b/pkg/diff/util_test.go index 684725c02..ab62213e9 100644 --- a/pkg/diff/util_test.go +++ b/pkg/diff/util_test.go @@ -15,6 +15,7 @@ package diff import ( . "github.com/pingcap/check" + "github.com/pingcap/parser" "github.com/pingcap/parser/model" "github.com/pingcap/tidb-tools/pkg/dbutil" ) @@ -25,7 +26,7 @@ type testUtilSuite struct{} func (s *testUtilSuite) TestIgnoreColumns(c *C) { createTableSQL1 := "CREATE TABLE `test`.`atest` (`a` int, `b` int, `c` int, `d` int, primary key(`a`))" - tableInfo1, err := dbutil.GetTableInfoBySQL(createTableSQL1, "") + tableInfo1, err := dbutil.GetTableInfoBySQL(createTableSQL1, parser.New()) c.Assert(err, IsNil) tbInfo := ignoreColumns(tableInfo1, []string{"a"}) c.Assert(tbInfo.Columns, HasLen, 3) @@ -33,14 +34,14 @@ func (s *testUtilSuite) TestIgnoreColumns(c *C) { c.Assert(tbInfo.Columns[2].Offset, Equals, 2) createTableSQL2 := "CREATE TABLE `test`.`atest` (`a` int, `b` int, `c` int, `d` int, primary key(`a`), index idx(`b`, `c`))" - tableInfo2, err := dbutil.GetTableInfoBySQL(createTableSQL2, "") + tableInfo2, err := dbutil.GetTableInfoBySQL(createTableSQL2, parser.New()) c.Assert(err, IsNil) tbInfo = ignoreColumns(tableInfo2, []string{"a", "b"}) c.Assert(tbInfo.Columns, HasLen, 2) c.Assert(tbInfo.Indices, HasLen, 0) createTableSQL3 := "CREATE TABLE `test`.`atest` (`a` int, `b` int, `c` int, `d` int, primary key(`a`), index idx(`b`, `c`))" - tableInfo3, err := dbutil.GetTableInfoBySQL(createTableSQL3, "") + tableInfo3, err := dbutil.GetTableInfoBySQL(createTableSQL3, parser.New()) c.Assert(err, IsNil) tbInfo = ignoreColumns(tableInfo3, []string{"b", "c"}) c.Assert(tbInfo.Columns, HasLen, 2) diff --git a/sync_diff_inspector/diff.go b/sync_diff_inspector/diff.go index 240b19582..061f70723 100644 --- a/sync_diff_inspector/diff.go +++ b/sync_diff_inspector/diff.go @@ -223,9 +223,9 @@ func (df *Diff) adjustTableConfigBySubTask(cfg *Config) (err error) { continue } - tableInfo, err := dbutil.GetTableInfo(df.ctx, df.targetDB.Conn, schema, table, df.targetDB.SQLMode) + tableInfo, err := dbutil.GetTableInfo(df.ctx, df.targetDB.Conn, schema, table) if err != nil { - return errors.Errorf("get table %s.%s's inforamtion error %s", schema, table, errors.ErrorStack(err)) + return errors.Errorf("get table %s.%s's information error %s", schema, table, errors.ErrorStack(err)) } if _, ok := df.tables[schema]; !ok { @@ -322,9 +322,9 @@ func (df *Diff) AdjustTableConfig(cfg *Config) (err error) { } for _, tableName := range tables { - tableInfo, err := dbutil.GetTableInfo(df.ctx, df.targetDB.Conn, schemaTables.Schema, tableName, df.targetDB.SQLMode) + tableInfo, err := dbutil.GetTableInfo(df.ctx, df.targetDB.Conn, schemaTables.Schema, tableName) if err != nil { - return errors.Errorf("get table %s.%s's inforamtion error %s", schemaTables.Schema, tableName, errors.ErrorStack(err)) + return errors.Errorf("get table %s.%s's information error %s", schemaTables.Schema, tableName, errors.ErrorStack(err)) } if _, ok := df.tables[schemaTables.Schema][tableName]; ok { @@ -405,10 +405,6 @@ func (df *Diff) AdjustTableConfig(cfg *Config) (err error) { } func (df *Diff) adjustDBCfgByDMSubTasks(cfg *Config) error { - sqlMode := "" - if df.subTaskCfgs[0].EnableANSIQuotes { - sqlMode = "ANSI_QUOTES" - } // all subtask had same target, so use subTaskCfgs[0] cfg.TargetDBCfg = DBConfig{ InstanceID: "target", @@ -417,7 +413,6 @@ func (df *Diff) adjustDBCfgByDMSubTasks(cfg *Config) error { Port: df.subTaskCfgs[0].To.Port, User: df.subTaskCfgs[0].To.User, Password: df.subTaskCfgs[0].To.Password, - SQLMode: sqlMode, }, } @@ -430,7 +425,6 @@ func (df *Diff) adjustDBCfgByDMSubTasks(cfg *Config) error { Port: subTaskCfg.From.Port, User: subTaskCfg.From.User, Password: subTaskCfg.From.Password, - SQLMode: sqlMode, }, }) } @@ -532,7 +526,6 @@ func (df *Diff) Equal() (err error) { Schema: sourceTable.Schema, Table: sourceTable.Table, InstanceID: sourceTable.InstanceID, - SQLMode: df.sourceDBs[sourceTable.InstanceID].SQLMode, } sourceTables = append(sourceTables, sourceTableInstance) } @@ -542,7 +535,6 @@ func (df *Diff) Equal() (err error) { Schema: table.Schema, Table: table.Table, InstanceID: df.targetDB.InstanceID, - SQLMode: df.targetDB.SQLMode, } // find tidb instance for getting statistical information to split chunk diff --git a/sync_diff_inspector/dm_test.go b/sync_diff_inspector/dm_test.go index 33e3ee5e6..a3fffae3c 100644 --- a/sync_diff_inspector/dm_test.go +++ b/sync_diff_inspector/dm_test.go @@ -157,6 +157,9 @@ func mockDB(c *C) (*sql.DB, *sql.DB, *sql.DB) { rows = sqlmock.NewRows([]string{"Table", "Create Table"}).AddRow("t_target", "CREATE TABLE t_target (id int primary key, name varchar(24))") targetMock.ExpectQuery("SHOW CREATE TABLE.*").WillReturnRows(rows) + rows = sqlmock.NewRows([]string{"Variable_name", "Value"}).AddRow("sql_mode", "ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION") + targetMock.ExpectQuery("SHOW VARIABLES LIKE 'sql_mode'").WillReturnRows(rows) + return sourceDB1, sourceDB2, targetDB } diff --git a/tests/sync_diff_inspector/snapshot/run.sh b/tests/sync_diff_inspector/snapshot/run.sh index 39d80d04d..f94ddcdb3 100644 --- a/tests/sync_diff_inspector/snapshot/run.sh +++ b/tests/sync_diff_inspector/snapshot/run.sh @@ -20,24 +20,19 @@ check_contains "check failed" $OUT_DIR/snapshot_diff.log # fix.sql will be empty after check below, so backup it cp $OUT_DIR/fix.sql $OUT_DIR/fix.sql.bak -echo "use snapshot compare data, test sql mode by the way, will return error, diff should not passed" +echo "use snapshot compare data, test sql mode by the way, will auto discover ANSI_QUOTES thus pass" mysql -uroot -h 127.0.0.1 -P 4000 -e "SET GLOBAL sql_mode = 'ANSI_QUOTES';" sleep 10 mysql -uroot -h 127.0.0.1 -P 4000 -e "show variables like '%sql_mode%'" mysql -uroot -h 127.0.0.1 -P 4000 -e "show create table diff_test.test" cp config_base.toml config.toml echo "snapshot = \"$ts\"" >> config.toml -sync_diff_inspector --config=./config.toml > $OUT_DIR/snapshot_diff.log || true -check_contains "get table diff_test.test's inforamtion error" $OUT_DIR/snapshot_diff.log - echo "use snapshot compare data, data should be equal" -echo "sql-mode = 'ANSI_QUOTES'" >> config.toml sync_diff_inspector --config=./config.toml > $OUT_DIR/snapshot_diff.log check_contains "check pass!!!" $OUT_DIR/snapshot_diff.log echo "execute fix.sql and use base config, and then compare data, data should be equal" cat $OUT_DIR/fix.sql.bak | mysql -uroot -h127.0.0.1 -P 4000 -echo "sql-mode = 'ANSI_QUOTES'" >> config_base.toml sync_diff_inspector --config=./config_base.toml > $OUT_DIR/snapshot_diff.log check_contains "check pass!!!" $OUT_DIR/snapshot_diff.log