summaryrefslogtreecommitdiff
path: root/sql/item.h
diff options
context:
space:
mode:
Diffstat (limited to 'sql/item.h')
-rw-r--r--sql/item.h41
1 files changed, 22 insertions, 19 deletions
diff --git a/sql/item.h b/sql/item.h
index 52a644677a6..2411904a00f 100644
--- a/sql/item.h
+++ b/sql/item.h
@@ -827,34 +827,35 @@ public:
class Item_ref :public Item_ident
{
+protected:
+ void set_properties();
public:
Field *result_field; /* Save result here */
Item **ref;
Item_ref(const char *db_par, const char *table_name_par,
const char *field_name_par)
:Item_ident(db_par, table_name_par, field_name_par), ref(0) {}
- Item_ref(Item **item, const char *table_name_par, const char *field_name_par)
- :Item_ident(NullS, table_name_par, field_name_par), ref(item) {}
-
/*
- This constructor is used when processing GROUP BY and referred Item is
- available. We set all properties here because fix_fields() will not be
- called for the created Item_ref. (see BUG#6976)
- TODO check if we could get rid of *_name_par parameters and if we need to
- perform similar initialization for other ctors.
+ This constructor is used in two scenarios:
+ A) *item = NULL
+ No initialization is performed, fix_fields() call will be necessary.
+
+ B) *item points to an Item this Item_ref will refer to. This is
+ used for GROUP BY. fix_fields() will not be called in this case,
+ so we call set_properties to make this item "fixed". set_properties
+ performs a subset of action Item_ref::fix_fields does, and this subset
+ is enough for Item_ref's used in GROUP BY.
+
TODO we probably fix a superset of problems like in BUG#6658. Check this
with Bar, and if we have a more broader set of problems like this.
*/
- Item_ref(Item **item, const char *table_name_par,
- const char *field_name_par, Item *src)
- : Item_ident(NullS, table_name_par, field_name_par), ref(item)
+ Item_ref(Item **item, const char *table_name_par, const char *field_name_par)
+ :Item_ident(NullS, table_name_par, field_name_par), ref(item)
{
- collation.set(src->collation);
- max_length= src->max_length;
- decimals= src->decimals;
- with_sum_func= src->with_sum_func;
- maybe_null= src->maybe_null;
+ if (*item)
+ set_properties();
}
+
/* Constructor need to process subselect with temporary tables (see Item) */
Item_ref(THD *thd, Item_ref *item) :Item_ident(thd, item), ref(item->ref) {}
enum Type type() const { return REF_ITEM; }
@@ -862,29 +863,34 @@ public:
{ return ref && (*ref)->eq(item, binary_cmp); }
double val()
{
+ DBUG_ASSERT(fixed);
double tmp=(*ref)->val_result();
null_value=(*ref)->null_value;
return tmp;
}
longlong val_int()
{
+ DBUG_ASSERT(fixed);
longlong tmp=(*ref)->val_int_result();
null_value=(*ref)->null_value;
return tmp;
}
String *val_str(String* tmp)
{
+ DBUG_ASSERT(fixed);
tmp=(*ref)->str_result(tmp);
null_value=(*ref)->null_value;
return tmp;
}
bool is_null()
{
+ DBUG_ASSERT(fixed);
(void) (*ref)->val_int_result();
return (*ref)->null_value;
}
bool get_date(TIME *ltime,uint fuzzydate)
{
+ DBUG_ASSERT(fixed);
return (null_value=(*ref)->get_date_result(ltime,fuzzydate));
}
bool send(Protocol *prot, String *tmp){ return (*ref)->send(prot, tmp); }
@@ -922,9 +928,6 @@ public:
:Item_ref(item, table_name_par, field_name_par) {}
/* Constructor need to process subselect with temporary tables (see Item) */
Item_direct_ref(THD *thd, Item_direct_ref *item) : Item_ref(thd, item) {}
- Item_direct_ref(Item **item, const char *table_name_par,
- const char *field_name_par, Item *src)
- : Item_ref(item, table_name_par, field_name_par, src) {}
double val()
{