SQLite

Check-in [7ecf3654aa]
Login

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

Overview
Comment:Cleanup the processing of MEM_Agg elements. (CVS 2660)
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 7ecf3654aa9a275a4cf0c3ec5f63a8c1e0a11fc9
User & Date: drh 2005-09-06 20:36:49.000
Context
2005-09-06
21:40
Changes to reduce the amount of stack space required. (CVS 2661) (check-in: b86bd70f30 user: drh tags: trunk)
20:36
Cleanup the processing of MEM_Agg elements. (CVS 2660) (check-in: 7ecf3654aa user: drh tags: trunk)
10:26
Fix ANALYZE so that it works even if the empty_result_callbacks pragma is enabled. Ticket #1409. (CVS 2659) (check-in: bfdaef1224 user: drh tags: trunk)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/func.c.
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
** This file contains the C functions that implement various SQL
** functions of SQLite.  
**
** There is only one exported symbol in this file - the function
** sqliteRegisterBuildinFunctions() found at the bottom of the file.
** All other code has file scope.
**
** $Id: func.c,v 1.106 2005/08/28 17:00:23 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
#include <math.h>
#include <stdlib.h>
#include <assert.h>
#include "vdbeInt.h"







|







12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
** This file contains the C functions that implement various SQL
** functions of SQLite.  
**
** There is only one exported symbol in this file - the function
** sqliteRegisterBuildinFunctions() found at the bottom of the file.
** All other code has file scope.
**
** $Id: func.c,v 1.107 2005/09/06 20:36:49 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
#include <math.h>
#include <stdlib.h>
#include <assert.h>
#include "vdbeInt.h"
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
  if( p && SQLITE_NULL!=sqlite3_value_type(argv[0]) ){
    p->sum += sqlite3_value_double(argv[0]);
    p->cnt++;
  }
}
static void sumFinalize(sqlite3_context *context){
  SumCtx *p;
  p = sqlite3_aggregate_context(context, sizeof(*p));
  sqlite3_result_double(context, p ? p->sum : 0.0);
}
static void avgFinalize(sqlite3_context *context){
  SumCtx *p;
  p = sqlite3_aggregate_context(context, sizeof(*p));
  if( p && p->cnt>0 ){
    sqlite3_result_double(context, p->sum/(double)p->cnt);
  }
}

/*
** An instance of the following structure holds the context of a







|




|







831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
  if( p && SQLITE_NULL!=sqlite3_value_type(argv[0]) ){
    p->sum += sqlite3_value_double(argv[0]);
    p->cnt++;
  }
}
static void sumFinalize(sqlite3_context *context){
  SumCtx *p;
  p = sqlite3_aggregate_context(context, 0);
  sqlite3_result_double(context, p ? p->sum : 0.0);
}
static void avgFinalize(sqlite3_context *context){
  SumCtx *p;
  p = sqlite3_aggregate_context(context, 0);
  if( p && p->cnt>0 ){
    sqlite3_result_double(context, p->sum/(double)p->cnt);
  }
}

/*
** An instance of the following structure holds the context of a
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
  p = sqlite3_aggregate_context(context, sizeof(*p));
  if( (argc==0 || SQLITE_NULL!=sqlite3_value_type(argv[0])) && p ){
    p->n++;
  }
}   
static void countFinalize(sqlite3_context *context){
  CountCtx *p;
  p = sqlite3_aggregate_context(context, sizeof(*p));
  sqlite3_result_int(context, p ? p->n : 0);
}

/*
** Routines to implement min() and max() aggregate functions.
*/
static void minmaxStep(sqlite3_context *context, int argc, sqlite3_value **argv){







|







874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
  p = sqlite3_aggregate_context(context, sizeof(*p));
  if( (argc==0 || SQLITE_NULL!=sqlite3_value_type(argv[0])) && p ){
    p->n++;
  }
}   
static void countFinalize(sqlite3_context *context){
  CountCtx *p;
  p = sqlite3_aggregate_context(context, 0);
  sqlite3_result_int(context, p ? p->n : 0);
}

