diff options
Diffstat (limited to 'sql')
-rw-r--r-- | sql/field.cc | 277 | ||||
-rw-r--r-- | sql/field.h | 65 | ||||
-rw-r--r-- | sql/item.cc | 12 | ||||
-rw-r--r-- | sql/item.h | 6 | ||||
-rw-r--r-- | sql/item_func.cc | 6 | ||||
-rw-r--r-- | sql/item_func.h | 34 | ||||
-rw-r--r-- | sql/item_timefunc.h | 4 | ||||
-rw-r--r-- | sql/sql_type.cc | 8 | ||||
-rw-r--r-- | sql/sql_type.h | 31 |
9 files changed, 237 insertions, 206 deletions
diff --git a/sql/field.cc b/sql/field.cc index 07f405ef47c..8f1efbefa38 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -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, unireg_check_arg, field_name_arg) { - field_charset= collation.collation; + m_collation= collation; if (collation.collation->state & MY_CS_BINSORT) 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' 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) 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 return non-unique values 'a' and 'A'. */ - DTCollation tmp(field_charset, field_derivation, repertoire()); - return !tmp.aggregate(item->collation) && tmp.collation == field_charset; + DTCollation tmp(dtcollation()); + 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()); return new_field.type_handler() == type_handler() && - new_field.charset == field_charset && + new_field.charset == field_charset() && 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(); 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) 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, cs, from, length, - field_length / field_charset->mbmaxlen, + Field_string::char_length(), false, ©_length); /* Append spaces if the string was shorter than the field. */ if (copy_length < field_length) - field_charset->cset->fill(field_charset,(char*) ptr+copy_length, - field_length-copy_length, - field_charset->pad_char); + field_charset()->cset->fill(field_charset(), + (char*) ptr + copy_length, + field_length - copy_length, + field_charset()->pad_char); return rc; } @@ -7032,13 +7031,13 @@ int Field_str::store(longlong nr, bool unsigned_val) { char buff[64]; uint length; - length= (uint) (field_charset->cset->longlong10_to_str)(field_charset, - buff, - sizeof(buff), - (unsigned_val ? 10: - -10), - nr); - return store(buff, length, field_charset); + length= (uint) (field_charset()->cset->longlong10_to_str)(field_charset(), + buff, + sizeof(buff), + (unsigned_val ? 10: + -10), + nr); + return store(buff, length, field_charset()); } @@ -7054,8 +7053,7 @@ int Field_str::store(double nr) { DBUG_ASSERT(marked_for_write_or_computed()); char buff[DOUBLE_TO_STRING_CONVERSION_BUFFER_SIZE]; - uint local_char_length= MY_MIN(sizeof(buff), - field_length / field_charset->mbmaxlen); + uint local_char_length= MY_MIN(sizeof(buff), Field_str::char_length()); size_t 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()); return new_field.type_handler() == type_handler() && new_field.char_length == char_length() && - new_field.charset == field_charset && + new_field.charset == field_charset() && 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) :Warn_filter(!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; if (get_thd()->variables.sql_mode & MODE_PAD_CHAR_TO_FULL_LENGTH) - length= my_charpos(field_charset, ptr, ptr + field_length, - field_length / field_charset->mbmaxlen); + length= my_charpos(field_charset(), ptr, ptr + field_length, + Field_string::char_length()); else - length= field_charset->cset->lengthsp(field_charset, (const char*) ptr, - field_length); - val_ptr->set((const char*) ptr, length, field_charset); + length= field_charset()->cset->lengthsp(field_charset(), + (const char*) ptr, + field_length); + val_ptr->set((const char*) ptr, length, field_charset()); 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; - if (field_charset->mbmaxlen != 1) + if (mbmaxlen() != 1) { - size_t char_len= field_length/field_charset->mbmaxlen; - 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); + size_t char_len= Field_string::char_length(); + 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); } else 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 like in latin_de 'ae' and 0xe4 */ - return field_charset->coll->strnncollsp(field_charset, - a_ptr, a_len, - b_ptr, b_len); + return field_charset()->coll->strnncollsp(field_charset(), + a_ptr, a_len, + b_ptr, b_len); } @@ -7285,13 +7284,13 @@ void Field_string::sort_string(uchar *to,uint length) #ifdef DBUG_ASSERT_EXISTS size_t tmp= #endif - field_charset->coll->strnxfrm(field_charset, - to, length, - char_length() * - field_charset->strxfrm_multiply, - ptr, field_length, - MY_STRXFRM_PAD_WITH_SPACE | - MY_STRXFRM_PAD_TO_MAXLEN); + field_charset()->coll->strnxfrm(field_charset(), + to, length, + char_length() * + field_charset()->strxfrm_multiply, + ptr, field_length, + MY_STRXFRM_PAD_WITH_SPACE | + MY_STRXFRM_PAD_TO_MAXLEN); 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) { 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, 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); 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 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 --; } 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 *to++= (uchar) length; @@ -7412,7 +7412,10 @@ Field_string::unpack(uchar *to, const uchar *from, const uchar *from_end, memcpy(to, from, length); // 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; } @@ -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) { - size_t bytes = my_charpos(field_charset, (char*) ptr, - (char*) ptr + field_length, - length / field_charset->mbmaxlen); + size_t bytes= my_charpos(field_charset(), (char*) ptr, + (char*) ptr + field_length, + length / mbmaxlen()); memcpy(buff, ptr, bytes); if (bytes < length) - field_charset->cset->fill(field_charset, (char*) buff + bytes, - length - bytes, field_charset->pad_char); + field_charset()->cset->fill(field_charset(), + (char*) buff + bytes, + length - bytes, + field_charset()->pad_char); 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, cs, from, length, - field_length / field_charset->mbmaxlen, + Field_varstring::char_length(), true, ©_length); store_length(copy_length); @@ -7592,7 +7597,7 @@ String *Field_varstring::val_str(String *val_buffer __attribute__((unused)), String *val_ptr) { 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; } @@ -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(b_length, max_len); - diff= field_charset->coll->strnncollsp(field_charset, - a_ptr+ - length_bytes, - a_length, - b_ptr+ - length_bytes, - b_length); + diff= field_charset()->coll->strnncollsp(field_charset(), + a_ptr + length_bytes, a_length, + b_ptr + length_bytes, b_length); 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 { 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, - ptr + length_bytes + length, local_char_length); + local_char_length= my_charpos(field_charset(), ptr + length_bytes, + ptr + length_bytes + length, local_char_length); set_if_smaller(length, local_char_length); - return field_charset->coll->strnncollsp(field_charset, - ptr + length_bytes, - length, - key_ptr+ - HA_KEY_BLOB_LENGTH, - uint2korr(key_ptr)); + return field_charset()->coll->strnncollsp(field_charset(), + ptr + length_bytes, + length, + key_ptr + HA_KEY_BLOB_LENGTH, + 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 { - return field_charset->coll->strnncollsp(field_charset, - a + HA_KEY_BLOB_LENGTH, - uint2korr(a), - b + HA_KEY_BLOB_LENGTH, - uint2korr(b)); + return field_charset()->coll->strnncollsp(field_charset(), + a + HA_KEY_BLOB_LENGTH, + uint2korr(a), + b + HA_KEY_BLOB_LENGTH, + uint2korr(b)); } @@ -7686,7 +7686,7 @@ void Field_varstring::sort_string(uchar *to,uint length) 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 */ if (length_bytes == 1) @@ -7699,11 +7699,13 @@ void Field_varstring::sort_string(uchar *to,uint length) #ifdef DBUG_ASSERT_EXISTS size_t rc= #endif - field_charset->coll->strnxfrm(field_charset, to, length, - char_length() * field_charset->strxfrm_multiply, - (const uchar*) buf.ptr(), buf.length(), - MY_STRXFRM_PAD_WITH_SPACE | - MY_STRXFRM_PAD_TO_MAXLEN); + field_charset()->coll->strnxfrm(field_charset(), + to, length, + char_length() * + field_charset()->strxfrm_multiply, + (const uchar*) buf.ptr(), buf.length(), + MY_STRXFRM_PAD_WITH_SPACE | + MY_STRXFRM_PAD_TO_MAXLEN); DBUG_ASSERT(rc == length); } @@ -7844,7 +7846,7 @@ uint Field_varstring::get_key_image(uchar *buff, uint length, val_str(&val, &val); 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()) val.length(local_char_length); /* 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) { 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.char_length == char_length() && !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; 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) { - 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)))) { *out_length= 0; @@ -8052,7 +8054,7 @@ String *Field_longstr::uncompress(String *val_buffer, String *val_ptr, /* Uncompressed data */ 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; } @@ -8061,7 +8063,7 @@ String *Field_longstr::uncompress(String *val_buffer, String *val_ptr, if (!compression_methods[method].uncompress(val_buffer, from, from_length, field_length)) { - val_buffer->set_charset(field_charset); + val_buffer->set_charset(field_charset()); status_var_increment(get_thd()->status_var.column_decompressions); 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 handler catch the error. */ - val_ptr->set("", 0, field_charset); + val_ptr->set("", 0, field_charset()); return val_ptr; } @@ -8105,7 +8107,7 @@ double Field_varstring_compressed::val_real(void) THD *thd= get_thd(); String 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(); } @@ -8116,7 +8118,7 @@ longlong Field_varstring_compressed::val_int(void) THD *thd= get_thd(); String 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(); } @@ -8146,7 +8148,7 @@ int Field_varstring_compressed::cmp_max(const uchar *a_ptr, const uchar *b_ptr, if (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) { - DBUG_ASSERT(field_charset == from->charset()); + DBUG_ASSERT(field_charset() == from->charset()); DBUG_ASSERT(!compression_method() == !from->compression_method()); int rc= 0; uint32 length= from->get_length(); @@ -8199,7 +8201,7 @@ int Field_blob::copy_value(Field_blob *from) if (packlength < from->packlength) { 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(); rc= report_if_important_data((const char *) data + 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 { DBUG_ASSERT(!f_is_hex_escape(flags)); - DBUG_ASSERT(field_charset == cs); + DBUG_ASSERT(field_charset() == cs); DBUG_ASSERT(length <= max_data_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 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); 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(); } - 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)) goto oom_error; tmp= const_cast<char*>(value.ptr()); 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, from, 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, uint32 b_length) const { - return field_charset->coll->strnncollsp(field_charset, - a, a_length, b, b_length); + return field_charset()->coll->strnncollsp(field_charset(), + 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); uchar *blob= get_ptr(); - size_t local_char_length= length / field_charset->mbmaxlen; - local_char_length= my_charpos(field_charset, blob, blob + blob_length, + size_t local_char_length= length / mbmaxlen(); + local_char_length= my_charpos(field_charset(), blob, blob + 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); (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 { 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; val_str(&buf, &buf); - if (!buf.length() && field_charset->pad_char == 0) + if (!buf.length() && field_charset()->pad_char == 0) bzero(to,length); 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 @@ -8529,10 +8531,10 @@ void Field_blob::sort_string(uchar *to,uint length) #ifdef DBUG_ASSERT_EXISTS size_t rc= #endif - field_charset->coll->strnxfrm(field_charset, to, length, length, - (const uchar*) buf.ptr(), buf.length(), - MY_STRXFRM_PAD_WITH_SPACE | - MY_STRXFRM_PAD_TO_MAXLEN); + field_charset()->coll->strnxfrm(field_charset(), to, length, length, + (const uchar*) buf.ptr(), buf.length(), + MY_STRXFRM_PAD_WITH_SPACE | + MY_STRXFRM_PAD_TO_MAXLEN); 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() && !new_field.compression_method() == !compression_method() && 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()); uint compressed_length; uint max_length= max_data_length(); - uint to_length= (uint) MY_MIN(max_length, - field_charset->mbmaxlen * length + 1); + uint to_length= (uint) MY_MIN(max_length, mbmaxlen() * length + 1); String tmp(from, length, cs); int rc; @@ -8734,7 +8735,7 @@ double Field_blob_compressed::val_real(void) THD *thd= get_thd(); String 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(); } @@ -8745,7 +8746,7 @@ longlong Field_blob_compressed::val_int(void) THD *thd= get_thd(); String 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(); } @@ -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); /* 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; - tmpstr.copy(from, length, cs, field_charset, &dummy_errors); + tmpstr.copy(from, length, cs, field_charset(), &dummy_errors); from= tmpstr.ptr(); length= tmpstr.length(); } /* Remove end space */ - length= (uint)field_charset->cset->lengthsp(field_charset, from, length); - uint tmp=find_type2(typelib, from, length, field_charset); + length= (uint)field_charset()->cset->lengthsp(field_charset(), from, length); + uint tmp=find_type2(typelib, from, length, field_charset()); if (!tmp) { 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(); if (!tmp || tmp > typelib->count) - val_ptr->set("", 0, field_charset); + val_ptr->set("", 0, field_charset()); else val_ptr->set((const char*) typelib->type_names[tmp-1], typelib->type_lengths[tmp-1], - field_charset); + field_charset()); 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); /* 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; - tmpstr.copy(from, length, cs, field_charset, &dummy_errors); + tmpstr.copy(from, length, cs, field_charset(), &dummy_errors); from= tmpstr.ptr(); length= tmpstr.length(); } - ulonglong tmp= find_set(typelib, from, length, field_charset, + ulonglong tmp= find_set(typelib, from, length, field_charset(), ¬_used, ¬_used2, &got_warning); if (!tmp && length && length < 22) { @@ -9040,7 +9041,7 @@ String *Field_set::val_str(String *val_buffer, return val_buffer; } - val_buffer->set_charset(field_charset); + val_buffer->set_charset(field_charset()); val_buffer->length(0); 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); String str(typelib->type_names[bitnr], typelib->type_lengths[bitnr], - field_charset); + field_charset()); val_buffer->append(str); } tmp>>=1; @@ -9137,7 +9138,7 @@ bool Field_enum::eq_def(const Field *field) const if (typelib->count != values->count) 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. */ if (new_field.type_handler() != type_handler() || - new_field.charset != field_charset || + new_field.charset != field_charset() || new_field.pack_length != pack_length()) return false; @@ -9172,7 +9173,7 @@ bool Field_enum::is_equal(const Column_definition &new_field) const return false; /* 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 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) { if (is_null()) @@ -10660,11 +10669,11 @@ uint32 Field_blob::max_display_length() const switch (packlength) { case 1: - return 255 * field_charset->mbmaxlen; + return 255 * mbmaxlen(); case 2: - return 65535 * field_charset->mbmaxlen; + return 65535 * mbmaxlen(); case 3: - return 16777215 * field_charset->mbmaxlen; + return 16777215 * mbmaxlen(); case 4: return (uint32) UINT_MAX32; default: @@ -10947,7 +10956,7 @@ void Field_string::print_key_value(String *out, uint32 length) { 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)); } else diff --git a/sql/field.h b/sql/field.h index 18404e5a7bd..634063fe774 100644 --- a/sql/field.h +++ b/sql/field.h @@ -781,10 +781,6 @@ public: const LEX_CSTRING *field_name_arg); virtual ~Field() {} - DTCollation dtcollation() const - { - return DTCollation(charset(), derivation(), repertoire()); - } virtual Type_std_attributes type_std_attributes() const { return Type_std_attributes(field_length, decimals(), @@ -1424,14 +1420,12 @@ public: uint fill_cache_field(struct st_cache_field *copy); virtual bool get_date(MYSQL_TIME *ltime, date_mode_t fuzzydate); 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 { return binary() ? &my_charset_bin : charset(); } virtual CHARSET_INFO *sort_charset(void) const { return charset(); } 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; } bool set_warning(Sql_condition::enum_warning_level, unsigned int code, int cuted_increment, ulong current_row=0) const; @@ -1826,9 +1820,14 @@ public: uchar null_bit_arg, utype unireg_check_arg, const LEX_CSTRING *field_name_arg, uint8 dec_arg, bool zero_arg, bool unsigned_arg); - enum Derivation derivation(void) const { return DERIVATION_NUMERIC; } - uint repertoire(void) const { return MY_REPERTOIRE_NUMERIC; } - CHARSET_INFO *charset(void) const { return &my_charset_numeric; } + CHARSET_INFO *charset(void) const + { + 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) { return (flags & ZEROFILL_FLAG) ? @@ -1879,10 +1878,10 @@ public: class Field_str :public Field { protected: - // TODO-10.2: Reuse DTCollation instead of these three members - CHARSET_INFO *field_charset; - enum Derivation field_derivation; - uint field_repertoire; + DTCollation m_collation; + // A short alias for m_collation.collation with non-virtual linkage + const CHARSET_INFO *field_charset() const { return m_collation.collation; } + uint mbmaxlen() const { return m_collation.collation->mbmaxlen; } public: bool can_be_substituted_to_equal_item(const Context &ctx, const Item_equal *item_equal); @@ -1906,13 +1905,18 @@ public: { return store(str, length, &my_charset_bin); } - uint repertoire(void) const { return field_repertoire; } - CHARSET_INFO *charset(void) const { return field_charset; } - enum Derivation derivation(void) const { return field_derivation; } - bool binary() const { return field_charset == &my_charset_bin; } + CHARSET_INFO *charset(void) const { return m_collation.collation; } + const DTCollation &dtcollation() const + { + return m_collation; + } + bool binary() const { return field_charset() == &my_charset_bin; } uint32 max_display_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() const { @@ -1961,7 +1965,7 @@ protected: { 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, nchars); @@ -2785,9 +2789,14 @@ public: bool memcpy_field_possible(const Field *from) const; uint32 max_display_length() const { return field_length; } bool str_needs_quotes() { return TRUE; } - enum Derivation derivation(void) const { return DERIVATION_NUMERIC; } - uint repertoire(void) const { return MY_REPERTOIRE_NUMERIC; } - CHARSET_INFO *charset(void) const { return &my_charset_numeric; } + CHARSET_INFO *charset(void) const + { + return DTCollation_numeric::singleton().collation; + } + const DTCollation &dtcollation() const + { + return DTCollation_numeric::singleton(); + } CHARSET_INFO *sort_charset(void) const { return &my_charset_bin; } bool binary() const { return true; } bool val_bool() { return val_real() != 0e0; } @@ -3762,7 +3771,7 @@ public: uint32 key_length() const { return (uint32) field_length; } 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); } Copy_func *get_copy_func(const Field *from) const; @@ -3854,7 +3863,7 @@ private: uint32 character_octet_length() const { return field_length - 1; } 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; @@ -3992,7 +4001,7 @@ public: information_schema_character_attributes() const { 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); } 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, const Relay_log_info *rli, const Conv_param ¶m) const; + CHARSET_INFO *charset() const { return &my_charset_bin; } + const DTCollation & dtcollation() const; Information_schema_numeric_attributes information_schema_numeric_attributes() const { diff --git a/sql/item.cc b/sql/item.cc index b460b01bb8d..0c598fbab9e 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -2060,7 +2060,7 @@ bool Item_name_const::fix_fields(THD *thd, Item **ref) return TRUE; } if (value_item->collation.derivation == DERIVATION_NUMERIC) - collation.set_numeric(); + collation= DTCollation_numeric(); else collation.set(value_item->collation.collation, DERIVATION_IMPLICIT); 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); value.integer= (longlong) i; state= SHORT_DATA_VALUE; - collation.set_numeric(); + collation= DTCollation_numeric(); max_length= max_length_arg; decimals= 0; maybe_null= 0; @@ -3937,7 +3937,7 @@ void Item_param::set_double(double d) DBUG_ASSERT(value.type_handler()->cmp_type() == REAL_RESULT); value.real= d; state= SHORT_DATA_VALUE; - collation.set_numeric(); + collation= DTCollation_numeric(); max_length= DBL_DIG + 8; decimals= NOT_FIXED_DEC; 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); state= SHORT_DATA_VALUE; decimals= value.m_decimal.frac; - collation.set_numeric(); + collation= DTCollation_numeric(); max_length= my_decimal_precision_to_length_no_truncation(value.m_decimal.precision(), 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); decimals= (uint8) value.m_decimal.frac; - collation.set_numeric(); + collation= DTCollation_numeric(); unsigned_flag= unsigned_arg; max_length= my_decimal_precision_to_length(value.m_decimal.intg + decimals, 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) { state= SHORT_DATA_VALUE; - collation.set_numeric(); + collation= DTCollation_numeric(); max_length= max_length_arg; decimals= decimals_arg; maybe_null= 0; diff --git a/sql/item.h b/sql/item.h index 14c29fe4e6a..db879e51077 100644 --- a/sql/item.h +++ b/sql/item.h @@ -3087,7 +3087,7 @@ public: class Item_num: public Item_literal { 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); 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_literal(thd) { - collation.set(&my_charset_numeric, DERIVATION_NUMERIC, MY_REPERTOIRE_ASCII); + collation= DTCollation_numeric(); decimals= 0; cached_time= *ltime; } Item_temporal_literal(THD *thd, const MYSQL_TIME *ltime, uint dec_arg): Item_literal(thd) { - collation.set(&my_charset_numeric, DERIVATION_NUMERIC, MY_REPERTOIRE_ASCII); + collation= DTCollation_numeric(); decimals= dec_arg; cached_time= *ltime; } diff --git a/sql/item_func.cc b/sql/item_func.cc index 24ab48adf4b..eb569aced9b 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -5502,7 +5502,7 @@ bool Item_func_get_system_var::fix_length_and_dec() case SHOW_SINT: case SHOW_SLONG: case SHOW_SLONGLONG: - collation.set_numeric(); + collation= DTCollation_numeric(); fix_char_length(MY_INT64_NUM_DECIMAL_DIGITS); decimals=0; break; @@ -5536,13 +5536,13 @@ bool Item_func_get_system_var::fix_length_and_dec() break; case SHOW_BOOL: case SHOW_MY_BOOL: - collation.set_numeric(); + collation= DTCollation_numeric(); fix_char_length(1); decimals=0; break; case SHOW_DOUBLE: decimals= 6; - collation.set_numeric(); + collation= DTCollation_numeric(); fix_char_length(DBL_DIG + 6); break; default: diff --git a/sql/item_func.h b/sql/item_func.h index 17f5378910c..2e97611699c 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -404,13 +404,13 @@ public: class Item_real_func :public Item_func { 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) - { collation.set_numeric(); } + { collation= DTCollation_numeric(); } 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) - { collation.set_numeric(); } + { collation= DTCollation_numeric(); } String *val_str(String*str); my_decimal *val_decimal(my_decimal *decimal_value); longlong val_int() @@ -721,19 +721,19 @@ public: public: Item_func_hybrid_field_type(THD *thd): Item_hybrid_func(thd) - { collation.set_numeric(); } + { collation= DTCollation_numeric(); } Item_func_hybrid_field_type(THD *thd, Item *a): Item_hybrid_func(thd, a) - { collation.set_numeric(); } + { collation= DTCollation_numeric(); } Item_func_hybrid_field_type(THD *thd, Item *a, Item *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_hybrid_func(thd, a, b, c) - { collation.set_numeric(); } + { collation= DTCollation_numeric(); } Item_func_hybrid_field_type(THD *thd, List<Item> &list): Item_hybrid_func(thd, list) - { collation.set_numeric(); } + { collation= DTCollation_numeric(); } double val_real() { @@ -987,20 +987,20 @@ public: Min signed = -9,223,372,036,854,775,808 = 19 digits, 20 characters */ 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) - { 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) - { 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) - { 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_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) - { 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) - { collation.set_numeric(); } + { collation= DTCollation_numeric(); } double val_real(); String *val_str(String*str); my_decimal *val_decimal(my_decimal *decimal_value) @@ -1207,7 +1207,7 @@ public: :Item_func(thd, a) { decimals= (uint8) dec; - collation.set_numeric(); + collation= DTCollation_numeric(); fix_char_length(my_decimal_precision_to_length_no_truncation(len, dec, unsigned_flag)); } diff --git a/sql/item_timefunc.h b/sql/item_timefunc.h index ae65e1fec18..65fd223d6d4 100644 --- a/sql/item_timefunc.h +++ b/sql/item_timefunc.h @@ -170,7 +170,7 @@ class Item_func_month :public Item_func { public: Item_func_month(THD *thd, Item *a): Item_func(thd, a) - { collation.set_numeric(); } + { collation= DTCollation_numeric(); } longlong val_int(); double val_real() { 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; public: 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(); double val_real() { DBUG_ASSERT(fixed == 1); return (double) val_int(); } String *val_str(String *str) diff --git a/sql/sql_type.cc b/sql/sql_type.cc index 103cd255b94..b618622b531 100644 --- a/sql/sql_type.cc +++ b/sql/sql_type.cc @@ -24,6 +24,14 @@ #include "log.h" #include "tztime.h" + +const DTCollation &DTCollation_numeric::singleton() +{ + static const DTCollation_numeric tmp; + return tmp; +} + + Type_handler_row type_handler_row; Type_handler_null type_handler_null; diff --git a/sql/sql_type.h b/sql/sql_type.h index 6eeca58df01..8f1d51b1aab 100644 --- a/sql/sql_type.h +++ b/sql/sql_type.h @@ -2706,9 +2706,7 @@ public: { } void set(const DTCollation &dt) { - collation= dt.collation; - derivation= dt.derivation; - repertoire= dt.repertoire; + *this= dt; } void set(CHARSET_INFO *collation_arg, Derivation derivation_arg) { @@ -2724,12 +2722,6 @@ public: derivation= derivation_arg; repertoire= repertoire_arg; } - void set_numeric() - { - collation= &my_charset_numeric; - derivation= DERIVATION_NUMERIC; - repertoire= MY_REPERTOIRE_NUMERIC; - } void set(CHARSET_INFO *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 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) { - collation.set_numeric(); + collation= DTCollation_numeric(); unsigned_flag= 0; 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) { - collation.set_numeric(); + collation= DTCollation_numeric(); unsigned_flag= 0; decimals= MY_MIN(dec, TIME_SECOND_PART_DIGITS); max_length= decimals + int_part_length + (dec ? 1 : 0); @@ -2881,18 +2884,18 @@ public: void aggregate_attributes_int(Item **items, uint nitems) { - collation.set_numeric(); + collation= DTCollation_numeric(); count_only_length(items, nitems); decimals= 0; } void aggregate_attributes_real(Item **items, uint nitems) { - collation.set_numeric(); + collation= DTCollation_numeric(); count_real_length(items, nitems); } void aggregate_attributes_decimal(Item **items, uint nitems) { - collation.set_numeric(); + collation= DTCollation_numeric(); count_decimal_length(items, nitems); } bool aggregate_attributes_string(const char *func_name, |