mirror of
https://github.com/MariaDB/server.git
synced 2025-01-19 05:22:25 +01:00
095b686c09
a second time". The bug was caused by incompatibility of negations elimination algorithm and PS: during first statement execute a subtree with negation was replaced with equivalent subtree without NOTs. The problem was that although this transformation was permanent, items of the new subtree were created in execute-local memory. The patch adds means to check if it is the first execute of a prepared statement, and if this is the case, to allocate items in memory of the prepared statement. The implementation: - backports Item_arena from 5.0 - adds Item_arena::is_stmt_prepare(), Item_arena::is_first_stmt_execute(). - deletes THD::allocate_temporary_pool_for_ps_preparing(), THD::free_temporary_pool_for_ps_preparing(); they were redundant. and adds a few invariants: - thd->free_list never contains junk (= freed items) - thd->current_arena is never null. If there is no prepared statement, it points at the thd. The rest of the patch contains mainly mechanical changes and cleanups. mysql-test/r/ps.result: Test results updated (test case for Bug#4912) mysql-test/t/ps.test: A test case for Bug#4912 "mysqld crashs in case a statement is executed a second time" sql/item_cmpfunc.cc: current_statement -> current_arena sql/item_subselect.cc: Statement -> Item_arena, current_statement -> current_arena sql/item_subselect.h: Item_subselect does not need to save thd->current_statement. sql/item_sum.cc: Statement -> Item_arena sql/item_sum.h: Statement -> Item_arena sql/mysql_priv.h: Statement -> Item_arena sql/sql_base.cc: current_statement -> current_arena sql/sql_class.cc: - Item_arena - convenient set_n_backup_statement, restore_backup_statement (nice idea, Sanja) sql/sql_class.h: - Item_arena: backport from 5.0 - allocate_temporary_pool_for_ps_preparing, free_temporary_pool_for_ps_preparing removed. sql/sql_derived.cc: current_statement -> current_arena sql/sql_lex.cc: current_statement -> current_arena sql/sql_parse.cc: Deploy invariant that thd->free_list never contains junk items (backport from 5.0). sql/sql_prepare.cc: - backporting Item_arena - no need to allocate_temporary_pool_for_ps_preparing(). sql/sql_select.cc: Fix for bug#4912 "mysqld crashs in case a statement is executed a second time": if this is the first execute of a prepared statement, negation elimination is done in memory of the prepared statement. sql/sql_union.cc: Backporting Item_arena from 5.0.
220 lines
5.7 KiB
Text
220 lines
5.7 KiB
Text
#
|
|
# SQL Syntax for Prepared Statements test
|
|
#
|
|
--disable_warnings
|
|
drop table if exists t1,t2;
|
|
--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;
|
|
|
|
set @str1 = 'select ?';
|
|
set @str2 = convert(@str1 using ucs2);
|
|
prepare stmt1 from @str2;
|
|
execute stmt1 using @ivar;
|
|
drop table t1,t2;
|
|
|
|
#
|
|
# 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(14), 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 12 # 13 # 14 #
|
|
execute stmt1;
|
|
--replace_column 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 and prepared statemens
|
|
#
|
|
|
|
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;
|
|
|