aboutsummaryrefslogtreecommitdiff
path: root/ext/misc/explain.c
diff options
context:
space:
mode:
Diffstat (limited to 'ext/misc/explain.c')
-rw-r--r--ext/misc/explain.c34
1 files changed, 23 insertions, 11 deletions
diff --git a/ext/misc/explain.c b/ext/misc/explain.c
index dc0c9d766..7a2fc4776 100644
--- a/ext/misc/explain.c
+++ b/ext/misc/explain.c
@@ -18,6 +18,10 @@
** .load ./explain
** SELECT p2 FROM explain('SELECT * FROM sqlite_master')
** WHERE opcode='OpenRead';
+**
+** This module was originally written to help simplify SQLite testing,
+** by providing an easier means of verifying certain patterns in the
+** generated bytecode.
*/
#if !defined(SQLITEINT_H)
#include "sqlite3ext.h"
@@ -232,23 +236,31 @@ static int explainBestIndex(
sqlite3_vtab *tab,
sqlite3_index_info *pIdxInfo
){
- int i;
+ int i; /* Loop counter */
+ int idx = -1; /* Index of a usable == constraint against SQL */
+ int unusable = 0; /* True if there are unusable constraints on SQL */
- pIdxInfo->estimatedCost = (double)1000000;
pIdxInfo->estimatedRows = 500;
for(i=0; i<pIdxInfo->nConstraint; i++){
struct sqlite3_index_constraint *p = &pIdxInfo->aConstraint[i];
- if( p->usable
- && p->iColumn==EXPLN_COLUMN_SQL
- && p->op==SQLITE_INDEX_CONSTRAINT_EQ
- ){
- pIdxInfo->estimatedCost = 10.0;
- pIdxInfo->idxNum = 1;
- pIdxInfo->aConstraintUsage[i].argvIndex = 1;
- pIdxInfo->aConstraintUsage[i].omit = 1;
- break;
+ if( p->iColumn!=EXPLN_COLUMN_SQL ) continue;
+ if( !p->usable ){
+ unusable = 1;
+ }else if( p->op==SQLITE_INDEX_CONSTRAINT_EQ ){
+ idx = i;
}
}
+ if( idx>=0 ){
+ /* There exists a usable == constraint against the SQL column */
+ pIdxInfo->estimatedCost = 10.0;
+ pIdxInfo->idxNum = 1;
+ pIdxInfo->aConstraintUsage[idx].argvIndex = 1;
+ pIdxInfo->aConstraintUsage[idx].omit = 1;
+ }else if( unusable ){
+ /* There are unusable constraints against the SQL column. Do not allow
+ ** this plan to continue forward. */
+ return SQLITE_CONSTRAINT;
+ }
return SQLITE_OK;
}