summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRamil Kalimullin <ramil@mysql.com>2009-03-25 23:41:16 +0400
committerRamil Kalimullin <ramil@mysql.com>2009-03-25 23:41:16 +0400
commitaca1a83fedd916492c97f77557d27c79ae54da43 (patch)
tree7aa34f58ecccff62834f2f5bd96104233a64261f
parent4f5f7f353ac4783fae7aa0bff891d1325177cc82 (diff)
parenteccad3f252e0263249eee45d3d76987d4fc0d4e2 (diff)
downloadmariadb-git-aca1a83fedd916492c97f77557d27c79ae54da43.tar.gz
Manual merge.
-rw-r--r--mysql-test/extra/binlog_tests/binlog.test40
-rw-r--r--mysql-test/suite/binlog/r/binlog_row_binlog.result32
-rw-r--r--mysql-test/suite/binlog/r/binlog_stm_binlog.result32
-rw-r--r--sql/sp_head.cc5
-rw-r--r--sql/sql_class.cc1
-rw-r--r--sql/sql_class.h3
-rw-r--r--sql/sql_parse.cc37
7 files changed, 150 insertions, 0 deletions
diff --git a/mysql-test/extra/binlog_tests/binlog.test b/mysql-test/extra/binlog_tests/binlog.test
index 98bd116ba29..d72dc693cee 100644
--- a/mysql-test/extra/binlog_tests/binlog.test
+++ b/mysql-test/extra/binlog_tests/binlog.test
@@ -164,6 +164,46 @@ DROP TABLE t1;
DROP DATABASE bug39182;
USE test;
+#
+# Bug#35383: binlog playback and replication breaks due to
+# name_const substitution
+#
+DELIMITER //;
+CREATE PROCEDURE p1(IN v1 INT)
+BEGIN
+ CREATE TABLE t1 SELECT v1;
+ DROP TABLE t1;
+END//
+CREATE PROCEDURE p2()
+BEGIN
+ DECLARE v1 INT;
+ CREATE TABLE t1 SELECT v1+1;
+ DROP TABLE t1;
+END//
+CREATE PROCEDURE p3(IN v1 INT)
+BEGIN
+ CREATE TABLE t1 SELECT 1 FROM DUAL WHERE v1!=0;
+ DROP TABLE t1;
+END//
+CREATE PROCEDURE p4(IN v1 INT)
+BEGIN
+ DECLARE v2 INT;
+ CREATE TABLE t1 SELECT 1, v1, v2;
+ DROP TABLE t1;
+ CREATE TABLE t1 SELECT 1, v1+1, v2;
+ DROP TABLE t1;
+END//
+DELIMITER ;//
+
+CALL p1(1);
+CALL p2();
+CALL p3(0);
+CALL p4(0);
+DROP PROCEDURE p1;
+DROP PROCEDURE p2;
+DROP PROCEDURE p3;
+DROP PROCEDURE p4;
+
--echo End of 5.0 tests
# Test of a too big SET INSERT_ID: see if the truncated value goes
diff --git a/mysql-test/suite/binlog/r/binlog_row_binlog.result b/mysql-test/suite/binlog/r/binlog_row_binlog.result
index 1a56e048b27..25cb7a4726f 100644
--- a/mysql-test/suite/binlog/r/binlog_row_binlog.result
+++ b/mysql-test/suite/binlog/r/binlog_row_binlog.result
@@ -1137,6 +1137,38 @@ DROP PROCEDURE p1;
DROP TABLE t1;
DROP DATABASE bug39182;
USE test;
+CREATE PROCEDURE p1(IN v1 INT)
+BEGIN
+CREATE TABLE t1 SELECT v1;
+DROP TABLE t1;
+END//
+CREATE PROCEDURE p2()
+BEGIN
+DECLARE v1 INT;
+CREATE TABLE t1 SELECT v1+1;
+DROP TABLE t1;
+END//
+CREATE PROCEDURE p3(IN v1 INT)
+BEGIN
+CREATE TABLE t1 SELECT 1 FROM DUAL WHERE v1!=0;
+DROP TABLE t1;
+END//
+CREATE PROCEDURE p4(IN v1 INT)
+BEGIN
+DECLARE v2 INT;
+CREATE TABLE t1 SELECT 1, v1, v2;
+DROP TABLE t1;
+CREATE TABLE t1 SELECT 1, v1+1, v2;
+DROP TABLE t1;
+END//
+CALL p1(1);
+CALL p2();
+CALL p3(0);
+CALL p4(0);
+DROP PROCEDURE p1;
+DROP PROCEDURE p2;
+DROP PROCEDURE p3;
+DROP PROCEDURE p4;
End of 5.0 tests
reset master;
create table t1 (id tinyint auto_increment primary key);
diff --git a/mysql-test/suite/binlog/r/binlog_stm_binlog.result b/mysql-test/suite/binlog/r/binlog_stm_binlog.result
index aadbf950b21..efdeb30a2af 100644
--- a/mysql-test/suite/binlog/r/binlog_stm_binlog.result
+++ b/mysql-test/suite/binlog/r/binlog_stm_binlog.result
@@ -644,6 +644,38 @@ DROP PROCEDURE p1;
DROP TABLE t1;
DROP DATABASE bug39182;
USE test;
+CREATE PROCEDURE p1(IN v1 INT)
+BEGIN
+CREATE TABLE t1 SELECT v1;
+DROP TABLE t1;
+END//
+CREATE PROCEDURE p2()
+BEGIN
+DECLARE v1 INT;
+CREATE TABLE t1 SELECT v1+1;
+DROP TABLE t1;
+END//
+CREATE PROCEDURE p3(IN v1 INT)
+BEGIN
+CREATE TABLE t1 SELECT 1 FROM DUAL WHERE v1!=0;
+DROP TABLE t1;
+END//
+CREATE PROCEDURE p4(IN v1 INT)
+BEGIN
+DECLARE v2 INT;
+CREATE TABLE t1 SELECT 1, v1, v2;
+DROP TABLE t1;
+CREATE TABLE t1 SELECT 1, v1+1, v2;
+DROP TABLE t1;
+END//
+CALL p1(1);
+CALL p2();
+CALL p3(0);
+CALL p4(0);
+DROP PROCEDURE p1;
+DROP PROCEDURE p2;
+DROP PROCEDURE p3;
+DROP PROCEDURE p4;
End of 5.0 tests
reset master;
create table t1 (id tinyint auto_increment primary key);
diff --git a/sql/sp_head.cc b/sql/sp_head.cc
index ef6cb556f4c..fcf51aac1b5 100644
--- a/sql/sp_head.cc
+++ b/sql/sp_head.cc
@@ -956,6 +956,8 @@ subst_spvars(THD *thd, sp_instr *instr, LEX_STRING *query_str)
qbuf.length(0);
cur= query_str->str;
prev_pos= res= 0;
+ thd->query_name_consts= 0;
+
for (Item_splocal **splocal= sp_vars_uses.front();
splocal < sp_vars_uses.back(); splocal++)
{
@@ -989,6 +991,8 @@ subst_spvars(THD *thd, sp_instr *instr, LEX_STRING *query_str)
res|= qbuf.append(')');
if (res)
break;
+
+ thd->query_name_consts++;
}
res|= qbuf.append(cur + prev_pos, query_str->length - prev_pos);
if (res)
@@ -2853,6 +2857,7 @@ sp_instr_stmt::execute(THD *thd, uint *nextp)
*nextp= m_ip+1;
thd->query= query;
thd->query_length= query_length;
+ thd->query_name_consts= 0;
if (!thd->is_error())
thd->main_da.reset_diagnostics_area();
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index 4f92d3aea10..7f15508caa1 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -599,6 +599,7 @@ THD::THD()
one_shot_set= 0;
file_id = 0;
query_id= 0;
+ query_name_consts= 0;
warn_id= 0;
db_charset= global_system_variables.collation_database;
bzero(ha_data, sizeof(ha_data));
diff --git a/sql/sql_class.h b/sql/sql_class.h
index 148e4b86e9e..ce4524fb982 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -1775,6 +1775,9 @@ public:
sp_cache *sp_proc_cache;
sp_cache *sp_func_cache;
+ /** number of name_const() substitutions, see sp_head.cc:subst_spvars() */
+ uint query_name_consts;
+
/*
If we do a purge of binary logs, log index info of the threads
that are currently reading it needs to be adjusted. To do that
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index d1296c4127d..2974dff9ea9 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -2558,6 +2558,43 @@ mysql_execute_command(THD *thd)
{
select_result *result;
+ /*
+ If:
+ a) we inside an SP and there was NAME_CONST substitution,
+ b) binlogging is on (STMT mode),
+ c) we log the SP as separate statements
+ raise a warning, as it may cause problems
+ (see 'NAME_CONST issues' in 'Binary Logging of Stored Programs')
+ */
+ if (thd->query_name_consts &&
+ mysql_bin_log.is_open() &&
+ thd->variables.binlog_format == BINLOG_FORMAT_STMT &&
+ !mysql_bin_log.is_query_in_union(thd, thd->query_id))
+ {
+ List_iterator_fast<Item> it(select_lex->item_list);
+ Item *item;
+ uint splocal_refs= 0;
+ /* Count SP local vars in the top-level SELECT list */
+ while ((item= it++))
+ {
+ if (item->is_splocal())
+ splocal_refs++;
+ }
+ /*
+ If it differs from number of NAME_CONST substitution applied,
+ we may have a SOME_FUNC(NAME_CONST()) in the SELECT list,
+ that may cause a problem with binary log (see BUG#35383),
+ raise a warning.
+ */
+ if (splocal_refs != thd->query_name_consts)
+ push_warning(thd,
+ MYSQL_ERROR::WARN_LEVEL_WARN,
+ ER_UNKNOWN_ERROR,
+"Invoked routine ran a statement that may cause problems with "
+"binary log, see 'NAME_CONST issues' in 'Binary Logging of Stored Programs' "
+"section of the manual.");
+ }
+
select_lex->options|= SELECT_NO_UNLOCK;
unit->set_limit(select_lex);