[MDEV-19245] Impossible WHERE should be noticed earlier after HAVING pushdown Created: 2019-04-12  Updated: 2019-04-22  Resolved: 2019-04-22

Status: Closed
Project: MariaDB Server
Component/s: Optimizer
Affects Version/s: 10.4
Fix Version/s: 10.4.5

Type: Bug Priority: Major
Reporter: Galina Shalygina (Inactive) Assignee: Galina Shalygina (Inactive)
Resolution: Fixed Votes: 0
Labels: None


 Description   

WHERE clause after pushdown from HAVING into WHERE should look the same as if the pushed condition was initially in the WHERE clause.

Now consider queries which after pushdown will cause impossible WHERE:

CREATE TABLE t1 (a INT, b INT);
INSERT INTO t1 VALUES (1,2),(3,2),(5,6),(3,4);
 
--Q1
EXPLAIN SELECT t1.a,MAX(t1.b) FROM t1 WHERE t1.a>3 GROUP BY t1.a HAVING t1.a=3;
--Q2
EXPLAIN SELECT t1.a,MAX(t1.b) FROM t1 WHERE t1.a=3 GROUP BY t1.a HAVING t1.a<3;
--Q3
EXPLAIN SELECT t1.a,MAX(t1.b) FROM t1 WHERE t1.a>3 AND t1.a=3 GROUP BY t1.a ;

Q1 is a query with inequality in WHERE clause and equality in HAVING clause.
Q2 is a query with equality in WHERE clause and inequality in HAVING clause.
Q3 is how should Q1 and Q2 should look if pushdown is made before optimize_cond().

MariaDB [test]> --Q1
MariaDB [test]> EXPLAIN SELECT t1.a,MAX(t1.b) FROM t1 WHERE t1.a>3 GROUP BY t1.a HAVING t1.a=3;
+------+-------------+-------+------+---------------+------+---------+------+------+-----------------------------------------------------+
| id   | select_type | table | type | possible_keys | key  | key_len | ref  | rows | Extra                                               |
+------+-------------+-------+------+---------------+------+---------+------+------+-----------------------------------------------------+
|    1 | SIMPLE      | NULL  | NULL | NULL          | NULL | NULL    | NULL | NULL | Impossible WHERE noticed after reading const tables |
+------+-------------+-------+------+---------------+------+---------+------+------+-----------------------------------------------------+
1 row in set (0.001 sec)
 
MariaDB [test]> --Q2
MariaDB [test]> EXPLAIN SELECT t1.a,MAX(t1.b) FROM t1 WHERE t1.a=3 GROUP BY t1.a HAVING t1.a<3;
+------+-------------+-------+------+---------------+------+---------+------+------+-----------------------------------------------------+
| id   | select_type | table | type | possible_keys | key  | key_len | ref  | rows | Extra                                               |
+------+-------------+-------+------+---------------+------+---------+------+------+-----------------------------------------------------+
|    1 | SIMPLE      | NULL  | NULL | NULL          | NULL | NULL    | NULL | NULL | Impossible WHERE noticed after reading const tables |
+------+-------------+-------+------+---------------+------+---------+------+------+-----------------------------------------------------+
1 row in set (0.000 sec)
 
MariaDB [test]> --Q3
MariaDB [test]> EXPLAIN SELECT t1.a,MAX(t1.b) FROM t1 WHERE t1.a>3 AND t1.a=3 GROUP BY t1.a ;
+------+-------------+-------+------+---------------+------+---------+------+------+------------------+
| 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 row in set (0.000 sec)

It can be seen that there are different “Extra” messages. Q3 is said to have impossible after optimize_cond() for WHERE. Q1 and Q2 are said to have impossible WHERE only after reading const tables. So there is difference while it shouldn’t be.

If to look on Q4 and Q5 queries in debugger it can be found out that after pushdown from HAVING into WHERE WHERE clause is looking this way:

3>3 AND a=3

