Commit f4684f28 authored by Varun Gupta's avatar Varun Gupta

Introduced more classes for fixed size to handle rowid elimination

parent 67546a26
......@@ -667,41 +667,6 @@ int count_distinct_walk(void *elem, element_count count, void *arg)
C_MODE_END
/**
Correctly compare composite keys.
Used by the Unique class to compare keys. Will do correct comparisons
for composite keys with various field types.
@param arg Pointer to the relevant Aggregator_distinct instance
@param key1 left key image
@param key2 right key image
@return comparison result
@retval <0 if key1 < key2
@retval =0 if key1 = key2
@retval >0 if key1 > key2
*/
int Aggregator_distinct::composite_key_cmp(void* arg, uchar* key1, uchar* key2)
{
Aggregator_distinct *aggr= (Aggregator_distinct *) arg;
Field **field = aggr->table->field;
Field **field_end= field + aggr->table->s->fields;
uint32 *lengths=aggr->field_lengths;
for (; field < field_end; ++field)
{
Field* f = *field;
int len = *lengths++;
int res = f->cmp(key1, key2);
if (res)
return res;
key1 += len;
key2 += len;
}
return 0;
}
/**
@brief
Compare composite variable size keys.
......@@ -720,38 +685,7 @@ int Aggregator_distinct::composite_key_cmp(void* arg, uchar* key1, uchar* key2)
@retval >0 if key1 > key2
*/
int
Aggregator_distinct::composite_packed_key_cmp(void* arg,
uchar* key1,
uchar* key2)
{
Aggregator_distinct *aggr= (Aggregator_distinct *) arg;
DBUG_ASSERT(aggr->tree);
return aggr->tree->get_descriptor()->compare_keys(key1, key2);
}
/**
@brief
compare single component key.
@notes
Used by the Unique class to compare packed keys
which have a single argument
@param arg Pointer to the relevant Aggregator_distinct instance
@param key1 left key image
@param key2 right key image
@return comparison result
@retval <0 if key1 < key2
@retval =0 if key1 = key2
@retval >0 if key1 > key2
*/
int
Aggregator_distinct::packed_key_cmp_single_arg(void *arg,
uchar *key1,
uchar *key2)
int Aggregator_distinct::key_cmp(void* arg, uchar* key1, uchar* key2)
{
Aggregator_distinct *aggr= (Aggregator_distinct *) arg;
DBUG_ASSERT(aggr->tree);
......@@ -907,14 +841,14 @@ bool Aggregator_distinct::setup(THD *thd)
compare method that can take advantage of not having to worry
about other fields.
*/
compare_key= (qsort_cmp2) simple_str_key_cmp;
compare_key= (qsort_cmp2) key_cmp;
cmp_arg= (void*) table->field[0];
/* tree_key_length has been set already */
}
else
{
uint32 *length;
compare_key= (qsort_cmp2) composite_key_cmp;
compare_key= (qsort_cmp2) key_cmp;
cmp_arg= (void*) this;
field_lengths= (uint32*) thd->alloc(table->s->fields * sizeof(uint32));
for (tree_key_length= 0, length= field_lengths, field= table->field;
......@@ -930,14 +864,14 @@ bool Aggregator_distinct::setup(THD *thd)
if (allow_packing)
{
compare_key= get_compare_func_for_packed_keys();
compare_key= (qsort_cmp2) key_cmp;
cmp_arg= (void*)this;
}
DBUG_ASSERT(tree == 0);
tree= item_sum->get_unique(compare_key, cmp_arg, tree_key_length,
item_sum->ram_limitation(thd), 0,
allow_packing);
allow_packing, non_const_items);
/*
The only time tree_key_length could be 0 is if someone does
count(distinct) on a char(0) field - stupid thing to do,
......@@ -997,7 +931,7 @@ bool Aggregator_distinct::setup(THD *thd)
*/
tree= item_sum->get_unique(simple_raw_key_cmp, &tree_key_length, tree_key_length,
item_sum->ram_limitation(thd), 0,
false);
false, 1);
DBUG_RETURN(tree == 0);
}
}
......@@ -1073,21 +1007,6 @@ int Aggregator_distinct::insert_record_to_unique()
}
/*
@brief
Get compare function for packed keys
@retval
comparison function
*/
qsort_cmp2 Aggregator_distinct::get_compare_func_for_packed_keys()
{
return item_sum->get_arg_count() == 1 ?
(qsort_cmp2) packed_key_cmp_single_arg:
(qsort_cmp2) composite_packed_key_cmp;
}
/**
Process incoming row.
......@@ -4692,7 +4611,8 @@ bool Item_func_group_concat::setup(THD *thd)
unique_filter= get_unique(get_comparator_function_for_distinct(allow_packing),
(void*)this,
tree_key_length + get_null_bytes(),
ram_limitation(thd), 0, allow_packing);
ram_limitation(thd), 0, allow_packing,
non_const_items);
if (!unique_filter ||
(unique_filter->get_descriptor()->setup(thd, this,
......@@ -4926,14 +4846,25 @@ bool Item_sum::is_packing_allowed(TABLE *table, uint* total_length)
Unique_impl*
Item_sum::get_unique(qsort_cmp2 comp_func, void *comp_func_fixed_arg,
uint size_arg, size_t max_in_memory_size_arg,
uint min_dupl_count_arg, bool allow_packing)
uint min_dupl_count_arg, bool allow_packing,
uint number_of_args)
{
Descriptor *desc;
if (allow_packing)
desc= new Variable_size_keys_descriptor(size_arg);
{
if (number_of_args == 1)
desc= new Variable_size_keys_simple(size_arg);
else
desc= new Variable_size_keys_descriptor(size_arg);
}
else
desc= new Fixed_size_keys_descriptor(size_arg);
{
if (number_of_args == 1)
desc= new Fixed_size_keys_descriptor(size_arg);
else
desc= new Fixed_size_composite_keys_descriptor(size_arg);
}
if (!desc)
return NULL;
......
......@@ -594,7 +594,8 @@ class Item_sum :public Item_func_or_sum
bool is_packing_allowed(TABLE* table, uint* total_length);
Unique_impl *get_unique(qsort_cmp2 comp_func, void *comp_func_fixed_arg,
uint size_arg, size_t max_in_memory_size_arg,
uint min_dupl_count_arg, bool allow_packing);
uint min_dupl_count_arg, bool allow_packing,
uint number_of_args);
};
......@@ -700,9 +701,7 @@ class Aggregator_distinct : public Aggregator
bool unique_walk_function_for_count(void *element);
int insert_record_to_unique();
qsort_cmp2 get_compare_func_for_packed_keys();
static int composite_key_cmp(void* arg, uchar* key1, uchar* key2);
static int composite_packed_key_cmp(void* arg, uchar* key1, uchar* key2);
static int packed_key_cmp_single_arg(void *arg, uchar *key1, uchar *key2);
static int key_cmp(void* arg, uchar* key1, uchar* key2);
};
......
......@@ -11758,14 +11758,14 @@ int read_keys_and_merge_scans(THD *thd,
DBUG_EXECUTE_IF("only_one_Unique_may_be_created",
DBUG_SET("+d,index_merge_may_not_create_a_Unique"); );
Descriptor *desc= new Fixed_size_keys_descriptor(file->ref_length);
Descriptor *desc= new Fixed_size_keys_for_rowids(file);
if (!desc)
goto err;
unique= new Unique_impl(refpos_order_cmp, (void *)file,
file->ref_length,
(size_t)thd->variables.sortbuff_size,
intersection ? quick_selects.elements : 0, desc);
unique= new Unique_impl(refpos_cmp, (void *)desc,
file->ref_length,
(size_t)thd->variables.sortbuff_size,
intersection ? quick_selects.elements : 0, desc);
if (!unique)
goto err;
*unique_ptr= unique;
......
......@@ -702,11 +702,11 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
clause. Instead of deleting the rows, first mark them deleted.
*/
ha_rows tmplimit=limit;
Descriptor *desc= new Fixed_size_keys_descriptor(table->file->ref_length);
Descriptor *desc= new Fixed_size_keys_for_rowids(table->file);
if (!desc)
goto terminate_delete; // OOM
deltempfile= new (thd->mem_root) Unique_impl(refpos_order_cmp, table->file,
deltempfile= new (thd->mem_root) Unique_impl(refpos_cmp, desc,
table->file->ref_length,
MEM_STRIP_BUF_SIZE, 0, desc);
......@@ -1064,6 +1064,13 @@ extern "C" int refpos_order_cmp(void* arg, const void *a,const void *b)
return file->cmp_ref((const uchar*)a, (const uchar*)b);
}
extern "C" int refpos_cmp(void* arg, const void *a, const void *b)
{
Fixed_size_keys_for_rowids *desc= (Fixed_size_keys_for_rowids *) arg;
return desc->compare_keys((uchar*)a, (uchar *)b);
}
/*
make delete specific preparation and checks after opening tables
......@@ -1277,15 +1284,15 @@ multi_delete::initialize_tables(JOIN *join)
for (;walk ;walk= walk->next_local)
{
TABLE *table=walk->table;
desc= new Fixed_size_keys_descriptor(table->file->ref_length);
desc= new Fixed_size_keys_for_rowids(table->file);
if (!desc)
DBUG_RETURN(TRUE); // OOM
unique= new (thd->mem_root) Unique_impl(refpos_order_cmp,
table->file,
table->file->ref_length,
MEM_STRIP_BUF_SIZE,
0, desc);
unique= new (thd->mem_root) Unique_impl(refpos_cmp,
desc,
table->file->ref_length,
MEM_STRIP_BUF_SIZE,
0, desc);
if (!unique)
DBUG_RETURN(TRUE); // OOM
*tempfiles_ptr++= unique;
......
......@@ -1866,6 +1866,8 @@ int opt_sum_query(THD* thd,
/* from sql_delete.cc, used by opt_range.cc */
extern "C" int refpos_order_cmp(void* arg, const void *a,const void *b);
extern "C" int refpos_cmp(void* arg, const void *a, const void *b);
/** class to copying an field/item to a key struct */
class store_key :public Sql_alloc
......
......@@ -1734,7 +1734,7 @@ class Count_distinct_field: public Sql_alloc
}
tree_key_length= table_field->pack_length();
desc= new Fixed_size_keys_simple(tree_key_length);
desc= new Fixed_size_keys_descriptor(tree_key_length);
if (!desc)
return true; // OOM
tree= new Unique_impl((qsort_cmp2) key_cmp, (void*) this,
......@@ -1865,11 +1865,11 @@ class Count_distinct_field_bit: public Count_distinct_field
bool setup(THD *thd, size_t max_heap_table_size)
{
tree_key_length= sizeof(ulonglong);
Descriptor *desc= new Fixed_size_keys_descriptor(tree_key_length);
Descriptor *desc= new Fixed_size_keys_mem_comparable(tree_key_length);
if (!desc)
return true;
tree= new Unique_impl((qsort_cmp2) simple_ulonglong_key_cmp,
(void*) &tree_key_length,
(void*) this,
tree_key_length, max_heap_table_size, 1, desc);
return tree == NULL;
}
......@@ -1895,9 +1895,9 @@ int Count_distinct_field_bit::simple_ulonglong_key_cmp(void* arg,
uchar* key1,
uchar* key2)
{
ulonglong *val1= (ulonglong *) key1;
ulonglong *val2= (ulonglong *) key2;
return *val1 > *val2 ? 1 : *val1 == *val2 ? 0 : -1;
Count_distinct_field_bit *compare_arg= (Count_distinct_field_bit*)arg;
DBUG_ASSERT(compare_arg->tree->get_descriptor());
return compare_arg->tree->get_descriptor()->compare_keys(key1, key2);
}
......
......@@ -1064,8 +1064,21 @@ Variable_size_keys_simple::Variable_size_keys_simple(uint length)
{}
int Fixed_size_keys_simple::compare_keys(uchar *a, uchar *b)
/* FIXED SIZE KEYS DESCRIPTOR */
Fixed_size_keys_descriptor::Fixed_size_keys_descriptor(uint length)
{
max_length= length;
flags= (1 << FIXED_SIZED_KEYS);
sort_keys= NULL;
sortorder= NULL;
}
int Fixed_size_keys_descriptor::compare_keys(uchar *a, uchar *b)
{
DBUG_ASSERT(sort_keys);
SORT_FIELD *sort_field= sort_keys->begin();
DBUG_ASSERT(sort_field->field);
return sort_field->field->cmp(a, b);
......@@ -1076,6 +1089,30 @@ bool
Fixed_size_keys_descriptor::setup(THD *thd, Item_sum *item,
uint non_const_args, uint arg_count)
{
SORT_FIELD *sort,*pos;
if (sortorder)
return false;
DBUG_ASSERT(sort_keys == NULL);
sortorder= (SORT_FIELD*) thd->alloc(sizeof(SORT_FIELD) * non_const_args);
pos= sort= sortorder;
if (!pos)
return true;
sort_keys= new Sort_keys(sortorder, non_const_args);
if (!sort_keys)
return true;
sort=pos= sortorder;
for (uint i= 0; i < arg_count; i++)
{
Item *arg= item->get_arg(i);
if (arg->const_item())
continue;
Field *field= arg->get_tmp_table_field();
DBUG_ASSERT(field);
pos->setup_for_fixed_size_keys(field);
pos++;
}
return false;
}
......@@ -1102,21 +1139,30 @@ Fixed_size_keys_descriptor::setup(THD *thd, Field *field)
}
int Fixed_size_keys_descriptor::compare_keys(uchar *a, uchar *b)
int Fixed_size_keys_mem_comparable::compare_keys(uchar *key1, uchar *key2)
{
return 0;
return memcmp(key1, key2, max_length);
}
Fixed_size_keys_descriptor::Fixed_size_keys_descriptor(uint length)
int
Fixed_size_composite_keys_descriptor::compare_keys(uchar *key1, uchar *key2)
{
max_length= length;
flags= (1 << FIXED_SIZED_KEYS);
sort_keys= NULL;
sortorder= NULL;
for (SORT_FIELD *sort_field= sort_keys->begin();
sort_field != sort_keys->end(); sort_field++)
{
Field *field= sort_field->field;
int res = field->cmp(key1, key2);
if (res)
return res;
key1 += sort_field->length;
key2 += sort_field->length;
}
return 0;
}
Fixed_size_keys_simple::Fixed_size_keys_simple(uint length)
:Fixed_size_keys_descriptor(length)
{}
int Fixed_size_keys_for_rowids::compare_keys(uchar *key1, uchar *key2)
{
return file->cmp_ref(key1, key2);
}
......@@ -71,7 +71,7 @@ class Descriptor : public Sql_alloc
/*
Descriptor for fixed size keys
Descriptor for fixed size keys for multiple key components
*/
class Fixed_size_keys_descriptor : public Descriptor
{
......@@ -86,11 +86,44 @@ class Fixed_size_keys_descriptor : public Descriptor
};
class Fixed_size_keys_simple : public Fixed_size_keys_descriptor
class Fixed_size_keys_mem_comparable: public Fixed_size_keys_descriptor
{
public:
Fixed_size_keys_simple(uint length);
~Fixed_size_keys_simple() {}
Fixed_size_keys_mem_comparable(uint length)
:Fixed_size_keys_descriptor(length){}
~Fixed_size_keys_mem_comparable() {}
int compare_keys(uchar *a, uchar *b) override;
};
class Fixed_size_keys_for_rowids: public Fixed_size_keys_descriptor
{
private:
handler *file;
public:
Fixed_size_keys_for_rowids(handler *file_arg)
:Fixed_size_keys_descriptor(file_arg->ref_length)
{
file= file_arg;
}
~Fixed_size_keys_for_rowids() {}
int compare_keys(uchar *a, uchar *b) override;
};
/*
Descriptor for fixed size keys with multiple key parts
*/
class Fixed_size_composite_keys_descriptor : public Fixed_size_keys_descriptor
{
public:
Fixed_size_composite_keys_descriptor(uint length)
: Fixed_size_keys_descriptor(length) {}
~Fixed_size_composite_keys_descriptor() {}
int compare_keys(uchar *a, uchar *b) override;
};
......
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