MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
sp_head.h
1 /* Copyright (c) 2002, 2012, 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 #ifndef _SP_HEAD_H_
17 #define _SP_HEAD_H_
18 
19 /*
20  It is necessary to include set_var.h instead of item.h because there
21  are dependencies on include order for set_var.h and item.h. This
22  will be resolved later.
23 */
24 #include "my_global.h" /* NO_EMBEDDED_ACCESS_CHECKS */
25 #include "sql_class.h" // THD, set_var.h: THD
26 #include "set_var.h" // Item
27 #include "sp_pcontext.h" // sp_pcontext
28 
35 class sp_instr;
36 class sp_branch_instr;
38 
40 
46 {
47 public:
48  virtual void print(String *str) = 0;
49 
50  virtual ~sp_printable()
51  { }
52 };
53 
55 
62 {
63 public:
64  const CHARSET_INFO *get_db_cl()
65  {
66  return m_db_cl;
67  }
68 
69 public:
70  virtual Stored_program_creation_ctx *clone(MEM_ROOT *mem_root) = 0;
71 
72 protected:
75  m_db_cl(thd->variables.collation_database)
76  { }
77 
79  const CHARSET_INFO *connection_cl,
80  const CHARSET_INFO *db_cl)
81  : Default_object_creation_ctx(client_cs, connection_cl),
82  m_db_cl(db_cl)
83  { }
84 
85 protected:
86  virtual void change_env(THD *thd) const
87  {
88  thd->variables.collation_database= m_db_cl;
89 
90  Default_object_creation_ctx::change_env(thd);
91  }
92 
93 protected:
102 };
103 
105 
106 class sp_name : public Sql_alloc
107 {
108 public:
109 
110  LEX_STRING m_db;
111  LEX_STRING m_name;
112  LEX_STRING m_qname;
115  sp_name(LEX_STRING db, LEX_STRING name, bool use_explicit_name)
116  : m_db(db), m_name(name), m_explicit_name(use_explicit_name)
117  {
118  m_qname.str= 0;
119  m_qname.length= 0;
120  }
121 
123  sp_name(const MDL_key *key, char *qname_buff);
124 
125  // Init. the qualified name from the db and name.
126  void init_qname(THD *thd); // thd for memroot allocation
127 };
128 
130 
136 {
137 private:
138  struct Backpatch_info
139  {
140  sp_label *label;
141  sp_branch_instr *instr;
142  };
143 
144 public:
145  sp_parser_data() :
146  m_expr_start_ptr(NULL),
147  m_current_stmt_start_ptr(NULL),
148  m_option_start_ptr(NULL),
149  m_param_start_ptr(NULL),
150  m_param_end_ptr(NULL),
151  m_body_start_ptr(NULL),
152  m_cont_level(0),
153  m_saved_memroot(NULL),
154  m_saved_free_list(NULL)
155  { }
156 
158 
169  void start_parsing_sp_body(THD *thd, sp_head *sp);
170 
179  void finish_parsing_sp_body(THD *thd)
180  {
181  /*
182  In some cases the parser detects a syntax error and calls
183  LEX::cleanup_lex_after_parse_error() method only after finishing parsing
184  the whole routine. In such a situation sp_head::restore_thd_mem_root() will
185  be called twice - the first time as part of normal parsing process and the
186  second time by cleanup_lex_after_parse_error().
187 
188  To avoid ruining active arena/mem_root state in this case we skip
189  restoration of old arena/mem_root if this method has been already called for
190  this routine.
191  */
192  if (!is_parsing_sp_body())
193  return;
194 
195  thd->free_items();
196  thd->mem_root= m_saved_memroot;
197  thd->free_list= m_saved_free_list;
198 
199  m_saved_memroot= NULL;
200  m_saved_free_list= NULL;
201  }
202 
207  bool is_parsing_sp_body() const
208  { return m_saved_memroot != NULL; }
209 
211 
212  void process_new_sp_instr(THD *thd, sp_instr *i);
213 
215 
226  const char *pop_expr_start_ptr()
227  {
228 #ifndef DBUG_OFF
229  DBUG_ASSERT(m_expr_start_ptr);
230  const char *p= m_expr_start_ptr;
231  m_expr_start_ptr= NULL;
232  return p;
233 #else
234  return m_expr_start_ptr;
235 #endif
236  }
237 
246  void push_expr_start_ptr(const char *expr_start_ptr)
247  {
248  DBUG_ASSERT(!m_expr_start_ptr);
249  m_expr_start_ptr= expr_start_ptr;
250  }
251 
253 
254  const char *get_current_stmt_start_ptr() const
255  { return m_current_stmt_start_ptr; }
256 
257  void set_current_stmt_start_ptr(const char *stmt_start_ptr)
258  { m_current_stmt_start_ptr= stmt_start_ptr; }
259 
261 
262  const char *get_option_start_ptr() const
263  { return m_option_start_ptr; }
264 
265  void set_option_start_ptr(const char *option_start_ptr)
266  { m_option_start_ptr= option_start_ptr; }
267 
269 
270  const char *get_parameter_start_ptr() const
271  { return m_param_start_ptr; }
272 
273  void set_parameter_start_ptr(const char *ptr)
274  { m_param_start_ptr= ptr; }
275 
276  const char *get_parameter_end_ptr() const
277  { return m_param_end_ptr; }
278 
279  void set_parameter_end_ptr(const char *ptr)
280  { m_param_end_ptr= ptr; }
281 
283 
284  const char *get_body_start_ptr() const
285  { return m_body_start_ptr; }
286 
287  void set_body_start_ptr(const char *ptr)
288  { m_body_start_ptr= ptr; }
289 
291 
292  void push_lex(LEX *lex)
293  { m_lex_stack.push_front(lex); }
294 
295  LEX *pop_lex()
296  { return m_lex_stack.pop(); }
297 
299  // Backpatch-list operations.
301 
311 
319  void do_backpatch(sp_label *label, uint dest);
320 
322  // Backpatch operations for supporting CONTINUE handlers.
324 
347  {
348  ++m_cont_level;
349  return false;
350  }
351 
360 
366  void do_cont_backpatch(uint dest);
367 
368 private:
370  const char *m_expr_start_ptr;
371 
373  const char *m_current_stmt_start_ptr;
374 
376  const char *m_option_start_ptr;
377 
382  List<LEX> m_lex_stack;
383 
389  const char *m_param_start_ptr;
390 
396  const char *m_param_end_ptr;
397 
402  const char *m_body_start_ptr;
403 
405  List<Backpatch_info> m_backpatch;
406 
416  List<sp_lex_branch_instr> m_cont_backpatch;
417 
419  uint m_cont_level;
420 
421  /**********************************************************************
422  The following attributes are used to store THD values during parsing
423  of stored program body.
424 
425  @sa start_parsing_sp_body()
426  @sa finish_parsing_sp_body()
427  **********************************************************************/
428 
430  MEM_ROOT *m_saved_memroot;
431 
433  Item *m_saved_free_list;
434 };
435 
437 
442 class sp_head : private Query_arena
443 {
444 public:
446  enum {
447  HAS_RETURN= 1, // For FUNCTIONs only: is set if has RETURN
448  MULTI_RESULTS= 8, // Is set if a procedure with SELECT(s)
449  CONTAINS_DYNAMIC_SQL= 16, // Is set if a procedure with PREPARE/EXECUTE
450  IS_INVOKED= 32, // Is set if this sp_head is being used
451  HAS_SET_AUTOCOMMIT_STMT= 64,// Is set if a procedure with 'set autocommit'
452  /* Is set if a procedure with COMMIT (implicit or explicit) | ROLLBACK */
453  HAS_COMMIT_OR_ROLLBACK= 128,
454  LOG_SLOW_STATEMENTS= 256, // Used by events
455  LOG_GENERAL_LOG= 512, // Used by events
456  HAS_SQLCOM_RESET= 1024,
457  HAS_SQLCOM_FLUSH= 2048,
458 
472  };
473 
474 public:
475  /************************************************************************
476  Public attributes.
477  ************************************************************************/
478 
480  enum_sp_type m_type;
481 
483  uint m_flags;
484 
490 
493 
495  st_sp_chistics *m_chistics;
496 
503  sql_mode_t m_sql_mode;
504 
507 
509 
510  LEX_STRING m_db;
511  LEX_STRING m_name;
512  LEX_STRING m_params;
513  LEX_STRING m_body;
514  LEX_STRING m_body_utf8;
515  LEX_STRING m_defstr;
516  LEX_STRING m_definer_user;
517  LEX_STRING m_definer_host;
518 
519  longlong m_created;
520  longlong m_modified;
521 
524 
532 
535 
544 
550 
559 
560  /*
561  Security context for stored routine which should be run under
562  definer privileges.
563  */
564  Security_context m_security_ctx;
565 
567  // Trigger-specific public attributes.
569 
578 
580  st_trg_chistics m_trg_chistics;
581 
584 
585 public:
586  static void *operator new(size_t size) throw ();
587  static void operator delete(void *ptr, size_t size) throw ();
588 
589  ~sp_head();
590 
592  bool is_invoked() const
593  { return m_flags & IS_INVOKED; }
594 
599  ulong sp_cache_version() const
600  { return m_sp_cache_version; }
601 
604  { m_sp_cache_version= sp_cache_version; }
605 
606  Stored_program_creation_ctx *get_creation_ctx()
607  { return m_creation_ctx; }
608 
609  void set_creation_ctx(Stored_program_creation_ctx *creation_ctx)
610  { m_creation_ctx= creation_ctx->clone(mem_root); }
611 
613  void set_body_start(THD *thd, const char *begin_ptr);
614 
616  void set_body_end(THD *thd);
617 
640  bool execute_trigger(THD *thd,
641  const LEX_STRING *db_name,
642  const LEX_STRING *table_name,
643  GRANT_INFO *grant_info);
644 
674  bool execute_function(THD *thd, Item **args, uint argcount,
675  Field *return_fld);
676 
693  bool execute_procedure(THD *thd, List<Item> *args);
694 
704  bool show_create_routine(THD *thd, enum_sp_type type);
705 
714  bool add_instr(THD *thd, sp_instr *instr);
715 
722  bool modifies_data() const
723  { return m_flags & MODIFIES_DATA; }
724 
725  uint instructions()
726  { return m_instructions.elements(); }
727 
728  sp_instr *last_instruction()
729  { return *m_instructions.back(); }
730 
738  bool reset_lex(THD *thd);
739 
747  bool restore_lex(THD *thd);
748 
749  char *name(uint *lenp = 0) const
750  {
751  if (lenp)
752  *lenp= (uint) m_name.length;
753  return m_name.str;
754  }
755 
756  char *create_string(THD *thd, ulong *lenp);
757 
769  Field *create_result_field(uint field_max_length,
770  const char *field_name,
771  TABLE *table);
772 
773  void set_info(longlong created,
774  longlong modified,
775  st_sp_chistics *chistics,
776  sql_mode_t sql_mode);
777 
778  void set_definer(const char *definer, uint definerlen);
779  void set_definer(const LEX_STRING *user_name, const LEX_STRING *host_name);
780 
796  void optimize();
797 
805  void add_mark_lead(uint ip, List<sp_instr> *leads);
806 
815  {
816  return (i < (uint) m_instructions.elements()) ? m_instructions.at(i) : NULL;
817  }
818 
838  bool add_used_tables_to_table_list(THD *thd,
839  TABLE_LIST ***query_tables_last_ptr,
840  TABLE_LIST *belong_to_view);
841 
847  bool is_not_allowed_in_function(const char *where)
848  {
849  if (m_flags & CONTAINS_DYNAMIC_SQL)
850  my_error(ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG, MYF(0), "Dynamic SQL");
851  else if (m_flags & MULTI_RESULTS)
852  my_error(ER_SP_NO_RETSET, MYF(0), where);
853  else if (m_flags & HAS_SET_AUTOCOMMIT_STMT)
854  my_error(ER_SP_CANT_SET_AUTOCOMMIT, MYF(0));
855  else if (m_flags & HAS_COMMIT_OR_ROLLBACK)
856  my_error(ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG, MYF(0));
857  else if (m_flags & HAS_SQLCOM_RESET)
858  my_error(ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG, MYF(0), "RESET");
859  else if (m_flags & HAS_SQLCOM_FLUSH)
860  my_error(ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG, MYF(0), "FLUSH");
861 
862  return test(m_flags &
863  (CONTAINS_DYNAMIC_SQL|MULTI_RESULTS|HAS_SET_AUTOCOMMIT_STMT|
864  HAS_COMMIT_OR_ROLLBACK|HAS_SQLCOM_RESET|HAS_SQLCOM_FLUSH));
865  }
866 
867 #ifndef DBUG_OFF
868 
872  bool show_routine_code(THD *thd);
873 #endif
874 
875  /*
876  This method is intended for attributes of a routine which need
877  to propagate upwards to the Query_tables_list of the caller (when
878  a property of a sp_head needs to "taint" the calling statement).
879  */
880  void propagate_attributes(Query_tables_list *prelocking_ctx)
881  {
882  /*
883  If this routine needs row-based binary logging, the entire top statement
884  too (we cannot switch from statement-based to row-based only for this
885  routine, as in statement-based the top-statement may be binlogged and
886  the sub-statements not).
887  */
888  DBUG_PRINT("info", ("lex->get_stmt_unsafe_flags(): 0x%x",
889  prelocking_ctx->get_stmt_unsafe_flags()));
890  DBUG_PRINT("info", ("sp_head(0x%p=%s)->unsafe_flags: 0x%x",
891  this, name(), unsafe_flags));
892  prelocking_ctx->set_stmt_unsafe_flags(unsafe_flags);
893  }
894 
899  { return const_cast<sp_pcontext *> (m_root_parsing_ctx); }
900 
906  { return const_cast<MEM_ROOT *> (&main_mem_root); }
907 
912  { return const_cast<MEM_ROOT *> (mem_root); }
913 
924  bool check_show_access(THD *thd, bool *full_access);
925 
926 #ifndef NO_EMBEDDED_ACCESS_CHECKS
927 
941  bool set_security_ctx(THD *thd, Security_context **save_ctx);
942 #endif
943 
944 private:
946  sp_head(enum_sp_type type);
947 
949  MEM_ROOT main_mem_root;
950 
952  sp_pcontext *m_root_parsing_ctx;
953 
955  Dynamic_array<sp_instr *> m_instructions;
956 
966  HASH m_sptabs;
967 
978  ulong m_sp_cache_version;
979 
981  Stored_program_creation_ctx *m_creation_ctx;
982 
984  uint32 unsafe_flags;
985 
986 private:
988  void init_sp_name(THD *thd, sp_name *spname);
989 
1005  bool execute(THD *thd, bool merge_da_on_success);
1006 
1011  void opt_mark();
1012 
1028  bool merge_table_list(THD *thd, TABLE_LIST *table, LEX *lex_for_tmp_check);
1029 
1030  friend sp_head *sp_start_parsing(THD *, enum_sp_type, sp_name *);
1031 
1032  // Prevent use of copy constructor and assignment operator.
1033  sp_head(const sp_head &);
1034  void operator=(sp_head &);
1035 };
1036 
1038 
1043 #endif /* _SP_HEAD_H_ */