** 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. */
| 11384 | ** IdxStatement.zIdx and IdxStatement.zEQP with the results. |
| 11385 | */ |
| 11386 | static int idxFindIndexes( |
| 11387 | sqlite3expert *p, |
| 11388 | char **pzErr /* OUT: Error message (sqlite3_malloc) */ |
| 11389 | ){ |
| 11390 | IdxStatement *pStmt; |
| 11391 | sqlite3 *dbm = p->dbm; |
| 11392 | int rc = SQLITE_OK; |
| 11393 | |
| 11394 | IdxHash hIdx; |
| 11395 | idxHashInit(&hIdx); |
| 11396 | |
| 11397 | for(pStmt=p->pStatement; rc==SQLITE_OK && pStmt; pStmt=pStmt->pNext){ |
| 11398 | IdxHashEntry *pEntry; |
| 11399 | sqlite3_stmt *pExplain = 0; |
| 11400 | idxHashClear(&hIdx); |
| 11401 | rc = idxPrintfPrepareStmt(dbm, &pExplain, pzErr, |
| 11402 | "EXPLAIN QUERY PLAN %s", pStmt->zSql |
| 11403 | ); |
| 11404 | while( rc==SQLITE_OK && sqlite3_step(pExplain)==SQLITE_ROW ){ |
| 11405 | /* int iId = sqlite3_column_int(pExplain, 0); */ |
| 11406 | /* int iParent = sqlite3_column_int(pExplain, 1); */ |
| 11407 | /* int iNotUsed = sqlite3_column_int(pExplain, 2); */ |
| 11408 | const char *zDetail = (const char*)sqlite3_column_text(pExplain, 3); |
| 11409 | int nDetail; |
| 11410 | int i; |
| 11411 | |
| 11412 | if( !zDetail ) continue; |
| 11413 | nDetail = STRLEN(zDetail); |
| 11414 | |
| 11415 | for(i=0; i<nDetail; i++){ |
| 11416 | const char *zIdx = 0; |
| 11417 | if( i+13<nDetail && memcmp(&zDetail[i], " USING INDEX ", 13)==0 ){ |
| 11418 | zIdx = &zDetail[i+13]; |
| 11419 | }else if( i+22<nDetail |
| 11420 | && memcmp(&zDetail[i], " USING COVERING INDEX ", 22)==0 |
| 11421 | ){ |
| 11422 | zIdx = &zDetail[i+22]; |
| 11423 | } |
| 11424 | if( zIdx ){ |
| 11425 | const char *zSql; |
| 11426 | int nIdx = 0; |
| 11427 | while( zIdx[nIdx]!='\0' && (zIdx[nIdx]!=' ' || zIdx[nIdx+1]!='(') ){ |
| 11428 | nIdx++; |
| 11429 | } |
| 11430 | zSql = idxHashSearch(&p->hIdx, zIdx, nIdx); |
| 11431 | if( zSql ){ |
| 11432 | idxHashAdd(&rc, &hIdx, zSql, 0); |
| 11433 | if( rc ) goto find_indexes_out; |
| 11434 | } |
| 11435 | break; |
| 11436 | } |
| 11437 | } |
| 11438 | |
| 11439 | if( zDetail[0]!='-' ){ |
| 11440 | pStmt->zEQP = idxAppendText(&rc, pStmt->zEQP, "%s\n", zDetail); |
| 11441 | } |
| 11442 | } |
| 11443 |
no test coverage detected