21 #include "sp_rcontext.h"
22 #include "sp_pcontext.h"
26 extern "C" void sql_alloc_error_handler(
void);
33 sp_rcontext::sp_rcontext(
const sp_pcontext *root_parsing_ctx,
34 Field *return_value_fld,
36 :end_partial_result_set(false),
37 m_root_parsing_ctx(root_parsing_ctx),
39 m_return_value_fld(return_value_fld),
40 m_return_value_set(false),
41 m_in_sub_stmt(in_sub_stmt),
47 sp_rcontext::~sp_rcontext()
50 free_blobs(m_var_table);
52 while (m_activated_handlers.elements())
53 delete m_activated_handlers.
pop();
55 while (m_visible_handlers.elements())
56 delete m_visible_handlers.
pop();
67 Field *return_value_fld)
76 if (ctx->alloc_arrays(thd) ||
77 ctx->init_var_table(thd) ||
78 ctx->init_var_items(thd))
88 bool sp_rcontext::alloc_arrays(THD *thd)
91 size_t n= m_root_parsing_ctx->max_cursor_index();
93 static_cast<sp_cursor **> (
99 size_t n= m_root_parsing_ctx->get_num_case_exprs();
100 m_case_expr_holders.reset(
101 static_cast<Item_cache **> (
106 return !m_cstack.array() || !m_case_expr_holders.array();
110 bool sp_rcontext::init_var_table(THD *thd)
119 DBUG_ASSERT(field_def_lst.elements == m_root_parsing_ctx->
max_var_index());
121 if (!(m_var_table= create_virtual_tmp_table(thd, field_def_lst)))
124 m_var_table->copy_blobs=
true;
125 m_var_table->alias=
"";
131 bool sp_rcontext::init_var_items(THD *thd)
136 static_cast<Item **> (
137 thd->alloc(num_vars * sizeof (
Item *))),
140 if (!m_var_items.array())
143 for (uint idx = 0; idx < num_vars; ++idx)
145 if (!(m_var_items[idx]=
new Item_field(m_var_table->field[idx])))
153 bool sp_rcontext::set_return_value(THD *thd,
Item **return_value_item)
155 DBUG_ASSERT(m_return_value_fld);
157 m_return_value_set =
true;
159 return sp_eval_expr(thd, m_return_value_fld, return_value_item);
176 sql_alloc_error_handler();
180 m_cstack[m_ccount++]= c;
187 DBUG_ASSERT(m_ccount >= count);
190 delete m_cstack[--m_ccount];
205 sp_handler_entry *he=
206 new (std::nothrow) sp_handler_entry(handler, first_ip);
210 sql_alloc_error_handler();
214 return m_visible_handlers.
append(he);
220 for (
int i= m_visible_handlers.elements() - 1;
i >= 0; --
i)
222 int handler_level= m_visible_handlers.
at(
i)->handler->scope->get_level();
224 if (handler_level >= current_scope->get_level())
225 delete m_visible_handlers.
pop();
234 delete m_activated_handlers.
pop();
238 for (
int i= m_activated_handlers.elements() - 1;
i >= 0; --
i)
240 int handler_level= m_activated_handlers.
at(
i)->handler->scope->get_level();
246 if (handler_level > target_scope->get_level())
247 delete m_activated_handlers.
pop();
258 DBUG_ENTER(
"sp_rcontext::handle_sql_condition");
266 if (thd->is_fatal_sub_stmt_error && m_in_sub_stmt)
272 uint condition_sql_errno= 0;
273 Sql_condition::enum_warning_level condition_level=
274 Sql_condition::WARN_LEVEL_NOTE;
275 const char *condition_sqlstate= NULL;
276 const char *condition_message= NULL;
282 found_handler= cur_pctx->
find_handler(da->get_sqlstate(),
284 Sql_condition::WARN_LEVEL_ERROR);
289 if (da->get_error_condition())
305 condition_sql_errno= da->sql_errno();
306 condition_level= Sql_condition::WARN_LEVEL_ERROR;
307 condition_sqlstate= da->get_sqlstate();
308 condition_message= da->message();
311 else if (da->current_statement_warn_count())
322 if (c->
get_level() == Sql_condition::WARN_LEVEL_WARN ||
323 c->
get_level() == Sql_condition::WARN_LEVEL_NOTE)
332 found_handler= handler;
350 DBUG_ASSERT(condition_sql_errno != 0);
352 sp_handler_entry *handler_entry= NULL;
353 for (
int i= 0;
i < m_visible_handlers.elements(); ++
i)
355 sp_handler_entry *h= m_visible_handlers.
at(
i);
357 if (h->handler == found_handler)
384 da->mark_sql_conditions_for_removal();
386 uint continue_ip= handler_entry->handler->type == sp_handler::CONTINUE ?
391 thd->protocol->end_partial_result_set(thd);
394 Handler_call_frame *frame=
395 new (std::nothrow) Handler_call_frame(found_handler,
404 thd->killed= THD::NOT_KILLED;
409 sql_alloc_error_handler();
413 m_activated_handlers.
append(frame);
415 *ip= handler_entry->first_ip;
421 bool sp_rcontext::set_variable(THD *thd,
Field *field,
Item **value)
429 return sp_eval_expr(thd, field, value);
433 Item_cache *sp_rcontext::create_case_expr_holder(THD *thd,
434 const Item *item)
const
437 Query_arena current_arena;
439 thd->set_n_backup_active_arena(thd->sp_runtime_ctx->callers_arena,
442 holder= Item_cache::get_cache(item);
444 thd->restore_active_arena(thd->sp_runtime_ctx->callers_arena, ¤t_arena);
451 Item **case_expr_item_ptr)
453 Item *case_expr_item= sp_prepare_func_item(thd, case_expr_item_ptr);
457 if (!m_case_expr_holders[case_expr_id] ||
458 m_case_expr_holders[case_expr_id]->result_type() !=
459 case_expr_item->result_type())
461 m_case_expr_holders[case_expr_id]=
462 create_case_expr_holder(thd, case_expr_item);
465 m_case_expr_holders[case_expr_id]->store(case_expr_item);
466 m_case_expr_holders[case_expr_id]->cache_value();
486 if (m_server_side_cursor)
488 my_message(ER_SP_CURSOR_ALREADY_OPEN, ER(ER_SP_CURSOR_ALREADY_OPEN),
493 return mysql_open_cursor(thd, &m_result, &m_server_side_cursor);
497 bool sp_cursor::close(THD *thd)
499 if (! m_server_side_cursor)
501 my_message(ER_SP_CURSOR_NOT_OPEN, ER(ER_SP_CURSOR_NOT_OPEN), MYF(0));
510 void sp_cursor::destroy()
512 delete m_server_side_cursor;
513 m_server_side_cursor= NULL;
519 if (! m_server_side_cursor)
521 my_message(ER_SP_CURSOR_NOT_OPEN, ER(ER_SP_CURSOR_NOT_OPEN), MYF(0));
525 if (vars->elements != m_result.get_field_count())
527 my_message(ER_SP_WRONG_NO_OF_FETCH_ARGS,
528 ER(ER_SP_WRONG_NO_OF_FETCH_ARGS), MYF(0));
532 DBUG_EXECUTE_IF(
"bug23032_emit_warning",
533 push_warning(thd, Sql_condition::WARN_LEVEL_WARN,
535 ER(ER_UNKNOWN_ERROR)););
537 m_result.set_spvar_list(vars);
540 if (m_server_side_cursor->is_open())
541 m_server_side_cursor->fetch(1);
547 if (! m_server_side_cursor->is_open())
549 my_message(ER_SP_FETCH_NO_DATA, ER(ER_SP_FETCH_NO_DATA), MYF(0));
562 int sp_cursor::Select_fetch_into_spvars::prepare(
List<Item> &fields,
569 field_count= fields.elements;
570 return select_result_interceptor::prepare(fields, u);
582 DBUG_ASSERT(spvar_list->elements == items.elements);
588 for (; spvar= spvar_iter++, item= item_iter++; )
590 if (thd->sp_runtime_ctx->set_variable(thd, spvar->
offset, &item))