/ Check-in [4d46685f]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Prevent an == constraint specified using the table-valued-function argument syntax from being used to optimize any scan not related to the virtual table for which it was specified as an argument.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 4d46685f282409f7154be288719cbea4b743d7ea5315a55a91462003497469f7
User & Date: dan 2018-10-26 15:36:53
Context
2018-10-26
17:05
Add the sqlite3session_config() interface. For configuring global parameters belonging to the sessions module. check-in: 1e69f3ff user: dan tags: trunk
15:36
Prevent an == constraint specified using the table-valued-function argument syntax from being used to optimize any scan not related to the virtual table for which it was specified as an argument. check-in: 4d46685f user: dan tags: trunk
2018-10-25
14:15
In the WHERE-constraint propagation optimization, if there are duplicate constraint, make sure only one of them propagates. Proposed fix for ticket [cf5ed20fc8621b165]. check-in: 5d5b596f user: drh tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/whereexpr.c.

1569
1570
1571
1572
1573
1574
1575

1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588

1589
1590
1591
  Expr *pTerm;
  if( pItem->fg.isTabFunc==0 ) return;
  pTab = pItem->pTab;
  assert( pTab!=0 );
  pArgs = pItem->u1.pFuncArg;
  if( pArgs==0 ) return;
  for(j=k=0; j<pArgs->nExpr; j++){

    while( k<pTab->nCol && (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;
    }
    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));

    whereClauseInsert(pWC, pTerm, TERM_DYNAMIC);
  }
}







>











|
|
>



1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
  Expr *pTerm;
  if( pItem->fg.isTabFunc==0 ) return;
  pTab = pItem->pTab;
  assert( pTab!=0 );
  pArgs = pItem->u1.pFuncArg;
  if( pArgs==0 ) return;
  for(j=k=0; j<pArgs->nExpr; j++){
    Expr *pRhs;
    while( k<pTab->nCol && (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;
    }
    pColRef = sqlite3ExprAlloc(pParse->db, TK_COLUMN, 0, 0);
    if( pColRef==0 ) return;
    pColRef->iTable = pItem->iCursor;
    pColRef->iColumn = k++;
    pColRef->y.pTab = pTab;
    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);
  }
}

Changes to test/bestindex4.test.

112
113
114
115
116
117
118
119





















































120
            set {} {}
        } {}
      }
    }

  }
}






















































finish_test








>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
            set {} {}
        } {}
      }
    }

  }
}

#-------------------------------------------------------------------------
# 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