SQLite

Check-in [2401ea5acf]
Login

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

Overview
Comment:Fix a segfault introduced by the row-value enhancement that comes up on a skip-scan where the first term of the index is unconstrained and the second term is of the form "columm IN (SELECT...)".
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 2401ea5acfeee8042489d1db38036ff86e8a6916
User & Date: drh 2016-09-19 11:00:42.662
Context
2016-09-19
23:39
Very small optimization in the bytecode engine. (check-in: 46002511e5 user: drh tags: trunk)
11:00
Fix a segfault introduced by the row-value enhancement that comes up on a skip-scan where the first term of the index is unconstrained and the second term is of the form "columm IN (SELECT...)". (check-in: 2401ea5acf user: drh tags: trunk)
10:24
Improved performance in sqlite3ExprCodeTarget(). (check-in: 75146165dc user: drh tags: trunk)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/where.c.
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420

        /* The expression may actually be of the form (x, y) IN (SELECT...).
        ** In this case there is a separate term for each of (x) and (y).
        ** However, the nIn multiplier should only be applied once, not once
        ** for each such term. The following loop checks that pTerm is the
        ** first such term in use, and sets nIn back to 0 if it is not. */
        for(i=0; i<pNew->nLTerm-1; i++){
          if( pNew->aLTerm[i]->pExpr==pExpr ) nIn = 0;
        }
      }else if( ALWAYS(pExpr->x.pList && pExpr->x.pList->nExpr) ){
        /* "x IN (value, value, ...)" */
        nIn = sqlite3LogEst(pExpr->x.pList->nExpr);
        assert( nIn>0 );  /* RHS always has 2 or more terms...  The parser
                          ** changes "x IN (?)" into "x=?". */
      }







|







2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420

        /* The expression may actually be of the form (x, y) IN (SELECT...).
        ** In this case there is a separate term for each of (x) and (y).
        ** However, the nIn multiplier should only be applied once, not once
        ** for each such term. The following loop checks that pTerm is the
        ** first such term in use, and sets nIn back to 0 if it is not. */
        for(i=0; i<pNew->nLTerm-1; i++){
          if( pNew->aLTerm[i] && pNew->aLTerm[i]->pExpr==pExpr ) nIn = 0;
        }
      }else if( ALWAYS(pExpr->x.pList && pExpr->x.pList->nExpr) ){
        /* "x IN (value, value, ...)" */
        nIn = sqlite3LogEst(pExpr->x.pList->nExpr);
        assert( nIn>0 );  /* RHS always has 2 or more terms...  The parser
                          ** changes "x IN (?)" into "x=?". */
      }
Changes to test/skipscan1.test.
317
318
319
320
321
322
323















324
325
      OR (y = 'EF' AND x = 5);
} {/ANY/}
do_execsql_test skipscan1-8.2 {
  SELECT * FROM t1
   WHERE y = 'AB' OR (y = 'CD' AND x = 2)
  ORDER BY +x;
} {1 AB 2 CD}
















finish_test







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


317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
      OR (y = 'EF' AND x = 5);
} {/ANY/}
do_execsql_test skipscan1-8.2 {
  SELECT * FROM t1
   WHERE y = 'AB' OR (y = 'CD' AND x = 2)
  ORDER BY +x;
} {1 AB 2 CD}

# Segfault reported on the mailing list by Keith Medcalf on 2016-09-18.
# A skip-scan with a "column IN (SELECT ...)" on the second term of the
# index.
#
do_execsql_test skipscan1-9.2 {
  CREATE TABLE t9a(a,b,c);
  CREATE INDEX t9a_ab ON t9a(a,b);
  CREATE TABLE t9b(x,y);
  ANALYZE sqlite_master;
  INSERT INTO sqlite_stat1 VALUES('t9a','t9a_ab','1000000 250000 1');
  ANALYZE sqlite_master;
  EXPLAIN QUERY PLAN
  SELECT * FROM t9a WHERE b IN (SELECT x FROM t9b WHERE y!=5);
} {/USING INDEX t9a_ab .ANY.a. AND b=./}

finish_test