MDEV-20331 Add class Type_numeric_attributes
This commit is contained in:
parent
e7525beac8
commit
0e0d57141e
24
sql/field.h
24
sql/field.h
@ -781,11 +781,13 @@ public:
|
||||
const LEX_CSTRING *field_name_arg);
|
||||
virtual ~Field() {}
|
||||
|
||||
virtual Type_std_attributes type_std_attributes() const
|
||||
virtual Type_numeric_attributes type_numeric_attributes() const
|
||||
{
|
||||
return Type_std_attributes(field_length, decimals(),
|
||||
MY_TEST(flags & UNSIGNED_FLAG),
|
||||
dtcollation());
|
||||
return Type_numeric_attributes(field_length, decimals(), is_unsigned());
|
||||
}
|
||||
Type_std_attributes type_std_attributes() const
|
||||
{
|
||||
return Type_std_attributes(type_numeric_attributes(), dtcollation());
|
||||
}
|
||||
|
||||
bool is_unsigned() const { return flags & UNSIGNED_FLAG; }
|
||||
@ -2238,7 +2240,7 @@ public:
|
||||
{
|
||||
return type_limits_int()->char_length();
|
||||
}
|
||||
Type_std_attributes type_std_attributes() const
|
||||
Type_numeric_attributes type_numeric_attributes() const
|
||||
{
|
||||
/*
|
||||
For integer data types, the user-specified length does not constrain the
|
||||
@ -2252,9 +2254,8 @@ public:
|
||||
*/
|
||||
uint32 length1= max_display_length();
|
||||
uint32 length2= field_length;
|
||||
return Type_std_attributes(MY_MAX(length1, length2), decimals(),
|
||||
MY_TEST(flags & UNSIGNED_FLAG),
|
||||
dtcollation());
|
||||
return Type_numeric_attributes(MY_MAX(length1, length2),
|
||||
decimals(), is_unsigned());
|
||||
}
|
||||
Information_schema_numeric_attributes
|
||||
information_schema_numeric_attributes() const
|
||||
@ -3991,11 +3992,10 @@ public:
|
||||
{
|
||||
return FIELD_BLOB;
|
||||
}
|
||||
Type_std_attributes type_std_attributes() const
|
||||
Type_numeric_attributes type_numeric_attributes() const
|
||||
{
|
||||
return Type_std_attributes(Field_blob::max_display_length(), decimals(),
|
||||
MY_TEST(flags & UNSIGNED_FLAG),
|
||||
dtcollation());
|
||||
return Type_numeric_attributes(Field_blob::max_display_length(),
|
||||
decimals(), is_unsigned());
|
||||
}
|
||||
Information_schema_character_attributes
|
||||
information_schema_character_attributes() const
|
||||
|
@ -449,7 +449,7 @@ const TABLE_SHARE *Item::field_table_or_null()
|
||||
tables.
|
||||
*/
|
||||
Item::Item(THD *thd, Item *item):
|
||||
Type_all_attributes(item),
|
||||
Type_all_attributes(*item),
|
||||
join_tab_idx(item->join_tab_idx),
|
||||
is_expensive_cache(-1),
|
||||
rsize(0),
|
||||
|
@ -950,7 +950,7 @@ public:
|
||||
bool fix_type_handler(const Type_aggregator *aggregator);
|
||||
void fix_length_and_dec_double()
|
||||
{
|
||||
count_real_length(args, arg_count);
|
||||
aggregate_numeric_attributes_real(args, arg_count);
|
||||
max_length= float_length(decimals);
|
||||
}
|
||||
void fix_length_and_dec_decimal()
|
||||
|
@ -1920,7 +1920,10 @@ bool Item_func_from_unixtime::fix_length_and_dec()
|
||||
THD *thd= current_thd;
|
||||
thd->time_zone_used= 1;
|
||||
tz= thd->variables.time_zone;
|
||||
fix_attributes_datetime_not_fixed_dec(args[0]->decimals);
|
||||
Type_std_attributes::set(
|
||||
Type_temporal_attributes_not_fixed_dec(MAX_DATETIME_WIDTH,
|
||||
args[0]->decimals, false),
|
||||
DTCollation_numeric());
|
||||
maybe_null= true;
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -1556,9 +1556,11 @@ public:
|
||||
{
|
||||
uint dec= MY_MAX(item->arguments()[0]->datetime_precision(current_thd),
|
||||
interval_dec(item->arguments()[1], int_type(item)));
|
||||
item->collation.set(item->default_charset(),
|
||||
DERIVATION_COERCIBLE, MY_REPERTOIRE_ASCII);
|
||||
item->fix_char_length_temporal_not_fixed_dec(MAX_DATETIME_WIDTH, dec);
|
||||
item->Type_std_attributes::set(
|
||||
Type_temporal_attributes_not_fixed_dec(MAX_DATETIME_WIDTH, dec, false),
|
||||
DTCollation(item->default_charset(),
|
||||
DERIVATION_COERCIBLE, MY_REPERTOIRE_ASCII));
|
||||
item->fix_char_length(item->max_length);
|
||||
return false;
|
||||
}
|
||||
bool get_date(THD *thd, Item_handled_func *item,
|
||||
@ -1663,9 +1665,11 @@ public:
|
||||
uint dec0= item->arguments()[0]->decimals;
|
||||
uint dec1= Interval_DDhhmmssff::fsp(current_thd, item->arguments()[1]);
|
||||
uint dec= MY_MAX(dec0, dec1);
|
||||
item->collation.set(item->default_charset(),
|
||||
DERIVATION_COERCIBLE, MY_REPERTOIRE_ASCII);
|
||||
item->fix_char_length_temporal_not_fixed_dec(MAX_DATETIME_WIDTH, dec);
|
||||
item->Type_std_attributes::set(
|
||||
Type_temporal_attributes_not_fixed_dec(MAX_DATETIME_WIDTH, dec, false),
|
||||
DTCollation(item->default_charset(),
|
||||
DERIVATION_COERCIBLE, MY_REPERTOIRE_ASCII));
|
||||
item->fix_char_length(item->max_length);
|
||||
return false;
|
||||
}
|
||||
bool get_date(THD *thd, Item_handled_func *item,
|
||||
|
110
sql/sql_type.cc
110
sql/sql_type.cc
@ -1078,7 +1078,7 @@ Datetime_truncation_not_needed::Datetime_truncation_not_needed(THD *thd, Item *i
|
||||
|
||||
/********************************************************************/
|
||||
|
||||
uint Type_std_attributes::count_max_decimals(Item **item, uint nitems)
|
||||
uint Type_numeric_attributes::find_max_decimals(Item **item, uint nitems)
|
||||
{
|
||||
uint res= 0;
|
||||
for (uint i= 0; i < nitems; i++)
|
||||
@ -1087,55 +1087,61 @@ uint Type_std_attributes::count_max_decimals(Item **item, uint nitems)
|
||||
}
|
||||
|
||||
|
||||
uint Type_numeric_attributes::count_unsigned(Item **item, uint nitems)
|
||||
{
|
||||
uint res= 0;
|
||||
for (uint i= 0 ; i < nitems ; i++)
|
||||
{
|
||||
if (item[i]->unsigned_flag)
|
||||
res++;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
uint32 Type_numeric_attributes::find_max_char_length(Item **item, uint nitems)
|
||||
{
|
||||
uint32 char_length= 0;
|
||||
for (uint i= 0; i < nitems ; i++)
|
||||
set_if_bigger(char_length, item[i]->max_char_length());
|
||||
return char_length;
|
||||
}
|
||||
|
||||
|
||||
uint32 Type_numeric_attributes::find_max_octet_length(Item **item, uint nitems)
|
||||
{
|
||||
uint32 octet_length= 0;
|
||||
for (uint i= 0; i < nitems ; i++)
|
||||
set_if_bigger(octet_length, item[i]->max_length);
|
||||
return octet_length;
|
||||
}
|
||||
|
||||
|
||||
int Type_numeric_attributes::find_max_decimal_int_part(Item **item, uint nitems)
|
||||
{
|
||||
int max_int_part= 0;
|
||||
for (uint i=0 ; i < nitems ; i++)
|
||||
set_if_bigger(max_int_part, item[i]->decimal_int_part());
|
||||
return max_int_part;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
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)
|
||||
void
|
||||
Type_numeric_attributes::aggregate_numeric_attributes_decimal(Item **item,
|
||||
uint nitems,
|
||||
bool unsigned_arg)
|
||||
{
|
||||
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 max_int_part= find_max_decimal_int_part(item, nitems);
|
||||
decimals= find_max_decimals(item, nitems);
|
||||
int precision= MY_MIN(max_int_part + decimals, DECIMAL_MAX_PRECISION);
|
||||
fix_char_length(my_decimal_precision_to_length_no_truncation(precision,
|
||||
(uint8) 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);
|
||||
}
|
||||
max_length= my_decimal_precision_to_length_no_truncation(precision,
|
||||
(uint8) decimals,
|
||||
unsigned_flag);
|
||||
}
|
||||
|
||||
|
||||
@ -1144,7 +1150,9 @@ void Type_std_attributes::count_octet_length(Item **item, uint nitems)
|
||||
result length/precision depends on argument ones.
|
||||
*/
|
||||
|
||||
void Type_std_attributes::count_real_length(Item **items, uint nitems)
|
||||
void
|
||||
Type_numeric_attributes::aggregate_numeric_attributes_real(Item **items,
|
||||
uint nitems)
|
||||
{
|
||||
uint32 length= 0;
|
||||
decimals= 0;
|
||||
@ -1183,16 +1191,17 @@ void Type_std_attributes::count_real_length(Item **items, uint nitems)
|
||||
|
||||
@retval False on success, true on error.
|
||||
*/
|
||||
bool Type_std_attributes::count_string_length(const char *func_name,
|
||||
Item **items, uint nitems)
|
||||
bool Type_std_attributes::aggregate_attributes_string(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);
|
||||
max_length= find_max_octet_length(items, nitems);
|
||||
else
|
||||
count_only_length(items, nitems);
|
||||
fix_char_length(find_max_char_length(items, nitems));
|
||||
unsigned_flag= count_unsigned(items, nitems) > 0;
|
||||
decimals= max_length ? NOT_FIXED_DEC : 0;
|
||||
return false;
|
||||
}
|
||||
@ -4170,7 +4179,7 @@ bool Type_handler_int_result::
|
||||
{
|
||||
// Convert a mixture of signed and unsigned int to decimal
|
||||
handler->set_handler(&type_handler_newdecimal);
|
||||
func->aggregate_attributes_decimal(items, nitems);
|
||||
func->aggregate_attributes_decimal(items, nitems, false);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -4198,7 +4207,8 @@ bool Type_handler_decimal_result::
|
||||
Type_all_attributes *func,
|
||||
Item **items, uint nitems) const
|
||||
{
|
||||
func->aggregate_attributes_decimal(items, nitems);
|
||||
uint unsigned_count= func->count_unsigned(items, nitems);
|
||||
func->aggregate_attributes_decimal(items, nitems, unsigned_count == nitems);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
162
sql/sql_type.h
162
sql/sql_type.h
@ -2773,38 +2773,87 @@ char_to_byte_length_safe(size_t char_length_arg, uint32 mbmaxlen_arg)
|
||||
return tmp > UINT_MAX32 ? (uint32) UINT_MAX32 : static_cast<uint32>(tmp);
|
||||
}
|
||||
|
||||
/**
|
||||
A class to store type attributes for the standard data types.
|
||||
Does not include attributes for the extended data types
|
||||
such as ENUM, SET, GEOMETRY.
|
||||
*/
|
||||
class Type_std_attributes
|
||||
|
||||
class Type_numeric_attributes
|
||||
{
|
||||
public:
|
||||
DTCollation collation;
|
||||
uint decimals;
|
||||
static uint count_unsigned(Item **item, uint nitems);
|
||||
static uint32 find_max_char_length(Item **item, uint nitems);
|
||||
static uint32 find_max_octet_length(Item **item, uint nitems);
|
||||
static int find_max_decimal_int_part(Item **item, uint nitems);
|
||||
static uint find_max_decimals(Item **item, uint nitems);
|
||||
public:
|
||||
/*
|
||||
The maximum value length in characters multiplied by collation->mbmaxlen.
|
||||
Almost always it's the maximum value length in bytes.
|
||||
*/
|
||||
uint32 max_length;
|
||||
uint decimals;
|
||||
bool unsigned_flag;
|
||||
public:
|
||||
Type_numeric_attributes()
|
||||
:max_length(0), decimals(0), unsigned_flag(false)
|
||||
{ }
|
||||
Type_numeric_attributes(uint32 max_length_arg, uint decimals_arg,
|
||||
bool unsigned_flag_arg)
|
||||
:max_length(max_length_arg),
|
||||
decimals(decimals_arg),
|
||||
unsigned_flag(unsigned_flag_arg)
|
||||
{ }
|
||||
protected:
|
||||
void aggregate_numeric_attributes_real(Item **item, uint nitems);
|
||||
void aggregate_numeric_attributes_decimal(Item **item, uint nitems,
|
||||
bool unsigned_arg);
|
||||
};
|
||||
|
||||
|
||||
|
||||
class Type_temporal_attributes: public Type_numeric_attributes
|
||||
{
|
||||
public:
|
||||
Type_temporal_attributes(uint int_part_length, uint dec, bool unsigned_arg)
|
||||
:Type_numeric_attributes(int_part_length + (dec ? 1 : 0),
|
||||
MY_MIN(dec, TIME_SECOND_PART_DIGITS),
|
||||
unsigned_arg)
|
||||
{
|
||||
max_length+= decimals;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class Type_temporal_attributes_not_fixed_dec: public Type_numeric_attributes
|
||||
{
|
||||
public:
|
||||
Type_temporal_attributes_not_fixed_dec(uint32 int_part_length, uint dec,
|
||||
bool unsigned_flag)
|
||||
:Type_numeric_attributes(int_part_length, dec, unsigned_flag)
|
||||
{
|
||||
if (decimals == NOT_FIXED_DEC)
|
||||
max_length+= TIME_SECOND_PART_DIGITS + 1;
|
||||
else if (decimals)
|
||||
{
|
||||
set_if_smaller(decimals, TIME_SECOND_PART_DIGITS);
|
||||
max_length+= decimals + 1;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
A class to store type attributes for the standard data types.
|
||||
Does not include attributes for the extended data types
|
||||
such as ENUM, SET, GEOMETRY.
|
||||
*/
|
||||
class Type_std_attributes: public Type_numeric_attributes
|
||||
{
|
||||
public:
|
||||
DTCollation collation;
|
||||
Type_std_attributes()
|
||||
:collation(&my_charset_bin, DERIVATION_COERCIBLE),
|
||||
decimals(0), max_length(0), unsigned_flag(false)
|
||||
:collation(&my_charset_bin, DERIVATION_COERCIBLE)
|
||||
{ }
|
||||
Type_std_attributes(const Type_std_attributes *other)
|
||||
:collation(other->collation),
|
||||
decimals(other->decimals),
|
||||
max_length(other->max_length),
|
||||
unsigned_flag(other->unsigned_flag)
|
||||
{ }
|
||||
Type_std_attributes(uint32 max_length_arg, uint decimals_arg,
|
||||
bool unsigned_flag_arg, const DTCollation &dtc)
|
||||
:collation(dtc),
|
||||
decimals(decimals_arg),
|
||||
max_length(max_length_arg),
|
||||
unsigned_flag(unsigned_flag_arg)
|
||||
Type_std_attributes(const Type_numeric_attributes &nattr,
|
||||
const DTCollation &dtc)
|
||||
:Type_numeric_attributes(nattr), collation(dtc)
|
||||
{ }
|
||||
void set(const Type_std_attributes *other)
|
||||
{
|
||||
@ -2814,6 +2863,10 @@ public:
|
||||
{
|
||||
*this= other;
|
||||
}
|
||||
void set(const Type_numeric_attributes &nattr, const DTCollation &dtc)
|
||||
{
|
||||
*this= Type_std_attributes(nattr, dtc);
|
||||
}
|
||||
uint32 max_char_length() const
|
||||
{ return max_length / collation.collation->mbmaxlen; }
|
||||
void fix_length_and_charset(uint32 max_char_length_arg, CHARSET_INFO *cs)
|
||||
@ -2826,41 +2879,11 @@ public:
|
||||
max_length= char_to_byte_length_safe(max_char_length_arg,
|
||||
collation.collation->mbmaxlen);
|
||||
}
|
||||
void fix_char_length_temporal_not_fixed_dec(uint int_part_length, uint dec)
|
||||
void fix_attributes_temporal(uint32 int_part_length, uint dec)
|
||||
{
|
||||
uint char_length= int_part_length;
|
||||
if ((decimals= dec))
|
||||
{
|
||||
if (decimals == NOT_FIXED_DEC)
|
||||
char_length+= TIME_SECOND_PART_DIGITS + 1;
|
||||
else
|
||||
{
|
||||
set_if_smaller(decimals, TIME_SECOND_PART_DIGITS);
|
||||
char_length+= decimals + 1;
|
||||
}
|
||||
}
|
||||
fix_char_length(char_length);
|
||||
}
|
||||
void fix_attributes_temporal_not_fixed_dec(uint int_part_length, uint dec)
|
||||
{
|
||||
collation= DTCollation_numeric();
|
||||
unsigned_flag= 0;
|
||||
fix_char_length_temporal_not_fixed_dec(int_part_length, dec);
|
||||
}
|
||||
void fix_attributes_time_not_fixed_dec(uint dec)
|
||||
{
|
||||
fix_attributes_temporal_not_fixed_dec(MIN_TIME_WIDTH, dec);
|
||||
}
|
||||
void fix_attributes_datetime_not_fixed_dec(uint dec)
|
||||
{
|
||||
fix_attributes_temporal_not_fixed_dec(MAX_DATETIME_WIDTH, dec);
|
||||
}
|
||||
void fix_attributes_temporal(uint int_part_length, uint dec)
|
||||
{
|
||||
collation= DTCollation_numeric();
|
||||
unsigned_flag= 0;
|
||||
decimals= MY_MIN(dec, TIME_SECOND_PART_DIGITS);
|
||||
max_length= decimals + int_part_length + (dec ? 1 : 0);
|
||||
*this= Type_std_attributes(
|
||||
Type_temporal_attributes(int_part_length, dec, false),
|
||||
DTCollation_numeric());
|
||||
}
|
||||
void fix_attributes_date()
|
||||
{
|
||||
@ -2875,38 +2898,31 @@ public:
|
||||
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= DTCollation_numeric();
|
||||
count_only_length(items, nitems);
|
||||
fix_char_length(find_max_char_length(items, nitems));
|
||||
unsigned_flag= count_unsigned(items, nitems) > 0;
|
||||
decimals= 0;
|
||||
}
|
||||
void aggregate_attributes_real(Item **items, uint nitems)
|
||||
{
|
||||
collation= DTCollation_numeric();
|
||||
count_real_length(items, nitems);
|
||||
aggregate_numeric_attributes_real(items, nitems);
|
||||
}
|
||||
void aggregate_attributes_decimal(Item **items, uint nitems)
|
||||
void aggregate_attributes_decimal(Item **items, uint nitems,
|
||||
bool unsigned_arg)
|
||||
{
|
||||
collation= DTCollation_numeric();
|
||||
count_decimal_length(items, nitems);
|
||||
aggregate_numeric_attributes_decimal(items, nitems,
|
||||
(unsigned_flag= unsigned_arg));
|
||||
}
|
||||
bool aggregate_attributes_string(const char *func_name,
|
||||
Item **item, uint nitems)
|
||||
{
|
||||
return count_string_length(func_name, item, nitems);
|
||||
}
|
||||
Item **item, uint nitems);
|
||||
void aggregate_attributes_temporal(uint int_part_length,
|
||||
Item **item, uint nitems)
|
||||
{
|
||||
fix_attributes_temporal(int_part_length, count_max_decimals(item, nitems));
|
||||
fix_attributes_temporal(int_part_length, find_max_decimals(item, nitems));
|
||||
}
|
||||
|
||||
bool agg_item_collations(DTCollation &c, const char *name,
|
||||
@ -3010,7 +3026,7 @@ public:
|
||||
Type_all_attributes()
|
||||
:Type_std_attributes()
|
||||
{ }
|
||||
Type_all_attributes(const Type_all_attributes *other)
|
||||
Type_all_attributes(const Type_all_attributes &other)
|
||||
:Type_std_attributes(other)
|
||||
{ }
|
||||
virtual ~Type_all_attributes() {}
|
||||
|
Loading…
x
Reference in New Issue
Block a user