diff options
author | Alexander Barkov <bar@mariadb.com> | 2019-02-21 21:44:44 +0400 |
---|---|---|
committer | Alexander Barkov <bar@mariadb.com> | 2019-02-25 12:29:42 +0400 |
commit | b25ad1bc47d2db600ab241d889f9f8f9e775b99d (patch) | |
tree | 52de378bed623d6f90cffb3d5d011ba6ee2c3668 /sql/protocol.h | |
parent | 1ab2e7573a378144fc120e97e8218081d17cfa89 (diff) | |
download | mariadb-git-b25ad1bc47d2db600ab241d889f9f8f9e775b99d.tar.gz |
MDEV-18408 Assertion `0' failed in Item::val_native_result / Timestamp_or_zero_datetime_native_null::Timestamp_or_zero_datetime_native_null upon mysqld_list_fields after crash recovery
The problem happened because Item_ident_for_show did not implement val_native().
Solution:
- Removing class Item_ident_for_show
- Implementing a new method Protocol::send_list_fields() instead,
which accepts a List<Field> instead of List<Item> as input.
Now no any Item creation is done during mysqld_list_fields().
Adding helper methods, to reuse the code easier:
- Moved a part of Protocol::send_result_set_metadata(),
responsible for sending an individual field metadata,
into a new method Protocol_text::store_field_metadata().
Reusing it in both send_list_fields() and send_result_set_metadata().
- Adding Protocol_text::store_field_metadata()
- Adding Protocol_text::store_field_metadata_for_list_fields()
Note, this patch also automatically fixed another bug:
MDEV-18685 mysql_list_fields() returns DEFAULT 0 instead of DEFAULT NULL for view columns
The reason for this bug was that Item_ident_for_show::val_xxx() and get_date()
did not check field->is_null() before calling field->val_xxx()/get_date().
Now the default value is correctly sent by Protocol_text::store(Field*).
Diffstat (limited to 'sql/protocol.h')
-rw-r--r-- | sql/protocol.h | 31 |
1 files changed, 28 insertions, 3 deletions
diff --git a/sql/protocol.h b/sql/protocol.h index 6397e3dd5e6..6dd3e5c7521 100644 --- a/sql/protocol.h +++ b/sql/protocol.h @@ -25,8 +25,10 @@ class i_string; class Field; +class Send_field; class THD; class Item_param; +struct TABLE_LIST; typedef struct st_mysql_field MYSQL_FIELD; typedef struct st_mysql_rows MYSQL_ROWS; @@ -75,8 +77,9 @@ public: virtual ~Protocol() {} void init(THD* thd_arg); - enum { SEND_NUM_ROWS= 1, SEND_DEFAULTS= 2, SEND_EOF= 4 }; + enum { SEND_NUM_ROWS= 1, SEND_EOF= 2 }; virtual bool send_result_set_metadata(List<Item> *list, uint flags); + bool send_list_fields(List<Field> *list, const TABLE_LIST *table_list); bool send_result_set_row(List<Item> *row_items); bool store(I_List<i_string> *str_list); @@ -113,6 +116,15 @@ public: virtual bool store(const char *from, size_t length, CHARSET_INFO *cs)=0; virtual bool store(const char *from, size_t length, CHARSET_INFO *fromcs, CHARSET_INFO *tocs)=0; + bool store_str(const char *s, CHARSET_INFO *fromcs, CHARSET_INFO *tocs) + { + DBUG_ASSERT(s); + return store(s, (uint) strlen(s), fromcs, tocs); + } + bool store_str(const LEX_CSTRING &s, CHARSET_INFO *fromcs, CHARSET_INFO *tocs) + { + return store(s.str, (uint) s.length, fromcs, tocs); + } virtual bool store(float from, uint32 decimals, String *buffer)=0; virtual bool store(double from, uint32 decimals, String *buffer)=0; virtual bool store(MYSQL_TIME *time, int decimals)=0; @@ -122,7 +134,8 @@ public: virtual bool send_out_parameters(List<Item_param> *sp_params)=0; #ifdef EMBEDDED_LIBRARY - int begin_dataset(); + bool begin_dataset(); + bool begin_dataset(THD *thd, uint numfields); virtual void remove_last_row() {} #else void remove_last_row() {} @@ -150,7 +163,12 @@ public: class Protocol_text :public Protocol { public: - Protocol_text(THD *thd_arg) :Protocol(thd_arg) {} + Protocol_text(THD *thd_arg, ulong prealloc= 0) + :Protocol(thd_arg) + { + if (prealloc) + packet->alloc(prealloc); + } virtual void prepare_for_resend(); virtual bool store_null(); virtual bool store_tiny(longlong from); @@ -172,6 +190,13 @@ public: #ifdef EMBEDDED_LIBRARY void remove_last_row(); #endif + bool store_field_metadata(const THD *thd, const Send_field &field, + CHARSET_INFO *charset_for_protocol, + uint pos); + bool store_field_metadata(THD *thd, Item *item, uint pos); + bool store_field_metadata_for_list_fields(const THD *thd, Field *field, + const TABLE_LIST *table_list, + uint pos); virtual enum enum_protocol_type type() { return PROTOCOL_TEXT; }; }; |