1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-29 05:21:33 +03:00

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*).
This commit is contained in:
Alexander Barkov
2019-02-21 21:44:44 +04:00
parent 1ab2e7573a
commit b25ad1bc47
8 changed files with 411 additions and 271 deletions

View File

@ -1521,7 +1521,6 @@ void
mysqld_list_fields(THD *thd, TABLE_LIST *table_list, const char *wild)
{
TABLE *table;
MEM_ROOT *mem_root= thd->mem_root;
DBUG_ENTER("mysqld_list_fields");
DBUG_PRINT("enter",("table: %s", table_list->table_name.str));
@ -1531,28 +1530,18 @@ mysqld_list_fields(THD *thd, TABLE_LIST *table_list, const char *wild)
DBUG_VOID_RETURN;
table= table_list->table;
List<Item> field_list;
List<Field> field_list;
Field **ptr,*field;
for (ptr=table->field ; (field= *ptr); ptr++)
{
if (!wild || !wild[0] ||
!wild_case_compare(system_charset_info, field->field_name.str,wild))
{
if (table_list->view)
field_list.push_back(new (mem_root)
Item_ident_for_show(thd, field,
table_list->view_db.str,
table_list->view_name.str),
mem_root);
else
field_list.push_back(new (mem_root) Item_field(thd, field), mem_root);
}
field_list.push_back(field);
}
restore_record(table, s->default_values); // Get empty record
table->use_all_columns();
if (thd->protocol->send_result_set_metadata(&field_list,
Protocol::SEND_DEFAULTS))
if (thd->protocol->send_list_fields(&field_list, table_list))
DBUG_VOID_RETURN;
my_eof(thd);
DBUG_VOID_RETURN;