mirror of
https://github.com/sqlite/sqlite.git
synced 2025-11-16 23:02:26 +03:00
Implement the "lookaside" memory allocation cache. Use of this cache makes
the speed1.test script run about 15% faster. Added new interfaces to control the cache. (CVS 5488) FossilOrigin-Name: e48f9697e9fea339e150ddc32940760027dd07d9
This commit is contained in:
44
src/where.c
44
src/where.c
@@ -16,7 +16,7 @@
|
||||
** so is applicable. Because this module is responsible for selecting
|
||||
** indices, you might also think of this module as the "query optimizer".
|
||||
**
|
||||
** $Id: where.c,v 1.317 2008/07/12 14:52:20 drh Exp $
|
||||
** $Id: where.c,v 1.318 2008/07/28 19:34:54 drh Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
|
||||
@@ -92,7 +92,7 @@ struct WhereTerm {
|
||||
/*
|
||||
** Allowed values of WhereTerm.flags
|
||||
*/
|
||||
#define TERM_DYNAMIC 0x01 /* Need to call sqlite3ExprDelete(pExpr) */
|
||||
#define TERM_DYNAMIC 0x01 /* Need to call sqlite3ExprDelete(db, pExpr) */
|
||||
#define TERM_VIRTUAL 0x02 /* Added by the optimizer. Do not code */
|
||||
#define TERM_CODED 0x04 /* This term is already coded */
|
||||
#define TERM_COPIED 0x08 /* Has a child */
|
||||
@@ -203,13 +203,14 @@ static void whereClauseInit(
|
||||
static void whereClauseClear(WhereClause *pWC){
|
||||
int i;
|
||||
WhereTerm *a;
|
||||
sqlite3 *db = pWC->pParse->db;
|
||||
for(i=pWC->nTerm-1, a=pWC->a; i>=0; i--, a++){
|
||||
if( a->flags & TERM_DYNAMIC ){
|
||||
sqlite3ExprDelete(a->pExpr);
|
||||
sqlite3ExprDelete(db, a->pExpr);
|
||||
}
|
||||
}
|
||||
if( pWC->a!=pWC->aStatic ){
|
||||
sqlite3_free(pWC->a);
|
||||
sqlite3DbFree(db, pWC->a);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -230,18 +231,18 @@ static int whereClauseInsert(WhereClause *pWC, Expr *p, int flags){
|
||||
int idx;
|
||||
if( pWC->nTerm>=pWC->nSlot ){
|
||||
WhereTerm *pOld = pWC->a;
|
||||
pWC->a = sqlite3Malloc( sizeof(pWC->a[0])*pWC->nSlot*2 );
|
||||
sqlite3 *db = pWC->pParse->db;
|
||||
pWC->a = sqlite3DbMallocRaw(db, sizeof(pWC->a[0])*pWC->nSlot*2 );
|
||||
if( pWC->a==0 ){
|
||||
pWC->pParse->db->mallocFailed = 1;
|
||||
if( flags & TERM_DYNAMIC ){
|
||||
sqlite3ExprDelete(p);
|
||||
sqlite3ExprDelete(db, p);
|
||||
}
|
||||
pWC->a = pOld;
|
||||
return 0;
|
||||
}
|
||||
memcpy(pWC->a, pOld, sizeof(pWC->a[0])*pWC->nTerm);
|
||||
if( pOld!=pWC->aStatic ){
|
||||
sqlite3_free(pOld);
|
||||
sqlite3DbFree(db, pOld);
|
||||
}
|
||||
pWC->nSlot *= 2;
|
||||
}
|
||||
@@ -773,7 +774,7 @@ static void exprAnalyze(
|
||||
int idxNew;
|
||||
pDup = sqlite3ExprDup(db, pExpr);
|
||||
if( db->mallocFailed ){
|
||||
sqlite3ExprDelete(pDup);
|
||||
sqlite3ExprDelete(db, pDup);
|
||||
return;
|
||||
}
|
||||
idxNew = whereClauseInsert(pWC, pDup, TERM_VIRTUAL|TERM_DYNAMIC);
|
||||
@@ -889,7 +890,7 @@ static void exprAnalyze(
|
||||
pWC->a[idxNew].iParent = idxTerm;
|
||||
pTerm->nChild = 1;
|
||||
}else{
|
||||
sqlite3ExprListDelete(pList);
|
||||
sqlite3ExprListDelete(db, pList);
|
||||
}
|
||||
}
|
||||
or_not_possible:
|
||||
@@ -1908,14 +1909,15 @@ static int nQPlan = 0; /* Next free slow in _query_plan[] */
|
||||
static void whereInfoFree(WhereInfo *pWInfo){
|
||||
if( pWInfo ){
|
||||
int i;
|
||||
sqlite3 *db = pWInfo->pParse->db;
|
||||
for(i=0; i<pWInfo->nLevel; i++){
|
||||
sqlite3_index_info *pInfo = pWInfo->a[i].pIdxInfo;
|
||||
if( pInfo ){
|
||||
assert( pInfo->needToFreeIdxStr==0 );
|
||||
sqlite3_free(pInfo);
|
||||
sqlite3DbFree(db, pInfo);
|
||||
}
|
||||
}
|
||||
sqlite3_free(pWInfo);
|
||||
sqlite3DbFree(db, pWInfo);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2248,22 +2250,22 @@ WhereInfo *sqlite3WhereBegin(
|
||||
struct SrcList_item *pItem = &pTabList->a[pLevel->iFrom];
|
||||
zMsg = sqlite3MPrintf(db, "TABLE %s", pItem->zName);
|
||||
if( pItem->zAlias ){
|
||||
zMsg = sqlite3MPrintf(db, "%z AS %s", zMsg, pItem->zAlias);
|
||||
zMsg = sqlite3MAppendf(db, zMsg, "%s AS %s", zMsg, pItem->zAlias);
|
||||
}
|
||||
if( (pIx = pLevel->pIdx)!=0 ){
|
||||
zMsg = sqlite3MPrintf(db, "%z WITH INDEX %s", zMsg, pIx->zName);
|
||||
zMsg = sqlite3MAppendf(db, zMsg, "%s WITH INDEX %s", zMsg, pIx->zName);
|
||||
}else if( pLevel->flags & (WHERE_ROWID_EQ|WHERE_ROWID_RANGE) ){
|
||||
zMsg = sqlite3MPrintf(db, "%z USING PRIMARY KEY", zMsg);
|
||||
zMsg = sqlite3MAppendf(db, zMsg, "%s USING PRIMARY KEY", zMsg);
|
||||
}
|
||||
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
||||
else if( pLevel->pBestIdx ){
|
||||
sqlite3_index_info *pBestIdx = pLevel->pBestIdx;
|
||||
zMsg = sqlite3MPrintf(db, "%z VIRTUAL TABLE INDEX %d:%s", zMsg,
|
||||
zMsg = sqlite3MAppendf(db, zMsg, "%s VIRTUAL TABLE INDEX %d:%s", zMsg,
|
||||
pBestIdx->idxNum, pBestIdx->idxStr);
|
||||
}
|
||||
#endif
|
||||
if( pLevel->flags & WHERE_ORDERBY ){
|
||||
zMsg = sqlite3MPrintf(db, "%z ORDER BY", zMsg);
|
||||
zMsg = sqlite3MAppendf(db, zMsg, "%s ORDER BY", zMsg);
|
||||
}
|
||||
sqlite3VdbeAddOp4(v, OP_Explain, i, pLevel->iFrom, 0, zMsg, P4_DYNAMIC);
|
||||
}
|
||||
@@ -2779,14 +2781,16 @@ whereBeginNoMem:
|
||||
** sqlite3WhereBegin() for additional information.
|
||||
*/
|
||||
void sqlite3WhereEnd(WhereInfo *pWInfo){
|
||||
Vdbe *v = pWInfo->pParse->pVdbe;
|
||||
Parse *pParse = pWInfo->pParse;
|
||||
Vdbe *v = pParse->pVdbe;
|
||||
int i;
|
||||
WhereLevel *pLevel;
|
||||
SrcList *pTabList = pWInfo->pTabList;
|
||||
sqlite3 *db = pParse->db;
|
||||
|
||||
/* Generate loop termination code.
|
||||
*/
|
||||
sqlite3ExprClearColumnCache(pWInfo->pParse, -1);
|
||||
sqlite3ExprClearColumnCache(pParse, -1);
|
||||
for(i=pTabList->nSrc-1; i>=0; i--){
|
||||
pLevel = &pWInfo->a[i];
|
||||
sqlite3VdbeResolveLabel(v, pLevel->cont);
|
||||
@@ -2802,7 +2806,7 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){
|
||||
sqlite3VdbeAddOp2(v, OP_Next, pIn->iCur, pIn->topAddr);
|
||||
sqlite3VdbeJumpHere(v, pIn->topAddr-1);
|
||||
}
|
||||
sqlite3_free(pLevel->aInLoop);
|
||||
sqlite3DbFree(db, pLevel->aInLoop);
|
||||
}
|
||||
sqlite3VdbeResolveLabel(v, pLevel->brk);
|
||||
if( pLevel->iLeftJoin ){
|
||||
|
||||
Reference in New Issue
Block a user