[MDEV-3595] LP:727667 - Wrong result with OR + NOT NULL in maria-5.3 Created: 2011-03-02 Updated: 2015-02-02 Resolved: 2012-10-04 |
|
| Status: | Closed |
| Project: | MariaDB Server |
| Component/s: | None |
| Affects Version/s: | None |
| Fix Version/s: | None |
| Type: | Bug | Priority: | Major |
| Reporter: | Philip Stoev (Inactive) | Assignee: | Sergei Petrunia |
| Resolution: | Fixed | Votes: | 0 |
| Labels: | Launchpad | ||
| Attachments: |
|
| Description |
|
Not reproducible in maria-5.2. The following query: SELECT * FROM t1 WHERE (f3 = 83) OR (f10 = 'q' AND f3 IS NULL); returns -----
-----
----- which is obviously wrong since neither f3 = 83 nor f10 = 'q' test case: CREATE TABLE t1 ( SELECT * FROM t1 WHERE (f3 = 83) OR (f10 = 'z' AND f3 IS NULL); bzr version-info: revision-id: <email address hidden> |
| Comments |
| Comment by Sergei Petrunia [ 2011-03-02 ] | ||||||||||||||||||||
|
Re: Wrong result with OR + NOT NULL in maria-5.3 MariaDB [j28]> explain SELECT * FROM t1 WHERE (f3 = 83) OR (f10 = 'z' AND f3 IS NULL);
---
--- Note the lack of "Using where". Debugging shows that
| ||||||||||||||||||||
| Comment by Sergei Petrunia [ 2011-03-02 ] | ||||||||||||||||||||
|
Re: Wrong result with OR + NOT NULL in maria-5.3
---
--- | ||||||||||||||||||||
| Comment by Sergei Petrunia [ 2011-03-05 ] | ||||||||||||||||||||
|
Re: Wrong result with OR + NOT NULL in maria-5.3 test_if_ref()/part_of_refkey() will indicate to make_cond_for_table() that condition "f3 = 83" will be always true, which actually is not satisfied by the (NULL,'r'), which will be returned by ref-or-null access. when make_cond_for_table() considers a WHERE clause of: (f3 = 83) OR (f10 = 'z' AND f3 IS NULL) and it is told that (f3 = 83) is universally true, it (correctly) concludes that entire WHERE condition is universally true, so there is no point in checking it. | ||||||||||||||||||||
| Comment by Sergei Petrunia [ 2011-03-05 ] | ||||||||||||||||||||
|
Re: Wrong result with OR + NOT NULL in maria-5.3 How it worked before the backport ... { KEY_PART_INFO *key_part= table->key_info[table->reginfo.join_tab->ref.key].key_part; for (uint part=0 ; part < ref_parts ; part++,key_part++) if (field->eq(key_part->field) && !(key_part->key_part_flag & (HA_PART_KEY_SEG | HA_NULL_PART))) return table->reginfo.join_tab->ref.items[part]; }The important part here: we check HA_NULL_PART bit. If it is present, equality will not be removed. It serves two purposes: P2. Also cover ref_or_null access method. When ref_or_null is used, table access can return either the lookup value or a record with NULLs, so the equality is not universally guaranteed. ref_or_null is only employed for NULL-able columns (no point to look for NULLs in non-NULLable column), so if we keep the equality for NULLable columns, we cut off ref_or_null, too. | ||||||||||||||||||||
| Comment by Sergei Petrunia [ 2011-03-05 ] | ||||||||||||||||||||
|
Re: Wrong result with OR + NOT NULL in maria-5.3 Somewhere along with DS-MRR/ICP works, we've added "Early/Late NULLs filtering", which would cut off the case of P1 form the previous post. That is, if we have a ref access on "t.key=col" and we get NULL for col, the new code will not search for NULL value of t.key, and so will not need the equality check to filter out NULL results. We forgot about case p2, though. The implementation in the code was odd. It worked as follows: the check in part_of_refkey() looked the same: !(key_part->key_part_flag & (HA_PART_KEY_SEG | HA_NULL_PART))) However, the part that sets the HA_PART_KEY_SEG flag was gone. It had been located in table.cc:open_binary_frm() and looked like this: ... /* so I went ahead and deleted that code. The effect was as desired: lots equalities weren't checked anymore, and lots of "Using where" were gone from ref access EXPLAINs. | ||||||||||||||||||||
| Comment by Sergei Petrunia [ 2011-03-05 ] | ||||||||||||||||||||
|
Re: Wrong result with OR + NOT NULL in maria-5.3 When I've tried to remove HA_NULL_PART flag completely (so that we don't have checks for something we don't set) So, the solution is:
in other words: 1. NULL-ability of the lookup column should not prevent the removal of ref-equality. | ||||||||||||||||||||
| Comment by Rasmus Johansson (Inactive) [ 2011-12-13 ] | ||||||||||||||||||||
|
Launchpad bug id: 727667 |