mirror of
https://github.com/MariaDB/server.git
synced 2025-07-07 06:01:31 +03:00
Manual merge
This commit is contained in:
104
sql/opt_range.cc
104
sql/opt_range.cc
@ -301,10 +301,11 @@ typedef struct st_qsel_param {
|
||||
uint imerge_cost_buff_size; /* size of the buffer */
|
||||
} PARAM;
|
||||
|
||||
static SEL_TREE * get_mm_parts(PARAM *param,Field *field,
|
||||
static SEL_TREE * get_mm_parts(PARAM *param,COND *cond_func,Field *field,
|
||||
Item_func::Functype type,Item *value,
|
||||
Item_result cmp_type);
|
||||
static SEL_ARG *get_mm_leaf(PARAM *param,Field *field,KEY_PART *key_part,
|
||||
static SEL_ARG *get_mm_leaf(PARAM *param,COND *cond_func,Field *field,
|
||||
KEY_PART *key_part,
|
||||
Item_func::Functype type,Item *value);
|
||||
static SEL_TREE *get_mm_tree(PARAM *param,COND *cond);
|
||||
static ha_rows check_quick_select(PARAM *param,uint index,SEL_ARG *key_tree);
|
||||
@ -612,14 +613,25 @@ SQL_SELECT::SQL_SELECT() :quick(0),cond(0),free_cond(0)
|
||||
}
|
||||
|
||||
|
||||
SQL_SELECT::~SQL_SELECT()
|
||||
void SQL_SELECT::cleanup()
|
||||
{
|
||||
delete quick;
|
||||
quick= 0;
|
||||
if (free_cond)
|
||||
{
|
||||
free_cond=0;
|
||||
delete cond;
|
||||
cond= 0;
|
||||
}
|
||||
close_cached_file(&file);
|
||||
}
|
||||
|
||||
|
||||
SQL_SELECT::~SQL_SELECT()
|
||||
{
|
||||
cleanup();
|
||||
}
|
||||
|
||||
#undef index // Fix for Unixware 7
|
||||
|
||||
QUICK_SELECT_I::QUICK_SELECT_I()
|
||||
@ -1746,7 +1758,8 @@ static SEL_TREE *get_mm_tree(PARAM *param,COND *cond)
|
||||
|
||||
|
||||
static SEL_TREE *
|
||||
get_mm_parts(PARAM *param, Field *field, Item_func::Functype type,
|
||||
get_mm_parts(PARAM *param, COND *cond_func, Field *field,
|
||||
Item_func::Functype type,
|
||||
Item *value, Item_result cmp_type)
|
||||
{
|
||||
DBUG_ENTER("get_mm_parts");
|
||||
@ -1768,7 +1781,8 @@ get_mm_parts(PARAM *param, Field *field, Item_func::Functype type,
|
||||
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);
|
||||
sel_arg=get_mm_leaf(param,cond_func,
|
||||
key_part->field,key_part,type,value);
|
||||
if (!sel_arg)
|
||||
continue;
|
||||
if (sel_arg->type == SEL_ARG::IMPOSSIBLE)
|
||||
@ -1794,7 +1808,7 @@ get_mm_parts(PARAM *param, Field *field, Item_func::Functype type,
|
||||
|
||||
|
||||
static SEL_ARG *
|
||||
get_mm_leaf(PARAM *param, Field *field, KEY_PART *key_part,
|
||||
get_mm_leaf(PARAM *param, COND *conf_func, Field *field, KEY_PART *key_part,
|
||||
Item_func::Functype type,Item *value)
|
||||
{
|
||||
uint maybe_null=(uint) field->real_maybe_null(), copies;
|
||||
@ -1803,6 +1817,32 @@ get_mm_leaf(PARAM *param, Field *field, KEY_PART *key_part,
|
||||
char *str, *str2;
|
||||
DBUG_ENTER("get_mm_leaf");
|
||||
|
||||
if (!value) // IS NULL or IS NOT NULL
|
||||
{
|
||||
if (field->table->outer_join) // Can't use a key on this
|
||||
DBUG_RETURN(0);
|
||||
if (!maybe_null) // Not null field
|
||||
DBUG_RETURN(type == Item_func::ISNULL_FUNC ? &null_element : 0);
|
||||
if (!(tree=new SEL_ARG(field,is_null_string,is_null_string)))
|
||||
DBUG_RETURN(0); // out of memory
|
||||
if (type == Item_func::ISNOTNULL_FUNC)
|
||||
{
|
||||
tree->min_flag=NEAR_MIN; /* IS NOT NULL -> X > NULL */
|
||||
tree->max_flag=NO_MAX_RANGE;
|
||||
}
|
||||
DBUG_RETURN(tree);
|
||||
}
|
||||
|
||||
/*
|
||||
We can't use an index when comparing strings of
|
||||
different collations
|
||||
*/
|
||||
if (field->result_type() == STRING_RESULT &&
|
||||
value->result_type() == STRING_RESULT &&
|
||||
key_part->image_type == Field::itRAW &&
|
||||
((Field_str*)field)->charset() != conf_func->compare_collation())
|
||||
DBUG_RETURN(0);
|
||||
|
||||
if (type == Item_func::LIKE_FUNC)
|
||||
{
|
||||
bool like_error;
|
||||
@ -1866,22 +1906,6 @@ get_mm_leaf(PARAM *param, Field *field, KEY_PART *key_part,
|
||||
DBUG_RETURN(new SEL_ARG(field,min_str,max_str));
|
||||
}
|
||||
|
||||
if (!value) // IS NULL or IS NOT NULL
|
||||
{
|
||||
if (field->table->outer_join) // Can't use a key on this
|
||||
DBUG_RETURN(0);
|
||||
if (!maybe_null) // Not null field
|
||||
DBUG_RETURN(type == Item_func::ISNULL_FUNC ? &null_element : 0);
|
||||
if (!(tree=new SEL_ARG(field,is_null_string,is_null_string)))
|
||||
DBUG_RETURN(0); // out of memory
|
||||
if (type == Item_func::ISNOTNULL_FUNC)
|
||||
{
|
||||
tree->min_flag=NEAR_MIN; /* IS NOT NULL -> X > NULL */
|
||||
tree->max_flag=NO_MAX_RANGE;
|
||||
}
|
||||
DBUG_RETURN(tree);
|
||||
}
|
||||
|
||||
if (!field->optimize_range(param->real_keynr[key_part->key]) &&
|
||||
type != Item_func::EQ_FUNC &&
|
||||
type != Item_func::EQUAL_FUNC)
|
||||
@ -1895,7 +1919,7 @@ get_mm_leaf(PARAM *param, Field *field, KEY_PART *key_part,
|
||||
value->result_type() != STRING_RESULT &&
|
||||
field->cmp_type() != value->result_type())
|
||||
DBUG_RETURN(0);
|
||||
|
||||
|
||||
if (value->save_in_field(field, 1) > 0)
|
||||
{
|
||||
/* This happens when we try to insert a NULL field in a not null column */
|
||||
@ -3097,6 +3121,7 @@ check_quick_select(PARAM *param,uint idx,SEL_ARG *tree)
|
||||
param->table->quick_rows[key]=records;
|
||||
param->table->quick_key_parts[key]=param->max_key_part+1;
|
||||
}
|
||||
DBUG_PRINT("exit", ("Records: %lu", (ulong) records));
|
||||
DBUG_RETURN(records);
|
||||
}
|
||||
|
||||
@ -3440,8 +3465,30 @@ QUICK_RANGE_SELECT *get_quick_select_for_ref(THD *thd, TABLE *table,
|
||||
key_part->part_length+=HA_KEY_BLOB_LENGTH;
|
||||
key_part->null_bit= key_info->key_part[part].null_bit;
|
||||
}
|
||||
if (!insert_dynamic(&quick->ranges,(gptr)&range))
|
||||
return quick;
|
||||
if (insert_dynamic(&quick->ranges,(gptr)&range))
|
||||
goto err;
|
||||
|
||||
/*
|
||||
Add a NULL range if REF_OR_NULL optimization is used.
|
||||
For example:
|
||||
if we have "WHERE A=2 OR A IS NULL" we created the (A=2) range above
|
||||
and have ref->null_ref_key set. Will create a new NULL range here.
|
||||
*/
|
||||
if (ref->null_ref_key)
|
||||
{
|
||||
QUICK_RANGE *null_range;
|
||||
|
||||
*ref->null_ref_key= 1; // Set null byte then create a range
|
||||
if (!(null_range= new QUICK_RANGE(ref->key_buff, ref->key_length,
|
||||
ref->key_buff, ref->key_length,
|
||||
EQ_RANGE)))
|
||||
goto err;
|
||||
*ref->null_ref_key= 0; // Clear null byte
|
||||
if (insert_dynamic(&quick->ranges,(gptr)&null_range))
|
||||
goto err;
|
||||
}
|
||||
|
||||
return quick;
|
||||
|
||||
err:
|
||||
delete quick;
|
||||
@ -3584,12 +3631,7 @@ int QUICK_RANGE_SELECT::get_next()
|
||||
int result;
|
||||
if (range)
|
||||
{ // Already read through key
|
||||
/* result=((range->flag & EQ_RANGE) ?
|
||||
file->index_next_same(record, (byte*) range->min_key,
|
||||
range->min_length) :
|
||||
file->index_next(record));
|
||||
*/
|
||||
result=((range->flag & (EQ_RANGE | GEOM_FLAG) ) ?
|
||||
result=((range->flag & (EQ_RANGE | GEOM_FLAG)) ?
|
||||
file->index_next_same(record, (byte*) range->min_key,
|
||||
range->min_length) :
|
||||
file->index_next(record));
|
||||
|
Reference in New Issue
Block a user