|
|
|
@ -13523,6 +13523,35 @@ void propagate_new_equalities(THD *thd, Item *cond, |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
Check if passed condtition has for of |
|
|
|
|
|
|
|
not_null_date_col IS NULL |
|
|
|
|
|
|
|
where not_null_date_col has a datte or datetime type |
|
|
|
*/ |
|
|
|
|
|
|
|
bool cond_is_datetime_is_null(Item *cond) |
|
|
|
{ |
|
|
|
if (cond->type() == Item::FUNC_ITEM && |
|
|
|
((Item_func*) cond)->functype() == Item_func::ISNULL_FUNC) |
|
|
|
{ |
|
|
|
Item **args= ((Item_func_isnull*) cond)->arguments(); |
|
|
|
if (args[0]->type() == Item::FIELD_ITEM) |
|
|
|
{ |
|
|
|
Field *field=((Item_field*) args[0])->field; |
|
|
|
|
|
|
|
if (((field->type() == MYSQL_TYPE_DATE) || |
|
|
|
(field->type() == MYSQL_TYPE_DATETIME)) && |
|
|
|
(field->flags & NOT_NULL_FLAG)) |
|
|
|
{ |
|
|
|
return TRUE; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
return FALSE; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
@brief |
|
|
|
@ -13776,6 +13805,52 @@ internal_remove_eq_conds(THD *thd, COND *cond, Item::cond_result *cond_value) |
|
|
|
return item; |
|
|
|
} |
|
|
|
} |
|
|
|
else if (cond_is_datetime_is_null(cond)) |
|
|
|
{ |
|
|
|
/* fix to replace 'NULL' dates with '0' (shreeve@uci.edu) */ |
|
|
|
/*
|
|
|
|
See BUG#12594011 |
|
|
|
Documentation says that |
|
|
|
SELECT datetime_notnull d FROM t1 WHERE d IS NULL |
|
|
|
shall return rows where d=='0000-00-00' |
|
|
|
|
|
|
|
Thus, for DATE and DATETIME columns defined as NOT NULL, |
|
|
|
"date_notnull IS NULL" has to be modified to |
|
|
|
"date_notnull IS NULL OR date_notnull == 0" (if outer join) |
|
|
|
"date_notnull == 0" (otherwise) |
|
|
|
|
|
|
|
*/ |
|
|
|
Item **args= ((Item_func_isnull*) cond)->arguments(); |
|
|
|
Field *field=((Item_field*) args[0])->field; |
|
|
|
|
|
|
|
Item *item0= new(thd->mem_root) Item_int((longlong)0, 1); |
|
|
|
Item *eq_cond= new(thd->mem_root) Item_func_eq(args[0], item0); |
|
|
|
if (!eq_cond) |
|
|
|
return cond; |
|
|
|
|
|
|
|
if (field->table->pos_in_table_list->outer_join) |
|
|
|
{ |
|
|
|
// outer join: transform "col IS NULL" to "col IS NULL or col=0"
|
|
|
|
Item *or_cond= new(thd->mem_root) Item_cond_or(eq_cond, cond); |
|
|
|
if (!or_cond) |
|
|
|
return cond; |
|
|
|
cond= or_cond; |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
// not outer join: transform "col IS NULL" to "col=0"
|
|
|
|
cond= eq_cond; |
|
|
|
} |
|
|
|
|
|
|
|
cond->fix_fields(thd, &cond); |
|
|
|
|
|
|
|
if (cond->const_item() && !cond->is_expensive()) |
|
|
|
{ |
|
|
|
*cond_value= eval_const_cond(cond) ? Item::COND_TRUE : Item::COND_FALSE; |
|
|
|
return (COND*) 0; |
|
|
|
} |
|
|
|
} |
|
|
|
#if 0
|
|
|
|
else if (cond->type() == Item::FUNC_ITEM && |
|
|
|
((Item_func*) cond)->functype() == Item_func::ISNULL_FUNC) |
|
|
|
{ |
|
|
|
@ -13829,6 +13904,7 @@ internal_remove_eq_conds(THD *thd, COND *cond, Item::cond_result *cond_value) |
|
|
|
return (COND*) 0; |
|
|
|
} |
|
|
|
} |
|
|
|
#endif
|
|
|
|
else if (cond->const_item() && !cond->is_expensive()) |
|
|
|
{ |
|
|
|
*cond_value= eval_const_cond(cond) ? Item::COND_TRUE : Item::COND_FALSE; |
|
|
|
|