aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordrh <drh@noemail.net>2012-09-27 15:05:54 +0000
committerdrh <drh@noemail.net>2012-09-27 15:05:54 +0000
commit7e5418e4a487f7579c1249857bf69b7a6985bf32 (patch)
treeeff4f900e32553fefdafc99158c8f5464a95c95f /src
parent32634d270ce9de65ac8a1cec14df671a477ce91c (diff)
downloadsqlite-7e5418e4a487f7579c1249857bf69b7a6985bf32.tar.gz
sqlite-7e5418e4a487f7579c1249857bf69b7a6985bf32.zip
Add more bits to the bit vector that is used to disable optimizations for
built-in test. Add specific bit patterns to disable ORDER BY using an index in general and for joins. Use macros to test for bits in the disabled-optimization bit vector, in order to make the code clearer. FossilOrigin-Name: d2fcba1e143beca8c45724d2108870657c269e17
Diffstat (limited to 'src')
-rw-r--r--src/delete.c4
-rw-r--r--src/expr.c4
-rw-r--r--src/main.c3
-rw-r--r--src/select.c4
-rw-r--r--src/sqliteInt.h88
-rw-r--r--src/test1.c4
-rw-r--r--src/where.c13
7 files changed, 67 insertions, 53 deletions
diff --git a/src/delete.c b/src/delete.c
index 44e5995a6..f7f52865e 100644
--- a/src/delete.c
+++ b/src/delete.c
@@ -638,7 +638,9 @@ int sqlite3GenerateIndexKey(
}
if( doMakeRec ){
const char *zAff;
- if( pTab->pSelect || (pParse->db->flags & SQLITE_IdxRealAsInt)!=0 ){
+ if( pTab->pSelect
+ || OptimizationDisabled(pParse->db, SQLITE_IdxRealAsInt)
+ ){
zAff = 0;
}else{
zAff = sqlite3IndexAffinityStr(v, pIdx);
diff --git a/src/expr.c b/src/expr.c
index 3d6373881..2d1fb38ed 100644
--- a/src/expr.c
+++ b/src/expr.c
@@ -2066,7 +2066,7 @@ void sqlite3ExprCacheStore(Parse *pParse, int iTab, int iCol, int iReg){
** for testing only - to verify that SQLite always gets the same answer
** with and without the column cache.
*/
- if( pParse->db->flags & SQLITE_ColumnCache ) return;
+ if( OptimizationDisabled(pParse->db, SQLITE_ColumnCache) ) return;
/* First replace any existing entry.
**
@@ -3382,7 +3382,7 @@ static int evalConstExpr(Walker *pWalker, Expr *pExpr){
void sqlite3ExprCodeConstants(Parse *pParse, Expr *pExpr){
Walker w;
if( pParse->cookieGoto ) return;
- if( (pParse->db->flags & SQLITE_FactorOutConst)!=0 ) return;
+ if( OptimizationDisabled(pParse->db, SQLITE_FactorOutConst) ) return;
w.xExprCallback = evalConstExpr;
w.xSelectCallback = 0;
w.pParse = pParse;
diff --git a/src/main.c b/src/main.c
index 466dee551..8713c790c 100644
--- a/src/main.c
+++ b/src/main.c
@@ -3018,8 +3018,7 @@ int sqlite3_test_control(int op, ...){
*/
case SQLITE_TESTCTRL_OPTIMIZATIONS: {
sqlite3 *db = va_arg(ap, sqlite3*);
- int x = va_arg(ap,int);
- db->flags = (x & SQLITE_OptMask) | (db->flags & ~SQLITE_OptMask);
+ db->dbOptFlags = (u16)(va_arg(ap, int) & 0xffff);
break;
}
diff --git a/src/select.c b/src/select.c
index 0f2320f59..2da14d93e 100644
--- a/src/select.c
+++ b/src/select.c
@@ -2809,7 +2809,7 @@ static int flattenSubquery(
*/
assert( p!=0 );
assert( p->pPrior==0 ); /* Unable to flatten compound queries */
- if( db->flags & SQLITE_QueryFlattener ) return 0;
+ if( OptimizationDisabled(db, SQLITE_QueryFlattener) ) return 0;
pSrc = p->pSrc;
assert( pSrc && iFrom>=0 && iFrom<pSrc->nSrc );
pSubitem = &pSrc->a[iFrom];
@@ -4012,7 +4012,7 @@ int sqlite3Select(
** to disable this optimization for testing purposes.
*/
if( sqlite3ExprListCompare(p->pGroupBy, pOrderBy)==0
- && (db->flags & SQLITE_GroupByOrder)==0 ){
+ && OptimizationEnabled(db, SQLITE_GroupByOrder) ){
pOrderBy = 0;
}
diff --git a/src/sqliteInt.h b/src/sqliteInt.h
index cd38dc870..4501c737f 100644
--- a/src/sqliteInt.h
+++ b/src/sqliteInt.h
@@ -827,6 +827,7 @@ struct sqlite3 {
unsigned int openFlags; /* Flags passed to sqlite3_vfs.xOpen() */
int errCode; /* Most recent error code (SQLITE_*) */
int errMask; /* & result codes with this before returning */
+ u16 dbOptFlags; /* Flags to enable/disable optimizations */
u8 autoCommit; /* The auto-commit flag. */
u8 temp_store; /* 1: file 2: memory 0: default */
u8 mallocFailed; /* True if we have seen a malloc failure */
@@ -931,46 +932,59 @@ struct sqlite3 {
/*
** Possible values for the sqlite3.flags.
*/
-#define SQLITE_VdbeTrace 0x00000100 /* True to trace VDBE execution */
-#define SQLITE_InternChanges 0x00000200 /* Uncommitted Hash table changes */
-#define SQLITE_FullColNames 0x00000400 /* Show full column names on SELECT */
-#define SQLITE_ShortColNames 0x00000800 /* Show short columns names */
-#define SQLITE_CountRows 0x00001000 /* Count rows changed by INSERT, */
+#define SQLITE_VdbeTrace 0x00000001 /* True to trace VDBE execution */
+#define SQLITE_InternChanges 0x00000002 /* Uncommitted Hash table changes */
+#define SQLITE_FullColNames 0x00000004 /* Show full column names on SELECT */
+#define SQLITE_ShortColNames 0x00000008 /* Show short columns names */
+#define SQLITE_CountRows 0x00000010 /* Count rows changed by INSERT, */
/* DELETE, or UPDATE and return */
/* the count using a callback. */
-#define SQLITE_NullCallback 0x00002000 /* Invoke the callback once if the */
+#define SQLITE_NullCallback 0x00000020 /* Invoke the callback once if the */
/* result set is empty */
-#define SQLITE_SqlTrace 0x00004000 /* Debug print SQL as it executes */
-#define SQLITE_VdbeListing 0x00008000 /* Debug listings of VDBE programs */
-#define SQLITE_WriteSchema 0x00010000 /* OK to update SQLITE_MASTER */
- /* 0x00020000 Unused */
-#define SQLITE_IgnoreChecks 0x00040000 /* Do not enforce check constraints */
-#define SQLITE_ReadUncommitted 0x0080000 /* For shared-cache mode */
-#define SQLITE_LegacyFileFmt 0x00100000 /* Create new databases in format 1 */
-#define SQLITE_FullFSync 0x00200000 /* Use full fsync on the backend */
-#define SQLITE_CkptFullFSync 0x00400000 /* Use full fsync for checkpoint */
-#define SQLITE_RecoveryMode 0x00800000 /* Ignore schema errors */
-#define SQLITE_ReverseOrder 0x01000000 /* Reverse unordered SELECTs */
-#define SQLITE_RecTriggers 0x02000000 /* Enable recursive triggers */
-#define SQLITE_ForeignKeys 0x04000000 /* Enforce foreign key constraints */
-#define SQLITE_AutoIndex 0x08000000 /* Enable automatic indexes */
-#define SQLITE_PreferBuiltin 0x10000000 /* Preference to built-in funcs */
-#define SQLITE_LoadExtension 0x20000000 /* Enable load_extension */
-#define SQLITE_EnableTrigger 0x40000000 /* True to enable triggers */
-
-/*
-** Bits of the sqlite3.flags field that are used by the
-** sqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS,...) interface.
-** These must be the low-order bits of the flags field.
-*/
-#define SQLITE_QueryFlattener 0x01 /* Disable query flattening */
-#define SQLITE_ColumnCache 0x02 /* Disable the column cache */
-#define SQLITE_GroupByOrder 0x04 /* Disable GROUPBY cover of ORDERBY */
-#define SQLITE_FactorOutConst 0x08 /* Disable factoring out constants */
-#define SQLITE_IdxRealAsInt 0x10 /* Store REAL as INT in indices */
-#define SQLITE_DistinctOpt 0x20 /* DISTINCT using indexes */
-#define SQLITE_CoverIdxScan 0x40 /* Disable covering index scans */
-#define SQLITE_OptMask 0xff /* Mask of all disablable opts */
+#define SQLITE_SqlTrace 0x00000040 /* Debug print SQL as it executes */
+#define SQLITE_VdbeListing 0x00000080 /* Debug listings of VDBE programs */
+#define SQLITE_WriteSchema 0x00000100 /* OK to update SQLITE_MASTER */
+ /* 0x00000200 Unused */
+#define SQLITE_IgnoreChecks 0x00000400 /* Do not enforce check constraints */
+#define SQLITE_ReadUncommitted 0x0000800 /* For shared-cache mode */
+#define SQLITE_LegacyFileFmt 0x00001000 /* Create new databases in format 1 */
+#define SQLITE_FullFSync 0x00002000 /* Use full fsync on the backend */
+#define SQLITE_CkptFullFSync 0x00004000 /* Use full fsync for checkpoint */
+#define SQLITE_RecoveryMode 0x00008000 /* Ignore schema errors */
+#define SQLITE_ReverseOrder 0x00010000 /* Reverse unordered SELECTs */
+#define SQLITE_RecTriggers 0x00020000 /* Enable recursive triggers */
+#define SQLITE_ForeignKeys 0x00040000 /* Enforce foreign key constraints */
+#define SQLITE_AutoIndex 0x00080000 /* Enable automatic indexes */
+#define SQLITE_PreferBuiltin 0x00100000 /* Preference to built-in funcs */
+#define SQLITE_LoadExtension 0x00200000 /* Enable load_extension */
+#define SQLITE_EnableTrigger 0x00400000 /* True to enable triggers */
+
+/*
+** Bits of the sqlite3.dbOptFlags field that are used by the
+** sqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS,...) interface to
+** selectively disable various optimizations.
+*/
+#define SQLITE_QueryFlattener 0x0001 /* Query flattening */
+#define SQLITE_ColumnCache 0x0002 /* Column cache */
+#define SQLITE_GroupByOrder 0x0004 /* GROUPBY cover of ORDERBY */
+#define SQLITE_FactorOutConst 0x0008 /* Constant factoring */
+#define SQLITE_IdxRealAsInt 0x0010 /* Store REAL as INT in indices */
+#define SQLITE_DistinctOpt 0x0020 /* DISTINCT using indexes */
+#define SQLITE_CoverIdxScan 0x0040 /* Covering index scans */
+#define SQLITE_OrderByIdx 0x0180 /* ORDER BY using indices */
+#define SQLITE_OrderByIdxJoin 0x0100 /* ORDER BY of joins via index */
+#define SQLITE_AllOpts 0x01ff /* All optimizations */
+
+/*
+** Macros for testing whether or not optimizations are enabled or disabled.
+*/
+#ifndef SQLITE_OMIT_BUILTIN_TEST
+#define OptimizationDisabled(db, mask) (((db)->dbOptFlags&(mask))!=0)
+#define OptimizationEnabled(db, mask) (((db)->dbOptFlags&(mask))==0)
+#else
+#define OptimizationDisabled(db, mask) 0
+#define OptimizationEnabled(db, mask) 1
+#endif
/*
** Possible values for the sqlite.magic field.
diff --git a/src/test1.c b/src/test1.c
index 0b9b812e8..45ca124bb 100644
--- a/src/test1.c
+++ b/src/test1.c
@@ -5933,7 +5933,7 @@ static int optimization_control(
const char *zOptName;
int mask;
} aOpt[] = {
- { "all", SQLITE_OptMask },
+ { "all", SQLITE_AllOpts },
{ "query-flattener", SQLITE_QueryFlattener },
{ "column-cache", SQLITE_ColumnCache },
{ "groupby-order", SQLITE_GroupByOrder },
@@ -5941,6 +5941,8 @@ static int optimization_control(
{ "real-as-int", SQLITE_IdxRealAsInt },
{ "distinct-opt", SQLITE_DistinctOpt },
{ "cover-idx-scan", SQLITE_CoverIdxScan },
+ { "order-by-idx", SQLITE_OrderByIdx },
+ { "order-by-idx-join",SQLITE_OrderByIdxJoin },
};
if( objc!=4 ){
diff --git a/src/where.c b/src/where.c
index ce5437a9f..039549657 100644
--- a/src/where.c
+++ b/src/where.c
@@ -1646,9 +1646,11 @@ static int isSortingIndex(
int nPriorSat; /* ORDER BY terms satisfied by outer loops */
int seenRowid = 0; /* True if an ORDER BY rowid term is seen */
+ if( OptimizationDisabled(db, SQLITE_OrderByIdx) ) return 0;
if( p->i==0 ){
nPriorSat = 0;
}else{
+ if( OptimizationDisabled(db, SQLITE_OrderByIdxJoin) ) return 0;
nPriorSat = p->aLevel[p->i-1].plan.nOBSat;
}
if( p->i>0 && nEqCol==0 /*&& !allOuterLoopsUnique(p)*/ ) return nPriorSat;
@@ -2879,10 +2881,7 @@ static int isOrderedColumn(WhereBestIdx *p, int iTab, int iCol, int *pbRev){
u8 sortOrder;
for(i=p->i-1; i>=0; i--, pLevel--){
if( pLevel->iTabCur!=iTab ) continue;
- if( (pLevel->plan.wsFlags & (WHERE_ROWID_EQ|WHERE_ROWID_RANGE))!=0 ){
- if( iCol!=(-1) ) return 0;
- sortOrder = 0;
- }else if( (pLevel->plan.wsFlags & WHERE_INDEXED)!=0 ){
+ if( (pLevel->plan.wsFlags & WHERE_INDEXED)!=0 ){
pIdx = pLevel->plan.u.pIdx;
for(j=0; j<pIdx->nColumn; j++){
if( iCol==pIdx->aiColumn[j] ) break;
@@ -3289,9 +3288,7 @@ static void bestBtreeIndex(WhereBestIdx *p){
if( wsFlags==WHERE_IDX_ONLY
&& (pWC->wctrlFlags & WHERE_ONEPASS_DESIRED)==0
&& sqlite3GlobalConfig.bUseCis
-#ifndef SQLITE_OMIT_BUILTIN_TEST
- && (pParse->db->flags & SQLITE_CoverIdxScan)==0
-#endif
+ && OptimizationEnabled(pParse->db, SQLITE_CoverIdxScan)
){
/* This index is not useful for indexing, but it is a covering index.
** A full-scan of the index might be a little faster than a full-scan
@@ -4841,7 +4838,7 @@ WhereInfo *sqlite3WhereBegin(
/* Disable the DISTINCT optimization if SQLITE_DistinctOpt is set via
** sqlite3_test_ctrl(SQLITE_TESTCTRL_OPTIMIZATIONS,...) */
- if( db->flags & SQLITE_DistinctOpt ) pDistinct = 0;
+ if( OptimizationDisabled(db, SQLITE_DistinctOpt) ) pDistinct = 0;
/* Split the WHERE clause into separate subexpressions where each
** subexpression is separated by an AND operator.