Repository: pingcap/dumpling
Pull request #87 (2020-05-30 12:20:06)

Quote tables, databases, columns in output sqls
Quote tables, databases, columns in output sqls to make sure tables/databases/columns with special name can be outputed correctly.

codecov-commenter: # [Codecov](https://codecov.io/gh/pingcap/dumpling/pull/87?src=pr&el=h1) Report
> Merging [#87](https://codecov.io/gh/pingcap/dumpling/pull/87?src=pr&el=desc) into [master](https://codecov.io/gh/pingcap/dumpling/commit/7e161c7e84f324633045f01067aacc6a51e52413&el=desc) will **increase** coverage by `0.31%`.
> The diff coverage is `72.22%`.


```diff
@@            Coverage Diff             @@
##           master      #87      +/-   ##
==========================================
+ Coverage   56.53%   56.85%   +0.31%     
==========================================
  Files          16       16              
  Lines        1576     1576              
==========================================
+ Hits          891      896       +5     
+ Misses        609      606       -3     
+ Partials       76       74       -2     
```


Patch:
diff --git a/v4/export/ir_impl.go b/v4/export/ir_impl.go
index 7fee859..8940110 100644
--- a/v4/export/ir_impl.go
+++ b/v4/export/ir_impl.go
@@ -255,7 +255,7 @@ func splitTableDataIntoChunks(
 	}
 
 	query := fmt.Sprintf("SELECT MIN(`%s`),MAX(`%s`) FROM `%s`.`%s` ",
-		field, field, dbName, tableName)
+		escapeString(field), escapeString(field), escapeString(dbName), escapeString(tableName))
 	if conf.Where != "" {
 		query = fmt.Sprintf("%s WHERE %s", query, conf.Where)
 	}
