/ Check-in [e4bfffb9]
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:Merge the vdbesort.c optimization from trunk.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | orderby-planning
Files: files | file ages | folders
SHA1: e4bfffb988283c077778c60696be0d285ad66c3c
User & Date: drh 2014-03-19 23:42:51
Context
2014-03-20
20:56
Merge trunk fixes for "x IN (?)" handling. check-in: eca35871 user: drh tags: orderby-planning
2014-03-19
23:42
Merge the vdbesort.c optimization from trunk. check-in: e4bfffb9 user: drh tags: orderby-planning
23:24
Fix query planner weights associated with choosing block-sorting. Fix block sorting of tables with collating functions. Fix various test cases. All "veryquick" tests are now passing, though more tests need to be added. check-in: 01afbf97 user: drh tags: orderby-planning
20:01
Avoid some unnecessary calls to sqlite3VdbeRecordUnpack() that were being made when merging data from two or more temp files together in vdbesort.c check-in: 707ea170 user: dan tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/vdbesort.c.

   969    969   */
   970    970   int sqlite3VdbeSorterNext(sqlite3 *db, const VdbeCursor *pCsr, int *pbEof){
   971    971     VdbeSorter *pSorter = pCsr->pSorter;
   972    972     int rc;                         /* Return code */
   973    973   
   974    974     if( pSorter->aTree ){
   975    975       int iPrev = pSorter->aTree[1];/* Index of iterator to advance */
   976         -    int i;                        /* Index of aTree[] to recalculate */
   977         -
   978    976       rc = vdbeSorterIterNext(db, &pSorter->aIter[iPrev]);
   979         -    for(i=(pSorter->nTree+iPrev)/2; rc==SQLITE_OK && i>0; i=i/2){
   980         -      rc = vdbeSorterDoCompare(pCsr, i);
   981         -    }
          977  +    if( rc==SQLITE_OK ){
          978  +      int i;                      /* Index of aTree[] to recalculate */
          979  +      VdbeSorterIter *pIter1;     /* First iterator to compare */
          980  +      VdbeSorterIter *pIter2;     /* Second iterator to compare */
          981  +      u8 *pKey2;                  /* To pIter2->aKey, or 0 if record cached */
          982  +
          983  +      /* Find the first two iterators to compare. The one that was just
          984  +      ** advanced (iPrev) and the one next to it in the array.  */
          985  +      pIter1 = &pSorter->aIter[(iPrev & 0xFFFE)];
          986  +      pIter2 = &pSorter->aIter[(iPrev | 0x0001)];
          987  +      pKey2 = pIter2->aKey;
          988  +
          989  +      for(i=(pSorter->nTree+iPrev)/2; i>0; i=i/2){
          990  +        /* Compare pIter1 and pIter2. Store the result in variable iRes. */
          991  +        int iRes;
          992  +        if( pIter1->pFile==0 ){
          993  +          iRes = +1;
          994  +        }else if( pIter2->pFile==0 ){
          995  +          iRes = -1;
          996  +        }else{
          997  +          vdbeSorterCompare(pCsr, 0, 
          998  +              pIter1->aKey, pIter1->nKey, pKey2, pIter2->nKey, &iRes
          999  +          );
         1000  +        }
         1001  +
         1002  +        /* If pIter1 contained the smaller value, set aTree[i] to its index.
         1003  +        ** Then set pIter2 to the next iterator to compare to pIter1. In this
         1004  +        ** case there is no cache of pIter2 in pSorter->pUnpacked, so set
         1005  +        ** pKey2 to point to the record belonging to pIter2.
         1006  +        **
         1007  +        ** Alternatively, if pIter2 contains the smaller of the two values,
         1008  +        ** set aTree[i] to its index and update pIter1. If vdbeSorterCompare()
         1009  +        ** was actually called above, then pSorter->pUnpacked now contains
         1010  +        ** a value equivalent to pIter2. So set pKey2 to NULL to prevent
         1011  +        ** vdbeSorterCompare() from decoding pIter2 again.  */
         1012  +        if( iRes<=0 ){
         1013  +          pSorter->aTree[i] = (pIter1 - pSorter->aIter);
         1014  +          pIter2 = &pSorter->aIter[ pSorter->aTree[i ^ 0x0001] ];
         1015  +          pKey2 = pIter2->aKey;
         1016  +        }else{
         1017  +          if( pIter1->pFile ) pKey2 = 0;
         1018  +          pSorter->aTree[i] = (pIter2 - pSorter->aIter);
         1019  +          pIter1 = &pSorter->aIter[ pSorter->aTree[i ^ 0x0001] ];
         1020  +        }
   982   1021   
   983         -    *pbEof = (pSorter->aIter[pSorter->aTree[1]].pFile==0);
         1022  +      }
         1023  +      *pbEof = (pSorter->aIter[pSorter->aTree[1]].pFile==0);
         1024  +    }
   984   1025     }else{
   985   1026       SorterRecord *pFree = pSorter->pRecord;
   986   1027       pSorter->pRecord = pFree->pNext;
   987   1028       pFree->pNext = 0;
   988   1029       vdbeSorterRecordFree(db, pFree);
   989   1030       *pbEof = !pSorter->pRecord;
   990   1031       rc = SQLITE_OK;