-C Rewrite\sthe\saggregate\shandling\slogic\sso\sthat\sit\sruns\sin\sO(1)\sspace.\nThis\sis\sthe\sfirst\scut\sat\sthe\scode.\s\sMany\sregression\stests\sfail.\s(CVS\s2662)
-D 2005-09-07T21:22:46
+C Bug\sfixes\sin\saggregate\sprocessing.\s\sFewer\stests\sfail.\s(CVS\s2663)
+D 2005-09-07T22:09:48
F Makefile.in 12784cdce5ffc8dfb707300c34e4f1eb3b8a14f1
F Makefile.linux-gcc 06be33b2a9ad4f005a5f42b22c4a19dab3cbb5c7
F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028
F src/prepare.c 86f0d8e744b8d956eff6bc40e29049efee017610
F src/printf.c c01e9ad473d79463fb1f483b1eca5c3cbed2a4e5
F src/random.c 90adff4e73a3b249eb4f1fc2a6ff9cf78c7233a4
-F src/select.c 2f965220652f5417a70720ea3bf7703bf432fb6b
+F src/select.c 25df0f7aa195aebb9c34b04b4de4a9ef412d2341
F src/shell.c b21daba017b8feef2fdc65ecde57f70209494217
F src/sqlite.h.in d6561d51025d08de4f455607f3f9f9aa76e855d5
F src/sqliteInt.h 97d7d13bfcccd67974b0db9c19fce4428ae9d236
F src/utf.c bda5eb85039ef16f2d17004c1e18c96e1ab0a80c
F src/util.c 5650f6fe5ee30e0678985ad7b94da91e3f85752b
F src/vacuum.c 829d9e1a6d7c094b80e0899686670932eafd768c
-F src/vdbe.c e774761b4566540e0007ec3d6ff24ed7a89f51c9
+F src/vdbe.c 71b0c1e63d83af04c38c71015b40716375879d7e
F src/vdbe.h c8e105979fc7aaf5b8004e9621904e3bd096dfa2
-F src/vdbeInt.h 15a32128a8173c724a90829b90af495b370c09cc
-F src/vdbeapi.c 46e2fd47e2ce3c1aea9bb48bbbac31a1dc75a6ff
+F src/vdbeInt.h 3dd2a29c7b0a55404c35f93caae81fb42f4cb70a
+F src/vdbeapi.c 352f088f8e30385acfad7deee09edc4c73422129
F src/vdbeaux.c 11db0de973c850bb5d92c67af1c8f3c189f08741
F src/vdbefifo.c 9efb94c8c3f4c979ebd0028219483f88e57584f5
-F src/vdbemem.c 3cb63f021ac5ed102d80ec888d6f76fc0dcac153
+F src/vdbemem.c e1da6b772e8a05e95ede8eb6f2f6d0ef4f2e1034
F src/where.c 92ab208abe6bec15e81616b8c1a619be23ece506
F tclinstaller.tcl 046e3624671962dc50f0481d7c25b38ef803eb42
F test/all.test 7f0988442ab811dfa41793b5b550f5828ce316f3
F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
F www/version3.tcl a99cf5f6d8bd4d5537584a2b342f0fb9fa601d8b
F www/whentouse.tcl 97e2b5cd296f7d8057e11f44427dea8a4c2db513
-P b86bd70f301205d6ca66475a425e157b976107e2
-R 47d4cda0a17a577f38d2fea59c44e4f5
+P 17039ec3ff4396862beedf4a8af89654b2140f58
+R 6c06595443fe21ccea4edb3f23aa8075
U drh
-Z e6ce677b69437ad913acfe1b1ebf26c2
+Z 5adf4da7e52b069f7d7876deaf8155c7
-17039ec3ff4396862beedf4a8af89654b2140f58
\ No newline at end of file
+c3ac58592f5e6305640868cdf42c129f1a25255d
\ No newline at end of file
** This file contains C code routines that are called by the parser
** to handle SELECT statements in SQLite.
**
-** $Id: select.c,v 1.261 2005/09/07 21:22:47 drh Exp $
+** $Id: select.c,v 1.262 2005/09/07 22:09:48 drh Exp $
*/
#include "sqliteInt.h"
int i;
struct AggInfo_func *pF;
for(i=0, pF=pAggInfo->aFunc; i<pAggInfo->nFunc; i++, pF++){
- sqlite3VdbeAddOp(v, OP_AggFinal, pF->iMem, 0);
+ ExprList *pList = pF->pExpr->pList;
+ sqlite3VdbeOp3(v, OP_AggFinal, pF->iMem, pList ? pList->nExpr : 0,
+ (void*)pF->pFunc, P3_FUNCDEF);
}
}
** in this file for details. If in doubt, do not deviate from existing
** commenting and indentation practices when changing or adding code.
**
-** $Id: vdbe.c,v 1.482 2005/09/07 21:22:47 drh Exp $
+** $Id: vdbe.c,v 1.483 2005/09/07 22:09:48 drh Exp $
*/
#include "sqliteInt.h"
#include "os.h"
break;
}
-/* Opcode: AggFinal P1 * *
+/* Opcode: AggFinal P1 P2 P3
**
** Execute the finalizer function for an aggregate. P1 is
** the memory location that is the accumulator for the aggregate.
+**
+** P2 is the number of arguments that the step function takes and
+** P3 is a pointer to the FuncDef for this function. The P2
+** argument is not used by this opcode. It is only there to disambiguate
+** functions that can take varying numbers of arguments. The
+** P3 argument is only needed for the degenerate case where
+** the step function was not previously called.
*/
case OP_AggFinal: { /* no-push */
Mem *pMem;
assert( pOp->p1>=0 && pOp->p1<p->nMem );
pMem = &p->aMem[pOp->p1];
- sqlite3VdbeMemFinalize(pMem);
+ assert( (pMem->flags & ~(MEM_Null|MEM_Agg))==0 );
+ sqlite3VdbeMemFinalize(pMem, (FuncDef*)pOp->p3);
break;
}
int sqlite3VdbeMemRealify(Mem*);
int sqlite3VdbeMemFromBtree(BtCursor*,int,int,int,Mem*);
void sqlite3VdbeMemRelease(Mem *p);
-void sqlite3VdbeMemFinalize(Mem*);
+void sqlite3VdbeMemFinalize(Mem*, FuncDef*);
#ifndef NDEBUG
void sqlite3VdbeMemSanity(Mem*, u8);
int sqlite3VdbeOpcodeNoPush(u8);
void *sqlite3_aggregate_context(sqlite3_context *p, int nByte){
assert( p && p->pFunc && p->pFunc->xStep );
Mem *pMem = p->pMem;
- if( (pMem->flags & MEM_Agg)==0 && nByte>0 ){
- pMem->flags = MEM_Agg;
- *(FuncDef**)&pMem->i = p->pFunc;
- if( nByte<=NBFS ){
- pMem->z = pMem->zShort;
- memset(pMem->z, 0, nByte);
+ if( (pMem->flags & MEM_Agg)==0 ){
+ if( nByte==0 ){
+ assert( pMem->flags==MEM_Null );
+ pMem->z = 0;
}else{
- pMem->z = sqliteMalloc( nByte );
+ pMem->flags = MEM_Agg;
+ *(FuncDef**)&pMem->i = p->pFunc;
+ if( nByte<=NBFS ){
+ pMem->z = pMem->zShort;
+ memset(pMem->z, 0, nByte);
+ }else{
+ pMem->z = sqliteMalloc( nByte );
+ }
}
}
return (void*)pMem->z;
** This routine calls the finalize method for that function. The
** result of the aggregate is stored back into pMem.
*/
-void sqlite3VdbeMemFinalize(Mem *pMem){
- if( pMem->flags & MEM_Agg ){
- FuncDef *pFunc = *(FuncDef**)&pMem->i;
- if( pFunc && pFunc->xFinalize ){
- sqlite3_context ctx;
- ctx.s.flags = MEM_Null;
- ctx.s.z = pMem->zShort;
- ctx.pMem = pMem;
- ctx.pFunc = pFunc;
- pFunc->xFinalize(&ctx);
- if( pMem->z && pMem->z!=pMem->zShort ){
- sqliteFree( pMem->z );
- }
- *pMem = ctx.s;
- if( pMem->flags & MEM_Short ){
- pMem->z = pMem->zShort;
- }
+void sqlite3VdbeMemFinalize(Mem *pMem, FuncDef *pFunc){
+ if( pFunc && pFunc->xFinalize ){
+ sqlite3_context ctx;
+ assert( (pMem->flags & MEM_Null)!=0 || pFunc==*(FuncDef**)&pMem->i );
+ ctx.s.flags = MEM_Null;
+ ctx.s.z = pMem->zShort;
+ ctx.pMem = pMem;
+ ctx.pFunc = pFunc;
+ pFunc->xFinalize(&ctx);
+ if( pMem->z && pMem->z!=pMem->zShort ){
+ sqliteFree( pMem->z );
+ }
+ *pMem = ctx.s;
+ if( pMem->flags & MEM_Short ){
+ pMem->z = pMem->zShort;
}
}
}
if( p->flags & (MEM_Dyn|MEM_Agg) ){
if( p->xDel ){
if( p->flags & MEM_Agg ){
- sqlite3VdbeMemFinalize(p);
+ sqlite3VdbeMemFinalize(p, *(FuncDef**)&p->i);
assert( (p->flags & MEM_Agg)==0 );
sqlite3VdbeMemRelease(p);
}else{