SQLite

Check-in [4d02df6349]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Avoid opening a temp table for aggregate queries with no GROUP BY clause. (CVS 1649)
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 4d02df63496091a1e643601f84313f42130d6282
User & Date: danielk1977 2004-06-21 10:45:07.000
Context
2004-06-21
11:30
Remove unused OP_UtfXX opcodes. (CVS 1650) (check-in: 84d6354fce user: danielk1977 tags: trunk)
10:45
Avoid opening a temp table for aggregate queries with no GROUP BY clause. (CVS 1649) (check-in: 4d02df6349 user: danielk1977 tags: trunk)
09:06
Add the OP_Concat8 opcode, similar in concept to OP_String8. (CVS 1648) (check-in: bbd3e93348 user: danielk1977 tags: trunk)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/build.c.
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
**     DROP INDEX
**     creating ID lists
**     BEGIN TRANSACTION
**     COMMIT
**     ROLLBACK
**     PRAGMA
**
** $Id: build.c,v 1.228 2004/06/21 09:06:42 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

/*
** This routine is called when a new SQL statement is beginning to
** be parsed.  Check to see if the schema for the database needs







|







19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
**     DROP INDEX
**     creating ID lists
**     BEGIN TRANSACTION
**     COMMIT
**     ROLLBACK
**     PRAGMA
**
** $Id: build.c,v 1.229 2004/06/21 10:45:07 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

/*
** This routine is called when a new SQL statement is beginning to
** be parsed.  Check to see if the schema for the database needs
955
956
957
958
959
960
961


962
963
964
965

966
967
968
969
970
971
972

973
974
975
976
977
978
979
980
981
982
983


984
985
986
987
988

989
990
991
992
993
994
995
      break;
    default: 
      assert(!"Cannot happen");
  }
  return pColl;
}



static void callCollNeeded(sqlite *db, const char *zName, int nName){
  /* No collation sequence of this type for this encoding is registered.
  ** Call the collation factory to see if it can supply us with one.
  */

  char const *zExternal = 0;
  assert( !db->xCollNeeded || !db->xCollNeeded16 );
  if( nName<0 ) nName = strlen(zName);
  if( db->xCollNeeded ){
    zExternal = sqliteStrNDup(zName, nName);
    if( !zExternal ) return;
      db->xCollNeeded(db->pCollNeededArg, db, (int)db->enc, zExternal);

  }
  if( db->xCollNeeded16 ){
    sqlite3_value *pTmp = sqlite3GetTransientValue(db);
    sqlite3ValueSetStr(pTmp, -1, zName, SQLITE_UTF8, SQLITE_STATIC);
    zExternal = sqlite3ValueText(pTmp, SQLITE_UTF16NATIVE);
    if( !zExternal ) return;
    db->xCollNeeded16(db->pCollNeededArg, db, (int)db->enc, zExternal);
  }
}

static int synthCollSeq(Parse *pParse, CollSeq *pColl){


  /* The collation factory failed to deliver a function but there may be
  ** other versions of this collation function (for other text encodings)
  ** available. Use one of these instead. Avoid a UTF-8 <-> UTF-16
  ** conversion if possible.
  */

  CollSeq *pColl2 = 0;
  char *z = pColl->zName;
  int n = strlen(z);
  switch( pParse->db->enc ){
    case SQLITE_UTF16LE:
      pColl2 = sqlite3FindCollSeq(pParse->db, SQLITE_UTF16BE, z, n, 0);
      assert( pColl2 );







>
>
|
|
<
|
>






|
>










<
>
>
|
|
|
|
|
>







955
956
957
958
959
960
961
962
963
964
965

966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985

986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
      break;
    default: 
      assert(!"Cannot happen");
  }
  return pColl;
}

