mirror of
https://github.com/MariaDB/server.git
synced 2025-09-11 05:52:26 +03:00
A cleanup for MDEV-20273 Add class Item_sum_min_max
- removing duplicate code
Reusing the MIN()/MAX() fix_length_and_dec() related code for window functions - FIRST_VALUE() - LAST_VALUE() - NTH_VALUE() - LEAD() - LAG
This commit is contained in:
@@ -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()
|
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]->field_type() == args[0]->real_item()->field_type());
|
||||||
DBUG_ASSERT(args[0]->result_type() == args[0]->real_item()->result_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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -1044,6 +1044,9 @@ public:
|
|||||||
{ }
|
{ }
|
||||||
const Type_handler *type_handler() const
|
const Type_handler *type_handler() const
|
||||||
{ return Type_handler_hybrid_field_type::type_handler(); }
|
{ 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();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@@ -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]))
|
if (args[i]->fix_fields_if_needed_for_scalar(thd, &args[i]))
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
Type_std_attributes::set(args[0]);
|
|
||||||
for (uint i= 0; i < arg_count && !m_with_subquery; i++)
|
for (uint i= 0; i < arg_count && !m_with_subquery; i++)
|
||||||
m_with_subquery|= args[i]->with_subquery();
|
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);
|
|
||||||
|
|
||||||
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())
|
if (fix_length_and_dec())
|
||||||
return TRUE;
|
return true;
|
||||||
|
|
||||||
|
setup_hybrid(thd, args[0]);
|
||||||
|
result_field=0;
|
||||||
|
|
||||||
if (check_sum_func(thd, ref))
|
if (check_sum_func(thd, ref))
|
||||||
return TRUE;
|
return TRUE;
|
||||||
@@ -397,6 +373,14 @@ bool Item_sum_hybrid_simple::fix_fields(THD *thd, Item **ref)
|
|||||||
return FALSE;
|
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()
|
bool Item_sum_hybrid_simple::add()
|
||||||
{
|
{
|
||||||
value->store(args[0]);
|
value->store(args[0]);
|
||||||
|
@@ -307,6 +307,7 @@ class Item_sum_hybrid_simple : public Item_sum_hybrid
|
|||||||
|
|
||||||
bool add();
|
bool add();
|
||||||
bool fix_fields(THD *, Item **);
|
bool fix_fields(THD *, Item **);
|
||||||
|
bool fix_length_and_dec();
|
||||||
void setup_hybrid(THD *thd, Item *item);
|
void setup_hybrid(THD *thd, Item *item);
|
||||||
double val_real();
|
double val_real();
|
||||||
longlong val_int();
|
longlong val_int();
|
||||||
|
@@ -365,7 +365,7 @@ Type_handler::blob_type_handler(const Item *item)
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
This method is used by:
|
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
|
- Item_func_set_user_var
|
||||||
*/
|
*/
|
||||||
const Type_handler *
|
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::
|
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,
|
return func->fix_length_and_dec_numeric(&type_handler_longlong);
|
||||||
&type_handler_longlong);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Type_handler_real_result::
|
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,
|
(void) func->fix_length_and_dec_numeric(&type_handler_double);
|
||||||
&type_handler_double);
|
|
||||||
func->max_length= func->float_length(func->decimals);
|
func->max_length= func->float_length(func->decimals);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Type_handler_decimal_result::
|
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,
|
return func->fix_length_and_dec_numeric(&type_handler_newdecimal);
|
||||||
&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::
|
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];
|
return func->fix_length_and_dec_string();
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -3164,13 +3110,9 @@ bool Type_handler_string_result::
|
|||||||
Traditional temporal types always preserve the type of the argument.
|
Traditional temporal types always preserve the type of the argument.
|
||||||
*/
|
*/
|
||||||
bool Type_handler_temporal_result::
|
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];
|
return func->fix_length_and_dec_generic();
|
||||||
func->Type_std_attributes::set(item);
|
|
||||||
func->maybe_null= func->null_value= true;
|
|
||||||
func->set_handler(item->type_handler());
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -33,7 +33,7 @@ class Item;
|
|||||||
class Item_param;
|
class Item_param;
|
||||||
class Item_cache;
|
class Item_cache;
|
||||||
class Item_func_or_sum;
|
class Item_func_or_sum;
|
||||||
class Item_sum_min_max;
|
class Item_sum_hybrid;
|
||||||
class Item_sum_sum;
|
class Item_sum_sum;
|
||||||
class Item_sum_avg;
|
class Item_sum_avg;
|
||||||
class Item_sum_variance;
|
class Item_sum_variance;
|
||||||
@@ -1314,7 +1314,7 @@ public:
|
|||||||
Item_func_min_max *func,
|
Item_func_min_max *func,
|
||||||
Item **items,
|
Item **items,
|
||||||
uint nitems) const;
|
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_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 bool Item_sum_avg_fix_length_and_dec(Item_sum_avg *) const= 0;
|
||||||
virtual
|
virtual
|
||||||
@@ -1563,7 +1563,7 @@ public:
|
|||||||
DBUG_ASSERT(0);
|
DBUG_ASSERT(0);
|
||||||
return true;
|
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);
|
DBUG_ASSERT(0);
|
||||||
return true;
|
return true;
|
||||||
@@ -1742,10 +1742,6 @@ public:
|
|||||||
*/
|
*/
|
||||||
class Type_handler_numeric: public Type_handler
|
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:
|
public:
|
||||||
String *print_item_value(THD *thd, Item *item, String *str) const;
|
String *print_item_value(THD *thd, Item *item, String *str) const;
|
||||||
double Item_func_min_max_val_real(Item_func_min_max *) const;
|
double Item_func_min_max_val_real(Item_func_min_max *) const;
|
||||||
@@ -1796,7 +1792,7 @@ public:
|
|||||||
Item **items, uint nitems) const;
|
Item **items, uint nitems) const;
|
||||||
bool Item_func_min_max_fix_attributes(THD *thd, Item_func_min_max *func,
|
bool Item_func_min_max_fix_attributes(THD *thd, Item_func_min_max *func,
|
||||||
Item **items, uint nitems) const;
|
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_sum_fix_length_and_dec(Item_sum_sum *) const;
|
||||||
bool Item_sum_avg_fix_length_and_dec(Item_sum_avg *) 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;
|
bool Item_sum_variance_fix_length_and_dec(Item_sum_variance *) const;
|
||||||
@@ -1874,7 +1870,7 @@ public:
|
|||||||
Type_handler_hybrid_field_type *,
|
Type_handler_hybrid_field_type *,
|
||||||
Type_all_attributes *atrr,
|
Type_all_attributes *atrr,
|
||||||
Item **items, uint nitems) const;
|
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_sum_fix_length_and_dec(Item_sum_sum *) const;
|
||||||
bool Item_sum_avg_fix_length_and_dec(Item_sum_avg *) 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;
|
bool Item_sum_variance_fix_length_and_dec(Item_sum_variance *) const;
|
||||||
@@ -2068,7 +2064,7 @@ public:
|
|||||||
Type_handler_hybrid_field_type *,
|
Type_handler_hybrid_field_type *,
|
||||||
Type_all_attributes *atrr,
|
Type_all_attributes *atrr,
|
||||||
Item **items, uint nitems) const;
|
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_sum_fix_length_and_dec(Item_sum_sum *) const;
|
||||||
bool Item_sum_avg_fix_length_and_dec(Item_sum_avg *) 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;
|
bool Item_sum_variance_fix_length_and_dec(Item_sum_variance *) const;
|
||||||
@@ -2145,7 +2141,7 @@ public:
|
|||||||
const Item *outer) const;
|
const Item *outer) const;
|
||||||
bool Item_func_min_max_fix_attributes(THD *thd, Item_func_min_max *func,
|
bool Item_func_min_max_fix_attributes(THD *thd, Item_func_min_max *func,
|
||||||
Item **items, uint nitems) const;
|
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_sum_fix_length_and_dec(Item_sum_sum *) const;
|
||||||
bool Item_sum_avg_fix_length_and_dec(Item_sum_avg *) 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;
|
bool Item_sum_variance_fix_length_and_dec(Item_sum_variance *) const;
|
||||||
@@ -2258,7 +2254,7 @@ public:
|
|||||||
Type_handler_hybrid_field_type *,
|
Type_handler_hybrid_field_type *,
|
||||||
Type_all_attributes *atrr,
|
Type_all_attributes *atrr,
|
||||||
Item **items, uint nitems) const;
|
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_sum_fix_length_and_dec(Item_sum_sum *) const;
|
||||||
bool Item_sum_avg_fix_length_and_dec(Item_sum_avg *) 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;
|
bool Item_sum_variance_fix_length_and_dec(Item_sum_variance *) const;
|
||||||
|
Reference in New Issue
Block a user