diff options
author | Sergey Petrunya <psergey@askmonty.org> | 2013-08-26 16:31:58 +0400 |
---|---|---|
committer | Sergey Petrunya <psergey@askmonty.org> | 2013-08-26 16:31:58 +0400 |
commit | af753c2188d9582a36a550bab0d2ee64205630c8 (patch) | |
tree | 0420a75bca3a02db57bfefaa293d0b0fe6a61c9f /sql | |
parent | 7907b9b4da8c299318bd73d32b621dc34acc0f35 (diff) | |
parent | 970542ec90951c3e9d68ff310cdf181465854aaa (diff) | |
download | mariadb-git-af753c2188d9582a36a550bab0d2ee64205630c8.tar.gz |
Fix for MDEV-4836: Merge with current 5.5
Diffstat (limited to 'sql')
-rw-r--r-- | sql/item_cmpfunc.cc | 27 | ||||
-rw-r--r-- | sql/sql_select.cc | 103 | ||||
-rw-r--r-- | sql/sql_select.h | 1 |
3 files changed, 73 insertions, 58 deletions
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index dcc356ce5b2..6f181c39b67 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -4302,7 +4302,8 @@ Item_cond::fix_fields(THD *thd, Item **ref) used_tables_cache|= item->used_tables(); if (item->const_item()) { - if (!item->is_expensive() && item->val_int() == 0) + if (!item->is_expensive() && !cond_is_datetime_is_null(item) && + item->val_int() == 0) { /* This is "... OR false_cond OR ..." @@ -4314,27 +4315,18 @@ Item_cond::fix_fields(THD *thd, Item **ref) /* This is "... OR const_cond OR ..." In this case, cond_or->not_null_tables()=0, because the condition - some_cond_or might be true regardless of what tables are - NULL-complemented. + const_cond might evaluate to true (regardless of whether some tables + were NULL-complemented). */ and_tables_cache= (table_map) 0; } } else { - /* - If an item is a - - constant - - inexpensive - - its value is 0 - then we don't need to account it in not_null_tables_cache - */ - //if (!(item->const_item() && !item->is_expensive() )) - { - table_map tmp_table_map= item->not_null_tables(); - not_null_tables_cache|= tmp_table_map; - and_tables_cache&= tmp_table_map; - } + table_map tmp_table_map= item->not_null_tables(); + not_null_tables_cache|= tmp_table_map; + and_tables_cache&= tmp_table_map; + const_item_cache= FALSE; } @@ -4363,7 +4355,8 @@ Item_cond::eval_not_null_tables(uchar *opt_arg) table_map tmp_table_map; if (item->const_item()) { - if (!item->is_expensive() && item->val_int() == 0) + if (!item->is_expensive() && !cond_is_datetime_is_null(item) && + item->val_int() == 0) { /* This is "... OR false_cond OR ..." diff --git a/sql/sql_select.cc b/sql/sql_select.cc index d4062f5e0c9..51ce9bccf6c 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -13527,6 +13527,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 @@ -13781,53 +13810,45 @@ internal_remove_eq_conds(THD *thd, COND *cond, Item::cond_result *cond_value) return item; } } - else if (cond->type() == Item::FUNC_ITEM && - ((Item_func*) cond)->functype() == Item_func::ISNULL_FUNC) + else if (cond_is_datetime_is_null(cond)) { - Item_func_isnull *func=(Item_func_isnull*) cond; - Item **args= func->arguments(); - if (args[0]->type() == Item::FIELD_ITEM) - { - Field *field=((Item_field*) args[0])->field; - /* 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' + /* 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) + 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) - */ - if (((field->type() == MYSQL_TYPE_DATE) || - (field->type() == MYSQL_TYPE_DATETIME)) && - (field->flags & NOT_NULL_FLAG)) - { - 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; + */ + Item **args= ((Item_func_isnull*) cond)->arguments(); + Field *field=((Item_field*) args[0])->field; - 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; - } + 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; - cond->fix_fields(thd, &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; diff --git a/sql/sql_select.h b/sql/sql_select.h index 478eede7108..fd12cfae335 100644 --- a/sql/sql_select.h +++ b/sql/sql_select.h @@ -1795,6 +1795,7 @@ ORDER *simple_remove_const(ORDER *order, COND *where); bool const_expression_in_where(COND *cond, Item *comp_item, Field *comp_field= NULL, Item **const_item= NULL); +bool cond_is_datetime_is_null(Item *cond); /* Table elimination entry point function */ void eliminate_tables(JOIN *join); |