Auto-merge from upstream 5.1-bugteam

This commit is contained in:
Timothy Smith 2009-01-16 17:33:24 +01:00
commit 6770a687db
25 changed files with 464 additions and 75 deletions

View file

@ -10,7 +10,7 @@ AC_CANONICAL_SYSTEM
#
# When changing major version number please also check switch statement
# in mysqlbinlog::check_master_version().
AM_INIT_AUTOMAKE(mysql, 5.1.31)
AM_INIT_AUTOMAKE(mysql, 5.1.32)
AM_CONFIG_HEADER([include/config.h:config.h.in])
PROTOCOL_VERSION=10

View file

@ -67,10 +67,10 @@ a
2
show status like "Qcache_queries_in_cache";
Variable_name Value
Qcache_queries_in_cache 3
Qcache_queries_in_cache 6
show status like "Qcache_hits";
Variable_name Value
Qcache_hits 3
Qcache_hits 0
insert into t1 values (3);
insert into t2 values (3);
insert into t1 values (4);
@ -91,14 +91,14 @@ a
2
show status like "Qcache_queries_in_cache";
Variable_name Value
Qcache_queries_in_cache 1
Qcache_queries_in_cache 2
show status like "Qcache_hits";
Variable_name Value
Qcache_hits 4
Qcache_hits 1
commit;
show status like "Qcache_queries_in_cache";
Variable_name Value
Qcache_queries_in_cache 1
Qcache_queries_in_cache 2
drop table t3,t2,t1;
CREATE TABLE t1 (id int(11) NOT NULL auto_increment, PRIMARY KEY (id));
select count(*) from t1;
@ -217,5 +217,5 @@ Variable_name Value
Qcache_queries_in_cache 1
show status like "Qcache_hits";
Variable_name Value
Qcache_hits 2
Qcache_hits 1
drop table t2;

View file

@ -44,3 +44,10 @@ IS_FREE_LOCK('bug31418')
SELECT IS_USED_LOCK('bug31418');
IS_USED_LOCK('bug31418')
NULL
FLUSH STATUS;
SHOW GLOBAL STATUS LIKE 'com_select';
Variable_name Value
Com_select 112
SHOW GLOBAL STATUS LIKE 'com_select';
Variable_name Value
Com_select 112

View file

@ -655,3 +655,80 @@ show status like 'Last_query_cost';
Variable_name Value
Last_query_cost 794.837037
drop table t1,t2,t3,t4,t5,t6,t7;
CREATE TABLE t1 (a int, b int, d int, i int);
INSERT INTO t1 VALUES (1,1,1,1);
CREATE TABLE t2 (b int, c int, j int);
INSERT INTO t2 VALUES (1,1,1);
CREATE TABLE t2_1 (j int);
INSERT INTO t2_1 VALUES (1);
CREATE TABLE t3 (c int, f int);
INSERT INTO t3 VALUES (1,1);
CREATE TABLE t3_1 (f int);
INSERT INTO t3_1 VALUES (1);
CREATE TABLE t4 (d int, e int, k int);
INSERT INTO t4 VALUES (1,1,1);
CREATE TABLE t4_1 (k int);
INSERT INTO t4_1 VALUES (1);
CREATE TABLE t5 (g int, d int, h int, l int);
INSERT INTO t5 VALUES (1,1,1,1);
CREATE TABLE t5_1 (l int);
INSERT INTO t5_1 VALUES (1);
SET optimizer_search_depth = 3;
SELECT 1
FROM t1
LEFT JOIN (
t2 JOIN t3 ON t3.c = t2.c
) ON t2.b = t1.b
LEFT JOIN (
t4 JOIN t5 ON t5.d = t4.d
) ON t4.d = t1.d
;
1
1
SELECT 1
FROM t1
LEFT JOIN (
t2 LEFT JOIN (t3 JOIN t3_1 ON t3.f = t3_1.f) ON t3.c = t2.c
) ON t2.b = t1.b
LEFT JOIN (
t4 JOIN t5 ON t5.d = t4.d
) ON t4.d = t1.d
;
1
1
SELECT 1
FROM t1
LEFT JOIN (
(t2 JOIN t2_1 ON t2.j = t2_1.j) JOIN t3 ON t3.c = t2.c
) ON t2.b = t1.b
LEFT JOIN (
t4 JOIN t5 ON t5.d = t4.d
) ON t4.d = t1.d
;
1
1
SELECT 1
FROM t1
LEFT JOIN (
t2 JOIN t3 ON t3.c = t2.c
) ON t2.b = t1.b
LEFT JOIN (
(t4 JOIN t4_1 ON t4.k = t4_1.k) LEFT JOIN t5 ON t5.d = t4.d
) ON t4.d = t1.d
;
1
1
SELECT 1
FROM t1
LEFT JOIN (
t2 JOIN t3 ON t3.c = t2.c
) ON t2.b = t1.b
LEFT JOIN (
t4 LEFT JOIN (t5 JOIN t5_1 ON t5.l = t5_1.l) ON t5.d = t4.d
) ON t4.d = t1.d
;
1
1
SET optimizer_search_depth = DEFAULT;
DROP TABLE t1,t2,t2_1,t3,t3_1,t4,t4_1,t5,t5_1;
End of 5.0 tests

