2006-12-28 06:42:04 +01:00
-- source include/not_embedded.inc
2007-06-07 19:20:49 +02:00
-- source include/have_log_bin.inc
2004-04-05 17:43:37 +02:00
#
# SQL Syntax for Prepared Statements test
#
--disable_warnings
2005-12-26 08:16:36 +01:00
drop table if exists t1,t2,t3,t4;
2005-05-16 12:34:23 +02:00
# Avoid wrong warnings if mysql_client_test fails
drop database if exists client_test_db;
2004-04-05 17:43:37 +02:00
--enable_warnings
create table t1
(
2005-05-05 14:31:18 +02:00
a int primary key,
b char(10)
2004-04-05 17:43:37 +02:00
);
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:
2007-05-11 15:26:12 +02:00
--error ER_UNSUPPORTED_PS
2004-04-05 17:43:37 +02:00
prepare stmt2 from 'prepare nested_stmt from "select 1"';
2007-05-11 15:26:12 +02:00
--error ER_UNSUPPORTED_PS
2004-04-05 17:43:37 +02:00
prepare stmt2 from 'execute stmt1';
2007-05-11 15:26:12 +02:00
--error ER_UNSUPPORTED_PS
2004-04-05 17:43:37 +02:00
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;
2004-04-07 10:58:28 +02:00
set @nullvar=1;
2004-04-05 17:43:37 +02:00
set @nullvar=NULL;
execute stmt5 using @nullvar;
2004-04-07 10:58:28 +02:00
set @nullvar2=NULL;
execute stmt5 using @nullvar2;
2004-04-30 18:08:38 +02:00
# 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';
2004-05-07 01:32:51 +02:00
create table t2
(
2005-05-05 14:31:18 +02:00
a int
2004-05-07 01:32:51 +02:00
);
insert into t2 values (0);
# parameter is NULL
set @arg00=NULL ;
prepare stmt1 from 'select 1 FROM t2 where a=?' ;
execute stmt1 using @arg00 ;
2004-05-21 02:27:50 +02:00
# 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;
2004-05-07 01:32:51 +02:00
drop table t1,t2;
A fix and a test case for Bug#16365 "Prepared Statements: DoS with
too many open statements". The patch adds a new global variable
@@max_prepared_stmt_count. This variable limits the total number
of prepared statements in the server. The default value of
@@max_prepared_stmt_count is 16382. 16382 small statements
(a select against 3 tables with GROUP, ORDER and LIMIT) consume
100MB of RAM. Once this limit has been reached, the server will
refuse to prepare a new statement and return ER_UNKNOWN_ERROR
(unfortunately, we can't add new errors to 4.1 without breaking 5.0). The limit is changeable after startup
and can accept any value from 0 to 1 million. In case
the new value of the limit is less than the current
statement count, no new statements can be added, while the old
still can be used. Additionally, the current count of prepared
statements is now available through a global read-only variable
@@prepared_stmt_count.
mysql-test/r/ps.result:
Test results fixed (a test case for Bug#16365)
mysql-test/t/ps.test:
A test case for Bug#16365 "Prepared Statements: DoS with too many
open statements". Also fix statement leaks in other tests.
sql/mysql_priv.h:
Add declarations for new global variables.
sql/mysqld.cc:
Add definitions of max_prepared_stmt_count, prepared_stmt_count.
sql/set_var.cc:
Implement support for @@prepared_stmt_count and
@@max_prepared_stmt_count. Currently these variables are queried
without acquiring LOCK_prepared_stmt_count due to limitations of
the set_var/sys_var class design. Updates are, however, protected
with a lock.
sql/set_var.h:
New declarations to add support for @@max_prepared_stmt_count.
Implement a new class, where the lock to be used when updating
a variable is a parameter.
sql/sql_class.cc:
Add accounting of the total number of prepared statements in the
server to the methods of Statement_map.
sql/sql_class.h:
Add accounting of the total number of prepared statements in the
server to the methods of Statement_map.
sql/sql_prepare.cc:
Statement_map::insert will now send a message in case of an
error.
2006-04-07 21:37:06 +02:00
deallocate prepare stmt3;
deallocate prepare stmt4;
deallocate prepare stmt5;
2004-06-25 10:37:43 +02:00
2004-06-18 02:16:08 +02:00
#
# 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;
2004-06-22 19:38:07 +02:00
#
# 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;
2004-06-25 10:37:43 +02:00
drop table t1;
#
# prepared EXPLAIN
#
create table t1
(
2005-05-05 14:31:18 +02:00
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),
bug#10466: Datatype "timestamp" displays "YYYYMMDDHHMMSS" irrespective of display sizes.
- Print warning that says display width is not supported for datatype TIMESTAMP, if user tries to create a TIMESTAMP column with display width.
- Use display width for TIMESTAMP only in type_timestamp test to make sure warning is displayed correctly.
mysql-test/include/ps_create.inc:
Reove all uses of display width in for TIMESTAMP columns, except in the type_timestamp test.
mysql-test/r/alias.result:
Reove all uses of display width in for TIMESTAMP columns, except in the type_timestamp test.
mysql-test/r/func_date_add.result:
Reove all uses of display width in for TIMESTAMP columns, except in the type_timestamp test.
mysql-test/r/func_str.result:
Reove all uses of display width in for TIMESTAMP columns, except in the type_timestamp test.
mysql-test/r/func_time.result:
Reove all uses of display width in for TIMESTAMP columns, except in the type_timestamp test.
mysql-test/r/group_by.result:
Reove all uses of display width in for TIMESTAMP columns, except in the type_timestamp test.
mysql-test/r/innodb.result:
Reove all uses of display width in for TIMESTAMP columns, except in the type_timestamp test.
mysql-test/r/ps.result:
Reove all uses of display width in for TIMESTAMP columns, except in the type_timestamp test.
mysql-test/r/ps_1general.result:
Reove all uses of display width in for TIMESTAMP columns, except in the type_timestamp test.
mysql-test/r/ps_2myisam.result:
Reove all uses of display width in for TIMESTAMP columns, except in the type_timestamp test.
mysql-test/r/ps_3innodb.result:
Reove all uses of display width in for TIMESTAMP columns, except in the type_timestamp test.
mysql-test/r/ps_4heap.result:
Reove all uses of display width in for TIMESTAMP columns, except in the type_timestamp test.
mysql-test/r/ps_5merge.result:
Reove all uses of display width in for TIMESTAMP columns, except in the type_timestamp test.
mysql-test/r/ps_6bdb.result:
Reove all uses of display width in for TIMESTAMP columns, except in the type_timestamp test.
mysql-test/r/ps_7ndb.result:
Reove all uses of display width in for TIMESTAMP columns, except in the type_timestamp test.
mysql-test/r/select.result:
Reove all uses of display width in for TIMESTAMP columns, except in the type_timestamp test.
mysql-test/r/type_timestamp.result:
When display width is used for a TIMESTAMP column a warning is printed that the display width will be ignored.
mysql-test/r/update.result:
Reove all uses of display width in for TIMESTAMP columns, except in the type_timestamp test.
mysql-test/t/alias.test:
Reove all uses of display width in for TIMESTAMP columns, except in the type_timestamp test.
mysql-test/t/func_date_add.test:
Reove all uses of display width in for TIMESTAMP columns, except in the type_timestamp test.
mysql-test/t/func_str.test:
Reove all uses of display width in for TIMESTAMP columns, except in the type_timestamp test.
mysql-test/t/func_time.test:
Reove all uses of display width in for TIMESTAMP columns, except in the type_timestamp test.
mysql-test/t/group_by.test:
Reove all uses of display width in for TIMESTAMP columns, except in the type_timestamp test.
mysql-test/t/innodb.test:
Reove all uses of display width in for TIMESTAMP columns, except in the type_timestamp test.
mysql-test/t/ps.test:
Reove all uses of display width in for TIMESTAMP columns, except in the type_timestamp test.
mysql-test/t/ps_4heap.test:
Reove all uses of display width in for TIMESTAMP columns, except in the type_timestamp test.
mysql-test/t/ps_5merge.test:
Reove all uses of display width in for TIMESTAMP columns, except in the type_timestamp test.
mysql-test/t/select.test:
Reove all uses of display width in for TIMESTAMP columns, except in the type_timestamp test.
mysql-test/t/update.test:
Reove all uses of display width in for TIMESTAMP columns, except in the type_timestamp test.
sql/share/errmsg.txt:
Correct swedish error message
sql/sql_parse.cc:
Print warning if datatype is TIMESTAMP and display width is used.
2005-06-20 12:09:00 +02:00
c13 date, c14 datetime, c15 timestamp, c16 time,
2005-05-05 14:31:18 +02:00
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')
2004-06-25 10:37:43 +02:00
) 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;
2004-06-25 17:33:31 +02:00
2004-06-25 14:16:00 +02:00
#
# 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;
2004-06-26 23:55:38 +02:00
deallocate prepare stmt1;
drop table t1;
#
# eq() for parameters
#
create table t1 (id int(10) unsigned NOT NULL default '0',
2005-05-05 14:31:18 +02:00
name varchar(64) NOT NULL default '',
PRIMARY KEY (id), UNIQUE KEY `name` (`name`));
2004-06-26 23:55:38 +02:00
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;
2004-06-25 14:16:00 +02:00
drop table t1;
2004-06-27 00:34:05 +02:00
#
# 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%'' ';
2004-09-16 20:13:24 +02:00
--replace_column 8 4294967295 12 # 13 # 14 #
2004-06-27 00:34:05 +02:00
execute stmt1;
2004-09-16 20:13:24 +02:00
--replace_column 8 4294967295 12 # 13 # 14 #
2004-06-27 00:34:05 +02:00
show table status from test like 't1%' ;
deallocate prepare stmt1 ;
drop table t1;
Fix for bug#4912 "mysqld crashs in case a statement is executed
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.
2004-08-21 00:02:46 +02:00
#
# Bug#4912 "mysqld crashs in case a statement is executed a second time":
2004-08-24 18:17:11 +02:00
# negation elimination should work once and not break prepared statements
Fix for bug#4912 "mysqld crashs in case a statement is executed
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.
2004-08-21 00:02:46 +02:00
#
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;
2004-08-24 18:17:11 +02:00
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
#
Fix for bug#4912 "mysqld crashs in case a statement is executed
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.
2004-08-21 00:02:46 +02:00
2004-08-24 18:17:11 +02:00
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;
2004-08-29 17:44:28 +02:00
#
# 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> `;
A fix and a test case for Bug#16365 "Prepared Statements: DoS with
too many open statements". The patch adds a new global variable
@@max_prepared_stmt_count. This variable limits the total number
of prepared statements in the server. The default value of
@@max_prepared_stmt_count is 16382. 16382 small statements
(a select against 3 tables with GROUP, ORDER and LIMIT) consume
100MB of RAM. Once this limit has been reached, the server will
refuse to prepare a new statement and return ER_UNKNOWN_ERROR
(unfortunately, we can't add new errors to 4.1 without breaking 5.0). The limit is changeable after startup
and can accept any value from 0 to 1 million. In case
the new value of the limit is less than the current
statement count, no new statements can be added, while the old
still can be used. Additionally, the current count of prepared
statements is now available through a global read-only variable
@@prepared_stmt_count.
mysql-test/r/ps.result:
Test results fixed (a test case for Bug#16365)
mysql-test/t/ps.test:
A test case for Bug#16365 "Prepared Statements: DoS with too many
open statements". Also fix statement leaks in other tests.
sql/mysql_priv.h:
Add declarations for new global variables.
sql/mysqld.cc:
Add definitions of max_prepared_stmt_count, prepared_stmt_count.
sql/set_var.cc:
Implement support for @@prepared_stmt_count and
@@max_prepared_stmt_count. Currently these variables are queried
without acquiring LOCK_prepared_stmt_count due to limitations of
the set_var/sys_var class design. Updates are, however, protected
with a lock.
sql/set_var.h:
New declarations to add support for @@max_prepared_stmt_count.
Implement a new class, where the lock to be used when updating
a variable is a parameter.
sql/sql_class.cc:
Add accounting of the total number of prepared statements in the
server to the methods of Statement_map.
sql/sql_class.h:
Add accounting of the total number of prepared statements in the
server to the methods of Statement_map.
sql/sql_prepare.cc:
Statement_map::insert will now send a message in case of an
error.
2006-04-07 21:37:06 +02:00
deallocate prepare `<60> `;
2004-08-29 17:44:28 +02:00
set names default;
2004-09-03 21:28:49 +02:00
#
# 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;
2004-09-17 23:10:09 +02:00
#
# 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;
2004-09-23 16:01:55 +02:00
#
# 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;
2004-10-08 00:21:19 +02:00
#
# 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;
A fix and test case for Bug#5987 "subselect in bool function
crashes server (prepared statements)": the bug was that all boolean
items always recovered its original arguments at statement cleanup
stage.
This collided with Item_subselect::select_transformer, which tries to
permanently change the item tree to use a transformed subselect instead of
original one.
So we had this call sequence for prepare:
mysql_stmt_prepare -> JOIN::prepare ->
Item_subselect::fix_fields -> the item tree gets transformed ->
Item_bool_rowready_func2::cleanup, item tree is recovered to original
state, while it shouldn't have been;
mysql_stmt_execute -> attempts to execute a broken tree -> crash.
Now instead of bluntly recovering all arguments of bool functions in
Item_bool_rowready_func2::cleanup, we recover only those
which were changed, and do it in one place.
There still would exist a possibility for a collision with subselect
tranformation, if permanent and temporary changes were performed at the
same stage.
But fortunately subselect transformation is always done first, so it
doesn't conflict with the optimization done by propogate_cond_constants.
Now we have:
mysql_stmt_prepare -> JOIN::prepare -> subselect transformation
permanently changes the tree -> cleanup doesn't recover anything,
because nothing was registered for recovery.
mysql_stmt_execute -> JOIN::prepare (the tree is already transformed,
so it doesn't change), JOIN::optimize ->
propogate_cond_constants -> temporary changes the item tree
with constants -> JOIN::execute -> cleanup ->
the changes done by propogate_cond_constants are recovered, as
they were registered for recovery.
mysql-test/r/ps.result:
Bug#5987: test results fixed.
mysql-test/t/ps.test:
A test for bug#5987 "subselect in bool function crashes server
(prepared statements)"
sql/item.cc:
resolve_const_item is now responsible to register all changes of the
item tree for recovery
sql/item.h:
resolve_const_item signagture changed
sql/item_cmpfunc.h:
Arguments of boolean functions are now recovered using the
centralized registry of THD.
sql/sql_class.cc:
It's crucial to add new items to the beginning of the recovery list,
so that the recovery is performed in LIFO mode: otherwise if we
change one node of a tree twice, it will be recovered to some intermediate
state.
sql/sql_select.cc:
change_cond_ref_to_const and propogate_cond_constants are now responsible
to register all changes of the item tree for recovery.
The recovery is done using the centralized THD registry of
changed tree items.
2004-10-10 00:39:22 +02:00
#
# 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;
2004-10-12 19:16:07 +02:00
#
# 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;
2006-10-11 13:53:56 +02:00
set @v=0;
2004-10-12 19:16:07 +02:00
--replace_column 1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 -
2006-10-11 13:53:56 +02:00
execute stmt using @v;
2004-10-12 19:16:07 +02:00
set @v=5;
2006-10-11 13:53:56 +02:00
--replace_column 1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 -
2004-10-12 19:16:07 +02:00
execute stmt using @v;
drop table t1;
deallocate prepare stmt;
2004-10-14 00:53:59 +02:00
#
# 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(),
2005-09-06 13:19:59 +02:00
cast(rand(10)*@precision as unsigned integer) from t1;
2004-10-14 00:53:59 +02:00
prepare stmt from
"select rand(),
2005-05-05 14:31:18 +02:00
cast(rand(10)*@precision as unsigned integer),
cast(rand(?)*@precision as unsigned integer) from t1";
2004-10-14 00:53:59 +02:00
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;
2004-10-22 12:47:35 +02:00
#
# 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;
2004-10-22 17:44:51 +02:00
#
# Test CREATE TABLE ... SELECT (Bug #6094)
#
create table t1 (a int);
insert into t1 values (1),(2),(3);
create table t2 select * from t1;
2004-10-22 20:55:49 +02:00
prepare stmt FROM 'create table t2 select * from t1';
2004-10-22 17:44:51 +02:00
drop table t2;
2004-10-22 20:55:49 +02:00
execute stmt;
2004-10-22 17:44:51 +02:00
drop table t2;
2004-10-22 20:55:49 +02:00
execute stmt;
2004-10-22 17:44:51 +02:00
--error 1050
2004-10-22 20:55:49 +02:00
execute stmt;
2004-10-22 17:44:51 +02:00
drop table t2;
2004-10-22 20:55:49 +02:00
execute stmt;
2004-10-22 17:44:51 +02:00
drop table t1,t2;
2004-10-22 20:55:49 +02:00
deallocate prepare stmt;
2004-10-22 20:51:16 +02:00
#
# 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();
2004-10-22 20:55:49 +02:00
deallocate prepare stmt;
drop table t1;
2004-10-23 02:30:27 +02:00
#
# 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;
2004-11-21 10:04:27 +01:00
#
# 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;
2004-12-08 22:37:17 +01:00
#
# 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;
2006-08-02 12:13:01 +02:00
#
2004-11-05 20:02:07 +01:00
#
2006-07-14 01:35:25 +02:00
# 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;
2004-11-05 20:02:07 +01:00
# 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');
prepare stmt FROM 'SELECT char_length (a) FROM t1';
2006-11-02 22:02:07 +01:00
-- error ER_SP_DOES_NOT_EXIST
prepare stmt2 FROM 'SELECT not_a_function (a) FROM t1';
2004-11-05 20:02:07 +01:00
drop table t1;
2004-11-22 21:33:15 +01:00
2005-03-02 17:00:48 +01:00
#
# 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;
2005-03-03 15:38:59 +01:00
2005-05-03 10:47:27 +02:00
#
# 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,
2005-05-05 14:31:18 +02:00
primary key (c1,c2), key c2 (c2), key c1 (c1));
2005-05-03 10:47:27 +02:00
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;
2005-05-03 17:32:29 +02:00
2005-05-05 10:55:09 +02:00
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;
Patch two (the final one) for Bug#7306 "the server side preparedStatement
error for LIMIT placeholder".
The patch adds grammar support for LIMIT ?, ? and changes the
type of ST_SELECT_LEX::select_limit,offset_limit from ha_rows to Item*,
so that it can point to Item_param.
mysql-test/include/ps_modify.inc:
Fix existing tests: now LIMIT can contain placeholders.
mysql-test/include/ps_query.inc:
Fix existing tests: now LIMIT can contain placeholders.
mysql-test/r/ps.result:
Add basic test coverage for LIMIT ?, ? and fix test results.
mysql-test/r/ps_2myisam.result:
Fix test results: now LIMIT can contain placeholders.
mysql-test/r/ps_3innodb.result:
Fix test results: now LIMIT can contain placeholders.
mysql-test/r/ps_4heap.result:
Fix test results: now LIMIT can contain placeholders.
mysql-test/r/ps_5merge.result:
Fix test results: now LIMIT can contain placeholders.
mysql-test/r/ps_6bdb.result:
Fix test results: now LIMIT can contain placeholders.
mysql-test/r/ps_7ndb.result:
Fix test results: now LIMIT can contain placeholders.
mysql-test/t/ps.test:
Add basic test coverage for LIMIT ?, ?.
sql/item.h:
Add a short-cut for (ulonglong) val_int() to Item.
Add a constructor to Item_int() that accepts ulonglong.
Simplify Item_uint constructor by using the c-tor above.
sql/item_subselect.cc:
Now select_limit has type Item *.
We can safely create an Item in Item_exists_subselect::fix_length_and_dec():
it will be allocated in runtime memory root and freed in the end of
execution.
sql/sp_head.cc:
Add a special initalization state for stored procedures to
be able to easily distinguish the first execution of a stored procedure
from prepared statement prepare.
sql/sql_class.h:
Introduce new state 'INITIALIZED_FOR_SP' to be able to easily distinguish
the first execution of a stored procedure from prepared statement prepare.
sql/sql_derived.cc:
- use unit->set_limit() to set unit->select_limit_cnt, offset_limit_cnt
evreryplace. Add a warning about use of set_limit in
mysql_derived_filling.
sql/sql_error.cc:
- use unit->set_limit() to set unit->select_limit_cnt, offset_limit_cnt
evreryplace.
- this change is also aware of bug#11095 "show warnings limit 0 returns
all rows instead of zero rows", so the one who merges the bugfix from
4.1 can use local version of sql_error.cc.
sql/sql_handler.cc:
- use unit->set_limit() to initalize
unit->select_limit_cnt,offset_limit_cnt everyplace.
sql/sql_lex.cc:
Now ST_SELECT_LEX::select_limit, offset_limit have type Item *
sql/sql_lex.h:
Now ST_SELECT_LEX::select_limit, offset_limit have type Item *
sql/sql_parse.cc:
- use unit->set_limit() to initalize
unit->select_limit_cnt,offset_limit_cnt everyplace.
- we can create an Item_int to set global limit of a statement:
it will be created in the runtime mem root and freed in the end of
execution.
sql/sql_repl.cc:
Use unit->set_limit to initialize limits.
sql/sql_select.cc:
- select_limit is now Item* so the proper way to check for default value
is to compare it with NULL.
sql/sql_union.cc:
Evaluate offset_limit_cnt using the new type of ST_SELECT_LEX::offset_limit
sql/sql_view.cc:
Now ST_SELECT_LEX::select_limit, offset_limit have type Item *
sql/sql_yacc.yy:
Add grammar support for LIMIT ?, ? clause.
2005-06-07 12:11:36 +02:00
2005-06-20 14:07:00 +02:00
#
# 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;
2005-07-13 15:38:55 +02:00
#
# 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;
2005-07-13 16:05:57 +02:00
deallocate prepare stmt;
drop table t1, t2, t3, t4;
2005-07-13 21:43:46 +02:00
#
# 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;
2005-07-13 22:15:23 +02:00
#
2005-07-14 22:01:49 +02:00
# 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";
2005-07-15 00:11:07 +02:00
--disable_ps_protocol
2005-07-14 22:01:49 +02:00
--error 1064
select ?;
--error 1064
select ??;
--error 1064
select ? from t1;
2005-07-15 00:11:07 +02:00
--enable_ps_protocol
2005-07-14 22:01:49 +02:00
drop table t1;
2005-07-16 01:29:13 +02:00
#
# 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;
2005-07-28 02:22:47 +02:00
2005-11-25 11:25:31 +01:00
#
# 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;
2006-01-14 02:55:07 +01:00
#
# 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;
2006-02-21 17:52:20 +01:00
#
# 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;
2006-04-07 20:26:25 +02:00
#
# 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;
A fix and a test case for Bug#16365 "Prepared Statements: DoS with
too many open statements". The patch adds a new global variable
@@max_prepared_stmt_count. This variable limits the total number
of prepared statements in the server. The default value of
@@max_prepared_stmt_count is 16382. 16382 small statements
(a select against 3 tables with GROUP, ORDER and LIMIT) consume
100MB of RAM. Once this limit has been reached, the server will
refuse to prepare a new statement and return ER_UNKNOWN_ERROR
(unfortunately, we can't add new errors to 4.1 without breaking 5.0). The limit is changeable after startup
and can accept any value from 0 to 1 million. In case
the new value of the limit is less than the current
statement count, no new statements can be added, while the old
still can be used. Additionally, the current count of prepared
statements is now available through a global read-only variable
@@prepared_stmt_count.
mysql-test/r/ps.result:
Test results fixed (a test case for Bug#16365)
mysql-test/t/ps.test:
A test case for Bug#16365 "Prepared Statements: DoS with too many
open statements". Also fix statement leaks in other tests.
sql/mysql_priv.h:
Add declarations for new global variables.
sql/mysqld.cc:
Add definitions of max_prepared_stmt_count, prepared_stmt_count.
sql/set_var.cc:
Implement support for @@prepared_stmt_count and
@@max_prepared_stmt_count. Currently these variables are queried
without acquiring LOCK_prepared_stmt_count due to limitations of
the set_var/sys_var class design. Updates are, however, protected
with a lock.
sql/set_var.h:
New declarations to add support for @@max_prepared_stmt_count.
Implement a new class, where the lock to be used when updating
a variable is a parameter.
sql/sql_class.cc:
Add accounting of the total number of prepared statements in the
server to the methods of Statement_map.
sql/sql_class.h:
Add accounting of the total number of prepared statements in the
server to the methods of Statement_map.
sql/sql_prepare.cc:
Statement_map::insert will now send a message in case of an
error.
2006-04-07 21:37:06 +02:00
#
# Bug#16365 Prepared Statements: DoS with too many open statements
# Check that the limit @@max_prpeared_stmt_count works.
#
2006-11-21 14:49:18 +01:00
# This is also the test for bug#23159 prepared_stmt_count should be
# status variable.
#
A fix and a test case for Bug#16365 "Prepared Statements: DoS with
too many open statements". The patch adds a new global variable
@@max_prepared_stmt_count. This variable limits the total number
of prepared statements in the server. The default value of
@@max_prepared_stmt_count is 16382. 16382 small statements
(a select against 3 tables with GROUP, ORDER and LIMIT) consume
100MB of RAM. Once this limit has been reached, the server will
refuse to prepare a new statement and return ER_UNKNOWN_ERROR
(unfortunately, we can't add new errors to 4.1 without breaking 5.0). The limit is changeable after startup
and can accept any value from 0 to 1 million. In case
the new value of the limit is less than the current
statement count, no new statements can be added, while the old
still can be used. Additionally, the current count of prepared
statements is now available through a global read-only variable
@@prepared_stmt_count.
mysql-test/r/ps.result:
Test results fixed (a test case for Bug#16365)
mysql-test/t/ps.test:
A test case for Bug#16365 "Prepared Statements: DoS with too many
open statements". Also fix statement leaks in other tests.
sql/mysql_priv.h:
Add declarations for new global variables.
sql/mysqld.cc:
Add definitions of max_prepared_stmt_count, prepared_stmt_count.
sql/set_var.cc:
Implement support for @@prepared_stmt_count and
@@max_prepared_stmt_count. Currently these variables are queried
without acquiring LOCK_prepared_stmt_count due to limitations of
the set_var/sys_var class design. Updates are, however, protected
with a lock.
sql/set_var.h:
New declarations to add support for @@max_prepared_stmt_count.
Implement a new class, where the lock to be used when updating
a variable is a parameter.
sql/sql_class.cc:
Add accounting of the total number of prepared statements in the
server to the methods of Statement_map.
sql/sql_class.h:
Add accounting of the total number of prepared statements in the
server to the methods of Statement_map.
sql/sql_prepare.cc:
Statement_map::insert will now send a message in case of an
error.
2006-04-07 21:37:06 +02:00
# 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
#
2006-11-21 14:49:18 +01:00
# A. Check that the new variables are present in SHOW VARIABLES and
# SHOW STATUS lists.
A fix and a test case for Bug#16365 "Prepared Statements: DoS with
too many open statements". The patch adds a new global variable
@@max_prepared_stmt_count. This variable limits the total number
of prepared statements in the server. The default value of
@@max_prepared_stmt_count is 16382. 16382 small statements
(a select against 3 tables with GROUP, ORDER and LIMIT) consume
100MB of RAM. Once this limit has been reached, the server will
refuse to prepare a new statement and return ER_UNKNOWN_ERROR
(unfortunately, we can't add new errors to 4.1 without breaking 5.0). The limit is changeable after startup
and can accept any value from 0 to 1 million. In case
the new value of the limit is less than the current
statement count, no new statements can be added, while the old
still can be used. Additionally, the current count of prepared
statements is now available through a global read-only variable
@@prepared_stmt_count.
mysql-test/r/ps.result:
Test results fixed (a test case for Bug#16365)
mysql-test/t/ps.test:
A test case for Bug#16365 "Prepared Statements: DoS with too many
open statements". Also fix statement leaks in other tests.
sql/mysql_priv.h:
Add declarations for new global variables.
sql/mysqld.cc:
Add definitions of max_prepared_stmt_count, prepared_stmt_count.
sql/set_var.cc:
Implement support for @@prepared_stmt_count and
@@max_prepared_stmt_count. Currently these variables are queried
without acquiring LOCK_prepared_stmt_count due to limitations of
the set_var/sys_var class design. Updates are, however, protected
with a lock.
sql/set_var.h:
New declarations to add support for @@max_prepared_stmt_count.
Implement a new class, where the lock to be used when updating
a variable is a parameter.
sql/sql_class.cc:
Add accounting of the total number of prepared statements in the
server to the methods of Statement_map.
sql/sql_class.h:
Add accounting of the total number of prepared statements in the
server to the methods of Statement_map.
sql/sql_prepare.cc:
Statement_map::insert will now send a message in case of an
error.
2006-04-07 21:37:06 +02:00
#
show variables like 'max_prepared_stmt_count';
2006-11-21 14:49:18 +01:00
show status like 'prepared_stmt_count';
A fix and a test case for Bug#16365 "Prepared Statements: DoS with
too many open statements". The patch adds a new global variable
@@max_prepared_stmt_count. This variable limits the total number
of prepared statements in the server. The default value of
@@max_prepared_stmt_count is 16382. 16382 small statements
(a select against 3 tables with GROUP, ORDER and LIMIT) consume
100MB of RAM. Once this limit has been reached, the server will
refuse to prepare a new statement and return ER_UNKNOWN_ERROR
(unfortunately, we can't add new errors to 4.1 without breaking 5.0). The limit is changeable after startup
and can accept any value from 0 to 1 million. In case
the new value of the limit is less than the current
statement count, no new statements can be added, while the old
still can be used. Additionally, the current count of prepared
statements is now available through a global read-only variable
@@prepared_stmt_count.
mysql-test/r/ps.result:
Test results fixed (a test case for Bug#16365)
mysql-test/t/ps.test:
A test case for Bug#16365 "Prepared Statements: DoS with too many
open statements". Also fix statement leaks in other tests.
sql/mysql_priv.h:
Add declarations for new global variables.
sql/mysqld.cc:
Add definitions of max_prepared_stmt_count, prepared_stmt_count.
sql/set_var.cc:
Implement support for @@prepared_stmt_count and
@@max_prepared_stmt_count. Currently these variables are queried
without acquiring LOCK_prepared_stmt_count due to limitations of
the set_var/sys_var class design. Updates are, however, protected
with a lock.
sql/set_var.h:
New declarations to add support for @@max_prepared_stmt_count.
Implement a new class, where the lock to be used when updating
a variable is a parameter.
sql/sql_class.cc:
Add accounting of the total number of prepared statements in the
server to the methods of Statement_map.
sql/sql_class.h:
Add accounting of the total number of prepared statements in the
server to the methods of Statement_map.
sql/sql_prepare.cc:
Statement_map::insert will now send a message in case of an
error.
2006-04-07 21:37:06 +02:00
#
2006-11-21 14:49:18 +01:00
# B. Check that the new system variable is selectable.
A fix and a test case for Bug#16365 "Prepared Statements: DoS with
too many open statements". The patch adds a new global variable
@@max_prepared_stmt_count. This variable limits the total number
of prepared statements in the server. The default value of
@@max_prepared_stmt_count is 16382. 16382 small statements
(a select against 3 tables with GROUP, ORDER and LIMIT) consume
100MB of RAM. Once this limit has been reached, the server will
refuse to prepare a new statement and return ER_UNKNOWN_ERROR
(unfortunately, we can't add new errors to 4.1 without breaking 5.0). The limit is changeable after startup
and can accept any value from 0 to 1 million. In case
the new value of the limit is less than the current
statement count, no new statements can be added, while the old
still can be used. Additionally, the current count of prepared
statements is now available through a global read-only variable
@@prepared_stmt_count.
mysql-test/r/ps.result:
Test results fixed (a test case for Bug#16365)
mysql-test/t/ps.test:
A test case for Bug#16365 "Prepared Statements: DoS with too many
open statements". Also fix statement leaks in other tests.
sql/mysql_priv.h:
Add declarations for new global variables.
sql/mysqld.cc:
Add definitions of max_prepared_stmt_count, prepared_stmt_count.
sql/set_var.cc:
Implement support for @@prepared_stmt_count and
@@max_prepared_stmt_count. Currently these variables are queried
without acquiring LOCK_prepared_stmt_count due to limitations of
the set_var/sys_var class design. Updates are, however, protected
with a lock.
sql/set_var.h:
New declarations to add support for @@max_prepared_stmt_count.
Implement a new class, where the lock to be used when updating
a variable is a parameter.
sql/sql_class.cc:
Add accounting of the total number of prepared statements in the
server to the methods of Statement_map.
sql/sql_class.h:
Add accounting of the total number of prepared statements in the
server to the methods of Statement_map.
sql/sql_prepare.cc:
Statement_map::insert will now send a message in case of an
error.
2006-04-07 21:37:06 +02:00
#
2006-11-21 14:49:18 +01:00
select @@max_prepared_stmt_count;
A fix and a test case for Bug#16365 "Prepared Statements: DoS with
too many open statements". The patch adds a new global variable
@@max_prepared_stmt_count. This variable limits the total number
of prepared statements in the server. The default value of
@@max_prepared_stmt_count is 16382. 16382 small statements
(a select against 3 tables with GROUP, ORDER and LIMIT) consume
100MB of RAM. Once this limit has been reached, the server will
refuse to prepare a new statement and return ER_UNKNOWN_ERROR
(unfortunately, we can't add new errors to 4.1 without breaking 5.0). The limit is changeable after startup
and can accept any value from 0 to 1 million. In case
the new value of the limit is less than the current
statement count, no new statements can be added, while the old
still can be used. Additionally, the current count of prepared
statements is now available through a global read-only variable
@@prepared_stmt_count.
mysql-test/r/ps.result:
Test results fixed (a test case for Bug#16365)
mysql-test/t/ps.test:
A test case for Bug#16365 "Prepared Statements: DoS with too many
open statements". Also fix statement leaks in other tests.
sql/mysql_priv.h:
Add declarations for new global variables.
sql/mysqld.cc:
Add definitions of max_prepared_stmt_count, prepared_stmt_count.
sql/set_var.cc:
Implement support for @@prepared_stmt_count and
@@max_prepared_stmt_count. Currently these variables are queried
without acquiring LOCK_prepared_stmt_count due to limitations of
the set_var/sys_var class design. Updates are, however, protected
with a lock.
sql/set_var.h:
New declarations to add support for @@max_prepared_stmt_count.
Implement a new class, where the lock to be used when updating
a variable is a parameter.
sql/sql_class.cc:
Add accounting of the total number of prepared statements in the
server to the methods of Statement_map.
sql/sql_class.h:
Add accounting of the total number of prepared statements in the
server to the methods of Statement_map.
sql/sql_prepare.cc:
Statement_map::insert will now send a message in case of an
error.
2006-04-07 21:37:06 +02:00
#
2006-11-21 14:49:18 +01:00
# C. Check that max_prepared_stmt_count is settable (global only).
A fix and a test case for Bug#16365 "Prepared Statements: DoS with
too many open statements". The patch adds a new global variable
@@max_prepared_stmt_count. This variable limits the total number
of prepared statements in the server. The default value of
@@max_prepared_stmt_count is 16382. 16382 small statements
(a select against 3 tables with GROUP, ORDER and LIMIT) consume
100MB of RAM. Once this limit has been reached, the server will
refuse to prepare a new statement and return ER_UNKNOWN_ERROR
(unfortunately, we can't add new errors to 4.1 without breaking 5.0). The limit is changeable after startup
and can accept any value from 0 to 1 million. In case
the new value of the limit is less than the current
statement count, no new statements can be added, while the old
still can be used. Additionally, the current count of prepared
statements is now available through a global read-only variable
@@prepared_stmt_count.
mysql-test/r/ps.result:
Test results fixed (a test case for Bug#16365)
mysql-test/t/ps.test:
A test case for Bug#16365 "Prepared Statements: DoS with too many
open statements". Also fix statement leaks in other tests.
sql/mysql_priv.h:
Add declarations for new global variables.
sql/mysqld.cc:
Add definitions of max_prepared_stmt_count, prepared_stmt_count.
sql/set_var.cc:
Implement support for @@prepared_stmt_count and
@@max_prepared_stmt_count. Currently these variables are queried
without acquiring LOCK_prepared_stmt_count due to limitations of
the set_var/sys_var class design. Updates are, however, protected
with a lock.
sql/set_var.h:
New declarations to add support for @@max_prepared_stmt_count.
Implement a new class, where the lock to be used when updating
a variable is a parameter.
sql/sql_class.cc:
Add accounting of the total number of prepared statements in the
server to the methods of Statement_map.
sql/sql_class.h:
Add accounting of the total number of prepared statements in the
server to the methods of Statement_map.
sql/sql_prepare.cc:
Statement_map::insert will now send a message in case of an
error.
2006-04-07 21:37:06 +02:00
#
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;
2006-04-12 23:46:44 +02:00
--error ER_GLOBAL_VARIABLE
A fix and a test case for Bug#16365 "Prepared Statements: DoS with
too many open statements". The patch adds a new global variable
@@max_prepared_stmt_count. This variable limits the total number
of prepared statements in the server. The default value of
@@max_prepared_stmt_count is 16382. 16382 small statements
(a select against 3 tables with GROUP, ORDER and LIMIT) consume
100MB of RAM. Once this limit has been reached, the server will
refuse to prepare a new statement and return ER_UNKNOWN_ERROR
(unfortunately, we can't add new errors to 4.1 without breaking 5.0). The limit is changeable after startup
and can accept any value from 0 to 1 million. In case
the new value of the limit is less than the current
statement count, no new statements can be added, while the old
still can be used. Additionally, the current count of prepared
statements is now available through a global read-only variable
@@prepared_stmt_count.
mysql-test/r/ps.result:
Test results fixed (a test case for Bug#16365)
mysql-test/t/ps.test:
A test case for Bug#16365 "Prepared Statements: DoS with too many
open statements". Also fix statement leaks in other tests.
sql/mysql_priv.h:
Add declarations for new global variables.
sql/mysqld.cc:
Add definitions of max_prepared_stmt_count, prepared_stmt_count.
sql/set_var.cc:
Implement support for @@prepared_stmt_count and
@@max_prepared_stmt_count. Currently these variables are queried
without acquiring LOCK_prepared_stmt_count due to limitations of
the set_var/sys_var class design. Updates are, however, protected
with a lock.
sql/set_var.h:
New declarations to add support for @@max_prepared_stmt_count.
Implement a new class, where the lock to be used when updating
a variable is a parameter.
sql/sql_class.cc:
Add accounting of the total number of prepared statements in the
server to the methods of Statement_map.
sql/sql_class.h:
Add accounting of the total number of prepared statements in the
server to the methods of Statement_map.
sql/sql_prepare.cc:
Statement_map::insert will now send a message in case of an
error.
2006-04-07 21:37:06 +02:00
set @@max_prepared_stmt_count=1;
2006-04-12 23:46:44 +02:00
--error ER_GLOBAL_VARIABLE
A fix and a test case for Bug#16365 "Prepared Statements: DoS with
too many open statements". The patch adds a new global variable
@@max_prepared_stmt_count. This variable limits the total number
of prepared statements in the server. The default value of
@@max_prepared_stmt_count is 16382. 16382 small statements
(a select against 3 tables with GROUP, ORDER and LIMIT) consume
100MB of RAM. Once this limit has been reached, the server will
refuse to prepare a new statement and return ER_UNKNOWN_ERROR
(unfortunately, we can't add new errors to 4.1 without breaking 5.0). The limit is changeable after startup
and can accept any value from 0 to 1 million. In case
the new value of the limit is less than the current
statement count, no new statements can be added, while the old
still can be used. Additionally, the current count of prepared
statements is now available through a global read-only variable
@@prepared_stmt_count.
mysql-test/r/ps.result:
Test results fixed (a test case for Bug#16365)
mysql-test/t/ps.test:
A test case for Bug#16365 "Prepared Statements: DoS with too many
open statements". Also fix statement leaks in other tests.
sql/mysql_priv.h:
Add declarations for new global variables.
sql/mysqld.cc:
Add definitions of max_prepared_stmt_count, prepared_stmt_count.
sql/set_var.cc:
Implement support for @@prepared_stmt_count and
@@max_prepared_stmt_count. Currently these variables are queried
without acquiring LOCK_prepared_stmt_count due to limitations of
the set_var/sys_var class design. Updates are, however, protected
with a lock.
sql/set_var.h:
New declarations to add support for @@max_prepared_stmt_count.
Implement a new class, where the lock to be used when updating
a variable is a parameter.
sql/sql_class.cc:
Add accounting of the total number of prepared statements in the
server to the methods of Statement_map.
sql/sql_class.h:
Add accounting of the total number of prepared statements in the
server to the methods of Statement_map.
sql/sql_prepare.cc:
Statement_map::insert will now send a message in case of an
error.
2006-04-07 21:37:06 +02:00
set max_prepared_stmt_count=1;
2006-04-12 23:46:44 +02:00
--error ER_GLOBAL_VARIABLE
A fix and a test case for Bug#16365 "Prepared Statements: DoS with
too many open statements". The patch adds a new global variable
@@max_prepared_stmt_count. This variable limits the total number
of prepared statements in the server. The default value of
@@max_prepared_stmt_count is 16382. 16382 small statements
(a select against 3 tables with GROUP, ORDER and LIMIT) consume
100MB of RAM. Once this limit has been reached, the server will
refuse to prepare a new statement and return ER_UNKNOWN_ERROR
(unfortunately, we can't add new errors to 4.1 without breaking 5.0). The limit is changeable after startup
and can accept any value from 0 to 1 million. In case
the new value of the limit is less than the current
statement count, no new statements can be added, while the old
still can be used. Additionally, the current count of prepared
statements is now available through a global read-only variable
@@prepared_stmt_count.
mysql-test/r/ps.result:
Test results fixed (a test case for Bug#16365)
mysql-test/t/ps.test:
A test case for Bug#16365 "Prepared Statements: DoS with too many
open statements". Also fix statement leaks in other tests.
sql/mysql_priv.h:
Add declarations for new global variables.
sql/mysqld.cc:
Add definitions of max_prepared_stmt_count, prepared_stmt_count.
sql/set_var.cc:
Implement support for @@prepared_stmt_count and
@@max_prepared_stmt_count. Currently these variables are queried
without acquiring LOCK_prepared_stmt_count due to limitations of
the set_var/sys_var class design. Updates are, however, protected
with a lock.
sql/set_var.h:
New declarations to add support for @@max_prepared_stmt_count.
Implement a new class, where the lock to be used when updating
a variable is a parameter.
sql/sql_class.cc:
Add accounting of the total number of prepared statements in the
server to the methods of Statement_map.
sql/sql_class.h:
Add accounting of the total number of prepared statements in the
server to the methods of Statement_map.
sql/sql_prepare.cc:
Statement_map::insert will now send a message in case of an
error.
2006-04-07 21:37:06 +02:00
set local max_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;
2006-11-21 14:49:18 +01:00
select @@max_prepared_stmt_count;
show status like 'prepared_stmt_count';
2006-04-12 23:46:44 +02:00
--error ER_MAX_PREPARED_STMT_COUNT_REACHED
A fix and a test case for Bug#16365 "Prepared Statements: DoS with
too many open statements". The patch adds a new global variable
@@max_prepared_stmt_count. This variable limits the total number
of prepared statements in the server. The default value of
@@max_prepared_stmt_count is 16382. 16382 small statements
(a select against 3 tables with GROUP, ORDER and LIMIT) consume
100MB of RAM. Once this limit has been reached, the server will
refuse to prepare a new statement and return ER_UNKNOWN_ERROR
(unfortunately, we can't add new errors to 4.1 without breaking 5.0). The limit is changeable after startup
and can accept any value from 0 to 1 million. In case
the new value of the limit is less than the current
statement count, no new statements can be added, while the old
still can be used. Additionally, the current count of prepared
statements is now available through a global read-only variable
@@prepared_stmt_count.
mysql-test/r/ps.result:
Test results fixed (a test case for Bug#16365)
mysql-test/t/ps.test:
A test case for Bug#16365 "Prepared Statements: DoS with too many
open statements". Also fix statement leaks in other tests.
sql/mysql_priv.h:
Add declarations for new global variables.
sql/mysqld.cc:
Add definitions of max_prepared_stmt_count, prepared_stmt_count.
sql/set_var.cc:
Implement support for @@prepared_stmt_count and
@@max_prepared_stmt_count. Currently these variables are queried
without acquiring LOCK_prepared_stmt_count due to limitations of
the set_var/sys_var class design. Updates are, however, protected
with a lock.
sql/set_var.h:
New declarations to add support for @@max_prepared_stmt_count.
Implement a new class, where the lock to be used when updating
a variable is a parameter.
sql/sql_class.cc:
Add accounting of the total number of prepared statements in the
server to the methods of Statement_map.
sql/sql_class.h:
Add accounting of the total number of prepared statements in the
server to the methods of Statement_map.
sql/sql_prepare.cc:
Statement_map::insert will now send a message in case of an
error.
2006-04-07 21:37:06 +02:00
prepare stmt from "select 1";
2006-11-21 14:49:18 +01:00
show status like 'prepared_stmt_count';
A fix and a test case for Bug#16365 "Prepared Statements: DoS with
too many open statements". The patch adds a new global variable
@@max_prepared_stmt_count. This variable limits the total number
of prepared statements in the server. The default value of
@@max_prepared_stmt_count is 16382. 16382 small statements
(a select against 3 tables with GROUP, ORDER and LIMIT) consume
100MB of RAM. Once this limit has been reached, the server will
refuse to prepare a new statement and return ER_UNKNOWN_ERROR
(unfortunately, we can't add new errors to 4.1 without breaking 5.0). The limit is changeable after startup
and can accept any value from 0 to 1 million. In case
the new value of the limit is less than the current
statement count, no new statements can be added, while the old
still can be used. Additionally, the current count of prepared
statements is now available through a global read-only variable
@@prepared_stmt_count.
mysql-test/r/ps.result:
Test results fixed (a test case for Bug#16365)
mysql-test/t/ps.test:
A test case for Bug#16365 "Prepared Statements: DoS with too many
open statements". Also fix statement leaks in other tests.
sql/mysql_priv.h:
Add declarations for new global variables.
sql/mysqld.cc:
Add definitions of max_prepared_stmt_count, prepared_stmt_count.
sql/set_var.cc:
Implement support for @@prepared_stmt_count and
@@max_prepared_stmt_count. Currently these variables are queried
without acquiring LOCK_prepared_stmt_count due to limitations of
the set_var/sys_var class design. Updates are, however, protected
with a lock.
sql/set_var.h:
New declarations to add support for @@max_prepared_stmt_count.
Implement a new class, where the lock to be used when updating
a variable is a parameter.
sql/sql_class.cc:
Add accounting of the total number of prepared statements in the
server to the methods of Statement_map.
sql/sql_class.h:
Add accounting of the total number of prepared statements in the
server to the methods of Statement_map.
sql/sql_prepare.cc:
Statement_map::insert will now send a message in case of an
error.
2006-04-07 21:37:06 +02:00
set global max_prepared_stmt_count=1;
prepare stmt from "select 1";
2006-11-21 14:49:18 +01:00
show status like 'prepared_stmt_count';
2006-04-12 23:46:44 +02:00
--error ER_MAX_PREPARED_STMT_COUNT_REACHED
A fix and a test case for Bug#16365 "Prepared Statements: DoS with
too many open statements". The patch adds a new global variable
@@max_prepared_stmt_count. This variable limits the total number
of prepared statements in the server. The default value of
@@max_prepared_stmt_count is 16382. 16382 small statements
(a select against 3 tables with GROUP, ORDER and LIMIT) consume
100MB of RAM. Once this limit has been reached, the server will
refuse to prepare a new statement and return ER_UNKNOWN_ERROR
(unfortunately, we can't add new errors to 4.1 without breaking 5.0). The limit is changeable after startup
and can accept any value from 0 to 1 million. In case
the new value of the limit is less than the current
statement count, no new statements can be added, while the old
still can be used. Additionally, the current count of prepared
statements is now available through a global read-only variable
@@prepared_stmt_count.
mysql-test/r/ps.result:
Test results fixed (a test case for Bug#16365)
mysql-test/t/ps.test:
A test case for Bug#16365 "Prepared Statements: DoS with too many
open statements". Also fix statement leaks in other tests.
sql/mysql_priv.h:
Add declarations for new global variables.
sql/mysqld.cc:
Add definitions of max_prepared_stmt_count, prepared_stmt_count.
sql/set_var.cc:
Implement support for @@prepared_stmt_count and
@@max_prepared_stmt_count. Currently these variables are queried
without acquiring LOCK_prepared_stmt_count due to limitations of
the set_var/sys_var class design. Updates are, however, protected
with a lock.
sql/set_var.h:
New declarations to add support for @@max_prepared_stmt_count.
Implement a new class, where the lock to be used when updating
a variable is a parameter.
sql/sql_class.cc:
Add accounting of the total number of prepared statements in the
server to the methods of Statement_map.
sql/sql_class.h:
Add accounting of the total number of prepared statements in the
server to the methods of Statement_map.
sql/sql_prepare.cc:
Statement_map::insert will now send a message in case of an
error.
2006-04-07 21:37:06 +02:00
prepare stmt1 from "select 1";
2006-11-21 14:49:18 +01:00
show status like 'prepared_stmt_count';
A fix and a test case for Bug#16365 "Prepared Statements: DoS with
too many open statements". The patch adds a new global variable
@@max_prepared_stmt_count. This variable limits the total number
of prepared statements in the server. The default value of
@@max_prepared_stmt_count is 16382. 16382 small statements
(a select against 3 tables with GROUP, ORDER and LIMIT) consume
100MB of RAM. Once this limit has been reached, the server will
refuse to prepare a new statement and return ER_UNKNOWN_ERROR
(unfortunately, we can't add new errors to 4.1 without breaking 5.0). The limit is changeable after startup
and can accept any value from 0 to 1 million. In case
the new value of the limit is less than the current
statement count, no new statements can be added, while the old
still can be used. Additionally, the current count of prepared
statements is now available through a global read-only variable
@@prepared_stmt_count.
mysql-test/r/ps.result:
Test results fixed (a test case for Bug#16365)
mysql-test/t/ps.test:
A test case for Bug#16365 "Prepared Statements: DoS with too many
open statements". Also fix statement leaks in other tests.
sql/mysql_priv.h:
Add declarations for new global variables.
sql/mysqld.cc:
Add definitions of max_prepared_stmt_count, prepared_stmt_count.
sql/set_var.cc:
Implement support for @@prepared_stmt_count and
@@max_prepared_stmt_count. Currently these variables are queried
without acquiring LOCK_prepared_stmt_count due to limitations of
the set_var/sys_var class design. Updates are, however, protected
with a lock.
sql/set_var.h:
New declarations to add support for @@max_prepared_stmt_count.
Implement a new class, where the lock to be used when updating
a variable is a parameter.
sql/sql_class.cc:
Add accounting of the total number of prepared statements in the
server to the methods of Statement_map.
sql/sql_class.h:
Add accounting of the total number of prepared statements in the
server to the methods of Statement_map.
sql/sql_prepare.cc:
Statement_map::insert will now send a message in case of an
error.
2006-04-07 21:37:06 +02:00
deallocate prepare stmt;
2006-11-21 14:49:18 +01:00
show status like 'prepared_stmt_count';
A fix and a test case for Bug#16365 "Prepared Statements: DoS with
too many open statements". The patch adds a new global variable
@@max_prepared_stmt_count. This variable limits the total number
of prepared statements in the server. The default value of
@@max_prepared_stmt_count is 16382. 16382 small statements
(a select against 3 tables with GROUP, ORDER and LIMIT) consume
100MB of RAM. Once this limit has been reached, the server will
refuse to prepare a new statement and return ER_UNKNOWN_ERROR
(unfortunately, we can't add new errors to 4.1 without breaking 5.0). The limit is changeable after startup
and can accept any value from 0 to 1 million. In case
the new value of the limit is less than the current
statement count, no new statements can be added, while the old
still can be used. Additionally, the current count of prepared
statements is now available through a global read-only variable
@@prepared_stmt_count.
mysql-test/r/ps.result:
Test results fixed (a test case for Bug#16365)
mysql-test/t/ps.test:
A test case for Bug#16365 "Prepared Statements: DoS with too many
open statements". Also fix statement leaks in other tests.
sql/mysql_priv.h:
Add declarations for new global variables.
sql/mysqld.cc:
Add definitions of max_prepared_stmt_count, prepared_stmt_count.
sql/set_var.cc:
Implement support for @@prepared_stmt_count and
@@max_prepared_stmt_count. Currently these variables are queried
without acquiring LOCK_prepared_stmt_count due to limitations of
the set_var/sys_var class design. Updates are, however, protected
with a lock.
sql/set_var.h:
New declarations to add support for @@max_prepared_stmt_count.
Implement a new class, where the lock to be used when updating
a variable is a parameter.
sql/sql_class.cc:
Add accounting of the total number of prepared statements in the
server to the methods of Statement_map.
sql/sql_class.h:
Add accounting of the total number of prepared statements in the
server to the methods of Statement_map.
sql/sql_prepare.cc:
Statement_map::insert will now send a message in case of an
error.
2006-04-07 21:37:06 +02:00
#
# E. Check that we can prepare a statement with the same name
# successfully, without hitting the limit.
#
prepare stmt from "select 1";
2006-11-21 14:49:18 +01:00
show status like 'prepared_stmt_count';
A fix and a test case for Bug#16365 "Prepared Statements: DoS with
too many open statements". The patch adds a new global variable
@@max_prepared_stmt_count. This variable limits the total number
of prepared statements in the server. The default value of
@@max_prepared_stmt_count is 16382. 16382 small statements
(a select against 3 tables with GROUP, ORDER and LIMIT) consume
100MB of RAM. Once this limit has been reached, the server will
refuse to prepare a new statement and return ER_UNKNOWN_ERROR
(unfortunately, we can't add new errors to 4.1 without breaking 5.0). The limit is changeable after startup
and can accept any value from 0 to 1 million. In case
the new value of the limit is less than the current
statement count, no new statements can be added, while the old
still can be used. Additionally, the current count of prepared
statements is now available through a global read-only variable
@@prepared_stmt_count.
mysql-test/r/ps.result:
Test results fixed (a test case for Bug#16365)
mysql-test/t/ps.test:
A test case for Bug#16365 "Prepared Statements: DoS with too many
open statements". Also fix statement leaks in other tests.
sql/mysql_priv.h:
Add declarations for new global variables.
sql/mysqld.cc:
Add definitions of max_prepared_stmt_count, prepared_stmt_count.
sql/set_var.cc:
Implement support for @@prepared_stmt_count and
@@max_prepared_stmt_count. Currently these variables are queried
without acquiring LOCK_prepared_stmt_count due to limitations of
the set_var/sys_var class design. Updates are, however, protected
with a lock.
sql/set_var.h:
New declarations to add support for @@max_prepared_stmt_count.
Implement a new class, where the lock to be used when updating
a variable is a parameter.
sql/sql_class.cc:
Add accounting of the total number of prepared statements in the
server to the methods of Statement_map.
sql/sql_class.h:
Add accounting of the total number of prepared statements in the
server to the methods of Statement_map.
sql/sql_prepare.cc:
Statement_map::insert will now send a message in case of an
error.
2006-04-07 21:37:06 +02:00
prepare stmt from "select 2";
2006-11-21 14:49:18 +01:00
show status like 'prepared_stmt_count';
A fix and a test case for Bug#16365 "Prepared Statements: DoS with
too many open statements". The patch adds a new global variable
@@max_prepared_stmt_count. This variable limits the total number
of prepared statements in the server. The default value of
@@max_prepared_stmt_count is 16382. 16382 small statements
(a select against 3 tables with GROUP, ORDER and LIMIT) consume
100MB of RAM. Once this limit has been reached, the server will
refuse to prepare a new statement and return ER_UNKNOWN_ERROR
(unfortunately, we can't add new errors to 4.1 without breaking 5.0). The limit is changeable after startup
and can accept any value from 0 to 1 million. In case
the new value of the limit is less than the current
statement count, no new statements can be added, while the old
still can be used. Additionally, the current count of prepared
statements is now available through a global read-only variable
@@prepared_stmt_count.
mysql-test/r/ps.result:
Test results fixed (a test case for Bug#16365)
mysql-test/t/ps.test:
A test case for Bug#16365 "Prepared Statements: DoS with too many
open statements". Also fix statement leaks in other tests.
sql/mysql_priv.h:
Add declarations for new global variables.
sql/mysqld.cc:
Add definitions of max_prepared_stmt_count, prepared_stmt_count.
sql/set_var.cc:
Implement support for @@prepared_stmt_count and
@@max_prepared_stmt_count. Currently these variables are queried
without acquiring LOCK_prepared_stmt_count due to limitations of
the set_var/sys_var class design. Updates are, however, protected
with a lock.
sql/set_var.h:
New declarations to add support for @@max_prepared_stmt_count.
Implement a new class, where the lock to be used when updating
a variable is a parameter.
sql/sql_class.cc:
Add accounting of the total number of prepared statements in the
server to the methods of Statement_map.
sql/sql_class.h:
Add accounting of the total number of prepared statements in the
server to the methods of Statement_map.
sql/sql_prepare.cc:
Statement_map::insert will now send a message in case of an
error.
2006-04-07 21:37:06 +02:00
#
# F. We can set the max below the current count. In this case no new
# statements should be allowed to prepare.
#
2006-11-21 14:49:18 +01:00
show status like 'prepared_stmt_count';
select @@max_prepared_stmt_count;
A fix and a test case for Bug#16365 "Prepared Statements: DoS with
too many open statements". The patch adds a new global variable
@@max_prepared_stmt_count. This variable limits the total number
of prepared statements in the server. The default value of
@@max_prepared_stmt_count is 16382. 16382 small statements
(a select against 3 tables with GROUP, ORDER and LIMIT) consume
100MB of RAM. Once this limit has been reached, the server will
refuse to prepare a new statement and return ER_UNKNOWN_ERROR
(unfortunately, we can't add new errors to 4.1 without breaking 5.0). The limit is changeable after startup
and can accept any value from 0 to 1 million. In case
the new value of the limit is less than the current
statement count, no new statements can be added, while the old
still can be used. Additionally, the current count of prepared
statements is now available through a global read-only variable
@@prepared_stmt_count.
mysql-test/r/ps.result:
Test results fixed (a test case for Bug#16365)
mysql-test/t/ps.test:
A test case for Bug#16365 "Prepared Statements: DoS with too many
open statements". Also fix statement leaks in other tests.
sql/mysql_priv.h:
Add declarations for new global variables.
sql/mysqld.cc:
Add definitions of max_prepared_stmt_count, prepared_stmt_count.
sql/set_var.cc:
Implement support for @@prepared_stmt_count and
@@max_prepared_stmt_count. Currently these variables are queried
without acquiring LOCK_prepared_stmt_count due to limitations of
the set_var/sys_var class design. Updates are, however, protected
with a lock.
sql/set_var.h:
New declarations to add support for @@max_prepared_stmt_count.
Implement a new class, where the lock to be used when updating
a variable is a parameter.
sql/sql_class.cc:
Add accounting of the total number of prepared statements in the
server to the methods of Statement_map.
sql/sql_class.h:
Add accounting of the total number of prepared statements in the
server to the methods of Statement_map.
sql/sql_prepare.cc:
Statement_map::insert will now send a message in case of an
error.
2006-04-07 21:37:06 +02:00
set global max_prepared_stmt_count=0;
2006-04-12 23:46:44 +02:00
--error ER_MAX_PREPARED_STMT_COUNT_REACHED
A fix and a test case for Bug#16365 "Prepared Statements: DoS with
too many open statements". The patch adds a new global variable
@@max_prepared_stmt_count. This variable limits the total number
of prepared statements in the server. The default value of
@@max_prepared_stmt_count is 16382. 16382 small statements
(a select against 3 tables with GROUP, ORDER and LIMIT) consume
100MB of RAM. Once this limit has been reached, the server will
refuse to prepare a new statement and return ER_UNKNOWN_ERROR
(unfortunately, we can't add new errors to 4.1 without breaking 5.0). The limit is changeable after startup
and can accept any value from 0 to 1 million. In case
the new value of the limit is less than the current
statement count, no new statements can be added, while the old
still can be used. Additionally, the current count of prepared
statements is now available through a global read-only variable
@@prepared_stmt_count.
mysql-test/r/ps.result:
Test results fixed (a test case for Bug#16365)
mysql-test/t/ps.test:
A test case for Bug#16365 "Prepared Statements: DoS with too many
open statements". Also fix statement leaks in other tests.
sql/mysql_priv.h:
Add declarations for new global variables.
sql/mysqld.cc:
Add definitions of max_prepared_stmt_count, prepared_stmt_count.
sql/set_var.cc:
Implement support for @@prepared_stmt_count and
@@max_prepared_stmt_count. Currently these variables are queried
without acquiring LOCK_prepared_stmt_count due to limitations of
the set_var/sys_var class design. Updates are, however, protected
with a lock.
sql/set_var.h:
New declarations to add support for @@max_prepared_stmt_count.
Implement a new class, where the lock to be used when updating
a variable is a parameter.
sql/sql_class.cc:
Add accounting of the total number of prepared statements in the
server to the methods of Statement_map.
sql/sql_class.h:
Add accounting of the total number of prepared statements in the
server to the methods of Statement_map.
sql/sql_prepare.cc:
Statement_map::insert will now send a message in case of an
error.
2006-04-07 21:37:06 +02:00
prepare stmt from "select 1";
# Result: the old statement is deallocated, the new is not created.
2006-11-21 14:57:23 +01:00
--error ER_UNKNOWN_STMT_HANDLER
A fix and a test case for Bug#16365 "Prepared Statements: DoS with
too many open statements". The patch adds a new global variable
@@max_prepared_stmt_count. This variable limits the total number
of prepared statements in the server. The default value of
@@max_prepared_stmt_count is 16382. 16382 small statements
(a select against 3 tables with GROUP, ORDER and LIMIT) consume
100MB of RAM. Once this limit has been reached, the server will
refuse to prepare a new statement and return ER_UNKNOWN_ERROR
(unfortunately, we can't add new errors to 4.1 without breaking 5.0). The limit is changeable after startup
and can accept any value from 0 to 1 million. In case
the new value of the limit is less than the current
statement count, no new statements can be added, while the old
still can be used. Additionally, the current count of prepared
statements is now available through a global read-only variable
@@prepared_stmt_count.
mysql-test/r/ps.result:
Test results fixed (a test case for Bug#16365)
mysql-test/t/ps.test:
A test case for Bug#16365 "Prepared Statements: DoS with too many
open statements". Also fix statement leaks in other tests.
sql/mysql_priv.h:
Add declarations for new global variables.
sql/mysqld.cc:
Add definitions of max_prepared_stmt_count, prepared_stmt_count.
sql/set_var.cc:
Implement support for @@prepared_stmt_count and
@@max_prepared_stmt_count. Currently these variables are queried
without acquiring LOCK_prepared_stmt_count due to limitations of
the set_var/sys_var class design. Updates are, however, protected
with a lock.
sql/set_var.h:
New declarations to add support for @@max_prepared_stmt_count.
Implement a new class, where the lock to be used when updating
a variable is a parameter.
sql/sql_class.cc:
Add accounting of the total number of prepared statements in the
server to the methods of Statement_map.
sql/sql_class.h:
Add accounting of the total number of prepared statements in the
server to the methods of Statement_map.
sql/sql_prepare.cc:
Statement_map::insert will now send a message in case of an
error.
2006-04-07 21:37:06 +02:00
execute stmt;
2006-11-21 14:49:18 +01:00
show status like 'prepared_stmt_count';
2006-04-12 23:46:44 +02:00
--error ER_MAX_PREPARED_STMT_COUNT_REACHED
A fix and a test case for Bug#16365 "Prepared Statements: DoS with
too many open statements". The patch adds a new global variable
@@max_prepared_stmt_count. This variable limits the total number
of prepared statements in the server. The default value of
@@max_prepared_stmt_count is 16382. 16382 small statements
(a select against 3 tables with GROUP, ORDER and LIMIT) consume
100MB of RAM. Once this limit has been reached, the server will
refuse to prepare a new statement and return ER_UNKNOWN_ERROR
(unfortunately, we can't add new errors to 4.1 without breaking 5.0). The limit is changeable after startup
and can accept any value from 0 to 1 million. In case
the new value of the limit is less than the current
statement count, no new statements can be added, while the old
still can be used. Additionally, the current count of prepared
statements is now available through a global read-only variable
@@prepared_stmt_count.
mysql-test/r/ps.result:
Test results fixed (a test case for Bug#16365)
mysql-test/t/ps.test:
A test case for Bug#16365 "Prepared Statements: DoS with too many
open statements". Also fix statement leaks in other tests.
sql/mysql_priv.h:
Add declarations for new global variables.
sql/mysqld.cc:
Add definitions of max_prepared_stmt_count, prepared_stmt_count.
sql/set_var.cc:
Implement support for @@prepared_stmt_count and
@@max_prepared_stmt_count. Currently these variables are queried
without acquiring LOCK_prepared_stmt_count due to limitations of
the set_var/sys_var class design. Updates are, however, protected
with a lock.
sql/set_var.h:
New declarations to add support for @@max_prepared_stmt_count.
Implement a new class, where the lock to be used when updating
a variable is a parameter.
sql/sql_class.cc:
Add accounting of the total number of prepared statements in the
server to the methods of Statement_map.
sql/sql_class.h:
Add accounting of the total number of prepared statements in the
server to the methods of Statement_map.
sql/sql_prepare.cc:
Statement_map::insert will now send a message in case of an
error.
2006-04-07 21:37:06 +02:00
prepare stmt from "select 1";
2006-11-21 14:49:18 +01:00
show status like 'prepared_stmt_count';
A fix and a test case for Bug#16365 "Prepared Statements: DoS with
too many open statements". The patch adds a new global variable
@@max_prepared_stmt_count. This variable limits the total number
of prepared statements in the server. The default value of
@@max_prepared_stmt_count is 16382. 16382 small statements
(a select against 3 tables with GROUP, ORDER and LIMIT) consume
100MB of RAM. Once this limit has been reached, the server will
refuse to prepare a new statement and return ER_UNKNOWN_ERROR
(unfortunately, we can't add new errors to 4.1 without breaking 5.0). The limit is changeable after startup
and can accept any value from 0 to 1 million. In case
the new value of the limit is less than the current
statement count, no new statements can be added, while the old
still can be used. Additionally, the current count of prepared
statements is now available through a global read-only variable
@@prepared_stmt_count.
mysql-test/r/ps.result:
Test results fixed (a test case for Bug#16365)
mysql-test/t/ps.test:
A test case for Bug#16365 "Prepared Statements: DoS with too many
open statements". Also fix statement leaks in other tests.
sql/mysql_priv.h:
Add declarations for new global variables.
sql/mysqld.cc:
Add definitions of max_prepared_stmt_count, prepared_stmt_count.
sql/set_var.cc:
Implement support for @@prepared_stmt_count and
@@max_prepared_stmt_count. Currently these variables are queried
without acquiring LOCK_prepared_stmt_count due to limitations of
the set_var/sys_var class design. Updates are, however, protected
with a lock.
sql/set_var.h:
New declarations to add support for @@max_prepared_stmt_count.
Implement a new class, where the lock to be used when updating
a variable is a parameter.
sql/sql_class.cc:
Add accounting of the total number of prepared statements in the
server to the methods of Statement_map.
sql/sql_class.h:
Add accounting of the total number of prepared statements in the
server to the methods of Statement_map.
sql/sql_prepare.cc:
Statement_map::insert will now send a message in case of an
error.
2006-04-07 21:37:06 +02:00
#
# 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;
2006-11-21 14:49:18 +01:00
select @@max_prepared_stmt_count;
show status like 'prepared_stmt_count';
A fix and a test case for Bug#16365 "Prepared Statements: DoS with
too many open statements". The patch adds a new global variable
@@max_prepared_stmt_count. This variable limits the total number
of prepared statements in the server. The default value of
@@max_prepared_stmt_count is 16382. 16382 small statements
(a select against 3 tables with GROUP, ORDER and LIMIT) consume
100MB of RAM. Once this limit has been reached, the server will
refuse to prepare a new statement and return ER_UNKNOWN_ERROR
(unfortunately, we can't add new errors to 4.1 without breaking 5.0). The limit is changeable after startup
and can accept any value from 0 to 1 million. In case
the new value of the limit is less than the current
statement count, no new statements can be added, while the old
still can be used. Additionally, the current count of prepared
statements is now available through a global read-only variable
@@prepared_stmt_count.
mysql-test/r/ps.result:
Test results fixed (a test case for Bug#16365)
mysql-test/t/ps.test:
A test case for Bug#16365 "Prepared Statements: DoS with too many
open statements". Also fix statement leaks in other tests.
sql/mysql_priv.h:
Add declarations for new global variables.
sql/mysqld.cc:
Add definitions of max_prepared_stmt_count, prepared_stmt_count.
sql/set_var.cc:
Implement support for @@prepared_stmt_count and
@@max_prepared_stmt_count. Currently these variables are queried
without acquiring LOCK_prepared_stmt_count due to limitations of
the set_var/sys_var class design. Updates are, however, protected
with a lock.
sql/set_var.h:
New declarations to add support for @@max_prepared_stmt_count.
Implement a new class, where the lock to be used when updating
a variable is a parameter.
sql/sql_class.cc:
Add accounting of the total number of prepared statements in the
server to the methods of Statement_map.
sql/sql_class.h:
Add accounting of the total number of prepared statements in the
server to the methods of Statement_map.
sql/sql_prepare.cc:
Statement_map::insert will now send a message in case of an
error.
2006-04-07 21:37:06 +02:00
prepare stmt from "select 1";
connect (con1,localhost,root,,);
connection con1;
prepare stmt from "select 2";
prepare stmt1 from "select 3";
2006-04-12 23:46:44 +02:00
--error ER_MAX_PREPARED_STMT_COUNT_REACHED
A fix and a test case for Bug#16365 "Prepared Statements: DoS with
too many open statements". The patch adds a new global variable
@@max_prepared_stmt_count. This variable limits the total number
of prepared statements in the server. The default value of
@@max_prepared_stmt_count is 16382. 16382 small statements
(a select against 3 tables with GROUP, ORDER and LIMIT) consume
100MB of RAM. Once this limit has been reached, the server will
refuse to prepare a new statement and return ER_UNKNOWN_ERROR
(unfortunately, we can't add new errors to 4.1 without breaking 5.0). The limit is changeable after startup
and can accept any value from 0 to 1 million. In case
the new value of the limit is less than the current
statement count, no new statements can be added, while the old
still can be used. Additionally, the current count of prepared
statements is now available through a global read-only variable
@@prepared_stmt_count.
mysql-test/r/ps.result:
Test results fixed (a test case for Bug#16365)
mysql-test/t/ps.test:
A test case for Bug#16365 "Prepared Statements: DoS with too many
open statements". Also fix statement leaks in other tests.
sql/mysql_priv.h:
Add declarations for new global variables.
sql/mysqld.cc:
Add definitions of max_prepared_stmt_count, prepared_stmt_count.
sql/set_var.cc:
Implement support for @@prepared_stmt_count and
@@max_prepared_stmt_count. Currently these variables are queried
without acquiring LOCK_prepared_stmt_count due to limitations of
the set_var/sys_var class design. Updates are, however, protected
with a lock.
sql/set_var.h:
New declarations to add support for @@max_prepared_stmt_count.
Implement a new class, where the lock to be used when updating
a variable is a parameter.
sql/sql_class.cc:
Add accounting of the total number of prepared statements in the
server to the methods of Statement_map.
sql/sql_class.h:
Add accounting of the total number of prepared statements in the
server to the methods of Statement_map.
sql/sql_prepare.cc:
Statement_map::insert will now send a message in case of an
error.
2006-04-07 21:37:06 +02:00
prepare stmt2 from "select 4";
connection default;
2006-11-21 14:57:23 +01:00
--error ER_MAX_PREPARED_STMT_COUNT_REACHED
A fix and a test case for Bug#16365 "Prepared Statements: DoS with
too many open statements". The patch adds a new global variable
@@max_prepared_stmt_count. This variable limits the total number
of prepared statements in the server. The default value of
@@max_prepared_stmt_count is 16382. 16382 small statements
(a select against 3 tables with GROUP, ORDER and LIMIT) consume
100MB of RAM. Once this limit has been reached, the server will
refuse to prepare a new statement and return ER_UNKNOWN_ERROR
(unfortunately, we can't add new errors to 4.1 without breaking 5.0). The limit is changeable after startup
and can accept any value from 0 to 1 million. In case
the new value of the limit is less than the current
statement count, no new statements can be added, while the old
still can be used. Additionally, the current count of prepared
statements is now available through a global read-only variable
@@prepared_stmt_count.
mysql-test/r/ps.result:
Test results fixed (a test case for Bug#16365)
mysql-test/t/ps.test:
A test case for Bug#16365 "Prepared Statements: DoS with too many
open statements". Also fix statement leaks in other tests.
sql/mysql_priv.h:
Add declarations for new global variables.
sql/mysqld.cc:
Add definitions of max_prepared_stmt_count, prepared_stmt_count.
sql/set_var.cc:
Implement support for @@prepared_stmt_count and
@@max_prepared_stmt_count. Currently these variables are queried
without acquiring LOCK_prepared_stmt_count due to limitations of
the set_var/sys_var class design. Updates are, however, protected
with a lock.
sql/set_var.h:
New declarations to add support for @@max_prepared_stmt_count.
Implement a new class, where the lock to be used when updating
a variable is a parameter.
sql/sql_class.cc:
Add accounting of the total number of prepared statements in the
server to the methods of Statement_map.
sql/sql_class.h:
Add accounting of the total number of prepared statements in the
server to the methods of Statement_map.
sql/sql_prepare.cc:
Statement_map::insert will now send a message in case of an
error.
2006-04-07 21:37:06 +02:00
prepare stmt2 from "select 4";
2006-11-21 14:49:18 +01:00
select @@max_prepared_stmt_count;
show status like 'prepared_stmt_count';
A fix and a test case for Bug#16365 "Prepared Statements: DoS with
too many open statements". The patch adds a new global variable
@@max_prepared_stmt_count. This variable limits the total number
of prepared statements in the server. The default value of
@@max_prepared_stmt_count is 16382. 16382 small statements
(a select against 3 tables with GROUP, ORDER and LIMIT) consume
100MB of RAM. Once this limit has been reached, the server will
refuse to prepare a new statement and return ER_UNKNOWN_ERROR
(unfortunately, we can't add new errors to 4.1 without breaking 5.0). The limit is changeable after startup
and can accept any value from 0 to 1 million. In case
the new value of the limit is less than the current
statement count, no new statements can be added, while the old
still can be used. Additionally, the current count of prepared
statements is now available through a global read-only variable
@@prepared_stmt_count.
mysql-test/r/ps.result:
Test results fixed (a test case for Bug#16365)
mysql-test/t/ps.test:
A test case for Bug#16365 "Prepared Statements: DoS with too many
open statements". Also fix statement leaks in other tests.
sql/mysql_priv.h:
Add declarations for new global variables.
sql/mysqld.cc:
Add definitions of max_prepared_stmt_count, prepared_stmt_count.
sql/set_var.cc:
Implement support for @@prepared_stmt_count and
@@max_prepared_stmt_count. Currently these variables are queried
without acquiring LOCK_prepared_stmt_count due to limitations of
the set_var/sys_var class design. Updates are, however, protected
with a lock.
sql/set_var.h:
New declarations to add support for @@max_prepared_stmt_count.
Implement a new class, where the lock to be used when updating
a variable is a parameter.
sql/sql_class.cc:
Add accounting of the total number of prepared statements in the
server to the methods of Statement_map.
sql/sql_class.h:
Add accounting of the total number of prepared statements in the
server to the methods of Statement_map.
sql/sql_prepare.cc:
Statement_map::insert will now send a message in case of an
error.
2006-04-07 21:37:06 +02:00
disconnect con1;
connection default;
2006-11-21 15:23:54 +01:00
# Wait for the connection to die: deal with a possible race
A fix and a test case for Bug#16365 "Prepared Statements: DoS with
too many open statements". The patch adds a new global variable
@@max_prepared_stmt_count. This variable limits the total number
of prepared statements in the server. The default value of
@@max_prepared_stmt_count is 16382. 16382 small statements
(a select against 3 tables with GROUP, ORDER and LIMIT) consume
100MB of RAM. Once this limit has been reached, the server will
refuse to prepare a new statement and return ER_UNKNOWN_ERROR
(unfortunately, we can't add new errors to 4.1 without breaking 5.0). The limit is changeable after startup
and can accept any value from 0 to 1 million. In case
the new value of the limit is less than the current
statement count, no new statements can be added, while the old
still can be used. Additionally, the current count of prepared
statements is now available through a global read-only variable
@@prepared_stmt_count.
mysql-test/r/ps.result:
Test results fixed (a test case for Bug#16365)
mysql-test/t/ps.test:
A test case for Bug#16365 "Prepared Statements: DoS with too many
open statements". Also fix statement leaks in other tests.
sql/mysql_priv.h:
Add declarations for new global variables.
sql/mysqld.cc:
Add definitions of max_prepared_stmt_count, prepared_stmt_count.
sql/set_var.cc:
Implement support for @@prepared_stmt_count and
@@max_prepared_stmt_count. Currently these variables are queried
without acquiring LOCK_prepared_stmt_count due to limitations of
the set_var/sys_var class design. Updates are, however, protected
with a lock.
sql/set_var.h:
New declarations to add support for @@max_prepared_stmt_count.
Implement a new class, where the lock to be used when updating
a variable is a parameter.
sql/sql_class.cc:
Add accounting of the total number of prepared statements in the
server to the methods of Statement_map.
sql/sql_class.h:
Add accounting of the total number of prepared statements in the
server to the methods of Statement_map.
sql/sql_prepare.cc:
Statement_map::insert will now send a message in case of an
error.
2006-04-07 21:37:06 +02:00
deallocate prepare stmt;
2006-11-21 15:23:54 +01:00
let $query= select variable_value from information_schema.global_status
where variable_name = 'prepared_stmt_count';
let $count= `$query`;
if ($count)
{
--sleep 1
let $count= `$query`;
}
select @@max_prepared_stmt_count;
show status like 'prepared_stmt_count';
A fix and a test case for Bug#16365 "Prepared Statements: DoS with
too many open statements". The patch adds a new global variable
@@max_prepared_stmt_count. This variable limits the total number
of prepared statements in the server. The default value of
@@max_prepared_stmt_count is 16382. 16382 small statements
(a select against 3 tables with GROUP, ORDER and LIMIT) consume
100MB of RAM. Once this limit has been reached, the server will
refuse to prepare a new statement and return ER_UNKNOWN_ERROR
(unfortunately, we can't add new errors to 4.1 without breaking 5.0). The limit is changeable after startup
and can accept any value from 0 to 1 million. In case
the new value of the limit is less than the current
statement count, no new statements can be added, while the old
still can be used. Additionally, the current count of prepared
statements is now available through a global read-only variable
@@prepared_stmt_count.
mysql-test/r/ps.result:
Test results fixed (a test case for Bug#16365)
mysql-test/t/ps.test:
A test case for Bug#16365 "Prepared Statements: DoS with too many
open statements". Also fix statement leaks in other tests.
sql/mysql_priv.h:
Add declarations for new global variables.
sql/mysqld.cc:
Add definitions of max_prepared_stmt_count, prepared_stmt_count.
sql/set_var.cc:
Implement support for @@prepared_stmt_count and
@@max_prepared_stmt_count. Currently these variables are queried
without acquiring LOCK_prepared_stmt_count due to limitations of
the set_var/sys_var class design. Updates are, however, protected
with a lock.
sql/set_var.h:
New declarations to add support for @@max_prepared_stmt_count.
Implement a new class, where the lock to be used when updating
a variable is a parameter.
sql/sql_class.cc:
Add accounting of the total number of prepared statements in the
server to the methods of Statement_map.
sql/sql_class.h:
Add accounting of the total number of prepared statements in the
server to the methods of Statement_map.
sql/sql_prepare.cc:
Statement_map::insert will now send a message in case of an
error.
2006-04-07 21:37:06 +02:00
#
# Restore the old value.
#
set global max_prepared_stmt_count= @old_max_prepared_stmt_count;
--enable_ps_protocol
2006-11-21 14:53:33 +01:00
2006-07-06 21:59:04 +02:00
#
# 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;
2006-10-10 15:08:47 +02:00
2006-09-19 21:18:24 +02:00
#
# 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;
2006-10-10 15:08:47 +02:00
#
# 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;
5.1 version of a fix and test cases for bugs:
Bug#4968 ""Stored procedure crash if cursor opened on altered table"
Bug#6895 "Prepared Statements: ALTER TABLE DROP COLUMN does nothing"
Bug#19182 "CREATE TABLE bar (m INT) SELECT n FROM foo; doesn't work from
stored procedure."
Bug#19733 "Repeated alter, or repeated create/drop, fails"
Bug#22060 "ALTER TABLE x AUTO_INCREMENT=y in SP crashes server"
Bug#24879 "Prepared Statements: CREATE TABLE (UTF8 KEY) produces a
growing key length" (this bug is not fixed in 5.0)
Re-execution of CREATE DATABASE, CREATE TABLE and ALTER TABLE
statements in stored routines or as prepared statements caused
incorrect results (and crashes in versions prior to 5.0.25).
In 5.1 the problem occured only for CREATE DATABASE, CREATE TABLE
SELECT and CREATE TABLE with INDEX/DATA DIRECTOY options).
The problem of bugs 4968, 19733, 19282 and 6895 was that functions
mysql_prepare_table, mysql_create_table and mysql_alter_table are not
re-execution friendly: during their operation they modify contents
of LEX (members create_info, alter_info, key_list, create_list),
thus making the LEX unusable for the next execution.
In particular, these functions removed processed columns and keys from
create_list, key_list and drop_list. Search the code in sql_table.cc
for drop_it.remove() and similar patterns to find evidence.
The fix is to supply to these functions a usable copy of each of the
above structures at every re-execution of an SQL statement.
To simplify memory management, LEX::key_list and LEX::create_list
were added to LEX::alter_info, a fresh copy of which is created for
every execution.
The problem of crashing bug 22060 stemmed from the fact that the above
metnioned functions were not only modifying HA_CREATE_INFO structure
in LEX, but also were changing it to point to areas in volatile memory
of the execution memory root.
The patch solves this problem by creating and using an on-stack
copy of HA_CREATE_INFO in mysql_execute_command.
Additionally, this patch splits the part of mysql_alter_table
that analizes and rewrites information from the parser into
a separate function - mysql_prepare_alter_table, in analogy with
mysql_prepare_table, which is renamed to mysql_prepare_create_table.
mysql-test/r/ps.result:
Update test results (Bug#19182, Bug#22060, Bug#4968, Bug#6895)
mysql-test/r/sp.result:
Update results (Bug#19733)
mysql-test/t/ps.test:
Add test cases for Bug#19182, Bug#22060, Bug#4968, Bug#6895
mysql-test/t/sp.test:
Add a test case for Bug#19733
sql/field.h:
Implement a deep copy constructor for create_field
sql/mysql_priv.h:
LEX::key_list and LEX::create_list were moved to LEX::alter_info.
Update declarations to use LEX::alter_info instead of these two
members.
Remove declarations of mysql_add_index, mysql_drop_index.
sql/sql_class.cc:
Implement deep copy constructors.
sql/sql_class.h:
Implement (almost) deep copy constructors for key_part_spec,
Alter_drop, Alter_column, Key, foreign_key.
Replace pair<columns, keys> with an instance of Alter_info in
select_create constructor. We create a new copy of Alter_info
each time we re-execute SELECT .. CREATE prepared statement.
sql/sql_insert.cc:
Adjust to a new signature of create_table_from_items.
sql/sql_lex.cc:
Implement Alter_info::Alter_info that would make a "deep" copy
of all definition lists (keys, columns).
Move is_partition_management() from sql_partition.cc (feature-based
file division is evil).
sql/sql_lex.h:
Move key_list and create_list to class Alter_info. Implement
Alter_info::Alter_info that can be used with PS and SP.
Get rid of Alter_info::clear() which was an attempt to save on
matches and always use Alter_info::reset().
Implement an auxiliary Alter_info::init_for_create_from_alter()
which is used in mysql_alter_table.
sql/sql_list.cc:
Implement a copy constructor of class List that makes a deep copy
of all list nodes.
sql/sql_list.h:
Implement a way to make a deep copy of all list nodes.
sql/sql_parse.cc:
Adjust to new signatures of mysql_create_table, mysql_alter_table,
select_create. Functions mysql_create_index and mysql_drop_index has
become identical after initialization of alter_info was moved to the
parser, and were merged. Flag enable_slow_log was not updated for
SQLCOM_DROP_INDEX, which was a bug.
Just like CREATE INDEX, DROP INDEX is currently done via complete
table rebuild and is rightfully a slow administrative statement.
sql/sql_partition.cc:
Move is_partition_management() to sql_lex.cc
Adjust code to the new Alter_info.
sql/sql_table.cc:
Adjust mysql_alter_table, mysql_recreate_table, mysql_create_table,
mysql_prepare_table to new signatures.
Rename mysql_prepare_table to mysql_prepare_create_table. Make
sure it follows the convention and returns FALSE for success and
TRUE for error.
Move parts of mysql_alter_table to mysql_prepare_alter_table.
Move the first invokation of mysql_prepare_table from mysql_alter_table
to compare_tables, as it was needed only for the purpose
of correct comparison.
Since now Alter_info itself is created in the runtime mem root,
adjust mysql_prepare_table to always allocate memory in the
runtime memory root.
Remove dead code.
sql/sql_yacc.yy:
LEX::key_list and LEX::create_list moved to class Alter_info
2007-05-28 13:30:01 +02:00
#
# Bug#19182: CREATE TABLE bar (m INT) SELECT n FROM foo; doesn't work
# from stored procedure.
#
# The cause of a bug was that cached LEX::create_list was modified,
# and then together with LEX::key_list was reset.
#
--disable_warnings
DROP TABLE IF EXISTS t1, t2;
--enable_warnings
CREATE TABLE t1 (i INT);
PREPARE st_19182
FROM "CREATE TABLE t2 (i INT, j INT, KEY (i), KEY(j)) SELECT i FROM t1";
EXECUTE st_19182;
DESC t2;
DROP TABLE t2;
# Check that on second execution we don't loose 'j' column and the keys
# on 'i' and 'j' columns.
EXECUTE st_19182;
DESC t2;
DEALLOCATE PREPARE st_19182;
DROP TABLE t2, t1;
#
# Bug #22060 "ALTER TABLE x AUTO_INCREMENT=y in SP crashes server"
#
# Code which implemented CREATE/ALTER TABLE and CREATE DATABASE
# statement modified HA_CREATE_INFO structure in LEX, making these
# statements PS/SP-unsafe (their re-execution might have resulted
# in incorrect results).
#
--disable_warnings
drop database if exists mysqltest;
drop table if exists t1, t2;
--enable_warnings
# CREATE TABLE and CREATE TABLE ... SELECT
create database mysqltest character set utf8;
prepare stmt1 from "create table mysqltest.t1 (c char(10))";
prepare stmt2 from "create table mysqltest.t2 select 'test'";
execute stmt1;
execute stmt2;
show create table mysqltest.t1;
show create table mysqltest.t2;
drop table mysqltest.t1;
drop table mysqltest.t2;
alter database mysqltest character set latin1;
execute stmt1;
execute stmt2;
show create table mysqltest.t1;
show create table mysqltest.t2;
drop database mysqltest;
deallocate prepare stmt1;
deallocate prepare stmt2;
#
# CREATE TABLE with DATA DIRECTORY option
#
--disable_warnings
--disable_query_log
eval prepare stmt from "create table t1 (c char(10)) data directory='$MYSQLTEST_VARDIR/tmp'";
--enable_query_log
execute stmt;
#
# DATA DIRECTORY option does not always work: if the operating
# system does not support symlinks, have_symlinks option is automatically
# disabled.
# In this case DATA DIRECTORY is silently ignored when
# creating a table, and is not output by SHOW CREATE TABLE.
#
--disable_result_log
show create table t1;
--enable_result_log
drop table t1;
execute stmt;
--disable_result_log
show create table t1;
--enable_result_log
--enable_warnings
drop table t1;
deallocate prepare stmt;
#
#
# Bug #27937: crash on the second execution for prepared statement
# from UNION with ORDER BY an expression containing RAND()
#
CREATE TABLE t1(a int);
INSERT INTO t1 VALUES (2), (3), (1);
PREPARE st1 FROM
'(SELECT a FROM t1) UNION (SELECT a+10 FROM t1) ORDER BY RAND()*0+a';
EXECUTE st1;
EXECUTE st1;
DEALLOCATE PREPARE st1;
DROP TABLE t1;
2007-01-19 17:30:40 +01:00
--echo End of 4.1 tests.
2006-07-11 19:19:57 +02:00
############################# 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');
prepare stmt FROM 'SELECT char_length (a) FROM t1';
2006-11-02 22:02:07 +01:00
-- error ER_SP_DOES_NOT_EXIST
prepare stmt2 FROM 'SELECT not_a_function (a) FROM t1';
2006-07-11 19:19:57 +02:00
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;
2005-11-23 23:57:26 +01:00
#
# 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;
2006-03-28 14:16:21 +02:00
#
# 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 ?";
2006-04-12 23:46:44 +02:00
set @a=NULL;
2006-03-28 14:16:21 +02:00
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;
2006-04-25 02:27:23 +02:00
#
# 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;
Re-apply missing changeset, orignally pushed by elliot
Add define YASSL_PREFIX when compiling yassl
Import patch from yaSSL
- avoid allocating memory for each call to 'EVP_md5' and
'EVP_des_ede3_cbc' which were not released until server was stopped
- Those functions are used from the SQL function 'des_encrypt' and
'des_decrypt'.
Add new define YASSL_PREFIX beforee including ssl.h to activate inclusion of prefix_*.h files
Bug#20022 mysql-test-run can't be run with secure connections turned on for all testcases
- Part 1, fixes rpl- and federated-tests where connection is made to 127.0.0.1
- Include prefix files that renames all public functions in yaSSLs
OpenSSL API to ya<function_name>. They will otherwise conflict
with OpenSSL functions if loaded by an application that uses OpenSSL
as well as libmysqlclient with yaSSL support.
Bug#18235: assertion/crash when windows mysqld is ended with ctrl-c
Two threads both try a shutdown sequence which creates a race to the
de-init/free of certain resources.
This exists in similar form in the client as 17926: "mysql.exe crashes
when ctrl-c is pressed in windows."
Update after merge to 5.0
BUG#18669: Session COM_STATISTICS breaks mysqladmin status.
Changed COM_STATISTICS to display the global status, instead of thead status, for slow queries and table opens.
- In function 'handle_grant_struct' when searching the memory structures for an
entry to modify, convert all entries here host.hostname is NULL to "" and compare that
with the host passed in argument "user_from".
- A user created with hostname "" is stored in "mysql.user" table as host="" but when loaded into
memory it'll be stored as host.hostname NULL. Specifiying "" as hostname means
that "any host" can connect. Thus is's correct to turn on allow_all_hosts
when such a user is found.
- Review and fix other places where host.hostname may be NULL.
BUG#19394 OPT_INNODB_THREAD_CONCURRENCY duplicated
Removed duplication (not a user-visible change)
client/Makefile.am:
Remove $yassl_includes
client/mysqltest.c:
Turn on ssl_verify_server_cert only if host is "localhost"
extra/yassl/include/openssl/crypto.h:
Add prefix file for ssl.h
extra/yassl/include/openssl/ssl.h:
Add include file "prefix_crypto.h" to rename SSL_* functions to yaSSL_*
extra/yassl/include/yassl_int.hpp:
Import patch yassl.diff
extra/yassl/src/Makefile.am:
Add defined YASSL_PREFIX when building yassl/testsuite
extra/yassl/src/ssl.cpp:
Import patch yassl.diff
extra/yassl/src/template_instnt.cpp:
Import patch yassl.diff
extra/yassl/src/yassl_int.cpp:
Import patch yassl.diff
extra/yassl/testsuite/Makefile.am:
Add defined YASSL_PREFIX when building yassl/testsuite
extra/yassl/yassl.vcproj:
Add define YASSL_PREFIX when compiling yassl
include/violite.h:
Add new define YASSL_PREFIX beforee including ssl.h to activate inclusion of prefix_*.h files
libmysql/Makefile.am:
Remove yassl_includes
libmysql_r/Makefile.am:
Remove yassl_includes
libmysqld/Makefile.am:
Remove yassl_includes
libmysqld/examples/Makefile.am:
Remove yassl_includes
mysql-test/r/analyze.result:
Add missing drop table
mysql-test/r/grant.result:
Reorder test result
Add test cases for users with hostname ""
mysql-test/r/ps.result:
Add missing drop table
mysql-test/t/analyze.test:
Add missing drop table
mysql-test/t/grant.test:
Add "use test"
Add test cases for users with hostname ""
- Test create, grant and drop as well as connecting as the user with hostname "".
mysql-test/t/ps.test:
Add missing drop table
server-tools/instance-manager/Makefile.am:
Remove yassl_includes
sql/Makefile.am:
Remove yassl_includes
sql/mysqld.cc:
We have three potential ways of hitting the iceberg:
- unireg_end() has basic de-init
- unireg_abort() has extended de-init
- main() has a de-init sequence similar to unireg_abort()
In the Windows version of the server, Control-C is handled
in a different thread from the one main() is in. The main
loop is told to end, then unireg_abort() is called. Its
de-init and that of main() will then race each other for
mutex- and cond-var-destroys, free(), and finally exit().
This patch introduces a special case for Windows that will eliminate
the race by ending the signal-handler via unireg_end() instead if
SIGINT is signalled. This seems the least intrusive fix that still
fixes user-visible behaviour.
Two of the startup options for mysqld, innodb_commit_concurrency
and innodb_thread_concurrency, were using the same enumeration
value. Changed to give innodb_commit_concurrency it's own value.
sql/sql_acl.cc:
Add check if host is NULL
Add check if grant_name->host.hostname is null
Convert places where host.hostname is NULL to "" before using it.
sql/sql_parse.cc:
Calculate and display the global statistics.
vio/Makefile.am:
Remove yassl_includes
extra/yassl/include/openssl/generate_prefix_files.pl:
New BitKeeper file ``extra/yassl/include/openssl/generate_prefix_files.pl''
extra/yassl/include/openssl/prefix_crypto.h:
New BitKeeper file ``extra/yassl/include/openssl/prefix_crypto.h''
extra/yassl/include/openssl/prefix_ssl.h:
New BitKeeper file ``extra/yassl/include/openssl/prefix_ssl.h''
2006-06-06 13:21:07 +02:00
drop table t1, t2, t3;
A fix and a test case for
Bug#19022 "Memory bug when switching db during trigger execution"
Bug#17199 "Problem when view calls function from another database."
Bug#18444 "Fully qualified stored function names don't work correctly in
SELECT statements"
Documentation note: this patch introduces a change in behaviour of prepared
statements.
This patch adds a few new invariants with regard to how THD::db should
be used. These invariants should be preserved in future:
- one should never refer to THD::db by pointer and always make a deep copy
(strmake, strdup)
- one should never compare two databases by pointer, but use strncmp or
my_strncasecmp
- TABLE_LIST object table->db should be always initialized in the parser or
by creator of the object.
For prepared statements it means that if the current database is changed
after a statement is prepared, the database that was current at prepare
remains active. This also means that you can not prepare a statement that
implicitly refers to the current database if the latter is not set.
This is not documented, and therefore needs documentation. This is NOT a
change in behavior for almost all SQL statements except:
- ALTER TABLE t1 RENAME t2
- OPTIMIZE TABLE t1
- ANALYZE TABLE t1
- TRUNCATE TABLE t1 --
until this patch t1 or t2 could be evaluated at the first execution of
prepared statement.
CURRENT_DATABASE() still works OK and is evaluated at every execution
of prepared statement.
Note, that in stored routines this is not an issue as the default
database is the database of the stored procedure and "use" statement
is prohibited in stored routines.
This patch makes obsolete the use of check_db_used (it was never used in the
old code too) and all other places that check for table->db and assign it
from THD::db if it's NULL, except the parser.
How this patch was created: THD::{db,db_length} were replaced with a
LEX_STRING, THD::db. All the places that refer to THD::{db,db_length} were
manually checked and:
- if the place uses thd->db by pointer, it was fixed to make a deep copy
- if a place compared two db pointers, it was fixed to compare them by value
(via strcmp/my_strcasecmp, whatever was approproate)
Then this intermediate patch was used to write a smaller patch that does the
same thing but without a rename.
TODO in 5.1:
- remove check_db_used
- deploy THD::set_db in mysql_change_db
See also comments to individual files.
mysql-test/r/create.result:
Modify the result file: a database can never be NULL.
mysql-test/r/ps.result:
Update test results (Bug#17199 et al)
mysql-test/r/sp.result:
Update test results (Bug#17199 et al)
mysql-test/t/create.test:
Update the id of the returned error.
mysql-test/t/ps.test:
Add test coverage for prepared statements and current database. In scope of
work on Bug#17199 "Problem when view calls function from another database."
mysql-test/t/sp.test:
Add a test case for Bug#17199 "Problem when view calls function from another
database." and Bug#18444 "Fully qualified stored function names don't work
correctly in SELECT statements". Test a complementary problem.
sql/item_strfunc.cc:
Touch the code that reads thd->db (cleanup).
sql/log_event.cc:
While we are at it, replace direct access to thd->db with a method.
Should simplify future conversion of THD::db to LEX_STRING.
sql/slave.cc:
While we are at it, replace direct access to thd->db with a method.
Should simplify future conversion of THD::db to LEX_STRING.
sql/slave.h:
Remove a declaration for a method that is used only in one module.
sql/sp.cc:
Rewrite sp_use_new_db: this is a cleanup that I needed in order to understand
this function and ensure that it has no bugs.
sql/sp.h:
Add a new declaration for sp_use_new_db (uses LEX_STRINGs) and a comment.
sql/sp_head.cc:
- drop sp_name_current_db_new - a creator of sp_name class that was used
when sp_name was created for an identifier without an explicitly initialized
database. Now we pass thd->db to constructor of sp_name right in the
parser.
- rewrite sp_head::init_strings: name->m_db is always set now
- use the new variant of sp_use_new_db
- we don't need to update thd->db with SP MEM_ROOT pointer anymore when
parsing a stored procedure, as noone will refer to it (yes!)
sql/sp_head.h:
- remove unneded methods and members
sql/sql_class.h:
- introduce 3 THD methods to work with THD::db:
.set_db to assign the current database
.reset_db to reset the current database (temporarily) or set it to NULL
.opt_copy_db_to - to deep-copy thd->db to a pointer if it's not NULL
sql/sql_db.cc:
While we are at it, replace direct access to thd->db with a method.
Should simplify future conversion of THD::db to LEX_STRING.
sql/sql_insert.cc:
- replace checks with asserts: table_list->db must be always set in the parser.
sql/sql_lex.h:
- add a comment
sql/sql_parse.cc:
- implement the invariant described in the changeset comment.
- remove juggling with lex->sphead in SQLCOM_CREATE_PROCEDURE:
now db_load_routine uses its own LEX object and doesn't damage the main
LEX.
- add DBUG_ASSERT(0) to unused "check_db_used"
sql/sql_table.cc:
- replace a check with an assert (table_ident->db)
sql/sql_trigger.cc:
While we are at it, replace direct access to thd->db with a method.
Should simplify future conversion of THD::db to LEX_STRING.
sql/sql_udf.cc:
- use thd->set_db instead of direct modification of to thd->db
sql/sql_view.cc:
- replace a check with an assert (view->db)
sql/sql_yacc.yy:
- make sure that we always copy table->db or name->db or ident->db or
select_lex->db from thd->db if the former is not set. If thd->db
is not set but is accessed, return an error.
sql/tztime.cc:
- be nice, never copy thd->db by pointer.
2006-06-26 22:47:52 +02:00
#
# 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;
2006-08-23 15:50:06 +02:00
2006-08-24 13:49:12 +02:00
#
# 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;
2006-09-27 21:11:45 +02:00
#
# 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;
2006-11-29 12:52:11 +01:00
#
# BUG#20327: Marking of a wrong field leads to a wrong result on select with
# view, prepared statement and subquery.
#
CREATE TABLE t1 (i INT);
CREATE VIEW v1 AS SELECT * FROM t1;
INSERT INTO t1 VALUES (1), (2);
let $query = SELECT t1.i FROM t1 JOIN v1 ON t1.i = v1.i
WHERE EXISTS (SELECT * FROM t1 WHERE v1.i = 1);
eval $query;
eval PREPARE stmt FROM "$query";
# Statement execution should return '1'.
EXECUTE stmt;
# Check re-execution.
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
DROP VIEW v1;
DROP TABLE t1;
2006-11-29 13:03:53 +01:00
2006-10-19 12:43:52 +02:00
#
# 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
2006-10-13 01:10:34 +02:00
#
# 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;
2006-10-19 12:43:52 +02:00
2007-01-23 13:03:48 +01:00
2006-12-13 09:39:13 +01:00
#
# Bug 25027: query with a single-row non-correlated subquery
# and IS NULL predicate
#
CREATE TABLE t1 (a int);
INSERT INTO t1 VALUES (1), (2);
CREATE TABLE t2 (b int);
INSERT INTO t2 VALUES (NULL);
SELECT a FROM t1 WHERE (SELECT b FROM t2) IS NULL;
PREPARE stmt FROM 'SELECT a FROM t1 WHERE (SELECT b FROM t2) IS NULL';
EXECUTE stmt;
2006-12-14 06:08:25 +01:00
DEALLOCATE PREPARE stmt;
2006-12-13 09:39:13 +01:00
2006-12-14 06:08:25 +01:00
PREPARE stmt FROM 'SELECT a FROM t1 WHERE (SELECT b FROM t2 limit ?) IS NULL';
SET @arg=1;
EXECUTE stmt USING @arg;
2006-12-13 09:39:13 +01:00
DEALLOCATE PREPARE stmt;
2006-12-14 06:08:25 +01:00
2006-12-13 09:39:13 +01:00
DROP TABLE t1,t2;
5.1 version of a fix and test cases for bugs:
Bug#4968 ""Stored procedure crash if cursor opened on altered table"
Bug#6895 "Prepared Statements: ALTER TABLE DROP COLUMN does nothing"
Bug#19182 "CREATE TABLE bar (m INT) SELECT n FROM foo; doesn't work from
stored procedure."
Bug#19733 "Repeated alter, or repeated create/drop, fails"
Bug#22060 "ALTER TABLE x AUTO_INCREMENT=y in SP crashes server"
Bug#24879 "Prepared Statements: CREATE TABLE (UTF8 KEY) produces a
growing key length" (this bug is not fixed in 5.0)
Re-execution of CREATE DATABASE, CREATE TABLE and ALTER TABLE
statements in stored routines or as prepared statements caused
incorrect results (and crashes in versions prior to 5.0.25).
In 5.1 the problem occured only for CREATE DATABASE, CREATE TABLE
SELECT and CREATE TABLE with INDEX/DATA DIRECTOY options).
The problem of bugs 4968, 19733, 19282 and 6895 was that functions
mysql_prepare_table, mysql_create_table and mysql_alter_table are not
re-execution friendly: during their operation they modify contents
of LEX (members create_info, alter_info, key_list, create_list),
thus making the LEX unusable for the next execution.
In particular, these functions removed processed columns and keys from
create_list, key_list and drop_list. Search the code in sql_table.cc
for drop_it.remove() and similar patterns to find evidence.
The fix is to supply to these functions a usable copy of each of the
above structures at every re-execution of an SQL statement.
To simplify memory management, LEX::key_list and LEX::create_list
were added to LEX::alter_info, a fresh copy of which is created for
every execution.
The problem of crashing bug 22060 stemmed from the fact that the above
metnioned functions were not only modifying HA_CREATE_INFO structure
in LEX, but also were changing it to point to areas in volatile memory
of the execution memory root.
The patch solves this problem by creating and using an on-stack
copy of HA_CREATE_INFO in mysql_execute_command.
Additionally, this patch splits the part of mysql_alter_table
that analizes and rewrites information from the parser into
a separate function - mysql_prepare_alter_table, in analogy with
mysql_prepare_table, which is renamed to mysql_prepare_create_table.
mysql-test/r/ps.result:
Update test results (Bug#19182, Bug#22060, Bug#4968, Bug#6895)
mysql-test/r/sp.result:
Update results (Bug#19733)
mysql-test/t/ps.test:
Add test cases for Bug#19182, Bug#22060, Bug#4968, Bug#6895
mysql-test/t/sp.test:
Add a test case for Bug#19733
sql/field.h:
Implement a deep copy constructor for create_field
sql/mysql_priv.h:
LEX::key_list and LEX::create_list were moved to LEX::alter_info.
Update declarations to use LEX::alter_info instead of these two
members.
Remove declarations of mysql_add_index, mysql_drop_index.
sql/sql_class.cc:
Implement deep copy constructors.
sql/sql_class.h:
Implement (almost) deep copy constructors for key_part_spec,
Alter_drop, Alter_column, Key, foreign_key.
Replace pair<columns, keys> with an instance of Alter_info in
select_create constructor. We create a new copy of Alter_info
each time we re-execute SELECT .. CREATE prepared statement.
sql/sql_insert.cc:
Adjust to a new signature of create_table_from_items.
sql/sql_lex.cc:
Implement Alter_info::Alter_info that would make a "deep" copy
of all definition lists (keys, columns).
Move is_partition_management() from sql_partition.cc (feature-based
file division is evil).
sql/sql_lex.h:
Move key_list and create_list to class Alter_info. Implement
Alter_info::Alter_info that can be used with PS and SP.
Get rid of Alter_info::clear() which was an attempt to save on
matches and always use Alter_info::reset().
Implement an auxiliary Alter_info::init_for_create_from_alter()
which is used in mysql_alter_table.
sql/sql_list.cc:
Implement a copy constructor of class List that makes a deep copy
of all list nodes.
sql/sql_list.h:
Implement a way to make a deep copy of all list nodes.
sql/sql_parse.cc:
Adjust to new signatures of mysql_create_table, mysql_alter_table,
select_create. Functions mysql_create_index and mysql_drop_index has
become identical after initialization of alter_info was moved to the
parser, and were merged. Flag enable_slow_log was not updated for
SQLCOM_DROP_INDEX, which was a bug.
Just like CREATE INDEX, DROP INDEX is currently done via complete
table rebuild and is rightfully a slow administrative statement.
sql/sql_partition.cc:
Move is_partition_management() to sql_lex.cc
Adjust code to the new Alter_info.
sql/sql_table.cc:
Adjust mysql_alter_table, mysql_recreate_table, mysql_create_table,
mysql_prepare_table to new signatures.
Rename mysql_prepare_table to mysql_prepare_create_table. Make
sure it follows the convention and returns FALSE for success and
TRUE for error.
Move parts of mysql_alter_table to mysql_prepare_alter_table.
Move the first invokation of mysql_prepare_table from mysql_alter_table
to compare_tables, as it was needed only for the purpose
of correct comparison.
Since now Alter_info itself is created in the runtime mem root,
adjust mysql_prepare_table to always allocate memory in the
runtime memory root.
Remove dead code.
sql/sql_yacc.yy:
LEX::key_list and LEX::create_list moved to class Alter_info
2007-05-28 13:30:01 +02:00
#
# Bug#4968 "Stored procedure crash if cursor opened on altered table"
# The bug is not repeatable any more after the fix for
# Bug#15217 "Bug #15217 Using a SP cursor on a table created with PREPARE
# fails with weird error", however ALTER TABLE is not re-execution friendly
# and that caused a valgrind warning. Check that the warning is gone.
#
--disable_warnings
drop table if exists t1;
--enable_warnings
create table t1 (s1 char(20));
prepare stmt from "alter table t1 modify s1 int";
execute stmt;
execute stmt;
drop table t1;
deallocate prepare stmt;
#
# Bug#6895 "Prepared Statements: ALTER TABLE DROP COLUMN does nothing"
#
--disable_warnings
drop table if exists t1;
--enable_warnings
create table t1 (a int, b int);
prepare s_6895 from "alter table t1 drop column b";
execute s_6895;
show columns from t1;
drop table t1;
create table t1 (a int, b int);
execute s_6895;
show columns from t1;
drop table t1;
create table t1 (a int, b int);
execute s_6895;
show columns from t1;
deallocate prepare s_6895;
drop table t1;
#
# Bug #22060 "ALTER TABLE x AUTO_INCREMENT=y in SP crashes server"
#
# 5.0 part of the test.
#
# ALTER TABLE
create table t1 (i int primary key auto_increment) comment='comment for table t1';
create table t2 (i int, j int, k int);
prepare stmt from "alter table t1 auto_increment=100";
execute stmt;
show create table t1;
# Let us trash table-cache's memory
flush tables;
select * from t2;
execute stmt;
show create table t1;
deallocate prepare stmt;
drop table t1, t2;
# 5.1 part of the test.
# CREATE DATABASE
set @old_character_set_server= @@character_set_server;
set @@character_set_server= latin1;
prepare stmt from "create database mysqltest_1";
execute stmt;
show create database mysqltest_1;
drop database mysqltest_1;
set @@character_set_server= utf8;
execute stmt;
show create database mysqltest_1;
drop database mysqltest_1;
deallocate prepare stmt;
set @@character_set_server= @old_character_set_server;
2006-12-13 09:39:13 +01:00
2007-01-23 13:57:46 +01:00
2007-01-23 13:03:48 +01:00
#
# BUG#24491 "using alias from source table in insert ... on duplicate key"
#
--disable_warnings
drop tables if exists t1;
--enable_warnings
create table t1 (id int primary key auto_increment, value varchar(10));
insert into t1 (id, value) values (1, 'FIRST'), (2, 'SECOND'), (3, 'THIRD');
# Let us prepare INSERT ... SELECT ... ON DUPLICATE KEY UPDATE statement
# which in its ON DUPLICATE KEY clause erroneously tries to assign value
# to a column which is mentioned only in SELECT part.
prepare stmt from "insert into t1 (id, value) select * from (select 4 as i, 'FOURTH' as v) as y on duplicate key update v = 'DUP'";
# Both first and second attempts to execute it should fail
--error ER_BAD_FIELD_ERROR
execute stmt;
--error ER_BAD_FIELD_ERROR
execute stmt;
deallocate prepare stmt;
# And now the same test for more complex case which is more close
# to the one that was reported originally.
prepare stmt from "insert into t1 (id, value) select * from (select 4 as id, 'FOURTH' as value) as y on duplicate key update y.value = 'DUP'";
--error ER_BAD_FIELD_ERROR
execute stmt;
--error ER_BAD_FIELD_ERROR
execute stmt;
deallocate prepare stmt;
drop tables t1;
2007-05-18 15:16:51 +02:00
#
# Bug #28509: strange behaviour: passing a decimal value to PS
#
prepare stmt from "create table t1 select ?";
set @a=1.0;
execute stmt using @a;
show create table t1;
drop table t1;
2007-01-23 13:03:48 +01:00
2006-08-24 13:49:12 +02:00
--echo End of 5.0 tests.
2006-08-30 01:00:19 +02:00
2006-08-23 15:50:06 +02:00
#
# Bug #20665: All commands supported in Stored Procedures should work in
# Prepared Statements
#
create procedure proc_1() reset query cache;
call proc_1();
call proc_1();
call proc_1();
delimiter |;
2006-10-11 13:53:56 +02:00
--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG
Bug#16456 RBR: rpl_sp.test expects query to fail, but passes in RBR
Fix tests for new behaviour: an error is thrown if a NON DETERMINISTIC
stored function (SF) is called during statement-based replication (SBR).
mysql-test/r/func_time.result:
Bug#16456 RBR: rpl_sp.test expects query to fail, but passes in RBR
Modify test that contains non-deterministic functions so it can still be
called with no error while doing statement-based replication (SBR).
mysql-test/r/gis.result:
Bug#16456 RBR: rpl_sp.test expects query to fail, but passes in RBR
Mark function as DETERMINISTIC so it can be called with no error while
doing statement-based replication (SBR).
mysql-test/r/grant2.result:
Bug#16456 RBR: rpl_sp.test expects query to fail, but passes in RBR
Modify test that contains non-deterministic functions so it can still be
called with no error while doing statement-based replication (SBR).
mysql-test/r/innodb_notembedded.result:
Bug#16456 RBR: rpl_sp.test expects query to fail, but passes in RBR
Modify test that contains non-deterministic functions so it can still be
called with no error while doing statement-based replication (SBR).
mysql-test/r/ps.result:
Bug#16456 RBR: rpl_sp.test expects query to fail, but passes in RBR
Mark function as DETERMINISTIC so it can be called with no error while
doing statement-based replication (SBR).
mysql-test/r/query_cache.result:
Bug#16456 RBR: rpl_sp.test expects query to fail, but passes in RBR
Modify test that contains non-deterministic functions so it can still be
called with no error while doing statement-based replication (SBR).
mysql-test/r/query_cache_notembedded.result:
Bug#16456 RBR: rpl_sp.test expects query to fail, but passes in RBR
Modify test that contains non-deterministic functions so it can still be
called with no error while doing statement-based replication (SBR).
mysql-test/r/rpl_sp.result:
Bug#16456 RBR: rpl_sp.test expects query to fail, but passes in RBR
Move test for SF-calls in different replication modes to its own file, rpl_sf.
mysql-test/r/rpl_sp_effects.result:
Bug#16456 RBR: rpl_sp.test expects query to fail, but passes in RBR
Modify test that contains non-deterministic functions so it can still be
called with no error while doing statement-based replication (SBR).
mysql-test/r/sp.result:
Bug#16456 RBR: rpl_sp.test expects query to fail, but passes in RBR
Mark function as DETERMINISTIC so it can be called with no error while
doing statement-based replication (SBR).
mysql-test/r/timezone2.result:
Bug#16456 RBR: rpl_sp.test expects query to fail, but passes in RBR
Modify test that contains non-deterministic functions so it can still be
called with no error while doing statement-based replication (SBR).
mysql-test/t/func_time.test:
Bug#16456 RBR: rpl_sp.test expects query to fail, but passes in RBR
Modify test that contains non-deterministic functions so it can still be
called with no error while doing statement-based replication (SBR).
mysql-test/t/gis.test:
Bug#16456 RBR: rpl_sp.test expects query to fail, but passes in RBR
Mark function as DETERMINISTIC so it can be called with no error while
doing statement-based replication (SBR).
mysql-test/t/grant2.test:
Bug#16456 RBR: rpl_sp.test expects query to fail, but passes in RBR
Modify test that contains non-deterministic functions so it can still be
called with no error while doing statement-based replication (SBR).
mysql-test/t/innodb_notembedded.test:
Bug#16456 RBR: rpl_sp.test expects query to fail, but passes in RBR
Modify test that contains non-deterministic functions so it can still be
called with no error while doing statement-based replication (SBR).
mysql-test/t/ps.test:
Bug#16456 RBR: rpl_sp.test expects query to fail, but passes in RBR
Modify test that contains non-deterministic functions so it can still be
called with no error while doing statement-based replication (SBR).
mysql-test/t/query_cache.test:
Bug#16456 RBR: rpl_sp.test expects query to fail, but passes in RBR
Modify test that contains non-deterministic functions so it can still be
called with no error while doing statement-based replication (SBR).
mysql-test/t/query_cache_notembedded.test:
Bug#16456 RBR: rpl_sp.test expects query to fail, but passes in RBR
Modify test that contains non-deterministic functions so it can still be
called with no error while doing statement-based replication (SBR).
mysql-test/t/rpl_sp.test:
Bug#16456 RBR: rpl_sp.test expects query to fail, but passes in RBR
Modify test that contains non-deterministic functions so it can still be
called with no error while doing statement-based replication (SBR).
mysql-test/t/rpl_sp_effects.test:
Bug#16456 RBR: rpl_sp.test expects query to fail, but passes in RBR
Modify test that contains non-deterministic functions so it can still be
called with no error while doing statement-based replication (SBR).
mysql-test/t/sp.test:
Bug#16456 RBR: rpl_sp.test expects query to fail, but passes in RBR
Mark function as DETERMINISTIC so it can be called with no error while
doing statement-based replication (SBR).
mysql-test/t/timezone2.test:
Bug#16456 RBR: rpl_sp.test expects query to fail, but passes in RBR
Modify test that contains non-deterministic functions so it can still be
called with no error while doing statement-based replication (SBR).
sql/item_func.cc:
Bug#16456 RBR: rpl_sp.test expects query to fail, but passes in RBR
If 'log_bin_trust_function_creators' variable is set, don't throw an error
on calling a non-deterministc function in statement-based replication (SBR).
sql/sql_parse.cc:
Bug#16456 RBR: rpl_sp.test expects query to fail, but passes in RBR
Do not throw an error on calling a NON DETERMINISTIC stored procedure (SP)
while doing statement-based replication (SBR), as the routine body is
executed statement-by-statement.
mysql-test/r/rpl_sf.result:
Bug#16456 RBR: rpl_sp.test expects query to fail, but passes in RBR
Test for stored function (SF) calls in different replication modes.
NON DETERMINISTIC SFs are not allowed while doing
statement-based replication (SBR).
mysql-test/t/rpl_sf.test:
Bug#16456 RBR: rpl_sp.test expects query to fail, but passes in RBR
Test for stored function (SF) calls in different replication modes.
NON DETERMINISTIC SFs are not allowed while doing
statement-based replication (SBR).
2006-11-17 21:30:28 +01:00
create function func_1() returns int deterministic begin reset query cache; return 1; end|
create function func_1() returns int deterministic begin call proc_1(); return 1; end|
2006-08-23 15:50:06 +02:00
delimiter ;|
--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG
select func_1(), func_1(), func_1() from dual;
drop function func_1;
2006-10-11 13:53:56 +02:00
drop procedure proc_1;
2006-08-23 15:50:06 +02:00
prepare abc from "reset query cache";
execute abc;
execute abc;
execute abc;
deallocate prepare abc;
create procedure proc_1() reset master;
delimiter |;
2006-10-11 13:53:56 +02:00
--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG
2006-08-23 15:50:06 +02:00
create function func_1() returns int begin reset master; return 1; end|
2006-10-11 13:53:56 +02:00
create function func_1() returns int begin call proc_1(); return 1; end|
2006-08-23 15:50:06 +02:00
delimiter ;|
--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG
select func_1(), func_1(), func_1() from dual;
drop function func_1;
2006-10-11 13:53:56 +02:00
drop procedure proc_1;
2006-08-23 15:50:06 +02:00
prepare abc from "reset master";
execute abc;
execute abc;
execute abc;
deallocate prepare abc;
create procedure proc_1() reset slave;
call proc_1();
call proc_1();
call proc_1();
delimiter |;
2006-10-11 13:53:56 +02:00
--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG
2006-08-23 15:50:06 +02:00
create function func_1() returns int begin reset slave; return 1; end|
2006-10-11 13:53:56 +02:00
create function func_1() returns int begin call proc_1(); return 1; end|
2006-08-23 15:50:06 +02:00
delimiter ;|
--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG
select func_1(), func_1(), func_1() from dual;
drop function func_1;
2006-10-11 13:53:56 +02:00
drop procedure proc_1;
2006-08-23 15:50:06 +02:00
prepare abc from "reset slave";
execute abc;
execute abc;
execute abc;
deallocate prepare abc;
create procedure proc_1(a integer) kill a;
--error ER_NO_SUCH_THREAD
call proc_1(0);
--error ER_NO_SUCH_THREAD
call proc_1(0);
--error ER_NO_SUCH_THREAD
call proc_1(0);
drop procedure proc_1;
delimiter |;
create function func_1() returns int begin kill 0; return 1; end|
delimiter ;|
--error ER_NO_SUCH_THREAD
select func_1() from dual;
--error ER_NO_SUCH_THREAD
select func_1() from dual;
--error ER_NO_SUCH_THREAD
select func_1() from dual;
drop function func_1;
prepare abc from "kill 0";
--error ER_NO_SUCH_THREAD
execute abc;
--error ER_NO_SUCH_THREAD
execute abc;
--error ER_NO_SUCH_THREAD
execute abc;
deallocate prepare abc;
create procedure proc_1() flush hosts;
call proc_1();
call proc_1();
call proc_1();
call proc_1();
delimiter |;
--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG
create function func_1() returns int begin flush hosts; return 1; end|
2006-10-11 13:53:56 +02:00
create function func_1() returns int begin call proc_1(); return 1; end|
2006-08-23 15:50:06 +02:00
delimiter ;|
2006-10-11 13:53:56 +02:00
--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG
2006-08-23 15:50:06 +02:00
select func_1(), func_1(), func_1() from dual;
drop function func_1;
2006-10-11 13:53:56 +02:00
drop procedure proc_1;
2006-08-23 15:50:06 +02:00
prepare abc from "flush hosts";
execute abc;
execute abc;
execute abc;
deallocate prepare abc;
create procedure proc_1() flush privileges;
call proc_1();
call proc_1();
call proc_1();
delimiter |;
--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG
create function func_1() returns int begin flush privileges; return 1; end|
2006-10-11 13:53:56 +02:00
create function func_1() returns int begin call proc_1(); return 1; end|
2006-08-23 15:50:06 +02:00
delimiter ;|
2006-10-11 13:53:56 +02:00
--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG
2006-08-23 15:50:06 +02:00
select func_1(), func_1(), func_1() from dual;
drop function func_1;
2006-10-11 13:53:56 +02:00
drop procedure proc_1;
2006-08-23 15:50:06 +02:00
prepare abc from "flush privileges";
deallocate prepare abc;
create procedure proc_1() flush tables with read lock;
call proc_1();
unlock tables;
call proc_1();
unlock tables;
call proc_1();
unlock tables;
delimiter |;
--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG
create function func_1() returns int begin flush tables with read lock; return 1; end|
2006-10-11 13:53:56 +02:00
create function func_1() returns int begin call proc_1(); return 1; end|
2006-08-23 15:50:06 +02:00
delimiter ;|
2006-10-11 13:53:56 +02:00
--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG
select func_1(), func_1(), func_1() from dual;
drop function func_1;
drop procedure proc_1;
2006-08-23 15:50:06 +02:00
prepare abc from "flush tables with read lock";
execute abc;
execute abc;
execute abc;
deallocate prepare abc;
unlock tables;
create procedure proc_1() flush tables;
call proc_1();
call proc_1();
call proc_1();
delimiter |;
--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG
create function func_1() returns int begin flush tables; return 1; end|
2006-10-11 13:53:56 +02:00
create function func_1() returns int begin call proc_1(); return 1; end|
2006-08-23 15:50:06 +02:00
delimiter ;|
2006-10-11 13:53:56 +02:00
--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG
2006-08-23 15:50:06 +02:00
select func_1(), func_1(), func_1() from dual;
drop function func_1;
2006-10-11 13:53:56 +02:00
drop procedure proc_1;
2006-08-23 15:50:06 +02:00
prepare abc from "flush tables";
execute abc;
execute abc;
execute abc;
deallocate prepare abc;
create procedure proc_1() flush tables;
flush tables;
show open tables from mysql;
select Host, User from mysql.user limit 0;
select Host, Db from mysql.host limit 0;
show open tables from mysql;
call proc_1();
show open tables from mysql;
select Host, User from mysql.user limit 0;
select Host, Db from mysql.host limit 0;
show open tables from mysql;
call proc_1();
show open tables from mysql;
select Host, User from mysql.user limit 0;
select Host, Db from mysql.host limit 0;
show open tables from mysql;
call proc_1();
show open tables from mysql;
select Host, User from mysql.user limit 0;
select Host, Db from mysql.host limit 0;
show open tables from mysql;
flush tables;
delimiter |;
--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG
create function func_1() returns int begin flush tables; return 1; end|
2006-10-11 13:53:56 +02:00
create function func_1() returns int begin call proc_1(); return 1; end|
2006-08-23 15:50:06 +02:00
delimiter ;|
2006-10-11 13:53:56 +02:00
--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG
2006-08-23 15:50:06 +02:00
select func_1(), func_1(), func_1() from dual;
drop function func_1;
2006-10-11 13:53:56 +02:00
drop procedure proc_1;
WL#3984 (Revise locking of mysql.general_log and mysql.slow_log)
Bug#25422 (Hang with log tables)
Bug 17876 (Truncating mysql.slow_log in a SP after using cursor locks the
thread)
Bug 23044 (Warnings on flush of a log table)
Bug 29129 (Resetting general_log while the GLOBAL READ LOCK is set causes
a deadlock)
Prior to this fix, the server would hang when performing concurrent
ALTER TABLE or TRUNCATE TABLE statements against the LOG TABLES,
which are mysql.general_log and mysql.slow_log.
The root cause traces to the following code:
in sql_base.cc, open_table()
if (table->in_use != thd)
{
/* wait_for_condition will unlock LOCK_open for us */
wait_for_condition(thd, &LOCK_open, &COND_refresh);
}
The problem with this code is that the current implementation of the
LOGGER creates 'fake' THD objects, like
- Log_to_csv_event_handler::general_log_thd
- Log_to_csv_event_handler::slow_log_thd
which are not associated to a real thread running in the server,
so that waiting for these non-existing threads to release table locks
cause the dead lock.
In general, the design of Log_to_csv_event_handler does not fit into the
general architecture of the server, so that the concept of general_log_thd
and slow_log_thd has to be abandoned:
- this implementation does not work with table locking
- it will not work with commands like SHOW PROCESSLIST
- having the log tables always opened does not integrate well with DDL
operations / FLUSH TABLES / SET GLOBAL READ_ONLY
With this patch, the fundamental design of the LOGGER has been changed to:
- always open and close a log table when writing a log
- remove totally the usage of fake THD objects
- clarify how locking of log tables is implemented in general.
See WL#3984 for details related to the new locking design.
Additional changes (misc bugs exposed and fixed):
1)
mysqldump which would ignore some tables in dump_all_tables_in_db(),
but forget to ignore the same in dump_all_views_in_db().
2)
mysqldump would also issue an empty "LOCK TABLE" command when all the tables
to lock are to be ignored (numrows == 0), instead of not issuing the query.
3)
Internal errors handlers could intercept errors but not warnings
(see sql_error.cc).
4)
Implementing a nested call to open tables, for the performance schema tables,
exposed an existing bug in remove_table_from_cache(), which would perform:
in_use->some_tables_deleted=1;
against another thread, without any consideration about thread locking.
This call inside remove_table_from_cache() was not required anyway,
since calling mysql_lock_abort() takes care of aborting -- cleanly -- threads
that might hold a lock on a table.
This line (in_use->some_tables_deleted=1) has been removed.
sql/handler.cc:
Moved logic for system / log tables in the SQL layer.
sql/handler.h:
Moved logic for system / log tables in the SQL layer.
sql/lock.cc:
Revised locking of log tables
sql/log.cc:
Major cleanup: changed how log tables are locked / written to.
sql/log.h:
Major cleanup: changed how log tables are locked / written to.
sql/mysql_priv.h:
performance schema helpers
sql/slave.cc:
open_ltable() lock flags
sql/sp.cc:
open_ltable() lock flags
sql/sql_acl.cc:
open_ltable() lock flags
sql/sql_class.h:
performance schema helpers
sql/sql_delete.cc:
log tables cleanup in TRUNCATE
sql/sql_error.cc:
Internal handlers can also intercept warnings
sql/sql_insert.cc:
open_ltable() lock flags
sql/sql_parse.cc:
performance schema helpers
sql/sql_plugin.cc:
open_ltable() lock flags
sql/sql_rename.cc:
log tables cleanup in RENAME
sql/sql_servers.cc:
open_ltable() lock flags
sql/sql_show.cc:
Move INFORMATION_SCHEMA_NAME to table.cc
sql/sql_table.cc:
log tables cleanup (admin operations, ALTER TABLE)
sql/sql_udf.cc:
open_ltable() lock flags
sql/table.cc:
Implemented TABLE_CATEGORY.
sql/share/errmsg.txt:
Changed the wording and name of ER_CANT_READ_LOCK_LOG_TABLE
sql/table.h:
Implemented TABLE_CATEGORY.
storage/csv/ha_tina.cc:
Moved logic for system / log tables in the SQL layer.
storage/csv/ha_tina.h:
Moved logic for system / log tables in the SQL layer.
storage/myisam/ha_myisam.cc:
Moved logic for system / log tables in the SQL layer.
storage/myisam/ha_myisam.h:
Moved logic for system / log tables in the SQL layer.
client/mysqldump.c:
Don't lock tables in the ignore list.
Don't issue empty LOCK TABLES queries.
sql/sql_base.cc:
log tables cleanup
performance schema helpers
mysql-test/r/ps.result:
Adjust test results
mysql-test/r/show_check.result:
Adjust test results
mysql-test/r/status.result:
Adjust test results
mysql-test/t/log_state.test:
Added tests for Bug#29129
mysql-test/t/ps.test:
Make the test output deterministic
mysql-test/t/show_check.test:
Make the test output deterministic
mysql-test/r/log_state.result:
Changed the default location of the log output to LOG_FILE,
for backward compatibility with MySQL 5.0
---
Adjust test results
mysql-test/r/log_tables.result:
cleanup for -ps-protocol
mysql-test/t/log_tables.test:
cleanup for -ps-protocol
sql/set_var.cc:
Changed the default location of the log output to LOG_FILE,
for backward compatibility with MySQL 5.0
---
log tables cleanup
2007-07-27 08:31:06 +02:00
# make the output deterministic:
# the order used in SHOW OPEN TABLES
# is too much implementation dependent
--disable_ps_protocol
2006-08-23 15:50:06 +02:00
flush tables;
select Host, User from mysql.user limit 0;
select Host, Db from mysql.host limit 0;
show open tables from mysql;
WL#3984 (Revise locking of mysql.general_log and mysql.slow_log)
Bug#25422 (Hang with log tables)
Bug 17876 (Truncating mysql.slow_log in a SP after using cursor locks the
thread)
Bug 23044 (Warnings on flush of a log table)
Bug 29129 (Resetting general_log while the GLOBAL READ LOCK is set causes
a deadlock)
Prior to this fix, the server would hang when performing concurrent
ALTER TABLE or TRUNCATE TABLE statements against the LOG TABLES,
which are mysql.general_log and mysql.slow_log.
The root cause traces to the following code:
in sql_base.cc, open_table()
if (table->in_use != thd)
{
/* wait_for_condition will unlock LOCK_open for us */
wait_for_condition(thd, &LOCK_open, &COND_refresh);
}
The problem with this code is that the current implementation of the
LOGGER creates 'fake' THD objects, like
- Log_to_csv_event_handler::general_log_thd
- Log_to_csv_event_handler::slow_log_thd
which are not associated to a real thread running in the server,
so that waiting for these non-existing threads to release table locks
cause the dead lock.
In general, the design of Log_to_csv_event_handler does not fit into the
general architecture of the server, so that the concept of general_log_thd
and slow_log_thd has to be abandoned:
- this implementation does not work with table locking
- it will not work with commands like SHOW PROCESSLIST
- having the log tables always opened does not integrate well with DDL
operations / FLUSH TABLES / SET GLOBAL READ_ONLY
With this patch, the fundamental design of the LOGGER has been changed to:
- always open and close a log table when writing a log
- remove totally the usage of fake THD objects
- clarify how locking of log tables is implemented in general.
See WL#3984 for details related to the new locking design.
Additional changes (misc bugs exposed and fixed):
1)
mysqldump which would ignore some tables in dump_all_tables_in_db(),
but forget to ignore the same in dump_all_views_in_db().
2)
mysqldump would also issue an empty "LOCK TABLE" command when all the tables
to lock are to be ignored (numrows == 0), instead of not issuing the query.
3)
Internal errors handlers could intercept errors but not warnings
(see sql_error.cc).
4)
Implementing a nested call to open tables, for the performance schema tables,
exposed an existing bug in remove_table_from_cache(), which would perform:
in_use->some_tables_deleted=1;
against another thread, without any consideration about thread locking.
This call inside remove_table_from_cache() was not required anyway,
since calling mysql_lock_abort() takes care of aborting -- cleanly -- threads
that might hold a lock on a table.
This line (in_use->some_tables_deleted=1) has been removed.
sql/handler.cc:
Moved logic for system / log tables in the SQL layer.
sql/handler.h:
Moved logic for system / log tables in the SQL layer.
sql/lock.cc:
Revised locking of log tables
sql/log.cc:
Major cleanup: changed how log tables are locked / written to.
sql/log.h:
Major cleanup: changed how log tables are locked / written to.
sql/mysql_priv.h:
performance schema helpers
sql/slave.cc:
open_ltable() lock flags
sql/sp.cc:
open_ltable() lock flags
sql/sql_acl.cc:
open_ltable() lock flags
sql/sql_class.h:
performance schema helpers
sql/sql_delete.cc:
log tables cleanup in TRUNCATE
sql/sql_error.cc:
Internal handlers can also intercept warnings
sql/sql_insert.cc:
open_ltable() lock flags
sql/sql_parse.cc:
performance schema helpers
sql/sql_plugin.cc:
open_ltable() lock flags
sql/sql_rename.cc:
log tables cleanup in RENAME
sql/sql_servers.cc:
open_ltable() lock flags
sql/sql_show.cc:
Move INFORMATION_SCHEMA_NAME to table.cc
sql/sql_table.cc:
log tables cleanup (admin operations, ALTER TABLE)
sql/sql_udf.cc:
open_ltable() lock flags
sql/table.cc:
Implemented TABLE_CATEGORY.
sql/share/errmsg.txt:
Changed the wording and name of ER_CANT_READ_LOCK_LOG_TABLE
sql/table.h:
Implemented TABLE_CATEGORY.
storage/csv/ha_tina.cc:
Moved logic for system / log tables in the SQL layer.
storage/csv/ha_tina.h:
Moved logic for system / log tables in the SQL layer.
storage/myisam/ha_myisam.cc:
Moved logic for system / log tables in the SQL layer.
storage/myisam/ha_myisam.h:
Moved logic for system / log tables in the SQL layer.
client/mysqldump.c:
Don't lock tables in the ignore list.
Don't issue empty LOCK TABLES queries.
sql/sql_base.cc:
log tables cleanup
performance schema helpers
mysql-test/r/ps.result:
Adjust test results
mysql-test/r/show_check.result:
Adjust test results
mysql-test/r/status.result:
Adjust test results
mysql-test/t/log_state.test:
Added tests for Bug#29129
mysql-test/t/ps.test:
Make the test output deterministic
mysql-test/t/show_check.test:
Make the test output deterministic
mysql-test/r/log_state.result:
Changed the default location of the log output to LOG_FILE,
for backward compatibility with MySQL 5.0
---
Adjust test results
mysql-test/r/log_tables.result:
cleanup for -ps-protocol
mysql-test/t/log_tables.test:
cleanup for -ps-protocol
sql/set_var.cc:
Changed the default location of the log output to LOG_FILE,
for backward compatibility with MySQL 5.0
---
log tables cleanup
2007-07-27 08:31:06 +02:00
--enable_ps_protocol
2006-08-23 15:50:06 +02:00
prepare abc from "flush tables";
execute abc;
show open tables from mysql;
select Host, User from mysql.user limit 0;
select Host, Db from mysql.host limit 0;
show open tables from mysql;
execute abc;
show open tables from mysql;
select Host, User from mysql.user limit 0;
select Host, Db from mysql.host limit 0;
show open tables from mysql;
execute abc;
show open tables from mysql;
select Host, User from mysql.user limit 0;
select Host, Db from mysql.host limit 0;
show open tables from mysql;
flush tables;
deallocate prepare abc;
create procedure proc_1() flush logs;
call proc_1();
call proc_1();
call proc_1();
delimiter |;
--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG
create function func_1() returns int begin flush logs; return 1; end|
2006-10-11 13:53:56 +02:00
create function func_1() returns int begin call proc_1(); return 1; end|
2006-08-23 15:50:06 +02:00
delimiter ;|
2006-10-11 13:53:56 +02:00
--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG
2006-08-23 15:50:06 +02:00
select func_1(), func_1(), func_1() from dual;
drop function func_1;
2006-10-11 13:53:56 +02:00
drop procedure proc_1;
2006-08-23 15:50:06 +02:00
prepare abc from "flush logs";
execute abc;
execute abc;
execute abc;
deallocate prepare abc;
create procedure proc_1() flush status;
call proc_1();
call proc_1();
call proc_1();
delimiter |;
--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG
create function func_1() returns int begin flush status; return 1; end|
2006-10-11 13:53:56 +02:00
create function func_1() returns int begin call proc_1(); return 1; end|
2006-08-23 15:50:06 +02:00
delimiter ;|
2006-10-11 13:53:56 +02:00
--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG
2006-08-23 15:50:06 +02:00
select func_1(), func_1(), func_1() from dual;
drop function func_1;
2006-10-11 13:53:56 +02:00
drop procedure proc_1;
2006-08-23 15:50:06 +02:00
prepare abc from "flush status";
execute abc;
execute abc;
execute abc;
deallocate prepare abc;
create procedure proc_1() flush slave;
call proc_1();
call proc_1();
call proc_1();
delimiter |;
--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG
create function func_1() returns int begin flush slave; return 1; end|
2006-10-11 13:53:56 +02:00
create function func_1() returns int begin call proc_1(); return 1; end|
2006-08-23 15:50:06 +02:00
delimiter ;|
2006-10-11 13:53:56 +02:00
--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG
2006-08-23 15:50:06 +02:00
select func_1(), func_1(), func_1() from dual;
drop function func_1;
2006-10-11 13:53:56 +02:00
drop procedure proc_1;
2006-08-23 15:50:06 +02:00
prepare abc from "flush slave";
execute abc;
execute abc;
execute abc;
deallocate prepare abc;
create procedure proc_1() flush master;
delimiter |;
--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG
create function func_1() returns int begin flush master; return 1; end|
2006-10-11 13:53:56 +02:00
create function func_1() returns int begin call proc_1(); return 1; end|
2006-08-23 15:50:06 +02:00
delimiter ;|
2006-10-11 13:53:56 +02:00
--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG
2006-08-23 15:50:06 +02:00
select func_1(), func_1(), func_1() from dual;
drop function func_1;
2006-10-11 13:53:56 +02:00
drop procedure proc_1;
2006-08-23 15:50:06 +02:00
prepare abc from "flush master";
deallocate prepare abc;
create procedure proc_1() flush des_key_file;
call proc_1();
call proc_1();
call proc_1();
delimiter |;
--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG
create function func_1() returns int begin flush des_key_file; return 1; end|
2006-10-11 13:53:56 +02:00
create function func_1() returns int begin call proc_1(); return 1; end|
2006-08-23 15:50:06 +02:00
delimiter ;|
2006-10-11 13:53:56 +02:00
--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG
2006-08-23 15:50:06 +02:00
select func_1(), func_1(), func_1() from dual;
drop function func_1;
2006-10-11 13:53:56 +02:00
drop procedure proc_1;
2006-08-23 15:50:06 +02:00
prepare abc from "flush des_key_file";
execute abc;
execute abc;
execute abc;
deallocate prepare abc;
create procedure proc_1() flush user_resources;
call proc_1();
call proc_1();
call proc_1();
delimiter |;
--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG
create function func_1() returns int begin flush user_resources; return 1; end|
2006-10-11 13:53:56 +02:00
create function func_1() returns int begin call proc_1(); return 1; end|
2006-08-23 15:50:06 +02:00
delimiter ;|
2006-10-11 13:53:56 +02:00
--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG
2006-08-23 15:50:06 +02:00
select func_1(), func_1(), func_1() from dual;
drop function func_1;
2006-10-11 13:53:56 +02:00
drop procedure proc_1;
2006-08-23 15:50:06 +02:00
prepare abc from "flush user_resources";
execute abc;
execute abc;
execute abc;
deallocate prepare abc;
create procedure proc_1() start slave;
drop procedure proc_1;
delimiter |;
create function func_1() returns int begin start slave; return 1; end|
delimiter ;|
drop function func_1;
prepare abc from "start slave";
deallocate prepare abc;
create procedure proc_1() stop slave;
drop procedure proc_1;
delimiter |;
create function func_1() returns int begin stop slave; return 1; end|
delimiter ;|
drop function func_1;
prepare abc from "stop slave";
deallocate prepare abc;
create procedure proc_1() show binlog events;
drop procedure proc_1;
delimiter |;
--error ER_SP_NO_RETSET
create function func_1() returns int begin show binlog events; return 1; end|
delimiter ;|
--error ER_SP_DOES_NOT_EXIST
select func_1(), func_1(), func_1() from dual;
--error ER_SP_DOES_NOT_EXIST
drop function func_1;
prepare abc from "show binlog events";
deallocate prepare abc;
create procedure proc_1() show slave status;
drop procedure proc_1;
delimiter |;
--error ER_SP_NO_RETSET
create function func_1() returns int begin show slave status; return 1; end|
delimiter ;|
--error ER_SP_DOES_NOT_EXIST
select func_1(), func_1(), func_1() from dual;
--error ER_SP_DOES_NOT_EXIST
drop function func_1;
prepare abc from "show slave status";
deallocate prepare abc;
create procedure proc_1() show master status;
drop procedure proc_1;
delimiter |;
--error ER_SP_NO_RETSET
create function func_1() returns int begin show master status; return 1; end|
delimiter ;|
--error ER_SP_DOES_NOT_EXIST
select func_1(), func_1(), func_1() from dual;
--error ER_SP_DOES_NOT_EXIST
drop function func_1;
prepare abc from "show master status";
deallocate prepare abc;
create procedure proc_1() show master logs;
drop procedure proc_1;
delimiter |;
--error ER_SP_NO_RETSET
create function func_1() returns int begin show master logs; return 1; end|
delimiter ;|
--error ER_SP_DOES_NOT_EXIST
select func_1(), func_1(), func_1() from dual;
--error ER_SP_DOES_NOT_EXIST
drop function func_1;
prepare abc from "show master logs";
deallocate prepare abc;
create procedure proc_1() show events;
call proc_1();
call proc_1();
call proc_1();
drop procedure proc_1;
delimiter |;
--error ER_SP_NO_RETSET
create function func_1() returns int begin show events; return 1; end|
delimiter ;|
--error ER_SP_DOES_NOT_EXIST
select func_1(), func_1(), func_1() from dual;
--error ER_SP_DOES_NOT_EXIST
drop function func_1;
prepare abc from "show events";
execute abc;
execute abc;
execute abc;
deallocate prepare abc;
--disable_warnings
drop procedure if exists a;
--enable_warnings
create procedure a() select 42;
create procedure proc_1(a char(2)) show create procedure a;
call proc_1("bb");
call proc_1("bb");
call proc_1("bb");
drop procedure proc_1;
delimiter |;
--error ER_SP_NO_RETSET
create function func_1() returns int begin show create procedure a; return 1; end|
delimiter ;|
--error ER_SP_DOES_NOT_EXIST
select func_1(), func_1(), func_1() from dual;
--error ER_SP_DOES_NOT_EXIST
drop function func_1;
prepare abc from "show create procedure a";
execute abc;
execute abc;
execute abc;
deallocate prepare abc;
drop procedure a;
--disable_warnings
drop function if exists a;
--enable_warnings
create function a() returns int return 42+13;
create procedure proc_1(a char(2)) show create function a;
call proc_1("bb");
call proc_1("bb");
call proc_1("bb");
drop procedure proc_1;
delimiter |;
--error ER_SP_NO_RETSET
create function func_1() returns int begin show create function a; return 1; end|
delimiter ;|
--error ER_SP_DOES_NOT_EXIST
select func_1(), func_1(), func_1() from dual;
--error ER_SP_DOES_NOT_EXIST
drop function func_1;
prepare abc from "show create function a";
execute abc;
execute abc;
execute abc;
deallocate prepare abc;
drop function a;
--disable_warnings
drop table if exists tab1;
--enable_warnings
create table tab1(a int, b char(1), primary key(a,b));
create procedure proc_1() show create table tab1;
call proc_1();
call proc_1();
call proc_1();
drop procedure proc_1;
delimiter |;
--error ER_SP_NO_RETSET
create function func_1() returns int begin show create table tab1; return 1; end|
delimiter ;|
--error ER_SP_DOES_NOT_EXIST
select func_1(), func_1(), func_1() from dual;
--error ER_SP_DOES_NOT_EXIST
drop function func_1;
prepare abc from "show create table tab1";
execute abc;
execute abc;
execute abc;
deallocate prepare abc;
drop table tab1;
--disable_warnings
drop view if exists v1;
drop table if exists t1;
--enable_warnings
create table t1(a int, b char(5));
insert into t1 values (1, "one"), (1, "edno"), (2, "two"), (2, "dve");
create view v1 as
(select a, count(*) from t1 group by a)
union all
(select b, count(*) from t1 group by b);
create procedure proc_1() show create view v1;
call proc_1();
call proc_1();
call proc_1();
drop procedure proc_1;
delimiter |;
--error ER_SP_NO_RETSET
create function func_1() returns int begin show create view v1; return 1; end|
delimiter ;|
--error ER_SP_DOES_NOT_EXIST
select func_1(), func_1(), func_1() from dual;
--error ER_SP_DOES_NOT_EXIST
drop function func_1;
prepare abc from "show create view v1";
execute abc;
execute abc;
execute abc;
deallocate prepare abc;
drop view v1;
drop table t1;
create procedure proc_1() install plugin my_plug soname 'some_plugin.so';
2006-10-11 13:53:56 +02:00
--replace_regex /(Can\'t open shared library).*$/\1/
2007-02-23 12:13:55 +01:00
--error ER_CANT_OPEN_LIBRARY,ER_FEATURE_DISABLED
2006-08-23 15:50:06 +02:00
call proc_1();
2006-10-11 13:53:56 +02:00
--replace_regex /(Can\'t open shared library).*$/\1/
2007-02-23 12:13:55 +01:00
--error ER_CANT_OPEN_LIBRARY,ER_FEATURE_DISABLED
2006-08-23 15:50:06 +02:00
call proc_1();
2006-10-11 13:53:56 +02:00
--replace_regex /(Can\'t open shared library).*$/\1/
2007-02-23 12:13:55 +01:00
--error ER_CANT_OPEN_LIBRARY,ER_FEATURE_DISABLED
2006-08-23 15:50:06 +02:00
call proc_1();
drop procedure proc_1;
delimiter |;
--error ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG
create function func_1() returns int begin install plugin my_plug soname '/tmp/plugin'; return 1; end|
delimiter ;|
--error ER_SP_DOES_NOT_EXIST
select func_1(), func_1(), func_1() from dual;
--error ER_SP_DOES_NOT_EXIST
drop function func_1;
prepare abc from "install plugin my_plug soname 'some_plugin.so'";
deallocate prepare abc;
create procedure proc_1() uninstall plugin my_plug;
--error ER_SP_DOES_NOT_EXIST
call proc_1();
--error ER_SP_DOES_NOT_EXIST
call proc_1();
--error ER_SP_DOES_NOT_EXIST
call proc_1();
drop procedure proc_1;
delimiter |;
--error ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG
create function func_1() returns int begin uninstall plugin my_plug; return 1; end|
delimiter ;|
--error ER_SP_DOES_NOT_EXIST
select func_1(), func_1(), func_1() from dual;
--error ER_SP_DOES_NOT_EXIST
drop function func_1;
prepare abc from "uninstall plugin my_plug";
--error ER_SP_DOES_NOT_EXIST
execute abc;
--error ER_SP_DOES_NOT_EXIST
execute abc;
--error ER_SP_DOES_NOT_EXIST
execute abc;
deallocate prepare abc;
--disable_warnings
drop database if exists mysqltest_xyz;
--enable_warnings
create procedure proc_1() create database mysqltest_xyz;
call proc_1();
drop database if exists mysqltest_xyz;
call proc_1();
--error ER_DB_CREATE_EXISTS
call proc_1();
drop database if exists mysqltest_xyz;
call proc_1();
drop database if exists mysqltest_xyz;
drop procedure proc_1;
delimiter |;
--error ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG
create function func_1() returns int begin create database mysqltest_xyz; return 1; end|
delimiter ;|
--error ER_SP_DOES_NOT_EXIST
select func_1(), func_1(), func_1() from dual;
--error ER_SP_DOES_NOT_EXIST
drop function func_1;
prepare abc from "create database mysqltest_xyz";
execute abc;
drop database if exists mysqltest_xyz;
execute abc;
--error ER_DB_CREATE_EXISTS
execute abc;
drop database if exists mysqltest_xyz;
execute abc;
drop database if exists mysqltest_xyz;
deallocate prepare abc;
--disable_warnings
drop table if exists t1;
--enable_warnings
create table t1 (a int, b char(5));
insert into t1 values (1, "one"), (2, "two"), (3, "three");
create procedure proc_1() checksum table xyz;
call proc_1();
call proc_1();
call proc_1();
drop procedure proc_1;
delimiter |;
--error ER_SP_NO_RETSET
create function func_1() returns int begin checksum table t1; return 1; end|
delimiter ;|
--error ER_SP_DOES_NOT_EXIST
select func_1(), func_1(), func_1() from dual;
--error ER_SP_DOES_NOT_EXIST
drop function func_1;
prepare abc from "checksum table t1";
execute abc;
execute abc;
execute abc;
deallocate prepare abc;
create procedure proc_1() create user pstest_xyz@localhost;
call proc_1();
drop user pstest_xyz@localhost;
call proc_1();
--error ER_CANNOT_USER
call proc_1();
drop user pstest_xyz@localhost;
call proc_1();
drop user pstest_xyz@localhost;
drop procedure proc_1;
delimiter |;
--error ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG
create function func_1() returns int begin create user pstest_xyz@localhost; return 1; end|
delimiter ;|
--error ER_SP_DOES_NOT_EXIST
select func_1(), func_1(), func_1() from dual;
--error ER_SP_DOES_NOT_EXIST
drop function func_1;
prepare abc from "create user pstest_xyz@localhost";
execute abc;
drop user pstest_xyz@localhost;
execute abc;
--error ER_CANNOT_USER
execute abc;
drop user pstest_xyz@localhost;
execute abc;
drop user pstest_xyz@localhost;
deallocate prepare abc;
--disable_warnings
drop event if exists xyz;
--enable_warnings
#create procedure proc_1() create event xyz on schedule every 5 minute disable do select 123;
#call proc_1();
#drop event xyz;
#call proc_1();
#--error ER_EVENT_ALREADY_EXISTS
#call proc_1();
#drop event xyz;
#call proc_1();
#drop event xyz;
#drop procedure proc_1;
delimiter |;
2007-03-27 20:15:51 +02:00
--error ER_EVENT_RECURSION_FORBIDDEN
2006-08-23 15:50:06 +02:00
create function func_1() returns int begin create event xyz on schedule at now() do select 123; return 1; end|
delimiter ;|
--error ER_SP_DOES_NOT_EXIST
select func_1(), func_1(), func_1() from dual;
--error ER_SP_DOES_NOT_EXIST
drop function func_1;
--error ER_UNSUPPORTED_PS
prepare abc from "create event xyz on schedule at now() do select 123";
--error ER_UNKNOWN_STMT_HANDLER
deallocate prepare abc;
--disable_warnings
drop event if exists xyz;
create event xyz on schedule every 5 minute disable do select 123;
--enable_warnings
create procedure proc_1() alter event xyz comment 'xyz';
call proc_1();
drop event xyz;
create event xyz on schedule every 5 minute disable do select 123;
call proc_1();
drop event xyz;
create event xyz on schedule every 5 minute disable do select 123;
call proc_1();
drop event xyz;
drop procedure proc_1;
delimiter |;
--error ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG
create function func_1() returns int begin alter event xyz comment 'xyz'; return 1; end|
delimiter ;|
--error ER_UNSUPPORTED_PS
prepare abc from "alter event xyz comment 'xyz'";
--error ER_UNKNOWN_STMT_HANDLER
deallocate prepare abc;
--disable_warnings
drop event if exists xyz;
create event xyz on schedule every 5 minute disable do select 123;
--enable_warnings
create procedure proc_1() drop event xyz;
call proc_1();
create event xyz on schedule every 5 minute disable do select 123;
call proc_1();
--error ER_EVENT_DOES_NOT_EXIST
call proc_1();
drop procedure proc_1;
delimiter |;
--error ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG
create function func_1() returns int begin drop event xyz; return 1; end|
delimiter ;|
--error ER_UNSUPPORTED_PS
prepare abc from "drop event xyz";
--error ER_UNKNOWN_STMT_HANDLER
deallocate prepare abc;
--disable_warnings
drop table if exists t1;
create table t1 (a int, b char(5)) engine=myisam;
insert into t1 values (1, "one"), (2, "two"), (3, "three");
--enable_warnings
SET GLOBAL new_cache.key_buffer_size=128*1024;
create procedure proc_1() cache index t1 in new_cache;
call proc_1();
call proc_1();
call proc_1();
drop procedure proc_1;
SET GLOBAL second_cache.key_buffer_size=128*1024;
prepare abc from "cache index t1 in second_cache";
execute abc;
execute abc;
execute abc;
deallocate prepare abc;
drop table t1;
--disable_warnings
drop table if exists t1;
drop table if exists t2;
create table t1 (a int, b char(5)) engine=myisam;
insert into t1 values (1, "one"), (2, "two"), (3, "three");
create table t2 (a int, b char(5)) engine=myisam;
insert into t2 values (1, "one"), (2, "two"), (3, "three");
--enable_warnings
create procedure proc_1() load index into cache t1 ignore leaves;
call proc_1();
call proc_1();
call proc_1();
drop procedure proc_1;
delimiter |;
--error ER_SP_NO_RETSET
create function func_1() returns int begin load index into cache t1 ignore leaves; return 1; end|
delimiter ;|
prepare abc from "load index into cache t2 ignore leaves";
execute abc;
execute abc;
execute abc;
deallocate prepare abc;
drop table t1, t2;
#
# Bug #21422: GRANT/REVOKE possible inside stored function, probably in a trigger
# This is disabled for now till it is resolved in 5.0
#
#create procedure proc_1() grant all on *.* to abc@host;
#drop procedure proc_1;
#delimiter |;
#--error ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG
#create function func_1() returns int begin grant all on *.* to abc@host; return 1; end|
#delimiter ;|
#prepare abc from "grant all on *.* to abc@host";
#
#create procedure proc_1() revoke all on *.* from abc@host;
#drop procedure proc_1;
#delimiter |;#--error ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG
#create function func_1() returns int begin revoke all on *.* from abc@host; return 1; end|
#delimiter ;|
#prepare abc from "revoke all on *.* from abc@host";
create procedure proc_1() show errors;
call proc_1();
call proc_1();
call proc_1();
drop procedure proc_1;
delimiter |;
--error ER_SP_NO_RETSET
create function func_1() returns int begin show errors; return 1; end|
delimiter ;|
prepare abc from "show errors";
deallocate prepare abc;
--disable_warnings
drop table if exists t1;
drop table if exists t2;
--enable_warnings
create procedure proc_1() show warnings;
drop table if exists t1;
call proc_1();
drop table if exists t2;
call proc_1();
drop table if exists t1, t2;
call proc_1();
drop procedure proc_1;
delimiter |;
--error ER_SP_NO_RETSET
create function func_1() returns int begin show warnings; return 1; end|
delimiter ;|
prepare abc from "show warnings";
drop table if exists t1;
execute abc;
drop table if exists t2;
execute abc;
drop table if exists t1, t2;
execute abc;
deallocate prepare abc;
Bug#22684 (BENCHMARK, ENCODE, DECODE and FORMAT are not real functions)
Before this change, the functions BENCHMARK, ENCODE, DECODE and FORMAT could
only accept a constant for some parameters.
After this change, this restriction has been removed. An implication is that
these functions can also be used in prepared statements.
The change consist of changing the following classes:
- Item_func_benchmark
- Item_func_encode
- Item_func_decode
- Item_func_format
to:
- only accept Item* in the constructor,
- and evaluate arguments during calls to val_xxx()
which fits the general design of all the other functions.
The 'TODO' items identified in item_create.cc during the work done for
Bug 21114 are addressed by this fix, as a natural consequence of aligning
the design.
In the 'func_str' test, a single very long test line involving an explain
extended select with many functions has been rewritten into multiple
separate tests, to improve maintainability.
The result of explain extended select decode(encode(...)) has changed,
since the encode and decode functions now print all their parameters.
mysql-test/r/func_str.result:
Bug#22684 (BENCHMARK, ENCODE, DECODE and FORMAT are not real functions)
mysql-test/r/parser.result:
Bug#22684 (BENCHMARK, ENCODE, DECODE and FORMAT are not real functions)
mysql-test/r/ps.result:
Bug#22684 (BENCHMARK, ENCODE, DECODE and FORMAT are not real functions)
mysql-test/t/func_str.test:
Bug#22684 (BENCHMARK, ENCODE, DECODE and FORMAT are not real functions)
mysql-test/t/parser.test:
Bug#22684 (BENCHMARK, ENCODE, DECODE and FORMAT are not real functions)
mysql-test/t/ps.test:
Bug#22684 (BENCHMARK, ENCODE, DECODE and FORMAT are not real functions)
sql/item_create.cc:
Bug#22684 (BENCHMARK, ENCODE, DECODE and FORMAT are not real functions)
sql/item_func.cc:
Bug#22684 (BENCHMARK, ENCODE, DECODE and FORMAT are not real functions)
sql/item_func.h:
Bug#22684 (BENCHMARK, ENCODE, DECODE and FORMAT are not real functions)
sql/item_strfunc.cc:
Bug#22684 (BENCHMARK, ENCODE, DECODE and FORMAT are not real functions)
sql/item_strfunc.h:
Bug#22684 (BENCHMARK, ENCODE, DECODE and FORMAT are not real functions)
2006-11-16 17:03:47 +01:00
#
# Bug#22684: The Functions ENCODE, DECODE and FORMAT are not real functions
#
set @my_password="password";
set @my_data="clear text to encode";
prepare stmt1 from 'select decode(encode(?, ?), ?)';
execute stmt1 using @my_data, @my_password, @my_password;
set @my_data="more text to encode";
execute stmt1 using @my_data, @my_password, @my_password;
set @my_password="new password";
execute stmt1 using @my_data, @my_password, @my_password;
deallocate prepare stmt1;
set @to_format="123456789.123456789";
set @dec=0;
prepare stmt2 from 'select format(?, ?)';
execute stmt2 using @to_format, @dec;
set @dec=4;
execute stmt2 using @to_format, @dec;
set @dec=6;
execute stmt2 using @to_format, @dec;
set @dec=2;
execute stmt2 using @to_format, @dec;
set @to_format="100";
execute stmt2 using @to_format, @dec;
set @to_format="1000000";
execute stmt2 using @to_format, @dec;
set @to_format="10000";
execute stmt2 using @to_format, @dec;
deallocate prepare stmt2;
2007-03-07 16:51:49 +01:00
#
# BUG#18326: Do not lock table for writing during prepare of statement
#
--disable_warnings
DROP TABLE IF EXISTS t1, t2;
--enable_warnings
CREATE TABLE t1 (i INT);
INSERT INTO t1 VALUES (1);
CREATE TABLE t2 (i INT);
INSERT INTO t2 VALUES (2);
LOCK TABLE t1 READ, t2 WRITE;
connect (conn1, localhost, root, , );
# Prepare never acquires the lock, and thus should not block.
PREPARE stmt1 FROM "SELECT i FROM t1";
PREPARE stmt2 FROM "INSERT INTO t2 (i) VALUES (3)";
# This should not block because READ lock on t1 is shared.
EXECUTE stmt1;
# This should block because WRITE lock on t2 is exclusive.
send EXECUTE stmt2;
connection default;
SELECT * FROM t2;
UNLOCK TABLES;
let $wait_condition= SELECT COUNT(*) = 2 FROM t2;
--source include/wait_condition.inc
SELECT * FROM t2;
# DDL and DML works even if some client have a prepared statement
# referencing the table.
ALTER TABLE t1 ADD COLUMN j INT;
ALTER TABLE t2 ADD COLUMN j INT;
INSERT INTO t1 VALUES (4, 5);
INSERT INTO t2 VALUES (4, 5);
connection conn1;
reap;
EXECUTE stmt1;
EXECUTE stmt2;
SELECT * FROM t2;
disconnect conn1;
connection default;
DROP TABLE t1, t2;
5.1 version of a fix and test cases for bugs:
Bug#4968 ""Stored procedure crash if cursor opened on altered table"
Bug#6895 "Prepared Statements: ALTER TABLE DROP COLUMN does nothing"
Bug#19182 "CREATE TABLE bar (m INT) SELECT n FROM foo; doesn't work from
stored procedure."
Bug#19733 "Repeated alter, or repeated create/drop, fails"
Bug#22060 "ALTER TABLE x AUTO_INCREMENT=y in SP crashes server"
Bug#24879 "Prepared Statements: CREATE TABLE (UTF8 KEY) produces a
growing key length" (this bug is not fixed in 5.0)
Re-execution of CREATE DATABASE, CREATE TABLE and ALTER TABLE
statements in stored routines or as prepared statements caused
incorrect results (and crashes in versions prior to 5.0.25).
In 5.1 the problem occured only for CREATE DATABASE, CREATE TABLE
SELECT and CREATE TABLE with INDEX/DATA DIRECTOY options).
The problem of bugs 4968, 19733, 19282 and 6895 was that functions
mysql_prepare_table, mysql_create_table and mysql_alter_table are not
re-execution friendly: during their operation they modify contents
of LEX (members create_info, alter_info, key_list, create_list),
thus making the LEX unusable for the next execution.
In particular, these functions removed processed columns and keys from
create_list, key_list and drop_list. Search the code in sql_table.cc
for drop_it.remove() and similar patterns to find evidence.
The fix is to supply to these functions a usable copy of each of the
above structures at every re-execution of an SQL statement.
To simplify memory management, LEX::key_list and LEX::create_list
were added to LEX::alter_info, a fresh copy of which is created for
every execution.
The problem of crashing bug 22060 stemmed from the fact that the above
metnioned functions were not only modifying HA_CREATE_INFO structure
in LEX, but also were changing it to point to areas in volatile memory
of the execution memory root.
The patch solves this problem by creating and using an on-stack
copy of HA_CREATE_INFO in mysql_execute_command.
Additionally, this patch splits the part of mysql_alter_table
that analizes and rewrites information from the parser into
a separate function - mysql_prepare_alter_table, in analogy with
mysql_prepare_table, which is renamed to mysql_prepare_create_table.
mysql-test/r/ps.result:
Update test results (Bug#19182, Bug#22060, Bug#4968, Bug#6895)
mysql-test/r/sp.result:
Update results (Bug#19733)
mysql-test/t/ps.test:
Add test cases for Bug#19182, Bug#22060, Bug#4968, Bug#6895
mysql-test/t/sp.test:
Add a test case for Bug#19733
sql/field.h:
Implement a deep copy constructor for create_field
sql/mysql_priv.h:
LEX::key_list and LEX::create_list were moved to LEX::alter_info.
Update declarations to use LEX::alter_info instead of these two
members.
Remove declarations of mysql_add_index, mysql_drop_index.
sql/sql_class.cc:
Implement deep copy constructors.
sql/sql_class.h:
Implement (almost) deep copy constructors for key_part_spec,
Alter_drop, Alter_column, Key, foreign_key.
Replace pair<columns, keys> with an instance of Alter_info in
select_create constructor. We create a new copy of Alter_info
each time we re-execute SELECT .. CREATE prepared statement.
sql/sql_insert.cc:
Adjust to a new signature of create_table_from_items.
sql/sql_lex.cc:
Implement Alter_info::Alter_info that would make a "deep" copy
of all definition lists (keys, columns).
Move is_partition_management() from sql_partition.cc (feature-based
file division is evil).
sql/sql_lex.h:
Move key_list and create_list to class Alter_info. Implement
Alter_info::Alter_info that can be used with PS and SP.
Get rid of Alter_info::clear() which was an attempt to save on
matches and always use Alter_info::reset().
Implement an auxiliary Alter_info::init_for_create_from_alter()
which is used in mysql_alter_table.
sql/sql_list.cc:
Implement a copy constructor of class List that makes a deep copy
of all list nodes.
sql/sql_list.h:
Implement a way to make a deep copy of all list nodes.
sql/sql_parse.cc:
Adjust to new signatures of mysql_create_table, mysql_alter_table,
select_create. Functions mysql_create_index and mysql_drop_index has
become identical after initialization of alter_info was moved to the
parser, and were merged. Flag enable_slow_log was not updated for
SQLCOM_DROP_INDEX, which was a bug.
Just like CREATE INDEX, DROP INDEX is currently done via complete
table rebuild and is rightfully a slow administrative statement.
sql/sql_partition.cc:
Move is_partition_management() to sql_lex.cc
Adjust code to the new Alter_info.
sql/sql_table.cc:
Adjust mysql_alter_table, mysql_recreate_table, mysql_create_table,
mysql_prepare_table to new signatures.
Rename mysql_prepare_table to mysql_prepare_create_table. Make
sure it follows the convention and returns FALSE for success and
TRUE for error.
Move parts of mysql_alter_table to mysql_prepare_alter_table.
Move the first invokation of mysql_prepare_table from mysql_alter_table
to compare_tables, as it was needed only for the purpose
of correct comparison.
Since now Alter_info itself is created in the runtime mem root,
adjust mysql_prepare_table to always allocate memory in the
runtime memory root.
Remove dead code.
sql/sql_yacc.yy:
LEX::key_list and LEX::create_list moved to class Alter_info
2007-05-28 13:30:01 +02:00
#
# Bug #24879 Prepared Statements: CREATE TABLE (UTF8 KEY) produces a growing
# key length
#
# Test that parse information is not altered by subsequent executions of a
# prepared statement
#
drop table if exists t1;
prepare stmt
from "create table t1 (c char(100) character set utf8, key (c(10)))";
execute stmt;
show create table t1;
drop table t1;
execute stmt;
show create table t1;
drop table t1;
2007-03-07 16:51:49 +01:00
--echo End of 5.1 tests.