diff options
author | Monty <monty@mariadb.org> | 2017-01-05 01:07:03 +0200 |
---|---|---|
committer | Monty <monty@mariadb.org> | 2017-01-11 09:19:45 +0200 |
commit | 135e144479c70d8e470e67fd95e4b17051127952 (patch) | |
tree | 1fbca0bf595cae0ee787192e2948c8690220844d /sql | |
parent | de22cd3fe5caa1db8839701e45f379b3b5be7328 (diff) | |
download | mariadb-git-135e144479c70d8e470e67fd95e4b17051127952.tar.gz |
MDEV-11598 Assertion `!table || (!table->read_set || bitmap_is_set(table->read_set, field_index))' failed
Found and fixed 2 problems:
- Filesort addon fields didn't mark virtual columns properly
- multi-range-read calculated vcol bitmap but was not using it.
This caused wrong vcol field to be calculated on read, which caused the assert.
Diffstat (limited to 'sql')
-rw-r--r-- | sql/field.cc | 11 | ||||
-rw-r--r-- | sql/field.h | 3 | ||||
-rw-r--r-- | sql/filesort.cc | 32 | ||||
-rw-r--r-- | sql/opt_range.cc | 53 | ||||
-rw-r--r-- | sql/opt_range.h | 12 |
5 files changed, 68 insertions, 43 deletions
diff --git a/sql/field.cc b/sql/field.cc index 8d53fca27d7..ff8b948ef62 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -10864,3 +10864,14 @@ bool Field::save_in_field_ignore_value(bool view_error_processing) return save_in_field_default_value(view_error_processing); return 0; // ignore } + + +void Field::register_field_in_read_map() +{ + if (vcol_info) + { + Item *vcol_item= vcol_info->expr; + vcol_item->walk(&Item::register_field_in_read_map, 1, 0); + } + bitmap_set_bit(table->read_set, field_index); +} diff --git a/sql/field.h b/sql/field.h index 400d2ef0e5e..fd68ade1165 100644 --- a/sql/field.h +++ b/sql/field.h @@ -1475,6 +1475,9 @@ public: bool save_in_field_default_value(bool view_eror_processing); bool save_in_field_ignore_value(bool view_error_processing); + /* Mark field in read map. Updates also virtual fields */ + void register_field_in_read_map(); + friend int cre_myisam(char * name, register TABLE *form, uint options, ulonglong auto_increment_value); friend class Copy_field; diff --git a/sql/filesort.cc b/sql/filesort.cc index 2210dc569df..6046693cba1 100644 --- a/sql/filesort.cc +++ b/sql/filesort.cc @@ -716,7 +716,7 @@ static ha_rows find_all_keys(THD *thd, Sort_param *param, SQL_SELECT *select, TABLE *sort_form; handler *file; MY_BITMAP *save_read_set, *save_write_set, *save_vcol_set; - + Item *sort_cond; DBUG_ENTER("find_all_keys"); DBUG_PRINT("info",("using: %s", (select ? select->quick ? "ranges" : "where": @@ -754,22 +754,22 @@ static ha_rows find_all_keys(THD *thd, Sort_param *param, SQL_SELECT *select, /* Remember original bitmaps */ save_read_set= sort_form->read_set; save_write_set= sort_form->write_set; - save_vcol_set= sort_form->vcol_set; + save_vcol_set= sort_form->vcol_set; + /* Set up temporary column read map for columns used by sort */ bitmap_clear_all(&sort_form->tmp_set); - /* Temporary set for register_used_fields and register_field_in_read_map */ - sort_form->read_set= &sort_form->tmp_set; + sort_form->column_bitmaps_set(&sort_form->tmp_set, &sort_form->tmp_set, + &sort_form->tmp_set); register_used_fields(param); if (quick_select) - select->quick->add_used_key_part_to_set(sort_form->read_set); + select->quick->add_used_key_part_to_set(); - Item *sort_cond= !select ? - 0 : !select->pre_idx_push_select_cond ? - select->cond : select->pre_idx_push_select_cond; + sort_cond= (!select ? 0 : + (!select->pre_idx_push_select_cond ? + select->cond : select->pre_idx_push_select_cond)); if (sort_cond) sort_cond->walk(&Item::register_field_in_read_map, 1, sort_form); - sort_form->column_bitmaps_set(&sort_form->tmp_set, &sort_form->tmp_set, - &sort_form->tmp_set); + sort_form->file->column_bitmaps_signal(); if (quick_select) { @@ -1259,7 +1259,6 @@ static void register_used_fields(Sort_param *param) { reg1 SORT_FIELD *sort_field; TABLE *table=param->sort_form; - MY_BITMAP *bitmap= table->read_set; for (sort_field= param->local_sortorder ; sort_field != param->end ; @@ -1269,14 +1268,7 @@ static void register_used_fields(Sort_param *param) if ((field= sort_field->field)) { if (field->table == table) - { - if (field->vcol_info) - { - Item *vcol_item= field->vcol_info->expr; - vcol_item->walk(&Item::register_field_in_read_map, 1, 0); - } - bitmap_set_bit(bitmap, field->field_index); - } + field->register_field_in_read_map(); } else { // Item @@ -1289,7 +1281,7 @@ static void register_used_fields(Sort_param *param) SORT_ADDON_FIELD *addonf= param->addon_field; Field *field; for ( ; (field= addonf->field) ; addonf++) - bitmap_set_bit(bitmap, field->field_index); + field->register_field_in_read_map(); } else { diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 01b836fddf7..8446da51926 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -11101,6 +11101,7 @@ int QUICK_RANGE_SELECT::reset() HANDLER_BUFFER empty_buf; MY_BITMAP * const save_read_set= head->read_set; MY_BITMAP * const save_write_set= head->write_set; + MY_BITMAP * const save_vcol_set= head->vcol_set; DBUG_ENTER("QUICK_RANGE_SELECT::reset"); last_range= NULL; cur_range= (QUICK_RANGE**) ranges.buffer; @@ -11114,7 +11115,8 @@ int QUICK_RANGE_SELECT::reset() } if (in_ror_merged_scan) - head->column_bitmaps_set_no_signal(&column_bitmap, &column_bitmap); + head->column_bitmaps_set_no_signal(&column_bitmap, &column_bitmap, + &column_bitmap); if (file->inited == handler::NONE) { @@ -11157,8 +11159,8 @@ int QUICK_RANGE_SELECT::reset() err: /* Restore bitmaps set on entry */ if (in_ror_merged_scan) - head->column_bitmaps_set_no_signal(save_read_set, save_write_set); - + head->column_bitmaps_set_no_signal(save_read_set, save_write_set, + save_vcol_set); DBUG_RETURN(error); } @@ -11189,13 +11191,16 @@ int QUICK_RANGE_SELECT::get_next() MY_BITMAP * const save_read_set= head->read_set; MY_BITMAP * const save_write_set= head->write_set; + MY_BITMAP * const save_vcol_set= head->vcol_set; /* We don't need to signal the bitmap change as the bitmap is always the same for this head->file */ - head->column_bitmaps_set_no_signal(&column_bitmap, &column_bitmap); + head->column_bitmaps_set_no_signal(&column_bitmap, &column_bitmap, + &column_bitmap); result= file->multi_range_read_next(&dummy); - head->column_bitmaps_set_no_signal(save_read_set, save_write_set); + head->column_bitmaps_set_no_signal(save_read_set, save_write_set, + save_vcol_set); DBUG_RETURN(result); } @@ -11372,7 +11377,7 @@ QUICK_SELECT_DESC::QUICK_SELECT_DESC(QUICK_RANGE_SELECT *q, used_key_parts (used_key_parts_arg) { QUICK_RANGE *r; - /* + /* Use default MRR implementation for reverse scans. No table engine currently can do an MRR scan with output in reverse index order. */ @@ -11847,62 +11852,76 @@ void QUICK_ROR_UNION_SELECT::add_keys_and_lengths(String *key_names, } -void QUICK_RANGE_SELECT::add_used_key_part_to_set(MY_BITMAP *col_set) +void QUICK_RANGE_SELECT::add_used_key_part_to_set() { uint key_len; KEY_PART *part= key_parts; for (key_len=0; key_len < max_used_key_length; key_len += (part++)->store_length) { - bitmap_set_bit(col_set, part->field->field_index); + /* + We have to use field_index instead of part->field + as for partial fields, part->field points to + a temporary field that is only part of the original + field. field_index always points to the original field + */ + Field *field= head->field[part->field->field_index]; + field->register_field_in_read_map(); } } -void QUICK_GROUP_MIN_MAX_SELECT::add_used_key_part_to_set(MY_BITMAP *col_set) +void QUICK_GROUP_MIN_MAX_SELECT::add_used_key_part_to_set() { uint key_len; KEY_PART_INFO *part= index_info->key_part; for (key_len=0; key_len < max_used_key_length; key_len += (part++)->store_length) { - bitmap_set_bit(col_set, part->field->field_index); + /* + We have to use field_index instead of part->field + as for partial fields, part->field points to + a temporary field that is only part of the original + field. field_index always points to the original field + */ + Field *field= head->field[part->field->field_index]; + field->register_field_in_read_map(); } } -void QUICK_ROR_INTERSECT_SELECT::add_used_key_part_to_set(MY_BITMAP *col_set) +void QUICK_ROR_INTERSECT_SELECT::add_used_key_part_to_set() { List_iterator_fast<QUICK_SELECT_WITH_RECORD> it(quick_selects); QUICK_SELECT_WITH_RECORD *quick; while ((quick= it++)) { - quick->quick->add_used_key_part_to_set(col_set); + quick->quick->add_used_key_part_to_set(); } } -void QUICK_INDEX_SORT_SELECT::add_used_key_part_to_set(MY_BITMAP *col_set) +void QUICK_INDEX_SORT_SELECT::add_used_key_part_to_set() { QUICK_RANGE_SELECT *quick; List_iterator_fast<QUICK_RANGE_SELECT> it(quick_selects); while ((quick= it++)) { - quick->add_used_key_part_to_set(col_set); + quick->add_used_key_part_to_set(); } if (pk_quick_select) - pk_quick_select->add_used_key_part_to_set(col_set); + pk_quick_select->add_used_key_part_to_set(); } -void QUICK_ROR_UNION_SELECT::add_used_key_part_to_set(MY_BITMAP *col_set) +void QUICK_ROR_UNION_SELECT::add_used_key_part_to_set() { QUICK_SELECT_I *quick; List_iterator_fast<QUICK_SELECT_I> it(quick_selects); while ((quick= it++)) { - quick->add_used_key_part_to_set(col_set); + quick->add_used_key_part_to_set(); } } diff --git a/sql/opt_range.h b/sql/opt_range.h index 6970b87f6d8..9e4521a9437 100644 --- a/sql/opt_range.h +++ b/sql/opt_range.h @@ -1006,7 +1006,7 @@ public: This is used by an optimization in filesort. */ - virtual void add_used_key_part_to_set(MY_BITMAP *col_set)=0; + virtual void add_used_key_part_to_set()=0; }; @@ -1097,7 +1097,7 @@ public: virtual void replace_handler(handler *new_file) { file= new_file; } QUICK_SELECT_I *make_reverse(uint used_key_parts_arg); - virtual void add_used_key_part_to_set(MY_BITMAP *col_set); + virtual void add_used_key_part_to_set(); private: /* Default copy ctor used by QUICK_SELECT_DESC */ @@ -1261,7 +1261,7 @@ public: /* used to get rows collected in Unique */ READ_RECORD read_record; - virtual void add_used_key_part_to_set(MY_BITMAP *col_set); + virtual void add_used_key_part_to_set(); }; @@ -1336,7 +1336,7 @@ public: void add_keys_and_lengths(String *key_names, String *used_lengths); Explain_quick_select *get_explain(MEM_ROOT *alloc); bool is_keys_used(const MY_BITMAP *fields); - void add_used_key_part_to_set(MY_BITMAP *col_set); + void add_used_key_part_to_set(); #ifndef DBUG_OFF void dbug_dump(int indent, bool verbose); #endif @@ -1416,7 +1416,7 @@ public: void add_keys_and_lengths(String *key_names, String *used_lengths); Explain_quick_select *get_explain(MEM_ROOT *alloc); bool is_keys_used(const MY_BITMAP *fields); - void add_used_key_part_to_set(MY_BITMAP *col_set); + void add_used_key_part_to_set(); #ifndef DBUG_OFF void dbug_dump(int indent, bool verbose); #endif @@ -1560,7 +1560,7 @@ public: bool unique_key_range() { return false; } int get_type() { return QS_TYPE_GROUP_MIN_MAX; } void add_keys_and_lengths(String *key_names, String *used_lengths); - void add_used_key_part_to_set(MY_BITMAP *col_set); + void add_used_key_part_to_set(); #ifndef DBUG_OFF void dbug_dump(int indent, bool verbose); #endif |