summaryrefslogtreecommitdiff
path: root/ext/pdo_sqlite/sqlite/src/vdbemem.c
diff options
context:
space:
mode:
Diffstat (limited to 'ext/pdo_sqlite/sqlite/src/vdbemem.c')
-rw-r--r--ext/pdo_sqlite/sqlite/src/vdbemem.c37
1 files changed, 34 insertions, 3 deletions
diff --git a/ext/pdo_sqlite/sqlite/src/vdbemem.c b/ext/pdo_sqlite/sqlite/src/vdbemem.c
index 416beb6c78..0b7e193bec 100644
--- a/ext/pdo_sqlite/sqlite/src/vdbemem.c
+++ b/ext/pdo_sqlite/sqlite/src/vdbemem.c
@@ -188,14 +188,44 @@ int sqlite3VdbeMemStringify(Mem *pMem, int enc){
}
/*
+** 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;
+ 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;
+ }
+ }
+}
+
+/*
** 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->flags & (MEM_Dyn|MEM_Agg) ){
if( p->xDel ){
- p->xDel((void *)p->z);
+ 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);
}
@@ -287,6 +317,7 @@ void sqlite3VdbeMemSetNull(Mem *pMem){
sqlite3VdbeMemRelease(pMem);
pMem->flags = MEM_Null;
pMem->type = SQLITE_NULL;
+ pMem->n = 0;
}
/*
@@ -699,7 +730,7 @@ const void *sqlite3ValueText(sqlite3_value* pVal, u8 enc){
/*
** Create a new sqlite3_value object.
*/
-sqlite3_value* sqlite3ValueNew(){
+sqlite3_value* sqlite3ValueNew(void){
Mem *p = sqliteMalloc(sizeof(*p));
if( p ){
p->flags = MEM_Null;