summaryrefslogtreecommitdiff
path: root/mysql-test
diff options
context:
space:
mode:
authorunknown <konstantin@mysql.com>2006-07-04 23:46:15 +0400
committerunknown <konstantin@mysql.com>2006-07-04 23:46:15 +0400
commitc12cc90d12b0be745975fcfdc010f53e707af1d3 (patch)
treea7a8aa12da0a32c3c9b7147eb0d41983bdb0aff1 /mysql-test
parent6a8f2ee2931342d40576736c2286352f0c654c33 (diff)
downloadmariadb-git-c12cc90d12b0be745975fcfdc010f53e707af1d3.tar.gz
A fix and a test case for Bug#17843 "Certain stored procedures fail to
run at startup" The server returned an error when trying to execute init-file with a stored procedure that could return multiple result sets to the client. A stored procedure can return multiple result sets if it contains PREPARE, SELECT, SHOW and similar statements. The fix is to set client_capabilites|=CLIENT_MULTI_RESULTS in sql_parse.cc:handle_bootstrap(). There is no "client" really, so nothing is ever sent. This makes init-file feature behave consistently: the prepared statements that can be called directly in the init-file can be used in a stored procedure too. Re-committed the patch originally submitted by Per-Erik after review. mysql-test/Makefile.am: Fix re-make without make clean. mysql-test/r/init_connect.result: Updated results (a test case for Bug#17843) mysql-test/r/init_file.result: Updated results (a test case for Bug#17843) mysql-test/std_data/init_file.dat: Add test coverage for new features added in 5.0. Note, that what can be done in init_file is very limited as it does not support any other delimiter except ';' -- only "one liners" and no multiple statement procedures. Also, this is executed with a dummy user "boot@", which calls for the use of DEFINER clause. mysql-test/t/init_connect.test: Add test coverage for new features added in 5.0. mysql-test/t/init_file.test: Add test coverage for new features added in 5.0 -- stored routines, views, triggers. The actual tests are in std_data/init_file.dat, here we just check the results and clean up. sql/sql_class.cc: Initialize Security_context::priv_host to an empty string: when executing an init-file, sql_parse.cc:get_default_definer() will use this for the value of the definer if it's not set in the query. sql/sql_parse.cc: Set CLIENT_MULTI_RESULTS in handle_bootstrap(), to make prepared statements work in stored procedures called from init-file.
Diffstat (limited to 'mysql-test')
-rw-r--r--mysql-test/Makefile.am10
-rw-r--r--mysql-test/r/init_connect.result114
-rw-r--r--mysql-test/r/init_file.result15
-rw-r--r--mysql-test/std_data/init_file.dat28
-rw-r--r--mysql-test/t/init_connect.test203
-rw-r--r--mysql-test/t/init_file.test14
6 files changed, 376 insertions, 8 deletions
diff --git a/mysql-test/Makefile.am b/mysql-test/Makefile.am
index 73074397086..629189b8ee6 100644
--- a/mysql-test/Makefile.am
+++ b/mysql-test/Makefile.am
@@ -101,15 +101,15 @@ uninstall-local:
@RM@ -f -r $(DESTDIR)$(testdir)
std_data/client-key.pem: $(top_srcdir)/SSL/$(@F)
- @CP@ $(top_srcdir)/SSL/$(@F) $(srcdir)/std_data
+ @CP@ -f $(top_srcdir)/SSL/$(@F) $(srcdir)/std_data
std_data/client-cert.pem: $(top_srcdir)/SSL/$(@F)
- @CP@ $(top_srcdir)/SSL/$(@F) $(srcdir)/std_data
+ @CP@ -f $(top_srcdir)/SSL/$(@F) $(srcdir)/std_data
std_data/cacert.pem: $(top_srcdir)/SSL/$(@F)
- @CP@ $(top_srcdir)/SSL/$(@F) $(srcdir)/std_data
+ @CP@ -f $(top_srcdir)/SSL/$(@F) $(srcdir)/std_data
std_data/server-cert.pem: $(top_srcdir)/SSL/$(@F)
- @CP@ $(top_srcdir)/SSL/$(@F) $(srcdir)/std_data
+ @CP@ -f $(top_srcdir)/SSL/$(@F) $(srcdir)/std_data
std_data/server-key.pem: $(top_srcdir)/SSL/$(@F)
- @CP@ $(top_srcdir)/SSL/$(@F) $(srcdir)/std_data
+ @CP@ -f $(top_srcdir)/SSL/$(@F) $(srcdir)/std_data
SUFFIXES = .sh
diff --git a/mysql-test/r/init_connect.result b/mysql-test/r/init_connect.result
index eeae422edc4..f90ee5913a1 100644
--- a/mysql-test/r/init_connect.result
+++ b/mysql-test/r/init_connect.result
@@ -22,3 +22,117 @@ set GLOBAL init_connect="adsfsdfsdfs";
select @a;
Got one of the listed errors
drop table t1;
+End of 4.1 tests
+create table t1 (x int);
+insert into t1 values (3), (5), (7);
+create table t2 (y int);
+create user mysqltest1@localhost;
+grant all privileges on test.* to mysqltest1@localhost;
+set global init_connect="create procedure p1() select * from t1";
+call p1();
+x
+3
+5
+7
+drop procedure p1;
+set global init_connect="create procedure p1(x int)\
+begin\
+ select count(*) from t1;\
+ select * from t1;\
+ set @x = x;
+end";
+call p1(42);
+count(*)
+3
+x
+3
+5
+7
+select @x;
+@x
+42
+set global init_connect="call p1(4711)";
+select @x;
+@x
+4711
+set global init_connect="drop procedure if exists p1";
+call p1();
+ERROR 42000: PROCEDURE test.p1 does not exist
+create procedure p1(out sum int)
+begin
+declare n int default 0;
+declare c cursor for select * from t1;
+declare exit handler for not found
+begin
+close c;
+set sum = n;
+end;
+open c;
+loop
+begin
+declare x int;
+fetch c into x;
+if x > 3 then
+set n = n + x;
+end if;
+end;
+end loop;
+end|
+set global init_connect="call p1(@sum)";
+select @sum;
+@sum
+12
+drop procedure p1;
+create procedure p1(tbl char(10), v int)
+begin
+set @s = concat('insert into ', tbl, ' values (?)');
+set @v = v;
+prepare stmt1 from @s;
+execute stmt1 using @v;
+deallocate prepare stmt1;
+end|
+set global init_connect="call p1('t1', 11)";
+select * from t1;
+x
+3
+5
+7
+11
+drop procedure p1;
+create function f1() returns int
+begin
+declare n int;
+select count(*) into n from t1;
+return n;
+end|
+set global init_connect="set @x = f1()";
+select @x;
+@x
+4
+set global init_connect="create view v1 as select f1()";
+select * from v1;
+f1()
+4
+set global init_connect="drop view v1";
+select * from v1;
+ERROR 42S02: Table 'test.v1' doesn't exist
+drop function f1;
+create trigger trg1
+after insert on t2
+for each row
+insert into t1 values (new.y);
+set global init_connect="insert into t2 values (13), (17), (19)";
+select * from t1;
+x
+3
+5
+7
+11
+13
+17
+19
+drop trigger trg1;
+set global init_connect=default;
+revoke all privileges, grant option from mysqltest1@localhost;
+drop user mysqltest1@localhost;
+drop table t1, t2;
diff --git a/mysql-test/r/init_file.result b/mysql-test/r/init_file.result
index 9766475a418..1569f2c3d68 100644
--- a/mysql-test/r/init_file.result
+++ b/mysql-test/r/init_file.result
@@ -1 +1,16 @@
ok
+end of 4.1 tests
+select * from t1;
+x
+3
+5
+7
+11
+13
+select * from t2;
+y
+30
+3
+11
+13
+drop table t1, t2;
diff --git a/mysql-test/std_data/init_file.dat b/mysql-test/std_data/init_file.dat
index 6105ca2ac1b..814e968eb31 100644
--- a/mysql-test/std_data/init_file.dat
+++ b/mysql-test/std_data/init_file.dat
@@ -1 +1,29 @@
select * from mysql.user as t1, mysql.user as t2, mysql.user as t3;
+use test;
+
+drop table if exists t1;
+create table t1 (x int);
+drop table if exists t2;
+create table t2 (y int);
+
+drop procedure if exists p1;
+create definer=root@localhost procedure p1() select * from t1;
+call p1();
+drop procedure p1;
+
+create definer=root@localhost procedure p1() insert into t1 values (3),(5),(7);
+call p1();
+
+drop function if exists f1;
+create definer=root@localhost function f1() returns int return (select count(*) from t1);
+insert into t2 set y = f1()*10;
+
+drop view if exists v1;
+create definer=root@localhost view v1 as select f1();
+insert into t2 (y) select * from v1;
+
+create trigger trg1 after insert on t2 for each row insert into t1 values (new.y);
+insert into t2 values (11), (13);
+drop procedure p1;
+drop function f1;
+drop view v1;
diff --git a/mysql-test/t/init_connect.test b/mysql-test/t/init_connect.test
index 0ee6387d985..31a98df33df 100644
--- a/mysql-test/t/init_connect.test
+++ b/mysql-test/t/init_connect.test
@@ -35,4 +35,205 @@ select @a;
connection con0;
drop table t1;
-# End of 4.1 tests
+disconnect con1;
+disconnect con2;
+disconnect con3;
+disconnect con4;
+disconnect con5;
+
+--echo End of 4.1 tests
+#
+# Test 5.* features
+#
+
+create table t1 (x int);
+insert into t1 values (3), (5), (7);
+create table t2 (y int);
+
+create user mysqltest1@localhost;
+grant all privileges on test.* to mysqltest1@localhost;
+#
+# Create a simple procedure
+#
+set global init_connect="create procedure p1() select * from t1";
+connect (con1,localhost,mysqltest1,,);
+connection con1;
+call p1();
+drop procedure p1;
+
+connection con0;
+disconnect con1;
+#
+# Create a multi-result set procedure
+#
+set global init_connect="create procedure p1(x int)\
+begin\
+ select count(*) from t1;\
+ select * from t1;\
+ set @x = x;
+end";
+connect (con1,localhost,mysqltest1,,);
+connection con1;
+call p1(42);
+select @x;
+
+connection con0;
+disconnect con1;
+#
+# Just call it - this will not generate any output
+#
+set global init_connect="call p1(4711)";
+connect (con1,localhost,mysqltest1,,);
+connection con1;
+select @x;
+
+connection con0;
+disconnect con1;
+#
+# Drop the procedure
+#
+set global init_connect="drop procedure if exists p1";
+connect (con1,localhost,mysqltest1,,);
+connection con1;
+--error ER_SP_DOES_NOT_EXIST
+call p1();
+
+connection con0;
+disconnect con1;
+#
+# Execution of a more complex procedure
+#
+delimiter |;
+create procedure p1(out sum int)
+begin
+ declare n int default 0;
+ declare c cursor for select * from t1;
+ declare exit handler for not found
+ begin
+ close c;
+ set sum = n;
+ end;
+
+ open c;
+ loop
+ begin
+ declare x int;
+
+ fetch c into x;
+ if x > 3 then
+ set n = n + x;
+ end if;
+ end;
+ end loop;
+end|
+delimiter ;|
+# Call the procedure with a cursor
+set global init_connect="call p1(@sum)";
+connect (con1,localhost,mysqltest1,,);
+connection con1;
+select @sum;
+
+connection con0;
+disconnect con1;
+drop procedure p1;
+#
+# Test Dynamic SQL
+#
+delimiter |;
+create procedure p1(tbl char(10), v int)
+begin
+ set @s = concat('insert into ', tbl, ' values (?)');
+ set @v = v;
+ prepare stmt1 from @s;
+ execute stmt1 using @v;
+ deallocate prepare stmt1;
+end|
+delimiter ;|
+# Call the procedure with prepared statements
+set global init_connect="call p1('t1', 11)";
+connect (con1,localhost,mysqltest1,,);
+connection con1;
+select * from t1;
+
+connection con0;
+disconnect con1;
+drop procedure p1;
+#
+# Stored functions
+#
+delimiter |;
+create function f1() returns int
+begin
+ declare n int;
+
+ select count(*) into n from t1;
+ return n;
+end|
+delimiter ;|
+# Invoke a function
+set global init_connect="set @x = f1()";
+connect (con1,localhost,mysqltest1,,);
+connection con1;
+select @x;
+
+connection con0;
+disconnect con1;
+#
+# Create a view
+#
+set global init_connect="create view v1 as select f1()";
+connect (con1,localhost,mysqltest1,,);
+connection con1;
+select * from v1;
+
+connection con0;
+disconnect con1;
+#
+# Drop the view
+#
+set global init_connect="drop view v1";
+connect (con1,localhost,mysqltest1,,);
+connection con1;
+--error ER_NO_SUCH_TABLE
+select * from v1;
+
+connection con0;
+disconnect con1;
+drop function f1;
+
+# We can't test "create trigger", since this requires super privileges
+# in 5.0, but with super privileges, init_connect is not executed.
+# (However, this can be tested in 5.1)
+#
+#set global init_connect="create trigger trg1\
+# after insert on t2\
+# for each row\
+# insert into t1 values (new.y)";
+#connect (con1,localhost,mysqltest1,,);
+#connection con1;
+#insert into t2 values (2), (4);
+#select * from t1;
+#
+#connection con0;
+#disconnect con1;
+
+create trigger trg1
+ after insert on t2
+ for each row
+ insert into t1 values (new.y);
+
+# Invoke trigger
+set global init_connect="insert into t2 values (13), (17), (19)";
+connect (con1,localhost,mysqltest1,,);
+connection con1;
+select * from t1;
+
+connection con0;
+disconnect con1;
+
+drop trigger trg1;
+set global init_connect=default;
+
+revoke all privileges, grant option from mysqltest1@localhost;
+drop user mysqltest1@localhost;
+drop table t1, t2;
diff --git a/mysql-test/t/init_file.test b/mysql-test/t/init_file.test
index 8b4b788777b..6b5e032fd99 100644
--- a/mysql-test/t/init_file.test
+++ b/mysql-test/t/init_file.test
@@ -6,5 +6,15 @@
# mysql-test/t/init_file-master.opt for the actual test
#
-# End of 4.1 tests
-echo ok;
+--echo ok
+--echo end of 4.1 tests
+#
+# Chec 5.x features
+#
+# Expected:
+# 3, 5, 7, 11, 13
+select * from t1;
+# Expected:
+# 30, 3, 11, 13
+select * from t2;
+drop table t1, t2;