mirror of
				https://github.com/MariaDB/server.git
				synced 2025-10-24 07:13:33 +03:00 
			
		
		
		
	
		
			
				
	
	
		
			1550 lines
		
	
	
		
			42 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			1550 lines
		
	
	
		
			42 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
| #
 | ||
| # SQL Syntax for Prepared Statements test
 | ||
| #
 | ||
| --disable_warnings
 | ||
| drop table if exists t1,t2;
 | ||
| 
 | ||
| # Avoid wrong warnings if mysql_client_test fails
 | ||
| drop database if exists client_test_db;
 | ||
| --enable_warnings
 | ||
| 
 | ||
| create table t1
 | ||
| (
 | ||
|   a int primary key,
 | ||
|   b char(10)
 | ||
| );
 | ||
| insert into t1 values (1,'one');
 | ||
| insert into t1 values (2,'two');
 | ||
| insert into t1 values (3,'three');
 | ||
| insert into t1 values (4,'four');
 | ||
| 
 | ||
| # basic functionality
 | ||
| set @a=2;
 | ||
| prepare stmt1 from 'select * from t1 where a <= ?';
 | ||
| execute stmt1 using @a;
 | ||
| set @a=3;
 | ||
| execute stmt1 using @a;
 | ||
| 
 | ||
| # non-existant statement
 | ||
| --error 1243
 | ||
| deallocate prepare no_such_statement;
 | ||
| 
 | ||
| --error 1210
 | ||
| execute stmt1;
 | ||
| 
 | ||
| # Nesting ps commands is not allowed: 
 | ||
| --error 1064
 | ||
| prepare stmt2 from 'prepare nested_stmt from "select 1"';
 | ||
| 
 | ||
| --error 1064
 | ||
| prepare stmt2 from 'execute stmt1';
 | ||
| 
 | ||
| --error 1064
 | ||
| prepare stmt2 from 'deallocate prepare z';
 | ||
| 
 | ||
| # PS insert 
 | ||
| prepare stmt3 from 'insert into t1 values (?,?)';
 | ||
| set @arg1=5, @arg2='five';
 | ||
| execute stmt3 using @arg1, @arg2;
 | ||
| select * from t1 where a>3;
 | ||
| 
 | ||
| # PS update 
 | ||
| prepare stmt4 from 'update t1 set a=? where b=?';
 | ||
| set @arg1=55, @arg2='five';
 | ||
| execute stmt4 using @arg1, @arg2;
 | ||
| select * from t1 where a>3;
 | ||
| 
 | ||
| # PS create/delete
 | ||
| prepare stmt4 from 'create table t2 (a int)';
 | ||
| execute stmt4;
 | ||
| prepare stmt4 from 'drop table t2';
 | ||
| execute stmt4;
 | ||
| 
 | ||
| # Do something that will cause error
 | ||
| --error 1051
 | ||
| execute stmt4;
 | ||
| 
 | ||
| # placeholders in result field names.
 | ||
| prepare stmt5 from 'select ? + a from t1';
 | ||
| set @a=1;
 | ||
| execute stmt5 using @a;
 | ||
| 
 | ||
| execute stmt5 using @no_such_var;
 | ||
| 
 | ||
| set @nullvar=1;
 | ||
| set @nullvar=NULL;
 | ||
| execute stmt5 using @nullvar;
 | ||
| 
 | ||
| set @nullvar2=NULL;
 | ||
| execute stmt5 using @nullvar2;
 | ||
| 
 | ||
| # Check that multiple SQL statements are disabled inside PREPARE
 | ||
| --error 1064
 | ||
| prepare stmt6 from 'select 1; select2';
 | ||
| 
 | ||
| --error 1064
 | ||
| prepare stmt6 from 'insert into t1 values (5,"five"); select2';
 | ||
| 
 | ||
| # This shouldn't parse
 | ||
| --error 1064
 | ||
| explain prepare stmt6 from 'insert into t1 values (5,"five"); select2';
 | ||
| 
 | ||
| create table t2
 | ||
| (
 | ||
|   a int
 | ||
| );
 | ||
| 
 | ||
| insert into t2 values (0);
 | ||
| 
 | ||
| # parameter is NULL
 | ||
| set @arg00=NULL ;
 | ||
| prepare stmt1 from 'select 1 FROM t2 where a=?' ;
 | ||
| execute stmt1 using @arg00 ;
 | ||
| 
 | ||
| # prepare using variables:
 | ||
| --error 1064
 | ||
| prepare stmt1 from @nosuchvar;
 | ||
| 
 | ||
| set @ivar= 1234;
 | ||
| --error 1064
 | ||
| prepare stmt1 from @ivar;
 | ||
| 
 | ||
| set @fvar= 123.4567;
 | ||
| --error 1064
 | ||
| prepare stmt1 from @fvar;
 | ||
| 
 | ||
| drop table t1,t2;
 | ||
| deallocate prepare stmt3;
 | ||
| deallocate prepare stmt4;
 | ||
| deallocate prepare stmt5;
 | ||
| 
 | ||
| #
 | ||
| # Bug #4105: Server crash on attempt to prepare a statement with character
 | ||
| # set introducer
 | ||
| #
 | ||
| PREPARE stmt1 FROM "select _utf8 'A' collate utf8_bin = ?";
 | ||
| set @var='A';
 | ||
| EXECUTE stmt1 USING @var;
 | ||
| DEALLOCATE PREPARE stmt1;
 | ||
| 
 | ||
| #
 | ||
| # BUG#3486:  FOUND_ROWS() fails inside stored procedure [and prepared statement]
 | ||
| #
 | ||
| create table t1 (id int);
 | ||
| prepare stmt1 from "select FOUND_ROWS()";
 | ||
| select SQL_CALC_FOUND_ROWS * from t1;
 | ||
| # Expect 0
 | ||
| execute stmt1;
 | ||
| insert into t1 values (1);
 | ||
| select SQL_CALC_FOUND_ROWS * from t1;
 | ||
| # Expect 1
 | ||
| execute stmt1;
 | ||
| # Expect 0
 | ||
| execute stmt1;
 | ||
| deallocate prepare stmt1;
 | ||
| drop table t1;
 | ||
| 
 | ||
| #
 | ||
| # prepared EXPLAIN
 | ||
| #
 | ||
| create table t1 
 | ||
| (
 | ||
|   c1  tinyint, c2  smallint, c3  mediumint, c4  int,
 | ||
|   c5  integer, c6  bigint, c7  float, c8  double,
 | ||
|   c9  double precision, c10 real, c11 decimal(7, 4), c12 numeric(8, 4),
 | ||
|   c13 date, c14 datetime, c15 timestamp, c16 time,
 | ||
|   c17 year, c18 bit, c19 bool, c20 char,
 | ||
|   c21 char(10), c22 varchar(30), c23 tinyblob, c24 tinytext,
 | ||
|   c25 blob, c26 text, c27 mediumblob, c28 mediumtext,
 | ||
|   c29 longblob, c30 longtext, c31 enum('one', 'two', 'three'),
 | ||
|   c32 set('monday', 'tuesday', 'wednesday')
 | ||
| ) engine = MYISAM ;
 | ||
| create table t2 like t1;
 | ||
| 
 | ||
| set @stmt= ' explain SELECT (SELECT SUM(c1 + c12 + 0.0) FROM t2 where (t1.c2 - 0e-3) = t2.c2 GROUP BY t1.c15 LIMIT 1) as scalar_s, exists (select 1.0e+0 from t2 where t2.c3 * 9.0000000000 = t1.c4) as exists_s, c5 * 4 in (select c6 + 0.3e+1 from t2) as in_s, (c7 - 4, c8 - 4) in (select c9 + 4.0, c10 + 40e-1 from t2) as in_row_s FROM t1, (select c25 x, c32 y from t2) tt WHERE x * 1 = c25 ' ;
 | ||
| prepare stmt1 from @stmt ;
 | ||
| execute stmt1 ;
 | ||
| execute stmt1 ;
 | ||
| explain SELECT (SELECT SUM(c1 + c12 + 0.0) FROM t2 where (t1.c2 - 0e-3) = t2.c2 GROUP BY t1.c15 LIMIT 1) as scalar_s, exists (select 1.0e+0 from t2 where t2.c3 * 9.0000000000 = t1.c4) as exists_s, c5 * 4 in (select c6 + 0.3e+1 from t2) as in_s, (c7 - 4, c8 - 4) in (select c9 + 4.0, c10 + 40e-1 from t2) as in_row_s FROM t1, (select c25 x, c32 y from t2) tt WHERE x * 1 = c25;
 | ||
| deallocate prepare stmt1;
 | ||
| drop tables t1,t2;
 | ||
| 
 | ||
| #
 | ||
| # parameters from variables (for field creation)
 | ||
| #
 | ||
| set @arg00=1;
 | ||
| prepare stmt1 from ' create table t1 (m int) as select 1 as m ' ;
 | ||
| execute stmt1 ;
 | ||
| select m from t1;
 | ||
| drop table t1;
 | ||
| prepare stmt1 from ' create table t1 (m int) as select ? as m ' ;
 | ||
| execute stmt1 using @arg00;
 | ||
| select m from t1;
 | ||
| deallocate prepare stmt1;
 | ||
| drop table t1;
 | ||
| 
 | ||
| #
 | ||
