** This function is called after candidate indexes have been created. It ** runs all the queries to see which indexes they prefer, and populates ** IdxStatement.zIdx and IdxStatement.zEQP with the results. */
| 9482 | ** IdxStatement.zIdx and IdxStatement.zEQP with the results. |
| 9483 | */ |
| 9484 | int idxFindIndexes( |
| 9485 | sqlite3expert *p, |
| 9486 | char **pzErr /* OUT: Error message (sqlite3_malloc) */ |
| 9487 | ){ |
| 9488 | IdxStatement *pStmt; |
| 9489 | sqlite3 *dbm = p->dbm; |
| 9490 | int rc = SQLITE_OK; |
| 9491 | |
| 9492 | IdxHash hIdx; |
| 9493 | idxHashInit(&hIdx); |
| 9494 | |
| 9495 | for(pStmt=p->pStatement; rc==SQLITE_OK && pStmt; pStmt=pStmt->pNext){ |
| 9496 | IdxHashEntry *pEntry; |
| 9497 | sqlite3_stmt *pExplain = 0; |
| 9498 | idxHashClear(&hIdx); |
| 9499 | rc = idxPrintfPrepareStmt(dbm, &pExplain, pzErr, |
| 9500 | "EXPLAIN QUERY PLAN %s", pStmt->zSql |
| 9501 | ); |
| 9502 | while( rc==SQLITE_OK && sqlite3_step(pExplain)==SQLITE_ROW ){ |
| 9503 | /* int iId = sqlite3_column_int(pExplain, 0); */ |
| 9504 | /* int iParent = sqlite3_column_int(pExplain, 1); */ |
| 9505 | /* int iNotUsed = sqlite3_column_int(pExplain, 2); */ |
| 9506 | const char *zDetail = (const char*)sqlite3_column_text(pExplain, 3); |
| 9507 | int nDetail; |
| 9508 | int i; |
| 9509 | |
| 9510 | if( !zDetail ) continue; |
| 9511 | nDetail = STRLEN(zDetail); |
| 9512 | |
| 9513 | for(i=0; i<nDetail; i++){ |
| 9514 | const char *zIdx = 0; |
| 9515 | if( i+13<nDetail && memcmp(&zDetail[i], " USING INDEX ", 13)==0 ){ |
| 9516 | zIdx = &zDetail[i+13]; |
| 9517 | }else if( i+22<nDetail |
| 9518 | && memcmp(&zDetail[i], " USING COVERING INDEX ", 22)==0 |
| 9519 | ){ |
| 9520 | zIdx = &zDetail[i+22]; |
| 9521 | } |
| 9522 | if( zIdx ){ |
| 9523 | const char *zSql; |
| 9524 | int nIdx = 0; |
| 9525 | while( zIdx[nIdx]!='\0' && (zIdx[nIdx]!=' ' || zIdx[nIdx+1]!='(') ){ |
| 9526 | nIdx++; |
| 9527 | } |
| 9528 | zSql = idxHashSearch(&p->hIdx, zIdx, nIdx); |
| 9529 | if( zSql ){ |
| 9530 | idxHashAdd(&rc, &hIdx, zSql, 0); |
| 9531 | if( rc ) goto find_indexes_out; |
| 9532 | } |
| 9533 | break; |
| 9534 | } |
| 9535 | } |
| 9536 | |
| 9537 | if( zDetail[0]!='-' ){ |
| 9538 | pStmt->zEQP = idxAppendText(&rc, pStmt->zEQP, "%s\n", zDetail); |
| 9539 | } |
| 9540 | } |
| 9541 |
no test coverage detected