Index: src/whereexpr.c ================================================================== --- src/whereexpr.c +++ src/whereexpr.c @@ -1571,10 +1571,11 @@ pTab = pItem->pTab; assert( pTab!=0 ); pArgs = pItem->u1.pFuncArg; if( pArgs==0 ) return; for(j=k=0; jnExpr; j++){ + Expr *pRhs; while( knCol && (pTab->aCol[k].colFlags & COLFLAG_HIDDEN)==0 ){k++;} if( k>=pTab->nCol ){ sqlite3ErrorMsg(pParse, "too many arguments on %s() - max %d", pTab->zName, j); return; @@ -1582,10 +1583,11 @@ pColRef = sqlite3ExprAlloc(pParse->db, TK_COLUMN, 0, 0); if( pColRef==0 ) return; pColRef->iTable = pItem->iCursor; pColRef->iColumn = k++; pColRef->y.pTab = pTab; - pTerm = sqlite3PExpr(pParse, TK_EQ, pColRef, - sqlite3ExprDup(pParse->db, pArgs->a[j].pExpr, 0)); + pRhs = sqlite3PExpr(pParse, TK_UPLUS, + sqlite3ExprDup(pParse->db, pArgs->a[j].pExpr, 0), 0); + pTerm = sqlite3PExpr(pParse, TK_EQ, pColRef, pRhs); whereClauseInsert(pWC, pTerm, TERM_DYNAMIC); } } Index: test/bestindex4.test ================================================================== --- test/bestindex4.test +++ test/bestindex4.test @@ -114,7 +114,60 @@ } } } } + +#------------------------------------------------------------------------- +# Test that a parameter passed to a table-valued function cannot be +# used to drive an index. i.e. that in the following: +# +# SELECT * FROM tbl, vtab(tbl.x); +# +# The implicit constraint "tbl.x = vtab.hidden" is not optimized using +# an index on tbl.x. +# +reset_db +register_tcl_module db +proc vtab_command {method args} { + switch -- $method { + xConnect { + return "CREATE TABLE t1(a, b, c, d HIDDEN)" + } + + xBestIndex { + set clist [lindex $args 0] + if {[llength $clist]!=1} { error "unexpected constraint list" } + catch { array unset C } + array set C [lindex $clist 0] + if {$C(usable)} { + return [list omit 0 idxnum 555 rows 10 cost 100] + } + return [list cost 100000000] + } + + } + + return {} +} + +do_execsql_test 2.0 { + CREATE VIRTUAL TABLE x1 USING tcl(vtab_command); + CREATE TABLE t1 (x INT PRIMARY KEY); +} {} + +do_execsql_test 2.1 { + EXPLAIN QUERY PLAN SELECT * FROM t1, x1 WHERE x1.d=t1.x; +} { + 3 0 0 {SCAN TABLE x1 VIRTUAL TABLE INDEX 0:} + 7 0 0 {SEARCH TABLE t1 USING COVERING INDEX sqlite_autoindex_t1_1 (x=?)} +} + +do_execsql_test 2.2 { + EXPLAIN QUERY PLAN SELECT * FROM t1, x1(t1.x) +} { + 3 0 0 {SCAN TABLE t1} + 5 0 0 {SCAN TABLE x1 VIRTUAL TABLE INDEX 555:} +} + finish_test