/ Check-in [fa94b49e]
Login

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

Overview
Comment:Fix the OP_SeekRowid opcode so that it has no type-change side-effects on the key register in P3. This fixes an obcure problem that arises when doing equi-joins between a table with a TEXT column against another table with an INTEGER PRIMARY KEY. The original problem was discovered when OSSFuzz created such a query and hit an assert() in OP_VerifyTabCol that was specifically designed to catch these kinds of errors at run-time. Test cases for this fix are in TH3.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: fa94b49e02eb6b8fc4acc220ecc2fabef546c65845696758b25965c26b251ea9
User & Date: drh 2018-08-03 15:58:07
Original Comment: Fix the OP_SeekRowid opcode so that it has no type-change side-effects on the key register in P3. This fixes an obcure problem that arises when doing equi-joins between a table with a TEXT column against another table with an INTEGER PRIMARY KEY. The original problem was discovered when OSSFuzz created such a query and hit an assert() in OP_VerifyTabCol that was specifically designed to catch these kinds of errors at run-time.
Context
2018-08-03
20:19
Fix the handling of sub-queries with LIMIT clauses by the optimization activated by compile-time symbol SQLITE_COUNTOFVIEW_OPTIMIZATION. check-in: 21235d9a user: dan tags: trunk
15:58
Fix the OP_SeekRowid opcode so that it has no type-change side-effects on the key register in P3. This fixes an obcure problem that arises when doing equi-joins between a table with a TEXT column against another table with an INTEGER PRIMARY KEY. The original problem was discovered when OSSFuzz created such a query and hit an assert() in OP_VerifyTabCol that was specifically designed to catch these kinds of errors at run-time. Test cases for this fix are in TH3. check-in: fa94b49e user: drh tags: trunk
13:56
Improve "PRAGMA vdbe_trace=ON" to always show the key values for the OP_IdxGT and related opcodes. check-in: 0f881955 user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/vdbe.c.

  4319   4319     VdbeCursor *pC;
  4320   4320     BtCursor *pCrsr;
  4321   4321     int res;
  4322   4322     u64 iKey;
  4323   4323   
  4324   4324     pIn3 = &aMem[pOp->p3];
  4325   4325     if( (pIn3->flags & MEM_Int)==0 ){
         4326  +    /* Make sure pIn3->u.i contains a valid integer representation of
         4327  +    ** the key value, but do not change the datatype of the register, as
         4328  +    ** other parts of the perpared statement might be depending on the
         4329  +    ** current datatype. */
         4330  +    u16 origFlags = pIn3->flags;
         4331  +    int isNotInt;
  4326   4332       applyAffinity(pIn3, SQLITE_AFF_NUMERIC, encoding);
  4327         -    if( (pIn3->flags & MEM_Int)==0 ) goto jump_to_p2;
         4333  +    isNotInt = (pIn3->flags & MEM_Int)==0;
         4334  +    pIn3->flags = origFlags;
         4335  +    if( isNotInt ) goto jump_to_p2;
  4328   4336     }
  4329   4337     /* Fall through into OP_NotExists */
  4330   4338   case OP_NotExists:          /* jump, in3 */
  4331   4339     pIn3 = &aMem[pOp->p3];
  4332         -  assert( pIn3->flags & MEM_Int );
         4340  +  assert( (pIn3->flags & MEM_Int)!=0 || pOp->opcode==OP_SeekRowid );
  4333   4341     assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  4334   4342     pC = p->apCsr[pOp->p1];
  4335   4343     assert( pC!=0 );
  4336   4344   #ifdef SQLITE_DEBUG
  4337   4345     pC->seekOp = OP_SeekRowid;
  4338   4346   #endif
  4339   4347     assert( pC->isTable );

Changes to src/wherecode.c.

  1349   1349       testcase( pTerm->wtFlags & TERM_VIRTUAL );
  1350   1350       iReleaseReg = ++pParse->nMem;
  1351   1351       iRowidReg = codeEqualityTerm(pParse, pTerm, pLevel, 0, bRev, iReleaseReg);
  1352   1352       if( iRowidReg!=iReleaseReg ) sqlite3ReleaseTempReg(pParse, iReleaseReg);
  1353   1353       addrNxt = pLevel->addrNxt;
  1354   1354       sqlite3VdbeAddOp3(v, OP_SeekRowid, iCur, addrNxt, iRowidReg);
  1355   1355       VdbeCoverage(v);
  1356         -    sqlite3ExprCacheAffinityChange(pParse, iRowidReg, 1);
  1357         -    sqlite3ExprCacheStore(pParse, iCur, -1, iRowidReg);
  1358         -    VdbeComment((v, "pk"));
  1359   1356       pLevel->op = OP_Noop;
  1360   1357     }else if( (pLoop->wsFlags & WHERE_IPK)!=0
  1361   1358            && (pLoop->wsFlags & WHERE_COLUMN_RANGE)!=0
  1362   1359     ){
  1363   1360       /* Case 3:  We have an inequality comparison against the ROWID field.
  1364   1361       */
  1365   1362       int testOp = OP_Noop;