mirror of
https://github.com/MariaDB/server.git
synced 2026-01-06 05:22:24 +03:00
MDEV-11672 mysql_list_field() returns wrong default values for VIEW
The problem happened because Item_ident_for_show::field_type() always
returned MYSQL_TYPE_DOUBLE and ignored the actual data type of the
referenced Field. As a result, the execution always used
Item_ident_for_show::val_real() to send the default value of the field,
so most default values for non-numeric types were displayed as '0'.
This patch:
1. Cleanup:
a. Removes Send_field::charsetnr, as it's been unused since
introduction of Item::charset_for_protocol() in MySQL-5.5.
b. Adds the "const" qualifier to Field::char_length().
This is needed for (5.a), see below.
2. Introduces a new virtual method Type_handler::charset_for_protocol(),
returning item->collation.collation for string data types, or
&my_charset_bin for non-string data types.
3. Changes Item::charset_for_protocol() from virtual to non-virtual.
It now calls type_handler()->charset_for_protocol().
As a good side effect, duplicate code in Item::charset_for_protocol() and
Item_temporal_hybrid_func::charset_for_protocol() is now gone.
4. Fixes Item_ident_for_show::field_type() to correctly return
its data type according to the data type of the referenced field.
This actually fixes the problem reported in MDEV-11672.
Now the default value is sent using a correct method, e.g.
val_str() for VARCHAR/TEXT, or val_int() for INT/BIGINT.
This required additional changes:
a. in DBUG_ASSERT in Protocol::store(const char *,size_t,CHARSET_INFO),
This method is now used by mysqld_list_fields(), which
(unlike normal SELECT queries) does not set
field_types/field_pos/field_count.
b. Item_ident_for_show::Item_ident_for_show() now set standard attributes
(collation, decimals, max_length, unsigned_flag) according to the
referenced field, to make charset_for_protocol() return the correct
value and to make mysqld_list_fields() correctly send default
values.
5. In order to share the code between Item_field::set_field() and
Item_ident_for_show::Item_ident_for_show():
a. Introduces a new method Type_std_attributes::set(const Field*)
b. To make (a) possible, moves Item::fix_char_length() from Item
to Type_std_attributes, also moves char_to_byte_length_safe()
from item.h to sql_type.h
c. Additionally, moves Item::fix_length_and_charset() and
Item::max_char_length() from Item to Type_std_attributes.
This is not directly needed for the fix and is done just for symmetry
with fix_char_length(), as these three methods are directly related
to each other.
This commit is contained in:
@@ -176,6 +176,13 @@ public:
|
||||
};
|
||||
|
||||
|
||||
static inline uint32
|
||||
char_to_byte_length_safe(uint32 char_length_arg, uint32 mbmaxlen_arg)
|
||||
{
|
||||
ulonglong tmp= ((ulonglong) char_length_arg) * mbmaxlen_arg;
|
||||
return (tmp > UINT_MAX32) ? (uint32) UINT_MAX32 : (uint32) tmp;
|
||||
}
|
||||
|
||||
/**
|
||||
A class to store type attributes for the standard data types.
|
||||
Does not include attributes for the extended data types
|
||||
@@ -217,6 +224,19 @@ public:
|
||||
{
|
||||
*this= other;
|
||||
}
|
||||
void set(const Field *field);
|
||||
uint32 max_char_length() const
|
||||
{ return max_length / collation.collation->mbmaxlen; }
|
||||
void fix_length_and_charset(uint32 max_char_length_arg, CHARSET_INFO *cs)
|
||||
{
|
||||
max_length= char_to_byte_length_safe(max_char_length_arg, cs->mbmaxlen);
|
||||
collation.collation= cs;
|
||||
}
|
||||
void fix_char_length(uint32 max_char_length_arg)
|
||||
{
|
||||
max_length= char_to_byte_length_safe(max_char_length_arg,
|
||||
collation.collation->mbmaxlen);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -246,6 +266,7 @@ public:
|
||||
virtual Item_result result_type() const= 0;
|
||||
virtual Item_result cmp_type() const= 0;
|
||||
virtual const Type_handler *type_handler_for_comparison() const= 0;
|
||||
virtual CHARSET_INFO *charset_for_protocol(const Item *item) const;
|
||||
virtual const Type_handler*
|
||||
type_handler_adjusted_to_max_octet_length(uint max_octet_length,
|
||||
CHARSET_INFO *cs) const
|
||||
@@ -628,6 +649,7 @@ class Type_handler_string_result: public Type_handler
|
||||
public:
|
||||
Item_result result_type() const { return STRING_RESULT; }
|
||||
Item_result cmp_type() const { return STRING_RESULT; }
|
||||
CHARSET_INFO *charset_for_protocol(const Item *item) const;
|
||||
virtual ~Type_handler_string_result() {}
|
||||
const Type_handler *type_handler_for_comparison() const;
|
||||
const Type_handler *
|
||||
|
||||
Reference in New Issue
Block a user