summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sql/item_sum.cc64
-rw-r--r--sql/item_sum.h3
-rw-r--r--sql/item_windowfunc.cc38
-rw-r--r--sql/item_windowfunc.h1
-rw-r--r--sql/sql_type.cc80
-rw-r--r--sql/sql_type.h20
6 files changed, 97 insertions, 109 deletions
diff --git a/sql/item_sum.cc b/sql/item_sum.cc
index 081db08e943..08ee190e96c 100644
--- a/sql/item_sum.cc
+++ b/sql/item_sum.cc
@@ -1184,11 +1184,73 @@ Item_sum_min_max::fix_fields(THD *thd, Item **ref)
}
+bool Item_sum_hybrid::fix_length_and_dec_generic()
+{
+ Item *item= arguments()[0];
+ Type_std_attributes::set(item);
+ set_handler(item->type_handler());
+ return false;
+}
+
+
+/**
+ MAX/MIN for the traditional numeric types preserve the exact data type
+ from Fields, but do not preserve the exact type from Items:
+ MAX(float_field) -> FLOAT
+ MAX(smallint_field) -> LONGLONG
+ MAX(COALESCE(float_field)) -> DOUBLE
+ MAX(COALESCE(smallint_field)) -> LONGLONG
+ QQ: Items should probably be fixed to preserve the exact type.
+*/
+bool Item_sum_hybrid::fix_length_and_dec_numeric(const Type_handler *handler)
+{
+ Item *item= arguments()[0];
+ Item *item2= item->real_item();
+ Type_std_attributes::set(item);
+ if (item2->type() == Item::FIELD_ITEM)
+ set_handler(item2->type_handler());
+ else
+ set_handler(handler);
+ return false;
+}
+
+
+/**
+ MAX(str_field) converts ENUM/SET to CHAR, and preserve all other types
+ for Fields.
+ QQ: This works differently from UNION, which preserve the exact data
+ type for ENUM/SET if the joined ENUM/SET fields are equally defined.
+ Perhaps should be fixed.
+ MAX(str_item) chooses the best suitable string type.
+*/
+bool Item_sum_hybrid::fix_length_and_dec_string()
+{
+ Item *item= arguments()[0];
+ Item *item2= item->real_item();
+ Type_std_attributes::set(item);
+ if (item2->type() == Item::FIELD_ITEM)
+ {
+ // Fields: convert ENUM/SET to CHAR, preserve the type otherwise.
+ set_handler(item->type_handler());
+ }
+ else
+ {
+ // Items: choose VARCHAR/BLOB/MEDIUMBLOB/LONGBLOB, depending on length.
+ set_handler(type_handler_varchar.
+ type_handler_adjusted_to_max_octet_length(max_length,
+ collation.collation));
+ }
+ return false;
+}
+
+
bool Item_sum_min_max::fix_length_and_dec()
{
DBUG_ASSERT(args[0]->field_type() == args[0]->real_item()->field_type());
DBUG_ASSERT(args[0]->result_type() == args[0]->real_item()->result_type());
- return args[0]->type_handler()->Item_sum_min_max_fix_length_and_dec(this);
+ /* MIN/MAX can return NULL for empty set indepedent of the used column */
+ maybe_null= null_value= true;
+ return args[0]->type_handler()->Item_sum_hybrid_fix_length_and_dec(this);
}
diff --git a/sql/item_sum.h b/sql/item_sum.h
index df37d0dbfa4..a3e10c25763 100644
--- a/sql/item_sum.h
+++ b/sql/item_sum.h
@@ -1044,6 +1044,9 @@ public:
{ }
const Type_handler *type_handler() const
{ return Type_handler_hybrid_field_type::type_handler(); }
+ bool fix_length_and_dec_generic();
+ bool fix_length_and_dec_numeric(const Type_handler *h);
+ bool fix_length_and_dec_string();
};
diff --git a/sql/item_windowfunc.cc b/sql/item_windowfunc.cc
index 98474f62d4f..17c5740feda 100644
--- a/sql/item_windowfunc.cc
+++ b/sql/item_windowfunc.cc
@@ -353,39 +353,15 @@ bool Item_sum_hybrid_simple::fix_fields(THD *thd, Item **ref)
if (args[i]->fix_fields_if_needed_for_scalar(thd, &args[i]))
return TRUE;
}
- Type_std_attributes::set(args[0]);
+
for (uint i= 0; i < arg_count && !m_with_subquery; i++)
m_with_subquery|= args[i]->with_subquery();
- Item *item2= args[0]->real_item();
- if (item2->type() == Item::FIELD_ITEM)
- set_handler(item2->type_handler());
- else if (args[0]->cmp_type() == TIME_RESULT)
- set_handler(item2->type_handler());
- else
- set_handler_by_result_type(item2->result_type(),
- max_length, collation.collation);
+ if (fix_length_and_dec())
+ return true;
- switch (result_type()) {
- case INT_RESULT:
- case DECIMAL_RESULT:
- case STRING_RESULT:
- break;
- case REAL_RESULT:
- max_length= float_length(decimals);
- break;
- case ROW_RESULT:
- case TIME_RESULT:
- DBUG_ASSERT(0); // XXX(cvicentiu) Should this never happen?
- return TRUE;
- };
setup_hybrid(thd, args[0]);
- /* MIN/MAX can return NULL for empty set indepedent of the used column */
- maybe_null= 1;
result_field=0;
- null_value=1;
- if (fix_length_and_dec())
- return TRUE;
if (check_sum_func(thd, ref))
return TRUE;
@@ -397,6 +373,14 @@ bool Item_sum_hybrid_simple::fix_fields(THD *thd, Item **ref)
return FALSE;
}
+
+bool Item_sum_hybrid_simple::fix_length_and_dec()
+{
+ maybe_null= null_value= true;
+ return args[0]->type_handler()->Item_sum_hybrid_fix_length_and_dec(this);
+}
+
+
bool Item_sum_hybrid_simple::add()
{
value->store(args[0]);
diff --git a/sql/item_windowfunc.h b/sql/item_windowfunc.h
index 1432643dfc8..e6389c01832 100644
--- a/sql/item_windowfunc.h
+++ b/sql/item_windowfunc.h
@@ -307,6 +307,7 @@ class Item_sum_hybrid_simple : public Item_sum_hybrid
bool add();
bool fix_fields(THD *, Item **);
+ bool fix_length_and_dec();
void setup_hybrid(THD *thd, Item *item);
double val_real();
longlong val_int();
diff --git a/sql/sql_type.cc b/sql/sql_type.cc
index 573d9721fc1..114e4cac367 100644
--- a/sql/sql_type.cc
+++ b/sql/sql_type.cc
@@ -365,7 +365,7 @@ Type_handler::blob_type_handler(const Item *item)
/**
This method is used by:
- - Item_sum_min_max, e.g. MAX(item), MIN(item).
+ - Item_sum_hybrid, e.g. MAX(item), MIN(item).
- Item_func_set_user_var
*/
const Type_handler *
@@ -3076,87 +3076,33 @@ bool Type_handler_real_result::
/*************************************************************************/
-/**
- MAX/MIN for the traditional numeric types preserve the exact data type
- from Fields, but do not preserve the exact type from Items:
- MAX(float_field) -> FLOAT
- MAX(smallint_field) -> LONGLONG
- MAX(COALESCE(float_field)) -> DOUBLE
- MAX(COALESCE(smallint_field)) -> LONGLONG
- QQ: Items should probably be fixed to preserve the exact type.
-*/
-bool Type_handler_numeric::
- Item_sum_min_max_fix_length_and_dec_numeric(Item_sum_min_max *func,
- const Type_handler *handler)
- const
-{
- Item *item= func->arguments()[0];
- Item *item2= item->real_item();
- func->Type_std_attributes::set(item);
- /* MIN/MAX can return NULL for empty set indepedent of the used column */
- func->maybe_null= func->null_value= true;
- if (item2->type() == Item::FIELD_ITEM)
- func->set_handler(item2->type_handler());
- else
- func->set_handler(handler);
- return false;
-}
-
-
bool Type_handler_int_result::
- Item_sum_min_max_fix_length_and_dec(Item_sum_min_max *func) const
+ Item_sum_hybrid_fix_length_and_dec(Item_sum_hybrid *func) const
{
- return Item_sum_min_max_fix_length_and_dec_numeric(func,
- &type_handler_longlong);
+ return func->fix_length_and_dec_numeric(&type_handler_longlong);
}
bool Type_handler_real_result::
- Item_sum_min_max_fix_length_and_dec(Item_sum_min_max *func) const
+ Item_sum_hybrid_fix_length_and_dec(Item_sum_hybrid *func) const
{
- (void) Item_sum_min_max_fix_length_and_dec_numeric(func,
- &type_handler_double);
+ (void) func->fix_length_and_dec_numeric(&type_handler_double);
func->max_length= func->float_length(func->decimals);
return false;
}
bool Type_handler_decimal_result::
- Item_sum_min_max_fix_length_and_dec(Item_sum_min_max *func) const
+ Item_sum_hybrid_fix_length_and_dec(Item_sum_hybrid *func) const
{
- return Item_sum_min_max_fix_length_and_dec_numeric(func,
- &type_handler_newdecimal);
+ return func->fix_length_and_dec_numeric(&type_handler_newdecimal);
}
-/**
- MAX(str_field) converts ENUM/SET to CHAR, and preserve all other types
- for Fields.
- QQ: This works differently from UNION, which preserve the exact data
- type for ENUM/SET if the joined ENUM/SET fields are equally defined.
- Perhaps should be fixed.
- MAX(str_item) chooses the best suitable string type.
-*/
bool Type_handler_string_result::
- Item_sum_min_max_fix_length_and_dec(Item_sum_min_max *func) const
+ Item_sum_hybrid_fix_length_and_dec(Item_sum_hybrid *func) const
{
- Item *item= func->arguments()[0];
- Item *item2= item->real_item();
- func->Type_std_attributes::set(item);
- func->maybe_null= func->null_value= true;
- if (item2->type() == Item::FIELD_ITEM)
- {
- // Fields: convert ENUM/SET to CHAR, preserve the type otherwise.
- func->set_handler(item->type_handler());
- }
- else
- {
- // Items: choose VARCHAR/BLOB/MEDIUMBLOB/LONGBLOB, depending on length.
- func->set_handler(type_handler_varchar.
- type_handler_adjusted_to_max_octet_length(func->max_length,
- func->collation.collation));
- }
- return false;
+ return func->fix_length_and_dec_string();
}
@@ -3164,13 +3110,9 @@ bool Type_handler_string_result::
Traditional temporal types always preserve the type of the argument.
*/
bool Type_handler_temporal_result::
- Item_sum_min_max_fix_length_and_dec(Item_sum_min_max *func) const
+ Item_sum_hybrid_fix_length_and_dec(Item_sum_hybrid *func) const
{
- Item *item= func->arguments()[0];
- func->Type_std_attributes::set(item);
- func->maybe_null= func->null_value= true;
- func->set_handler(item->type_handler());
- return false;
+ return func->fix_length_and_dec_generic();
}
diff --git a/sql/sql_type.h b/sql/sql_type.h
index a7915ddc463..df4b99569c1 100644
--- a/sql/sql_type.h
+++ b/sql/sql_type.h
@@ -33,7 +33,7 @@ class Item;
class Item_param;
class Item_cache;
class Item_func_or_sum;
-class Item_sum_min_max;
+class Item_sum_hybrid;
class Item_sum_sum;
class Item_sum_avg;
class Item_sum_variance;
@@ -1314,7 +1314,7 @@ public:
Item_func_min_max *func,
Item **items,
uint nitems) const;
- virtual bool Item_sum_min_max_fix_length_and_dec(Item_sum_min_max *) const= 0;
+ virtual bool Item_sum_hybrid_fix_length_and_dec(Item_sum_hybrid *) const= 0;
virtual bool Item_sum_sum_fix_length_and_dec(Item_sum_sum *) const= 0;
virtual bool Item_sum_avg_fix_length_and_dec(Item_sum_avg *) const= 0;
virtual
@@ -1563,7 +1563,7 @@ public:
DBUG_ASSERT(0);
return true;
}
- bool Item_sum_min_max_fix_length_and_dec(Item_sum_min_max *func) const
+ bool Item_sum_hybrid_fix_length_and_dec(Item_sum_hybrid *func) const
{
DBUG_ASSERT(0);
return true;
@@ -1742,10 +1742,6 @@ public:
*/
class Type_handler_numeric: public Type_handler
{
-protected:
- bool Item_sum_min_max_fix_length_and_dec_numeric(Item_sum_min_max *func,
- const Type_handler *handler)
- const;
public:
String *print_item_value(THD *thd, Item *item, String *str) const;
double Item_func_min_max_val_real(Item_func_min_max *) const;
@@ -1796,7 +1792,7 @@ public:
Item **items, uint nitems) const;
bool Item_func_min_max_fix_attributes(THD *thd, Item_func_min_max *func,
Item **items, uint nitems) const;
- bool Item_sum_min_max_fix_length_and_dec(Item_sum_min_max *func) const;
+ bool Item_sum_hybrid_fix_length_and_dec(Item_sum_hybrid *func) const;
bool Item_sum_sum_fix_length_and_dec(Item_sum_sum *) const;
bool Item_sum_avg_fix_length_and_dec(Item_sum_avg *) const;
bool Item_sum_variance_fix_length_and_dec(Item_sum_variance *) const;
@@ -1874,7 +1870,7 @@ public:
Type_handler_hybrid_field_type *,
Type_all_attributes *atrr,
Item **items, uint nitems) const;
- bool Item_sum_min_max_fix_length_and_dec(Item_sum_min_max *func) const;
+ bool Item_sum_hybrid_fix_length_and_dec(Item_sum_hybrid *func) const;
bool Item_sum_sum_fix_length_and_dec(Item_sum_sum *) const;
bool Item_sum_avg_fix_length_and_dec(Item_sum_avg *) const;
bool Item_sum_variance_fix_length_and_dec(Item_sum_variance *) const;
@@ -2068,7 +2064,7 @@ public:
Type_handler_hybrid_field_type *,
Type_all_attributes *atrr,
Item **items, uint nitems) const;
- bool Item_sum_min_max_fix_length_and_dec(Item_sum_min_max *func) const;
+ bool Item_sum_hybrid_fix_length_and_dec(Item_sum_hybrid *func) const;
bool Item_sum_sum_fix_length_and_dec(Item_sum_sum *) const;
bool Item_sum_avg_fix_length_and_dec(Item_sum_avg *) const;
bool Item_sum_variance_fix_length_and_dec(Item_sum_variance *) const;
@@ -2145,7 +2141,7 @@ public:
const Item *outer) const;
bool Item_func_min_max_fix_attributes(THD *thd, Item_func_min_max *func,
Item **items, uint nitems) const;
- bool Item_sum_min_max_fix_length_and_dec(Item_sum_min_max *func) const;
+ bool Item_sum_hybrid_fix_length_and_dec(Item_sum_hybrid *func) const;
bool Item_sum_sum_fix_length_and_dec(Item_sum_sum *) const;
bool Item_sum_avg_fix_length_and_dec(Item_sum_avg *) const;
bool Item_sum_variance_fix_length_and_dec(Item_sum_variance *) const;
@@ -2258,7 +2254,7 @@ public:
Type_handler_hybrid_field_type *,
Type_all_attributes *atrr,
Item **items, uint nitems) const;
- bool Item_sum_min_max_fix_length_and_dec(Item_sum_min_max *func) const;
+ bool Item_sum_hybrid_fix_length_and_dec(Item_sum_hybrid *func) const;
bool Item_sum_sum_fix_length_and_dec(Item_sum_sum *) const;
bool Item_sum_avg_fix_length_and_dec(Item_sum_avg *) const;
bool Item_sum_variance_fix_length_and_dec(Item_sum_variance *) const;