From: drh Date: Wed, 7 Sep 2005 22:09:48 +0000 (+0000) Subject: Bug fixes in aggregate processing. Fewer tests fail. (CVS 2663) X-Git-Tag: version-3.6.10~3496 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=a10a34b88fad7dc5831d695fb7af2c3983f67dcc;p=thirdparty%2Fsqlite.git Bug fixes in aggregate processing. Fewer tests fail. (CVS 2663) FossilOrigin-Name: c3ac58592f5e6305640868cdf42c129f1a25255d --- diff --git a/manifest b/manifest index cf457f8a60..7c04d369fb 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -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 @@ -63,7 +63,7 @@ F src/pragma.c 69413fbdc0c6aaa493a776ea52c1b3e6cf35dfb2 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 @@ -80,13 +80,13 @@ F src/update.c a9d2c5f504212d62da1b094476f1389c0e02f83f 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 @@ -306,7 +306,7 @@ F www/tclsqlite.tcl 3df553505b6efcad08f91e9b975deb2e6c9bb955 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 diff --git a/manifest.uuid b/manifest.uuid index f90b49b398..1b2d1e5fe2 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -17039ec3ff4396862beedf4a8af89654b2140f58 \ No newline at end of file +c3ac58592f5e6305640868cdf42c129f1a25255d \ No newline at end of file diff --git a/src/select.c b/src/select.c index dc1a57890b..07e1339a49 100644 --- a/src/select.c +++ b/src/select.c @@ -12,7 +12,7 @@ ** 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" @@ -2431,7 +2431,9 @@ static void finalizeAggFunctions(Parse *pParse, AggInfo *pAggInfo){ int i; struct AggInfo_func *pF; for(i=0, pF=pAggInfo->aFunc; inFunc; 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); } } diff --git a/src/vdbe.c b/src/vdbe.c index c4ad4d511d..c9fb9f33bb 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -43,7 +43,7 @@ ** 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" @@ -4186,16 +4186,24 @@ case OP_AggStep: { /* no-push */ 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->p1nMem ); pMem = &p->aMem[pOp->p1]; - sqlite3VdbeMemFinalize(pMem); + assert( (pMem->flags & ~(MEM_Null|MEM_Agg))==0 ); + sqlite3VdbeMemFinalize(pMem, (FuncDef*)pOp->p3); break; } diff --git a/src/vdbeInt.h b/src/vdbeInt.h index 77951b2cd5..d2faef8380 100644 --- a/src/vdbeInt.h +++ b/src/vdbeInt.h @@ -363,7 +363,7 @@ double sqlite3VdbeRealValue(Mem*); 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); diff --git a/src/vdbeapi.c b/src/vdbeapi.c index 6c786f1dce..2d94ba0a98 100644 --- a/src/vdbeapi.c +++ b/src/vdbeapi.c @@ -259,14 +259,19 @@ void *sqlite3_user_data(sqlite3_context *p){ 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; diff --git a/src/vdbemem.c b/src/vdbemem.c index 70a46637e9..085e2aaaa0 100644 --- a/src/vdbemem.c +++ b/src/vdbemem.c @@ -192,23 +192,21 @@ int sqlite3VdbeMemStringify(Mem *pMem, int enc){ ** 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; } } } @@ -222,7 +220,7 @@ void sqlite3VdbeMemRelease(Mem *p){ 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{