Index: src/vdbe.h ================================================================== --- src/vdbe.h +++ src/vdbe.h @@ -230,10 +230,11 @@ void sqlite3VdbeChangeP5(Vdbe*, u16 P5); void sqlite3VdbeJumpHere(Vdbe*, int addr); void sqlite3VdbeJumpHereOrPopInst(Vdbe*, int addr); int sqlite3VdbeChangeToNoop(Vdbe*, int addr); int sqlite3VdbeDeletePriorOpcode(Vdbe*, u8 op); +void sqlite3VdbeUndoBackTo(Vdbe*, int addr); #ifdef SQLITE_DEBUG void sqlite3VdbeReleaseRegisters(Parse*,int addr, int n, u32 mask, int); #else # define sqlite3VdbeReleaseRegisters(P,A,N,M,F) #endif Index: src/vdbeaux.c ================================================================== --- src/vdbeaux.c +++ src/vdbeaux.c @@ -1300,10 +1300,26 @@ return sqlite3VdbeChangeToNoop(p, p->nOp-1); }else{ return 0; } } + +/* +** Undo all opcode inserts so that addr is the last opcode. +*/ +void sqlite3VdbeUndoBackTo(Vdbe *p, int addr){ + while( p->nOp>addr ){ +#ifdef SQLITE_DEBUG + if( p->db->flags & SQLITE_VdbeAddopTrace ){ + printf("UNDO: "); + sqlite3VdbePrintOp(0, p->nOp-1, &p->aOp[p->nOp-1]); + } +#endif + sqlite3VdbeChangeToNoop(p, p->nOp-1); + p->nOp--; + } +} #ifdef SQLITE_DEBUG /* ** Generate an OP_ReleaseReg opcode to indicate that a range of ** registers, except any identified by mask, are no longer in use. Index: src/wherecode.c ================================================================== --- src/wherecode.c +++ src/wherecode.c @@ -617,18 +617,20 @@ pX = removeUnindexableInClauseTerms(pParse, iEq, pLoop, pX); if( !db->mallocFailed ){ aiMap = (int*)sqlite3DbMallocZero(pParse->db, sizeof(int)*nEq); eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, aiMap,&iTab); pExpr->iTable = iTab; - pExpr->op2 = eType; } sqlite3ExprDelete(db, pX); }else{ - sqlite3VdbeAddOp2(v, OP_Gosub, pExpr->y.sub.regReturn, - pExpr->y.sub.iAddr); + int j1; + j1 = sqlite3VdbeAddOp2(v, OP_Gosub, pExpr->y.sub.regReturn, + pExpr->y.sub.iAddr); + aiMap = (int*)sqlite3DbMallocZero(pParse->db, sizeof(int)*nEq); + eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, aiMap,&iTab); iTab = pExpr->iTable; - eType = pExpr->op2; + sqlite3VdbeUndoBackTo(v, j1+1); } pX = pExpr; } if( eType==IN_INDEX_INDEX_DESC ){ Index: test/join8.test ================================================================== --- test/join8.test +++ test/join8.test @@ -170,7 +170,14 @@ CREATE TABLE t1(a INT PRIMARY KEY, b TEXT, c TEXT, d INT) WITHOUT ROWID; INSERT INTO t1 VALUES(15,'xray','baker',42); SELECT value, t1.* FROM json_each('7') NATURAL RIGHT JOIN t1 WHERE (a,b) IN (SELECT a, b FROM t1); } {7 15 xray baker 42} +do_execsql_test join8-6020 { + DROP TABLE IF EXISTS t1; + CREATE TABLE t1(a INTEGER PRIMARY KEY,b); + INSERT INTO t1 VALUES(0,NULL),(1,2); + SELECT value, t1.* FROM json_each('17') NATURAL RIGHT JOIN t1 + WHERE (a,b) IN (SELECT rowid, b FROM t1); +} {17 1 2} finish_test