Commit e978efd9 authored by Alexander Barkov's avatar Alexander Barkov

MDEV-20273 Add class Item_sum_min_max

parent a8def12e
......@@ -654,7 +654,7 @@ class Item_func_trig_cond: public Item_bool_func
class Item_func_not_all :public Item_func_not
{
/* allow to check presence of values in max/min optimization */
Item_sum_hybrid *test_sum_item;
Item_sum_min_max *test_sum_item;
Item_maxmin_subselect *test_sub_item;
public:
......@@ -670,7 +670,7 @@ class Item_func_not_all :public Item_func_not
bool fix_fields(THD *thd, Item **ref)
{return Item_func::fix_fields(thd, ref);}
virtual void print(String *str, enum_query_type query_type);
void set_sum_test(Item_sum_hybrid *item) { test_sum_item= item; test_sub_item= 0; };
void set_sum_test(Item_sum_min_max *item) { test_sum_item= item; test_sub_item= 0; };
void set_sub_test(Item_maxmin_subselect *item) { test_sub_item= item; test_sum_item= 0;};
bool empty_underlying_subquery();
Item *neg_transformer(THD *thd);
......
......@@ -1966,7 +1966,7 @@ bool Item_allany_subselect::transform_into_max_min(JOIN *join)
(!select_lex->ref_pointer_array[0]->maybe_null || /*4*/
substype() != Item_subselect::ALL_SUBS)) /*4*/
{
Item_sum_hybrid *item;
Item_sum_min_max *item;
nesting_map save_allow_sum_func;
if (func->l_op())
{
......
......@@ -1152,9 +1152,9 @@ Item_sum_num::fix_fields(THD *thd, Item **ref)
bool
Item_sum_hybrid::fix_fields(THD *thd, Item **ref)
Item_sum_min_max::fix_fields(THD *thd, Item **ref)
{
DBUG_ENTER("Item_sum_hybrid::fix_fields");
DBUG_ENTER("Item_sum_min_max::fix_fields");
DBUG_ASSERT(fixed == 0);
if (init_sum_func_check(thd))
......@@ -1184,11 +1184,11 @@ Item_sum_hybrid::fix_fields(THD *thd, Item **ref)
}
bool Item_sum_hybrid::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]->result_type() == args[0]->real_item()->result_type());
return args[0]->type_handler()->Item_sum_hybrid_fix_length_and_dec(this);
return args[0]->type_handler()->Item_sum_min_max_fix_length_and_dec(this);
}
......@@ -1209,9 +1209,9 @@ bool Item_sum_hybrid::fix_length_and_dec()
and Item_sum_min::add() to use different values!
*/
void Item_sum_hybrid::setup_hybrid(THD *thd, Item *item, Item *value_arg)
void Item_sum_min_max::setup_hybrid(THD *thd, Item *item, Item *value_arg)
{
DBUG_ENTER("Item_sum_hybrid::setup_hybrid");
DBUG_ENTER("Item_sum_min_max::setup_hybrid");
if (!(value= item->get_cache(thd)))
DBUG_VOID_RETURN;
value->setup(thd, item);
......@@ -1232,9 +1232,9 @@ void Item_sum_hybrid::setup_hybrid(THD *thd, Item *item, Item *value_arg)
}
Field *Item_sum_hybrid::create_tmp_field(bool group, TABLE *table)
Field *Item_sum_min_max::create_tmp_field(bool group, TABLE *table)
{
DBUG_ENTER("Item_sum_hybrid::create_tmp_field");
DBUG_ENTER("Item_sum_min_max::create_tmp_field");
if (args[0]->type() == Item::FIELD_ITEM)
{
......@@ -2314,9 +2314,9 @@ Item *Item_sum_variance::result_item(THD *thd, Field *field)
/* min & max */
void Item_sum_hybrid::clear()
void Item_sum_min_max::clear()
{
DBUG_ENTER("Item_sum_hybrid::clear");
DBUG_ENTER("Item_sum_min_max::clear");
value->clear();
null_value= 1;
DBUG_VOID_RETURN;
......@@ -2324,7 +2324,7 @@ void Item_sum_hybrid::clear()
bool
Item_sum_hybrid::get_date(MYSQL_TIME *ltime, ulonglong fuzzydate)
Item_sum_min_max::get_date(MYSQL_TIME *ltime, ulonglong fuzzydate)
{
DBUG_ASSERT(fixed == 1);
if (null_value)
......@@ -2336,9 +2336,9 @@ Item_sum_hybrid::get_date(MYSQL_TIME *ltime, ulonglong fuzzydate)
}
void Item_sum_hybrid::direct_add(Item *item)
void Item_sum_min_max::direct_add(Item *item)
{
DBUG_ENTER("Item_sum_hybrid::direct_add");
DBUG_ENTER("Item_sum_min_max::direct_add");
DBUG_PRINT("info", ("item: %p", item));
direct_added= TRUE;
direct_item= item;
......@@ -2346,9 +2346,9 @@ void Item_sum_hybrid::direct_add(Item *item)
}
double Item_sum_hybrid::val_real()
double Item_sum_min_max::val_real()
{
DBUG_ENTER("Item_sum_hybrid::val_real");
DBUG_ENTER("Item_sum_min_max::val_real");
DBUG_ASSERT(fixed == 1);
if (null_value)
DBUG_RETURN(0.0);
......@@ -2358,9 +2358,9 @@ double Item_sum_hybrid::val_real()
DBUG_RETURN(retval);
}
longlong Item_sum_hybrid::val_int()
longlong Item_sum_min_max::val_int()
{
DBUG_ENTER("Item_sum_hybrid::val_int");
DBUG_ENTER("Item_sum_min_max::val_int");
DBUG_ASSERT(fixed == 1);
if (null_value)
DBUG_RETURN(0);
......@@ -2371,9 +2371,9 @@ longlong Item_sum_hybrid::val_int()
}
my_decimal *Item_sum_hybrid::val_decimal(my_decimal *val)
my_decimal *Item_sum_min_max::val_decimal(my_decimal *val)
{
DBUG_ENTER("Item_sum_hybrid::val_decimal");
DBUG_ENTER("Item_sum_min_max::val_decimal");
DBUG_ASSERT(fixed == 1);
if (null_value)
DBUG_RETURN(0);
......@@ -2385,9 +2385,9 @@ my_decimal *Item_sum_hybrid::val_decimal(my_decimal *val)
String *
Item_sum_hybrid::val_str(String *str)
Item_sum_min_max::val_str(String *str)
{
DBUG_ENTER("Item_sum_hybrid::val_str");
DBUG_ENTER("Item_sum_min_max::val_str");
DBUG_ASSERT(fixed == 1);
if (null_value)
DBUG_RETURN(0);
......@@ -2398,9 +2398,9 @@ Item_sum_hybrid::val_str(String *str)
}
void Item_sum_hybrid::cleanup()
void Item_sum_min_max::cleanup()
{
DBUG_ENTER("Item_sum_hybrid::cleanup");
DBUG_ENTER("Item_sum_min_max::cleanup");
Item_sum::cleanup();
if (cmp)
delete cmp;
......@@ -2416,9 +2416,9 @@ void Item_sum_hybrid::cleanup()
DBUG_VOID_RETURN;
}
void Item_sum_hybrid::no_rows_in_result()
void Item_sum_min_max::no_rows_in_result()
{
DBUG_ENTER("Item_sum_hybrid::no_rows_in_result");
DBUG_ENTER("Item_sum_min_max::no_rows_in_result");
/* We may be called here twice in case of ref field in function */
if (was_values)
{
......@@ -2429,7 +2429,7 @@ void Item_sum_hybrid::no_rows_in_result()
DBUG_VOID_RETURN;
}
void Item_sum_hybrid::restore_to_before_no_rows_in_result()
void Item_sum_min_max::restore_to_before_no_rows_in_result()
{
if (!was_values)
{
......@@ -2693,10 +2693,10 @@ void Item_sum_num::reset_field()
}
void Item_sum_hybrid::reset_field()
void Item_sum_min_max::reset_field()
{
Item *UNINIT_VAR(tmp_item), *arg0;
DBUG_ENTER("Item_sum_hybrid::reset_field");
DBUG_ENTER("Item_sum_min_max::reset_field");
arg0= args[0];
if (unlikely(direct_added))
......@@ -3049,9 +3049,9 @@ Item *Item_sum_avg::result_item(THD *thd, Field *field)
}
void Item_sum_hybrid::update_field()
void Item_sum_min_max::update_field()
{
DBUG_ENTER("Item_sum_hybrid::update_field");
DBUG_ENTER("Item_sum_min_max::update_field");
Item *UNINIT_VAR(tmp_item);
if (unlikely(direct_added))
{
......@@ -3081,9 +3081,9 @@ void Item_sum_hybrid::update_field()
void
Item_sum_hybrid::min_max_update_str_field()
Item_sum_min_max::min_max_update_str_field()
{
DBUG_ENTER("Item_sum_hybrid::min_max_update_str_field");
DBUG_ENTER("Item_sum_min_max::min_max_update_str_field");
DBUG_ASSERT(cmp);
String *res_str=args[0]->val_str(&cmp->value1);
......@@ -3104,11 +3104,11 @@ Item_sum_hybrid::min_max_update_str_field()
void
Item_sum_hybrid::min_max_update_real_field()
Item_sum_min_max::min_max_update_real_field()
{
double nr,old_nr;
DBUG_ENTER("Item_sum_hybrid::min_max_update_real_field");
DBUG_ENTER("Item_sum_min_max::min_max_update_real_field");
old_nr=result_field->val_real();
nr= args[0]->val_real();
if (!args[0]->null_value)
......@@ -3126,11 +3126,11 @@ Item_sum_hybrid::min_max_update_real_field()
void
Item_sum_hybrid::min_max_update_int_field()
Item_sum_min_max::min_max_update_int_field()
{
longlong nr,old_nr;
DBUG_ENTER("Item_sum_hybrid::min_max_update_int_field");
DBUG_ENTER("Item_sum_min_max::min_max_update_int_field");
old_nr=result_field->val_int();
nr=args[0]->val_int();
if (!args[0]->null_value)
......@@ -3161,9 +3161,9 @@ Item_sum_hybrid::min_max_update_int_field()
optimize: do not get result_field in case of args[0] is NULL
*/
void
Item_sum_hybrid::min_max_update_decimal_field()
Item_sum_min_max::min_max_update_decimal_field()
{
DBUG_ENTER("Item_sum_hybrid::min_max_update_decimal_field");
DBUG_ENTER("Item_sum_min_max::min_max_update_decimal_field");
my_decimal old_val, nr_val;
const my_decimal *old_nr;
const my_decimal *nr= args[0]->val_decimal(&nr_val);
......
......@@ -1025,10 +1025,32 @@ class Item_sum_std :public Item_sum_variance
{ return get_item_copy<Item_sum_std>(thd, this); }
};
class Item_sum_hybrid: public Item_sum,
public Type_handler_hybrid_field_type
{
public:
Item_sum_hybrid(THD *thd, Item *item_par):
Item_sum(thd, item_par),
Type_handler_hybrid_field_type(&type_handler_longlong)
{ collation.set(&my_charset_bin); }
Item_sum_hybrid(THD *thd, Item *a, Item *b):
Item_sum(thd, a, b),
Type_handler_hybrid_field_type(&type_handler_longlong)
{ collation.set(&my_charset_bin); }
Item_sum_hybrid(THD *thd, Item_sum_hybrid *item)
:Item_sum(thd, item),
Type_handler_hybrid_field_type(item)
{ }
const Type_handler *type_handler() const
{ return Type_handler_hybrid_field_type::type_handler(); }
};
// This class is a string or number function depending on num_func
class Arg_comparator;
class Item_cache;
class Item_sum_hybrid :public Item_sum, public Type_handler_hybrid_field_type
class Item_sum_min_max :public Item_sum_hybrid
{
protected:
bool direct_added;
......@@ -1039,16 +1061,14 @@ class Item_sum_hybrid :public Item_sum, public Type_handler_hybrid_field_type
bool was_values; // Set if we have found at least one row (for max/min only)
bool was_null_value;
public:
Item_sum_hybrid(THD *thd, Item *item_par,int sign):
Item_sum(thd, item_par),
Type_handler_hybrid_field_type(&type_handler_longlong),
public:
Item_sum_min_max(THD *thd, Item *item_par,int sign):
Item_sum_hybrid(thd, item_par),
direct_added(FALSE), value(0), arg_cache(0), cmp(0),
cmp_sign(sign), was_values(TRUE)
{ collation.set(&my_charset_bin); }
Item_sum_hybrid(THD *thd, Item_sum_hybrid *item)
:Item_sum(thd, item),
Type_handler_hybrid_field_type(item),
Item_sum_min_max(THD *thd, Item_sum_min_max *item)
:Item_sum_hybrid(thd, item),
direct_added(FALSE), value(item->value), arg_cache(0),
cmp_sign(item->cmp_sign), was_values(item->was_values)
{ }
......@@ -1067,8 +1087,6 @@ class Item_sum_hybrid :public Item_sum, public Type_handler_hybrid_field_type
{
return get_arg(0)->real_type_handler();
}
const Type_handler *type_handler() const
{ return Type_handler_hybrid_field_type::type_handler(); }
TYPELIB *get_typelib() const { return args[0]->get_typelib(); }
void update_field();
void min_max_update_str_field();
......@@ -1084,11 +1102,11 @@ class Item_sum_hybrid :public Item_sum, public Type_handler_hybrid_field_type
};
class Item_sum_min :public Item_sum_hybrid
class Item_sum_min :public Item_sum_min_max
{
public:
Item_sum_min(THD *thd, Item *item_par): Item_sum_hybrid(thd, item_par, 1) {}
Item_sum_min(THD *thd, Item_sum_min *item) :Item_sum_hybrid(thd, item) {}
Item_sum_min(THD *thd, Item *item_par): Item_sum_min_max(thd, item_par, 1) {}
Item_sum_min(THD *thd, Item_sum_min *item) :Item_sum_min_max(thd, item) {}
enum Sumfunctype sum_func () const {return MIN_FUNC;}
bool add();
......@@ -1099,11 +1117,11 @@ class Item_sum_min :public Item_sum_hybrid
};
class Item_sum_max :public Item_sum_hybrid
class Item_sum_max :public Item_sum_min_max
{
public:
Item_sum_max(THD *thd, Item *item_par): Item_sum_hybrid(thd, item_par, -1) {}
Item_sum_max(THD *thd, Item_sum_max *item) :Item_sum_hybrid(thd, item) {}
Item_sum_max(THD *thd, Item *item_par): Item_sum_min_max(thd, item_par, -1) {}
Item_sum_max(THD *thd, Item_sum_max *item) :Item_sum_min_max(thd, item) {}
enum Sumfunctype sum_func () const {return MAX_FUNC;}
bool add();
......
......@@ -292,21 +292,18 @@ class Item_sum_dense_rank: public Item_sum_int
{ return get_item_copy<Item_sum_dense_rank>(thd, this); }
};
class Item_sum_hybrid_simple : public Item_sum,
public Type_handler_hybrid_field_type
class Item_sum_hybrid_simple : public Item_sum_hybrid
{
public:
Item_sum_hybrid_simple(THD *thd, Item *arg):
Item_sum(thd, arg),
Type_handler_hybrid_field_type(&type_handler_longlong),
Item_sum_hybrid(thd, arg),
value(NULL)
{ collation.set(&my_charset_bin); }
{ }
Item_sum_hybrid_simple(THD *thd, Item *arg1, Item *arg2):
Item_sum(thd, arg1, arg2),
Type_handler_hybrid_field_type(&type_handler_longlong),
Item_sum_hybrid(thd, arg1, arg2),
value(NULL)
{ collation.set(&my_charset_bin); }
{ }
bool add();
bool fix_fields(THD *, Item **);
......@@ -317,8 +314,6 @@ class Item_sum_hybrid_simple : public Item_sum,
void reset_field();
String *val_str(String *);
bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate);
const Type_handler *type_handler() const
{ return Type_handler_hybrid_field_type::type_handler(); }
void update_field();
Field *create_tmp_field(bool group, TABLE *table);
void clear()
......
......@@ -365,7 +365,7 @@ Type_handler::blob_type_handler(const Item *item)
/**
This method is used by:
- Item_sum_hybrid, e.g. MAX(item), MIN(item).
- Item_sum_min_max, e.g. MAX(item), MIN(item).
- Item_func_set_user_var
*/
const Type_handler *
......@@ -3086,9 +3086,9 @@ bool Type_handler_real_result::
QQ: Items should probably be fixed to preserve the exact type.
*/
bool Type_handler_numeric::
Item_sum_hybrid_fix_length_and_dec_numeric(Item_sum_hybrid *func,
const Type_handler *handler)
const
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();
......@@ -3104,28 +3104,28 @@ bool Type_handler_numeric::
bool Type_handler_int_result::
Item_sum_hybrid_fix_length_and_dec(Item_sum_hybrid *func) const
Item_sum_min_max_fix_length_and_dec(Item_sum_min_max *func) const
{
return Item_sum_hybrid_fix_length_and_dec_numeric(func,
&type_handler_longlong);
return Item_sum_min_max_fix_length_and_dec_numeric(func,
&type_handler_longlong);
}
bool Type_handler_real_result::
Item_sum_hybrid_fix_length_and_dec(Item_sum_hybrid *func) const
Item_sum_min_max_fix_length_and_dec(Item_sum_min_max *func) const
{
(void) Item_sum_hybrid_fix_length_and_dec_numeric(func,
&type_handler_double);
(void) Item_sum_min_max_fix_length_and_dec_numeric(func,
&type_handler_double);
func->max_length= func->float_length(func->decimals);
return false;
}
bool Type_handler_decimal_result::
Item_sum_hybrid_fix_length_and_dec(Item_sum_hybrid *func) const
Item_sum_min_max_fix_length_and_dec(Item_sum_min_max *func) const
{
return Item_sum_hybrid_fix_length_and_dec_numeric(func,
&type_handler_newdecimal);
return Item_sum_min_max_fix_length_and_dec_numeric(func,
&type_handler_newdecimal);
}
......@@ -3138,7 +3138,7 @@ bool Type_handler_decimal_result::
MAX(str_item) chooses the best suitable string type.
*/
bool Type_handler_string_result::
Item_sum_hybrid_fix_length_and_dec(Item_sum_hybrid *func) const
Item_sum_min_max_fix_length_and_dec(Item_sum_min_max *func) const
{
Item *item= func->arguments()[0];
Item *item2= item->real_item();
......@@ -3164,7 +3164,7 @@ bool Type_handler_string_result::
Traditional temporal types always preserve the type of the argument.
*/
bool Type_handler_temporal_result::
Item_sum_hybrid_fix_length_and_dec(Item_sum_hybrid *func) const
Item_sum_min_max_fix_length_and_dec(Item_sum_min_max *func) const
{
Item *item= func->arguments()[0];
func->Type_std_attributes::set(item);
......
......@@ -33,7 +33,7 @@ class Item;
class Item_param;
class Item_cache;
class Item_func_or_sum;
class Item_sum_hybrid;
class Item_sum_min_max;
class Item_sum_sum;
class Item_sum_avg;
class Item_sum_variance;
......@@ -1314,7 +1314,7 @@ class Type_handler
Item_func_min_max *func,
Item **items,
uint nitems) const;
virtual bool Item_sum_hybrid_fix_length_and_dec(Item_sum_hybrid *) const= 0;
virtual bool Item_sum_min_max_fix_length_and_dec(Item_sum_min_max *) 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 @@ class Type_handler_row: public Type_handler
DBUG_ASSERT(0);
return true;
}
bool Item_sum_hybrid_fix_length_and_dec(Item_sum_hybrid *func) const
bool Item_sum_min_max_fix_length_and_dec(Item_sum_min_max *func) const
{
DBUG_ASSERT(0);
return true;
......@@ -1743,9 +1743,9 @@ class Type_handler_row: public Type_handler
class Type_handler_numeric: public Type_handler
{
protected:
bool Item_sum_hybrid_fix_length_and_dec_numeric(Item_sum_hybrid *func,
const Type_handler *handler)
const;
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 +1796,7 @@ class Type_handler_real_result: public Type_handler_numeric
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_hybrid_fix_length_and_dec(Item_sum_hybrid *func) const;
bool Item_sum_min_max_fix_length_and_dec(Item_sum_min_max *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 +1874,7 @@ class Type_handler_decimal_result: public Type_handler_numeric
Type_handler_hybrid_field_type *,
Type_all_attributes *atrr,
Item **items, uint nitems) const;
bool Item_sum_hybrid_fix_length_and_dec(Item_sum_hybrid *func) const;
bool Item_sum_min_max_fix_length_and_dec(Item_sum_min_max *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 +2068,7 @@ class Type_handler_int_result: public Type_handler_numeric
Type_handler_hybrid_field_type *,
Type_all_attributes *atrr,
Item **items, uint nitems) const;
bool Item_sum_hybrid_fix_length_and_dec(Item_sum_hybrid *func) const;
bool Item_sum_min_max_fix_length_and_dec(Item_sum_min_max *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 +2145,7 @@ class Type_handler_temporal_result: public Type_handler
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_hybrid_fix_length_and_dec(Item_sum_hybrid *func) const;
bool Item_sum_min_max_fix_length_and_dec(Item_sum_min_max *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 +2258,7 @@ class Type_handler_string_result: public Type_handler
Type_handler_hybrid_field_type *,
Type_all_attributes *atrr,
Item **items, uint nitems) const;
bool Item_sum_hybrid_fix_length_and_dec(Item_sum_hybrid *func) const;
bool Item_sum_min_max_fix_length_and_dec(Item_sum_min_max *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;
......
......@@ -2705,7 +2705,7 @@ int spider_db_fetch_for_item_sum_func(
thd->free_list = free_list;
}
Item_sum_hybrid *item_hybrid = (Item_sum_hybrid *) item_sum;
Item_sum_min_max *item_sum_min_max = (Item_sum_min_max *) item_sum;
Item_string *item =
(Item_string *) spider->direct_aggregate_item_current->item;
if (row->is_null())
......@@ -2732,7 +2732,7 @@ int spider_db_fetch_for_item_sum_func(
#endif
item->null_value = FALSE;
}
item_hybrid->direct_add(item);
item_sum_min_max->direct_add(item);
row->next();
}
break;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment