/ Check-in [10021941]
Login

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

Overview
Comment:Fix compiler warnings. Fix a harmless off-by-one error in the solver.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | nextgen-query-plan-exp
Files: files | file ages | folders
SHA1:10021941d0258951b916e788881df140113f0597
User & Date: drh 2013-06-19 03:27:12
Context
2013-06-19
12:34
Simplify and add invariants to the WhereLoop merging logic inside of whereLoopInsert(). check-in: 8f27f35f user: drh tags: nextgen-query-plan-exp
03:27
Fix compiler warnings. Fix a harmless off-by-one error in the solver. check-in: 10021941 user: drh tags: nextgen-query-plan-exp
2013-06-18
20:06
Adjustments to testcase() macros for improved testability. check-in: 4fbb0c4d user: drh tags: nextgen-query-plan-exp
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/prepare.c.

   588    588         }
   589    589       }
   590    590     }
   591    591   
   592    592     sqlite3VtabUnlockList(db);
   593    593   
   594    594     pParse->db = db;
   595         -  pParse->nQueryLoop = 1;
          595  +  pParse->nQueryLoop = 0;  /* Logarithmic, so 0 really means 1 */
   596    596     if( nBytes>=0 && (nBytes==0 || zSql[nBytes-1]!=0) ){
   597    597       char *zSqlCopy;
   598    598       int mxLen = db->aLimit[SQLITE_LIMIT_SQL_LENGTH];
   599    599       testcase( nBytes==mxLen );
   600    600       testcase( nBytes==mxLen+1 );
   601    601       if( nBytes>mxLen ){
   602    602         sqlite3Error(db, SQLITE_TOOBIG, "statement too long");
................................................................................
   610    610         pParse->zTail = &zSql[pParse->zTail-zSqlCopy];
   611    611       }else{
   612    612         pParse->zTail = &zSql[nBytes];
   613    613       }
   614    614     }else{
   615    615       sqlite3RunParser(pParse, zSql, &zErrMsg);
   616    616     }
   617         -  assert( 1==pParse->nQueryLoop );
          617  +  assert( 0==pParse->nQueryLoop );
   618    618   
   619    619     if( db->mallocFailed ){
   620    620       pParse->rc = SQLITE_NOMEM;
   621    621     }
   622    622     if( pParse->rc==SQLITE_DONE ) pParse->rc = SQLITE_OK;
   623    623     if( pParse->checkSchema ){
   624    624       schemaIsValid(pParse);

Changes to src/where.c.

  4233   4233     int saved_nEq;                  /* Original value of pNew->u.btree.nEq */
  4234   4234     u32 saved_wsFlags;              /* Original value of pNew->wsFlags */
  4235   4235     WhereCost saved_nOut;           /* Original value of pNew->nOut */
  4236   4236     int iCol;                       /* Index of the column in the table */
  4237   4237     int rc = SQLITE_OK;             /* Return code */
  4238   4238     WhereCost nRowEst;              /* Estimated index selectivity */
  4239   4239     WhereCost rLogSize;             /* Logarithm of table size */
  4240         -  WhereTerm *pTop, *pBtm;         /* Top and bottom range constraints */
         4240  +  WhereTerm *pTop = 0, *pBtm = 0; /* Top and bottom range constraints */
  4241   4241   
  4242   4242     pNew = pBuilder->pNew;
  4243   4243     if( db->mallocFailed ) return SQLITE_NOMEM;
  4244   4244   
  4245   4245     assert( (pNew->wsFlags & WHERE_VIRTUALTABLE)==0 );
  4246   4246     assert( (pNew->wsFlags & WHERE_TOP_LIMIT)==0 );
  4247   4247     if( pNew->wsFlags & WHERE_BTM_LIMIT ){
................................................................................
  4253   4253     }
  4254   4254     if( pProbe->bUnordered ) opMask &= ~(WO_GT|WO_GE|WO_LT|WO_LE);
  4255   4255   
  4256   4256     assert( pNew->u.btree.nEq<=pProbe->nColumn );
  4257   4257     if( pNew->u.btree.nEq < pProbe->nColumn ){
  4258   4258       iCol = pProbe->aiColumn[pNew->u.btree.nEq];
  4259   4259       nRowEst = whereCost(pProbe->aiRowEst[pNew->u.btree.nEq+1]);
         4260  +    if( nRowEst==0 && pProbe->onError==OE_None ) nRowEst = 1;
  4260   4261     }else{
  4261   4262       iCol = -1;
  4262   4263       nRowEst = 0;
  4263   4264     }
  4264   4265     pTerm = whereScanInit(&scan, pBuilder->pWC, pSrc->iCursor, iCol,
  4265   4266                           opMask, pProbe);
  4266   4267     saved_nEq = pNew->u.btree.nEq;
................................................................................
  4782   4783         whereLoopInit(&sBest);
  4783   4784         pItem = pWInfo->pTabList->a + pNew->iTab;
  4784   4785         iCur = pItem->iCursor;
  4785   4786         sSubBuild = *pBuilder;
  4786   4787         sSubBuild.pOrderBy = 0;
  4787   4788         sSubBuild.pBest = &sBest;
  4788   4789   
  4789         -      for(pOrTerm=pOrWC->a; rc==SQLITE_OK && pOrTerm<pOrWCEnd; pOrTerm++){
         4790  +      for(pOrTerm=pOrWC->a; pOrTerm<pOrWCEnd; pOrTerm++){
  4790   4791           if( (pOrTerm->eOperator & WO_AND)!=0 ){
  4791   4792             sSubBuild.pWC = &pOrTerm->u.pAndInfo->wc;
  4792   4793           }else if( pOrTerm->leftCursor==iCur ){
  4793   4794             tempWC.pWInfo = pWC->pWInfo;
  4794   4795             tempWC.pOuter = pWC;
  4795   4796             tempWC.op = TK_AND;
  4796   4797             tempWC.nTerm = 1;
................................................................................
  4806   4807           if( IsVirtual(pItem->pTab) ){
  4807   4808             rc = whereLoopAddVirtual(&sSubBuild);
  4808   4809           }else
  4809   4810   #endif
  4810   4811           {
  4811   4812             rc = whereLoopAddBtree(&sSubBuild, mExtra);
  4812   4813           }
         4814  +        /* sBest.maskSelf is always zero if an error occurs */
         4815  +        assert( rc==SQLITE_OK || sBest.maskSelf==0 );
  4813   4816           if( sBest.maskSelf==0 ) break;
  4814   4817           assert( sBest.rSetup==0 );
  4815   4818           rTotal = whereCostAdd(rTotal, sBest.rRun);
  4816   4819           nRow = whereCostAdd(nRow, sBest.nOut);
  4817   4820           prereq |= sBest.prereq;
  4818   4821         }
  4819   4822         assert( pNew->nLSlot>=1 );
................................................................................
  5130   5133   #endif
  5131   5134   
  5132   5135   
  5133   5136   /*
  5134   5137   ** Given the list of WhereLoop objects on pWInfo->pLoops, this routine
  5135   5138   ** attempts to find the lowest cost path that visits each WhereLoop
  5136   5139   ** once.  This path is then loaded into the pWInfo->a[].pWLoop fields.
         5140  +**
         5141  +** Assume that the total number of output rows that will need to be sorted
         5142  +** will be nRowEst (in the 10*log2 representation).  Or, ignore sorting
         5143  +** costs if nRowEst==0.
  5137   5144   **
  5138   5145   ** Return SQLITE_OK on success or SQLITE_NOMEM of a memory allocation
  5139   5146   ** error occurs.
  5140   5147   */
  5141   5148   static int wherePathSolver(WhereInfo *pWInfo, WhereCost nRowEst){
  5142   5149     int mxChoice;             /* Maximum number of simultaneous paths tracked */
  5143   5150     int nLoop;                /* Number of terms in the join */
  5144   5151     Parse *pParse;            /* Parsing context */
  5145   5152     sqlite3 *db;              /* The database connection */
  5146   5153     int iLoop;                /* Loop counter over the terms of the join */
  5147   5154     int ii, jj;               /* Loop counters */
  5148   5155     WhereCost rCost;             /* Cost of a path */
  5149         -  WhereCost mxCost;            /* Maximum cost of a set of paths */
         5156  +  WhereCost mxCost = 0;        /* Maximum cost of a set of paths */
  5150   5157     WhereCost rSortCost;         /* Cost to do a sort */
  5151   5158     int nTo, nFrom;           /* Number of valid entries in aTo[] and aFrom[] */
  5152   5159     WherePath *aFrom;         /* All nFrom paths at the previous level */
  5153   5160     WherePath *aTo;           /* The nTo best paths at the current level */
  5154   5161     WherePath *pFrom;         /* An element of aFrom[] that we are working on */
  5155   5162     WherePath *pTo;           /* An element of aTo[] that we are working on */
  5156   5163     WhereLoop *pWLoop;        /* One of the WhereLoop objects */
................................................................................
  5735   5742         }
  5736   5743       }
  5737   5744   #endif
  5738   5745     
  5739   5746       wherePathSolver(pWInfo, 0);
  5740   5747       if( db->mallocFailed ) goto whereBeginError;
  5741   5748       if( pWInfo->pOrderBy ){
  5742         -       wherePathSolver(pWInfo, pWInfo->nRowOut);
         5749  +       wherePathSolver(pWInfo, pWInfo->nRowOut+1);
  5743   5750          if( db->mallocFailed ) goto whereBeginError;
  5744   5751       }
  5745   5752     }
  5746   5753     if( pWInfo->pOrderBy==0 && (db->flags & SQLITE_ReverseOrder)!=0 ){
  5747   5754        pWInfo->revMask = (Bitmask)(-1);
  5748   5755     }
  5749   5756     if( pParse->nErr || NEVER(db->mallocFailed) ){