** Search database dbm for an index compatible with the one idxCreateFromCons() ** would create from arguments pScan, pEq and pTail. If no error occurs and ** such an index is found, return non-zero. Or, if no such index is found, ** return zero. ** ** If an error occurs, set *pRc to an SQLite error code and return zero. */
| 9218 | ** If an error occurs, set *pRc to an SQLite error code and return zero. |
| 9219 | */ |
| 9220 | static int idxFindCompatible( |
| 9221 | int *pRc, /* OUT: Error code */ |
| 9222 | sqlite3* dbm, /* Database to search */ |
| 9223 | IdxScan *pScan, /* Scan for table to search for index on */ |
| 9224 | IdxConstraint *pEq, /* List of == constraints */ |
| 9225 | IdxConstraint *pTail /* List of range constraints */ |
| 9226 | ){ |
| 9227 | const char *zTbl = pScan->pTab->zName; |
| 9228 | sqlite3_stmt *pIdxList = 0; |
| 9229 | IdxConstraint *pIter; |
| 9230 | int nEq = 0; /* Number of elements in pEq */ |
| 9231 | int rc; |
| 9232 | |
| 9233 | /* Count the elements in list pEq */ |
| 9234 | for(pIter=pEq; pIter; pIter=pIter->pLink) nEq++; |
| 9235 | |
| 9236 | rc = idxPrintfPrepareStmt(dbm, &pIdxList, 0, "PRAGMA index_list=%Q", zTbl); |
| 9237 | while( rc==SQLITE_OK && sqlite3_step(pIdxList)==SQLITE_ROW ){ |
| 9238 | int bMatch = 1; |
| 9239 | IdxConstraint *pT = pTail; |
| 9240 | sqlite3_stmt *pInfo = 0; |
| 9241 | const char *zIdx = (const char*)sqlite3_column_text(pIdxList, 1); |
| 9242 | |
| 9243 | /* Zero the IdxConstraint.bFlag values in the pEq list */ |
| 9244 | for(pIter=pEq; pIter; pIter=pIter->pLink) pIter->bFlag = 0; |
| 9245 | |
| 9246 | rc = idxPrintfPrepareStmt(dbm, &pInfo, 0, "PRAGMA index_xInfo=%Q", zIdx); |
| 9247 | while( rc==SQLITE_OK && sqlite3_step(pInfo)==SQLITE_ROW ){ |
| 9248 | int iIdx = sqlite3_column_int(pInfo, 0); |
| 9249 | int iCol = sqlite3_column_int(pInfo, 1); |
| 9250 | const char *zColl = (const char*)sqlite3_column_text(pInfo, 4); |
| 9251 | |
| 9252 | if( iIdx<nEq ){ |
| 9253 | for(pIter=pEq; pIter; pIter=pIter->pLink){ |
| 9254 | if( pIter->bFlag ) continue; |
| 9255 | if( pIter->iCol!=iCol ) continue; |
| 9256 | if( sqlite3_stricmp(pIter->zColl, zColl) ) continue; |
| 9257 | pIter->bFlag = 1; |
| 9258 | break; |
| 9259 | } |
| 9260 | if( pIter==0 ){ |
| 9261 | bMatch = 0; |
| 9262 | break; |
| 9263 | } |
| 9264 | }else{ |
| 9265 | if( pT ){ |
| 9266 | if( pT->iCol!=iCol || sqlite3_stricmp(pT->zColl, zColl) ){ |
| 9267 | bMatch = 0; |
| 9268 | break; |
| 9269 | } |
| 9270 | pT = pT->pLink; |
| 9271 | } |
| 9272 | } |
| 9273 | } |
| 9274 | idxFinalize(&rc, pInfo); |
| 9275 | |
| 9276 | if( rc==SQLITE_OK && bMatch ){ |
| 9277 | sqlite3_finalize(pIdxList); |
no test coverage detected