SQLite4
Check-in [9844269b3d]
Not logged in

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

Overview
Comment:Further updates to ngqp code.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | nextgen-query-planner
Files: files | file ages | folders
SHA1: 9844269b3d3729972ccd31c1cb61cb69ae693a9e
User & Date: dan 2013-07-17 18:49:27
Context
2013-07-17
20:03
Fix a bug preventing the planner from finding sorting indexes. check-in: 6f06ebee56 user: dan tags: nextgen-query-planner
18:49
Further updates to ngqp code. check-in: 9844269b3d user: dan tags: nextgen-query-planner
2013-07-16
20:01
Updates to use the next-generation-query-planner from the SQLite3 project. This branch is largely broken. check-in: bc9c9f73c5 user: dan tags: nextgen-query-planner
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/where.c.

   933    933     if( iIdxCol<pIdx->nColumn ){
   934    934       iRet = pIdx->aiColumn[iIdxCol];
   935    935     }else if( pPk && iIdxCol<(pIdx->nColumn + pPk->nColumn) ){
   936    936       iRet = pPk->aiColumn[iIdxCol - pIdx->nColumn];
   937    937     }
   938    938     return iRet;
   939    939   }
          940  +
          941  +/*
          942  +** Return a pointer to a buffer containing the name of the collation 
          943  +** sequence used with the iIdxCol'th field in index pIdx, including any
          944  +** appended PRIMARY KEY fields.
          945  +*/
          946  +static char *idxColumnCollation(Index *pIdx, Index *pPk, int iIdxCol){
          947  +  char *zColl;
          948  +  assert( iIdxCol<(pIdx->nColumn + pPk->nColumn) );
          949  +  if( iIdxCol<pIdx->nColumn ){
          950  +    zColl = pIdx->azColl[iIdxCol];
          951  +  }else if( pPk && iIdxCol<(pIdx->nColumn + pPk->nColumn) ){
          952  +    zColl = pPk->azColl[iIdxCol - pIdx->nColumn];
          953  +  }
          954  +  return zColl;
          955  +}
   940    956   
   941    957   /*
   942    958   ** Return the total number of fields in the index pIdx, including any
   943    959   ** trailing primary key fields.
   944    960   */
   945    961   static int idxColumnCount(Index *pIdx, Index *pPk){
   946    962     return (pIdx->nColumn + (pIdx==pPk ? 0 : pPk->nColumn));
................................................................................
   977    993     pScan->pWC = pWC;
   978    994     if( pIdx && iColumn>=0 ){
   979    995       Index *pPk = sqlite4FindPrimaryKey(pIdx->pTable, 0);
   980    996       pScan->idxaff = pIdx->pTable->aCol[iColumn].affinity;
   981    997       for(j=0; idxColumnNumber(pIdx, pPk, j)!=iColumn; j++){
   982    998         if( NEVER(j>=idxColumnCount(pIdx, pPk)) ) return 0;
   983    999       }
   984         -    pScan->zCollName = pIdx->azColl[j];
         1000  +    pScan->zCollName = idxColumnCollation(pIdx, pPk, j);
   985   1001     }else{
   986   1002       pScan->idxaff = 0;
   987   1003       pScan->zCollName = 0;
   988   1004     }
   989   1005     pScan->opMask = opMask;
   990   1006     pScan->k = 0;
   991   1007     pScan->aEquiv[0] = iCur;
................................................................................
  3019   3035     zAff = sqlite4DbStrDup(pParse->db, sqlite4IndexAffinityStr(v, pIdx));
  3020   3036     if( !zAff ){
  3021   3037       pParse->db->mallocFailed = 1;
  3022   3038     }
  3023   3039   
  3024   3040     /* Evaluate the equality constraints
  3025   3041     */
  3026         -  assert( pIdx->nColumn>=nEq );
         3042  +  assert( idxColumnCount(pIdx, sqlite4FindPrimaryKey(pIdx->pTable, 0))>=nEq );
  3027   3043     for(j=0; j<nEq; j++){
  3028   3044       int r1;
  3029   3045       pTerm = pLoop->aLTerm[j];
  3030   3046       assert( pTerm!=0 );
  3031   3047       /* The following true for indices with redundant columns. 
  3032   3048       ** Ex: CREATE INDEX i1 ON t1(a,b,a); SELECT * FROM t1 WHERE a=0 AND b=0; */
  3033   3049       testcase( (pTerm->wtFlags & TERM_CODED)!=0 );
................................................................................
  3750   3766       */
  3751   3767       WhereClause *pOrWc;    /* The OR-clause broken out into subterms */
  3752   3768       SrcList *pOrTab;       /* Shortened table list or OR-clause generation */
  3753   3769       Index *pCov = 0;             /* Potential covering index (or NULL) */
  3754   3770       int iCovCur = pParse->nTab++;  /* Cursor used for index scans (if any) */
  3755   3771   
  3756   3772       int regReturn = ++pParse->nMem;           /* Register used with OP_Gosub */
  3757         -    int regRowset = 0;                        /* Register for RowSet object */
  3758         -    int regRowid = 0;                         /* Register holding rowid */
         3773  +    int regKeyset = 0;                        /* Register for RowSet object */
         3774  +    int regKey = 0;                           /* Register holding key */
  3759   3775       int iLoopBody = sqlite4VdbeMakeLabel(v);  /* Start of loop body */
  3760   3776       int iRetInit;                             /* Address of regReturn init */
  3761   3777       int untestedTerms = 0;             /* Some terms not completely tested */
  3762   3778       int ii;                            /* Loop counter */
  3763   3779       Expr *pAndExpr = 0;                /* An ".. AND (...)" expression */
  3764   3780      
  3765   3781       pTerm = pLoop->aLTerm[0];
................................................................................
  3788   3804         for(k=1; k<=nNotReady; k++){
  3789   3805           memcpy(&pOrTab->a[k], &origSrc[pLevel[k].iFrom], sizeof(pOrTab->a[k]));
  3790   3806         }
  3791   3807       }else{
  3792   3808         pOrTab = pWInfo->pTabList;
  3793   3809       }
  3794   3810   
  3795         -    /* Initialize the rowset register to contain NULL. An SQL NULL is 
  3796         -    ** equivalent to an empty rowset.
         3811  +    /* Initialize the keyset register to contain NULL. An SQL NULL is 
         3812  +    ** equivalent to an empty keyset.
  3797   3813       **
  3798   3814       ** Also initialize regReturn to contain the address of the instruction 
  3799   3815       ** immediately following the OP_Return at the bottom of the loop. This
  3800   3816       ** is required in a few obscure LEFT JOIN cases where control jumps
  3801   3817       ** over the top of the loop into the body of it. In this case the 
  3802   3818       ** correct response for the end-of-loop code (the OP_Return) is to 
  3803   3819       ** fall through to the next instruction, just as an OP_Next does if
  3804   3820       ** called on an uninitialized cursor.
  3805   3821       */
  3806   3822       if( (pWInfo->wctrlFlags & WHERE_DUPLICATES_OK)==0 ){
  3807         -      regRowset = ++pParse->nMem;
  3808         -      regRowid = ++pParse->nMem;
  3809         -      sqlite4VdbeAddOp2(v, OP_Null, 0, regRowset);
         3823  +      regKeyset = ++pParse->nMem;
         3824  +      regKey = ++pParse->nMem;
         3825  +      sqlite4VdbeAddOp2(v, OP_Null, 0, regKeyset);
  3810   3826       }
  3811   3827       iRetInit = sqlite4VdbeAddOp2(v, OP_Integer, 0, regReturn);
  3812   3828   
  3813   3829       /* If the original WHERE clause is z of the form:  (x1 OR x2 OR ...) AND y
  3814   3830       ** Then for every term xN, evaluate as the subexpression: xN AND z
  3815   3831       ** That way, terms in y that are factored into the disjunction will
  3816   3832       ** be picked up by the recursive calls to sqlite4WhereBegin() below.
................................................................................
  3856   3872           if( pSubWInfo ){
  3857   3873             WhereLoop *pSubLoop;
  3858   3874             explainOneScan(
  3859   3875                 pParse, pOrTab, &pSubWInfo->a[0], iLevel, pLevel->iFrom, 0
  3860   3876             );
  3861   3877             if( (pWInfo->wctrlFlags & WHERE_DUPLICATES_OK)==0 ){
  3862   3878               int iSet = ((ii==pOrWc->nTerm-1)?-1:ii);
  3863         -            int r;
  3864         -            r = sqlite4ExprCodeGetColumn(pParse, pTabItem->pTab, -1, iCur, 
  3865         -                                         regRowid);
  3866         -            sqlite4VdbeAddOp4Int(v, OP_RowSetTest, regRowset,
  3867         -                                 sqlite4VdbeCurrentAddr(v)+2, r, iSet);
         3879  +            sqlite4VdbeAddOp2(v, OP_RowKey, iCur, regKey);
         3880  +            sqlite4VdbeAddOp4Int(v, OP_RowSetTest, regKeyset,
         3881  +                                 sqlite4VdbeCurrentAddr(v)+2, regKey, iSet);
  3868   3882             }
  3869   3883             sqlite4VdbeAddOp2(v, OP_Gosub, regReturn, iLoopBody);
  3870   3884   
  3871   3885             /* The pSubWInfo->untestedTerms flag means that this OR term
  3872   3886             ** contained one or more AND term from a notReady table.  The
  3873   3887             ** terms from the notReady table could not be tested and will
  3874   3888             ** need to be tested later.
................................................................................
  3883   3897             ** If the call to sqlite4WhereBegin() above resulted in a scan that
  3884   3898             ** uses an index, and this is either the first OR-connected term
  3885   3899             ** processed or the index is the same as that used by all previous
  3886   3900             ** terms, set pCov to the candidate covering index. Otherwise, set 
  3887   3901             ** pCov to NULL to indicate that no candidate covering index will 
  3888   3902             ** be available.
  3889   3903             */
         3904  +#if 0
  3890   3905             pSubLoop = pSubWInfo->a[0].pWLoop;
  3891   3906             assert( (pSubLoop->wsFlags & WHERE_AUTO_INDEX)==0 );
  3892   3907             if( (pSubLoop->wsFlags & WHERE_INDEXED)!=0
  3893   3908              && (ii==0 || pSubLoop->u.btree.pIndex==pCov)
  3894   3909             ){
  3895   3910               assert( pSubWInfo->a[0].iIdxCur==iCovCur );
  3896   3911               pCov = pSubLoop->u.btree.pIndex;
  3897   3912             }else{
  3898   3913               pCov = 0;
  3899   3914             }
         3915  +#endif
  3900   3916   
  3901   3917             /* Finish the loop through table entries that match term pOrTerm. */
  3902   3918             sqlite4WhereEnd(pSubWInfo);
  3903   3919           }
  3904   3920         }
  3905   3921       }
  3906   3922       pLevel->u.pCovidx = pCov;
