Index: src/expr.c ================================================================== --- src/expr.c +++ src/expr.c @@ -2241,10 +2241,19 @@ } default: break; } return rc; } + +/* +** Return true if p is a Column node that references a virtual table. +*/ +int sqlite3ExprIsVtabRef(Expr *p){ + if( p->op!=TK_COLUMN ) return 0; + if( p->y.pTab==0 ) return 0; + return IsVirtual(p->y.pTab); +} /* ** Return FALSE if there is no chance that the expression can be NULL. ** ** If the expression might be NULL or if the expression is too complex @@ -5477,12 +5486,12 @@ testcase( pExpr->op==TK_NE ); testcase( pExpr->op==TK_LT ); testcase( pExpr->op==TK_LE ); testcase( pExpr->op==TK_GT ); testcase( pExpr->op==TK_GE ); - if( (pExpr->pLeft->op==TK_COLUMN && IsVirtual(pExpr->pLeft->y.pTab)) - || (pExpr->pRight->op==TK_COLUMN && IsVirtual(pExpr->pRight->y.pTab)) + if( sqlite3ExprIsVtabRef(pExpr->pLeft) + || sqlite3ExprIsVtabRef(pExpr->pRight) ){ return WRC_Prune; } default: Index: src/sqliteInt.h ================================================================== --- src/sqliteInt.h +++ src/sqliteInt.h @@ -4276,10 +4276,11 @@ int sqlite3ExprIsTableConstant(Expr*,int); #ifdef SQLITE_ENABLE_CURSOR_HINTS int sqlite3ExprContainsSubquery(Expr*); #endif int sqlite3ExprIsInteger(Expr*, int*); +int sqlite3ExprIsVtabRef(Expr*); int sqlite3ExprCanBeNull(const Expr*); int sqlite3ExprNeedsNoAffinityChange(const Expr*, char); int sqlite3IsRowid(const char*); void sqlite3GenerateRowDelete( Parse*,Table*,Trigger*,int,int,int,i16,u8,u8,u8,int); Index: src/whereexpr.c ================================================================== --- src/whereexpr.c +++ src/whereexpr.c @@ -375,11 +375,11 @@ ** ** vtab_column MATCH expression ** MATCH(expression,vtab_column) */ pCol = pList->a[1].pExpr; - if( pCol->op==TK_COLUMN && IsVirtual(pCol->y.pTab) ){ + if( sqlite3ExprIsVtabRef(pCol) ){ for(i=0; iu.zToken, aOp[i].zOp)==0 ){ *peOp2 = aOp[i].eOp2; *ppRight = pList->a[0].pExpr; *ppLeft = pCol; @@ -397,11 +397,11 @@ ** Historically, xFindFunction expected to see lower-case function ** names. But for this use case, xFindFunction is expected to deal ** with function names in an arbitrary case. */ pCol = pList->a[0].pExpr; - if( pCol->op==TK_COLUMN && IsVirtual(pCol->y.pTab) ){ + if( sqlite3ExprIsVtabRef(pCol) ){ sqlite3_vtab *pVtab; sqlite3_module *pMod; void (*xNotUsed)(sqlite3_context*,int,sqlite3_value**); void *pNotUsed; pVtab = sqlite3GetVTable(db, pCol->y.pTab)->pVtab; @@ -420,14 +420,14 @@ } }else if( pExpr->op==TK_NE || pExpr->op==TK_ISNOT || pExpr->op==TK_NOTNULL ){ int res = 0; Expr *pLeft = pExpr->pLeft; Expr *pRight = pExpr->pRight; - if( pLeft->op==TK_COLUMN && IsVirtual(pLeft->y.pTab) ){ + if( sqlite3ExprIsVtabRef(pLeft) ){ res++; } - if( pRight && pRight->op==TK_COLUMN && IsVirtual(pRight->y.pTab) ){ + if( pRight && sqlite3ExprIsVtabRef(pRight) ){ res++; SWAP(Expr*, pLeft, pRight); } *ppLeft = pLeft; *ppRight = pRight;