| # eq() for parameters
 | ||
| #
 | ||
| create table t1 (id int(10) unsigned NOT NULL default '0',
 | ||
|                  name varchar(64) NOT NULL default '',
 | ||
|                  PRIMARY KEY  (id), UNIQUE KEY `name` (`name`));
 | ||
| insert into t1 values (1,'1'),(2,'2'),(3,'3'),(4,'4'),(5,'5'),(6,'6'),(7,'7');
 | ||
| prepare stmt1 from 'select name from t1 where id=? or id=?';
 | ||
| set @id1=1,@id2=6;
 | ||
| execute stmt1 using @id1, @id2;
 | ||
| select name from t1 where id=1 or id=6;
 | ||
| deallocate prepare stmt1;
 | ||
| drop table t1;
 | ||
| 
 | ||
| #
 | ||
| # SHOW TABLE STATUS test
 | ||
| #
 | ||
| create table t1 ( a int primary key, b varchar(30)) engine = MYISAM ;
 | ||
| prepare stmt1 from ' show table status from test like ''t1%'' ';
 | ||
| --replace_column 8 4294967295 12 # 13 # 14 #
 | ||
| execute stmt1;
 | ||
| --replace_column 8 4294967295 12 # 13 # 14 #
 | ||
| show table status from test like 't1%' ;
 | ||
| deallocate prepare stmt1 ;
 | ||
| drop table t1;
 | ||
| 
 | ||
| #
 | ||
| # Bug#4912 "mysqld crashs in case a statement is executed a second time":
 | ||
| # negation elimination should work once and not break prepared statements
 | ||
| # 
 | ||
| 
 | ||
| create table t1(a varchar(2), b varchar(3));
 | ||
| prepare stmt1 from "select a, b from t1 where (not (a='aa' and b < 'zzz'))";
 | ||
| execute stmt1;
 | ||
| execute stmt1;
 | ||
| deallocate prepare stmt1;
 | ||
| drop table t1;
 | ||
| 
 | ||
| #
 | ||
| # Bug#5034 "prepared "select 1 into @arg15", second execute crashes
 | ||
| # server".
 | ||
| # Check that descendands of select_result can be reused in prepared 
 | ||
| # statements or are correctly created and deleted on each execute
 | ||
| #
 | ||
| 
 | ||
| prepare stmt1 from "select 1 into @var";
 | ||
| execute stmt1;
 | ||
| execute stmt1;
 | ||
| prepare stmt1 from "create table t1 select 1 as i";
 | ||
| execute stmt1;
 | ||
| drop table t1;
 | ||
| execute stmt1;
 | ||
| prepare stmt1 from "insert into t1 select i from t1";
 | ||
| execute stmt1;
 | ||
| execute stmt1;
 | ||
| prepare stmt1 from "select * from t1 into outfile 'f1.txt'";
 | ||
| execute stmt1;
 | ||
| deallocate prepare stmt1;
 | ||
| drop table t1;
 | ||
| 
 | ||
| # 
 | ||
| # BUG#5242 "Prepared statement names are case sensitive"
 | ||
| #
 | ||
| prepare stmt1 from 'select 1';
 | ||
| prepare STMT1 from 'select 2';
 | ||
| execute sTmT1;
 | ||
| deallocate prepare StMt1;
 | ||
| 
 | ||
| --error 1243
 | ||
| deallocate prepare Stmt1;
 | ||
| 
 | ||
| # also check that statement names are in right charset.
 | ||
| set names utf8;
 | ||
| prepare `ü` from 'select 1234';
 | ||
| execute `ü` ;
 | ||
| set names latin1;
 | ||
| execute `<60>`;
 | ||
| deallocate prepare `<60>`;
 | ||
| set names default;
 | ||
| 
 | ||
| 
 | ||
| # 
 | ||
| # BUG#4368 "select * from t1 where a like ?" crashes server if a is in utf8
 | ||
| # and ? is in latin1
 | ||
| # Check that Item converting latin1 to utf8 (for LIKE function) is created
 | ||
| # in memory of prepared statement.
 | ||
| #
 | ||
| 
 | ||
| create table t1 (a varchar(10)) charset=utf8;
 | ||
| insert into t1 (a) values ('yahoo');
 | ||
| set character_set_connection=latin1;
 | ||
| prepare stmt from 'select a from t1 where a like ?';
 | ||
| set @var='google';
 | ||
| execute stmt using @var;
 | ||
| execute stmt using @var;
 | ||
| deallocate prepare stmt;
 | ||
| drop table t1;
 | ||
| 
 | ||
| # 
 | ||
| # BUG#5510 "inserting Null in AutoIncrement primary key Column Fails" 
 | ||
| # (prepared statements) 
 | ||
| # The cause: misuse of internal MySQL 'Field' API.
 | ||
| # 
 | ||
| 
 | ||
| create table t1 (a bigint(20) not null primary key auto_increment);
 | ||
| insert into t1 (a) values (null);
 | ||
| select * from t1;
 | ||
| prepare stmt from "insert into t1 (a) values (?)";
 | ||
| set @var=null;
 | ||
| execute stmt using @var;
 | ||
| select * from t1;
 | ||
| drop table t1;
 | ||
| #
 | ||
| # check the same for timestamps
 | ||
| #
 | ||
| create table t1 (a timestamp not null);
 | ||
| prepare stmt from "insert into t1 (a) values (?)";
 | ||
| execute stmt using @var;
 | ||
| --disable_result_log
 | ||
| select * from t1;
 | ||
| --enable_result_log
 | ||
| deallocate prepare stmt;
 | ||
| drop table t1;
 | ||
| 
 | ||
| # 
 | ||
| # BUG#5688 "Upgraded 4.1.5 Server seg faults" # (prepared statements)
 | ||
| # The test case speaks for itself.
 | ||
| # Just another place where we used wrong memory root for Items created
 | ||
| # during statement prepare.
 | ||
| # 
 | ||
| prepare stmt from "select 'abc' like convert('abc' using utf8)";
 | ||
| execute stmt;
 | ||
| execute stmt;
 | ||
| deallocate prepare stmt;
 | ||
| 
 | ||
| # 
 | ||
| # BUG#5748 "Prepared statement with BETWEEN and bigint values crashes
 | ||
| # mysqld". Just another place where an item tree modification must be 
 | ||
| # rolled back.
 | ||
| # 
 | ||
| create table t1 ( a bigint );
 | ||
| prepare stmt from 'select a from t1 where a between ? and ?';
 | ||
| set @a=1;
 | ||
| execute stmt using @a, @a;
 | ||
| execute stmt using @a, @a;
 | ||
| execute stmt using @a, @a;
 | ||
| drop table t1;
 | ||
| deallocate prepare stmt;
 | ||
| 
 | ||
| #
 | ||
| # Bug #5987 subselect in bool function crashes server (prepared statements):
 | ||
| # don't overwrite transformed subselects with old arguments of a bool
 | ||
| # function.
 | ||
| #
 | ||
| create table t1 (a int);
 | ||
| prepare stmt from "select * from t1 where 1 > (1 in (SELECT * FROM t1))";
 | ||
| execute stmt;
 | ||
| execute stmt;
 | ||
| execute stmt;
 | ||
| drop table t1;
 | ||
| deallocate prepare stmt;
 | ||
| 
 | ||
| #
 | ||
| # Test case for Bug#6042 "constants propogation works only once (prepared
 | ||
| # statements): check that the query plan changes whenever we change
 | ||
| # placeholder value.
 | ||
| #
 | ||
| create table t1 (a int, b int);
 | ||
| insert into t1 (a, b) values (1,1), (1,2), (2,1), (2,2);
 | ||
| prepare stmt from
 | ||
| "explain select * from t1 where t1.a=2 and t1.a=t1.b and t1.b > 1 + ?";
 | ||
| set @v=5;
 | ||
| --replace_column 1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 -
 | ||
| execute stmt using @v;
 | ||
| set @v=0;
 | ||
| --replace_column 1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 -
 | ||
| execute stmt using @v;
 | ||
| set @v=5;
 | ||
| --replace_column 1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 -
 | ||
| execute stmt using @v;
 | ||
| drop table t1;
 | ||
| deallocate prepare stmt;
 | ||
| 
 | ||
| #
 | ||
| # A test case for Bug#5985 prepare stmt from "select rand(?)" crashes
 | ||
| # server. Check that Item_func_rand is prepared-statements friendly.
 | ||
| #
 | ||
| create table t1 (a int);
 | ||
| insert into t1 (a) values (1), (2), (3), (4);
 | ||
| set @precision=10000000000;
 | ||
| --replace_column 1 - 3 -
 | ||
| select rand(), 
 | ||
|        cast(rand(10)*@precision as unsigned integer) from t1;
 | ||
| prepare stmt from
 | ||
| "select rand(), 
 | ||
|         cast(rand(10)*@precision as unsigned integer),
 | ||
|         cast(rand(?)*@precision as unsigned integer) from t1";
 | ||
| set @var=1;
 | ||
| --replace_column 1 - 3 -
 | ||
| execute stmt using @var;
 | ||
| set @var=2;
 | ||
| --replace_column 1 -
 | ||
| execute stmt using @var;
 | ||
| set @var=3;
 | ||
| --replace_column 1 -
 | ||
| execute stmt using @var;
 | ||
| drop table t1;
 | ||
