diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/pragma.c | 3 | ||||
-rw-r--r-- | src/sqliteInt.h | 3 | ||||
-rw-r--r-- | src/where.c | 24 |
3 files changed, 24 insertions, 6 deletions
diff --git a/src/pragma.c b/src/pragma.c index 8497e69e2..496558e7a 100644 --- a/src/pragma.c +++ b/src/pragma.c @@ -11,7 +11,7 @@ ************************************************************************* ** This file contains code used to implement the PRAGMA command. ** -** $Id: pragma.c,v 1.203 2009/02/19 14:39:25 danielk1977 Exp $ +** $Id: pragma.c,v 1.204 2009/02/23 16:52:08 drh Exp $ */ #include "sqliteInt.h" @@ -172,6 +172,7 @@ static int flagPragma(Parse *pParse, const char *zLeft, const char *zRight){ { "empty_result_callbacks", SQLITE_NullCallback }, { "legacy_file_format", SQLITE_LegacyFileFmt }, { "fullfsync", SQLITE_FullFSync }, + { "reverse_unordered_selects", SQLITE_ReverseOrder }, #ifdef SQLITE_DEBUG { "sql_trace", SQLITE_SqlTrace }, { "vdbe_listing", SQLITE_VdbeListing }, diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 440771f92..98c3e364f 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -11,7 +11,7 @@ ************************************************************************* ** Internal interface definitions for SQLite. ** -** @(#) $Id: sqliteInt.h,v 1.834 2009/02/19 14:39:25 danielk1977 Exp $ +** @(#) $Id: sqliteInt.h,v 1.835 2009/02/23 16:52:08 drh Exp $ */ #ifndef _SQLITEINT_H_ #define _SQLITEINT_H_ @@ -847,6 +847,7 @@ struct sqlite3 { #define SQLITE_SharedCache 0x00080000 /* Cache sharing is enabled */ #define SQLITE_Vtab 0x00100000 /* There exists a virtual table */ #define SQLITE_CommitBusy 0x00200000 /* In the process of committing */ +#define SQLITE_ReverseOrder 0x00400000 /* Reverse unordered SELECTs */ /* ** Possible values for the sqlite.magic field. diff --git a/src/where.c b/src/where.c index 858c54912..ea6e00a80 100644 --- a/src/where.c +++ b/src/where.c @@ -16,7 +16,7 @@ ** so is applicable. Because this module is responsible for selecting ** indices, you might also think of this module as the "query optimizer". ** -** $Id: where.c,v 1.370 2009/02/20 10:58:42 danielk1977 Exp $ +** $Id: where.c,v 1.371 2009/02/23 16:52:08 drh Exp $ */ #include "sqliteInt.h" @@ -1837,7 +1837,15 @@ static void bestIndex( cost += cost*estLog(cost); WHERETRACE(("... sorting increases cost to %.9g\n", cost)); } + }else if( pParse->db->flags & SQLITE_ReverseOrder ){ + /* For application testing, randomly reverse the output order for + ** SELECT statements that omit the ORDER BY clause. This will help + ** to find cases where + */ + wsFlags |= WHERE_REVERSE; } + + /* Remember this case if it is the best so far */ if( cost<pCost->rCost ){ pCost->rCost = cost; pCost->nRow = nRow; @@ -1987,6 +1995,12 @@ static void bestIndex( cost += cost*estLog(cost); WHERETRACE(("...... orderby increases cost to %.9g\n", cost)); } + }else if( pParse->db->flags & SQLITE_ReverseOrder ){ + /* For application testing, randomly reverse the output order for + ** SELECT statements that omit the ORDER BY clause. This will help + ** to find cases where + */ + wsFlags |= WHERE_REVERSE; } /* Check to see if we can get away with using just the index without @@ -2747,11 +2761,13 @@ static Bitmask codeOneLoopStart( /* Case 5: There is no usable index. We must do a complete ** scan of the entire table. */ + static const u8 aStep[] = { OP_Next, OP_Prev }; + static const u8 aStart[] = { OP_Rewind, OP_Last }; + assert( bRev==0 || bRev==1 ); assert( omitTable==0 ); - assert( bRev==0 ); - pLevel->op = OP_Next; + pLevel->op = aStep[bRev]; pLevel->p1 = iCur; - pLevel->p2 = 1 + sqlite3VdbeAddOp2(v, OP_Rewind, iCur, addrBrk); + pLevel->p2 = 1 + sqlite3VdbeAddOp2(v, aStart[bRev], iCur, addrBrk); pLevel->p5 = SQLITE_STMTSTATUS_FULLSCAN_STEP; codeRowSetEarly = 0; } |