MySQL  8.0.20
Source Code Documentation
sp_instr.h
Go to the documentation of this file.
1 /* Copyright (c) 2012, 2019, 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, version 2.0,
5  as published by the Free Software Foundation.
6 
7  This program is also distributed with certain software (including
8  but not limited to OpenSSL) that is licensed under separate terms,
9  as designated in a particular file or component or in included license
10  documentation. The authors of MySQL hereby grant you an additional
11  permission to link the program and your derivative works with the
12  separately licensed software that they have included with MySQL.
13 
14  This program is distributed in the hope that it will be useful,
15  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  GNU General Public License, version 2.0, for more details.
18 
19  You should have received a copy of the GNU General Public License
20  along with this program; if not, write to the Free Software
21  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
22 
23 #ifndef _SP_INSTR_H_
24 #define _SP_INSTR_H_
25 
26 #include <limits.h>
27 #include <string.h>
28 #include <sys/types.h>
29 
30 #include "field_types.h"
31 #include "lex_string.h"
32 #include "m_string.h"
33 #include "my_alloc.h"
34 #include "my_compiler.h"
35 #include "my_dbug.h"
36 #include "my_inttypes.h"
37 #include "my_psi_config.h"
38 #include "my_sys.h"
40 #include "sql/sql_class.h" // Query_arena
41 #include "sql/sql_error.h"
42 #include "sql/sql_lex.h"
43 #include "sql/sql_list.h"
44 #include "sql_string.h"
45 
46 class Item;
47 class Item_case_expr;
48 class Item_trigger_field;
49 class sp_condition_value;
50 class sp_handler;
51 class sp_head;
52 class sp_pcontext;
53 class sp_variable;
54 struct TABLE_LIST;
55 
56 ///////////////////////////////////////////////////////////////////////////
57 // This file contains SP-instruction classes.
58 ///////////////////////////////////////////////////////////////////////////
59 
60 /**
61  sp_printable defines an interface which should be implemented if a class wants
62  report some internal information about its state.
63 */
64 class sp_printable {
65  public:
66  virtual void print(const THD *thd, String *str) = 0;
67 
68  virtual ~sp_printable() {}
69 };
70 
71 /**
72  An interface for all SP-instructions with destinations that
73  need to be updated by the SP-optimizer.
74 */
76  public:
77  /**
78  Update the destination; used by the SP-instruction-optimizer.
79 
80  @param old_dest current (old) destination (instruction pointer).
81  @param new_dest new destination (instruction pointer).
82  */
83  virtual void set_destination(uint old_dest, uint new_dest) = 0;
84 
85  /**
86  Update all instruction with the given label in the backpatch list to
87  the specified instruction pointer.
88 
89  @param dest destination instruction pointer.
90  */
91  virtual void backpatch(uint dest) = 0;
92 
93  virtual ~sp_branch_instr() {}
94 };
95 
96 ///////////////////////////////////////////////////////////////////////////
97 
98 /**
99  Base class for every SP-instruction. sp_instr defines interface and provides
100  base implementation.
101 */
102 class sp_instr : public sp_printable {
103  public:
105  : m_arena(nullptr, Query_arena::STMT_INITIALIZED_FOR_SP),
106  m_marked(false),
107  m_ip(ip),
108  m_parsing_ctx(ctx) {}
109 
110  virtual ~sp_instr() { m_arena.free_items(); }
111 
112  /**
113  Execute this instruction
114 
115  @param thd Thread context
116  @param[out] nextp index of the next instruction to execute. (For most
117  instructions this will be the instruction following this
118  one). Note that this parameter is undefined in case of
119  errors, use get_cont_dest() to find the continuation
120  instruction for CONTINUE error handlers.
121 
122  @return Error status.
123  */
124  virtual bool execute(THD *thd, uint *nextp) = 0;
125 #ifdef HAVE_PSI_INTERFACE
126  virtual PSI_statement_info *get_psi_info() = 0;
127 #endif
128 
129  uint get_ip() const { return m_ip; }
130 
131  /**
132  Get the continuation destination (instruction pointer for the CONTINUE
133  HANDLER) of this instruction.
134  @return the continuation destination
135  */
136  virtual uint get_cont_dest() const { return get_ip() + 1; }
137 
138  sp_pcontext *get_parsing_ctx() const { return m_parsing_ctx; }
139 
140  protected:
141  /**
142  Clear diagnostics area.
143  @param thd Thread context
144  */
145  void clear_da(THD *thd) const {
147  thd->get_stmt_da()->reset_condition_info(thd);
148  }
149 
150  ///////////////////////////////////////////////////////////////////////////
151  // The following operations are used solely for SP-code-optimizer.
152  ///////////////////////////////////////////////////////////////////////////
153 
154  public:
155  /**
156  Mark this instruction as reachable during optimization and return the
157  index to the next instruction. Jump instruction will add their
158  destination to the leads list.
159  */
160  virtual uint opt_mark(sp_head *,
161  List<sp_instr> *leads MY_ATTRIBUTE((unused))) {
162  m_marked = true;
163  return get_ip() + 1;
164  }
165 
166  /**
167  Short-cut jumps to jumps during optimization. This is used by the
168  jump instructions' opt_mark() methods. 'start' is the starting point,
169  used to prevent the mark sweep from looping for ever. Return the
170  end destination.
171  */
173  sp_instr *start MY_ATTRIBUTE((unused))) {
174  return get_ip();
175  }
176 
177  /**
178  Inform the instruction that it has been moved during optimization.
179  Most instructions will simply update its index, but jump instructions
180  must also take care of their destination pointers. Forward jumps get
181  pushed to the backpatch list 'ibp'.
182  */
183  virtual void opt_move(uint dst,
184  List<sp_branch_instr> *ibp MY_ATTRIBUTE((unused))) {
185  m_ip = dst;
186  }
187 
188  bool opt_is_marked() const { return m_marked; }
189 
191  return nullptr;
192  }
193 
195 
196  protected:
197  /// Show if this instruction is reachable within the SP
198  /// (used by SP-optimizer).
199  bool m_marked;
200 
201  /// Instruction pointer.
203 
204  /// Instruction parsing context.
206 
207  private:
208  // Prevent use of copy constructor and assignment operator.
209  sp_instr(const sp_instr &);
210  void operator=(sp_instr &);
211 };
212 
213 ///////////////////////////////////////////////////////////////////////////
214 
215 /**
216  sp_lex_instr is a class providing the interface and base implementation
217  for SP-instructions, whose execution is based on expression evaluation.
218 
219  sp_lex_instr keeps LEX-object to be able to evaluate the expression.
220 
221  sp_lex_instr also provides possibility to re-parse the original query
222  string if for some reason the LEX-object is not valid any longer.
223 */
224 class sp_lex_instr : public sp_instr {
225  public:
226  sp_lex_instr(uint ip, sp_pcontext *ctx, LEX *lex, bool is_lex_owner)
227  : sp_instr(ip, ctx),
228  m_lex(nullptr),
229  m_is_lex_owner(false),
230  m_first_execution(true),
231  m_prelocking_tables(nullptr),
232  m_lex_query_tables_own_last(nullptr) {
233  set_lex(lex, is_lex_owner);
234  }
235 
236  virtual ~sp_lex_instr() {
237  free_lex();
238  /*
239  If the instruction is reparsed, m_lex_mem_root was used to allocate
240  the items, then freeing the memroot, frees the items. Also free the
241  items allocated on heap as well.
242  */
243  if (alloc_root_inited(&m_lex_mem_root)) m_arena.free_items();
244  }
245 
246  /**
247  Make a few attempts to execute the instruction.
248 
249  Basically, this operation does the following things:
250  - install Reprepare_observer to catch metadata changes (if any);
251  - calls reset_lex_and_exec_core() to execute the instruction;
252  - if the execution fails due to a change in metadata, re-parse the
253  instruction's SQL-statement and repeat execution.
254 
255  @param thd Thread context.
256  @param[out] nextp Next instruction pointer
257  @param open_tables Flag to specify if the function should check read
258  access to tables in LEX's table list and open and
259  lock them (used in instructions which need to
260  calculate some expression and don't execute
261  complete statement).
262 
263  @return Error status.
264  */
265  bool validate_lex_and_execute_core(THD *thd, uint *nextp, bool open_tables);
266 
268  return &m_trig_field_list;
269  }
270 
271  private:
272  /**
273  Prepare LEX and thread for execution of instruction, if requested open
274  and lock LEX's tables, execute instruction's core function, perform
275  cleanup afterwards.
276 
277  @param thd thread context
278  @param [out] nextp next instruction pointer
279  @param open_tables if true then check read access to tables in LEX's table
280  list and open and lock them (used in instructions which
281  need to calculate some expression and don't execute
282  complete statement).
283 
284  @note
285  We are not saving/restoring some parts of THD which may need this because
286  we do this once for whole routine execution in sp_head::execute().
287 
288  @return Error status.
289  */
290  bool reset_lex_and_exec_core(THD *thd, uint *nextp, bool open_tables);
291 
292  /**
293  (Re-)parse the query corresponding to this instruction and return a new
294  LEX-object.
295 
296  @param thd Thread context.
297  @param sp The stored program.
298 
299  @return new LEX-object or NULL in case of failure.
300  */
301  LEX *parse_expr(THD *thd, sp_head *sp);
302 
303  /**
304  Set LEX-object.
305 
306  Previously assigned LEX-object (if any) will be properly cleaned up
307  and destroyed.
308 
309  @param lex LEX-object to be used by this instance of sp_lex_instr.
310  @param is_lex_owner the flag specifying if this instance sp_lex_instr
311  owns (and thus deletes when needed) passed LEX-object.
312  */
313  void set_lex(LEX *lex, bool is_lex_owner);
314 
315  /**
316  Cleanup and destroy assigned LEX-object if needed.
317  */
318  void free_lex();
319 
320  public:
321  /////////////////////////////////////////////////////////////////////////
322  // sp_instr implementation.
323  /////////////////////////////////////////////////////////////////////////
324 
325  virtual bool execute(THD *thd, uint *nextp) {
326  /*
327  SP instructions with expressions should clear DA before execution.
328  Note that sp_instr_stmt will override execute(), but it clears DA
329  during normal mysql_execute_command().
330  */
331  clear_da(thd);
332  return validate_lex_and_execute_core(thd, nextp, true);
333  }
334 
335  protected:
336  /////////////////////////////////////////////////////////////////////////
337  // Interface (virtual) methods.
338  /////////////////////////////////////////////////////////////////////////
339 
340  /**
341  Execute core function of instruction after all preparations
342  (e.g. setting of proper LEX, saving part of the thread context).
343 
344  @param thd Thread context.
345  @param [out] nextp next instruction pointer
346 
347  @return Error flag.
348  */
349  virtual bool exec_core(THD *thd, uint *nextp) = 0;
350 
351  /**
352  @retval false if the object (i.e. LEX-object) is valid and exec_core() can
353  be just called.
354 
355  @retval true if the object is not valid any longer, exec_core() can not be
356  called. The original query string should be re-parsed and a new LEX-object
357  should be used.
358  */
359  virtual bool is_invalid() const = 0;
360 
361  /**
362  Invalidate the object.
363  */
364  virtual void invalidate() = 0;
365 
366  /**
367  Return the query string, which can be passed to the parser. I.e. the
368  operation should return a valid SQL-statement query string.
369 
370  @param[out] sql_query SQL-statement query string.
371  */
372  virtual void get_query(String *sql_query) const;
373 
374  /**
375  @return the expression query string. This string can not be passed directly
376  to the parser as it is most likely not a valid SQL-statement.
377 
378  @note as it can be seen in the get_query() implementation, get_expr_query()
379  might return EMPTY_CSTR. EMPTY_CSTR means that no query-expression is
380  available. That happens when class provides different implementation of
381  get_query(). Strictly speaking, this is a drawback of the current class
382  hierarchy.
383  */
384  virtual LEX_CSTRING get_expr_query() const { return EMPTY_CSTR; }
385 
386  /**
387  Callback function which is called after the statement query string is
388  successfully parsed, and the thread context has not been switched to the
389  outer context. The thread context contains new LEX-object corresponding to
390  the parsed query string.
391 
392  @param thd Thread context.
393 
394  @return Error flag.
395  */
396  virtual bool on_after_expr_parsing(THD *thd MY_ATTRIBUTE((unused))) {
397  return false;
398  }
399 
400  /**
401  Destroy items in the free list before re-parsing the statement query
402  string (and thus, creating new items).
403 
404  @param thd Thread context.
405  */
406  virtual void cleanup_before_parsing(THD *thd);
407 
408  /// LEX-object.
410 
411  private:
412  /**
413  Mem-root for storing the LEX-tree during reparse. This
414  mem-root is freed when a reparse is triggered or the stored
415  routine is dropped.
416  */
418 
419  /**
420  Indicates whether this sp_lex_instr instance is responsible for
421  LEX-object deletion.
422  */
424 
425  /**
426  Indicates whether exec_core() has not been already called on the current
427  LEX-object.
428  */
430 
431  /*****************************************************************************
432  Support for being able to execute this statement in two modes:
433  a) inside prelocked mode set by the calling procedure or its ancestor.
434  b) outside of prelocked mode, when this statement enters/leaves
435  prelocked mode itself.
436  *****************************************************************************/
437 
438  /**
439  List of additional tables this statement needs to lock when it
440  enters/leaves prelocked mode on its own.
441  */
443 
444  /**
445  The value m_lex->query_tables_own_last should be set to this when the
446  statement enters/leaves prelocked mode on its own.
447  */
449 
450  /**
451  List of all the Item_trigger_field's of instruction.
452  */
454 };
455 
456 ///////////////////////////////////////////////////////////////////////////
457 
458 /**
459  sp_instr_stmt represents almost all conventional SQL-statements, which are
460  supported outside stored programs.
461 
462  SET-statements, which deal with SP-variable or NEW/OLD trigger pseudo-rows are
463  not represented by this instruction.
464 */
465 class sp_instr_stmt : public sp_lex_instr {
466  public:
468  : sp_lex_instr(ip, lex->get_sp_current_parsing_ctx(), lex, true),
469  m_query(query),
470  m_valid(true) {}
471 
472  /////////////////////////////////////////////////////////////////////////
473  // sp_instr implementation.
474  /////////////////////////////////////////////////////////////////////////
475 
476  virtual bool execute(THD *thd, uint *nextp);
477 
478  /////////////////////////////////////////////////////////////////////////
479  // sp_printable implementation.
480  /////////////////////////////////////////////////////////////////////////
481 
482  virtual void print(const THD *thd, String *str);
483 
484  /////////////////////////////////////////////////////////////////////////
485  // sp_lex_instr implementation.
486  /////////////////////////////////////////////////////////////////////////
487 
488  virtual bool exec_core(THD *thd, uint *nextp);
489 
490  virtual bool is_invalid() const { return !m_valid; }
491 
492  virtual void invalidate() { m_valid = false; }
493 
494  virtual void get_query(String *sql_query) const {
495  sql_query->append(m_query.str, m_query.length);
496  }
497 
498  virtual bool on_after_expr_parsing(THD *) {
499  m_valid = true;
500  return false;
501  }
502 
503  private:
504  /// Complete query of the SQL-statement.
506 
507  /// Specify if the stored LEX-object is up-to-date.
508  bool m_valid;
509 
510 #ifdef HAVE_PSI_INTERFACE
511  public:
512  virtual PSI_statement_info *get_psi_info() { return &psi_info; }
513 
515 #endif
516 };
517 
518 ///////////////////////////////////////////////////////////////////////////
519 
520 /**
521  sp_instr_set represents SET-statements, which deal with SP-variables.
522 */
523 class sp_instr_set : public sp_lex_instr {
524  public:
525  sp_instr_set(uint ip, LEX *lex, uint offset, Item *value_item,
526  LEX_CSTRING value_query, bool is_lex_owner)
527  : sp_lex_instr(ip, lex->get_sp_current_parsing_ctx(), lex, is_lex_owner),
528  m_offset(offset),
529  m_value_item(value_item),
530  m_value_query(value_query) {}
531 
532  /////////////////////////////////////////////////////////////////////////
533  // sp_printable implementation.
534  /////////////////////////////////////////////////////////////////////////
535 
536  virtual void print(const THD *thd, String *str);
537 
538  /////////////////////////////////////////////////////////////////////////
539  // sp_lex_instr implementation.
540  /////////////////////////////////////////////////////////////////////////
541 
542  virtual bool exec_core(THD *thd, uint *nextp);
543 
544  virtual bool is_invalid() const { return m_value_item == nullptr; }
545 
546  virtual void invalidate() { m_value_item = nullptr; }
547 
548  virtual bool on_after_expr_parsing(THD *thd) {
550 
551  m_value_item = thd->lex->select_lex->item_list.head();
552 
553  return false;
554  }
555 
556  virtual LEX_CSTRING get_expr_query() const { return m_value_query; }
557 
558  private:
559  /// Frame offset.
561 
562  /// Value expression item of the SET-statement.
564 
565  /// SQL-query corresponding to the value expression.
567 
568 #ifdef HAVE_PSI_INTERFACE
569  public:
571  virtual PSI_statement_info *get_psi_info() { return &psi_info; }
572 #endif
573 };
574 
575 ///////////////////////////////////////////////////////////////////////////
576 
577 /**
578  sp_instr_set_trigger_field represents SET-statements, which deal with NEW/OLD
579  trigger pseudo-rows.
580 */
582  public:
583  sp_instr_set_trigger_field(uint ip, LEX *lex, LEX_CSTRING trigger_field_name,
584  Item_trigger_field *trigger_field,
585  Item *value_item, LEX_CSTRING value_query)
586  : sp_lex_instr(ip, lex->get_sp_current_parsing_ctx(), lex, true),
587  m_trigger_field_name(trigger_field_name),
588  m_trigger_field(trigger_field),
589  m_value_item(value_item),
590  m_value_query(value_query) {}
591 
592  /////////////////////////////////////////////////////////////////////////
593  // sp_printable implementation.
594  /////////////////////////////////////////////////////////////////////////
595 
596  virtual void print(const THD *thd, String *str);
597 
598  /////////////////////////////////////////////////////////////////////////
599  // sp_lex_instr implementation.
600  /////////////////////////////////////////////////////////////////////////
601 
602  virtual bool exec_core(THD *thd, uint *nextp);
603 
604  virtual bool is_invalid() const { return m_value_item == nullptr; }
605 
606  virtual void invalidate() { m_value_item = nullptr; }
607 
608  virtual bool on_after_expr_parsing(THD *thd);
609 
610  virtual void cleanup_before_parsing(THD *thd);
611 
612  virtual LEX_CSTRING get_expr_query() const { return m_value_query; }
613 
614  private:
615  /// Trigger field name ("field_name" of the "NEW.field_name").
617 
618  /// Item corresponding to the NEW/OLD trigger field.
620 
621  /// Value expression item of the SET-statement.
623 
624  /// SQL-query corresponding to the value expression.
626 
627 #ifdef HAVE_PSI_INTERFACE
628  public:
629  virtual PSI_statement_info *get_psi_info() { return &psi_info; }
630 
632 #endif
633 };
634 
635 ///////////////////////////////////////////////////////////////////////////
636 
637 /**
638  sp_instr_freturn represents RETURN statement in stored functions.
639 */
641  public:
642  sp_instr_freturn(uint ip, LEX *lex, Item *expr_item, LEX_CSTRING expr_query,
643  enum enum_field_types return_field_type)
644  : sp_lex_instr(ip, lex->get_sp_current_parsing_ctx(), lex, true),
645  m_expr_item(expr_item),
646  m_expr_query(expr_query),
647  m_return_field_type(return_field_type) {}
648 
649  /////////////////////////////////////////////////////////////////////////
650  // sp_printable implementation.
651  /////////////////////////////////////////////////////////////////////////
652 
653  virtual void print(const THD *thd, String *str);
654 
655  /////////////////////////////////////////////////////////////////////////
656  // sp_instr implementation.
657  /////////////////////////////////////////////////////////////////////////
658 
660  m_marked = true;
661  return UINT_MAX;
662  }
663 
664  /////////////////////////////////////////////////////////////////////////
665  // sp_lex_instr implementation.
666  /////////////////////////////////////////////////////////////////////////
667 
668  virtual bool exec_core(THD *thd, uint *nextp);
669 
670  virtual bool is_invalid() const { return m_expr_item == nullptr; }
671 
672  virtual void invalidate() {
673  // it's already deleted.
674  m_expr_item = nullptr;
675  }
676 
677  virtual bool on_after_expr_parsing(THD *thd) {
679 
680  m_expr_item = thd->lex->select_lex->item_list.head();
681 
682  return false;
683  }
684 
685  virtual LEX_CSTRING get_expr_query() const { return m_expr_query; }
686 
687  private:
688  /// RETURN-expression item.
690 
691  /// SQL-query corresponding to the RETURN-expression.
693 
694  /// RETURN-field type code.
695  enum enum_field_types m_return_field_type;
696 
697 #ifdef HAVE_PSI_INTERFACE
698  public:
699  virtual PSI_statement_info *get_psi_info() { return &psi_info; }
700 
702 #endif
703 };
704 
705 ///////////////////////////////////////////////////////////////////////////
706 
707 /**
708  This is base class for all kinds of jump instructions.
709 
710  @note this is the only class, we directly construct instances of, that has
711  subclasses. We also redefine sp_instr_jump behavior in those subclasses.
712 
713  @todo later we will consider introducing a new class, which will be the base
714  for sp_instr_jump, sp_instr_set_case_expr and sp_instr_jump_case_when.
715  Something like sp_regular_branch_instr (similar to sp_lex_branch_instr).
716 */
717 class sp_instr_jump : public sp_instr, public sp_branch_instr {
718  public:
720  : sp_instr(ip, ctx), m_dest(0), m_optdest(nullptr) {}
721 
723  : sp_instr(ip, ctx), m_dest(dest), m_optdest(nullptr) {}
724 
725  /////////////////////////////////////////////////////////////////////////
726  // sp_printable implementation.
727  /////////////////////////////////////////////////////////////////////////
728 
729  virtual void print(const THD *thd, String *str);
730 
731  /////////////////////////////////////////////////////////////////////////
732  // sp_instr implementation.
733  /////////////////////////////////////////////////////////////////////////
734 
735  virtual bool execute(THD *, uint *nextp) {
736  *nextp = m_dest;
737  return false;
738  }
739 
740  virtual uint opt_mark(sp_head *sp, List<sp_instr> *leads);
741 
742  virtual uint opt_shortcut_jump(sp_head *sp, sp_instr *start);
743 
744  virtual void opt_move(uint dst, List<sp_branch_instr> *ibp);
745 
746  /////////////////////////////////////////////////////////////////////////
747  // sp_branch_instr implementation.
748  /////////////////////////////////////////////////////////////////////////
749 
750  virtual void set_destination(uint old_dest, uint new_dest) {
751  if (m_dest == old_dest) m_dest = new_dest;
752  }
753 
754  virtual void backpatch(uint dest) {
755  /* Calling backpatch twice is a logic flaw in jump resolution. */
756  DBUG_ASSERT(m_dest == 0);
757  m_dest = dest;
758  }
759 
760  protected:
761  /// Where we will go.
763 
764  // The following attribute is used by SP-optimizer.
766 
767 #ifdef HAVE_PSI_INTERFACE
768  public:
769  virtual PSI_statement_info *get_psi_info() { return &psi_info; }
770 
772 #endif
773 };
774 
775 ///////////////////////////////////////////////////////////////////////////
776 
777 /**
778  sp_lex_branch_instr is a base class for SP-instructions, which might perform
779  conditional jump depending on the value of an SQL-expression.
780 */
782  protected:
783  sp_lex_branch_instr(uint ip, sp_pcontext *ctx, LEX *lex, Item *expr_item,
784  LEX_CSTRING expr_query)
785  : sp_lex_instr(ip, ctx, lex, true),
786  m_dest(0),
787  m_cont_dest(0),
788  m_optdest(nullptr),
789  m_cont_optdest(nullptr),
790  m_expr_item(expr_item),
791  m_expr_query(expr_query) {}
792 
793  sp_lex_branch_instr(uint ip, sp_pcontext *ctx, LEX *lex, Item *expr_item,
794  LEX_CSTRING expr_query, uint dest)
795  : sp_lex_instr(ip, ctx, lex, true),
796  m_dest(dest),
797  m_cont_dest(0),
798  m_optdest(nullptr),
799  m_cont_optdest(nullptr),
800  m_expr_item(expr_item),
801  m_expr_query(expr_query) {}
802 
803  public:
804  void set_cont_dest(uint cont_dest) { m_cont_dest = cont_dest; }
805 
806  /////////////////////////////////////////////////////////////////////////
807  // sp_instr implementation.
808  /////////////////////////////////////////////////////////////////////////
809 
810  virtual uint opt_mark(sp_head *sp, List<sp_instr> *leads);
811 
812  virtual void opt_move(uint dst, List<sp_branch_instr> *ibp);
813 
814  virtual uint get_cont_dest() const { return m_cont_dest; }
815 
816  /////////////////////////////////////////////////////////////////////////
817  // sp_lex_instr implementation.
818  /////////////////////////////////////////////////////////////////////////
819 
820  virtual bool is_invalid() const { return m_expr_item == nullptr; }
821 
822  virtual void invalidate() {
823  m_expr_item = nullptr; /* it's already deleted. */
824  }
825 
826  virtual LEX_CSTRING get_expr_query() const { return m_expr_query; }
827 
828  /////////////////////////////////////////////////////////////////////////
829  // sp_branch_instr implementation.
830  /////////////////////////////////////////////////////////////////////////
831 
832  virtual void set_destination(uint old_dest, uint new_dest) {
833  if (m_dest == old_dest) m_dest = new_dest;
834 
835  if (m_cont_dest == old_dest) m_cont_dest = new_dest;
836  }
837 
838  virtual void backpatch(uint dest) {
839  /* Calling backpatch twice is a logic flaw in jump resolution. */
840  DBUG_ASSERT(m_dest == 0);
841  m_dest = dest;
842  }
843 
844  protected:
845  /// Where we will go.
847 
848  /// Where continue handlers will go.
850 
851  // The following attributes are used by SP-optimizer.
854 
855  /// Expression item.
857 
858  /// SQL-query corresponding to the expression.
860 };
861 
862 ///////////////////////////////////////////////////////////////////////////
863 
864 /**
865  sp_instr_jump_if_not implements SP-instruction, which does the jump if its
866  SQL-expression is false.
867 */
869  public:
870  sp_instr_jump_if_not(uint ip, LEX *lex, Item *expr_item,
871  LEX_CSTRING expr_query)
872  : sp_lex_branch_instr(ip, lex->get_sp_current_parsing_ctx(), lex,
873  expr_item, expr_query) {}
874 
875  sp_instr_jump_if_not(uint ip, LEX *lex, Item *expr_item,
876  LEX_CSTRING expr_query, uint dest)
877  : sp_lex_branch_instr(ip, lex->get_sp_current_parsing_ctx(), lex,
878  expr_item, expr_query, dest) {}
879 
880  /////////////////////////////////////////////////////////////////////////
881  // sp_printable implementation.
882  /////////////////////////////////////////////////////////////////////////
883 
884  virtual void print(const THD *thd, String *str);
885 
886  /////////////////////////////////////////////////////////////////////////
887  // sp_lex_instr implementation.
888  /////////////////////////////////////////////////////////////////////////
889 
890  virtual bool exec_core(THD *thd, uint *nextp);
891 
892  virtual bool on_after_expr_parsing(THD *thd) {
894 
895  m_expr_item = thd->lex->select_lex->item_list.head();
896 
897  return false;
898  }
899 
900 #ifdef HAVE_PSI_INTERFACE
901  public:
902  virtual PSI_statement_info *get_psi_info() { return &psi_info; }
903 
905 #endif
906 };
907 
908 ///////////////////////////////////////////////////////////////////////////
909 // Instructions used for the "simple CASE" implementation.
910 ///////////////////////////////////////////////////////////////////////////
911 
912 /**
913  sp_instr_set_case_expr is used in the "simple CASE" implementation to evaluate
914  and store the CASE-expression in the runtime context.
915 */
917  public:
918  sp_instr_set_case_expr(uint ip, LEX *lex, uint case_expr_id,
919  Item *case_expr_item, LEX_CSTRING case_expr_query)
920  : sp_lex_branch_instr(ip, lex->get_sp_current_parsing_ctx(), lex,
921  case_expr_item, case_expr_query),
922  m_case_expr_id(case_expr_id) {}
923 
924  /////////////////////////////////////////////////////////////////////////
925  // sp_printable implementation.
926  /////////////////////////////////////////////////////////////////////////
927 
928  virtual void print(const THD *thd, String *str);
929 
930  /////////////////////////////////////////////////////////////////////////
931  // sp_instr implementation.
932  /////////////////////////////////////////////////////////////////////////
933 
934  virtual uint opt_mark(sp_head *sp, List<sp_instr> *leads);
935 
936  virtual void opt_move(uint dst, List<sp_branch_instr> *ibp);
937 
938  /////////////////////////////////////////////////////////////////////////
939  // sp_branch_instr implementation.
940  /////////////////////////////////////////////////////////////////////////
941 
942  /*
943  NOTE: set_destination() and backpatch() are overriden here just because the
944  m_dest attribute is not used by this class, so there is no need to do
945  anything about it.
946 
947  @todo These operations probably should be left as they are (i.e. do not
948  override them here). The m_dest attribute would be set and not used, but
949  that should not be a big deal.
950 
951  @todo This also indicates deficiency of the current SP-istruction class
952  hierarchy.
953  */
954 
955  virtual void set_destination(uint old_dest, uint new_dest) {
956  if (m_cont_dest == old_dest) m_cont_dest = new_dest;
957  }
958 
959  virtual void backpatch(uint) {}
960 
961  /////////////////////////////////////////////////////////////////////////
962  // sp_lex_instr implementation.
963  /////////////////////////////////////////////////////////////////////////
964 
965  virtual bool exec_core(THD *thd, uint *nextp);
966 
967  virtual bool on_after_expr_parsing(THD *thd) {
969 
970  m_expr_item = thd->lex->select_lex->item_list.head();
971 
972  return false;
973  }
974 
975  private:
976  /// Identifier (index) of the CASE-expression in the runtime context.
978 
979 #ifdef HAVE_PSI_INTERFACE
980  public:
981  virtual PSI_statement_info *get_psi_info() { return &psi_info; }
982 
984 #endif
985 };
986 
987 ///////////////////////////////////////////////////////////////////////////
988 
989 /**
990  sp_instr_jump_case_when instruction is used in the "simple CASE"
991  implementation. It's a jump instruction with the following condition:
992  (CASE-expression = WHEN-expression)
993  CASE-expression is retrieved from sp_rcontext;
994  WHEN-expression is kept by this instruction.
995 */
997  public:
998  sp_instr_jump_case_when(uint ip, LEX *lex, int case_expr_id,
999  Item *when_expr_item, LEX_CSTRING when_expr_query)
1000  : sp_lex_branch_instr(ip, lex->get_sp_current_parsing_ctx(), lex,
1001  when_expr_item, when_expr_query),
1002  m_case_expr_id(case_expr_id) {}
1003 
1004  /////////////////////////////////////////////////////////////////////////
1005  // sp_printable implementation.
1006  /////////////////////////////////////////////////////////////////////////
1007 
1008  virtual void print(const THD *thd, String *str);
1009 
1010  /////////////////////////////////////////////////////////////////////////
1011  // sp_lex_instr implementation.
1012  /////////////////////////////////////////////////////////////////////////
1013 
1014  virtual bool exec_core(THD *thd, uint *nextp);
1015 
1016  virtual void invalidate() {
1017  // Items should be already deleted in lex-keeper.
1018  m_case_expr_item = nullptr;
1019  m_eq_item = nullptr;
1020  m_expr_item = nullptr; // it's a WHEN-expression.
1021  }
1022 
1023  /**
1024  Build CASE-expression item tree:
1025  Item_func_eq(case-expression, when-i-expression)
1026 
1027  This function is used for the following form of CASE statement:
1028  CASE case-expression
1029  WHEN when-1-expression THEN ...
1030  WHEN when-2-expression THEN ...
1031  ...
1032  WHEN when-n-expression THEN ...
1033  END CASE
1034 
1035  The thing is that after the parsing we have an item (item tree) for the
1036  case-expression and for each when-expression. Here we build jump
1037  conditions: expressions like (case-expression = when-i-expression).
1038 
1039  @param thd Thread context.
1040 
1041  @return Error flag.
1042  */
1043  virtual bool on_after_expr_parsing(THD *thd);
1044 
1045  private:
1046  /// Identifier (index) of the CASE-expression in the runtime context.
1048 
1049  /// Item representing the CASE-expression.
1051 
1052  /**
1053  Item corresponding to the main item of the jump-condition-expression:
1054  it's the equal function (=) in the (case-expression = when-i-expression)
1055  expression.
1056  */
1058 
1059 #ifdef HAVE_PSI_INTERFACE
1060  public:
1061  virtual PSI_statement_info *get_psi_info() { return &psi_info; }
1062 
1064 #endif
1065 };
1066 
1067 ///////////////////////////////////////////////////////////////////////////
1068 // SQL-condition handler instructions.
1069 ///////////////////////////////////////////////////////////////////////////
1070 
1072  public:
1074 
1075  virtual ~sp_instr_hpush_jump();
1076 
1077  void add_condition(sp_condition_value *condition_value);
1078 
1079  sp_handler *get_handler() { return m_handler; }
1080 
1081  /////////////////////////////////////////////////////////////////////////
1082  // sp_printable implementation.
1083  /////////////////////////////////////////////////////////////////////////
1084 
1085  virtual void print(const THD *thd, String *str);
1086 
1087  /////////////////////////////////////////////////////////////////////////
1088  // sp_instr implementation.
1089  /////////////////////////////////////////////////////////////////////////
1090 
1091  virtual bool execute(THD *thd, uint *nextp);
1092 
1093  virtual uint opt_mark(sp_head *sp, List<sp_instr> *leads);
1094 
1095  /** Override sp_instr_jump's shortcut; we stop here. */
1096  virtual uint opt_shortcut_jump(sp_head *, sp_instr *) { return get_ip(); }
1097 
1098  /////////////////////////////////////////////////////////////////////////
1099  // sp_branch_instr implementation.
1100  /////////////////////////////////////////////////////////////////////////
1101 
1102  virtual void backpatch(uint dest) {
1103  DBUG_ASSERT(!m_dest || !m_opt_hpop);
1104  if (!m_dest)
1105  m_dest = dest;
1106  else
1107  m_opt_hpop = dest;
1108  }
1109 
1110  private:
1111  /// Handler.
1113 
1114  /// hpop marking end of handler scope.
1116 
1117  // This attribute is needed for SHOW PROCEDURE CODE only (i.e. it's needed in
1118  // debug version only). It's used in print().
1120 
1121 #ifdef HAVE_PSI_INTERFACE
1122  public:
1123  virtual PSI_statement_info *get_psi_info() { return &psi_info; }
1124 
1126 #endif
1127 };
1128 
1129 ///////////////////////////////////////////////////////////////////////////
1130 
1131 class sp_instr_hpop : public sp_instr {
1132  public:
1133  sp_instr_hpop(uint ip, sp_pcontext *ctx) : sp_instr(ip, ctx) {}
1134 
1135  /////////////////////////////////////////////////////////////////////////
1136  // sp_printable implementation.
1137  /////////////////////////////////////////////////////////////////////////
1138 
1139  virtual void print(const THD *, String *str) {
1140  str->append(STRING_WITH_LEN("hpop"));
1141  }
1142 
1143  /////////////////////////////////////////////////////////////////////////
1144  // sp_instr implementation.
1145  /////////////////////////////////////////////////////////////////////////
1146 
1147  virtual bool execute(THD *thd, uint *nextp);
1148 
1149 #ifdef HAVE_PSI_INTERFACE
1150  public:
1151  virtual PSI_statement_info *get_psi_info() { return &psi_info; }
1152 
1154 #endif
1155 };
1156 
1157 ///////////////////////////////////////////////////////////////////////////
1158 
1160  public:
1161  sp_instr_hreturn(uint ip, sp_pcontext *ctx);
1162 
1163  /////////////////////////////////////////////////////////////////////////
1164  // sp_printable implementation.
1165  /////////////////////////////////////////////////////////////////////////
1166 
1167  virtual void print(const THD *thd, String *str);
1168 
1169  /////////////////////////////////////////////////////////////////////////
1170  // sp_instr implementation.
1171  /////////////////////////////////////////////////////////////////////////
1172 
1173  virtual bool execute(THD *thd, uint *nextp);
1174 
1175  /** Override sp_instr_jump's shortcut; we stop here. */
1176  virtual uint opt_shortcut_jump(sp_head *, sp_instr *) { return get_ip(); }
1177 
1178  virtual uint opt_mark(sp_head *sp, List<sp_instr> *leads);
1179 
1180  private:
1181  // This attribute is needed for SHOW PROCEDURE CODE only (i.e. it's needed in
1182  // debug version only). It's used in print().
1184 
1185 #ifdef HAVE_PSI_INTERFACE
1186  public:
1187  virtual PSI_statement_info *get_psi_info() { return &psi_info; }
1188 
1190 #endif
1191 };
1192 
1193 ///////////////////////////////////////////////////////////////////////////
1194 // Cursor implementation.
1195 ///////////////////////////////////////////////////////////////////////////
1196 
1197 /**
1198  sp_instr_cpush corresponds to DECLARE CURSOR, implements DECLARE CURSOR and
1199  OPEN.
1200 
1201  This is the most important instruction in cursor implementation. It is created
1202  and added to sp_head when DECLARE CURSOR is being parsed. The arena of this
1203  instruction contains LEX-object for the cursor's SELECT-statement.
1204 
1205  This instruction is actually used to open the cursor.
1206 
1207  execute() operation "implements" DECLARE CURSOR statement -- it merely pushes
1208  a new cursor object into the stack in sp_rcontext object.
1209 
1210  exec_core() operation implements OPEN statement. It is important to implement
1211  OPEN statement in this instruction, because OPEN may lead to re-parsing of the
1212  SELECT-statement. So, the original Arena and parsing context must be used.
1213 */
1215  public:
1216  sp_instr_cpush(uint ip, sp_pcontext *ctx, LEX *cursor_lex,
1217  LEX_CSTRING cursor_query, int cursor_idx)
1218  : sp_lex_instr(ip, ctx, cursor_lex, true),
1219  m_cursor_query(cursor_query),
1220  m_valid(true),
1221  m_cursor_idx(cursor_idx) {
1222  /*
1223  Cursors cause queries to depend on external state, so they are
1224  noncacheable.
1225  */
1226  cursor_lex->safe_to_cache_query = false;
1227  }
1228 
1229  /////////////////////////////////////////////////////////////////////////
1230  // sp_printable implementation.
1231  /////////////////////////////////////////////////////////////////////////
1232 
1233  virtual void print(const THD *thd, String *str);
1234 
1235  /////////////////////////////////////////////////////////////////////////
1236  // sp_instr implementation.
1237  /////////////////////////////////////////////////////////////////////////
1238 
1239  virtual bool execute(THD *thd, uint *nextp);
1240 
1241  /////////////////////////////////////////////////////////////////////////
1242  // sp_lex_instr implementation.
1243  /////////////////////////////////////////////////////////////////////////
1244 
1245  virtual bool exec_core(THD *thd, uint *nextp);
1246 
1247  virtual bool is_invalid() const { return !m_valid; }
1248 
1249  virtual void invalidate() { m_valid = false; }
1250 
1251  virtual void get_query(String *sql_query) const {
1252  sql_query->append(m_cursor_query.str, m_cursor_query.length);
1253  }
1254 
1255  virtual bool on_after_expr_parsing(THD *) {
1256  m_valid = true;
1257  return false;
1258  }
1259 
1260  private:
1261  /// This attribute keeps the cursor SELECT statement.
1263 
1264  /// Flag if the LEX-object of this instruction is valid or not.
1265  /// The LEX-object is not valid when metadata have changed.
1266  bool m_valid;
1267 
1268  /// Used to identify the cursor in the sp_rcontext.
1270 
1271 #ifdef HAVE_PSI_INTERFACE
1272  public:
1273  virtual PSI_statement_info *get_psi_info() { return &psi_info; }
1274 
1276 #endif
1277 };
1278 
1279 ///////////////////////////////////////////////////////////////////////////
1280 
1281 /**
1282  sp_instr_cpop instruction is added at the end of BEGIN..END block.
1283  It's used to remove declared cursors so that they are not visible any longer.
1284 */
1285 class sp_instr_cpop : public sp_instr {
1286  public:
1288  : sp_instr(ip, ctx), m_count(count) {}
1289 
1290  /////////////////////////////////////////////////////////////////////////
1291  // sp_printable implementation.
1292  /////////////////////////////////////////////////////////////////////////
1293 
1294  virtual void print(const THD *thd, String *str);
1295 
1296  /////////////////////////////////////////////////////////////////////////
1297  // sp_instr implementation.
1298  /////////////////////////////////////////////////////////////////////////
1299 
1300  virtual bool execute(THD *thd, uint *nextp);
1301 
1302  private:
1304 
1305 #ifdef HAVE_PSI_INTERFACE
1306  public:
1307  virtual PSI_statement_info *get_psi_info() { return &psi_info; }
1308 
1310 #endif
1311 };
1312 
1313 ///////////////////////////////////////////////////////////////////////////
1314 
1315 /**
1316  sp_instr_copen represents OPEN statement (opens the cursor).
1317  However, the actual implementation is in sp_instr_cpush::exec_core().
1318 */
1319 class sp_instr_copen : public sp_instr {
1320  public:
1321  sp_instr_copen(uint ip, sp_pcontext *ctx, int cursor_idx)
1322  : sp_instr(ip, ctx), m_cursor_idx(cursor_idx) {}
1323 
1324  /////////////////////////////////////////////////////////////////////////
1325  // sp_printable implementation.
1326  /////////////////////////////////////////////////////////////////////////
1327 
1328  virtual void print(const THD *thd, String *str);
1329 
1330  /////////////////////////////////////////////////////////////////////////
1331  // sp_instr implementation.
1332  /////////////////////////////////////////////////////////////////////////
1333 
1334  virtual bool execute(THD *thd, uint *nextp);
1335 
1336  private:
1337  /// Used to identify the cursor in the sp_rcontext.
1339 
1340 #ifdef HAVE_PSI_INTERFACE
1341  public:
1342  virtual PSI_statement_info *get_psi_info() { return &psi_info; }
1343 
1345 #endif
1346 };
1347 
1348 ///////////////////////////////////////////////////////////////////////////
1349 
1350 /**
1351  The instruction corresponds to the CLOSE statement.
1352  It just forwards the close-call to the appropriate sp_cursor object in the
1353  sp_rcontext.
1354 */
1355 class sp_instr_cclose : public sp_instr {
1356  public:
1357  sp_instr_cclose(uint ip, sp_pcontext *ctx, int cursor_idx)
1358  : sp_instr(ip, ctx), m_cursor_idx(cursor_idx) {}
1359 
1360  /////////////////////////////////////////////////////////////////////////
1361  // sp_printable implementation.
1362  /////////////////////////////////////////////////////////////////////////
1363 
1364  virtual void print(const THD *thd, String *str);
1365 
1366  /////////////////////////////////////////////////////////////////////////
1367  // sp_instr implementation.
1368  /////////////////////////////////////////////////////////////////////////
1369 
1370  virtual bool execute(THD *thd, uint *nextp);
1371 
1372  private:
1373  /// Used to identify the cursor in the sp_rcontext.
1375 
1376 #ifdef HAVE_PSI_INTERFACE
1377  public:
1378  virtual PSI_statement_info *get_psi_info() { return &psi_info; }
1379 
1381 #endif
1382 };
1383 
1384 ///////////////////////////////////////////////////////////////////////////
1385 
1386 /**
1387  The instruction corresponds to the FETCH statement.
1388  It just forwards the close-call to the appropriate sp_cursor object in the
1389  sp_rcontext.
1390 */
1391 class sp_instr_cfetch : public sp_instr {
1392  public:
1393  sp_instr_cfetch(uint ip, sp_pcontext *ctx, int cursor_idx)
1394  : sp_instr(ip, ctx), m_cursor_idx(cursor_idx) {}
1395 
1396  /////////////////////////////////////////////////////////////////////////
1397  // sp_printable implementation.
1398  /////////////////////////////////////////////////////////////////////////
1399 
1400  virtual void print(const THD *thd, String *str);
1401 
1402  /////////////////////////////////////////////////////////////////////////
1403  // sp_instr implementation.
1404  /////////////////////////////////////////////////////////////////////////
1405 
1406  virtual bool execute(THD *thd, uint *nextp);
1407 
1408  void add_to_varlist(sp_variable *var) { m_varlist.push_back(var); }
1409 
1410  private:
1411  /// List of SP-variables to store fetched values.
1413 
1414  /// Used to identify the cursor in the sp_rcontext.
1416 
1417 #ifdef HAVE_PSI_INTERFACE
1418  public:
1419  virtual PSI_statement_info *get_psi_info() { return &psi_info; }
1420 
1422 #endif
1423 };
1424 
1425 ///////////////////////////////////////////////////////////////////////////
1426 ///////////////////////////////////////////////////////////////////////////
1427 
1428 /**
1429  sp_instr_error just throws an SQL-condition if the execution flow comes to it.
1430  It's used in the CASE implementation to perform runtime-check that the
1431  CASE-expression is handled by some WHEN/ELSE clause.
1432 */
1433 class sp_instr_error : public sp_instr {
1434  public:
1435  sp_instr_error(uint ip, sp_pcontext *ctx, int errcode)
1436  : sp_instr(ip, ctx), m_errcode(errcode) {}
1437 
1438  /////////////////////////////////////////////////////////////////////////
1439  // sp_printable implementation.
1440  /////////////////////////////////////////////////////////////////////////
1441 
1442  virtual void print(const THD *thd, String *str);
1443 
1444  /////////////////////////////////////////////////////////////////////////
1445  // sp_instr implementation.
1446  /////////////////////////////////////////////////////////////////////////
1447 
1448  virtual bool execute(THD *, uint *nextp) {
1449  my_error(m_errcode, MYF(0));
1450  *nextp = get_ip() + 1;
1451  return true;
1452  }
1453 
1455  m_marked = true;
1456  return UINT_MAX;
1457  }
1458 
1459  private:
1460  /// The error code, which should be raised by this instruction.
1462 
1463 #ifdef HAVE_PSI_INTERFACE
1464  public:
1465  virtual PSI_statement_info *get_psi_info() { return &psi_info; }
1466 
1468 #endif
1469 };
1470 
1471 ///////////////////////////////////////////////////////////////////////////
1472 
1473 #endif // _SP_INSTR_H_
virtual void invalidate()
Invalidate the object.
Definition: sp_instr.h:672
sp_instr_hpop(uint ip, sp_pcontext *ctx)
Definition: sp_instr.h:1133
int m_case_expr_id
Identifier (index) of the CASE-expression in the runtime context.
Definition: sp_instr.h:1047
This file contains the field type.
This is base class for all kinds of jump instructions.
Definition: sp_instr.h:717
virtual PSI_statement_info * get_psi_info()
Definition: sp_instr.h:769
Our own string classes, used pervasively throughout the executor.
bool safe_to_cache_query
Whether this query will return the same answer every time, given unchanged data.
Definition: sql_lex.h:3526
virtual PSI_statement_info * get_psi_info()
Definition: sp_instr.h:1151
Base class for every SP-instruction.
Definition: sp_instr.h:102
virtual PSI_statement_info * get_psi_info()
Definition: sp_instr.h:1465
virtual uint opt_mark(sp_head *, List< sp_instr > *)
Mark this instruction as reachable during optimization and return the index to the next instruction...
Definition: sp_instr.h:659
virtual void backpatch(uint dest)
Update all instruction with the given label in the backpatch list to the specified instruction pointe...
Definition: sp_instr.h:754
The instruction corresponds to the FETCH statement.
Definition: sp_instr.h:1391
static PSI_statement_info psi_info
Definition: sp_instr.h:631
virtual PSI_statement_info * get_psi_info()
Definition: sp_instr.h:1342
virtual void get_query(String *sql_query) const
Return the query string, which can be passed to the parser.
Definition: sp_instr.h:1251
virtual bool execute(THD *, uint *nextp)
Execute this instruction.
Definition: sp_instr.h:1448
sp_instr_stmt represents almost all conventional SQL-statements, which are supported outside stored p...
Definition: sp_instr.h:465
Definition: sql_lex.h:3303
virtual bool is_invalid() const
Definition: sp_instr.h:604
ssize_t count
Definition: memcached.c:386
static char * query
Definition: myisam_ftdump.cc:44
sp_instr_jump(uint ip, sp_pcontext *ctx)
Definition: sp_instr.h:719
virtual uint get_cont_dest() const
Get the continuation destination (instruction pointer for the CONTINUE HANDLER) of this instruction...
Definition: sp_instr.h:136
sp_instr_copen(uint ip, sp_pcontext *ctx, int cursor_idx)
Definition: sp_instr.h:1321
virtual PSI_statement_info * get_psi_info()
Definition: sp_instr.h:1187
virtual void invalidate()
Invalidate the object.
Definition: sp_instr.h:822
MEM_ROOT m_lex_mem_root
Mem-root for storing the LEX-tree during reparse.
Definition: sp_instr.h:417
virtual PSI_statement_info * get_psi_info()
Definition: sp_instr.h:699
Some integer typedefs for easier portability.
uint m_ip
Instruction pointer.
Definition: sp_instr.h:202
void my_error(int nr, myf MyFlags,...)
Fill in and print a previously registered error message.
Definition: my_error.cc:215
virtual LEX_CSTRING get_expr_query() const
Definition: sp_instr.h:685
virtual bool is_invalid() const
Definition: sp_instr.h:490
virtual LEX_CSTRING get_expr_query() const
Definition: sp_instr.h:556
LEX * m_lex
LEX-object.
Definition: sp_instr.h:409
sp_instr_error just throws an SQL-condition if the execution flow comes to it.
Definition: sp_instr.h:1433
sp_instr_cpop(uint ip, sp_pcontext *ctx, uint count)
Definition: sp_instr.h:1287
The instruction corresponds to the CLOSE statement.
Definition: sp_instr.h:1355
virtual bool is_invalid() const
Definition: sp_instr.h:544
virtual bool on_after_expr_parsing(THD *)
Callback function which is called after the statement query string is successfully parsed...
Definition: sp_instr.h:498
sp_instr_jump_if_not(uint ip, LEX *lex, Item *expr_item, LEX_CSTRING expr_query)
Definition: sp_instr.h:870
virtual PSI_statement_info * get_psi_info()
Definition: sp_instr.h:1273
virtual uint opt_shortcut_jump(sp_head *, sp_instr *)
Override sp_instr_jump&#39;s shortcut; we stop here.
Definition: sp_instr.h:1176
sp_handler * m_handler
Handler.
Definition: sp_instr.h:1112
bool open_tables(THD *thd, TABLE_LIST **start, uint *counter, uint flags, Prelocking_strategy *prelocking_strategy)
Open all tables in list.
Definition: sql_base.cc:5569
int m_cursor_idx
Used to identify the cursor in the sp_rcontext.
Definition: sp_instr.h:1374
uint m_count
Definition: sp_instr.h:1303
Definition: mysql_lex_string.h:39
sp_lex_instr is a class providing the interface and base implementation for SP-instructions, whose execution is based on expression evaluation.
Definition: sp_instr.h:224
static app_data_list nextp(app_data_list l)
Return next element in list of app_data.
Definition: app_data.c:319
sp_handler * get_handler()
Definition: sp_instr.h:1079
virtual bool on_after_expr_parsing(THD *)
Callback function which is called after the statement query string is successfully parsed...
Definition: sp_instr.h:1255
This class represents &#39;DECLARE HANDLER&#39; statement.
Definition: sp_pcontext.h:191
sp_instr_set(uint ip, LEX *lex, uint offset, Item *value_item, LEX_CSTRING value_query, bool is_lex_owner)
Definition: sp_instr.h:525
SELECT_LEX * select_lex
First query block.
Definition: sql_lex.h:3308
LEX_CSTRING m_expr_query
SQL-query corresponding to the expression.
Definition: sp_instr.h:859
static PSI_statement_info psi_info
Definition: sp_instr.h:983
LEX_CSTRING m_value_query
SQL-query corresponding to the value expression.
Definition: sp_instr.h:625
virtual bool on_after_expr_parsing(THD *thd)
Callback function which is called after the statement query string is successfully parsed...
Definition: sp_instr.h:677
sp_instr_stmt(uint ip, LEX *lex, LEX_CSTRING query)
Definition: sp_instr.h:467
virtual PSI_statement_info * get_psi_info()
Definition: sp_instr.h:902
static bool execute(MYSQL_STMT *stmt, char *packet, ulong length)
Definition: libmysql.cc:1918
sp_instr_jump(uint ip, sp_pcontext *ctx, uint dest)
Definition: sp_instr.h:722
sp_instr_cclose(uint ip, sp_pcontext *ctx, int cursor_idx)
Definition: sp_instr.h:1357
sp_instr_cpush(uint ip, sp_pcontext *ctx, LEX *cursor_lex, LEX_CSTRING cursor_query, int cursor_idx)
Definition: sp_instr.h:1216
List< Item > item_list
List of columns and expressions: SELECT: Columns and expressions in the SELECT list.
Definition: sql_lex.h:1199
The handler class is the interface for dynamically loadable storage engines.
Definition: handler.h:3986
sp_instr * m_cont_optdest
Definition: sp_instr.h:853
Using this class is fraught with peril, and you need to be very careful when doing so...
Definition: sql_string.h:164
virtual bool is_invalid() const
Definition: sp_instr.h:820
virtual void print(const THD *thd, String *str)=0
virtual bool on_after_expr_parsing(THD *thd)
Callback function which is called after the statement query string is successfully parsed...
Definition: sp_instr.h:548
Item_case_expr * m_case_expr_item
Item representing the CASE-expression.
Definition: sp_instr.h:1050
sp_instr_jump_if_not(uint ip, LEX *lex, Item *expr_item, LEX_CSTRING expr_query, uint dest)
Definition: sp_instr.h:875
Item_trigger_field * m_trigger_field
Item corresponding to the NEW/OLD trigger field.
Definition: sp_instr.h:619
sp_instr_cpush corresponds to DECLARE CURSOR, implements DECLARE CURSOR and OPEN. ...
Definition: sp_instr.h:1214
Diagnostics_area * get_stmt_da()
Returns first Diagnostics Area for the current statement.
Definition: sql_class.h:2872
virtual PSI_statement_info * get_psi_info()
Definition: sp_instr.h:1061
Item * m_expr_item
RETURN-expression item.
Definition: sp_instr.h:689
sp_instr_error(uint ip, sp_pcontext *ctx, int errcode)
Definition: sp_instr.h:1435
#define DBUG_ASSERT(A)
Definition: my_dbug.h:199
sp_instr_set_case_expr(uint ip, LEX *lex, uint case_expr_id, Item *case_expr_item, LEX_CSTRING case_expr_query)
Definition: sp_instr.h:918
static PSI_statement_info psi_info
Definition: sp_instr.h:1344
virtual void invalidate()
Invalidate the object.
Definition: sp_instr.h:1249
void add_to_varlist(sp_variable *var)
Definition: sp_instr.h:1408
uint m_cont_dest
Where continue handlers will go.
Definition: sp_instr.h:849
void clear_da(THD *thd) const
Clear diagnostics area.
Definition: sp_instr.h:145
bool append(const String &s)
Definition: sql_string.cc:443
List< sp_variable > m_varlist
List of SP-variables to store fetched values.
Definition: sp_instr.h:1412
#define MYF(v)
sp_pcontext * get_parsing_ctx() const
Definition: sp_instr.h:138
Definition: sql_class.h:226
static PSI_statement_info psi_info
Definition: sp_instr.h:1189
LEX_CSTRING m_value_query
SQL-query corresponding to the value expression.
Definition: sp_instr.h:566
virtual ~sp_branch_instr()
Definition: sp_instr.h:93
virtual bool is_invalid() const
Definition: sp_instr.h:670
uint m_opt_hpop
hpop marking end of handler scope.
Definition: sp_instr.h:1115
static PSI_statement_info psi_info
Definition: sp_instr.h:1380
static PSI_statement_info psi_info
Definition: sp_instr.h:1309
sp_instr_set_case_expr is used in the "simple CASE" implementation to evaluate and store the CASE-exp...
Definition: sp_instr.h:916
Definition: sp_instr.h:1131
Definition: aggregate_check.h:523
virtual bool on_after_expr_parsing(THD *thd)
Callback function which is called after the statement query string is successfully parsed...
Definition: sp_instr.h:892
int m_errcode
The error code, which should be raised by this instruction.
Definition: sp_instr.h:1461
static PSI_statement_info psi_info
Definition: sp_instr.h:1153
Item * m_expr_item
Expression item.
Definition: sp_instr.h:856
sp_instr_set_trigger_field represents SET-statements, which deal with NEW/OLD trigger pseudo-rows...
Definition: sp_instr.h:581
This class represents condition-value term in DECLARE CONDITION or DECLARE HANDLER statements...
Definition: sp_pcontext.h:131
The class represents parse-time context, which keeps track of declared variables/parameters, conditions, handlers, cursors and labels.
Definition: sp_pcontext.h:250
Definition: sp_instr.h:1159
sp_lex_branch_instr(uint ip, sp_pcontext *ctx, LEX *lex, Item *expr_item, LEX_CSTRING expr_query, uint dest)
Definition: sp_instr.h:793
sp_instr_jump_case_when instruction is used in the "simple CASE" implementation.
Definition: sp_instr.h:996
Header for compiler-dependent features.
LEX_CSTRING m_query
Complete query of the SQL-statement.
Definition: sp_instr.h:505
sp_instr * m_optdest
Definition: sp_instr.h:852
static PSI_statement_info psi_info
Definition: sp_instr.h:570
enum_field_types
Column types for MySQL.
Definition: field_types.h:52
An interface for all SP-instructions with destinations that need to be updated by the SP-optimizer...
Definition: sp_instr.h:75
Defines various enable/disable and HAVE_ macros related to the performance schema instrumentation sys...
Statement instrument information.
Definition: psi_statement_bits.h:108
This class represents a stored program variable or a parameter (also referenced as &#39;SP-variable&#39;)...
Definition: sp_pcontext.h:47
bool opt_is_marked() const
Definition: sp_instr.h:188
Definition: item.h:740
unsigned int uint
Definition: uca-dump.cc:29
virtual bool on_after_expr_parsing(THD *thd)
Callback function which is called after the statement query string is successfully parsed...
Definition: sp_instr.h:967
virtual uint opt_mark(sp_head *, List< sp_instr > *)
Mark this instruction as reachable during optimization and return the index to the next instruction...
Definition: sp_instr.h:1454
sp_instr_jump_if_not implements SP-instruction, which does the jump if its SQL-expression is false...
Definition: sp_instr.h:868
#define true
Definition: config_static.h:44
virtual bool execute(THD *, uint *nextp)
Execute this instruction.
Definition: sp_instr.h:735
virtual ~sp_lex_instr()
Definition: sp_instr.h:236
static PSI_statement_info psi_info
Definition: sp_instr.h:1125
Performance schema instrumentation interface.
static PSI_statement_info psi_info
Definition: sp_instr.h:1275
LEX_CSTRING m_expr_query
SQL-query corresponding to the RETURN-expression.
Definition: sp_instr.h:692
static PSI_statement_info psi_info
Definition: sp_instr.h:1421
bool m_first_execution
Indicates whether exec_core() has not been already called on the current LEX-object.
Definition: sp_instr.h:429
static PSI_statement_info psi_info
Definition: sp_instr.h:1467
virtual SQL_I_List< Item_trigger_field > * get_instr_trig_field_list()
Definition: sp_instr.h:267
sp_instr * m_optdest
Definition: sp_instr.h:765
sp_instr_cpop instruction is added at the end of BEGIN..END block.
Definition: sp_instr.h:1285
static PSI_statement_info psi_info
Definition: sp_instr.h:701
virtual uint opt_shortcut_jump(sp_head *, sp_instr *)
Override sp_instr_jump&#39;s shortcut; we stop here.
Definition: sp_instr.h:1096
void reset_condition_info(THD *thd)
Reset the current condition information stored in the Diagnostics Area.
Definition: sql_error.cc:482
uint m_dest
Where we will go.
Definition: sp_instr.h:762
virtual void print(const THD *, String *str)
Definition: sp_instr.h:1139
sp_head represents one instance of a stored program.
Definition: sp_head.h:379
Common header for many mysys elements.
bool m_is_lex_owner
Indicates whether this sp_lex_instr instance is responsible for LEX-object deletion.
Definition: sp_instr.h:423
virtual PSI_statement_info * get_psi_info()
Definition: sp_instr.h:981
Item * m_value_item
Value expression item of the SET-statement.
Definition: sp_instr.h:622
virtual void set_destination(uint old_dest, uint new_dest)
Update the destination; used by the SP-instruction-optimizer.
Definition: sp_instr.h:955
virtual bool on_after_expr_parsing(THD *thd)
Callback function which is called after the statement query string is successfully parsed...
Definition: sp_instr.h:396
LEX * lex
Definition: sql_class.h:825
sp_instr_set_trigger_field(uint ip, LEX *lex, LEX_CSTRING trigger_field_name, Item_trigger_field *trigger_field, Item *value_item, LEX_CSTRING value_query)
Definition: sp_instr.h:583
virtual void invalidate()
Invalidate the object.
Definition: sp_instr.h:546
virtual PSI_statement_info * get_psi_info()
Definition: sp_instr.h:1307
Definition: sp_instr.h:1071
sp_instr_jump_case_when(uint ip, LEX *lex, int case_expr_id, Item *when_expr_item, LEX_CSTRING when_expr_query)
Definition: sp_instr.h:998
virtual PSI_statement_info * get_psi_info()
Definition: sp_instr.h:1378
uint m_frame
Definition: sp_instr.h:1183
virtual uint get_cont_dest() const
Get the continuation destination (instruction pointer for the CONTINUE HANDLER) of this instruction...
Definition: sp_instr.h:814
LEX_CSTRING m_trigger_field_name
Trigger field name ("field_name" of the "NEW.field_name").
Definition: sp_instr.h:616
static PSI_statement_info psi_info
Definition: sp_instr.h:904
virtual PSI_statement_info * get_psi_info()
Definition: sp_instr.h:629
virtual ~sp_printable()
Definition: sp_instr.h:68
LEX_CSTRING EMPTY_CSTR
Definition: sql_class.cc:121
#define alloc_root_inited(A)
Definition: my_sys.h:796
uint elements
Definition: sql_list.h:135
TABLE_LIST ** m_lex_query_tables_own_last
The value m_lex->query_tables_own_last should be set to this when the statement enters/leaves prelock...
Definition: sp_instr.h:448
virtual uint opt_shortcut_jump(sp_head *, sp_instr *start)
Short-cut jumps to jumps during optimization.
Definition: sp_instr.h:172
static PSI_statement_info psi_info
Definition: sp_instr.h:771
TABLE_LIST * m_prelocking_tables
List of additional tables this statement needs to lock when it enters/leaves prelocked mode on its ow...
Definition: sp_instr.h:442
int m_cursor_idx
Used to identify the cursor in the sp_rcontext.
Definition: sp_instr.h:1415
sp_instr_copen represents OPEN statement (opens the cursor).
Definition: sp_instr.h:1319
sp_printable defines an interface which should be implemented if a class wants report some internal i...
Definition: sp_instr.h:64
sp_instr_freturn(uint ip, LEX *lex, Item *expr_item, LEX_CSTRING expr_query, enum enum_field_types return_field_type)
Definition: sp_instr.h:642
LEX_CSTRING m_cursor_query
This attribute keeps the cursor SELECT statement.
Definition: sp_instr.h:1262
virtual PSI_statement_info * get_psi_info()
Definition: sp_instr.h:1123
sp_pcontext * m_parsing_ctx
Instruction parsing context.
Definition: sp_instr.h:205
sp_lex_branch_instr(uint ip, sp_pcontext *ctx, LEX *lex, Item *expr_item, LEX_CSTRING expr_query)
Definition: sp_instr.h:783
virtual PSI_statement_info * get_psi_info()
Definition: sp_instr.h:512
void set_cont_dest(uint cont_dest)
Definition: sp_instr.h:804
uint m_case_expr_id
Identifier (index) of the CASE-expression in the runtime context.
Definition: sp_instr.h:977
uint get_ip() const
Definition: sp_instr.h:129
static PSI_statement_info psi_info
Definition: sp_instr.h:514
virtual LEX_CSTRING get_expr_query() const
Definition: sp_instr.h:384
sp_instr_cfetch(uint ip, sp_pcontext *ctx, int cursor_idx)
Definition: sp_instr.h:1393
Item * m_eq_item
Item corresponding to the main item of the jump-condition-expression: it&#39;s the equal function (=) in ...
Definition: sp_instr.h:1057
bool m_marked
Show if this instruction is reachable within the SP (used by SP-optimizer).
Definition: sp_instr.h:199
virtual void invalidate()
Invalidate the object.
Definition: sp_instr.h:1016
int m_cursor_idx
Used to identify the cursor in the sp_rcontext.
Definition: sp_instr.h:1269
sp_lex_branch_instr is a base class for SP-instructions, which might perform conditional jump dependi...
Definition: sp_instr.h:781
sp_instr(uint ip, sp_pcontext *ctx)
Definition: sp_instr.h:104
Represents NEW/OLD version of field of row which is changed/read in trigger.
Definition: item.h:5868
virtual bool execute(THD *thd, uint *nextp)
Execute this instruction.
Definition: sp_instr.h:325
The MEM_ROOT is a simple arena, where allocations are carved out of larger blocks.
Definition: my_alloc.h:77
bool m_valid
Specify if the stored LEX-object is up-to-date.
Definition: sp_instr.h:508
uint m_offset
Frame offset.
Definition: sp_instr.h:560
Definition: table.h:2481
virtual PSI_statement_info * get_psi_info()
Definition: sp_instr.h:571
uint m_frame
Definition: sp_instr.h:1119
virtual void set_destination(uint old_dest, uint new_dest)
Update the destination; used by the SP-instruction-optimizer.
Definition: sp_instr.h:750
virtual LEX_CSTRING get_expr_query() const
Definition: sp_instr.h:612
virtual void invalidate()
Invalidate the object.
Definition: sp_instr.h:606
static PSI_statement_info psi_info
Definition: sp_instr.h:1063
virtual void invalidate()
Invalidate the object.
Definition: sp_instr.h:492
sp_instr_set represents SET-statements, which deal with SP-variables.
Definition: sp_instr.h:523
Item * m_value_item
Value expression item of the SET-statement.
Definition: sp_instr.h:563
uint m_dest
Where we will go.
Definition: sp_instr.h:846
void reset_diagnostics_area()
Clear this Diagnostics Area.
Definition: sql_error.cc:357
virtual void set_destination(uint old_dest, uint new_dest)
Update the destination; used by the SP-instruction-optimizer.
Definition: sp_instr.h:832
T * head()
Definition: sql_list.h:464
Query_arena m_arena
Definition: sp_instr.h:194
SQL_I_List< Item_trigger_field > m_trig_field_list
List of all the Item_trigger_field&#39;s of instruction.
Definition: sp_instr.h:453
virtual void opt_move(uint dst, List< sp_branch_instr > *ibp)
Inform the instruction that it has been moved during optimization.
Definition: sp_instr.h:183
#define false
Definition: config_static.h:43
sp_instr_freturn represents RETURN statement in stored functions.
Definition: sp_instr.h:640
virtual bool is_invalid() const
Definition: sp_instr.h:1247
int m_cursor_idx
Used to identify the cursor in the sp_rcontext.
Definition: sp_instr.h:1338
virtual PSI_statement_info * get_psi_info()
Definition: sp_instr.h:1419
bool m_valid
Flag if the LEX-object of this instruction is valid or not.
Definition: sp_instr.h:1266
virtual void backpatch(uint dest)
Update all instruction with the given label in the backpatch list to the specified instruction pointe...
Definition: sp_instr.h:1102
virtual uint opt_mark(sp_head *, List< sp_instr > *leads)
Mark this instruction as reachable during optimization and return the index to the next instruction...
Definition: sp_instr.h:160
virtual ~sp_instr()
Definition: sp_instr.h:110
virtual SQL_I_List< Item_trigger_field > * get_instr_trig_field_list()
Definition: sp_instr.h:190
Definition: item.h:3220
sp_lex_instr(uint ip, sp_pcontext *ctx, LEX *lex, bool is_lex_owner)
Definition: sp_instr.h:226
virtual void backpatch(uint)
Update all instruction with the given label in the backpatch list to the specified instruction pointe...
Definition: sp_instr.h:959
virtual void get_query(String *sql_query) const
Return the query string, which can be passed to the parser.
Definition: sp_instr.h:494
virtual void backpatch(uint dest)
Update all instruction with the given label in the backpatch list to the specified instruction pointe...
Definition: sp_instr.h:838
#define STRING_WITH_LEN(X)
Definition: m_string.h:315
This file follows Google coding style, except for the name MEM_ROOT (which is kept for historical rea...
For each client connection we create a separate thread with THD serving as a thread/connection descri...
Definition: sql_class.h:765
Dialog Client Authentication nullptr
Definition: dialog.cc:353
virtual LEX_CSTRING get_expr_query() const
Definition: sp_instr.h:826
static void start(PluginFuncEnv *env)
Definition: http_auth_backend_plugin.cc:165