summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
Diffstat (limited to 'sql')
-rw-r--r--sql/item.cc11
-rw-r--r--sql/item_strfunc.cc2
-rw-r--r--sql/item_subselect.cc15
-rw-r--r--sql/item_subselect.h1
-rw-r--r--sql/sql_select.cc10
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);