mirror of
https://github.com/MariaDB/server.git
synced 2025-01-29 18:20:07 +01:00
Bug #37936: ASSERT_COLUMN_MARKED_FOR_WRITE in Field_datetime::store ,
Field_varstring::store The code that temporary saved the bitmaps of the read set and the write set so that it can set it to all columns for debug purposes was not expecting that the table->read_set and table->write_set can be the same. And was always saving both in sequence. As a result the original value was never restored. Fixed by saving & restoring the original value only once if the two sets are the same (in a special set of functions).
This commit is contained in:
parent
54eaadf01c
commit
71296ae2e2
5 changed files with 106 additions and 27 deletions
|
@ -4358,3 +4358,29 @@ a
|
|||
4
|
||||
5
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE A (date_key date);
|
||||
CREATE TABLE C (
|
||||
pk int,
|
||||
int_nokey int,
|
||||
int_key int,
|
||||
date_key date NOT NULL,
|
||||
date_nokey date,
|
||||
varchar_key varchar(1)
|
||||
);
|
||||
INSERT INTO C VALUES
|
||||
(1,1,1,'0000-00-00',NULL,NULL),
|
||||
(1,1,1,'0000-00-00',NULL,NULL);
|
||||
SELECT 1 FROM C WHERE pk > ANY (SELECT 1 FROM C);
|
||||
1
|
||||
SELECT COUNT(DISTINCT 1) FROM C
|
||||
WHERE date_key = (SELECT 1 FROM A WHERE C.date_key IS NULL) GROUP BY pk;
|
||||
COUNT(DISTINCT 1)
|
||||
SELECT date_nokey FROM C
|
||||
WHERE int_key IN (SELECT 1 FROM A)
|
||||
HAVING date_nokey = '10:41:7'
|
||||
ORDER BY date_key;
|
||||
date_nokey
|
||||
Warnings:
|
||||
Warning 1292 Incorrect date value: '10:41:7' for column 'date_nokey' at row 1
|
||||
DROP TABLE A,C;
|
||||
End of 5.1 tests
|
||||
|
|
|
@ -3701,3 +3701,36 @@ SELECT a FROM t1 ORDER BY a LIMIT 2;
|
|||
SELECT a FROM t1 ORDER BY a LIMIT 2,4294967296;
|
||||
SELECT a FROM t1 ORDER BY a LIMIT 2,4294967297;
|
||||
DROP TABLE t1;
|
||||
|
||||
#
|
||||
# Bug #37936: ASSERT_COLUMN_MARKED_FOR_WRITE in Field_datetime::store ,
|
||||
# Field_varstring::store
|
||||
#
|
||||
|
||||
CREATE TABLE A (date_key date);
|
||||
|
||||
CREATE TABLE C (
|
||||
pk int,
|
||||
int_nokey int,
|
||||
int_key int,
|
||||
date_key date NOT NULL,
|
||||
date_nokey date,
|
||||
varchar_key varchar(1)
|
||||
);
|
||||
|
||||
INSERT INTO C VALUES
|
||||
(1,1,1,'0000-00-00',NULL,NULL),
|
||||
(1,1,1,'0000-00-00',NULL,NULL);
|
||||
|
||||
SELECT 1 FROM C WHERE pk > ANY (SELECT 1 FROM C);
|
||||
|
||||
SELECT COUNT(DISTINCT 1) FROM C
|
||||
WHERE date_key = (SELECT 1 FROM A WHERE C.date_key IS NULL) GROUP BY pk;
|
||||
SELECT date_nokey FROM C
|
||||
WHERE int_key IN (SELECT 1 FROM A)
|
||||
HAVING date_nokey = '10:41:7'
|
||||
ORDER BY date_key;
|
||||
|
||||
DROP TABLE A,C;
|
||||
|
||||
--echo End of 5.1 tests
|
||||
|
|
|
@ -394,19 +394,16 @@ static bool convert_constant_item(THD *thd, Item_field *field_item,
|
|||
TABLE *table= field->table;
|
||||
ulong orig_sql_mode= thd->variables.sql_mode;
|
||||
enum_check_fields orig_count_cuted_fields= thd->count_cuted_fields;
|
||||
my_bitmap_map *old_write_map;
|
||||
my_bitmap_map *old_read_map;
|
||||
my_bitmap_map *old_maps[2];
|
||||
ulonglong orig_field_val; /* original field value if valid */
|
||||
|
||||
LINT_INIT(old_write_map);
|
||||
LINT_INIT(old_read_map);
|
||||
LINT_INIT(old_maps[0]);
|
||||
LINT_INIT(old_maps[1]);
|
||||
LINT_INIT(orig_field_val);
|
||||
|
||||
if (table)
|
||||
{
|
||||
old_write_map= dbug_tmp_use_all_columns(table, table->write_set);
|
||||
old_read_map= dbug_tmp_use_all_columns(table, table->read_set);
|
||||
}
|
||||
dbug_tmp_use_all_columns(table, old_maps,
|
||||
table->read_set, table->write_set);
|
||||
/* For comparison purposes allow invalid dates like 2000-01-32 */
|
||||
thd->variables.sql_mode= (orig_sql_mode & ~MODE_NO_ZERO_DATE) |
|
||||
MODE_INVALID_DATES;
|
||||
|
@ -437,10 +434,7 @@ static bool convert_constant_item(THD *thd, Item_field *field_item,
|
|||
thd->variables.sql_mode= orig_sql_mode;
|
||||
thd->count_cuted_fields= orig_count_cuted_fields;
|
||||
if (table)
|
||||
{
|
||||
dbug_tmp_restore_column_map(table->write_set, old_write_map);
|
||||
dbug_tmp_restore_column_map(table->read_set, old_read_map);
|
||||
}
|
||||
dbug_tmp_restore_column_maps(table->read_set, table->write_set, old_maps);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -2668,7 +2668,7 @@ bool prune_partitions(THD *thd, TABLE *table, Item *pprune_cond)
|
|||
PART_PRUNE_PARAM prune_param;
|
||||
MEM_ROOT alloc;
|
||||
RANGE_OPT_PARAM *range_par= &prune_param.range_param;
|
||||
my_bitmap_map *old_read_set, *old_write_set;
|
||||
my_bitmap_map *old_sets[2];
|
||||
|
||||
prune_param.part_info= part_info;
|
||||
init_sql_alloc(&alloc, thd->variables.range_alloc_block_size, 0);
|
||||
|
@ -2682,8 +2682,8 @@ bool prune_partitions(THD *thd, TABLE *table, Item *pprune_cond)
|
|||
DBUG_RETURN(FALSE);
|
||||
}
|
||||
|
||||
old_write_set= dbug_tmp_use_all_columns(table, table->write_set);
|
||||
old_read_set= dbug_tmp_use_all_columns(table, table->read_set);
|
||||
dbug_tmp_use_all_columns(table, old_sets,
|
||||
table->read_set, table->write_set);
|
||||
range_par->thd= thd;
|
||||
range_par->table= table;
|
||||
/* range_par->cond doesn't need initialization */
|
||||
|
@ -2773,8 +2773,7 @@ all_used:
|
|||
retval= FALSE; // some partitions are used
|
||||
mark_all_partitions_as_used(prune_param.part_info);
|
||||
end:
|
||||
dbug_tmp_restore_column_map(table->write_set, old_write_set);
|
||||
dbug_tmp_restore_column_map(table->read_set, old_read_set);
|
||||
dbug_tmp_restore_column_maps(table->read_set, table->write_set, old_sets);
|
||||
thd->no_errors=0;
|
||||
thd->mem_root= range_par->old_root;
|
||||
free_root(&alloc,MYF(0)); // Return memory & allocator
|
||||
|
@ -11145,9 +11144,9 @@ print_key(KEY_PART *key_part, const uchar *key, uint used_length)
|
|||
String tmp(buff,sizeof(buff),&my_charset_bin);
|
||||
uint store_length;
|
||||
TABLE *table= key_part->field->table;
|
||||
my_bitmap_map *old_write_set, *old_read_set;
|
||||
old_write_set= dbug_tmp_use_all_columns(table, table->write_set);
|
||||
old_read_set= dbug_tmp_use_all_columns(table, table->read_set);
|
||||
my_bitmap_map *old_sets[2];
|
||||
|
||||
dbug_tmp_use_all_columns(table, old_sets, table->read_set, table->write_set);
|
||||
|
||||
for (; key < key_end; key+=store_length, key_part++)
|
||||
{
|
||||
|
@ -11173,8 +11172,7 @@ print_key(KEY_PART *key_part, const uchar *key, uint used_length)
|
|||
if (key+store_length < key_end)
|
||||
fputc('/',DBUG_FILE);
|
||||
}
|
||||
dbug_tmp_restore_column_map(table->write_set, old_write_set);
|
||||
dbug_tmp_restore_column_map(table->read_set, old_read_set);
|
||||
dbug_tmp_restore_column_maps(table->read_set, table->write_set, old_sets);
|
||||
}
|
||||
|
||||
|
||||
|
@ -11182,18 +11180,16 @@ static void print_quick(QUICK_SELECT_I *quick, const key_map *needed_reg)
|
|||
{
|
||||
char buf[MAX_KEY/8+1];
|
||||
TABLE *table;
|
||||
my_bitmap_map *old_read_map, *old_write_map;
|
||||
my_bitmap_map *old_sets[2];
|
||||
DBUG_ENTER("print_quick");
|
||||
if (!quick)
|
||||
DBUG_VOID_RETURN;
|
||||
DBUG_LOCK_FILE;
|
||||
|
||||
table= quick->head;
|
||||
old_read_map= dbug_tmp_use_all_columns(table, table->read_set);
|
||||
old_write_map= dbug_tmp_use_all_columns(table, table->write_set);
|
||||
dbug_tmp_use_all_columns(table, old_sets, table->read_set, table->write_set);
|
||||
quick->dbug_dump(0, TRUE);
|
||||
dbug_tmp_restore_column_map(table->read_set, old_read_map);
|
||||
dbug_tmp_restore_column_map(table->write_set, old_write_map);
|
||||
dbug_tmp_restore_column_maps(table->read_set, table->write_set, old_sets);
|
||||
|
||||
fprintf(DBUG_FILE,"other_keys: 0x%s:\n", needed_reg->print(buf));
|
||||
|
||||
|
|
30
sql/table.h
30
sql/table.h
|
@ -1692,5 +1692,35 @@ static inline void dbug_tmp_restore_column_map(MY_BITMAP *bitmap,
|
|||
#endif
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Variant of the above : handle both read and write sets.
|
||||
Provide for the possiblity of the read set being the same as the write set
|
||||
*/
|
||||
static inline void dbug_tmp_use_all_columns(TABLE *table,
|
||||
my_bitmap_map **save,
|
||||
MY_BITMAP *read_set,
|
||||
MY_BITMAP *write_set)
|
||||
{
|
||||
#ifndef DBUG_OFF
|
||||
save[0]= read_set->bitmap;
|
||||
save[1]= write_set->bitmap;
|
||||
(void) tmp_use_all_columns(table, read_set);
|
||||
(void) tmp_use_all_columns(table, write_set);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
static inline void dbug_tmp_restore_column_maps(MY_BITMAP *read_set,
|
||||
MY_BITMAP *write_set,
|
||||
my_bitmap_map **old)
|
||||
{
|
||||
#ifndef DBUG_OFF
|
||||
tmp_restore_column_map(read_set, old[0]);
|
||||
tmp_restore_column_map(write_set, old[1]);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
size_t max_row_length(TABLE *table, const uchar *data);
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue