1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-08-08 14:02:16 +03:00

Experimental code-generator changes to utilize new opcodes for sorting.

FossilOrigin-Name: bab2e560f6cb989c83a96aad60f666960ede7abe
This commit is contained in:
drh
2011-09-01 15:32:47 +00:00
parent 96862072b8
commit c6aff30ca4
7 changed files with 58 additions and 18 deletions

View File

@@ -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

View File

@@ -1 +1 @@
2869ed28299b1c9f355ecc24635830f7f1249126
bab2e560f6cb989c83a96aad60f666960ede7abe

View 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.
*/

View 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 */
/*

View 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;

View 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 */

View 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 ){