Merge branch '5.5' into 10.0
This commit is contained in:
commit
a2e47f8c41
@ -2349,11 +2349,27 @@ CREATE TABLE t1 (b1 BIT NOT NULL);
|
|||||||
INSERT INTO t1 VALUES (0),(1);
|
INSERT INTO t1 VALUES (0),(1);
|
||||||
CREATE TABLE t2 (b2 BIT NOT NULL);
|
CREATE TABLE t2 (b2 BIT NOT NULL);
|
||||||
INSERT INTO t2 VALUES (0),(1);
|
INSERT INTO t2 VALUES (0),(1);
|
||||||
SET SESSION JOIN_CACHE_LEVEL = 3;
|
set @save_join_cache_level= @@join_cache_level;
|
||||||
|
SET @@join_cache_level = 3;
|
||||||
SELECT t1.b1+'0' , t2.b2 + '0' FROM t1 LEFT JOIN t2 ON b1 = b2;
|
SELECT t1.b1+'0' , t2.b2 + '0' FROM t1 LEFT JOIN t2 ON b1 = b2;
|
||||||
t1.b1+'0' t2.b2 + '0'
|
t1.b1+'0' t2.b2 + '0'
|
||||||
0 0
|
0 0
|
||||||
1 1
|
1 1
|
||||||
DROP TABLE t1, t2;
|
DROP TABLE t1, t2;
|
||||||
|
set @join_cache_level= @save_join_cache_level;
|
||||||
|
#
|
||||||
|
# MDEV-14779: using left join causes incorrect results with materialization and derived tables
|
||||||
|
#
|
||||||
|
create table t1(id int);
|
||||||
|
insert into t1 values (1),(2);
|
||||||
|
create table t2(sid int, id int);
|
||||||
|
insert into t2 values (1,1),(2,2);
|
||||||
|
select * from t1 t
|
||||||
|
left join (select * from t2 where sid in (select max(sid) from t2 where 0=1 group by id)) r
|
||||||
|
on t.id=r.id ;
|
||||||
|
id sid id
|
||||||
|
1 NULL NULL
|
||||||
|
2 NULL NULL
|
||||||
|
drop table t1, t2;
|
||||||
# end of 5.5 tests
|
# end of 5.5 tests
|
||||||
SET optimizer_switch=@save_optimizer_switch;
|
SET optimizer_switch=@save_optimizer_switch;
|
||||||
|
@ -2360,12 +2360,28 @@ CREATE TABLE t1 (b1 BIT NOT NULL);
|
|||||||
INSERT INTO t1 VALUES (0),(1);
|
INSERT INTO t1 VALUES (0),(1);
|
||||||
CREATE TABLE t2 (b2 BIT NOT NULL);
|
CREATE TABLE t2 (b2 BIT NOT NULL);
|
||||||
INSERT INTO t2 VALUES (0),(1);
|
INSERT INTO t2 VALUES (0),(1);
|
||||||
SET SESSION JOIN_CACHE_LEVEL = 3;
|
set @save_join_cache_level= @@join_cache_level;
|
||||||
|
SET @@join_cache_level = 3;
|
||||||
SELECT t1.b1+'0' , t2.b2 + '0' FROM t1 LEFT JOIN t2 ON b1 = b2;
|
SELECT t1.b1+'0' , t2.b2 + '0' FROM t1 LEFT JOIN t2 ON b1 = b2;
|
||||||
t1.b1+'0' t2.b2 + '0'
|
t1.b1+'0' t2.b2 + '0'
|
||||||
0 0
|
0 0
|
||||||
1 1
|
1 1
|
||||||
DROP TABLE t1, t2;
|
DROP TABLE t1, t2;
|
||||||
|
set @join_cache_level= @save_join_cache_level;
|
||||||
|
#
|
||||||
|
# MDEV-14779: using left join causes incorrect results with materialization and derived tables
|
||||||
|
#
|
||||||
|
create table t1(id int);
|
||||||
|
insert into t1 values (1),(2);
|
||||||
|
create table t2(sid int, id int);
|
||||||
|
insert into t2 values (1,1),(2,2);
|
||||||
|
select * from t1 t
|
||||||
|
left join (select * from t2 where sid in (select max(sid) from t2 where 0=1 group by id)) r
|
||||||
|
on t.id=r.id ;
|
||||||
|
id sid id
|
||||||
|
1 NULL NULL
|
||||||
|
2 NULL NULL
|
||||||
|
drop table t1, t2;
|
||||||
# end of 5.5 tests
|
# end of 5.5 tests
|
||||||
SET optimizer_switch=@save_optimizer_switch;
|
SET optimizer_switch=@save_optimizer_switch;
|
||||||
set join_cache_level=default;
|
set join_cache_level=default;
|
||||||
|
23
mysql-test/r/ps_qc_innodb.result
Normal file
23
mysql-test/r/ps_qc_innodb.result
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
#
|
||||||
|
# MDEV-15492: Subquery crash similar to MDEV-10050
|
||||||
|
#
|
||||||
|
SET @qcs.save= @@global.query_cache_size, @qct.save= @@global.query_cache_type;
|
||||||
|
SET GLOBAL query_cache_size= 512*1024*1024, query_cache_type= ON;
|
||||||
|
CREATE TABLE t1 (a INT) ENGINE=InnoDB;
|
||||||
|
CREATE TABLE t2 (b INT) ENGINE=InnoDB;
|
||||||
|
CREATE VIEW v AS select a from t1 join t2;
|
||||||
|
PREPARE stmt1 FROM "SELECT * FROM t1 WHERE a in (SELECT a FROM v)";
|
||||||
|
PREPARE stmt2 FROM "SELECT * FROM t1 WHERE a in (SELECT a FROM v)";
|
||||||
|
EXECUTE stmt2;
|
||||||
|
a
|
||||||
|
EXECUTE stmt1;
|
||||||
|
a
|
||||||
|
INSERT INTO t2 VALUES (0);
|
||||||
|
EXECUTE stmt1;
|
||||||
|
a
|
||||||
|
START TRANSACTION;
|
||||||
|
EXECUTE stmt1;
|
||||||
|
a
|
||||||
|
DROP VIEW v;
|
||||||
|
DROP TABLE t1, t2;
|
||||||
|
SET GLOBAL query_cache_size= @qcs.save, query_cache_type= @qct.save;
|
@ -2485,5 +2485,16 @@ FROM t2 WHERE b <= 'quux' GROUP BY field;
|
|||||||
field COUNT(DISTINCT c)
|
field COUNT(DISTINCT c)
|
||||||
0 1
|
0 1
|
||||||
drop table t1,t2;
|
drop table t1,t2;
|
||||||
|
#
|
||||||
|
# MDEV-15555: select from DUAL where false yielding wrong result when in a IN
|
||||||
|
#
|
||||||
|
explain
|
||||||
|
SELECT 2 IN (SELECT 2 from DUAL WHERE 1 != 1);
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL No tables used
|
||||||
|
2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
|
||||||
|
SELECT 2 IN (SELECT 2 from DUAL WHERE 1 != 1);
|
||||||
|
2 IN (SELECT 2 from DUAL WHERE 1 != 1)
|
||||||
|
0
|
||||||
SET optimizer_switch= @@global.optimizer_switch;
|
SET optimizer_switch= @@global.optimizer_switch;
|
||||||
set @@tmp_table_size= @@global.tmp_table_size;
|
set @@tmp_table_size= @@global.tmp_table_size;
|
||||||
|
@ -1891,9 +1891,25 @@ INSERT INTO t1 VALUES (0),(1);
|
|||||||
CREATE TABLE t2 (b2 BIT NOT NULL);
|
CREATE TABLE t2 (b2 BIT NOT NULL);
|
||||||
INSERT INTO t2 VALUES (0),(1);
|
INSERT INTO t2 VALUES (0),(1);
|
||||||
|
|
||||||
SET SESSION JOIN_CACHE_LEVEL = 3;
|
set @save_join_cache_level= @@join_cache_level;
|
||||||
|
SET @@join_cache_level = 3;
|
||||||
SELECT t1.b1+'0' , t2.b2 + '0' FROM t1 LEFT JOIN t2 ON b1 = b2;
|
SELECT t1.b1+'0' , t2.b2 + '0' FROM t1 LEFT JOIN t2 ON b1 = b2;
|
||||||
DROP TABLE t1, t2;
|
DROP TABLE t1, t2;
|
||||||
|
set @join_cache_level= @save_join_cache_level;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # MDEV-14779: using left join causes incorrect results with materialization and derived tables
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
create table t1(id int);
|
||||||
|
insert into t1 values (1),(2);
|
||||||
|
create table t2(sid int, id int);
|
||||||
|
insert into t2 values (1,1),(2,2);
|
||||||
|
|
||||||
|
select * from t1 t
|
||||||
|
left join (select * from t2 where sid in (select max(sid) from t2 where 0=1 group by id)) r
|
||||||
|
on t.id=r.id ;
|
||||||
|
drop table t1, t2;
|
||||||
|
|
||||||
--echo # end of 5.5 tests
|
--echo # end of 5.5 tests
|
||||||
|
|
||||||
|
35
mysql-test/t/ps_qc_innodb.test
Normal file
35
mysql-test/t/ps_qc_innodb.test
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
--source include/have_query_cache.inc
|
||||||
|
--source include/have_innodb.inc
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # MDEV-15492: Subquery crash similar to MDEV-10050
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
SET @qcs.save= @@global.query_cache_size, @qct.save= @@global.query_cache_type;
|
||||||
|
SET GLOBAL query_cache_size= 512*1024*1024, query_cache_type= ON;
|
||||||
|
|
||||||
|
--connect (con1,localhost,root,,test)
|
||||||
|
CREATE TABLE t1 (a INT) ENGINE=InnoDB;
|
||||||
|
CREATE TABLE t2 (b INT) ENGINE=InnoDB;
|
||||||
|
CREATE VIEW v AS select a from t1 join t2;
|
||||||
|
|
||||||
|
PREPARE stmt1 FROM "SELECT * FROM t1 WHERE a in (SELECT a FROM v)";
|
||||||
|
|
||||||
|
--connect (con2,localhost,root,,test)
|
||||||
|
PREPARE stmt2 FROM "SELECT * FROM t1 WHERE a in (SELECT a FROM v)";
|
||||||
|
EXECUTE stmt2;
|
||||||
|
|
||||||
|
--connection con1
|
||||||
|
EXECUTE stmt1;
|
||||||
|
INSERT INTO t2 VALUES (0);
|
||||||
|
EXECUTE stmt1;
|
||||||
|
START TRANSACTION;
|
||||||
|
EXECUTE stmt1;
|
||||||
|
|
||||||
|
# Cleanup
|
||||||
|
--disconnect con1
|
||||||
|
--disconnect con2
|
||||||
|
--connection default
|
||||||
|
DROP VIEW v;
|
||||||
|
DROP TABLE t1, t2;
|
||||||
|
SET GLOBAL query_cache_size= @qcs.save, query_cache_type= @qct.save;
|
@ -2032,5 +2032,13 @@ SELECT ( SELECT COUNT(*) FROM t1 WHERE a = c ) AS field, COUNT(DISTINCT c)
|
|||||||
FROM t2 WHERE b <= 'quux' GROUP BY field;
|
FROM t2 WHERE b <= 'quux' GROUP BY field;
|
||||||
drop table t1,t2;
|
drop table t1,t2;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # MDEV-15555: select from DUAL where false yielding wrong result when in a IN
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
explain
|
||||||
|
SELECT 2 IN (SELECT 2 from DUAL WHERE 1 != 1);
|
||||||
|
SELECT 2 IN (SELECT 2 from DUAL WHERE 1 != 1);
|
||||||
|
|
||||||
SET optimizer_switch= @@global.optimizer_switch;
|
SET optimizer_switch= @@global.optimizer_switch;
|
||||||
set @@tmp_table_size= @@global.tmp_table_size;
|
set @@tmp_table_size= @@global.tmp_table_size;
|
||||||
|
@ -260,6 +260,7 @@ public:
|
|||||||
bool is_null();
|
bool is_null();
|
||||||
longlong val_int();
|
longlong val_int();
|
||||||
void cleanup();
|
void cleanup();
|
||||||
|
enum Functype functype() const { return IN_OPTIMIZER_FUNC; }
|
||||||
const char *func_name() const { return "<in_optimizer>"; }
|
const char *func_name() const { return "<in_optimizer>"; }
|
||||||
Item_cache **get_cache() { return &cache; }
|
Item_cache **get_cache() { return &cache; }
|
||||||
void keep_top_level_cache();
|
void keep_top_level_cache();
|
||||||
@ -277,6 +278,10 @@ public:
|
|||||||
void reset_cache() { cache= NULL; }
|
void reset_cache() { cache= NULL; }
|
||||||
virtual void print(String *str, enum_query_type query_type);
|
virtual void print(String *str, enum_query_type query_type);
|
||||||
void restore_first_argument();
|
void restore_first_argument();
|
||||||
|
Item* get_wrapped_in_subselect_item()
|
||||||
|
{
|
||||||
|
return args[1];
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class Comp_creator
|
class Comp_creator
|
||||||
|
@ -73,7 +73,7 @@ public:
|
|||||||
NOW_FUNC, TRIG_COND_FUNC,
|
NOW_FUNC, TRIG_COND_FUNC,
|
||||||
SUSERVAR_FUNC, GUSERVAR_FUNC, COLLATE_FUNC,
|
SUSERVAR_FUNC, GUSERVAR_FUNC, COLLATE_FUNC,
|
||||||
EXTRACT_FUNC, CHAR_TYPECAST_FUNC, FUNC_SP, UDF_FUNC,
|
EXTRACT_FUNC, CHAR_TYPECAST_FUNC, FUNC_SP, UDF_FUNC,
|
||||||
NEG_FUNC, GSYSVAR_FUNC, DYNCOL_FUNC };
|
NEG_FUNC, GSYSVAR_FUNC, IN_OPTIMIZER_FUNC, DYNCOL_FUNC };
|
||||||
enum optimize_type { OPTIMIZE_NONE,OPTIMIZE_KEY,OPTIMIZE_OP, OPTIMIZE_NULL,
|
enum optimize_type { OPTIMIZE_NONE,OPTIMIZE_KEY,OPTIMIZE_OP, OPTIMIZE_NULL,
|
||||||
OPTIMIZE_EQUAL };
|
OPTIMIZE_EQUAL };
|
||||||
enum Type type() const { return FUNC_ITEM; }
|
enum Type type() const { return FUNC_ITEM; }
|
||||||
|
@ -1763,7 +1763,7 @@ Item_in_subselect::single_value_transformer(JOIN *join)
|
|||||||
Item* join_having= join->having ? join->having : join->tmp_having;
|
Item* join_having= join->having ? join->having : join->tmp_having;
|
||||||
if (!(join_having || select_lex->with_sum_func ||
|
if (!(join_having || select_lex->with_sum_func ||
|
||||||
select_lex->group_list.elements) &&
|
select_lex->group_list.elements) &&
|
||||||
select_lex->table_list.elements == 0 &&
|
select_lex->table_list.elements == 0 && !join->conds &&
|
||||||
!select_lex->master_unit()->is_union())
|
!select_lex->master_unit()->is_union())
|
||||||
{
|
{
|
||||||
Item *where_item= (Item*) select_lex->item_list.head();
|
Item *where_item= (Item*) select_lex->item_list.head();
|
||||||
|
@ -1006,6 +1006,10 @@ bool check_for_outer_joins(List<TABLE_LIST> *join_list)
|
|||||||
void find_and_block_conversion_to_sj(Item *to_find,
|
void find_and_block_conversion_to_sj(Item *to_find,
|
||||||
List_iterator_fast<Item_in_subselect> &li)
|
List_iterator_fast<Item_in_subselect> &li)
|
||||||
{
|
{
|
||||||
|
if (to_find->type() == Item::FUNC_ITEM &&
|
||||||
|
((Item_func*)to_find)->functype() == Item_func::IN_OPTIMIZER_FUNC)
|
||||||
|
to_find= ((Item_in_optimizer*)to_find)->get_wrapped_in_subselect_item();
|
||||||
|
|
||||||
if (to_find->type() != Item::SUBSELECT_ITEM ||
|
if (to_find->type() != Item::SUBSELECT_ITEM ||
|
||||||
((Item_subselect *) to_find)->substype() != Item_subselect::IN_SUBS)
|
((Item_subselect *) to_find)->substype() != Item_subselect::IN_SUBS)
|
||||||
return;
|
return;
|
||||||
|
@ -2454,15 +2454,19 @@ void THD::check_and_register_item_tree_change(Item **place, Item **new_value,
|
|||||||
|
|
||||||
void THD::rollback_item_tree_changes()
|
void THD::rollback_item_tree_changes()
|
||||||
{
|
{
|
||||||
|
DBUG_ENTER("THD::rollback_item_tree_changes");
|
||||||
I_List_iterator<Item_change_record> it(change_list);
|
I_List_iterator<Item_change_record> it(change_list);
|
||||||
Item_change_record *change;
|
Item_change_record *change;
|
||||||
|
|
||||||
while ((change= it++))
|
while ((change= it++))
|
||||||
{
|
{
|
||||||
|
DBUG_PRINT("info", ("Rollback: %p (%p) <- %p",
|
||||||
|
*change->place, change->place, change->old_value));
|
||||||
*change->place= change->old_value;
|
*change->place= change->old_value;
|
||||||
}
|
}
|
||||||
/* We can forget about changes memory: it's allocated in runtime memroot */
|
/* We can forget about changes memory: it's allocated in runtime memroot */
|
||||||
change_list.empty();
|
change_list.empty();
|
||||||
|
DBUG_VOID_RETURN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -3858,6 +3858,7 @@ bool Prepared_statement::execute(String *expanded_query, bool open_cursor)
|
|||||||
Statement stmt_backup;
|
Statement stmt_backup;
|
||||||
Query_arena *old_stmt_arena;
|
Query_arena *old_stmt_arena;
|
||||||
bool error= TRUE;
|
bool error= TRUE;
|
||||||
|
bool qc_executed= FALSE;
|
||||||
|
|
||||||
char saved_cur_db_name_buf[SAFE_NAME_LEN+1];
|
char saved_cur_db_name_buf[SAFE_NAME_LEN+1];
|
||||||
LEX_STRING saved_cur_db_name=
|
LEX_STRING saved_cur_db_name=
|
||||||
@ -3980,6 +3981,7 @@ bool Prepared_statement::execute(String *expanded_query, bool open_cursor)
|
|||||||
thd->lex->sql_command= SQLCOM_SELECT;
|
thd->lex->sql_command= SQLCOM_SELECT;
|
||||||
status_var_increment(thd->status_var.com_stat[SQLCOM_SELECT]);
|
status_var_increment(thd->status_var.com_stat[SQLCOM_SELECT]);
|
||||||
thd->update_stats();
|
thd->update_stats();
|
||||||
|
qc_executed= TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4018,7 +4020,7 @@ bool Prepared_statement::execute(String *expanded_query, bool open_cursor)
|
|||||||
thd->set_statement(&stmt_backup);
|
thd->set_statement(&stmt_backup);
|
||||||
thd->stmt_arena= old_stmt_arena;
|
thd->stmt_arena= old_stmt_arena;
|
||||||
|
|
||||||
if (state == Query_arena::STMT_PREPARED)
|
if (state == Query_arena::STMT_PREPARED && !qc_executed)
|
||||||
state= Query_arena::STMT_EXECUTED;
|
state= Query_arena::STMT_EXECUTED;
|
||||||
|
|
||||||
if (error == 0 && this->lex->sql_command == SQLCOM_CALL)
|
if (error == 0 && this->lex->sql_command == SQLCOM_CALL)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user