/*
** Invoke the 'collation needed' callback to request a collation sequence
** in the database text encoding of name zName, length nName.
** If the collation sequence

*/
static void callCollNeeded(sqlite *db, const char *zName, int nName){
  char const *zExternal = 0;
  assert( !db->xCollNeeded || !db->xCollNeeded16 );
  if( nName<0 ) nName = strlen(zName);
  if( db->xCollNeeded ){
    zExternal = sqliteStrNDup(zName, nName);
    if( !zExternal ) return;
    db->xCollNeeded(db->pCollNeededArg, db, (int)db->enc, zExternal);
    sqliteFree(zExternal);
  }
  if( db->xCollNeeded16 ){
    sqlite3_value *pTmp = sqlite3GetTransientValue(db);
    sqlite3ValueSetStr(pTmp, -1, zName, SQLITE_UTF8, SQLITE_STATIC);
    zExternal = sqlite3ValueText(pTmp, SQLITE_UTF16NATIVE);
    if( !zExternal ) return;
    db->xCollNeeded16(db->pCollNeededArg, db, (int)db->enc, zExternal);
  }
}


/*
** This routine is called if the collation factory fails to deliver a
** collation function in the best encoding but there may be other versions
** of this collation function (for other text encodings) available. Use one
** of these instead if they exist. Avoid a UTF-8 <-> UTF-16 conversion if
** possible.
*/
static int synthCollSeq(Parse *pParse, CollSeq *pColl){
  CollSeq *pColl2 = 0;
  char *z = pColl->zName;
  int n = strlen(z);
  switch( pParse->db->enc ){
    case SQLITE_UTF16LE:
      pColl2 = sqlite3FindCollSeq(pParse->db, SQLITE_UTF16BE, z, n, 0);
      assert( pColl2 );
1036
1037
1038
1039
1040
1041
1042



1043
1044
1045
1046
1047
1048
1049
** If required, this routine calls the 'collation needed' callback to
** request a definition of the collating sequence. If this doesn't work, 
** an equivalent collating sequence that uses a text encoding different
** from the main database is substituted, if one is available.
*/
int sqlite3CheckCollSeq(Parse *pParse, CollSeq *pColl){
  if( pColl && !pColl->xCmp ){



    callCollNeeded(pParse->db, pColl->zName, strlen(pColl->zName));
    if( !pColl->xCmp && synthCollSeq(pParse, pColl) ){
      return SQLITE_ERROR;
    }
  }
  return SQLITE_OK;
}







>
>
>







1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
** If required, this routine calls the 'collation needed' callback to
** request a definition of the collating sequence. If this doesn't work, 
** an equivalent collating sequence that uses a text encoding different
** from the main database is substituted, if one is available.
*/
int sqlite3CheckCollSeq(Parse *pParse, CollSeq *pColl){
  if( pColl && !pColl->xCmp ){
    /* No collation sequence of this type for this encoding is registered.
    ** Call the collation factory to see if it can supply us with one.
    */
    callCollNeeded(pParse->db, pColl->zName, strlen(pColl->zName));
    if( !pColl->xCmp && synthCollSeq(pParse, pColl) ){
      return SQLITE_ERROR;
    }
  }
  return SQLITE_OK;
}
Changes to src/select.c.
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains C code routines that are called by the parser
** to handle SELECT statements in SQLite.
**
** $Id: select.c,v 1.194 2004/06/21 07:36:32 danielk1977 Exp $
*/
#include "sqliteInt.h"


/*
** Allocate a new Select structure and return a pointer to that
** structure.







|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains C code routines that are called by the parser
** to handle SELECT statements in SQLite.
**
** $Id: select.c,v 1.195 2004/06/21 10:45:09 danielk1977 Exp $
*/
#include "sqliteInt.h"


/*
** Allocate a new Select structure and return a pointer to that
** structure.
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
      }
    }
  }

  /* Reset the aggregator
  */
  if( isAgg ){
    int addr = sqlite3VdbeAddOp(v, OP_AggReset, 0, pParse->nAgg);
    for(i=0; i<pParse->nAgg; i++){
      FuncDef *pFunc;
      if( (pFunc = pParse->aAgg[i].pFunc)!=0 && pFunc->xFinalize!=0 ){
        sqlite3VdbeOp3(v, OP_AggInit, 0, i, (char*)pFunc, P3_FUNCDEF);
      }
    }
    if( pGroupBy==0 ){
      sqlite3VdbeAddOp(v, OP_String8, 0, 0);
      sqlite3VdbeAddOp(v, OP_AggFocus, 0, 0);
    }else{
      int sz = sizeof(KeyInfo) + pGroupBy->nExpr*sizeof(CollSeq*);
      KeyInfo *pKey = (KeyInfo *)sqliteMalloc(sz);
      if( 0==pKey ){
        goto select_end;
      }
      pKey->enc = pParse->db->enc;
      pKey->nField = pGroupBy->nExpr;







|






|
<
<
<







2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462



2463
2464
2465
2466
2467
2468
2469
      }
    }
  }

  /* Reset the aggregator
  */
  if( isAgg ){
    int addr = sqlite3VdbeAddOp(v, OP_AggReset, (pGroupBy?0:1), pParse->nAgg);
    for(i=0; i<pParse->nAgg; i++){
      FuncDef *pFunc;
      if( (pFunc = pParse->aAgg[i].pFunc)!=0 && pFunc->xFinalize!=0 ){
        sqlite3VdbeOp3(v, OP_AggInit, 0, i, (char*)pFunc, P3_FUNCDEF);
      }
    }
    if( pGroupBy ){



      int sz = sizeof(KeyInfo) + pGroupBy->nExpr*sizeof(CollSeq*);
      KeyInfo *pKey = (KeyInfo *)sqliteMalloc(sz);
      if( 0==pKey ){
        goto select_end;
      }
      pKey->enc = pParse->db->enc;
      pKey->nField = pGroupBy->nExpr;
Changes to src/vdbe.c.
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
**
** Various scripts scan this source file in order to generate HTML
** documentation, headers files, or other derived files.  The formatting
** of the code in this file is, therefore, important.  See other comments
** 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.383 2004/06/21 09:06:42 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>
#include "vdbeInt.h"

/*







|







39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
**
** Various scripts scan this source file in order to generate HTML
** documentation, headers files, or other derived files.  The formatting
** of the code in this file is, therefore, important.  See other comments
** 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.384 2004/06/21 10:45:09 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>
#include "vdbeInt.h"

/*
166
167
168
169
170
171
172
173
174
175
176
177

178
179
180
181
182
183
184
  pElem = sqliteMalloc( sizeof(AggElem) + nKey +
                        (p->nMem-1)*sizeof(pElem->aMem[0]) );
  if( pElem==0 ) return SQLITE_NOMEM;
  pElem->zKey = (char*)&pElem->aMem[p->nMem];
  memcpy(pElem->zKey, zKey, nKey);
  pElem->nKey = nKey;

  assert( p->pCsr );
  rc = sqlite3BtreeInsert(p->pCsr, zKey, nKey, &pElem, sizeof(AggElem*));
  if( rc!=SQLITE_OK ){
    sqliteFree(pElem);
    return rc;

  }

  for(i=0; i<p->nMem; i++){
    pElem->aMem[i].flags = MEM_Null;
  }
  p->pCurrent = pElem;
  return 0;







|
|
|
|
|
>







166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
  pElem = sqliteMalloc( sizeof(AggElem) + nKey +
                        (p->nMem-1)*sizeof(pElem->aMem[0]) );
  if( pElem==0 ) return SQLITE_NOMEM;
  pElem->zKey = (char*)&pElem->aMem[p->nMem];
  memcpy(pElem->zKey, zKey, nKey);
  pElem->nKey = nKey;

  if( p->pCsr ){
    rc = sqlite3BtreeInsert(p->pCsr, zKey, nKey, &pElem, sizeof(AggElem*));
    if( rc!=SQLITE_OK ){
      sqliteFree(pElem);
      return rc;
    }
  }

  for(i=0; i<p->nMem; i++){
    pElem->aMem[i].flags = MEM_Null;
  }
  p->pCurrent = pElem;
  return 0;
4255
4256
4257
4258
4259
4260
4261
4262
4263
4264
4265
4266




4267
4268
4269





4270


4271
4272
4273
4274
4275
4276
4277
4278
4279
4280
4281
  pMem->i++;
  if( pOp->p2>0 && pMem->i>0 ){
     pc = pOp->p2 - 1;
  }
  break;
}

/* Opcode: AggReset * P2 P3
**
** Reset the aggregator so that it no longer contains any data.
** Future aggregator elements will contain P2 values each and be sorted
** using the KeyInfo structure pointed to by P3.




*/
case OP_AggReset: {
  assert( !pOp->p3 || pOp->p3type==P3_KEYINFO );





  rc = sqlite3VdbeAggReset(db, &p->agg, (KeyInfo *)pOp->p3);


  if( rc!=SQLITE_OK ){
    goto abort_due_to_error;
  }
  p->agg.nMem = pOp->p2;
  p->agg.apFunc = sqliteMalloc( p->agg.nMem*sizeof(p->agg.apFunc[0]) );
  if( p->agg.apFunc==0 ) goto no_mem;
  break;
}

/* Opcode: AggInit * P2 P3
**







|




>
>
>
>



>
>
>
>
>
|
>
>



<







4256
4257
4258
4259
4260
4261
4262
4263
4264
4265
4266
4267
4268
4269
4270
4271
4272
4273
4274
4275
4276
4277
4278
4279
4280
4281
4282
4283
4284
4285

4286
4287
4288
4289
4290
4291
4292
  pMem->i++;
  if( pOp->p2>0 && pMem->i>0 ){
     pc = pOp->p2 - 1;
  }
  break;
}

/* Opcode: AggReset P1 P2 P3
**
** Reset the aggregator so that it no longer contains any data.
** Future aggregator elements will contain P2 values each and be sorted
** using the KeyInfo structure pointed to by P3.
**
** If P1 is non-zero, then only a single aggregator row is available (i.e.
** there is no GROUP BY expression). In this case it is illegal to invoke
** OP_AggFocus.
*/
case OP_AggReset: {
  assert( !pOp->p3 || pOp->p3type==P3_KEYINFO );
  if( pOp->p1 ){
    rc = sqlite3VdbeAggReset(0, &p->agg, (KeyInfo *)pOp->p3);
    p->agg.nMem = pOp->p2;    /* Agg.nMem is used by AggInsert() */
    AggInsert(&p->agg, 0, 0);
  }else{
    rc = sqlite3VdbeAggReset(db, &p->agg, (KeyInfo *)pOp->p3);
    p->agg.nMem = pOp->p2;
  }
  if( rc!=SQLITE_OK ){
    goto abort_due_to_error;
  }

  p->agg.apFunc = sqliteMalloc( p->agg.nMem*sizeof(p->agg.apFunc[0]) );
  if( p->agg.apFunc==0 ) goto no_mem;
  break;
}

/* Opcode: AggInit * P2 P3
**
4364
4365
4366
4367
4368
4369
4370


4371
4372
4373
4374
4375
4376
4377
  char *zKey;
  int nKey;
  int res;
  assert( pTos>=p->aStack );
  Stringify(pTos, db->enc);
  zKey = pTos->z;
  nKey = pTos->n;


  rc = sqlite3BtreeMoveto(p->agg.pCsr, zKey, nKey, &res);
  if( rc!=SQLITE_OK ){
    goto abort_due_to_error;
  }
  if( res==0 ){
    rc = sqlite3BtreeData(p->agg.pCsr, 0, sizeof(AggElem*),
        (char *)&p->agg.pCurrent);







>
>







4375
4376
4377
4378
4379
4380
4381
4382
4383
4384
4385
4386
4387
4388
4389
4390
  char *zKey;
  int nKey;
  int res;
  assert( pTos>=p->aStack );
  Stringify(pTos, db->enc);
  zKey = pTos->z;
  nKey = pTos->n;
  assert( p->agg.pBtree );
  assert( p->agg.pCsr );
  rc = sqlite3BtreeMoveto(p->agg.pCsr, zKey, nKey, &res);
  if( rc!=SQLITE_OK ){
    goto abort_due_to_error;
  }
  if( res==0 ){
    rc = sqlite3BtreeData(p->agg.pCsr, 0, sizeof(AggElem*),
        (char *)&p->agg.pCurrent);
4458
4459
4460
4461
4462
4463
4464

4465
4466
4467




4468
4469



4470
4471
4472
4473
4474
4475
4476
4477

4478
4479
4480
4481
4482
4483
4484
4485
4486
4487
4488
** in between an AggNext and an AggReset.
*/
case OP_AggNext: {
  int res;
  CHECK_FOR_INTERRUPT;
  if( p->agg.searching==0 ){
    p->agg.searching = 1;

    rc = sqlite3BtreeFirst(p->agg.pCsr, &res);
    if( rc!=SQLITE_OK ) goto abort_due_to_error;
  }else{




    rc = sqlite3BtreeNext(p->agg.pCsr, &res);
    if( rc!=SQLITE_OK ) goto abort_due_to_error;



  }
  if( res!=0 ){
    pc = pOp->p2 - 1;
  }else{
    int i;
    sqlite3_context ctx;
    Mem *aMem;


    rc = sqlite3BtreeData(p->agg.pCsr, 0, sizeof(AggElem*),
        (char *)&p->agg.pCurrent);
    if( rc!=SQLITE_OK ){
      goto abort_due_to_error;
    }
    aMem = p->agg.pCurrent->aMem;
    for(i=0; i<p->agg.nMem; i++){
      int freeCtx;
      if( p->agg.apFunc[i]==0 ) continue;
      if( p->agg.apFunc[i]->xFinalize==0 ) continue;
      ctx.s.flags = MEM_Null;







>
|
|
|
>
>
>
>
|
|
>
>
>








>
|
|
|
<







4471
4472
4473
4474
4475
4476
4477
4478
4479
4480
4481
4482
4483
4484
4485
4486
4487
4488
4489
4490
4491
4492
4493
4494
4495
4496
4497
4498
4499
4500
4501
4502

4503
4504
4505
4506
4507
4508
4509
** in between an AggNext and an AggReset.
*/
case OP_AggNext: {
  int res;
  CHECK_FOR_INTERRUPT;
  if( p->agg.searching==0 ){
    p->agg.searching = 1;
    if( p->agg.pCsr ){
      rc = sqlite3BtreeFirst(p->agg.pCsr, &res);
      if( rc!=SQLITE_OK ) goto abort_due_to_error;
    }else{
      res = 0;
    }
  }else{
    if( p->agg.pCsr ){
      rc = sqlite3BtreeNext(p->agg.pCsr, &res);
      if( rc!=SQLITE_OK ) goto abort_due_to_error;
    }else{
      res = 1;
    }
  }
  if( res!=0 ){
    pc = pOp->p2 - 1;
  }else{
    int i;
    sqlite3_context ctx;
    Mem *aMem;

    if( p->agg.pCsr ){
      rc = sqlite3BtreeData(p->agg.pCsr, 0, sizeof(AggElem*),
          (char *)&p->agg.pCurrent);
      if( rc!=SQLITE_OK ) goto abort_due_to_error;

    }
    aMem = p->agg.pCurrent->aMem;
    for(i=0; i<p->agg.nMem; i++){
      int freeCtx;
      if( p->agg.apFunc[i]==0 ) continue;
      if( p->agg.apFunc[i]->xFinalize==0 ) continue;
      ctx.s.flags = MEM_Null;
Changes to src/vdbeInt.h.
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
*/
typedef struct Agg Agg;
typedef struct AggElem AggElem;
struct Agg {
  int nMem;            /* Number of values stored in each AggElem */
  AggElem *pCurrent;   /* The AggElem currently in focus */
  FuncDef **apFunc;    /* Information about aggregate functions */
#if 0
  HashElem *pSearch;   /* The hash element for pCurrent */
  Hash hash;           /* Hash table of all aggregate elements */
#endif
  Btree *pBtree;       /* The temporary btree used to group elements */
  BtCursor *pCsr;      /* Read/write cursor to the table in pBtree */
  int nTab;            /* Root page of the table in pBtree */
  u8 searching;        /* True between the first AggNext and AggReset */
};
struct AggElem {
  char *zKey;          /* The key to this AggElem */
  int nKey;            /* Number of bytes in the key, including '\0' at end */







<
<
<
<
|







234
235
236
237
238
239
240




241
242
243
244
245
246
247
248
*/
typedef struct Agg Agg;
typedef struct AggElem AggElem;
struct Agg {
  int nMem;            /* Number of values stored in each AggElem */
  AggElem *pCurrent;   /* The AggElem currently in focus */
  FuncDef **apFunc;    /* Information about aggregate functions */




  Btree *pBtree;       /* The tmp. btree used to group elements, if required. */
  BtCursor *pCsr;      /* Read/write cursor to the table in pBtree */
  int nTab;            /* Root page of the table in pBtree */
  u8 searching;        /* True between the first AggNext and AggReset */
};
struct AggElem {
  char *zKey;          /* The key to this AggElem */
  int nKey;            /* Number of bytes in the key, including '\0' at end */
Changes to src/vdbeaux.c.
666
667
668
669
670
671
672





























673
674
675
676
677
678
679
    Sorter *pSorter = p->pSort;
    p->pSort = pSorter->pNext;
    sqliteFree(pSorter->zKey);
    sqlite3VdbeMemRelease(&pSorter->data);
    sqliteFree(pSorter);
  }
}






























/*
** Reset an Agg structure.  Delete all its contents.
**
** For installable aggregate functions, if the step function has been
** called, make sure the finalizer function has also been called.  The
** finalizer might need to free memory that was allocated as part of its







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
    Sorter *pSorter = p->pSort;
    p->pSort = pSorter->pNext;
    sqliteFree(pSorter->zKey);
    sqlite3VdbeMemRelease(&pSorter->data);
    sqliteFree(pSorter);
  }
}

/*
** Free all resources allociated with AggElem pElem, an element of
** aggregate pAgg.
*/
int freeAggElem(AggElem *pElem, Agg *pAgg){
  int i;
  for(i=0; i<pAgg->nMem; i++){
    Mem *pMem = &pElem->aMem[i];
    if( pAgg->apFunc[i] && (pMem->flags & MEM_AggCtx)!=0 ){
      sqlite3_context ctx;
      ctx.pFunc = pAgg->apFunc[i];
      ctx.s.flags = MEM_Null;
      ctx.pAgg = pMem->z;
      ctx.cnt = pMem->i;
      ctx.isStep = 0;
      ctx.isError = 0;
      (*pAgg->apFunc[i]->xFinalize)(&ctx);
      pMem->z = ctx.pAgg;
      if( pMem->z!=0 && pMem->z!=pMem->zShort ){
        sqliteFree(pMem->z);
      }
      sqlite3VdbeMemRelease(&ctx.s);
    }else{
      sqlite3VdbeMemRelease(pMem);
    }
  }
  sqliteFree(pElem);
}

/*
** Reset an Agg structure.  Delete all its contents.
**
** For installable aggregate functions, if the step function has been
** called, make sure the finalizer function has also been called.  The
** finalizer might need to free memory that was allocated as part of its
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746







747
748
749
750
751
752
753
    while( res==0 && rc==SQLITE_OK ){
      AggElem *pElem;
      rc = sqlite3BtreeData(pCsr, 0, sizeof(AggElem*), (char *)&pElem);
      if( res!=SQLITE_OK ){
        return rc;
      }
      assert( pAgg->apFunc!=0 );
      for(i=0; i<pAgg->nMem; i++){
        Mem *pMem = &pElem->aMem[i];
        if( pAgg->apFunc[i] && (pMem->flags & MEM_AggCtx)!=0 ){
          sqlite3_context ctx;
          ctx.pFunc = pAgg->apFunc[i];
          ctx.s.flags = MEM_Null;
          ctx.pAgg = pMem->z;
          ctx.cnt = pMem->i;
          ctx.isStep = 0;
          ctx.isError = 0;
          (*pAgg->apFunc[i]->xFinalize)(&ctx);
          pMem->z = ctx.pAgg;
          if( pMem->z!=0 && pMem->z!=pMem->zShort ){
            sqliteFree(pMem->z);
          }
          sqlite3VdbeMemRelease(&ctx.s);
        }else{
          sqlite3VdbeMemRelease(pMem);
        }
      }
      sqliteFree(pElem);
      rc=sqlite3BtreeNext(pCsr, &res);
    }
    if( rc!=SQLITE_OK ){
      return rc;
    }

    sqlite3BtreeCloseCursor(pCsr);
    sqlite3BtreeClearTable(pAgg->pBtree, pAgg->nTab);







  }

  /* If db is not NULL and we have not yet and we have not yet opened
  ** the temporary btree then do so and create the table to store aggregate
  ** information.
  **
  ** If db is NULL, then close the temporary btree if it is open.







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|








>
>
>
>
>
>
>







740
741
742
743
744
745
746




















747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
    while( res==0 && rc==SQLITE_OK ){
      AggElem *pElem;
      rc = sqlite3BtreeData(pCsr, 0, sizeof(AggElem*), (char *)&pElem);
      if( res!=SQLITE_OK ){
        return rc;
      }
      assert( pAgg->apFunc!=0 );




















      freeAggElem(pElem, pAgg);
      rc=sqlite3BtreeNext(pCsr, &res);
    }
    if( rc!=SQLITE_OK ){
      return rc;
    }

    sqlite3BtreeCloseCursor(pCsr);
    sqlite3BtreeClearTable(pAgg->pBtree, pAgg->nTab);
  }else{ 
    /* The cursor may not be open because the aggregator was never used,
    ** or it could be that it was used but there was no GROUP BY clause.
    */
    if( pAgg->pCurrent ){
      freeAggElem(pAgg->pCurrent, pAgg);
    }
  }

  /* If db is not NULL and we have not yet and we have not yet opened
  ** the temporary btree then do so and create the table to store aggregate
  ** information.
  **
  ** If db is NULL, then close the temporary btree if it is open.
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
    sqlite3ResetInternalSchema(db, 0);
  }
  return rc;
}

/*
** Call the destructor for each auxdata entry in pVdbeFunc for which
** the corresponding bit in mask is set.  Auxdata entries beyond 31
** are always destroyed.  To destroy all auxdata entries, call this
** routine with mask==-1.
*/
void sqlite3VdbeDeleteAuxData(VdbeFunc *pVdbeFunc, int mask){
  int i;
  for(i=0; i<pVdbeFunc->nAux; i++){
    struct AuxData *pAux = &pVdbeFunc->apAux[i];
    if( (i>31 || !(mask&(1<<i))) && pAux->pAux ){
      if( pAux->xDelete ){







|

|







1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
    sqlite3ResetInternalSchema(db, 0);
  }
  return rc;
}

/*
** Call the destructor for each auxdata entry in pVdbeFunc for which
** the corresponding bit in mask is clear.  Auxdata entries beyond 31
** are always destroyed.  To destroy all auxdata entries, call this
** routine with mask==0.
*/
void sqlite3VdbeDeleteAuxData(VdbeFunc *pVdbeFunc, int mask){
  int i;
  for(i=0; i<pVdbeFunc->nAux; i++){
    struct AuxData *pAux = &pVdbeFunc->apAux[i];
    if( (i>31 || !(mask&(1<<i))) && pAux->pAux ){
      if( pAux->xDelete ){
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
  for(i=0; i<p->nOp; i++){
    Op *pOp = &p->aOp[i];
    if( pOp->p3type==P3_DYNAMIC || pOp->p3type==P3_KEYINFO ){
      sqliteFree(pOp->p3);
    }
    if( pOp->p3type==P3_VDBEFUNC ){
      VdbeFunc *pVdbeFunc = (VdbeFunc *)pOp->p3;
      sqlite3VdbeDeleteAuxData(pVdbeFunc, -1);
      sqliteFree(pVdbeFunc);
    }
#ifndef NDEBUG
    sqliteFree(pOp->zComment);
#endif
  }
  for(i=0; i<p->nVar; i++){







|







1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
  for(i=0; i<p->nOp; i++){
    Op *pOp = &p->aOp[i];
    if( pOp->p3type==P3_DYNAMIC || pOp->p3type==P3_KEYINFO ){
      sqliteFree(pOp->p3);
    }
    if( pOp->p3type==P3_VDBEFUNC ){
      VdbeFunc *pVdbeFunc = (VdbeFunc *)pOp->p3;
      sqlite3VdbeDeleteAuxData(pVdbeFunc, 0);
      sqliteFree(pVdbeFunc);
    }
#ifndef NDEBUG
    sqliteFree(pOp->zComment);
#endif
  }
  for(i=0; i<p->nVar; i++){