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:
23
manifest
23
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
|
||||
|
@@ -1 +1 @@
|
||||
2869ed28299b1c9f355ecc24635830f7f1249126
|
||||
bab2e560f6cb989c83a96aad60f666960ede7abe
|
35
src/select.c
35
src/select.c
@@ -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.
|
||||
*/
|
||||
|
@@ -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 */
|
||||
|
||||
|
||||
/*
|
||||
|
12
src/vdbe.c
12
src/vdbe.c
@@ -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;
|
||||
|
@@ -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 */
|
||||
|
@@ -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 ){
|
||||
|
Reference in New Issue
Block a user