From: drh Date: Fri, 29 May 2009 19:00:12 +0000 (+0000) Subject: Enhance the sqlite3VdbeGetOp() routine so that it always returns a pointer X-Git-Tag: version-3.6.15~69 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=20411ea70012558d0c66911471ab8619b4b1add8;p=thirdparty%2Fsqlite.git Enhance the sqlite3VdbeGetOp() routine so that it always returns a pointer to VdbeOp, even following an OOM fault. This simplifies error handling in callers. Cleanup to the column cache logic and the expr.c source module. (CVS 6691) FossilOrigin-Name: ede06dacdf7acab23cd9666a0a0d092a637bcb78 --- diff --git a/manifest b/manifest index 6553897649..31af058f6e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Refinements\sin\sexpression\shandling\slogic\sthat\shave\sresulted\sfrom\srecent\nstructural\stesting.\s(CVS\s6690) -D 2009-05-29T14:39:08 +C Enhance\sthe\ssqlite3VdbeGetOp()\sroutine\sso\sthat\sit\salways\sreturns\sa\spointer\nto\sVdbeOp,\seven\sfollowing\san\sOOM\sfault.\s\sThis\ssimplifies\serror\shandling\sin\ncallers.\s\sCleanup\sto\sthe\scolumn\scache\slogic\sand\sthe\sexpr.c\ssource\smodule.\s(CVS\s6691) +D 2009-05-29T19:00:13 F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0 F Makefile.in 583e87706abc3026960ed759aff6371faf84c211 F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654 @@ -114,14 +114,14 @@ F src/callback.c 57359fa93de47c341b6b8ee504a88ff276397686 F src/complete.c 5ad5c6cd4548211867c204c41a126d73a9fbcea0 F src/date.c ab5f7137656652a48434d64f96bdcdc823bb23b3 F src/delete.c cb791855c7948cecc96def9d97989879ca26f257 -F src/expr.c ba5ba6a6332ec07d81cda97585dabf6c88bffbab +F src/expr.c b844f5f63bc46c160ce20ec7b76ca2fe4aa70323 F src/fault.c dc88c821842157460750d2d61a8a8b4197d047ff F src/func.c 9d7b47729c337c5e4b78d795922ed34eec4aef67 F src/global.c 448419c44ce0701104c2121b0e06919b44514c0c F src/hash.c ebcaa921ffd9d86f7ea5ae16a0a29d1c871130a7 F src/hash.h 35b216c13343d0b4f87d9f21969ac55ad72174e1 F src/hwtime.h 4a1d45f4cae1f402ea19686acf24acf4f0cb53cb -F src/insert.c 050536ea91c6cf74d87a2386b5da241141943c94 +F src/insert.c 69ef88ce30d1f65315b57aba63b2d4e9bdca1090 F src/journal.c e00df0c0da8413ab6e1bb7d7cab5665d4a9000d0 F src/legacy.c 9a56cf126ceee332b56061bf16bd0fb4ff9e26c0 F src/loadext.c a281f9890ce4f8f2b68967a124322c6ae98f1245 @@ -207,7 +207,7 @@ F src/vdbe.c b859cb274024e5755aa03625251ff859e3e95158 F src/vdbe.h 35a648bc3279a120da24f34d9a25213ec15daf8a F src/vdbeInt.h 43183a2a18654fa570219ab65e53a608057c48ae F src/vdbeapi.c 86aa27a5f3493aaffb8ac051782aa3b22670d7ed -F src/vdbeaux.c 1a07329bdf51cc3687f88d9f5b2bd3f1d47cc5a8 +F src/vdbeaux.c 37730f227a5301c04e5bf03fd303b9086ada990c F src/vdbeblob.c 5c5abe9af28316772e7829359f6f9cda2c737ebd F src/vdbemem.c 05183d46094aa99b8f8350e5761b9369dbef35a8 F src/vtab.c b0216337ae7d27708dedd56d220e6f4fecda92f1 @@ -731,7 +731,7 @@ F tool/speedtest16.c c8a9c793df96db7e4933f0852abb7a03d48f2e81 F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e -P 726b425e43e5d864e7e83853bdf134debc1ffb59 -R 7782c740d0e684d85e0d73fa4ed3175a +P bd89f2c29b00e6b473f30c2e929d2f626721ad92 +R 29b49f3922c1a42fc4c3255229bf7dca U drh -Z 3b276276ba95400e6569bffb7e01828d +Z 402c7be7f2f60e461e03a4ddcdf6f1bd diff --git a/manifest.uuid b/manifest.uuid index 56bb8a9768..c67e2e159e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -bd89f2c29b00e6b473f30c2e929d2f626721ad92 \ No newline at end of file +ede06dacdf7acab23cd9666a0a0d092a637bcb78 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index d0b96a039a..b9979d6020 100644 --- a/src/expr.c +++ b/src/expr.c @@ -12,7 +12,7 @@ ** This file contains routines used for analyzing expressions and ** for generating VDBE code that evaluates expressions in SQLite. ** -** $Id: expr.c,v 1.440 2009/05/29 14:39:08 drh Exp $ +** $Id: expr.c,v 1.441 2009/05/29 19:00:13 drh Exp $ */ #include "sqliteInt.h" @@ -1773,6 +1773,9 @@ void sqlite3ExprCacheStore(Parse *pParse, int iTab, int iCol, int iReg){ int idxLru; struct yColCache *p; + assert( iReg>0 ); /* Register numbers are always positive */ + assert( iCol>=-1 && iCol<32768 ); /* Finite column numbers */ + /* First replace any existing entry */ for(i=0, p=pParse->aColCache; iiReg && p->iTable==iTab && p->iColumn==iCol ){ @@ -1784,7 +1787,6 @@ void sqlite3ExprCacheStore(Parse *pParse, int iTab, int iCol, int iReg){ return; } } - if( iReg<=0 ) return; /* Find an empty slot and replace it */ for(i=0, p=pParse->aColCache; ilru; } } - if( idxLru>=0 ){ + if( ALWAYS(idxLru>=0) ){ p = &pParse->aColCache[idxLru]; p->iLevel = pParse->iCacheLevel; p->iTable = iTab; @@ -1911,10 +1913,6 @@ int sqlite3ExprCodeGetColumn( for(i=0, p=pParse->aColCache; iiReg>0 && p->iTable==iTable && p->iColumn==iColumn && (!p->affChange || allowAffChng) ){ -#if 0 - sqlite3VdbeAddOp0(v, OP_Noop); - VdbeComment((v, "OPT: tab%d.col%d -> r%d", iTable, iColumn, p->iReg)); -#endif p->lru = pParse->iCacheCnt++; sqlite3ExprCachePinRegister(pParse, p->iReg); return p->iReg; @@ -1923,9 +1921,7 @@ int sqlite3ExprCodeGetColumn( assert( v!=0 ); if( iColumn<0 ){ sqlite3VdbeAddOp2(v, OP_Rowid, iTable, iReg); - }else if( pTab==0 ){ - sqlite3VdbeAddOp3(v, OP_Column, iTable, iColumn, iReg); - }else{ + }else if( ALWAYS(pTab!=0) ){ int op = IsVirtual(pTab) ? OP_VColumn : OP_Column; sqlite3VdbeAddOp3(v, op, iTable, iColumn, iReg); sqlite3ColumnDefault(v, pTab, iColumn); @@ -1977,7 +1973,7 @@ void sqlite3ExprCacheAffinityChange(Parse *pParse, int iStart, int iCount){ void sqlite3ExprCodeMove(Parse *pParse, int iFrom, int iTo, int nReg){ int i; struct yColCache *p; - if( iFrom==iTo ) return; + if( NEVER(iFrom==iTo) ) return; sqlite3VdbeAddOp3(pParse->pVdbe, OP_Move, iFrom, iTo, nReg); for(i=0, p=pParse->aColCache; iiReg; @@ -1993,7 +1989,7 @@ void sqlite3ExprCodeMove(Parse *pParse, int iFrom, int iTo, int nReg){ */ void sqlite3ExprCodeCopy(Parse *pParse, int iFrom, int iTo, int nReg){ int i; - if( iFrom==iTo ) return; + if( NEVER(iFrom==iTo) ) return; for(i=0; ipVdbe, OP_Copy, iFrom+i, iTo+i); } @@ -2019,15 +2015,15 @@ static int usedAsColumnCache(Parse *pParse, int iFrom, int iTo){ ** convert the last instruction from OP_SCopy to OP_Copy. */ void sqlite3ExprHardCopy(Parse *pParse, int iReg, int nReg){ - int addr; VdbeOp *pOp; Vdbe *v; + assert( pParse->db->mallocFailed==0 ); v = pParse->pVdbe; - addr = sqlite3VdbeCurrentAddr(v); - pOp = sqlite3VdbeGetOp(v, addr-1); - assert( pOp || pParse->db->mallocFailed ); - if( pOp && pOp->opcode==OP_SCopy && pOp->p1>=iReg && pOp->p1opcode==OP_SCopy && pOp->p1>=iReg && pOp->p1opcode = OP_Copy; } } @@ -2098,12 +2094,13 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){ int regFree1 = 0; /* If non-zero free this temporary register */ int regFree2 = 0; /* If non-zero free this temporary register */ int r1, r2, r3, r4; /* Various register numbers */ - sqlite3 *db; + sqlite3 *db = pParse->db; /* The database connection */ - db = pParse->db; - assert( v!=0 || db->mallocFailed ); assert( target>0 && target<=pParse->nMem ); - if( v==0 ) return 0; + if( v==0 ){ + assert( pParse->db->mallocFailed ); + return 0; + } if( pExpr==0 ){ op = TK_NULL; @@ -2173,14 +2170,12 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){ } #endif case TK_VARIABLE: { - int iPrior; VdbeOp *pOp; assert( !ExprHasProperty(pExpr, EP_IntValue) ); assert( pExpr->u.zToken!=0 ); assert( pExpr->u.zToken[0]!=0 ); if( pExpr->u.zToken[1]==0 - && (iPrior = sqlite3VdbeCurrentAddr(v)-1)>=0 - && (pOp = sqlite3VdbeGetOp(v, iPrior))->opcode==OP_Variable + && (pOp = sqlite3VdbeGetOp(v, -1))->opcode==OP_Variable && pOp->p1+pOp->p3==pExpr->iTable && pOp->p2+pOp->p3==target && pOp->p4.z==0 @@ -2888,7 +2883,7 @@ int sqlite3ExprCodeExprList( }else{ sqlite3ExprCode(pParse, pItem->pExpr, target+i); } - if( doHardCopy ){ + if( doHardCopy && !pParse->db->mallocFailed ){ sqlite3ExprHardCopy(pParse, target, n); } } diff --git a/src/insert.c b/src/insert.c index 89c5df6b4d..27549f0018 100644 --- a/src/insert.c +++ b/src/insert.c @@ -12,7 +12,7 @@ ** This file contains C code routines that are called by the parser ** to handle INSERT statements in SQLite. ** -** $Id: insert.c,v 1.267 2009/05/04 11:42:30 danielk1977 Exp $ +** $Id: insert.c,v 1.268 2009/05/29 19:00:13 drh Exp $ */ #include "sqliteInt.h" @@ -862,7 +862,7 @@ void sqlite3Insert( }else{ VdbeOp *pOp; sqlite3ExprCode(pParse, pList->a[keyColumn].pExpr, regRowid); - pOp = sqlite3VdbeGetOp(v, sqlite3VdbeCurrentAddr(v) - 1); + pOp = sqlite3VdbeGetOp(v, -1); if( ALWAYS(pOp) && pOp->opcode==OP_Null && !IsVirtual(pTab) ){ appendFlag = 1; pOp->opcode = OP_NewRowid; diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 8d696e57cb..711de8b5f9 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -14,7 +14,7 @@ ** to version 2.8.7, all this code was combined into the vdbe.c source file. ** But that file was getting too big so this subroutines were split out. ** -** $Id: vdbeaux.c,v 1.457 2009/05/06 18:57:10 shane Exp $ +** $Id: vdbeaux.c,v 1.458 2009/05/29 19:00:13 drh Exp $ */ #include "sqliteInt.h" #include "vdbeInt.h" @@ -618,12 +618,25 @@ void sqlite3VdbeNoopComment(Vdbe *p, const char *zFormat, ...){ #endif /* NDEBUG */ /* -** Return the opcode for a given address. +** Return the opcode for a given address. If the address is -1, then +** return the most recently inserted opcode. +** +** If a memory allocation error has occurred prior to the calling of this +** routine, then a pointer to a dummy VdbeOp will be returned. That opcode +** is readable and writable, but it has no effect. The return of a dummy +** opcode allows the call to continue functioning after a OOM fault without +** having to check to see if the return from this routine is a valid pointer. */ VdbeOp *sqlite3VdbeGetOp(Vdbe *p, int addr){ + static VdbeOp dummy; assert( p->magic==VDBE_MAGIC_INIT ); + if( addr<0 ) addr = p->nOp - 1; assert( (addr>=0 && addrnOp) || p->db->mallocFailed ); - return ((addr>=0 && addrnOp)?(&p->aOp[addr]):0); + if( p->db->mallocFailed ){ + return &dummy; + }else{ + return &p->aOp[addr]; + } } #if !defined(SQLITE_OMIT_EXPLAIN) || !defined(NDEBUG) \