Commit cb7a5b53 authored by unknown's avatar unknown

A fix and a test case for Bug#11299 "prepared statement makes wrong SQL

 syntax in binlog which stops replication":
disallow the use of parameter markers which can lead to generation
of malformed binlog queries. 


mysql-test/r/ps.result:
  Test results fixed: a test case for Bug#11299
mysql-test/t/ps.test:
  A test case for Bug#11299
sql/sql_lex.cc:
  Introduce a new parser token for a parameter marker. Make sure
  that a parameter marker can not be used in a query which, when
  transformed to a binlog query, becomes grammatically incorrect.
sql/sql_yacc.yy:
  The check for COM_PREPARE has been moved into the lexer.
mysql-test/var:
  New BitKeeper file ``mysql-test/var''
parent bd44c99b
......@@ -660,3 +660,19 @@ lily
river
drop table t1;
deallocate prepare stmt;
create table t1 (a int);
prepare stmt from "select ??";
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '?' at line 1
prepare stmt from "select ?FROM t1";
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '?FROM t1' at line 1
prepare stmt from "select FROM t1 WHERE?=1";
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'FROM t1 WHERE?=1' at line 1
prepare stmt from "update t1 set a=a+?WHERE 1";
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '?WHERE 1' at line 1
select ?;
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '?' at line 1
select ??;
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '??' at line 1
select ? from t1;
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '? from t1' at line 1
drop table t1;
......@@ -679,3 +679,25 @@ execute stmt using @param1;
select utext from t1 where utext like '%%';
drop table t1;
deallocate prepare stmt;
#
# Bug#11299 "prepared statement makes wrong SQL syntax in binlog which stops
# replication": check that errouneous queries with placeholders are not
# allowed
#
create table t1 (a int);
--error 1064
prepare stmt from "select ??";
--error 1064
prepare stmt from "select ?FROM t1";
--error 1064
prepare stmt from "select FROM t1 WHERE?=1";
--error 1064
prepare stmt from "update t1 set a=a+?WHERE 1";
--error 1064
select ?;
--error 1064
select ??;
--error 1064
select ? from t1;
drop table t1;
#
......@@ -554,6 +554,15 @@ int yylex(void *arg, void *yythd)
lex->next_state= MY_LEX_START; // Allow signed numbers
if (c == ',')
lex->tok_start=lex->ptr; // Let tok_start point at next item
/*
Check for a placeholder: it should not precede a possible identifier
because of binlogging: when a placeholder is replaced with
its value in a query for the binlog, the query must stay
grammatically correct.
*/
else if (c == '?' && ((THD*) yythd)->command == COM_PREPARE &&
!ident_map[cs, yyPeek()])
return(PARAM_MARKER);
return((int) c);
case MY_LEX_IDENT_OR_NCHAR:
......
......@@ -528,6 +528,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%token NOW_SYM
%token OLD_PASSWORD
%token PASSWORD
%token PARAM_MARKER
%token POINTFROMTEXT
%token POINT_SYM
%token POLYFROMTEXT
......@@ -4857,23 +4858,15 @@ text_string:
;
param_marker:
'?'
PARAM_MARKER
{
THD *thd=YYTHD;
LEX *lex= thd->lex;
if (thd->command == COM_PREPARE)
{
Item_param *item= new Item_param((uint) (lex->tok_start -
(uchar *) thd->query));
if (!($$= item) || lex->param_list.push_back(item))
{
send_error(thd, ER_OUT_OF_RESOURCES);
YYABORT;
}
}
else
Item_param *item= new Item_param((uint) (lex->tok_start -
(uchar *) thd->query));
if (!($$= item) || lex->param_list.push_back(item))
{
yyerror(ER(ER_SYNTAX_ERROR));
send_error(thd, ER_OUT_OF_RESOURCES);
YYABORT;
}
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment