1
0
mirror of https://github.com/MariaDB/server.git synced 2025-08-08 11:22:35 +03:00

MDEV-20326 Add class DTCollation_numeric

This commit is contained in:
Alexander Barkov
2019-08-12 18:41:02 +04:00
parent f6e386f00b
commit e7525beac8
9 changed files with 237 additions and 206 deletions

View File

@@ -2141,11 +2141,9 @@ Field_str::Field_str(uchar *ptr_arg,uint32 len_arg, uchar *null_ptr_arg,
:Field(ptr_arg, len_arg, null_ptr_arg, null_bit_arg, :Field(ptr_arg, len_arg, null_ptr_arg, null_bit_arg,
unireg_check_arg, field_name_arg) unireg_check_arg, field_name_arg)
{ {
field_charset= collation.collation; m_collation= collation;
if (collation.collation->state & MY_CS_BINSORT) if (collation.collation->state & MY_CS_BINSORT)
flags|=BINARY_FLAG; flags|=BINARY_FLAG;
field_derivation= collation.derivation;
field_repertoire= collation.repertoire;
} }
@@ -2159,7 +2157,7 @@ bool Field_str::test_if_equality_guarantees_uniqueness(const Item *item) const
SELECT * FROM t1 WHERE varchar_column=DATE'2001-01-01' SELECT * FROM t1 WHERE varchar_column=DATE'2001-01-01'
return non-unuque values, e.g. '2001-01-01' and '2001-01-01x'. return non-unuque values, e.g. '2001-01-01' and '2001-01-01x'.
*/ */
if (!field_charset->coll->propagate(field_charset, 0, 0) || if (!field_charset()->coll->propagate(field_charset(), 0, 0) ||
item->cmp_type() != STRING_RESULT) item->cmp_type() != STRING_RESULT)
return false; return false;
/* /*
@@ -2170,8 +2168,8 @@ bool Field_str::test_if_equality_guarantees_uniqueness(const Item *item) const
WHERE latin1_bin_column = _latin1'A' COLLATE latin1_swedish_ci WHERE latin1_bin_column = _latin1'A' COLLATE latin1_swedish_ci
return non-unique values 'a' and 'A'. return non-unique values 'a' and 'A'.
*/ */
DTCollation tmp(field_charset, field_derivation, repertoire()); DTCollation tmp(dtcollation());
return !tmp.aggregate(item->collation) && tmp.collation == field_charset; return !tmp.aggregate(item->collation) && tmp.collation == field_charset();
} }
@@ -2453,7 +2451,7 @@ bool Field_null::is_equal(const Column_definition &new_field) const
{ {
DBUG_ASSERT(!compression_method()); DBUG_ASSERT(!compression_method());
return new_field.type_handler() == type_handler() && return new_field.type_handler() == type_handler() &&
new_field.charset == field_charset && new_field.charset == field_charset() &&
new_field.length == max_display_length(); new_field.length == max_display_length();
} }
@@ -6984,7 +6982,7 @@ Field_longstr::report_if_important_data(const char *pstr, const char *end,
THD *thd= get_thd(); THD *thd= get_thd();
if ((pstr < end) && thd->count_cuted_fields > CHECK_FIELD_EXPRESSION) if ((pstr < end) && thd->count_cuted_fields > CHECK_FIELD_EXPRESSION)
{ {
if (test_if_important_data(field_charset, pstr, end)) if (test_if_important_data(field_charset(), pstr, end))
{ {
if (thd->abort_on_warning) if (thd->abort_on_warning)
set_warning(ER_DATA_TOO_LONG, 1); set_warning(ER_DATA_TOO_LONG, 1);
@@ -7015,14 +7013,15 @@ int Field_string::store(const char *from, size_t length,CHARSET_INFO *cs)
rc= well_formed_copy_with_check((char*) ptr, field_length, rc= well_formed_copy_with_check((char*) ptr, field_length,
cs, from, length, cs, from, length,
field_length / field_charset->mbmaxlen, Field_string::char_length(),
false, &copy_length); false, &copy_length);
/* Append spaces if the string was shorter than the field. */ /* Append spaces if the string was shorter than the field. */
if (copy_length < field_length) if (copy_length < field_length)
field_charset->cset->fill(field_charset,(char*) ptr+copy_length, field_charset()->cset->fill(field_charset(),
field_length-copy_length, (char*) ptr + copy_length,
field_charset->pad_char); field_length - copy_length,
field_charset()->pad_char);
return rc; return rc;
} }
@@ -7032,13 +7031,13 @@ int Field_str::store(longlong nr, bool unsigned_val)
{ {
char buff[64]; char buff[64];
uint length; uint length;
length= (uint) (field_charset->cset->longlong10_to_str)(field_charset, length= (uint) (field_charset()->cset->longlong10_to_str)(field_charset(),
buff, buff,
sizeof(buff), sizeof(buff),
(unsigned_val ? 10: (unsigned_val ? 10:
-10), -10),
nr); nr);
return store(buff, length, field_charset); return store(buff, length, field_charset());
} }
@@ -7054,8 +7053,7 @@ int Field_str::store(double nr)
{ {
DBUG_ASSERT(marked_for_write_or_computed()); DBUG_ASSERT(marked_for_write_or_computed());
char buff[DOUBLE_TO_STRING_CONVERSION_BUFFER_SIZE]; char buff[DOUBLE_TO_STRING_CONVERSION_BUFFER_SIZE];
uint local_char_length= MY_MIN(sizeof(buff), uint local_char_length= MY_MIN(sizeof(buff), Field_str::char_length());
field_length / field_charset->mbmaxlen);
size_t length= 0; size_t length= 0;
my_bool error= (local_char_length == 0); my_bool error= (local_char_length == 0);
@@ -7078,7 +7076,7 @@ bool Field_string::is_equal(const Column_definition &new_field) const
DBUG_ASSERT(!compression_method()); DBUG_ASSERT(!compression_method());
return new_field.type_handler() == type_handler() && return new_field.type_handler() == type_handler() &&
new_field.char_length == char_length() && new_field.char_length == char_length() &&
new_field.charset == field_charset && new_field.charset == field_charset() &&
new_field.length == max_display_length(); new_field.length == max_display_length();
} }
@@ -7164,7 +7162,7 @@ Field_string::Warn_filter_string::Warn_filter_string(const THD *thd,
const Field_string *field) const Field_string *field)
:Warn_filter(!thd->no_errors, :Warn_filter(!thd->no_errors,
!thd->no_errors && !thd->no_errors &&
field->Field_string::charset() == &my_charset_bin) field->field_charset() == &my_charset_bin)
{ } { }
@@ -7200,12 +7198,13 @@ String *Field_string::val_str(String *val_buffer __attribute__((unused)),
size_t length; size_t length;
if (get_thd()->variables.sql_mode & if (get_thd()->variables.sql_mode &
MODE_PAD_CHAR_TO_FULL_LENGTH) MODE_PAD_CHAR_TO_FULL_LENGTH)
length= my_charpos(field_charset, ptr, ptr + field_length, length= my_charpos(field_charset(), ptr, ptr + field_length,
field_length / field_charset->mbmaxlen); Field_string::char_length());
else else
length= field_charset->cset->lengthsp(field_charset, (const char*) ptr, length= field_charset()->cset->lengthsp(field_charset(),
field_length); (const char*) ptr,
val_ptr->set((const char*) ptr, length, field_charset); field_length);
val_ptr->set((const char*) ptr, length, field_charset());
return val_ptr; return val_ptr;
} }
@@ -7262,11 +7261,11 @@ int Field_string::cmp(const uchar *a_ptr, const uchar *b_ptr) const
{ {
size_t a_len, b_len; size_t a_len, b_len;
if (field_charset->mbmaxlen != 1) if (mbmaxlen() != 1)
{ {
size_t char_len= field_length/field_charset->mbmaxlen; size_t char_len= Field_string::char_length();
a_len= my_charpos(field_charset, a_ptr, a_ptr + field_length, char_len); a_len= my_charpos(field_charset(), a_ptr, a_ptr + field_length, char_len);
b_len= my_charpos(field_charset, b_ptr, b_ptr + field_length, char_len); b_len= my_charpos(field_charset(), b_ptr, b_ptr + field_length, char_len);
} }
else else
a_len= b_len= field_length; a_len= b_len= field_length;
@@ -7274,9 +7273,9 @@ int Field_string::cmp(const uchar *a_ptr, const uchar *b_ptr) const
We have to remove end space to be able to compare multi-byte-characters We have to remove end space to be able to compare multi-byte-characters
like in latin_de 'ae' and 0xe4 like in latin_de 'ae' and 0xe4
*/ */
return field_charset->coll->strnncollsp(field_charset, return field_charset()->coll->strnncollsp(field_charset(),
a_ptr, a_len, a_ptr, a_len,
b_ptr, b_len); b_ptr, b_len);
} }
@@ -7285,13 +7284,13 @@ void Field_string::sort_string(uchar *to,uint length)
#ifdef DBUG_ASSERT_EXISTS #ifdef DBUG_ASSERT_EXISTS
size_t tmp= size_t tmp=
#endif #endif
field_charset->coll->strnxfrm(field_charset, field_charset()->coll->strnxfrm(field_charset(),
to, length, to, length,
char_length() * char_length() *
field_charset->strxfrm_multiply, field_charset()->strxfrm_multiply,
ptr, field_length, ptr, field_length,
MY_STRXFRM_PAD_WITH_SPACE | MY_STRXFRM_PAD_WITH_SPACE |
MY_STRXFRM_PAD_TO_MAXLEN); MY_STRXFRM_PAD_TO_MAXLEN);
DBUG_ASSERT(tmp == length); DBUG_ASSERT(tmp == length);
} }
@@ -7319,12 +7318,12 @@ void Field_string::sql_type(String &res) const
uchar *Field_string::pack(uchar *to, const uchar *from, uint max_length) uchar *Field_string::pack(uchar *to, const uchar *from, uint max_length)
{ {
size_t length= MY_MIN(field_length,max_length); size_t length= MY_MIN(field_length,max_length);
size_t local_char_length= max_length/field_charset->mbmaxlen; size_t local_char_length= Field_string::char_length();
DBUG_PRINT("debug", ("Packing field '%s' - length: %zu ", field_name.str, DBUG_PRINT("debug", ("Packing field '%s' - length: %zu ", field_name.str,
length)); length));
if (length > local_char_length) if (length > local_char_length)
local_char_length= my_charpos(field_charset, from, from+length, local_char_length= my_charpos(field_charset(), from, from + length,
local_char_length); local_char_length);
set_if_smaller(length, local_char_length); set_if_smaller(length, local_char_length);
@@ -7334,13 +7333,14 @@ uchar *Field_string::pack(uchar *to, const uchar *from, uint max_length)
(this is for not packing padding adding bytes in BINARY (this is for not packing padding adding bytes in BINARY
fields). fields).
*/ */
if (field_charset->mbmaxlen == 1) if (mbmaxlen() == 1)
{ {
while (length && from[length-1] == field_charset->pad_char) while (length && from[length-1] == field_charset()->pad_char)
length --; length --;
} }
else else
length= field_charset->cset->lengthsp(field_charset, (const char*) from, length); length= field_charset()->cset->lengthsp(field_charset(),
(const char*) from, length);
// Length always stored little-endian // Length always stored little-endian
*to++= (uchar) length; *to++= (uchar) length;
@@ -7412,7 +7412,10 @@ Field_string::unpack(uchar *to, const uchar *from, const uchar *from_end,
memcpy(to, from, length); memcpy(to, from, length);
// Pad the string with the pad character of the fields charset // Pad the string with the pad character of the fields charset
field_charset->cset->fill(field_charset, (char*) to + length, field_length - length, field_charset->pad_char); field_charset()->cset->fill(field_charset(),
(char*) to + length,
field_length - length,
field_charset()->pad_char);
return from+length; return from+length;
} }
@@ -7475,13 +7478,15 @@ uint Field_string::max_packed_col_length(uint max_length)
uint Field_string::get_key_image(uchar *buff, uint length, imagetype type_arg) uint Field_string::get_key_image(uchar *buff, uint length, imagetype type_arg)
{ {
size_t bytes = my_charpos(field_charset, (char*) ptr, size_t bytes= my_charpos(field_charset(), (char*) ptr,
(char*) ptr + field_length, (char*) ptr + field_length,
length / field_charset->mbmaxlen); length / mbmaxlen());
memcpy(buff, ptr, bytes); memcpy(buff, ptr, bytes);
if (bytes < length) if (bytes < length)
field_charset->cset->fill(field_charset, (char*) buff + bytes, field_charset()->cset->fill(field_charset(),
length - bytes, field_charset->pad_char); (char*) buff + bytes,
length - bytes,
field_charset()->pad_char);
return (uint)bytes; return (uint)bytes;
} }
@@ -7557,7 +7562,7 @@ int Field_varstring::store(const char *from,size_t length,CHARSET_INFO *cs)
rc= well_formed_copy_with_check((char*) get_data(), field_length, rc= well_formed_copy_with_check((char*) get_data(), field_length,
cs, from, length, cs, from, length,
field_length / field_charset->mbmaxlen, Field_varstring::char_length(),
true, &copy_length); true, &copy_length);
store_length(copy_length); store_length(copy_length);
@@ -7592,7 +7597,7 @@ String *Field_varstring::val_str(String *val_buffer __attribute__((unused)),
String *val_ptr) String *val_ptr)
{ {
DBUG_ASSERT(marked_for_read()); DBUG_ASSERT(marked_for_read());
val_ptr->set((const char*) get_data(), get_length(), field_charset); val_ptr->set((const char*) get_data(), get_length(), field_charset());
return val_ptr; return val_ptr;
} }
@@ -7629,13 +7634,9 @@ int Field_varstring::cmp_max(const uchar *a_ptr, const uchar *b_ptr,
} }
set_if_smaller(a_length, max_len); set_if_smaller(a_length, max_len);
set_if_smaller(b_length, max_len); set_if_smaller(b_length, max_len);
diff= field_charset->coll->strnncollsp(field_charset, diff= field_charset()->coll->strnncollsp(field_charset(),
a_ptr+ a_ptr + length_bytes, a_length,
length_bytes, b_ptr + length_bytes, b_length);
a_length,
b_ptr+
length_bytes,
b_length);
return diff; return diff;
} }
@@ -7648,17 +7649,16 @@ int Field_varstring::cmp_max(const uchar *a_ptr, const uchar *b_ptr,
int Field_varstring::key_cmp(const uchar *key_ptr, uint max_key_length) const int Field_varstring::key_cmp(const uchar *key_ptr, uint max_key_length) const
{ {
size_t length= length_bytes == 1 ? (uint) *ptr : uint2korr(ptr); size_t length= length_bytes == 1 ? (uint) *ptr : uint2korr(ptr);
size_t local_char_length= max_key_length / field_charset->mbmaxlen; size_t local_char_length= max_key_length / mbmaxlen();
local_char_length= my_charpos(field_charset, ptr + length_bytes, local_char_length= my_charpos(field_charset(), ptr + length_bytes,
ptr + length_bytes + length, local_char_length); ptr + length_bytes + length, local_char_length);
set_if_smaller(length, local_char_length); set_if_smaller(length, local_char_length);
return field_charset->coll->strnncollsp(field_charset, return field_charset()->coll->strnncollsp(field_charset(),
ptr + length_bytes, ptr + length_bytes,
length, length,
key_ptr+ key_ptr + HA_KEY_BLOB_LENGTH,
HA_KEY_BLOB_LENGTH, uint2korr(key_ptr));
uint2korr(key_ptr));
} }
@@ -7672,11 +7672,11 @@ int Field_varstring::key_cmp(const uchar *key_ptr, uint max_key_length) const
int Field_varstring::key_cmp(const uchar *a,const uchar *b) const int Field_varstring::key_cmp(const uchar *a,const uchar *b) const
{ {
return field_charset->coll->strnncollsp(field_charset, return field_charset()->coll->strnncollsp(field_charset(),
a + HA_KEY_BLOB_LENGTH, a + HA_KEY_BLOB_LENGTH,
uint2korr(a), uint2korr(a),
b + HA_KEY_BLOB_LENGTH, b + HA_KEY_BLOB_LENGTH,
uint2korr(b)); uint2korr(b));
} }
@@ -7686,7 +7686,7 @@ void Field_varstring::sort_string(uchar *to,uint length)
val_str(&buf, &buf); val_str(&buf, &buf);
if (field_charset == &my_charset_bin) if (field_charset() == &my_charset_bin)
{ {
/* Store length last in high-byte order to sort longer strings first */ /* Store length last in high-byte order to sort longer strings first */
if (length_bytes == 1) if (length_bytes == 1)
@@ -7699,11 +7699,13 @@ void Field_varstring::sort_string(uchar *to,uint length)
#ifdef DBUG_ASSERT_EXISTS #ifdef DBUG_ASSERT_EXISTS
size_t rc= size_t rc=
#endif #endif
field_charset->coll->strnxfrm(field_charset, to, length, field_charset()->coll->strnxfrm(field_charset(),
char_length() * field_charset->strxfrm_multiply, to, length,
(const uchar*) buf.ptr(), buf.length(), char_length() *
MY_STRXFRM_PAD_WITH_SPACE | field_charset()->strxfrm_multiply,
MY_STRXFRM_PAD_TO_MAXLEN); (const uchar*) buf.ptr(), buf.length(),
MY_STRXFRM_PAD_WITH_SPACE |
MY_STRXFRM_PAD_TO_MAXLEN);
DBUG_ASSERT(rc == length); DBUG_ASSERT(rc == length);
} }
@@ -7844,7 +7846,7 @@ uint Field_varstring::get_key_image(uchar *buff, uint length,
val_str(&val, &val); val_str(&val, &val);
dbug_tmp_restore_column_map(table->read_set, old_map); dbug_tmp_restore_column_map(table->read_set, old_map);
local_char_length= val.charpos(length / field_charset->mbmaxlen); local_char_length= val.charpos(length / mbmaxlen());
if (local_char_length < val.length()) if (local_char_length < val.length())
val.length(local_char_length); val.length(local_char_length);
/* Key is always stored with 2 bytes */ /* Key is always stored with 2 bytes */
@@ -7865,7 +7867,7 @@ uint Field_varstring::get_key_image(uchar *buff, uint length,
void Field_varstring::set_key_image(const uchar *buff,uint length) void Field_varstring::set_key_image(const uchar *buff,uint length)
{ {
length= uint2korr(buff); // Real length is here length= uint2korr(buff); // Real length is here
(void) store((const char*) buff + HA_KEY_BLOB_LENGTH, length, field_charset); (void) store((const char*) buff + HA_KEY_BLOB_LENGTH, length, field_charset());
} }
@@ -7925,7 +7927,7 @@ bool Field_varstring::is_equal(const Column_definition &new_field) const
new_field.length == field_length && new_field.length == field_length &&
new_field.char_length == char_length() && new_field.char_length == char_length() &&
!new_field.compression_method() == !compression_method() && !new_field.compression_method() == !compression_method() &&
new_field.charset == field_charset; new_field.charset == field_charset();
} }
@@ -7989,10 +7991,10 @@ int Field_longstr::compress(char *to, uint to_length,
uint buf_length; uint buf_length;
int rc= 0; int rc= 0;
if (String::needs_conversion_on_storage(length, cs, field_charset) || if (String::needs_conversion_on_storage(length, cs, field_charset()) ||
max_length < length) max_length < length)
{ {
set_if_smaller(max_length, static_cast<ulonglong>(field_charset->mbmaxlen) * length + 1); set_if_smaller(max_length, static_cast<ulonglong>(mbmaxlen()) * length + 1);
if (!(buf= (char*) my_malloc(max_length, MYF(MY_WME)))) if (!(buf= (char*) my_malloc(max_length, MYF(MY_WME))))
{ {
*out_length= 0; *out_length= 0;
@@ -8052,7 +8054,7 @@ String *Field_longstr::uncompress(String *val_buffer, String *val_ptr,
/* Uncompressed data */ /* Uncompressed data */
if (!method) if (!method)
{ {
val_ptr->set((const char*) from + 1, from_length - 1, field_charset); val_ptr->set((const char*) from + 1, from_length - 1, field_charset());
return val_ptr; return val_ptr;
} }
@@ -8061,7 +8063,7 @@ String *Field_longstr::uncompress(String *val_buffer, String *val_ptr,
if (!compression_methods[method].uncompress(val_buffer, from, from_length, if (!compression_methods[method].uncompress(val_buffer, from, from_length,
field_length)) field_length))
{ {
val_buffer->set_charset(field_charset); val_buffer->set_charset(field_charset());
status_var_increment(get_thd()->status_var.column_decompressions); status_var_increment(get_thd()->status_var.column_decompressions);
return val_buffer; return val_buffer;
} }
@@ -8073,7 +8075,7 @@ String *Field_longstr::uncompress(String *val_buffer, String *val_ptr,
safer route, let's return a zero string and let the general safer route, let's return a zero string and let the general
handler catch the error. handler catch the error.
*/ */
val_ptr->set("", 0, field_charset); val_ptr->set("", 0, field_charset());
return val_ptr; return val_ptr;
} }
@@ -8105,7 +8107,7 @@ double Field_varstring_compressed::val_real(void)
THD *thd= get_thd(); THD *thd= get_thd();
String buf; String buf;
val_str(&buf, &buf); val_str(&buf, &buf);
return Converter_strntod_with_warn(thd, Warn_filter(thd), field_charset, return Converter_strntod_with_warn(thd, Warn_filter(thd), field_charset(),
buf.ptr(), buf.length()).result(); buf.ptr(), buf.length()).result();
} }
@@ -8116,7 +8118,7 @@ longlong Field_varstring_compressed::val_int(void)
THD *thd= get_thd(); THD *thd= get_thd();
String buf; String buf;
val_str(&buf, &buf); val_str(&buf, &buf);
return Converter_strntoll_with_warn(thd, Warn_filter(thd), field_charset, return Converter_strntoll_with_warn(thd, Warn_filter(thd), field_charset(),
buf.ptr(), buf.length()).result(); buf.ptr(), buf.length()).result();
} }
@@ -8146,7 +8148,7 @@ int Field_varstring_compressed::cmp_max(const uchar *a_ptr, const uchar *b_ptr,
if (b.length() > max_len) if (b.length() > max_len)
b.length(max_len); b.length(max_len);
return sortcmp(&a, &b, field_charset); return sortcmp(&a, &b, field_charset());
} }
@@ -8191,7 +8193,7 @@ uint32 Field_blob::get_length(const uchar *pos, uint packlength_arg) const
*/ */
int Field_blob::copy_value(Field_blob *from) int Field_blob::copy_value(Field_blob *from)
{ {
DBUG_ASSERT(field_charset == from->charset()); DBUG_ASSERT(field_charset() == from->charset());
DBUG_ASSERT(!compression_method() == !from->compression_method()); DBUG_ASSERT(!compression_method() == !from->compression_method());
int rc= 0; int rc= 0;
uint32 length= from->get_length(); uint32 length= from->get_length();
@@ -8199,7 +8201,7 @@ int Field_blob::copy_value(Field_blob *from)
if (packlength < from->packlength) if (packlength < from->packlength)
{ {
set_if_smaller(length, Field_blob::max_data_length()); set_if_smaller(length, Field_blob::max_data_length());
length= (uint32) Well_formed_prefix(field_charset, length= (uint32) Well_formed_prefix(field_charset(),
(const char *) data, length).length(); (const char *) data, length).length();
rc= report_if_important_data((const char *) data + length, rc= report_if_important_data((const char *) data + length,
(const char *) data + from->get_length(), (const char *) data + from->get_length(),
@@ -8236,7 +8238,7 @@ int Field_blob::store(const char *from,size_t length,CHARSET_INFO *cs)
if (table && table->blob_storage) // GROUP_CONCAT with ORDER BY | DISTINCT if (table && table->blob_storage) // GROUP_CONCAT with ORDER BY | DISTINCT
{ {
DBUG_ASSERT(!f_is_hex_escape(flags)); DBUG_ASSERT(!f_is_hex_escape(flags));
DBUG_ASSERT(field_charset == cs); DBUG_ASSERT(field_charset() == cs);
DBUG_ASSERT(length <= max_data_length()); DBUG_ASSERT(length <= max_data_length());
new_length= length; new_length= length;
@@ -8267,7 +8269,7 @@ int Field_blob::store(const char *from,size_t length,CHARSET_INFO *cs)
If content of the 'from'-address is cached in the 'value'-object If content of the 'from'-address is cached in the 'value'-object
it is possible that the content needs a character conversion. it is possible that the content needs a character conversion.
*/ */
if (!String::needs_conversion_on_storage(length, cs, field_charset)) if (!String::needs_conversion_on_storage(length, cs, field_charset()))
{ {
Field_blob::store_length(length); Field_blob::store_length(length);
bmove(ptr + packlength, &from, sizeof(char*)); bmove(ptr + packlength, &from, sizeof(char*));
@@ -8278,14 +8280,14 @@ int Field_blob::store(const char *from,size_t length,CHARSET_INFO *cs)
from= tmpstr.ptr(); from= tmpstr.ptr();
} }
new_length= MY_MIN(max_data_length(), field_charset->mbmaxlen * length); new_length= MY_MIN(max_data_length(), mbmaxlen() * length);
if (value.alloc(new_length)) if (value.alloc(new_length))
goto oom_error; goto oom_error;
tmp= const_cast<char*>(value.ptr()); tmp= const_cast<char*>(value.ptr());
if (f_is_hex_escape(flags)) if (f_is_hex_escape(flags))
{ {
copy_length= my_copy_with_hex_escaping(field_charset, copy_length= my_copy_with_hex_escaping(field_charset(),
tmp, new_length, tmp, new_length,
from, length); from, length);
Field_blob::store_length(copy_length); Field_blob::store_length(copy_length);
@@ -8375,8 +8377,8 @@ my_decimal *Field_blob::val_decimal(my_decimal *decimal_value)
int Field_blob::cmp(const uchar *a,uint32 a_length, const uchar *b, int Field_blob::cmp(const uchar *a,uint32 a_length, const uchar *b,
uint32 b_length) const uint32 b_length) const
{ {
return field_charset->coll->strnncollsp(field_charset, return field_charset()->coll->strnncollsp(field_charset(),
a, a_length, b, b_length); a, a_length, b, b_length);
} }
@@ -8418,8 +8420,8 @@ uint Field_blob::get_key_image_itRAW(uchar *buff, uint length)
{ {
size_t blob_length= get_length(ptr); size_t blob_length= get_length(ptr);
uchar *blob= get_ptr(); uchar *blob= get_ptr();
size_t local_char_length= length / field_charset->mbmaxlen; size_t local_char_length= length / mbmaxlen();
local_char_length= my_charpos(field_charset, blob, blob + blob_length, local_char_length= my_charpos(field_charset(), blob, blob + blob_length,
local_char_length); local_char_length);
set_if_smaller(blob_length, local_char_length); set_if_smaller(blob_length, local_char_length);
@@ -8442,7 +8444,7 @@ void Field_blob::set_key_image(const uchar *buff,uint length)
{ {
length= uint2korr(buff); length= uint2korr(buff);
(void) Field_blob::store((const char*) buff+HA_KEY_BLOB_LENGTH, length, (void) Field_blob::store((const char*) buff+HA_KEY_BLOB_LENGTH, length,
field_charset); field_charset());
} }
@@ -8504,7 +8506,7 @@ int Field_blob::save_field_metadata(uchar *metadata_ptr)
uint32 Field_blob::sort_length() const uint32 Field_blob::sort_length() const
{ {
return (uint32) (get_thd()->variables.max_sort_length + return (uint32) (get_thd()->variables.max_sort_length +
(field_charset == &my_charset_bin ? 0 : packlength)); (field_charset() == &my_charset_bin ? 0 : packlength));
} }
@@ -8513,11 +8515,11 @@ void Field_blob::sort_string(uchar *to,uint length)
String buf; String buf;
val_str(&buf, &buf); val_str(&buf, &buf);
if (!buf.length() && field_charset->pad_char == 0) if (!buf.length() && field_charset()->pad_char == 0)
bzero(to,length); bzero(to,length);
else else
{ {
if (field_charset == &my_charset_bin) if (field_charset() == &my_charset_bin)
{ {
/* /*
Store length of blob last in blob to shorter blobs before longer blobs Store length of blob last in blob to shorter blobs before longer blobs
@@ -8529,10 +8531,10 @@ void Field_blob::sort_string(uchar *to,uint length)
#ifdef DBUG_ASSERT_EXISTS #ifdef DBUG_ASSERT_EXISTS
size_t rc= size_t rc=
#endif #endif
field_charset->coll->strnxfrm(field_charset, to, length, length, field_charset()->coll->strnxfrm(field_charset(), to, length, length,
(const uchar*) buf.ptr(), buf.length(), (const uchar*) buf.ptr(), buf.length(),
MY_STRXFRM_PAD_WITH_SPACE | MY_STRXFRM_PAD_WITH_SPACE |
MY_STRXFRM_PAD_TO_MAXLEN); MY_STRXFRM_PAD_TO_MAXLEN);
DBUG_ASSERT(rc == length); DBUG_ASSERT(rc == length);
} }
} }
@@ -8663,7 +8665,7 @@ bool Field_blob::is_equal(const Column_definition &new_field) const
return new_field.type_handler() == type_handler() && return new_field.type_handler() == type_handler() &&
!new_field.compression_method() == !compression_method() && !new_field.compression_method() == !compression_method() &&
new_field.pack_length == pack_length() && new_field.pack_length == pack_length() &&
new_field.charset == field_charset; new_field.charset == field_charset();
} }
@@ -8699,8 +8701,7 @@ int Field_blob_compressed::store(const char *from, size_t length,
DBUG_ASSERT(marked_for_write_or_computed()); DBUG_ASSERT(marked_for_write_or_computed());
uint compressed_length; uint compressed_length;
uint max_length= max_data_length(); uint max_length= max_data_length();
uint to_length= (uint) MY_MIN(max_length, uint to_length= (uint) MY_MIN(max_length, mbmaxlen() * length + 1);
field_charset->mbmaxlen * length + 1);
String tmp(from, length, cs); String tmp(from, length, cs);
int rc; int rc;
@@ -8734,7 +8735,7 @@ double Field_blob_compressed::val_real(void)
THD *thd= get_thd(); THD *thd= get_thd();
String buf; String buf;
val_str(&buf, &buf); val_str(&buf, &buf);
return Converter_strntod_with_warn(thd, Warn_filter(thd), field_charset, return Converter_strntod_with_warn(thd, Warn_filter(thd), field_charset(),
buf.ptr(), buf.length()).result(); buf.ptr(), buf.length()).result();
} }
@@ -8745,7 +8746,7 @@ longlong Field_blob_compressed::val_int(void)
THD *thd= get_thd(); THD *thd= get_thd();
String buf; String buf;
val_str(&buf, &buf); val_str(&buf, &buf);
return Converter_strntoll_with_warn(thd, Warn_filter(thd), field_charset, return Converter_strntoll_with_warn(thd, Warn_filter(thd), field_charset(),
buf.ptr(), buf.length()).result(); buf.ptr(), buf.length()).result();
} }
@@ -8787,17 +8788,17 @@ int Field_enum::store(const char *from,size_t length,CHARSET_INFO *cs)
String tmpstr(buff,sizeof(buff), &my_charset_bin); String tmpstr(buff,sizeof(buff), &my_charset_bin);
/* Convert character set if necessary */ /* Convert character set if necessary */
if (String::needs_conversion_on_storage(length, cs, field_charset)) if (String::needs_conversion_on_storage(length, cs, field_charset()))
{ {
uint dummy_errors; uint dummy_errors;
tmpstr.copy(from, length, cs, field_charset, &dummy_errors); tmpstr.copy(from, length, cs, field_charset(), &dummy_errors);
from= tmpstr.ptr(); from= tmpstr.ptr();
length= tmpstr.length(); length= tmpstr.length();
} }
/* Remove end space */ /* Remove end space */
length= (uint)field_charset->cset->lengthsp(field_charset, from, length); length= (uint)field_charset()->cset->lengthsp(field_charset(), from, length);
uint tmp=find_type2(typelib, from, length, field_charset); uint tmp=find_type2(typelib, from, length, field_charset());
if (!tmp) if (!tmp)
{ {
if (length < 6) // Can't be more than 99999 enums if (length < 6) // Can't be more than 99999 enums
@@ -8890,11 +8891,11 @@ String *Field_enum::val_str(String *val_buffer __attribute__((unused)),
{ {
uint tmp=(uint) Field_enum::val_int(); uint tmp=(uint) Field_enum::val_int();
if (!tmp || tmp > typelib->count) if (!tmp || tmp > typelib->count)
val_ptr->set("", 0, field_charset); val_ptr->set("", 0, field_charset());
else else
val_ptr->set((const char*) typelib->type_names[tmp-1], val_ptr->set((const char*) typelib->type_names[tmp-1],
typelib->type_lengths[tmp-1], typelib->type_lengths[tmp-1],
field_charset); field_charset());
return val_ptr; return val_ptr;
} }
@@ -8973,14 +8974,14 @@ int Field_set::store(const char *from,size_t length,CHARSET_INFO *cs)
String tmpstr(buff,sizeof(buff), &my_charset_bin); String tmpstr(buff,sizeof(buff), &my_charset_bin);
/* Convert character set if necessary */ /* Convert character set if necessary */
if (String::needs_conversion_on_storage(length, cs, field_charset)) if (String::needs_conversion_on_storage(length, cs, field_charset()))
{ {
uint dummy_errors; uint dummy_errors;
tmpstr.copy(from, length, cs, field_charset, &dummy_errors); tmpstr.copy(from, length, cs, field_charset(), &dummy_errors);
from= tmpstr.ptr(); from= tmpstr.ptr();
length= tmpstr.length(); length= tmpstr.length();
} }
ulonglong tmp= find_set(typelib, from, length, field_charset, ulonglong tmp= find_set(typelib, from, length, field_charset(),
&not_used, &not_used2, &got_warning); &not_used, &not_used2, &got_warning);
if (!tmp && length && length < 22) if (!tmp && length && length < 22)
{ {
@@ -9040,7 +9041,7 @@ String *Field_set::val_str(String *val_buffer,
return val_buffer; return val_buffer;
} }
val_buffer->set_charset(field_charset); val_buffer->set_charset(field_charset());
val_buffer->length(0); val_buffer->length(0);
while (tmp && bitnr < (uint) typelib->count) while (tmp && bitnr < (uint) typelib->count)
@@ -9051,7 +9052,7 @@ String *Field_set::val_str(String *val_buffer,
val_buffer->append(&field_separator, 1, &my_charset_latin1); val_buffer->append(&field_separator, 1, &my_charset_latin1);
String str(typelib->type_names[bitnr], String str(typelib->type_names[bitnr],
typelib->type_lengths[bitnr], typelib->type_lengths[bitnr],
field_charset); field_charset());
val_buffer->append(str); val_buffer->append(str);
} }
tmp>>=1; tmp>>=1;
@@ -9137,7 +9138,7 @@ bool Field_enum::eq_def(const Field *field) const
if (typelib->count != values->count) if (typelib->count != values->count)
return FALSE; return FALSE;
return compare_type_names(field_charset, typelib, values); return compare_type_names(field_charset(), typelib, values);
} }
@@ -9159,7 +9160,7 @@ bool Field_enum::is_equal(const Column_definition &new_field) const
type, charset and have the same underlying length. type, charset and have the same underlying length.
*/ */
if (new_field.type_handler() != type_handler() || if (new_field.type_handler() != type_handler() ||
new_field.charset != field_charset || new_field.charset != field_charset() ||
new_field.pack_length != pack_length()) new_field.pack_length != pack_length())
return false; return false;
@@ -9172,7 +9173,7 @@ bool Field_enum::is_equal(const Column_definition &new_field) const
return false; return false;
/* Check whether there are modification before the end. */ /* Check whether there are modification before the end. */
if (! compare_type_names(field_charset, typelib, new_field.interval)) if (! compare_type_names(field_charset(), typelib, new_field.interval))
return false; return false;
return true; return true;
@@ -9334,6 +9335,14 @@ Field_bit::Field_bit(uchar *ptr_arg, uint32 len_arg, uchar *null_ptr_arg,
} }
const DTCollation & Field_bit::dtcollation() const
{
static DTCollation tmp(&my_charset_bin,
DERIVATION_IMPLICIT, MY_REPERTOIRE_UNICODE30);
return tmp;
}
void Field_bit::hash(ulong *nr, ulong *nr2) void Field_bit::hash(ulong *nr, ulong *nr2)
{ {
if (is_null()) if (is_null())
@@ -10660,11 +10669,11 @@ uint32 Field_blob::max_display_length() const
switch (packlength) switch (packlength)
{ {
case 1: case 1:
return 255 * field_charset->mbmaxlen; return 255 * mbmaxlen();
case 2: case 2:
return 65535 * field_charset->mbmaxlen; return 65535 * mbmaxlen();
case 3: case 3:
return 16777215 * field_charset->mbmaxlen; return 16777215 * mbmaxlen();
case 4: case 4:
return (uint32) UINT_MAX32; return (uint32) UINT_MAX32;
default: default:
@@ -10947,7 +10956,7 @@ void Field_string::print_key_value(String *out, uint32 length)
{ {
if (charset() == &my_charset_bin) if (charset() == &my_charset_bin)
{ {
size_t len= field_charset->cset->lengthsp(field_charset, (const char*) ptr, length); size_t len= field_charset()->cset->lengthsp(field_charset(), (const char*) ptr, length);
print_key_value_binary(out, ptr, static_cast<uint32>(len)); print_key_value_binary(out, ptr, static_cast<uint32>(len));
} }
else else

View File

@@ -781,10 +781,6 @@ public:
const LEX_CSTRING *field_name_arg); const LEX_CSTRING *field_name_arg);
virtual ~Field() {} virtual ~Field() {}
DTCollation dtcollation() const
{
return DTCollation(charset(), derivation(), repertoire());
}
virtual Type_std_attributes type_std_attributes() const virtual Type_std_attributes type_std_attributes() const
{ {
return Type_std_attributes(field_length, decimals(), return Type_std_attributes(field_length, decimals(),
@@ -1424,14 +1420,12 @@ public:
uint fill_cache_field(struct st_cache_field *copy); uint fill_cache_field(struct st_cache_field *copy);
virtual bool get_date(MYSQL_TIME *ltime, date_mode_t fuzzydate); virtual bool get_date(MYSQL_TIME *ltime, date_mode_t fuzzydate);
virtual const TYPELIB *get_typelib() const { return NULL; } virtual const TYPELIB *get_typelib() const { return NULL; }
virtual CHARSET_INFO *charset(void) const { return &my_charset_bin; } virtual CHARSET_INFO *charset(void) const= 0;
virtual const DTCollation &dtcollation() const= 0;
virtual CHARSET_INFO *charset_for_protocol(void) const virtual CHARSET_INFO *charset_for_protocol(void) const
{ return binary() ? &my_charset_bin : charset(); } { return binary() ? &my_charset_bin : charset(); }
virtual CHARSET_INFO *sort_charset(void) const { return charset(); } virtual CHARSET_INFO *sort_charset(void) const { return charset(); }
virtual bool has_charset(void) const { return FALSE; } virtual bool has_charset(void) const { return FALSE; }
virtual enum Derivation derivation(void) const
{ return DERIVATION_IMPLICIT; }
virtual uint repertoire(void) const { return MY_REPERTOIRE_UNICODE30; }
virtual int set_time() { return 1; } virtual int set_time() { return 1; }
bool set_warning(Sql_condition::enum_warning_level, unsigned int code, bool set_warning(Sql_condition::enum_warning_level, unsigned int code,
int cuted_increment, ulong current_row=0) const; int cuted_increment, ulong current_row=0) const;
@@ -1826,9 +1820,14 @@ public:
uchar null_bit_arg, utype unireg_check_arg, uchar null_bit_arg, utype unireg_check_arg,
const LEX_CSTRING *field_name_arg, const LEX_CSTRING *field_name_arg,
uint8 dec_arg, bool zero_arg, bool unsigned_arg); uint8 dec_arg, bool zero_arg, bool unsigned_arg);
enum Derivation derivation(void) const { return DERIVATION_NUMERIC; } CHARSET_INFO *charset(void) const
uint repertoire(void) const { return MY_REPERTOIRE_NUMERIC; } {
CHARSET_INFO *charset(void) const { return &my_charset_numeric; } return DTCollation_numeric::singleton().collation;
}
const DTCollation &dtcollation() const
{
return DTCollation_numeric::singleton();
}
Item *get_equal_const_item(THD *thd, const Context &ctx, Item *const_item) Item *get_equal_const_item(THD *thd, const Context &ctx, Item *const_item)
{ {
return (flags & ZEROFILL_FLAG) ? return (flags & ZEROFILL_FLAG) ?
@@ -1879,10 +1878,10 @@ public:
class Field_str :public Field { class Field_str :public Field {
protected: protected:
// TODO-10.2: Reuse DTCollation instead of these three members DTCollation m_collation;
CHARSET_INFO *field_charset; // A short alias for m_collation.collation with non-virtual linkage
enum Derivation field_derivation; const CHARSET_INFO *field_charset() const { return m_collation.collation; }
uint field_repertoire; uint mbmaxlen() const { return m_collation.collation->mbmaxlen; }
public: public:
bool can_be_substituted_to_equal_item(const Context &ctx, bool can_be_substituted_to_equal_item(const Context &ctx,
const Item_equal *item_equal); const Item_equal *item_equal);
@@ -1906,13 +1905,18 @@ public:
{ {
return store(str, length, &my_charset_bin); return store(str, length, &my_charset_bin);
} }
uint repertoire(void) const { return field_repertoire; } CHARSET_INFO *charset(void) const { return m_collation.collation; }
CHARSET_INFO *charset(void) const { return field_charset; } const DTCollation &dtcollation() const
enum Derivation derivation(void) const { return field_derivation; } {
bool binary() const { return field_charset == &my_charset_bin; } return m_collation;
}
bool binary() const { return field_charset() == &my_charset_bin; }
uint32 max_display_length() const { return field_length; } uint32 max_display_length() const { return field_length; }
uint32 character_octet_length() const { return field_length; } uint32 character_octet_length() const { return field_length; }
uint32 char_length() const { return field_length / field_charset->mbmaxlen; } uint32 char_length() const
{
return field_length / mbmaxlen();
}
Information_schema_character_attributes Information_schema_character_attributes
information_schema_character_attributes() const information_schema_character_attributes() const
{ {
@@ -1961,7 +1965,7 @@ protected:
{ {
String_copier copier; String_copier copier;
*copy_length= copier.well_formed_copy(field_charset, to, to_length, *copy_length= copier.well_formed_copy(field_charset(), to, to_length,
from_cs, from, from_length, from_cs, from, from_length,
nchars); nchars);
@@ -2785,9 +2789,14 @@ public:
bool memcpy_field_possible(const Field *from) const; bool memcpy_field_possible(const Field *from) const;
uint32 max_display_length() const { return field_length; } uint32 max_display_length() const { return field_length; }
bool str_needs_quotes() { return TRUE; } bool str_needs_quotes() { return TRUE; }
enum Derivation derivation(void) const { return DERIVATION_NUMERIC; } CHARSET_INFO *charset(void) const
uint repertoire(void) const { return MY_REPERTOIRE_NUMERIC; } {
CHARSET_INFO *charset(void) const { return &my_charset_numeric; } return DTCollation_numeric::singleton().collation;
}
const DTCollation &dtcollation() const
{
return DTCollation_numeric::singleton();
}
CHARSET_INFO *sort_charset(void) const { return &my_charset_bin; } CHARSET_INFO *sort_charset(void) const { return &my_charset_bin; }
bool binary() const { return true; } bool binary() const { return true; }
bool val_bool() { return val_real() != 0e0; } bool val_bool() { return val_real() != 0e0; }
@@ -3762,7 +3771,7 @@ public:
uint32 key_length() const { return (uint32) field_length; } uint32 key_length() const { return (uint32) field_length; }
uint32 sort_length() const uint32 sort_length() const
{ {
return (uint32) field_length + (field_charset == &my_charset_bin ? return (uint32) field_length + (field_charset() == &my_charset_bin ?
length_bytes : 0); length_bytes : 0);
} }
Copy_func *get_copy_func(const Field *from) const; Copy_func *get_copy_func(const Field *from) const;
@@ -3854,7 +3863,7 @@ private:
uint32 character_octet_length() const { return field_length - 1; } uint32 character_octet_length() const { return field_length - 1; }
uint32 char_length() const uint32 char_length() const
{ {
return (field_length - 1) / field_charset->mbmaxlen; return (field_length - 1) / mbmaxlen();
} }
int cmp_max(const uchar *a_ptr, const uchar *b_ptr, uint max_len) const; int cmp_max(const uchar *a_ptr, const uchar *b_ptr, uint max_len) const;
@@ -3992,7 +4001,7 @@ public:
information_schema_character_attributes() const information_schema_character_attributes() const
{ {
uint32 octets= Field_blob::character_octet_length(); uint32 octets= Field_blob::character_octet_length();
uint32 chars= octets / field_charset->mbminlen; uint32 chars= octets / field_charset()->mbminlen;
return Information_schema_character_attributes(octets, chars); return Information_schema_character_attributes(octets, chars);
} }
void update_data_type_statistics(Data_type_statistics *st) const void update_data_type_statistics(Data_type_statistics *st) const
@@ -4411,6 +4420,8 @@ public:
enum_conv_type rpl_conv_type_from(const Conv_source &source, enum_conv_type rpl_conv_type_from(const Conv_source &source,
const Relay_log_info *rli, const Relay_log_info *rli,
const Conv_param &param) const; const Conv_param &param) const;
CHARSET_INFO *charset() const { return &my_charset_bin; }
const DTCollation & dtcollation() const;
Information_schema_numeric_attributes Information_schema_numeric_attributes
information_schema_numeric_attributes() const information_schema_numeric_attributes() const
{ {

View File

@@ -2060,7 +2060,7 @@ bool Item_name_const::fix_fields(THD *thd, Item **ref)
return TRUE; return TRUE;
} }
if (value_item->collation.derivation == DERIVATION_NUMERIC) if (value_item->collation.derivation == DERIVATION_NUMERIC)
collation.set_numeric(); collation= DTCollation_numeric();
else else
collation.set(value_item->collation.collation, DERIVATION_IMPLICIT); collation.set(value_item->collation.collation, DERIVATION_IMPLICIT);
max_length= value_item->max_length; max_length= value_item->max_length;
@@ -3923,7 +3923,7 @@ void Item_param::set_int(longlong i, uint32 max_length_arg)
DBUG_ASSERT(value.type_handler()->cmp_type() == INT_RESULT); DBUG_ASSERT(value.type_handler()->cmp_type() == INT_RESULT);
value.integer= (longlong) i; value.integer= (longlong) i;
state= SHORT_DATA_VALUE; state= SHORT_DATA_VALUE;
collation.set_numeric(); collation= DTCollation_numeric();
max_length= max_length_arg; max_length= max_length_arg;
decimals= 0; decimals= 0;
maybe_null= 0; maybe_null= 0;
@@ -3937,7 +3937,7 @@ void Item_param::set_double(double d)
DBUG_ASSERT(value.type_handler()->cmp_type() == REAL_RESULT); DBUG_ASSERT(value.type_handler()->cmp_type() == REAL_RESULT);
value.real= d; value.real= d;
state= SHORT_DATA_VALUE; state= SHORT_DATA_VALUE;
collation.set_numeric(); collation= DTCollation_numeric();
max_length= DBL_DIG + 8; max_length= DBL_DIG + 8;
decimals= NOT_FIXED_DEC; decimals= NOT_FIXED_DEC;
maybe_null= 0; maybe_null= 0;
@@ -3968,7 +3968,7 @@ void Item_param::set_decimal(const char *str, ulong length)
str2my_decimal(E_DEC_FATAL_ERROR, str, &value.m_decimal, &end); str2my_decimal(E_DEC_FATAL_ERROR, str, &value.m_decimal, &end);
state= SHORT_DATA_VALUE; state= SHORT_DATA_VALUE;
decimals= value.m_decimal.frac; decimals= value.m_decimal.frac;
collation.set_numeric(); collation= DTCollation_numeric();
max_length= max_length=
my_decimal_precision_to_length_no_truncation(value.m_decimal.precision(), my_decimal_precision_to_length_no_truncation(value.m_decimal.precision(),
decimals, unsigned_flag); decimals, unsigned_flag);
@@ -3985,7 +3985,7 @@ void Item_param::set_decimal(const my_decimal *dv, bool unsigned_arg)
my_decimal2decimal(dv, &value.m_decimal); my_decimal2decimal(dv, &value.m_decimal);
decimals= (uint8) value.m_decimal.frac; decimals= (uint8) value.m_decimal.frac;
collation.set_numeric(); collation= DTCollation_numeric();
unsigned_flag= unsigned_arg; unsigned_flag= unsigned_arg;
max_length= my_decimal_precision_to_length(value.m_decimal.intg + decimals, max_length= my_decimal_precision_to_length(value.m_decimal.intg + decimals,
decimals, unsigned_flag); decimals, unsigned_flag);
@@ -3997,7 +3997,7 @@ void Item_param::set_decimal(const my_decimal *dv, bool unsigned_arg)
void Item_param::fix_temporal(uint32 max_length_arg, uint decimals_arg) void Item_param::fix_temporal(uint32 max_length_arg, uint decimals_arg)
{ {
state= SHORT_DATA_VALUE; state= SHORT_DATA_VALUE;
collation.set_numeric(); collation= DTCollation_numeric();
max_length= max_length_arg; max_length= max_length_arg;
decimals= decimals_arg; decimals= decimals_arg;
maybe_null= 0; maybe_null= 0;

View File

@@ -3087,7 +3087,7 @@ public:
class Item_num: public Item_literal class Item_num: public Item_literal
{ {
public: public:
Item_num(THD *thd): Item_literal(thd) { collation.set_numeric(); } Item_num(THD *thd): Item_literal(thd) { collation= DTCollation_numeric(); }
Item *safe_charset_converter(THD *thd, CHARSET_INFO *tocs); Item *safe_charset_converter(THD *thd, CHARSET_INFO *tocs);
bool get_date(THD *thd, MYSQL_TIME *ltime, date_mode_t fuzzydate) bool get_date(THD *thd, MYSQL_TIME *ltime, date_mode_t fuzzydate)
{ {
@@ -4653,14 +4653,14 @@ public:
Item_temporal_literal(THD *thd, const MYSQL_TIME *ltime) Item_temporal_literal(THD *thd, const MYSQL_TIME *ltime)
:Item_literal(thd) :Item_literal(thd)
{ {
collation.set(&my_charset_numeric, DERIVATION_NUMERIC, MY_REPERTOIRE_ASCII); collation= DTCollation_numeric();
decimals= 0; decimals= 0;
cached_time= *ltime; cached_time= *ltime;
} }
Item_temporal_literal(THD *thd, const MYSQL_TIME *ltime, uint dec_arg): Item_temporal_literal(THD *thd, const MYSQL_TIME *ltime, uint dec_arg):
Item_literal(thd) Item_literal(thd)
{ {
collation.set(&my_charset_numeric, DERIVATION_NUMERIC, MY_REPERTOIRE_ASCII); collation= DTCollation_numeric();
decimals= dec_arg; decimals= dec_arg;
cached_time= *ltime; cached_time= *ltime;
} }

View File

@@ -5502,7 +5502,7 @@ bool Item_func_get_system_var::fix_length_and_dec()
case SHOW_SINT: case SHOW_SINT:
case SHOW_SLONG: case SHOW_SLONG:
case SHOW_SLONGLONG: case SHOW_SLONGLONG:
collation.set_numeric(); collation= DTCollation_numeric();
fix_char_length(MY_INT64_NUM_DECIMAL_DIGITS); fix_char_length(MY_INT64_NUM_DECIMAL_DIGITS);
decimals=0; decimals=0;
break; break;
@@ -5536,13 +5536,13 @@ bool Item_func_get_system_var::fix_length_and_dec()
break; break;
case SHOW_BOOL: case SHOW_BOOL:
case SHOW_MY_BOOL: case SHOW_MY_BOOL:
collation.set_numeric(); collation= DTCollation_numeric();
fix_char_length(1); fix_char_length(1);
decimals=0; decimals=0;
break; break;
case SHOW_DOUBLE: case SHOW_DOUBLE:
decimals= 6; decimals= 6;
collation.set_numeric(); collation= DTCollation_numeric();
fix_char_length(DBL_DIG + 6); fix_char_length(DBL_DIG + 6);
break; break;
default: default:

View File

@@ -404,13 +404,13 @@ public:
class Item_real_func :public Item_func class Item_real_func :public Item_func
{ {
public: public:
Item_real_func(THD *thd): Item_func(thd) { collation.set_numeric(); } Item_real_func(THD *thd): Item_func(thd) { collation= DTCollation_numeric(); }
Item_real_func(THD *thd, Item *a): Item_func(thd, a) Item_real_func(THD *thd, Item *a): Item_func(thd, a)
{ collation.set_numeric(); } { collation= DTCollation_numeric(); }
Item_real_func(THD *thd, Item *a, Item *b): Item_func(thd, a, b) Item_real_func(THD *thd, Item *a, Item *b): Item_func(thd, a, b)
{ collation.set_numeric(); } { collation= DTCollation_numeric(); }
Item_real_func(THD *thd, List<Item> &list): Item_func(thd, list) Item_real_func(THD *thd, List<Item> &list): Item_func(thd, list)
{ collation.set_numeric(); } { collation= DTCollation_numeric(); }
String *val_str(String*str); String *val_str(String*str);
my_decimal *val_decimal(my_decimal *decimal_value); my_decimal *val_decimal(my_decimal *decimal_value);
longlong val_int() longlong val_int()
@@ -721,19 +721,19 @@ public:
public: public:
Item_func_hybrid_field_type(THD *thd): Item_func_hybrid_field_type(THD *thd):
Item_hybrid_func(thd) Item_hybrid_func(thd)
{ collation.set_numeric(); } { collation= DTCollation_numeric(); }
Item_func_hybrid_field_type(THD *thd, Item *a): Item_func_hybrid_field_type(THD *thd, Item *a):
Item_hybrid_func(thd, a) Item_hybrid_func(thd, a)
{ collation.set_numeric(); } { collation= DTCollation_numeric(); }
Item_func_hybrid_field_type(THD *thd, Item *a, Item *b): Item_func_hybrid_field_type(THD *thd, Item *a, Item *b):
Item_hybrid_func(thd, a, b) Item_hybrid_func(thd, a, b)
{ collation.set_numeric(); } { collation= DTCollation_numeric(); }
Item_func_hybrid_field_type(THD *thd, Item *a, Item *b, Item *c): Item_func_hybrid_field_type(THD *thd, Item *a, Item *b, Item *c):
Item_hybrid_func(thd, a, b, c) Item_hybrid_func(thd, a, b, c)
{ collation.set_numeric(); } { collation= DTCollation_numeric(); }
Item_func_hybrid_field_type(THD *thd, List<Item> &list): Item_func_hybrid_field_type(THD *thd, List<Item> &list):
Item_hybrid_func(thd, list) Item_hybrid_func(thd, list)
{ collation.set_numeric(); } { collation= DTCollation_numeric(); }
double val_real() double val_real()
{ {
@@ -987,20 +987,20 @@ public:
Min signed = -9,223,372,036,854,775,808 = 19 digits, 20 characters Min signed = -9,223,372,036,854,775,808 = 19 digits, 20 characters
*/ */
Item_int_func(THD *thd): Item_func(thd) Item_int_func(THD *thd): Item_func(thd)
{ collation.set_numeric(); fix_char_length(21); } { collation= DTCollation_numeric(); fix_char_length(21); }
Item_int_func(THD *thd, Item *a): Item_func(thd, a) Item_int_func(THD *thd, Item *a): Item_func(thd, a)
{ collation.set_numeric(); fix_char_length(21); } { collation= DTCollation_numeric(); fix_char_length(21); }
Item_int_func(THD *thd, Item *a, Item *b): Item_func(thd, a, b) Item_int_func(THD *thd, Item *a, Item *b): Item_func(thd, a, b)
{ collation.set_numeric(); fix_char_length(21); } { collation= DTCollation_numeric(); fix_char_length(21); }
Item_int_func(THD *thd, Item *a, Item *b, Item *c): Item_func(thd, a, b, c) Item_int_func(THD *thd, Item *a, Item *b, Item *c): Item_func(thd, a, b, c)
{ collation.set_numeric(); fix_char_length(21); } { collation= DTCollation_numeric(); fix_char_length(21); }
Item_int_func(THD *thd, Item *a, Item *b, Item *c, Item *d): Item_int_func(THD *thd, Item *a, Item *b, Item *c, Item *d):
Item_func(thd, a, b, c, d) Item_func(thd, a, b, c, d)
{ collation.set_numeric(); fix_char_length(21); } { collation= DTCollation_numeric(); fix_char_length(21); }
Item_int_func(THD *thd, List<Item> &list): Item_func(thd, list) Item_int_func(THD *thd, List<Item> &list): Item_func(thd, list)
{ collation.set_numeric(); fix_char_length(21); } { collation= DTCollation_numeric(); fix_char_length(21); }
Item_int_func(THD *thd, Item_int_func *item) :Item_func(thd, item) Item_int_func(THD *thd, Item_int_func *item) :Item_func(thd, item)
{ collation.set_numeric(); } { collation= DTCollation_numeric(); }
double val_real(); double val_real();
String *val_str(String*str); String *val_str(String*str);
my_decimal *val_decimal(my_decimal *decimal_value) my_decimal *val_decimal(my_decimal *decimal_value)
@@ -1207,7 +1207,7 @@ public:
:Item_func(thd, a) :Item_func(thd, a)
{ {
decimals= (uint8) dec; decimals= (uint8) dec;
collation.set_numeric(); collation= DTCollation_numeric();
fix_char_length(my_decimal_precision_to_length_no_truncation(len, dec, fix_char_length(my_decimal_precision_to_length_no_truncation(len, dec,
unsigned_flag)); unsigned_flag));
} }

View File

@@ -170,7 +170,7 @@ class Item_func_month :public Item_func
{ {
public: public:
Item_func_month(THD *thd, Item *a): Item_func(thd, a) Item_func_month(THD *thd, Item *a): Item_func(thd, a)
{ collation.set_numeric(); } { collation= DTCollation_numeric(); }
longlong val_int(); longlong val_int();
double val_real() double val_real()
{ DBUG_ASSERT(fixed == 1); return (double) Item_func_month::val_int(); } { DBUG_ASSERT(fixed == 1); return (double) Item_func_month::val_int(); }
@@ -446,7 +446,7 @@ class Item_func_weekday :public Item_func
bool odbc_type; bool odbc_type;
public: public:
Item_func_weekday(THD *thd, Item *a, bool type_arg): Item_func_weekday(THD *thd, Item *a, bool type_arg):
Item_func(thd, a), odbc_type(type_arg) { collation.set_numeric(); } Item_func(thd, a), odbc_type(type_arg) { collation= DTCollation_numeric(); }
longlong val_int(); longlong val_int();
double val_real() { DBUG_ASSERT(fixed == 1); return (double) val_int(); } double val_real() { DBUG_ASSERT(fixed == 1); return (double) val_int(); }
String *val_str(String *str) String *val_str(String *str)

View File

@@ -24,6 +24,14 @@
#include "log.h" #include "log.h"
#include "tztime.h" #include "tztime.h"
const DTCollation &DTCollation_numeric::singleton()
{
static const DTCollation_numeric tmp;
return tmp;
}
Type_handler_row type_handler_row; Type_handler_row type_handler_row;
Type_handler_null type_handler_null; Type_handler_null type_handler_null;

View File

@@ -2706,9 +2706,7 @@ public:
{ } { }
void set(const DTCollation &dt) void set(const DTCollation &dt)
{ {
collation= dt.collation; *this= dt;
derivation= dt.derivation;
repertoire= dt.repertoire;
} }
void set(CHARSET_INFO *collation_arg, Derivation derivation_arg) void set(CHARSET_INFO *collation_arg, Derivation derivation_arg)
{ {
@@ -2724,12 +2722,6 @@ public:
derivation= derivation_arg; derivation= derivation_arg;
repertoire= repertoire_arg; repertoire= repertoire_arg;
} }
void set_numeric()
{
collation= &my_charset_numeric;
derivation= DERIVATION_NUMERIC;
repertoire= MY_REPERTOIRE_NUMERIC;
}
void set(CHARSET_INFO *collation_arg) void set(CHARSET_INFO *collation_arg)
{ {
collation= collation_arg; collation= collation_arg;
@@ -2763,6 +2755,17 @@ public:
}; };
class DTCollation_numeric: public DTCollation
{
public:
DTCollation_numeric()
:DTCollation(charset_info(), DERIVATION_NUMERIC, MY_REPERTOIRE_NUMERIC)
{ }
static const CHARSET_INFO *charset_info() { return &my_charset_numeric; }
static const DTCollation & singleton();
};
static inline uint32 static inline uint32
char_to_byte_length_safe(size_t char_length_arg, uint32 mbmaxlen_arg) char_to_byte_length_safe(size_t char_length_arg, uint32 mbmaxlen_arg)
{ {
@@ -2840,7 +2843,7 @@ public:
} }
void fix_attributes_temporal_not_fixed_dec(uint int_part_length, uint dec) void fix_attributes_temporal_not_fixed_dec(uint int_part_length, uint dec)
{ {
collation.set_numeric(); collation= DTCollation_numeric();
unsigned_flag= 0; unsigned_flag= 0;
fix_char_length_temporal_not_fixed_dec(int_part_length, dec); fix_char_length_temporal_not_fixed_dec(int_part_length, dec);
} }
@@ -2854,7 +2857,7 @@ public:
} }
void fix_attributes_temporal(uint int_part_length, uint dec) void fix_attributes_temporal(uint int_part_length, uint dec)
{ {
collation.set_numeric(); collation= DTCollation_numeric();
unsigned_flag= 0; unsigned_flag= 0;
decimals= MY_MIN(dec, TIME_SECOND_PART_DIGITS); decimals= MY_MIN(dec, TIME_SECOND_PART_DIGITS);
max_length= decimals + int_part_length + (dec ? 1 : 0); max_length= decimals + int_part_length + (dec ? 1 : 0);
@@ -2881,18 +2884,18 @@ public:
void aggregate_attributes_int(Item **items, uint nitems) void aggregate_attributes_int(Item **items, uint nitems)
{ {
collation.set_numeric(); collation= DTCollation_numeric();
count_only_length(items, nitems); count_only_length(items, nitems);
decimals= 0; decimals= 0;
} }
void aggregate_attributes_real(Item **items, uint nitems) void aggregate_attributes_real(Item **items, uint nitems)
{ {
collation.set_numeric(); collation= DTCollation_numeric();
count_real_length(items, nitems); count_real_length(items, nitems);
} }
void aggregate_attributes_decimal(Item **items, uint nitems) void aggregate_attributes_decimal(Item **items, uint nitems)
{ {
collation.set_numeric(); collation= DTCollation_numeric();
count_decimal_length(items, nitems); count_decimal_length(items, nitems);
} }
bool aggregate_attributes_string(const char *func_name, bool aggregate_attributes_string(const char *func_name,