| deallocate prepare stmt;
 | ||
| 
 | ||
| #
 | ||
| # A test case for Bug#6050 "EXECUTE stmt reports ambiguous fieldnames with
 | ||
| # identical tables from different schemata"
 | ||
| # Check that field name resolving in prepared statements works OK.
 | ||
| #
 | ||
| create database mysqltest1;
 | ||
| create table t1 (a int);
 | ||
| create table mysqltest1.t1 (a int);
 | ||
| select * from t1, mysqltest1.t1;
 | ||
| prepare stmt from "select * from t1, mysqltest1.t1";
 | ||
| execute stmt;
 | ||
| execute stmt;
 | ||
| execute stmt;
 | ||
| drop table t1;
 | ||
| drop table mysqltest1.t1;
 | ||
| drop database mysqltest1;
 | ||
| deallocate prepare stmt; 
 | ||
| select '1.1' as a, '1.2' as a UNION SELECT '2.1', '2.2';
 | ||
| prepare stmt from
 | ||
| "select '1.1' as a, '1.2' as a UNION SELECT '2.1', '2.2'";
 | ||
| execute stmt;
 | ||
| execute stmt;
 | ||
| execute stmt;
 | ||
| deallocate prepare stmt;
 | ||
| 
 | ||
| #
 | ||
| # Test CREATE TABLE ... SELECT (Bug #6094)
 | ||
| #
 | ||
| create table t1 (a int); 
 | ||
| insert into t1 values (1),(2),(3);
 | ||
| create table t2 select * from t1;
 | ||
| prepare stmt FROM 'create table t2 select * from t1';
 | ||
| drop table t2;
 | ||
| execute stmt;
 | ||
| drop table t2;
 | ||
| execute stmt;
 | ||
| --error 1050
 | ||
| execute stmt;
 | ||
| drop table t2;
 | ||
| execute stmt;
 | ||
| drop table t1,t2;
 | ||
| deallocate prepare stmt;
 | ||
| 
 | ||
| #
 | ||
| # Bug#6088 "FOUND_ROWS returns wrong values for prepared statements when
 | ||
| # LIMIT is used"
 | ||
| # 
 | ||
| create table t1 (a int);
 | ||
| insert into t1 (a) values (1), (2), (3), (4), (5), (6), (7), (8), (9), (10);
 | ||
| prepare stmt from "select sql_calc_found_rows * from t1 limit 2";
 | ||
| execute stmt;
 | ||
| select found_rows();
 | ||
| execute stmt;
 | ||
| select found_rows();
 | ||
| execute stmt;
 | ||
| select found_rows();
 | ||
| deallocate prepare stmt;
 | ||
| drop table t1;
 | ||
| 
 | ||
| #
 | ||
| # Bug#6047 "permission problem when executing mysql_stmt_execute with derived
 | ||
| # table"
 | ||
| #
 | ||
| 
 | ||
| CREATE TABLE t1 (N int, M tinyint); 
 | ||
| INSERT INTO t1 VALUES (1,0),(1,0),(2,0),(2,0),(3,0);
 | ||
| PREPARE stmt FROM 'UPDATE t1 AS P1 INNER JOIN (SELECT N FROM t1 GROUP BY N HAVING COUNT(M) > 1) AS P2 ON P1.N = P2.N SET P1.M = 2';
 | ||
| EXECUTE stmt;
 | ||
| DEALLOCATE PREPARE stmt;
 | ||
| DROP TABLE t1;
 | ||
| 
 | ||
| # 
 | ||
| # Bug#6297 "prepared statement, wrong handling of <parameter> IS NULL"
 | ||
| # Test that placeholders work with IS NULL/IS NOT NULL clauses. 
 | ||
| #
 | ||
| prepare stmt from "select ? is null, ? is not null, ?";
 | ||
| select @no_such_var is null, @no_such_var is not null, @no_such_var;
 | ||
| execute stmt using @no_such_var, @no_such_var, @no_such_var;
 | ||
| set @var='abc';
 | ||
| select @var is null, @var is not null, @var;
 | ||
| execute stmt using @var, @var, @var;
 | ||
| set @var=null;
 | ||
| select @var is null, @var is not null, @var;
 | ||
| execute stmt using @var, @var, @var;
 | ||
| 
 | ||
| # 
 | ||
| # Bug#6873 "PS, having with subquery, crash during execute"
 | ||
| # check that if we modify having subtree, we update JOIN->having pointer
 | ||
| #
 | ||
| create table t1 (pnum char(3));
 | ||
| create table t2 (pnum char(3));
 | ||
| prepare stmt from "select pnum from t2 having pnum in (select 'p1' from t1)";
 | ||
| execute stmt;
 | ||
| execute stmt;
 | ||
| execute stmt;
 | ||
| deallocate prepare stmt;
 | ||
| drop table t1, t2;
 | ||
| 
 | ||
| #
 | ||
| #
 | ||
| # Bug#19399 "Stored Procedures 'Lost Connection' when dropping/creating
 | ||
| #            tables"
 | ||
| # Check that multi-delete tables are also cleaned up before re-execution.
 | ||
| # 
 | ||
| --disable_warnings
 | ||
| drop table if exists t1;
 | ||
| create temporary table if not exists t1 (a1 int);
 | ||
| --enable_warnings
 | ||
| # exact delete syntax is essential
 | ||
| prepare stmt from "delete t1 from t1 where (cast(a1/3 as unsigned) * 3) = a1";
 | ||
| drop temporary table t1;
 | ||
| create temporary table if not exists t1 (a1 int);
 | ||
| # the server crashed on  the next statement without the fix
 | ||
| execute stmt;
 | ||
| drop temporary table t1;
 | ||
| create temporary table if not exists t1 (a1 int);
 | ||
| # the problem was in memory corruption: repeat the test just in case
 | ||
| execute stmt;
 | ||
| drop temporary table t1;
 | ||
| create temporary table if not exists t1 (a1 int);
 | ||
| execute stmt;
 | ||
| drop temporary table t1;
 | ||
| deallocate prepare stmt;
 | ||
| 
 | ||
| # Bug#6102 "Server crash with prepared statement and blank after
 | ||
| # function name"
 | ||
| # ensure that stored functions are cached when preparing a statement
 | ||
| # before we open tables
 | ||
| #
 | ||
| create table t1 (a varchar(20)); 
 | ||
| insert into t1 values ('foo'); 
 | ||
| --error 1305
 | ||
| prepare stmt FROM 'SELECT char_length (a) FROM t1'; 
 | ||
| drop table t1;
 | ||
| 
 | ||
| #
 | ||
| # Bug #6089: FOUND_ROWS returns wrong values when no table/view is used 
 | ||
| #
 | ||
| 
 | ||
| prepare stmt from "SELECT SQL_CALC_FOUND_ROWS 'foo' UNION SELECT 'bar' LIMIT 0";
 | ||
| execute stmt;
 | ||
| SELECT FOUND_ROWS();
 | ||
| execute stmt;                                                                   
 | ||
| SELECT FOUND_ROWS();                                                            
 | ||
| deallocate prepare stmt;
 | ||
| 
 | ||
| #
 | ||
| # Bug#9096 "select doesn't return all matched records if prepared statements
 | ||
| # is used"
 | ||
| # The bug was is bad co-operation of the optimizer's algorithm which determines
 | ||
| # which keys can be used to execute a query, constants propagation
 | ||
| # part of the optimizer and parameter markers used by prepared statements.
 | ||
| 
 | ||
| drop table if exists t1;
 | ||
| create table t1 (c1 int(11) not null, c2 int(11) not null,
 | ||
|              primary key  (c1,c2), key c2 (c2), key c1 (c1));
 | ||
| 
 | ||
| insert into t1 values (200887, 860);
 | ||
| insert into t1 values (200887, 200887);
 | ||
| 
 | ||
| select * from t1 where (c1=200887 and c2=200887) or c2=860;
 | ||
| 
 | ||
| prepare stmt from
 | ||
| "select * from t1 where (c1=200887 and c2=200887) or c2=860";
 | ||
| execute stmt;
 | ||
| prepare stmt from
 | ||
| "select * from t1 where (c1=200887 and c2=?) or c2=?";
 | ||
| set @a=200887, @b=860;
 | ||
| # this query did not return all matching rows
 | ||
| execute stmt using @a, @b;
 | ||
| deallocate prepare stmt;
 | ||
| 
 | ||
| drop table t1;
 | ||
| 
 | ||
| #
 | ||
| # Bug#9777 - another occurrence of the problem stated in Bug#9096:
 | ||
| # we can not compare basic constants by their names, because a placeholder
 | ||
| # is a basic constant while his name is always '?'
 | ||
| #
 | ||
| 
 | ||
| create table t1 (
 | ||
|    id bigint(20) not null auto_increment,
 | ||
|    code varchar(20) character set utf8 collate utf8_bin not null default '',
 | ||
|    company_name varchar(250) character set utf8 collate utf8_bin default null,
 | ||
|    setup_mode tinyint(4) default null,
 | ||
|    start_date datetime default null,
 | ||
|    primary key  (id), unique key code (code)
 | ||
| );
 | ||
| 
 | ||
