mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
MDEV-12655 Move Item_func::count_xxx_length() to Type_std_attributes
This commit is contained in:
@ -2355,7 +2355,7 @@ void my_coll_agg_error(Item** args, uint count, const char *fname,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Item_func_or_sum::agg_item_collations(DTCollation &c, const char *fname,
|
bool Type_std_attributes::agg_item_collations(DTCollation &c, const char *fname,
|
||||||
Item **av, uint count,
|
Item **av, uint count,
|
||||||
uint flags, int item_sep)
|
uint flags, int item_sep)
|
||||||
{
|
{
|
||||||
@ -2402,7 +2402,7 @@ bool Item_func_or_sum::agg_item_collations(DTCollation &c, const char *fname,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Item_func_or_sum::agg_item_set_converter(const DTCollation &coll,
|
bool Type_std_attributes::agg_item_set_converter(const DTCollation &coll,
|
||||||
const char *fname,
|
const char *fname,
|
||||||
Item **args, uint nargs,
|
Item **args, uint nargs,
|
||||||
uint flags, int item_sep)
|
uint flags, int item_sep)
|
||||||
|
74
sql/item.h
74
sql/item.h
@ -4059,80 +4059,31 @@ class Item_func_or_sum: public Item_result_field,
|
|||||||
public Item_args,
|
public Item_args,
|
||||||
public Used_tables_and_const_cache
|
public Used_tables_and_const_cache
|
||||||
{
|
{
|
||||||
bool agg_item_collations(DTCollation &c, const char *name,
|
|
||||||
Item **items, uint nitems,
|
|
||||||
uint flags, int item_sep);
|
|
||||||
bool agg_item_set_converter(const DTCollation &coll, const char *fname,
|
|
||||||
Item **args, uint nargs,
|
|
||||||
uint flags, int item_sep);
|
|
||||||
protected:
|
protected:
|
||||||
/*
|
|
||||||
Collect arguments' character sets together.
|
|
||||||
We allow to apply automatic character set conversion in some cases.
|
|
||||||
The conditions when conversion is possible are:
|
|
||||||
- arguments A and B have different charsets
|
|
||||||
- A wins according to coercibility rules
|
|
||||||
(i.e. a column is stronger than a string constant,
|
|
||||||
an explicit COLLATE clause is stronger than a column)
|
|
||||||
- character set of A is either superset for character set of B,
|
|
||||||
or B is a string constant which can be converted into the
|
|
||||||
character set of A without data loss.
|
|
||||||
|
|
||||||
If all of the above is true, then it's possible to convert
|
|
||||||
B into the character set of A, and then compare according
|
|
||||||
to the collation of A.
|
|
||||||
|
|
||||||
For functions with more than two arguments:
|
|
||||||
|
|
||||||
collect(A,B,C) ::= collect(collect(A,B),C)
|
|
||||||
|
|
||||||
Since this function calls THD::change_item_tree() on the passed Item **
|
|
||||||
pointers, it is necessary to pass the original Item **'s, not copies.
|
|
||||||
Otherwise their values will not be properly restored (see BUG#20769).
|
|
||||||
If the items are not consecutive (eg. args[2] and args[5]), use the
|
|
||||||
item_sep argument, ie.
|
|
||||||
|
|
||||||
agg_item_charsets(coll, fname, &args[2], 2, flags, 3)
|
|
||||||
*/
|
|
||||||
bool agg_arg_charsets(DTCollation &c, Item **items, uint nitems,
|
bool agg_arg_charsets(DTCollation &c, Item **items, uint nitems,
|
||||||
uint flags, int item_sep)
|
uint flags, int item_sep)
|
||||||
{
|
{
|
||||||
if (agg_item_collations(c, func_name(), items, nitems, flags, item_sep))
|
return Type_std_attributes::agg_arg_charsets(c, func_name(),
|
||||||
return true;
|
items, nitems,
|
||||||
|
|
||||||
return agg_item_set_converter(c, func_name(), items, nitems,
|
|
||||||
flags, item_sep);
|
flags, item_sep);
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
Aggregate arguments for string result, e.g: CONCAT(a,b)
|
|
||||||
- convert to @@character_set_connection if all arguments are numbers
|
|
||||||
- allow DERIVATION_NONE
|
|
||||||
*/
|
|
||||||
bool agg_arg_charsets_for_string_result(DTCollation &c,
|
bool agg_arg_charsets_for_string_result(DTCollation &c,
|
||||||
Item **items, uint nitems,
|
Item **items, uint nitems,
|
||||||
int item_sep= 1)
|
int item_sep= 1)
|
||||||
{
|
{
|
||||||
uint flags= MY_COLL_ALLOW_SUPERSET_CONV |
|
return Type_std_attributes::
|
||||||
MY_COLL_ALLOW_COERCIBLE_CONV |
|
agg_arg_charsets_for_string_result(c, func_name(),
|
||||||
MY_COLL_ALLOW_NUMERIC_CONV;
|
items, nitems, item_sep);
|
||||||
return agg_arg_charsets(c, items, nitems, flags, item_sep);
|
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
Aggregate arguments for string result, when some comparison
|
|
||||||
is involved internally, e.g: REPLACE(a,b,c)
|
|
||||||
- convert to @@character_set_connection if all arguments are numbers
|
|
||||||
- disallow DERIVATION_NONE
|
|
||||||
*/
|
|
||||||
bool agg_arg_charsets_for_string_result_with_comparison(DTCollation &c,
|
bool agg_arg_charsets_for_string_result_with_comparison(DTCollation &c,
|
||||||
Item **items,
|
Item **items,
|
||||||
uint nitems,
|
uint nitems,
|
||||||
int item_sep= 1)
|
int item_sep= 1)
|
||||||
{
|
{
|
||||||
uint flags= MY_COLL_ALLOW_SUPERSET_CONV |
|
return Type_std_attributes::
|
||||||
MY_COLL_ALLOW_COERCIBLE_CONV |
|
agg_arg_charsets_for_string_result_with_comparison(c, func_name(),
|
||||||
MY_COLL_ALLOW_NUMERIC_CONV |
|
items, nitems,
|
||||||
MY_COLL_DISALLOW_NONE;
|
item_sep);
|
||||||
return agg_arg_charsets(c, items, nitems, flags, item_sep);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -4144,13 +4095,10 @@ protected:
|
|||||||
Item **items, uint nitems,
|
Item **items, uint nitems,
|
||||||
int item_sep= 1)
|
int item_sep= 1)
|
||||||
{
|
{
|
||||||
uint flags= MY_COLL_ALLOW_SUPERSET_CONV |
|
return Type_std_attributes::
|
||||||
MY_COLL_ALLOW_COERCIBLE_CONV |
|
agg_arg_charsets_for_comparison(c, func_name(), items, nitems, item_sep);
|
||||||
MY_COLL_DISALLOW_NONE;
|
|
||||||
return agg_arg_charsets(c, items, nitems, flags, item_sep);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// This method is used by Arg_comparator
|
// This method is used by Arg_comparator
|
||||||
bool agg_arg_charsets_for_comparison(CHARSET_INFO **cs, Item **a, Item **b)
|
bool agg_arg_charsets_for_comparison(CHARSET_INFO **cs, Item **a, Item **b)
|
||||||
|
110
sql/item_func.cc
110
sql/item_func.cc
@ -592,116 +592,6 @@ void Item_udf_func::fix_num_length_and_dec()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
Set max_length/decimals of function if function is fixed point and
|
|
||||||
result length/precision depends on argument ones.
|
|
||||||
*/
|
|
||||||
|
|
||||||
void Item_func::count_decimal_length(Item **item, uint nitems)
|
|
||||||
{
|
|
||||||
int max_int_part= 0;
|
|
||||||
decimals= 0;
|
|
||||||
unsigned_flag= 1;
|
|
||||||
for (uint i=0 ; i < nitems ; i++)
|
|
||||||
{
|
|
||||||
set_if_bigger(decimals, item[i]->decimals);
|
|
||||||
set_if_bigger(max_int_part, item[i]->decimal_int_part());
|
|
||||||
set_if_smaller(unsigned_flag, item[i]->unsigned_flag);
|
|
||||||
}
|
|
||||||
int precision= MY_MIN(max_int_part + decimals, DECIMAL_MAX_PRECISION);
|
|
||||||
fix_char_length(my_decimal_precision_to_length_no_truncation(precision,
|
|
||||||
decimals,
|
|
||||||
unsigned_flag));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
Set max_length of if it is maximum length of its arguments.
|
|
||||||
*/
|
|
||||||
|
|
||||||
void Item_func::count_only_length(Item **item, uint nitems)
|
|
||||||
{
|
|
||||||
uint32 char_length= 0;
|
|
||||||
unsigned_flag= 0;
|
|
||||||
for (uint i= 0; i < nitems ; i++)
|
|
||||||
{
|
|
||||||
set_if_bigger(char_length, item[i]->max_char_length());
|
|
||||||
set_if_bigger(unsigned_flag, item[i]->unsigned_flag);
|
|
||||||
}
|
|
||||||
fix_char_length(char_length);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Item_func::count_octet_length(Item **item, uint nitems)
|
|
||||||
{
|
|
||||||
max_length= 0;
|
|
||||||
unsigned_flag= 0;
|
|
||||||
for (uint i= 0; i < nitems ; i++)
|
|
||||||
{
|
|
||||||
set_if_bigger(max_length, item[i]->max_length);
|
|
||||||
set_if_bigger(unsigned_flag, item[i]->unsigned_flag);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
Set max_length/decimals of function if function is floating point and
|
|
||||||
result length/precision depends on argument ones.
|
|
||||||
*/
|
|
||||||
|
|
||||||
void Item_func::count_real_length(Item **items, uint nitems)
|
|
||||||
{
|
|
||||||
uint32 length= 0;
|
|
||||||
decimals= 0;
|
|
||||||
max_length= 0;
|
|
||||||
unsigned_flag= false;
|
|
||||||
for (uint i=0 ; i < nitems ; i++)
|
|
||||||
{
|
|
||||||
if (decimals < FLOATING_POINT_DECIMALS)
|
|
||||||
{
|
|
||||||
set_if_bigger(decimals, items[i]->decimals);
|
|
||||||
/* Will be ignored if items[i]->decimals >= FLOATING_POINT_DECIMALS */
|
|
||||||
set_if_bigger(length, (items[i]->max_length - items[i]->decimals));
|
|
||||||
}
|
|
||||||
set_if_bigger(max_length, items[i]->max_length);
|
|
||||||
}
|
|
||||||
if (decimals < FLOATING_POINT_DECIMALS)
|
|
||||||
{
|
|
||||||
max_length= length;
|
|
||||||
length+= decimals;
|
|
||||||
if (length < max_length) // If previous operation gave overflow
|
|
||||||
max_length= UINT_MAX32;
|
|
||||||
else
|
|
||||||
max_length= length;
|
|
||||||
}
|
|
||||||
// Corner case: COALESCE(DOUBLE(255,4), DOUBLE(255,3)) -> FLOAT(255, 4)
|
|
||||||
set_if_smaller(max_length, MAX_FIELD_CHARLENGTH);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
Calculate max_length and decimals for string functions.
|
|
||||||
|
|
||||||
@param field_type Field type.
|
|
||||||
@param items Argument array.
|
|
||||||
@param nitems Number of arguments.
|
|
||||||
|
|
||||||
@retval False on success, true on error.
|
|
||||||
*/
|
|
||||||
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 (collation.collation == &my_charset_bin)
|
|
||||||
count_octet_length(items, nitems);
|
|
||||||
else
|
|
||||||
count_only_length(items, nitems);
|
|
||||||
decimals= max_length ? NOT_FIXED_DEC : 0;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Item_func::signal_divide_by_null()
|
void Item_func::signal_divide_by_null()
|
||||||
{
|
{
|
||||||
THD *thd= current_thd;
|
THD *thd= current_thd;
|
||||||
|
@ -42,45 +42,8 @@ protected:
|
|||||||
uint allowed_arg_cols;
|
uint allowed_arg_cols;
|
||||||
String *val_str_from_val_str_ascii(String *str, String *str2);
|
String *val_str_from_val_str_ascii(String *str, String *str2);
|
||||||
|
|
||||||
void count_only_length(Item **item, uint nitems);
|
|
||||||
void count_octet_length(Item **item, uint nitems);
|
|
||||||
void count_real_length(Item **item, uint nitems);
|
|
||||||
void count_decimal_length(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;
|
|
||||||
}
|
|
||||||
virtual bool check_allowed_arg_cols(uint argno);
|
virtual bool check_allowed_arg_cols(uint argno);
|
||||||
public:
|
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 aggregate_attributes_temporal(uint int_part_length,
|
|
||||||
Item **item, uint nitems)
|
|
||||||
{
|
|
||||||
fix_attributes_temporal(int_part_length, count_max_decimals(item, nitems));
|
|
||||||
}
|
|
||||||
|
|
||||||
table_map not_null_tables_cache;
|
table_map not_null_tables_cache;
|
||||||
|
|
||||||
|
124
sql/sql_type.cc
124
sql/sql_type.cc
@ -129,6 +129,126 @@ void Type_std_attributes::set(const Field *field)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint Type_std_attributes::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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Set max_length/decimals of function if function is fixed point and
|
||||||
|
result length/precision depends on argument ones.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void Type_std_attributes::count_decimal_length(Item **item, uint nitems)
|
||||||
|
{
|
||||||
|
int max_int_part= 0;
|
||||||
|
decimals= 0;
|
||||||
|
unsigned_flag= 1;
|
||||||
|
for (uint i=0 ; i < nitems ; i++)
|
||||||
|
{
|
||||||
|
set_if_bigger(decimals, item[i]->decimals);
|
||||||
|
set_if_bigger(max_int_part, item[i]->decimal_int_part());
|
||||||
|
set_if_smaller(unsigned_flag, item[i]->unsigned_flag);
|
||||||
|
}
|
||||||
|
int precision= MY_MIN(max_int_part + decimals, DECIMAL_MAX_PRECISION);
|
||||||
|
fix_char_length(my_decimal_precision_to_length_no_truncation(precision,
|
||||||
|
decimals,
|
||||||
|
unsigned_flag));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Set max_length of if it is maximum length of its arguments.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void Type_std_attributes::count_only_length(Item **item, uint nitems)
|
||||||
|
{
|
||||||
|
uint32 char_length= 0;
|
||||||
|
unsigned_flag= 0;
|
||||||
|
for (uint i= 0; i < nitems ; i++)
|
||||||
|
{
|
||||||
|
set_if_bigger(char_length, item[i]->max_char_length());
|
||||||
|
set_if_bigger(unsigned_flag, item[i]->unsigned_flag);
|
||||||
|
}
|
||||||
|
fix_char_length(char_length);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Type_std_attributes::count_octet_length(Item **item, uint nitems)
|
||||||
|
{
|
||||||
|
max_length= 0;
|
||||||
|
unsigned_flag= 0;
|
||||||
|
for (uint i= 0; i < nitems ; i++)
|
||||||
|
{
|
||||||
|
set_if_bigger(max_length, item[i]->max_length);
|
||||||
|
set_if_bigger(unsigned_flag, item[i]->unsigned_flag);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Set max_length/decimals of function if function is floating point and
|
||||||
|
result length/precision depends on argument ones.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void Type_std_attributes::count_real_length(Item **items, uint nitems)
|
||||||
|
{
|
||||||
|
uint32 length= 0;
|
||||||
|
decimals= 0;
|
||||||
|
max_length= 0;
|
||||||
|
unsigned_flag= false;
|
||||||
|
for (uint i=0 ; i < nitems ; i++)
|
||||||
|
{
|
||||||
|
if (decimals < FLOATING_POINT_DECIMALS)
|
||||||
|
{
|
||||||
|
set_if_bigger(decimals, items[i]->decimals);
|
||||||
|
/* Will be ignored if items[i]->decimals >= FLOATING_POINT_DECIMALS */
|
||||||
|
set_if_bigger(length, (items[i]->max_length - items[i]->decimals));
|
||||||
|
}
|
||||||
|
set_if_bigger(max_length, items[i]->max_length);
|
||||||
|
}
|
||||||
|
if (decimals < FLOATING_POINT_DECIMALS)
|
||||||
|
{
|
||||||
|
max_length= length;
|
||||||
|
length+= decimals;
|
||||||
|
if (length < max_length) // If previous operation gave overflow
|
||||||
|
max_length= UINT_MAX32;
|
||||||
|
else
|
||||||
|
max_length= length;
|
||||||
|
}
|
||||||
|
// Corner case: COALESCE(DOUBLE(255,4), DOUBLE(255,3)) -> FLOAT(255, 4)
|
||||||
|
set_if_smaller(max_length, MAX_FIELD_CHARLENGTH);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Calculate max_length and decimals for string functions.
|
||||||
|
|
||||||
|
@param field_type Field type.
|
||||||
|
@param items Argument array.
|
||||||
|
@param nitems Number of arguments.
|
||||||
|
|
||||||
|
@retval False on success, true on error.
|
||||||
|
*/
|
||||||
|
bool Type_std_attributes::count_string_length(const char *func_name,
|
||||||
|
Item **items, uint nitems)
|
||||||
|
{
|
||||||
|
if (agg_arg_charsets_for_string_result(collation, func_name,
|
||||||
|
items, nitems, 1))
|
||||||
|
return true;
|
||||||
|
if (collation.collation == &my_charset_bin)
|
||||||
|
count_octet_length(items, nitems);
|
||||||
|
else
|
||||||
|
count_only_length(items, nitems);
|
||||||
|
decimals= max_length ? NOT_FIXED_DEC : 0;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
This method is used by:
|
This method is used by:
|
||||||
- Item_user_var_as_out_param::field_type()
|
- Item_user_var_as_out_param::field_type()
|
||||||
@ -1933,7 +2053,7 @@ bool Type_handler_string_result::
|
|||||||
Item_hybrid_func_fix_attributes(THD *thd, Item_hybrid_func *func,
|
Item_hybrid_func_fix_attributes(THD *thd, Item_hybrid_func *func,
|
||||||
Item **items, uint nitems) const
|
Item **items, uint nitems) const
|
||||||
{
|
{
|
||||||
return func->aggregate_attributes_string(items, nitems);
|
return func->aggregate_attributes_string(func->func_name(), items, nitems);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1941,7 +2061,7 @@ bool Type_handler_blob_common::
|
|||||||
Item_hybrid_func_fix_attributes(THD *thd, Item_hybrid_func *func,
|
Item_hybrid_func_fix_attributes(THD *thd, Item_hybrid_func *func,
|
||||||
Item **items, uint nitems) const
|
Item **items, uint nitems) const
|
||||||
{
|
{
|
||||||
if (func->aggregate_attributes_string(items, nitems))
|
if (func->aggregate_attributes_string(func->func_name(), items, nitems))
|
||||||
return true;
|
return true;
|
||||||
func->set_handler(blob_type_handler(func->max_length));
|
func->set_handler(blob_type_handler(func->max_length));
|
||||||
return false;
|
return false;
|
||||||
|
128
sql/sql_type.h
128
sql/sql_type.h
@ -60,7 +60,6 @@ class Item_func_div;
|
|||||||
class Item_func_mod;
|
class Item_func_mod;
|
||||||
class cmp_item;
|
class cmp_item;
|
||||||
class in_vector;
|
class in_vector;
|
||||||
class Type_std_attributes;
|
|
||||||
class Sort_param;
|
class Sort_param;
|
||||||
class Arg_comparator;
|
class Arg_comparator;
|
||||||
struct st_value;
|
struct st_value;
|
||||||
@ -327,6 +326,133 @@ public:
|
|||||||
{
|
{
|
||||||
fix_attributes_temporal(MAX_DATETIME_WIDTH, dec);
|
fix_attributes_temporal(MAX_DATETIME_WIDTH, dec);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void count_only_length(Item **item, uint nitems);
|
||||||
|
void count_octet_length(Item **item, uint nitems);
|
||||||
|
void count_real_length(Item **item, uint nitems);
|
||||||
|
void count_decimal_length(Item **item, uint nitems);
|
||||||
|
bool count_string_length(const char *func_name, Item **item, uint nitems);
|
||||||
|
uint count_max_decimals(Item **item, uint nitems);
|
||||||
|
|
||||||
|
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(const char *func_name,
|
||||||
|
Item **item, uint nitems)
|
||||||
|
{
|
||||||
|
return count_string_length(func_name, item, nitems);
|
||||||
|
}
|
||||||
|
void aggregate_attributes_temporal(uint int_part_length,
|
||||||
|
Item **item, uint nitems)
|
||||||
|
{
|
||||||
|
fix_attributes_temporal(int_part_length, count_max_decimals(item, nitems));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool agg_item_collations(DTCollation &c, const char *name,
|
||||||
|
Item **items, uint nitems,
|
||||||
|
uint flags, int item_sep);
|
||||||
|
bool agg_item_set_converter(const DTCollation &coll, const char *fname,
|
||||||
|
Item **args, uint nargs,
|
||||||
|
uint flags, int item_sep);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Collect arguments' character sets together.
|
||||||
|
We allow to apply automatic character set conversion in some cases.
|
||||||
|
The conditions when conversion is possible are:
|
||||||
|
- arguments A and B have different charsets
|
||||||
|
- A wins according to coercibility rules
|
||||||
|
(i.e. a column is stronger than a string constant,
|
||||||
|
an explicit COLLATE clause is stronger than a column)
|
||||||
|
- character set of A is either superset for character set of B,
|
||||||
|
or B is a string constant which can be converted into the
|
||||||
|
character set of A without data loss.
|
||||||
|
|
||||||
|
If all of the above is true, then it's possible to convert
|
||||||
|
B into the character set of A, and then compare according
|
||||||
|
to the collation of A.
|
||||||
|
|
||||||
|
For functions with more than two arguments:
|
||||||
|
|
||||||
|
collect(A,B,C) ::= collect(collect(A,B),C)
|
||||||
|
|
||||||
|
Since this function calls THD::change_item_tree() on the passed Item **
|
||||||
|
pointers, it is necessary to pass the original Item **'s, not copies.
|
||||||
|
Otherwise their values will not be properly restored (see BUG#20769).
|
||||||
|
If the items are not consecutive (eg. args[2] and args[5]), use the
|
||||||
|
item_sep argument, ie.
|
||||||
|
|
||||||
|
agg_item_charsets(coll, fname, &args[2], 2, flags, 3)
|
||||||
|
*/
|
||||||
|
bool agg_arg_charsets(DTCollation &c, const char *func_name,
|
||||||
|
Item **items, uint nitems,
|
||||||
|
uint flags, int item_sep)
|
||||||
|
{
|
||||||
|
if (agg_item_collations(c, func_name, items, nitems, flags, item_sep))
|
||||||
|
return true;
|
||||||
|
return agg_item_set_converter(c, func_name, items, nitems, flags, item_sep);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
Aggregate arguments for string result, e.g: CONCAT(a,b)
|
||||||
|
- convert to @@character_set_connection if all arguments are numbers
|
||||||
|
- allow DERIVATION_NONE
|
||||||
|
*/
|
||||||
|
bool agg_arg_charsets_for_string_result(DTCollation &c, const char *func_name,
|
||||||
|
Item **items, uint nitems,
|
||||||
|
int item_sep)
|
||||||
|
{
|
||||||
|
uint flags= MY_COLL_ALLOW_SUPERSET_CONV |
|
||||||
|
MY_COLL_ALLOW_COERCIBLE_CONV |
|
||||||
|
MY_COLL_ALLOW_NUMERIC_CONV;
|
||||||
|
return agg_arg_charsets(c, func_name, items, nitems, flags, item_sep);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
Aggregate arguments for string result, when some comparison
|
||||||
|
is involved internally, e.g: REPLACE(a,b,c)
|
||||||
|
- convert to @@character_set_connection if all arguments are numbers
|
||||||
|
- disallow DERIVATION_NONE
|
||||||
|
*/
|
||||||
|
bool agg_arg_charsets_for_string_result_with_comparison(DTCollation &c,
|
||||||
|
const char *func_name,
|
||||||
|
Item **items,
|
||||||
|
uint nitems,
|
||||||
|
int item_sep)
|
||||||
|
{
|
||||||
|
uint flags= MY_COLL_ALLOW_SUPERSET_CONV |
|
||||||
|
MY_COLL_ALLOW_COERCIBLE_CONV |
|
||||||
|
MY_COLL_ALLOW_NUMERIC_CONV |
|
||||||
|
MY_COLL_DISALLOW_NONE;
|
||||||
|
return agg_arg_charsets(c, func_name, items, nitems, flags, item_sep);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Aggregate arguments for comparison, e.g: a=b, a LIKE b, a RLIKE b
|
||||||
|
- don't convert to @@character_set_connection if all arguments are numbers
|
||||||
|
- don't allow DERIVATION_NONE
|
||||||
|
*/
|
||||||
|
bool agg_arg_charsets_for_comparison(DTCollation &c,
|
||||||
|
const char *func_name,
|
||||||
|
Item **items, uint nitems,
|
||||||
|
int item_sep)
|
||||||
|
{
|
||||||
|
uint flags= MY_COLL_ALLOW_SUPERSET_CONV |
|
||||||
|
MY_COLL_ALLOW_COERCIBLE_CONV |
|
||||||
|
MY_COLL_DISALLOW_NONE;
|
||||||
|
return agg_arg_charsets(c, func_name, items, nitems, flags, item_sep);
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user