Index: src/expr.c ================================================================== --- src/expr.c +++ src/expr.c @@ -2514,10 +2514,13 @@ if( pX->pLeft->iColumn<0 && !ExprHasProperty(pX, EP_xIsSelect) ){ eType = IN_INDEX_ROWID; } }else if( prRhsHasNull ){ *prRhsHasNull = rMayHaveNull = ++pParse->nMem; + } + if( ExprHasProperty(pX, EP_xIsSelect) ){ + pX->x.pSelect->selFlags |= SF_RhsOfIN; } sqlite3CodeSubselect(pParse, pX, rMayHaveNull, eType==IN_INDEX_ROWID); pParse->nQueryLoop = savedNQueryLoop; }else{ pX->iTable = iTab; Index: src/select.c ================================================================== --- src/select.c +++ src/select.c @@ -5877,18 +5877,19 @@ /* Generate code to implement the subquery ** ** The subquery is implemented as a co-routine if the subquery is ** guaranteed to be the outer loop (so that it does not need to be - ** computed more than once) + ** computed more than once). (1) ** - ** TODO: Are there other reasons beside (1) to use a co-routine - ** implementation? + ** Avoid using a co-routines to compute any SELECT that occurs in + ** the RHS of an IN operator, as they can be used multiple times. (2) */ if( i==0 && (pTabList->nSrc==1 || (pTabList->a[1].fg.jointype&(JT_LEFT|JT_CROSS))!=0) /* (1) */ + && (p->selFlags & SF_RhsOfIN)==0 /* (2) */ ){ /* Implement a co-routine that will return a single row of the result ** set on each invocation. */ int addrTop = sqlite3VdbeCurrentAddr(v)+1; Index: src/sqliteInt.h ================================================================== --- src/sqliteInt.h +++ src/sqliteInt.h @@ -2862,10 +2862,11 @@ #define SF_FixedLimit 0x04000 /* nSelectRow set by a constant LIMIT */ #define SF_MaybeConvert 0x08000 /* Need convertCompoundSelectToSubquery() */ #define SF_Converted 0x10000 /* By convertCompoundSelectToSubquery() */ #define SF_IncludeHidden 0x20000 /* Include hidden columns in output */ #define SF_ComplexResult 0x40000 /* Result contains subquery or function */ +#define SF_RhsOfIN 0x80000 /* Result uses as the RHS of IN operator */ /* ** The results of a SELECT can be distributed in several ways, as defined ** by one of the following macros. The "SRT" prefix means "SELECT Result ** Type".