mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
MDEV-11615 Split Item_hybrid_func::fix_attributes into virtual methods in Type_handler
This commit is contained in:
@ -3108,12 +3108,11 @@ void Item_func_case::fix_length_and_dec()
|
||||
|
||||
set_handler_by_field_type(agg_field_type(agg, nagg, true));
|
||||
|
||||
if (Item_func_case::result_type() == STRING_RESULT)
|
||||
{
|
||||
if (count_string_result_length(Item_func_case::field_type(), agg, nagg))
|
||||
if (fix_attributes(agg, nagg))
|
||||
return;
|
||||
|
||||
/*
|
||||
Copy all THEN and ELSE items back to args[] array.
|
||||
Copy all modified THEN and ELSE items back to args[] array.
|
||||
Some of the items might have been changed to Item_func_conv_charset.
|
||||
*/
|
||||
for (nagg= 0 ; nagg < ncases / 2 ; nagg++)
|
||||
@ -3121,11 +3120,6 @@ void Item_func_case::fix_length_and_dec()
|
||||
|
||||
if (else_expr_num != -1)
|
||||
change_item_tree_if_needed(thd, &args[else_expr_num], agg[nagg++]);
|
||||
}
|
||||
else
|
||||
{
|
||||
fix_attributes(agg, nagg);
|
||||
}
|
||||
|
||||
/*
|
||||
Aggregate first expression and all WHEN expression types
|
||||
@ -3405,31 +3399,12 @@ my_decimal *Item_func_coalesce::decimal_op(my_decimal *decimal_value)
|
||||
}
|
||||
|
||||
|
||||
void Item_hybrid_func::fix_attributes(Item **items, uint nitems)
|
||||
bool Item_hybrid_func::fix_attributes(Item **items, uint nitems)
|
||||
{
|
||||
switch (Item_hybrid_func::result_type()) {
|
||||
case STRING_RESULT:
|
||||
if (count_string_result_length(Item_hybrid_func::field_type(),
|
||||
items, nitems))
|
||||
return;
|
||||
break;
|
||||
case DECIMAL_RESULT:
|
||||
collation.set_numeric();
|
||||
count_decimal_length(items, nitems);
|
||||
break;
|
||||
case REAL_RESULT:
|
||||
collation.set_numeric();
|
||||
count_real_length(items, nitems);
|
||||
break;
|
||||
case INT_RESULT:
|
||||
collation.set_numeric();
|
||||
count_only_length(items, nitems);
|
||||
decimals= 0;
|
||||
break;
|
||||
case ROW_RESULT:
|
||||
case TIME_RESULT:
|
||||
DBUG_ASSERT(0);
|
||||
}
|
||||
bool rc= Item_hybrid_func::type_handler()->
|
||||
Item_hybrid_func_fix_attributes(current_thd, this, items, nitems);
|
||||
DBUG_ASSERT(!rc || current_thd->is_error());
|
||||
return rc;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -567,30 +567,6 @@ void Item_udf_func::fix_num_length_and_dec()
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Count max_length and decimals for temporal functions.
|
||||
|
||||
@param item Argument array
|
||||
@param nitems Number of arguments in the array.
|
||||
|
||||
@retval False on success, true on error.
|
||||
*/
|
||||
void Item_func::count_datetime_length(enum_field_types field_type_arg,
|
||||
Item **item, uint nitems)
|
||||
{
|
||||
unsigned_flag= 0;
|
||||
decimals= 0;
|
||||
if (field_type_arg != MYSQL_TYPE_DATE)
|
||||
{
|
||||
for (uint i= 0; i < nitems; i++)
|
||||
set_if_bigger(decimals, item[i]->decimals);
|
||||
}
|
||||
set_if_smaller(decimals, TIME_SECOND_PART_DIGITS);
|
||||
uint len= decimals ? (decimals + 1) : 0;
|
||||
len+= mysql_temporal_int_part_length(field_type_arg);
|
||||
fix_char_length(len);
|
||||
}
|
||||
|
||||
/**
|
||||
Set max_length/decimals of function if function is fixed point and
|
||||
result length/precision depends on argument ones.
|
||||
@ -665,7 +641,7 @@ void Item_func::count_real_length(Item **items, uint nitems)
|
||||
|
||||
|
||||
/**
|
||||
Calculate max_length and decimals for STRING_RESULT functions.
|
||||
Calculate max_length and decimals for string functions.
|
||||
|
||||
@param field_type Field type.
|
||||
@param items Argument array.
|
||||
@ -673,18 +649,13 @@ void Item_func::count_real_length(Item **items, uint nitems)
|
||||
|
||||
@retval False on success, true on error.
|
||||
*/
|
||||
bool Item_func::count_string_result_length(enum_field_types field_type_arg,
|
||||
Item **items, uint nitems)
|
||||
bool Item_func::count_string_length(Item **items, uint nitems)
|
||||
{
|
||||
DBUG_ASSERT(!is_temporal_type(field_type()));
|
||||
if (agg_arg_charsets_for_string_result(collation, items, nitems, 1))
|
||||
return true;
|
||||
if (is_temporal_type(field_type_arg))
|
||||
count_datetime_length(field_type_arg, items, nitems);
|
||||
else
|
||||
{
|
||||
count_only_length(items, nitems);
|
||||
decimals= max_length ? NOT_FIXED_DEC : 0;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -45,11 +45,49 @@ protected:
|
||||
void count_only_length(Item **item, uint nitems);
|
||||
void count_real_length(Item **item, uint nitems);
|
||||
void count_decimal_length(Item **item, uint nitems);
|
||||
void count_datetime_length(enum_field_types field_type,
|
||||
Item **item, uint nitems);
|
||||
bool count_string_result_length(enum_field_types field_type,
|
||||
Item **item, uint nitems);
|
||||
bool count_string_length(Item **item, uint nitems);
|
||||
uint count_max_decimals(Item **item, uint nitems)
|
||||
{
|
||||
uint res= 0;
|
||||
for (uint i= 0; i < nitems; i++)
|
||||
set_if_bigger(res, item[i]->decimals);
|
||||
return res;
|
||||
}
|
||||
public:
|
||||
void aggregate_attributes_int(Item **items, uint nitems)
|
||||
{
|
||||
collation.set_numeric();
|
||||
count_only_length(items, nitems);
|
||||
decimals= 0;
|
||||
}
|
||||
void aggregate_attributes_real(Item **items, uint nitems)
|
||||
{
|
||||
collation.set_numeric();
|
||||
count_real_length(items, nitems);
|
||||
}
|
||||
void aggregate_attributes_decimal(Item **items, uint nitems)
|
||||
{
|
||||
collation.set_numeric();
|
||||
count_decimal_length(items, nitems);
|
||||
}
|
||||
bool aggregate_attributes_string(Item **item, uint nitems)
|
||||
{
|
||||
return count_string_length(item, nitems);
|
||||
}
|
||||
void set_attributes_temporal(uint int_part_length, uint dec)
|
||||
{
|
||||
collation.set_numeric();
|
||||
unsigned_flag= 0;
|
||||
decimals= MY_MIN(dec, TIME_SECOND_PART_DIGITS);
|
||||
uint length= decimals + int_part_length + (dec ? 1 : 0);
|
||||
fix_char_length(length);
|
||||
}
|
||||
void aggregate_attributes_temporal(uint int_part_length,
|
||||
Item **item, uint nitems)
|
||||
{
|
||||
set_attributes_temporal(int_part_length, count_max_decimals(item, nitems));
|
||||
}
|
||||
|
||||
table_map not_null_tables_cache;
|
||||
|
||||
enum Functype { UNKNOWN_FUNC,EQ_FUNC,EQUAL_FUNC,NE_FUNC,LT_FUNC,LE_FUNC,
|
||||
@ -389,7 +427,7 @@ class Item_hybrid_func: public Item_func,
|
||||
public Type_handler_hybrid_field_type
|
||||
{
|
||||
protected:
|
||||
void fix_attributes(Item **item, uint nitems);
|
||||
bool fix_attributes(Item **item, uint nitems);
|
||||
public:
|
||||
Item_hybrid_func(THD *thd): Item_func(thd) { }
|
||||
Item_hybrid_func(THD *thd, Item *a): Item_func(thd, a) { }
|
||||
|
@ -888,6 +888,79 @@ Type_handler_temporal_result::Item_get_cache(THD *thd, const Item *item) const
|
||||
return new (thd->mem_root) Item_cache_temporal(thd, item->field_type());
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
bool Type_handler_int_result::
|
||||
Item_hybrid_func_fix_attributes(THD *thd, Item_hybrid_func *func,
|
||||
Item **items, uint nitems) const
|
||||
{
|
||||
func->aggregate_attributes_int(items, nitems);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool Type_handler_real_result::
|
||||
Item_hybrid_func_fix_attributes(THD *thd, Item_hybrid_func *func,
|
||||
Item **items, uint nitems) const
|
||||
{
|
||||
func->aggregate_attributes_real(items, nitems);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool Type_handler_decimal_result::
|
||||
Item_hybrid_func_fix_attributes(THD *thd, Item_hybrid_func *func,
|
||||
Item **items, uint nitems) const
|
||||
{
|
||||
func->aggregate_attributes_decimal(items, nitems);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool Type_handler_string_result::
|
||||
Item_hybrid_func_fix_attributes(THD *thd, Item_hybrid_func *func,
|
||||
Item **items, uint nitems) const
|
||||
{
|
||||
return func->aggregate_attributes_string(items, nitems);
|
||||
}
|
||||
|
||||
|
||||
bool Type_handler_date_common::
|
||||
Item_hybrid_func_fix_attributes(THD *thd, Item_hybrid_func *func,
|
||||
Item **items, uint nitems) const
|
||||
{
|
||||
func->set_attributes_temporal(MAX_DATE_WIDTH, 0);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool Type_handler_time_common::
|
||||
Item_hybrid_func_fix_attributes(THD *thd, Item_hybrid_func *func,
|
||||
Item **items, uint nitems) const
|
||||
{
|
||||
func->aggregate_attributes_temporal(MIN_TIME_WIDTH, items, nitems);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool Type_handler_datetime_common::
|
||||
Item_hybrid_func_fix_attributes(THD *thd, Item_hybrid_func *func,
|
||||
Item **items, uint nitems) const
|
||||
{
|
||||
func->aggregate_attributes_temporal(MAX_DATETIME_WIDTH, items, nitems);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool Type_handler_timestamp_common::
|
||||
Item_hybrid_func_fix_attributes(THD *thd, Item_hybrid_func *func,
|
||||
Item **items, uint nitems) const
|
||||
{
|
||||
func->aggregate_attributes_temporal(MAX_DATETIME_WIDTH, items, nitems);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
/**
|
||||
|
@ -28,6 +28,7 @@ class Item;
|
||||
class Item_cache;
|
||||
class Item_sum_hybrid;
|
||||
class Item_func_hex;
|
||||
class Item_hybrid_func;
|
||||
class Item_func_hybrid_field_type;
|
||||
class Item_func_between;
|
||||
class Item_func_in;
|
||||
@ -298,6 +299,9 @@ public:
|
||||
bool no_conversions) const= 0;
|
||||
virtual Item_cache *Item_get_cache(THD *thd, const Item *item) const= 0;
|
||||
virtual bool set_comparator_func(Arg_comparator *cmp) const= 0;
|
||||
virtual bool Item_hybrid_func_fix_attributes(THD *thd, Item_hybrid_func *func,
|
||||
Item **items,
|
||||
uint nitems) const= 0;
|
||||
virtual bool Item_sum_hybrid_fix_length_and_dec(Item_sum_hybrid *) const= 0;
|
||||
virtual String *Item_func_hex_val_str_ascii(Item_func_hex *item,
|
||||
String *str) const= 0;
|
||||
@ -391,6 +395,12 @@ public:
|
||||
}
|
||||
Item_cache *Item_get_cache(THD *thd, const Item *item) const;
|
||||
bool set_comparator_func(Arg_comparator *cmp) const;
|
||||
bool Item_hybrid_func_fix_attributes(THD *thd, Item_hybrid_func *func,
|
||||
Item **items, uint nitems) const
|
||||
{
|
||||
DBUG_ASSERT(0);
|
||||
return true;
|
||||
}
|
||||
bool Item_sum_hybrid_fix_length_and_dec(Item_sum_hybrid *func) const
|
||||
{
|
||||
DBUG_ASSERT(0);
|
||||
@ -473,6 +483,8 @@ public:
|
||||
int Item_save_in_field(Item *item, Field *field, bool no_conversions) const;
|
||||
Item_cache *Item_get_cache(THD *thd, const Item *item) const;
|
||||
bool set_comparator_func(Arg_comparator *cmp) const;
|
||||
bool Item_hybrid_func_fix_attributes(THD *thd, Item_hybrid_func *func,
|
||||
Item **items, uint nitems) const;
|
||||
bool Item_sum_hybrid_fix_length_and_dec(Item_sum_hybrid *func) const;
|
||||
String *Item_func_hex_val_str_ascii(Item_func_hex *item, String *str) const;
|
||||
String *Item_func_hybrid_field_type_val_str(Item_func_hybrid_field_type *,
|
||||
@ -513,6 +525,8 @@ public:
|
||||
int Item_save_in_field(Item *item, Field *field, bool no_conversions) const;
|
||||
Item_cache *Item_get_cache(THD *thd, const Item *item) const;
|
||||
bool set_comparator_func(Arg_comparator *cmp) const;
|
||||
bool Item_hybrid_func_fix_attributes(THD *thd, Item_hybrid_func *func,
|
||||
Item **items, uint nitems) const;
|
||||
bool Item_sum_hybrid_fix_length_and_dec(Item_sum_hybrid *func) const;
|
||||
String *Item_func_hex_val_str_ascii(Item_func_hex *item, String *str) const;
|
||||
String *Item_func_hybrid_field_type_val_str(Item_func_hybrid_field_type *,
|
||||
@ -551,6 +565,8 @@ public:
|
||||
int Item_save_in_field(Item *item, Field *field, bool no_conversions) const;
|
||||
Item_cache *Item_get_cache(THD *thd, const Item *item) const;
|
||||
bool set_comparator_func(Arg_comparator *cmp) const;
|
||||
bool Item_hybrid_func_fix_attributes(THD *thd, Item_hybrid_func *func,
|
||||
Item **items, uint nitems) const;
|
||||
bool Item_sum_hybrid_fix_length_and_dec(Item_sum_hybrid *func) const;
|
||||
String *Item_func_hex_val_str_ascii(Item_func_hex *item, String *str) const;
|
||||
String *Item_func_hybrid_field_type_val_str(Item_func_hybrid_field_type *,
|
||||
@ -626,6 +642,8 @@ public:
|
||||
int Item_save_in_field(Item *item, Field *field, bool no_conversions) const;
|
||||
Item_cache *Item_get_cache(THD *thd, const Item *item) const;
|
||||
bool set_comparator_func(Arg_comparator *cmp) const;
|
||||
bool Item_hybrid_func_fix_attributes(THD *thd, Item_hybrid_func *func,
|
||||
Item **items, uint nitems) const;
|
||||
bool Item_sum_hybrid_fix_length_and_dec(Item_sum_hybrid *func) const;
|
||||
String *Item_func_hex_val_str_ascii(Item_func_hex *item, String *str) const;
|
||||
String *Item_func_hybrid_field_type_val_str(Item_func_hybrid_field_type *,
|
||||
@ -778,6 +796,8 @@ public:
|
||||
enum_field_types field_type() const { return MYSQL_TYPE_TIME; }
|
||||
const Type_handler *type_handler_for_comparison() const;
|
||||
int Item_save_in_field(Item *item, Field *field, bool no_conversions) const;
|
||||
bool Item_hybrid_func_fix_attributes(THD *thd, Item_hybrid_func *func,
|
||||
Item **items, uint nitems) const;
|
||||
cmp_item *make_cmp_item(THD *thd, CHARSET_INFO *cs) const;
|
||||
in_vector *make_in_vector(THD *, const Item_func_in *, uint nargs) const;
|
||||
};
|
||||
@ -813,62 +833,85 @@ public:
|
||||
};
|
||||
|
||||
|
||||
class Type_handler_date: public Type_handler_temporal_with_date
|
||||
class Type_handler_date_common: public Type_handler_temporal_with_date
|
||||
{
|
||||
public:
|
||||
virtual ~Type_handler_date_common() {}
|
||||
enum_field_types field_type() const { return MYSQL_TYPE_DATE; }
|
||||
bool Item_hybrid_func_fix_attributes(THD *thd, Item_hybrid_func *func,
|
||||
Item **items, uint nitems) const;
|
||||
};
|
||||
|
||||
class Type_handler_date: public Type_handler_date_common
|
||||
{
|
||||
public:
|
||||
virtual ~Type_handler_date() {}
|
||||
enum_field_types field_type() const { return MYSQL_TYPE_DATE; }
|
||||
Field *make_conversion_table_field(TABLE *, uint metadata,
|
||||
const Field *target) const;
|
||||
};
|
||||
|
||||
|
||||
class Type_handler_newdate: public Type_handler_temporal_with_date
|
||||
class Type_handler_newdate: public Type_handler_date_common
|
||||
{
|
||||
public:
|
||||
virtual ~Type_handler_newdate() {}
|
||||
enum_field_types field_type() const { return MYSQL_TYPE_DATE; }
|
||||
Field *make_conversion_table_field(TABLE *, uint metadata,
|
||||
const Field *target) const;
|
||||
};
|
||||
|
||||
|
||||
class Type_handler_datetime: public Type_handler_temporal_with_date
|
||||
class Type_handler_datetime_common: public Type_handler_temporal_with_date
|
||||
{
|
||||
public:
|
||||
virtual ~Type_handler_datetime_common() {}
|
||||
enum_field_types field_type() const { return MYSQL_TYPE_DATETIME; }
|
||||
bool Item_hybrid_func_fix_attributes(THD *thd, Item_hybrid_func *func,
|
||||
Item **items, uint nitems) const;
|
||||
};
|
||||
|
||||
|
||||
class Type_handler_datetime: public Type_handler_datetime_common
|
||||
{
|
||||
public:
|
||||
virtual ~Type_handler_datetime() {}
|
||||
enum_field_types field_type() const { return MYSQL_TYPE_DATETIME; }
|
||||
Field *make_conversion_table_field(TABLE *, uint metadata,
|
||||
const Field *target) const;
|
||||
};
|
||||
|
||||
|
||||
class Type_handler_datetime2: public Type_handler_temporal_with_date
|
||||
class Type_handler_datetime2: public Type_handler_datetime_common
|
||||
{
|
||||
public:
|
||||
virtual ~Type_handler_datetime2() {}
|
||||
enum_field_types field_type() const { return MYSQL_TYPE_DATETIME; }
|
||||
enum_field_types real_field_type() const { return MYSQL_TYPE_DATETIME2; }
|
||||
Field *make_conversion_table_field(TABLE *, uint metadata,
|
||||
const Field *target) const;
|
||||
};
|
||||
|
||||
|
||||
class Type_handler_timestamp: public Type_handler_temporal_with_date
|
||||
class Type_handler_timestamp_common: public Type_handler_temporal_with_date
|
||||
{
|
||||
public:
|
||||
virtual ~Type_handler_timestamp_common() {}
|
||||
enum_field_types field_type() const { return MYSQL_TYPE_TIMESTAMP; }
|
||||
bool Item_hybrid_func_fix_attributes(THD *thd, Item_hybrid_func *func,
|
||||
Item **items, uint nitems) const;
|
||||
};
|
||||
|
||||
|
||||
class Type_handler_timestamp: public Type_handler_timestamp_common
|
||||
{
|
||||
public:
|
||||
virtual ~Type_handler_timestamp() {}
|
||||
enum_field_types field_type() const { return MYSQL_TYPE_TIMESTAMP; }
|
||||
Field *make_conversion_table_field(TABLE *, uint metadata,
|
||||
const Field *target) const;
|
||||
};
|
||||
|
||||
|
||||
class Type_handler_timestamp2: public Type_handler_temporal_with_date
|
||||
class Type_handler_timestamp2: public Type_handler_timestamp_common
|
||||
{
|
||||
public:
|
||||
virtual ~Type_handler_timestamp2() {}
|
||||
enum_field_types field_type() const { return MYSQL_TYPE_TIMESTAMP; }
|
||||
enum_field_types real_field_type() const { return MYSQL_TYPE_TIMESTAMP2; }
|
||||
Field *make_conversion_table_field(TABLE *, uint metadata,
|
||||
const Field *target) const;
|
||||
|
Reference in New Issue
Block a user