/*
** Routines to implement min() and max() aggregate functions.
*/
static void minmaxStep(sqlite3_context *context, int argc, sqlite3_value **argv){
912
913
914
915
916
917
918
919

920
921
922
923

924
925
926
927
928
929
930
    }
  }else{
    sqlite3VdbeMemCopy(pBest, pArg);
  }
}
static void minMaxFinalize(sqlite3_context *context){
  sqlite3_value *pRes;
  pRes = (sqlite3_value *)sqlite3_aggregate_context(context, sizeof(Mem));

  if( pRes->flags ){
    sqlite3_result_value(context, pRes);
  }
  sqlite3VdbeMemRelease(pRes);

}


/*
** This function registered all of the above C functions as SQL
** functions.  This should be the only routine in this file with
** external linkage.







|
>
|
|
|
|
>







912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
    }
  }else{
    sqlite3VdbeMemCopy(pBest, pArg);
  }
}
static void minMaxFinalize(sqlite3_context *context){
  sqlite3_value *pRes;
  pRes = (sqlite3_value *)sqlite3_aggregate_context(context, 0);
  if( pRes ){
    if( pRes->flags ){
      sqlite3_result_value(context, pRes);
    }
    sqlite3VdbeMemRelease(pRes);
  }
}


/*
** This function registered all of the above C functions as SQL
** functions.  This should be the only routine in this file with
** external linkage.
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.480 2005/09/01 12:16:29 drh 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.481 2005/09/06 20:36:49 drh Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>
#include "vdbeInt.h"

/*
4274
4275
4276
4277
4278
4279
4280
4281
4282
4283
4284
4285
4286
4287
4288
4289
4290
4291
4292
4293
4294
4295
4296
4297
4298
4299
4300
4301
4302
  for(i=0; i<n; i++, pRec++){
    apVal[i] = pRec;
    storeTypeInfo(pRec, db->enc);
  }
  i = pTos->i;
  assert( i>=0 && i<p->pAgg->nMem );
  ctx.pFunc = (FuncDef*)pOp->p3;
  pMem = &p->pAgg->pCurrent->aMem[i];
  ctx.s.z = pMem->zShort;  /* Space used for small aggregate contexts */
  ctx.pAgg = pMem->z;
  ctx.cnt = ++pMem->i;
  ctx.isError = 0;
  ctx.pColl = 0;
  if( ctx.pFunc->needCollSeq ){
    assert( pOp>p->aOp );
    assert( pOp[-1].p3type==P3_COLLSEQ );
    assert( pOp[-1].opcode==OP_CollSeq );
    ctx.pColl = (CollSeq *)pOp[-1].p3;
  }
  (ctx.pFunc->xStep)(&ctx, n, apVal);
  pMem->z = ctx.pAgg;
  pMem->flags = MEM_AggCtx;
  popStack(&pTos, n+1);
  if( ctx.isError ){
    rc = SQLITE_ERROR;
  }
  break;
}








|
<
|
<









<
<







4274
4275
4276
4277
4278
4279
4280
4281

4282

4283
4284
4285
4286
4287
4288
4289
4290
4291


4292
4293
4294
4295
4296
4297
4298
  for(i=0; i<n; i++, pRec++){
    apVal[i] = pRec;
    storeTypeInfo(pRec, db->enc);
  }
  i = pTos->i;
  assert( i>=0 && i<p->pAgg->nMem );
  ctx.pFunc = (FuncDef*)pOp->p3;
  ctx.pMem = pMem = &p->pAgg->pCurrent->aMem[i];

  pMem->n++;

  ctx.isError = 0;
  ctx.pColl = 0;
  if( ctx.pFunc->needCollSeq ){
    assert( pOp>p->aOp );
    assert( pOp[-1].p3type==P3_COLLSEQ );
    assert( pOp[-1].opcode==OP_CollSeq );
    ctx.pColl = (CollSeq *)pOp[-1].p3;
  }
  (ctx.pFunc->xStep)(&ctx, n, apVal);


  popStack(&pTos, n+1);
  if( ctx.isError ){
    rc = SQLITE_ERROR;
  }
  break;
}

