Commit 7afa5f1c authored by evgen@moonbone.local's avatar evgen@moonbone.local

Bug#22331: Wrong WHERE in EXPLAIN EXTENDED when all expressions were optimized

away.

During optimization stage the WHERE conditions can be changed or even
be removed at all if they know for sure to be true of false. Thus they aren't
showed in the EXPLAIN EXTENDED which prints conditions after optimization.

Now if all elements of an Item_cond were removed this Item_cond is substituted
for an Item_int with the int value of the Item_cond.
If there were conditions that were totally optimized away then values of the
saved cond_value and having_value will be printed instead.
parent 0461228a
...@@ -57,3 +57,32 @@ select 3 into @v1; ...@@ -57,3 +57,32 @@ select 3 into @v1;
explain select 3 into @v1; explain select 3 into @v1;
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL No tables used 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL No tables used
create table t1(f1 int, f2 int);
insert into t1 values (1,1);
create view v1 as select * from t1 where f1=1;
explain extended select * from v1 where f2=1;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 system NULL NULL NULL NULL 1
Warnings:
Note 1003 select `test`.`t1`.`f1` AS `f1`,`test`.`t1`.`f2` AS `f2` from `test`.`t1` where 1
explain extended select * from t1 where 0;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
Warnings:
Note 1003 select `test`.`t1`.`f1` AS `f1`,`test`.`t1`.`f2` AS `f2` from `test`.`t1` where 0
explain extended select * from t1 where 1;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 system NULL NULL NULL NULL 1
Warnings:
Note 1003 select `test`.`t1`.`f1` AS `f1`,`test`.`t1`.`f2` AS `f2` from `test`.`t1` where 1
explain extended select * from t1 having 0;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible HAVING
Warnings:
Note 1003 select `test`.`t1`.`f1` AS `f1`,`test`.`t1`.`f2` AS `f2` from `test`.`t1` having 0
explain extended select * from t1 having 1;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 system NULL NULL NULL NULL 1
Warnings:
Note 1003 select `test`.`t1`.`f1` AS `f1`,`test`.`t1`.`f2` AS `f2` from `test`.`t1` having 1
drop table t1;
...@@ -79,7 +79,7 @@ explain extended select * from t1 where 1 xor 1; ...@@ -79,7 +79,7 @@ explain extended select * from t1 where 1 xor 1;
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
Warnings: Warnings:
Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where 0
select - a from t1; select - a from t1;
- a - a
-1 -1
......
...@@ -421,7 +421,7 @@ id select_type table type possible_keys key key_len ref rows Extra ...@@ -421,7 +421,7 @@ id select_type table type possible_keys key key_len ref rows Extra
3 UNION NULL NULL NULL NULL NULL NULL NULL No tables used 3 UNION NULL NULL NULL NULL NULL NULL NULL No tables used
NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL
Warnings: Warnings:
Note 1003 select 1 AS `1` from `test`.`t1` Note 1003 select 1 AS `1` from `test`.`t1` where 1
drop table t1; drop table t1;
CREATE TABLE `t1` ( CREATE TABLE `t1` (
`numeropost` mediumint(8) unsigned NOT NULL auto_increment, `numeropost` mediumint(8) unsigned NOT NULL auto_increment,
...@@ -1180,7 +1180,7 @@ id select_type table type possible_keys key key_len ref rows Extra ...@@ -1180,7 +1180,7 @@ 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 1 PRIMARY NULL NULL NULL NULL NULL NULL NULL No tables used
2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE 2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
Warnings: Warnings:
Note 1003 select <in_optimizer>(0,<exists>(select 1 AS `Not_used` from `test`.`t1` `a`)) AS `0 IN (SELECT 1 FROM t1 a)` Note 1003 select <in_optimizer>(0,<exists>(select 1 AS `Not_used` from `test`.`t1` `a` where 0)) AS `0 IN (SELECT 1 FROM t1 a)`
INSERT INTO t1 (pseudo) VALUES ('test1'); INSERT INTO t1 (pseudo) VALUES ('test1');
SELECT 0 IN (SELECT 1 FROM t1 a); SELECT 0 IN (SELECT 1 FROM t1 a);
0 IN (SELECT 1 FROM t1 a) 0 IN (SELECT 1 FROM t1 a)
...@@ -1190,7 +1190,7 @@ id select_type table type possible_keys key key_len ref rows Extra ...@@ -1190,7 +1190,7 @@ 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 1 PRIMARY NULL NULL NULL NULL NULL NULL NULL No tables used
2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE 2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
Warnings: Warnings:
Note 1003 select <in_optimizer>(0,<exists>(select 1 AS `Not_used` from `test`.`t1` `a`)) AS `0 IN (SELECT 1 FROM t1 a)` Note 1003 select <in_optimizer>(0,<exists>(select 1 AS `Not_used` from `test`.`t1` `a` where 0)) AS `0 IN (SELECT 1 FROM t1 a)`
drop table t1; drop table t1;
CREATE TABLE `t1` ( CREATE TABLE `t1` (
`i` int(11) NOT NULL default '0', `i` int(11) NOT NULL default '0',
...@@ -1532,7 +1532,7 @@ id select_type table type possible_keys key key_len ref rows Extra ...@@ -1532,7 +1532,7 @@ id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE 1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
2 SUBQUERY t2 system NULL NULL NULL NULL 0 const row not found 2 SUBQUERY t2 system NULL NULL NULL NULL 0 const row not found
Warnings: Warnings:
Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where 0
select * from t3 where NULL >= any (select b from t2 group by 1); select * from t3 where NULL >= any (select b from t2 group by 1);
a a
explain extended select * from t3 where NULL >= any (select b from t2 group by 1); explain extended select * from t3 where NULL >= any (select b from t2 group by 1);
...@@ -1540,7 +1540,7 @@ id select_type table type possible_keys key key_len ref rows Extra ...@@ -1540,7 +1540,7 @@ id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE 1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
2 SUBQUERY t2 system NULL NULL NULL NULL 0 const row not found 2 SUBQUERY t2 system NULL NULL NULL NULL 0 const row not found
Warnings: Warnings:
Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where 0
select * from t3 where NULL >= some (select b from t2); select * from t3 where NULL >= some (select b from t2);
a a
explain extended select * from t3 where NULL >= some (select b from t2); explain extended select * from t3 where NULL >= some (select b from t2);
...@@ -1548,7 +1548,7 @@ id select_type table type possible_keys key key_len ref rows Extra ...@@ -1548,7 +1548,7 @@ id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE 1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
2 SUBQUERY t2 system NULL NULL NULL NULL 0 const row not found 2 SUBQUERY t2 system NULL NULL NULL NULL 0 const row not found
Warnings: Warnings:
Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where 0
select * from t3 where NULL >= some (select b from t2 group by 1); select * from t3 where NULL >= some (select b from t2 group by 1);
a a
explain extended select * from t3 where NULL >= some (select b from t2 group by 1); explain extended select * from t3 where NULL >= some (select b from t2 group by 1);
...@@ -1556,7 +1556,7 @@ id select_type table type possible_keys key key_len ref rows Extra ...@@ -1556,7 +1556,7 @@ id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE 1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
2 SUBQUERY t2 system NULL NULL NULL NULL 0 const row not found 2 SUBQUERY t2 system NULL NULL NULL NULL 0 const row not found
Warnings: Warnings:
Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where 0
insert into t2 values (2,2), (2,1), (3,3), (3,1); insert into t2 values (2,2), (2,1), (3,3), (3,1);
select * from t3 where a > all (select max(b) from t2 group by a); select * from t3 where a > all (select max(b) from t2 group by a);
a a
...@@ -1618,7 +1618,7 @@ id select_type table type possible_keys key key_len ref rows Extra ...@@ -1618,7 +1618,7 @@ id select_type table type possible_keys key key_len ref rows Extra
3 UNION t1 system NULL NULL NULL NULL 1 3 UNION t1 system NULL NULL NULL NULL 1
NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL
Warnings: Warnings:
Note 1003 select `test`.`t1`.`s1` AS `s1` from `test`.`t1` Note 1003 select `test`.`t1`.`s1` AS `s1` from `test`.`t1` where 1
drop table t1; drop table t1;
CREATE TABLE t1 (number char(11) NOT NULL default '') ENGINE=MyISAM CHARSET=latin1; CREATE TABLE t1 (number char(11) NOT NULL default '') ENGINE=MyISAM CHARSET=latin1;
INSERT INTO t1 VALUES ('69294728265'),('18621828126'),('89356874041'),('95895001874'); INSERT INTO t1 VALUES ('69294728265'),('18621828126'),('89356874041'),('95895001874');
......
...@@ -51,4 +51,18 @@ set names latin1; ...@@ -51,4 +51,18 @@ set names latin1;
select 3 into @v1; select 3 into @v1;
explain select 3 into @v1; explain select 3 into @v1;
#
# Bug#22331: Wrong WHERE in EXPLAIN EXTENDED when all expressions were
# optimized away.
#
create table t1(f1 int, f2 int);
insert into t1 values (1,1);
create view v1 as select * from t1 where f1=1;
explain extended select * from v1 where f2=1;
explain extended select * from t1 where 0;
explain extended select * from t1 where 1;
explain extended select * from t1 having 0;
explain extended select * from t1 having 1;
drop table t1;
# End of 5.0 tests. # End of 5.0 tests.
...@@ -1192,6 +1192,7 @@ void st_select_lex::init_select() ...@@ -1192,6 +1192,7 @@ void st_select_lex::init_select()
is_correlated= 0; is_correlated= 0;
cur_pos_in_select_list= UNDEF_POS; cur_pos_in_select_list= UNDEF_POS;
non_agg_fields.empty(); non_agg_fields.empty();
cond_value= having_value= Item::COND_UNDEF;
} }
/* /*
......
...@@ -487,6 +487,8 @@ public: ...@@ -487,6 +487,8 @@ public:
Item *where, *having; /* WHERE & HAVING clauses */ Item *where, *having; /* WHERE & HAVING clauses */
Item *prep_where; /* saved WHERE clause for prepared statement processing */ Item *prep_where; /* saved WHERE clause for prepared statement processing */
Item *prep_having;/* saved HAVING clause for prepared statement processing */ Item *prep_having;/* saved HAVING clause for prepared statement processing */
/* Saved values of the WHERE and HAVING clauses*/
Item::cond_result cond_value, having_value;
/* point on lex in which it was created, used in view subquery detection */ /* point on lex in which it was created, used in view subquery detection */
st_lex *parent_lex; st_lex *parent_lex;
enum olap_type olap; enum olap_type olap;
......
...@@ -681,7 +681,6 @@ JOIN::optimize() ...@@ -681,7 +681,6 @@ JOIN::optimize()
} }
{ {
Item::cond_result having_value;
having= optimize_cond(this, having, join_list, &having_value); having= optimize_cond(this, having, join_list, &having_value);
if (thd->net.report_error) if (thd->net.report_error)
{ {
...@@ -689,6 +688,10 @@ JOIN::optimize() ...@@ -689,6 +688,10 @@ JOIN::optimize()
DBUG_PRINT("error",("Error from optimize_cond")); DBUG_PRINT("error",("Error from optimize_cond"));
DBUG_RETURN(1); DBUG_RETURN(1);
} }
if (select_lex->where)
select_lex->cond_value= cond_value;
if (select_lex->having)
select_lex->having_value= having_value;
if (cond_value == Item::COND_FALSE || having_value == Item::COND_FALSE || if (cond_value == Item::COND_FALSE || having_value == Item::COND_FALSE ||
(!unit->select_limit_cnt && !(select_options & OPTION_FOUND_ROWS))) (!unit->select_limit_cnt && !(select_options & OPTION_FOUND_ROWS)))
...@@ -829,6 +832,7 @@ JOIN::optimize() ...@@ -829,6 +832,7 @@ JOIN::optimize()
conds->update_used_tables(); conds->update_used_tables();
DBUG_EXECUTE("where", print_where(conds, "after substitute_best_equal");); DBUG_EXECUTE("where", print_where(conds, "after substitute_best_equal"););
} }
/* /*
Permorm the the optimization on fields evaluation mentioned above Permorm the the optimization on fields evaluation mentioned above
for all on expressions. for all on expressions.
...@@ -7535,6 +7539,9 @@ static COND* substitute_for_best_equal_field(COND *cond, ...@@ -7535,6 +7539,9 @@ static COND* substitute_for_best_equal_field(COND *cond,
break; break;
} }
} }
if (!((Item_cond*)cond)->argument_list()->elements)
cond= new Item_int(cond->val_bool());
} }
else if (cond->type() == Item::FUNC_ITEM && else if (cond->type() == Item::FUNC_ITEM &&
((Item_cond*) cond)->functype() == Item_func::MULT_EQUAL_FUNC) ((Item_cond*) cond)->functype() == Item_func::MULT_EQUAL_FUNC)
...@@ -15259,10 +15266,13 @@ void st_select_lex::print(THD *thd, String *str) ...@@ -15259,10 +15266,13 @@ void st_select_lex::print(THD *thd, String *str)
Item *cur_where= where; Item *cur_where= where;
if (join) if (join)
cur_where= join->conds; cur_where= join->conds;
if (cur_where) if (cur_where || cond_value != Item::COND_UNDEF)
{ {
str->append(STRING_WITH_LEN(" where ")); str->append(STRING_WITH_LEN(" where "));
cur_where->print(str); if (cur_where)
cur_where->print(str);
else
str->append(cond_value != Item::COND_FALSE ? "1" : "0");
} }
// group by & olap // group by & olap
...@@ -15288,10 +15298,13 @@ void st_select_lex::print(THD *thd, String *str) ...@@ -15288,10 +15298,13 @@ void st_select_lex::print(THD *thd, String *str)
if (join) if (join)
cur_having= join->having; cur_having= join->having;
if (cur_having) if (cur_having || having_value != Item::COND_UNDEF)
{ {
str->append(STRING_WITH_LEN(" having ")); str->append(STRING_WITH_LEN(" having "));
cur_having->print(str); if (cur_having)
cur_having->print(str);
else
str->append(having_value != Item::COND_FALSE ? "1" : "0");
} }
if (order_list.elements) if (order_list.elements)
......
...@@ -292,7 +292,7 @@ public: ...@@ -292,7 +292,7 @@ public:
bool need_tmp, hidden_group_fields; bool need_tmp, hidden_group_fields;
DYNAMIC_ARRAY keyuse; DYNAMIC_ARRAY keyuse;
Item::cond_result cond_value; Item::cond_result cond_value, having_value;
List<Item> all_fields; // to store all fields that used in query List<Item> all_fields; // to store all fields that used in query
//Above list changed to use temporary table //Above list changed to use temporary table
List<Item> tmp_all_fields1, tmp_all_fields2, tmp_all_fields3; List<Item> tmp_all_fields1, tmp_all_fields2, tmp_all_fields3;
......
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