| 8809 | } |
| 8810 | |
| 8811 | static int expertBestIndex(sqlite3_vtab *pVtab, sqlite3_index_info *pIdxInfo){ |
| 8812 | ExpertVtab *p = (ExpertVtab*)pVtab; |
| 8813 | int rc = SQLITE_OK; |
| 8814 | int n = 0; |
| 8815 | IdxScan *pScan; |
| 8816 | const int opmask = |
| 8817 | SQLITE_INDEX_CONSTRAINT_EQ | SQLITE_INDEX_CONSTRAINT_GT | |
| 8818 | SQLITE_INDEX_CONSTRAINT_LT | SQLITE_INDEX_CONSTRAINT_GE | |
| 8819 | SQLITE_INDEX_CONSTRAINT_LE; |
| 8820 | |
| 8821 | pScan = idxMalloc(&rc, sizeof(IdxScan)); |
| 8822 | if( pScan ){ |
| 8823 | int i; |
| 8824 | |
| 8825 | /* Link the new scan object into the list */ |
| 8826 | pScan->pTab = p->pTab; |
| 8827 | pScan->pNextScan = p->pExpert->pScan; |
| 8828 | p->pExpert->pScan = pScan; |
| 8829 | |
| 8830 | /* Add the constraints to the IdxScan object */ |
| 8831 | for(i=0; i<pIdxInfo->nConstraint; i++){ |
| 8832 | struct sqlite3_index_constraint *pCons = &pIdxInfo->aConstraint[i]; |
| 8833 | if( pCons->usable |
| 8834 | && pCons->iColumn>=0 |
| 8835 | && p->pTab->aCol[pCons->iColumn].iPk==0 |
| 8836 | && (pCons->op & opmask) |
| 8837 | ){ |
| 8838 | IdxConstraint *pNew; |
| 8839 | const char *zColl = sqlite3_vtab_collation(pIdxInfo, i); |
| 8840 | pNew = idxNewConstraint(&rc, zColl); |
| 8841 | if( pNew ){ |
| 8842 | pNew->iCol = pCons->iColumn; |
| 8843 | if( pCons->op==SQLITE_INDEX_CONSTRAINT_EQ ){ |
| 8844 | pNew->pNext = pScan->pEq; |
| 8845 | pScan->pEq = pNew; |
| 8846 | }else{ |
| 8847 | pNew->bRange = 1; |
| 8848 | pNew->pNext = pScan->pRange; |
| 8849 | pScan->pRange = pNew; |
| 8850 | } |
| 8851 | } |
| 8852 | n++; |
| 8853 | pIdxInfo->aConstraintUsage[i].argvIndex = n; |
| 8854 | } |
| 8855 | } |
| 8856 | |
| 8857 | /* Add the ORDER BY to the IdxScan object */ |
| 8858 | for(i=pIdxInfo->nOrderBy-1; i>=0; i--){ |
| 8859 | int iCol = pIdxInfo->aOrderBy[i].iColumn; |
| 8860 | if( iCol>=0 ){ |
| 8861 | IdxConstraint *pNew = idxNewConstraint(&rc, p->pTab->aCol[iCol].zColl); |
| 8862 | if( pNew ){ |
| 8863 | pNew->iCol = iCol; |
| 8864 | pNew->bDesc = pIdxInfo->aOrderBy[i].desc; |
| 8865 | pNew->pNext = pScan->pOrder; |
| 8866 | pNew->pLink = pScan->pOrder; |
| 8867 | pScan->pOrder = pNew; |
| 8868 | n++; |
nothing calls this directly
no test coverage detected