4432
4433
4434
4435
4436
4437
4438
4439
4440
4441
4442
4443
4444
4445
4446
4447
4448
4449
4450
4451
4452
4453
4454
4455
4456
4457
4458
4459
4460
4461
4462
4463
4464
4465
4466
4467
4468
4469
4470
4471
4472
    }
  }
  if( rc!=SQLITE_OK ) goto abort_due_to_error;
  if( res!=0 ){
    pc = pOp->p2 - 1;
  }else{
    int i;
    sqlite3_context ctx;
    Mem *aMem;

    if( p->pAgg->pCsr ){
      rc = sqlite3BtreeData(p->pAgg->pCsr, 0, sizeof(AggElem*),
          (char *)&p->pAgg->pCurrent);
      if( rc!=SQLITE_OK ) goto abort_due_to_error;
    }
    aMem = p->pAgg->pCurrent->aMem;
    for(i=0; i<p->pAgg->nMem; i++){
      FuncDef *pFunc = p->pAgg->apFunc[i];
      Mem *pMem = &aMem[i];
      if( pFunc==0 || pFunc->xFinalize==0 ) continue;
      ctx.s.flags = MEM_Null;
      ctx.s.z = pMem->zShort;
      ctx.pAgg = (void*)pMem->z;
      ctx.cnt = pMem->i;
      ctx.pFunc = pFunc;
      pFunc->xFinalize(&ctx);
      pMem->z = ctx.pAgg;
      if( pMem->z && pMem->z!=pMem->zShort ){
        sqliteFree( pMem->z );
      }
      *pMem = ctx.s;
      if( pMem->flags & MEM_Short ){
        pMem->z = pMem->zShort;
      }
    }
  }
  break;
}

/* Opcode: Vacuum * * *
**







<











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







4428
4429
4430
4431
4432
4433
4434

4435
4436
4437
4438
4439
4440
4441
4442
4443
4444
4445






4446








4447
4448
4449
4450
4451
4452
4453
    }
  }
  if( rc!=SQLITE_OK ) goto abort_due_to_error;
  if( res!=0 ){
    pc = pOp->p2 - 1;
  }else{
    int i;

    Mem *aMem;

    if( p->pAgg->pCsr ){
      rc = sqlite3BtreeData(p->pAgg->pCsr, 0, sizeof(AggElem*),
          (char *)&p->pAgg->pCurrent);
      if( rc!=SQLITE_OK ) goto abort_due_to_error;
    }
    aMem = p->pAgg->pCurrent->aMem;
    for(i=0; i<p->pAgg->nMem; i++){
      FuncDef *pFunc = p->pAgg->apFunc[i];
      Mem *pMem = &aMem[i];






      sqlite3VdbeMemFinalize(pMem, pFunc);








    }
  }
  break;
}

/* Opcode: Vacuum * * *
**
Changes to src/vdbeInt.h.
110
111
112
113
114
115
116
117


118
119
120
121
122
123
124
125
126
127
128
129
130
**
** Each value has a manifest type. The manifest type of the value stored
** in a Mem struct is returned by the MemType(Mem*) macro. The type is
** one of SQLITE_NULL, SQLITE_INTEGER, SQLITE_REAL, SQLITE_TEXT or
** SQLITE_BLOB.
*/
struct Mem {
  i64 i;              /* Integer value */


  int n;              /* Number of characters in string value, including '\0' */
  u16 flags;          /* Some combination of MEM_Null, MEM_Str, MEM_Dyn, etc. */
  u8  type;           /* One of MEM_Null, MEM_Str, etc. */
  u8  enc;            /* TEXT_Utf8, TEXT_Utf16le, or TEXT_Utf16be */
  double r;           /* Real value */
  char *z;            /* String or BLOB value */
  void (*xDel)(void *);  /* If not null, call this function to delete Mem.z */
  char zShort[NBFS];  /* Space for short strings */
};
typedef struct Mem Mem;

/* One or more of the following flags are set to indicate the validOK
** representations of the value stored in the Mem struct.







|
>
>




<
<







110
111
112
113
114
115
116
117
118
119
120
121
122
123


124
125
126
127
128
129
130
**
** Each value has a manifest type. The manifest type of the value stored
** in a Mem struct is returned by the MemType(Mem*) macro. The type is
** one of SQLITE_NULL, SQLITE_INTEGER, SQLITE_REAL, SQLITE_TEXT or
** SQLITE_BLOB.
*/
struct Mem {
  i64 i;              /* Integer value. Or FuncDef* when flags==MEM_Agg */
  double r;           /* Real value */
  char *z;            /* String or BLOB value */
  int n;              /* Number of characters in string value, including '\0' */
  u16 flags;          /* Some combination of MEM_Null, MEM_Str, MEM_Dyn, etc. */
  u8  type;           /* One of MEM_Null, MEM_Str, etc. */
  u8  enc;            /* TEXT_Utf8, TEXT_Utf16le, or TEXT_Utf16be */