@@ -325,7 +325,7 @@ func splitTableDataIntoChunks(
 LOOP:
 	for cutoff <= max {
 		chunkIndex += 1
-		where := fmt.Sprintf("(`%s` >= %d AND `%s` < %d)", field, cutoff, field, cutoff+estimatedStep)
+		where := fmt.Sprintf("(`%s` >= %d AND `%s` < %d)", escapeString(field), cutoff, escapeString(field), cutoff+estimatedStep)
 		query = buildSelectQuery(dbName, tableName, selectedField, buildWhereCondition(conf, where), orderByClause)
 		rows, err := db.Query(query)
 		if err != nil {
diff --git a/v4/export/sql.go b/v4/export/sql.go
index 13bebed..7bbdf44 100644
--- a/v4/export/sql.go
+++ b/v4/export/sql.go
@@ -34,7 +34,7 @@ func ShowCreateDatabase(db *sql.DB, database string) (string, error) {
 	handleOneRow := func(rows *sql.Rows) error {
 		return rows.Scan(&oneRow[0], &oneRow[1])
 	}
-	query := fmt.Sprintf("SHOW CREATE DATABASE %s", database)
+	query := fmt.Sprintf("SHOW CREATE DATABASE `%s`", escapeString(database))
 	err := simpleQuery(db, query, handleOneRow)
 	if err != nil {
 		return "", errors.WithMessage(err, query)
@@ -47,7 +47,7 @@ func ShowCreateTable(db *sql.DB, database, table string) (string, error) {
 	handleOneRow := func(rows *sql.Rows) error {
 		return rows.Scan(&oneRow[0], &oneRow[1])
 	}
-	query := fmt.Sprintf("SHOW CREATE TABLE %s.%s", database, table)
+	query := fmt.Sprintf("SHOW CREATE TABLE `%s`.`%s`", escapeString(database), escapeString(table))
 	err := simpleQuery(db, query, handleOneRow)
 	if err != nil {
 		return "", errors.WithMessage(err, query)
@@ -60,7 +60,7 @@ func ShowCreateView(db *sql.DB, database, view string) (string, error) {
 	handleOneRow := func(rows *sql.Rows) error {
 		return rows.Scan(&oneRow[0], &oneRow[1], &oneRow[2], &oneRow[3])
 	}
-	query := fmt.Sprintf("SHOW CREATE TABLE %s.%s", database, view)
+	query := fmt.Sprintf("SHOW CREATE TABLE `%s`.`%s`", escapeString(database), escapeString(view))
 	err := simpleQuery(db, query, handleOneRow)
 	if err != nil {
 		return "", errors.WithMessage(err, query)
@@ -70,8 +70,8 @@ func ShowCreateView(db *sql.DB, database, view string) (string, error) {
 
 func ListAllTables(db *sql.DB, database string) ([]string, error) {
 	var tables oneStrColumnTable
-	const query = "SELECT table_name FROM information_schema.tables WHERE table_schema = '%s' and table_type = 'BASE TABLE'"
-	if err := simpleQuery(db, fmt.Sprintf(query, database), tables.handleOneRow); err != nil {
+	const query = "SELECT table_name FROM information_schema.tables WHERE table_schema = ? and table_type = 'BASE TABLE'"
+	if err := simpleQueryWithArgs(db, tables.handleOneRow, query, database); err != nil {
 		return nil, errors.WithMessage(err, query)
 	}
 	return tables.data, nil
@@ -79,8 +79,8 @@ func ListAllTables(db *sql.DB, database string) ([]string, error) {
 
 func ListAllViews(db *sql.DB, database string) ([]string, error) {
 	var views oneStrColumnTable
-	const query = "SELECT table_name FROM information_schema.tables WHERE table_schema = '%s' and table_type = 'VIEW'"
-	if err := simpleQuery(db, fmt.Sprintf(query, database), views.handleOneRow); err != nil {
+	const query = "SELECT table_name FROM information_schema.tables WHERE table_schema = ? and table_type = 'VIEW'"
+	if err := simpleQueryWithArgs(db, views.handleOneRow, query, database); err != nil {
 		return nil, errors.WithMessage(err, query)
 	}
 	return views.data, nil
@@ -159,10 +159,11 @@ func buildSelectQuery(database, table string, fields string, where string, order
 	var query strings.Builder
 	query.WriteString("SELECT ")
 	query.WriteString(fields)
-	query.WriteString(" FROM ")
-	query.WriteString(database)
-	query.WriteString(".")
-	query.WriteString(table)
+	query.WriteString(" FROM `")
+	query.WriteString(escapeString(database))
+	query.WriteString("`.`")
+	query.WriteString(escapeString(table))
+	query.WriteString("`")
 
 	if where != "" {
 		query.WriteString(" ")
@@ -198,14 +199,14 @@ func buildOrderByClause(conf *Config, db *sql.DB, database, table string) (strin
 	}
 	tableContainsPriKey := pkName != ""
 	if tableContainsPriKey {
-		return fmt.Sprintf("ORDER BY %s", pkName), nil
+		return fmt.Sprintf("ORDER BY `%s`", escapeString(pkName)), nil
 	}
 	return "", nil
 }
 
 func SelectTiDBRowID(db *sql.DB, database, table string) (bool, error) {
 	const errBadFieldCode = 1054
-	tiDBRowIDQuery := fmt.Sprintf("SELECT _tidb_rowid from %s.%s LIMIT 0", database, table)
+	tiDBRowIDQuery := fmt.Sprintf("SELECT _tidb_rowid from `%s`.`%s` LIMIT 0", escapeString(database), escapeString(table))
 	_, err := db.Exec(tiDBRowIDQuery)
 	if err != nil {
 		errMsg := strings.ToLower(err.Error())
@@ -218,7 +219,7 @@ func SelectTiDBRowID(db *sql.DB, database, table string) (bool, error) {
 }
 
 func GetColumnTypes(db *sql.DB, fields, database, table string) ([]*sql.ColumnType, error) {
-	query := fmt.Sprintf("SELECT %s FROM %s.%s LIMIT 1", fields, database, table)
+	query := fmt.Sprintf("SELECT %s FROM `%s`.`%s` LIMIT 1", fields, escapeString(database), escapeString(table))
 	rows, err := db.Query(query)
 	if err != nil {
 		return nil, withStack(errors.WithMessage(err, query))
@@ -228,23 +229,15 @@ func GetColumnTypes(db *sql.DB, fields, database, table string) ([]*sql.ColumnTy
 }
 
 func GetPrimaryKeyName(db *sql.DB, database, table string) (string, error) {
-	priKeyQuery := `SELECT column_name FROM information_schema.columns
-		WHERE table_schema = ? AND table_name = ? AND column_key = 'PRI';`
-	stmt, err := db.Prepare(priKeyQuery)
-	if err != nil {
-		return "", err
-	}
-	defer stmt.Close()
-	rows, err := stmt.Query(database, table)
-	if err != nil {
-		return "", withStack(errors.WithMessage(err, priKeyQuery))
-	}
-
+	priKeyQuery := "SELECT column_name FROM information_schema.columns " +
+		"WHERE table_schema = ? AND table_name = ? AND column_key = 'PRI';"
 	var colName string
-	for rows.Next() {
-		if err := rows.Scan(&colName); err != nil {
-			rows.Close()
-			return "", withStack(err)
+	row := db.QueryRow(priKeyQuery, database, table)
+	if err := row.Scan(&colName); err != nil {
+		if err == sql.ErrNoRows {
+			return "", nil
+		} else {
+			return "", withStack(errors.WithMessage(err, priKeyQuery))
 		}
 	}
 	return colName, nil
@@ -271,7 +264,7 @@ func FlushTableWithReadLock(db *sql.DB) error {
 }
 
 func LockTables(db *sql.DB, database, table string) error {
-	_, err := db.Exec(fmt.Sprintf("LOCK TABLES `%s`.`%s` READ", database, table))
+	_, err := db.Exec(fmt.Sprintf("LOCK TABLES `%s`.`%s` READ", escapeString(database), escapeString(table)))
 	return withStack(err)
 }
 
@@ -281,7 +274,7 @@ func UnlockTables(db *sql.DB) error {
 }
 
 func UseDatabase(db *sql.DB, databaseName string) error {
-	_, err := db.Exec(fmt.Sprintf("USE %s", databaseName))
+	_, err := db.Exec(fmt.Sprintf("USE `%s`", escapeString(databaseName)))
 	return withStack(err)
 }
 
@@ -340,7 +333,7 @@ func buildSelectField(db *sql.DB, dbName, tableName string) (string, error) {
 			hasGenerateColumn = true
 			continue
 		}
-		availableFields = append(availableFields, wrapBackTicks(fieldName))
+		availableFields = append(availableFields, wrapBackTicks(escapeString(fieldName)))
 	}
 	if hasGenerateColumn {
 		return strings.Join(availableFields, ","), nil
@@ -362,7 +355,11 @@ func (o *oneStrColumnTable) handleOneRow(rows *sql.Rows) error {
 }
 
 func simpleQuery(db *sql.DB, sql string, handleOneRow func(*sql.Rows) error) error {
-	rows, err := db.Query(sql)
+	return simpleQueryWithArgs(db, handleOneRow, sql)
+}
+
+func simpleQueryWithArgs(db *sql.DB, handleOneRow func(*sql.Rows) error, sql string, args ...interface{}) error {
+	rows, err := db.Query(sql, args...)
 	if err != nil {
 		return withStack(err)
 	}
@@ -425,7 +422,7 @@ func pickupPossibleField(dbName, tableName string, db *sql.DB, conf *Config) (st
 }
 
 func estimateCount(dbName, tableName string, db *sql.DB, field string, conf *Config) uint64 {
-	query := fmt.Sprintf("EXPLAIN SELECT `%s` FROM `%s`.`%s`", field, dbName, tableName)
+	query := fmt.Sprintf("EXPLAIN SELECT `%s` FROM `%s`.`%s`", field, escapeString(dbName), escapeString(tableName))
 
 	if conf.Where != "" {
 		query += " WHERE "
@@ -517,3 +514,7 @@ func buildWhereCondition(conf *Config, where string) string {
 	}
 	return query.String()
 }
+
+func escapeString(s string) string {
+	return strings.ReplaceAll(s, "`", "``")
+}
diff --git a/v4/export/writer_util.go b/v4/export/writer_util.go
index 0f371cb..ce50310 100644
--- a/v4/export/writer_util.go
+++ b/v4/export/writer_util.go
@@ -132,10 +132,10 @@ func WriteInsert(tblIR TableDataIR, w io.Writer) error {
 	// if has generated column
 	if selectedField != "" {
 		insertStatementPrefix = fmt.Sprintf("INSERT INTO %s %s VALUES\n",
-			wrapBackTicks(tblIR.TableName()), selectedField)
+			wrapBackTicks(escapeString(tblIR.TableName())), selectedField)
 	} else {
 		insertStatementPrefix = fmt.Sprintf("INSERT INTO %s VALUES\n",
-			wrapBackTicks(tblIR.TableName()))
+			wrapBackTicks(escapeString(tblIR.TableName())))
 	}
 
 	for fileRowIter.HasNextSQLRowIter() {


Test patch:
diff --git a/tests/quote/data/quo`te-database-schema-create.sql b/tests/quote/data/quo`te-database-schema-create.sql
new file mode 100755
index 0000000..f432fbb
--- /dev/null
+++ b/tests/quote/data/quo`te-database-schema-create.sql
@@ -0,0 +1,1 @@
+CREATE DATABASE `quo``te-database` /*!40100 DEFAULT CHARACTER SET latin1 */;
diff --git a/tests/quote/data/quo`te-database.quo`te-table-schema.sql b/tests/quote/data/quo`te-database.quo`te-table-schema.sql
new file mode 100755
index 0000000..736ae73
--- /dev/null
+++ b/tests/quote/data/quo`te-database.quo`te-table-schema.sql
@@ -0,0 +1,6 @@
+CREATE TABLE `quo``te-table` (
+  `quo``te-col` int(11) NOT NULL,
+  `a` int(11) DEFAULT NULL,
+  `gen``id` int(11) GENERATED ALWAYS AS (`quo``te-col`) VIRTUAL,
+  PRIMARY KEY (`quo``te-col`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
diff --git a/tests/quote/data/quo`te-database.quo`te-table.0.sql b/tests/quote/data/quo`te-database.quo`te-table.0.sql
new file mode 100755
index 0000000..6e02b56
--- /dev/null
+++ b/tests/quote/data/quo`te-database.quo`te-table.0.sql
@@ -0,0 +1,13 @@
+/*!40101 SET NAMES binary*/;
+INSERT INTO `quo``te-table` (`quo``te-col`,`a`) VALUES
+(0,10),
+(1,9),
+(2,8),
+(3,7),
+(4,6),
+(5,5),
+(6,4),
+(7,3),
+(8,2),
+(9,1),
+(10,0);
diff --git a/tests/quote/run.sh b/tests/quote/run.sh
new file mode 100644
index 0000000..e9234fd
--- /dev/null
+++ b/tests/quote/run.sh
@@ -0,0 +1,20 @@
+#!/bin/sh
+
+set -eu
+
+db="quo\`te-database"
+run_sql "drop database if exists \`quo\`\`te-database\`"
+run_sql_file "$DUMPLING_BASE_NAME/data/quo\`te-database-schema-create.sql"
+export DUMPLING_TEST_DATABASE=$db
+
+run_sql_file "$DUMPLING_BASE_NAME/data/quo\`te-database.quo\`te-table-schema.sql"
+run_sql_file "$DUMPLING_BASE_NAME/data/quo\`te-database.quo\`te-table.0.sql"
+
+run_dumpling
+
+for file_path in "$DUMPLING_BASE_NAME"/data/*; do
+  base_name=$(basename "$file_path")
+  file_should_exist "$DUMPLING_BASE_NAME/data/$base_name"
+  file_should_exist "$DUMPLING_OUTPUT_DIR/$base_name"
+  diff "$DUMPLING_BASE_NAME/data/$base_name" "$DUMPLING_OUTPUT_DIR/$base_name"
+done
diff --git a/v4/export/dump_test.go b/v4/export/dump_test.go
index fc6a9c0..afa7163 100644
--- a/v4/export/dump_test.go
+++ b/v4/export/dump_test.go
@@ -52,16 +52,16 @@ func (s *testDumpSuite) TestDumpDatabase(c *C) {
 
 	showCreateDatabase := "CREATE DATABASE `test`"
 	rows := mock.NewRows([]string{"Database", "Create Database"}).AddRow("test", showCreateDatabase)
-	mock.ExpectQuery("SHOW CREATE DATABASE test").WillReturnRows(rows)
+	mock.ExpectQuery("SHOW CREATE DATABASE `test`").WillReturnRows(rows)
 	showCreateTableResult := "CREATE TABLE t (a INT)"
 	rows = mock.NewRows([]string{"Table", "Create Table"}).AddRow("t", showCreateTableResult)
-	mock.ExpectQuery("SHOW CREATE TABLE test.t").WillReturnRows(rows)
+	mock.ExpectQuery("SHOW CREATE TABLE `test`.`t`").WillReturnRows(rows)
 	rows = mock.NewRows([]string{"column_name", "extra"}).AddRow("id", "").AddRow("name", "")
 	mock.ExpectQuery("SELECT COLUMN_NAME").WithArgs(sqlmock.AnyArg(), sqlmock.AnyArg()).WillReturnRows(rows)
 	rows = mock.NewRows([]string{"a"}).AddRow(1)
-	mock.ExpectQuery("SELECT (.) FROM test.t LIMIT 1").WillReturnRows(rows)
+	mock.ExpectQuery("SELECT (.) FROM `test`.`t` LIMIT 1").WillReturnRows(rows)
 	rows = mock.NewRows([]string{"a"}).AddRow(1).AddRow(2)
-	mock.ExpectQuery("SELECT (.) FROM test.t").WillReturnRows(rows)
+	mock.ExpectQuery("SELECT (.) FROM `test`.`t`").WillReturnRows(rows)
 
 	mockWriter := newMockWriter()
 	err = dumpDatabases(context.Background(), mockConfig, db, mockWriter)
@@ -81,13 +81,13 @@ func (s *testDumpSuite) TestDumpTable(c *C) {
 
 	showCreateTableResult := "CREATE TABLE t (a INT)"
 	rows := mock.NewRows([]string{"Table", "Create Table"}).AddRow("t", showCreateTableResult)
-	mock.ExpectQuery("SHOW CREATE TABLE test.t").WillReturnRows(rows)
+	mock.ExpectQuery("SHOW CREATE TABLE `test`.`t`").WillReturnRows(rows)
 	rows = mock.NewRows([]string{"column_name", "extra"}).AddRow("id", "").AddRow("name", "")
 	mock.ExpectQuery("SELECT COLUMN_NAME").WithArgs(sqlmock.AnyArg(), sqlmock.AnyArg()).WillReturnRows(rows)
 	rows = mock.NewRows([]string{"a"}).AddRow(1)
-	mock.ExpectQuery("SELECT (.) FROM test.t LIMIT 1").WillReturnRows(rows)
+	mock.ExpectQuery("SELECT (.) FROM `test`.`t` LIMIT 1").WillReturnRows(rows)
 	rows = mock.NewRows([]string{"a"}).AddRow(1).AddRow(2)
-	mock.ExpectQuery("SELECT (.) FROM test.t").WillReturnRows(rows)
+	mock.ExpectQuery("SELECT (.) FROM `test`.`t`").WillReturnRows(rows)
 
 	mockWriter := newMockWriter()
 	err = dumpTable(context.Background(), mockConfig, db, "test", &TableInfo{Name: "t"}, mockWriter)
@@ -124,17 +124,17 @@ func (s *testDumpSuite) TestDumpTableWhereClause(c *C) {
 
 	showCreateTableResult := "CREATE TABLE t (a INT)"
 	rows := mock.NewRows([]string{"Table", "Create Table"}).AddRow("t", showCreateTableResult)
-	mock.ExpectQuery("SHOW CREATE TABLE test.t").WillReturnRows(rows)
+	mock.ExpectQuery("SHOW CREATE TABLE `test`.`t`").WillReturnRows(rows)
 
 	rows = mock.NewRows([]string{"column_name", "extra"}).AddRow("id", "").AddRow("name", "")
 	mock.ExpectQuery("SELECT COLUMN_NAME").WithArgs(sqlmock.AnyArg(), sqlmock.AnyArg()).WillReturnRows(rows)
 	rows = mock.NewRows([]string{"a"}).AddRow(1)
-	mock.ExpectQuery("SELECT (.) FROM test.t LIMIT 1").WillReturnRows(rows)
+	mock.ExpectQuery("SELECT (.) FROM `test`.`t` LIMIT 1").WillReturnRows(rows)
 	rows = mock.NewRows([]string{"a"})
 	for i := 4; i < 9; i++ {
 		rows.AddRow(i)
 	}
-	mock.ExpectQuery("SELECT (.) FROM test.t WHERE a > 3 and a < 9").WillReturnRows(rows)
+	mock.ExpectQuery("SELECT (.) FROM `test`.`t` WHERE a > 3 and a < 9").WillReturnRows(rows)
 
 	mockWriter := newMockWriter()
 	err = dumpTable(context.Background(), mockConfig, db, "test", &TableInfo{Name: "t"}, mockWriter)
diff --git a/v4/export/sql_test.go b/v4/export/sql_test.go
index 5658f91..01e6f11 100644
--- a/v4/export/sql_test.go
+++ b/v4/export/sql_test.go
@@ -62,7 +62,7 @@ func (s *testDumpSuite) TestBuildSelectAllQuery(c *C) {
 	mockConf.ServerInfo.ServerType = ServerTypeTiDB
 
 	// _tidb_rowid is available.
-	mock.ExpectExec("SELECT _tidb_rowid from test.t").
+	mock.ExpectExec("SELECT _tidb_rowid from `test`.`t`").
 		WillReturnResult(sqlmock.NewResult(0, 0))
 
 	orderByClause, err := buildOrderByClause(mockConf, db, "test", "t")
@@ -75,10 +75,10 @@ func (s *testDumpSuite) TestBuildSelectAllQuery(c *C) {
 	selectedField, err := buildSelectField(db, "test", "t")
 	c.Assert(err, IsNil)
 	q := buildSelectQuery("test", "t", selectedField, "", orderByClause)
-	c.Assert(q, Equals, "SELECT * FROM test.t ORDER BY _tidb_rowid")
+	c.Assert(q, Equals, "SELECT * FROM `test`.`t` ORDER BY _tidb_rowid")
 
 	// _tidb_rowid is unavailable, or PKIsHandle.
-	mock.ExpectExec("SELECT _tidb_rowid from test.t").
+	mock.ExpectExec("SELECT _tidb_rowid from `test`.`t`").
 		WillReturnError(errors.New(`1054, "Unknown column '_tidb_rowid' in 'field list'"`))
 
 	orderByClause, err = buildOrderByClause(mockConf, db, "test", "t")
@@ -91,7 +91,7 @@ func (s *testDumpSuite) TestBuildSelectAllQuery(c *C) {
 	selectedField, err = buildSelectField(db, "test", "t")
 	c.Assert(err, IsNil)
 	q = buildSelectQuery("test", "t", selectedField, "", orderByClause)
-	c.Assert(q, Equals, "SELECT * FROM test.t")
+	c.Assert(q, Equals, "SELECT * FROM `test`.`t`")
 	c.Assert(mock.ExpectationsWereMet(), IsNil)
 
 	// Test other servers.
@@ -101,8 +101,8 @@ func (s *testDumpSuite) TestBuildSelectAllQuery(c *C) {
 	for _, serverTp := range otherServers {
 		mockConf.ServerInfo.ServerType = serverTp
 		cmt := Commentf("server type: %s", serverTp)
-		mock.ExpectPrepare("SELECT column_name FROM information_schema.columns").
-			ExpectQuery().WithArgs("test", "t").
+		mock.ExpectQuery("SELECT column_name FROM information_schema.columns").
+			WithArgs("test", "t").
 			WillReturnRows(sqlmock.NewRows([]string{"column_name"}).AddRow("id"))
 		orderByClause, err := buildOrderByClause(mockConf, db, "test", "t")
 		c.Assert(err, IsNil, cmt)
@@ -114,7 +114,7 @@ func (s *testDumpSuite) TestBuildSelectAllQuery(c *C) {
 		selectedField, err = buildSelectField(db, "test", "t")
 		c.Assert(err, IsNil)
 		q = buildSelectQuery("test", "t", selectedField, "", orderByClause)
-		c.Assert(q, Equals, "SELECT * FROM test.t ORDER BY id", cmt)
+		c.Assert(q, Equals, "SELECT * FROM `test`.`t` ORDER BY `id`", cmt)
 		err = mock.ExpectationsWereMet()
 		c.Assert(err, IsNil, cmt)
 		c.Assert(mock.ExpectationsWereMet(), IsNil, cmt)
@@ -124,8 +124,8 @@ func (s *testDumpSuite) TestBuildSelectAllQuery(c *C) {
 	for _, serverTp := range otherServers {
 		mockConf.ServerInfo.ServerType = serverTp
 		cmt := Commentf("server type: %s", serverTp)
-		mock.ExpectPrepare("SELECT column_name FROM information_schema.columns").
-			ExpectQuery().WithArgs("test", "t").
+		mock.ExpectQuery("SELECT column_name FROM information_schema.columns").
+			WithArgs("test", "t").
 			WillReturnRows(sqlmock.NewRows([]string{"column_name"}))
 
 		orderByClause, err := buildOrderByClause(mockConf, db, "test", "t")
@@ -138,7 +138,7 @@ func (s *testDumpSuite) TestBuildSelectAllQuery(c *C) {
 		selectedField, err = buildSelectField(db, "test", "t")
 		c.Assert(err, IsNil)
 		q := buildSelectQuery("test", "t", selectedField, "", orderByClause)
-		c.Assert(q, Equals, "SELECT * FROM test.t", cmt)
+		c.Assert(q, Equals, "SELECT * FROM `test`.`t`", cmt)
 		err = mock.ExpectationsWereMet()
 		c.Assert(err, IsNil, cmt)
 		c.Assert(mock.ExpectationsWereMet(), IsNil)
@@ -157,7 +157,7 @@ func (s *testDumpSuite) TestBuildSelectAllQuery(c *C) {
 		selectedField, err := buildSelectField(db, "test", "t")
 		c.Assert(err, IsNil)
 		q := buildSelectQuery("test", "t", selectedField, "", "")
-		c.Assert(q, Equals, "SELECT * FROM test.t", cmt)
+		c.Assert(q, Equals, "SELECT * FROM `test`.`t`", cmt)
 		c.Assert(mock.ExpectationsWereMet(), IsNil, cmt)
 	}
 }
@@ -181,10 +181,10 @@ func (s *testDumpSuite) TestBuildSelectField(c *C) {
 	mock.ExpectQuery("SELECT COLUMN_NAME").
 		WithArgs(sqlmock.AnyArg(), sqlmock.AnyArg()).
 		WillReturnRows(sqlmock.NewRows([]string{"column_name", "extra"}).
-			AddRow("id", "").AddRow("name", "").AddRow("generated", "VIRTUAL GENERATED"))
+			AddRow("id", "").AddRow("name", "").AddRow("quo`te", "").AddRow("generated", "VIRTUAL GENERATED"))
 
 	selectedField, err = buildSelectField(db, "test", "t")
-	c.Assert(selectedField, Equals, "`id`,`name`")
+	c.Assert(selectedField, Equals, "`id`,`name`,`quo``te`")
 	c.Assert(err, IsNil)
 	c.Assert(mock.ExpectationsWereMet(), IsNil)