summaryrefslogtreecommitdiff
path: root/sql/opt_range.cc
diff options
context:
space:
mode:
authorunknown <monty@mashka.mysql.fi>2003-10-13 15:50:30 +0300
committerunknown <monty@mashka.mysql.fi>2003-10-13 15:50:30 +0300
commit3974119b5f1a735d4087105eb8c07f241a70f64b (patch)
tree9b5d0d5098c97ae49c22be860572ba78e7471faa /sql/opt_range.cc
parent0cdddbf144de80d1c4da00ee681632bc0ac6c7c9 (diff)
parent74ea459412f9a479ea1385a72cc27b4245c06435 (diff)
downloadmariadb-git-3974119b5f1a735d4087105eb8c07f241a70f64b.tar.gz
merge with 4.0 for more memory allocation variables.
configure.in: Auto merged mysql-test/r/variables.result: Auto merged mysql-test/t/variables.test: Auto merged sql/ha_berkeley.cc: Auto merged sql/mysql_priv.h: Auto merged sql/opt_range.h: Auto merged sql/sql_acl.cc: Auto merged sql/sql_select.cc: Auto merged sql/sql_test.cc: Auto merged sql/sql_udf.cc: Auto merged sql/sql_update.cc: Auto merged sql/table.cc: Auto merged scripts/Makefile.am: merge sql/log_event.cc: merge sql/mysqld.cc: merge sql/opt_range.cc: merge sql/set_var.cc: merge sql/sql_class.h: merge sql/sql_delete.cc: merge sql/sql_parse.cc: merge
Diffstat (limited to 'sql/opt_range.cc')
-rw-r--r--sql/opt_range.cc103
1 files changed, 66 insertions, 37 deletions
diff --git a/sql/opt_range.cc b/sql/opt_range.cc
index 24768537e3d..b356bda6112 100644
--- a/sql/opt_range.cc
+++ b/sql/opt_range.cc
@@ -279,6 +279,7 @@ public:
typedef struct st_qsel_param {
+ THD *thd;
TABLE *table;
KEY_PART *key_parts,*key_parts_end,*key[MAX_KEY];
MEM_ROOT *mem_root;
@@ -378,13 +379,14 @@ SQL_SELECT::~SQL_SELECT()
#undef index // Fix for Unixware 7
-QUICK_SELECT::QUICK_SELECT(TABLE *table,uint key_nr,bool no_alloc)
+QUICK_SELECT::QUICK_SELECT(THD *thd, TABLE *table, uint key_nr, bool no_alloc)
:dont_free(0),error(0),index(key_nr),max_used_key_length(0),
used_key_parts(0), head(table), it(ranges),range(0)
{
if (!no_alloc)
{
- init_sql_alloc(&alloc,1024,0); // Allocates everything here
+ // Allocates everything through the internal memroot
+ init_sql_alloc(&alloc, thd->variables.range_alloc_block_size, 0);
my_pthread_setspecific_ptr(THR_MALLOC,&alloc);
}
else
@@ -456,17 +458,17 @@ SEL_ARG *SEL_ARG::clone(SEL_ARG *new_parent,SEL_ARG **next_arg)
SEL_ARG *tmp;
if (type != KEY_RANGE)
{
- if (!(tmp=new SEL_ARG(type)))
- return 0; // out of memory
+ if (!(tmp= new SEL_ARG(type)))
+ return 0; // out of memory
tmp->prev= *next_arg; // Link into next/prev chain
(*next_arg)->next=tmp;
(*next_arg)= tmp;
}
else
{
- if (!(tmp=new SEL_ARG(field,part, min_value,max_value,
- min_flag, max_flag, maybe_flag)))
- return 0; // out of memory
+ if (!(tmp= new SEL_ARG(field,part, min_value,max_value,
+ min_flag, max_flag, maybe_flag)))
+ return 0; // OOM
tmp->parent=new_parent;
tmp->next_key_part=next_key_part;
if (left != &null_element)
@@ -477,7 +479,8 @@ SEL_ARG *SEL_ARG::clone(SEL_ARG *new_parent,SEL_ARG **next_arg)
(*next_arg)= tmp;
if (right != &null_element)
- tmp->right=right->clone(tmp,next_arg);
+ if (!(tmp->right= right->clone(tmp,next_arg)))
+ return 0; // OOM
}
increment_use_count(1);
return tmp;
@@ -556,10 +559,11 @@ SEL_ARG *SEL_ARG::clone_tree()
{
SEL_ARG tmp_link,*next_arg,*root;
next_arg= &tmp_link;
- root=clone((SEL_ARG *) 0, &next_arg);
+ root= clone((SEL_ARG *) 0, &next_arg);
next_arg->next=0; // Fix last link
tmp_link.next->prev=0; // Fix first link
- root->use_count=0;
+ if (root) // If not OOM
+ root->use_count= 0;
return root;
}
@@ -577,7 +581,8 @@ SEL_ARG *SEL_ARG::clone_tree()
** quick_rows ; How many rows the key matches
*****************************************************************************/
-int SQL_SELECT::test_quick_select(key_map keys_to_use, table_map prev_tables,
+int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use,
+ table_map prev_tables,
ha_rows limit, bool force_quick_range)
{
uint basflag;
@@ -618,9 +623,9 @@ int SQL_SELECT::test_quick_select(key_map keys_to_use, table_map prev_tables,
SEL_TREE *tree;
KEY_PART *key_parts;
PARAM param;
- THD *thd= current_thd;
-
+
/* set up parameter that is passed to all functions */
+ param.thd= thd;
param.baseflag=basflag;
param.prev_tables=prev_tables | const_tables;
param.read_tables=read_tables;
@@ -630,7 +635,7 @@ int SQL_SELECT::test_quick_select(key_map keys_to_use, table_map prev_tables,
param.mem_root= &alloc;
thd->no_errors=1; // Don't warn about NULL
- init_sql_alloc(&alloc,2048,0);
+ init_sql_alloc(&alloc, thd->variables.range_alloc_block_size, 0);
if (!(param.key_parts = (KEY_PART*) alloc_root(&alloc,
sizeof(KEY_PART)*
head->key_parts)))
@@ -765,7 +770,7 @@ static SEL_TREE *get_mm_tree(PARAM *param,COND *cond)
while ((item=li++))
{
SEL_TREE *new_tree=get_mm_tree(param,item);
- if (current_thd->is_fatal_error)
+ if (param->thd->is_fatal_error)
DBUG_RETURN(0); // out of memory
tree=tree_and(param,tree,new_tree);
if (tree && tree->type == SEL_TREE::IMPOSSIBLE)
@@ -906,7 +911,7 @@ get_mm_parts(PARAM *param, Field *field, Item_func::Functype type,
{
SEL_ARG *sel_arg=0;
if (!tree && !(tree=new SEL_TREE()))
- DBUG_RETURN(0); // out of memory
+ DBUG_RETURN(0); // OOM
if (!value || !(value->used_tables() & ~param->read_tables))
{
sel_arg=get_mm_leaf(param,key_part->field,key_part,type,value);
@@ -918,10 +923,11 @@ get_mm_parts(PARAM *param, Field *field, Item_func::Functype type,
DBUG_RETURN(tree);
}
}
- else {
+ else
+ {
// This key may be used later
- if (!(sel_arg=new SEL_ARG(SEL_ARG::MAYBE_KEY)))
- DBUG_RETURN(0); // out of memory
+ if (!(sel_arg= new SEL_ARG(SEL_ARG::MAYBE_KEY)))
+ DBUG_RETURN(0); // OOM
}
sel_arg->part=(uchar) key_part->part;
tree->keys[key_part->key]=sel_add(tree->keys[key_part->key],sel_arg);
@@ -1126,8 +1132,8 @@ get_mm_leaf(PARAM *param, Field *field, KEY_PART *key_part,
******************************************************************************/
/*
-** Add a new key test to a key when scanning through all keys
-** This will never be called for same key parts.
+ Add a new key test to a key when scanning through all keys
+ This will never be called for same key parts.
*/
static SEL_ARG *
@@ -1311,7 +1317,8 @@ key_and(SEL_ARG *key1,SEL_ARG *key2,uint clone_flag)
// key1->part < key2->part
key1->use_count--;
if (key1->use_count > 0)
- key1=key1->clone_tree();
+ if (!(key1= key1->clone_tree()))
+ return 0; // OOM
return and_all_keys(key1,key2,clone_flag);
}
@@ -1330,7 +1337,8 @@ key_and(SEL_ARG *key1,SEL_ARG *key2,uint clone_flag)
if (key1->use_count > 1)
{
key1->use_count--;
- key1=key1->clone_tree();
+ if (!(key1=key1->clone_tree()))
+ return 0; // OOM
key1->use_count++;
}
if (key1->type == SEL_ARG::MAYBE_KEY)
@@ -1374,6 +1382,8 @@ key_and(SEL_ARG *key1,SEL_ARG *key2,uint clone_flag)
if (!next || next->type != SEL_ARG::IMPOSSIBLE)
{
SEL_ARG *new_arg= e1->clone_and(e2);
+ if (!new_arg)
+ return &null_element; // End of memory
new_arg->next_key_part=next;
if (!new_tree)
{
@@ -1461,8 +1471,8 @@ key_or(SEL_ARG *key1,SEL_ARG *key2)
{
swap(SEL_ARG *,key1,key2);
}
- else
- key1=key1->clone_tree();
+ else if (!(key1=key1->clone_tree()))
+ return 0; // OOM
}
// Add tree at key2 to tree at key1
@@ -1530,7 +1540,10 @@ key_or(SEL_ARG *key1,SEL_ARG *key2)
SEL_ARG *next=key2->next; // Keys are not overlapping
if (key2_shared)
{
- key1=key1->insert(new SEL_ARG(*key2)); // Must make copy
+ SEL_ARG *tmp= new SEL_ARG(*key2); // Must make copy
+ if (!tmp)
+ return 0; // OOM
+ key1=key1->insert(tmp);
key2->increment_use_count(key1->use_count+1);
}
else
@@ -1576,6 +1589,8 @@ key_or(SEL_ARG *key1,SEL_ARG *key2)
if (cmp >= 0 && tmp->cmp_min_to_min(key2) < 0)
{ // tmp.min <= x < key2.min
SEL_ARG *new_arg=tmp->clone_first(key2);
+ if (!new_arg)
+ return 0; // OOM
if ((new_arg->next_key_part= key1->next_key_part))
new_arg->increment_use_count(key1->use_count+1);
tmp->copy_min_to_min(key2);
@@ -1589,6 +1604,8 @@ key_or(SEL_ARG *key1,SEL_ARG *key2)
if (tmp->cmp_min_to_min(&key) > 0)
{ // key.min <= x < tmp.min
SEL_ARG *new_arg=key.clone_first(tmp);
+ if (!new_arg)
+ return 0; // OOM
if ((new_arg->next_key_part=key.next_key_part))
new_arg->increment_use_count(key1->use_count+1);
key1=key1->insert(new_arg);
@@ -1603,19 +1620,27 @@ key_or(SEL_ARG *key1,SEL_ARG *key2)
key.copy_max_to_min(tmp);
if (!(tmp=tmp->next))
{
- key1=key1->insert(new SEL_ARG(key));
+ SEL_ARG *tmp2= new SEL_ARG(key);
+ if (!tmp2)
+ return 0; // OOM
+ key1=key1->insert(tmp2);
key2=key2->next;
goto end;
}
if (tmp->cmp_min_to_max(&key) > 0)
{
- key1=key1->insert(new SEL_ARG(key));
+ SEL_ARG *tmp2= new SEL_ARG(key);
+ if (!tmp2)
+ return 0; // OOM
+ key1=key1->insert(tmp2);
break;
}
}
else
{
SEL_ARG *new_arg=tmp->clone_last(&key); // tmp.min <= x <= key.max
+ if (!new_arg)
+ return 0; // OOM
tmp->copy_max_to_min(&key);
tmp->increment_use_count(key1->use_count+1);
new_arg->next_key_part=key_or(tmp->next_key_part,key.next_key_part);
@@ -1632,8 +1657,11 @@ end:
SEL_ARG *next=key2->next;
if (key2_shared)
{
+ SEL_ARG *tmp=new SEL_ARG(*key2); // Must make copy
+ if (!tmp)
+ return 0;
key2->increment_use_count(key1->use_count+1);
- key1=key1->insert(new SEL_ARG(*key2)); // Must make copy
+ key1=key1->insert(tmp);
}
else
key1=key1->insert(key2); // Will destroy key2_root
@@ -2222,7 +2250,8 @@ get_quick_select(PARAM *param,uint idx,SEL_ARG *key_tree)
{
QUICK_SELECT *quick;
DBUG_ENTER("get_quick_select");
- if ((quick=new QUICK_SELECT(param->table,param->real_keynr[idx])))
+ if ((quick=new QUICK_SELECT(param->thd, param->table,
+ param->real_keynr[idx])))
{
if (quick->error ||
get_quick_keys(param,quick,param->key[idx],key_tree,param->min_key,0,
@@ -2334,10 +2363,10 @@ get_quick_keys(PARAM *param,QUICK_SELECT *quick,KEY_PART *key,
/* Get range for retrieving rows in QUICK_SELECT::get_next */
if (!(range= new QUICK_RANGE(param->min_key,
- (uint) (tmp_min_key - param->min_key),
- param->max_key,
- (uint) (tmp_max_key - param->max_key),
- flag)))
+ (uint) (tmp_min_key - param->min_key),
+ param->max_key,
+ (uint) (tmp_max_key - param->max_key),
+ flag)))
return 1; // out of memory
set_if_bigger(quick->max_used_key_length,range->min_length);
@@ -2394,10 +2423,10 @@ static bool null_part_in_key(KEY_PART *key_part, const char *key, uint length)
** Create a QUICK RANGE based on a key
****************************************************************************/
-QUICK_SELECT *get_quick_select_for_ref(TABLE *table, TABLE_REF *ref)
+QUICK_SELECT *get_quick_select_for_ref(THD *thd, TABLE *table, TABLE_REF *ref)
{
table->file->index_end(); // Remove old cursor
- QUICK_SELECT *quick=new QUICK_SELECT(table, ref->key, 1);
+ QUICK_SELECT *quick=new QUICK_SELECT(thd, table, ref->key, 1);
KEY *key_info = &table->key_info[ref->key];
KEY_PART *key_part;
uint part;
@@ -2406,7 +2435,7 @@ QUICK_SELECT *get_quick_select_for_ref(TABLE *table, TABLE_REF *ref)
return 0; /* no ranges found */
if (cp_buffer_from_ref(ref))
{
- if (current_thd->is_fatal_error)
+ if (thd->is_fatal_error)
return 0; // out of memory
return quick; // empty range
}