diff options
author | unknown <holyfoot/hf@mysql.com/hfmain.(none)> | 2007-04-19 21:43:42 +0500 |
---|---|---|
committer | unknown <holyfoot/hf@mysql.com/hfmain.(none)> | 2007-04-19 21:43:42 +0500 |
commit | 611456362f520bd5b3380e7cf90cfb2aaadd18be (patch) | |
tree | 0eaec27c535b248bcfac6751f1bea94265b8d1cd /sql/key.cc | |
parent | cc76701e8f47ca52ca209150f49ba665a215c1d0 (diff) | |
download | mariadb-git-611456362f520bd5b3380e7cf90cfb2aaadd18be.tar.gz |
Bug #27123 (partition + on duplicate key update + varchar = Can't find
record in table)
key_restore function didn't work as intended in the case of
VARCHAR or BLOB fields, stored the restored key in field->ptr instead
of to_record.
That produced the wrong key so search returned wrong result
mysql-test/r/partition.result:
result added
mysql-test/t/partition.test:
testcase
sql/field.cc:
Field_blob::store_length made static
sql/field.h:
Field_blob::store_length and set_ptr functions implemented in slightly
different way
sql/ha_ndbcluster.cc:
set_ptr_offset used
sql/key.cc:
set key_part->field->ptr to the proper place inside the to_record
so the restored key will be placed there as key_restore
is supposed to behave
Diffstat (limited to 'sql/key.cc')
-rw-r--r-- | sql/key.cc | 23 |
1 files changed, 17 insertions, 6 deletions
diff --git a/sql/key.cc b/sql/key.cc index faa7bf1f04b..5054998bd99 100644 --- a/sql/key.cc +++ b/sql/key.cc @@ -221,23 +221,34 @@ void key_restore(byte *to_record, byte *from_key, KEY *key_info, } if (key_part->key_part_flag & HA_BLOB_PART) { + /* + This in fact never happens, as we have only partial BLOB + keys yet anyway, so it's difficult to find any sence to + restore the part of a record. + Maybe this branch is to be removed, but now we + have to ignore GCov compaining. + */ uint blob_length= uint2korr(from_key); + Field_blob *field= (Field_blob*) key_part->field; from_key+= HA_KEY_BLOB_LENGTH; key_length-= HA_KEY_BLOB_LENGTH; - ((Field_blob*) key_part->field)->set_ptr((ulong) blob_length, - (char*) from_key); + field->set_ptr_offset(to_record - field->table->record[0], + (ulong) blob_length, (char*) from_key); length= key_part->length; } else if (key_part->key_part_flag & HA_VAR_LENGTH_PART) { + Field *field= key_part->field; my_bitmap_map *old_map; + my_ptrdiff_t ptrdiff= to_record - field->table->record[0]; + field->move_field_offset(ptrdiff); key_length-= HA_KEY_BLOB_LENGTH; length= min(key_length, key_part->length); - old_map= dbug_tmp_use_all_columns(key_part->field->table, - key_part->field->table->write_set); - key_part->field->set_key_image((char *) from_key, length); - dbug_tmp_restore_column_map(key_part->field->table->write_set, old_map); + old_map= dbug_tmp_use_all_columns(field->table, field->table->write_set); + field->set_key_image((char *) from_key, length); + dbug_tmp_restore_column_map(field->table->write_set, old_map); from_key+= HA_KEY_BLOB_LENGTH; + field->move_field_offset(-ptrdiff); } else { |