List:Commits« Previous MessageNext Message »
From:Mattias Jonsson Date:July 8 2008 1:05am
Subject:bzr commit into mysql-5.1 branch (mattiasj:2692)
View as plain text  
#At file:///Users/mattiasj/clones/bzrroot/topush2-51-bugteam/

 2692 Mattias Jonsson	2008-07-08 [merge]
      merge (update of 51-bugteam, during testing for pushing...)
modified:
  mysql-test/r/comments.result
  mysql-test/r/parser.result
  mysql-test/r/ps.result
  mysql-test/t/parser.test
  sql/sql_lex.cc
  sql/sql_parse.cc
  sql/sql_yacc.yy

=== modified file 'mysql-test/r/comments.result'
--- a/mysql-test/r/comments.result	2007-08-30 18:57:05 +0000
+++ b/mysql-test/r/comments.result	2008-07-07 21:53:20 +0000
@@ -45,7 +45,7 @@ ERROR 42000: You have an error in your S
 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';*";

=== modified file 'mysql-test/r/parser.result'
--- a/mysql-test/r/parser.result	2007-12-19 22:59:57 +0000
+++ b/mysql-test/r/parser.result	2008-07-07 21:53:20 +0000
@@ -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();

=== modified file 'mysql-test/r/ps.result'
--- a/mysql-test/r/ps.result	2008-05-20 18:43:26 +0000
+++ b/mysql-test/r/ps.result	2008-07-07 21:53:20 +0000
@@ -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

=== modified file 'mysql-test/t/parser.test'
--- a/mysql-test/t/parser.test	2007-12-19 22:59:57 +0000
+++ b/mysql-test/t/parser.test	2008-07-07 21:53:20 +0000
@@ -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)
 #=============================================================================

=== modified file 'sql/sql_lex.cc'
--- a/sql/sql_lex.cc	2008-03-28 15:09:14 +0000
+++ b/sql/sql_lex.cc	2008-07-07 21:53:20 +0000
@@ -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()))

=== modified file 'sql/sql_parse.cc'
--- a/sql/sql_parse.cc	2008-05-20 16:36:26 +0000
+++ b/sql/sql_parse.cc	2008-07-07 21:53:20 +0000
@@ -5641,6 +5641,11 @@ void mysql_parse(THD *thd, const char *i
               (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);
 	}

=== modified file 'sql/sql_yacc.yy'
--- a/sql/sql_yacc.yy	2008-05-20 07:38:17 +0000
+++ b/sql/sql_yacc.yy	2008-07-07 21:53:20 +0000
@@ -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 */
           }
@@ -1805,15 +1825,6 @@ event_tail:
           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);
           }
         ;

Thread
bzr commit into mysql-5.1 branch (mattiasj:2692) Mattias Jonsson8 Jul