View file

@ -424,3 +424,10 @@ select f1 from t1 group by f1 having max(f1)=f1;
f1
set session sql_mode='';
drop table t1;
CREATE TABLE t1 ( a INT, b INT);
INSERT INTO t1 VALUES (1, 1), (2,2), (3, NULL);
SELECT b, COUNT(DISTINCT a) FROM t1 GROUP BY b HAVING b is NULL;
b COUNT(DISTINCT a)
NULL 1
DROP TABLE t1;
End of 5.0 tests

View file

@ -146,7 +146,7 @@ CREATE TABLE `я` (a INT);
SET NAMES DEFAULT;
mysqlcheck --default-character-set="latin1" --databases test
test.?
Error : Table 'test.?' doesn't exist
Error : Table doesn't exist
error : Corrupt
mysqlcheck --default-character-set="utf8" --databases test
test.я OK

View file

@ -3,10 +3,3 @@ execute stmt1;
ID USER HOST DB COMMAND TIME STATE INFO
number root localhost test Query time executing SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST WHERE COMMAND!='Daemon'
deallocate prepare stmt1;
FLUSH STATUS;
SHOW GLOBAL STATUS LIKE 'com_select';
Variable_name Value
Com_select 102
SHOW GLOBAL STATUS LIKE 'com_select';
Variable_name Value
Com_select 102

View file

@ -1656,6 +1656,57 @@ Qcache_hits 1
DROP TABLE t1;
SET GLOBAL concurrent_insert= @save_concurrent_insert;
SET GLOBAL query_cache_size= default;
DROP TABLE IF EXISTS t1;
FLUSH STATUS;
SET GLOBAL query_cache_size=1048576;
CREATE TABLE t1 (a INT);
INSERT INTO t1 VALUES (1),(2),(3),(4),(5);
SHOW STATUS LIKE 'Qcache_queries_in_cache';
Variable_name Value
Qcache_queries_in_cache 0
SELECT * FROM t1;
a
1
2
3
4
5
BEGIN;
SELECT * FROM t1;
a
1
2
3
4
5
COMMIT;
SHOW STATUS LIKE 'Qcache_queries_in_cache';
Variable_name Value
Qcache_queries_in_cache 2
SHOW STATUS LIKE "Qcache_hits";
Variable_name Value
Qcache_hits 0
SELECT * FROM t1;
a
1
2
3
4
5
BEGIN;
SELECT * FROM t1;
a
1
2
3
4
5
COMMIT;
SHOW STATUS LIKE "Qcache_hits";
Variable_name Value
Qcache_hits 2
DROP TABLE t1;
SET GLOBAL query_cache_size= default;
End of 5.0 tests
CREATE TABLE t1 (a ENUM('rainbow'));
INSERT INTO t1 VALUES (),(),(),(),();

