Commit edd98022 authored by Sergey Petrunya's avatar Sergey Petrunya

Fix for MDEV-4836 fix: take into account situation where "notnull_col IS NULL" is not

a direct child of the WHERE clause item, but rather is embedded inside Item_cond_and or 
Item_cond_or.
parent af753c21
...@@ -2150,6 +2150,14 @@ id d i ...@@ -2150,6 +2150,14 @@ id d i
1 0000-00-00 NULL 1 0000-00-00 NULL
2 0000-00-00 NULL 2 0000-00-00 NULL
DROP TABLE t1,t2; DROP TABLE t1,t2;
CREATE TABLE t1 (i1 INT, d1 DATE NOT NULL);
INSERT INTO t1 VALUES (1,'2012-12-21'),(2,'0000-00-00');
CREATE TABLE t2 (i2 INT, j2 INT);
INSERT INTO t2 VALUES (1,10),(2,20);
SELECT * FROM t1 LEFT JOIN t2 ON i1 = j2 WHERE d1 IS NULL AND 1 OR i1 = i2;
i1 d1 i2 j2
2 0000-00-00 NULL NULL
DROP TABLE t1,t2;
# #
# Bug mdev-4942: LEFT JOIN with conjunctive # Bug mdev-4942: LEFT JOIN with conjunctive
# <non-nullable datetime field> IS NULL in WHERE # <non-nullable datetime field> IS NULL in WHERE
......
...@@ -2161,6 +2161,14 @@ id d i ...@@ -2161,6 +2161,14 @@ id d i
1 0000-00-00 NULL 1 0000-00-00 NULL
2 0000-00-00 NULL 2 0000-00-00 NULL
DROP TABLE t1,t2; DROP TABLE t1,t2;
CREATE TABLE t1 (i1 INT, d1 DATE NOT NULL);
INSERT INTO t1 VALUES (1,'2012-12-21'),(2,'0000-00-00');
CREATE TABLE t2 (i2 INT, j2 INT);
INSERT INTO t2 VALUES (1,10),(2,20);
SELECT * FROM t1 LEFT JOIN t2 ON i1 = j2 WHERE d1 IS NULL AND 1 OR i1 = i2;
i1 d1 i2 j2
2 0000-00-00 NULL NULL
DROP TABLE t1,t2;
# #
# Bug mdev-4942: LEFT JOIN with conjunctive # Bug mdev-4942: LEFT JOIN with conjunctive
# <non-nullable datetime field> IS NULL in WHERE # <non-nullable datetime field> IS NULL in WHERE
......
...@@ -1696,6 +1696,17 @@ CREATE TABLE t2 (i INT); ...@@ -1696,6 +1696,17 @@ CREATE TABLE t2 (i INT);
SELECT * FROM t1 LEFT JOIN t2 ON (id=i) WHERE NULL OR d IS NULL; SELECT * FROM t1 LEFT JOIN t2 ON (id=i) WHERE NULL OR d IS NULL;
DROP TABLE t1,t2; DROP TABLE t1,t2;
CREATE TABLE t1 (i1 INT, d1 DATE NOT NULL);
INSERT INTO t1 VALUES (1,'2012-12-21'),(2,'0000-00-00');
CREATE TABLE t2 (i2 INT, j2 INT);
INSERT INTO t2 VALUES (1,10),(2,20);
SELECT * FROM t1 LEFT JOIN t2 ON i1 = j2 WHERE d1 IS NULL AND 1 OR i1 = i2;
DROP TABLE t1,t2;
--echo # --echo #
--echo # Bug mdev-4942: LEFT JOIN with conjunctive --echo # Bug mdev-4942: LEFT JOIN with conjunctive
--echo # <non-nullable datetime field> IS NULL in WHERE --echo # <non-nullable datetime field> IS NULL in WHERE
......
...@@ -4302,7 +4302,7 @@ Item_cond::fix_fields(THD *thd, Item **ref) ...@@ -4302,7 +4302,7 @@ Item_cond::fix_fields(THD *thd, Item **ref)
used_tables_cache|= item->used_tables(); used_tables_cache|= item->used_tables();
if (item->const_item()) if (item->const_item())
{ {
if (!item->is_expensive() && !cond_is_datetime_is_null(item) && if (!item->is_expensive() && !cond_has_datetime_is_null(item) &&
item->val_int() == 0) item->val_int() == 0)
{ {
/* /*
...@@ -4355,7 +4355,7 @@ Item_cond::eval_not_null_tables(uchar *opt_arg) ...@@ -4355,7 +4355,7 @@ Item_cond::eval_not_null_tables(uchar *opt_arg)
table_map tmp_table_map; table_map tmp_table_map;
if (item->const_item()) if (item->const_item())
{ {
if (!item->is_expensive() && !cond_is_datetime_is_null(item) && if (!item->is_expensive() && !cond_has_datetime_is_null(item) &&
item->val_int() == 0) item->val_int() == 0)
{ {
/* /*
......
...@@ -13526,6 +13526,28 @@ void propagate_new_equalities(THD *thd, Item *cond, ...@@ -13526,6 +13526,28 @@ void propagate_new_equalities(THD *thd, Item *cond,
} }
} }
/*
Check if cond_is_datetime_is_null() is true for the condition cond, or
for any of its AND/OR-children
*/
bool cond_has_datetime_is_null(Item *cond)
{
if (cond_is_datetime_is_null(cond))
return true;
if (cond->type() == Item::COND_ITEM)
{
List<Item> *cond_arg_list= ((Item_cond*) cond)->argument_list();
List_iterator<Item> li(*cond_arg_list);
Item *item;
while ((item= li++))
{
if (cond_has_datetime_is_null(item))
return true;
}
}
return false;
}
/* /*
Check if passed condtition has for of Check if passed condtition has for of
......
...@@ -1796,6 +1796,7 @@ bool const_expression_in_where(COND *cond, Item *comp_item, ...@@ -1796,6 +1796,7 @@ bool const_expression_in_where(COND *cond, Item *comp_item,
Field *comp_field= NULL, Field *comp_field= NULL,
Item **const_item= NULL); Item **const_item= NULL);
bool cond_is_datetime_is_null(Item *cond); bool cond_is_datetime_is_null(Item *cond);
bool cond_has_datetime_is_null(Item *cond);
/* Table elimination entry point function */ /* Table elimination entry point function */
void eliminate_tables(JOIN *join); void eliminate_tables(JOIN *join);
......
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