diff options
author | Sergei Golubchik <serg@mariadb.org> | 2018-03-23 17:40:53 +0100 |
---|---|---|
committer | Sergei Golubchik <serg@mariadb.org> | 2018-03-23 17:40:53 +0100 |
commit | febe1e850342ea52ce0900ba5767852b0aa42dc7 (patch) | |
tree | af188bde7aff4951c9f845a5c22912222b6ca888 | |
parent | d3681c18f96ebf9b66c7541459b2eb34a4827734 (diff) | |
parent | a2e47f8c41e60fb0eeaa01cdd41fc07b9c963768 (diff) | |
download | mariadb-git-febe1e850342ea52ce0900ba5767852b0aa42dc7.tar.gz |
Merge branch '10.0' into 10.1
-rw-r--r-- | mysql-test/r/join_outer.result | 18 | ||||
-rw-r--r-- | mysql-test/r/join_outer_jcl6.result | 18 | ||||
-rw-r--r-- | mysql-test/r/ps_qc_innodb.result | 23 | ||||
-rw-r--r-- | mysql-test/r/subselect4.result | 11 | ||||
-rw-r--r-- | mysql-test/t/join_outer.test | 18 | ||||
-rw-r--r-- | mysql-test/t/ps_qc_innodb.test | 35 | ||||
-rw-r--r-- | mysql-test/t/subselect4.test | 8 | ||||
-rw-r--r-- | sql/item_cmpfunc.h | 5 | ||||
-rw-r--r-- | sql/item_func.h | 2 | ||||
-rw-r--r-- | sql/item_subselect.cc | 2 | ||||
-rw-r--r-- | sql/opt_subselect.cc | 4 | ||||
-rw-r--r-- | sql/sql_class.cc | 4 | ||||
-rw-r--r-- | sql/sql_prepare.cc | 4 |
13 files changed, 146 insertions, 6 deletions
diff --git a/mysql-test/r/join_outer.result b/mysql-test/r/join_outer.result index 78cdfe6ecb1..312b36c16ca 100644 --- a/mysql-test/r/join_outer.result +++ b/mysql-test/r/join_outer.result @@ -2440,11 +2440,27 @@ CREATE TABLE t1 (b1 BIT NOT NULL); INSERT INTO t1 VALUES (0),(1); CREATE TABLE t2 (b2 BIT NOT NULL); 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; t1.b1+'0' t2.b2 + '0' 0 0 1 1 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 SET optimizer_switch=@save_optimizer_switch; diff --git a/mysql-test/r/join_outer_jcl6.result b/mysql-test/r/join_outer_jcl6.result index 861b224043c..a006bafcfc0 100644 --- a/mysql-test/r/join_outer_jcl6.result +++ b/mysql-test/r/join_outer_jcl6.result @@ -2451,12 +2451,28 @@ CREATE TABLE t1 (b1 BIT NOT NULL); INSERT INTO t1 VALUES (0),(1); CREATE TABLE t2 (b2 BIT NOT NULL); 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; t1.b1+'0' t2.b2 + '0' 0 0 1 1 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 SET optimizer_switch=@save_optimizer_switch; set join_cache_level=default; diff --git a/mysql-test/r/ps_qc_innodb.result b/mysql-test/r/ps_qc_innodb.result new file mode 100644 index 00000000000..775055e858f --- /dev/null +++ b/mysql-test/r/ps_qc_innodb.result @@ -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; diff --git a/mysql-test/r/subselect4.result b/mysql-test/r/subselect4.result index 4e70615120f..2ae8ff3ba1b 100644 --- a/mysql-test/r/subselect4.result +++ b/mysql-test/r/subselect4.result @@ -2489,6 +2489,17 @@ FROM t2 WHERE b <= 'quux' GROUP BY field; field COUNT(DISTINCT c) 0 1 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 @@tmp_table_size= @@global.tmp_table_size; # diff --git a/mysql-test/t/join_outer.test b/mysql-test/t/join_outer.test index acbe19b5e87..34b0551a32e 100644 --- a/mysql-test/t/join_outer.test +++ b/mysql-test/t/join_outer.test @@ -1972,9 +1972,25 @@ INSERT INTO t1 VALUES (0),(1); CREATE TABLE t2 (b2 BIT NOT NULL); 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; 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 diff --git a/mysql-test/t/ps_qc_innodb.test b/mysql-test/t/ps_qc_innodb.test new file mode 100644 index 00000000000..e09a2bf4070 --- /dev/null +++ b/mysql-test/t/ps_qc_innodb.test @@ -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; diff --git a/mysql-test/t/subselect4.test b/mysql-test/t/subselect4.test index d4ccbcf6f66..77ea117b15f 100644 --- a/mysql-test/t/subselect4.test +++ b/mysql-test/t/subselect4.test @@ -2032,6 +2032,14 @@ SELECT ( SELECT COUNT(*) FROM t1 WHERE a = c ) AS field, COUNT(DISTINCT c) FROM t2 WHERE b <= 'quux' GROUP BY field; 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 @@tmp_table_size= @@global.tmp_table_size; diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index f35859fd3c1..03f234ad1e4 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -330,6 +330,7 @@ public: bool is_null(); longlong val_int(); void cleanup(); + enum Functype functype() const { return IN_OPTIMIZER_FUNC; } const char *func_name() const { return "<in_optimizer>"; } Item_cache **get_cache() { return &cache; } void keep_top_level_cache(); @@ -347,6 +348,10 @@ public: void reset_cache() { cache= NULL; } virtual void print(String *str, enum_query_type query_type); void restore_first_argument(); + Item* get_wrapped_in_subselect_item() + { + return args[1]; + } }; diff --git a/sql/item_func.h b/sql/item_func.h index 1209fc5cdd8..f47b1895c87 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -67,7 +67,7 @@ public: NOW_FUNC, TRIG_COND_FUNC, SUSERVAR_FUNC, GUSERVAR_FUNC, COLLATE_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 Type type() const { return FUNC_ITEM; } virtual enum Functype functype() const { return UNKNOWN_FUNC; } Item_func(THD *thd): Item_func_or_sum(thd), allowed_arg_cols(1) diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index 7dbaf313ad9..b275f749f25 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -1818,7 +1818,7 @@ Item_in_subselect::single_value_transformer(JOIN *join) Item* join_having= join->having ? join->having : join->tmp_having; if (!(join_having || select_lex->with_sum_func || 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()) { Item *where_item= (Item*) select_lex->item_list.head(); diff --git a/sql/opt_subselect.cc b/sql/opt_subselect.cc index 12ae3286159..88204ef4102 100644 --- a/sql/opt_subselect.cc +++ b/sql/opt_subselect.cc @@ -1008,6 +1008,10 @@ bool check_for_outer_joins(List<TABLE_LIST> *join_list) void find_and_block_conversion_to_sj(Item *to_find, 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 || ((Item_subselect *) to_find)->substype() != Item_subselect::IN_SUBS) return; diff --git a/sql/sql_class.cc b/sql/sql_class.cc index e3b7b31b01d..63442182e08 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -2717,15 +2717,19 @@ void THD::check_and_register_item_tree_change(Item **place, Item **new_value, void THD::rollback_item_tree_changes() { + DBUG_ENTER("THD::rollback_item_tree_changes"); I_List_iterator<Item_change_record> it(change_list); Item_change_record *change; while ((change= it++)) { + DBUG_PRINT("info", ("Rollback: %p (%p) <- %p", + *change->place, change->place, change->old_value)); *change->place= change->old_value; } /* We can forget about changes memory: it's allocated in runtime memroot */ change_list.empty(); + DBUG_VOID_RETURN; } diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index b515578eb05..d7f549899f2 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -4168,6 +4168,7 @@ bool Prepared_statement::execute(String *expanded_query, bool open_cursor) Statement stmt_backup; Query_arena *old_stmt_arena; bool error= TRUE; + bool qc_executed= FALSE; char saved_cur_db_name_buf[SAFE_NAME_LEN+1]; LEX_STRING saved_cur_db_name= @@ -4290,6 +4291,7 @@ bool Prepared_statement::execute(String *expanded_query, bool open_cursor) thd->lex->sql_command= SQLCOM_SELECT; status_var_increment(thd->status_var.com_stat[SQLCOM_SELECT]); thd->update_stats(); + qc_executed= TRUE; } } @@ -4328,7 +4330,7 @@ bool Prepared_statement::execute(String *expanded_query, bool open_cursor) thd->set_statement(&stmt_backup); 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; if (error == 0 && this->lex->sql_command == SQLCOM_CALL) |