| create table t2 (
 | ||
|    id bigint(20) not null auto_increment,
 | ||
|    email varchar(250) character set utf8 collate utf8_bin default null,
 | ||
|    name varchar(250) character set utf8 collate utf8_bin default null,
 | ||
|    t1_id bigint(20) default null,
 | ||
|    password varchar(250) character set utf8 collate utf8_bin default null,
 | ||
|    primary_contact tinyint(4) not null default '0',
 | ||
|    email_opt_in tinyint(4) not null default '1',
 | ||
|    primary key  (id), unique key email (email), key t1_id (t1_id),
 | ||
|    constraint t2_fk1 foreign key (t1_id) references t1 (id)
 | ||
| );
 | ||
| 
 | ||
| insert into t1 values
 | ||
| (1, 'demo', 'demo s', 0, current_date()),
 | ||
| (2, 'code2', 'name 2', 0, current_date()),
 | ||
| (3, 'code3', 'name 3', 0, current_date());
 | ||
| 
 | ||
| insert into t2 values
 | ||
| (2, 'email1', 'name1', 3, 'password1', 0, 0),
 | ||
| (3, 'email2', 'name1', 1, 'password2', 1, 0),
 | ||
| (5, 'email3', 'name3', 2, 'password3', 0, 0);
 | ||
| 
 | ||
| prepare stmt from 'select t2.id from t2, t1 where (t1.id=? and t2.t1_id=t1.id)';
 | ||
| set @a=1;
 | ||
| execute stmt using @a;
 | ||
| 
 | ||
| select t2.id from t2, t1 where (t1.id=1 and t2.t1_id=t1.id);
 | ||
| 
 | ||
| deallocate prepare stmt;
 | ||
| drop table t1, t2;
 | ||
| 
 | ||
| #
 | ||
| # Bug#11060 "Server crashes on calling stored procedure with INSERT SELECT
 | ||
| # UNION SELECT" aka "Server crashes on re-execution of prepared INSERT ...
 | ||
| # SELECT with UNION".
 | ||
| #
 | ||
| create table t1 (id int);
 | ||
| prepare stmt from "insert into t1 (id) select id from t1 union select id from t1";
 | ||
| execute stmt;
 | ||
| execute stmt;
 | ||
| deallocate prepare stmt;
 | ||
| drop table t1;
 | ||
| #
 | ||
| # Bug#11458 "Prepared statement with subselects return random data":
 | ||
| # drop PARAM_TABLE_BIT from the list of tables used by a subquery
 | ||
| #
 | ||
| create table t1 (
 | ||
|   id int(11) unsigned not null primary key auto_increment,
 | ||
|   partner_id varchar(35) not null,
 | ||
|   t1_status_id int(10) unsigned
 | ||
| );
 | ||
| 
 | ||
| insert into t1 values ("1", "partner1", "10"), ("2", "partner2", "10"),
 | ||
|                       ("3", "partner3", "10"), ("4", "partner4", "10");
 | ||
| 
 | ||
| create table t2 (
 | ||
|   id int(11) unsigned not null default '0',
 | ||
|   t1_line_id int(11) unsigned not null default '0',
 | ||
|   article_id varchar(20),
 | ||
|   sequence int(11) not null default '0',
 | ||
|   primary key  (id,t1_line_id)
 | ||
| );
 | ||
| 
 | ||
| insert into t2 values ("1", "1", "sup", "0"), ("2", "1", "sup", "1"),
 | ||
|                       ("2", "2", "sup", "2"), ("2", "3", "sup", "3"),
 | ||
|                       ("2", "4", "imp", "4"), ("3", "1", "sup", "0"),
 | ||
|                       ("4", "1", "sup", "0");
 | ||
| 
 | ||
| create table t3 (
 | ||
|   id int(11) not null default '0',
 | ||
|   preceeding_id int(11) not null default '0',
 | ||
|   primary key  (id,preceeding_id)
 | ||
| );
 | ||
| 
 | ||
| create table t4 (
 | ||
|   user_id varchar(50) not null,
 | ||
|   article_id varchar(20) not null,
 | ||
|   primary key  (user_id,article_id)
 | ||
| );
 | ||
| 
 | ||
| insert into t4 values("nicke", "imp");
 | ||
| 
 | ||
| prepare stmt from
 | ||
| 'select distinct t1.partner_id
 | ||
| from t1 left join t3 on t1.id = t3.id
 | ||
|      left join t1 pp on pp.id = t3.preceeding_id
 | ||
| where
 | ||
|   exists (
 | ||
|     select *
 | ||
|     from t2 as pl_inner
 | ||
|     where pl_inner.id = t1.id
 | ||
|     and pl_inner.sequence <= (
 | ||
|       select min(sequence) from t2 pl_seqnr
 | ||
|       where pl_seqnr.id = t1.id
 | ||
|     )
 | ||
|     and exists (
 | ||
|       select * from t4
 | ||
|       where t4.article_id = pl_inner.article_id
 | ||
|       and t4.user_id = ?
 | ||
|     )
 | ||
|   )
 | ||
|   and t1.id = ?
 | ||
| group by t1.id
 | ||
| having count(pp.id) = 0';
 | ||
| set @user_id = 'nicke';
 | ||
| set @id = '2';
 | ||
| execute stmt using @user_id, @id;
 | ||
| execute stmt using @user_id, @id;
 | ||
| deallocate prepare stmt;
 | ||
| drop table t1, t2, t3, t4;
 | ||
| #
 | ||
| # Bug#9379: make sure that Item::collation is reset when one sets
 | ||
| # a parameter marker from a string variable.
 | ||
| #
 | ||
| prepare stmt from 'select ?=?';
 | ||
| set @a='CHRISTINE           ';
 | ||
| set @b='CHRISTINE';
 | ||
| execute stmt using @a, @b;
 | ||
| execute stmt using @a, @b;
 | ||
| set @a=1, @b=2;
 | ||
| execute stmt using @a, @b;
 | ||
| set @a='CHRISTINE           ';
 | ||
| set @b='CHRISTINE';
 | ||
| execute stmt using @a, @b;
 | ||
| deallocate prepare stmt;
 | ||
| #
 | ||
| # Bug#11299 "prepared statement makes wrong SQL syntax in binlog which stops
 | ||
| # replication": check that errouneous queries with placeholders are not
 | ||
| # allowed
 | ||
| #
 | ||
| create table t1 (a int);
 | ||
| --error 1064
 | ||
| prepare stmt from "select ??";
 | ||
| --error 1064
 | ||
| prepare stmt from "select ?FROM t1";
 | ||
| --error 1064
 | ||
| prepare stmt from "select FROM t1 WHERE?=1";
 | ||
| --error 1064
 | ||
| prepare stmt from "update t1 set a=a+?WHERE 1";
 | ||
| --disable_ps_protocol
 | ||
| --error 1064
 | ||
| select ?;
 | ||
| --error 1064
 | ||
| select ??;
 | ||
| --error 1064
 | ||
| select ? from t1;
 | ||
| --enable_ps_protocol
 | ||
| drop table t1;
 | ||
| #
 | ||
| # Bug#9359 "Prepared statements take snapshot of system vars at PREPARE
 | ||
| # time"
 | ||
| #
 | ||
| prepare stmt from "select @@time_zone";
 | ||
| execute stmt;
 | ||
| set @@time_zone:='Japan';
 | ||
| execute stmt;
 | ||
| prepare stmt from "select @@tx_isolation";
 | ||
| execute stmt;
 | ||
| set transaction isolation level read committed;
 | ||
| execute stmt;
 | ||
| set transaction isolation level serializable;
 | ||
| execute stmt;
 | ||
| set @@tx_isolation=default;
 | ||
| execute stmt;
 | ||
| deallocate prepare stmt;
 | ||
| 
 | ||
| #
 | ||
| # Bug#14410 "Crash in Enum or Set type in CREATE TABLE and PS/SP"
 | ||
| #
 | ||
| # Part I. Make sure the typelib for ENUM is created in the statement memory
 | ||
| # root.
 | ||
| prepare stmt from "create temporary table t1 (letter enum('','a','b','c')
 | ||
| not null)";
 | ||
| execute stmt;
 | ||
| drop table t1;
 | ||
| execute stmt;
 | ||
| drop table t1;
 | ||
| execute stmt;
 | ||
| drop table t1;
 | ||
| # Part II. Make sure that when the default value is converted to UTF-8,
 | ||
| # the new item is # created in the statement memory root.
 | ||
| set names latin1;
 | ||
| prepare stmt from "create table t1 (a enum('test') default 'test')
 | ||
|  character set utf8";
 | ||
| execute stmt;
 | ||
| drop table t1;
 | ||
| execute stmt;
 | ||
| drop table t1;
 | ||
| execute stmt;
 | ||
| drop table t1;
 | ||
| # Cleanup
 | ||
| set names default;
 | ||
| deallocate prepare stmt;
 | ||
| 
 | ||
| #
 | ||
| # A test case for Bug#12734 "prepared statement may return incorrect result
 | ||
| # set for a select SQL request": test that canDoTurboBM is reset for each
 | ||
| # execute of a prepared statement.
 | ||
| #
 | ||
| create table t1 (
 | ||
|   word_id mediumint(8) unsigned not null default '0',
 | ||
|   formatted varchar(20) not null default ''
 | ||
| );
 | ||
| 
 | ||
| insert into t1 values
 | ||
|   (80,'pendant'), (475,'pretendants'), (989,'tendances'),
 | ||
