diff options
Diffstat (limited to 'sql')
-rw-r--r-- | sql/item.cc | 11 | ||||
-rw-r--r-- | sql/item_strfunc.cc | 2 | ||||
-rw-r--r-- | sql/item_subselect.cc | 15 | ||||
-rw-r--r-- | sql/item_subselect.h | 1 | ||||
-rw-r--r-- | sql/sql_select.cc | 10 |
5 files changed, 32 insertions, 7 deletions
diff --git a/sql/item.cc b/sql/item.cc index 84da69adc39..6080feec9d8 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -1781,7 +1781,16 @@ bool agg_item_set_converter(DTCollation &coll, const char *fname, if (!(conv= (*arg)->safe_charset_converter(coll.collation)) && ((*arg)->collation.repertoire == MY_REPERTOIRE_ASCII)) - conv= new Item_func_conv_charset(*arg, coll.collation, 1); + { + /* + We should disable const subselect item evaluation because + subselect transformation does not happen in view_prepare_mode + and thus val_...() methods can not be called for const items. + */ + bool resolve_const= ((*arg)->type() == Item::SUBSELECT_ITEM && + thd->lex->view_prepare_mode) ? FALSE : TRUE; + conv= new Item_func_conv_charset(*arg, coll.collation, resolve_const); + } if (!conv) { diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index dab29bb58c4..9e3f9189b01 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -357,7 +357,7 @@ String *Item_func_concat::val_str(String *str) } else if (str->alloced_length() >= res->length()+res2->length()) { - if (str == res2) + if (str->ptr() == res2->ptr()) str->replace(0,0,*res); else { diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index 83e1f9b0625..3e3f8e93266 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -122,6 +122,21 @@ void Item_subselect::cleanup() DBUG_VOID_RETURN; } + +/* + We cannot use generic Item::safe_charset_converter() because + Subselect transformation does not happen in view_prepare_mode + and thus we can not evaluate val_...() for const items. +*/ + +Item *Item_subselect::safe_charset_converter(CHARSET_INFO *tocs) +{ + Item_func_conv_charset *conv= + new Item_func_conv_charset(this, tocs, thd->lex->view_prepare_mode ? 0 : 1); + return conv->safe ? conv : NULL; +} + + void Item_singlerow_subselect::cleanup() { DBUG_ENTER("Item_singlerow_subselect::cleanup"); diff --git a/sql/item_subselect.h b/sql/item_subselect.h index 3503d42edc0..d22104dddf1 100644 --- a/sql/item_subselect.h +++ b/sql/item_subselect.h @@ -129,6 +129,7 @@ public: virtual void reset_value_registration() {} enum_parsing_place place() { return parsing_place; } bool walk(Item_processor processor, bool walk_subquery, uchar *arg); + Item *safe_charset_converter(CHARSET_INFO *tocs); /** Get the SELECT_LEX structure associated with this Item. diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 6c9c671a093..8e123ca9167 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -1128,13 +1128,13 @@ JOIN::optimize() elements may be lost during further having condition transformation in JOIN::exec. */ - if (having && !having->with_sum_func) + if (having && const_table_map) { - COND *const_cond= make_cond_for_table(having, const_table_map, 0); - DBUG_EXECUTE("where", print_where(const_cond, "const_having_cond", - QT_ORDINARY);); - if (const_cond && !const_cond->val_int()) + having->update_used_tables(); + having= remove_eq_conds(thd, having, &having_value); + if (having_value == Item::COND_FALSE) { + having= new Item_int((longlong) 0,1); zero_result_cause= "Impossible HAVING noticed after reading const tables"; error= 0; DBUG_RETURN(0); |