  void (*xDel)(void *);  /* If not null, call this function to delete Mem.z */
  char zShort[NBFS];  /* Space for short strings */
};
typedef struct Mem Mem;

/* One or more of the following flags are set to indicate the validOK
** representations of the value stored in the Mem struct.
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
** string is \000 or \u0000 terminated
*/
#define MEM_Term      0x0020   /* String rep is nul terminated */
#define MEM_Dyn       0x0040   /* Need to call sqliteFree() on Mem.z */
#define MEM_Static    0x0080   /* Mem.z points to a static string */
#define MEM_Ephem     0x0100   /* Mem.z points to an ephemeral string */
#define MEM_Short     0x0200   /* Mem.z points to Mem.zShort */

/* The following MEM_ value appears only in AggElem.aMem.s.flag fields.
** It indicates that the corresponding AggElem.aMem.z points to a
** aggregate function context that needs to be finalized.
*/
#define MEM_AggCtx    0x0400  /* Mem.z points to an agg function context */


/* A VdbeFunc is just a FuncDef (defined in sqliteInt.h) that contains
** additional information about auxiliary information bound to arguments
** of the function.  This is used to implement the sqlite3_get_auxdata()
** and sqlite3_set_auxdata() APIs.  The "auxdata" is some auxiliary data
** that can be associated with a constant argument to a function.  This







<
<
<
<
<
|







153
154
155
156
157
158
159





160
161
162
163
164
165
166
167
** string is \000 or \u0000 terminated
*/
#define MEM_Term      0x0020   /* String rep is nul terminated */
#define MEM_Dyn       0x0040   /* Need to call sqliteFree() on Mem.z */
#define MEM_Static    0x0080   /* Mem.z points to a static string */
#define MEM_Ephem     0x0100   /* Mem.z points to an ephemeral string */
#define MEM_Short     0x0200   /* Mem.z points to Mem.zShort */





#define MEM_Agg       0x0400   /* Mem.z points to an agg function context */


/* A VdbeFunc is just a FuncDef (defined in sqliteInt.h) that contains
** additional information about auxiliary information bound to arguments
** of the function.  This is used to implement the sqlite3_get_auxdata()
** and sqlite3_set_auxdata() APIs.  The "auxdata" is some auxiliary data
** that can be associated with a constant argument to a function.  This
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
** implement the SQL functions.
**
** There is a typedef for this structure in sqlite.h.  So all routines,
** even the public interface to SQLite, can use a pointer to this structure.
** But this file is the only place where the internal details of this
** structure are known.
**
** This structure is defined inside of vdbe.c because it uses substructures
** (Mem) which are only defined there.
*/
struct sqlite3_context {
  FuncDef *pFunc;   /* Pointer to function information.  MUST BE FIRST */
  VdbeFunc *pVdbeFunc;  /* Auxilary data, if created. */
  Mem s;            /* The return value is stored here */
  void *pAgg;       /* Aggregate context */
  u8 isError;       /* Set to true for an error */
  int cnt;          /* Number of times that the step function has been called */
  CollSeq *pColl;
};

/*
** An Agg structure describes an Aggregator.  Each Agg consists of
** zero or more Aggregator elements (AggElem).  Each AggElem contains
** a key and one or more values.  The values are used in processing
** aggregate functions in a SELECT.  The key is used to implement







|



|

|
|
|
<
|







185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200

201
202
203
204
205
206
207
208
** implement the SQL functions.
**
** There is a typedef for this structure in sqlite.h.  So all routines,
** even the public interface to SQLite, can use a pointer to this structure.
** But this file is the only place where the internal details of this
** structure are known.
**
** This structure is defined inside of vdbeInt.h because it uses substructures
** (Mem) which are only defined there.
*/
struct sqlite3_context {
  FuncDef *pFunc;       /* Pointer to function information.  MUST BE FIRST */
  VdbeFunc *pVdbeFunc;  /* Auxilary data, if created. */
  Mem s;                /* The return value is stored here */
  Mem *pMem;            /* Memory cell used to store aggregate context */
  u8 isError;           /* Set to true for an error */

