/ Check-in [43c59c85]
Login

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

Overview
Comment:Fix a buffer overrun in the previous commit.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | query-planner-fix
Files: files | file ages | folders
SHA1: 43c59c85436dc8001c81f4aac7f5231b13d741cb
User & Date: dan 2014-08-08 17:25:33
Context
2014-08-08
17:49
Improvements to the way the query planner handles sorting costs, so that very large sorting costs do not overwhelm the loop costs. check-in: bdaa6947 user: drh tags: trunk
17:25
Fix a buffer overrun in the previous commit. Closed-Leaf check-in: 43c59c85 user: dan tags: query-planner-fix
16:52
Because SQLite internally calculates query plan costs using a logarithmic scale, very large estimated sorting costs can cause all other estimated costs to be rounded down to zero. In these cases break ties between plans with the same total cost by comparing the costs with sorting excluded. This is an alternative fix for the problem addressed by [2af630c572]. check-in: 299b9570 user: dan tags: query-planner-fix
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/where.c.

  5467   5467     WherePath *aTo;           /* The nTo best paths at the current level */
  5468   5468     WherePath *pFrom;         /* An element of aFrom[] that we are working on */
  5469   5469     WherePath *pTo;           /* An element of aTo[] that we are working on */
  5470   5470     WhereLoop *pWLoop;        /* One of the WhereLoop objects */
  5471   5471     WhereLoop **pX;           /* Used to divy up the pSpace memory */
  5472   5472     LogEst *aSortCost = 0;    /* Sorting and partial sorting costs */
  5473   5473     char *pSpace;             /* Temporary memory used by this routine */
         5474  +  int nSpace;               /* Bytes of space allocated at pSpace */
  5474   5475   
  5475   5476     pParse = pWInfo->pParse;
  5476   5477     db = pParse->db;
  5477   5478     nLoop = pWInfo->nLevel;
  5478   5479     /* TUNING: For simple queries, only the best path is tracked.
  5479   5480     ** For 2-way joins, the 5 best paths are followed.
  5480   5481     ** For joins of 3 or more tables, track the 10 best paths */
................................................................................
  5490   5491     if( pWInfo->pOrderBy==0 || nRowEst==0 ){
  5491   5492       nOrderBy = 0;
  5492   5493     }else{
  5493   5494       nOrderBy = pWInfo->pOrderBy->nExpr;
  5494   5495     }
  5495   5496   
  5496   5497     /* Allocate and initialize space for aTo, aFrom and aSortCost[] */
  5497         -  ii = (sizeof(WherePath)+sizeof(WhereLoop*)*nLoop)*mxChoice*2;
  5498         -  ii += sizeof(LogEst) * nOrderBy;
  5499         -  pSpace = sqlite3DbMallocRaw(db, ii);
         5498  +  nSpace = (sizeof(WherePath)+sizeof(WhereLoop*)*nLoop)*mxChoice*2;
         5499  +  nSpace += sizeof(LogEst) * nOrderBy;
         5500  +  pSpace = sqlite3DbMallocRaw(db, nSpace);
  5500   5501     if( pSpace==0 ) return SQLITE_NOMEM;
  5501   5502     aTo = (WherePath*)pSpace;
  5502   5503     aFrom = aTo+mxChoice;
  5503   5504     memset(aFrom, 0, sizeof(aFrom[0]));
  5504   5505     pX = (WhereLoop**)(aFrom+mxChoice);
  5505   5506     for(ii=mxChoice*2, pFrom=aTo; ii>0; ii--, pFrom++, pX += nLoop){
  5506   5507       pFrom->aLoop = pX;
................................................................................
  5509   5510       /* If there is an ORDER BY clause and it is not being ignored, set up
  5510   5511       ** space for the aSortCost[] array. Each element of the aSortCost array
  5511   5512       ** is either zero - meaning it has not yet been initialized - or the
  5512   5513       ** cost of sorting nRowEst rows of data where the first X terms of
  5513   5514       ** the ORDER BY clause are already in order, where X is the array 
  5514   5515       ** index.  */
  5515   5516       aSortCost = (LogEst*)pX;
  5516         -    memset(aSortCost, 0, sizeof(LogEst) * (nOrderBy+1));
         5517  +    memset(aSortCost, 0, sizeof(LogEst) * nOrderBy);
  5517   5518     }
         5519  +  assert( aSortCost==0 || &pSpace[nSpace]==(char*)&aSortCost[nOrderBy] );
         5520  +  assert( aSortCost!=0 || &pSpace[nSpace]==(char*)pX );
  5518   5521   
  5519   5522     /* Seed the search with a single WherePath containing zero WhereLoops.
  5520   5523     **
  5521   5524     ** TUNING: Do not let the number of iterations go above 25.  If the cost
  5522   5525     ** of computing an automatic index is not paid back within the first 25
  5523   5526     ** rows, then do not use the automatic index. */
  5524   5527     aFrom[0].nRow = MIN(pParse->nQueryLoop, 46);  assert( 46==sqlite3LogEst(25) );