Skip to content

Commit 21809f9

Browse files
committed
MDEV-17556 Assertion `bitmap_is_set_all(&table->s->all_set)' failed
The assertion failed in handler::ha_reset upon SELECT under READ UNCOMMITTED from table with index on virtual column. This was the debug-only failure, though the problem is mush wider: * MY_BITMAP is a structure containing my_bitmap_map, the latter is a raw bitmap. * read_set, write_set and vcol_set of TABLE are the pointers to MY_BITMAP * The rest of MY_BITMAPs are stored in TABLE and TABLE_SHARE * The pointers to the stored MY_BITMAPs, like orig_read_set etc, and sometimes all_set and tmp_set, are assigned to the pointers. * Sometimes tmp_use_all_columns is used to substitute the raw bitmap directly with all_set.bitmap * Sometimes even bitmaps are directly modified, like in TABLE::update_virtual_field(): bitmap_clear_all(&tmp_set) is called. The last three bullets in the list, when used together (which is mostly always) make the program flow cumbersome and impossible to follow, notwithstanding the errors they cause, like this MDEV-17556, where tmp_set pointer was assigned to read_set, write_set and vcol_set, then its bitmap was substituted with all_set.bitmap by dbug_tmp_use_all_columns() call, and then bitmap_clear_all(&tmp_set) was applied to all this. To untangle this knot, the rule should be applied: * Never substitute bitmaps! This patch is about this. orig_*, all_set bitmaps are never substituted already. This patch changes the following function prototypes: * tmp_use_all_columns, dbug_tmp_use_all_columns to accept MY_BITMAP** and to return MY_BITMAP * instead of my_bitmap_map* * tmp_restore_column_map, dbug_tmp_restore_column_maps to accept MY_BITMAP* instead of my_bitmap_map* These functions now will substitute read_set/write_set/vcol_set directly, and won't touch underlying bitmaps.
1 parent c207f04 commit 21809f9

37 files changed

+244
-265
lines changed

plugin/feedback/sender_thread.cc

+1-1
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ static int table_to_string(TABLE *table, String *result)
4747

4848
res= table->file->ha_rnd_init(1);
4949

50-
dbug_tmp_use_all_columns(table, table->read_set);
50+
dbug_tmp_use_all_columns(table, &table->read_set);
5151

5252
while(!res && !table->file->ha_rnd_next(table->record[0]))
5353
{

sql/field.cc

+4-5
Original file line numberDiff line numberDiff line change
@@ -7976,11 +7976,10 @@ uint Field_varstring::get_key_image(uchar *buff, uint length,
79767976
{
79777977
String val;
79787978
uint local_char_length;
7979-
my_bitmap_map *old_map;
79807979

7981-
old_map= dbug_tmp_use_all_columns(table, table->read_set);
7980+
MY_BITMAP *old_map= dbug_tmp_use_all_columns(table, &table->read_set);
79827981
val_str(&val, &val);
7983-
dbug_tmp_restore_column_map(table->read_set, old_map);
7982+
dbug_tmp_restore_column_map(&table->read_set, old_map);
79847983

79857984
local_char_length= val.charpos(length / field_charset->mbmaxlen);
79867985
if (local_char_length < val.length())
@@ -11496,7 +11495,7 @@ key_map Field::get_possible_keys()
1149611495

1149711496
bool Field::validate_value_in_record_with_warn(THD *thd, const uchar *record)
1149811497
{
11499-
my_bitmap_map *old_map= dbug_tmp_use_all_columns(table, table->read_set);
11498+
MY_BITMAP *old_map= dbug_tmp_use_all_columns(table, &table->read_set);
1150011499
bool rc;
1150111500
if ((rc= validate_value_in_record(thd, record)))
1150211501
{
@@ -11508,7 +11507,7 @@ bool Field::validate_value_in_record_with_warn(THD *thd, const uchar *record)
1150811507
ER_THD(thd, ER_INVALID_DEFAULT_VALUE_FOR_FIELD),
1150911508
ErrConvString(&tmp).ptr(), field_name.str);
1151011509
}
11511-
dbug_tmp_restore_column_map(table->read_set, old_map);
11510+
dbug_tmp_restore_column_map(&table->read_set, old_map);
1151211511
return rc;
1151311512
}
1151411513

sql/ha_partition.cc

+5-6
Original file line numberDiff line numberDiff line change
@@ -4278,7 +4278,7 @@ int ha_partition::write_row(uchar * buf)
42784278
int error;
42794279
longlong func_value;
42804280
bool have_auto_increment= table->next_number_field && buf == table->record[0];
4281-
my_bitmap_map *old_map;
4281+
MY_BITMAP *old_map;
42824282
THD *thd= ha_thd();
42834283
sql_mode_t saved_sql_mode= thd->variables.sql_mode;
42844284
bool saved_auto_inc_field_not_null= table->auto_increment_field_not_null;
@@ -4320,9 +4320,9 @@ int ha_partition::write_row(uchar * buf)
43204320
}
43214321
}
43224322

4323-
old_map= dbug_tmp_use_all_columns(table, table->read_set);
4323+
old_map= dbug_tmp_use_all_columns(table, &table->read_set);
43244324
error= m_part_info->get_partition_id(m_part_info, &part_id, &func_value);
4325-
dbug_tmp_restore_column_map(table->read_set, old_map);
4325+
dbug_tmp_restore_column_map(&table->read_set, old_map);
43264326
if (unlikely(error))
43274327
{
43284328
m_part_info->err_value= func_value;
@@ -11191,13 +11191,12 @@ int ha_partition::bulk_update_row(const uchar *old_data, const uchar *new_data,
1119111191
int error= 0;
1119211192
uint32 part_id;
1119311193
longlong func_value;
11194-
my_bitmap_map *old_map;
1119511194
DBUG_ENTER("ha_partition::bulk_update_row");
1119611195

11197-
old_map= dbug_tmp_use_all_columns(table, table->read_set);
11196+
MY_BITMAP *old_map= dbug_tmp_use_all_columns(table, &table->read_set);
1119811197
error= m_part_info->get_partition_id(m_part_info, &part_id,
1119911198
&func_value);
11200-
dbug_tmp_restore_column_map(table->read_set, old_map);
11199+
dbug_tmp_restore_column_map(&table->read_set, old_map);
1120111200
if (unlikely(error))
1120211201
{
1120311202
m_part_info->err_value= func_value;

sql/item.cc

+4-4
Original file line numberDiff line numberDiff line change
@@ -1624,9 +1624,9 @@ int Item::save_in_field_no_warnings(Field *field, bool no_conversions)
16241624
Sql_mode_save sql_mode(thd);
16251625
thd->variables.sql_mode&= ~(MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE);
16261626
thd->variables.sql_mode|= MODE_INVALID_DATES;
1627-
my_bitmap_map *old_map= dbug_tmp_use_all_columns(table, table->write_set);
1627+
MY_BITMAP *old_map= dbug_tmp_use_all_columns(table, &table->write_set);
16281628
res= save_in_field(field, no_conversions);
1629-
dbug_tmp_restore_column_map(table->write_set, old_map);
1629+
dbug_tmp_restore_column_map(&table->write_set, old_map);
16301630
return res;
16311631
}
16321632

@@ -6051,7 +6051,7 @@ bool Item_field::fix_fields(THD *thd, Item **reference)
60516051
Field *from_field= (Field *)not_found_field;
60526052
bool outer_fixed= false;
60536053
SELECT_LEX *select= thd->lex->current_select;
6054-
6054+
60556055
if (select && select->in_tvc)
60566056
{
60576057
my_error(ER_FIELD_REFERENCE_IN_TVC, MYF(0), full_name());
@@ -6947,7 +6947,7 @@ Item *Item_string::make_odbc_literal(THD *thd, const LEX_CSTRING *typestr)
69476947
}
69486948

69496949

6950-
static int save_int_value_in_field (Field *field, longlong nr,
6950+
static int save_int_value_in_field (Field *field, longlong nr,
69516951
bool null_value, bool unsigned_flag)
69526952
{
69536953
if (null_value)

sql/item_cmpfunc.cc

+4-4
Original file line numberDiff line numberDiff line change
@@ -345,13 +345,13 @@ static bool convert_const_to_int(THD *thd, Item_field *field_item,
345345
TABLE *table= field->table;
346346
Sql_mode_save sql_mode(thd);
347347
Check_level_instant_set check_level_save(thd, CHECK_FIELD_IGNORE);
348-
my_bitmap_map *old_maps[2] = { NULL, NULL };
348+
MY_BITMAP *old_maps[2] = { NULL, NULL };
349349
ulonglong UNINIT_VAR(orig_field_val); /* original field value if valid */
350350

351351
/* table->read_set may not be set if we come here from a CREATE TABLE */
352352
if (table && table->read_set)
353353
dbug_tmp_use_all_columns(table, old_maps,
354-
table->read_set, table->write_set);
354+
&table->read_set, &table->write_set);
355355
/* For comparison purposes allow invalid dates like 2000-01-32 */
356356
thd->variables.sql_mode= (thd->variables.sql_mode & ~MODE_NO_ZERO_DATE) |
357357
MODE_INVALID_DATES;
@@ -392,7 +392,7 @@ static bool convert_const_to_int(THD *thd, Item_field *field_item,
392392
DBUG_ASSERT(!result);
393393
}
394394
if (table && table->read_set)
395-
dbug_tmp_restore_column_maps(table->read_set, table->write_set, old_maps);
395+
dbug_tmp_restore_column_maps(&table->read_set, &table->write_set, old_maps);
396396
}
397397
return result;
398398
}
@@ -3101,7 +3101,7 @@ bool Item_func_decode_oracle::fix_length_and_dec()
31013101
/*
31023102
Aggregate all THEN and ELSE expression types
31033103
and collations when string result
3104-
3104+
31053105
@param THD - current thd
31063106
@param start - an element in args to start aggregating from
31073107
*/

sql/key.cc

+4-5
Original file line numberDiff line numberDiff line change
@@ -244,14 +244,13 @@ void key_restore(uchar *to_record, const uchar *from_key, KEY *key_info,
244244
else if (key_part->key_part_flag & HA_VAR_LENGTH_PART)
245245
{
246246
Field *field= key_part->field;
247-
my_bitmap_map *old_map;
248247
my_ptrdiff_t ptrdiff= to_record - field->table->record[0];
249248
field->move_field_offset(ptrdiff);
250249
key_length-= HA_KEY_BLOB_LENGTH;
251250
length= MY_MIN(key_length, key_part->length);
252-
old_map= dbug_tmp_use_all_columns(field->table, field->table->write_set);
251+
MY_BITMAP *old_map= dbug_tmp_use_all_columns(field->table, &field->table->write_set);
253252
field->set_key_image(from_key, length);
254-
dbug_tmp_restore_column_map(field->table->write_set, old_map);
253+
dbug_tmp_restore_column_map(&field->table->write_set, old_map);
255254
from_key+= HA_KEY_BLOB_LENGTH;
256255
field->move_field_offset(-ptrdiff);
257256
}
@@ -419,7 +418,7 @@ void field_unpack(String *to, Field *field, const uchar *rec, uint max_length,
419418

420419
void key_unpack(String *to, TABLE *table, KEY *key)
421420
{
422-
my_bitmap_map *old_map= dbug_tmp_use_all_columns(table, table->read_set);
421+
MY_BITMAP *old_map= dbug_tmp_use_all_columns(table, &table->read_set);
423422
DBUG_ENTER("key_unpack");
424423

425424
to->length(0);
@@ -443,7 +442,7 @@ void key_unpack(String *to, TABLE *table, KEY *key)
443442
field_unpack(to, key_part->field, table->record[0], key_part->length,
444443
MY_TEST(key_part->key_part_flag & HA_PART_KEY_SEG));
445444
}
446-
dbug_tmp_restore_column_map(table->read_set, old_map);
445+
dbug_tmp_restore_column_map(&table->read_set, old_map);
447446
DBUG_VOID_RETURN;
448447
}
449448

sql/log_event.cc

+3-3
Original file line numberDiff line numberDiff line change
@@ -13699,11 +13699,11 @@ int Rows_log_event::update_sequence()
1369913699
/* This event come from a setval function executed on the master.
1370013700
Update the sequence next_number and round, like we do with setval()
1370113701
*/
13702-
my_bitmap_map *old_map= dbug_tmp_use_all_columns(table,
13703-
table->read_set);
13702+
MY_BITMAP *old_map= dbug_tmp_use_all_columns(table,
13703+
&table->read_set);
1370413704
longlong nextval= table->field[NEXT_FIELD_NO]->val_int();
1370513705
longlong round= table->field[ROUND_FIELD_NO]->val_int();
13706-
dbug_tmp_restore_column_map(table->read_set, old_map);
13706+
dbug_tmp_restore_column_map(&table->read_set, old_map);
1370713707

1370813708
return table->s->sequence->set_value(table, nextval, round, 0) > 0;
1370913709
}

sql/opt_range.cc

+16-17
Original file line numberDiff line numberDiff line change
@@ -3264,8 +3264,7 @@ bool calculate_cond_selectivity_for_table(THD *thd, TABLE *table, Item **cond)
32643264

32653265
void store_key_image_to_rec(Field *field, uchar *ptr, uint len)
32663266
{
3267-
/* Do the same as print_key() does */
3268-
my_bitmap_map *old_map;
3267+
/* Do the same as print_key() does */
32693268

32703269
if (field->real_maybe_null())
32713270
{
@@ -3277,10 +3276,10 @@ void store_key_image_to_rec(Field *field, uchar *ptr, uint len)
32773276
field->set_notnull();
32783277
ptr++;
32793278
}
3280-
old_map= dbug_tmp_use_all_columns(field->table,
3281-
field->table->write_set);
3279+
MY_BITMAP *old_map= dbug_tmp_use_all_columns(field->table,
3280+
&field->table->write_set);
32823281
field->set_key_image(ptr, len);
3283-
dbug_tmp_restore_column_map(field->table->write_set, old_map);
3282+
dbug_tmp_restore_column_map(&field->table->write_set, old_map);
32843283
}
32853284

32863285
#ifdef WITH_PARTITION_STORAGE_ENGINE
@@ -3495,7 +3494,7 @@ bool prune_partitions(THD *thd, TABLE *table, Item *pprune_cond)
34953494
PART_PRUNE_PARAM prune_param;
34963495
MEM_ROOT alloc;
34973496
RANGE_OPT_PARAM *range_par= &prune_param.range_param;
3498-
my_bitmap_map *old_sets[2];
3497+
MY_BITMAP *old_sets[2];
34993498

35003499
prune_param.part_info= part_info;
35013500
init_sql_alloc(&alloc, "prune_partitions",
@@ -3512,7 +3511,7 @@ bool prune_partitions(THD *thd, TABLE *table, Item *pprune_cond)
35123511
}
35133512

35143513
dbug_tmp_use_all_columns(table, old_sets,
3515-
table->read_set, table->write_set);
3514+
&table->read_set, &table->write_set);
35163515
range_par->thd= thd;
35173516
range_par->table= table;
35183517
/* range_par->cond doesn't need initialization */
@@ -3609,7 +3608,7 @@ bool prune_partitions(THD *thd, TABLE *table, Item *pprune_cond)
36093608
retval= FALSE; // some partitions are used
36103609
mark_all_partitions_as_used(prune_param.part_info);
36113610
end:
3612-
dbug_tmp_restore_column_maps(table->read_set, table->write_set, old_sets);
3611+
dbug_tmp_restore_column_maps(&table->read_set, &table->write_set, old_sets);
36133612
thd->no_errors=0;
36143613
thd->mem_root= range_par->old_root;
36153614
free_root(&alloc,MYF(0)); // Return memory & allocator
@@ -14852,8 +14851,8 @@ static void
1485214851
print_sel_arg_key(Field *field, const uchar *key, String *out)
1485314852
{
1485414853
TABLE *table= field->table;
14855-
my_bitmap_map *old_sets[2];
14856-
dbug_tmp_use_all_columns(table, old_sets, table->read_set, table->write_set);
14854+
MY_BITMAP *old_sets[2];
14855+
dbug_tmp_use_all_columns(table, old_sets, &table->read_set, &table->write_set);
1485714856

1485814857
if (field->real_maybe_null())
1485914858
{
@@ -14873,7 +14872,7 @@ print_sel_arg_key(Field *field, const uchar *key, String *out)
1487314872
field->val_str(out);
1487414873

1487514874
end:
14876-
dbug_tmp_restore_column_maps(table->read_set, table->write_set, old_sets);
14875+
dbug_tmp_restore_column_maps(&table->read_set, &table->write_set, old_sets);
1487714876
}
1487814877

1487914878

@@ -14968,9 +14967,9 @@ print_key(KEY_PART *key_part, const uchar *key, uint used_length)
1496814967
const uchar *key_end= key+used_length;
1496914968
uint store_length;
1497014969
TABLE *table= key_part->field->table;
14971-
my_bitmap_map *old_sets[2];
14970+
MY_BITMAP *old_sets[2];
1497214971

14973-
dbug_tmp_use_all_columns(table, old_sets, table->read_set, table->write_set);
14972+
dbug_tmp_use_all_columns(table, old_sets, &table->read_set, &table->write_set);
1497414973

1497514974
for (; key < key_end; key+=store_length, key_part++)
1497614975
{
@@ -14997,24 +14996,24 @@ print_key(KEY_PART *key_part, const uchar *key, uint used_length)
1499714996
if (key+store_length < key_end)
1499814997
fputc('/',DBUG_FILE);
1499914998
}
15000-
dbug_tmp_restore_column_maps(table->read_set, table->write_set, old_sets);
14999+
dbug_tmp_restore_column_maps(&table->read_set, &table->write_set, old_sets);
1500115000
}
1500215001

1500315002

1500415003
static void print_quick(QUICK_SELECT_I *quick, const key_map *needed_reg)
1500515004
{
1500615005
char buf[MAX_KEY/8+1];
1500715006
TABLE *table;
15008-
my_bitmap_map *old_sets[2];
15007+
MY_BITMAP *old_sets[2];
1500915008
DBUG_ENTER("print_quick");
1501015009
if (!quick)
1501115010
DBUG_VOID_RETURN;
1501215011
DBUG_LOCK_FILE;
1501315012

1501415013
table= quick->head;
15015-
dbug_tmp_use_all_columns(table, old_sets, table->read_set, table->write_set);
15014+
dbug_tmp_use_all_columns(table, old_sets, &table->read_set, &table->write_set);
1501615015
quick->dbug_dump(0, TRUE);
15017-
dbug_tmp_restore_column_maps(table->read_set, table->write_set, old_sets);
15016+
dbug_tmp_restore_column_maps(&table->read_set, &table->write_set, old_sets);
1501815017

1501915018
fprintf(DBUG_FILE,"other_keys: 0x%s:\n", needed_reg->print(buf));
1502015019

sql/partition_info.cc

+2-2
Original file line numberDiff line numberDiff line change
@@ -1449,13 +1449,13 @@ void partition_info::print_no_partition_found(TABLE *table_arg, myf errflag)
14491449
buf_ptr= (char*)"from column_list";
14501450
else
14511451
{
1452-
my_bitmap_map *old_map= dbug_tmp_use_all_columns(table_arg, table_arg->read_set);
1452+
MY_BITMAP *old_map= dbug_tmp_use_all_columns(table_arg, &table_arg->read_set);
14531453
if (part_expr->null_value)
14541454
buf_ptr= (char*)"NULL";
14551455
else
14561456
longlong10_to_str(err_value, buf,
14571457
part_expr->unsigned_flag ? 10 : -10);
1458-
dbug_tmp_restore_column_map(table_arg->read_set, old_map);
1458+
dbug_tmp_restore_column_map(&table_arg->read_set, old_map);
14591459
}
14601460
my_error(ER_NO_PARTITION_FOR_GIVEN_VALUE, errflag, buf_ptr);
14611461
}

sql/protocol.cc

+3-3
Original file line numberDiff line numberDiff line change
@@ -1251,15 +1251,15 @@ bool Protocol_text::store(Field *field)
12511251
CHARSET_INFO *tocs= this->thd->variables.character_set_results;
12521252
#ifdef DBUG_ASSERT_EXISTS
12531253
TABLE *table= field->table;
1254-
my_bitmap_map *old_map= 0;
1254+
MY_BITMAP *old_map= 0;
12551255
if (table->file)
1256-
old_map= dbug_tmp_use_all_columns(table, table->read_set);
1256+
old_map= dbug_tmp_use_all_columns(table, &table->read_set);
12571257
#endif
12581258

12591259
field->val_str(&str);
12601260
#ifdef DBUG_ASSERT_EXISTS
12611261
if (old_map)
1262-
dbug_tmp_restore_column_map(table->read_set, old_map);
1262+
dbug_tmp_restore_column_map(&table->read_set, old_map);
12631263
#endif
12641264

12651265
return store_string_aux(str.ptr(), str.length(), str.charset(), tocs);

sql/sql_handler.cc

+2-3
Original file line numberDiff line numberDiff line change
@@ -689,7 +689,6 @@ mysql_ha_fix_cond_and_key(SQL_HANDLER *handler,
689689

690690
for (keypart_map= key_len=0 ; (item=it_ke++) ; key_part++)
691691
{
692-
my_bitmap_map *old_map;
693692
/* note that 'item' can be changed by fix_fields() call */
694693
if (item->fix_fields_if_needed_for_scalar(thd, it_ke.ref()))
695694
return 1;
@@ -701,9 +700,9 @@ mysql_ha_fix_cond_and_key(SQL_HANDLER *handler,
701700
}
702701
if (!in_prepare)
703702
{
704-
old_map= dbug_tmp_use_all_columns(table, table->write_set);
703+
MY_BITMAP *old_map= dbug_tmp_use_all_columns(table, &table->write_set);
705704
(void) item->save_in_field(key_part->field, 1);
706-
dbug_tmp_restore_column_map(table->write_set, old_map);
705+
dbug_tmp_restore_column_map(&table->write_set, old_map);
707706
}
708707
key_len+= key_part->store_length;
709708
keypart_map= (keypart_map << 1) | 1;

0 commit comments

Comments
 (0)