View file

@ -0,0 +1 @@
--force-restart

View file

@ -45,9 +45,26 @@ SELECT IS_USED_LOCK('bug31418');
# Bug#31222: com_% global status counters behave randomly with
# mysql_change_user.
#
# Moved to not_embedded_server.test due to Bug#34517: SHOW GLOBAL STATUS does
# not work properly in embedded server.
#
# TODO: move it back when Bug#34517 is fixed (don't forget to add
# --force-restart into change_user-master.opt).
#
FLUSH STATUS;
--disable_result_log
--disable_query_log
let $i = 100;
while ($i)
{
dec $i;
SELECT 1;
}
--enable_query_log
--enable_result_log
SHOW GLOBAL STATUS LIKE 'com_select';
--change_user
SHOW GLOBAL STATUS LIKE 'com_select';

View file

@ -311,3 +311,76 @@ explain select t1.c11 from t7, t6, t5, t4, t3, t2, t1 where t1.c11 = t2.c21 and
show status like 'Last_query_cost';
drop table t1,t2,t3,t4,t5,t6,t7;
#
# Bug # 38795: Automatic search depth and nested join's results in server
# crash
#
CREATE TABLE t1 (a int, b int, d int, i int); INSERT INTO t1 VALUES (1,1,1,1);
CREATE TABLE t2 (b int, c int, j int); INSERT INTO t2 VALUES (1,1,1);
CREATE TABLE t2_1 (j int); INSERT INTO t2_1 VALUES (1);
CREATE TABLE t3 (c int, f int); INSERT INTO t3 VALUES (1,1);
CREATE TABLE t3_1 (f int); INSERT INTO t3_1 VALUES (1);
CREATE TABLE t4 (d int, e int, k int); INSERT INTO t4 VALUES (1,1,1);
CREATE TABLE t4_1 (k int); INSERT INTO t4_1 VALUES (1);
CREATE TABLE t5 (g int, d int, h int, l int); INSERT INTO t5 VALUES (1,1,1,1);
CREATE TABLE t5_1 (l int); INSERT INTO t5_1 VALUES (1);
SET optimizer_search_depth = 3;
SELECT 1
FROM t1
LEFT JOIN (
t2 JOIN t3 ON t3.c = t2.c
) ON t2.b = t1.b
LEFT JOIN (
t4 JOIN t5 ON t5.d = t4.d
) ON t4.d = t1.d
;
SELECT 1
FROM t1
LEFT JOIN (
t2 LEFT JOIN (t3 JOIN t3_1 ON t3.f = t3_1.f) ON t3.c = t2.c
) ON t2.b = t1.b
LEFT JOIN (
t4 JOIN t5 ON t5.d = t4.d
) ON t4.d = t1.d
;
SELECT 1
FROM t1
LEFT JOIN (
(t2 JOIN t2_1 ON t2.j = t2_1.j) JOIN t3 ON t3.c = t2.c
) ON t2.b = t1.b
LEFT JOIN (
t4 JOIN t5 ON t5.d = t4.d
) ON t4.d = t1.d
;
SELECT 1
FROM t1
LEFT JOIN (
t2 JOIN t3 ON t3.c = t2.c
) ON t2.b = t1.b
LEFT JOIN (
(t4 JOIN t4_1 ON t4.k = t4_1.k) LEFT JOIN t5 ON t5.d = t4.d
) ON t4.d = t1.d
;
SELECT 1
FROM t1
LEFT JOIN (
t2 JOIN t3 ON t3.c = t2.c
) ON t2.b = t1.b
LEFT JOIN (
t4 LEFT JOIN (t5 JOIN t5_1 ON t5.l = t5_1.l) ON t5.d = t4.d
) ON t4.d = t1.d
;
SET optimizer_search_depth = DEFAULT;
DROP TABLE t1,t2,t2_1,t3,t3_1,t4,t4_1,t5,t5_1;
--echo End of 5.0 tests

