From c555dc768f80b2836bf14cdb437e1f4920964b83 Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Sun, 22 Apr 2018 13:30:31 +0400 Subject: [PATCH] MDEV-15971 Split the code for CHARACTER_OCTET_LENGTH and CHARACTER_MAXIMUM_LENGTH into methods in Field --- sql/field.cc | 6 ++++++ sql/field.h | 30 ++++++++++++++++++++++++++++++ sql/sql_show.cc | 21 ++++++++------------- sql/sql_type.h | 28 ++++++++++++++++++++++++++++ 4 files changed, 72 insertions(+), 13 deletions(-) diff --git a/sql/field.cc b/sql/field.cc index fceb3cc17d7..11672f38c03 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -10997,6 +10997,12 @@ Column_definition::redefine_stage1_common(const Column_definition *dup_field, */ uint32 Field_blob::char_length() const +{ + return Field_blob::octet_length(); +} + + +uint32 Field_blob::octet_length() const { switch (packlength) { diff --git a/sql/field.h b/sql/field.h index cdb62d6af16..cb182877a9f 100644 --- a/sql/field.h +++ b/sql/field.h @@ -1121,6 +1121,11 @@ public: { return Information_schema_numeric_attributes(); } + virtual Information_schema_character_attributes + information_schema_character_attributes() const + { + return Information_schema_character_attributes(); + } /* Caller beware: sql_type can change str.Ptr, so check ptr() to see if it changed if you are using your own buffer @@ -1731,6 +1736,13 @@ public: enum Derivation derivation(void) const { return field_derivation; } bool binary() const { return field_charset == &my_charset_bin; } uint32 max_display_length() const { return field_length; } + uint32 char_length() const { return field_length / field_charset->mbmaxlen; } + Information_schema_character_attributes + information_schema_character_attributes() const + { + return Information_schema_character_attributes(field_length, + char_length()); + } friend class Create_field; my_decimal *val_decimal(my_decimal *); bool val_bool() { return val_real() != 0e0; } @@ -2424,6 +2436,11 @@ public: unireg_check_arg, field_name_arg, collation) {} const Type_handler *type_handler() const { return &type_handler_null; } + Information_schema_character_attributes + information_schema_character_attributes() const + { + return Information_schema_character_attributes(); + } Copy_func *get_copy_func(const Field *from) const { return do_field_string; @@ -3564,6 +3581,13 @@ public: } enum ha_base_keytype key_type() const { return binary() ? HA_KEYTYPE_VARBINARY2 : HA_KEYTYPE_VARTEXT2; } + Information_schema_character_attributes + information_schema_character_attributes() const + { + uint32 octets= Field_blob::octet_length(); + uint32 chars= octets / field_charset->mbminlen; + return Information_schema_character_attributes(octets, chars); + } Copy_func *get_copy_func(const Field *from) const { /* @@ -3726,6 +3750,7 @@ public: { return charset() == &my_charset_bin ? FALSE : TRUE; } uint32 max_display_length() const; uint32 char_length() const; + uint32 octet_length() const; uint is_equal(Create_field *new_field); private: int save_field_metadata(uchar *first_byte); @@ -3808,6 +3833,11 @@ public: { return MYSQL_TYPE_GEOMETRY; } + Information_schema_character_attributes + information_schema_character_attributes() const + { + return Information_schema_character_attributes(); + } bool can_optimize_range(const Item_bool_func *cond, const Item *item, bool is_eq_func) const; diff --git a/sql/sql_show.cc b/sql/sql_show.cc index a45ca325d1a..e51633033ba 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -5635,7 +5635,6 @@ err: static void store_column_type(TABLE *table, Field *field, CHARSET_INFO *cs, uint offset) { - bool is_blob; const char *tmp_buff; char column_type_buff[MAX_FIELD_WIDTH]; String column_type(column_type_buff, sizeof(column_type_buff), cs); @@ -5661,22 +5660,18 @@ static void store_column_type(TABLE *table, Field *field, CHARSET_INFO *cs, (tmp_buff ? (uint)(tmp_buff - column_type.ptr()) : column_type.length()), cs); - is_blob= (field->type() == MYSQL_TYPE_BLOB); - if (field->has_charset() || is_blob || - field->real_type() == MYSQL_TYPE_VARCHAR || // For varbinary type - field->real_type() == MYSQL_TYPE_STRING) // For binary type + Information_schema_character_attributes cattr= + field->information_schema_character_attributes(); + if (cattr.has_char_length()) { - uint32 octet_max_length= field->max_display_length(); - if (is_blob && octet_max_length != (uint32) UINT_MAX32) - octet_max_length /= field->charset()->mbmaxlen; - longlong char_max_len= is_blob ? - (longlong) octet_max_length / field->charset()->mbminlen : - (longlong) octet_max_length / field->charset()->mbmaxlen; /* CHARACTER_MAXIMUM_LENGTH column*/ - table->field[offset + 1]->store(char_max_len, TRUE); + table->field[offset + 1]->store((longlong) cattr.char_length(), true); table->field[offset + 1]->set_notnull(); + } + if (cattr.has_octet_length()) + { /* CHARACTER_OCTET_LENGTH column */ - table->field[offset + 2]->store((longlong) octet_max_length, TRUE); + table->field[offset + 2]->store((longlong) cattr.octet_length(), true); table->field[offset + 2]->set_notnull(); } diff --git a/sql/sql_type.h b/sql/sql_type.h index e9307db7125..8d1884f3860 100644 --- a/sql/sql_type.h +++ b/sql/sql_type.h @@ -951,6 +951,34 @@ public: }; +class Information_schema_character_attributes +{ + uint32 m_octet_length; + uint32 m_char_length; + bool m_is_set; +public: + Information_schema_character_attributes() + :m_octet_length(0), m_char_length(0), m_is_set(false) + { } + Information_schema_character_attributes(uint32 octet_length, + uint32 char_length) + :m_octet_length(octet_length), m_char_length(char_length), m_is_set(true) + { } + bool has_octet_length() const { return m_is_set; } + bool has_char_length() const { return m_is_set; } + uint32 octet_length() const + { + DBUG_ASSERT(has_octet_length()); + return m_octet_length; + } + uint char_length() const + { + DBUG_ASSERT(has_char_length()); + return m_char_length; + } +}; + + class Type_handler { protected: