summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergei Golubchik <serg@mariadb.org>2018-03-23 17:40:53 +0100
committerSergei Golubchik <serg@mariadb.org>2018-03-23 17:40:53 +0100
commitfebe1e850342ea52ce0900ba5767852b0aa42dc7 (patch)
treeaf188bde7aff4951c9f845a5c22912222b6ca888
parentd3681c18f96ebf9b66c7541459b2eb34a4827734 (diff)
parenta2e47f8c41e60fb0eeaa01cdd41fc07b9c963768 (diff)
downloadmariadb-git-febe1e850342ea52ce0900ba5767852b0aa42dc7.tar.gz
Merge branch '10.0' into 10.1
-rw-r--r--mysql-test/r/join_outer.result18
-rw-r--r--mysql-test/r/join_outer_jcl6.result18
-rw-r--r--mysql-test/r/ps_qc_innodb.result23
-rw-r--r--mysql-test/r/subselect4.result11
-rw-r--r--mysql-test/t/join_outer.test18
-rw-r--r--mysql-test/t/ps_qc_innodb.test35
-rw-r--r--mysql-test/t/subselect4.test8
-rw-r--r--sql/item_cmpfunc.h5
-rw-r--r--sql/item_func.h2
-rw-r--r--sql/item_subselect.cc2
-rw-r--r--sql/opt_subselect.cc4
-rw-r--r--sql/sql_class.cc4
-rw-r--r--sql/sql_prepare.cc4
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)