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:
27
manifest
27
manifest
@@ -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
|
||||||
|
@@ -1 +1 @@
|
|||||||
557c69055a300b4082830b5f4803091dca1c3140
|
521d72bdf67b4b1972331307345a18c231a6e1d6
|
@@ -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;
|
||||||
|
@@ -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);
|
||||||
|
@@ -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
|
||||||
|
11
src/update.c
11
src/update.c
@@ -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 ){
|
||||||
|
48
src/vdbe.c
48
src/vdbe.c
@@ -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);
|
||||||
|
@@ -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;
|
||||||
|
Reference in New Issue
Block a user