DBD-SQLite2
view release on metacpan or search on metacpan
}
/*
** 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
** private context. If the finalizer has not been called yet, call it
** now.
*/
void sqliteVdbeAggReset(Agg *pAgg){
int i;
HashElem *p;
for(p = sqliteHashFirst(&pAgg->hash); p; p = sqliteHashNext(p)){
AggElem *pElem = sqliteHashData(p);
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 ){
sqlite_func 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);
if( pMem->z!=0 && pMem->z!=pMem->zShort ){
sqliteFree(pMem->z);
}
if( ctx.s.flags & MEM_Dyn ){
sqliteFree(ctx.s.z);
}
}else if( pMem->flags & MEM_Dyn ){
sqliteFree(pMem->z);
}
}
sqliteFree(pElem);
}
sqliteHashClear(&pAgg->hash);
sqliteFree(pAgg->apFunc);
pAgg->apFunc = 0;
pAgg->pCurrent = 0;
pAgg->pSearch = 0;
pAgg->nMem = 0;
}
/*
** Delete a keylist
*/
void sqliteVdbeKeylistFree(Keylist *p){
while( p ){
Keylist *pNext = p->pNext;
sqliteFree(p);
p = pNext;
}
}
/*
** Close a cursor and release all the resources that cursor happens
** to hold.
*/
void sqliteVdbeCleanupCursor(Cursor *pCx){
if( pCx->pCursor ){
sqliteBtreeCloseCursor(pCx->pCursor);
}
if( pCx->pBt ){
sqliteBtreeClose(pCx->pBt);
}
sqliteFree(pCx->pData);
memset(pCx, 0, sizeof(Cursor));
}
/*
** Close all cursors
*/
static void closeAllCursors(Vdbe *p){
int i;
for(i=0; i<p->nCursor; i++){
sqliteVdbeCleanupCursor(&p->aCsr[i]);
}
sqliteFree(p->aCsr);
p->aCsr = 0;
p->nCursor = 0;
}
/*
** Clean up the VM after execution.
**
** This routine will automatically close any cursors, lists, and/or
** sorters that were left open. It also deletes the values of
** variables in the azVariable[] array.
*/
static void Cleanup(Vdbe *p){
int i;
if( p->aStack ){
Mem *pTos = p->pTos;
while( pTos>=p->aStack ){
if( pTos->flags & MEM_Dyn ){
sqliteFree(pTos->z);
}
pTos--;
}
p->pTos = pTos;
}
closeAllCursors(p);
if( p->aMem ){
for(i=0; i<p->nMem; i++){
if( p->aMem[i].flags & MEM_Dyn ){
sqliteFree(p->aMem[i].z);
}
}
}
sqliteFree(p->aMem);
p->aMem = 0;
p->nMem = 0;
if( p->pList ){
sqliteVdbeKeylistFree(p->pList);
p->pList = 0;
}
sqliteVdbeSorterReset(p);
if( p->pFile ){
if( p->pFile!=stdin ) fclose(p->pFile);
p->pFile = 0;
}
if( p->azField ){
sqliteFree(p->azField);
p->azField = 0;
}
p->nField = 0;
if( p->zLine ){
sqliteFree(p->zLine);
p->zLine = 0;
}
p->nLineAlloc = 0;
sqliteVdbeAggReset(&p->agg);
if( p->aSet ){
for(i=0; i<p->nSet; i++){
sqliteHashClear(&p->aSet[i].hash);
}
}
sqliteFree(p->aSet);
p->aSet = 0;
p->nSet = 0;
if( p->keylistStack ){
int ii;
for(ii = 0; ii < p->keylistStackDepth; ii++){
sqliteVdbeKeylistFree(p->keylistStack[ii]);
}
sqliteFree(p->keylistStack);
int i;
if( p==0 ) return;
Cleanup(p);
if( p->pPrev ){
p->pPrev->pNext = p->pNext;
}else{
assert( p->db->pVdbe==p );
p->db->pVdbe = p->pNext;
}
if( p->pNext ){
p->pNext->pPrev = p->pPrev;
}
p->pPrev = p->pNext = 0;
if( p->nOpAlloc==0 ){
p->aOp = 0;
p->nOp = 0;
}
for(i=0; i<p->nOp; i++){
if( p->aOp[i].p3type==P3_DYNAMIC ){
sqliteFree(p->aOp[i].p3);
}
}
for(i=0; i<p->nVar; i++){
if( p->abVar[i] ) sqliteFree(p->azVar[i]);
}
sqliteFree(p->aOp);
sqliteFree(p->aLabel);
sqliteFree(p->aStack);
p->magic = VDBE_MAGIC_DEAD;
sqliteFree(p);
}
/*
** Convert an integer in between the native integer format and
** the bigEndian format used as the record number for tables.
**
** The bigEndian format (most significant byte first) is used for
** record numbers so that records will sort into the correct order
** even though memcmp() is used to compare the keys. On machines
** whose native integer format is little endian (ex: i486) the
** order of bytes is reversed. On native big-endian machines
** (ex: Alpha, Sparc, Motorola) the byte order is the same.
**
** This function is its own inverse. In other words
**
** X == byteSwap(byteSwap(X))
*/
int sqliteVdbeByteSwap(int x){
union {
char zBuf[sizeof(int)];
int i;
} ux;
ux.zBuf[3] = x&0xff;
ux.zBuf[2] = (x>>8)&0xff;
ux.zBuf[1] = (x>>16)&0xff;
ux.zBuf[0] = (x>>24)&0xff;
return ux.i;
}
/*
** If a MoveTo operation is pending on the given cursor, then do that
** MoveTo now. Return an error code. If no MoveTo is pending, this
** routine does nothing and returns SQLITE_OK.
*/
int sqliteVdbeCursorMoveto(Cursor *p){
if( p->deferredMoveto ){
int res;
extern int sqlite_search_count;
sqliteBtreeMoveto(p->pCursor, (char*)&p->movetoTarget, sizeof(int), &res);
p->lastRecno = keyToInt(p->movetoTarget);
p->recnoIsValid = res==0;
if( res<0 ){
sqliteBtreeNext(p->pCursor, &res);
}
sqlite_search_count++;
p->deferredMoveto = 0;
}
return SQLITE_OK;
}
( run in 0.583 second using v1.01-cache-2.11-cpan-e1769b4cff6 )