mirror of
https://github.com/MariaDB/server.git
synced 2026-05-06 15:15:34 +02:00
Implementation of SUM(DISTINCT), tests cases
sql/filesort.cc: Snippet of filesort() code moved to function reuse_freed_buff() - change buffpek pointers to use buff from freed BUFFPEK Used in filesort() and merge_walk(). sql/item_sum.cc: Implementation of Item_sum_sum_distinct - SUM(DISTINCT) item, which uses Unique to resolve duplicates sql/item_sum.h: New sum Item added - Item_sum_sum_distinct - for SUM(DISTINCT) function sql/sql_class.h: added walk() and reset() methods to Unique, used in Item_sum_sum_distinct. sql/sql_sort.h: declaration for reuse_freed_buff() to be able to use it in uniques.cc sql/sql_yacc.yy: parser extended to handle MIN(DISTICNT), MAX(DISTINCT), SUM(DISTINCT) sql/uniques.cc: Implementation for Unique::reset(), Unique::walk() as well as for merge_walk() algorithm.
This commit is contained in:
parent
844d9b766a
commit
58a52a2a84
9 changed files with 834 additions and 35 deletions
|
|
@ -756,6 +756,39 @@ uint read_to_buffer(IO_CACHE *fromfile, BUFFPEK *buffpek,
|
|||
} /* read_to_buffer */
|
||||
|
||||
|
||||
/*
|
||||
Put all room used by freed buffer to use in adjacent buffer. Note, that
|
||||
we can't simply distribute memory evenly between all buffers, because
|
||||
new areas must not overlap with old ones.
|
||||
SYNOPSYS
|
||||
reuse_freed_buff()
|
||||
queue IN list of non-empty buffers, without freed buffer
|
||||
reuse IN empty buffer
|
||||
key_length IN key length
|
||||
*/
|
||||
|
||||
void reuse_freed_buff(QUEUE *queue, BUFFPEK *reuse, uint key_length)
|
||||
{
|
||||
uchar *reuse_end= reuse->base + reuse->max_keys * key_length;
|
||||
for (uint i= 0; i < queue->elements; ++i)
|
||||
{
|
||||
BUFFPEK *bp= (BUFFPEK *) queue_element(queue, i);
|
||||
if (bp->base + bp->max_keys * key_length == reuse->base)
|
||||
{
|
||||
bp->max_keys+= reuse->max_keys;
|
||||
return;
|
||||
}
|
||||
else if (bp->base == reuse_end)
|
||||
{
|
||||
bp->base= reuse->base;
|
||||
bp->max_keys+= reuse->max_keys;
|
||||
return;
|
||||
}
|
||||
}
|
||||
DBUG_ASSERT(0);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Merge buffers to one buffer
|
||||
*/
|
||||
|
|
@ -881,29 +914,8 @@ int merge_buffers(SORTPARAM *param, IO_CACHE *from_file,
|
|||
if (!(error= (int) read_to_buffer(from_file,buffpek,
|
||||
rec_length)))
|
||||
{
|
||||
uchar *base= buffpek->base;
|
||||
ulong max_keys= buffpek->max_keys;
|
||||
|
||||
VOID(queue_remove(&queue,0));
|
||||
|
||||
/* Put room used by buffer to use in other buffer */
|
||||
for (refpek= (BUFFPEK**) &queue_top(&queue);
|
||||
refpek <= (BUFFPEK**) &queue_end(&queue);
|
||||
refpek++)
|
||||
{
|
||||
buffpek= *refpek;
|
||||
if (buffpek->base+buffpek->max_keys*rec_length == base)
|
||||
{
|
||||
buffpek->max_keys+= max_keys;
|
||||
break;
|
||||
}
|
||||
else if (base+max_keys*rec_length == buffpek->base)
|
||||
{
|
||||
buffpek->base= base;
|
||||
buffpek->max_keys+= max_keys;
|
||||
break;
|
||||
}
|
||||
}
|
||||
reuse_freed_buff(&queue, buffpek, rec_length);
|
||||
break; /* One buffer have been removed */
|
||||
}
|
||||
else if (error == -1)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue