/ Check-in [e22d2f90]
Login

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

Overview
Comment:Use the new SQLITE_IDXTYPE_IPK values (3) on Index.idxType to indicate the fake INTEGER PRIMARY KEY index used during query planning.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: e22d2f905fe840bea51b536ebedc9b637190ea0a37f16559668d99a61e971411
User & Date: drh 2019-01-10 13:56:08
Context
2019-01-10
14:33
More aggressive early detection of orphaned and malformed autoindexes when parsing the schema. check-in: 10f9e39d user: drh tags: trunk
13:56
Use the new SQLITE_IDXTYPE_IPK values (3) on Index.idxType to indicate the fake INTEGER PRIMARY KEY index used during query planning. check-in: e22d2f90 user: drh tags: trunk
01:12
Fix the fts3DecodeIntArray() function so that it will not read off the end of the buffer it is handed. Any unread integers are set to zero. check-in: 666cf8f6 user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/sqliteInt.h.

  2239   2239     Expr *pPartIdxWhere;     /* WHERE clause for partial indices */
  2240   2240     ExprList *aColExpr;      /* Column expressions */
  2241   2241     int tnum;                /* DB Page containing root of this index */
  2242   2242     LogEst szIdxRow;         /* Estimated average row size in bytes */
  2243   2243     u16 nKeyCol;             /* Number of columns forming the key */
  2244   2244     u16 nColumn;             /* Number of columns stored in the index */
  2245   2245     u8 onError;              /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */
  2246         -  unsigned idxType:2;      /* 1==UNIQUE, 2==PRIMARY KEY, 0==CREATE INDEX */
         2246  +  unsigned idxType:2;      /* 0:Normal 1:UNIQUE, 2:PRIMARY KEY, 3:IPK */
  2247   2247     unsigned bUnordered:1;   /* Use this index for == or IN queries only */
  2248   2248     unsigned uniqNotNull:1;  /* True if UNIQUE and NOT NULL for all columns */
  2249   2249     unsigned isResized:1;    /* True if resizeIndexObject() has been called */
  2250   2250     unsigned isCovering:1;   /* True if this is a covering index */
  2251   2251     unsigned noSkipScan:1;   /* Do not try to use skip-scan if true */
  2252   2252     unsigned hasStat1:1;     /* aiRowLogEst values come from sqlite_stat1 */
  2253   2253     unsigned bNoQuery:1;     /* Do not use this index to optimize queries */
................................................................................
  2264   2264   
  2265   2265   /*
  2266   2266   ** Allowed values for Index.idxType
  2267   2267   */
  2268   2268   #define SQLITE_IDXTYPE_APPDEF      0   /* Created using CREATE INDEX */
  2269   2269   #define SQLITE_IDXTYPE_UNIQUE      1   /* Implements a UNIQUE constraint */
  2270   2270   #define SQLITE_IDXTYPE_PRIMARYKEY  2   /* Is the PRIMARY KEY for the table */
         2271  +#define SQLITE_IDXTYPE_IPK         3   /* INTEGER PRIMARY KEY index */
  2271   2272   
  2272   2273   /* Return true if index X is a PRIMARY KEY index */
  2273   2274   #define IsPrimaryKeyIndex(X)  ((X)->idxType==SQLITE_IDXTYPE_PRIMARYKEY)
  2274   2275   
  2275   2276   /* Return true if index X is a UNIQUE index */
  2276   2277   #define IsUniqueIndex(X)      ((X)->onError!=OE_None)
  2277   2278   

