Commit 1e9b0a4e authored by Varun Gupta's avatar Varun Gupta

Fixed size descriptors for unique

parent f4684f28
......@@ -3611,51 +3611,12 @@ int group_concat_key_cmp_with_distinct(void* arg, const void* key1,
*/
int group_concat_key_cmp_with_distinct_with_nulls(void* arg,
const void* key1_arg,
const void* key2_arg)
const void* key1,
const void* key2)
{
Item_func_group_concat *item_func= (Item_func_group_concat*)arg;
uchar *key1= (uchar*)key1_arg + item_func->table->s->null_bytes;
uchar *key2= (uchar*)key2_arg + item_func->table->s->null_bytes;
/*
JSON_ARRAYAGG function only accepts one argument.
*/
Item *item= item_func->args[0];
/*
If item is a const item then either get_tmp_table_field returns 0
or it is an item over a const table.
*/
if (item->const_item())
return 0;
/*
We have to use get_tmp_table_field() instead of
real_item()->get_tmp_table_field() because we want the field in
the temporary table, not the original field
*/
Field *field= item->get_tmp_table_field();
if (!field)
return 0;
if (field->is_null_in_record((uchar*)key1_arg) &&
field->is_null_in_record((uchar*)key2_arg))
return 0;
if (field->is_null_in_record((uchar*)key1_arg))
return -1;
if (field->is_null_in_record((uchar*)key2_arg))
return 1;
uint offset= (field->offset(field->table->record[0]) -
field->table->s->null_bytes);
int res= field->cmp(key1 + offset, key2 + offset);
if (res)
return res;
return 0;
return item_func->unique_filter->get_descriptor()
->compare_keys((uchar *)key1, (uchar *)key2);
}
......@@ -4873,6 +4834,38 @@ Item_sum::get_unique(qsort_cmp2 comp_func, void *comp_func_fixed_arg,
}
Unique_impl*
Item_func_group_concat::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 number_of_args)
{
Descriptor *desc;
if (allow_packing)
{
if (number_of_args == 1)
desc= new Variable_size_keys_simple(size_arg);
else
desc= new Variable_size_keys_descriptor(size_arg);
}
else
{
if (number_of_args == 1 && !skip_nulls())
desc= new Fixed_size_keys_descriptor_with_nulls(size_arg);
else
desc= new Fixed_size_keys_for_group_concat(size_arg);
}
if (!desc)
return NULL;
return new Unique_impl(comp_func, comp_func_fixed_arg, size_arg,
max_in_memory_size_arg, min_dupl_count_arg, desc);
}
void Item_func_group_concat::print(String *str, enum_query_type query_type)
{
str->append(func_name());
......
......@@ -592,10 +592,11 @@ class Item_sum :public Item_func_or_sum
bool with_sum_func() const { return true; }
virtual void set_partition_row_count(ulonglong count) { DBUG_ASSERT(0); }
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 number_of_args);
virtual 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 number_of_args);
};
......@@ -2033,6 +2034,11 @@ class Item_func_group_concat : public Item_sum
element_count __attribute__((unused)),
void *item_arg);
int insert_record_to_unique();
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 number_of_args);
};
#endif /* ITEM_SUM_INCLUDED */
......@@ -1166,3 +1166,56 @@ int Fixed_size_keys_for_rowids::compare_keys(uchar *key1, uchar *key2)
{
return file->cmp_ref(key1, key2);
}
int
Fixed_size_keys_descriptor_with_nulls::compare_keys(uchar *key1_arg,
uchar *key2_arg)
{
/*
We have to use get_tmp_table_field() instead of
real_item()->get_tmp_table_field() because we want the field in
the temporary table, not the original field
*/
for (SORT_FIELD *sort_field= sort_keys->begin();
sort_field != sort_keys->end(); sort_field++)
{
Field *field= sort_field->field;
if (field->is_null_in_record(key1_arg) &&
field->is_null_in_record(key2_arg))
return 0;
if (field->is_null_in_record(key1_arg))
return -1;
if (field->is_null_in_record(key2_arg))
return 1;
uchar *key1= (uchar*)key1_arg + field->table->s->null_bytes;
uchar *key2= (uchar*)key2_arg + field->table->s->null_bytes;
uint offset= (field->offset(field->table->record[0]) -
field->table->s->null_bytes);
int res= field->cmp(key1 + offset, key2 + offset);
if (res)
return res;
}
return 0;
}
int Fixed_size_keys_for_group_concat::compare_keys(uchar *key1, uchar *key2)
{
for (SORT_FIELD *sort_field= sort_keys->begin();
sort_field != sort_keys->end(); sort_field++)
{
Field *field= sort_field->field;
uint offset= (field->offset(field->table->record[0]) -
field->table->s->null_bytes);
int res= field->cmp(key1 + offset, key2 + offset);
if (res)
return res;
}
return 0;
}
\ No newline at end of file
......@@ -71,8 +71,9 @@ class Descriptor : public Sql_alloc
/*
Descriptor for fixed size keys for multiple key components
Descriptor for fixed size keys with single key part
*/
class Fixed_size_keys_descriptor : public Descriptor
{
public:
......@@ -86,6 +87,9 @@ class Fixed_size_keys_descriptor : public Descriptor
};
/*
Descriptor for fixed size mem-comparable keys with single key part
*/
class Fixed_size_keys_mem_comparable: public Fixed_size_keys_descriptor
{
public:
......@@ -96,7 +100,9 @@ class Fixed_size_keys_mem_comparable: public Fixed_size_keys_descriptor
};
/*
Descriptor for fixed size keys for rowid comparison
*/
class Fixed_size_keys_for_rowids: public Fixed_size_keys_descriptor
{
private:
......@@ -113,6 +119,33 @@ class Fixed_size_keys_for_rowids: public Fixed_size_keys_descriptor
};
/*
Descriptor for fixed size keys where a keypart can be NULL
Used currently in JSON_ARRAYAGG
*/
class Fixed_size_keys_descriptor_with_nulls : public Fixed_size_keys_descriptor
{
public:
Fixed_size_keys_descriptor_with_nulls(uint length)
: Fixed_size_keys_descriptor(length) {}
~Fixed_size_keys_descriptor_with_nulls() {}
int compare_keys(uchar *a, uchar *b) override;
};
/*
Descriptor for fixed size keys in group_concat
*/
class Fixed_size_keys_for_group_concat : public Fixed_size_keys_descriptor
{
public:
Fixed_size_keys_for_group_concat(uint length)
: Fixed_size_keys_descriptor(length) {}
~Fixed_size_keys_for_group_concat() {}
int compare_keys(uchar *a, uchar *b) override;
};
/*
Descriptor for fixed size keys with multiple key parts
......
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