]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Experimental code-generator changes to utilize new opcodes for sorting.
authordrh <drh@noemail.net>
Thu, 1 Sep 2011 15:32:47 +0000 (15:32 +0000)
committerdrh <drh@noemail.net>
Thu, 1 Sep 2011 15:32:47 +0000 (15:32 +0000)
FossilOrigin-Name: bab2e560f6cb989c83a96aad60f666960ede7abe

manifest
manifest.uuid
src/select.c
src/sqliteInt.h
src/vdbe.c
src/vdbeInt.h
src/vdbeaux.c

index cf95f75fde56c3958ade9222baa8e2476e0e63b2..b233b883968b61ecc8ff8c01c8cfdf0d411aead3 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Avoid\susing\suninitialized\svariables\safter\sfailures\sin\sthe\smerge\ssort\scode.
-D 2011-08-31T23:57:22.695
+C Experimental\scode-generator\schanges\sto\sutilize\snew\sopcodes\sfor\ssorting.
+D 2011-09-01T15:32:47.873
 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
 F Makefile.in d314143fa6be24828021d3f583ad37d9afdce505
 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -179,11 +179,11 @@ F src/printf.c 585a36b6a963df832cfb69505afa3a34ed5ef8a1
 F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50
 F src/resolve.c 36368f44569208fa074e61f4dd0b6c4fb60ca2b4
 F src/rowset.c 69afa95a97c524ba6faf3805e717b5b7ae85a697
-F src/select.c 14552e9ff4b27ec027a43fafb62ea5d049cd2809
+F src/select.c 20bef6860c5f69c6a90666b4968d4c5cb88056c0
 F src/shell.c bbe7818ff5bc8614105ceb81ad67b8bdc0b671dd
 F src/sqlite.h.in 0a6c9c23337fd1352c5c75a613ff9533aa7d91cb
 F src/sqlite3ext.h 1a1a4f784aa9c3b00edd287940197de52487cd93
-F src/sqliteInt.h 86a4fdb3ba9ab31d98b266797606f30fefe5b8a9
+F src/sqliteInt.h f6debf9a9eb8463ab2ef8be4b2b740ea9af5afba
 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d
 F src/status.c 7ac64842c86cec2fc1a1d0e5c16d3beb8ad332bf
 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e
@@ -238,11 +238,11 @@ F src/update.c 74a6cfb34e9732c1e2a86278b229913b4b51eeec
 F src/utf.c c53eb7404b3eb5c1cbb5655c6a7a0e0ce6bd50f0
 F src/util.c 06302ffd2b80408d4f6c7af71f7090e0cf8d8ff7
 F src/vacuum.c 05513dca036a1e7848fe18d5ed1265ac0b32365e
-F src/vdbe.c 9165b35da939f4a66c7e68b0c6d3f017ca982cb1
+F src/vdbe.c 9260e5138855399bea2611a29da336688bfa1b79
 F src/vdbe.h c1eeedacab6bcf1e7c2cf8203ba9763a616f9a86
-F src/vdbeInt.h 70767f6504aac4f0057ec2a55738470a890789ac
+F src/vdbeInt.h 51a902e12c7d571e3b516e5407e30f996494aafe
 F src/vdbeapi.c 11dc47987abacb76ad016dcf5abc0dc422482a98
-F src/vdbeaux.c de1e4cab060a45df9ebee68dd63543d14559f0e7
+F src/vdbeaux.c e58acbc5ea3823922a0cd8fa21f94f39af51ee88
 F src/vdbeblob.c f024f0bf420f36b070143c32b15cc7287341ffd3
 F src/vdbemem.c 5e6effb96dd53d233361cbfaa3f0a43b9af689e9
 F src/vdbesort.c f3d043a1bab7409d4a23cd7a35287c3ac440a167
@@ -961,7 +961,10 @@ F tool/symbols.sh caaf6ccc7300fd43353318b44524853e222557d5
 F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06
 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
 F tool/warnings.sh b7fdb2cc525f5ef4fa43c80e771636dd3690f9d2