|   (1019,'cependant'),(1022,'abondance'),(1205,'independants'),
 | ||
|   (13,'lessiver'),(25,'lambiner'),(46,'situer'),(71,'terminer'),
 | ||
|   (82,'decrocher');
 | ||
| 
 | ||
| select count(*) from t1 where formatted like '%NDAN%';
 | ||
| select count(*) from t1 where formatted like '%ER';
 | ||
| prepare stmt from "select count(*) from t1 where formatted like ?";
 | ||
| set @like="%NDAN%";
 | ||
| execute stmt using @like;
 | ||
| set @like="%ER";
 | ||
| execute stmt using @like;
 | ||
| set @like="%NDAN%";
 | ||
| execute stmt using @like;
 | ||
| set @like="%ER";
 | ||
| execute stmt using @like;
 | ||
| deallocate prepare stmt;
 | ||
| drop table t1;
 | ||
| 
 | ||
| #
 | ||
| # Bug#13134 "Length of VARCHAR() utf8 column is increasing when table is
 | ||
| # recreated with PS/SP"
 | ||
| #
 | ||
| 
 | ||
| prepare stmt from 'create table t1 (a varchar(10) character set utf8)';
 | ||
| execute stmt;
 | ||
| --disable_warnings
 | ||
| insert into t1 (a) values (repeat('a', 20));
 | ||
| --enable_warnings
 | ||
| select length(a) from t1;
 | ||
| drop table t1;
 | ||
| execute stmt;
 | ||
| --disable_warnings
 | ||
| insert into t1 (a) values (repeat('a', 20));
 | ||
| --enable_warnings
 | ||
| # Check that the data is truncated to the same length
 | ||
| select length(a) from t1;
 | ||
| drop table t1;
 | ||
| deallocate prepare stmt;
 | ||
| 
 | ||
| #
 | ||
| # Bug#16248 "WHERE (col1,col2) IN ((?,?)) gives wrong results":
 | ||
| # check that ROW implementation is reexecution-friendly.
 | ||
| #
 | ||
| create table t1 (col1 integer, col2 integer);
 | ||
| insert into t1 values(100,100),(101,101),(102,102),(103,103);
 | ||
| prepare stmt from 'select col1, col2 from t1 where (col1, col2) in ((?,?))';
 | ||
| set @a=100, @b=100;
 | ||
| execute stmt using @a,@b;
 | ||
| set @a=101, @b=101;
 | ||
| execute stmt using @a,@b;
 | ||
| set @a=102, @b=102;
 | ||
| execute stmt using @a,@b;
 | ||
| set @a=102, @b=103;
 | ||
| execute stmt using @a,@b;
 | ||
| deallocate prepare stmt;
 | ||
| drop table t1;
 | ||
| 
 | ||
| #
 | ||
| # Bug#16365 Prepared Statements: DoS with too many open statements
 | ||
| # Check that the limit @@max_prpeared_stmt_count works.
 | ||
| #
 | ||
| # Save the old value
 | ||
| set @old_max_prepared_stmt_count= @@max_prepared_stmt_count;
 | ||
| #
 | ||
| # Disable prepared statement protocol: in this test we set
 | ||
| # @@max_prepared_stmt_count to 0 or 1 and would like to test the limit
 | ||
| # manually.
 | ||
| #
 | ||
| --disable_ps_protocol
 | ||
| #
 | ||
| # A. Check that the new variables are present in SHOW VARIABLES list.
 | ||
| #
 | ||
| show variables like 'max_prepared_stmt_count';
 | ||
| show variables like 'prepared_stmt_count';
 | ||
| #
 | ||
| # B. Check that the new variables are selectable.
 | ||
| #
 | ||
| select @@max_prepared_stmt_count, @@prepared_stmt_count;
 | ||
| #
 | ||
| # C. Check that max_prepared_stmt_count is settable (global only),
 | ||
| #    whereas prepared_stmt_count is readonly.
 | ||
| #
 | ||
| set global max_prepared_stmt_count=-1;
 | ||
| select @@max_prepared_stmt_count;
 | ||
| set global max_prepared_stmt_count=10000000000000000;
 | ||
| select @@max_prepared_stmt_count;
 | ||
| set global max_prepared_stmt_count=default;
 | ||
| select @@max_prepared_stmt_count;
 | ||
| --error ER_GLOBAL_VARIABLE
 | ||
| set @@max_prepared_stmt_count=1;
 | ||
| --error ER_GLOBAL_VARIABLE
 | ||
| set max_prepared_stmt_count=1;
 | ||
| --error ER_GLOBAL_VARIABLE
 | ||
| set local max_prepared_stmt_count=1;
 | ||
| --error ER_INCORRECT_GLOBAL_LOCAL_VAR
 | ||
| set local prepared_stmt_count=0;
 | ||
| --error ER_INCORRECT_GLOBAL_LOCAL_VAR
 | ||
| set @@prepared_stmt_count=0;
 | ||
| --error ER_INCORRECT_GLOBAL_LOCAL_VAR 
 | ||
| set global prepared_stmt_count=1;
 | ||
| # set to a reasonable limit works
 | ||
| set global max_prepared_stmt_count=1;
 | ||
| select @@max_prepared_stmt_count;
 | ||
| #
 | ||
| # D. Check that the variables actually work.
 | ||
| #
 | ||
| set global max_prepared_stmt_count=0;
 | ||
| select @@max_prepared_stmt_count, @@prepared_stmt_count;
 | ||
| --error ER_MAX_PREPARED_STMT_COUNT_REACHED
 | ||
| prepare stmt from "select 1";
 | ||
| select @@prepared_stmt_count;
 | ||
| set global max_prepared_stmt_count=1;
 | ||
| prepare stmt from "select 1";
 | ||
| select @@prepared_stmt_count;
 | ||
| --error ER_MAX_PREPARED_STMT_COUNT_REACHED
 | ||
| prepare stmt1 from "select 1";
 | ||
| select @@prepared_stmt_count;
 | ||
| deallocate prepare stmt;
 | ||
| select @@prepared_stmt_count;
 | ||
| #
 | ||
| # E. Check that we can prepare a statement with the same name 
 | ||
| # successfully, without hitting the limit.
 | ||
| #
 | ||
| prepare stmt from "select 1";
 | ||
| select @@prepared_stmt_count;
 | ||
| prepare stmt from "select 2";
 | ||
| select @@prepared_stmt_count;
 | ||
| #
 | ||
| # F. We can set the max below the current count. In this case no new 
 | ||
| # statements should be allowed to prepare.
 | ||
| #
 | ||
| select @@prepared_stmt_count, @@max_prepared_stmt_count;
 | ||
| set global max_prepared_stmt_count=0;
 | ||
| --error ER_MAX_PREPARED_STMT_COUNT_REACHED
 | ||
| prepare stmt from "select 1";
 | ||
| # Result: the old statement is deallocated, the new is not created.
 | ||
| --error 1243 # ER_UNKNOWN_STMT_HANDLER
 | ||
| execute stmt;
 | ||
| select @@prepared_stmt_count;
 | ||
| --error ER_MAX_PREPARED_STMT_COUNT_REACHED
 | ||
| prepare stmt from "select 1";
 | ||
| select @@prepared_stmt_count;
 | ||
| #
 | ||
| # G. Show that the variables are up to date even after a connection with all
 | ||
| # statements in it was terminated.
 | ||
| #
 | ||
| set global max_prepared_stmt_count=3;
 | ||
| select @@max_prepared_stmt_count, @@prepared_stmt_count;
 | ||
| prepare stmt from "select 1";
 | ||
| connect (con1,localhost,root,,);
 | ||
| connection con1;
 | ||
| prepare stmt from "select 2";
 | ||
| prepare stmt1 from "select 3";
 | ||
| --error ER_MAX_PREPARED_STMT_COUNT_REACHED
 | ||
| prepare stmt2 from "select 4";
 | ||
| connection default;
 | ||
| --error ER_MAX_PREPARED_STMT_COUNT_REACHED
 | ||
| prepare stmt2 from "select 4";
 | ||
| select @@max_prepared_stmt_count, @@prepared_stmt_count;
 | ||
| disconnect con1;
 | ||
| connection default;
 | ||
| # Wait for the connection to die: deal with a possible race
 | ||
| deallocate prepare stmt;
 | ||
| let $count= `select @@prepared_stmt_count`;
 | ||
| if ($count)
 | ||
| {
 | ||
| --sleep 2
 | ||
|   let $count= `select @@prepared_stmt_count`;
 | ||
| }
 | ||
| select @@max_prepared_stmt_count, @@prepared_stmt_count;
 | ||
| #
 | ||
| # Restore the old value.
 | ||
| #
 | ||
| set global max_prepared_stmt_count= @old_max_prepared_stmt_count;
 | ||
| --enable_ps_protocol
 | ||
| 
 | ||
| #
 | ||
| # Bug#19399 "Stored Procedures 'Lost Connection' when dropping/creating
 | ||
| #            tables"
 | ||
| # Check that multi-delete tables are also cleaned up before re-execution.
 | ||
| # 
 | ||
| --disable_warnings
 | ||
| drop table if exists t1;
 | ||
| create temporary table if not exists t1 (a1 int);
 | ||
| --enable_warnings
 | ||
| # exact delete syntax is essential
 | ||