  CollSeq *pColl;       /* Collating sequence */
};

/*
** An Agg structure describes an Aggregator.  Each Agg consists of
** zero or more Aggregator elements (AggElem).  Each AggElem contains
** a key and one or more values.  The values are used in processing
** aggregate functions in a SELECT.  The key is used to implement
393
394
395
396
397
398
399

400
401
402
403
404
405
406
407
408
409
410
int sqlite3VdbeMemStringify(Mem*, int);
i64 sqlite3VdbeIntValue(Mem*);
int sqlite3VdbeMemIntegerify(Mem*);
double sqlite3VdbeRealValue(Mem*);
int sqlite3VdbeMemRealify(Mem*);
int sqlite3VdbeMemFromBtree(BtCursor*,int,int,int,Mem*);
void sqlite3VdbeMemRelease(Mem *p);

#ifndef NDEBUG
void sqlite3VdbeMemSanity(Mem*, u8);
int sqlite3VdbeOpcodeNoPush(u8);
#endif
int sqlite3VdbeMemTranslate(Mem*, u8);
void sqlite3VdbeMemPrettyPrint(Mem *pMem, char *zBuf, int nBuf);
int sqlite3VdbeMemHandleBom(Mem *pMem);
void sqlite3VdbeFifoInit(Fifo*);
int sqlite3VdbeFifoPush(Fifo*, i64);
int sqlite3VdbeFifoPop(Fifo*, i64*);
void sqlite3VdbeFifoClear(Fifo*);







>











387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
int sqlite3VdbeMemStringify(Mem*, int);
i64 sqlite3VdbeIntValue(Mem*);
int sqlite3VdbeMemIntegerify(Mem*);
double sqlite3VdbeRealValue(Mem*);
int sqlite3VdbeMemRealify(Mem*);
int sqlite3VdbeMemFromBtree(BtCursor*,int,int,int,Mem*);
void sqlite3VdbeMemRelease(Mem *p);
void sqlite3VdbeMemFinalize(Mem*, FuncDef*);
#ifndef NDEBUG
void sqlite3VdbeMemSanity(Mem*, u8);
int sqlite3VdbeOpcodeNoPush(u8);
#endif
int sqlite3VdbeMemTranslate(Mem*, u8);
void sqlite3VdbeMemPrettyPrint(Mem *pMem, char *zBuf, int nBuf);
int sqlite3VdbeMemHandleBom(Mem *pMem);
void sqlite3VdbeFifoInit(Fifo*);
int sqlite3VdbeFifoPush(Fifo*, i64);
int sqlite3VdbeFifoPop(Fifo*, i64*);
void sqlite3VdbeFifoClear(Fifo*);
Changes to src/vdbeapi.c.
254
255
256
257
258
259
260
261



262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
/*
** Allocate or return the aggregate context for a user function.  A new
** context is allocated on the first call.  Subsequent calls return the
** same context that was returned on prior calls.
*/
void *sqlite3_aggregate_context(sqlite3_context *p, int nByte){
  assert( p && p->pFunc && p->pFunc->xStep );
  if( p->pAgg==0 ){



    if( nByte<=NBFS ){
      p->pAgg = (void*)p->s.z;
      memset(p->pAgg, 0, nByte);
    }else{
      p->pAgg = sqliteMalloc( nByte );
    }
  }
  return p->pAgg;
}

/*
** Return the auxilary data pointer, if any, for the iArg'th argument to
** the user-function defined by pCtx.
*/
void *sqlite3_get_auxdata(sqlite3_context *pCtx, int iArg){







|
>
>
>

|
|

|


|







254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
/*
** Allocate or return the aggregate context for a user function.  A new
** context is allocated on the first call.  Subsequent calls return the
** same context that was returned on prior calls.
*/
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);
    }else{
      pMem->z = sqliteMalloc( nByte );
    }
  }
  return (void*)pMem->z;
}

