| 43 | */ |
| 44 | |
| 45 | int mysql_open_cursor(THD *thd, select_result *result, |
| 46 | Server_side_cursor **pcursor, |
| 47 | const Lex_ident_column &cursor_name, |
| 48 | const Virtual_tmp_table *return_type) |
| 49 | { |
| 50 | sql_digest_state *parent_digest; |
| 51 | PSI_statement_locker *parent_locker; |
| 52 | select_result *save_result; |
| 53 | Select_materialize *result_materialize; |
| 54 | LEX *lex= thd->lex; |
| 55 | int rc; |
| 56 | const CSET_STRING query_backup= thd->query_string; |
| 57 | |
| 58 | if (!(result_materialize= new (thd->mem_root) Select_materialize(thd, result, |
| 59 | cursor_name, return_type))) |
| 60 | return 1; |
| 61 | |
| 62 | save_result= lex->result; |
| 63 | |
| 64 | lex->result= result_materialize; |
| 65 | |
| 66 | if (const sp_lex_cursor *clex= lex->get_lex_for_cursor()) |
| 67 | { |
| 68 | const LEX_CSTRING tmp_query= get_cursor_query(clex->get_expr_str()); |
| 69 | thd->set_query((char*) tmp_query.str, tmp_query.length); |
| 70 | } |
| 71 | |
| 72 | MYSQL_QUERY_EXEC_START(thd->query(), |
| 73 | thd->thread_id, |
| 74 | thd->get_db(), |
| 75 | &thd->security_ctx->priv_user[0], |
| 76 | (char *) thd->security_ctx->host_or_ip, |
| 77 | 2); |
| 78 | parent_digest= thd->m_digest; |
| 79 | parent_locker= thd->m_statement_psi; |
| 80 | thd->m_digest= NULL; |
| 81 | thd->m_statement_psi= NULL; |
| 82 | /* Mark that we can't use query cache with cursors */ |
| 83 | thd->query_cache_is_applicable= 0; |
| 84 | rc= mysql_execute_command(thd); |
| 85 | thd->update_server_status(); |
| 86 | thd->lex->restore_set_statement_var(); |
| 87 | thd->m_digest= parent_digest; |
| 88 | thd->m_statement_psi= parent_locker; |
| 89 | MYSQL_QUERY_EXEC_DONE(rc); |
| 90 | |
| 91 | lex->result= save_result; |
| 92 | /* |
| 93 | Possible options here: |
| 94 | - a materialized cursor is open. In this case rc is 0 and |
| 95 | result_materialize->materialized is not NULL |
| 96 | - an error occurred during materialization. |
| 97 | result_materialize->materialized_cursor is not NULL, but rc != 0 |
| 98 | - successful completion of mysql_execute_command without |
| 99 | a cursor: rc is 0, result_materialize->materialized_cursor is NULL. |
| 100 | This is possible if some command writes directly to the |
| 101 | network, bypassing select_result mechanism. An example of |
| 102 | such command is SHOW VARIABLES or SHOW STATUS. |
no test coverage detected