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