| 10652 | } |
| 10653 | |
| 10654 | static int expertBestIndex(sqlite3_vtab *pVtab, sqlite3_index_info *pIdxInfo){ |
| 10655 | ExpertVtab *p = (ExpertVtab*)pVtab; |
| 10656 | int rc = SQLITE_OK; |
| 10657 | int n = 0; |
| 10658 | IdxScan *pScan; |
| 10659 | const int opmask = |
| 10660 | SQLITE_INDEX_CONSTRAINT_EQ | SQLITE_INDEX_CONSTRAINT_GT | |
| 10661 | SQLITE_INDEX_CONSTRAINT_LT | SQLITE_INDEX_CONSTRAINT_GE | |
| 10662 | SQLITE_INDEX_CONSTRAINT_LE; |
| 10663 | |
| 10664 | pScan = idxMalloc(&rc, sizeof(IdxScan)); |
| 10665 | if( pScan ){ |
| 10666 | int i; |
| 10667 | |
| 10668 | /* Link the new scan object into the list */ |
| 10669 | pScan->pTab = p->pTab; |
| 10670 | pScan->pNextScan = p->pExpert->pScan; |
| 10671 | p->pExpert->pScan = pScan; |
| 10672 | |
| 10673 | /* Add the constraints to the IdxScan object */ |
| 10674 | for(i=0; i<pIdxInfo->nConstraint; i++){ |
| 10675 | struct sqlite3_index_constraint *pCons = &pIdxInfo->aConstraint[i]; |
| 10676 | if( pCons->usable |
| 10677 | && pCons->iColumn>=0 |
| 10678 | && p->pTab->aCol[pCons->iColumn].iPk==0 |
| 10679 | && (pCons->op & opmask) |
| 10680 | ){ |
| 10681 | IdxConstraint *pNew; |
| 10682 | const char *zColl = sqlite3_vtab_collation(pIdxInfo, i); |
| 10683 | pNew = idxNewConstraint(&rc, zColl); |
| 10684 | if( pNew ){ |
| 10685 | pNew->iCol = pCons->iColumn; |
| 10686 | if( pCons->op==SQLITE_INDEX_CONSTRAINT_EQ ){ |
| 10687 | pNew->pNext = pScan->pEq; |
| 10688 | pScan->pEq = pNew; |
| 10689 | }else{ |
| 10690 | pNew->bRange = 1; |
| 10691 | pNew->pNext = pScan->pRange; |
| 10692 | pScan->pRange = pNew; |
| 10693 | } |
| 10694 | } |
| 10695 | n++; |
| 10696 | pIdxInfo->aConstraintUsage[i].argvIndex = n; |
| 10697 | } |
| 10698 | } |
| 10699 | |
| 10700 | /* Add the ORDER BY to the IdxScan object */ |
| 10701 | for(i=pIdxInfo->nOrderBy-1; i>=0; i--){ |
| 10702 | int iCol = pIdxInfo->aOrderBy[i].iColumn; |
| 10703 | if( iCol>=0 ){ |
| 10704 | IdxConstraint *pNew = idxNewConstraint(&rc, p->pTab->aCol[iCol].zColl); |
| 10705 | if( pNew ){ |
| 10706 | pNew->iCol = iCol; |
| 10707 | pNew->bDesc = pIdxInfo->aOrderBy[i].desc; |
| 10708 | pNew->pNext = pScan->pOrder; |
| 10709 | pNew->pLink = pScan->pOrder; |
| 10710 | pScan->pOrder = pNew; |
| 10711 | n++; |
nothing calls this directly
no test coverage detected