Commit 6f778f54 authored by unknown's avatar unknown

Automatic merge.

parents f72a2012 6e9db10c
...@@ -1190,6 +1190,54 @@ set @@optimizer_switch='materialization=off,semijoin=on'; ...@@ -1190,6 +1190,54 @@ set @@optimizer_switch='materialization=off,semijoin=on';
set @@optimizer_switch=@save_optimizer_switch; set @@optimizer_switch=@save_optimizer_switch;
drop table t1, t2; drop table t1, t2;
# #
# LP BUG#777691 Wrong result with subqery in select list and subquery cache=off in maria-5.3
#
CREATE TABLE t1 ( f1 varchar(32)) ;
INSERT INTO t1 VALUES ('b'),('x'),('c'),('x');
CREATE TABLE t2 ( f2 int, f3 varchar(32)) ;
INSERT INTO t2 VALUES (1,'x');
set @save_optimizer_switch=@@optimizer_switch;
set @@optimizer_switch='materialization=off,in_to_exists=on,subquery_cache=off';
EXPLAIN
SELECT t1.f1, ( SELECT MAX( f2 ) FROM t2 WHERE t2.f3 = t1.f1 ) as max_f2 FROM t1;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 4
2 DEPENDENT SUBQUERY t2 system NULL NULL NULL NULL 1
SELECT t1.f1, ( SELECT MAX( f2 ) FROM t2 WHERE t2.f3 = t1.f1 ) as max_f2 FROM t1;
f1 max_f2
b NULL
x 1
c NULL
x 1
set @@optimizer_switch='materialization=on,in_to_exists=off,subquery_cache=off';
EXPLAIN
SELECT t1.f1, ( SELECT MAX( f2 ) FROM t2 WHERE t2.f3 = t1.f1 ) as max_f2 FROM t1;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 4
2 DEPENDENT SUBQUERY t2 system NULL NULL NULL NULL 1
SELECT t1.f1, ( SELECT MAX( f2 ) FROM t2 WHERE t2.f3 = t1.f1 ) as max_f2 FROM t1;
f1 max_f2
b NULL
x 1
c NULL
x 1
set @@optimizer_switch='materialization=off,in_to_exists=on,subquery_cache=off';
Even when t2 is not constant table, the result must be the same.
INSERT INTO t2 VALUES (2,'y');
EXPLAIN
SELECT t1.f1, ( SELECT MAX( f2 ) FROM t2 WHERE t2.f3 = t1.f1 ) as max_f2 FROM t1;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 4
2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where
SELECT t1.f1, ( SELECT MAX( f2 ) FROM t2 WHERE t2.f3 = t1.f1 ) as max_f2 FROM t1;
f1 max_f2
b NULL
x 1
c NULL
x 1
set @@optimizer_switch=@save_optimizer_switch;
drop table t1, t2;
#
# LP BUG#641203 Query returns rows where no result is expected (impossible WHERE) # LP BUG#641203 Query returns rows where no result is expected (impossible WHERE)
# #
CREATE TABLE t1 (c1 varchar(1) DEFAULT NULL); CREATE TABLE t1 (c1 varchar(1) DEFAULT NULL);
......
This diff is collapsed.
...@@ -964,6 +964,40 @@ WHERE (t2.pk = t1.pk) AND t2.pk IN (SELECT f2 FROM t1); ...@@ -964,6 +964,40 @@ WHERE (t2.pk = t1.pk) AND t2.pk IN (SELECT f2 FROM t1);
-- echo set @@optimizer_switch='materialization=off,semijoin=on'; -- echo set @@optimizer_switch='materialization=off,semijoin=on';
set @@optimizer_switch=@save_optimizer_switch;
drop table t1, t2;
--echo #
--echo # LP BUG#777691 Wrong result with subqery in select list and subquery cache=off in maria-5.3
--echo #
CREATE TABLE t1 ( f1 varchar(32)) ;
INSERT INTO t1 VALUES ('b'),('x'),('c'),('x');
CREATE TABLE t2 ( f2 int, f3 varchar(32)) ;
INSERT INTO t2 VALUES (1,'x');
set @save_optimizer_switch=@@optimizer_switch;
set @@optimizer_switch='materialization=off,in_to_exists=on,subquery_cache=off';
EXPLAIN
SELECT t1.f1, ( SELECT MAX( f2 ) FROM t2 WHERE t2.f3 = t1.f1 ) as max_f2 FROM t1;
SELECT t1.f1, ( SELECT MAX( f2 ) FROM t2 WHERE t2.f3 = t1.f1 ) as max_f2 FROM t1;
set @@optimizer_switch='materialization=on,in_to_exists=off,subquery_cache=off';
EXPLAIN
SELECT t1.f1, ( SELECT MAX( f2 ) FROM t2 WHERE t2.f3 = t1.f1 ) as max_f2 FROM t1;
SELECT t1.f1, ( SELECT MAX( f2 ) FROM t2 WHERE t2.f3 = t1.f1 ) as max_f2 FROM t1;
set @@optimizer_switch='materialization=off,in_to_exists=on,subquery_cache=off';
--echo Even when t2 is not constant table, the result must be the same.
INSERT INTO t2 VALUES (2,'y');
EXPLAIN
SELECT t1.f1, ( SELECT MAX( f2 ) FROM t2 WHERE t2.f3 = t1.f1 ) as max_f2 FROM t1;
SELECT t1.f1, ( SELECT MAX( f2 ) FROM t2 WHERE t2.f3 = t1.f1 ) as max_f2 FROM t1;
set @@optimizer_switch=@save_optimizer_switch; set @@optimizer_switch=@save_optimizer_switch;
drop table t1, t2; drop table t1, t2;
......
This diff is collapsed.
This diff is collapsed.
...@@ -1131,11 +1131,18 @@ class subselect_partial_match_engine : public subselect_engine ...@@ -1131,11 +1131,18 @@ class subselect_partial_match_engine : public subselect_engine
/* A list of equalities between each pair of IN operands. */ /* A list of equalities between each pair of IN operands. */
List<Item> *equi_join_conds; List<Item> *equi_join_conds;
/* /*
If there is a row, such that all its NULL-able components are NULL, this True if there is an all NULL row in tmp_table. If so, then if there is
member is set to the number of covered columns. If there is no covering no complete match, there is a guaranteed partial match.
row, then this is 0.
*/ */
uint covering_null_row_width; bool has_covering_null_row;
/*
True if all nullable columns of tmp_table consist of only NULL values.
If so, then if there is a match in the non-null columns, there is a
guaranteed partial match.
*/
bool has_covering_null_columns;
protected: protected:
virtual bool partial_match()= 0; virtual bool partial_match()= 0;
public: public:
...@@ -1144,7 +1151,8 @@ class subselect_partial_match_engine : public subselect_engine ...@@ -1144,7 +1151,8 @@ class subselect_partial_match_engine : public subselect_engine
TABLE *tmp_table_arg, Item_subselect *item_arg, TABLE *tmp_table_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,
uint covering_null_row_width_arg); bool has_covering_null_row_arg,
bool has_covering_null_columns_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**) {}
...@@ -1191,11 +1199,6 @@ class subselect_rowid_merge_engine: public subselect_partial_match_engine ...@@ -1191,11 +1199,6 @@ class subselect_rowid_merge_engine: public subselect_partial_match_engine
outer reference. outer reference.
*/ */
MY_BITMAP matching_outer_cols; MY_BITMAP matching_outer_cols;
/*
Columns that consist of only NULLs. Such columns match any value.
Computed once per query execution.
*/
MY_BITMAP null_only_columns;
/* /*
Indexes of row numbers, sorted by <column_value, row_number>. If an Indexes of row numbers, sorted by <column_value, row_number>. If an
index may contain NULLs, the NULLs are stored efficiently in a bitmap. index may contain NULLs, the NULLs are stored efficiently in a bitmap.
...@@ -1205,13 +1208,13 @@ class subselect_rowid_merge_engine: public subselect_partial_match_engine ...@@ -1205,13 +1208,13 @@ class subselect_rowid_merge_engine: public subselect_partial_match_engine
non-NULL columns, it is contained in keys[0]. non-NULL columns, it is contained in keys[0].
*/ */
Ordered_key **merge_keys; Ordered_key **merge_keys;
/* The number of elements in keys. */ /* The number of elements in merge_keys. */
uint keys_count; uint merge_keys_count;
/* /*
An index on all non-NULL columns of 'tmp_table'. The index has the An index on all non-NULL columns of 'tmp_table'. The index has the
logical form: <[v_i1 | ... | v_ik], rownum>. It allows to find the row logical form: <[v_i1 | ... | v_ik], rownum>. It allows to find the row
number where the columns c_i1,...,c1_k contain the values v_i1,...,v_ik. number where the columns c_i1,...,c1_k contain the values v_i1,...,v_ik.
If such an index exists, it is always the first element of 'keys'. If such an index exists, it is always the first element of 'merge_keys'.
*/ */
Ordered_key *non_null_key; Ordered_key *non_null_key;
/* /*
...@@ -1236,15 +1239,17 @@ class subselect_rowid_merge_engine: public subselect_partial_match_engine ...@@ -1236,15 +1239,17 @@ class subselect_rowid_merge_engine: public subselect_partial_match_engine
public: public:
subselect_rowid_merge_engine(THD *thd_arg, subselect_rowid_merge_engine(THD *thd_arg,
subselect_uniquesubquery_engine *engine_arg, subselect_uniquesubquery_engine *engine_arg,
TABLE *tmp_table_arg, uint keys_count_arg, TABLE *tmp_table_arg, uint merge_keys_count_arg,
uint covering_null_row_width_arg, bool has_covering_null_row_arg,
bool has_covering_null_columns_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,
covering_null_row_width_arg), has_covering_null_row_arg,
keys_count(keys_count_arg), non_null_key(NULL) has_covering_null_columns_arg),
merge_keys_count(merge_keys_count_arg), non_null_key(NULL)
{} {}
~subselect_rowid_merge_engine(); ~subselect_rowid_merge_engine();
bool init(MY_BITMAP *non_null_key_parts, MY_BITMAP *partial_match_key_parts); bool init(MY_BITMAP *non_null_key_parts, MY_BITMAP *partial_match_key_parts);
...@@ -1263,7 +1268,8 @@ class subselect_table_scan_engine: public subselect_partial_match_engine ...@@ -1263,7 +1268,8 @@ class subselect_table_scan_engine: public subselect_partial_match_engine
TABLE *tmp_table_arg, Item_subselect *item_arg, TABLE *tmp_table_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,
uint covering_null_row_width_arg); bool has_covering_null_row_arg,
bool has_covering_null_columns_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; }
}; };
...@@ -14651,14 +14651,6 @@ do_select(JOIN *join,List<Item> *fields,TABLE *table,Procedure *procedure) ...@@ -14651,14 +14651,6 @@ do_select(JOIN *join,List<Item> *fields,TABLE *table,Procedure *procedure)
{ {
List<Item> *columns_list= (procedure ? &join->procedure_fields_list : List<Item> *columns_list= (procedure ? &join->procedure_fields_list :
fields); fields);
/*
With implicit grouping all fields of special row produced for an
empty result are NULL. See return_zero_rows() for the same behavior.
*/
TABLE_LIST *table;
List_iterator_fast<TABLE_LIST> li(join->select_lex->leaf_tables);
while ((table= li++))
mark_as_null_row(table->table);
rc= join->result->send_data(*columns_list) > 0; rc= join->result->send_data(*columns_list) > 0;
} }
} }
......
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