diff options
author | unknown <konstantin@mysql.com> | 2005-07-15 00:01:49 +0400 |
---|---|---|
committer | unknown <konstantin@mysql.com> | 2005-07-15 00:01:49 +0400 |
commit | cb7a5b53cc98cdd95273017a445ced3acae83365 (patch) | |
tree | f58984f3d67be4ee2ca5f3bc83e521b155dca05a | |
parent | bd44c99b853c07761554214f57c2a0700804ffc3 (diff) | |
download | mariadb-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.result | 16 | ||||
-rw-r--r-- | mysql-test/t/ps.test | 22 | ||||
-rw-r--r-- | sql/sql_lex.cc | 9 | ||||
-rw-r--r-- | sql/sql_yacc.yy | 19 |
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; } } |