summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <konstantin@mysql.com>2005-07-15 00:01:49 +0400
committerunknown <konstantin@mysql.com>2005-07-15 00:01:49 +0400
commitcb7a5b53cc98cdd95273017a445ced3acae83365 (patch)
treef58984f3d67be4ee2ca5f3bc83e521b155dca05a
parentbd44c99b853c07761554214f57c2a0700804ffc3 (diff)
downloadmariadb-git-cb7a5b53cc98cdd95273017a445ced3acae83365.tar.gz
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''
-rw-r--r--mysql-test/r/ps.result16
-rw-r--r--mysql-test/t/ps.test22
-rw-r--r--sql/sql_lex.cc9
-rw-r--r--sql/sql_yacc.yy19
4 files changed, 53 insertions, 13 deletions
diff --git a/mysql-test/r/ps.result b/mysql-test/r/ps.result
index ee558e0ea89..6cd32cbe8d0 100644
--- a/mysql-test/r/ps.result
+++ b/mysql-test/r/ps.result
@@ -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;
diff --git a/mysql-test/t/ps.test b/mysql-test/t/ps.test
index 01d62a2e198..d08098606a1 100644
--- a/mysql-test/t/ps.test
+++ b/mysql-test/t/ps.test
@@ -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;
+#
diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc
index 904b4675c74..42e3b678c09 100644
--- a/sql/sql_lex.cc
+++ b/sql/sql_lex.cc
@@ -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:
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index bc21649fe54..2587ce7e1a5 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -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;
}
}