SQLite

Check-in [292a04086a]
Login

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

Overview
Comment:Fix a problem causing an INDEXED BY specifying an unusable partial index to be mishandled.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 292a04086a902634fc514b379a2b245eb2681c1b84d9bb950b6ecb9aab28b468
User & Date: dan 2017-11-07 18:20:15.108
Context
2017-11-07
19:02
Fix handling of partial indexes in checkindex.c (sqlite3_checker). (check-in: 31932a9eb8 user: dan tags: trunk)
18:20
Fix a problem causing an INDEXED BY specifying an unusable partial index to be mishandled. (check-in: 292a04086a user: dan tags: trunk)
16:54
Add the --trace option to the sqlite3_checker utility program. (check-in: dc217b7cfe user: drh tags: trunk)
Changes
Side-by-Side Diff Ignore Whitespace Patch
Changes to src/where.c.
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874





2875
2876
2877
2878
2879
2880
2881
2865
2866
2867
2868
2869
2870
2871



2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883







-
-
-
+
+
+
+
+







        pNew->prereq = mPrereq | pTerm->prereqRight;
        rc = whereLoopInsert(pBuilder, pNew);
      }
    }
  }
#endif /* SQLITE_OMIT_AUTOMATIC_INDEX */

  /* Loop over all indices
  */
  for(; rc==SQLITE_OK && pProbe; pProbe=pProbe->pNext, iSortIdx++){
  /* Loop over all indices. If there was an INDEXED BY clause, then only 
  ** consider index pProbe.  */
  for(; rc==SQLITE_OK && pProbe; 
      pProbe=(pSrc->pIBIndex ? 0 : pProbe->pNext), iSortIdx++
  ){
    if( pProbe->pPartIdxWhere!=0
     && !whereUsablePartialIndex(pSrc->iCursor, pWC, pProbe->pPartIdxWhere) ){
      testcase( pNew->iTab!=pSrc->iCursor );  /* See ticket [98d973b8f5] */
      continue;  /* Partial index inappropriate for this query */
    }
    rSize = pProbe->aiRowLogEst[0];
    pNew->u.btree.nEq = 0;
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2979
2980
2981
2982
2983
2984
2985




2986
2987
2988
2989
2990
2991
2992







-
-
-
-







      pTab->tabFlags |= TF_StatsUsed;
    }
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
    sqlite3Stat4ProbeFree(pBuilder->pRec);
    pBuilder->nRecValid = 0;
    pBuilder->pRec = 0;
#endif

    /* If there was an INDEXED BY clause, then only that one index is
    ** considered. */
    if( pSrc->pIBIndex ) break;
  }
  return rc;
}

#ifndef SQLITE_OMIT_VIRTUALTABLE

/*
Changes to test/indexedby.test.
359
360
361
362
363
364
365





















366
367
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+


} {1 1 3}
do_execsql_test 11.9 {
  SELECT a,b,c FROM x2 INDEXED BY x2i WHERE a=1 AND b=1 AND c='3.0';
} {1 1 3}
do_eqp_test 11.10 {
  SELECT a,b,c FROM x2 INDEXED BY x2i WHERE a=1 AND b=1 AND c='3.0';
} {0 0 0 {SEARCH TABLE x2 USING COVERING INDEX x2i (a=? AND b=? AND rowid=?)}}

#-------------------------------------------------------------------------
# Check INDEXED BY works (throws an exception) with partial indexes that 
# cannot be used.
do_execsql_test 12.1 {
  CREATE TABLE o1(x INTEGER PRIMARY KEY, y, z);
  CREATE INDEX p1 ON o1(z);
  CREATE INDEX p2 ON o1(y) WHERE z=1;
}
do_catchsql_test 12.2 {
  SELECT * FROM o1 INDEXED BY p2 ORDER BY 1;
} {1 {no query solution}}
do_execsql_test 12.3 {
  DROP INDEX p1;
  DROP INDEX p2;
  CREATE INDEX p2 ON o1(y) WHERE z=1;
  CREATE INDEX p1 ON o1(z);
}
do_catchsql_test 12.4 {
  SELECT * FROM o1 INDEXED BY p2 ORDER BY 1;
} {1 {no query solution}}

finish_test