1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-11-14 00:22:38 +03:00

Avoid opening a temp table for aggregate queries with no GROUP BY clause. (CVS 1649)

FossilOrigin-Name: 4d02df63496091a1e643601f84313f42130d6282
This commit is contained in:
danielk1977
2004-06-21 10:45:06 +00:00
parent 72c952a1c4
commit e159fdf21c
7 changed files with 111 additions and 73 deletions

View File

@@ -671,6 +671,35 @@ void sqlite3VdbeSorterReset(Vdbe *p){
}
}
/*
** 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.
**
@@ -715,27 +744,7 @@ int sqlite3VdbeAggReset(sqlite *db, Agg *pAgg, KeyInfo *pKeyInfo){
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);
freeAggElem(pElem, pAgg);
rc=sqlite3BtreeNext(pCsr, &res);
}
if( rc!=SQLITE_OK ){
@@ -744,6 +753,13 @@ int sqlite3VdbeAggReset(sqlite *db, Agg *pAgg, KeyInfo *pKeyInfo){
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
@@ -1313,9 +1329,9 @@ int sqlite3VdbeFinalize(Vdbe *p){
/*
** Call the destructor for each auxdata entry in pVdbeFunc for which
** the corresponding bit in mask is set. Auxdata entries beyond 31
** the corresponding bit in mask is clear. Auxdata entries beyond 31
** are always destroyed. To destroy all auxdata entries, call this
** routine with mask==-1.
** routine with mask==0.
*/
void sqlite3VdbeDeleteAuxData(VdbeFunc *pVdbeFunc, int mask){
int i;
@@ -1358,7 +1374,7 @@ void sqlite3VdbeDelete(Vdbe *p){
}
if( pOp->p3type==P3_VDBEFUNC ){
VdbeFunc *pVdbeFunc = (VdbeFunc *)pOp->p3;
sqlite3VdbeDeleteAuxData(pVdbeFunc, -1);
sqlite3VdbeDeleteAuxData(pVdbeFunc, 0);
sqliteFree(pVdbeFunc);
}
#ifndef NDEBUG