-P 70b5b309568ac55565558d5456aca1e431cfd26b
-R 09e04eb9163c46e529a61f2438cff2a1
+P 2869ed28299b1c9f355ecc24635830f7f1249126
+R e08eee2093eee8a9fb40d6646a4c9c76
+T *branch * merge-sort
+T *sym-merge-sort *
+T -sym-trunk *
 U drh
-Z bdb2832352809bf647849d42b7aa6060
+Z c5e8ef1774d371c2becb6d0057b76727
index 67e9d42efed87d537f8347c3683e6be46a87719a..c35621c65925fff37968078208cb50bfe884d53b 100644 (file)
@@ -1 +1 @@
-2869ed28299b1c9f355ecc24635830f7f1249126
\ No newline at end of file
+bab2e560f6cb989c83a96aad60f666960ede7abe
\ No newline at end of file
index 2e44522c6d5668ea13c6bdd3fb9ee0ee2e71dcc9..88253265941e009a655131d598e249776bfe4f83 100644 (file)
@@ -419,12 +419,18 @@ static void pushOntoSorter(
   int nExpr = pOrderBy->nExpr;
   int regBase = sqlite3GetTempRange(pParse, nExpr+2);
   int regRecord = sqlite3GetTempReg(pParse);
+  int op;
   sqlite3ExprCacheClear(pParse);
   sqlite3ExprCodeExprList(pParse, pOrderBy, regBase, 0);
   sqlite3VdbeAddOp2(v, OP_Sequence, pOrderBy->iECursor, regBase+nExpr);
   sqlite3ExprCodeMove(pParse, regData, regBase+nExpr+1, 1);
   sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase, nExpr + 2, regRecord);
