Commit 90e22408 authored by Sergei Golubchik's avatar Sergei Golubchik

MDEV-5461 Assertion `length <= column->length' fails in write_block_record...

MDEV-5461 Assertion `length <= column->length' fails in write_block_record with functions in select list, GROUP BY, ORDER BY

Old code in create_tmp_table(), that created an extra one-byte field (recinfo)
before every NULL-able grouping field (Field) in the tmp table, did not actually work.
Because the matching code in end_update(), that was supposed to update this byte,
was using a wrong offset, updating the first byte of the Field, not a byte before it.
Normally this wasn't an issue, because the Field value (written later in end_update)
was overwriting this byte anyway. But in this bug the Field was Field_null, with zero
length, so end_update() was overwriting the first byte of the following field.
And the following field was not-nullable constant, which was stored only once in
create_tmp_table and never updated later.

Fixed by removing the code that didn't do any useful work anyway.
parent 3f2f9c36
create table t1 (a int);
insert into t1 values (1),(2);
select max('foo') from t1 group by values(a), extractvalue('bar','qux') order by "v";
max('foo')
foo
drop table t1;
#
# MDEV-5461 Assertion `length <= column->length' fails in write_block_record with functions in select list, GROUP BY, ORDER BY
#
create table t1 (a int);
insert into t1 values (1),(2);
select max('foo') from t1 group by values(a), extractvalue('bar','qux') order by "v";
drop table t1;
...@@ -15243,23 +15243,8 @@ create_tmp_table(THD *thd, TMP_TABLE_PARAM *param, List<Item> &fields, ...@@ -15243,23 +15243,8 @@ create_tmp_table(THD *thd, TMP_TABLE_PARAM *param, List<Item> &fields,
if (!(field->flags & NOT_NULL_FLAG)) if (!(field->flags & NOT_NULL_FLAG))
{ {
if (field->flags & GROUP_FLAG && !using_unique_constraint) recinfo->null_bit= (uint8)1 << (null_count & 7);
{ recinfo->null_pos= null_count/8;
/*
We have to reserve one byte here for NULL bits,
as this is updated by 'end_update()'
*/
*pos++=0; // Null is stored here
recinfo->length=1;
recinfo->type=FIELD_NORMAL;
recinfo++;
bzero((uchar*) recinfo,sizeof(*recinfo));
}
else
{
recinfo->null_bit= (uint8)1 << (null_count & 7);
recinfo->null_pos= null_count/8;
}
field->move_field(pos,null_flags+null_count/8, field->move_field(pos,null_flags+null_count/8,
(uint8)1 << (null_count & 7)); (uint8)1 << (null_count & 7));
null_count++; null_count++;
...@@ -18186,19 +18171,6 @@ end_update(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)), ...@@ -18186,19 +18171,6 @@ end_update(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
goto end; goto end;
} }
/*
Copy null bits from group key to table
We can't copy all data as the key may have different format
as the row data (for example as with VARCHAR keys)
*/
KEY_PART_INFO *key_part;
for (group=table->group,key_part=table->key_info[0].key_part;
group ;
group=group->next,key_part++)
{
if (key_part->null_bit)
memcpy(table->record[0]+key_part->offset, group->buff, 1);
}
init_tmptable_sum_functions(join->sum_funcs); init_tmptable_sum_functions(join->sum_funcs);
if (copy_funcs(join->tmp_table_param.items_to_copy, join->thd)) if (copy_funcs(join->tmp_table_param.items_to_copy, join->thd))
DBUG_RETURN(NESTED_LOOP_ERROR); /* purecov: inspected */ DBUG_RETURN(NESTED_LOOP_ERROR); /* purecov: inspected */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment