List:Commits« Previous MessageNext Message »
From:Praveenkumar Hulakund Date:February 29 2012 9:22am
Subject:bzr push into mysql-5.1 branch (praveenkumar.hulakund:3698 to 3699)
Bug#12601974
View as plain text  
 3699 Praveenkumar Hulakund	2012-02-29 [merge]
      Bug#12601974 - STORED PROCEDURE SQL_MODE=NO_BACKSLASH_ESCAPES IGNORED AND BREAKS REPLICATION
      
      Analysis:
      ========================
      sql_mode "NO_BACKSLASH_ESCAPES": When user want to use backslash as character input,
      instead of escape character in a string literal then sql_mode can be set to 
      "NO_BACKSLASH_ESCAPES". With this mode enabled, backslash becomes an ordinary 
      character like any other. 
      
      SQL_MODE set applies to the current client session. And while creating the stored 
      procedure, MySQL stores the current sql_mode and always executes the stored 
      procedure in sql_mode stored with the Procedure, regardless of the server SQL 
      mode in effect when the routine is invoked.  
      
      In the scenario (for which bug is reported), the routine is created with 
      sql_mode=NO_BACKSLASH_ESCAPES. And routine is executed with the invoker sql_mode
      is "" (NOT SET) by executing statement "call testp('Axel\'s')".
      Since invoker sql_mode is "" (NOT_SET), the '\' in 'Axel\'s'(argument to function)
      is considered as escape character and column "a" (of table "t1") values are 
      updated with "Axel's". The binary log generated for above update operation is as below,
      
        set sql_mode=XXXXXX (for no_backslash_escapes)
        update test.t1 set a= NAME_CONST('var',_latin1'Axel\'s' COLLATE 'latin1_swedish_ci');
      
      While logging stored procedure statements, the local variables (params) used in
      statements are replaced with the NAME_CONST(var_name, var_value) (Internal function) 
      (http://dev.mysql.com/doc/refman/5.6/en/miscellaneous-functions.html#function_name-const)
      
      On slave, these logs are applied. NAME_CONST is parsed to get the variable and its
      value. Since, stored procedure is created with sql_mode="NO_BACKSLASH_ESCAPES", the sql_mode
      is also logged in. So that at slave this sql_mode is set before executing the statements
      of routine.  So at slave, sql_mode is set to "NO_BACKSLASH_ESCAPES" and then while
      parsing NAME_CONST of string variable, '\' is considered as NON ESCAPE character
      and parsing reported error for "'" (as we have only one "'" no backslash). 
      
      At slave, parsing was proper with sql_mode "NO_BACKSLASH_ESCAPES".
      But above error reported while writing bin log, "'" (of Axel's) is escaped with
      "\" character. Actually, all special characters (n, r, ', ", \, 0...) are escaped
      while writing NAME_CONST for string variable(param, local variable) in bin log 
      irrespective of "NO_BACKSLASH_ESCAPES" sql_mode. So, basically, the problem is 
      that logging string parameter does not take into account sql_mode value.
      
      Fix:
      ========================
      So when sql_mode is set to "NO_BACKSLASH_ESCAPES", escaping  characters as 
      (n, r, ', ", \, 0...) should be avoided. To do so, added a check to not to
      escape such characters while writing NAME_CONST for string variables in bin 
      log. 
      And when sql_mode is set to NO_BACKSLASH_ESCAPES, quote character "'" is
      represented as ''.
      http://dev.mysql.com/doc/refman/5.6/en/string-literals.html (There are several 
      ways to include quote characters within a string: )

    modified:
      mysql-test/r/sql_mode.result
      mysql-test/suite/binlog/r/binlog_sql_mode.result
      mysql-test/suite/binlog/t/binlog_sql_mode.test
      mysql-test/t/sql_mode.test
      sql/item.cc
      sql/item.h
      sql/log_event.cc
      sql/mysql_priv.h
      sql/sp_head.cc
      sql/sql_prepare.cc
 3698 Marko Mäkelä	2012-02-28
      Fix a mistake in the Bug#12861864 fix.
      
      row_drop_table_for_mysql(): Really flag the indexes unavailable before
      starting to drop the table.

    modified:
      storage/innodb_plugin/row/row0mysql.c
=== modified file 'mysql-test/r/sql_mode.result'
--- a/mysql-test/r/sql_mode.result	2009-06-12 21:11:19 +0000
+++ b/mysql-test/r/sql_mode.result	2012-02-29 06:53:15 +0000
@@ -527,3 +527,207 @@ SELECT * FROM mysql.columns_priv WHERE H
 Host	Db	User	Table_name	Column_name	Timestamp	Column_priv
 DROP TABLE t1;
 DROP TABLE t2;
+
+#
+# Test for Bug#12601974 - STORED PROCEDURE SQL_MODE=NO_BACKSLASH_ESCAPES
+# IGNORED AND BREAKS REPLICATION
+#
+DROP TABLE IF EXISTS test_table;
+DROP FUNCTION IF EXISTS test_function;
+CREATE TABLE test_table (c1 CHAR(50));
+SET @org_mode=@@sql_mode;
+SET @@sql_mode='';
+PREPARE insert_stmt FROM 'INSERT INTO test_table VALUES (?)';
+PREPARE update_stmt FROM 'UPDATE test_table SET c1= ? WHERE c1= ?';
+CREATE FUNCTION test_function(var CHAR(50)) RETURNS CHAR(50)
+BEGIN
+DECLARE char_val CHAR(50);
+SELECT c1 INTO char_val FROM test_table WHERE c1=var;
+RETURN char_val;
+END
+$
+SET @var1='abcd\'ef';
+SET @var2='abcd\"ef';
+SET @var3='abcd\bef';
+SET @var4='abcd\nef';
+SET @var5='abcd\ref';
+SET @var6='abcd\tef';
+SET @var7='abcd\\ef';
+SET @var8='abcd\%ef';
+SET @var9='abcd\_ef';
+SET @to_var1='wxyz\'ef';
+SET @to_var2='wxyz\"ef';
+SET @to_var3='wxyz\bef';
+SET @to_var4='wxyz\nef';
+SET @to_var5='wxyz\ref';
+SET @to_var6='wxyz\tef';
+SET @to_var7='wxyz\\ef';
+SET @to_var8='wxyz\%ef';
+SET @to_var9='wxyz\_ef';
+# STRING LILTERAL WITH BACKSLASH IN PREPARE STATEMENT
+EXECUTE insert_stmt USING @var1;
+EXECUTE insert_stmt USING @var2;
+EXECUTE insert_stmt USING @var3;
+EXECUTE insert_stmt USING @var4;
+EXECUTE insert_stmt USING @var5;
+EXECUTE insert_stmt USING @var6;
+EXECUTE insert_stmt USING @var7;
+EXECUTE insert_stmt USING @var8;
+EXECUTE insert_stmt USING @var9;
+SELECT * FROM test_table;
+c1
+abcd'ef
+abcd"ef
+abcdef
+abcd
+ef
+abcd
ef
+abcd	ef
+abcd\ef
+abcd\%ef
+abcd\_ef
+EXECUTE update_stmt USING @to_var1, @var1;
+EXECUTE update_stmt USING @to_var2, @var2;
+EXECUTE update_stmt USING @to_var3, @var3;
+EXECUTE update_stmt USING @to_var4, @var4;
+EXECUTE update_stmt USING @to_var5, @var5;
+EXECUTE update_stmt USING @to_var6, @var6;
+EXECUTE update_stmt USING @to_var7, @var7;
+EXECUTE update_stmt USING @to_var8, @var8;
+EXECUTE update_stmt USING @to_var9, @var9;
+SELECT * FROM test_table;
+c1
+wxyz'ef
+wxyz"ef
+wxyzef
+wxyz
+ef
+wxyz
ef
+wxyz	ef
+wxyz\ef
+wxyz\%ef
+wxyz\_ef
+
+# END OF CASE - STRING LILTERAL WITH BACKSLASH IN PREPARE STATEMENT
+# STRING LILTERAL WITH BACKSLASH IN FUNCTION RETURNING STRING
+select test_function(@to_var1);
+test_function(@to_var1)
+wxyz'ef
+SELECT test_function(@to_var2);
+test_function(@to_var2)
+wxyz"ef
+SELECT test_function(@to_var3);
+test_function(@to_var3)
+wxyzef
+SELECT test_function(@to_var4);
+test_function(@to_var4)
+wxyz
+ef
+SELECT test_function(@to_var5);
+test_function(@to_var5)
+wxyz
ef
+SELECT test_function(@to_var6);
+test_function(@to_var6)
+wxyz	ef
+SELECT test_function(@to_var7);
+test_function(@to_var7)
+wxyz\ef
+SELECT test_function(@to_var8);
+test_function(@to_var8)
+wxyz\%ef
+SELECT test_function(@to_var9);
+test_function(@to_var9)
+wxyz\_ef
+
+# END OF CASE - STRING LILTERAL WITH BACKSLASH IN FUNCTION RETURNING STRING
+DELETE FROM test_table;
+DROP FUNCTION test_function;
+SET @@sql_mode='NO_BACKSLASH_ESCAPES';
+CREATE FUNCTION test_function(var CHAR(50)) RETURNS CHAR(50)
+BEGIN
+DECLARE char_val CHAR(50);
+SELECT c1 INTO char_val FROM test_table WHERE c1=var;
+RETURN char_val;
+END
+$
+# STRING LILTERAL WITH BACKSLASH IN PREPARE STATEMENT
+EXECUTE insert_stmt USING @var1;
+EXECUTE insert_stmt USING @var2;
+EXECUTE insert_stmt USING @var3;
+EXECUTE insert_stmt USING @var4;
+EXECUTE insert_stmt USING @var5;
+EXECUTE insert_stmt USING @var6;
+EXECUTE insert_stmt USING @var7;
+EXECUTE insert_stmt USING @var8;
+EXECUTE insert_stmt USING @var9;
+SELECT * FROM test_table;
+c1
+abcd'ef
+abcd"ef
+abcdef
+abcd
+ef
+abcd
ef
+abcd	ef
+abcd\ef
+abcd\%ef
+abcd\_ef
+EXECUTE update_stmt USING @to_var1, @var1;
+EXECUTE update_stmt USING @to_var2, @var2;
+EXECUTE update_stmt USING @to_var3, @var3;
+EXECUTE update_stmt USING @to_var4, @var4;
+EXECUTE update_stmt USING @to_var5, @var5;
+EXECUTE update_stmt USING @to_var6, @var6;
+EXECUTE update_stmt USING @to_var7, @var7;
+EXECUTE update_stmt USING @to_var8, @var8;
+EXECUTE update_stmt USING @to_var9, @var9;
+SELECT * FROM test_table;
+c1
+wxyz'ef
+wxyz"ef
+wxyzef
+wxyz
+ef
+wxyz
ef
+wxyz	ef
+wxyz\ef
+wxyz\%ef
+wxyz\_ef
+
+# END OF CASE - STRING LILTERAL WITH BACKSLASH IN PREPARE STATEMENT
+# STRING LILTERAL WITH BACKSLASH IN FUNCTION RETURNING STRING
+select test_function(@to_var1);
+test_function(@to_var1)
+wxyz'ef
+SELECT test_function(@to_var2);
+test_function(@to_var2)
+wxyz"ef
+SELECT test_function(@to_var3);
+test_function(@to_var3)
+wxyzef
+SELECT test_function(@to_var4);
+test_function(@to_var4)
+wxyz
+ef
+SELECT test_function(@to_var5);
+test_function(@to_var5)
+wxyz
ef
+SELECT test_function(@to_var6);
+test_function(@to_var6)
+wxyz	ef
+SELECT test_function(@to_var7);
+test_function(@to_var7)
+wxyz\ef
+SELECT test_function(@to_var8);
+test_function(@to_var8)
+wxyz\%ef
+SELECT test_function(@to_var9);
+test_function(@to_var9)
+wxyz\_ef
+
+# END OF CASE - STRING LILTERAL WITH BACKSLASH IN FUNCTION RETURNING STRING
+DROP TABLE test_table;
+DROP FUNCTION test_function;
+SET @@sql_mode= @org_mode;
+
+#End of Test for Bug#12601974 

=== modified file 'mysql-test/suite/binlog/r/binlog_sql_mode.result'
--- a/mysql-test/suite/binlog/r/binlog_sql_mode.result	2010-12-19 17:07:28 +0000
+++ b/mysql-test/suite/binlog/r/binlog_sql_mode.result	2012-02-29 06:53:15 +0000
@@ -38,3 +38,114 @@ DROP VIEW testView;
 DROP TABLE t1;
 SET @@global.sql_mode= @old_sql_mode;
 SET @@session.binlog_format=@old_binlog_format;
+
+#
+# Test for Bug#12601974 - STORED PROCEDURE SQL_MODE=NO_BACKSLASH_ESCAPES
+# IGNORED AND BREAKS REPLICATION
+#
+DROP DATABASE IF EXISTS mysqltest_db;
+DROP TABLE IF EXISTS test_table;
+CREATE DATABASE mysqltest_db;
+USE mysqltest_db;
+CREATE TABLE test_table (c1 CHAR(50));
+SET @org_mode=@@sql_mode;
+SET @@sql_mode='';
+CREATE PROCEDURE proc_without_sql_mode (IN param1 CHAR(50), IN param2 CHAR(50))
+BEGIN
+DECLARE var1 CHAR(50) DEFAULT param1;
+DECLARE var2 CHAR(50) DEFAULT param2;
+DECLARE var3 CHAR(50) DEFAULT 'abcd\bef';
+DECLARE var4 CHAR(50) DEFAULT 'abcd\nef';
+DECLARE var5 CHAR(50) DEFAULT 'abcd\ref';
+DECLARE var6 CHAR(50) DEFAULT 'abcd\tef';
+DECLARE var7 CHAR(50) DEFAULT 'abcd\\ef';
+DECLARE var8 CHAR(50) DEFAULT 'abcd\%ef';
+DECLARE var9 CHAR(50) DEFAULT 'abcd\_ef';
+INSERT INTO test_table VALUES (var1);
+INSERT INTO test_table VALUES (var2);
+INSERT INTO test_table VALUES (var3);
+INSERT INTO test_table VALUES (var4);
+INSERT INTO test_table VALUES (var5);
+INSERT INTO test_table VALUES (var6);
+INSERT INTO test_table VALUES (var7);
+INSERT INTO test_table VALUES (var8);
+INSERT INTO test_table VALUES (var9);
+END
+$
+SET @@sql_mode='NO_BACKSLASH_ESCAPES'$
+CREATE PROCEDURE proc_with_sql_mode (IN param1 CHAR(50), IN param2 CHAR(50))
+BEGIN
+DECLARE var1 CHAR(50) DEFAULT param1;
+DECLARE var2 CHAR(50) DEFAULT param2;
+DECLARE var3 CHAR(50) DEFAULT 'wxyz\bef';
+DECLARE var4 CHAR(50) DEFAULT 'wxyz\nef';
+DECLARE var5 CHAR(50) DEFAULT 'wxyz\ref';
+DECLARE var6 CHAR(50) DEFAULT 'wxyz\tef';
+DECLARE var7 CHAR(50) DEFAULT 'wxyz\\ef';
+DECLARE var8 CHAR(50) DEFAULT 'wxyz\%ef';
+DECLARE var9 CHAR(50) DEFAULT 'wxyz\_ef';
+INSERT INTO test_table VALUES (var1);
+INSERT INTO test_table VALUES (var2);
+INSERT INTO test_table VALUES (var3);
+INSERT INTO test_table VALUES (var4);
+INSERT INTO test_table VALUES (var5);
+INSERT INTO test_table VALUES (var6);
+INSERT INTO test_table VALUES (var7);
+INSERT INTO test_table VALUES (var8);
+INSERT INTO test_table VALUES (var9);
+END
+$
+SET @@sql_mode='';
+CALL proc_without_sql_mode('abcd\'ef', 'abcd\"ef');
+CALL proc_with_sql_mode('wxyz\'ef', 'wxyz\"ef');
+SELECT * FROM test_table;
+c1
+abcd'ef
+abcd"ef
+abcdef
+abcd
+ef
+abcd
ef
+abcd	ef
+abcd\ef
+abcd\%ef
+abcd\_ef
+wxyz'ef
+wxyz"ef
+wxyz\bef
+wxyz\nef
+wxyz\ref
+wxyz\tef
+wxyz\\ef
+wxyz\%ef
+wxyz\_ef
+"Dropping table test_table"
+DROP TABLE test_table;
+#"test_table" content after replaying the binlog
+SELECT * FROM test_table;
+c1
+abcd'ef
+abcd"ef
+abcdef
+abcd
+ef
+abcd
ef
+abcd	ef
+abcd\ef
+abcd\%ef
+abcd\_ef
+wxyz'ef
+wxyz"ef
+wxyz\bef
+wxyz\nef
+wxyz\ref
+wxyz\tef
+wxyz\\ef
+wxyz\%ef
+wxyz\_ef
+#Clean up
+DROP DATABASE mysqltest_db;
+SET @@sql_mode= @org_mode;
+use test;
+
+#End of Test for Bug#12601974 

=== modified file 'mysql-test/suite/binlog/t/binlog_sql_mode.test'
--- a/mysql-test/suite/binlog/t/binlog_sql_mode.test	2010-12-19 17:07:28 +0000
+++ b/mysql-test/suite/binlog/t/binlog_sql_mode.test	2012-02-29 06:53:15 +0000
@@ -73,3 +73,99 @@ DROP TABLE t1;
 
 SET @@global.sql_mode= @old_sql_mode;
 SET @@session.binlog_format=@old_binlog_format;
+
+--echo 
+--echo #
+--echo # Test for Bug#12601974 - STORED PROCEDURE SQL_MODE=NO_BACKSLASH_ESCAPES
+--echo # IGNORED AND BREAKS REPLICATION
+--echo #
+
+--disable_warnings
+DROP DATABASE IF EXISTS mysqltest_db;
+DROP TABLE IF EXISTS test_table;
+--enable_warnings
+
+CREATE DATABASE mysqltest_db;
+USE mysqltest_db;
+CREATE TABLE test_table (c1 CHAR(50));
+
+SET @org_mode=@@sql_mode;
+
+SET @@sql_mode='';
+DELIMITER $;
+CREATE PROCEDURE proc_without_sql_mode (IN param1 CHAR(50), IN param2 CHAR(50))
+BEGIN
+  DECLARE var1 CHAR(50) DEFAULT param1;
+  DECLARE var2 CHAR(50) DEFAULT param2;
+  DECLARE var3 CHAR(50) DEFAULT 'abcd\bef';
+  DECLARE var4 CHAR(50) DEFAULT 'abcd\nef';
+  DECLARE var5 CHAR(50) DEFAULT 'abcd\ref';
+  DECLARE var6 CHAR(50) DEFAULT 'abcd\tef';
+  DECLARE var7 CHAR(50) DEFAULT 'abcd\\ef';
+  DECLARE var8 CHAR(50) DEFAULT 'abcd\%ef';
+  DECLARE var9 CHAR(50) DEFAULT 'abcd\_ef';
+
+  INSERT INTO test_table VALUES (var1);
+  INSERT INTO test_table VALUES (var2);
+  INSERT INTO test_table VALUES (var3);
+  INSERT INTO test_table VALUES (var4);
+  INSERT INTO test_table VALUES (var5);
+  INSERT INTO test_table VALUES (var6);
+  INSERT INTO test_table VALUES (var7);
+  INSERT INTO test_table VALUES (var8);
+  INSERT INTO test_table VALUES (var9);
+END
+$
+
+SET @@sql_mode='NO_BACKSLASH_ESCAPES'$
+CREATE PROCEDURE proc_with_sql_mode (IN param1 CHAR(50), IN param2 CHAR(50))
+BEGIN
+  DECLARE var1 CHAR(50) DEFAULT param1;
+  DECLARE var2 CHAR(50) DEFAULT param2;
+  DECLARE var3 CHAR(50) DEFAULT 'wxyz\bef';
+  DECLARE var4 CHAR(50) DEFAULT 'wxyz\nef';
+  DECLARE var5 CHAR(50) DEFAULT 'wxyz\ref';
+  DECLARE var6 CHAR(50) DEFAULT 'wxyz\tef';
+  DECLARE var7 CHAR(50) DEFAULT 'wxyz\\ef';
+  DECLARE var8 CHAR(50) DEFAULT 'wxyz\%ef';
+  DECLARE var9 CHAR(50) DEFAULT 'wxyz\_ef';
+
+  INSERT INTO test_table VALUES (var1);
+  INSERT INTO test_table VALUES (var2);
+  INSERT INTO test_table VALUES (var3);
+  INSERT INTO test_table VALUES (var4);
+  INSERT INTO test_table VALUES (var5);
+  INSERT INTO test_table VALUES (var6);
+  INSERT INTO test_table VALUES (var7);
+  INSERT INTO test_table VALUES (var8);
+  INSERT INTO test_table VALUES (var9);
+END
+$
+
+DELIMITER ;$
+SET @@sql_mode='';
+CALL proc_without_sql_mode('abcd\'ef', 'abcd\"ef');
+CALL proc_with_sql_mode('wxyz\'ef', 'wxyz\"ef');
+SELECT * FROM test_table;
+
+let $MYSQLD_DATADIR= `select @@datadir`;
+--exec $MYSQL_BINLOG --force-if-open -d mysqltest_db $MYSQLD_DATADIR/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/mysqlbinlog_bug12601974.binlog
+
+--echo "Dropping table test_table"
+DROP TABLE test_table;
+
+--exec $MYSQL -e "source $MYSQLTEST_VARDIR/tmp/mysqlbinlog_bug12601974.binlog"
+
+--echo #"test_table" content after replaying the binlog
+SELECT * FROM test_table;
+
+--echo #Clean up
+--remove_file $MYSQLTEST_VARDIR/tmp/mysqlbinlog_bug12601974.binlog
+DROP DATABASE mysqltest_db;
+SET @@sql_mode= @org_mode;
+use test;
+
+--echo 
+--echo #End of Test for Bug#12601974 
+
+

=== modified file 'mysql-test/t/sql_mode.test'
--- a/mysql-test/t/sql_mode.test	2009-06-12 21:11:19 +0000
+++ b/mysql-test/t/sql_mode.test	2012-02-29 06:53:15 +0000
@@ -344,3 +344,157 @@ SELECT * FROM mysql.columns_priv WHERE H
 # Cleanup
 DROP TABLE t1;
 DROP TABLE t2;
+
+
+--echo 
+--echo #
+--echo # Test for Bug#12601974 - STORED PROCEDURE SQL_MODE=NO_BACKSLASH_ESCAPES
+--echo # IGNORED AND BREAKS REPLICATION
+--echo #
+
+--disable_warnings
+DROP TABLE IF EXISTS test_table;
+DROP FUNCTION IF EXISTS test_function;
+--enable_warnings
+
+CREATE TABLE test_table (c1 CHAR(50));
+
+SET @org_mode=@@sql_mode;
+
+SET @@sql_mode='';
+
+PREPARE insert_stmt FROM 'INSERT INTO test_table VALUES (?)';
+PREPARE update_stmt FROM 'UPDATE test_table SET c1= ? WHERE c1= ?';
+DELIMITER $;
+CREATE FUNCTION test_function(var CHAR(50)) RETURNS CHAR(50)
+BEGIN
+  DECLARE char_val CHAR(50);
+  SELECT c1 INTO char_val FROM test_table WHERE c1=var;
+  RETURN char_val;
+END
+$
+DELIMITER ;$
+
+SET @var1='abcd\'ef';
+SET @var2='abcd\"ef';
+SET @var3='abcd\bef';
+SET @var4='abcd\nef';
+SET @var5='abcd\ref';
+SET @var6='abcd\tef';
+SET @var7='abcd\\ef';
+SET @var8='abcd\%ef';
+SET @var9='abcd\_ef';
+
+SET @to_var1='wxyz\'ef';
+SET @to_var2='wxyz\"ef';
+SET @to_var3='wxyz\bef';
+SET @to_var4='wxyz\nef';
+SET @to_var5='wxyz\ref';
+SET @to_var6='wxyz\tef';
+SET @to_var7='wxyz\\ef';
+SET @to_var8='wxyz\%ef';
+SET @to_var9='wxyz\_ef';
+
+--echo # STRING LILTERAL WITH BACKSLASH IN PREPARE STATEMENT
+EXECUTE insert_stmt USING @var1;
+EXECUTE insert_stmt USING @var2;
+EXECUTE insert_stmt USING @var3;
+EXECUTE insert_stmt USING @var4;
+EXECUTE insert_stmt USING @var5;
+EXECUTE insert_stmt USING @var6;
+EXECUTE insert_stmt USING @var7;
+EXECUTE insert_stmt USING @var8;
+EXECUTE insert_stmt USING @var9;
+
+SELECT * FROM test_table;
+
+EXECUTE update_stmt USING @to_var1, @var1;
+EXECUTE update_stmt USING @to_var2, @var2;
+EXECUTE update_stmt USING @to_var3, @var3;
+EXECUTE update_stmt USING @to_var4, @var4;
+EXECUTE update_stmt USING @to_var5, @var5;
+EXECUTE update_stmt USING @to_var6, @var6;
+EXECUTE update_stmt USING @to_var7, @var7;
+EXECUTE update_stmt USING @to_var8, @var8;
+EXECUTE update_stmt USING @to_var9, @var9;
+
+SELECT * FROM test_table;
+
+--echo 
+--echo # END OF CASE - STRING LILTERAL WITH BACKSLASH IN PREPARE STATEMENT
+
+--echo # STRING LILTERAL WITH BACKSLASH IN FUNCTION RETURNING STRING
+select test_function(@to_var1);
+SELECT test_function(@to_var2);
+SELECT test_function(@to_var3);
+SELECT test_function(@to_var4);
+SELECT test_function(@to_var5);
+SELECT test_function(@to_var6);
+SELECT test_function(@to_var7);
+SELECT test_function(@to_var8);
+SELECT test_function(@to_var9);
+
+--echo 
+--echo # END OF CASE - STRING LILTERAL WITH BACKSLASH IN FUNCTION RETURNING STRING
+DELETE FROM test_table;
+DROP FUNCTION test_function;
+
+SET @@sql_mode='NO_BACKSLASH_ESCAPES';
+DELIMITER $;
+CREATE FUNCTION test_function(var CHAR(50)) RETURNS CHAR(50)
+BEGIN
+  DECLARE char_val CHAR(50);
+  SELECT c1 INTO char_val FROM test_table WHERE c1=var;
+  RETURN char_val;
+END
+$
+DELIMITER ;$
+
+--echo # STRING LILTERAL WITH BACKSLASH IN PREPARE STATEMENT
+EXECUTE insert_stmt USING @var1;
+EXECUTE insert_stmt USING @var2;
+EXECUTE insert_stmt USING @var3;
+EXECUTE insert_stmt USING @var4;
+EXECUTE insert_stmt USING @var5;
+EXECUTE insert_stmt USING @var6;
+EXECUTE insert_stmt USING @var7;
+EXECUTE insert_stmt USING @var8;
+EXECUTE insert_stmt USING @var9;
+
+SELECT * FROM test_table;
+
+EXECUTE update_stmt USING @to_var1, @var1;
+EXECUTE update_stmt USING @to_var2, @var2;
+EXECUTE update_stmt USING @to_var3, @var3;
+EXECUTE update_stmt USING @to_var4, @var4;
+EXECUTE update_stmt USING @to_var5, @var5;
+EXECUTE update_stmt USING @to_var6, @var6;
+EXECUTE update_stmt USING @to_var7, @var7;
+EXECUTE update_stmt USING @to_var8, @var8;
+EXECUTE update_stmt USING @to_var9, @var9;
+
+SELECT * FROM test_table;
+
+--echo 
+--echo # END OF CASE - STRING LILTERAL WITH BACKSLASH IN PREPARE STATEMENT
+
+--echo # STRING LILTERAL WITH BACKSLASH IN FUNCTION RETURNING STRING
+select test_function(@to_var1);
+SELECT test_function(@to_var2);
+SELECT test_function(@to_var3);
+SELECT test_function(@to_var4);
+SELECT test_function(@to_var5);
+SELECT test_function(@to_var6);
+SELECT test_function(@to_var7);
+SELECT test_function(@to_var8);
+SELECT test_function(@to_var9);
+
+--echo 
+--echo # END OF CASE - STRING LILTERAL WITH BACKSLASH IN FUNCTION RETURNING STRING
+
+DROP TABLE test_table;
+DROP FUNCTION test_function;
+SET @@sql_mode= @org_mode;
+
+--echo 
+--echo #End of Test for Bug#12601974 

=== modified file 'sql/item.cc'
--- a/sql/item.cc	2012-02-15 16:21:38 +0000
+++ b/sql/item.cc	2012-02-29 06:53:15 +0000
@@ -3085,7 +3085,7 @@ String *Item_param::val_str(String* str)
     that binary log contains wrong statement 
 */
 
-const String *Item_param::query_val_str(String* str) const
+const String *Item_param::query_val_str(THD *thd, String* str) const
 {
   switch (state) {
   case INT_VALUE:
@@ -3123,7 +3123,8 @@ const String *Item_param::query_val_str(
   case LONG_DATA_VALUE:
     {
       str->length(0);
-      append_query_string(value.cs_info.character_set_client, &str_value, str);
+      append_query_string(thd, value.cs_info.character_set_client, &str_value,
+                          str);
       break;
     }
   case NULL_VALUE:
@@ -3256,7 +3257,7 @@ void Item_param::print(String *str, enum
     char buffer[STRING_BUFFER_USUAL_SIZE];
     String tmp(buffer, sizeof(buffer), &my_charset_bin);
     const String *res;
-    res= query_val_str(&tmp);
+    res= query_val_str(current_thd, &tmp);
     str->append(*res);
   }
 }

=== modified file 'sql/item.h'
--- a/sql/item.h	2011-07-03 15:47:37 +0000
+++ b/sql/item.h	2012-02-29 06:53:15 +0000
@@ -1703,7 +1703,7 @@ public:
   */
   void (*set_param_func)(Item_param *param, uchar **pos, ulong len);
 
-  const String *query_val_str(String *str) const;
+  const String *query_val_str(THD *thd, String *str) const;
 
   bool convert_str_value(THD *thd);
 

=== modified file 'sql/log_event.cc'
--- a/sql/log_event.cc	2011-07-15 11:42:06 +0000
+++ b/sql/log_event.cc	2012-02-29 06:53:15 +0000
@@ -572,7 +572,7 @@ char *str_to_hex(char *to, const char *f
 */
 
 int
-append_query_string(CHARSET_INFO *csinfo,
+append_query_string(THD *thd, CHARSET_INFO *csinfo,
                     String const *from, String *to)
 {
   char *beg, *ptr;
@@ -587,9 +587,26 @@ append_query_string(CHARSET_INFO *csinfo
   else
   {
     *ptr++= '\'';
-    ptr+= escape_string_for_mysql(csinfo, ptr, 0,
-                                  from->ptr(), from->length());
-    *ptr++='\'';
+    if (!(thd->variables.sql_mode & MODE_NO_BACKSLASH_ESCAPES))
+    {
+      ptr+= escape_string_for_mysql(csinfo, ptr, 0,
+                                    from->ptr(), from->length());
+    }
+    else
+    {
+      const char *frm_str= from->ptr();
+
+      for (; frm_str < (from->ptr() + from->length()); frm_str++)
+      {
+        /* Using '' way to represent "'" */
+        if (*frm_str == '\'')
+          *ptr++= *frm_str;
+
+        *ptr++= *frm_str;
+      }
+    }
+
+    *ptr++= '\'';
   }
   to->length(orig_len + ptr - beg);
   return 0;

=== modified file 'sql/mysql_priv.h'
--- a/sql/mysql_priv.h	2011-07-07 08:06:59 +0000
+++ b/sql/mysql_priv.h	2012-02-29 06:53:15 +0000
@@ -799,7 +799,7 @@ bool delete_precheck(THD *thd, TABLE_LIS
 bool insert_precheck(THD *thd, TABLE_LIST *tables);
 bool create_table_precheck(THD *thd, TABLE_LIST *tables,
                            TABLE_LIST *create_table);
-int append_query_string(CHARSET_INFO *csinfo,
+int append_query_string(THD *thd, CHARSET_INFO *csinfo,
                         String const *from, String *to);
 
 void get_default_definer(THD *thd, LEX_USER *definer);

=== modified file 'sql/sp_head.cc'
--- a/sql/sp_head.cc	2012-02-15 16:21:38 +0000
+++ b/sql/sp_head.cc	2012-02-29 06:53:15 +0000
@@ -157,7 +157,7 @@ sp_get_item_value(THD *thd, Item *item,
         buf.append(result->charset()->csname);
         if (cs->escape_with_backslash_is_dangerous)
           buf.append(' ');
-        append_query_string(cs, result, &buf);
+        append_query_string(thd, cs, result, &buf);
         buf.append(" COLLATE '");
         buf.append(item->collation.collation->name);
         buf.append('\'');

=== modified file 'sql/sql_prepare.cc'
--- a/sql/sql_prepare.cc	2011-08-02 07:33:45 +0000
+++ b/sql/sql_prepare.cc	2012-02-29 06:53:15 +0000
@@ -795,7 +795,7 @@ static bool insert_params_with_log(Prepa
     */
     else if (! is_param_long_data_type(param))
       DBUG_RETURN(1);
-    res= param->query_val_str(&str);
+    res= param->query_val_str(thd, &str);
     if (param->convert_str_value(thd))
       DBUG_RETURN(1);                           /* out of memory */
 
@@ -969,7 +969,7 @@ static bool emb_insert_params_with_log(P
           DBUG_RETURN(1);
       }
     }
-    res= param->query_val_str(&str);
+    res= param->query_val_str(thd, &str);
     if (param->convert_str_value(thd))
       DBUG_RETURN(1);                           /* out of memory */
 
@@ -1115,7 +1115,7 @@ static bool insert_params_from_vars_with
     setup_one_conversion_function(thd, param, param->param_type);
     if (param->set_from_user_var(thd, entry))
       DBUG_RETURN(1);
-    val= param->query_val_str(&buf);
+    val= param->query_val_str(thd, &buf);
 
     if (param->convert_str_value(thd))
       DBUG_RETURN(1);                           /* out of memory */

No bundle (reason: useless for push emails).
Thread
bzr push into mysql-5.1 branch (praveenkumar.hulakund:3698 to 3699)Bug#12601974Praveenkumar Hulakund5 Mar