#At file:///home/kgeorge/mysql/bzr/B37936-5.1-bugteam/
2690 Georgi Kodinov 2008-11-05
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.
modified:
mysql-test/r/select.result
mysql-test/t/select.test
sql/item_cmpfunc.cc
sql/opt_range.cc
per-file messages:
mysql-test/r/select.result
Bug #37936: test case
mysql-test/t/select.test
Bug #37936: test case
sql/item_cmpfunc.cc
Bug #37936: don't save/restore twice if the read and write sets are the same
sql/opt_range.cc
Bug #37936: don't save/restore twice if the read and write sets are the same
=== modified file 'mysql-test/r/select.result'
--- a/mysql-test/r/select.result 2008-03-12 08:19:46 +0000
+++ b/mysql-test/r/select.result 2008-11-05 14:54:33 +0000
@@ -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
=== modified file 'mysql-test/t/select.test'
--- a/mysql-test/t/select.test 2008-02-18 15:20:14 +0000
+++ b/mysql-test/t/select.test 2008-11-05 14:54:33 +0000
@@ -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
=== modified file 'sql/item_cmpfunc.cc'
--- a/sql/item_cmpfunc.cc 2008-10-27 16:19:26 +0000
+++ b/sql/item_cmpfunc.cc 2008-11-05 14:54:33 +0000
@@ -396,16 +396,21 @@ static bool convert_constant_item(THD *t
enum_check_fields orig_count_cuted_fields= thd->count_cuted_fields;
my_bitmap_map *old_write_map;
my_bitmap_map *old_read_map;
+ bool different_sets;
ulonglong orig_field_val; /* original field value if valid */
LINT_INIT(old_write_map);
LINT_INIT(old_read_map);
LINT_INIT(orig_field_val);
+ LINT_INIT(different_sets);
if (table)
{
+ different_sets= table->write_set != table->read_set;
+
old_write_map= dbug_tmp_use_all_columns(table, table->write_set);
- old_read_map= dbug_tmp_use_all_columns(table, table->read_set);
+ if (different_sets)
+ old_read_map= dbug_tmp_use_all_columns(table, table->read_set);
}
/* For comparison purposes allow invalid dates like 2000-01-32 */
thd->variables.sql_mode= (orig_sql_mode & ~MODE_NO_ZERO_DATE) |
@@ -439,7 +444,8 @@ static bool convert_constant_item(THD *t
if (table)
{
dbug_tmp_restore_column_map(table->write_set, old_write_map);
- dbug_tmp_restore_column_map(table->read_set, old_read_map);
+ if (different_sets)
+ dbug_tmp_restore_column_map(table->read_set, old_read_map);
}
}
return result;
=== modified file 'sql/opt_range.cc'
--- a/sql/opt_range.cc 2008-10-10 13:07:53 +0000
+++ b/sql/opt_range.cc 2008-11-05 14:54:33 +0000
@@ -2669,6 +2669,7 @@ bool prune_partitions(THD *thd, TABLE *t
MEM_ROOT alloc;
RANGE_OPT_PARAM *range_par= &prune_param.range_param;
my_bitmap_map *old_read_set, *old_write_set;
+ bool different_sets;
prune_param.part_info= part_info;
init_sql_alloc(&alloc, thd->variables.range_alloc_block_size, 0);
@@ -2682,8 +2683,10 @@ bool prune_partitions(THD *thd, TABLE *t
DBUG_RETURN(FALSE);
}
+ different_sets= table->read_set != table->write_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);
+ if (different_sets)
+ old_read_set= dbug_tmp_use_all_columns(table, table->read_set);
range_par->thd= thd;
range_par->table= table;
/* range_par->cond doesn't need initialization */
@@ -2774,7 +2777,8 @@ all_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);
+ if (different_sets)
+ dbug_tmp_restore_column_map(table->read_set, old_read_set);
thd->no_errors=0;
thd->mem_root= range_par->old_root;
free_root(&alloc,MYF(0)); // Return memory & allocator
@@ -11146,8 +11150,11 @@ print_key(KEY_PART *key_part, const ucha
uint store_length;
TABLE *table= key_part->field->table;
my_bitmap_map *old_write_set, *old_read_set;
+ bool different_sets;
+ different_sets= table->read_set != table->write_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);
+ if (different_sets)
+ old_read_set= dbug_tmp_use_all_columns(table, table->read_set);
for (; key < key_end; key+=store_length, key_part++)
{
@@ -11174,7 +11181,8 @@ print_key(KEY_PART *key_part, const ucha
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);
+ if (different_sets)
+ dbug_tmp_restore_column_map(table->read_set, old_read_set);
}
@@ -11183,17 +11191,21 @@ static void print_quick(QUICK_SELECT_I *
char buf[MAX_KEY/8+1];
TABLE *table;
my_bitmap_map *old_read_map, *old_write_map;
+ bool different_sets;
DBUG_ENTER("print_quick");
if (!quick)
DBUG_VOID_RETURN;
DBUG_LOCK_FILE;
table= quick->head;
+ different_sets= table->read_set != table->write_set;
old_read_map= dbug_tmp_use_all_columns(table, table->read_set);
- old_write_map= dbug_tmp_use_all_columns(table, table->write_set);
+ if (different_sets)
+ old_write_map= dbug_tmp_use_all_columns(table, 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);
+ if (different_sets)
+ dbug_tmp_restore_column_map(table->write_set, old_write_map);
fprintf(DBUG_FILE,"other_keys: 0x%s:\n", needed_reg->print(buf));