It can be said on this step that WHERE is impossible and finish processing of these queries. Now queries are processed further until it is found out that they are impossible after reading const tables.

Let’s look at another queries.
Q4 and Q5 have OR condition in WHERE and HAVING respectively.
Q6 is how Q4 and Q5 should look if pushdown is made before optimize_cond().

--Q4
 EXPLAIN SELECT t1.a,MAX(t1.b) FROM t1 WHERE (t1.a<2 OR t1.a>3) GROUP BY t1.a HAVING t1.a=3;
--Q5
 EXPLAIN SELECT t1.a,MAX(t1.b) FROM t1 WHERE t1.a=3 GROUP BY t1.a HAVING (t1.a<2 OR t1.a>3);
--Q6
 EXPLAIN SELECT t1.a,MAX(t1.b) FROM t1 WHERE t1.a=3 AND (t1.a<2 OR t1.a>3) GROUP BY t1.a;

MariaDB [test]> --Q4
MariaDB [test]>  EXPLAIN SELECT t1.a,MAX(t1.b) FROM t1 WHERE (t1.a<2 OR t1.a>3) GROUP BY t1.a HAVING t1.a=3;
+------+-------------+-------+------+---------------+------+---------+------+------+-----------------------------------------------------+
| id   | select_type | table | type | possible_keys | key  | key_len | ref  | rows | Extra                                               |
+------+-------------+-------+------+---------------+------+---------+------+------+-----------------------------------------------------+
|    1 | SIMPLE      | NULL  | NULL | NULL          | NULL | NULL    | NULL | NULL | Impossible WHERE noticed after reading const tables |
+------+-------------+-------+------+---------------+------+---------+------+------+-----------------------------------------------------+
1 row in set (0.001 sec)
 
MariaDB [test]> --Q5
MariaDB [test]>  EXPLAIN SELECT t1.a,MAX(t1.b) FROM t1 WHERE t1.a=3 GROUP BY t1.a HAVING (t1.a<2 OR t1.a>3);
+------+-------------+-------+------+---------------+------+---------+------+------+------------------+
| 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 row in set (0.000 sec)
 
MariaDB [test]> --Q6
MariaDB [test]>  EXPLAIN SELECT t1.a,MAX(t1.b) FROM t1 WHERE t1.a=3 AND (t1.a<2 OR t1.a>3) GROUP BY t1.a;
+------+-------------+-------+------+---------------+------+---------+------+------+------------------+
| 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 row in set (0.000 sec)

It can be seen that Q5 and Q6 have both “Impossible WHERE”. While Q4 is found to have impossible WHERE only after reading const tables.

Q1,Q2 and Q4 queries should be found to be impossible just after pushdown was made as it is done for Q5



 Comments   
Comment by Galina Shalygina (Inactive) [ 2019-04-14 ]

Impossible WHERE should be recognized after pushdown from HAVING into WHERE in and_new_conditions_to_optimized_cond() as it is done for Q3 query.

If the result condition in and_new_conditions_to_optimized_cond() method is found to be always false the result is saved in cond_value.

Impossible cond is checked in remove_eq_conds(). This is a last call in and_new_conditions_to_optimized_cond().
This call is made only if the cond was found to be simplified.

For the queries mentioned above it wasn't found that they have simplified conditions.

To check simplified conditions new method should be added to find all simplified conditions.

Comment by Galina Shalygina (Inactive) [ 2019-04-15 ]

Now simplified conditions are found in and_new_conditions_to_optimized_cond() only:
1. if they are joined to optimized condition
2. if they are inside OR condition which is inside top AND condition in final joined condition

So the case when optimized condition becomes simplified after new conditions are joined to it is ignored.

Comment by Igor Babaev [ 2019-04-18 ]

Ok to push into 10.4

Generated at Thu Feb 08 08:50:09 UTC 2024 using Jira 8.20.16#820016-sha1:9d11dbea5f4be3d4cc21f03a88dd11d8c8687422.