]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Bug fixes in aggregate processing. Fewer tests fail. (CVS 2663)
authordrh <drh@noemail.net>
Wed, 7 Sep 2005 22:09:48 +0000 (22:09 +0000)
committerdrh <drh@noemail.net>
Wed, 7 Sep 2005 22:09:48 +0000 (22:09 +0000)
FossilOrigin-Name: c3ac58592f5e6305640868cdf42c129f1a25255d

manifest
manifest.uuid
src/select.c
src/vdbe.c
src/vdbeInt.h
src/vdbeapi.c
src/vdbemem.c

index cf457f8a608a6cdad11d6b8588194265090dbe18..7c04d369fb24680c62e7d509428f6501b32e87b8 100644 (file)
--- 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
index f90b49b3985b40c8480463925abf24a3103cd424..1b2d1e5fe2868ac0d61be4b9767fbe0833c5fcc4 100644 (file)
@@ -1 +1 @@
-17039ec3ff4396862beedf4a8af89654b2140f58
\ No newline at end of file
+c3ac58592f5e6305640868cdf42c129f1a25255d
\ No newline at end of file
index dc1a57890b24d1b28a9a19a7dcd0d6bc004d1438..07e1339a492da707db87554affc163a9684912c4 100644 (file)
@@ -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; 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);
   }
 }
 
index c4ad4d511d8f0f3c638f9c6f73a918b04de8a984..c9fb9f33bb044c3c11c5236a5f64d9040375ded6 100644 (file)
@@ -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->p1<p->nMem );
   pMem = &p->aMem[pOp->p1];
-  sqlite3VdbeMemFinalize(pMem);
+  assert( (pMem->flags & ~(MEM_Null|MEM_Agg))==0 );
+  sqlite3VdbeMemFinalize(pMem, (FuncDef*)pOp->p3);
   break;
 }
 
index 77951b2cd560c745ae9f970853f2ba50f2a82719..d2faef8380b151f02e52150e2f1b4679b05a9885 100644 (file)
@@ -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);
index 6c786f1dcee9a5142a9fedc1f88be4c2f8575e60..2d94ba0a989617cac6efe71d6307d66bcf63ef2c 100644 (file)
@@ -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;
index 70a46637e9f3ee1d1b29c085ff3aaa688f3dd19d..085e2aaaa0ba6ef75c78f6e79881a3e786895607 100644 (file)
@@ -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{