summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarc Alff <marc.alff@sun.com>2008-07-14 19:43:12 -0600
committerMarc Alff <marc.alff@sun.com>2008-07-14 19:43:12 -0600
commitf34c99b4d8b60e6ae5cddde206ef4da30811e5fe (patch)
tree302ecb26a02762cc90a264a5d6a12c76a15939fd
parenta3619d2e865eb5705a8acfc10db91ae700bb7043 (diff)
parent5f9f35e291eba2e6b8fbdc7e763c14c370c676ec (diff)
downloadmariadb-git-f34c99b4d8b60e6ae5cddde206ef4da30811e5fe.tar.gz
Bug#35577, manual merge mysql-5.0-bugteam -> mysql-5.1-bugteam
-rw-r--r--mysql-test/r/parser_stack.result306
-rw-r--r--mysql-test/t/parser_stack.test402
-rw-r--r--sql/event_data_objects.cc4
-rw-r--r--sql/mysql_priv.h6
-rw-r--r--sql/sp.cc4
-rw-r--r--sql/sp_head.cc4
-rw-r--r--sql/sql_class.cc2
-rw-r--r--sql/sql_class.h12
-rw-r--r--sql/sql_lex.cc19
-rw-r--r--sql/sql_lex.h54
-rw-r--r--sql/sql_parse.cc62
-rw-r--r--sql/sql_partition.cc4
-rw-r--r--sql/sql_prepare.cc6
-rw-r--r--sql/sql_trigger.cc6
-rw-r--r--sql/sql_view.cc8
-rw-r--r--sql/sql_yacc.yy81
16 files changed, 863 insertions, 117 deletions
diff --git a/mysql-test/r/parser_stack.result b/mysql-test/r/parser_stack.result
new file mode 100644
index 00000000000..a0040fc6ae6
--- /dev/null
+++ b/mysql-test/r/parser_stack.result
@@ -0,0 +1,306 @@
+use test;
+SELECT
+((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((
+((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((
+((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((
+1
+))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
+))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
+))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
+;
+1
+1
+prepare stmt from
+"
+SELECT
+((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((
+((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((
+((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((
+1
+))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
+))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
+))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
+"
+;
+execute stmt;
+1
+1
+drop view if exists view_overflow;
+CREATE VIEW view_overflow AS
+SELECT
+((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((
+((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((
+((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((
+1
+))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
+))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
+))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
+;
+SELECT * from view_overflow;
+1
+1
+drop view view_overflow;
+drop procedure if exists proc_overflow;
+CREATE PROCEDURE proc_overflow()
+BEGIN
+BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
+BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
+BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
+BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
+BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
+BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
+BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
+BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
+BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
+BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
+select 1;
+select 2;
+select 3;
+END; END; END; END; END; END; END; END; END; END; END; END;
+END; END; END; END; END; END; END; END; END; END; END; END;
+END; END; END; END; END; END; END; END; END; END; END; END;
+END; END; END; END; END; END; END; END; END; END; END; END;
+END; END; END; END; END; END; END; END; END; END; END; END;
+END; END; END; END; END; END; END; END; END; END; END; END;
+END; END; END; END; END; END; END; END; END; END; END; END;
+END; END; END; END; END; END; END; END; END; END; END; END;
+END; END; END; END; END; END; END; END; END; END; END; END;
+END; END; END; END; END; END; END; END; END; END; END; END;
+END $$
+call proc_overflow();
+1
+1
+2
+2
+3
+3
+drop procedure proc_overflow;
+drop function if exists func_overflow;
+create function func_overflow() returns int
+BEGIN
+DECLARE x int default 0;
+BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
+BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
+BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
+BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
+BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
+BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
+BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
+BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
+BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
+BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
+SET x=x+1;
+SET x=x+2;
+SET x=x+3;
+END; END; END; END; END; END; END; END; END; END; END; END;
+END; END; END; END; END; END; END; END; END; END; END; END;
+END; END; END; END; END; END; END; END; END; END; END; END;
+END; END; END; END; END; END; END; END; END; END; END; END;
+END; END; END; END; END; END; END; END; END; END; END; END;
+END; END; END; END; END; END; END; END; END; END; END; END;
+END; END; END; END; END; END; END; END; END; END; END; END;
+END; END; END; END; END; END; END; END; END; END; END; END;
+END; END; END; END; END; END; END; END; END; END; END; END;
+END; END; END; END; END; END; END; END; END; END; END; END;
+return x;
+END $$
+select func_overflow();
+func_overflow()
+6
+drop function func_overflow;
+drop table if exists table_overflow;
+create table table_overflow(a int, b int);
+create trigger trigger_overflow before insert on table_overflow
+for each row
+BEGIN
+BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
+BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
+BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
+BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
+BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
+BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
+BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
+BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
+BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
+BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
+SET NEW.b := NEW.a;
+SET NEW.b := NEW.b + 1;
+SET NEW.b := NEW.b + 2;
+SET NEW.b := NEW.b + 3;
+END; END; END; END; END; END; END; END; END; END; END; END;
+END; END; END; END; END; END; END; END; END; END; END; END;
+END; END; END; END; END; END; END; END; END; END; END; END;
+END; END; END; END; END; END; END; END; END; END; END; END;
+END; END; END; END; END; END; END; END; END; END; END; END;
+END; END; END; END; END; END; END; END; END; END; END; END;
+END; END; END; END; END; END; END; END; END; END; END; END;
+END; END; END; END; END; END; END; END; END; END; END; END;
+END; END; END; END; END; END; END; END; END; END; END; END;
+END; END; END; END; END; END; END; END; END; END; END; END;
+END $$
+insert into table_overflow set a=10;
+insert into table_overflow set a=20;
+select * from table_overflow;
+a b
+10 16
+20 26
+drop table table_overflow;
+drop procedure if exists proc_35577;
+CREATE PROCEDURE proc_35577()
+BEGIN
+DECLARE z_done INT DEFAULT 0;
+DECLARE t_done VARCHAR(5000);
+outer_loop: LOOP
+IF t_done=1 THEN
+LEAVE outer_loop;
+END IF;
+inner_block:BEGIN
+DECLARE z_done INT DEFAULT 0;
+SET z_done = 0;
+inner_loop: LOOP
+IF z_done=1 THEN
+LEAVE inner_loop;
+END IF;
+IF (t_done = 'a') THEN
+IF (t_done <> 0) THEN
+IF ( t_done > 0) THEN
+IF (t_done = 'a') THEN
+SET t_done = 'a';
+ELSEIF (t_done = 'a') THEN
+SET t_done = 'a';
+ELSEIF(t_done = 'a') THEN
+SET t_done = 'a';
+ELSEIF(t_done = 'a') THEN
+SET t_done = 'a';
+ELSEIF(t_done = 'a') THEN
+SET t_done = 'a';
+ELSEIF(t_done = 'a') THEN
+SET t_done = 'a';
+ELSEIF(t_done = 'a') THEN
+SET t_done = 'a';
+ELSEIF(t_done = 'a') THEN
+SET t_done = 'a';
+END IF;
+END IF;
+END IF;
+END IF;
+END LOOP inner_loop;
+END inner_block;
+END LOOP outer_loop;
+END $$
+drop procedure proc_35577;
+drop procedure if exists p_37269;
+create procedure p_37269()
+begin
+declare done int default 0;
+declare varb int default 0;
+declare vara int default 0;
+repeat
+select now();
+until done end repeat;
+while varb do
+select now();
+begin
+select now();
+repeat
+select now();
+until done end repeat;
+if vara then
+select now();
+repeat
+select now();
+loop
+select now();
+end loop;
+repeat
+select now();
+label1: while varb do
+select now();
+end while label1;
+if vara then
+select now();
+repeat
+select now();
+until done end repeat;
+begin
+select now();
+while varb do
+select now();
+label1: while varb do
+select now();
+end while label1;
+if vara then
+select now();
+while varb do
+select now();
+loop
+select now();
+end loop;
+repeat
+select now();
+loop
+select now();
+while varb do
+select now();
+end while;
+repeat
+select now();
+label1: loop
+select now();
+if vara then
+select now();
+end if;
+end loop label1;
+until done end repeat;
+end loop;
+until done end repeat;
+end while;
+end if;
+end while;
+end;
+end if;
+until done end repeat;
+until done end repeat;
+end if;
+end;
+end while;
+end $$
+drop procedure p_37269;
+drop procedure if exists p_37228;
+create procedure p_37228 ()
+BEGIN
+DECLARE v INT DEFAULT 123;
+IF (v > 1) THEN SET v = 1;
+ELSEIF (v < 10) THEN SET v = 10;
+ELSEIF (v < 11) THEN SET v = 11;
+ELSEIF (v < 12) THEN SET v = 12;
+ELSEIF (v < 13) THEN SET v = 13;
+ELSEIF (v < 14) THEN SET v = 14;
+ELSEIF (v < 15) THEN SET v = 15;
+ELSEIF (v < 16) THEN SET v = 16;
+ELSEIF (v < 17) THEN SET v = 17;
+ELSEIF (v < 18) THEN SET v = 18;
+ELSEIF (v < 19) THEN SET v = 19;
+ELSEIF (v < 20) THEN SET v = 20;
+ELSEIF (v < 21) THEN SET v = 21;
+ELSEIF (v < 22) THEN SET v = 22;
+ELSEIF (v < 23) THEN SET v = 23;
+ELSEIF (v < 24) THEN SET v = 24;
+ELSEIF (v < 25) THEN SET v = 25;
+ELSEIF (v < 26) THEN SET v = 26;
+ELSEIF (v < 27) THEN SET v = 27;
+ELSEIF (v < 28) THEN SET v = 28;
+ELSEIF (v < 29) THEN SET v = 29;
+ELSEIF (v < 30) THEN SET v = 30;
+ELSEIF (v < 31) THEN SET v = 31;
+ELSEIF (v < 32) THEN SET v = 32;
+ELSEIF (v < 33) THEN SET v = 33;
+ELSEIF (v < 34) THEN SET v = 34;
+ELSEIF (v < 35) THEN SET v = 35;
+ELSEIF (v < 36) THEN SET v = 36;
+ELSEIF (v < 37) THEN SET v = 37;
+ELSEIF (v < 38) THEN SET v = 38;
+ELSEIF (v < 39) THEN SET v = 39;
+END IF;
+END $$
+drop procedure p_37228;
diff --git a/mysql-test/t/parser_stack.test b/mysql-test/t/parser_stack.test
new file mode 100644
index 00000000000..3330ef41833
--- /dev/null
+++ b/mysql-test/t/parser_stack.test
@@ -0,0 +1,402 @@
+# Copyright (C) 2008 Sun Microsystems, Inc
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+#
+# These tests are designed to cause an internal parser stack overflow,
+# and trigger my_yyoverflow().
+#
+
+use test;
+
+SELECT
+((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((
+((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((
+((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((
+1
+))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
+))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
+))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
+;
+
+prepare stmt from
+"
+SELECT
+((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((
+((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((
+((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((
+1
+))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
+))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
+))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
+"
+;
+
+execute stmt;
+
+--disable_warnings
+drop view if exists view_overflow;
+--enable_warnings
+
+CREATE VIEW view_overflow AS
+SELECT
+((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((
+((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((
+((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((
+1
+))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
+))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
+))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
+;
+
+SELECT * from view_overflow;
+
+drop view view_overflow;
+
+--disable_warnings
+drop procedure if exists proc_overflow;
+--enable_warnings
+
+delimiter $$;
+
+CREATE PROCEDURE proc_overflow()
+BEGIN
+
+ BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
+ BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
+ BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
+ BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
+ BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
+ BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
+ BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
+ BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
+ BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
+ BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
+
+ select 1;
+ select 2;
+ select 3;
+
+ END; END; END; END; END; END; END; END; END; END; END; END;
+ END; END; END; END; END; END; END; END; END; END; END; END;
+ END; END; END; END; END; END; END; END; END; END; END; END;
+ END; END; END; END; END; END; END; END; END; END; END; END;
+ END; END; END; END; END; END; END; END; END; END; END; END;
+ END; END; END; END; END; END; END; END; END; END; END; END;
+ END; END; END; END; END; END; END; END; END; END; END; END;
+ END; END; END; END; END; END; END; END; END; END; END; END;
+ END; END; END; END; END; END; END; END; END; END; END; END;
+ END; END; END; END; END; END; END; END; END; END; END; END;
+
+END $$
+
+delimiter ;$$
+
+call proc_overflow();
+
+drop procedure proc_overflow;
+
+--disable_warnings
+drop function if exists func_overflow;
+--enable_warnings
+
+delimiter $$;
+
+create function func_overflow() returns int
+BEGIN
+ DECLARE x int default 0;
+
+ BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
+ BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
+ BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
+ BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
+ BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
+ BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
+ BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
+ BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
+ BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
+ BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
+
+ SET x=x+1;
+ SET x=x+2;
+ SET x=x+3;
+
+ END; END; END; END; END; END; END; END; END; END; END; END;
+ END; END; END; END; END; END; END; END; END; END; END; END;
+ END; END; END; END; END; END; END; END; END; END; END; END;
+ END; END; END; END; END; END; END; END; END; END; END; END;
+ END; END; END; END; END; END; END; END; END; END; END; END;
+ END; END; END; END; END; END; END; END; END; END; END; END;
+ END; END; END; END; END; END; END; END; END; END; END; END;
+ END; END; END; END; END; END; END; END; END; END; END; END;
+ END; END; END; END; END; END; END; END; END; END; END; END;
+ END; END; END; END; END; END; END; END; END; END; END; END;
+
+ return x;
+END $$
+
+delimiter ;$$
+
+select func_overflow();
+
+drop function func_overflow;
+
+--disable_warnings
+drop table if exists table_overflow;
+--enable_warnings
+
+create table table_overflow(a int, b int);
+
+delimiter $$;
+
+create trigger trigger_overflow before insert on table_overflow
+for each row
+BEGIN
+
+ BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
+ BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
+ BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
+ BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
+ BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
+ BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
+ BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
+ BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
+ BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
+ BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
+
+ SET NEW.b := NEW.a;
+ SET NEW.b := NEW.b + 1;
+ SET NEW.b := NEW.b + 2;
+ SET NEW.b := NEW.b + 3;
+
+ END; END; END; END; END; END; END; END; END; END; END; END;
+ END; END; END; END; END; END; END; END; END; END; END; END;
+ END; END; END; END; END; END; END; END; END; END; END; END;
+ END; END; END; END; END; END; END; END; END; END; END; END;
+ END; END; END; END; END; END; END; END; END; END; END; END;
+ END; END; END; END; END; END; END; END; END; END; END; END;
+ END; END; END; END; END; END; END; END; END; END; END; END;
+ END; END; END; END; END; END; END; END; END; END; END; END;
+ END; END; END; END; END; END; END; END; END; END; END; END;
+ END; END; END; END; END; END; END; END; END; END; END; END;
+
+END $$
+
+delimiter ;$$
+
+insert into table_overflow set a=10;
+insert into table_overflow set a=20;
+select * from table_overflow;
+
+drop table table_overflow;
+
+--disable_warnings
+drop procedure if exists proc_35577;
+--enable_warnings
+
+delimiter $$;
+
+CREATE PROCEDURE proc_35577()
+BEGIN
+ DECLARE z_done INT DEFAULT 0;
+ DECLARE t_done VARCHAR(5000);
+ outer_loop: LOOP
+ IF t_done=1 THEN
+ LEAVE outer_loop;
+ END IF;
+
+ inner_block:BEGIN
+ DECLARE z_done INT DEFAULT 0;
+ SET z_done = 0;
+ inner_loop: LOOP
+ IF z_done=1 THEN
+ LEAVE inner_loop;
+ END IF;
+ IF (t_done = 'a') THEN
+ IF (t_done <> 0) THEN
+ IF ( t_done > 0) THEN
+ IF (t_done = 'a') THEN
+ SET t_done = 'a';
+ ELSEIF (t_done = 'a') THEN
+ SET t_done = 'a';
+ ELSEIF(t_done = 'a') THEN
+ SET t_done = 'a';
+ ELSEIF(t_done = 'a') THEN
+ SET t_done = 'a';
+ ELSEIF(t_done = 'a') THEN
+ SET t_done = 'a';
+ ELSEIF(t_done = 'a') THEN
+ SET t_done = 'a';
+ ELSEIF(t_done = 'a') THEN
+ SET t_done = 'a';
+ ELSEIF(t_done = 'a') THEN
+ SET t_done = 'a';
+ END IF;
+ END IF;
+ END IF;
+ END IF;
+ END LOOP inner_loop;
+ END inner_block;
+ END LOOP outer_loop;
+END $$
+
+delimiter ;$$
+
+drop procedure proc_35577;
+
+#
+# Bug#37269 (parser crash when creating stored procedure)
+#
+
+--disable_warnings
+drop procedure if exists p_37269;
+--enable_warnings
+
+delimiter $$;
+
+create procedure p_37269()
+begin
+ declare done int default 0;
+ declare varb int default 0;
+ declare vara int default 0;
+
+ repeat
+ select now();
+ until done end repeat;
+ while varb do
+ select now();
+ begin
+ select now();
+ repeat
+ select now();
+ until done end repeat;
+ if vara then
+ select now();
+ repeat
+ select now();
+ loop
+ select now();
+ end loop;
+ repeat
+ select now();
+ label1: while varb do
+ select now();
+ end while label1;
+ if vara then
+ select now();
+ repeat
+ select now();
+ until done end repeat;
+ begin
+ select now();
+ while varb do
+ select now();
+ label1: while varb do
+ select now();
+ end while label1;
+ if vara then
+ select now();
+ while varb do
+ select now();
+ loop
+ select now();
+ end loop;
+ repeat
+ select now();
+ loop
+ select now();
+ while varb do
+ select now();
+ end while;
+ repeat
+ select now();
+ label1: loop
+ select now();
+ if vara then
+ select now();
+ end if;
+ end loop label1;
+ until done end repeat;
+ end loop;
+ until done end repeat;
+ end while;
+ end if;
+ end while;
+ end;
+ end if;
+ until done end repeat;
+ until done end repeat;
+ end if;
+ end;
+ end while;
+end $$
+
+delimiter ;$$
+
+drop procedure p_37269;
+
+#
+# Bug#37228 (Sever crashes when creating stored procedure with more than
+# 10 IF/ELSEIF)
+#
+
+--disable_warnings
+drop procedure if exists p_37228;
+--enable_warnings
+
+delimiter $$;
+
+create procedure p_37228 ()
+BEGIN
+ DECLARE v INT DEFAULT 123;
+
+ IF (v > 1) THEN SET v = 1;
+ ELSEIF (v < 10) THEN SET v = 10;
+ ELSEIF (v < 11) THEN SET v = 11;
+ ELSEIF (v < 12) THEN SET v = 12;
+ ELSEIF (v < 13) THEN SET v = 13;
+ ELSEIF (v < 14) THEN SET v = 14;
+ ELSEIF (v < 15) THEN SET v = 15;
+ ELSEIF (v < 16) THEN SET v = 16;
+ ELSEIF (v < 17) THEN SET v = 17;
+ ELSEIF (v < 18) THEN SET v = 18;
+ ELSEIF (v < 19) THEN SET v = 19;
+ ELSEIF (v < 20) THEN SET v = 20;
+ ELSEIF (v < 21) THEN SET v = 21;
+ ELSEIF (v < 22) THEN SET v = 22;
+ ELSEIF (v < 23) THEN SET v = 23;
+ ELSEIF (v < 24) THEN SET v = 24;
+ ELSEIF (v < 25) THEN SET v = 25;
+ ELSEIF (v < 26) THEN SET v = 26;
+ ELSEIF (v < 27) THEN SET v = 27;
+ ELSEIF (v < 28) THEN SET v = 28;
+ ELSEIF (v < 29) THEN SET v = 29;
+ ELSEIF (v < 30) THEN SET v = 30;
+ ELSEIF (v < 31) THEN SET v = 31;
+ ELSEIF (v < 32) THEN SET v = 32;
+ ELSEIF (v < 33) THEN SET v = 33;
+ ELSEIF (v < 34) THEN SET v = 34;
+ ELSEIF (v < 35) THEN SET v = 35;
+ ELSEIF (v < 36) THEN SET v = 36;
+ ELSEIF (v < 37) THEN SET v = 37;
+ ELSEIF (v < 38) THEN SET v = 38;
+ ELSEIF (v < 39) THEN SET v = 39;
+ END IF;
+END $$
+
+delimiter ;$$
+
+drop procedure p_37228;
+
+
diff --git a/sql/event_data_objects.cc b/sql/event_data_objects.cc
index dd47b8dd916..ea3c9f17e23 100644
--- a/sql/event_data_objects.cc
+++ b/sql/event_data_objects.cc
@@ -1439,10 +1439,10 @@ Event_job_data::execute(THD *thd, bool drop)
thd->query_length= sp_sql.length();
{
- Lex_input_stream lip(thd, thd->query, thd->query_length);
+ Parser_state parser_state(thd, thd->query, thd->query_length);
lex_start(thd);
- if (parse_sql(thd, &lip, creation_ctx))
+ if (parse_sql(thd, & parser_state, creation_ctx))
{
sql_print_error("Event Scheduler: "
"%serror during compilation of %s.%s",
diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h
index 0060e7873e1..88aba4c9662 100644
--- a/sql/mysql_priv.h
+++ b/sql/mysql_priv.h
@@ -44,6 +44,8 @@
#include "sql_plugin.h"
#include "scheduler.h"
+class Parser_state;
+
/**
Query type constants.
@@ -804,8 +806,8 @@ bool check_string_char_length(LEX_STRING *str, const char *err_msg,
bool test_if_data_home_dir(const char *dir);
bool parse_sql(THD *thd,
- class Lex_input_stream *lip,
- class Object_creation_ctx *creation_ctx);
+ Parser_state *parser_state,
+ Object_creation_ctx *creation_ctx);
enum enum_mysql_completiontype {
ROLLBACK_RELEASE=-2, ROLLBACK=1, ROLLBACK_AND_CHAIN=7,
diff --git a/sql/sp.cc b/sql/sp.cc
index a1e5e1291ae..cc545992857 100644
--- a/sql/sp.cc
+++ b/sql/sp.cc
@@ -617,12 +617,12 @@ db_load_routine(THD *thd, int type, sp_name *name, sp_head **sphp,
thd->spcont= NULL;
{
- Lex_input_stream lip(thd, defstr.c_ptr(), defstr.length());
+ Parser_state parser_state(thd, defstr.c_ptr(), defstr.length());
lex_start(thd);
thd->push_internal_handler(&warning_handler);
- ret= parse_sql(thd, &lip, creation_ctx) || newlex.sphead == NULL;
+ ret= parse_sql(thd, & parser_state, creation_ctx) || newlex.sphead == NULL;
thd->pop_internal_handler();
/*
diff --git a/sql/sp_head.cc b/sql/sp_head.cc
index c450c9dd25d..92dcafa7aa8 100644
--- a/sql/sp_head.cc
+++ b/sql/sp_head.cc
@@ -627,14 +627,14 @@ void
sp_head::set_body_start(THD *thd, const char *begin_ptr)
{
m_body_begin= begin_ptr;
- thd->m_lip->body_utf8_start(thd, begin_ptr);
+ thd->m_parser_state->m_lip.body_utf8_start(thd, begin_ptr);
}
void
sp_head::set_stmt_end(THD *thd)
{
- Lex_input_stream *lip= thd->m_lip; /* shortcut */
+ Lex_input_stream *lip= & thd->m_parser_state->m_lip; /* shortcut */
const char *end_ptr= lip->get_cpp_ptr(); /* shortcut */
/* Make the string of parameters. */
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index b54aea94424..691b176e59d 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -529,7 +529,7 @@ THD::THD()
bootstrap(0),
derived_tables_processing(FALSE),
spcont(NULL),
- m_lip(NULL)
+ m_parser_state(NULL)
{
ulong tmp;
diff --git a/sql/sql_class.h b/sql/sql_class.h
index a86b4d36d00..9e0272b8891 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -75,7 +75,7 @@ class Load_log_event;
class Slave_log_event;
class sp_rcontext;
class sp_cache;
-class Lex_input_stream;
+class Parser_state;
class Rows_log_event;
enum enum_enable_or_disable { LEAVE_AS_IS, ENABLE, DISABLE };
@@ -1771,13 +1771,11 @@ public:
} binlog_evt_union;
/**
- Character input stream consumed by the lexical analyser,
- used during parsing.
- Note that since the parser is not re-entrant, we keep only one input
- stream here. This member is valid only when executing code during parsing,
- and may point to invalid memory after that.
+ Internal parser state.
+ Note that since the parser is not re-entrant, we keep only one parser
+ state here. This member is valid only when executing code during parsing.
*/
- Lex_input_stream *m_lip;
+ Parser_state *m_parser_state;
#ifdef WITH_PARTITION_STORAGE_ENGINE
partition_info *work_part_info;
diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc
index 64c2a911313..1822176f00a 100644
--- a/sql/sql_lex.cc
+++ b/sql/sql_lex.cc
@@ -371,13 +371,6 @@ void lex_end(LEX *lex)
{
DBUG_ENTER("lex_end");
DBUG_PRINT("enter", ("lex: 0x%lx", (long) lex));
- if (lex->yacc_yyss)
- {
- my_free(lex->yacc_yyss, MYF(0));
- my_free(lex->yacc_yyvs, MYF(0));
- lex->yacc_yyss= 0;
- lex->yacc_yyvs= 0;
- }
/* release used plugins */
plugin_unlock_list(0, (plugin_ref*)lex->plugins.buffer,
@@ -387,6 +380,14 @@ void lex_end(LEX *lex)
DBUG_VOID_RETURN;
}
+Yacc_state::~Yacc_state()
+{
+ if (yacc_yyss)
+ {
+ my_free(yacc_yyss, MYF(0));
+ my_free(yacc_yyvs, MYF(0));
+ }
+}
static int find_keyword(Lex_input_stream *lip, uint len, bool function)
{
@@ -726,7 +727,7 @@ int MYSQLlex(void *arg, void *yythd)
uint length;
enum my_lex_states state;
THD *thd= (THD *)yythd;
- Lex_input_stream *lip= thd->m_lip;
+ Lex_input_stream *lip= & thd->m_parser_state->m_lip;
LEX *lex= thd->lex;
YYSTYPE *yylval=(YYSTYPE*) arg;
CHARSET_INFO *cs= thd->charset();
@@ -2128,7 +2129,7 @@ void Query_tables_list::destroy_query_tables_list()
*/
st_lex::st_lex()
- :result(0), yacc_yyss(0), yacc_yyvs(0),
+ :result(0),
sql_command(SQLCOM_END), option_type(OPT_DEFAULT), is_lex_started(0)
{
diff --git a/sql/sql_lex.h b/sql/sql_lex.h
index 443c85b4854..5af22a895a7 100644
--- a/sql/sql_lex.h
+++ b/sql/sql_lex.h
@@ -1513,7 +1513,6 @@ typedef struct st_lex : public Query_tables_list
LEX_STRING comment, ident;
LEX_USER *grant_user;
XID *xid;
- uchar* yacc_yyss, *yacc_yyvs;
THD *thd;
/* maintain a list of used plugins for this LEX */
@@ -1847,6 +1846,59 @@ typedef struct st_lex : public Query_tables_list
}
} LEX;
+
+/**
+ The internal state of the syntax parser.
+ This object is only available during parsing,
+ and is private to the syntax parser implementation (sql_yacc.yy).
+*/
+class Yacc_state
+{
+public:
+ Yacc_state()
+ : yacc_yyss(NULL), yacc_yyvs(NULL)
+ {}
+
+ ~Yacc_state();
+
+ /**
+ Bison internal state stack, yyss, when dynamically allocated using
+ my_yyoverflow().
+ */
+ uchar *yacc_yyss;
+
+ /**
+ Bison internal semantic value stack, yyvs, when dynamically allocated using
+ my_yyoverflow().
+ */
+ uchar *yacc_yyvs;
+
+ /*
+ TODO: move more attributes from the LEX structure here.
+ */
+};
+
+/**
+ Internal state of the parser.
+ The complete state consist of:
+ - state data used during lexical parsing,
+ - state data used during syntactic parsing.
+*/
+class Parser_state
+{
+public:
+ Parser_state(THD *thd, const char* buff, unsigned int length)
+ : m_lip(thd, buff, length), m_yacc()
+ {}
+
+ ~Parser_state()
+ {}
+
+ Lex_input_stream m_lip;
+ Yacc_state m_yacc;
+};
+
+
struct st_lex_local: public st_lex
{
static void *operator new(size_t size) throw()
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 349e92b00d3..14b14106925 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -5323,29 +5323,35 @@ bool check_stack_overrun(THD *thd, long margin,
bool my_yyoverflow(short **yyss, YYSTYPE **yyvs, ulong *yystacksize)
{
- LEX *lex= current_thd->lex;
+ Yacc_state *state= & current_thd->m_parser_state->m_yacc;
ulong old_info=0;
+ DBUG_ASSERT(state);
if ((uint) *yystacksize >= MY_YACC_MAX)
return 1;
- if (!lex->yacc_yyvs)
+ if (!state->yacc_yyvs)
old_info= *yystacksize;
*yystacksize= set_zone((*yystacksize)*2,MY_YACC_INIT,MY_YACC_MAX);
- if (!(lex->yacc_yyvs= (uchar*)
- my_realloc(lex->yacc_yyvs,
- *yystacksize*sizeof(**yyvs),
- MYF(MY_ALLOW_ZERO_PTR | MY_FREE_ON_ERROR))) ||
- !(lex->yacc_yyss= (uchar*)
- my_realloc(lex->yacc_yyss,
- *yystacksize*sizeof(**yyss),
- MYF(MY_ALLOW_ZERO_PTR | MY_FREE_ON_ERROR))))
+ if (!(state->yacc_yyvs= (uchar*)
+ my_realloc(state->yacc_yyvs,
+ *yystacksize*sizeof(**yyvs),
+ MYF(MY_ALLOW_ZERO_PTR | MY_FREE_ON_ERROR))) ||
+ !(state->yacc_yyss= (uchar*)
+ my_realloc(state->yacc_yyss,
+ *yystacksize*sizeof(**yyss),
+ MYF(MY_ALLOW_ZERO_PTR | MY_FREE_ON_ERROR))))
return 1;
if (old_info)
- { // Copy old info from stack
- memcpy(lex->yacc_yyss, (uchar*) *yyss, old_info*sizeof(**yyss));
- memcpy(lex->yacc_yyvs, (uchar*) *yyvs, old_info*sizeof(**yyvs));
+ {
+ /*
+ Only copy the old stack on the first call to my_yyoverflow(),
+ when replacing a static stack (YYINITDEPTH) by a dynamic stack.
+ For subsequent calls, my_realloc already did preserve the old stack.
+ */
+ memcpy(state->yacc_yyss, *yyss, old_info*sizeof(**yyss));
+ memcpy(state->yacc_yyvs, *yyvs, old_info*sizeof(**yyvs));
}
- *yyss=(short*) lex->yacc_yyss;
- *yyvs=(YYSTYPE*) lex->yacc_yyvs;
+ *yyss= (short*) state->yacc_yyss;
+ *yyvs= (YYSTYPE*) state->yacc_yyvs;
return 0;
}
@@ -5609,10 +5615,10 @@ void mysql_parse(THD *thd, const char *inBuf, uint length,
sp_cache_flush_obsolete(&thd->sp_proc_cache);
sp_cache_flush_obsolete(&thd->sp_func_cache);
- Lex_input_stream lip(thd, inBuf, length);
+ Parser_state parser_state(thd, inBuf, length);
- bool err= parse_sql(thd, &lip, NULL);
- *found_semicolon= lip.found_semicolon;
+ bool err= parse_sql(thd, & parser_state, NULL);
+ *found_semicolon= parser_state.m_lip.found_semicolon;
if (!err)
{
@@ -5697,11 +5703,11 @@ bool mysql_test_parse_for_slave(THD *thd, char *inBuf, uint length)
bool error= 0;
DBUG_ENTER("mysql_test_parse_for_slave");
- Lex_input_stream lip(thd, inBuf, length);
+ Parser_state parser_state(thd, inBuf, length);
lex_start(thd);
mysql_reset_thd_for_next_command(thd);
- if (!parse_sql(thd, &lip, NULL) &&
+ if (!parse_sql(thd, & parser_state, NULL) &&
all_tables_not_ok(thd,(TABLE_LIST*) lex->select_lex.table_list.first))
error= 1; /* Ignore question */
thd->end_statement();
@@ -6740,7 +6746,7 @@ bool check_simple_select()
if (lex->current_select != &lex->select_lex)
{
char command[80];
- Lex_input_stream *lip= thd->m_lip;
+ Lex_input_stream *lip= & thd->m_parser_state->m_lip;
strmake(command, lip->yylval->symbol.str,
min(lip->yylval->symbol.length, sizeof(command)-1));
my_error(ER_CANT_USE_OPTION_HERE, MYF(0), command);
@@ -7417,7 +7423,7 @@ extern int MYSQLparse(void *thd); // from sql_yacc.cc
instead of MYSQLparse().
@param thd Thread context.
- @param lip Lexer context.
+ @param parser_state Parser state.
@param creation_ctx Object creation context.
@return Error status.
@@ -7426,10 +7432,10 @@ extern int MYSQLparse(void *thd); // from sql_yacc.cc
*/
bool parse_sql(THD *thd,
- Lex_input_stream *lip,
+ Parser_state *parser_state,
Object_creation_ctx *creation_ctx)
{
- DBUG_ASSERT(thd->m_lip == NULL);
+ DBUG_ASSERT(thd->m_parser_state == NULL);
/* Backup creation context. */
@@ -7438,9 +7444,9 @@ bool parse_sql(THD *thd,
if (creation_ctx)
backup_ctx= creation_ctx->set_n_backup(thd);
- /* Set Lex_input_stream. */
+ /* Set parser state. */
- thd->m_lip= lip;
+ thd->m_parser_state= parser_state;
/* Parse the query. */
@@ -7451,9 +7457,9 @@ bool parse_sql(THD *thd,
DBUG_ASSERT(!mysql_parse_status ||
mysql_parse_status && thd->is_error());
- /* Reset Lex_input_stream. */
+ /* Reset parser state. */
- thd->m_lip= NULL;
+ thd->m_parser_state= NULL;
/* Restore creation context. */
diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc
index 037da87be7f..121ee3c22b4 100644
--- a/sql/sql_partition.cc
+++ b/sql/sql_partition.cc
@@ -3767,7 +3767,7 @@ bool mysql_unpack_partition(THD *thd,
thd->lex= &lex;
thd->variables.character_set_client= system_charset_info;
- Lex_input_stream lip(thd, part_buf, part_info_len);
+ Parser_state parser_state(thd, part_buf, part_info_len);
lex_start(thd);
*work_part_info_used= false;
@@ -3797,7 +3797,7 @@ bool mysql_unpack_partition(THD *thd,
lex.part_info->part_state= part_state;
lex.part_info->part_state_len= part_state_len;
DBUG_PRINT("info", ("Parse: %s", part_buf));
- if (parse_sql(thd, &lip, NULL))
+ if (parse_sql(thd, & parser_state, NULL))
{
thd->free_items();
goto end;
diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc
index 16e4812655e..7fcc374e3f3 100644
--- a/sql/sql_prepare.cc
+++ b/sql/sql_prepare.cc
@@ -3017,11 +3017,11 @@ bool Prepared_statement::prepare(const char *packet, uint packet_len)
old_stmt_arena= thd->stmt_arena;
thd->stmt_arena= this;
- Lex_input_stream lip(thd, thd->query, thd->query_length);
- lip.stmt_prepare_mode= TRUE;
+ Parser_state parser_state(thd, thd->query, thd->query_length);
+ parser_state.m_lip.stmt_prepare_mode= TRUE;
lex_start(thd);
- error= parse_sql(thd, &lip, NULL) ||
+ error= parse_sql(thd, & parser_state, NULL) ||
thd->is_error() ||
init_param_array(this);
diff --git a/sql/sql_trigger.cc b/sql/sql_trigger.cc
index d426904e4b2..32389bde44c 100644
--- a/sql/sql_trigger.cc
+++ b/sql/sql_trigger.cc
@@ -1287,7 +1287,9 @@ bool Table_triggers_list::check_n_load(THD *thd, const char *db,
thd->variables.sql_mode= (ulong)*trg_sql_mode;
- Lex_input_stream lip(thd, trg_create_str->str, trg_create_str->length);
+ Parser_state parser_state(thd,
+ trg_create_str->str,
+ trg_create_str->length);
Trigger_creation_ctx *creation_ctx=
Trigger_creation_ctx::create(thd,
@@ -1300,7 +1302,7 @@ bool Table_triggers_list::check_n_load(THD *thd, const char *db,
lex_start(thd);
thd->spcont= NULL;
- if (parse_sql(thd, &lip, creation_ctx))
+ if (parse_sql(thd, & parser_state, creation_ctx))
{
/* Currently sphead is always deleted in case of a parse error */
DBUG_ASSERT(lex.sphead == 0);
diff --git a/sql/sql_view.cc b/sql/sql_view.cc
index a654721de37..12b2adf4f13 100644
--- a/sql/sql_view.cc
+++ b/sql/sql_view.cc
@@ -1147,9 +1147,9 @@ bool mysql_make_view(THD *thd, File_parser *parser, TABLE_LIST *table,
char old_db_buf[NAME_LEN+1];
LEX_STRING old_db= { old_db_buf, sizeof(old_db_buf) };
bool dbchanged;
- Lex_input_stream lip(thd,
- table->select_stmt.str,
- table->select_stmt.length);
+ Parser_state parser_state(thd,
+ table->select_stmt.str,
+ table->select_stmt.length);
/*
Use view db name as thread default database, in order to ensure
@@ -1193,7 +1193,7 @@ bool mysql_make_view(THD *thd, File_parser *parser, TABLE_LIST *table,
/* Parse the query. */
- parse_status= parse_sql(thd, &lip, table->view_creation_ctx);
+ parse_status= parse_sql(thd, & parser_state, table->view_creation_ctx);
/* Restore environment. */
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index 3652fe8d6b4..ccd64c24960 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -28,6 +28,7 @@
#define YYPARSE_PARAM yythd
#define YYLEX_PARAM yythd
#define YYTHD ((THD *)yythd)
+#define YYLIP (& YYTHD->m_parser_state->m_lip)
#define MYSQL_YACC
#define YYINITDEPTH 100
@@ -121,7 +122,7 @@ const LEX_STRING null_lex_str= {0,0};
void my_parse_error(const char *s)
{
THD *thd= current_thd;
- Lex_input_stream *lip= thd->m_lip;
+ Lex_input_stream *lip= & thd->m_parser_state->m_lip;
const char *yytext= lip->get_tok_start();
/* Push an error into the error stack */
@@ -1356,11 +1357,11 @@ query:
MYSQL_YYABORT;
}
thd->lex->sql_command= SQLCOM_EMPTY_QUERY;
- thd->m_lip->found_semicolon= NULL;
+ YYLIP->found_semicolon= NULL;
}
| verb_clause
{
- Lex_input_stream *lip = YYTHD->m_lip;
+ Lex_input_stream *lip = YYLIP;
if ((YYTHD->client_capabilities & CLIENT_MULTI_QUERIES) &&
! lip->stmt_prepare_mode &&
@@ -1386,7 +1387,7 @@ query:
| verb_clause END_OF_INPUT
{
/* Single query, not terminated. */
- YYTHD->m_lip->found_semicolon= NULL;
+ YYLIP->found_semicolon= NULL;
}
;
@@ -1917,7 +1918,7 @@ ev_sql_stmt:
{
THD *thd= YYTHD;
LEX *lex= thd->lex;
- Lex_input_stream *lip= thd->m_lip;
+ Lex_input_stream *lip= YYLIP;
/*
This stops the following :
@@ -2574,7 +2575,7 @@ sp_proc_stmt_statement:
{
THD *thd= YYTHD;
LEX *lex= thd->lex;
- Lex_input_stream *lip= thd->m_lip;
+ Lex_input_stream *lip= YYLIP;
lex->sphead->reset_lex(thd);
lex->sphead->m_tmp_query= lip->get_tok_start();
@@ -2583,7 +2584,7 @@ sp_proc_stmt_statement:
{
THD *thd= YYTHD;
LEX *lex= thd->lex;
- Lex_input_stream *lip= thd->m_lip;
+ Lex_input_stream *lip= YYLIP;
sp_head *sp= lex->sphead;
sp->m_flags|= sp_get_flags_for_command(lex);
@@ -6455,17 +6456,13 @@ select_item:
remember_name:
{
- THD *thd= YYTHD;
- Lex_input_stream *lip= thd->m_lip;
- $$= (char*) lip->get_cpp_tok_start();
+ $$= (char*) YYLIP->get_cpp_tok_start();
}
;
remember_end:
{
- THD *thd= YYTHD;
- Lex_input_stream *lip= thd->m_lip;
- $$= (char*) lip->get_cpp_tok_end();
+ $$= (char*) YYLIP->get_cpp_tok_end();
}
;
@@ -9645,7 +9642,7 @@ load:
{
THD *thd= YYTHD;
LEX *lex= thd->lex;
- Lex_input_stream *lip= thd->m_lip;
+ Lex_input_stream *lip= YYLIP;
if (lex->sphead)
{
@@ -9686,10 +9683,7 @@ load_data:
}
opt_duplicate INTO
{
- THD *thd= YYTHD;
- LEX *lex= thd->lex;
- Lex_input_stream *lip= thd->m_lip;
- lex->fname_end= lip->get_ptr();
+ Lex->fname_end= YYLIP->get_ptr();
}
TABLE_SYM table_ident
{
@@ -9924,7 +9918,7 @@ param_marker:
{
THD *thd= YYTHD;
LEX *lex= thd->lex;
- Lex_input_stream *lip= thd->m_lip;
+ Lex_input_stream *lip= YYLIP;
Item_param *item;
if (! lex->parsing_options.allows_variable)
{
@@ -9956,7 +9950,7 @@ literal:
| NULL_SYM
{
$$ = new Item_null();
- YYTHD->m_lip->next_state=MY_LEX_OPERATOR_OR_IDENT;
+ YYLIP->next_state= MY_LEX_OPERATOR_OR_IDENT;
}
| FALSE_SYM { $$= new Item_int((char*) "FALSE",0,1); }
| TRUE_SYM { $$= new Item_int((char*) "TRUE",1,1); }
@@ -10086,7 +10080,7 @@ simple_ident:
{
THD *thd= YYTHD;
LEX *lex= thd->lex;
- Lex_input_stream *lip= thd->m_lip;
+ Lex_input_stream *lip= YYLIP;
sp_variable_t *spv;
sp_pcontext *spc = lex->spcont;
if (spc && (spv = spc->find_variable(&$1)))
@@ -10776,7 +10770,7 @@ option_type_value:
{
THD *thd= YYTHD;
LEX *lex= thd->lex;
- Lex_input_stream *lip= thd->m_lip;
+ Lex_input_stream *lip= YYLIP;
if (lex->sphead)
{
@@ -10807,7 +10801,7 @@ option_type_value:
{
THD *thd= YYTHD;
LEX *lex= thd->lex;
- Lex_input_stream *lip= thd->m_lip;
+ Lex_input_stream *lip= YYLIP;
if (lex->sphead)
{
@@ -12076,19 +12070,17 @@ view_select:
{
THD *thd= YYTHD;
LEX *lex= Lex;
- Lex_input_stream *lip= thd->m_lip;
lex->parsing_options.allows_variable= FALSE;
lex->parsing_options.allows_select_into= FALSE;
lex->parsing_options.allows_select_procedure= FALSE;
lex->parsing_options.allows_derived= FALSE;
- lex->create_view_select.str= (char *) lip->get_cpp_ptr();
+ lex->create_view_select.str= (char *) YYLIP->get_cpp_ptr();
}
view_select_aux view_check_option
{
THD *thd= YYTHD;
LEX *lex= Lex;
- Lex_input_stream *lip= thd->m_lip;
- uint len= lip->get_cpp_ptr() - lex->create_view_select.str;
+ uint len= YYLIP->get_cpp_ptr() - lex->create_view_select.str;
void *create_view_select= thd->memdup(lex->create_view_select.str, len);
lex->create_view_select.length= len;
lex->create_view_select.str= (char *) create_view_select;
@@ -12131,26 +12123,20 @@ trigger_tail:
ON
remember_name /* $7 */
{ /* $8 */
- THD *thd= YYTHD;
- LEX *lex= thd->lex;
- Lex_input_stream *lip= thd->m_lip;
- lex->raw_trg_on_table_name_begin= lip->get_tok_start();
+ Lex->raw_trg_on_table_name_begin= YYLIP->get_tok_start();
}
table_ident /* $9 */
FOR_SYM
remember_name /* $11 */
{ /* $12 */
- THD *thd= YYTHD;
- LEX *lex= thd->lex;
- Lex_input_stream *lip= thd->m_lip;
- lex->raw_trg_on_table_name_end= lip->get_tok_start();
+ Lex->raw_trg_on_table_name_end= YYLIP->get_tok_start();
}
EACH_SYM
ROW_SYM
{ /* $15 */
THD *thd= YYTHD;
LEX *lex= thd->lex;
- Lex_input_stream *lip= thd->m_lip;
+ Lex_input_stream *lip= YYLIP;
sp_head *sp;
if (lex->sphead)
@@ -12254,7 +12240,7 @@ sf_tail:
{ /* $5 */
THD *thd= YYTHD;
LEX *lex= thd->lex;
- Lex_input_stream *lip= thd->m_lip;
+ Lex_input_stream *lip= YYLIP;
sp_head *sp;
const char* tmp_param_begin;
@@ -12282,11 +12268,7 @@ sf_tail:
sp_fdparam_list /* $6 */
')' /* $7 */
{ /* $8 */
- THD *thd= YYTHD;
- LEX *lex= thd->lex;
- Lex_input_stream *lip= thd->m_lip;
-
- lex->sphead->m_param_end= lip->get_cpp_tok_start();
+ Lex->sphead->m_param_end= YYLIP->get_cpp_tok_start();
}
RETURNS_SYM /* $9 */
{ /* $10 */
@@ -12323,7 +12305,7 @@ sf_tail:
{ /* $14 */
THD *thd= YYTHD;
LEX *lex= thd->lex;
- Lex_input_stream *lip= thd->m_lip;
+ Lex_input_stream *lip= YYLIP;
lex->sphead->m_chistics= &lex->sp_chistics;
lex->sphead->set_body_start(thd, lip->get_cpp_tok_start());
@@ -12408,33 +12390,28 @@ sp_tail:
}
'('
{
- THD *thd= YYTHD;
- LEX *lex= thd->lex;
- Lex_input_stream *lip= thd->m_lip;
const char* tmp_param_begin;
- tmp_param_begin= lip->get_cpp_tok_start();
+ tmp_param_begin= YYLIP->get_cpp_tok_start();
tmp_param_begin++;
- lex->sphead->m_param_begin= tmp_param_begin;
+ Lex->sphead->m_param_begin= tmp_param_begin;
}
sp_pdparam_list
')'
{
THD *thd= YYTHD;
LEX *lex= thd->lex;
- Lex_input_stream *lip= thd->m_lip;
- lex->sphead->m_param_end= lip->get_cpp_tok_start();
+ lex->sphead->m_param_end= YYLIP->get_cpp_tok_start();
bzero((char *)&lex->sp_chistics, sizeof(st_sp_chistics));
}
sp_c_chistics
{
THD *thd= YYTHD;
LEX *lex= thd->lex;
- Lex_input_stream *lip= thd->m_lip;
lex->sphead->m_chistics= &lex->sp_chistics;
- lex->sphead->set_body_start(thd, lip->get_cpp_tok_start());
+ lex->sphead->set_body_start(thd, YYLIP->get_cpp_tok_start());
}
sp_proc_stmt
{