| 443 | } |
| 444 | |
| 445 | int stmt_cache_get(struct sqlthdstate *thd, struct sqlclntstate *clnt, |
| 446 | struct sql_state *rec, int prepFlags) |
| 447 | { |
| 448 | rec->status = CACHE_DISABLED; |
| 449 | if (gbl_enable_sql_stmt_caching == STMT_CACHE_NONE) |
| 450 | return 0; |
| 451 | if (gbl_enable_sql_stmt_caching == STMT_CACHE_PARAM && |
| 452 | param_count(clnt) == 0) |
| 453 | return 0; |
| 454 | if (extract_sqlcache_hint(rec->sql, rec->cache_hint, HINT_LEN)) { |
| 455 | rec->status = CACHE_HAS_HINT; |
| 456 | if (stmt_cache_find_and_remove_entry(thd->stmt_cache, rec->cache_hint, &rec->stmt_entry) == 0) { |
| 457 | rec->status |= CACHE_FOUND_STMT; |
| 458 | rec->stmt = rec->stmt_entry->stmt; |
| 459 | query_data_func(clnt, &rec->stmt_entry->stmt_data, |
| 460 | &rec->stmt_entry->stmt_data_sz, QUERY_STMT_DATA, |
| 461 | QUERY_DATA_SET); |
| 462 | } else { |
| 463 | /* We are not able to find the statement in cache, and this is a |
| 464 | * partial statement. Try to find sql string stored in hash table */ |
| 465 | void *data; |
| 466 | int data_sz; |
| 467 | if (find_sql_hint_table(rec->cache_hint, (char **)&rec->sql, &data, |
| 468 | &data_sz) == 0) { |
| 469 | rec->status |= CACHE_FOUND_STR; |
| 470 | query_data_func(clnt, &data, &data_sz, QUERY_HINT_DATA, QUERY_DATA_SET); |
| 471 | } |
| 472 | } |
| 473 | } else { |
| 474 | if (stmt_cache_find_and_remove_entry(thd->stmt_cache, rec->sql, &rec->stmt_entry) == 0) { |
| 475 | rec->status = CACHE_FOUND_STMT; |
| 476 | rec->stmt = rec->stmt_entry->stmt; |
| 477 | } |
| 478 | } |
| 479 | |
| 480 | if (rec->stmt) { |
| 481 | rec->sql = sqlite3_sql(rec->stmt); // save expanded query |
| 482 | if ((prepFlags & PREPARE_ONLY) == 0) { |
| 483 | int rc = sqlite3LockStmtTables(rec->stmt); |
| 484 | if (rc) { |
| 485 | stmt_cache_remove_entry(thd->stmt_cache, rec->stmt_entry, 1); |
| 486 | stmt_cache_free_entry(rec->stmt_entry); |
| 487 | rec->stmt_entry = NULL; |
| 488 | rec->stmt = NULL; |
| 489 | rec->status = CACHE_DISABLED; |
| 490 | } |
| 491 | } |
| 492 | } |
| 493 | return 0; |
| 494 | } |
| 495 | |
| 496 | /* This is called at the time of put_prepared_stmt_int() |
| 497 | * to determine whether the given sql should be cached. |
no test coverage detected