My Project
sp_head.h
00001 /* Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved.
00002 
00003    This program is free software; you can redistribute it and/or modify
00004    it under the terms of the GNU General Public License as published by
00005    the Free Software Foundation; version 2 of the License.
00006 
00007    This program is distributed in the hope that it will be useful,
00008    but WITHOUT ANY WARRANTY; without even the implied warranty of
00009    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00010    GNU General Public License for more details.
00011 
00012    You should have received a copy of the GNU General Public License
00013    along with this program; if not, write to the Free Software
00014    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA */
00015 
00016 #ifndef _SP_HEAD_H_
00017 #define _SP_HEAD_H_
00018 
00019 /*
00020   It is necessary to include set_var.h instead of item.h because there
00021   are dependencies on include order for set_var.h and item.h. This
00022   will be resolved later.
00023 */
00024 #include "my_global.h"                          /* NO_EMBEDDED_ACCESS_CHECKS */
00025 #include "sql_class.h"                          // THD, set_var.h: THD
00026 #include "set_var.h"                            // Item
00027 #include "sp_pcontext.h"                        // sp_pcontext
00028 
00035 class sp_instr;
00036 class sp_branch_instr;
00037 class sp_lex_branch_instr;
00038 
00040 
00045 class sp_printable
00046 {
00047 public:
00048   virtual void print(String *str) = 0;
00049 
00050   virtual ~sp_printable()
00051   { }
00052 };
00053 
00055 
00061 class Stored_program_creation_ctx : public Default_object_creation_ctx
00062 {
00063 public:
00064   const CHARSET_INFO *get_db_cl()
00065   {
00066     return m_db_cl;
00067   }
00068 
00069 public:
00070   virtual Stored_program_creation_ctx *clone(MEM_ROOT *mem_root) = 0;
00071 
00072 protected:
00073   Stored_program_creation_ctx(THD *thd)
00074     : Default_object_creation_ctx(thd),
00075       m_db_cl(thd->variables.collation_database)
00076   { }
00077 
00078   Stored_program_creation_ctx(const CHARSET_INFO *client_cs,
00079                               const CHARSET_INFO *connection_cl,
00080                               const CHARSET_INFO *db_cl)
00081     : Default_object_creation_ctx(client_cs, connection_cl),
00082       m_db_cl(db_cl)
00083   { }
00084 
00085 protected:
00086   virtual void change_env(THD *thd) const
00087   {
00088     thd->variables.collation_database= m_db_cl;
00089 
00090     Default_object_creation_ctx::change_env(thd);
00091   }
00092 
00093 protected:
00101   const CHARSET_INFO *m_db_cl;
00102 };
00103 
00105 
00106 class sp_name : public Sql_alloc
00107 {
00108 public:
00109 
00110   LEX_STRING m_db;
00111   LEX_STRING m_name;
00112   LEX_STRING m_qname;
00113   bool       m_explicit_name;                   
00115   sp_name(LEX_STRING db, LEX_STRING name, bool use_explicit_name)
00116     : m_db(db), m_name(name), m_explicit_name(use_explicit_name)
00117   {
00118     m_qname.str= 0;
00119     m_qname.length= 0;
00120   }
00121 
00123   sp_name(const MDL_key *key, char *qname_buff);
00124 
00125   // Init. the qualified name from the db and name.
00126   void init_qname(THD *thd);    // thd for memroot allocation
00127 };
00128 
00130 
00135 class sp_parser_data
00136 {
00137 private:
00138   struct Backpatch_info
00139   {
00140     sp_label *label;
00141     sp_branch_instr *instr;
00142   };
00143 
00144 public:
00145   sp_parser_data() :
00146     m_expr_start_ptr(NULL),
00147     m_current_stmt_start_ptr(NULL),
00148     m_option_start_ptr(NULL),
00149     m_param_start_ptr(NULL),
00150     m_param_end_ptr(NULL),
00151     m_body_start_ptr(NULL),
00152     m_cont_level(0),
00153     m_saved_memroot(NULL),
00154     m_saved_free_list(NULL)
00155   { }
00156 
00158 
00169   void start_parsing_sp_body(THD *thd, sp_head *sp);
00170 
00179   void finish_parsing_sp_body(THD *thd)
00180   {
00181     /*
00182       In some cases the parser detects a syntax error and calls
00183       LEX::cleanup_lex_after_parse_error() method only after finishing parsing
00184       the whole routine. In such a situation sp_head::restore_thd_mem_root() will
00185       be called twice - the first time as part of normal parsing process and the
00186       second time by cleanup_lex_after_parse_error().
00187 
00188       To avoid ruining active arena/mem_root state in this case we skip
00189       restoration of old arena/mem_root if this method has been already called for
00190       this routine.
00191     */
00192     if (!is_parsing_sp_body())
00193       return;
00194 
00195     thd->free_items();
00196     thd->mem_root= m_saved_memroot;
00197     thd->free_list= m_saved_free_list;
00198 
00199     m_saved_memroot= NULL;
00200     m_saved_free_list= NULL;
00201   }
00202 
00207   bool is_parsing_sp_body() const
00208   { return m_saved_memroot != NULL; }
00209 
00211 
00212   void process_new_sp_instr(THD *thd, sp_instr *i);
00213 
00215 
00226   const char *pop_expr_start_ptr()
00227   {
00228 #ifndef DBUG_OFF
00229     DBUG_ASSERT(m_expr_start_ptr);
00230     const char *p= m_expr_start_ptr;
00231     m_expr_start_ptr= NULL;
00232     return p;
00233 #else
00234     return m_expr_start_ptr;
00235 #endif
00236   }
00237 
00246   void push_expr_start_ptr(const char *expr_start_ptr)
00247   {
00248     DBUG_ASSERT(!m_expr_start_ptr);
00249     m_expr_start_ptr= expr_start_ptr;
00250   }
00251 
00253 
00254   const char *get_current_stmt_start_ptr() const
00255   { return m_current_stmt_start_ptr; }
00256 
00257   void set_current_stmt_start_ptr(const char *stmt_start_ptr)
00258   { m_current_stmt_start_ptr= stmt_start_ptr; }
00259 
00261 
00262   const char *get_option_start_ptr() const
00263   { return m_option_start_ptr; }
00264 
00265   void set_option_start_ptr(const char *option_start_ptr)
00266   { m_option_start_ptr= option_start_ptr; }
00267 
00269 
00270   const char *get_parameter_start_ptr() const
00271   { return m_param_start_ptr; }
00272 
00273   void set_parameter_start_ptr(const char *ptr)
00274   { m_param_start_ptr= ptr; }
00275 
00276   const char *get_parameter_end_ptr() const
00277   { return m_param_end_ptr; }
00278 
00279   void set_parameter_end_ptr(const char *ptr)
00280   { m_param_end_ptr= ptr; }
00281 
00283 
00284   const char *get_body_start_ptr() const
00285   { return m_body_start_ptr; }
00286 
00287   void set_body_start_ptr(const char *ptr)
00288   { m_body_start_ptr= ptr; }
00289 
00291 
00292   void push_lex(LEX *lex)
00293   { m_lex_stack.push_front(lex); }
00294 
00295   LEX *pop_lex()
00296   { return m_lex_stack.pop(); }
00297 
00299   // Backpatch-list operations.
00301 
00310   bool add_backpatch_entry(sp_branch_instr *i, sp_label *label);
00311 
00319   void do_backpatch(sp_label *label, uint dest);
00320 
00322   // Backpatch operations for supporting CONTINUE handlers.
00324 
00346   bool new_cont_backpatch()
00347   {
00348     ++m_cont_level;
00349     return false;
00350   }
00351 
00359   bool add_cont_backpatch_entry(sp_lex_branch_instr *i);
00360 
00366   void do_cont_backpatch(uint dest);
00367 
00368 private:
00370   const char *m_expr_start_ptr;
00371 
00373   const char *m_current_stmt_start_ptr;
00374 
00376   const char *m_option_start_ptr;
00377 
00382   List<LEX> m_lex_stack;
00383 
00389   const char *m_param_start_ptr;
00390 
00396   const char *m_param_end_ptr;
00397 
00402   const char *m_body_start_ptr;
00403 
00405   List<Backpatch_info> m_backpatch;
00406 
00416   List<sp_lex_branch_instr> m_cont_backpatch;
00417 
00419   uint m_cont_level;
00420 
00421   /**********************************************************************
00422     The following attributes are used to store THD values during parsing
00423     of stored program body.
00424 
00425     @sa start_parsing_sp_body()
00426     @sa finish_parsing_sp_body()
00427   **********************************************************************/
00428 
00430   MEM_ROOT *m_saved_memroot;
00431 
00433   Item *m_saved_free_list;
00434 };
00435 
00437 
00442 class sp_head : private Query_arena
00443 {
00444 public:
00446   enum {
00447     HAS_RETURN= 1,              // For FUNCTIONs only: is set if has RETURN
00448     MULTI_RESULTS= 8,           // Is set if a procedure with SELECT(s)
00449     CONTAINS_DYNAMIC_SQL= 16,   // Is set if a procedure with PREPARE/EXECUTE
00450     IS_INVOKED= 32,             // Is set if this sp_head is being used
00451     HAS_SET_AUTOCOMMIT_STMT= 64,// Is set if a procedure with 'set autocommit'
00452     /* Is set if a procedure with COMMIT (implicit or explicit) | ROLLBACK */
00453     HAS_COMMIT_OR_ROLLBACK= 128,
00454     LOG_SLOW_STATEMENTS= 256,   // Used by events
00455     LOG_GENERAL_LOG= 512,        // Used by events
00456     HAS_SQLCOM_RESET= 1024,
00457     HAS_SQLCOM_FLUSH= 2048,
00458 
00471     MODIFIES_DATA= 4096
00472   };
00473 
00474 public:
00475   /************************************************************************
00476     Public attributes.
00477   ************************************************************************/
00478 
00480   enum_sp_type m_type;
00481 
00483   uint m_flags;
00484 
00489   Create_field m_return_field_def;
00490 
00492   sp_parser_data m_parser_data;
00493 
00495   st_sp_chistics *m_chistics;
00496 
00503   sql_mode_t m_sql_mode;
00504 
00506   LEX_STRING m_qname;
00507 
00508   bool m_explicit_name;         
00509 
00510   LEX_STRING m_db;
00511   LEX_STRING m_name;
00512   LEX_STRING m_params;
00513   LEX_STRING m_body;
00514   LEX_STRING m_body_utf8;
00515   LEX_STRING m_defstr;
00516   LEX_STRING m_definer_user;
00517   LEX_STRING m_definer_host;
00518 
00519   longlong m_created;
00520   longlong m_modified;
00521 
00523   ulong m_recursion_level;
00524 
00531   sp_head *m_next_cached_sp;
00532 
00534   sp_head *m_first_instance;
00535 
00543   sp_head *m_first_free_instance;
00544 
00549   sp_head *m_last_cached_sp;
00550 
00558   HASH m_sroutines;
00559 
00560   /*
00561     Security context for stored routine which should be run under
00562     definer privileges.
00563   */
00564   Security_context m_security_ctx;
00565 
00567   // Trigger-specific public attributes.
00569 
00577   SQL_I_List<SQL_I_List<Item_trigger_field> > m_list_of_trig_fields_item_lists;
00584   SQL_I_List<Item_trigger_field> m_cur_instr_trig_field_items;
00585 
00587   st_trg_chistics m_trg_chistics;
00588 
00590   class Table_triggers_list *m_trg_list;
00591 
00592 public:
00593   static void *operator new(size_t size) throw ();
00594   static void operator delete(void *ptr, size_t size) throw ();
00595 
00596   ~sp_head();
00597 
00599   bool is_invoked() const
00600   { return m_flags & IS_INVOKED; }
00601 
00606   ulong sp_cache_version() const
00607   { return m_sp_cache_version; }
00608 
00610   void set_sp_cache_version(ulong sp_cache_version)
00611   { m_sp_cache_version= sp_cache_version; }
00612 
00613   Stored_program_creation_ctx *get_creation_ctx()
00614   { return m_creation_ctx; }
00615 
00616   void set_creation_ctx(Stored_program_creation_ctx *creation_ctx)
00617   { m_creation_ctx= creation_ctx->clone(mem_root); }
00618 
00620   void set_body_start(THD *thd, const char *begin_ptr);
00621 
00623   void set_body_end(THD *thd);
00624 
00647   bool execute_trigger(THD *thd,
00648                        const LEX_STRING *db_name,
00649                        const LEX_STRING *table_name,
00650                        GRANT_INFO *grant_info);
00651 
00681   bool execute_function(THD *thd, Item **args, uint argcount,
00682                         Field *return_fld);
00683 
00700   bool execute_procedure(THD *thd, List<Item> *args);
00701 
00711   bool show_create_routine(THD *thd, enum_sp_type type);
00712 
00721   bool add_instr(THD *thd, sp_instr *instr);
00722 
00729   bool modifies_data() const
00730   { return m_flags & MODIFIES_DATA; }
00731 
00732   uint instructions()
00733   { return m_instructions.elements(); }
00734 
00735   sp_instr *last_instruction()
00736   { return *m_instructions.back(); }
00737 
00745   bool reset_lex(THD *thd);
00746 
00754   bool restore_lex(THD *thd);
00755 
00756   char *name(uint *lenp = 0) const
00757   {
00758     if (lenp)
00759       *lenp= (uint) m_name.length;
00760     return m_name.str;
00761   }
00762 
00763   char *create_string(THD *thd, ulong *lenp);
00764 
00776   Field *create_result_field(uint field_max_length,
00777                              const char *field_name,
00778                              TABLE *table);
00779 
00780   void set_info(longlong created,
00781                 longlong modified,
00782                 st_sp_chistics *chistics,
00783                 sql_mode_t sql_mode);
00784 
00785   void set_definer(const char *definer, uint definerlen);
00786   void set_definer(const LEX_STRING *user_name, const LEX_STRING *host_name);
00787 
00803   void optimize();
00804 
00812   void add_mark_lead(uint ip, List<sp_instr> *leads);
00813 
00821   sp_instr *get_instr(uint i)
00822   {
00823     return (i < (uint) m_instructions.elements()) ? m_instructions.at(i) : NULL;
00824   }
00825 
00845   bool add_used_tables_to_table_list(THD *thd,
00846                                      TABLE_LIST ***query_tables_last_ptr,
00847                                      TABLE_LIST *belong_to_view);
00848 
00854   bool is_not_allowed_in_function(const char *where)
00855   {
00856     if (m_flags & CONTAINS_DYNAMIC_SQL)
00857       my_error(ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG, MYF(0), "Dynamic SQL");
00858     else if (m_flags & MULTI_RESULTS)
00859       my_error(ER_SP_NO_RETSET, MYF(0), where);
00860     else if (m_flags & HAS_SET_AUTOCOMMIT_STMT)
00861       my_error(ER_SP_CANT_SET_AUTOCOMMIT, MYF(0));
00862     else if (m_flags & HAS_COMMIT_OR_ROLLBACK)
00863       my_error(ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG, MYF(0));
00864     else if (m_flags & HAS_SQLCOM_RESET)
00865       my_error(ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG, MYF(0), "RESET");
00866     else if (m_flags & HAS_SQLCOM_FLUSH)
00867       my_error(ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG, MYF(0), "FLUSH");
00868 
00869     return MY_TEST(m_flags &
00870                    (CONTAINS_DYNAMIC_SQL|MULTI_RESULTS|HAS_SET_AUTOCOMMIT_STMT|
00871                     HAS_COMMIT_OR_ROLLBACK|HAS_SQLCOM_RESET|HAS_SQLCOM_FLUSH));
00872   }
00873 
00874 #ifndef DBUG_OFF
00875 
00879   bool show_routine_code(THD *thd);
00880 #endif
00881 
00882   /*
00883     This method is intended for attributes of a routine which need
00884     to propagate upwards to the Query_tables_list of the caller (when
00885     a property of a sp_head needs to "taint" the calling statement).
00886   */
00887   void propagate_attributes(Query_tables_list *prelocking_ctx)
00888   {
00889     /*
00890       If this routine needs row-based binary logging, the entire top statement
00891       too (we cannot switch from statement-based to row-based only for this
00892       routine, as in statement-based the top-statement may be binlogged and
00893       the sub-statements not).
00894     */
00895     DBUG_PRINT("info", ("lex->get_stmt_unsafe_flags(): 0x%x",
00896                         prelocking_ctx->get_stmt_unsafe_flags()));
00897     DBUG_PRINT("info", ("sp_head(0x%p=%s)->unsafe_flags: 0x%x",
00898                         this, name(), unsafe_flags));
00899     prelocking_ctx->set_stmt_unsafe_flags(unsafe_flags);
00900   }
00901 
00905   sp_pcontext *get_root_parsing_context() const
00906   { return const_cast<sp_pcontext *> (m_root_parsing_ctx); }
00907 
00912   MEM_ROOT *get_persistent_mem_root() const
00913   { return const_cast<MEM_ROOT *> (&main_mem_root); }
00914 
00918   MEM_ROOT *get_current_mem_root() const
00919   { return const_cast<MEM_ROOT *> (mem_root); }
00920 
00931   bool check_show_access(THD *thd, bool *full_access);
00932 
00933 #ifndef NO_EMBEDDED_ACCESS_CHECKS
00934 
00948   bool set_security_ctx(THD *thd, Security_context **save_ctx);
00949 #endif
00950 
00951 private:
00953   sp_head(enum_sp_type type);
00954 
00956   MEM_ROOT main_mem_root;
00957 
00959   sp_pcontext *m_root_parsing_ctx;
00960 
00962   Dynamic_array<sp_instr *> m_instructions;
00963 
00973   HASH m_sptabs;
00974 
00985   ulong m_sp_cache_version;
00986 
00988   Stored_program_creation_ctx *m_creation_ctx;
00989 
00991   uint32 unsafe_flags;
00992 
00993 private:
00995   void init_sp_name(THD *thd, sp_name *spname);
00996 
01012   bool execute(THD *thd, bool merge_da_on_success);
01013 
01018   void opt_mark();
01019 
01035   bool merge_table_list(THD *thd, TABLE_LIST *table, LEX *lex_for_tmp_check);
01036 
01037   friend sp_head *sp_start_parsing(THD *, enum_sp_type, sp_name *);
01038 
01039   // Prevent use of copy constructor and assignment operator.
01040   sp_head(const sp_head &);
01041   void operator=(sp_head &);
01042 };
01043 
01045 
01050 #endif /* _SP_HEAD_H_ */
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines