aboutsummaryrefslogtreecommitdiff
path: root/ext/misc/closure.c
diff options
context:
space:
mode:
authordan <dan@noemail.net>2018-05-02 08:12:22 +0000
committerdan <dan@noemail.net>2018-05-02 08:12:22 +0000
commitfa5c69f5cb57778e5ced0490e2eda4498437b596 (patch)
tree807c05675e03b7bb1671c663fae10497b9a3d878 /ext/misc/closure.c
parent07430a8caf78e0fcd1956227d99f51ad6c57bec7 (diff)
downloadsqlite-fa5c69f5cb57778e5ced0490e2eda4498437b596.tar.gz
sqlite-fa5c69f5cb57778e5ced0490e2eda4498437b596.zip
Fix a problem in the xBestIndex method of the closure extension causing it to
allocate non-contiguous argvIndex values in some cases (an "xBestIndex malfunction" error). FossilOrigin-Name: 0c67150749cb3d067e14b2dcac9c3489e0f14bd18c0387f1d9bc93d21fc96fe5
Diffstat (limited to 'ext/misc/closure.c')
-rw-r--r--ext/misc/closure.c18
1 files changed, 12 insertions, 6 deletions
diff --git a/ext/misc/closure.c b/ext/misc/closure.c
index 510c46ec9..74bffc770 100644
--- a/ext/misc/closure.c
+++ b/ext/misc/closure.c
@@ -826,17 +826,12 @@ static int closureBestIndex(
int iPlan = 0;
int i;
int idx = 1;
- int seenMatch = 0;
const struct sqlite3_index_constraint *pConstraint;
closure_vtab *pVtab = (closure_vtab*)pTab;
double rCost = 10000000.0;
pConstraint = pIdxInfo->aConstraint;
for(i=0; i<pIdxInfo->nConstraint; i++, pConstraint++){
- if( pConstraint->iColumn==CLOSURE_COL_ROOT
- && pConstraint->op==SQLITE_INDEX_CONSTRAINT_EQ ){
- seenMatch = 1;
- }
if( pConstraint->usable==0 ) continue;
if( (iPlan & 1)==0
&& pConstraint->iColumn==CLOSURE_COL_ROOT
@@ -893,6 +888,18 @@ static int closureBestIndex(
** or else the result is an empty set. */
iPlan = 0;
}
+ if( (iPlan&1)==0 ){
+ /* If there is no usable "root=?" term, then set the index-type to 0.
+ ** Also clear any argvIndex variables already set. This is necessary
+ ** to prevent the core from throwing an "xBestIndex malfunction error"
+ ** error (because the argvIndex values are not contiguously assigned
+ ** starting from 1). */
+ rCost *= 1e30;
+ for(i=0; i<pIdxInfo->nConstraint; i++, pConstraint++){
+ pIdxInfo->aConstraintUsage[i].argvIndex = 0;
+ }
+ iPlan = 0;
+ }
pIdxInfo->idxNum = iPlan;
if( pIdxInfo->nOrderBy==1
&& pIdxInfo->aOrderBy[0].iColumn==CLOSURE_COL_ID
@@ -900,7 +907,6 @@ static int closureBestIndex(
){
pIdxInfo->orderByConsumed = 1;
}
- if( seenMatch && (iPlan&1)==0 ) rCost *= 1e30;
pIdxInfo->estimatedCost = rCost;
return SQLITE_OK;