Commit 8aaccbfc authored by Marc Alff's avatar Marc Alff

Manual merge of bug#26030 in mysql-5.1-bugteam

parents 50853ac3 c7724872
......@@ -45,7 +45,7 @@ ERROR 42000: You have an error in your SQL syntax; check the manual that corresp
prepare bar from "DELETE FROM table_28779 WHERE a = 7 OR 1=1/*! AND 2=2;";
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 bar from "DELETE FROM table_28779 WHERE a = 7 OR 1=1/*! AND 2=2;*";
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
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 bar from "DELETE FROM table_28779 WHERE a = 7 OR 1=1/*!98765' AND b = 'bar';";
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 '/*!98765' AND b = 'bar'' at line 1
prepare bar from "DELETE FROM table_28779 WHERE a = 7 OR 1=1/*!98765' AND b = 'bar';*";
......
......@@ -284,6 +284,74 @@ Field Type Null Key Default Extra
DROP TABLE table_25930_a;
DROP TABLE table_25930_b;
SET @@sql_mode=@save_sql_mode;
DROP PROCEDURE IF EXISTS p26030;
select "non terminated"$$
non terminated
non terminated
select "terminated";$$
terminated
terminated
select "non terminated, space" $$
non terminated, space
non terminated, space
select "terminated, space"; $$
terminated, space
terminated, space
select "non terminated, comment" /* comment */$$
non terminated, comment
non terminated, comment
select "terminated, comment"; /* comment */$$
terminated, comment
terminated, comment
select "stmt 1";select "stmt 2 non terminated"$$
stmt 1
stmt 1
stmt 2 non terminated
stmt 2 non terminated
select "stmt 1";select "stmt 2 terminated";$$
stmt 1
stmt 1
stmt 2 terminated
stmt 2 terminated
select "stmt 1";select "stmt 2 non terminated, space" $$
stmt 1
stmt 1
stmt 2 non terminated, space
stmt 2 non terminated, space
select "stmt 1";select "stmt 2 terminated, space"; $$
stmt 1
stmt 1
stmt 2 terminated, space
stmt 2 terminated, space
select "stmt 1";select "stmt 2 non terminated, comment" /* comment */$$
stmt 1
stmt 1
stmt 2 non terminated, comment
stmt 2 non terminated, comment
select "stmt 1";select "stmt 2 terminated, comment"; /* comment */$$
stmt 1
stmt 1
stmt 2 terminated, comment
stmt 2 terminated, comment
select "stmt 1"; select "space, stmt 2"$$
stmt 1
stmt 1
space, stmt 2
space, stmt 2
select "stmt 1";/* comment */select "comment, stmt 2"$$
stmt 1
stmt 1
comment, stmt 2
comment, stmt 2
DROP PROCEDURE IF EXISTS p26030; CREATE PROCEDURE p26030() BEGIN SELECT 1; END; CALL p26030()
$$
1
1
DROP PROCEDURE IF EXISTS p26030; CREATE PROCEDURE p26030() SELECT 1; CALL p26030()
$$
1
1
DROP PROCEDURE p26030;
select pi(3.14);
ERROR 42000: Incorrect parameter count in the call to native function 'pi'
select tan();
......
......@@ -85,9 +85,9 @@ NULL
NULL
NULL
prepare stmt6 from 'select 1; select2';
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 '; select2' at line 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 'select2' at line 1
prepare stmt6 from 'insert into t1 values (5,"five"); select2';
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 '; select2' at line 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 'select2' at line 1
explain prepare stmt6 from 'insert into t1 values (5,"five"); select2';
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 'insert into t1 values (5,"five"); select2'' at line 1
create table t2
......
......@@ -6,6 +6,11 @@
# LEXICAL PARSER (lex)
#=============================================================================
#
# Maintainer: these tests are for the lexical parser, so every character,
# even whitespace or comments, is significant here.
#
SET @save_sql_mode=@@sql_mode;
#
......@@ -387,6 +392,48 @@ DROP TABLE table_25930_b;
SET @@sql_mode=@save_sql_mode;
#
# Bug#26030 (Parsing fails for stored routine w/multi-statement execution
# enabled)
#
--disable_warnings
DROP PROCEDURE IF EXISTS p26030;
--enable_warnings
delimiter $$;
select "non terminated"$$
select "terminated";$$
select "non terminated, space" $$
select "terminated, space"; $$
select "non terminated, comment" /* comment */$$
select "terminated, comment"; /* comment */$$
# Multi queries can not be used in --ps-protocol test mode
--disable_ps_protocol
select "stmt 1";select "stmt 2 non terminated"$$
select "stmt 1";select "stmt 2 terminated";$$
select "stmt 1";select "stmt 2 non terminated, space" $$
select "stmt 1";select "stmt 2 terminated, space"; $$
select "stmt 1";select "stmt 2 non terminated, comment" /* comment */$$
select "stmt 1";select "stmt 2 terminated, comment"; /* comment */$$
select "stmt 1"; select "space, stmt 2"$$
select "stmt 1";/* comment */select "comment, stmt 2"$$
DROP PROCEDURE IF EXISTS p26030; CREATE PROCEDURE p26030() BEGIN SELECT 1; END; CALL p26030()
$$
DROP PROCEDURE IF EXISTS p26030; CREATE PROCEDURE p26030() SELECT 1; CALL p26030()
$$
--enable_ps_protocol
delimiter ;$$
DROP PROCEDURE p26030;
#=============================================================================
# SYNTACTIC PARSER (bison)
#=============================================================================
......
......@@ -1317,23 +1317,8 @@ int MYSQLlex(void *arg, void *yythd)
lip->yySkip();
return (SET_VAR);
case MY_LEX_SEMICOLON: // optional line terminator
if (lip->yyPeek())
{
if ((thd->client_capabilities & CLIENT_MULTI_STATEMENTS) &&
!lip->stmt_prepare_mode)
{
lex->safe_to_cache_query= 0;
lip->found_semicolon= lip->get_ptr();
thd->server_status|= SERVER_MORE_RESULTS_EXISTS;
lip->next_state= MY_LEX_END;
lip->set_echo(TRUE);
return (END_OF_INPUT);
}
state= MY_LEX_CHAR; // Return ';'
break;
}
lip->next_state=MY_LEX_END; // Mark for next loop
return(END_OF_INPUT);
state= MY_LEX_CHAR; // Return ';'
break;
case MY_LEX_EOL:
if (lip->eof())
{
......@@ -1352,7 +1337,7 @@ int MYSQLlex(void *arg, void *yythd)
case MY_LEX_END:
lip->next_state=MY_LEX_END;
return(0); // We found end of input last time
/* Actually real shouldn't start with . but allow them anyhow */
case MY_LEX_REAL_OR_POINT:
if (my_isdigit(cs,lip->yyPeek()))
......
......@@ -5641,6 +5641,11 @@ void mysql_parse(THD *thd, const char *inBuf, uint length,
(thd->query_length= (ulong)(*found_semicolon - thd->query)))
thd->query_length--;
/* Actually execute the query */
if (*found_semicolon)
{
lex->safe_to_cache_query= 0;
thd->server_status|= SERVER_MORE_RESULTS_EXISTS;
}
lex->set_trg_event_type_for_tables();
mysql_execute_command(thd);
}
......
......@@ -1355,12 +1355,44 @@ query:
my_message(ER_EMPTY_QUERY, ER(ER_EMPTY_QUERY), MYF(0));
MYSQL_YYABORT;
}
thd->lex->sql_command= SQLCOM_EMPTY_QUERY;
thd->m_lip->found_semicolon= NULL;
}
| verb_clause
{
Lex_input_stream *lip = YYTHD->m_lip;
if ((YYTHD->client_capabilities & CLIENT_MULTI_QUERIES) &&
! lip->stmt_prepare_mode &&
! lip->eof())
{
/*
We found a well formed query, and multi queries are allowed:
- force the parser to stop after the ';'
- mark the start of the next query for the next invocation
of the parser.
*/
lip->next_state= MY_LEX_END;
lip->found_semicolon= lip->get_ptr();
}
else
{
thd->lex->sql_command= SQLCOM_EMPTY_QUERY;
/* Single query, terminated. */
lip->found_semicolon= NULL;
}
}
| verb_clause END_OF_INPUT {}
';'
opt_end_of_input
| verb_clause END_OF_INPUT
{
/* Single query, not terminated. */
YYTHD->m_lip->found_semicolon= NULL;
}
;
opt_end_of_input:
/* empty */
| END_OF_INPUT
;
verb_clause:
......@@ -1774,10 +1806,6 @@ server_option:
event_tail:
EVENT_SYM opt_if_not_exists sp_name
/*
BE CAREFUL when you add a new rule to update the block where
YYTHD->client_capabilities is set back to original value
*/
{
THD *thd= YYTHD;
LEX *lex=Lex;
......@@ -1787,14 +1815,6 @@ event_tail:
MYSQL_YYABORT;
lex->event_parse_data->identifier= $3;
/*
We have to turn of CLIENT_MULTI_QUERIES while parsing a
stored procedure, otherwise yylex will chop it into pieces
at each ';'.
*/
$<ulong_num>$= thd->client_capabilities & CLIENT_MULTI_QUERIES;
thd->client_capabilities &= (~CLIENT_MULTI_QUERIES);
lex->sql_command= SQLCOM_CREATE_EVENT;
/* We need that for disallowing subqueries */
}
......@@ -1804,15 +1824,6 @@ event_tail:
opt_ev_comment
DO_SYM ev_sql_stmt
{
/*
Restore flag if it was cleared above
$1 - EVENT_SYM
$2 - opt_if_not_exists
$3 - sp_name
$4 - the block above
*/
YYTHD->client_capabilities |= $<ulong_num>4;
/*
sql_command is set here because some rules in ev_sql_stmt
can overwrite it
......@@ -5406,10 +5417,6 @@ alter:
view_tail
{}
| ALTER definer_opt EVENT_SYM sp_name
/*
BE CAREFUL when you add a new rule to update the block where
YYTHD->client_capabilities is set back to original value
*/
{
/*
It is safe to use Lex->spname because
......@@ -5423,14 +5430,6 @@ alter:
MYSQL_YYABORT;
Lex->event_parse_data->identifier= $4;
/*
We have to turn off CLIENT_MULTI_QUERIES while parsing a
stored procedure, otherwise yylex will chop it into pieces
at each ';'.
*/
$<ulong_num>$= YYTHD->client_capabilities & CLIENT_MULTI_QUERIES;
YYTHD->client_capabilities &= ~CLIENT_MULTI_QUERIES;
Lex->sql_command= SQLCOM_ALTER_EVENT;
}
ev_alter_on_schedule_completion
......@@ -5439,15 +5438,6 @@ alter:
opt_ev_comment
opt_ev_sql_stmt
{
/*
$1 - ALTER
$2 - definer_opt
$3 - EVENT_SYM
$4 - sp_name
$5 - the block above
*/
YYTHD->client_capabilities |= $<ulong_num>5;
if (!($6 || $7 || $8 || $9 || $10))
{
my_parse_error(ER(ER_SYNTAX_ERROR));
......@@ -12181,13 +12171,6 @@ trigger_tail:
lex->sphead= sp;
lex->spname= $3;
/*
We have to turn of CLIENT_MULTI_QUERIES while parsing a
stored procedure, otherwise yylex will chop it into pieces
at each ';'.
*/
$<ulong_num>$= thd->client_capabilities & CLIENT_MULTI_QUERIES;
thd->client_capabilities &= ~CLIENT_MULTI_QUERIES;
bzero((char *)&lex->sp_chistics, sizeof(st_sp_chistics));
lex->sphead->m_chistics= &lex->sp_chistics;
......@@ -12200,9 +12183,6 @@ trigger_tail:
lex->sql_command= SQLCOM_CREATE_TRIGGER;
sp->set_stmt_end(YYTHD);
/* Restore flag if it was cleared above */
YYTHD->client_capabilities |= $<ulong_num>15;
sp->restore_thd_mem_root(YYTHD);
if (sp->is_not_allowed_in_function("trigger"))
......@@ -12294,13 +12274,6 @@ sf_tail:
sp->m_type= TYPE_ENUM_FUNCTION;
lex->sphead= sp;
/*
We have to turn off CLIENT_MULTI_QUERIES while parsing a
stored procedure, otherwise yylex will chop it into pieces
at each ';'.
*/
$<ulong_num>$= thd->client_capabilities & CLIENT_MULTI_QUERIES;
thd->client_capabilities &= ~CLIENT_MULTI_QUERIES;
tmp_param_begin= lip->get_cpp_tok_start();
tmp_param_begin++;
......@@ -12406,8 +12379,6 @@ sf_tail:
ER(ER_NATIVE_FCT_NAME_COLLISION),
sp->m_name.str);
}
/* Restore flag if it was cleared above */
thd->client_capabilities |= $<ulong_num>5;
sp->restore_thd_mem_root(thd);
}
;
......@@ -12434,13 +12405,6 @@ sp_tail:
sp->init_sp_name(YYTHD, $3);
lex->sphead= sp;
/*
* We have to turn of CLIENT_MULTI_QUERIES while parsing a
* stored procedure, otherwise yylex will chop it into pieces
* at each ';'.
*/
$<ulong_num>$= YYTHD->client_capabilities & CLIENT_MULTI_QUERIES;
YYTHD->client_capabilities &= (~CLIENT_MULTI_QUERIES);
}
'('
{
......@@ -12479,12 +12443,6 @@ sp_tail:
sp->set_stmt_end(YYTHD);
lex->sql_command= SQLCOM_CREATE_PROCEDURE;
/*
Restore flag if it was cleared above
Be careful with counting. the block where we save the value
is $4.
*/
YYTHD->client_capabilities |= $<ulong_num>4;
sp->restore_thd_mem_root(YYTHD);
}
;
......
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