summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergei Golubchik <serg@mariadb.org>2017-06-28 10:10:31 +0200
committerSergei Golubchik <serg@mariadb.org>2017-06-28 10:10:31 +0200
commita02ba9c1c96f8245b2fd5c8b555c74204af421e3 (patch)
tree8d84e04d7ee6ec5713a120f2fb1ac436d0348508
parent8baf9b0c469e2845d15cc1181bc6b101cdfba087 (diff)
parentd5cd33450413816f8696125cd66c8393921e6267 (diff)
downloadmariadb-git-a02ba9c1c96f8245b2fd5c8b555c74204af421e3.tar.gz
Merge branch '5.5' into 10.0
-rw-r--r--client/mysql.cc6
-rw-r--r--client/mysqltest.cc14
-rw-r--r--include/mysql_com.h2
-rw-r--r--mysql-test/r/mysql.result58
-rw-r--r--mysql-test/r/mysqltest.result5
-rw-r--r--mysql-test/t/mysql.test30
-rw-r--r--mysql-test/t/mysqltest.test8
-rw-r--r--sql/sql_class.cc2
-rw-r--r--sql/sys_vars.cc4
9 files changed, 124 insertions, 5 deletions
diff --git a/client/mysql.cc b/client/mysql.cc
index 3461f8bbc75..faef4670b31 100644
--- a/client/mysql.cc
+++ b/client/mysql.cc
@@ -2321,8 +2321,10 @@ static bool add_line(String &buffer, char *line, ulong line_length,
continue;
}
#endif
- if (!*ml_comment && inchar == '\\' &&
- !(*in_string &&
+ if (!*ml_comment && inchar == '\\' && *in_string != '`' &&
+ !(*in_string == '"' &&
+ (mysql.server_status & SERVER_STATUS_ANSI_QUOTES)) &&
+ !(*in_string &&
(mysql.server_status & SERVER_STATUS_NO_BACKSLASH_ESCAPES)))
{
// Found possbile one character command like \c
diff --git a/client/mysqltest.cc b/client/mysqltest.cc
index 2ed2a10e975..5c17f22acce 100644
--- a/client/mysqltest.cc
+++ b/client/mysqltest.cc
@@ -6562,6 +6562,16 @@ my_bool end_of_query(int c)
}
+static inline bool is_escape_char(char c, char in_string)
+{
+ if (c != '\\' || in_string == '`') return false;
+ if (!cur_con) return true;
+ uint server_status= cur_con->mysql->server_status;
+ if (server_status & SERVER_STATUS_NO_BACKSLASH_ESCAPES) return false;
+ return !(server_status & SERVER_STATUS_ANSI_QUOTES && in_string == '"');
+}
+
+
/*
Read one "line" from the file
@@ -6670,7 +6680,7 @@ int read_line(char *buf, int size)
state= R_Q;
}
}
- have_slash= (c == '\\');
+ have_slash= is_escape_char(c, last_quote);
break;
case R_COMMENT:
@@ -6740,7 +6750,7 @@ int read_line(char *buf, int size)
case R_Q:
if (c == last_quote)
state= R_NORMAL;
- else if (c == '\\')
+ else if (is_escape_char(c, last_quote))
state= R_SLASH_IN_Q;
break;
diff --git a/include/mysql_com.h b/include/mysql_com.h
index 96514a28310..7853aa0195a 100644
--- a/include/mysql_com.h
+++ b/include/mysql_com.h
@@ -329,6 +329,8 @@ enum enum_server_command
*/
#define SERVER_STATUS_IN_TRANS_READONLY 8192
+#define SERVER_STATUS_ANSI_QUOTES 32768
+
/**
Server status flags that must be cleared when starting
diff --git a/mysql-test/r/mysql.result b/mysql-test/r/mysql.result
index dd0129df0d9..8a24128daa2 100644
--- a/mysql-test/r/mysql.result
+++ b/mysql-test/r/mysql.result
@@ -529,3 +529,61 @@ a
+-------------------+
End of tests
+create table `a1\``b1` (a int);
+show tables;
+Tables_in_test
+a1\`b1
+insert `a1\``b1` values (1),(2);
+show create table `a1\``b1`;
+Table Create Table
+a1\`b1 CREATE TABLE `a1\``b1` (
+ `a` int(11) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `a1\``b1` (
+ `a` int(11) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+/*!40101 SET character_set_client = @saved_cs_client */;
+INSERT INTO `a1\``b1` VALUES (1),(2);
+insert `a1\``b1` values (4),(5);
+show create table `a1\``b1`;
+Table Create Table
+a1\`b1 CREATE TABLE `a1\``b1` (
+ `a` int(11) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+select * from `a1\``b1`;
+a
+1
+2
+drop table `a1\``b1`;
+set sql_mode=ansi_quotes;
+create table "a1\""b1" (a int);
+show tables;
+Tables_in_test
+a1\"b1
+insert "a1\""b1" values (1),(2);
+show create table "a1\""b1";
+Table Create Table
+a1\"b1 CREATE TABLE "a1\""b1" (
+ "a" int(11) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE "a1\""b1" (
+ "a" int(11) DEFAULT NULL
+);
+/*!40101 SET character_set_client = @saved_cs_client */;
+INSERT INTO "a1\""b1" VALUES (1),(2);
+insert "a1\""b1" values (4),(5);
+show create table "a1\""b1";
+Table Create Table
+a1\"b1 CREATE TABLE "a1\""b1" (
+ "a" int(11) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+select * from "a1\""b1";
+a
+1
+2
+drop table "a1\""b1";
+set sql_mode=default;
diff --git a/mysql-test/r/mysqltest.result b/mysql-test/r/mysqltest.result
index fa054d457f9..b3d8fb93e1f 100644
--- a/mysql-test/r/mysqltest.result
+++ b/mysql-test/r/mysqltest.result
@@ -960,4 +960,9 @@ con1
con2
con2
-closed_connection-
+set sql_mode=no_backslash_escapes;
+select "foo\""bar";
+foo\"bar
+foo\"bar
+set sql_mode=default;
End of tests
diff --git a/mysql-test/t/mysql.test b/mysql-test/t/mysql.test
index 263e1103e8b..4403a9d668f 100644
--- a/mysql-test/t/mysql.test
+++ b/mysql-test/t/mysql.test
@@ -618,3 +618,33 @@ EOF
--echo
--echo End of tests
+
+#
+# MDEV-13187 incorrect backslash parsing in clients
+#
+create table `a1\``b1` (a int);
+show tables;
+insert `a1\``b1` values (1),(2);
+show create table `a1\``b1`;
+--exec $MYSQL_DUMP --compact test
+--exec $MYSQL_DUMP test > $MYSQLTEST_VARDIR/tmp/bug.sql
+insert `a1\``b1` values (4),(5);
+--exec $MYSQL test < $MYSQLTEST_VARDIR/tmp/bug.sql
+show create table `a1\``b1`;
+select * from `a1\``b1`;
+drop table `a1\``b1`;
+
+# same with ansi_quotes
+set sql_mode=ansi_quotes;
+create table "a1\""b1" (a int);
+show tables;
+insert "a1\""b1" values (1),(2);
+show create table "a1\""b1";
+--exec $MYSQL_DUMP --compact --compatible=postgres test
+--exec $MYSQL_DUMP --compatible=postgres test > $MYSQLTEST_VARDIR/tmp/bug.sql
+insert "a1\""b1" values (4),(5);
+--exec $MYSQL test < $MYSQLTEST_VARDIR/tmp/bug.sql
+show create table "a1\""b1";
+select * from "a1\""b1";
+drop table "a1\""b1";
+set sql_mode=default;
diff --git a/mysql-test/t/mysqltest.test b/mysql-test/t/mysqltest.test
index e85d793b628..aea4ba6432d 100644
--- a/mysql-test/t/mysqltest.test
+++ b/mysql-test/t/mysqltest.test
@@ -2948,11 +2948,17 @@ disconnect $x;
# Disconnect the selected connection
disconnect $y;
--echo $CURRENT_CONNECTION
+connection default;
+#
+# MDEV-13187 incorrect backslash parsing in clients
+#
+set sql_mode=no_backslash_escapes;
+select "foo\""bar";
+set sql_mode=default;
--echo End of tests
-connection default;
# Wait till we reached the initial number of concurrent sessions
--source include/wait_until_count_sessions.inc
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index 666cdb3afc3..e397dd88a88 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -1378,6 +1378,8 @@ void THD::init(void)
server_status= SERVER_STATUS_AUTOCOMMIT;
if (variables.sql_mode & MODE_NO_BACKSLASH_ESCAPES)
server_status|= SERVER_STATUS_NO_BACKSLASH_ESCAPES;
+ if (variables.sql_mode & MODE_ANSI_QUOTES)
+ server_status|= SERVER_STATUS_ANSI_QUOTES;
transaction.all.modified_non_trans_table=
transaction.stmt.modified_non_trans_table= FALSE;
diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc
index 99248457bb8..8d164ea86f5 100644
--- a/sql/sys_vars.cc
+++ b/sql/sys_vars.cc
@@ -2899,6 +2899,10 @@ static bool fix_sql_mode(sys_var *self, THD *thd, enum_var_type type)
thd->server_status|= SERVER_STATUS_NO_BACKSLASH_ESCAPES;
else
thd->server_status&= ~SERVER_STATUS_NO_BACKSLASH_ESCAPES;
+ if (thd->variables.sql_mode & MODE_ANSI_QUOTES)
+ thd->server_status|= SERVER_STATUS_ANSI_QUOTES;
+ else
+ thd->server_status&= ~SERVER_STATUS_ANSI_QUOTES;
}
return false;
}