Commit 6ecaac01 authored by sasha@mysql.sashanet.com's avatar sasha@mysql.sashanet.com
Browse files

count(distinct) cleanup

parent 73e6a690
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -45,7 +45,7 @@ select count(distinct n2), n1 from t1 group by n1;
drop table t1;

# test the converstion from tree to MyISAM
create table t1 (n int);
create table t1 (n int default NULL);
let $1=5000;
while ($1)
{
+8 −2
Original line number Diff line number Diff line
@@ -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)))
  {
@@ -888,6 +889,7 @@ bool Item_sum_count_distinct::setup(THD *thd)
  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
    {
@@ -895,6 +897,10 @@ bool Item_sum_count_distinct::setup(THD *thd)
      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
	// to use a simpler key compare method that can take advantage
@@ -941,7 +947,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;
+4 −3
Original line number Diff line number Diff line
@@ -148,19 +148,20 @@ class Item_sum_count_distinct :public Item_sum_int
  bool fix_fields(THD *thd,TABLE_LIST *tables);
  TMP_TABLE_PARAM *tmp_table_param;
  TREE tree;
  uint max_elements_in_tree;
  
  // calculated based on max_heap_table_size. If reached,
  // walk the tree and dump it into MyISAM table
  uint max_elements_in_tree;
  
  bool use_tree;
  // If there are no blobs, we can use a tree, which
  // is faster than heap table. In that case, we still use the table
  // to help get things set up, but we insert nothing in it
  bool use_tree;
  
  int rec_offset;
  // the first few bytes of record ( at least one)
  // are just markers for deleted and NULLs. We want to skip them since
  // they will just bloat the tree without providing any valuable info
  int rec_offset;

  int tree_to_myisam();