1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-08-08 14:02:16 +03:00

Make no assumptions about the initial state of VDBE registers.

FossilOrigin-Name: 521d72bdf67b4b1972331307345a18c231a6e1d6
This commit is contained in:
drh
2011-12-09 16:21:19 +00:00
parent 1d8cb21fdb
commit b8475df809
8 changed files with 79 additions and 37 deletions

View File

@@ -1,5 +1,5 @@
C Modify\sthe\sOP_Once\sopcode\sso\sthat\sit\sworks\scorrectly\sin\strigger\ssub-programs.\sThis\sis\sa\scandidate\sfix\sfor\s[7bbfb7d442]. C Make\sno\sassumptions\sabout\sthe\sinitial\sstate\sof\sVDBE\sregisters.
D 2011-12-09T13:24:16.480 D 2011-12-09T16:21:19.224
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -134,7 +134,7 @@ F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac
F src/ctime.c a9c26822515f81ec21588cbb482ca6724be02e33 F src/ctime.c a9c26822515f81ec21588cbb482ca6724be02e33
F src/date.c 067a81c9942c497aafd2c260e13add8a7d0c7dd4 F src/date.c 067a81c9942c497aafd2c260e13add8a7d0c7dd4
F src/delete.c 51d32f0a9c880663e54ce309f52e40c325d5e112 F src/delete.c 51d32f0a9c880663e54ce309f52e40c325d5e112
F src/expr.c 672c6e5fa3ad2eae9ff2588eac2317d76fcdfaef F src/expr.c b5920f108d6955b262f8db8e38f40f59b2bfcd7d
F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
F src/fkey.c 657212460bf5cfd3ae607d12ea62092844c227b5 F src/fkey.c 657212460bf5cfd3ae607d12ea62092844c227b5
F src/func.c 6261ce00aad9c63cd5b4219249b05683979060e9 F src/func.c 6261ce00aad9c63cd5b4219249b05683979060e9
@@ -142,7 +142,7 @@ F src/global.c 107ccaacb4b30895cf3a3a39decf417c804acfa1
F src/hash.c 458488dcc159c301b8e7686280ab209f1fb915af F src/hash.c 458488dcc159c301b8e7686280ab209f1fb915af
F src/hash.h 2894c932d84d9f892d4b4023a75e501f83050970 F src/hash.h 2894c932d84d9f892d4b4023a75e501f83050970
F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08 F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08
F src/insert.c 8f283d6734dd837ed7531b26d7622fda70874390 F src/insert.c 2d0162f70c45ccd0beb390661b63a85f303fc7e4
F src/journal.c 552839e54d1bf76fb8f7abe51868b66acacf6a0e F src/journal.c 552839e54d1bf76fb8f7abe51868b66acacf6a0e
F src/legacy.c a199d7683d60cef73089e892409113e69c23a99f F src/legacy.c a199d7683d60cef73089e892409113e69c23a99f
F src/lempar.c 0ee69fca0be54cd93939df98d2aca4ca46f44416 F src/lempar.c 0ee69fca0be54cd93939df98d2aca4ca46f44416
@@ -180,7 +180,7 @@ F src/printf.c 03104cbff6959ff45df69dc9060ba6212f60a869
F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50 F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50
F src/resolve.c 365ab1c870e38596d6869e76fb544fe6e4ffc809 F src/resolve.c 365ab1c870e38596d6869e76fb544fe6e4ffc809
F src/rowset.c 69afa95a97c524ba6faf3805e717b5b7ae85a697 F src/rowset.c 69afa95a97c524ba6faf3805e717b5b7ae85a697
F src/select.c e16b188449a7841e9e801a3c45c973c24e345199 F src/select.c d1895ff59f2051ad55e9075bf093fd28bcd36a89
F src/shell.c 29812a900a780eb0f835c4bc65e216272689def8 F src/shell.c 29812a900a780eb0f835c4bc65e216272689def8
F src/sqlite.h.in 57081d8e6b53ce29541d7437c93bce6087ac53b5 F src/sqlite.h.in 57081d8e6b53ce29541d7437c93bce6087ac53b5
F src/sqlite3ext.h 6904f4aadf976f95241311fbffb00823075d9477 F src/sqlite3ext.h 6904f4aadf976f95241311fbffb00823075d9477
@@ -235,15 +235,15 @@ F src/test_wholenumber.c 6129adfbe7c7444f2e60cc785927f3aa74e12290
F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9
F src/tokenize.c c819d9f72168a035d545a5bdafe9b085b20df705 F src/tokenize.c c819d9f72168a035d545a5bdafe9b085b20df705
F src/trigger.c ee7e178fb9188f44b532cebd449a7c1df90fb684 F src/trigger.c ee7e178fb9188f44b532cebd449a7c1df90fb684
F src/update.c 25e046a8f69d5e557aabde2000487b8545509d8d F src/update.c d3076782c887c10e882996550345da9c4c9f9dea
F src/utf.c 890c67dcfcc7a74623c95baac7535aadfe265e84 F src/utf.c 890c67dcfcc7a74623c95baac7535aadfe265e84
F src/util.c 01238e2b0f24a14779181dbf991fe02620a80e31 F src/util.c 01238e2b0f24a14779181dbf991fe02620a80e31
F src/vacuum.c 0c0ba2242355c6048d65e2b333abe0f7c06348fa F src/vacuum.c 0c0ba2242355c6048d65e2b333abe0f7c06348fa
F src/vdbe.c f49816f99b853c6cbdec950eedd4434cb2452376 F src/vdbe.c 9fc8110b1f2c5285e53948ac59ab4d0e75f18d28
F src/vdbe.h 18f581cac1f4339ec3299f3e0cc6e11aec654cdb F src/vdbe.h 18f581cac1f4339ec3299f3e0cc6e11aec654cdb
F src/vdbeInt.h 23a9506c9ab31e7823d7257d1828d2d7843443a0 F src/vdbeInt.h 23a9506c9ab31e7823d7257d1828d2d7843443a0
F src/vdbeapi.c 86189ebba2c49791d75eaa12929f3ce6527596bd F src/vdbeapi.c 86189ebba2c49791d75eaa12929f3ce6527596bd
F src/vdbeaux.c cdd74a86c6281b4393c5f94d8f5e40e160e44e19 F src/vdbeaux.c d9d406ae5963a4b0424f2f56415e3d4d330667b6
F src/vdbeblob.c 32f2a4899d67f69634ea4dd93e3f651936d732cb F src/vdbeblob.c 32f2a4899d67f69634ea4dd93e3f651936d732cb
F src/vdbemem.c 2fc78b3e0fabcc1eaa23cd79dd2e30e6dcfe1e56 F src/vdbemem.c 2fc78b3e0fabcc1eaa23cd79dd2e30e6dcfe1e56
F src/vdbesort.c 468d43c057063e54da4f1988b38b4f46d60e7790 F src/vdbesort.c 468d43c057063e54da4f1988b38b4f46d60e7790
@@ -978,7 +978,10 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06
F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a
F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381
P 3702a31e56fe02d14ce246109b318a124cad9f1a P 557c69055a300b4082830b5f4803091dca1c3140
R 212172c6a4e482305cc0a6c8ccb724d1 R 3fc70f66913132be9fb89d0f0027fcb9
U dan T *branch * uninit-vdbe-mem
Z fd67074fb89c049640d6ea2f96341088 T *sym-uninit-vdbe-mem *
T -sym-trunk *
U drh
Z 6b717a43993e129981a6c5acd19a7014

