/ Check-in [0775501a]
Login
SQLite training in Houston TX on 2019-11-05 (details)
Part of the 2019 Tcl Conference

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

Overview
Comment:Defer the creation of automatic indices until the index is actually used.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 0775501acf152dcbf4dd039f4511f3d8c4330d85
User & Date: drh 2013-08-22 02:56:28
Context
2013-08-23
12:04
Modify script mkautoconfamal.sh to use the download.html naming convention for the tar.gz it creates. check-in: 375b4e3d user: dan tags: trunk
2013-08-22
15:07
Merge in minor bug fixes and performance tweaks from trunk leading up to the version 3.8.0 release. check-in: 831492dc user: drh tags: sessions
02:56
Defer the creation of automatic indices until the index is actually used. check-in: 0775501a user: drh tags: trunk
2013-08-21
23:42
Simplify the btreeGetPage() routine so that it uses a single flag parameter in place of two boolean parameters. check-in: 617e23ec user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/where.c.

    86     86     int iLeftJoin;        /* Memory cell used to implement LEFT OUTER JOIN */
    87     87     int iTabCur;          /* The VDBE cursor used to access the table */
    88     88     int iIdxCur;          /* The VDBE cursor used to access pIdx */
    89     89     int addrBrk;          /* Jump here to break out of the loop */
    90     90     int addrNxt;          /* Jump here to start the next IN combination */
    91     91     int addrCont;         /* Jump here to continue with the next loop cycle */
    92     92     int addrFirst;        /* First instruction of interior of the loop */
           93  +  int addrBody;         /* Beginning of the body of this loop */
    93     94     u8 iFrom;             /* Which entry in the FROM clause */
    94     95     u8 op, p5;            /* Opcode and P5 of the opcode that ends the loop */
    95     96     int p1, p2;           /* Operands of the opcode used to ends the loop */
    96     97     union {               /* Information that depends on pWLoop->wsFlags */
    97     98       struct {
    98     99         int nIn;              /* Number of entries in aInLoop[] */
    99    100         struct InLoop {
................................................................................
  5980   5981           sqlite3VdbeChangeP4(v, sqlite3VdbeCurrentAddr(v)-1, 
  5981   5982                               SQLITE_INT_TO_PTR(n), P4_INT32);
  5982   5983           assert( n<=pTab->nCol );
  5983   5984         }
  5984   5985       }else{
  5985   5986         sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName);
  5986   5987       }
  5987         -#ifndef SQLITE_OMIT_AUTOMATIC_INDEX
  5988         -    if( (pLoop->wsFlags & WHERE_AUTO_INDEX)!=0 ){
  5989         -      constructAutomaticIndex(pParse, &pWInfo->sWC, pTabItem, notReady, pLevel);
  5990         -    }else
  5991         -#endif
  5992   5988       if( pLoop->wsFlags & WHERE_INDEXED ){
  5993   5989         Index *pIx = pLoop->u.btree.pIndex;
  5994   5990         KeyInfo *pKey = sqlite3IndexKeyinfo(pParse, pIx);
  5995   5991         /* FIXME:  As an optimization use pTabItem->iCursor if WHERE_IDX_ONLY */
  5996   5992         int iIndexCur = pLevel->iIdxCur = iIdxCur ? iIdxCur : pParse->nTab++;
  5997   5993         assert( pIx->pSchema==pTab->pSchema );
  5998   5994         assert( iIndexCur>=0 );
................................................................................
  6009   6005     /* Generate the code to do the search.  Each iteration of the for
  6010   6006     ** loop below generates code for a single nested loop of the VM
  6011   6007     ** program.
  6012   6008     */
  6013   6009     notReady = ~(Bitmask)0;
  6014   6010     for(ii=0; ii<nTabList; ii++){
  6015   6011       pLevel = &pWInfo->a[ii];
         6012  +#ifndef SQLITE_OMIT_AUTOMATIC_INDEX
         6013  +    if( (pLevel->pWLoop->wsFlags & WHERE_AUTO_INDEX)!=0 ){
         6014  +      constructAutomaticIndex(pParse, &pWInfo->sWC,
         6015  +                &pTabList->a[pLevel->iFrom], notReady, pLevel);
         6016  +      if( db->mallocFailed ) goto whereBeginError;
         6017  +    }
         6018  +#endif
  6016   6019       explainOneScan(pParse, pTabList, pLevel, ii, pLevel->iFrom, wctrlFlags);
         6020  +    pLevel->addrBody = sqlite3VdbeCurrentAddr(v);
  6017   6021       notReady = codeOneLoopStart(pWInfo, ii, notReady);
  6018   6022       pWInfo->iContinue = pLevel->addrCont;
  6019   6023     }
  6020   6024   
  6021   6025     /* Done. */
  6022   6026     return pWInfo;
  6023   6027   
................................................................................
  6129   6133       }else if( pLoop->wsFlags & WHERE_MULTI_OR ){
  6130   6134         pIdx = pLevel->u.pCovidx;
  6131   6135       }
  6132   6136       if( pIdx && !db->mallocFailed ){
  6133   6137         int k, j, last;
  6134   6138         VdbeOp *pOp;
  6135   6139   
  6136         -      pOp = sqlite3VdbeGetOp(v, pWInfo->iTop);
  6137   6140         last = sqlite3VdbeCurrentAddr(v);
  6138         -      for(k=pWInfo->iTop; k<last; k++, pOp++){
         6141  +      k = pLevel->addrBody;
         6142  +      pOp = sqlite3VdbeGetOp(v, k);
         6143  +      for(; k<last; k++, pOp++){
  6139   6144           if( pOp->p1!=pLevel->iTabCur ) continue;
  6140   6145           if( pOp->opcode==OP_Column ){
  6141   6146             for(j=0; j<pIdx->nColumn; j++){
  6142   6147               if( pOp->p2==pIdx->aiColumn[j] ){
  6143   6148                 pOp->p2 = j;
  6144   6149                 pOp->p1 = pLevel->iIdxCur;
  6145   6150                 break;