diff options
author | Alexander Barkov <bar@mariadb.org> | 2016-12-29 07:40:49 +0400 |
---|---|---|
committer | Alexander Barkov <bar@mariadb.org> | 2016-12-29 07:40:49 +0400 |
commit | f6138883b14989cd4faf81dd4586238f3e4f590e (patch) | |
tree | aad308e59bfc70b81c4249bb96a66ab5583f2de9 /sql/protocol.cc | |
parent | d8c695ead448ae36be7b98f586a67e858c270147 (diff) | |
download | mariadb-git-f6138883b14989cd4faf81dd4586238f3e4f590e.tar.gz |
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.
Diffstat (limited to 'sql/protocol.cc')
-rw-r--r-- | sql/protocol.cc | 2 |
1 files changed, 1 insertions, 1 deletions
diff --git a/sql/protocol.cc b/sql/protocol.cc index f8b68c02fff..3cc73071310 100644 --- a/sql/protocol.cc +++ b/sql/protocol.cc @@ -1116,7 +1116,7 @@ bool Protocol_text::store(const char *from, size_t length, #ifndef DBUG_OFF DBUG_PRINT("info", ("Protocol_text::store field %u (%u): %.*s", field_pos, field_count, (int) length, (length == 0 ? "" : from))); - DBUG_ASSERT(field_pos < field_count); + DBUG_ASSERT(field_types == 0 || field_pos < field_count); DBUG_ASSERT(field_types == 0 || field_types[field_pos] == MYSQL_TYPE_DECIMAL || field_types[field_pos] == MYSQL_TYPE_BIT || |