| prepare stmt from "delete t1 from t1 where (cast(a1/3 as unsigned) * 3) = a1";
 | ||
| drop temporary table t1;
 | ||
| create temporary table if not exists t1 (a1 int);
 | ||
| # the server crashed on  the next statement without the fix
 | ||
| execute stmt;
 | ||
| drop temporary table t1;
 | ||
| create temporary table if not exists t1 (a1 int);
 | ||
| # the problem was in memory corruption: repeat the test just in case
 | ||
| execute stmt;
 | ||
| drop temporary table t1;
 | ||
| create temporary table if not exists t1 (a1 int);
 | ||
| execute stmt;
 | ||
| drop temporary table t1;
 | ||
| deallocate prepare stmt;
 | ||
| 
 | ||
| 
 | ||
| #
 | ||
| # BUG#22085: Crash on the execution of a prepared statement that
 | ||
| #            uses an IN subquery with aggregate functions in HAVING 
 | ||
| #
 | ||
| 
 | ||
| CREATE TABLE t1(
 | ||
|   ID int(10) unsigned NOT NULL auto_increment,
 | ||
|   Member_ID varchar(15) NOT NULL default '',
 | ||
|   Action varchar(12) NOT NULL,
 | ||
|   Action_Date datetime NOT NULL,
 | ||
|   Track varchar(15) default NULL,
 | ||
|   User varchar(12) default NULL,
 | ||
|   Date_Updated timestamp NOT NULL default CURRENT_TIMESTAMP on update
 | ||
|     CURRENT_TIMESTAMP,
 | ||
|   PRIMARY KEY (ID),
 | ||
|   KEY Action (Action),
 | ||
|   KEY Action_Date (Action_Date)
 | ||
| );
 | ||
| 
 | ||
| INSERT INTO t1(Member_ID, Action, Action_Date, Track) VALUES
 | ||
|   ('111111', 'Disenrolled', '2006-03-01', 'CAD' ),
 | ||
|   ('111111', 'Enrolled', '2006-03-01', 'CAD' ),
 | ||
|   ('111111', 'Disenrolled', '2006-07-03', 'CAD' ),
 | ||
|   ('222222', 'Enrolled', '2006-03-07', 'CAD' ),
 | ||
|   ('222222', 'Enrolled', '2006-03-07', 'CHF' ),
 | ||
|   ('222222', 'Disenrolled', '2006-08-02', 'CHF' ),
 | ||
|   ('333333', 'Enrolled', '2006-03-01', 'CAD' ),
 | ||
|   ('333333', 'Disenrolled', '2006-03-01', 'CAD' ),
 | ||
|   ('444444', 'Enrolled', '2006-03-01', 'CAD' ),
 | ||
|   ('555555', 'Disenrolled', '2006-03-01', 'CAD' ),
 | ||
|   ('555555', 'Enrolled', '2006-07-21', 'CAD' ),
 | ||
|   ('555555', 'Disenrolled', '2006-03-01', 'CHF' ),
 | ||
|   ('666666', 'Enrolled', '2006-02-09', 'CAD' ),
 | ||
|   ('666666', 'Enrolled', '2006-05-12', 'CHF' ),
 | ||
|   ('666666', 'Disenrolled', '2006-06-01', 'CAD' );
 | ||
| 
 | ||
| PREPARE STMT FROM
 | ||
| "SELECT GROUP_CONCAT(Track SEPARATOR ', ') FROM t1
 | ||
|   WHERE Member_ID=? AND Action='Enrolled' AND
 | ||
|         (Track,Action_Date) IN (SELECT Track, MAX(Action_Date) FROM t1
 | ||
|                                   WHERE Member_ID=?
 | ||
|                                     GROUP BY Track 
 | ||
|                                       HAVING Track>='CAD' AND
 | ||
|                                              MAX(Action_Date)>'2006-03-01')";
 | ||
| SET @id='111111';
 | ||
| EXECUTE STMT USING @id,@id;
 | ||
| SET @id='222222';
 | ||
| EXECUTE STMT USING @id,@id;
 | ||
| 
 | ||
| DEALLOCATE PREPARE STMT;
 | ||
| DROP TABLE t1;
 | ||
| 
 | ||
| 
 | ||
| #
 | ||
| # BUG#21354: (COUNT(*) = 1) not working in SELECT inside prepared
 | ||
| # statement 
 | ||
| #
 | ||
| --disable_warnings
 | ||
| DROP TABLE IF EXISTS t1;
 | ||
| --enable_warnings
 | ||
| 
 | ||
| CREATE TABLE t1 (i INT, INDEX(i));
 | ||
| INSERT INTO t1 VALUES (1);
 | ||
| 
 | ||
| PREPARE stmt FROM "SELECT (COUNT(i) = 1), COUNT(i) FROM t1 WHERE i = ?";
 | ||
| SET @a = 0;
 | ||
| EXECUTE stmt USING @a;
 | ||
| SET @a = 1;
 | ||
| EXECUTE stmt USING @a;
 | ||
| SET @a = 0;
 | ||
| EXECUTE stmt USING @a;
 | ||
| 
 | ||
| PREPARE stmt FROM "SELECT (AVG(i) = 1), AVG(i) FROM t1 WHERE i = ?";
 | ||
| SET @a = 0;
 | ||
| EXECUTE stmt USING @a;
 | ||
| SET @a = 1;
 | ||
| EXECUTE stmt USING @a;
 | ||
| SET @a = 0;
 | ||
| EXECUTE stmt USING @a;
 | ||
| 
 | ||
| PREPARE stmt FROM "SELECT (VARIANCE(i) = 1), VARIANCE(i) FROM t1 WHERE i = ?";
 | ||
| SET @a = 0;
 | ||
| EXECUTE stmt USING @a;
 | ||
| SET @a = 1;
 | ||
| EXECUTE stmt USING @a;
 | ||
| SET @a = 0;
 | ||
| EXECUTE stmt USING @a;
 | ||
| 
 | ||
| PREPARE stmt FROM "SELECT (STDDEV(i) = 1), STDDEV(i) FROM t1 WHERE i = ?";
 | ||
| SET @a = 0;
 | ||
| EXECUTE stmt USING @a;
 | ||
| SET @a = 1;
 | ||
| EXECUTE stmt USING @a;
 | ||
| SET @a = 0;
 | ||
| EXECUTE stmt USING @a;
 | ||
| 
 | ||
| PREPARE stmt FROM "SELECT (BIT_OR(i) = 1), BIT_OR(i) FROM t1 WHERE i = ?";
 | ||
| SET @a = 0;
 | ||
| EXECUTE stmt USING @a;
 | ||
| SET @a = 1;
 | ||
| EXECUTE stmt USING @a;
 | ||
| SET @a = 0;
 | ||
| EXECUTE stmt USING @a;
 | ||
| 
 | ||
| PREPARE stmt FROM "SELECT (BIT_AND(i) = 1), BIT_AND(i) FROM t1 WHERE i = ?";
 | ||
| SET @a = 0;
 | ||
| EXECUTE stmt USING @a;
 | ||
| SET @a = 1;
 | ||
| EXECUTE stmt USING @a;
 | ||
| SET @a = 0;
 | ||
| EXECUTE stmt USING @a;
 | ||
| 
 | ||
| PREPARE stmt FROM "SELECT (BIT_XOR(i) = 1), BIT_XOR(i) FROM t1 WHERE i = ?";
 | ||
| SET @a = 0;
 | ||
| EXECUTE stmt USING @a;
 | ||
| SET @a = 1;
 | ||
| EXECUTE stmt USING @a;
 | ||
| SET @a = 0;
 | ||
| EXECUTE stmt USING @a;
 | ||
| 
 | ||
| DEALLOCATE PREPARE stmt;
 | ||
| DROP TABLE t1;
 | ||
| 
 | ||
| 
 | ||
| --echo End of 4.1 tests.
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| ############################# 5.0 tests start ################################
 | ||
| #
 | ||
| #
 | ||
| # Bug#6102 "Server crash with prepared statement and blank after
 | ||
| # function name"
 | ||
| # ensure that stored functions are cached when preparing a statement
 | ||
| # before we open tables
 | ||
| #
 | ||
| create table t1 (a varchar(20)); 
 | ||
| insert into t1 values ('foo'); 
 | ||
| --error 1305
 | ||
| prepare stmt FROM 'SELECT char_length (a) FROM t1'; 
 | ||
| drop table t1;
 | ||
| 
 | ||
| #
 | ||
| # Bug#8115: equality propagation and prepared statements
 | ||
| #
 | ||
| 
 | ||
| create table t1 (a char(3) not null, b char(3) not null,
 | ||
|                  c char(3) not null, primary key  (a, b, c));
 | ||
| create table t2 like t1;
 | ||
| 
 | ||
| # reduced query
 | ||
| prepare stmt from
 | ||
|   "select t1.a from (t1 left outer join t2 on t2.a=1 and t1.b=t2.b)
 | ||
|   where t1.a=1";
 | ||
| execute stmt;
 | ||
| execute stmt;
 | ||
| execute stmt;
 | ||
| 
 | ||
| # original query
 | ||
| prepare stmt from
 | ||
| "select t1.a, t1.b, t1.c, t2.a, t2.b, t2.c from
 | ||
| (t1 left outer join t2 on t2.a=? and t1.b=t2.b)
 | ||
