aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/pragma.c3
-rw-r--r--src/sqliteInt.h3
-rw-r--r--src/where.c24
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;
}