summaryrefslogtreecommitdiff
path: root/sql/opt_range.cc
diff options
context:
space:
mode:
authorMartin Hansson <martin.hansson@sun.com>2010-06-24 15:21:23 +0200
committerMartin Hansson <martin.hansson@sun.com>2010-06-24 15:21:23 +0200
commit2b734bbee9aeb98a64a5b59808f56342819053a7 (patch)
tree2021a4b16d7dd8402d35c567685bc77fcdd32115 /sql/opt_range.cc
parentf4420a3b90e57c68cc72606b4ecb240266260861 (diff)
downloadmariadb-git-2b734bbee9aeb98a64a5b59808f56342819053a7.tar.gz
Bug#41660: Sort-index_merge for non-first join table may
require O(#scans) memory When an index merge operation was restarted, it would re-allocate the Unique object controlling the duplicate row ID elimination. Fixed by making the Unique object a member of QUICK_INDEX_MERGE_SELECT and thus reusing it throughout the lifetime of this object.
Diffstat (limited to 'sql/opt_range.cc')
-rw-r--r--sql/opt_range.cc37
1 files changed, 19 insertions, 18 deletions
diff --git a/sql/opt_range.cc b/sql/opt_range.cc
index 2f4281d539f..f2f14a2dcc9 100644
--- a/sql/opt_range.cc
+++ b/sql/opt_range.cc
@@ -1194,7 +1194,7 @@ QUICK_RANGE_SELECT::~QUICK_RANGE_SELECT()
QUICK_INDEX_MERGE_SELECT::QUICK_INDEX_MERGE_SELECT(THD *thd_param,
TABLE *table)
- :pk_quick_select(NULL), thd(thd_param)
+ :unique(NULL), pk_quick_select(NULL), thd(thd_param)
{
DBUG_ENTER("QUICK_INDEX_MERGE_SELECT::QUICK_INDEX_MERGE_SELECT");
index= MAX_KEY;
@@ -1236,6 +1236,7 @@ QUICK_INDEX_MERGE_SELECT::~QUICK_INDEX_MERGE_SELECT()
List_iterator_fast<QUICK_RANGE_SELECT> quick_it(quick_selects);
QUICK_RANGE_SELECT* quick;
DBUG_ENTER("QUICK_INDEX_MERGE_SELECT::~QUICK_INDEX_MERGE_SELECT");
+ delete unique;
quick_it.rewind();
while ((quick= quick_it++))
quick->file= NULL;
@@ -8153,7 +8154,6 @@ int QUICK_INDEX_MERGE_SELECT::read_keys_and_merge()
List_iterator_fast<QUICK_RANGE_SELECT> cur_quick_it(quick_selects);
QUICK_RANGE_SELECT* cur_quick;
int result;
- Unique *unique;
handler *file= head->file;
DBUG_ENTER("QUICK_INDEX_MERGE_SELECT::read_keys_and_merge");
@@ -8172,9 +8172,22 @@ int QUICK_INDEX_MERGE_SELECT::read_keys_and_merge()
if (cur_quick->init() || cur_quick->reset())
DBUG_RETURN(1);
- unique= new Unique(refpos_order_cmp, (void *)file,
- file->ref_length,
- thd->variables.sortbuff_size);
+ if (unique == NULL)
+ {
+ DBUG_EXECUTE_IF("index_merge_may_not_create_a_Unique", abort(); );
+ DBUG_EXECUTE_IF("only_one_Unique_may_be_created",
+ DBUG_SET("+d,index_merge_may_not_create_a_Unique"); );
+
+ unique= new Unique(refpos_order_cmp, (void *)file,
+ file->ref_length,
+ thd->variables.sortbuff_size);
+ }
+ else
+ unique->reset();
+
+ DBUG_ASSERT(file->ref_length == unique->get_size());
+ DBUG_ASSERT(thd->variables.sortbuff_size == unique->get_max_in_memory_size());
+
if (!unique)
DBUG_RETURN(1);
for (;;)
@@ -8189,10 +8202,7 @@ int QUICK_INDEX_MERGE_SELECT::read_keys_and_merge()
if (cur_quick->file->inited != handler::NONE)
cur_quick->file->ha_index_end();
if (cur_quick->init() || cur_quick->reset())
- {
- delete unique;
DBUG_RETURN(1);
- }
}
if (result)
@@ -8200,17 +8210,13 @@ int QUICK_INDEX_MERGE_SELECT::read_keys_and_merge()
if (result != HA_ERR_END_OF_FILE)
{
cur_quick->range_end();
- delete unique;
DBUG_RETURN(result);
}
break;
}
if (thd->killed)
- {
- delete unique;
DBUG_RETURN(1);
- }
/* skip row if it will be retrieved by clustered PK scan */
if (pk_quick_select && pk_quick_select->row_in_ranges())
@@ -8219,10 +8225,7 @@ int QUICK_INDEX_MERGE_SELECT::read_keys_and_merge()
cur_quick->file->position(cur_quick->record);
result= unique->unique_add((char*)cur_quick->file->ref);
if (result)
- {
- delete unique;
DBUG_RETURN(1);
- }
}
/*
@@ -8231,7 +8234,6 @@ int QUICK_INDEX_MERGE_SELECT::read_keys_and_merge()
sequence.
*/
result= unique->get(head);
- delete unique;
doing_pk_scan= FALSE;
/* index_merge currently doesn't support "using index" at all */
head->set_keyread(FALSE);
@@ -10277,7 +10279,7 @@ QUICK_GROUP_MIN_MAX_SELECT(TABLE *table, JOIN *join_arg, bool have_min_arg,
uint use_index, double read_cost_arg,
ha_rows records_arg, uint key_infix_len_arg,
uchar *key_infix_arg, MEM_ROOT *parent_alloc)
- :join(join_arg), index_info(index_info_arg),
+ :file(table->file), join(join_arg), index_info(index_info_arg),
group_prefix_len(group_prefix_len_arg),
group_key_parts(group_key_parts_arg), have_min(have_min_arg),
have_max(have_max_arg), seen_first_key(FALSE),
@@ -10286,7 +10288,6 @@ QUICK_GROUP_MIN_MAX_SELECT(TABLE *table, JOIN *join_arg, bool have_min_arg,
max_functions_it(NULL)
{
head= table;
- file= head->file;
index= use_index;
record= head->record[0];
tmp_record= head->record[1];