/ Check-in [f1cac24f]
Login

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

Overview
Comment:Fix the Parse.nQueryLoop state variable to work with NGQP.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | nextgen-query-plan-exp
Files: files | file ages | folders
SHA1: f1cac24f06b9c71cfa472fdcf2da4cd8689a7cc3
User & Date: drh 2013-06-11 13:30:04
Context
2013-06-11
18:59
Improved processing of DISTINCT. check-in: ba897100 user: drh tags: nextgen-query-plan-exp
13:30
Fix the Parse.nQueryLoop state variable to work with NGQP. check-in: f1cac24f user: drh tags: nextgen-query-plan-exp
02:36
Use a logarithmic rather than linear cost and row-count measures. Do not report row count estimates in EQP output. check-in: b777b109 user: drh tags: nextgen-query-plan-exp
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/expr.c.

  1592   1592       }
  1593   1593     }
  1594   1594   
  1595   1595     if( eType==0 ){
  1596   1596       /* Could not found an existing table or index to use as the RHS b-tree.
  1597   1597       ** We will have to generate an ephemeral table to do the job.
  1598   1598       */
  1599         -    double savedNQueryLoop = pParse->nQueryLoop;
         1599  +    u32 savedNQueryLoop = pParse->nQueryLoop;
  1600   1600       int rMayHaveNull = 0;
  1601   1601       eType = IN_INDEX_EPH;
  1602   1602       if( prNotFound ){
  1603   1603         *prNotFound = rMayHaveNull = ++pParse->nMem;
  1604   1604         sqlite3VdbeAddOp2(v, OP_Null, 0, *prNotFound);
  1605   1605       }else{
  1606         -      testcase( pParse->nQueryLoop>(double)1 );
  1607         -      pParse->nQueryLoop = (double)1;
         1606  +      testcase( pParse->nQueryLoop>1 );
         1607  +      pParse->nQueryLoop = 1;
  1608   1608         if( pX->pLeft->iColumn<0 && !ExprHasAnyProperty(pX, EP_xIsSelect) ){
  1609   1609           eType = IN_INDEX_ROWID;
  1610   1610         }
  1611   1611       }
  1612   1612       sqlite3CodeSubselect(pParse, pX, rMayHaveNull, eType==IN_INDEX_ROWID);
  1613   1613       pParse->nQueryLoop = savedNQueryLoop;
  1614   1614     }else{

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 = (double)1;
          595  +  pParse->nQueryLoop = 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==(int)pParse->nQueryLoop );
          617  +  assert( 1==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/sqliteInt.h.

  2222   2222     TableLock *aTableLock; /* Required table locks for shared-cache mode */
  2223   2223   #endif
  2224   2224     AutoincInfo *pAinc;  /* Information about AUTOINCREMENT counters */
  2225   2225   
  2226   2226     /* Information used while coding trigger programs. */
  2227   2227     Parse *pToplevel;    /* Parse structure for main program (or NULL) */
  2228   2228     Table *pTriggerTab;  /* Table triggers are being coded for */
  2229         -  u32 nQueryLoop;      /* Estimated number of iterations of a query */
         2229  +  u32 grep nQueryLoop; /* Est number of iterations of a query (10*log2(N)) */
  2230   2230     u32 oldmask;         /* Mask of old.* columns referenced */
  2231   2231     u32 newmask;         /* Mask of new.* columns referenced */
  2232   2232     u8 eTriggerOp;       /* TK_UPDATE, TK_INSERT or TK_DELETE */
  2233   2233     u8 eOrconf;          /* Default ON CONFLICT policy for trigger steps */
  2234   2234     u8 disableTriggers;  /* True to disable triggers */
  2235   2235   
  2236   2236     /* Above is constant between recursions.  Below is reset before and after

Changes to src/where.c.

   354    354     int iTop;                 /* The very beginning of the WHERE loop */
   355    355     int iContinue;            /* Jump here to continue with next record */
   356    356     int iBreak;               /* Jump here to break out of the loop */
   357    357     int nLevel;               /* Number of nested loop */
   358    358     WhereMaskSet sMaskSet;    /* Map cursor numbers to bitmasks */
   359    359     WhereClause sWC;          /* Decomposition of the WHERE clause */
   360    360     WhereLoop *pLoops;        /* List of all WhereLoop objects */
   361         -  WhereCost savedNQueryLoop; /* pParse->nQueryLoop outside the WHERE loop */
          361  +  int savedNQueryLoop;      /* pParse->nQueryLoop outside the WHERE loop */
   362    362     WhereCost nRowOut;        /* Estimated number of output rows */
   363    363     WhereLevel a[1];          /* Information about each nest loop in WHERE */
   364    364   };
   365    365   
   366    366   /*
   367    367   ** Bitmasks for the operators that indices are able to exploit.  An
   368    368   ** OR-ed combination of these values can be used when searching for
................................................................................
  3095   3095             ((flags & WHERE_TEMP_INDEX)?"": pLoop->u.btree.pIndex->zName),
  3096   3096             zWhere
  3097   3097         );
  3098   3098         sqlite3DbFree(db, zWhere);
  3099   3099       }else if( (flags & WHERE_IPK)!=0 && (flags & WHERE_CONSTRAINT)!=0 ){
  3100   3100         zMsg = sqlite3MAppendf(db, zMsg, "%s USING INTEGER PRIMARY KEY", zMsg);
  3101   3101   
  3102         -      if( flags&WHERE_COLUMN_EQ ){
         3102  +      if( flags&(WHERE_COLUMN_EQ|WHERE_COLUMN_IN) ){
  3103   3103           zMsg = sqlite3MAppendf(db, zMsg, "%s (rowid=?)", zMsg);
  3104   3104         }else if( (flags&WHERE_BOTH_LIMIT)==WHERE_BOTH_LIMIT ){
  3105   3105           zMsg = sqlite3MAppendf(db, zMsg, "%s (rowid>? AND rowid<?)", zMsg);
  3106   3106         }else if( flags&WHERE_BTM_LIMIT ){
  3107   3107           zMsg = sqlite3MAppendf(db, zMsg, "%s (rowid>?)", zMsg);
  3108   3108         }else if( flags&WHERE_TOP_LIMIT ){
  3109   3109           zMsg = sqlite3MAppendf(db, zMsg, "%s (rowid<?)", zMsg);
................................................................................
  4428   4428       pProbe = &sPk;
  4429   4429     }
  4430   4430     rSize = whereCostFromInt(pSrc->pTab->nRowEst);
  4431   4431     rLogSize = estLog(rSize);
  4432   4432   
  4433   4433     /* Automatic indexes */
  4434   4434     if( !pBuilder->pBest
  4435         -   && pTabList->nSrc>1
         4435  +//   && pTabList->nSrc>1
  4436   4436      && (pWInfo->pParse->db->flags & SQLITE_AutoIndex)!=0 
  4437   4437      && !pSrc->viaCoroutine
  4438   4438      && !pSrc->notIndexed
  4439   4439      && !pSrc->isCorrelated
  4440   4440     ){
  4441   4441       /* Generate auto-index WhereLoops */
  4442   4442       WhereClause *pWC = pBuilder->pWC;
................................................................................
  5070   5070     memset(aFrom, 0, sizeof(aFrom[0]));
  5071   5071     pX = (WhereLoop**)(aFrom+mxChoice);
  5072   5072     for(ii=mxChoice*2, pFrom=aTo; ii>0; ii--, pFrom++, pX += nLoop){
  5073   5073       pFrom->aLoop = pX;
  5074   5074     }
  5075   5075   
  5076   5076     /* Seed the search with a single WherePath containing zero WhereLoops */
  5077         -  aFrom[0].nRow = 0;
         5077  +  aFrom[0].nRow = pWInfo->pParse->nQueryLoop;
  5078   5078     nFrom = 1;
  5079   5079   
  5080   5080     /* Precompute the cost of sorting the final result set, if the caller
  5081   5081     ** to sqlite3WhereBegin() was concerned about sorting */
  5082   5082     rSortCost = 0;
  5083   5083     if( pWInfo->pOrderBy==0 || nRowEst==0 ){
  5084   5084       aFrom[0].isOrderedValid = 1;
................................................................................
  5611   5611       }
  5612   5612       for(ii=0; ii<nTabList; ii++){
  5613   5613         whereLoopPrint(pWInfo->a[ii].pWLoop, pTabList);
  5614   5614       }
  5615   5615     }
  5616   5616   #endif
  5617   5617     WHERETRACE(("*** Optimizer Finished ***\n"));
         5618  +  pWInfo->pParse->nQueryLoop += pWInfo->nRowOut;
  5618   5619   
  5619   5620   #if 0  /* FIXME: Add this back in? */
  5620   5621     /* If the caller is an UPDATE or DELETE statement that is requesting
  5621   5622     ** to use a one-pass algorithm, determine if this is appropriate.
  5622   5623     ** The one-pass algorithm only works if the WHERE clause constraints
  5623   5624     ** the statement to update a single row.
  5624   5625     */