/ Check-in [7e4ed8b5]
Login

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

Overview
Comment:Fix a problem with bytecode generation when a query involves two or more indexes on expressions connected by OR. Ticket [d96eba87698a428c1ddd0790ea04]
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 7e4ed8b5c2047b69bbb037497111e56e465a4d9f8afca3b337f9ac744471dc4a
User & Date: drh 2018-12-14 11:16:52
Context
2018-12-14
13:18
When saving the position of a cursor at the b-tree layer, allocate a few extra bytes at the end of the buffer used to save the key. Otherwise, if the key is corrupt, the code that restores the cursor position may overread the buffer by a little. check-in: 160b1e31 user: dan tags: trunk
11:16
Fix a problem with bytecode generation when a query involves two or more indexes on expressions connected by OR. Ticket [d96eba87698a428c1ddd0790ea04] check-in: 7e4ed8b5 user: drh tags: trunk
08:40
Possible fix for [d96eba87]. Closed-Leaf check-in: 89a25abf user: dan tags: tkt-d96eba87
03:16
Report corruption when an attempt is made to write a pointer-map page that is also being used as a btree page. Also, fix a bug in fuzzcheck that cause it to overlook a pointer-map bug that was trigger by the fuzzcheck test data, and also fix the pointer-map bug. check-in: cc42dd15 user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/whereexpr.c.

   774    774       ** other of the == operator in every subterm.  That table and column
   775    775       ** will be recorded in iCursor and iColumn.  There might not be any
   776    776       ** such table and column.  Set okToChngToIN if an appropriate table
   777    777       ** and column is found but leave okToChngToIN false if not found.
   778    778       */
   779    779       for(j=0; j<2 && !okToChngToIN; j++){
   780    780         pOrTerm = pOrWc->a;
          781  +      Expr *pLeft = 0;
   781    782         for(i=pOrWc->nTerm-1; i>=0; i--, pOrTerm++){
   782    783           assert( pOrTerm->eOperator & WO_EQ );
   783    784           pOrTerm->wtFlags &= ~TERM_OR_OK;
   784    785           if( pOrTerm->leftCursor==iCursor ){
   785    786             /* This is the 2-bit case and we are on the second iteration and
   786    787             ** current term is from the first iteration.  So skip this term. */
   787    788             assert( j==1 );
................................................................................
   796    797             testcase( pOrTerm->wtFlags & TERM_COPIED );
   797    798             testcase( pOrTerm->wtFlags & TERM_VIRTUAL );
   798    799             assert( pOrTerm->wtFlags & (TERM_COPIED|TERM_VIRTUAL) );
   799    800             continue;
   800    801           }
   801    802           iColumn = pOrTerm->u.leftColumn;
   802    803           iCursor = pOrTerm->leftCursor;
          804  +        pLeft = pOrTerm->pExpr->pLeft;
   803    805           break;
   804    806         }
   805    807         if( i<0 ){
   806    808           /* No candidate table+column was found.  This can only occur
   807    809           ** on the second iteration */
   808    810           assert( j==1 );
   809    811           assert( IsPowerOfTwo(chngToIN) );
................................................................................
   815    817         /* We have found a candidate table and column.  Check to see if that
   816    818         ** table and column is common to every term in the OR clause */
   817    819         okToChngToIN = 1;
   818    820         for(; i>=0 && okToChngToIN; i--, pOrTerm++){
   819    821           assert( pOrTerm->eOperator & WO_EQ );
   820    822           if( pOrTerm->leftCursor!=iCursor ){
   821    823             pOrTerm->wtFlags &= ~TERM_OR_OK;
   822         -        }else if( pOrTerm->u.leftColumn!=iColumn ){
          824  +        }else if( pOrTerm->u.leftColumn!=iColumn || (iColumn==XN_EXPR 
          825  +               && sqlite3ExprCompare(pParse, pOrTerm->pExpr->pLeft, pLeft, -1)
          826  +        )){
   823    827             okToChngToIN = 0;
   824    828           }else{
   825    829             int affLeft, affRight;
   826    830             /* If the right-hand side is also a column, then the affinities
   827    831             ** of both right and left sides must be such that no type
   828    832             ** conversions are required on the right.  (Ticket #2249)
   829    833             */

Changes to test/indexexpr2.test.

   226    226       SELECT sqlite_master.name 
   227    227         FROM sqlite_master, explain('UPDATE t2 SET c=c+1, f=NULL')
   228    228        WHERE explain.opcode LIKE 'Open%'
   229    229          AND sqlite_master.rootpage=explain.p2
   230    230        ORDER BY 1;
   231    231     } {t2 t2abc t2cd t2def}
   232    232   }
          233  +
          234  +#-------------------------------------------------------------------------
          235  +# Test that ticket [d96eba87] has been fixed.
          236  +#
          237  +do_execsql_test 5.0 {
          238  +  CREATE TABLE t5(a INTEGER, b INTEGER);
          239  +  INSERT INTO t5 VALUES(2, 4), (3, 9);
          240  +}
          241  +do_execsql_test 5.1 {
          242  +  SELECT * FROM t5 WHERE abs(a)=2 or abs(b)=9;
          243  +} {2 4 3 9}
          244  +do_execsql_test 5.2 {
          245  +  CREATE INDEX t5a ON t5( abs(a) );
          246  +  CREATE INDEX t5b ON t5( abs(b) );
          247  +}
          248  +do_execsql_test 5.4 {
          249  +  SELECT * FROM t5 WHERE abs(a)=2 or abs(b)=9;
          250  +} {2 4 3 9}
          251  +
   233    252   
   234    253   
   235    254   finish_test