Enhance the xBestIndex interface of virtual table so that if the xBestIndex
method returns SQLITE_CONSTRAINT then that particular combination of constraints is considered unusable and does not participate further in query planning. FossilOrigin-Name: 684013cef6bfcfd920a4aec645df9f5d41ace8b34e75fca61759c1b4f82cc89e
This commit is contained in:
+37
-11
@@ -846,27 +846,53 @@ static int fsdirBestIndex(
|
||||
sqlite3_index_info *pIdxInfo
|
||||
){
|
||||
int i; /* Loop over constraints */
|
||||
int idx4 = -1; /* Index in pIdxInfo->aConstraint of PATH= */
|
||||
int idx5 = -1; /* Index in pIdxInfo->aConstraint of DIR= */
|
||||
int idxPath = -1; /* Index in pIdxInfo->aConstraint of PATH= */
|
||||
int idxDir = -1; /* Index in pIdxInfo->aConstraint of DIR= */
|
||||
int seenPath = 0; /* True if an unusable PATH= constraint is seen */
|
||||
int seenDir = 0; /* True if an unusable DIR= constraint is seen */
|
||||
const struct sqlite3_index_constraint *pConstraint;
|
||||
|
||||
(void)tab;
|
||||
pConstraint = pIdxInfo->aConstraint;
|
||||
for(i=0; i<pIdxInfo->nConstraint; i++, pConstraint++){
|
||||
if( pConstraint->op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue;
|
||||
if( pConstraint->iColumn==4 && pConstraint->usable ) idx4 = i;
|
||||
if( pConstraint->iColumn==5 ) idx5 = i;
|
||||
switch( pConstraint->iColumn ){
|
||||
case FSDIR_COLUMN_PATH: {
|
||||
if( pConstraint->usable ){
|
||||
idxPath = i;
|
||||
seenPath = 0;
|
||||
}else if( idxPath<0 ){
|
||||
seenPath = 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case FSDIR_COLUMN_DIR: {
|
||||
if( pConstraint->usable ){
|
||||
idxDir = i;
|
||||
seenDir = 0;
|
||||
}else if( idxDir<0 ){
|
||||
seenDir = 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if( seenPath || seenDir ){
|
||||
/* If input parameters are unusable, disallow this plan */
|
||||
return SQLITE_CONSTRAINT;
|
||||
}
|
||||
|
||||
if( idx4<0 || (idx5>=0 && pIdxInfo->aConstraint[idx5].usable==0) ){
|
||||
if( idxPath<0 ){
|
||||
pIdxInfo->idxNum = 0;
|
||||
pIdxInfo->estimatedCost = (double)(((sqlite3_int64)1) << 60);
|
||||
/* The pIdxInfo->estimatedCost should have been initialized to a huge
|
||||
** number. Leave it unchanged. */
|
||||
pIdxInfo->estimatedRows = 0x7fffffff;
|
||||
}else{
|
||||
pIdxInfo->aConstraintUsage[idx4].omit = 1;
|
||||
pIdxInfo->aConstraintUsage[idx4].argvIndex = 1;
|
||||
if( idx5>=0 ){
|
||||
pIdxInfo->aConstraintUsage[idx5].omit = 1;
|
||||
pIdxInfo->aConstraintUsage[idx5].argvIndex = 2;
|
||||
pIdxInfo->aConstraintUsage[idxPath].omit = 1;
|
||||
pIdxInfo->aConstraintUsage[idxPath].argvIndex = 1;
|
||||
if( idxDir>=0 ){
|
||||
pIdxInfo->aConstraintUsage[idxDir].omit = 1;
|
||||
pIdxInfo->aConstraintUsage[idxDir].argvIndex = 2;
|
||||
pIdxInfo->idxNum = 2;
|
||||
pIdxInfo->estimatedCost = 10.0;
|
||||
}else{
|
||||
|
||||
Reference in New Issue
Block a user