| left outer join t2 t3 on t3.a=? where t1.a=?";
 | ||
| 
 | ||
| set @a:=1, @b:=1, @c:=1;
 | ||
| 
 | ||
| execute stmt using @a, @b, @c;
 | ||
| execute stmt using @a, @b, @c;
 | ||
| execute stmt using @a, @b, @c;
 | ||
| 
 | ||
| deallocate prepare stmt;
 | ||
| 
 | ||
| drop table t1,t2;
 | ||
| 
 | ||
| 
 | ||
| #
 | ||
| # Bug#9383: INFORMATION_SCHEMA.COLUMNS, JOIN, Crash, prepared statement
 | ||
| #
 | ||
| 
 | ||
| eval SET @aux= "SELECT COUNT(*)
 | ||
|                 FROM INFORMATION_SCHEMA.COLUMNS A,
 | ||
|                 INFORMATION_SCHEMA.COLUMNS B
 | ||
|                 WHERE A.TABLE_SCHEMA = B.TABLE_SCHEMA
 | ||
|                 AND A.TABLE_NAME = B.TABLE_NAME
 | ||
|                 AND A.COLUMN_NAME = B.COLUMN_NAME AND
 | ||
|                 A.TABLE_NAME = 'user'";
 | ||
| 
 | ||
| let $exec_loop_count= 3;
 | ||
| eval prepare my_stmt from @aux;
 | ||
| while ($exec_loop_count)
 | ||
| {
 | ||
|   eval execute my_stmt;
 | ||
|   dec $exec_loop_count;
 | ||
| }
 | ||
| deallocate prepare my_stmt;
 | ||
| 
 | ||
| # Test CALL in prepared mode
 | ||
| delimiter |;
 | ||
| --disable_warnings
 | ||
| drop procedure if exists p1|
 | ||
| drop table if exists t1|
 | ||
| --enable_warnings
 | ||
| create table t1 (id int)|
 | ||
| insert into t1 values(1)|
 | ||
| create procedure p1(a int, b int)
 | ||
| begin
 | ||
|   declare c int;
 | ||
|   select max(id)+1 into c from t1;
 | ||
|   insert into t1 select a+b;
 | ||
|   insert into t1 select a-b;
 | ||
|   insert into t1 select a-c;
 | ||
| end|
 | ||
| set @a= 3, @b= 4|
 | ||
| prepare stmt from "call p1(?, ?)"|
 | ||
| execute stmt using @a, @b|
 | ||
| execute stmt using @a, @b|
 | ||
| select * from t1|
 | ||
| deallocate prepare stmt|
 | ||
| drop procedure p1|
 | ||
| drop table t1|
 | ||
| delimiter ;|
 | ||
| 
 | ||
| 
 | ||
| #
 | ||
| # Bug#7306 LIMIT ?, ? and also WL#1785 " Prepared statements: implement
 | ||
| # support for placeholders in LIMIT clause."
 | ||
| # Add basic test coverage for the feature.
 | ||
| # 
 | ||
| create table t1 (a int);
 | ||
| insert into t1 (a) values (1), (2), (3), (4), (5), (6), (7), (8), (9), (10);
 | ||
| prepare stmt from "select * from t1 limit ?, ?";
 | ||
| set @offset=0, @limit=1;
 | ||
| execute stmt using @offset, @limit;
 | ||
| select * from t1 limit 0, 1;
 | ||
| set @offset=3, @limit=2;
 | ||
| execute stmt using @offset, @limit;
 | ||
| select * from t1 limit 3, 2;
 | ||
| prepare stmt from "select * from t1 limit ?";
 | ||
| execute stmt using @limit;
 | ||
| --error 1235
 | ||
| prepare stmt from "select * from t1 where a in (select a from t1 limit ?)";
 | ||
| prepare stmt from "select * from t1 union all select * from t1 limit ?, ?";
 | ||
| set @offset=9;
 | ||
| set @limit=2;
 | ||
| execute stmt using @offset, @limit;
 | ||
| prepare stmt from "(select * from t1 limit ?, ?) union all
 | ||
|                    (select * from t1 limit ?, ?) order by a limit ?";
 | ||
| execute stmt using @offset, @limit, @offset, @limit, @limit;
 | ||
| 
 | ||
| drop table t1;
 | ||
| deallocate prepare stmt;
 | ||
| 
 | ||
| #
 | ||
| # Bug#12651
 | ||
| # (Crash on a PS including a subquery which is a select from a simple view)
 | ||
| #
 | ||
| CREATE TABLE b12651_T1(a int) ENGINE=MYISAM;
 | ||
| CREATE TABLE b12651_T2(b int) ENGINE=MYISAM;
 | ||
| CREATE VIEW  b12651_V1 as SELECT b FROM b12651_T2;
 | ||
| 
 | ||
| PREPARE b12651 FROM 'SELECT 1 FROM b12651_T1 WHERE a IN (SELECT b FROM b12651_V1)';
 | ||
| EXECUTE b12651;
 | ||
| 
 | ||
| DROP VIEW b12651_V1;
 | ||
| DROP TABLE b12651_T1, b12651_T2;
 | ||
| DEALLOCATE PREPARE b12651;
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| #
 | ||
| # Bug #14956: ROW_COUNT() returns incorrect result after EXECUTE of prepared
 | ||
| # statement
 | ||
| #
 | ||
| create table t1 (id int);
 | ||
| prepare ins_call from "insert into t1 (id) values (1)";
 | ||
| execute ins_call;
 | ||
| select row_count();
 | ||
| drop table t1;
 | ||
| 
 | ||
| #
 | ||
| # BUG#16474: SP crashed MySQL
 | ||
| # (when using "order by localvar", where 'localvar' is just that.
 | ||
| # The actual bug test is in sp.test, this is just testing that we get the
 | ||
| # expected result for prepared statements too, i.e. place holders work as
 | ||
| # textual substitution. If it's a single integer, it works as the (deprecated)
 | ||
| # "order by column#", otherwise it's an expression.
 | ||
| #
 | ||
| create table t1 (a int, b int);
 | ||
| insert into t1 (a,b) values (2,8),(1,9),(3,7);
 | ||
| 
 | ||
| # Will order by index
 | ||
| prepare stmt from "select * from t1 order by ?";
 | ||
| set @a=NULL;
 | ||
| execute stmt using @a;
 | ||
| set @a=1;
 | ||
| execute stmt using @a;
 | ||
| set @a=2;
 | ||
| execute stmt using @a;
 | ||
| deallocate prepare stmt;
 | ||
| # For reference:
 | ||
| select * from t1 order by 1;
 | ||
| 
 | ||
| # Will not order by index.
 | ||
| prepare stmt from "select * from t1 order by ?+1";
 | ||
| set @a=0;
 | ||
| execute stmt using @a;
 | ||
| set @a=1;
 | ||
| execute stmt using @a;
 | ||
| deallocate prepare stmt;
 | ||
| # For reference:
 | ||
| select * from t1 order by 1+1;
 | ||
| 
 | ||
| drop table t1;
 | ||
| 
 | ||
| #
 | ||
| # Bug#19308 "REPAIR/OPTIMIZE/ANALYZE supported in SP but not in PS".
 | ||
| # Add test coverage for the added commands.
 | ||
| #
 | ||
| create table t1 (a int);
 | ||
| create table t2 like t1;
 | ||
| create table t3 like t2;
 | ||
| prepare stmt from "repair table t1";
 | ||
| execute stmt;
 | ||
| execute stmt;
 | ||
| prepare stmt from "optimize table t1";
 | ||
| execute stmt;
 | ||
| execute stmt;
 | ||
| prepare stmt from "analyze table t1";
 | ||
| execute stmt;
 | ||
| execute stmt;
 | ||
| prepare stmt from "repair table t1, t2, t3";
 | ||
| execute stmt;
 | ||
| execute stmt;
 | ||
| prepare stmt from "optimize table t1, t2, t3";
 | ||
| execute stmt;
 | ||
| execute stmt;
 | ||
| prepare stmt from "analyze table t1, t2, t3";
 | ||
| execute stmt;
 | ||
| execute stmt;
 | ||
| prepare stmt from "repair table t1, t4, t3";
 | ||
| execute stmt;
 | ||
| execute stmt;
 | ||
| prepare stmt from "optimize table t1, t3, t4";
 | ||
| execute stmt;
 | ||
| execute stmt;
 | ||
| prepare stmt from "analyze table t4, t1";
 | ||
| execute stmt;
 | ||
| execute stmt;
 | ||
| deallocate prepare stmt;
 | ||
| drop table t1, t2, t3;
 | ||
| 
 | ||
| #
 | ||
| # Bug#17199 "Table not found" error occurs if the query contains a call
 | ||
| #            to a function from another database.
 | ||
| #            Test prepared statements- related behaviour.
 | ||
| #
 | ||
| #
 | ||
| # ALTER TABLE RENAME and Prepared Statements: wrong DB name buffer was used
 | ||
| # in ALTER ... RENAME which caused memory corruption in prepared statements.
 | ||
| # No need to fix this problem in 4.1 as ALTER TABLE is not allowed in
 | ||
| # Prepared Statements in 4.1.
 | ||
| #
 | ||
| create database mysqltest_long_database_name_to_thrash_heap;
 | ||
| use test;
 | ||
| create table t1 (i int);
 | ||
