summaryrefslogtreecommitdiff
path: root/sql/item_sum.cc
diff options
context:
space:
mode:
authorunknown <serg@serg.mysql.com>2001-07-02 21:52:22 +0200
committerunknown <serg@serg.mysql.com>2001-07-02 21:52:22 +0200
commita1826b55198ebd1ea5a3bafb88a52d1cf0c2f427 (patch)
treeb02cd20fcbc632447cd4b10782204969c9e6af34 /sql/item_sum.cc
parent2d28c646cbd53c1fcdf800dc408580aa5377f3b9 (diff)
parentcdfc04fb0819109ba3f7b78e87191b9b8311b9bf (diff)
downloadmariadb-git-a1826b55198ebd1ea5a3bafb88a52d1cf0c2f427.tar.gz
merged
include/my_base.h: Auto merged include/myisam.h: Auto merged myisam/mi_open.c: Auto merged myisam/myisamdef.h: Auto merged myisam/myisampack.c: Auto merged mysql-test/t/alter_table.test: Auto merged mysys/tree.c: Auto merged sql/ha_myisam.cc: Auto merged sql/item_sum.cc: Auto merged sql/mysqld.cc: Auto merged sql/sql_table.cc: Auto merged
Diffstat (limited to 'sql/item_sum.cc')
-rw-r--r--sql/item_sum.cc64
1 files changed, 47 insertions, 17 deletions
diff --git a/sql/item_sum.cc b/sql/item_sum.cc
index 40fe52a12e5..8d025891877 100644
--- a/sql/item_sum.cc
+++ b/sql/item_sum.cc
@@ -811,7 +811,7 @@ int composite_key_cmp(void* arg, byte* key1, byte* key2)
{
int res;
Field* f = *field;
- int len = f->field_length;
+ int len = f->pack_length();
switch((*field)->type())
{
case FIELD_TYPE_STRING:
@@ -839,7 +839,8 @@ int dump_leaf(byte* key, uint32 count __attribute__((unused)),
{
char* buf = item->table->record[0];
int error;
- memset(buf, 0xff, item->rec_offset); // make up for cheating in the tree
+ // the first item->rec_offset bytes are taken care of with
+ // restore_record(table,2) in setup()
memcpy(buf + item->rec_offset, key, item->tree.size_of_element);
if ((error = item->table->file->write_row(buf)))
{
@@ -874,8 +875,19 @@ bool Item_sum_count_distinct::setup(THD *thd)
List<Item> list;
/* Create a table with an unique key over all parameters */
for (uint i=0; i < arg_count ; i++)
- if (list.push_back(args[i]))
- return 1;
+ {
+ Item *item=args[i];
+ if (list.push_back(item))
+ return 1; // End of memory
+ if (item->const_item())
+ {
+ (void) item->val_int();
+ if (item->null_value)
+ always_null=1;
+ }
+ }
+ if (always_null)
+ return 0;
count_field_types(tmp_table_param,list,0);
if (table)
{
@@ -883,17 +895,22 @@ bool Item_sum_count_distinct::setup(THD *thd)
tmp_table_param->cleanup();
}
if (!(table=create_tmp_table(thd, tmp_table_param, list, (ORDER*) 0, 1,
- 0, 0, current_lex->options | thd->options)))
+ 0, 0, current_lex->select->options | thd->options)))
return 1;
table->file->extra(HA_EXTRA_NO_ROWS); // Don't update rows
table->no_rows=1;
+
if(table->db_type == DB_TYPE_HEAP) // no blobs, otherwise it would be
// MyISAM
{
qsort_cmp2 compare_key;
void* cmp_arg;
int key_len;
+
+ // to make things easier for dump_leaf if we ever have to dump to
+ // MyISAM
+ restore_record(table,2);
if(table->fields == 1) // if we have only one field, which is
// the most common use of count(distinct), it is much faster
@@ -915,20 +932,31 @@ bool Item_sum_count_distinct::setup(THD *thd)
compare_key = (qsort_cmp2)simple_raw_key_cmp;
break;
}
- cmp_arg = (void*)(key_len = field->field_length);
+ cmp_arg = (void*)(key_len = field->pack_length());
rec_offset = 1;
}
else // too bad, cannot cheat - there is more than one field
{
- cmp_arg = (void*)this;
- compare_key = (qsort_cmp2)composite_key_cmp;
+ bool all_binary = 1;
Field** field, **field_end;
field_end = (field = table->field) + table->fields;
for(key_len = 0; field < field_end; ++field)
{
- key_len += (*field)->field_length;
+ key_len += (*field)->pack_length();
+ if(!(*field)->binary())
+ all_binary = 0;
}
rec_offset = table->reclength - key_len;
+ if(all_binary)
+ {
+ compare_key = (qsort_cmp2)simple_raw_key_cmp;
+ cmp_arg = (void*)key_len;
+ }
+ else
+ {
+ compare_key = (qsort_cmp2)composite_key_cmp ;
+ cmp_arg = (void*)this;
+ }
}
init_tree(&tree, min(max_heap_table_size, sortbuff_size/16), 0,
@@ -940,7 +968,7 @@ bool Item_sum_count_distinct::setup(THD *thd)
// but this has to be handled - otherwise someone can crash
// the server with a DoS attack
max_elements_in_tree = (key_len) ? max_heap_table_size/key_len :
- max_heap_table_size;
+ 1;
}
return 0;
@@ -960,20 +988,22 @@ int Item_sum_count_distinct::tree_to_myisam()
void Item_sum_count_distinct::reset()
{
- if(use_tree)
+ if (use_tree)
reset_tree(&tree);
- else
- {
- table->file->extra(HA_EXTRA_NO_CACHE);
- table->file->delete_all_rows();
- table->file->extra(HA_EXTRA_WRITE_CACHE);
- }
+ else if (table)
+ {
+ table->file->extra(HA_EXTRA_NO_CACHE);
+ table->file->delete_all_rows();
+ table->file->extra(HA_EXTRA_WRITE_CACHE);
+ }
(void) add();
}
bool Item_sum_count_distinct::add()
{
int error;
+ if (always_null)
+ return 0;
copy_fields(tmp_table_param);
copy_funcs(tmp_table_param->funcs);