/ Check-in [7ce2daaf]
Login

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

Overview
Comment:Make it possible for block-sort to use the OP_SorterOpen sorter in addition to a generic OP_OpenEphemeral.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | orderby-planning
Files: files | file ages | folders
SHA1: 7ce2daafd39a117041bfdd0a7132e2764fe7a74b
User & Date: drh 2014-03-19 17:41:36
Context
2014-03-19
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
17:41
Make it possible for block-sort to use the OP_SorterOpen sorter in addition to a generic OP_OpenEphemeral. check-in: 7ce2daaf user: drh tags: orderby-planning
16:56
Fix a problem in the block-sort logic that can arise if the VDBE opcode array is resized while the block-sort logic is being coded. "make test" now runs to completion, though there are still 17 failures. check-in: 62f3a220 user: drh tags: orderby-planning
Changes
Hide Diffs Side-by-Side Diffs Show Whitespace Changes Patch

Changes to src/select.c.

   484    484   
   485    485       regPrevKey = pParse->nMem+1;
   486    486       pParse->nMem += pSort->nOBSat;
   487    487       nKey = nExpr - pSort->nOBSat + 1;
   488    488       addrFirst = sqlite3VdbeAddOp1(v, OP_IfNot, regBase+nExpr); VdbeCoverage(v);
   489    489       sqlite3VdbeAddOp3(v, OP_Compare, regPrevKey, regBase, pSort->nOBSat);
   490    490       pOp = sqlite3VdbeGetOp(v, pSort->addrSortIndex);
   491         -    pOp->opcode = OP_OpenEphemeral;
   492         -    pSort->sortFlags &= ~SORTFLAG_UseSorter;
   493    491       pOp->p2 = nKey + 1;
   494    492       sqlite3VdbeChangeP4(v, -1, (char*)pOp->p4.pKeyInfo, P4_KEYINFO);
   495    493       pOp->p4.pKeyInfo = keyInfoFromExprList(pParse, pSort->pOrderBy, nOBSat, 1);
   496    494       addrJmp = sqlite3VdbeCurrentAddr(v);
   497    495       sqlite3VdbeAddOp3(v, OP_Jump, addrJmp+1, 0, addrJmp+1); VdbeCoverage(v);
   498    496       pSort->labelBkOut = sqlite3VdbeMakeLabel(v);
   499    497       pSort->regReturn = ++pParse->nMem;
   500    498       sqlite3VdbeAddOp2(v, OP_Gosub, pSort->regReturn, pSort->labelBkOut);
   501         -    sqlite3VdbeAddOp1(v, OP_ClearEphem, pSort->iECursor);
          499  +    sqlite3VdbeAddOp1(v, OP_ResetSorter, pSort->iECursor);
   502    500       sqlite3VdbeJumpHere(v, addrFirst);
   503    501       sqlite3VdbeAddOp3(v, OP_Move, regBase, regPrevKey, pSort->nOBSat);
   504    502       sqlite3VdbeJumpHere(v, addrJmp);
   505    503     }
   506    504     if( pSort->sortFlags & SORTFLAG_UseSorter ){
   507    505       op = OP_SorterInsert;
   508    506     }else{

Changes to src/vdbe.c.

  4868   4868         memAboutToChange(p, &aMem[pOp->p3]);
  4869   4869         aMem[pOp->p3].u.i += nChange;
  4870   4870       }
  4871   4871     }
  4872   4872     break;
  4873   4873   }
  4874   4874   
  4875         -/* Opcode: ClearEphem P1 * * * *
         4875  +/* Opcode: ResetSorter P1 * * * *
  4876   4876   **
  4877         -** Delete all contents from the ephemeral table that is open on cursor P1.
         4877  +** Delete all contents from the ephemeral table or sorter
         4878  +** that is open on cursor P1.
  4878   4879   **
  4879         -** See also: Clear, Destroy
         4880  +** This opcode only works for cursors used for sorting and
         4881  +** opened with OP_OpenEphemeral or OP_SorterOpen.
  4880   4882   */
  4881         -case OP_ClearEphem: {
         4883  +case OP_ResetSorter: {
  4882   4884     VdbeCursor *pC;
  4883   4885    
  4884   4886     assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  4885   4887     pC = p->apCsr[pOp->p1];
  4886   4888     assert( pC!=0 );
         4889  +  if( pC->pSorter ){
         4890  +    sqlite3VdbeSorterReset(db, pC->pSorter);
         4891  +  }else{
  4887   4892     assert( pC->isEphemeral );
  4888   4893     rc = sqlite3BtreeClearTableOfCursor(pC->pCursor);
         4894  +  }
  4889   4895     break;
  4890   4896   }
  4891   4897   
  4892   4898   /* Opcode: CreateTable P1 P2 * * *
  4893   4899   ** Synopsis: r[P2]=root iDb=P1
  4894   4900   **
  4895   4901   ** Allocate a new table in the main database file if P1==0 or in the

Changes to src/vdbeInt.h.

   434    434   int sqlite3VdbeMemGrow(Mem *pMem, int n, int preserve);
   435    435   int sqlite3VdbeCloseStatement(Vdbe *, int);
   436    436   void sqlite3VdbeFrameDelete(VdbeFrame*);
   437    437   int sqlite3VdbeFrameRestore(VdbeFrame *);
   438    438   int sqlite3VdbeTransferError(Vdbe *p);
   439    439   
   440    440   int sqlite3VdbeSorterInit(sqlite3 *, VdbeCursor *);
          441  +void sqlite3VdbeSorterReset(sqlite3 *, VdbeSorter *);
   441    442   void sqlite3VdbeSorterClose(sqlite3 *, VdbeCursor *);
   442    443   int sqlite3VdbeSorterRowkey(const VdbeCursor *, Mem *);
   443    444   int sqlite3VdbeSorterNext(sqlite3 *, const VdbeCursor *, int *);
   444    445   int sqlite3VdbeSorterRewind(sqlite3 *, const VdbeCursor *, int *);
   445    446   int sqlite3VdbeSorterWrite(sqlite3 *, const VdbeCursor *, Mem *);
   446    447   int sqlite3VdbeSorterCompare(const VdbeCursor *, Mem *, int, int *);
   447    448   

Changes to src/vdbesort.c.

   501    501     for(p=pRecord; p; p=pNext){
   502    502       pNext = p->pNext;
   503    503       sqlite3DbFree(db, p);
   504    504     }
   505    505   }
   506    506   
   507    507   /*
   508         -** Free any cursor components allocated by sqlite3VdbeSorterXXX routines.
          508  +** Reset a sorting cursor back to its original empty state.
   509    509   */
   510         -void sqlite3VdbeSorterClose(sqlite3 *db, VdbeCursor *pCsr){
   511         -  VdbeSorter *pSorter = pCsr->pSorter;
   512         -  if( pSorter ){
          510  +void sqlite3VdbeSorterReset(sqlite3 *db, VdbeSorter *pSorter){
   513    511       if( pSorter->aIter ){
   514    512         int i;
   515    513         for(i=0; i<pSorter->nTree; i++){
   516    514           vdbeSorterIterZero(db, &pSorter->aIter[i]);
   517    515         }
   518    516         sqlite3DbFree(db, pSorter->aIter);
          517  +    pSorter->aIter = 0;
   519    518       }
   520    519       if( pSorter->pTemp1 ){
   521    520         sqlite3OsCloseFree(pSorter->pTemp1);
          521  +    pSorter->pTemp1 = 0;
   522    522       }
   523    523       vdbeSorterRecordFree(db, pSorter->pRecord);
          524  +  pSorter->pRecord = 0;
          525  +  pSorter->iWriteOff = 0;
          526  +  pSorter->iReadOff = 0;
          527  +  pSorter->nInMemory = 0;
          528  +  pSorter->nTree = 0;
          529  +  pSorter->nPMA = 0;
          530  +  pSorter->aTree = 0;
          531  +}
          532  +
          533  +
          534  +/*
          535  +** Free any cursor components allocated by sqlite3VdbeSorterXXX routines.
          536  +*/
          537  +void sqlite3VdbeSorterClose(sqlite3 *db, VdbeCursor *pCsr){
          538  +  VdbeSorter *pSorter = pCsr->pSorter;
          539  +  if( pSorter ){
          540  +    sqlite3VdbeSorterReset(db, pSorter);
   524    541       sqlite3DbFree(db, pSorter->pUnpacked);
   525    542       sqlite3DbFree(db, pSorter);
   526    543       pCsr->pSorter = 0;
   527    544     }
   528    545   }
   529    546   
   530    547   /*