| prepare stmt from "alter table test.t1 rename t1";
 | ||
| use mysqltest_long_database_name_to_thrash_heap;
 | ||
| execute stmt;
 | ||
| show tables like 't1';
 | ||
| prepare stmt from "alter table test.t1 rename t1";
 | ||
| use test;
 | ||
| execute stmt;
 | ||
| show tables like 't1';
 | ||
| use mysqltest_long_database_name_to_thrash_heap;
 | ||
| show tables like 't1';
 | ||
| deallocate prepare stmt;
 | ||
| #
 | ||
| # Check that a prepared statement initializes its current database at
 | ||
| # PREPARE, and then works correctly even if the current database has been
 | ||
| # changed.
 | ||
| # 
 | ||
| use mysqltest_long_database_name_to_thrash_heap; 
 | ||
| # Necessary for preparation of INSERT/UPDATE/DELETE to succeed
 | ||
| prepare stmt_create from "create table t1 (i int)";
 | ||
| prepare stmt_insert from "insert into t1 (i) values (1)";
 | ||
| prepare stmt_update from "update t1 set i=2";
 | ||
| prepare stmt_delete from "delete from t1 where i=2";
 | ||
| prepare stmt_select from "select * from t1";
 | ||
| prepare stmt_alter from "alter table t1 add column (b int)";
 | ||
| prepare stmt_alter1 from "alter table t1 drop column b";
 | ||
| prepare stmt_analyze from "analyze table t1";
 | ||
| prepare stmt_optimize from "optimize table t1";
 | ||
| prepare stmt_show from "show tables like 't1'";
 | ||
| prepare stmt_truncate from "truncate table t1";
 | ||
| prepare stmt_drop from "drop table t1";
 | ||
| # Drop the table that was used to prepare INSERT/UPDATE/DELETE: we will
 | ||
| # create a new one by executing stmt_create
 | ||
| drop table t1;
 | ||
| # Switch the current database
 | ||
| use test;
 | ||
| # Check that all prepared statements operate on the database that was
 | ||
| # active at PREPARE
 | ||
| execute stmt_create;
 | ||
| # should return empty set
 | ||
| show tables like 't1';
 | ||
| use mysqltest_long_database_name_to_thrash_heap;
 | ||
| show tables like 't1';
 | ||
| use test;
 | ||
| execute stmt_insert;
 | ||
| select * from mysqltest_long_database_name_to_thrash_heap.t1;
 | ||
| execute stmt_update;
 | ||
| select * from mysqltest_long_database_name_to_thrash_heap.t1;
 | ||
| execute stmt_delete;
 | ||
| execute stmt_select;
 | ||
| execute stmt_alter;
 | ||
| show columns from mysqltest_long_database_name_to_thrash_heap.t1;
 | ||
| execute stmt_alter1;
 | ||
| show columns from mysqltest_long_database_name_to_thrash_heap.t1;
 | ||
| execute stmt_analyze;
 | ||
| execute stmt_optimize;
 | ||
| execute stmt_show;
 | ||
| execute stmt_truncate;
 | ||
| execute stmt_drop;
 | ||
| show tables like 't1';
 | ||
| use mysqltest_long_database_name_to_thrash_heap;
 | ||
| show tables like 't1';
 | ||
| #
 | ||
| # Attempt a statement PREPARE when there is no current database:
 | ||
| # is expected to return an error.
 | ||
| #
 | ||
| drop database mysqltest_long_database_name_to_thrash_heap;
 | ||
| --error ER_NO_DB_ERROR
 | ||
| prepare stmt_create from "create table t1 (i int)";
 | ||
| --error ER_NO_DB_ERROR
 | ||
| prepare stmt_insert from "insert into t1 (i) values (1)";
 | ||
| --error ER_NO_DB_ERROR
 | ||
| prepare stmt_update from "update t1 set i=2";
 | ||
| --error ER_NO_DB_ERROR
 | ||
| prepare stmt_delete from "delete from t1 where i=2";
 | ||
| --error ER_NO_DB_ERROR
 | ||
| prepare stmt_select from "select * from t1";
 | ||
| --error ER_NO_DB_ERROR
 | ||
| prepare stmt_alter from "alter table t1 add column (b int)";
 | ||
| --error ER_NO_DB_ERROR
 | ||
| prepare stmt_alter1 from "alter table t1 drop column b";
 | ||
| --error ER_NO_DB_ERROR
 | ||
| prepare stmt_analyze from "analyze table t1";
 | ||
| --error ER_NO_DB_ERROR
 | ||
| prepare stmt_optimize from "optimize table t1";
 | ||
| --error ER_NO_DB_ERROR
 | ||
| prepare stmt_show from "show tables like 't1'";
 | ||
| --error ER_NO_DB_ERROR
 | ||
| prepare stmt_truncate from "truncate table t1";
 | ||
| --error ER_NO_DB_ERROR
 | ||
| prepare stmt_drop from "drop table t1";
 | ||
| #
 | ||
| # The above has automatically deallocated all our statements.
 | ||
| #
 | ||
| # Attempt to CREATE a temporary table when no DB used: it should fail
 | ||
| # This proves that no table can be used without explicit specification of
 | ||
| # its database if there is no current database. 
 | ||
| #
 | ||
| --error ER_NO_DB_ERROR
 | ||
| create temporary table t1 (i int);
 | ||
| #
 | ||
| # Restore the old environemnt
 | ||
| #
 | ||
| use test;
 | ||
| 
 | ||
| 
 | ||
| #
 | ||
| # BUG#21166: Prepared statement causes signal 11 on second execution
 | ||
| #
 | ||
| # Changes in an item tree done by optimizer weren't properly
 | ||
| # registered and went unnoticed, which resulted in preliminary freeing
 | ||
| # of used memory.
 | ||
| #
 | ||
| --disable_warnings
 | ||
| DROP TABLE IF EXISTS t1, t2, t3;
 | ||
| --enable_warnings
 | ||
| 
 | ||
| CREATE TABLE t1 (i BIGINT, j BIGINT);
 | ||
| CREATE TABLE t2 (i BIGINT);
 | ||
| CREATE TABLE t3 (i BIGINT, j BIGINT);
 | ||
| 
 | ||
| PREPARE stmt FROM "SELECT * FROM t1 JOIN t2 ON (t2.i = t1.i)
 | ||
|                    LEFT JOIN t3 ON ((t3.i, t3.j) = (t1.i, t1.j))
 | ||
|                    WHERE t1.i = ?";
 | ||
| 
 | ||
| SET @a= 1;
 | ||
| EXECUTE stmt USING @a;
 | ||
| EXECUTE stmt USING @a;
 | ||
| 
 | ||
| DEALLOCATE PREPARE stmt;
 | ||
| DROP TABLE IF EXISTS t1, t2, t3;
 | ||
| 
 | ||
| 
 | ||
| #
 | ||
| # BUG#21081: SELECT inside stored procedure returns wrong results
 | ||
| #
 | ||
| --disable_warnings
 | ||
| DROP TABLE IF EXISTS t1, t2;
 | ||
| --enable_warnings
 | ||
| 
 | ||
| CREATE TABLE t1 (i INT KEY);
 | ||
| CREATE TABLE t2 (i INT);
 | ||
| 
 | ||
| INSERT INTO t1 VALUES (1), (2);
 | ||
| INSERT INTO t2 VALUES (1);
 | ||
| 
 | ||
| PREPARE stmt FROM "SELECT t2.i FROM t1 LEFT JOIN t2 ON t2.i = t1.i
 | ||
|                    WHERE t1.i = ?";
 | ||
| 
 | ||
| SET @arg= 1;
 | ||
| EXECUTE stmt USING @arg;
 | ||
| SET @arg= 2;
 | ||
| EXECUTE stmt USING @arg;
 | ||
| SET @arg= 1;
 | ||
| EXECUTE stmt USING @arg;
 | ||
| 
 | ||
| DEALLOCATE PREPARE stmt;
 | ||
| DROP TABLE t1, t2;
 | ||
| 
 | ||
| 
 | ||
| #
 | ||
| # BUG#21856: Prepared Statments: crash if bad create
 | ||
| #
 | ||
| --disable_warnings
 | ||
| DROP PROCEDURE IF EXISTS p1;
 | ||
| --enable_warnings
 | ||
| 
 | ||
| let $iterations= 100;
 | ||
| --disable_query_log
 | ||
| --disable_result_log
 | ||
| while ($iterations > 0)
 | ||
| {
 | ||
|   --error ER_PARSE_ERROR
 | ||
|   PREPARE stmt FROM "CREATE PROCEDURE p1()";
 | ||
|   dec $iterations;
 | ||
| }
 | ||
| --enable_query_log
 | ||
| --enable_result_log
 | ||
| 
 | ||
| #
 | ||
| # Bug 19764:  SHOW commands end up in the slow log as table scans
 | ||
| #
 | ||
| 
 | ||
| flush status;
 | ||
| prepare sq from 'show status like "slow_queries"';
 | ||
| execute sq;
 | ||
| prepare no_index from 'select 1 from information_schema.tables limit 1';
 | ||
| execute sq;
 | ||
| execute no_index;
 | ||
| execute sq;
 | ||
| deallocate prepare no_index;
 | ||
| deallocate prepare sq;
 | ||
| 
 | ||
| --echo End of 5.0 tests.
 | 