View file

@ -432,3 +432,14 @@ select f1 from t1 having max(f1)=f1;
select f1 from t1 group by f1 having max(f1)=f1;
set session sql_mode='';
drop table t1;
#
# Bug #38637: COUNT DISTINCT prevents NULL testing in HAVING clause
#
CREATE TABLE t1 ( a INT, b INT);
INSERT INTO t1 VALUES (1, 1), (2,2), (3, NULL);
SELECT b, COUNT(DISTINCT a) FROM t1 GROUP BY b HAVING b is NULL;
DROP TABLE t1;
--echo End of 5.0 tests

View file

@ -131,6 +131,8 @@ DROP TABLE `@`;
CREATE TABLE `я` (a INT);
SET NAMES DEFAULT;
--echo mysqlcheck --default-character-set="latin1" --databases test
# Error returned depends on platform, replace it with "Table doesn't exist"
--replace_result "Can't find file: './test/@003f.frm' (errno: 22)" "Table doesn't exist" "Table 'test.?' doesn't exist" "Table doesn't exist"
--exec $MYSQL_CHECK --default-character-set="latin1" --databases test
--echo mysqlcheck --default-character-set="utf8" --databases test
--exec $MYSQL_CHECK --default-character-set="utf8" --databases test

View file

@ -20,38 +20,4 @@ prepare stmt1 from ' SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST WHERE COMMAND!
execute stmt1;
deallocate prepare stmt1;
#
# Bug#31222: com_% global status counters behave randomly with
# mysql_change_user.
#
# Moved from change_user.test due to Bug#34517: SHOW GLOBAL STATUS does not
# work properly in embedded server.
#
# TODO: move it back when Bug#34517 is fixed.
#
FLUSH STATUS;
--disable_result_log
--disable_query_log
let $i = 100;
while ($i)
{
dec $i;
SELECT 1;
}
--enable_query_log
--enable_result_log
SHOW GLOBAL STATUS LIKE 'com_select';
--change_user
SHOW GLOBAL STATUS LIKE 'com_select';
# End of 5.1 tests

View file

@ -1261,6 +1261,33 @@ DROP TABLE t1;
SET GLOBAL concurrent_insert= @save_concurrent_insert;
SET GLOBAL query_cache_size= default;
#
# Bug#36326: nested transaction and select
#
--disable_warnings
DROP TABLE IF EXISTS t1;
--enable_warnings
FLUSH STATUS;
SET GLOBAL query_cache_size=1048576;
CREATE TABLE t1 (a INT);
INSERT INTO t1 VALUES (1),(2),(3),(4),(5);
SHOW STATUS LIKE 'Qcache_queries_in_cache';
SELECT * FROM t1;
BEGIN;
SELECT * FROM t1;
COMMIT;
SHOW STATUS LIKE 'Qcache_queries_in_cache';
SHOW STATUS LIKE "Qcache_hits";
SELECT * FROM t1;
BEGIN;
SELECT * FROM t1;
COMMIT;
SHOW STATUS LIKE "Qcache_hits";
DROP TABLE t1;
SET GLOBAL query_cache_size= default;
--echo End of 5.0 tests
#

View file

