From 669d29fd00fbc1540d23ffc2e221843c5704eae6 Mon Sep 17 00:00:00 2001 From: lance6716 Date: Mon, 12 Oct 2020 14:21:41 +0800 Subject: [PATCH] dumpling: properly enable EscapeBackslash since loader use upstream's SQL Mode --- dumpling/dumpling.go | 12 ++++++++---- tests/full_mode/data/db1.prepare.sql | 7 ++++--- tests/full_mode/run.sh | 3 +++ 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/dumpling/dumpling.go b/dumpling/dumpling.go index 957987671a..0988eaa8e4 100644 --- a/dumpling/dumpling.go +++ b/dumpling/dumpling.go @@ -59,6 +59,7 @@ func (m *Dumpling) Init(ctx context.Context) error { var err error m.dumpConfig, err = m.constructArgs() m.detectSQLMode() + m.logger.Info("create dumpling", zap.Stringer("config", m.dumpConfig)) return err } @@ -211,7 +212,6 @@ func (m *Dumpling) constructArgs() (*export.Config, error) { return nil, err } dumpConfig.TableFilter = tableFilter - dumpConfig.EscapeBackslash = true dumpConfig.CompleteInsert = true // always keep column name in `INSERT INTO` statements. dumpConfig.Logger = m.logger.Logger @@ -254,8 +254,6 @@ func (m *Dumpling) constructArgs() (*export.Config, error) { dumpConfig.PosAfterConnect = true } - m.logger.Info("create dumpling", zap.Stringer("config", dumpConfig)) - if !cfg.CaseSensitive { dumpConfig.TableFilter = filter.CaseInsensitive(dumpConfig.TableFilter) } @@ -263,7 +261,8 @@ func (m *Dumpling) constructArgs() (*export.Config, error) { return dumpConfig, nil } -// detectSQLMode tries to detect SQL mode from upstream. If success, write it to LoaderConfig +// detectSQLMode tries to detect SQL mode from upstream. If success, write it to LoaderConfig. +// Because loader will use this SQL mode, we need to treat disable `EscapeBackslash` when NO_BACKSLASH_ESCAPES func (m *Dumpling) detectSQLMode() { db, err := sql.Open("mysql", m.dumpConfig.GetDSN("")) if err != nil { @@ -277,4 +276,9 @@ func (m *Dumpling) detectSQLMode() { } m.logger.Info("found upstream SQL mode", zap.String("SQL mode", sqlMode)) m.cfg.LoaderConfig.SQLMode = sqlMode + if strings.Contains(sqlMode, "NO_BACKSLASH_ESCAPES") { + m.dumpConfig.EscapeBackslash = false + } else { + m.dumpConfig.EscapeBackslash = true + } } diff --git a/tests/full_mode/data/db1.prepare.sql b/tests/full_mode/data/db1.prepare.sql index 1234e12876..77592b929f 100644 --- a/tests/full_mode/data/db1.prepare.sql +++ b/tests/full_mode/data/db1.prepare.sql @@ -3,9 +3,10 @@ create database `full_mode`; use `full_mode`; create table t1 (id int, name varchar(20), primary key(`id`)); insert into t1 (id, name) values (1, 'arya'), (2, 'catelyn'); -insert into t1 (id, name) values (3, 'Eddard Stark'); -update t1 set name = 'Arya Stark' where id = 1; -update t1 set name = 'Catelyn Stark' where name = 'catelyn'; +insert into t1 (id, name) values (3, 'Eddard +Stark'); +update t1 set name = 'Arya S\\\\tark' where id = 1; +update t1 set name = 'Catelyn S\"\n\ttark' where name = 'catelyn'; -- test multi column index with generated column alter table t1 add column info json; diff --git a/tests/full_mode/run.sh b/tests/full_mode/run.sh index b66503f55b..3d8c848398 100755 --- a/tests/full_mode/run.sh +++ b/tests/full_mode/run.sh @@ -111,6 +111,8 @@ function run() { fail_acquire_global_lock escape_schema + run_sql_both_source "SET @@GLOBAL.SQL_MODE='NO_BACKSLASH_ESCAPES'" + run_sql_file $cur/data/db1.prepare.sql $MYSQL_HOST1 $MYSQL_PORT1 $MYSQL_PASSWORD1 check_contains 'Query OK, 2 rows affected' run_sql_file $cur/data/db2.prepare.sql $MYSQL_HOST2 $MYSQL_PORT2 $MYSQL_PASSWORD2 @@ -149,6 +151,7 @@ function run() { echo "check dump files have been cleaned" ls $WORK_DIR/worker1/dumped_data.test && exit 1 || echo "worker1 auto removed dump files" ls $WORK_DIR/worker2/dumped_data.test && exit 1 || echo "worker2 auto removed dump files" + run_sql_both_source "SET @@GLOBAL.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'" } cleanup_data full_mode