Bug #19929406: HANDLE_FATAL_SIGNAL (SIG=11) IN

               __MEMMOVE_SSSE3_BACK FROM STRING::COPY

Issue:
-----
While using row comparators, the store_value functions call
val_xxx functions in the prepare phase. This can cause
valgrind issues.

SOLUTION:
---------
Setting up of the comparators should be done by
alloc_comparators in the prepare phase. Also, make sure
store_value will be called only during execute phase.

This is a backport of the fix for Bug#17755540.
parent 17387bc5
/* Copyright (c) 2000, 2013, 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
it under the terms of the GNU General Public License as published by
......@@ -3708,29 +3708,39 @@ cmp_item_row::~cmp_item_row()
}
void cmp_item_row::alloc_comparators()
void cmp_item_row::alloc_comparators(Item *item)
{
n= item->cols();
DBUG_ASSERT(comparators == NULL);
if (!comparators)
comparators= (cmp_item **) current_thd->calloc(sizeof(cmp_item *)*n);
if (comparators)
{
for (uint i= 0; i < n; i++)
{
DBUG_ASSERT(comparators[i] == NULL);
Item *item_i= item->element_index(i);
if (!(comparators[i]=
cmp_item::get_comparator(item_i->result_type(),
item_i->collation.collation)))
break; // new failed
if (item_i->result_type() == ROW_RESULT)
static_cast<cmp_item_row*>(comparators[i])->alloc_comparators(item_i);
}
}
}
void cmp_item_row::store_value(Item *item)
{
DBUG_ENTER("cmp_item_row::store_value");
n= item->cols();
alloc_comparators();
DBUG_ASSERT(comparators);
if (comparators)
{
item->bring_value();
item->null_value= 0;
for (uint i=0; i < n; i++)
for (uint i= 0; i < n; i++)
{
if (!comparators[i])
if (!(comparators[i]=
cmp_item::get_comparator(item->element_index(i)->result_type(),
item->element_index(i)->collation.collation)))
break; // new failed
comparators[i]->store_value(item->element_index(i));
item->null_value|= item->element_index(i)->null_value;
}
......@@ -3991,7 +4001,7 @@ void Item_func_in::fix_length_and_dec()
cmp_items[ROW_RESULT]= cmp;
}
cmp->n= args[0]->cols();
cmp->alloc_comparators();
cmp->alloc_comparators(args[0]);
}
/* All DATE/DATETIME fields/functions has the STRING result type. */
if (cmp_type == STRING_RESULT || cmp_type == ROW_RESULT)
......@@ -4102,11 +4112,8 @@ void Item_func_in::fix_length_and_dec()
break;
case ROW_RESULT:
/*
The row comparator was created at the beginning but only DATETIME
items comparators were initialized. Call store_value() to setup
others.
The row comparator was created at the beginning.
*/
((in_row*)array)->tmp.store_value(args[0]);
break;
case DECIMAL_RESULT:
array= new in_decimal(arg_count - 1);
......
#ifndef ITEM_CMPFUNC_INCLUDED
#define ITEM_CMPFUNC_INCLUDED
/* Copyright (c) 2000, 2012, 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
it under the terms of the GNU General Public License as published by
......@@ -1288,7 +1288,7 @@ public:
cmp_item_row(): comparators(0), n(0) {}
~cmp_item_row();
void store_value(Item *item);
inline void alloc_comparators();
inline void alloc_comparators(Item *item);
int cmp(Item *arg);
int compare(cmp_item *arg);
cmp_item *make_same();
......
/*
Copyright (c) 2000, 2014, 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
it under the terms of the GNU General Public License as published by
......@@ -1910,21 +1910,6 @@ int open_table_from_share(THD *thd, TABLE_SHARE *share, const char *alias,
outparam->record[1]= outparam->record[0]; // Safety
}
#ifdef HAVE_purify
/*
We need this because when we read var-length rows, we are not updating
bytes after end of varchar
*/
if (records > 1)
{
memcpy(outparam->record[0], share->default_values, share->rec_buff_length);
memcpy(outparam->record[1], share->default_values, share->null_bytes);
if (records > 2)
memcpy(outparam->record[1], share->default_values,
share->rec_buff_length);
}
#endif
if (!(field_ptr = (Field **) alloc_root(&outparam->mem_root,
(uint) ((share->fields+1)*
sizeof(Field*)))))
......
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