/*
** Return the auxilary data pointer, if any, for the iArg'th argument to
** the user-function defined by pCtx.
*/
void *sqlite3_get_auxdata(sqlite3_context *pCtx, int iArg){
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
**
** This routine is defined here in vdbe.c because it depends on knowing
** the internals of the sqlite3_context structure which is only defined in
** this source file.
*/
int sqlite3_aggregate_count(sqlite3_context *p){
  assert( p && p->pFunc && p->pFunc->xStep );
  return p->cnt;
}

/*
** Return the number of columns in the result set for the statement pStmt.
*/
int sqlite3_column_count(sqlite3_stmt *pStmt){
  Vdbe *pVm = (Vdbe *)pStmt;







|







324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
**
** This routine is defined here in vdbe.c because it depends on knowing
** the internals of the sqlite3_context structure which is only defined in
** this source file.
*/
int sqlite3_aggregate_count(sqlite3_context *p){
  assert( p && p->pFunc && p->pFunc->xStep );
  return p->pMem->n;
}

/*
** Return the number of columns in the result set for the statement pStmt.
*/
int sqlite3_column_count(sqlite3_stmt *pStmt){
  Vdbe *pVm = (Vdbe *)pStmt;
Changes to src/vdbeaux.c.
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
** Free all resources allociated with AggElem pElem, an element of
** aggregate pAgg.
*/
static void freeAggElem(AggElem *pElem, Agg *pAgg){
  int i;
  for(i=0; i<pAgg->nMem; i++){
    Mem *pMem = &pElem->aMem[i];
    if( pAgg->apFunc && 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.isError = 0;
      (*ctx.pFunc->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.
**







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







772
773
774
775
776
777
778
779

780








781


782
783
784
785
786
787
788
789
790
** Free all resources allociated with AggElem pElem, an element of
** aggregate pAgg.
*/
static void freeAggElem(AggElem *pElem, Agg *pAgg){
  int i;
  for(i=0; i<pAgg->nMem; i++){
    Mem *pMem = &pElem->aMem[i];
    if( pAgg->apFunc && pAgg->apFunc[i] && (pMem->flags & MEM_Agg)!=0 ){

      sqlite3VdbeMemFinalize(pMem, pAgg->apFunc[i]);








    }


    sqlite3VdbeMemRelease(pMem);

  }
  sqliteFree(pElem);
}

/*
** Reset an Agg structure.  Delete all its contents.
**
Changes to src/vdbemem.c.
182
183
184
185
186
187
188























189
190
191
192
193
194
195
196
197





198

199
200
201
202
203
204
205
  pMem->n = strlen(z);
  pMem->z = z;
  pMem->enc = SQLITE_UTF8;
  pMem->flags |= MEM_Str | MEM_Short | MEM_Term;
  sqlite3VdbeChangeEncoding(pMem, enc);
  return rc;
}
























/*
** Release any memory held by the Mem. This may leave the Mem in an
** inconsistent state, for example with (Mem.z==0) and
** (Mem.type==SQLITE_TEXT).
*/
void sqlite3VdbeMemRelease(Mem *p){
  if( p->flags & MEM_Dyn ){
    if( p->xDel ){





      p->xDel((void *)p->z);

    }else{
      sqliteFree(p->z);
    }
    p->z = 0;
    p->xDel = 0;
  }
}







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







|

>
>
>
>
>
|
>







182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
  pMem->n = strlen(z);
  pMem->z = z;
  pMem->enc = SQLITE_UTF8;
  pMem->flags |= MEM_Str | MEM_Short | MEM_Term;
  sqlite3VdbeChangeEncoding(pMem, enc);
  return rc;
}

/*
** Memory cell pMem contains the context of an aggregate function.
** This routine calls the finalize method for that function.  The
** result of the aggregate is stored back into pMem.
*/
void sqlite3VdbeMemFinalize(Mem *pMem, FuncDef *pFunc){
  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;
    }
  }
}

/*
** Release any memory held by the Mem. This may leave the Mem in an
** inconsistent state, for example with (Mem.z==0) and
** (Mem.type==SQLITE_TEXT).
*/
void sqlite3VdbeMemRelease(Mem *p){
  if( p->flags & (MEM_Dyn|MEM_Agg) ){
    if( p->xDel ){
      if( p->flags & MEM_Agg ){
        sqlite3VdbeMemFinalize(p, (FuncDef*)&p->i);
        assert( (p->flags & MEM_Agg)==0 );
        sqlite3VdbeMemRelease(p);
      }else{
        p->xDel((void *)p->z);
      }
    }else{
      sqliteFree(p->z);
    }
    p->z = 0;
    p->xDel = 0;
  }
}