Bug #22023218: MYSQL 5.5: MAIN.FULLTEXT HAS VALGRIND ISSUES.


Issue
-----
This problem occurs when varchar columns are used in a
internal temporary table. The type of the field is set
incorrectly to the generic FIELD_NORMAL type. This in turn
results in an inaccurate calculation of the record length.
Valgrind issues will occur since initialization has not
happend for some bytes.

Fix
----
While creating the temporary table, the type of the field
needs to be to set FIELD_VARCHAR. This will allow myisam
to calculate the record length accurately.

This fix is a backport of BUG#13350136.
parent 9b6ac734
...@@ -10313,8 +10313,8 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields, ...@@ -10313,8 +10313,8 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
uint temp_pool_slot=MY_BIT_NONE; uint temp_pool_slot=MY_BIT_NONE;
uint fieldnr= 0; uint fieldnr= 0;
ulong reclength, string_total_length; ulong reclength, string_total_length;
bool using_unique_constraint= 0; bool using_unique_constraint= false;
bool use_packed_rows= 0; bool use_packed_rows= false;
bool not_all_columns= !(select_options & TMP_TABLE_ALL_COLUMNS); bool not_all_columns= !(select_options & TMP_TABLE_ALL_COLUMNS);
char *tmpname,path[FN_REFLEN]; char *tmpname,path[FN_REFLEN];
uchar *pos, *group_buff, *bitmaps; uchar *pos, *group_buff, *bitmaps;
...@@ -10370,10 +10370,10 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields, ...@@ -10370,10 +10370,10 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
{ {
(*tmp->item)->marker=4; // Store null in key (*tmp->item)->marker=4; // Store null in key
if ((*tmp->item)->max_length >= CONVERT_IF_BIGGER_TO_BLOB) if ((*tmp->item)->max_length >= CONVERT_IF_BIGGER_TO_BLOB)
using_unique_constraint=1; using_unique_constraint= true;
} }
if (param->group_length >= MAX_BLOB_WIDTH) if (param->group_length >= MAX_BLOB_WIDTH)
using_unique_constraint=1; using_unique_constraint= true;
if (group) if (group)
distinct=0; // Can't use distinct distinct=0; // Can't use distinct
} }
...@@ -10588,6 +10588,14 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields, ...@@ -10588,6 +10588,14 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
*blob_field++= fieldnr; *blob_field++= fieldnr;
blob_count++; blob_count++;
} }
if (new_field->real_type() == MYSQL_TYPE_STRING ||
new_field->real_type() == MYSQL_TYPE_VARCHAR)
{
string_count++;
string_total_length+= new_field->pack_length();
}
if (item->marker == 4 && item->maybe_null) if (item->marker == 4 && item->maybe_null)
{ {
group_null_items++; group_null_items++;
...@@ -10638,7 +10646,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields, ...@@ -10638,7 +10646,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
if (group && if (group &&
(param->group_parts > table->file->max_key_parts() || (param->group_parts > table->file->max_key_parts() ||
param->group_length > table->file->max_key_length())) param->group_length > table->file->max_key_length()))
using_unique_constraint=1; using_unique_constraint= true;
} }
else else
{ {
...@@ -10791,6 +10799,10 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields, ...@@ -10791,6 +10799,10 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
field->real_type() == MYSQL_TYPE_STRING && field->real_type() == MYSQL_TYPE_STRING &&
length >= MIN_STRING_LENGTH_TO_PACK_ROWS) length >= MIN_STRING_LENGTH_TO_PACK_ROWS)
recinfo->type=FIELD_SKIP_ENDSPACE; recinfo->type=FIELD_SKIP_ENDSPACE;
else if (use_packed_rows &&
field->real_type() == MYSQL_TYPE_VARCHAR &&
length >= MIN_STRING_LENGTH_TO_PACK_ROWS)
recinfo->type= FIELD_VARCHAR;
else else
recinfo->type=FIELD_NORMAL; recinfo->type=FIELD_NORMAL;
if (!--hidden_field_count) if (!--hidden_field_count)
...@@ -11229,11 +11241,15 @@ static bool create_myisam_tmp_table(TABLE *table,TMP_TABLE_PARAM *param, ...@@ -11229,11 +11241,15 @@ static bool create_myisam_tmp_table(TABLE *table,TMP_TABLE_PARAM *param,
create_info.data_file_length= ~(ulonglong) 0; create_info.data_file_length= ~(ulonglong) 0;
if ((error=mi_create(share->table_name.str, share->keys, &keydef, if ((error=mi_create(share->table_name.str, share->keys, &keydef,
(uint) (param->recinfo-param->start_recinfo), (uint) (param->recinfo-param->start_recinfo),
param->start_recinfo, param->start_recinfo,
share->uniques, &uniquedef, share->uniques, &uniquedef,
&create_info, &create_info,
HA_CREATE_TMP_TABLE))) HA_CREATE_TMP_TABLE |
((share->db_create_options & HA_OPTION_PACK_RECORD) ?
HA_PACK_RECORD : 0)
)))
{ {
table->file->print_error(error,MYF(0)); /* purecov: inspected */ table->file->print_error(error,MYF(0)); /* purecov: inspected */
/* /*
......
/* /*
Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
...@@ -462,7 +462,6 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs, ...@@ -462,7 +462,6 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
key_del[i]=HA_OFFSET_ERROR; key_del[i]=HA_OFFSET_ERROR;
unique_key_parts=0; unique_key_parts=0;
offset=reclength-uniques*MI_UNIQUE_HASH_LENGTH;
for (i=0, uniquedef=uniquedefs ; i < uniques ; i++ , uniquedef++) for (i=0, uniquedef=uniquedefs ; i < uniques ; i++ , uniquedef++)
{ {
uniquedef->key=keys+i; uniquedef->key=keys+i;
...@@ -727,7 +726,7 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs, ...@@ -727,7 +726,7 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
#endif #endif
} }
/* Create extra keys for unique definitions */ /* Create extra keys for unique definitions */
offset=reclength-uniques*MI_UNIQUE_HASH_LENGTH; offset=real_reclength - uniques * MI_UNIQUE_HASH_LENGTH;
bzero((char*) &tmp_keydef,sizeof(tmp_keydef)); bzero((char*) &tmp_keydef,sizeof(tmp_keydef));
bzero((char*) &tmp_keyseg,sizeof(tmp_keyseg)); bzero((char*) &tmp_keyseg,sizeof(tmp_keyseg));
for (i=0; i < uniques ; i++) for (i=0; i < uniques ; i++)
......
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