** 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. */
| 11079 | ** If an error occurs, set *pRc to an SQLite error code and return zero. |
| 11080 | */ |
| 11081 | static int idxFindCompatible( |
| 11082 | int *pRc, /* OUT: Error code */ |
| 11083 | sqlite3* dbm, /* Database to search */ |
| 11084 | IdxScan *pScan, /* Scan for table to search for index on */ |
| 11085 | IdxConstraint *pEq, /* List of == constraints */ |
| 11086 | IdxConstraint *pTail /* List of range constraints */ |
| 11087 | ){ |
| 11088 | const char *zTbl = pScan->pTab->zName; |
| 11089 | sqlite3_stmt *pIdxList = 0; |
| 11090 | IdxConstraint *pIter; |
| 11091 | int nEq = 0; /* Number of elements in pEq */ |
| 11092 | int rc; |
| 11093 | |
| 11094 | /* Count the elements in list pEq */ |
| 11095 | for(pIter=pEq; pIter; pIter=pIter->pLink) nEq++; |
| 11096 | |
| 11097 | rc = idxPrintfPrepareStmt(dbm, &pIdxList, 0, "PRAGMA index_list=%Q", zTbl); |
| 11098 | while( rc==SQLITE_OK && sqlite3_step(pIdxList)==SQLITE_ROW ){ |
| 11099 | int bMatch = 1; |
| 11100 | IdxConstraint *pT = pTail; |
| 11101 | sqlite3_stmt *pInfo = 0; |
| 11102 | const char *zIdx = (const char*)sqlite3_column_text(pIdxList, 1); |
| 11103 | if( zIdx==0 ) continue; |
| 11104 | |
| 11105 | /* Zero the IdxConstraint.bFlag values in the pEq list */ |
| 11106 | for(pIter=pEq; pIter; pIter=pIter->pLink) pIter->bFlag = 0; |
| 11107 | |
| 11108 | rc = idxPrintfPrepareStmt(dbm, &pInfo, 0, "PRAGMA index_xInfo=%Q", zIdx); |
| 11109 | while( rc==SQLITE_OK && sqlite3_step(pInfo)==SQLITE_ROW ){ |
| 11110 | int iIdx = sqlite3_column_int(pInfo, 0); |
| 11111 | int iCol = sqlite3_column_int(pInfo, 1); |
| 11112 | const char *zColl = (const char*)sqlite3_column_text(pInfo, 4); |
| 11113 | |
| 11114 | if( iIdx<nEq ){ |
| 11115 | for(pIter=pEq; pIter; pIter=pIter->pLink){ |
| 11116 | if( pIter->bFlag ) continue; |
| 11117 | if( pIter->iCol!=iCol ) continue; |
| 11118 | if( sqlite3_stricmp(pIter->zColl, zColl) ) continue; |
| 11119 | pIter->bFlag = 1; |
| 11120 | break; |
| 11121 | } |
| 11122 | if( pIter==0 ){ |
| 11123 | bMatch = 0; |
| 11124 | break; |
| 11125 | } |
| 11126 | }else{ |
| 11127 | if( pT ){ |
| 11128 | if( pT->iCol!=iCol || sqlite3_stricmp(pT->zColl, zColl) ){ |
| 11129 | bMatch = 0; |
| 11130 | break; |
| 11131 | } |
| 11132 | pT = pT->pLink; |
| 11133 | } |
| 11134 | } |
| 11135 | } |
| 11136 | idxFinalize(&rc, pInfo); |
| 11137 | |
| 11138 | if( rc==SQLITE_OK && bMatch ){ |
no test coverage detected