My Project
|
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_ */