Commit ee28dec8 authored by unknown's avatar unknown

Automatic merge.

parents 5dc1a223 c1a6dbe5
...@@ -2090,4 +2090,42 @@ EXECUTE st2; ...@@ -2090,4 +2090,42 @@ EXECUTE st2;
f2 f2
2 2
drop table t1, t2; drop table t1, t2;
#
# LP BUG#825018: Crash in check_and_do_in_subquery_rewrites() with corrlated subquery in select list
#
CREATE TABLE t1 (a int, b int);
INSERT INTO t1 VALUES (10,1),(11,7);
CREATE TABLE t2 (a int);
INSERT INTO t2 VALUES (2),(3);
CREATE TABLE t3 (a int, b int);
INSERT INTO t3 VALUES (1,1);
CREATE PROCEDURE sp1 () LANGUAGE SQL
SELECT (SELECT t1.a
FROM t1
WHERE t1.b = t3.b
AND t1.b IN ( SELECT a FROM t2 )) sq
FROM t3
GROUP BY 1;
CALL sp1();
sq
NULL
CALL sp1();
sq
NULL
drop procedure sp1;
prepare st1 from "
SELECT (SELECT t1.a
FROM t1
WHERE t1.b = t3.b
AND t1.b IN ( SELECT a FROM t2 )) sq
FROM t3
GROUP BY 1";
execute st1;
sq
NULL
execute st1;
sq
NULL
deallocate prepare st1;
drop table t1, t2, t3;
set optimizer_switch=@subselect4_tmp; set optimizer_switch=@subselect4_tmp;
...@@ -1812,3 +1812,35 @@ id select_type table type possible_keys key key_len ref rows filtered Extra ...@@ -1812,3 +1812,35 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
Warnings: Warnings:
Note 1003 select max(`test`.`t1`.`b`) AS `max_res` from `test`.`t1` where <in_optimizer>(9,<exists>(select `test`.`t2`.`a` from `test`.`t2` where (9 = `test`.`t2`.`a`))) Note 1003 select max(`test`.`t1`.`b`) AS `max_res` from `test`.`t1` where <in_optimizer>(9,<exists>(select `test`.`t2`.`a` from `test`.`t2` where (9 = `test`.`t2`.`a`)))
DROP TABLE t1,t2; DROP TABLE t1,t2;
#
# LPBUG#825095: Wrong result with materialization and NOT IN with 2 expressions
#
CREATE TABLE t1 (a int,b int);
INSERT INTO t1 VALUES (4,4),(4,2);
CREATE TABLE t2 (b int, a int);
INSERT INTO t2 VALUES (4,3),(8,4);
set @@optimizer_switch='semijoin=off,in_to_exists=off,materialization=on,partial_match_rowid_merge=on,partial_match_table_scan=off';
EXPLAIN SELECT *
FROM t1
WHERE (a, b) NOT IN (SELECT a, b FROM t2);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where
2 SUBQUERY t2 ALL NULL NULL NULL NULL 2
SELECT *
FROM t1
WHERE (a, b) NOT IN (SELECT a, b FROM t2);
a b
4 4
4 2
EXPLAIN
SELECT a, b, (a, b) NOT IN (SELECT a, b FROM t2) as sq
FROM t1;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 2
2 SUBQUERY t2 ALL NULL NULL NULL NULL 2
SELECT a, b, (a, b) NOT IN (SELECT a, b FROM t2) as sq
FROM t1;
a b sq
4 4 1
4 2 1
drop table t1, t2;
...@@ -1726,5 +1726,41 @@ EXECUTE st2; ...@@ -1726,5 +1726,41 @@ EXECUTE st2;
drop table t1, t2; drop table t1, t2;
--echo #
--echo # LP BUG#825018: Crash in check_and_do_in_subquery_rewrites() with corrlated subquery in select list
--echo #
CREATE TABLE t1 (a int, b int);
INSERT INTO t1 VALUES (10,1),(11,7);
CREATE TABLE t2 (a int);
INSERT INTO t2 VALUES (2),(3);
CREATE TABLE t3 (a int, b int);
INSERT INTO t3 VALUES (1,1);
CREATE PROCEDURE sp1 () LANGUAGE SQL
SELECT (SELECT t1.a
FROM t1
WHERE t1.b = t3.b
AND t1.b IN ( SELECT a FROM t2 )) sq
FROM t3
GROUP BY 1;
CALL sp1();
CALL sp1();
drop procedure sp1;
prepare st1 from "
SELECT (SELECT t1.a
FROM t1
WHERE t1.b = t3.b
AND t1.b IN ( SELECT a FROM t2 )) sq
FROM t3
GROUP BY 1";
execute st1;
execute st1;
deallocate prepare st1;
drop table t1, t2, t3;
set optimizer_switch=@subselect4_tmp; set optimizer_switch=@subselect4_tmp;
...@@ -226,3 +226,31 @@ SELECT MAX(t1.b) AS max_res FROM t1 WHERE (9) IN (SELECT a FROM t2); ...@@ -226,3 +226,31 @@ SELECT MAX(t1.b) AS max_res FROM t1 WHERE (9) IN (SELECT a FROM t2);
DROP TABLE t1,t2; DROP TABLE t1,t2;
--echo #
--echo # LPBUG#825095: Wrong result with materialization and NOT IN with 2 expressions
--echo #
CREATE TABLE t1 (a int,b int);
INSERT INTO t1 VALUES (4,4),(4,2);
CREATE TABLE t2 (b int, a int);
INSERT INTO t2 VALUES (4,3),(8,4);
set @@optimizer_switch='semijoin=off,in_to_exists=off,materialization=on,partial_match_rowid_merge=on,partial_match_table_scan=off';
EXPLAIN SELECT *
FROM t1
WHERE (a, b) NOT IN (SELECT a, b FROM t2);
SELECT *
FROM t1
WHERE (a, b) NOT IN (SELECT a, b FROM t2);
EXPLAIN
SELECT a, b, (a, b) NOT IN (SELECT a, b FROM t2) as sq
FROM t1;
SELECT a, b, (a, b) NOT IN (SELECT a, b FROM t2) as sq
FROM t1;
drop table t1, t2;
...@@ -1804,7 +1804,7 @@ Item *Item_in_optimizer::transform(Item_transformer transformer, uchar *argument ...@@ -1804,7 +1804,7 @@ Item *Item_in_optimizer::transform(Item_transformer transformer, uchar *argument
Item_subselect::ANY_SUBS)); Item_subselect::ANY_SUBS));
Item_in_subselect *in_arg= (Item_in_subselect*)args[1]; Item_in_subselect *in_arg= (Item_in_subselect*)args[1];
in_arg->left_expr= args[0]; current_thd->change_item_tree(&in_arg->left_expr, args[0]);
} }
return (this->*transformer)(argument); return (this->*transformer)(argument);
} }
......
...@@ -3898,6 +3898,8 @@ subselect_hash_sj_engine::get_strategy_using_data() ...@@ -3898,6 +3898,8 @@ subselect_hash_sj_engine::get_strategy_using_data()
} }
if (result_sink->get_null_count_of_col(i) == tmp_table->file->stats.records) if (result_sink->get_null_count_of_col(i) == tmp_table->file->stats.records)
++count_null_only_columns; ++count_null_only_columns;
if (result_sink->get_null_count_of_col(i))
++count_columns_with_nulls;
} }
/* If no column contains NULLs use regular hash index lookups. */ /* If no column contains NULLs use regular hash index lookups. */
...@@ -4659,6 +4661,7 @@ int subselect_hash_sj_engine::exec() ...@@ -4659,6 +4661,7 @@ int subselect_hash_sj_engine::exec()
count_pm_keys, count_pm_keys,
has_covering_null_row, has_covering_null_row,
has_covering_null_columns, has_covering_null_columns,
count_columns_with_nulls,
item, result, item, result,
semi_join_conds->argument_list()); semi_join_conds->argument_list());
if (!pm_engine || if (!pm_engine ||
...@@ -4684,7 +4687,8 @@ int subselect_hash_sj_engine::exec() ...@@ -4684,7 +4687,8 @@ int subselect_hash_sj_engine::exec()
item, result, item, result,
semi_join_conds->argument_list(), semi_join_conds->argument_list(),
has_covering_null_row, has_covering_null_row,
has_covering_null_columns))) has_covering_null_columns,
count_columns_with_nulls)))
{ {
/* This is an irrecoverable error. */ /* This is an irrecoverable error. */
res= 1; res= 1;
...@@ -5121,43 +5125,48 @@ subselect_partial_match_engine::subselect_partial_match_engine( ...@@ -5121,43 +5125,48 @@ subselect_partial_match_engine::subselect_partial_match_engine(
select_result_interceptor *result_arg, select_result_interceptor *result_arg,
List<Item> *equi_join_conds_arg, List<Item> *equi_join_conds_arg,
bool has_covering_null_row_arg, bool has_covering_null_row_arg,
bool has_covering_null_columns_arg) bool has_covering_null_columns_arg,
uint count_columns_with_nulls_arg)
:subselect_engine(thd_arg, item_arg, result_arg), :subselect_engine(thd_arg, item_arg, result_arg),
tmp_table(tmp_table_arg), lookup_engine(engine_arg), tmp_table(tmp_table_arg), lookup_engine(engine_arg),
equi_join_conds(equi_join_conds_arg), equi_join_conds(equi_join_conds_arg),
has_covering_null_row(has_covering_null_row_arg), has_covering_null_row(has_covering_null_row_arg),
has_covering_null_columns(has_covering_null_columns_arg) has_covering_null_columns(has_covering_null_columns_arg),
count_columns_with_nulls(count_columns_with_nulls_arg)
{} {}
int subselect_partial_match_engine::exec() int subselect_partial_match_engine::exec()
{ {
Item_in_subselect *item_in= (Item_in_subselect *) item; Item_in_subselect *item_in= (Item_in_subselect *) item;
int res; int copy_res, lookup_res;
/* Try to find a matching row by index lookup. */ /* Try to find a matching row by index lookup. */
res= lookup_engine->copy_ref_key_simple(); copy_res= lookup_engine->copy_ref_key_simple();
if (res == -1) if (copy_res == -1)
{ {
/* The result is FALSE based on the outer reference. */ /* The result is FALSE based on the outer reference. */
item_in->value= 0; item_in->value= 0;
item_in->null_value= 0; item_in->null_value= 0;
return 0; return 0;
} }
else if (res == 0) else if (copy_res == 0)
{ {
/* Search for a complete match. */ /* Search for a complete match. */
if ((res= lookup_engine->index_lookup())) if ((lookup_res= lookup_engine->index_lookup()))
{ {
/* An error occured during lookup(). */ /* An error occured during lookup(). */
item_in->value= 0; item_in->value= 0;
item_in->null_value= 0; item_in->null_value= 0;
return res; return lookup_res;
} }
else if (item_in->value) else if (item_in->value || !count_columns_with_nulls)
{ {
/* /*
A complete match was found, the result of IN is TRUE. A complete match was found, the result of IN is TRUE.
If no match was found, and there are no NULLs in the materialized
subquery, then the result is guaranteed to be false because this
branch is executed when the outer reference has no NULLs as well.
Notice: (this->item == lookup_engine->item) Notice: (this->item == lookup_engine->item)
*/ */
return 0; return 0;
...@@ -5608,6 +5617,7 @@ bool subselect_rowid_merge_engine::partial_match() ...@@ -5608,6 +5617,7 @@ bool subselect_rowid_merge_engine::partial_match()
{ {
min_key= cur_key; min_key= cur_key;
min_row_num= cur_row_num; min_row_num= cur_row_num;
bitmap_clear_all(&matching_keys);
bitmap_set_bit(&matching_keys, min_key->get_keyid()); bitmap_set_bit(&matching_keys, min_key->get_keyid());
bitmap_union(&matching_keys, &matching_outer_cols); bitmap_union(&matching_keys, &matching_outer_cols);
} }
...@@ -5641,11 +5651,13 @@ subselect_table_scan_engine::subselect_table_scan_engine( ...@@ -5641,11 +5651,13 @@ subselect_table_scan_engine::subselect_table_scan_engine(
select_result_interceptor *result_arg, select_result_interceptor *result_arg,
List<Item> *equi_join_conds_arg, List<Item> *equi_join_conds_arg,
bool has_covering_null_row_arg, bool has_covering_null_row_arg,
bool has_covering_null_columns_arg) bool has_covering_null_columns_arg,
uint count_columns_with_nulls_arg)
:subselect_partial_match_engine(thd_arg, engine_arg, tmp_table_arg, item_arg, :subselect_partial_match_engine(thd_arg, engine_arg, tmp_table_arg, item_arg,
result_arg, equi_join_conds_arg, result_arg, equi_join_conds_arg,
has_covering_null_row_arg, has_covering_null_row_arg,
has_covering_null_columns_arg) has_covering_null_columns_arg,
count_columns_with_nulls_arg)
{} {}
......
...@@ -870,7 +870,7 @@ public: ...@@ -870,7 +870,7 @@ public:
tmp_table(NULL), is_materialized(FALSE), materialize_engine(old_engine), tmp_table(NULL), is_materialized(FALSE), materialize_engine(old_engine),
materialize_join(NULL), semi_join_conds(NULL), lookup_engine(NULL), materialize_join(NULL), semi_join_conds(NULL), lookup_engine(NULL),
count_partial_match_columns(0), count_null_only_columns(0), count_partial_match_columns(0), count_null_only_columns(0),
strategy(UNDEFINED) count_columns_with_nulls(0), strategy(UNDEFINED)
{} {}
~subselect_hash_sj_engine(); ~subselect_hash_sj_engine();
...@@ -908,6 +908,7 @@ protected: ...@@ -908,6 +908,7 @@ protected:
MY_BITMAP partial_match_key_parts; MY_BITMAP partial_match_key_parts;
uint count_partial_match_columns; uint count_partial_match_columns;
uint count_null_only_columns; uint count_null_only_columns;
uint count_columns_with_nulls;
/* Possible execution strategies that can be used to compute hash semi-join.*/ /* Possible execution strategies that can be used to compute hash semi-join.*/
enum exec_strategy { enum exec_strategy {
UNDEFINED, UNDEFINED,
...@@ -1145,6 +1146,7 @@ protected: ...@@ -1145,6 +1146,7 @@ protected:
guaranteed partial match. guaranteed partial match.
*/ */
bool has_covering_null_columns; bool has_covering_null_columns;
uint count_columns_with_nulls;
protected: protected:
virtual bool partial_match()= 0; virtual bool partial_match()= 0;
...@@ -1155,7 +1157,8 @@ public: ...@@ -1155,7 +1157,8 @@ public:
select_result_interceptor *result_arg, select_result_interceptor *result_arg,
List<Item> *equi_join_conds_arg, List<Item> *equi_join_conds_arg,
bool has_covering_null_row_arg, bool has_covering_null_row_arg,
bool has_covering_null_columns_arg); bool has_covering_null_columns_arg,
uint count_columns_with_nulls_arg);
int prepare() { return 0; } int prepare() { return 0; }
int exec(); int exec();
void fix_length_and_dec(Item_cache**) {} void fix_length_and_dec(Item_cache**) {}
...@@ -1245,13 +1248,15 @@ public: ...@@ -1245,13 +1248,15 @@ public:
TABLE *tmp_table_arg, uint merge_keys_count_arg, TABLE *tmp_table_arg, uint merge_keys_count_arg,
bool has_covering_null_row_arg, bool has_covering_null_row_arg,
bool has_covering_null_columns_arg, bool has_covering_null_columns_arg,
uint count_columns_with_nulls_arg,
Item_subselect *item_arg, Item_subselect *item_arg,
select_result_interceptor *result_arg, select_result_interceptor *result_arg,
List<Item> *equi_join_conds_arg) List<Item> *equi_join_conds_arg)
:subselect_partial_match_engine(thd_arg, engine_arg, tmp_table_arg, :subselect_partial_match_engine(thd_arg, engine_arg, tmp_table_arg,
item_arg, result_arg, equi_join_conds_arg, item_arg, result_arg, equi_join_conds_arg,
has_covering_null_row_arg, has_covering_null_row_arg,
has_covering_null_columns_arg), has_covering_null_columns_arg,
count_columns_with_nulls_arg),
merge_keys_count(merge_keys_count_arg), non_null_key(NULL) merge_keys_count(merge_keys_count_arg), non_null_key(NULL)
{} {}
~subselect_rowid_merge_engine(); ~subselect_rowid_merge_engine();
...@@ -1272,7 +1277,8 @@ public: ...@@ -1272,7 +1277,8 @@ public:
select_result_interceptor *result_arg, select_result_interceptor *result_arg,
List<Item> *equi_join_conds_arg, List<Item> *equi_join_conds_arg,
bool has_covering_null_row_arg, bool has_covering_null_row_arg,
bool has_covering_null_columns_arg); bool has_covering_null_columns_arg,
uint count_columns_with_nulls_arg);
void cleanup(); void cleanup();
virtual enum_engine_type engine_type() { return TABLE_SCAN_ENGINE; } virtual enum_engine_type engine_type() { return TABLE_SCAN_ENGINE; }
}; };
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment