summaryrefslogtreecommitdiff
path: root/mysql-test/t
diff options
context:
space:
mode:
Diffstat (limited to 'mysql-test/t')
-rw-r--r--mysql-test/t/insert.test31
-rw-r--r--mysql-test/t/sp-error.test145
-rw-r--r--mysql-test/t/sp.test640
-rw-r--r--mysql-test/t/subselect.test5
-rw-r--r--mysql-test/t/variables.test16
5 files changed, 834 insertions, 3 deletions
diff --git a/mysql-test/t/insert.test b/mysql-test/t/insert.test
index bfa8aac7a1f..34302cdbc60 100644
--- a/mysql-test/t/insert.test
+++ b/mysql-test/t/insert.test
@@ -65,3 +65,34 @@ use test_$1;
create table t1 (c int);
insert into test_$1.t1 set test_$1.t1.c = '1';
drop database test_$1;
+use test;
+--disable_warnings
+drop table if exists t1,t2,t3;
+--enable_warnings
+create table t1(id1 int not null auto_increment primary key, t char(12));
+create table t2(id2 int not null, t char(12));
+create table t3(id3 int not null, t char(12), index(id3));
+disable_query_log;
+let $1 = 100;
+while ($1)
+ {
+ let $2 = 5;
+ eval insert into t1(t) values ('$1');
+ while ($2)
+ {
+ eval insert into t2(id2,t) values ($1,'$2');
+ let $3 = 10;
+ while ($3)
+ {
+ eval insert into t3(id3,t) values ($1,'$2');
+ dec $3;
+ }
+ dec $2;
+ }
+ dec $1;
+ }
+enable_query_log;
+select count(*) from t2;
+insert into t2 select t1.* from t1, t2 t, t3 where t1.id1 = t.id2 and t.id2 = t3.id3;
+select count(*) from t2;
+drop table if exists t1,t2,t3;
diff --git a/mysql-test/t/sp-error.test b/mysql-test/t/sp-error.test
new file mode 100644
index 00000000000..8fa0b3c55cf
--- /dev/null
+++ b/mysql-test/t/sp-error.test
@@ -0,0 +1,145 @@
+#
+# Stored PROCEDURE error tests
+#
+
+# Make sure we don't have any procedures left.
+delete from mysql.proc;
+
+delimiter |;
+
+# This should give three syntax errors (sometimes crashed; bug #643)
+# (Unfortunately, this is not a 100% test, on some platforms this
+# passed despite the bug.)
+--error 1064
+create procedure syntaxerror(t int)|
+--error 1064
+create procedure syntaxerror(t int)|
+--error 1064
+create procedure syntaxerror(t int)|
+
+# Check that we get the right error, i.e. UDF declaration parses correctly,
+# but foo.so doesn't exist.
+# QQ This generates an error message containing a misleading errno which
+# might vary between systems (it usually doesn't have anything to do with
+# the actual failing dlopen()).
+#--error 1126
+#create function foo returns real soname "foo.so"|
+
+create procedure proc1()
+ set @x = 42|
+
+create function func1() returns int
+ return 42|
+
+# Can't create recursively
+--error 1259
+create procedure foo()
+ create procedure bar() set @x=3|
+--error 1259
+create procedure foo()
+ create function bar() returns double return 2.3|
+
+# Already exists
+--error 1260
+create procedure proc1()
+ set @x = 42|
+--error 1260
+create function func1() returns int
+ return 42|
+
+drop procedure proc1|
+drop function func1|
+
+# Does not exist
+--error 1261
+alter procedure foo|
+--error 1261
+alter function foo|
+--error 1261
+drop procedure foo|
+--error 1261
+drop function foo|
+--error 1261
+call foo()|
+drop procedure if exists foo|
+
+# LEAVE/ITERATE with no match
+--error 1264
+create procedure foo()
+foo: loop
+ leave bar;
+end loop|
+--error 1264
+create procedure foo()
+foo: loop
+ iterate bar;
+end loop|
+
+# Redefining label
+--error 1265
+create procedure foo()
+foo: loop
+ foo: loop
+ set @x=2;
+ end loop foo;
+end loop foo|
+
+# End label mismatch
+--error 1266
+create procedure foo()
+foo: loop
+ set @x=2;
+end loop bar|
+
+# Referring to undef variable
+--error 1267
+create procedure foo(out x int)
+begin
+ declare y int;
+ set x = y;
+end|
+
+# We require INTO in SELECTs for some older clients (as mysql and mysqltest,
+# for now).
+create procedure foo()
+begin
+ select name from mysql.proc;
+ select type from mysql.proc;
+end|
+--error 1268
+call foo()|
+drop procedure foo|
+
+# RETURN in FUNCTION only
+--error 1269
+create procedure foo()
+ return 42|
+
+# Doesn't allow queries in FUNCTIONs (for now :-( )
+--error 1270
+create function foo() returns int
+begin
+ declare x int;
+ select max(c) into x from test.t;
+ return x;
+end|
+
+# Wrong number of arguments
+create procedure p(x int)
+ insert into test.t1 values (x)|
+create function f(x int) returns int
+ return x+42|
+
+--error 1274
+call p()|
+--error 1274
+call p(1, 2)|
+--error 1274
+select f()|
+--error 1274
+select f(1, 2)|
+
+drop procedure p|
+drop function f|
+
+delimiter ;|
diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test
new file mode 100644
index 00000000000..61519c52929
--- /dev/null
+++ b/mysql-test/t/sp.test
@@ -0,0 +1,640 @@
+#
+# Basic stored PROCEDURE tests
+#
+#
+
+use test;
+
+--disable_warnings
+drop table if exists t1;
+drop table if exists t2;
+--enable_warnings
+
+create table t1 (
+ id char(16) not null,
+ data int not null
+);
+create table t2 (
+ s char(16) not null,
+ i int not null,
+ d double not null
+);
+
+
+# Single statement, no params.
+create procedure foo42()
+ insert into test.t1 values ("foo", 42);
+
+call foo42();
+select * from t1;
+delete from t1;
+drop procedure foo42;
+
+
+# USE test: Make sure we remain in the same DB.
+create procedure u()
+ use sptmp;
+
+--disable_warnings
+drop database if exists sptmp;
+--enable_warnings
+create database sptmp;
+use test;
+call u();
+select database();
+drop database sptmp;
+drop procedure u;
+
+
+# Single statement, two IN params.
+create procedure bar(x char(16), y int)
+ insert into test.t1 values (x, y);
+
+call bar("bar", 666);
+select * from t1;
+delete from t1;
+# Don't drop procedure yet...
+
+
+# Now for multiple statements...
+delimiter |;
+
+# Two statements.
+create procedure two(x1 char(16), x2 char(16), y int)
+begin
+ insert into test.t1 values (x1, y);
+ insert into test.t1 values (x2, y);
+end|
+
+call two("one", "two", 3)|
+select * from t1|
+delete from t1|
+drop procedure two|
+
+
+# Simple test of local variables and SET.
+create procedure locset(x char(16), y int)
+begin
+ declare z1, z2 int;
+ set z1 = y;
+ set z2 = z1+2;
+ insert into test.t1 values (x, z2);
+end|
+
+call locset("locset", 19)|
+select * from t1|
+delete from t1|
+drop procedure locset|
+
+
+# The peculiar (non-standard) mixture of variables types in SET.
+create procedure mixset(x char(16), y int)
+begin
+ declare z int;
+
+ set @z = y, z = 666, max_join_size = 100;
+ insert into test.t1 values (x, z);
+end|
+
+call mixset("mixset", 19)|
+show variables like 'max_join_size'|
+select id,data,@z from t1|
+delete from t1|
+drop procedure mixset|
+
+
+# Multiple CALL statements, one with OUT parameter.
+create procedure zip(x char(16), y int)
+begin
+ declare z int;
+ call zap(y, z);
+ call bar(x, z);
+end|
+
+# SET local variables and OUT parameter.
+create procedure zap(x int, out y int)
+begin
+ declare z int;
+ set z = x+1, y = z;
+end|
+
+call zip("zip", 99)|
+select * from t1|
+delete from t1|
+drop procedure zip|
+drop procedure zap|
+drop procedure bar|
+
+
+# "Deep" calls...
+create procedure c1(x int)
+ call c2("c", x)|
+create procedure c2(s char(16), x int)
+ call c3(x, s)|
+create procedure c3(x int, s char(16))
+ call c4("level", x, s)|
+create procedure c4(l char(8), x int, s char(16))
+ insert into t1 values (concat(l,s), x)|
+
+call c1(42)|
+select * from t1|
+delete from t1|
+drop procedure c1|
+drop procedure c2|
+drop procedure c3|
+drop procedure c4|
+
+# INOUT test
+create procedure iotest(x1 char(16), x2 char(16), y int)
+begin
+ call inc2(x2, y);
+ insert into test.t1 values (x1, y);
+end|
+
+create procedure inc2(x char(16), y int)
+begin
+ call inc(y);
+ insert into test.t1 values (x, y);
+end|
+
+create procedure inc(inout io int)
+ set io = io + 1|
+
+call iotest("io1", "io2", 1)|
+select * from t1|
+delete from t1|
+drop procedure iotest|
+drop procedure inc2|
+drop procedure inc|
+
+
+# Call-by-value test
+# The expected result is:
+# ("cbv2", 4)
+# ("cbv1", 4711)
+create procedure cbv1()
+begin
+ declare y int default 3;
+
+ call cbv2(y+1, y);
+ insert into test.t1 values ("cbv1", y);
+end|
+
+create procedure cbv2(y1 int, inout y2 int)
+begin
+ set y2 = 4711;
+ insert into test.t1 values ("cbv2", y1);
+end|
+
+call cbv1()|
+select * from t1|
+delete from t1|
+drop procedure cbv1|
+drop procedure cbv2|
+
+
+# Subselect arguments
+
+insert into t2 values ("a", 1, 1.1), ("b", 2, 1.2), ("c", 3, 1.3)|
+
+create procedure sub1(id char(16), x int)
+ insert into test.t1 values (id, x)|
+
+# QQ This doesn't work yet
+#create procedure sub2(id char(16))
+#begin
+# declare x int;
+# set x = (select sum(t.x) from test.t2 t);
+# insert into test.t1 values (id, x);
+#end|
+
+create function sub3(i int) returns int
+ return i+1|
+
+call sub1("sub1a", (select 7))|
+call sub1("sub1b", (select max(i) from t2))|
+call sub1("sub1c", (select i,d from t2 limit 1))|
+call sub1("sub1d", (select 1 from (select 1) a))|
+#call sub2("sub2");
+select * from t1|
+select sub3((select max(i) from t2))|
+drop procedure sub1|
+#drop procedure sub2|
+drop function sub3|
+
+
+# Basic tests of the flow control constructs
+
+# Just test on 'x'...
+create procedure a0(x int)
+while x do
+ set x = x-1;
+ insert into test.t1 values ("a0", x);
+end while|
+
+call a0(3)|
+select * from t1|
+delete from t1|
+drop procedure a0|
+
+
+# The same, but with a more traditional test.
+create procedure a(x int)
+while x > 0 do
+ set x = x-1;
+ insert into test.t1 values ("a", x);
+end while|
+
+call a(3)|
+select * from t1|
+delete from t1|
+drop procedure a|
+
+
+# REPEAT
+create procedure b(x int)
+repeat
+ insert into test.t1 values (repeat("b",3), x);
+ set x = x-1;
+until x = 0 end repeat|
+
+call b(3)|
+select * from t1|
+delete from t1|
+drop procedure b|
+
+
+# Check that repeat isn't parsed the wrong way
+create procedure b2(x int)
+repeat(select 1 into outfile 'b2');
+ insert into test.t1 values (repeat("b2",3), x);
+ set x = x-1;
+until x = 0 end repeat|
+
+# We don't actually want to call it.
+drop procedure b2|
+
+
+# Labelled WHILE with ITERATE (pointless really)
+create procedure c(x int)
+hmm: while x > 0 do
+ insert into test.t1 values ("c", x);
+ set x = x-1;
+ iterate hmm;
+ insert into test.t1 values ("x", x);
+end while hmm|
+
+call c(3)|
+select * from t1|
+delete from t1|
+drop procedure c|
+
+
+# Labelled WHILE with LEAVE
+create procedure d(x int)
+hmm: while x > 0 do
+ insert into test.t1 values ("d", x);
+ set x = x-1;
+ leave hmm;
+ insert into test.t1 values ("x", x);
+end while hmm|
+
+call d(3)|
+select * from t1|
+delete from t1|
+drop procedure d|
+
+
+# LOOP, with simple IF statement
+create procedure e(x int)
+foo: loop
+ if x = 0 then
+ leave foo;
+ end if;
+ insert into test.t1 values ("e", x);
+ set x = x-1;
+end loop foo|
+
+call e(3)|
+select * from t1|
+delete from t1|
+drop procedure e|
+
+
+# A full IF statement
+create procedure f(x int)
+if x < 0 then
+ insert into test.t1 values ("f", 0);
+elseif x = 0 then
+ insert into test.t1 values ("f", 1);
+else
+ insert into test.t1 values ("f", 2);
+end if|
+
+call f(-2)|
+call f(0)|
+call f(4)|
+select * from t1|
+delete from t1|
+drop procedure f|
+
+
+# This form of CASE is really just syntactic sugar for IF-ELSEIF-...
+create procedure g(x int)
+case
+when x < 0 then
+ insert into test.t1 values ("g", 0);
+when x = 0 then
+ insert into test.t1 values ("g", 1);
+else
+ insert into test.t1 values ("g", 2);
+end case|
+
+call g(-42)|
+call g(0)|
+call g(1)|
+select * from t1|
+delete from t1|
+drop procedure g|
+
+
+# The "simple CASE"
+create procedure h(x int)
+case x
+when 0 then
+ insert into test.t1 values ("h0", x);
+when 1 then
+ insert into test.t1 values ("h1", x);
+else
+ insert into test.t1 values ("h?", x);
+end case|
+
+call h(0)|
+call h(1)|
+call h(17)|
+select * from t1|
+delete from t1|
+drop procedure h|
+
+
+# SELECT INTO local variables
+create procedure into_test(x char(16), y int)
+begin
+ insert into test.t1 values (x, y);
+ select id,data into x,y from test.t1 limit 1;
+ insert into test.t1 values (concat(x, "2"), y+2);
+end|
+
+call into_test("into", 100)|
+select * from t1|
+delete from t1|
+drop procedure into_test|
+
+
+# SELECT INTO with a mix of local and global variables
+create procedure into_test2(x char(16), y int)
+begin
+ insert into test.t1 values (x, y);
+ select id,data into x,@z from test.t1 limit 1;
+ insert into test.t1 values (concat(x, "2"), y+2);
+end|
+
+call into_test2("into", 100)|
+select id,data,@z from t1|
+delete from t1|
+drop procedure into_test2|
+
+
+# These two (and the two procedures above) caused an assert() to fail in
+# sql_base.cc:lock_tables() at some point.
+
+create procedure into_outfile(x char(16), y int)
+begin
+ insert into test.t1 values (x, y);
+ select * into outfile "/tmp/spout" from test.t1;
+ insert into test.t1 values (concat(x, "2"), y+2);
+end|
+
+system rm -f /tmp/spout|
+call into_outfile("ofile", 1)|
+system rm -f /tmp/spout|
+delete from t1|
+drop procedure into_outfile|
+
+create procedure into_dumpfile(x char(16), y int)
+begin
+ insert into test.t1 values (x, y);
+ select * into dumpfile "/tmp/spdump" from test.t1 limit 1;
+ insert into test.t1 values (concat(x, "2"), y+2);
+end|
+
+system rm -f /tmp/spdump|
+call into_dumpfile("dfile", 1)|
+system rm -f /tmp/spdump|
+delete from t1|
+drop procedure into_dumpfile|
+
+
+create procedure create_select(x char(16), y int)
+begin
+ insert into test.t1 values (x, y);
+ create table test.t3 select * from test.t1;
+ insert into test.t3 values (concat(x, "2"), y+2);
+end|
+
+--disable_warnings
+drop table if exists t3|
+--enable_warnings
+call create_select("cs", 90)|
+select * from t1, t3|
+--disable_warnings
+drop table if exists t3|
+--enable_warnings
+delete from t1|
+drop procedure create_select|
+
+
+# A minimal, constant FUNCTION.
+create function e() returns double
+ return 2.7182818284590452354|
+
+set @e = e()|
+select e(), @e|
+
+# A minimal function with one argument
+create function inc(i int) returns int
+ return i+1|
+
+select inc(1), inc(99), inc(-71)|
+
+# A minimal function with two arguments
+create function mul(x int, y int) returns int
+ return x*y|
+
+select mul(1,1), mul(3,5), mul(4711, 666)|
+
+# A minimal string function
+create function append(s1 char(8), s2 char(8)) returns char(16)
+ return concat(s1, s2)|
+
+select append("foo", "bar")|
+
+# A function with flow control
+create function fac(n int unsigned) returns bigint unsigned
+begin
+ declare f bigint unsigned default 1;
+
+ while n > 1 do
+ set f = f * n;
+ set n = n - 1;
+ end while;
+ return f;
+end|
+
+select fac(1), fac(2), fac(5), fac(10)|
+
+# Nested calls
+create function fun(d double, i int, u int unsigned) returns double
+ return mul(inc(i), fac(u)) / e()|
+
+select fun(2.3, 3, 5)|
+
+
+# Various function calls in differen statements
+
+insert into t2 values (append("xxx", "yyy"), mul(4,3), e())|
+insert into t2 values (append("a", "b"), mul(2,mul(3,4)), fun(1.7, 4, 6))|
+
+# These don't work yet.
+select * from t2 where s = append("a", "b")|
+select * from t2 where i = mul(4,3) or i = mul(mul(3,4),2)|
+select * from t2 where d = e()|
+select * from t2|
+delete from t2|
+
+drop function e|
+drop function inc|
+drop function mul|
+drop function append|
+drop function fun|
+
+
+#
+# Some "real" examples
+#
+
+# fac
+
+--disable_warnings
+drop table if exists fac|
+--enable_warnings
+create table fac (n int unsigned not null primary key, f bigint unsigned)|
+
+create procedure ifac(n int unsigned)
+begin
+ declare i int unsigned default 1;
+
+ if n > 20 then
+ set n = 20; # bigint overflow otherwise
+ end if;
+ while i <= n do
+ begin
+ insert into test.fac values (i, fac(i));
+ set i = i + 1;
+ end;
+ end while;
+end|
+
+call ifac(20)|
+select * from fac|
+drop table fac|
+drop procedure ifac|
+drop function fac|
+
+
+# primes
+
+--disable_warnings
+drop table if exists primes|
+--enable_warnings
+
+create table primes (
+ i int unsigned not null primary key,
+ p bigint unsigned not null
+)|
+
+insert into primes values
+ ( 0, 3), ( 1, 5), ( 2, 7), ( 3, 11), ( 4, 13),
+ ( 5, 17), ( 6, 19), ( 7, 23), ( 8, 29), ( 9, 31),
+ (10, 37), (11, 41), (12, 43), (13, 47), (14, 53),
+ (15, 59), (16, 61), (17, 67), (18, 71), (19, 73),
+ (20, 79), (21, 83), (22, 89), (23, 97), (24, 101),
+ (25, 103), (26, 107), (27, 109), (28, 113), (29, 127),
+ (30, 131), (31, 137), (32, 139), (33, 149), (34, 151),
+ (35, 157), (36, 163), (37, 167), (38, 173), (39, 179),
+ (40, 181), (41, 191), (42, 193), (43, 197), (44, 199)|
+
+create procedure opp(n bigint unsigned, out pp bool)
+begin
+ declare r double;
+ declare b, s bigint unsigned default 0;
+
+ set r = sqrt(n);
+
+ again:
+ loop
+ if s = 45 then
+ set b = b+200, s = 0;
+ else
+ begin
+ declare p bigint unsigned;
+
+ select t.p into p from test.primes t where t.i = s;
+ if b+p > r then
+ set pp = 1;
+ leave again;
+ end if;
+ if mod(n, b+p) = 0 then
+ set pp = 0;
+ leave again;
+ end if;
+ set s = s+1;
+ end;
+ end if;
+ end loop again;
+end|
+
+create procedure ip(m int unsigned)
+begin
+ declare p bigint unsigned;
+ declare i int unsigned;
+
+ set i=45, p=201;
+
+ while i < m do
+ begin
+ declare pp bool default 0;
+
+ call opp(p, pp);
+ if pp then
+ insert into test.primes values (i, p);
+ set i = i+1;
+ end if;
+ set p = p+2;
+ end;
+ end while;
+end|
+
+# This isn't the fastest way in the world to compute prime numbers, so
+# don't be too ambitious. ;-)
+call ip(200)|
+# We don't want to select the entire table here, just pick a few
+# examples.
+select * from primes where i=45 or i=100 or i=199|
+drop table primes|
+drop procedure opp|
+drop procedure ip|
+
+delimiter ;|
+drop table t1;
+drop table t2;
diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test
index 66d8dd2bc32..afa07d91545 100644
--- a/mysql-test/t/subselect.test
+++ b/mysql-test/t/subselect.test
@@ -351,7 +351,6 @@ INSERT DELAYED INTO t1 (x) VALUES ((SELECT SUM(a) FROM t2));
select * from t1;
INSERT INTO t1 (x) select (SELECT SUM(a)+1 FROM t2) FROM t2;
select * from t1;
--- error 1093
INSERT INTO t1 (x) select (SELECT SUM(x)+2 FROM t1) FROM t2;
-- error 1054
INSERT DELAYED INTO t1 (x) VALUES ((SELECT SUM(x) FROM t2));
@@ -503,6 +502,9 @@ select ROW(1, 1, 'a') IN (select b,a,c from t1 where c='b' or c='a');
select ROW(1, 1, 'a') IN (select b,a,c from t1 limit 2);
drop table t1;
+#
+# DO & SET
+#
create table t1 (a int);
insert into t1 values (1);
do @a:=(SELECT a from t1);
@@ -516,6 +518,7 @@ do (SELECT a from t1);
-- error 1146
set @a:=(SELECT a from t1);
+
CREATE TABLE t1 (a int, KEY(a));
HANDLER t1 OPEN;
-- error 1149
diff --git a/mysql-test/t/variables.test b/mysql-test/t/variables.test
index 7d4b25df0eb..3258950421f 100644
--- a/mysql-test/t/variables.test
+++ b/mysql-test/t/variables.test
@@ -5,8 +5,20 @@
drop table if exists t1,t2;
--enable_warnings
-set @`test`=1,@TEST=3,@select=2,@t5=1.23456;
-select @test,@`select`,@TEST,@not_used;
+# case insensitivity tests (new in 5.0)
+set @`test`=1;
+select @test, @`test`, @TEST, @`TEST`, @"teSt";
+set @TEST=2;
+select @test, @`test`, @TEST, @`TEST`, @"teSt";
+set @"tEST"=3;
+select @test, @`test`, @TEST, @`TEST`, @"teSt";
+set @`TeST`=4;
+select @test, @`test`, @TEST, @`TEST`, @"teSt";
+select @`teST`:=5;
+select @test, @`test`, @TEST, @`TEST`, @"teSt";
+
+set @select=2,@t5=1.23456;
+select @`select`,@not_used;
set @test_int=10,@test_double=1e-10,@test_string="abcdeghi",@test_string2="abcdefghij",@select=NULL;
select @test_int,@test_double,@test_string,@test_string2,@select;
set @test_int="hello",@test_double="hello",@test_string="hello",@test_string2="hello";