/ Check-in [ebcfa73e]
Login
SQLite training in Houston TX on 2019-11-05 (details)
Part of the 2019 Tcl Conference

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

Overview
Comment:Make sure sqlite3VdbeSetVarmask() is never invoked when QPSG is enabled.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | enable-QPSG
Files: files | file ages | folders
SHA3-256: ebcfa73e1c8ebb4fc371a6dcf77f97b6e06e405a299c66182aa4b20423d519ec
User & Date: drh 2017-06-26 14:46:05
Context
2017-06-27
23:36
Add SQLITE_DBCONFIG_ENABLE_QPSG that forces the query planner stability guarantee. This is the fix for ticket [b9f010107724c] check-in: b82efd2a user: drh tags: trunk
2017-06-26
14:46
Make sure sqlite3VdbeSetVarmask() is never invoked when QPSG is enabled. Closed-Leaf check-in: ebcfa73e user: drh tags: enable-QPSG
13:57
Add the SQLITE_DBCONFIG_ENABLE_QPSG option to activate the query planner stability guarantee. This involves refactoring the sqlite3.flags bitvector to carve out a free bit to use. check-in: 7076e828 user: drh tags: enable-QPSG
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/vdbeaux.c.

  4536   4536   ** 0 instead. Unless it is NULL, apply affinity aff (one of the SQLITE_AFF_*
  4537   4537   ** constants) to the value before returning it.
  4538   4538   **
  4539   4539   ** The returned value must be freed by the caller using sqlite3ValueFree().
  4540   4540   */
  4541   4541   sqlite3_value *sqlite3VdbeGetBoundValue(Vdbe *v, int iVar, u8 aff){
  4542   4542     assert( iVar>0 );
  4543         -  if( v && (v->db->flags & SQLITE_EnableQPSG)==0 ){
         4543  +  if( v ){
  4544   4544       Mem *pMem = &v->aVar[iVar-1];
         4545  +    assert( (v->db->flags & SQLITE_EnableQPSG)==0 );
  4545   4546       if( 0==(pMem->flags & MEM_Null) ){
  4546   4547         sqlite3_value *pRet = sqlite3ValueNew(v->db);
  4547   4548         if( pRet ){
  4548   4549           sqlite3VdbeMemCopy((Mem *)pRet, pMem);
  4549   4550           sqlite3ValueApplyAffinity(pRet, aff, SQLITE_UTF8);
  4550   4551         }
  4551   4552         return pRet;
................................................................................
  4557   4558   /*
  4558   4559   ** Configure SQL variable iVar so that binding a new value to it signals
  4559   4560   ** to sqlite3_reoptimize() that re-preparing the statement may result
  4560   4561   ** in a better query plan.
  4561   4562   */
  4562   4563   void sqlite3VdbeSetVarmask(Vdbe *v, int iVar){
  4563   4564     assert( iVar>0 );
         4565  +  assert( (v->db->flags & SQLITE_EnableQPSG)==0 );
  4564   4566     if( iVar>=32 ){
  4565   4567       v->expmask |= 0x80000000;
  4566   4568     }else{
  4567   4569       v->expmask |= ((u32)1 << (iVar-1));
  4568   4570     }
  4569   4571   }
  4570   4572   

Changes to src/vdbemem.c.

  1478   1478     int rc = SQLITE_OK;
  1479   1479     sqlite3_value *pVal = 0;
  1480   1480     sqlite3 *db = pParse->db;
  1481   1481   
  1482   1482     /* Skip over any TK_COLLATE nodes */
  1483   1483     pExpr = sqlite3ExprSkipCollate(pExpr);
  1484   1484   
         1485  +  assert( pExpr==0 || pExpr->op!=TK_REGISTER || pExpr->op2!=TK_VARIABLE );
  1485   1486     if( !pExpr ){
  1486   1487       pVal = valueNew(db, pAlloc);
  1487   1488       if( pVal ){
  1488   1489         sqlite3VdbeMemSetNull((Mem*)pVal);
  1489   1490       }
  1490         -  }else if( pExpr->op==TK_VARIABLE
  1491         -        || NEVER(pExpr->op==TK_REGISTER && pExpr->op2==TK_VARIABLE)
  1492         -  ){
         1491  +  }else if( pExpr->op==TK_VARIABLE && (db->flags & SQLITE_EnableQPSG)==0 ){
  1493   1492       Vdbe *v;
  1494   1493       int iBindVar = pExpr->iColumn;
  1495   1494       sqlite3VdbeSetVarmask(pParse->pVdbe, iBindVar);
  1496         -    if( (v = pParse->pReprepare)!=0 && (db->flags & SQLITE_EnableQPSG)==0 ){
         1495  +    if( (v = pParse->pReprepare)!=0 ){
  1497   1496         pVal = valueNew(db, pAlloc);
  1498   1497         if( pVal ){
  1499   1498           rc = sqlite3VdbeMemCopy((Mem*)pVal, &v->aVar[iBindVar-1]);
  1500   1499           sqlite3ValueApplyAffinity(pVal, affinity, ENC(db));
  1501   1500           pVal->db = pParse->db;
  1502   1501         }
  1503   1502       }

Changes to src/whereexpr.c.

   212    212     if( *pnoCase ) return 0;
   213    213   #endif
   214    214     pList = pExpr->x.pList;
   215    215     pLeft = pList->a[1].pExpr;
   216    216   
   217    217     pRight = sqlite3ExprSkipCollate(pList->a[0].pExpr);
   218    218     op = pRight->op;
   219         -  if( op==TK_VARIABLE ){
          219  +  if( op==TK_VARIABLE && (db->flags & SQLITE_EnableQPSG)==0 ){
   220    220       Vdbe *pReprepare = pParse->pReprepare;
   221    221       int iCol = pRight->iColumn;
   222    222       pVal = sqlite3VdbeGetBoundValue(pReprepare, iCol, SQLITE_AFF_BLOB);
   223    223       if( pVal && sqlite3_value_type(pVal)==SQLITE_TEXT ){
   224    224         z = (char *)sqlite3_value_text(pVal);
   225    225       }
   226    226       sqlite3VdbeSetVarmask(pParse->pVdbe, iCol);