Details
-
Bug
-
Status: Closed (View Workflow)
-
Critical
-
Resolution: Fixed
-
1.4.3, 1.5.2
-
None
Description
Consider the scenario.
create table cs1(i bigint)engine=columnstore;
|
insert into cs1 values (42),(43);
|
update cs1 set i = 41 where i = 42 or (i is null and 42 is null);
|
MariaDB [test]> create table cs1(i bigint)engine=columnstore;
|
Query OK, 0 rows affected (0.405 sec)
|
|
MariaDB [test]> insert into cs1 values (42),(43);
|
Query OK, 2 rows affected (0.316 sec)
|
Records: 2 Duplicates: 0 Warnings: 0
|
|
MariaDB [test]> update cs1 set i = 41 where i = 42 or (i is null and 42 is null);
|
Query OK, 2 rows affected (0.323 sec)
|
Rows matched: 2 Changed: 2 Warnings: 0
|
MCS updates two records instead of only one.
MDB optimizes WHERE conditions removing (i is null and 42 is null) block and pushes the the whole WHERE predicate using ha_mcs::cond_push(). cond_push() ignores pushes for UPDATEs thus MCS has an empty WHERE conditions producing CSEP in doUpdateDelete().getSelectPlan().
JFYI MDB both sends WHERE predicate using cond_push() and SELECT_LEX for some queries but doesn't for others.
We need to refactor cond_push to use handler instance to safe conditions for UPDATEs and push them down into doUpdateDelete().getSelectPlan().
NB There should be no cond_push calls for join conditions so the conditions pushed belongs to one table only.