................................................................................
  4179   4195   **    (5)  The template uses more terms of the same index but has no additional
  4180   4196   **         dependencies          
  4181   4197   */
  4182   4198   static int whereLoopInsert(WhereLoopBuilder *pBuilder, WhereLoop *pTemplate){
  4183   4199     WhereLoop **ppPrev, *p, *pNext = 0;
  4184   4200     WhereInfo *pWInfo = pBuilder->pWInfo;
  4185   4201     sqlite4 *db = pWInfo->pParse->db;
         4202  +
         4203  +  assert( pTemplate->u.btree.pIndex || !(pTemplate->wsFlags & WHERE_INDEXED) );
  4186   4204   
  4187   4205     /* If pBuilder->pBest is defined, then only keep track of the single
  4188   4206     ** best WhereLoop.  pBuilder->pBest->maskSelf==0 indicates that no
  4189   4207     ** prior WhereLoops have been evaluated and that the current pTemplate
  4190   4208     ** is therefore the first and hence the best and should be retained.
  4191   4209     */
  4192   4210     if( (p = pBuilder->pBest)!=0 ){
................................................................................
  4611   4629           pNew->wsFlags = WHERE_AUTO_INDEX;
  4612   4630           pNew->prereq = mExtra | pTerm->prereqRight;
  4613   4631           rc = whereLoopInsert(pBuilder, pNew);
  4614   4632         }
  4615   4633       }
  4616   4634     }
  4617   4635   #endif /* ifndef SQLITE4_OMIT_AUTOMATIC_INDEX */
         4636  +
         4637  +  /* If this table has no primary key, then it is either a materialized
         4638  +  ** view or ephemeral table. Either way, add an entry for a full-scan 
         4639  +  ** of it.  */
         4640  +  if( pPk==0 ){
         4641  +    assert( pSrc->pTab->pSelect || (pSrc->pTab->tabFlags & TF_Ephemeral) );
         4642  +    pNew->u.btree.nEq = 0;
         4643  +    pNew->nLTerm = 0;
         4644  +    pNew->iSortIdx = 0;
         4645  +    pNew->rSetup = 0;
         4646  +    pNew->prereq = mExtra;
         4647  +    pNew->nOut = rSize;
         4648  +    pNew->u.btree.pIndex = 0;
         4649  +    pNew->iSortIdx = 0;
         4650  +    pNew->wsFlags = 0;
         4651  +    pNew->rRun = whereCostAdd(rSize,rLogSize) + 16;
         4652  +    rc = whereLoopInsert(pBuilder, pNew);
         4653  +  }
  4618   4654   
  4619   4655     /* Loop through the set of indices being considered. */
  4620   4656     for(; rc==SQLITE4_OK && pProbe; pProbe=pProbe->pNext, iSortIdx++){
  4621   4657   
  4622   4658       if( pProbe->eIndexType==SQLITE4_INDEX_FTS5 ) continue;
  4623   4659   
  4624   4660       pNew->u.btree.nEq = 0;