diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/global.c | 5 | ||||
-rw-r--r-- | src/main.c | 5 | ||||
-rw-r--r-- | src/sqlite.h.in | 13 | ||||
-rw-r--r-- | src/sqliteInt.h | 2 | ||||
-rw-r--r-- | src/test1.c | 1 | ||||
-rw-r--r-- | src/test_malloc.c | 30 | ||||
-rw-r--r-- | src/where.c | 6 |
7 files changed, 61 insertions, 1 deletions
diff --git a/src/global.c b/src/global.c index 7de066825..dc86e1e08 100644 --- a/src/global.c +++ b/src/global.c @@ -133,6 +133,10 @@ const unsigned char sqlite3CtypeMap[256] = { # define SQLITE_USE_URI 0 #endif +#ifndef SQLITE_ALLOW_COVERING_INDEX_SCAN +# define SQLITE_ALLOW_COVERING_INDEX_SCAN 1 +#endif + /* ** The following singleton contains the global configuration for ** the SQLite library. @@ -142,6 +146,7 @@ SQLITE_WSD struct Sqlite3Config sqlite3Config = { 1, /* bCoreMutex */ SQLITE_THREADSAFE==1, /* bFullMutex */ SQLITE_USE_URI, /* bOpenUri */ + SQLITE_ALLOW_COVERING_INDEX_SCAN, /* bUseCis */ 0x7ffffffe, /* mxStrlen */ 128, /* szLookaside */ 500, /* nLookaside */ diff --git a/src/main.c b/src/main.c index 08e62a97e..466dee551 100644 --- a/src/main.c +++ b/src/main.c @@ -475,6 +475,11 @@ int sqlite3_config(int op, ...){ break; } + case SQLITE_CONFIG_COVERING_INDEX_SCAN: { + sqlite3GlobalConfig.bUseCis = va_arg(ap, int); + break; + } + default: { rc = SQLITE_ERROR; break; diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 3660c442d..cab0b8418 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -1563,6 +1563,18 @@ struct sqlite3_mem_methods { ** disabled. The default value may be changed by compiling with the ** [SQLITE_USE_URI] symbol defined. ** +** [[SQLITE_CONFIG_COVERING_INDEX_SCAN]] <dt>SQLITE_CONFIG_COVERING_INDEX_SCAN +** <dd> This option taks a single integer argument which is interpreted as +** a boolean in order to enable or disable the use of covering indices for +** full table scans in the query optimizer. The default setting is determined +** by the [SQLITE_ALLOW_COVERING_INDEX_SCAN] compile-time option, or is "on" +** if that compile-time option is omitted. +** The ability to disable the use of covering indices for full table scans +** is because some incorrectly coded legacy applications might malfunction +** malfunction when the optimization is enabled. Providing the ability to +** disable the optimization allows the older, buggy application code to work +** without change even with newer versions of SQLite. +** ** [[SQLITE_CONFIG_PCACHE]] [[SQLITE_CONFIG_GETPCACHE]] ** <dt>SQLITE_CONFIG_PCACHE and SQLITE_CONFIG_GETPCACHE ** <dd> These options are obsolete and should not be used by new code. @@ -1588,6 +1600,7 @@ struct sqlite3_mem_methods { #define SQLITE_CONFIG_URI 17 /* int */ #define SQLITE_CONFIG_PCACHE2 18 /* sqlite3_pcache_methods2* */ #define SQLITE_CONFIG_GETPCACHE2 19 /* sqlite3_pcache_methods2* */ +#define SQLITE_CONFIG_COVERING_INDEX_SCAN 20 /* int */ /* ** CAPI3REF: Database Connection Configuration Options diff --git a/src/sqliteInt.h b/src/sqliteInt.h index b0135f44c..e20e79774 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -968,6 +968,7 @@ struct sqlite3 { #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 */ /* @@ -2461,6 +2462,7 @@ struct Sqlite3Config { int bCoreMutex; /* True to enable core mutexing */ int bFullMutex; /* True to enable full mutexing */ int bOpenUri; /* True to interpret filenames as URIs */ + int bUseCis; /* Use covering indices for full-scans */ int mxStrlen; /* Maximum string length */ int szLookaside; /* Default lookaside buffer size */ int nLookaside; /* Default lookaside buffer count */ diff --git a/src/test1.c b/src/test1.c index 55e2df553..0b9b812e8 100644 --- a/src/test1.c +++ b/src/test1.c @@ -5940,6 +5940,7 @@ static int optimization_control( { "factor-constants", SQLITE_FactorOutConst }, { "real-as-int", SQLITE_IdxRealAsInt }, { "distinct-opt", SQLITE_DistinctOpt }, + { "cover-idx-scan", SQLITE_CoverIdxScan }, }; if( objc!=4 ){ diff --git a/src/test_malloc.c b/src/test_malloc.c index f52894d9e..e1420de64 100644 --- a/src/test_malloc.c +++ b/src/test_malloc.c @@ -1198,6 +1198,35 @@ static int test_config_uri( } /* +** Usage: sqlite3_config_cis BOOLEAN +** +** Enables or disables the use of the covering-index scan optimization. +** SQLITE_CONFIG_COVERING_INDEX_SCAN. +*/ +static int test_config_cis( + void * clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *CONST objv[] +){ + int rc; + int bUseCis; + + if( objc!=2 ){ + Tcl_WrongNumArgs(interp, 1, objv, "BOOL"); + return TCL_ERROR; + } + if( Tcl_GetBooleanFromObj(interp, objv[1], &bUseCis) ){ + return TCL_ERROR; + } + + rc = sqlite3_config(SQLITE_CONFIG_COVERING_INDEX_SCAN, bUseCis); + Tcl_SetResult(interp, (char *)sqlite3TestErrorName(rc), TCL_VOLATILE); + + return TCL_OK; +} + +/* ** Usage: sqlite3_dump_memsys3 FILENAME ** sqlite3_dump_memsys5 FILENAME ** @@ -1447,6 +1476,7 @@ int Sqlitetest_malloc_Init(Tcl_Interp *interp){ { "sqlite3_config_lookaside", test_config_lookaside ,0 }, { "sqlite3_config_error", test_config_error ,0 }, { "sqlite3_config_uri", test_config_uri ,0 }, + { "sqlite3_config_cis", test_config_cis ,0 }, { "sqlite3_db_config_lookaside",test_db_config_lookaside ,0 }, { "sqlite3_dump_memsys3", test_dump_memsys3 ,3 }, { "sqlite3_dump_memsys5", test_dump_memsys3 ,5 }, diff --git a/src/where.c b/src/where.c index c28386e29..9922d2b3d 100644 --- a/src/where.c +++ b/src/where.c @@ -3201,12 +3201,16 @@ static void bestBtreeIndex( */ 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 ){ /* 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 ** of the table, so give this case a cost slightly less than a table ** scan. */ - cost = aiRowEst[0]*3; + cost = aiRowEst[0]*3 + pProbe->nColumn; wsFlags |= WHERE_COVER_SCAN|WHERE_COLUMN_RANGE; }else if( (wsFlags & WHERE_NOT_FULLSCAN)==0 ){ /* The cost of a full table scan is a number of move operations equal |