Changes to src/where.c.

  2206   2206   #endif
  2207   2207         whereLoopDelete(db, pToDel);
  2208   2208       }
  2209   2209     }
  2210   2210     rc = whereLoopXfer(db, p, pTemplate);
  2211   2211     if( (p->wsFlags & WHERE_VIRTUALTABLE)==0 ){
  2212   2212       Index *pIndex = p->u.btree.pIndex;
  2213         -    if( pIndex && pIndex->tnum==0 ){
         2213  +    if( pIndex && pIndex->idxType==SQLITE_IDXTYPE_IPK ){
  2214   2214         p->u.btree.pIndex = 0;
  2215   2215       }
  2216   2216     }
  2217   2217     return rc;
  2218   2218   }
  2219   2219   
  2220   2220   /*
................................................................................
  2373   2373   ** index pIndex. Try to match one more.
  2374   2374   **
  2375   2375   ** When this function is called, pBuilder->pNew->nOut contains the 
  2376   2376   ** number of rows expected to be visited by filtering using the nEq 
  2377   2377   ** terms only. If it is modified, this value is restored before this 
  2378   2378   ** function returns.
  2379   2379   **
  2380         -** If pProbe->tnum==0, that means pIndex is a fake index used for the
  2381         -** INTEGER PRIMARY KEY.
         2380  +** If pProbe->idxType==SQLITE_IDXTYPE_IPK, that means pIndex is 
         2381  +** a fake index used for the INTEGER PRIMARY KEY.
  2382   2382   */
  2383   2383   static int whereLoopAddBtreeIndex(
  2384   2384     WhereLoopBuilder *pBuilder,     /* The WhereLoop factory */
  2385   2385     struct SrcList_item *pSrc,      /* FROM clause term being analyzed */
  2386   2386     Index *pProbe,                  /* An index on pSrc */
  2387   2387     LogEst nInMul                   /* log(Number of iterations due to IN) */
  2388   2388   ){
................................................................................
  2874   2874       sPk.nKeyCol = 1;
  2875   2875       sPk.nColumn = 1;
  2876   2876       sPk.aiColumn = &aiColumnPk;
  2877   2877       sPk.aiRowLogEst = aiRowEstPk;
  2878   2878       sPk.onError = OE_Replace;
  2879   2879       sPk.pTable = pTab;
  2880   2880       sPk.szIdxRow = pTab->szTabRow;
         2881  +    sPk.idxType = SQLITE_IDXTYPE_IPK;
  2881   2882       aiRowEstPk[0] = pTab->nRowLogEst;
  2882   2883       aiRowEstPk[1] = 0;
  2883   2884       pFirst = pSrc->pTab->pIndex;
  2884   2885       if( pSrc->fg.notIndexed==0 ){
  2885   2886         /* The real indices of the table are only considered if the
  2886   2887         ** NOT INDEXED qualifier is omitted from the FROM clause */
  2887   2888         sPk.pNext = pFirst;
................................................................................
  2964   2965       pNew->rSetup = 0;
  2965   2966       pNew->prereq = mPrereq;
  2966   2967       pNew->nOut = rSize;
  2967   2968       pNew->u.btree.pIndex = pProbe;
  2968   2969       b = indexMightHelpWithOrderBy(pBuilder, pProbe, pSrc->iCursor);
  2969   2970       /* The ONEPASS_DESIRED flags never occurs together with ORDER BY */
  2970   2971       assert( (pWInfo->wctrlFlags & WHERE_ONEPASS_DESIRED)==0 || b==0 );
  2971         -    if( pProbe->tnum<=0 ){
         2972  +    if( pProbe->idxType==SQLITE_IDXTYPE_IPK ){
  2972   2973         /* Integer primary key index */
  2973   2974         pNew->wsFlags = WHERE_IPK;
  2974   2975   
  2975   2976         /* Full table scan */
  2976   2977         pNew->iSortIdx = b ? iSortIdx : 0;
  2977   2978         /* TUNING: Cost of full table scan is (N*3.0). */
  2978   2979         pNew->rRun = rSize + 16;

Changes to test/fts3fuzz001.test.

    98     98       INSERT INTO t1(t1) VALUES('integrity-check');
    99     99     }
   100    100   } {1 {database disk image is malformed}}
   101    101   do_test fts3fuzz001-120 {
   102    102     catchsql {
   103    103       INSERT INTO t1(t1) VALUES('optimize');
   104    104     }
   105         -} {0 {}}
          105  +} {1 {database disk image is malformed}}
   106    106   do_test fts3fuzz001-121 {
   107    107     catchsql {
   108    108       INSERT INTO t1(t1) VALUES('integrity-check');
   109    109     }
   110    110   } {1 {database disk image is malformed}}
   111    111   
   112    112   
   113    113   finish_test