View File

@@ -1 +1 @@
557c69055a300b4082830b5f4803091dca1c3140 521d72bdf67b4b1972331307345a18c231a6e1d6

View File

@@ -1444,6 +1444,7 @@ int sqlite3FindInIndex(Parse *pParse, Expr *pX, int *prNotFound){
int eType = 0; /* Type of RHS table. IN_INDEX_* */ int eType = 0; /* Type of RHS table. IN_INDEX_* */
int iTab = pParse->nTab++; /* Cursor of the RHS table */ int iTab = pParse->nTab++; /* Cursor of the RHS table */
int mustBeUnique = (prNotFound==0); /* True if RHS must be unique */ int mustBeUnique = (prNotFound==0); /* True if RHS must be unique */
Vdbe *v = sqlite3GetVdbe(pParse); /* Virtual machine being coded */
assert( pX->op==TK_IN ); assert( pX->op==TK_IN );
@@ -1454,7 +1455,6 @@ int sqlite3FindInIndex(Parse *pParse, Expr *pX, int *prNotFound){
p = (ExprHasProperty(pX, EP_xIsSelect) ? pX->x.pSelect : 0); p = (ExprHasProperty(pX, EP_xIsSelect) ? pX->x.pSelect : 0);
if( ALWAYS(pParse->nErr==0) && isCandidateForInOpt(p) ){ if( ALWAYS(pParse->nErr==0) && isCandidateForInOpt(p) ){
sqlite3 *db = pParse->db; /* Database connection */ sqlite3 *db = pParse->db; /* Database connection */
Vdbe *v = sqlite3GetVdbe(pParse); /* Virtual machine being coded */
Table *pTab; /* Table <table>. */ Table *pTab; /* Table <table>. */
Expr *pExpr; /* Expression <column> */ Expr *pExpr; /* Expression <column> */
int iCol; /* Index of column <column> */ int iCol; /* Index of column <column> */
@@ -1521,6 +1521,7 @@ int sqlite3FindInIndex(Parse *pParse, Expr *pX, int *prNotFound){
sqlite3VdbeJumpHere(v, iAddr); sqlite3VdbeJumpHere(v, iAddr);
if( prNotFound && !pTab->aCol[iCol].notNull ){ if( prNotFound && !pTab->aCol[iCol].notNull ){
*prNotFound = ++pParse->nMem; *prNotFound = ++pParse->nMem;
sqlite3VdbeAddOp2(v, OP_Null, 0, *prNotFound);
} }
} }
} }
@@ -1536,6 +1537,7 @@ int sqlite3FindInIndex(Parse *pParse, Expr *pX, int *prNotFound){
eType = IN_INDEX_EPH; eType = IN_INDEX_EPH;
if( prNotFound ){ if( prNotFound ){
*prNotFound = rMayHaveNull = ++pParse->nMem; *prNotFound = rMayHaveNull = ++pParse->nMem;
sqlite3VdbeAddOp2(v, OP_Null, 0, *prNotFound);
}else{ }else{
testcase( pParse->nQueryLoop>(double)1 ); testcase( pParse->nQueryLoop>(double)1 );
pParse->nQueryLoop = (double)1; pParse->nQueryLoop = (double)1;

View File

@@ -240,6 +240,7 @@ void sqlite3AutoincrementBegin(Parse *pParse){
assert( sqlite3SchemaMutexHeld(db, 0, pDb->pSchema) ); assert( sqlite3SchemaMutexHeld(db, 0, pDb->pSchema) );
sqlite3OpenTable(pParse, 0, p->iDb, pDb->pSchema->pSeqTab, OP_OpenRead); sqlite3OpenTable(pParse, 0, p->iDb, pDb->pSchema->pSeqTab, OP_OpenRead);
addr = sqlite3VdbeCurrentAddr(v); addr = sqlite3VdbeCurrentAddr(v);
sqlite3VdbeAddOp2(v, OP_Null, 0, memId+1);
sqlite3VdbeAddOp4(v, OP_String8, 0, memId-1, 0, p->pTab->zName, 0); sqlite3VdbeAddOp4(v, OP_String8, 0, memId-1, 0, p->pTab->zName, 0);
sqlite3VdbeAddOp2(v, OP_Rewind, 0, addr+9); sqlite3VdbeAddOp2(v, OP_Rewind, 0, addr+9);
sqlite3VdbeAddOp3(v, OP_Column, 0, 0, memId); sqlite3VdbeAddOp3(v, OP_Column, 0, 0, memId);

View File

@@ -1947,13 +1947,12 @@ static int generateOutputSubroutine(
*/ */
if( regPrev ){ if( regPrev ){
int j1, j2; int j1, j2;
j1 = sqlite3VdbeAddOp1(v, OP_IfNot, regPrev); j1 = sqlite3VdbeAddOp1(v, OP_JumpOnce, pParse->nOnce++);
j2 = sqlite3VdbeAddOp4(v, OP_Compare, pIn->iMem, regPrev+1, pIn->nMem, j2 = sqlite3VdbeAddOp4(v, OP_Compare, pIn->iMem, regPrev+1, pIn->nMem,
(char*)pKeyInfo, p4type); (char*)pKeyInfo, p4type);
sqlite3VdbeAddOp3(v, OP_Jump, j2+2, iContinue, j2+2); sqlite3VdbeAddOp3(v, OP_Jump, j2+2, iContinue, j2+2);
sqlite3VdbeJumpHere(v, j1); sqlite3VdbeJumpHere(v, j1);
sqlite3ExprCodeCopy(pParse, pIn->iMem, regPrev+1, pIn->nMem); sqlite3ExprCodeCopy(pParse, pIn->iMem, regPrev+1, pIn->nMem);
sqlite3VdbeAddOp2(v, OP_Integer, 1, regPrev);
} }
if( pParse->db->mallocFailed ) return 0; if( pParse->db->mallocFailed ) return 0;
@@ -4154,6 +4153,7 @@ int sqlite3Select(
VdbeComment((v, "clear abort flag")); VdbeComment((v, "clear abort flag"));
sqlite3VdbeAddOp2(v, OP_Integer, 0, iUseFlag); sqlite3VdbeAddOp2(v, OP_Integer, 0, iUseFlag);
VdbeComment((v, "indicate accumulator empty")); VdbeComment((v, "indicate accumulator empty"));
sqlite3VdbeAddOp3(v, OP_Null, 0, iAMem, iAMem+pGroupBy->nExpr-1);
/* Begin a loop that will extract all source rows in GROUP BY order. /* Begin a loop that will extract all source rows in GROUP BY order.
** This might involve two separate loops with an OP_Sort in between, or ** This might involve two separate loops with an OP_Sort in between, or

View File

@@ -126,8 +126,8 @@ void sqlite3Update(
int regRowCount = 0; /* A count of rows changed */ int regRowCount = 0; /* A count of rows changed */
int regOldRowid; /* The old rowid */ int regOldRowid; /* The old rowid */
int regNewRowid; /* The new rowid */ int regNewRowid; /* The new rowid */
int regNew; int regNew; /* Content of the NEW.* table in triggers */
int regOld = 0; int regOld = 0; /* Content of OLD.* table in triggers */
int regRowSet = 0; /* Rowset of rows to be updated */ int regRowSet = 0; /* Rowset of rows to be updated */
memset(&sContext, 0, sizeof(sContext)); memset(&sContext, 0, sizeof(sContext));
@@ -276,6 +276,7 @@ void sqlite3Update(
#endif #endif
/* Allocate required registers. */ /* Allocate required registers. */
regRowSet = ++pParse->nMem;
regOldRowid = regNewRowid = ++pParse->nMem; regOldRowid = regNewRowid = ++pParse->nMem;
if( pTrigger || hasFK ){ if( pTrigger || hasFK ){
regOld = pParse->nMem + 1; regOld = pParse->nMem + 1;
@@ -310,7 +311,7 @@ void sqlite3Update(
/* Begin the database scan /* Begin the database scan
*/ */
sqlite3VdbeAddOp2(v, OP_Null, 0, regOldRowid); sqlite3VdbeAddOp3(v, OP_Null, 0, regRowSet, regOldRowid);
pWInfo = sqlite3WhereBegin( pWInfo = sqlite3WhereBegin(
pParse, pTabList, pWhere, 0, 0, WHERE_ONEPASS_DESIRED pParse, pTabList, pWhere, 0, 0, WHERE_ONEPASS_DESIRED
); );
@@ -321,7 +322,6 @@ void sqlite3Update(
*/ */
sqlite3VdbeAddOp2(v, OP_Rowid, iCur, regOldRowid); sqlite3VdbeAddOp2(v, OP_Rowid, iCur, regOldRowid);
if( !okOnePass ){ if( !okOnePass ){
regRowSet = ++pParse->nMem;
sqlite3VdbeAddOp2(v, OP_RowSetAdd, regRowSet, regOldRowid); sqlite3VdbeAddOp2(v, OP_RowSetAdd, regRowSet, regOldRowid);
} }
@@ -425,9 +425,10 @@ void sqlite3Update(
newmask = sqlite3TriggerColmask( newmask = sqlite3TriggerColmask(
pParse, pTrigger, pChanges, 1, TRIGGER_BEFORE, pTab, onError pParse, pTrigger, pChanges, 1, TRIGGER_BEFORE, pTab, onError
); );
sqlite3VdbeAddOp3(v, OP_Null, 0, regNew, regNew+pTab->nCol-1);
for(i=0; i<pTab->nCol; i++){ for(i=0; i<pTab->nCol; i++){
if( i==pTab->iPKey ){ if( i==pTab->iPKey ){
sqlite3VdbeAddOp2(v, OP_Null, 0, regNew+i); /*sqlite3VdbeAddOp2(v, OP_Null, 0, regNew+i);*/
}else{ }else{
j = aXRef[i]; j = aXRef[i];
if( j>=0 ){ if( j>=0 ){

View File

@@ -764,7 +764,8 @@ case OP_Goto: { /* jump */
** Write the current address onto register P1 ** Write the current address onto register P1
** and then jump to address P2. ** and then jump to address P2.
*/ */
case OP_Gosub: { /* jump, in1 */ case OP_Gosub: { /* jump */
assert( pOp->p1>0 && pOp->p1<=p->nMem );
pIn1 = &aMem[pOp->p1]; pIn1 = &aMem[pOp->p1];
assert( (pIn1->flags & MEM_Dyn)==0 ); assert( (pIn1->flags & MEM_Dyn)==0 );
memAboutToChange(p, pIn1); memAboutToChange(p, pIn1);
@@ -961,12 +962,25 @@ case OP_String: { /* out2-prerelease */
break; break;
} }
/* Opcode: Null * P2 * * * /* Opcode: Null * P2 P3 * *
** **
** Write a NULL into register P2. ** Write a NULL into registers P2. If P3 greater than P2, then also write
** NULL into register P3 and ever register in between P2 and P3. If P3
** is less than P2 (typically P3 is zero) then only register P2 is
** set to NULL
*/ */
case OP_Null: { /* out2-prerelease */ case OP_Null: { /* out2-prerelease */
int cnt;
cnt = pOp->p3-pOp->p2;
assert( pOp->p3<=p->nMem );
pOut->flags = MEM_Null; pOut->flags = MEM_Null;
while( cnt>0 ){
pOut++;
memAboutToChange(p, pOut);
MemReleaseExt(pOut);
pOut->flags = MEM_Null;
cnt--;
}
break; break;
} }
@@ -2025,6 +2039,8 @@ case OP_BitNot: { /* same as TK_BITNOT, in1, out2 */
** **
** Check if OP_Once flag P1 is set. If so, jump to instruction P2. Otherwise, ** Check if OP_Once flag P1 is set. If so, jump to instruction P2. Otherwise,
** set the flag and fall through to the next instruction. ** set the flag and fall through to the next instruction.
**
** See also: JumpOnce
*/ */
case OP_Once: { /* jump */ case OP_Once: { /* jump */
assert( pOp->p1<p->nOnceFlag ); assert( pOp->p1<p->nOnceFlag );
@@ -2036,17 +2052,33 @@ case OP_Once: { /* jump */
break; break;
} }
/* Opcode: JumpOnce P1 P2 * * *
**
** Check if OP_Once flag P1 is clear. If so, set the flag and
** jump to instruction P2. Otherwise fall through.
**
** See also: Once
*/
case OP_JumpOnce: { /* jump */
assert( pOp->p1<p->nOnceFlag );
if( !p->aOnceFlag[pOp->p1] ){
pc = pOp->p2-1;
p->aOnceFlag[pOp->p1] = 1;
}
break;
}
/* Opcode: If P1 P2 P3 * * /* Opcode: If P1 P2 P3 * *
** **
** Jump to P2 if the value in register P1 is true. The value ** Jump to P2 if the value in register P1 is true. The value
** is considered true if it is numeric and non-zero. If the value ** is considered true if it is numeric and non-zero. If the value
** in P1 is NULL then take the jump if P3 is true. ** in P1 is NULL then take the jump if P3 is non-zero.
*/ */
/* Opcode: IfNot P1 P2 P3 * * /* Opcode: IfNot P1 P2 P3 * *
** **
** Jump to P2 if the value in register P1 is False. The value ** Jump to P2 if the value in register P1 is False. The value
** is considered true if it has a numeric value of zero. If the value ** is considered false if it has a numeric value of zero. If the value
** in P1 is NULL then take the jump if P3 is true. ** in P1 is NULL then take the jump if P3 is zero.
*/ */
case OP_If: /* jump, in1 */ case OP_If: /* jump, in1 */
case OP_IfNot: { /* jump, in1 */ case OP_IfNot: { /* jump, in1 */
@@ -5069,7 +5101,7 @@ case OP_Program: { /* jump */
pProgram = pOp->p4.pProgram; pProgram = pOp->p4.pProgram;
pRt = &aMem[pOp->p3]; pRt = &aMem[pOp->p3];
assert( memIsValid(pRt) ); /*assert( memIsValid(pRt) );*/
assert( pProgram->nOp>0 ); assert( pProgram->nOp>0 );
/* If the p5 flag is clear, then recursive invocation of triggers is /* If the p5 flag is clear, then recursive invocation of triggers is
@@ -5246,7 +5278,7 @@ case OP_MemMax: { /* in2 */
}else{ }else{
pIn1 = &aMem[pOp->p1]; pIn1 = &aMem[pOp->p1];
} }
assert( memIsValid(pIn1) ); /*assert( memIsValid(pIn1) ); FIXME */
sqlite3VdbeMemIntegerify(pIn1); sqlite3VdbeMemIntegerify(pIn1);
pIn2 = &aMem[pOp->p2]; pIn2 = &aMem[pOp->p2];
sqlite3VdbeMemIntegerify(pIn2); sqlite3VdbeMemIntegerify(pIn2);

View File

@@ -913,13 +913,14 @@ static char *displayP4(Op *pOp, char *zTemp, int nTemp){
} }
case P4_MEM: { case P4_MEM: {
Mem *pMem = pOp->p4.pMem; Mem *pMem = pOp->p4.pMem;
assert( (pMem->flags & MEM_Null)==0 );
if( pMem->flags & MEM_Str ){ if( pMem->flags & MEM_Str ){
zP4 = pMem->z; zP4 = pMem->z;
}else if( pMem->flags & MEM_Int ){ }else if( pMem->flags & MEM_Int ){
sqlite3_snprintf(nTemp, zTemp, "%lld", pMem->u.i); sqlite3_snprintf(nTemp, zTemp, "%lld", pMem->u.i);
}else if( pMem->flags & MEM_Real ){ }else if( pMem->flags & MEM_Real ){
sqlite3_snprintf(nTemp, zTemp, "%.16g", pMem->r); sqlite3_snprintf(nTemp, zTemp, "%.16g", pMem->r);
}else if( pMem->flags & MEM_Null ){
sqlite3_snprintf(nTemp, zTemp, "NULL");
}else{ }else{
assert( pMem->flags & MEM_Blob ); assert( pMem->flags & MEM_Blob );
zP4 = "(blob)"; zP4 = "(blob)";
@@ -1094,7 +1095,7 @@ static void releaseMemArray(Mem *p, int N){
p->zMalloc = 0; p->zMalloc = 0;
} }
p->flags = MEM_Null; p->flags = MEM_Invalid;
} }
db->mallocFailed = malloc_failed; db->mallocFailed = malloc_failed;
} }
@@ -1532,8 +1533,7 @@ void sqlite3VdbeMakeReady(
p->azVar = allocSpace(p->azVar, nVar*sizeof(char*), &zCsr, zEnd, &nByte); p->azVar = allocSpace(p->azVar, nVar*sizeof(char*), &zCsr, zEnd, &nByte);
p->apCsr = allocSpace(p->apCsr, nCursor*sizeof(VdbeCursor*), p->apCsr = allocSpace(p->apCsr, nCursor*sizeof(VdbeCursor*),
&zCsr, zEnd, &nByte); &zCsr, zEnd, &nByte);
p->aOnceFlag = allocSpace(p->aOnceFlag, nOnce*sizeof(u8), p->aOnceFlag = allocSpace(p->aOnceFlag, nOnce, &zCsr, zEnd, &nByte);
&zCsr, zEnd, &nByte);
if( nByte ){ if( nByte ){
p->pFree = sqlite3DbMallocZero(db, nByte); p->pFree = sqlite3DbMallocZero(db, nByte);
} }
@@ -1559,10 +1559,11 @@ void sqlite3VdbeMakeReady(
p->aMem--; /* aMem[] goes from 1..nMem */ p->aMem--; /* aMem[] goes from 1..nMem */
p->nMem = nMem; /* not from 0..nMem-1 */ p->nMem = nMem; /* not from 0..nMem-1 */
for(n=1; n<=nMem; n++){ for(n=1; n<=nMem; n++){
p->aMem[n].flags = MEM_Null; p->aMem[n].flags = MEM_Invalid;
p->aMem[n].db = db; p->aMem[n].db = db;
} }
} }
if( p->aOnceFlag ) memset(p->aOnceFlag, 0, p->nOnceFlag);
p->explain = pParse->explain; p->explain = pParse->explain;
sqlite3VdbeRewind(p); sqlite3VdbeRewind(p);
} }
@@ -1649,7 +1650,6 @@ static void closeAllCursors(Vdbe *p){
p->pDelFrame = pDel->pParent; p->pDelFrame = pDel->pParent;
sqlite3VdbeFrameDelete(pDel); sqlite3VdbeFrameDelete(pDel);
} }
memset(p->aOnceFlag, 0, p->nOnceFlag);
} }
/* /*
@@ -1666,8 +1666,10 @@ static void Cleanup(Vdbe *p){
/* Execute assert() statements to ensure that the Vdbe.apCsr[] and /* Execute assert() statements to ensure that the Vdbe.apCsr[] and
** Vdbe.aMem[] arrays have already been cleaned up. */ ** Vdbe.aMem[] arrays have already been cleaned up. */
int i; int i;
for(i=0; i<p->nCursor; i++) assert( p->apCsr==0 || p->apCsr[i]==0 ); if( p->apCsr ) for(i=0; i<p->nCursor; i++) assert( p->apCsr[i]==0 );
for(i=1; i<=p->nMem; i++) assert( p->aMem==0 || p->aMem[i].flags==MEM_Null ); if( p->aMem ){
for(i=1; i<=p->nMem; i++) assert( p->aMem[i].flags==MEM_Invalid );
}
#endif #endif
sqlite3DbFree(db, p->zErrMsg); sqlite3DbFree(db, p->zErrMsg);
@@ -2135,6 +2137,7 @@ int sqlite3VdbeHalt(Vdbe *p){
if( p->db->mallocFailed ){ if( p->db->mallocFailed ){
p->rc = SQLITE_NOMEM; p->rc = SQLITE_NOMEM;
} }
if( p->aOnceFlag ) memset(p->aOnceFlag, 0, p->nOnceFlag);
closeAllCursors(p); closeAllCursors(p);
if( p->magic!=VDBE_MAGIC_RUN ){ if( p->magic!=VDBE_MAGIC_RUN ){
return SQLITE_OK; return SQLITE_OK;