@ -78,8 +78,12 @@ my_bool my_init(void)
my_umask= 0660; /* Default umask for new files */
my_umask_dir= 0700; /* Default umask for new directories */
init_glob_errs();
#if defined(THREAD) && defined(SAFE_MUTEX)
#if defined(THREAD)
if (my_thread_global_init())
return 1;
# if defined(SAFE_MUTEX)
safe_mutex_global_init(); /* Must be called early */
# endif
#endif
#if defined(THREAD) && defined(MY_PTHREAD_FASTMUTEX) && !defined(SAFE_MUTEX)
fastmutex_global_init(); /* Must be called early */
@ -89,8 +93,6 @@ my_bool my_init(void)
#if defined(HAVE_PTHREAD_INIT)
pthread_init(); /* Must be called before DBUG_ENTER */
#endif
if (my_thread_global_init())
return 1;
#if !defined( __WIN__) && !defined(__NETWARE__)
sigfillset(&my_signals); /* signals blocked by mf_brkhant */
#endif

View file

@ -21,6 +21,7 @@
basedir=""
builddir=""
ldata="@localstatedir@"
langdir=""
srcdir=""
args=""
@ -171,7 +172,20 @@ find_in_basedir()
cannot_find_file()
{
echo
echo "FATAL ERROR: Could not find $*"
echo "FATAL ERROR: Could not find $1"
shift
if test $# -ne 0
then
echo
echo "The following directories were searched:"
echo
for dir in "$@"
do
echo " $dir"
done
fi
echo
echo "If you compiled from source, you need to run 'make install' to"
echo "copy the software into the correct location ready for operation."
@ -210,6 +224,11 @@ then
elif test -n "$basedir"
then
print_defaults=`find_in_basedir my_print_defaults bin extra`
if test -z "$print_defaults"
then
cannot_find_file my_print_defaults $basedir/bin $basedir/extra
exit 1
fi
else
print_defaults="@bindir@/my_print_defaults"
fi
@ -232,7 +251,7 @@ then
bindir="$basedir/client"
extra_bindir="$basedir/extra"
mysqld="$basedir/sql/mysqld"
mysqld_opt="--language=$srcdir/sql/share/english"
langdir="$srcdir/sql/share/english"
pkgdatadir="$srcdir/scripts"
scriptdir="$srcdir/scripts"
elif test -n "$basedir"
@ -240,7 +259,23 @@ then
bindir="$basedir/bin"
extra_bindir="$bindir"
mysqld=`find_in_basedir mysqld libexec sbin bin`
if test -z "$mysqld"
then
cannot_find_file mysqld $basedir/libexec $basedir/sbin $basedir/bin
exit 1
fi
langdir=`find_in_basedir --dir errmsg.sys share/english share/mysql/english`
if test -z "$langdir"
then
cannot_find_file errmsg.sys $basedir/share/english $basedir/share/mysql/english
exit 1
fi
pkgdatadir=`find_in_basedir --dir fill_help_tables.sql share share/mysql`
if test -z "$pkgdatadir"
then
cannot_find_file fill_help_tables.sql $basedir/share $basedir/share/mysql
exit 1
fi
scriptdir="$basedir/scripts"
else
basedir="@prefix@"
@ -271,6 +306,16 @@ then
exit 1
fi
if test -n "$langdir"
then
if test ! -f "$langdir/errmsg.sys"
then
cannot_find_file "$langdir/errmsg.sys"
exit 1
fi
mysqld_opt="--language=$langdir"
fi
# Try to determine the hostname
hostname=`@HOSTNAME@`

View file

@ -2090,6 +2090,12 @@ bool Item_field::val_bool_result()
}
bool Item_field::is_null_result()
{
return (null_value=result_field->is_null());
}
bool Item_field::eq(const Item *item, bool binary_cmp) const
{
Item *real_item= ((Item *) item)->real_item();
@ -5800,6 +5806,15 @@ double Item_ref::val_result()
}
bool Item_ref::is_null_result()
{
if (result_field)
return (null_value=result_field->is_null());
return is_null();
}
longlong Item_ref::val_int_result()
{
if (result_field)
@ -5905,7 +5920,9 @@ String *Item_ref::val_str(String* tmp)
bool Item_ref::is_null()
{
DBUG_ASSERT(fixed);
return (*ref)->is_null();
bool tmp=(*ref)->is_null_result();
null_value=(*ref)->null_value;
return tmp;
}

View file

@ -729,6 +729,7 @@ public:
virtual my_decimal *val_decimal_result(my_decimal *val)
{ return val_decimal(val); }
virtual bool val_bool_result() { return val_bool(); }
virtual bool is_null_result() { return is_null(); }
/* bit map of tables used by item */
virtual table_map used_tables() const { return (table_map) 0L; }
@ -1436,6 +1437,7 @@ public:
String *str_result(String* tmp);
my_decimal *val_decimal_result(my_decimal *);
bool val_bool_result();
bool is_null_result();
bool send(Protocol *protocol, String *str_arg);
void reset_field(Field *f);
bool fix_fields(THD *, Item **);
@ -2178,6 +2180,7 @@ public:
String *str_result(String* tmp);
my_decimal *val_decimal_result(my_decimal *);
bool val_bool_result();
bool is_null_result();
bool send(Protocol *prot, String *tmp);
void make_field(Send_field *field);
bool fix_fields(THD *, Item **);

View file

@ -4307,6 +4307,15 @@ my_decimal *Item_func_set_user_var::val_decimal_result(my_decimal *val)
}
bool Item_func_set_user_var::is_null_result()
{
DBUG_ASSERT(fixed == 1);
check(TRUE);
update(); // Store expression
return is_null();
}
void Item_func_set_user_var::print(String *str, enum_query_type query_type)
{
str->append(STRING_WITH_LEN("(@"));

View file

@ -1335,6 +1335,7 @@ public:
longlong val_int_result();
String *str_result(String *str);
my_decimal *val_decimal_result(my_decimal *);
bool is_null_result();
bool update_hash(void *ptr, uint length, enum Item_result type,
CHARSET_INFO *cs, Derivation dv, bool unsigned_arg);
bool send(Protocol *protocol, String *str_arg);

View file

@ -862,6 +862,8 @@ struct Query_cache_query_flags
unsigned int client_protocol_41:1;
unsigned int result_in_binary_protocol:1;
unsigned int more_results_exists:1;
unsigned int in_trans:1;
unsigned int autocommit:1;
unsigned int pkt_nr;
uint character_set_client_num;
uint character_set_results_num;

View file

@ -1001,6 +1001,8 @@ void Query_cache::store_query(THD *thd, TABLE_LIST *tables_used)
flags.result_in_binary_protocol= (unsigned int) thd->protocol->type();
flags.more_results_exists= test(thd->server_status &
SERVER_MORE_RESULTS_EXISTS);
flags.in_trans= test(thd->server_status & SERVER_STATUS_IN_TRANS);
flags.autocommit= test(thd->server_status & SERVER_STATUS_AUTOCOMMIT);
flags.pkt_nr= net->pkt_nr;
flags.character_set_client_num=
thd->variables.character_set_client->number;
@ -1022,7 +1024,7 @@ void Query_cache::store_query(THD *thd, TABLE_LIST *tables_used)
long %d, 4.1: %d, bin_proto: %d, more results %d, pkt_nr: %d, \
CS client: %u, CS result: %u, CS conn: %u, limit: %lu, TZ: 0x%lx, \
sql mode: 0x%lx, sort len: %lu, conncat len: %lu, div_precision: %lu, \
def_week_frmt: %lu",
def_week_frmt: %lu, in_trans: %d, autocommit: %d",
(int)flags.client_long_flag,
(int)flags.client_protocol_41,
(int)flags.result_in_binary_protocol,
@ -1037,7 +1039,10 @@ def_week_frmt: %lu",
flags.max_sort_length,
flags.group_concat_max_len,
flags.div_precision_increment,
flags.default_week_format));
flags.default_week_format,
(int)flags.in_trans,
(int)flags.autocommit));
/*
Make InnoDB to release the adaptive hash index latch before
acquiring the query cache mutex.
@ -1269,6 +1274,8 @@ Query_cache::send_result_to_client(THD *thd, char *sql, uint query_length)
flags.result_in_binary_protocol= (unsigned int)thd->protocol->type();
flags.more_results_exists= test(thd->server_status &
SERVER_MORE_RESULTS_EXISTS);
flags.in_trans= test(thd->server_status & SERVER_STATUS_IN_TRANS);
flags.autocommit= test(thd->server_status & SERVER_STATUS_AUTOCOMMIT);
flags.pkt_nr= thd->net.pkt_nr;
flags.character_set_client_num= thd->variables.character_set_client->number;
flags.character_set_results_num=
@ -1288,7 +1295,7 @@ Query_cache::send_result_to_client(THD *thd, char *sql, uint query_length)
long %d, 4.1: %d, bin_proto: %d, more results %d, pkt_nr: %d, \
CS client: %u, CS result: %u, CS conn: %u, limit: %lu, TZ: 0x%lx, \
sql mode: 0x%lx, sort len: %lu, conncat len: %lu, div_precision: %lu, \
def_week_frmt: %lu",
def_week_frmt: %lu, in_trans: %d, autocommit: %d",
(int)flags.client_long_flag,
(int)flags.client_protocol_41,
(int)flags.result_in_binary_protocol,
@ -1303,7 +1310,9 @@ def_week_frmt: %lu",
flags.max_sort_length,
flags.group_concat_max_len,
flags.div_precision_increment,
flags.default_week_format));
flags.default_week_format,
(int)flags.in_trans,
(int)flags.autocommit));
memcpy((uchar *)(sql + (tot_length - QUERY_CACHE_FLAGS_SIZE)),
(uchar*) &flags, QUERY_CACHE_FLAGS_SIZE);
query_block = (Query_cache_block *) hash_search(&queries, (uchar*) sql,

View file

@ -109,7 +109,7 @@ static COND* substitute_for_best_equal_field(COND *cond,
void *table_join_idx);
static COND *simplify_joins(JOIN *join, List<TABLE_LIST> *join_list,
COND *conds, bool top);
static bool check_interleaving_with_nj(JOIN_TAB *last, JOIN_TAB *next);
static bool check_interleaving_with_nj(JOIN_TAB *next);
static void restore_prev_nj_state(JOIN_TAB *last);
static void reset_nj_counters(List<TABLE_LIST> *join_list);
static uint build_bitmap_for_nested_joins(List<TABLE_LIST> *join_list,
@ -4889,6 +4889,18 @@ greedy_search(JOIN *join,
*/
join->positions[idx]= best_pos;
/*
Update the interleaving state after extending the current partial plan
with a new table.
We are doing this here because best_extension_by_limited_search reverts
the interleaving state to the one of the non-extended partial plan
on exit.
*/
IF_DBUG(bool is_interleave_error= )
check_interleaving_with_nj (best_table);
/* This has been already checked by best_extension_by_limited_search */
DBUG_ASSERT(!is_interleave_error);
/* find the position of 'best_table' in 'join->best_ref' */
best_idx= idx;
JOIN_TAB *pos= join->best_ref[best_idx];
@ -4906,7 +4918,7 @@ greedy_search(JOIN *join,
--size_remain;
++idx;
DBUG_EXECUTE("opt", print_plan(join, join->tables,
DBUG_EXECUTE("opt", print_plan(join, idx,
record_count, read_time, read_time,
"extended"););
} while (TRUE);
@ -5064,7 +5076,7 @@ best_extension_by_limited_search(JOIN *join,
table_map real_table_bit= s->table->map;
if ((remaining_tables & real_table_bit) &&
!(remaining_tables & s->dependent) &&
(!idx || !check_interleaving_with_nj(join->positions[idx-1].table, s)))
(!idx || !check_interleaving_with_nj(s)))
{
double current_record_count, current_read_time;
@ -5210,7 +5222,7 @@ find_best(JOIN *join,table_map rest_tables,uint idx,double record_count,
{
table_map real_table_bit=s->table->map;
if ((rest_tables & real_table_bit) && !(rest_tables & s->dependent) &&
(!idx|| !check_interleaving_with_nj(join->positions[idx-1].table, s)))
(!idx|| !check_interleaving_with_nj(s)))
{
double records, best;
best_access_path(join, s, thd, rest_tables, idx, record_count,
@ -8790,9 +8802,6 @@ static void reset_nj_counters(List<TABLE_LIST> *join_list)
the partial join order.
@endverbatim
@param join Join being processed
@param last_tab Last table in current partial join order (this function is
not called for empty partial join orders)
@param next_tab Table we're going to extend the current partial join with
@retval
@ -8802,10 +8811,10 @@ static void reset_nj_counters(List<TABLE_LIST> *join_list)
TRUE Requested join order extension not allowed.
*/
static bool check_interleaving_with_nj(JOIN_TAB *last_tab, JOIN_TAB *next_tab)
static bool check_interleaving_with_nj(JOIN_TAB *next_tab)
{
TABLE_LIST *next_emb= next_tab->table->pos_in_table_list->embedding;
JOIN *join= last_tab->join;
JOIN *join= next_tab->join;
if (join->cur_embedding_map & ~next_tab->embedding_map)
{

View file

@ -17712,6 +17712,63 @@ static void test_bug40365(void)
DBUG_VOID_RETURN;
}
/**
Bug#36326: nested transaction and select
*/
#ifdef HAVE_QUERY_CACHE
static void test_bug36326()
{
int rc;
DBUG_ENTER("test_bug36326");
myheader("test_bug36326");
rc= mysql_autocommit(mysql, TRUE);
myquery(rc);
rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
myquery(rc);
rc= mysql_query(mysql, "CREATE TABLE t1 (a INTEGER)");
myquery(rc);
rc= mysql_query(mysql, "INSERT INTO t1 VALUES (1)");
myquery(rc);
rc= mysql_query(mysql, "SET GLOBAL query_cache_type = 1");
myquery(rc);
rc= mysql_query(mysql, "SET GLOBAL query_cache_size = 1048576");
myquery(rc);
DIE_UNLESS(!(mysql->server_status & SERVER_STATUS_IN_TRANS));
DIE_UNLESS(mysql->server_status & SERVER_STATUS_AUTOCOMMIT);
rc= mysql_query(mysql, "BEGIN");
myquery(rc);
DIE_UNLESS(mysql->server_status & SERVER_STATUS_IN_TRANS);
rc= mysql_query(mysql, "SELECT * FROM t1");
myquery(rc);
rc= my_process_result(mysql);
DIE_UNLESS(rc == 1);
rc= mysql_rollback(mysql);
myquery(rc);
rc= mysql_query(mysql, "ROLLBACK");
myquery(rc);
DIE_UNLESS(!(mysql->server_status & SERVER_STATUS_IN_TRANS));
rc= mysql_query(mysql, "SELECT * FROM t1");
myquery(rc);
DIE_UNLESS(!(mysql->server_status & SERVER_STATUS_IN_TRANS));
rc= my_process_result(mysql);
DIE_UNLESS(rc == 1);
rc= mysql_query(mysql, "DROP TABLE t1");
myquery(rc);
rc= mysql_query(mysql, "SET GLOBAL query_cache_size = 0");
myquery(rc);
DBUG_VOID_RETURN;
}
#endif
/*
Read and parse arguments and MySQL options from my.cnf
*/
@ -18024,6 +18081,9 @@ static struct my_tests_st my_tests[]= {
{ "test_bug40365", test_bug40365 },
#ifdef HAVE_SPATIAL
{ "test_bug37956", test_bug37956 },
#endif
#ifdef HAVE_QUERY_CACHE
{ "test_bug36326", test_bug36326 },
#endif
{ 0, 0 }
};