MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
sp_rcontext.cc
1 /* Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
2 
3  This program is free software; you can redistribute it and/or modify
4  it under the terms of the GNU General Public License as published by
5  the Free Software Foundation; version 2 of the License.
6 
7  This program is distributed in the hope that it will be useful,
8  but WITHOUT ANY WARRANTY; without even the implied warranty of
9  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  GNU General Public License for more details.
11 
12  You should have received a copy of the GNU General Public License
13  along with this program; if not, write to the Free Software Foundation,
14  51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA */
15 
16 #include "sql_priv.h"
17 #include "unireg.h"
18 #include "mysql.h"
19 #include "sp.h" // sp_eval_expr
20 #include "sql_cursor.h"
21 #include "sp_rcontext.h"
22 #include "sp_pcontext.h"
23 #include "sql_tmp_table.h" // create_virtual_tmp_table
24 #include "sp_instr.h"
25 
26 extern "C" void sql_alloc_error_handler(void);
27 
29 // sp_rcontext implementation.
31 
32 
33 sp_rcontext::sp_rcontext(const sp_pcontext *root_parsing_ctx,
34  Field *return_value_fld,
35  bool in_sub_stmt)
36  :end_partial_result_set(false),
37  m_root_parsing_ctx(root_parsing_ctx),
38  m_var_table(NULL),
39  m_return_value_fld(return_value_fld),
40  m_return_value_set(false),
41  m_in_sub_stmt(in_sub_stmt),
42  m_ccount(0)
43 {
44 }
45 
46 
47 sp_rcontext::~sp_rcontext()
48 {
49  if (m_var_table)
50  free_blobs(m_var_table);
51 
52  while (m_activated_handlers.elements())
53  delete m_activated_handlers.pop();
54 
55  while (m_visible_handlers.elements())
56  delete m_visible_handlers.pop();
57 
58  pop_all_cursors();
59 
60  // Leave m_var_items and m_case_expr_holders untouched.
61  // They are allocated in mem roots and will be freed accordingly.
62 }
63 
64 
66  const sp_pcontext *root_parsing_ctx,
67  Field *return_value_fld)
68 {
69  sp_rcontext *ctx= new (thd->mem_root) sp_rcontext(root_parsing_ctx,
70  return_value_fld,
71  thd->in_sub_stmt);
72 
73  if (!ctx)
74  return NULL;
75 
76  if (ctx->alloc_arrays(thd) ||
77  ctx->init_var_table(thd) ||
78  ctx->init_var_items(thd))
79  {
80  delete ctx;
81  return NULL;
82  }
83 
84  return ctx;
85 }
86 
87 
88 bool sp_rcontext::alloc_arrays(THD *thd)
89 {
90  {
91  size_t n= m_root_parsing_ctx->max_cursor_index();
92  m_cstack.reset(
93  static_cast<sp_cursor **> (
94  thd->alloc(n * sizeof (sp_cursor*))),
95  n);
96  }
97 
98  {
99  size_t n= m_root_parsing_ctx->get_num_case_exprs();
100  m_case_expr_holders.reset(
101  static_cast<Item_cache **> (
102  thd->calloc(n * sizeof (Item_cache*))),
103  n);
104  }
105 
106  return !m_cstack.array() || !m_case_expr_holders.array();
107 }
108 
109 
110 bool sp_rcontext::init_var_table(THD *thd)
111 {
112  List<Create_field> field_def_lst;
113 
114  if (!m_root_parsing_ctx->max_var_index())
115  return false;
116 
117  m_root_parsing_ctx->retrieve_field_definitions(&field_def_lst);
118 
119  DBUG_ASSERT(field_def_lst.elements == m_root_parsing_ctx->max_var_index());
120 
121  if (!(m_var_table= create_virtual_tmp_table(thd, field_def_lst)))
122  return true;
123 
124  m_var_table->copy_blobs= true;
125  m_var_table->alias= "";
126 
127  return false;
128 }
129 
130 
131 bool sp_rcontext::init_var_items(THD *thd)
132 {
133  uint num_vars= m_root_parsing_ctx->max_var_index();
134 
135  m_var_items.reset(
136  static_cast<Item **> (
137  thd->alloc(num_vars * sizeof (Item *))),
138  num_vars);
139 
140  if (!m_var_items.array())
141  return true;
142 
143  for (uint idx = 0; idx < num_vars; ++idx)
144  {
145  if (!(m_var_items[idx]= new Item_field(m_var_table->field[idx])))
146  return true;
147  }
148 
149  return false;
150 }
151 
152 
153 bool sp_rcontext::set_return_value(THD *thd, Item **return_value_item)
154 {
155  DBUG_ASSERT(m_return_value_fld);
156 
157  m_return_value_set = true;
158 
159  return sp_eval_expr(thd, m_return_value_fld, return_value_item);
160 }
161 
162 
164 {
165  /*
166  We should create cursors on the system heap because:
167  - they could be (and usually are) used in several instructions,
168  thus they can not be stored on an execution mem-root;
169  - a cursor can be pushed/popped many times in a loop, having these objects
170  on callers' mem-root would lead to a memory leak in every iteration.
171  */
172  sp_cursor *c= new (std::nothrow) sp_cursor(i);
173 
174  if (!c)
175  {
176  sql_alloc_error_handler();
177  return true;
178  }
179 
180  m_cstack[m_ccount++]= c;
181  return false;
182 }
183 
184 
185 void sp_rcontext::pop_cursors(uint count)
186 {
187  DBUG_ASSERT(m_ccount >= count);
188 
189  while (count--)
190  delete m_cstack[--m_ccount];
191 }
192 
193 
195 {
196  /*
197  We should create handler entries on the system heap because:
198  - they could be (and usually are) used in several instructions,
199  thus they can not be stored on an execution mem-root;
200  - a handler can be pushed/popped many times in a loop, having these
201  objects on callers' mem-root would lead to a memory leak in every
202  iteration.
203  */
204 
205  sp_handler_entry *he=
206  new (std::nothrow) sp_handler_entry(handler, first_ip);
207 
208  if (!he)
209  {
210  sql_alloc_error_handler();
211  return true;
212  }
213 
214  return m_visible_handlers.append(he);
215 }
216 
217 
219 {
220  for (int i= m_visible_handlers.elements() - 1; i >= 0; --i)
221  {
222  int handler_level= m_visible_handlers.at(i)->handler->scope->get_level();
223 
224  if (handler_level >= current_scope->get_level())
225  delete m_visible_handlers.pop();
226  }
227 }
228 
229 
231 {
232  // Pop the current handler frame.
233 
234  delete m_activated_handlers.pop();
235 
236  // Pop frames below the target scope level.
237 
238  for (int i= m_activated_handlers.elements() - 1; i >= 0; --i)
239  {
240  int handler_level= m_activated_handlers.at(i)->handler->scope->get_level();
241 
242  /*
243  Only pop until we hit the first handler with appropriate scope level.
244  Otherwise we can end up popping handlers from separate scopes.
245  */
246  if (handler_level > target_scope->get_level())
247  delete m_activated_handlers.pop();
248  else
249  break;
250  }
251 }
252 
253 
255  uint *ip,
256  const sp_instr *cur_spi)
257 {
258  DBUG_ENTER("sp_rcontext::handle_sql_condition");
259 
260  /*
261  If this is a fatal sub-statement error, and this runtime
262  context corresponds to a sub-statement, no CONTINUE/EXIT
263  handlers from this context are applicable: try to locate one
264  in the outer scope.
265  */
266  if (thd->is_fatal_sub_stmt_error && m_in_sub_stmt)
267  DBUG_RETURN(false);
268 
269  Diagnostics_area *da= thd->get_stmt_da();
270  const sp_handler *found_handler= NULL;
271 
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;
277 
278  if (thd->is_error())
279  {
280  sp_pcontext *cur_pctx= cur_spi->get_parsing_ctx();
281 
282  found_handler= cur_pctx->find_handler(da->get_sqlstate(),
283  da->sql_errno(),
284  Sql_condition::WARN_LEVEL_ERROR);
285 
286  if (!found_handler)
287  DBUG_RETURN(false);
288 
289  if (da->get_error_condition())
290  {
291  const Sql_condition *c= da->get_error_condition();
292  condition_sql_errno= c->get_sql_errno();
293  condition_level= c->get_level();
294  condition_sqlstate= c->get_sqlstate();
295  condition_message= c->get_message_text();
296  }
297  else
298  {
299  /*
300  SQL condition can be NULL if the diagnostics area was full
301  when the error was raised. It can also be NULL if
302  Diagnostics_area::set_error_status(uint sql_error) was used.
303  */
304 
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();
309  }
310  }
311  else if (da->current_statement_warn_count())
312  {
313  Diagnostics_area::Sql_condition_iterator it= da->sql_conditions();
314  const Sql_condition *c;
315 
316  // Here we need to find the last warning/note from the stack.
317  // In MySQL most substantial warning is the last one.
318  // (We could have used a reverse iterator here if one existed)
319 
320  while ((c= it++))
321  {
322  if (c->get_level() == Sql_condition::WARN_LEVEL_WARN ||
323  c->get_level() == Sql_condition::WARN_LEVEL_NOTE)
324  {
325  sp_pcontext *cur_pctx= cur_spi->get_parsing_ctx();
326 
327  const sp_handler *handler= cur_pctx->find_handler(c->get_sqlstate(),
328  c->get_sql_errno(),
329  c->get_level());
330  if (handler)
331  {
332  found_handler= handler;
333 
334  condition_sql_errno= c->get_sql_errno();
335  condition_level= c->get_level();
336  condition_sqlstate= c->get_sqlstate();
337  condition_message= c->get_message_text();
338  }
339  }
340  }
341  }
342 
343  if (!found_handler)
344  DBUG_RETURN(false);
345 
346  // At this point, we know that:
347  // - there is a pending SQL-condition (error or warning);
348  // - there is an SQL-handler for it.
349 
350  DBUG_ASSERT(condition_sql_errno != 0);
351 
352  sp_handler_entry *handler_entry= NULL;
353  for (int i= 0; i < m_visible_handlers.elements(); ++i)
354  {
355  sp_handler_entry *h= m_visible_handlers.at(i);
356 
357  if (h->handler == found_handler)
358  {
359  handler_entry= h;
360  break;
361  }
362  }
363 
364  /*
365  handler_entry usually should not be NULL here, as that indicates
366  that the parser context thinks a HANDLER should be activated,
367  but the runtime context cannot find it.
368 
369  However, this can happen (and this is in line with the Standard)
370  if SQL-condition has been raised before DECLARE HANDLER instruction
371  is processed.
372 
373  For example:
374  CREATE PROCEDURE p()
375  BEGIN
376  DECLARE v INT DEFAULT 'get'; -- raises SQL-warning here
377  DECLARE EXIT HANDLER ... -- this handler does not catch the warning
378  END
379  */
380  if (!handler_entry)
381  DBUG_RETURN(false);
382 
383  // Mark active conditions so that they can be deleted when the handler exits.
384  da->mark_sql_conditions_for_removal();
385 
386  uint continue_ip= handler_entry->handler->type == sp_handler::CONTINUE ?
387  cur_spi->get_cont_dest() : 0;
388 
389  /* End aborted result set. */
391  thd->protocol->end_partial_result_set(thd);
392 
393  /* Add a frame to handler-call-stack. */
394  Handler_call_frame *frame=
395  new (std::nothrow) Handler_call_frame(found_handler,
396  condition_sql_errno,
397  condition_sqlstate,
398  condition_level,
399  condition_message,
400  continue_ip);
401 
402  /* Reset error state. */
403  thd->clear_error();
404  thd->killed= THD::NOT_KILLED; // Some errors set thd->killed
405  // (e.g. "bad data").
406 
407  if (!frame)
408  {
409  sql_alloc_error_handler();
410  DBUG_RETURN(false);
411  }
412 
413  m_activated_handlers.append(frame);
414 
415  *ip= handler_entry->first_ip;
416 
417  DBUG_RETURN(true);
418 }
419 
420 
421 bool sp_rcontext::set_variable(THD *thd, Field *field, Item **value)
422 {
423  if (!value)
424  {
425  field->set_null();
426  return false;
427  }
428 
429  return sp_eval_expr(thd, field, value);
430 }
431 
432 
433 Item_cache *sp_rcontext::create_case_expr_holder(THD *thd,
434  const Item *item) const
435 {
436  Item_cache *holder;
437  Query_arena current_arena;
438 
439  thd->set_n_backup_active_arena(thd->sp_runtime_ctx->callers_arena,
440  &current_arena);
441 
442  holder= Item_cache::get_cache(item);
443 
444  thd->restore_active_arena(thd->sp_runtime_ctx->callers_arena, &current_arena);
445 
446  return holder;
447 }
448 
449 
450 bool sp_rcontext::set_case_expr(THD *thd, int case_expr_id,
451  Item **case_expr_item_ptr)
452 {
453  Item *case_expr_item= sp_prepare_func_item(thd, case_expr_item_ptr);
454  if (!case_expr_item)
455  return true;
456 
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())
460  {
461  m_case_expr_holders[case_expr_id]=
462  create_case_expr_holder(thd, case_expr_item);
463  }
464 
465  m_case_expr_holders[case_expr_id]->store(case_expr_item);
466  m_case_expr_holders[case_expr_id]->cache_value();
467  return false;
468 }
469 
470 
472 // sp_cursor implementation.
474 
475 
484 bool sp_cursor::open(THD *thd)
485 {
486  if (m_server_side_cursor)
487  {
488  my_message(ER_SP_CURSOR_ALREADY_OPEN, ER(ER_SP_CURSOR_ALREADY_OPEN),
489  MYF(0));
490  return true;
491  }
492 
493  return mysql_open_cursor(thd, &m_result, &m_server_side_cursor);
494 }
495 
496 
497 bool sp_cursor::close(THD *thd)
498 {
499  if (! m_server_side_cursor)
500  {
501  my_message(ER_SP_CURSOR_NOT_OPEN, ER(ER_SP_CURSOR_NOT_OPEN), MYF(0));
502  return true;
503  }
504 
505  destroy();
506  return false;
507 }
508 
509 
510 void sp_cursor::destroy()
511 {
512  delete m_server_side_cursor;
513  m_server_side_cursor= NULL;
514 }
515 
516 
517 bool sp_cursor::fetch(THD *thd, List<sp_variable> *vars)
518 {
519  if (! m_server_side_cursor)
520  {
521  my_message(ER_SP_CURSOR_NOT_OPEN, ER(ER_SP_CURSOR_NOT_OPEN), MYF(0));
522  return true;
523  }
524 
525  if (vars->elements != m_result.get_field_count())
526  {
527  my_message(ER_SP_WRONG_NO_OF_FETCH_ARGS,
528  ER(ER_SP_WRONG_NO_OF_FETCH_ARGS), MYF(0));
529  return true;
530  }
531 
532  DBUG_EXECUTE_IF("bug23032_emit_warning",
533  push_warning(thd, Sql_condition::WARN_LEVEL_WARN,
534  ER_UNKNOWN_ERROR,
535  ER(ER_UNKNOWN_ERROR)););
536 
537  m_result.set_spvar_list(vars);
538 
539  /* Attempt to fetch one row */
540  if (m_server_side_cursor->is_open())
541  m_server_side_cursor->fetch(1);
542 
543  /*
544  If the cursor was pointing after the last row, the fetch will
545  close it instead of sending any rows.
546  */
547  if (! m_server_side_cursor->is_open())
548  {
549  my_message(ER_SP_FETCH_NO_DATA, ER(ER_SP_FETCH_NO_DATA), MYF(0));
550  return true;
551  }
552 
553  return false;
554 }
555 
556 
558 // sp_cursor::Select_fetch_into_spvars implementation.
560 
561 
562 int sp_cursor::Select_fetch_into_spvars::prepare(List<Item> &fields,
563  SELECT_LEX_UNIT *u)
564 {
565  /*
566  Cache the number of columns in the result set in order to easily
567  return an error if column count does not match value count.
568  */
569  field_count= fields.elements;
570  return select_result_interceptor::prepare(fields, u);
571 }
572 
573 
574 bool sp_cursor::Select_fetch_into_spvars::send_data(List<Item> &items)
575 {
576  List_iterator_fast<sp_variable> spvar_iter(*spvar_list);
577  List_iterator_fast<Item> item_iter(items);
578  sp_variable *spvar;
579  Item *item;
580 
581  /* Must be ensured by the caller */
582  DBUG_ASSERT(spvar_list->elements == items.elements);
583 
584  /*
585  Assign the row fetched from a server side cursor to stored
586  procedure variables.
587  */
588  for (; spvar= spvar_iter++, item= item_iter++; )
589  {
590  if (thd->sp_runtime_ctx->set_variable(thd, spvar->offset, &item))
591  return true;
592  }
593  return false;
594 }