-  sqlite3VdbeAddOp2(v, OP_IdxInsert, pOrderBy->iECursor, regRecord);
+  if( pSelect->selFlags & SF_UseSorter ){
+    op = OP_SorterInsert;
+  }else{
+    op = OP_IdxInsert;
+  }
+  sqlite3VdbeAddOp2(v, op, pOrderBy->iECursor, regRecord);
   sqlite3ReleaseTempReg(pParse, regRecord);
   sqlite3ReleaseTempRange(pParse, regBase, nExpr+2);
   if( pSelect->iLimit ){
@@ -893,9 +899,20 @@ static void generateSortTail(
   }else{
     regRowid = sqlite3GetTempReg(pParse);
   }
-  addr = 1 + sqlite3VdbeAddOp2(v, OP_Sort, iTab, addrBreak);
-  codeOffset(v, p, addrContinue);
-  sqlite3VdbeAddOp3(v, OP_Column, iTab, pOrderBy->nExpr + 1, regRow);
+  if( p->selFlags & SF_UseSorter ){
+    int regSortOut = sqlite3GetTempReg(pParse);
+    int ptab2 = pParse->nTab++;
+    sqlite3VdbeAddOp3(v, OP_OpenPseudo, ptab2, regSortOut, pOrderBy->nExpr+2);
+    addr = 1 + sqlite3VdbeAddOp2(v, OP_SorterSort, iTab, addrBreak);
+    codeOffset(v, p, addrContinue);
+    sqlite3VdbeAddOp2(v, OP_SorterData, iTab, regSortOut);
+    sqlite3VdbeAddOp3(v, OP_Column, ptab2, pOrderBy->nExpr+1, regRow);
+    sqlite3VdbeChangeP5(v, OPFLAG_CLEARCACHE);
+  }else{
+    addr = 1 + sqlite3VdbeAddOp2(v, OP_Sort, iTab, addrBreak);
+    codeOffset(v, p, addrContinue);
+    sqlite3VdbeAddOp3(v, OP_Column, iTab, pOrderBy->nExpr+1, regRow);
+  }
   switch( eDest ){
     case SRT_Table:
     case SRT_EphemTab: {
@@ -948,7 +965,11 @@ static void generateSortTail(
   /* The bottom of the loop
   */
   sqlite3VdbeResolveLabel(v, addrContinue);
-  sqlite3VdbeAddOp2(v, OP_Next, iTab, addr);
+  if( p->selFlags & SF_UseSorter ){
+    sqlite3VdbeAddOp2(v, OP_SorterNext, iTab, addr);
+  }else{
+    sqlite3VdbeAddOp2(v, OP_Next, iTab, addr);
+  }
   sqlite3VdbeResolveLabel(v, addrBreak);
   if( eDest==SRT_Output || eDest==SRT_Coroutine ){
     sqlite3VdbeAddOp2(v, OP_Close, pseudoTab, 0);
@@ -3914,6 +3935,10 @@ int sqlite3Select(
   iEnd = sqlite3VdbeMakeLabel(v);
   p->nSelectRow = (double)LARGEST_INT64;
   computeLimitRegisters(pParse, p, iEnd);
+  if( p->iLimit==0 && addrSortIndex>=0 ){
+    sqlite3VdbeGetOp(v, addrSortIndex)->opcode = OP_SorterOpen;
+    p->selFlags |= SF_UseSorter;
+  }
 
   /* Open a virtual index to use for the distinct set.
   */
index 5934c74316f3d0d4c4da00268b5026c42c9d7f0f..18beb32e0f4f7a96542d872b84943685ffdaccdb 100644 (file)
@@ -2082,6 +2082,7 @@ struct Select {
 #define SF_UsesEphemeral   0x0008  /* Uses the OpenEphemeral opcode */
 #define SF_Expanded        0x0010  /* sqlite3SelectExpand() called on this */
 #define SF_HasTypeInfo     0x0020  /* FROM subqueries have Table metadata */
+#define SF_UseSorter       0x0040  /* Sort using a sorter */
 
 
 /*
index e7c7ed7fe2544b26db4d8e369d1207472b6dbf3c..f4ae4c44a615bff4aa6326e6308ee53b5fd17fae 100644 (file)
@@ -3170,6 +3170,7 @@ case OP_OpenWrite: {
 */
 case OP_OpenSorter: 
 case OP_OpenAutoindex: 
+case OP_SorterOpen:
 case OP_OpenEphemeral: {
   VdbeCursor *pCx;
   static const int vfsFlags = 
@@ -3214,6 +3215,7 @@ case OP_OpenEphemeral: {
   }
   pCx->isOrdered = (pOp->p5!=BTREE_UNORDERED);
   pCx->isIndex = !pCx->isTable;
+  pCx->isSorter = pOp->opcode==OP_SorterOpen;
 #ifndef SQLITE_OMIT_MERGE_SORT
   if( rc==SQLITE_OK && pOp->opcode==OP_OpenSorter ){
     rc = sqlite3VdbeSorterInit(db, pCx);
@@ -4090,6 +4092,7 @@ case OP_ResetCount: {
 ** If the P1 cursor must be pointing to a valid row (not a NULL row)
 ** of a real table, not a pseudo-table.
 */
+case OP_SorterData:
 case OP_RowKey:
 case OP_RowData: {
   VdbeCursor *pC;
@@ -4103,11 +4106,12 @@ case OP_RowData: {
   /* Note that RowKey and RowData are really exactly the same instruction */
   assert( pOp->p1>=0 && pOp->p1<p->nCursor );
   pC = p->apCsr[pOp->p1];
-  assert( pC->isTable || pOp->opcode==OP_RowKey );
+  assert( pC->isTable || pOp->opcode!=OP_RowData );
   assert( pC->isIndex || pOp->opcode==OP_RowData );
   assert( pC!=0 );
   assert( pC->nullRow==0 );
   assert( pC->pseudoTableReg==0 );
+  assert( pC->isSorter==(pOp->opcode==OP_SorterData) );
 
   if( isSorter(pC) ){
     assert( pOp->opcode==OP_RowKey );
@@ -4271,6 +4275,7 @@ case OP_Last: {        /* jump */
 ** regression tests can determine whether or not the optimizer is
 ** correctly optimizing out sorts.
 */
+case OP_SorterSort:    /* jump */
 case OP_Sort: {        /* jump */
 #ifdef SQLITE_TEST
   sqlite3_sort_count++;
@@ -4295,6 +4300,7 @@ case OP_Rewind: {        /* jump */
   assert( pOp->p1>=0 && pOp->p1<p->nCursor );
   pC = p->apCsr[pOp->p1];
   assert( pC!=0 );
+  assert( pC->isSorter==(pOp->opcode==OP_SorterSort) );
   res = 1;
   if( isSorter(pC) ){
     rc = sqlite3VdbeSorterRewind(db, pC, &res);
@@ -4347,6 +4353,7 @@ case OP_Rewind: {        /* jump */
 ** If P5 is positive and the jump is taken, then event counter
 ** number P5-1 in the prepared statement is incremented.
 */
+case OP_SorterNext:    /* jump */
 case OP_Prev:          /* jump */
 case OP_Next: {        /* jump */
   VdbeCursor *pC;
@@ -4359,6 +4366,7 @@ case OP_Next: {        /* jump */
   if( pC==0 ){
     break;  /* See ticket #2273 */
   }
+  assert( pC->isSorter==(pOp->opcode==OP_SorterNext) );
   if( isSorter(pC) ){
     assert( pOp->opcode==OP_Next );
     rc = sqlite3VdbeSorterNext(db, pC, &res);
@@ -4395,6 +4403,7 @@ case OP_Next: {        /* jump */
 ** This instruction only works for indices.  The equivalent instruction
 ** for tables is OP_Insert.
 */
+case OP_SorterInsert:
 case OP_IdxInsert: {        /* in2 */
   VdbeCursor *pC;
   BtCursor *pCrsr;
@@ -4404,6 +4413,7 @@ case OP_IdxInsert: {        /* in2 */
   assert( pOp->p1>=0 && pOp->p1<p->nCursor );
   pC = p->apCsr[pOp->p1];
   assert( pC!=0 );
+  assert( pC->isSorter==(pOp->opcode==OP_SorterInsert) );
   pIn2 = &aMem[pOp->p2];
   assert( pIn2->flags & MEM_Blob );
   pCrsr = pC->pCursor;
index 846d807075c8910341bd566465203fb2096894c3..70d80c9d3897b4655086b731e6826fc36c986fba 100644 (file)
@@ -59,6 +59,7 @@ struct VdbeCursor {
   Bool isTable;         /* True if a table requiring integer keys */
   Bool isIndex;         /* True if an index containing keys only - no data */
   Bool isOrdered;       /* True if the underlying table is BTREE_UNORDERED */
+  Bool isSorter;        /* True if a new-style sorter */
   sqlite3_vtab_cursor *pVtabCursor;  /* The cursor for a virtual table */
   const sqlite3_module *pModule;     /* Module for cursor pVtabCursor */
   i64 seqCount;         /* Sequence counter */
index 053d89f3b5f270a3cef75281eb23286f0b67ae32..f622e8d09a3529b1a65e7a5d6cb78ab2a1fb0300 100644 (file)
@@ -433,7 +433,7 @@ static void resolveP2Values(Vdbe *p, int *pMaxFuncArgs){
       n = pOp[-1].p1;
       if( n>nMaxArgs ) nMaxArgs = n;
 #endif
-    }else if( opcode==OP_Next ){
+    }else if( opcode==OP_Next || opcode==OP_SorterNext ){
       pOp->p4.xAdvance = sqlite3BtreeNext;
       pOp->p4type = P4_ADVANCE;
     }else if( opcode==OP_Prev ){