MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
sp_instr.cc
1 /* Copyright (c) 2012, 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
14  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
15 
16 #include "my_global.h" // NO_EMBEDDED_ACCESS_CHECKS
17 #include "sql_priv.h"
18 #include "sp_instr.h"
19 #include "item.h" // Item_splocal
20 #include "opt_trace.h" // opt_trace_disable_etc
21 #include "probes_mysql.h" // MYSQL_QUERY_EXEC_START
22 #include "sp_head.h" // sp_head
23 #include "sp.h" // sp_get_item_value
24 #include "sp_rcontext.h" // sp_rcontext
25 #include "sql_acl.h" // SELECT_ACL
26 #include "sql_base.h" // open_temporary_tables
27 #include "sql_parse.h" // check_table_access
28 #include "sql_prepare.h" // reinit_stmt_before_use
29 #include "transaction.h" // trans_commit_stmt
30 
31 #include <algorithm>
32 
34 // Static function implementation.
36 
37 
38 static int cmp_splocal_locations(Item_splocal * const *a,
39  Item_splocal * const *b)
40 {
41  return (int)((*a)->pos_in_query - (*b)->pos_in_query);
42 }
43 
44 
45 /*
46  StoredRoutinesBinlogging
47  This paragraph applies only to statement-based binlogging. Row-based
48  binlogging does not need anything special like this.
49 
50  Top-down overview:
51 
52  1. Statements
53 
54  Statements that have is_update_query(stmt) == TRUE are written into the
55  binary log verbatim.
56  Examples:
57  UPDATE tbl SET tbl.x = spfunc_w_side_effects()
58  UPDATE tbl SET tbl.x=1 WHERE spfunc_w_side_effect_that_returns_false(tbl.y)
59 
60  Statements that have is_update_query(stmt) == FALSE (e.g. SELECTs) are not
61  written into binary log. Instead we catch function calls the statement
62  makes and write it into binary log separately (see #3).
63 
64  2. PROCEDURE calls
65 
66  CALL statements are not written into binary log. Instead
67  * Any FUNCTION invocation (in SET, IF, WHILE, OPEN CURSOR and other SP
68  instructions) is written into binlog separately.
69 
70  * Each statement executed in SP is binlogged separately, according to rules
71  in #1, with the exception that we modify query string: we replace uses
72  of SP local variables with NAME_CONST('spvar_name', <spvar-value>) calls.
73  This substitution is done in subst_spvars().
74 
75  3. FUNCTION calls
76 
77  In sp_head::execute_function(), we check
78  * If this function invocation is done from a statement that is written
79  into the binary log.
80  * If there were any attempts to write events to the binary log during
81  function execution (grep for start_union_events and stop_union_events)
82 
83  If the answers are No and Yes, we write the function call into the binary
84  log as "SELECT spfunc(<param1value>, <param2value>, ...)"
85 
86 
87  4. Miscellaneous issues.
88 
89  4.1 User variables.
90 
91  When we call mysql_bin_log.write() for an SP statement, thd->user_var_events
92  must hold set<{var_name, value}> pairs for all user variables used during
93  the statement execution.
94  This set is produced by tracking user variable reads during statement
95  execution.
96 
97  For SPs, this has the following implications:
98  1) thd->user_var_events may contain events from several SP statements and
99  needs to be valid after execution of these statements was finished. In
100  order to achieve that, we
101  * Allocate user_var_events array elements on appropriate mem_root (grep
102  for user_var_events_alloc).
103  * Use is_query_in_union() to determine if user_var_event is created.
104 
105  2) We need to empty thd->user_var_events after we have wrote a function
106  call. This is currently done by making
107  reset_dynamic(&thd->user_var_events);
108  calls in several different places. (TODO consider moving this into
109  mysql_bin_log.write() function)
110 
111  4.2 Auto_increment storage in binlog
112 
113  As we may write two statements to binlog from one single logical statement
114  (case of "SELECT func1(),func2()": it is binlogged as "SELECT func1()" and
115  then "SELECT func2()"), we need to reset auto_increment binlog variables
116  after each binlogged SELECT. Otherwise, the auto_increment value of the
117  first SELECT would be used for the second too.
118 */
119 
138 static bool subst_spvars(THD *thd, sp_instr *instr, LEX_STRING *query_str)
139 {
140  Dynamic_array<Item_splocal*> sp_vars_uses;
141  char *pbuf, *cur, buffer[512];
142  String qbuf(buffer, sizeof(buffer), &my_charset_bin);
143  int prev_pos, res, buf_len;
144 
145  /* Find all instances of Item_splocal used in this statement */
146  for (Item *item= instr->free_list; item; item= item->next)
147  {
148  if (item->is_splocal())
149  {
150  Item_splocal *item_spl= (Item_splocal*)item;
151  if (item_spl->pos_in_query)
152  sp_vars_uses.append(item_spl);
153  }
154  }
155 
156  if (!sp_vars_uses.elements())
157  return false;
158 
159  /* Sort SP var refs by their occurrences in the query */
160  sp_vars_uses.sort(cmp_splocal_locations);
161 
162  /*
163  Construct a statement string where SP local var refs are replaced
164  with "NAME_CONST(name, value)"
165  */
166  qbuf.length(0);
167  cur= query_str->str;
168  prev_pos= res= 0;
169  thd->query_name_consts= 0;
170 
171  for (Item_splocal **splocal= sp_vars_uses.front();
172  splocal <= sp_vars_uses.back(); splocal++)
173  {
174  Item *val;
175 
176  char str_buffer[STRING_BUFFER_USUAL_SIZE];
177  String str_value_holder(str_buffer, sizeof(str_buffer),
178  &my_charset_latin1);
179  String *str_value;
180 
181  /* append the text between sp ref occurrences */
182  res|= qbuf.append(cur + prev_pos, (*splocal)->pos_in_query - prev_pos);
183  prev_pos= (*splocal)->pos_in_query + (*splocal)->len_in_query;
184 
185  res|= (*splocal)->fix_fields(thd, (Item **) splocal);
186  if (res)
187  break;
188 
189  if ((*splocal)->limit_clause_param)
190  {
191  res|= qbuf.append_ulonglong((*splocal)->val_uint());
192  if (res)
193  break;
194  continue;
195  }
196 
197  /* append the spvar substitute */
198  res|= qbuf.append(STRING_WITH_LEN(" NAME_CONST('"));
199  res|= qbuf.append((*splocal)->m_name);
200  res|= qbuf.append(STRING_WITH_LEN("',"));
201 
202  if (res)
203  break;
204 
205  val= (*splocal)->this_item();
206  str_value= sp_get_item_value(thd, val, &str_value_holder);
207  if (str_value)
208  res|= qbuf.append(*str_value);
209  else
210  res|= qbuf.append(STRING_WITH_LEN("NULL"));
211  res|= qbuf.append(')');
212  if (res)
213  break;
214 
215  thd->query_name_consts++;
216  }
217  if (res ||
218  qbuf.append(cur + prev_pos, query_str->length - prev_pos))
219  return true;
220 
221  /*
222  Allocate additional space at the end of the new query string for the
223  query_cache_send_result_to_client function.
224 
225  The query buffer layout is:
226  buffer :==
227  <statement> The input statement(s)
228  '\0' Terminating null char
229  <length> Length of following current database name (size_t)
230  <db_name> Name of current database
231  <flags> Flags struct
232  */
233  buf_len= qbuf.length() + 1 + sizeof(size_t) + thd->db_length +
234  QUERY_CACHE_FLAGS_SIZE + 1;
235  if ((pbuf= (char *) alloc_root(thd->mem_root, buf_len)))
236  {
237  memcpy(pbuf, qbuf.ptr(), qbuf.length());
238  pbuf[qbuf.length()]= 0;
239  memcpy(pbuf+qbuf.length()+1, (char *) &thd->db_length, sizeof(size_t));
240  }
241  else
242  return true;
243 
244  thd->set_query(pbuf, qbuf.length());
245 
246  return false;
247 }
248 
250 // Sufficient max length of printed destinations and frame offsets (all uints).
252 
253 #define SP_INSTR_UINT_MAXLEN 8
254 #define SP_STMT_PRINT_MAXLEN 40
255 
257 // sp_lex_instr implementation.
259 
260 
261 bool sp_lex_instr::reset_lex_and_exec_core(THD *thd,
262  uint *nextp,
263  bool open_tables)
264 {
265  bool rc= false;
266 
267  /*
268  The flag is saved at the entry to the following substatement.
269  It's reset further in the common code part.
270  It's merged with the saved parent's value at the exit of this func.
271  */
272 
273  unsigned int parent_unsafe_rollback_flags=
274  thd->transaction.stmt.get_unsafe_rollback_flags();
275  thd->transaction.stmt.reset_unsafe_rollback_flags();
276 
277  /* Check pre-conditions. */
278 
279  DBUG_ASSERT(!thd->derived_tables);
280  DBUG_ASSERT(thd->change_list.is_empty());
281 
282  /*
283  Use our own lex.
284 
285  Although it is saved/restored in sp_head::execute() when we are
286  entering/leaving routine, it's still should be saved/restored here,
287  in order to properly behave in case of ER_NEED_REPREPARE error
288  (when ER_NEED_REPREPARE happened, and we failed to re-parse the query).
289  */
290 
291  LEX *lex_saved= thd->lex;
292  thd->lex= m_lex;
293 
294  /* Set new query id. */
295 
296  thd->set_query_id(next_query_id());
297 
298  if (thd->locked_tables_mode <= LTM_LOCK_TABLES)
299  {
300  /*
301  This statement will enter/leave prelocked mode on its own.
302  Entering prelocked mode changes table list and related members
303  of LEX, so we'll need to restore them.
304  */
305  if (m_lex_query_tables_own_last)
306  {
307  /*
308  We've already entered/left prelocked mode with this statement.
309  Attach the list of tables that need to be prelocked and mark m_lex
310  as having such list attached.
311  */
312  *m_lex_query_tables_own_last= m_prelocking_tables;
313  m_lex->mark_as_requiring_prelocking(m_lex_query_tables_own_last);
314  }
315  }
316 
317  /* Reset LEX-object before re-use. */
318 
319  reinit_stmt_before_use(thd, m_lex);
320 
321  /* Open tables if needed. */
322 
323  if (open_tables)
324  {
325  /*
326  IF, CASE, DECLARE, SET, RETURN, have 'open_tables' true; they may
327  have a subquery in parameter and are worth tracing. They don't
328  correspond to a SQL command so we pretend that they are SQLCOM_SELECT.
329  */
330  Opt_trace_start ots(thd, m_lex->query_tables, SQLCOM_SELECT,
331  &m_lex->var_list, NULL, 0, this,
332  thd->variables.character_set_client);
333  Opt_trace_object trace_command(&thd->opt_trace);
334  Opt_trace_array trace_command_steps(&thd->opt_trace, "steps");
335 
336  /*
337  Check whenever we have access to tables for this statement
338  and open and lock them before executing instructions core function.
339  If we are not opening any tables, we don't need to check permissions
340  either.
341  */
342  if (m_lex->query_tables)
343  rc= (open_temporary_tables(thd, m_lex->query_tables) ||
344  check_table_access(thd, SELECT_ACL, m_lex->query_tables, false,
345  UINT_MAX, false));
346 
347  if (!rc)
348  rc= open_and_lock_tables(thd, m_lex->query_tables, true, 0);
349 
350  if (!rc)
351  {
352  rc= exec_core(thd, nextp);
353  DBUG_PRINT("info",("exec_core returned: %d", rc));
354  }
355 
356  /*
357  Call after unit->cleanup() to close open table
358  key read.
359  */
360 
361  m_lex->unit.cleanup();
362 
363  /* Here we also commit or rollback the current statement. */
364 
365  if (! thd->in_sub_stmt)
366  {
367  thd->get_stmt_da()->set_overwrite_status(true);
368  thd->is_error() ? trans_rollback_stmt(thd) : trans_commit_stmt(thd);
369  thd->get_stmt_da()->set_overwrite_status(false);
370  }
371  thd_proc_info(thd, "closing tables");
372  close_thread_tables(thd);
373  thd_proc_info(thd, 0);
374 
375  if (! thd->in_sub_stmt)
376  {
377  if (thd->transaction_rollback_request)
378  {
379  trans_rollback_implicit(thd);
380  thd->mdl_context.release_transactional_locks();
381  }
382  else if (! thd->in_multi_stmt_transaction_mode())
383  thd->mdl_context.release_transactional_locks();
384  else
385  thd->mdl_context.release_statement_locks();
386  }
387  }
388  else
389  {
390  rc= exec_core(thd, nextp);
391  DBUG_PRINT("info",("exec_core returned: %d", rc));
392  }
393 
394  if (m_lex->query_tables_own_last)
395  {
396  /*
397  We've entered and left prelocking mode when executing statement
398  stored in m_lex.
399  m_lex->query_tables(->next_global)* list now has a 'tail' - a list
400  of tables that are added for prelocking. (If this is the first
401  execution, the 'tail' was added by open_tables(), otherwise we've
402  attached it above in this function).
403  Now we'll save the 'tail', and detach it.
404  */
405  m_lex_query_tables_own_last= m_lex->query_tables_own_last;
406  m_prelocking_tables= *m_lex_query_tables_own_last;
407  *m_lex_query_tables_own_last= NULL;
408  m_lex->mark_as_requiring_prelocking(NULL);
409  }
410 
411  /* Rollback changes to the item tree during execution. */
412 
413  thd->rollback_item_tree_changes();
414 
415  /*
416  Update the state of the active arena if no errors on
417  open_tables stage.
418  */
419 
420  if (!rc || !thd->is_error() ||
421  (thd->get_stmt_da()->sql_errno() != ER_CANT_REOPEN_TABLE &&
422  thd->get_stmt_da()->sql_errno() != ER_NO_SUCH_TABLE &&
423  thd->get_stmt_da()->sql_errno() != ER_UPDATE_TABLE_USED))
424  thd->stmt_arena->state= Query_arena::STMT_EXECUTED;
425 
426  /*
427  Merge here with the saved parent's values
428  what is needed from the substatement gained
429  */
430 
431  thd->transaction.stmt.add_unsafe_rollback_flags(parent_unsafe_rollback_flags);
432 
433  /* Restore original lex. */
434 
435  thd->lex= lex_saved;
436 
437  /*
438  Unlike for PS we should not call Item's destructors for newly created
439  items after execution of each instruction in stored routine. This is
440  because SP often create Item (like Item_int, Item_string etc...) when
441  they want to store some value in local variable, pass return value and
442  etc... So their life time should be longer than one instruction.
443 
444  cleanup_items() is called in sp_head::execute()
445  */
446 
447  return rc || thd->is_error();
448 }
449 
450 
451 LEX *sp_lex_instr::parse_expr(THD *thd, sp_head *sp)
452 {
453  String sql_query;
454  PSI_statement_locker *parent_locker= thd->m_statement_psi;
455  sql_query.set_charset(system_charset_info);
456 
457  get_query(&sql_query);
458 
459  if (sql_query.length() == 0)
460  {
461  // The instruction has returned zero-length query string. That means, the
462  // re-preparation of the instruction is not possible. We should not come
463  // here in the normal life.
464  DBUG_ASSERT(false);
465  my_error(ER_UNKNOWN_ERROR, MYF(0));
466  return NULL;
467  }
468 
469  // Cleanup current THD from previously held objects before new parsing.
471 
472  // Cleanup and re-init the lex mem_root for re-parse.
473  free_root(&m_lex_mem_root, MYF(0));
474  init_sql_alloc(&m_lex_mem_root, MEM_ROOT_BLOCK_SIZE, MEM_ROOT_PREALLOC);
475 
476  /*
477  Switch mem-roots. We store the new LEX and its Items in the
478  m_lex_mem_root since it is freed before reparse triggered due to
479  invalidation. This avoids the memory leak in case re-parse is
480  initiated. Also set the statement query arena to the lex mem_root.
481  */
482  MEM_ROOT *execution_mem_root= thd->mem_root;
483  Query_arena parse_arena(&m_lex_mem_root, thd->stmt_arena->state);
484 
485  thd->mem_root= &m_lex_mem_root;
486  thd->stmt_arena->set_query_arena(&parse_arena);
487 
488  // Prepare parser state. It can be done just before parse_sql(), do it here
489  // only to simplify exit in case of failure (out-of-memory error).
490 
491  Parser_state parser_state;
492 
493  if (parser_state.init(thd, sql_query.c_ptr(), sql_query.length()))
494  return NULL;
495 
496  // Switch THD::free_list. It's used to remember the newly created set of Items
497  // during parsing. We should clean those items after each execution.
498 
499  Item *execution_free_list= thd->free_list;
500  thd->free_list= NULL;
501 
502  // Create a new LEX and intialize it.
503 
504  LEX *lex_saved= thd->lex;
505 
506  thd->lex= new (thd->mem_root) st_lex_local;
507  lex_start(thd);
508 
509  thd->lex->sphead= sp;
510  thd->lex->set_sp_current_parsing_ctx(get_parsing_ctx());
511  sp->m_parser_data.set_current_stmt_start_ptr(sql_query.c_ptr());
512 
513  // Parse the just constructed SELECT-statement.
514 
515  thd->m_statement_psi= NULL;
516  bool parsing_failed= parse_sql(thd, &parser_state, NULL);
517  thd->m_statement_psi= parent_locker;
518 
519  if (!parsing_failed)
520  {
521  thd->lex->set_trg_event_type_for_tables();
522 
523  if (sp->m_type == SP_TYPE_TRIGGER)
524  {
525  /*
526  Also let us bind these objects to Field objects in table being opened.
527 
528  We ignore errors of setup_field() here, because if even something is
529  wrong we still will be willing to open table to perform some operations
530  (e.g. SELECT)... Anyway some things can be checked only during trigger
531  execution.
532  */
533 
535  int event= sp->m_trg_chistics.event;
536  int action_time= sp->m_trg_chistics.action_time;
537  GRANT_INFO *grant_table= &ttl->subject_table_grants[event][action_time];
538 
539  for (Item_trigger_field *trg_field= sp->m_trg_table_fields.first;
540  trg_field;
541  trg_field= trg_field->next_trg_field)
542  {
543  trg_field->setup_field(thd, ttl->trigger_table, grant_table);
544  }
545  }
546 
547  // Call after-parsing callback.
548 
549  parsing_failed= on_after_expr_parsing(thd);
550 
551  // Append newly created Items to the list of Items, owned by this
552  // instruction.
553 
554  free_list= thd->free_list;
555  }
556 
557  // Restore THD::lex.
558 
559  thd->lex->sphead= NULL;
560  thd->lex->set_sp_current_parsing_ctx(NULL);
561 
562  LEX *expr_lex= thd->lex;
563  thd->lex= lex_saved;
564 
565  // Restore execution mem-root and THD::free_list.
566 
567  thd->mem_root= execution_mem_root;
568  thd->free_list= execution_free_list;
569 
570  // That's it.
571 
572  return parsing_failed ? NULL : expr_lex;
573 }
574 
575 
577  uint *nextp,
578  bool open_tables)
579 {
580  Reprepare_observer reprepare_observer;
581  int reprepare_attempt= 0;
582 
583  while (true)
584  {
585  if (is_invalid())
586  {
587  LEX *lex= parse_expr(thd, thd->sp_runtime_ctx->sp);
588 
589  if (!lex)
590  return true;
591 
592  set_lex(lex, true);
593 
594  m_first_execution= true;
595  }
596 
597  /*
598  Install the metadata observer. If some metadata version is
599  different from prepare time and an observer is installed,
600  the observer method will be invoked to push an error into
601  the error stack.
602  */
603  Reprepare_observer *stmt_reprepare_observer= NULL;
604 
605  /*
606  Meta-data versions are stored in the LEX-object on the first execution.
607  Thus, the reprepare observer should not be installed for the first
608  execution, because it will always be triggered.
609 
610  Then, the reprepare observer should be installed for the statements, which
611  are marked by CF_REEXECUTION_FRAGILE (@sa CF_REEXECUTION_FRAGILE) or if
612  the SQL-command is SQLCOM_END, which means that the LEX-object is
613  representing an expression, so the exact SQL-command does not matter.
614  */
615 
616  if (!m_first_execution &&
617  (sql_command_flags[m_lex->sql_command] & CF_REEXECUTION_FRAGILE ||
618  m_lex->sql_command == SQLCOM_END))
619  {
620  reprepare_observer.reset_reprepare_observer();
621  stmt_reprepare_observer= &reprepare_observer;
622  }
623 
624  thd->push_reprepare_observer(stmt_reprepare_observer);
625 
626  bool rc= reset_lex_and_exec_core(thd, nextp, open_tables);
627 
628  thd->pop_reprepare_observer();
629 
630  m_first_execution= false;
631 
632  if (!rc)
633  return false;
634 
635  /*
636  Here is why we need all the checks below:
637  - if the reprepare observer is not set, we've got an error, which should
638  be raised to the user;
639  - if we've got fatal error, it should be raised to the user;
640  - if our thread got killed during execution, the error should be raised
641  to the user;
642  - if we've got an error, different from ER_NEED_REPREPARE, we need to
643  raise it to the user;
644  - we take only 3 attempts to reprepare the query, otherwise we might end
645  up in the endless loop.
646  */
647  if (stmt_reprepare_observer &&
648  !thd->is_fatal_error &&
649  !thd->killed &&
650  thd->get_stmt_da()->sql_errno() == ER_NEED_REPREPARE &&
651  reprepare_attempt++ < 3)
652  {
653  DBUG_ASSERT(stmt_reprepare_observer->is_invalidated());
654 
655  thd->clear_error();
656  free_lex();
657  invalidate();
658  }
659  else
660  return true;
661  }
662 }
663 
664 
665 void sp_lex_instr::set_lex(LEX *lex, bool is_lex_owner)
666 {
667  free_lex();
668 
669  m_lex= lex;
670  m_is_lex_owner= is_lex_owner;
671  m_lex_query_tables_own_last= NULL;
672 
673  if (m_lex)
674  m_lex->sp_lex_in_use= true;
675 }
676 
677 
678 void sp_lex_instr::free_lex()
679 {
680  if (!m_is_lex_owner || !m_lex)
681  return;
682 
683  /* Prevent endless recursion. */
684  m_lex->sphead= NULL;
685  lex_end(m_lex);
686  delete (st_lex_local *) m_lex;
687 
688  m_lex= NULL;
689  m_is_lex_owner= false;
690  m_lex_query_tables_own_last= NULL;
691 }
692 
693 
695 {
696  /*
697  Destroy items in the instruction's free list before re-parsing the
698  statement query string (and thus, creating new items).
699  */
700  Item *p= free_list;
701  while (p)
702  {
703  Item *next= p->next;
704  p->delete_self();
705  p= next;
706  }
707 
708  free_list= NULL;
709 
710  // Remove previously stored trigger-field items.
711  sp_head *sp= thd->sp_runtime_ctx->sp;
712 
713  if (sp->m_type == SP_TYPE_TRIGGER)
714  sp->m_trg_table_fields.empty();
715 }
716 
717 
718 void sp_lex_instr::get_query(String *sql_query) const
719 {
720  LEX_STRING expr_query= this->get_expr_query();
721 
722  if (!expr_query.str)
723  {
724  sql_query->length(0);
725  return;
726  }
727 
728  sql_query->append("SELECT ");
729  sql_query->append(expr_query.str, expr_query.length);
730 }
731 
732 
734 // sp_instr_stmt implementation.
736 
737 
738 bool sp_instr_stmt::execute(THD *thd, uint *nextp)
739 {
740  bool need_subst= false;
741  bool rc= false;
742 
743  DBUG_PRINT("info", ("query: '%.*s'", (int) m_query.length, m_query.str));
744 
745  const CSET_STRING query_backup= thd->query_string;
746 
747 #if defined(ENABLED_PROFILING)
748  /* This SP-instr is profilable and will be captured. */
749  thd->profiling.set_query_source(m_query.str, m_query.length);
750 #endif
751 
752  /*
753  If we can't set thd->query_string at all, we give up on this statement.
754  */
755  if (alloc_query(thd, m_query.str, m_query.length))
756  return true;
757 
758  /*
759  Check whether we actually need a substitution of SP variables with
760  NAME_CONST(...) (using subst_spvars()).
761  If both of the following apply, we won't need to substitute:
762 
763  - general log is off
764 
765  - binary logging is off, or not in statement mode
766 
767  We don't have to substitute on behalf of the query cache as
768  queries with SP vars are not cached, anyway.
769 
770  query_name_consts is used elsewhere in a special case concerning
771  CREATE TABLE, but we do not need to do anything about that here.
772 
773  The slow query log is another special case: we won't know whether a
774  query qualifies for the slow query log until after it's been
775  executed. We assume that most queries are not slow, so we do not
776  pre-emptively substitute just for the slow query log. If a query
777  ends up being slow after all and we haven't done the substitution
778  already for any of the above (general log etc.), we'll do the
779  substitution immediately before writing to the log.
780  */
781 
782  need_subst= ((thd->variables.option_bits & OPTION_LOG_OFF) &&
783  (!(thd->variables.option_bits & OPTION_BIN_LOG) ||
784  !mysql_bin_log.is_open() ||
785  thd->is_current_stmt_binlog_format_row())) ? FALSE : TRUE;
786 
787  /*
788  If we need to do a substitution but can't (OOM), give up.
789  */
790 
791  if (need_subst && subst_spvars(thd, this, &m_query))
792  return true;
793 
794  /*
795  (the order of query cache and subst_spvars calls is irrelevant because
796  queries with SP vars can't be cached)
797  */
798  if (unlikely((thd->variables.option_bits & OPTION_LOG_OFF)==0))
799  general_log_write(thd, COM_QUERY, thd->query(), thd->query_length());
800 
801  if (query_cache_send_result_to_client(thd, thd->query(),
802  thd->query_length()) <= 0)
803  {
804  rc= validate_lex_and_execute_core(thd, nextp, false);
805 
806  if (thd->get_stmt_da()->is_eof())
807  {
808  /* Finalize server status flags after executing a statement. */
809  thd->update_server_status();
810 
811  thd->protocol->end_statement();
812  }
813 
814  query_cache_end_of_result(thd);
815 
816  if (!rc && unlikely(log_slow_applicable(thd)))
817  {
818  /*
819  We actually need to write the slow log. Check whether we already
820  called subst_spvars() above, otherwise, do it now. In the highly
821  unlikely event of subst_spvars() failing (OOM), we'll try to log
822  the unmodified statement instead.
823  */
824  if (!need_subst)
825  rc= subst_spvars(thd, this, &m_query);
826  log_slow_do(thd);
827  }
828 
829  /*
830  With the current setup, a subst_spvars() and a mysql_rewrite_query()
831  (rewriting passwords etc.) will not both happen to a query.
832  If this ever changes, we give the engineer pause here so they will
833  double-check whether the potential conflict they created is a
834  problem.
835  */
836  DBUG_ASSERT((thd->query_name_consts == 0) ||
837  (thd->rewritten_query.length() == 0));
838  }
839  else
840  *nextp= get_ip() + 1;
841 
842  thd->set_query(query_backup);
843  thd->query_name_consts= 0;
844 
845  if (!thd->is_error())
846  thd->get_stmt_da()->reset_diagnostics_area();
847 
848  return rc || thd->is_error();
849 }
850 
851 
852 void sp_instr_stmt::print(String *str)
853 {
854  /* stmt CMD "..." */
855  if (str->reserve(SP_STMT_PRINT_MAXLEN + SP_INSTR_UINT_MAXLEN + 8))
856  return;
857  str->qs_append(STRING_WITH_LEN("stmt"));
858  str->qs_append(STRING_WITH_LEN(" \""));
859 
860  /*
861  Print the query string (but not too much of it), just to indicate which
862  statement it is.
863  */
864  uint len= m_query.length;
865  if (len > SP_STMT_PRINT_MAXLEN)
866  len= SP_STMT_PRINT_MAXLEN-3;
867 
868  /* Copy the query string and replace '\n' with ' ' in the process */
869  for (uint i= 0 ; i < len ; i++)
870  {
871  char c= m_query.str[i];
872  if (c == '\n')
873  c= ' ';
874  str->qs_append(c);
875  }
876  if (m_query.length > SP_STMT_PRINT_MAXLEN)
877  str->qs_append(STRING_WITH_LEN("...")); /* Indicate truncated string */
878  str->qs_append('"');
879 }
880 
881 
882 bool sp_instr_stmt::exec_core(THD *thd, uint *nextp)
883 {
884  MYSQL_QUERY_EXEC_START(thd->query(),
885  thd->thread_id,
886  (char *) (thd->db ? thd->db : ""),
887  &thd->security_ctx->priv_user[0],
888  (char *)thd->security_ctx->host_or_ip,
889  3);
890 
891  thd->lex->set_sp_current_parsing_ctx(get_parsing_ctx());
892  thd->lex->sphead= thd->sp_runtime_ctx->sp;
893 
894  PSI_statement_locker *statement_psi_saved= thd->m_statement_psi;
895  thd->m_statement_psi= NULL;
896 
897  bool rc= mysql_execute_command(thd);
898 
899  thd->lex->set_sp_current_parsing_ctx(NULL);
900  thd->lex->sphead= NULL;
901  thd->m_statement_psi= statement_psi_saved;
902 
903  MYSQL_QUERY_EXEC_DONE(rc);
904 
905  *nextp= get_ip() + 1;
906 
907  return rc;
908 }
909 
910 
912 // sp_instr_set implementation.
914 
915 
916 bool sp_instr_set::exec_core(THD *thd, uint *nextp)
917 {
918  *nextp= get_ip() + 1;
919 
920  if (!thd->sp_runtime_ctx->set_variable(thd, m_offset, &m_value_item))
921  return false;
922 
923  /* Failed to evaluate the value. Reset the variable to NULL. */
924 
925  if (thd->sp_runtime_ctx->set_variable(thd, m_offset, 0))
926  {
927  /* If this also failed, let's abort. */
928  my_error(ER_OUT_OF_RESOURCES, MYF(ME_FATALERROR));
929  }
930 
931  return true;
932 }
933 
934 
935 void sp_instr_set::print(String *str)
936 {
937  /* set name@offset ... */
938  int rsrv = SP_INSTR_UINT_MAXLEN+6;
939  sp_variable *var = m_parsing_ctx->find_variable(m_offset);
940 
941  /* 'var' should always be non-null, but just in case... */
942  if (var)
943  rsrv+= var->name.length;
944  if (str->reserve(rsrv))
945  return;
946  str->qs_append(STRING_WITH_LEN("set "));
947  if (var)
948  {
949  str->qs_append(var->name.str, var->name.length);
950  str->qs_append('@');
951  }
952  str->qs_append(m_offset);
953  str->qs_append(' ');
954  m_value_item->print(str, QT_ORDINARY);
955 }
956 
957 
959 // sp_instr_set_trigger_field implementation.
961 
962 
963 bool sp_instr_set_trigger_field::exec_core(THD *thd, uint *nextp)
964 {
965  *nextp= get_ip() + 1;
966  thd->count_cuted_fields= CHECK_FIELD_ERROR_FOR_NULL;
967  return m_trigger_field->set_value(thd, &m_value_item);
968 }
969 
970 
971 void sp_instr_set_trigger_field::print(String *str)
972 {
973  str->append(STRING_WITH_LEN("set_trigger_field "));
974  m_trigger_field->print(str, QT_ORDINARY);
975  str->append(STRING_WITH_LEN(":="));
976  m_value_item->print(str, QT_ORDINARY);
977 }
978 
979 
981 {
982  DBUG_ASSERT(thd->lex->select_lex.item_list.elements == 1);
983 
984  m_value_item= thd->lex->select_lex.item_list.head();
985 
986  DBUG_ASSERT(!m_trigger_field);
987 
988  m_trigger_field=
989  new (thd->mem_root) Item_trigger_field(thd->lex->current_context(),
990  Item_trigger_field::NEW_ROW,
991  m_trigger_field_name.str,
992  UPDATE_ACL,
993  false);
994 
995  return m_value_item == NULL || m_trigger_field == NULL;
996 }
997 
998 
1000 {
1002 
1003  m_trigger_field= NULL;
1004 }
1005 
1006 
1008 // sp_instr_jump implementation.
1010 
1011 
1012 void sp_instr_jump::print(String *str)
1013 {
1014  /* jump dest */
1015  if (str->reserve(SP_INSTR_UINT_MAXLEN+5))
1016  return;
1017  str->qs_append(STRING_WITH_LEN("jump "));
1018  str->qs_append(m_dest);
1019 }
1020 
1021 
1023 {
1024  m_dest= opt_shortcut_jump(sp, this);
1025  if (m_dest != get_ip() + 1) /* Jumping to following instruction? */
1026  m_marked= true;
1027  m_optdest= sp->get_instr(m_dest);
1028  return m_dest;
1029 }
1030 
1031 
1033 {
1034  uint dest= m_dest;
1035  sp_instr *i;
1036 
1037  while ((i= sp->get_instr(dest)))
1038  {
1039  uint ndest;
1040 
1041  if (start == i || this == i)
1042  break;
1043  ndest= i->opt_shortcut_jump(sp, start);
1044  if (ndest == dest)
1045  break;
1046  dest= ndest;
1047  }
1048  return dest;
1049 }
1050 
1051 
1053 {
1054  if (m_dest > get_ip())
1055  bp->push_back(this); // Forward
1056  else if (m_optdest)
1057  m_dest= m_optdest->get_ip(); // Backward
1058  m_ip= dst;
1059 }
1060 
1061 
1063 // sp_instr_jump_if_not class implementation
1065 
1066 
1067 bool sp_instr_jump_if_not::exec_core(THD *thd, uint *nextp)
1068 {
1069  DBUG_ASSERT(m_expr_item);
1070 
1071  Item *item= sp_prepare_func_item(thd, &m_expr_item);
1072 
1073  if (!item)
1074  return true;
1075 
1076  *nextp= item->val_bool() ? get_ip() + 1 : m_dest;
1077 
1078  return false;
1079 }
1080 
1081 
1082 void sp_instr_jump_if_not::print(String *str)
1083 {
1084  /* jump_if_not dest(cont) ... */
1085  if (str->reserve(2*SP_INSTR_UINT_MAXLEN+14+32)) // Add some for the expr. too
1086  return;
1087  str->qs_append(STRING_WITH_LEN("jump_if_not "));
1088  str->qs_append(m_dest);
1089  str->qs_append('(');
1090  str->qs_append(m_cont_dest);
1091  str->qs_append(STRING_WITH_LEN(") "));
1092  m_expr_item->print(str, QT_ORDINARY);
1093 }
1094 
1095 
1097 // sp_lex_branch_instr implementation.
1099 
1100 
1102 {
1103  m_marked= true;
1104 
1105  sp_instr *i= sp->get_instr(m_dest);
1106 
1107  if (i)
1108  {
1109  m_dest= i->opt_shortcut_jump(sp, this);
1110  m_optdest= sp->get_instr(m_dest);
1111  }
1112 
1113  sp->add_mark_lead(m_dest, leads);
1114 
1115  i= sp->get_instr(m_cont_dest);
1116 
1117  if (i)
1118  {
1119  m_cont_dest= i->opt_shortcut_jump(sp, this);
1120  m_cont_optdest= sp->get_instr(m_cont_dest);
1121  }
1122 
1123  sp->add_mark_lead(m_cont_dest, leads);
1124 
1125  return get_ip() + 1;
1126 }
1127 
1128 
1130 {
1131  /*
1132  cont. destinations may point backwards after shortcutting jumps
1133  during the mark phase. If it's still pointing forwards, only
1134  push this for backpatching if sp_instr_jump::opt_move() will not
1135  do it (i.e. if the m_dest points backwards).
1136  */
1137  if (m_cont_dest > get_ip())
1138  { // Forward
1139  if (m_dest < get_ip())
1140  bp->push_back(this);
1141  }
1142  else if (m_cont_optdest)
1143  m_cont_dest= m_cont_optdest->get_ip(); // Backward
1144 
1145  /* This will take care of m_dest and m_ip */
1146  if (m_dest > get_ip())
1147  bp->push_back(this); // Forward
1148  else if (m_optdest)
1149  m_dest= m_optdest->get_ip(); // Backward
1150  m_ip= dst;
1151 }
1152 
1153 
1155 // sp_instr_jump_case_when implementation.
1157 
1158 
1159 bool sp_instr_jump_case_when::exec_core(THD *thd, uint *nextp)
1160 {
1161  DBUG_ASSERT(m_eq_item);
1162 
1163  Item *item= sp_prepare_func_item(thd, &m_eq_item);
1164 
1165  if (!item)
1166  return true;
1167 
1168  *nextp= item->val_bool() ? get_ip() + 1 : m_dest;
1169 
1170  return false;
1171 }
1172 
1173 
1174 void sp_instr_jump_case_when::print(String *str)
1175 {
1176  /* jump_if_not dest(cont) ... */
1177  if (str->reserve(2*SP_INSTR_UINT_MAXLEN+14+32)) // Add some for the expr. too
1178  return;
1179  str->qs_append(STRING_WITH_LEN("jump_if_not_case_when "));
1180  str->qs_append(m_dest);
1181  str->qs_append('(');
1182  str->qs_append(m_cont_dest);
1183  str->qs_append(STRING_WITH_LEN(") "));
1184  m_eq_item->print(str, QT_ORDINARY);
1185 }
1186 
1187 
1188 bool sp_instr_jump_case_when::build_expr_items(THD *thd)
1189 {
1190  // Setup CASE-expression item (m_case_expr_item).
1191 
1192  m_case_expr_item= new Item_case_expr(m_case_expr_id);
1193 
1194  if (!m_case_expr_item)
1195  return true;
1196 
1197 #ifndef DBUG_OFF
1198  m_case_expr_item->m_sp= thd->lex->sphead;
1199 #endif
1200 
1201  // Setup WHEN-expression item (m_expr_item) if it is not already set.
1202  //
1203  // This function can be called in two cases:
1204  //
1205  // - during initial (regular) parsing of SP. In this case we don't have
1206  // lex->select_lex (because it's not a SELECT statement), but
1207  // m_expr_item is already set in constructor.
1208  //
1209  // - during re-parsing after meta-data change. In this case we've just
1210  // parsed aux-SELECT statement, so we need to take 1st (and the only one)
1211  // item from its list.
1212 
1213  if (!m_expr_item)
1214  {
1215  DBUG_ASSERT(thd->lex->select_lex.item_list.elements == 1);
1216 
1217  m_expr_item= thd->lex->select_lex.item_list.head();
1218  }
1219 
1220  // Setup main expression item (m_expr_item).
1221 
1222  m_eq_item= new Item_func_eq(m_case_expr_item, m_expr_item);
1223 
1224  if (!m_eq_item)
1225  return true;
1226 
1227  return false;
1228 }
1229 
1230 
1232 // sp_instr_freturn implementation.
1234 
1235 
1236 bool sp_instr_freturn::exec_core(THD *thd, uint *nextp)
1237 {
1238  /*
1239  RETURN is a "procedure statement" (in terms of the SQL standard).
1240  That means, Diagnostics Area should be clean before its execution.
1241  */
1242 
1243  Diagnostics_area *da= thd->get_stmt_da();
1244  da->clear_warning_info(da->warning_info_id());
1245 
1246  /*
1247  Change <next instruction pointer>, so that this will be the last
1248  instruction in the stored function.
1249  */
1250 
1251  *nextp= UINT_MAX;
1252 
1253  /*
1254  Evaluate the value of return expression and store it in current runtime
1255  context.
1256 
1257  NOTE: It's necessary to evaluate result item right here, because we must
1258  do it in scope of execution the current context/block.
1259  */
1260 
1261  return thd->sp_runtime_ctx->set_return_value(thd, &m_expr_item);
1262 }
1263 
1264 
1265 void sp_instr_freturn::print(String *str)
1266 {
1267  /* freturn type expr... */
1268  if (str->reserve(1024+8+32)) // Add some for the expr. too
1269  return;
1270  str->qs_append(STRING_WITH_LEN("freturn "));
1271  str->qs_append((uint) m_return_field_type);
1272  str->qs_append(' ');
1273  m_expr_item->print(str, QT_ORDINARY);
1274 }
1275 
1276 
1278 // sp_instr_hpush_jump implementation.
1280 
1281 
1282 bool sp_instr_hpush_jump::execute(THD *thd, uint *nextp)
1283 {
1284  *nextp= m_dest;
1285 
1286  return thd->sp_runtime_ctx->push_handler(m_handler, get_ip() + 1);
1287 }
1288 
1289 
1290 void sp_instr_hpush_jump::print(String *str)
1291 {
1292  /* hpush_jump dest fsize type */
1293  if (str->reserve(SP_INSTR_UINT_MAXLEN*2 + 21))
1294  return;
1295 
1296  str->qs_append(STRING_WITH_LEN("hpush_jump "));
1297  str->qs_append(m_dest);
1298  str->qs_append(' ');
1299  str->qs_append(m_frame);
1300 
1301  switch (m_handler->type) {
1302  case sp_handler::EXIT:
1303  str->qs_append(STRING_WITH_LEN(" EXIT"));
1304  break;
1305  case sp_handler::CONTINUE:
1306  str->qs_append(STRING_WITH_LEN(" CONTINUE"));
1307  break;
1308  default:
1309  // The handler type must be either CONTINUE or EXIT.
1310  DBUG_ASSERT(0);
1311  }
1312 }
1313 
1314 
1316 {
1317  m_marked= true;
1318 
1319  sp_instr *i= sp->get_instr(m_dest);
1320 
1321  if (i)
1322  {
1323  m_dest= i->opt_shortcut_jump(sp, this);
1324  m_optdest= sp->get_instr(m_dest);
1325  }
1326 
1327  sp->add_mark_lead(m_dest, leads);
1328 
1329  /*
1330  For continue handlers, all instructions in the scope of the handler
1331  are possible leads. For example, the instruction after freturn might
1332  be executed if the freturn triggers the condition handled by the
1333  continue handler.
1334 
1335  m_dest marks the start of the handler scope. It's added as a lead
1336  above, so we start on m_dest+1 here.
1337  m_opt_hpop is the hpop marking the end of the handler scope.
1338  */
1339  if (m_handler->type == sp_handler::CONTINUE)
1340  {
1341  for (uint scope_ip= m_dest+1; scope_ip <= m_opt_hpop; scope_ip++)
1342  sp->add_mark_lead(scope_ip, leads);
1343  }
1344 
1345  return get_ip() + 1;
1346 }
1347 
1348 
1350 // sp_instr_hpop implementation.
1352 
1353 
1354 bool sp_instr_hpop::execute(THD *thd, uint *nextp)
1355 {
1356  thd->sp_runtime_ctx->pop_handlers(m_parsing_ctx);
1357  *nextp= get_ip() + 1;
1358  return false;
1359 }
1360 
1361 
1363 // sp_instr_hreturn implementation.
1365 
1366 
1367 bool sp_instr_hreturn::execute(THD *thd, uint *nextp)
1368 {
1369  /*
1370  Remove the SQL conditions that were present in DA when the
1371  handler was activated.
1372  */
1373 
1374  thd->get_stmt_da()->remove_marked_sql_conditions();
1375 
1376  /*
1377  Obtain next instruction pointer (m_dest is set for EXIT handlers, retrieve
1378  the instruction pointer from runtime context for CONTINUE handlers).
1379  */
1380 
1381  sp_rcontext *rctx= thd->sp_runtime_ctx;
1382 
1383  *nextp= m_dest ? m_dest : rctx->get_last_handler_continue_ip();
1384 
1385  /*
1386  Remove call frames for handlers, which are "below" the BEGIN..END block of
1387  the next instruction.
1388  */
1389 
1390  sp_instr *next_instr= rctx->sp->get_instr(*nextp);
1391  rctx->exit_handler(next_instr->get_parsing_ctx());
1392 
1393  return false;
1394 }
1395 
1396 
1397 void sp_instr_hreturn::print(String *str)
1398 {
1399  /* hreturn framesize dest */
1400  if (str->reserve(SP_INSTR_UINT_MAXLEN*2 + 9))
1401  return;
1402  str->qs_append(STRING_WITH_LEN("hreturn "));
1403  if (m_dest)
1404  {
1405  // NOTE: this is legacy: hreturn instruction for EXIT handler
1406  // should print out 0 as frame index.
1407  str->qs_append(STRING_WITH_LEN("0 "));
1408  str->qs_append(m_dest);
1409  }
1410  else
1411  {
1412  str->qs_append(m_frame);
1413  }
1414 }
1415 
1416 
1418 {
1419  m_marked= true;
1420 
1421  if (m_dest)
1422  {
1423  /*
1424  This is an EXIT handler; next instruction step is in m_dest.
1425  */
1426  return m_dest;
1427  }
1428 
1429  /*
1430  This is a CONTINUE handler; next instruction step will come from
1431  the handler stack and not from opt_mark.
1432  */
1433  return UINT_MAX;
1434 }
1435 
1436 
1438 // sp_instr_cpush implementation.
1440 
1441 
1442 bool sp_instr_cpush::execute(THD *thd, uint *nextp)
1443 {
1444  *nextp= get_ip() + 1;
1445 
1446  // sp_instr_cpush::execute() just registers the cursor in the runtime context.
1447 
1448  return thd->sp_runtime_ctx->push_cursor(this);
1449 }
1450 
1451 
1452 bool sp_instr_cpush::exec_core(THD *thd, uint *nextp)
1453 {
1454  sp_cursor *c= thd->sp_runtime_ctx->get_cursor(m_cursor_idx);
1455 
1456  // sp_instr_cpush::exec_core() opens the cursor (it's called from
1457  // sp_instr_copen::execute().
1458 
1459  return c ? c->open(thd) : true;
1460 }
1461 
1462 
1463 void sp_instr_cpush::print(String *str)
1464 {
1465  const LEX_STRING *cursor_name= m_parsing_ctx->find_cursor(m_cursor_idx);
1466 
1467  uint rsrv= SP_INSTR_UINT_MAXLEN + 7 + m_cursor_query.length + 1;
1468 
1469  if (cursor_name)
1470  rsrv+= cursor_name->length;
1471  if (str->reserve(rsrv))
1472  return;
1473  str->qs_append(STRING_WITH_LEN("cpush "));
1474  if (cursor_name)
1475  {
1476  str->qs_append(cursor_name->str, cursor_name->length);
1477  str->qs_append('@');
1478  }
1479  str->qs_append(m_cursor_idx);
1480 
1481  str->qs_append(':');
1482  str->qs_append(m_cursor_query.str, m_cursor_query.length);
1483 }
1484 
1485 
1487 // sp_instr_cpop implementation.
1489 
1490 
1491 bool sp_instr_cpop::execute(THD *thd, uint *nextp)
1492 {
1493  thd->sp_runtime_ctx->pop_cursors(m_count);
1494  *nextp= get_ip() + 1;
1495 
1496  return false;
1497 }
1498 
1499 
1500 void sp_instr_cpop::print(String *str)
1501 {
1502  /* cpop count */
1503  if (str->reserve(SP_INSTR_UINT_MAXLEN+5))
1504  return;
1505  str->qs_append(STRING_WITH_LEN("cpop "));
1506  str->qs_append(m_count);
1507 }
1508 
1509 
1511 // sp_instr_copen implementation.
1513 
1514 
1515 bool sp_instr_copen::execute(THD *thd, uint *nextp)
1516 {
1517  *nextp= get_ip() + 1;
1518 
1519  // Get the cursor pointer.
1520 
1521  sp_cursor *c= thd->sp_runtime_ctx->get_cursor(m_cursor_idx);
1522 
1523  if (!c)
1524  return true;
1525 
1526  // Retrieve sp_instr_cpush instance.
1527 
1528  sp_instr_cpush *push_instr= c->get_push_instr();
1529 
1530  // Switch Statement Arena to the sp_instr_cpush object. It contains the
1531  // free_list of the query, so new items (if any) are stored in the right
1532  // free_list, and we can cleanup after each open.
1533 
1534  Query_arena *stmt_arena_saved= thd->stmt_arena;
1535  thd->stmt_arena= push_instr;
1536 
1537  // Switch to the cursor's lex and execute sp_instr_cpush::exec_core().
1538  // sp_instr_cpush::exec_core() is *not* executed during
1539  // sp_instr_cpush::execute(). sp_instr_cpush::exec_core() is intended to be
1540  // executed on cursor opening.
1541 
1542  bool rc= push_instr->validate_lex_and_execute_core(thd, nextp, false);
1543 
1544  // Cleanup the query's items.
1545 
1546  if (push_instr->free_list)
1547  cleanup_items(push_instr->free_list);
1548 
1549  // Restore Statement Arena.
1550 
1551  thd->stmt_arena= stmt_arena_saved;
1552 
1553  return rc;
1554 }
1555 
1556 
1557 void sp_instr_copen::print(String *str)
1558 {
1559  const LEX_STRING *cursor_name= m_parsing_ctx->find_cursor(m_cursor_idx);
1560 
1561  /* copen name@offset */
1562  uint rsrv= SP_INSTR_UINT_MAXLEN+7;
1563 
1564  if (cursor_name)
1565  rsrv+= cursor_name->length;
1566  if (str->reserve(rsrv))
1567  return;
1568  str->qs_append(STRING_WITH_LEN("copen "));
1569  if (cursor_name)
1570  {
1571  str->qs_append(cursor_name->str, cursor_name->length);
1572  str->qs_append('@');
1573  }
1574  str->qs_append(m_cursor_idx);
1575 }
1576 
1577 
1579 // sp_instr_cclose implementation.
1581 
1582 
1583 bool sp_instr_cclose::execute(THD *thd, uint *nextp)
1584 {
1585  *nextp= get_ip() + 1;
1586 
1587  sp_cursor *c= thd->sp_runtime_ctx->get_cursor(m_cursor_idx);
1588 
1589  return c ? c->close(thd) : true;
1590 }
1591 
1592 
1593 void sp_instr_cclose::print(String *str)
1594 {
1595  const LEX_STRING *cursor_name= m_parsing_ctx->find_cursor(m_cursor_idx);
1596 
1597  /* cclose name@offset */
1598  uint rsrv= SP_INSTR_UINT_MAXLEN+8;
1599 
1600  if (cursor_name)
1601  rsrv+= cursor_name->length;
1602  if (str->reserve(rsrv))
1603  return;
1604  str->qs_append(STRING_WITH_LEN("cclose "));
1605  if (cursor_name)
1606  {
1607  str->qs_append(cursor_name->str, cursor_name->length);
1608  str->qs_append('@');
1609  }
1610  str->qs_append(m_cursor_idx);
1611 }
1612 
1613 
1615 // sp_instr_cfetch implementation.
1617 
1618 
1619 bool sp_instr_cfetch::execute(THD *thd, uint *nextp)
1620 {
1621  *nextp= get_ip() + 1;
1622 
1623  sp_cursor *c= thd->sp_runtime_ctx->get_cursor(m_cursor_idx);
1624 
1625  return c ? c->fetch(thd, &m_varlist) : true;
1626 }
1627 
1628 
1629 void sp_instr_cfetch::print(String *str)
1630 {
1631  List_iterator_fast<sp_variable> li(m_varlist);
1632  sp_variable *pv;
1633  const LEX_STRING *cursor_name= m_parsing_ctx->find_cursor(m_cursor_idx);
1634 
1635  /* cfetch name@offset vars... */
1636  uint rsrv= SP_INSTR_UINT_MAXLEN+8;
1637 
1638  if (cursor_name)
1639  rsrv+= cursor_name->length;
1640  if (str->reserve(rsrv))
1641  return;
1642  str->qs_append(STRING_WITH_LEN("cfetch "));
1643  if (cursor_name)
1644  {
1645  str->qs_append(cursor_name->str, cursor_name->length);
1646  str->qs_append('@');
1647  }
1648  str->qs_append(m_cursor_idx);
1649  while ((pv= li++))
1650  {
1651  if (str->reserve(pv->name.length+SP_INSTR_UINT_MAXLEN+2))
1652  return;
1653  str->qs_append(' ');
1654  str->qs_append(pv->name.str, pv->name.length);
1655  str->qs_append('@');
1656  str->qs_append(pv->offset);
1657  }
1658 }
1659 
1660 
1662 // sp_instr_error implementation.
1664 
1665 
1666 void sp_instr_error::print(String *str)
1667 {
1668  /* error code */
1669  if (str->reserve(SP_INSTR_UINT_MAXLEN+6))
1670  return;
1671  str->qs_append(STRING_WITH_LEN("error "));
1672  str->qs_append(m_errcode);
1673 }
1674 
1675 
1677 // sp_instr_set_case_expr implementation.
1679 
1680 
1681 bool sp_instr_set_case_expr::exec_core(THD *thd, uint *nextp)
1682 {
1683  *nextp= get_ip() + 1;
1684 
1685  sp_rcontext *rctx= thd->sp_runtime_ctx;
1686 
1687  if (rctx->set_case_expr(thd, m_case_expr_id, &m_expr_item) &&
1688  !rctx->get_case_expr(m_case_expr_id))
1689  {
1690  // Failed to evaluate the value, the case expression is still not
1691  // initialized. Set to NULL so we can continue.
1692 
1693  Item *null_item= new Item_null();
1694 
1695  if (!null_item || rctx->set_case_expr(thd, m_case_expr_id, &null_item))
1696  {
1697  // If this also failed, we have to abort.
1698  my_error(ER_OUT_OF_RESOURCES, MYF(ME_FATALERROR));
1699  }
1700 
1701  return true;
1702  }
1703 
1704  return false;
1705 }
1706 
1707 
1708 void sp_instr_set_case_expr::print(String *str)
1709 {
1710  /* set_case_expr (cont) id ... */
1711  str->reserve(2*SP_INSTR_UINT_MAXLEN+18+32); // Add some extra for expr too
1712  str->qs_append(STRING_WITH_LEN("set_case_expr ("));
1713  str->qs_append(m_cont_dest);
1714  str->qs_append(STRING_WITH_LEN(") "));
1715  str->qs_append(m_case_expr_id);
1716  str->qs_append(' ');
1717  m_expr_item->print(str, QT_ORDINARY);
1718 }
1719 
1720 
1722 {
1723  m_marked= true;
1724 
1726 
1727  if (i)
1728  {
1729  m_cont_dest= i->opt_shortcut_jump(sp, this);
1730  m_cont_optdest= sp->get_instr(m_cont_dest);
1731  }
1732 
1733  sp->add_mark_lead(m_cont_dest, leads);
1734  return get_ip() + 1;
1735 }
1736 
1737 
1739 {
1740  if (m_cont_dest > get_ip())
1741  bp->push_back(this); // Forward
1742  else if (m_cont_optdest)
1743  m_cont_dest= m_cont_optdest->get_ip(); // Backward
1744  m_ip= dst;
1745 }