Commit 8a28d5a3 authored by bar@bar.mysql.r18.ru's avatar bar@bar.mysql.r18.ru

COUNT(DISTINCT field) now honors charsets

parent e5103ce7
......@@ -542,7 +542,7 @@ void Item_sum_hybrid::reset_field()
if (hybrid_type == STRING_RESULT)
{
char buff[MAX_FIELD_WIDTH];
String tmp(buff,sizeof(buff),default_charset_info),*res;
String tmp(buff,sizeof(buff),result_field->charset()),*res;
res=args[0]->val_str(&tmp);
if (args[0]->null_value)
......@@ -897,17 +897,17 @@ String *Item_variance_field::val_str(String *str)
#include "sql_select.h"
static int simple_raw_key_cmp(void* arg, byte* key1, byte* key2)
int simple_raw_key_cmp(void* arg, byte* key1, byte* key2)
{
return memcmp(key1, key2, *(uint*) arg);
}
static int simple_str_key_cmp(void* arg, byte* key1, byte* key2)
int simple_str_key_cmp(void* arg, byte* key1, byte* key2)
{
/* BAR TODO: remove default_charset_info */
return my_strnncoll(default_charset_info,
(const uchar*) key1, *(uint*) arg,
(const uchar*) key2, *(uint*) arg);
Item_sum_count_distinct* item = (Item_sum_count_distinct*)arg;
CHARSET_INFO *cs=item->key_charset;
uint len=item->key_length;
return my_strnncoll(cs, (const uchar*) key1, len, (const uchar*) key2, len);
}
/*
......@@ -1037,14 +1037,22 @@ bool Item_sum_count_distinct::setup(THD *thd)
Field* field = table->field[0];
switch(field->type())
{
/*
If we have a string, we must take care of charsets and case
sensitivity
*/
case FIELD_TYPE_STRING:
case FIELD_TYPE_VAR_STRING:
compare_key = (qsort_cmp2)(field->binary() ? simple_raw_key_cmp:
simple_str_key_cmp);
if (field->binary())
{
compare_key = (qsort_cmp2)simple_raw_key_cmp;
cmp_arg = (void*) &key_length;
}
else
{
/*
If we have a string, we must take care of charsets and case
sensitivity
*/
compare_key = (qsort_cmp2)simple_str_key_cmp;
cmp_arg = (void*) this;
}
break;
default:
/*
......@@ -1052,11 +1060,12 @@ bool Item_sum_count_distinct::setup(THD *thd)
be compared with memcmp
*/
compare_key = (qsort_cmp2)simple_raw_key_cmp;
cmp_arg = (void*) &key_length;
break;
}
key_length = field->pack_length();
cmp_arg = (void*) &key_length;
rec_offset = 1;
key_charset = field->charset();
key_length = field->pack_length();
rec_offset = 1;
}
else // too bad, cannot cheat - there is more than one field
{
......
......@@ -156,7 +156,8 @@ class Item_sum_count_distinct :public Item_sum_int
TMP_TABLE_PARAM *tmp_table_param;
TREE tree;
uint key_length;
CHARSET_INFO *key_charset;
// calculated based on max_heap_table_size. If reached,
// walk the tree and dump it into MyISAM table
uint max_elements_in_tree;
......@@ -175,6 +176,8 @@ class Item_sum_count_distinct :public Item_sum_int
int tree_to_myisam();
friend int composite_key_cmp(void* arg, byte* key1, byte* key2);
friend int simple_str_key_cmp(void* arg, byte* key1, byte* key2);
friend int simple_raw_key_cmp(void* arg, byte* key1, byte* key2);
friend int dump_leaf(byte* key, uint32 count __attribute__((unused)),
Item_sum_count_distinct* item);
......
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