1 /* -*- C++ -*- */ 2 /* 3 Copyright (c) 2002, 2011, Oracle and/or its affiliates. 4 5 This program is free software; you can redistribute it and/or modify 6 it under the terms of the GNU General Public License as published by 7 the Free Software Foundation; version 2 of the License. 8 9 This program is distributed in the hope that it will be useful, 10 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 GNU General Public License for more details. 13 14 You should have received a copy of the GNU General Public License 15 along with this program; if not, write to the Free Software 16 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA */ 17 18 #ifndef _SP_HEAD_H_ 19 #define _SP_HEAD_H_ 20 21 #ifdef USE_PRAGMA_INTERFACE 22 #pragma interface /* gcc class implementation */ 23 #endif 24 25 /* 26 It is necessary to include set_var.h instead of item.h because there 27 are dependencies on include order for set_var.h and item.h. This 28 will be resolved later. 29 */ 30 #include "sql_class.h" // THD, set_var.h: THD 31 #include "set_var.h" // Item 32 #include "sp_pcontext.h" // sp_pcontext 33 #include <stddef.h> 34 #include "sp.h" 35 36 /** 37 @defgroup Stored_Routines Stored Routines 38 @ingroup Runtime_Environment 39 @{ 40 */ 41 42 Item::Type 43 sp_map_item_type(const Type_handler *handler); 44 45 uint 46 sp_get_flags_for_command(LEX *lex); 47 48 class sp_instr; 49 class sp_instr_opt_meta; 50 class sp_instr_jump_if_not; 51 52 /*************************************************************************/ 53 54 /** 55 Stored_program_creation_ctx -- base class for creation context of stored 56 programs (stored routines, triggers, events). 57 */ 58 59 class Stored_program_creation_ctx :public Default_object_creation_ctx 60 { 61 public: get_db_cl()62 CHARSET_INFO *get_db_cl() 63 { 64 return m_db_cl; 65 } 66 67 public: 68 virtual Stored_program_creation_ctx *clone(MEM_ROOT *mem_root) = 0; 69 70 protected: Stored_program_creation_ctx(THD * thd)71 Stored_program_creation_ctx(THD *thd) 72 : Default_object_creation_ctx(thd), 73 m_db_cl(thd->variables.collation_database) 74 { } 75 Stored_program_creation_ctx(CHARSET_INFO * client_cs,CHARSET_INFO * connection_cl,CHARSET_INFO * db_cl)76 Stored_program_creation_ctx(CHARSET_INFO *client_cs, 77 CHARSET_INFO *connection_cl, 78 CHARSET_INFO *db_cl) 79 : Default_object_creation_ctx(client_cs, connection_cl), 80 m_db_cl(db_cl) 81 { } 82 83 protected: change_env(THD * thd)84 virtual void change_env(THD *thd) const 85 { 86 thd->variables.collation_database= m_db_cl; 87 88 Default_object_creation_ctx::change_env(thd); 89 } 90 91 protected: 92 /** 93 db_cl stores the value of the database collation. Both character set 94 and collation attributes are used. 95 96 Database collation is included into the context because it defines the 97 default collation for stored-program variables. 98 */ 99 CHARSET_INFO *m_db_cl; 100 }; 101 102 /*************************************************************************/ 103 104 class sp_name : public Sql_alloc, 105 public Database_qualified_name 106 { 107 public: 108 bool m_explicit_name; /**< Prepend the db name? */ 109 sp_name(const LEX_CSTRING * db,const LEX_CSTRING * name,bool use_explicit_name)110 sp_name(const LEX_CSTRING *db, const LEX_CSTRING *name, 111 bool use_explicit_name) 112 : Database_qualified_name(db, name), m_explicit_name(use_explicit_name) 113 { 114 if (lower_case_table_names && m_db.length) 115 m_db.length= my_casedn_str(files_charset_info, (char*) m_db.str); 116 } 117 118 /** Create temporary sp_name object from MDL key. Store in qname_buff */ 119 sp_name(const MDL_key *key, char *qname_buff); 120 ~sp_name()121 ~sp_name() 122 {} 123 }; 124 125 126 bool 127 check_routine_name(const LEX_CSTRING *ident); 128 129 class sp_head :private Query_arena, 130 public Database_qualified_name, 131 public Sql_alloc 132 { 133 sp_head(const sp_head &); /**< Prevent use of these */ 134 void operator=(sp_head &); 135 136 protected: 137 MEM_ROOT main_mem_root; 138 public: 139 /** Possible values of m_flags */ 140 enum { 141 HAS_RETURN= 1, // For FUNCTIONs only: is set if has RETURN 142 MULTI_RESULTS= 8, // Is set if a procedure with SELECT(s) 143 CONTAINS_DYNAMIC_SQL= 16, // Is set if a procedure with PREPARE/EXECUTE 144 IS_INVOKED= 32, // Is set if this sp_head is being used 145 HAS_SET_AUTOCOMMIT_STMT= 64,// Is set if a procedure with 'set autocommit' 146 /* Is set if a procedure with COMMIT (implicit or explicit) | ROLLBACK */ 147 HAS_COMMIT_OR_ROLLBACK= 128, 148 LOG_SLOW_STATEMENTS= 256, // Used by events 149 LOG_GENERAL_LOG= 512, // Used by events 150 HAS_SQLCOM_RESET= 1024, 151 HAS_SQLCOM_FLUSH= 2048, 152 153 /** 154 Marks routines that directly (i.e. not by calling other routines) 155 change tables. Note that this flag is set automatically based on 156 type of statements used in the stored routine and is different 157 from routine characteristic provided by user in a form of CONTAINS 158 SQL, READS SQL DATA, MODIFIES SQL DATA clauses. The latter are 159 accepted by parser but pretty much ignored after that. 160 We don't rely on them: 161 a) for compatibility reasons. 162 b) because in CONTAINS SQL case they don't provide enough 163 information anyway. 164 */ 165 MODIFIES_DATA= 4096, 166 /* 167 Marks routines that have column type references: DECLARE a t1.a%TYPE; 168 */ 169 HAS_COLUMN_TYPE_REFS= 8192, 170 /* Set if has FETCH GROUP NEXT ROW instr. Used to ensure that only 171 functions with AGGREGATE keyword use the instr. */ 172 HAS_AGGREGATE_INSTR= 16384 173 }; 174 175 sp_package *m_parent; 176 const Sp_handler *m_handler; 177 uint m_flags; // Boolean attributes of a stored routine 178 179 Column_definition m_return_field_def; /**< This is used for FUNCTIONs only. */ 180 181 const char *m_tmp_query; ///< Temporary pointer to sub query string 182 private: 183 /* 184 Private to guarantee that m_chistics.comment is properly set to: 185 - a string which is alloced on this->mem_root 186 - or (NULL,0) 187 set_chistics() makes sure this. 188 */ 189 Sp_chistics m_chistics; 190 public: 191 sql_mode_t m_sql_mode; ///< For SHOW CREATE and execution 192 bool m_explicit_name; /**< Prepend the db name? */ 193 LEX_CSTRING m_qname; ///< db.name 194 LEX_CSTRING m_params; 195 LEX_CSTRING m_body; 196 LEX_CSTRING m_body_utf8; 197 LEX_CSTRING m_defstr; 198 AUTHID m_definer; 199 chistics()200 const st_sp_chistics &chistics() const { return m_chistics; } comment()201 const LEX_CSTRING &comment() const { return m_chistics.comment; } set_suid(enum_sp_suid_behaviour suid)202 void set_suid(enum_sp_suid_behaviour suid) { m_chistics.suid= suid; } suid()203 enum_sp_suid_behaviour suid() const { return m_chistics.suid; } detistic()204 bool detistic() const { return m_chistics.detistic; } daccess()205 enum_sp_data_access daccess() const { return m_chistics.daccess; } agg_type()206 enum_sp_aggregate_type agg_type() const { return m_chistics.agg_type; } 207 /** 208 Is this routine being executed? 209 */ is_invoked()210 virtual bool is_invoked() const { return m_flags & IS_INVOKED; } 211 212 /** 213 Get the value of the SP cache version, as remembered 214 when the routine was inserted into the cache. 215 */ 216 ulong sp_cache_version() const; 217 218 /** Set the value of the SP cache version. */ set_sp_cache_version(ulong version_arg)219 void set_sp_cache_version(ulong version_arg) const 220 { 221 m_sp_cache_version= version_arg; 222 } 223 224 sp_rcontext *rcontext_create(THD *thd, Field *retval, List<Item> *args); 225 sp_rcontext *rcontext_create(THD *thd, Field *retval, 226 Item **args, uint arg_count); 227 sp_rcontext *rcontext_create(THD *thd, Field *retval, 228 Row_definition_list *list, 229 bool switch_security_ctx); 230 bool eq_routine_spec(const sp_head *) const; 231 private: 232 /** 233 Version of the stored routine cache at the moment when the 234 routine was added to it. Is used only for functions and 235 procedures, not used for triggers or events. When sp_head is 236 created, its version is 0. When it's added to the cache, the 237 version is assigned the global value 'Cversion'. 238 If later on Cversion is incremented, we know that the routine 239 is obsolete and should not be used -- 240 sp_cache_flush_obsolete() will purge it. 241 */ 242 mutable ulong m_sp_cache_version; 243 Stored_program_creation_ctx *m_creation_ctx; 244 /** 245 Boolean combination of (1<<flag), where flag is a member of 246 LEX::enum_binlog_stmt_unsafe. 247 */ 248 uint32 unsafe_flags; 249 250 public: get_creation_ctx()251 inline Stored_program_creation_ctx *get_creation_ctx() 252 { 253 return m_creation_ctx; 254 } 255 set_creation_ctx(Stored_program_creation_ctx * creation_ctx)256 inline void set_creation_ctx(Stored_program_creation_ctx *creation_ctx) 257 { 258 m_creation_ctx= creation_ctx->clone(mem_root); 259 } 260 261 longlong m_created; 262 longlong m_modified; 263 /** Recursion level of the current SP instance. The levels are numbered from 0 */ 264 ulong m_recursion_level; 265 /** 266 A list of diferent recursion level instances for the same procedure. 267 For every recursion level we have a sp_head instance. This instances 268 connected in the list. The list ordered by increasing recursion level 269 (m_recursion_level). 270 */ 271 sp_head *m_next_cached_sp; 272 /** 273 Pointer to the first element of the above list 274 */ 275 sp_head *m_first_instance; 276 /** 277 Pointer to the first free (non-INVOKED) routine in the list of 278 cached instances for this SP. This pointer is set only for the first 279 SP in the list of instences (see above m_first_cached_sp pointer). 280 The pointer equal to 0 if we have no free instances. 281 For non-first instance value of this pointer meanless (point to itself); 282 */ 283 sp_head *m_first_free_instance; 284 /** 285 Pointer to the last element in the list of instances of the SP. 286 For non-first instance value of this pointer meanless (point to itself); 287 */ 288 sp_head *m_last_cached_sp; 289 /** 290 Set containing names of stored routines used by this routine. 291 Note that unlike elements of similar set for statement elements of this 292 set are not linked in one list. Because of this we are able save memory 293 by using for this set same objects that are used in 'sroutines' sets 294 for statements of which this stored routine consists. 295 */ 296 HASH m_sroutines; 297 // Pointers set during parsing 298 const char *m_param_begin; 299 const char *m_param_end; 300 301 private: 302 const char *m_body_begin; 303 304 public: 305 /* 306 Security context for stored routine which should be run under 307 definer privileges. 308 */ 309 Security_context m_security_ctx; 310 311 /** 312 List of all items (Item_trigger_field objects) representing fields in 313 old/new version of row in trigger. We use this list for checking whenever 314 all such fields are valid at trigger creation time and for binding these 315 fields to TABLE object at table open (although for latter pointer to table 316 being opened is probably enough). 317 */ 318 SQL_I_List<Item_trigger_field> m_trg_table_fields; 319 320 protected: 321 sp_head(MEM_ROOT *mem_root, sp_package *parent, const Sp_handler *handler); 322 virtual ~sp_head(); 323 public: 324 static void destroy(sp_head *sp); 325 static sp_head *create(sp_package *parent, const Sp_handler *handler); 326 327 /// Initialize after we have reset mem_root 328 void 329 init(LEX *lex); 330 331 /** Copy sp name from parser. */ 332 void 333 init_sp_name(const sp_name *spname); 334 335 /** Set the body-definition start position. */ 336 void 337 set_body_start(THD *thd, const char *begin_ptr); 338 339 /** Set the statement-definition (body-definition) end position. */ 340 void 341 set_stmt_end(THD *thd); 342 343 344 bool 345 execute_trigger(THD *thd, 346 const LEX_CSTRING *db_name, 347 const LEX_CSTRING *table_name, 348 GRANT_INFO *grant_info); 349 350 bool 351 execute_function(THD *thd, Item **args, uint argcount, Field *return_fld, 352 sp_rcontext **nctx, Query_arena *call_arena); 353 354 bool 355 execute_procedure(THD *thd, List<Item> *args); 356 357 static void 358 show_create_routine_get_fields(THD *thd, const Sp_handler *sph, 359 List<Item> *fields); 360 361 bool 362 show_create_routine(THD *thd, const Sp_handler *sph); 363 get_main_mem_root()364 MEM_ROOT *get_main_mem_root() { return &main_mem_root; } 365 366 int 367 add_instr(sp_instr *instr); 368 369 bool 370 add_instr_jump(THD *thd, sp_pcontext *spcont); 371 372 bool 373 add_instr_jump(THD *thd, sp_pcontext *spcont, uint dest); 374 375 bool 376 add_instr_jump_forward_with_backpatch(THD *thd, sp_pcontext *spcont, 377 sp_label *lab); 378 bool add_instr_jump_forward_with_backpatch(THD * thd,sp_pcontext * spcont)379 add_instr_jump_forward_with_backpatch(THD *thd, sp_pcontext *spcont) 380 { 381 return add_instr_jump_forward_with_backpatch(thd, spcont, 382 spcont->last_label()); 383 } 384 385 bool 386 add_instr_freturn(THD *thd, sp_pcontext *spcont, Item *item, LEX *lex); 387 388 bool 389 add_instr_preturn(THD *thd, sp_pcontext *spcont); 390 391 Item *adjust_assignment_source(THD *thd, Item *val, Item *val2); 392 /** 393 @param thd - the current thd 394 @param spcont - the current parse context 395 @param spv - the SP variable 396 @param val - the value to be assigned to the variable 397 @param lex - the LEX that was used to create "val" 398 @param responsible_to_free_lex - if the generated sp_instr_set should 399 free "lex". 400 @retval true - on error 401 @retval false - on success 402 */ 403 bool set_local_variable(THD *thd, sp_pcontext *spcont, 404 const Sp_rcontext_handler *rh, 405 sp_variable *spv, Item *val, LEX *lex, 406 bool responsible_to_free_lex); 407 bool set_local_variable_row_field(THD *thd, sp_pcontext *spcont, 408 const Sp_rcontext_handler *rh, 409 sp_variable *spv, uint field_idx, 410 Item *val, LEX *lex); 411 bool set_local_variable_row_field_by_name(THD *thd, sp_pcontext *spcont, 412 const Sp_rcontext_handler *rh, 413 sp_variable *spv, 414 const LEX_CSTRING *field_name, 415 Item *val, LEX *lex); 416 bool check_package_routine_end_name(const LEX_CSTRING &end_name) const; 417 private: 418 /** 419 Generate a code to set a single cursor parameter variable. 420 @param thd - current thd, for mem_root allocations. 421 @param param_spcont - the context of the parameter block 422 @param idx - the index of the parameter 423 @param prm - the actual parameter (contains information about 424 the assignment source expression Item, 425 its free list, and its LEX) 426 */ add_set_cursor_param_variable(THD * thd,sp_pcontext * param_spcont,uint idx,sp_assignment_lex * prm)427 bool add_set_cursor_param_variable(THD *thd, 428 sp_pcontext *param_spcont, uint idx, 429 sp_assignment_lex *prm) 430 { 431 DBUG_ASSERT(idx < param_spcont->context_var_count()); 432 sp_variable *spvar= param_spcont->get_context_variable(idx); 433 /* 434 add_instr() gets free_list from m_thd->free_list. 435 Initialize it before the set_local_variable() call. 436 */ 437 DBUG_ASSERT(m_thd->free_list == NULL); 438 m_thd->free_list= prm->get_free_list(); 439 if (set_local_variable(thd, param_spcont, 440 &sp_rcontext_handler_local, 441 spvar, prm->get_item(), prm, true)) 442 return true; 443 /* 444 Safety: 445 The item and its free_list are now fully owned by the sp_instr_set 446 instance, created by set_local_variable(). The sp_instr_set instance 447 is now responsible for freeing the item and the free_list. 448 Reset the "item" and the "free_list" members of "prm", 449 to avoid double pointers to the same objects from "prm" and 450 from the sp_instr_set instance. 451 */ 452 prm->set_item_and_free_list(NULL, NULL); 453 return false; 454 } 455 456 /** 457 Generate a code to set all cursor parameter variables. 458 This method is called only when parameters exists, 459 and the number of formal parameters matches the number of actual 460 parameters. See also comments to add_open_cursor(). 461 */ add_set_cursor_param_variables(THD * thd,sp_pcontext * param_spcont,List<sp_assignment_lex> * parameters)462 bool add_set_cursor_param_variables(THD *thd, sp_pcontext *param_spcont, 463 List<sp_assignment_lex> *parameters) 464 { 465 DBUG_ASSERT(param_spcont->context_var_count() == parameters->elements); 466 sp_assignment_lex *prm; 467 List_iterator<sp_assignment_lex> li(*parameters); 468 for (uint idx= 0; (prm= li++); idx++) 469 { 470 if (add_set_cursor_param_variable(thd, param_spcont, idx, prm)) 471 return true; 472 } 473 return false; 474 } 475 476 /** 477 Generate a code to set all cursor parameter variables for a FOR LOOP, e.g.: 478 FOR index IN cursor(1,2,3) 479 @param 480 */ 481 bool add_set_for_loop_cursor_param_variables(THD *thd, 482 sp_pcontext *param_spcont, 483 sp_assignment_lex *param_lex, 484 Item_args *parameters); 485 486 public: 487 /** 488 Generate a code for an "OPEN cursor" statement. 489 @param thd - current thd, for mem_root allocations 490 @param spcont - the context of the cursor 491 @param offset - the offset of the cursor 492 @param param_spcont - the context of the cursor parameter block 493 @param parameters - the list of the OPEN actual parameters 494 495 The caller must make sure that the number of local variables 496 in "param_spcont" (formal parameters) matches the number of list elements 497 in "parameters" (actual parameters). 498 NULL in either of them means 0 parameters. 499 */ 500 bool add_open_cursor(THD *thd, sp_pcontext *spcont, 501 uint offset, 502 sp_pcontext *param_spcont, 503 List<sp_assignment_lex> *parameters); 504 505 /** 506 Generate an initiation code for a CURSOR FOR LOOP, e.g.: 507 FOR index IN cursor -- cursor without parameters 508 FOR index IN cursor(1,2,3) -- cursor with parameters 509 510 The code generated by this method does the following during SP run-time: 511 - Sets all cursor parameter vartiables from "parameters" 512 - Initializes the index ROW-type variable from the cursor 513 (the structure is copied from the cursor to the index variable) 514 - The cursor gets opened 515 - The first records is fetched from the cursor to the variable "index". 516 517 @param thd - the current thread (for mem_root and error reporting) 518 @param spcont - the current parse context 519 @param index - the loop "index" ROW-type variable 520 @param pcursor - the cursor 521 @param coffset - the cursor offset 522 @param param_lex - the LEX that owns Items in "parameters" 523 @param parameters - the cursor parameters Item array 524 @retval true - on error (EOM) 525 @retval false - on success 526 */ 527 bool add_for_loop_open_cursor(THD *thd, sp_pcontext *spcont, 528 sp_variable *index, 529 const sp_pcursor *pcursor, uint coffset, 530 sp_assignment_lex *param_lex, 531 Item_args *parameters); 532 /** 533 Returns true if any substatement in the routine directly 534 (not through another routine) modifies data/changes table. 535 536 @sa Comment for MODIFIES_DATA flag. 537 */ modifies_data()538 bool modifies_data() const 539 { return m_flags & MODIFIES_DATA; } 540 instructions()541 inline uint instructions() 542 { return m_instr.elements; } 543 544 inline sp_instr * last_instruction()545 last_instruction() 546 { 547 sp_instr *i; 548 549 get_dynamic(&m_instr, (uchar*)&i, m_instr.elements-1); 550 return i; 551 } 552 553 bool replace_instr_to_nop(THD *thd, uint ip); 554 555 /* 556 Resets lex in 'thd' and keeps a copy of the old one. 557 558 @todo Conflicting comment in sp_head.cc 559 */ 560 bool 561 reset_lex(THD *thd); 562 563 bool 564 reset_lex(THD *thd, sp_lex_local *sublex); 565 566 /** 567 Merge two LEX instances. 568 @param oldlex - the upper level LEX we're going to restore to. 569 @param sublex - the local lex that have just parsed some substatement. 570 @returns - false on success, true on error (e.g. failed to 571 merge the routine list or the table list). 572 This method is shared by: 573 - restore_lex(), when the old LEX is popped by sp_head::m_lex.pop() 574 - THD::restore_from_local_lex_to_old_lex(), when the old LEX 575 is stored in the caller's local variable. 576 */ 577 bool 578 merge_lex(THD *thd, LEX *oldlex, LEX *sublex); 579 580 /** 581 Restores lex in 'thd' from our copy, but keeps some status from the 582 one in 'thd', like ptr, tables, fields, etc. 583 584 @todo Conflicting comment in sp_head.cc 585 */ 586 bool restore_lex(THD * thd)587 restore_lex(THD *thd) 588 { 589 DBUG_ENTER("sp_head::restore_lex"); 590 LEX *oldlex= (LEX *) m_lex.pop(); 591 if (!oldlex) 592 DBUG_RETURN(false); // Nothing to restore 593 LEX *sublex= thd->lex; 594 if (thd->restore_from_local_lex_to_old_lex(oldlex))// This restores thd->lex 595 DBUG_RETURN(true); 596 if (!sublex->sp_lex_in_use) 597 { 598 sublex->sphead= NULL; 599 lex_end(sublex); 600 delete sublex; 601 } 602 DBUG_RETURN(false); 603 } 604 605 /// Put the instruction on the backpatch list, associated with the label. 606 int 607 push_backpatch(THD *thd, sp_instr *, sp_label *); 608 int 609 push_backpatch_goto(THD *thd, sp_pcontext *ctx, sp_label *lab); 610 611 /// Update all instruction with this label in the backpatch list to 612 /// the current position. 613 void 614 backpatch(sp_label *); 615 void 616 backpatch_goto(THD *thd, sp_label *, sp_label *); 617 618 /// Check for unresolved goto label 619 bool 620 check_unresolved_goto(); 621 622 /// Start a new cont. backpatch level. If 'i' is NULL, the level is just incr. 623 int 624 new_cont_backpatch(sp_instr_opt_meta *i); 625 626 /// Add an instruction to the current level 627 int 628 add_cont_backpatch(sp_instr_opt_meta *i); 629 630 /// Backpatch (and pop) the current level to the current position. 631 void 632 do_cont_backpatch(); 633 634 /// Add cpush instructions for all cursors declared in the current frame 635 bool sp_add_instr_cpush_for_cursors(THD *thd, sp_pcontext *pcontext); 636 name()637 const LEX_CSTRING *name() const 638 { return &m_name; } 639 640 char *create_string(THD *thd, ulong *lenp); 641 642 Field *create_result_field(uint field_max_length, const LEX_CSTRING *field_name, 643 TABLE *table) const; 644 645 646 /** 647 Check and prepare an instance of Column_definition for field creation 648 (fill all necessary attributes), for variables, parameters and 649 function return values. 650 651 @param[in] thd Thread handle 652 @param[in] lex Yacc parsing context 653 @param[out] field_def An instance of create_field to be filled 654 655 @retval false on success 656 @retval true on error 657 */ fill_field_definition(THD * thd,Column_definition * field_def)658 bool fill_field_definition(THD *thd, Column_definition *field_def) 659 { 660 const Type_handler *h= field_def->type_handler(); 661 return h->Column_definition_fix_attributes(field_def) || 662 field_def->sp_prepare_create_field(thd, mem_root); 663 } row_fill_field_definitions(THD * thd,Row_definition_list * row)664 bool row_fill_field_definitions(THD *thd, Row_definition_list *row) 665 { 666 /* 667 Prepare all row fields. This will (among other things) 668 - convert VARCHAR lengths from character length to octet length 669 - calculate interval lengths for SET and ENUM 670 */ 671 List_iterator<Spvar_definition> it(*row); 672 for (Spvar_definition *def= it++; def; def= it++) 673 { 674 if (fill_spvar_definition(thd, def)) 675 return true; 676 } 677 return false; 678 } 679 /** 680 Check and prepare a Column_definition for a variable or a parameter. 681 */ fill_spvar_definition(THD * thd,Column_definition * def)682 bool fill_spvar_definition(THD *thd, Column_definition *def) 683 { 684 if (fill_field_definition(thd, def)) 685 return true; 686 def->pack_flag|= FIELDFLAG_MAYBE_NULL; 687 return false; 688 } fill_spvar_definition(THD * thd,Column_definition * def,LEX_CSTRING * name)689 bool fill_spvar_definition(THD *thd, Column_definition *def, 690 LEX_CSTRING *name) 691 { 692 def->field_name= *name; 693 return fill_spvar_definition(thd, def); 694 } 695 696 private: 697 /** 698 Set a column type reference for a parameter definition 699 */ fill_spvar_using_type_reference(sp_variable * spvar,Qualified_column_ident * ref)700 void fill_spvar_using_type_reference(sp_variable *spvar, 701 Qualified_column_ident *ref) 702 { 703 spvar->field_def.set_column_type_ref(ref); 704 spvar->field_def.field_name= spvar->name; 705 m_flags|= sp_head::HAS_COLUMN_TYPE_REFS; 706 } 707 fill_spvar_using_table_rowtype_reference(THD * thd,sp_variable * spvar,Table_ident * ref)708 void fill_spvar_using_table_rowtype_reference(THD *thd, 709 sp_variable *spvar, 710 Table_ident *ref) 711 { 712 spvar->field_def.set_table_rowtype_ref(ref); 713 spvar->field_def.field_name= spvar->name; 714 fill_spvar_definition(thd, &spvar->field_def); 715 m_flags|= sp_head::HAS_COLUMN_TYPE_REFS; 716 } 717 718 public: 719 bool spvar_fill_row(THD *thd, sp_variable *spvar, Row_definition_list *def); 720 bool spvar_fill_type_reference(THD *thd, sp_variable *spvar, 721 const LEX_CSTRING &table, 722 const LEX_CSTRING &column); 723 bool spvar_fill_type_reference(THD *thd, sp_variable *spvar, 724 const LEX_CSTRING &db, 725 const LEX_CSTRING &table, 726 const LEX_CSTRING &column); 727 bool spvar_fill_table_rowtype_reference(THD *thd, sp_variable *spvar, 728 const LEX_CSTRING &table); 729 bool spvar_fill_table_rowtype_reference(THD *thd, sp_variable *spvar, 730 const LEX_CSTRING &db, 731 const LEX_CSTRING &table); 732 733 void set_chistics(const st_sp_chistics &chistics); set_chistics_agg_type(enum enum_sp_aggregate_type type)734 inline void set_chistics_agg_type(enum enum_sp_aggregate_type type) 735 { 736 m_chistics.agg_type= type; 737 } 738 void set_info(longlong created, longlong modified, 739 const st_sp_chistics &chistics, sql_mode_t sql_mode); 740 set_definer(const char * definer,size_t definerlen)741 void set_definer(const char *definer, size_t definerlen) 742 { 743 AUTHID tmp; 744 tmp.parse(definer, definerlen); 745 m_definer.copy(mem_root, &tmp.user, &tmp.host); 746 } set_definer(const LEX_CSTRING * user_name,const LEX_CSTRING * host_name)747 void set_definer(const LEX_CSTRING *user_name, const LEX_CSTRING *host_name) 748 { 749 m_definer.copy(mem_root, user_name, host_name); 750 } 751 752 void reset_thd_mem_root(THD *thd); 753 754 void restore_thd_mem_root(THD *thd); 755 756 /** 757 Optimize the code. 758 */ 759 void optimize(); 760 761 /** 762 Helper used during flow analysis during code optimization. 763 See the implementation of <code>opt_mark()</code>. 764 @param ip the instruction to add to the leads list 765 @param leads the list of remaining paths to explore in the graph that 766 represents the code, during flow analysis. 767 */ 768 void add_mark_lead(uint ip, List<sp_instr> *leads); 769 770 inline sp_instr * get_instr(uint i)771 get_instr(uint i) 772 { 773 sp_instr *ip; 774 775 if (i < m_instr.elements) 776 get_dynamic(&m_instr, (uchar*)&ip, i); 777 else 778 ip= NULL; 779 return ip; 780 } 781 782 /* Add tables used by routine to the table list. */ 783 bool add_used_tables_to_table_list(THD *thd, 784 TABLE_LIST ***query_tables_last_ptr, 785 TABLE_LIST *belong_to_view); 786 787 /** 788 Check if this stored routine contains statements disallowed 789 in a stored function or trigger, and set an appropriate error message 790 if this is the case. 791 */ is_not_allowed_in_function(const char * where)792 bool is_not_allowed_in_function(const char *where) 793 { 794 if (m_flags & CONTAINS_DYNAMIC_SQL) 795 my_error(ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG, MYF(0), "Dynamic SQL"); 796 else if (m_flags & MULTI_RESULTS) 797 my_error(ER_SP_NO_RETSET, MYF(0), where); 798 else if (m_flags & HAS_SET_AUTOCOMMIT_STMT) 799 my_error(ER_SP_CANT_SET_AUTOCOMMIT, MYF(0)); 800 else if (m_flags & HAS_COMMIT_OR_ROLLBACK) 801 my_error(ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG, MYF(0)); 802 else if (m_flags & HAS_SQLCOM_RESET) 803 my_error(ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG, MYF(0), "RESET"); 804 else if (m_flags & HAS_SQLCOM_FLUSH) 805 my_error(ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG, MYF(0), "FLUSH"); 806 807 return MY_TEST(m_flags & 808 (CONTAINS_DYNAMIC_SQL | MULTI_RESULTS | 809 HAS_SET_AUTOCOMMIT_STMT | HAS_COMMIT_OR_ROLLBACK | 810 HAS_SQLCOM_RESET | HAS_SQLCOM_FLUSH)); 811 } 812 813 #ifndef DBUG_OFF 814 int show_routine_code(THD *thd); 815 #endif 816 817 /* 818 This method is intended for attributes of a routine which need 819 to propagate upwards to the Query_tables_list of the caller (when 820 a property of a sp_head needs to "taint" the calling statement). 821 */ propagate_attributes(Query_tables_list * prelocking_ctx)822 void propagate_attributes(Query_tables_list *prelocking_ctx) 823 { 824 DBUG_ENTER("sp_head::propagate_attributes"); 825 /* 826 If this routine needs row-based binary logging, the entire top statement 827 too (we cannot switch from statement-based to row-based only for this 828 routine, as in statement-based the top-statement may be binlogged and 829 the substatements not). 830 */ 831 DBUG_PRINT("info", ("lex->get_stmt_unsafe_flags(): 0x%x", 832 prelocking_ctx->get_stmt_unsafe_flags())); 833 DBUG_PRINT("info", ("sp_head(%p=%s)->unsafe_flags: 0x%x", 834 this, name()->str, unsafe_flags)); 835 prelocking_ctx->set_stmt_unsafe_flags(unsafe_flags); 836 DBUG_VOID_RETURN; 837 } 838 get_parse_context()839 sp_pcontext *get_parse_context() { return m_pcont; } 840 841 /* 842 Check EXECUTE access: 843 - in case of a standalone rotuine, for the routine itself 844 - in case of a package routine, for the owner package body 845 */ 846 bool check_execute_access(THD *thd) const; 847 get_package()848 virtual sp_package *get_package() 849 { 850 return NULL; 851 } 852 853 protected: 854 855 MEM_ROOT *m_thd_root; ///< Temp. store for thd's mem_root 856 THD *m_thd; ///< Set if we have reset mem_root 857 858 sp_pcontext *m_pcont; ///< Parse context 859 List<LEX> m_lex; ///< Temp. store for the other lex 860 DYNAMIC_ARRAY m_instr; ///< The "instructions" 861 862 enum backpatch_instr_type { GOTO, CPOP, HPOP }; 863 typedef struct 864 { 865 sp_label *lab; 866 sp_instr *instr; 867 backpatch_instr_type instr_type; 868 } bp_t; 869 List<bp_t> m_backpatch; ///< Instructions needing backpatching 870 List<bp_t> m_backpatch_goto; // Instructions needing backpatching (for goto) 871 872 /** 873 We need a special list for backpatching of instructions with a continue 874 destination (in the case of a continue handler catching an error in 875 the test), since it would otherwise interfere with the normal backpatch 876 mechanism - e.g. jump_if_not instructions have two different destinations 877 which are to be patched differently. 878 Since these occur in a more restricted way (always the same "level" in 879 the code), we don't need the label. 880 */ 881 List<sp_instr_opt_meta> m_cont_backpatch; 882 uint m_cont_level; // The current cont. backpatch level 883 884 /** 885 Multi-set representing optimized list of tables to be locked by this 886 routine. Does not include tables which are used by invoked routines. 887 888 @note 889 For prelocking-free SPs this multiset is constructed too. 890 We do so because the same instance of sp_head may be called both 891 in prelocked mode and in non-prelocked mode. 892 */ 893 HASH m_sptabs; 894 895 bool 896 execute(THD *thd, bool merge_da_on_success); 897 898 /** 899 Perform a forward flow analysis in the generated code. 900 Mark reachable instructions, for the optimizer. 901 */ 902 void opt_mark(); 903 904 /** 905 Merge the list of tables used by query into the multi-set of tables used 906 by routine. 907 */ 908 bool merge_table_list(THD *thd, TABLE_LIST *table, LEX *lex_for_tmp_check); 909 910 /// Put the instruction on the a backpatch list, associated with the label. 911 int 912 push_backpatch(THD *thd, sp_instr *, sp_label *, List<bp_t> *list, 913 backpatch_instr_type itype); 914 915 }; // class sp_head : public Sql_alloc 916 917 918 class sp_package: public sp_head 919 { 920 bool validate_public_routines(THD *thd, sp_package *spec); 921 bool validate_private_routines(THD *thd); 922 public: 923 class LexList: public List<LEX> 924 { 925 public: LexList()926 LexList() { elements= 0; } 927 // Find a package routine by a non qualified name 928 LEX *find(const LEX_CSTRING &name, stored_procedure_type type); 929 // Find a package routine by a package-qualified name, e.g. 'pkg.proc' 930 LEX *find_qualified(const LEX_CSTRING &name, stored_procedure_type type); 931 // Check if a routine with the given qualified name already exists check_dup_qualified(const LEX_CSTRING & name,const Sp_handler * sph)932 bool check_dup_qualified(const LEX_CSTRING &name, const Sp_handler *sph) 933 { 934 if (!find_qualified(name, sph->type())) 935 return false; 936 my_error(ER_SP_ALREADY_EXISTS, MYF(0), sph->type_str(), name.str); 937 return true; 938 } check_dup_qualified(const sp_head * sp)939 bool check_dup_qualified(const sp_head *sp) 940 { 941 return check_dup_qualified(sp->m_name, sp->m_handler); 942 } 943 void cleanup(); 944 }; 945 /* 946 The LEX for a new package subroutine is initially assigned to 947 m_current_routine. After scanning parameters, return type and chistics, 948 the parser detects if we have a declaration or a definition, e.g.: 949 PROCEDURE p1(a INT); 950 vs 951 PROCEDURE p1(a INT) AS BEGIN NULL; END; 952 (i.e. either semicolon or the "AS" keyword) 953 m_current_routine is then added either to m_routine_implementations, 954 or m_routine_declarations, and then m_current_routine is set to NULL. 955 */ 956 LEX *m_current_routine; 957 LexList m_routine_implementations; 958 LexList m_routine_declarations; 959 960 LEX *m_top_level_lex; 961 sp_rcontext *m_rcontext; 962 uint m_invoked_subroutine_count; 963 bool m_is_instantiated; 964 bool m_is_cloning_routine; 965 966 private: 967 sp_package(MEM_ROOT *mem_root, 968 LEX *top_level_lex, 969 const sp_name *name, 970 const Sp_handler *sph); 971 ~sp_package(); 972 public: 973 static sp_package *create(LEX *top_level_lex, const sp_name *name, 974 const Sp_handler *sph); 975 add_routine_declaration(LEX * lex)976 bool add_routine_declaration(LEX *lex) 977 { 978 return m_routine_declarations.check_dup_qualified(lex->sphead) || 979 m_routine_declarations.push_back(lex, &main_mem_root); 980 } add_routine_implementation(LEX * lex)981 bool add_routine_implementation(LEX *lex) 982 { 983 return m_routine_implementations.check_dup_qualified(lex->sphead) || 984 m_routine_implementations.push_back(lex, &main_mem_root); 985 } get_package()986 sp_package *get_package() { return this; } is_invoked()987 bool is_invoked() const 988 { 989 /* 990 Cannot flush a package out of the SP cache when: 991 - its initialization block is running 992 - one of its subroutine is running 993 */ 994 return sp_head::is_invoked() || m_invoked_subroutine_count > 0; 995 } find_package_variable(const LEX_CSTRING * name)996 sp_variable *find_package_variable(const LEX_CSTRING *name) const 997 { 998 /* 999 sp_head::m_pcont is a special level for routine parameters. 1000 Variables declared inside CREATE PACKAGE BODY reside in m_children.at(0). 1001 */ 1002 sp_pcontext *ctx= m_pcont->child_context(0); 1003 return ctx ? ctx->find_variable(name, true) : NULL; 1004 } 1005 bool validate_after_parser(THD *thd); 1006 bool instantiate_if_needed(THD *thd); 1007 }; 1008 1009 1010 class sp_lex_cursor: public sp_lex_local, public Query_arena 1011 { 1012 public: sp_lex_cursor(THD * thd,const LEX * oldlex,MEM_ROOT * mem_root_arg)1013 sp_lex_cursor(THD *thd, const LEX *oldlex, MEM_ROOT *mem_root_arg) 1014 :sp_lex_local(thd, oldlex), 1015 Query_arena(mem_root_arg, STMT_INITIALIZED_FOR_SP) 1016 { } sp_lex_cursor(THD * thd,const LEX * oldlex)1017 sp_lex_cursor(THD *thd, const LEX *oldlex) 1018 :sp_lex_local(thd, oldlex), 1019 Query_arena(thd->lex->sphead->get_main_mem_root(), STMT_INITIALIZED_FOR_SP) 1020 { } ~sp_lex_cursor()1021 ~sp_lex_cursor() { free_items(); } cleanup_stmt()1022 void cleanup_stmt() { } query_arena()1023 Query_arena *query_arena() { return this; } validate()1024 bool validate() 1025 { 1026 DBUG_ASSERT(sql_command == SQLCOM_SELECT); 1027 if (result) 1028 { 1029 my_error(ER_SP_BAD_CURSOR_SELECT, MYF(0)); 1030 return true; 1031 } 1032 return false; 1033 } stmt_finalize(THD * thd)1034 bool stmt_finalize(THD *thd) 1035 { 1036 if (validate()) 1037 return true; 1038 sp_lex_in_use= true; 1039 free_list= thd->free_list; 1040 thd->free_list= NULL; 1041 return false; 1042 } 1043 }; 1044 1045 1046 // 1047 // "Instructions"... 1048 // 1049 1050 class sp_instr :public Query_arena, public Sql_alloc 1051 { 1052 sp_instr(const sp_instr &); /**< Prevent use of these */ 1053 void operator=(sp_instr &); 1054 1055 public: 1056 1057 uint marked; 1058 uint m_ip; ///< My index 1059 sp_pcontext *m_ctx; ///< My parse context 1060 uint m_lineno; 1061 1062 /// Should give each a name or type code for debugging purposes? sp_instr(uint ip,sp_pcontext * ctx)1063 sp_instr(uint ip, sp_pcontext *ctx) 1064 :Query_arena(0, STMT_INITIALIZED_FOR_SP), marked(0), m_ip(ip), m_ctx(ctx) 1065 {} 1066 ~sp_instr()1067 virtual ~sp_instr() 1068 { free_items(); } 1069 1070 1071 /** 1072 Execute this instruction 1073 1074 1075 @param thd Thread handle 1076 @param[out] nextp index of the next instruction to execute. (For most 1077 instructions this will be the instruction following this 1078 one). Note that this parameter is undefined in case of 1079 errors, use get_cont_dest() to find the continuation 1080 instruction for CONTINUE error handlers. 1081 1082 @retval 0 on success, 1083 @retval other if some error occurred 1084 */ 1085 1086 virtual int execute(THD *thd, uint *nextp) = 0; 1087 1088 /** 1089 Execute <code>open_and_lock_tables()</code> for this statement. 1090 Open and lock the tables used by this statement, as a pre-requisite 1091 to execute the core logic of this instruction with 1092 <code>exec_core()</code>. 1093 @param thd the current thread 1094 @param tables the list of tables to open and lock 1095 @return zero on success, non zero on failure. 1096 */ 1097 int exec_open_and_lock_tables(THD *thd, TABLE_LIST *tables); 1098 1099 /** 1100 Get the continuation destination of this instruction. 1101 @return the continuation destination 1102 */ 1103 virtual uint get_cont_dest() const; 1104 1105 /* 1106 Execute core function of instruction after all preparations (e.g. 1107 setting of proper LEX, saving part of the thread context have been 1108 done). 1109 1110 Should be implemented for instructions using expressions or whole 1111 statements (thus having to have own LEX). Used in concert with 1112 sp_lex_keeper class and its descendants (there are none currently). 1113 */ 1114 virtual int exec_core(THD *thd, uint *nextp); 1115 1116 virtual void print(String *str) = 0; 1117 backpatch(uint dest,sp_pcontext * dst_ctx)1118 virtual void backpatch(uint dest, sp_pcontext *dst_ctx) 1119 {} 1120 1121 /** 1122 Mark this instruction as reachable during optimization and return the 1123 index to the next instruction. Jump instruction will add their 1124 destination to the leads list. 1125 */ opt_mark(sp_head * sp,List<sp_instr> * leads)1126 virtual uint opt_mark(sp_head *sp, List<sp_instr> *leads) 1127 { 1128 marked= 1; 1129 return m_ip+1; 1130 } 1131 1132 /** 1133 Short-cut jumps to jumps during optimization. This is used by the 1134 jump instructions' opt_mark() methods. 'start' is the starting point, 1135 used to prevent the mark sweep from looping for ever. Return the 1136 end destination. 1137 */ opt_shortcut_jump(sp_head * sp,sp_instr * start)1138 virtual uint opt_shortcut_jump(sp_head *sp, sp_instr *start) 1139 { 1140 return m_ip; 1141 } 1142 1143 /** 1144 Inform the instruction that it has been moved during optimization. 1145 Most instructions will simply update its index, but jump instructions 1146 must also take care of their destination pointers. Forward jumps get 1147 pushed to the backpatch list 'ibp'. 1148 */ opt_move(uint dst,List<sp_instr> * ibp)1149 virtual void opt_move(uint dst, List<sp_instr> *ibp) 1150 { 1151 m_ip= dst; 1152 } 1153 1154 }; // class sp_instr : public Sql_alloc 1155 1156 1157 /** 1158 Auxilary class to which instructions delegate responsibility 1159 for handling LEX and preparations before executing statement 1160 or calculating complex expression. 1161 1162 Exist mainly to avoid having double hierarchy between instruction 1163 classes. 1164 1165 @todo 1166 Add ability to not store LEX and do any preparations if 1167 expression used is simple. 1168 */ 1169 1170 class sp_lex_keeper 1171 { 1172 /** Prevent use of these */ 1173 sp_lex_keeper(const sp_lex_keeper &); 1174 void operator=(sp_lex_keeper &); 1175 public: 1176 sp_lex_keeper(LEX * lex,bool lex_resp)1177 sp_lex_keeper(LEX *lex, bool lex_resp) 1178 : m_lex(lex), m_lex_resp(lex_resp), 1179 lex_query_tables_own_last(NULL) 1180 { 1181 lex->sp_lex_in_use= TRUE; 1182 } ~sp_lex_keeper()1183 virtual ~sp_lex_keeper() 1184 { 1185 if (m_lex_resp) 1186 { 1187 /* Prevent endless recursion. */ 1188 m_lex->sphead= NULL; 1189 lex_end(m_lex); 1190 delete m_lex; 1191 } 1192 } 1193 1194 /** 1195 Prepare execution of instruction using LEX, if requested check whenever 1196 we have read access to tables used and open/lock them, call instruction's 1197 exec_core() method, perform cleanup afterwards. 1198 1199 @todo Conflicting comment in sp_head.cc 1200 */ 1201 int reset_lex_and_exec_core(THD *thd, uint *nextp, bool open_tables, 1202 sp_instr* instr); 1203 1204 int cursor_reset_lex_and_exec_core(THD *thd, uint *nextp, bool open_tables, 1205 sp_instr *instr); 1206 sql_command()1207 inline uint sql_command() const 1208 { 1209 return (uint)m_lex->sql_command; 1210 } 1211 disable_query_cache()1212 void disable_query_cache() 1213 { 1214 m_lex->safe_to_cache_query= 0; 1215 } 1216 1217 private: 1218 1219 LEX *m_lex; 1220 /** 1221 Indicates whenever this sp_lex_keeper instance responsible 1222 for LEX deletion. 1223 */ 1224 bool m_lex_resp; 1225 1226 /* 1227 Support for being able to execute this statement in two modes: 1228 a) inside prelocked mode set by the calling procedure or its ancestor. 1229 b) outside of prelocked mode, when this statement enters/leaves 1230 prelocked mode itself. 1231 */ 1232 1233 /** 1234 List of additional tables this statement needs to lock when it 1235 enters/leaves prelocked mode on its own. 1236 */ 1237 TABLE_LIST *prelocking_tables; 1238 1239 /** 1240 The value m_lex->query_tables_own_last should be set to this when the 1241 statement enters/leaves prelocked mode on its own. 1242 */ 1243 TABLE_LIST **lex_query_tables_own_last; 1244 }; 1245 1246 1247 /** 1248 Call out to some prepared SQL statement. 1249 */ 1250 class sp_instr_stmt : public sp_instr 1251 { 1252 sp_instr_stmt(const sp_instr_stmt &); /**< Prevent use of these */ 1253 void operator=(sp_instr_stmt &); 1254 1255 public: 1256 1257 LEX_STRING m_query; ///< For thd->query 1258 sp_instr_stmt(uint ip,sp_pcontext * ctx,LEX * lex)1259 sp_instr_stmt(uint ip, sp_pcontext *ctx, LEX *lex) 1260 : sp_instr(ip, ctx), m_lex_keeper(lex, TRUE) 1261 { 1262 m_query.str= 0; 1263 m_query.length= 0; 1264 } 1265 ~sp_instr_stmt()1266 virtual ~sp_instr_stmt() 1267 {}; 1268 1269 virtual int execute(THD *thd, uint *nextp); 1270 1271 virtual int exec_core(THD *thd, uint *nextp); 1272 1273 virtual void print(String *str); 1274 1275 private: 1276 1277 sp_lex_keeper m_lex_keeper; 1278 1279 }; // class sp_instr_stmt : public sp_instr 1280 1281 1282 class sp_instr_set : public sp_instr 1283 { 1284 sp_instr_set(const sp_instr_set &); /**< Prevent use of these */ 1285 void operator=(sp_instr_set &); 1286 1287 public: 1288 sp_instr_set(uint ip,sp_pcontext * ctx,const Sp_rcontext_handler * rh,uint offset,Item * val,LEX * lex,bool lex_resp)1289 sp_instr_set(uint ip, sp_pcontext *ctx, 1290 const Sp_rcontext_handler *rh, 1291 uint offset, Item *val, 1292 LEX *lex, bool lex_resp) 1293 : sp_instr(ip, ctx), 1294 m_rcontext_handler(rh), m_offset(offset), m_value(val), 1295 m_lex_keeper(lex, lex_resp) 1296 {} 1297 ~sp_instr_set()1298 virtual ~sp_instr_set() 1299 {} 1300 1301 virtual int execute(THD *thd, uint *nextp); 1302 1303 virtual int exec_core(THD *thd, uint *nextp); 1304 1305 virtual void print(String *str); 1306 1307 protected: 1308 sp_rcontext *get_rcontext(THD *thd) const; 1309 const Sp_rcontext_handler *m_rcontext_handler; 1310 uint m_offset; ///< Frame offset 1311 Item *m_value; 1312 sp_lex_keeper m_lex_keeper; 1313 }; // class sp_instr_set : public sp_instr 1314 1315 1316 /* 1317 This class handles assignments of a ROW fields: 1318 DECLARE rec ROW (a INT,b INT); 1319 SET rec.a= 10; 1320 */ 1321 class sp_instr_set_row_field : public sp_instr_set 1322 { 1323 sp_instr_set_row_field(const sp_instr_set_row_field &); // Prevent use of this 1324 void operator=(sp_instr_set_row_field &); 1325 uint m_field_offset; 1326 1327 public: 1328 sp_instr_set_row_field(uint ip,sp_pcontext * ctx,const Sp_rcontext_handler * rh,uint offset,uint field_offset,Item * val,LEX * lex,bool lex_resp)1329 sp_instr_set_row_field(uint ip, sp_pcontext *ctx, 1330 const Sp_rcontext_handler *rh, 1331 uint offset, uint field_offset, 1332 Item *val, 1333 LEX *lex, bool lex_resp) 1334 : sp_instr_set(ip, ctx, rh, offset, val, lex, lex_resp), 1335 m_field_offset(field_offset) 1336 {} 1337 ~sp_instr_set_row_field()1338 virtual ~sp_instr_set_row_field() 1339 {} 1340 1341 virtual int exec_core(THD *thd, uint *nextp); 1342 1343 virtual void print(String *str); 1344 }; // class sp_instr_set_field : public sp_instr_set 1345 1346 1347 /** 1348 This class handles assignment instructions like this: 1349 DECLARE 1350 CURSOR cur IS SELECT * FROM t1; 1351 rec cur%ROWTYPE; 1352 BEGIN 1353 rec.column1:= 10; -- This instruction 1354 END; 1355 1356 The idea is that during sp_rcontext::create() we do not know the extact 1357 structure of "rec". It gets resolved at run time, during the corresponding 1358 sp_instr_cursor_copy_struct::exec_core(). 1359 1360 So sp_instr_set_row_field_by_name searches for ROW fields by name, 1361 while sp_instr_set_row_field (see above) searches for ROW fields by index. 1362 */ 1363 class sp_instr_set_row_field_by_name : public sp_instr_set 1364 { 1365 // Prevent use of this 1366 sp_instr_set_row_field_by_name(const sp_instr_set_row_field &); 1367 void operator=(sp_instr_set_row_field_by_name &); 1368 const LEX_CSTRING m_field_name; 1369 1370 public: 1371 sp_instr_set_row_field_by_name(uint ip,sp_pcontext * ctx,const Sp_rcontext_handler * rh,uint offset,const LEX_CSTRING & field_name,Item * val,LEX * lex,bool lex_resp)1372 sp_instr_set_row_field_by_name(uint ip, sp_pcontext *ctx, 1373 const Sp_rcontext_handler *rh, 1374 uint offset, const LEX_CSTRING &field_name, 1375 Item *val, 1376 LEX *lex, bool lex_resp) 1377 : sp_instr_set(ip, ctx, rh, offset, val, lex, lex_resp), 1378 m_field_name(field_name) 1379 {} 1380 ~sp_instr_set_row_field_by_name()1381 virtual ~sp_instr_set_row_field_by_name() 1382 {} 1383 1384 virtual int exec_core(THD *thd, uint *nextp); 1385 1386 virtual void print(String *str); 1387 }; // class sp_instr_set_field_by_name : public sp_instr_set 1388 1389 1390 /** 1391 Set NEW/OLD row field value instruction. Used in triggers. 1392 */ 1393 class sp_instr_set_trigger_field : public sp_instr 1394 { 1395 sp_instr_set_trigger_field(const sp_instr_set_trigger_field &); 1396 void operator=(sp_instr_set_trigger_field &); 1397 1398 public: 1399 sp_instr_set_trigger_field(uint ip,sp_pcontext * ctx,Item_trigger_field * trg_fld,Item * val,LEX * lex)1400 sp_instr_set_trigger_field(uint ip, sp_pcontext *ctx, 1401 Item_trigger_field *trg_fld, 1402 Item *val, LEX *lex) 1403 : sp_instr(ip, ctx), 1404 trigger_field(trg_fld), 1405 value(val), m_lex_keeper(lex, TRUE) 1406 {} 1407 ~sp_instr_set_trigger_field()1408 virtual ~sp_instr_set_trigger_field() 1409 {} 1410 1411 virtual int execute(THD *thd, uint *nextp); 1412 1413 virtual int exec_core(THD *thd, uint *nextp); 1414 1415 virtual void print(String *str); 1416 1417 private: 1418 Item_trigger_field *trigger_field; 1419 Item *value; 1420 sp_lex_keeper m_lex_keeper; 1421 }; // class sp_instr_trigger_field : public sp_instr 1422 1423 1424 /** 1425 An abstract class for all instructions with destinations that 1426 needs to be updated by the optimizer. 1427 1428 Even if not all subclasses will use both the normal destination and 1429 the continuation destination, we put them both here for simplicity. 1430 */ 1431 class sp_instr_opt_meta : public sp_instr 1432 { 1433 public: 1434 1435 uint m_dest; ///< Where we will go 1436 uint m_cont_dest; ///< Where continue handlers will go 1437 sp_instr_opt_meta(uint ip,sp_pcontext * ctx)1438 sp_instr_opt_meta(uint ip, sp_pcontext *ctx) 1439 : sp_instr(ip, ctx), 1440 m_dest(0), m_cont_dest(0), m_optdest(0), m_cont_optdest(0) 1441 {} 1442 sp_instr_opt_meta(uint ip,sp_pcontext * ctx,uint dest)1443 sp_instr_opt_meta(uint ip, sp_pcontext *ctx, uint dest) 1444 : sp_instr(ip, ctx), 1445 m_dest(dest), m_cont_dest(0), m_optdest(0), m_cont_optdest(0) 1446 {} 1447 ~sp_instr_opt_meta()1448 virtual ~sp_instr_opt_meta() 1449 {} 1450 1451 virtual void set_destination(uint old_dest, uint new_dest) 1452 = 0; 1453 1454 virtual uint get_cont_dest() const; 1455 1456 protected: 1457 1458 sp_instr *m_optdest; ///< Used during optimization 1459 sp_instr *m_cont_optdest; ///< Used during optimization 1460 1461 }; // class sp_instr_opt_meta : public sp_instr 1462 1463 class sp_instr_jump : public sp_instr_opt_meta 1464 { 1465 sp_instr_jump(const sp_instr_jump &); /**< Prevent use of these */ 1466 void operator=(sp_instr_jump &); 1467 1468 public: 1469 sp_instr_jump(uint ip,sp_pcontext * ctx)1470 sp_instr_jump(uint ip, sp_pcontext *ctx) 1471 : sp_instr_opt_meta(ip, ctx) 1472 {} 1473 sp_instr_jump(uint ip,sp_pcontext * ctx,uint dest)1474 sp_instr_jump(uint ip, sp_pcontext *ctx, uint dest) 1475 : sp_instr_opt_meta(ip, ctx, dest) 1476 {} 1477 ~sp_instr_jump()1478 virtual ~sp_instr_jump() 1479 {} 1480 1481 virtual int execute(THD *thd, uint *nextp); 1482 1483 virtual void print(String *str); 1484 1485 virtual uint opt_mark(sp_head *sp, List<sp_instr> *leads); 1486 1487 virtual uint opt_shortcut_jump(sp_head *sp, sp_instr *start); 1488 1489 virtual void opt_move(uint dst, List<sp_instr> *ibp); 1490 backpatch(uint dest,sp_pcontext * dst_ctx)1491 virtual void backpatch(uint dest, sp_pcontext *dst_ctx) 1492 { 1493 /* Calling backpatch twice is a logic flaw in jump resolution. */ 1494 DBUG_ASSERT(m_dest == 0); 1495 m_dest= dest; 1496 } 1497 1498 /** 1499 Update the destination; used by the optimizer. 1500 */ set_destination(uint old_dest,uint new_dest)1501 virtual void set_destination(uint old_dest, uint new_dest) 1502 { 1503 if (m_dest == old_dest) 1504 m_dest= new_dest; 1505 } 1506 1507 }; // class sp_instr_jump : public sp_instr_opt_meta 1508 1509 1510 class sp_instr_jump_if_not : public sp_instr_jump 1511 { 1512 sp_instr_jump_if_not(const sp_instr_jump_if_not &); /**< Prevent use of these */ 1513 void operator=(sp_instr_jump_if_not &); 1514 1515 public: 1516 sp_instr_jump_if_not(uint ip,sp_pcontext * ctx,Item * i,LEX * lex)1517 sp_instr_jump_if_not(uint ip, sp_pcontext *ctx, Item *i, LEX *lex) 1518 : sp_instr_jump(ip, ctx), m_expr(i), 1519 m_lex_keeper(lex, TRUE) 1520 {} 1521 sp_instr_jump_if_not(uint ip,sp_pcontext * ctx,Item * i,uint dest,LEX * lex)1522 sp_instr_jump_if_not(uint ip, sp_pcontext *ctx, Item *i, uint dest, LEX *lex) 1523 : sp_instr_jump(ip, ctx, dest), m_expr(i), 1524 m_lex_keeper(lex, TRUE) 1525 {} 1526 ~sp_instr_jump_if_not()1527 virtual ~sp_instr_jump_if_not() 1528 {} 1529 1530 virtual int execute(THD *thd, uint *nextp); 1531 1532 virtual int exec_core(THD *thd, uint *nextp); 1533 1534 virtual void print(String *str); 1535 1536 virtual uint opt_mark(sp_head *sp, List<sp_instr> *leads); 1537 1538 /** Override sp_instr_jump's shortcut; we stop here */ opt_shortcut_jump(sp_head * sp,sp_instr * start)1539 virtual uint opt_shortcut_jump(sp_head *sp, sp_instr *start) 1540 { 1541 return m_ip; 1542 } 1543 1544 virtual void opt_move(uint dst, List<sp_instr> *ibp); 1545 set_destination(uint old_dest,uint new_dest)1546 virtual void set_destination(uint old_dest, uint new_dest) 1547 { 1548 sp_instr_jump::set_destination(old_dest, new_dest); 1549 if (m_cont_dest == old_dest) 1550 m_cont_dest= new_dest; 1551 } 1552 1553 private: 1554 1555 Item *m_expr; ///< The condition 1556 sp_lex_keeper m_lex_keeper; 1557 1558 }; // class sp_instr_jump_if_not : public sp_instr_jump 1559 1560 1561 class sp_instr_preturn : public sp_instr 1562 { 1563 sp_instr_preturn(const sp_instr_preturn &); /**< Prevent use of these */ 1564 void operator=(sp_instr_preturn &); 1565 1566 public: 1567 sp_instr_preturn(uint ip,sp_pcontext * ctx)1568 sp_instr_preturn(uint ip, sp_pcontext *ctx) 1569 : sp_instr(ip, ctx) 1570 {} 1571 ~sp_instr_preturn()1572 virtual ~sp_instr_preturn() 1573 {} 1574 execute(THD * thd,uint * nextp)1575 virtual int execute(THD *thd, uint *nextp) 1576 { 1577 DBUG_ENTER("sp_instr_preturn::execute"); 1578 *nextp= UINT_MAX; 1579 DBUG_RETURN(0); 1580 } 1581 print(String * str)1582 virtual void print(String *str) 1583 { 1584 str->append(STRING_WITH_LEN("preturn")); 1585 } 1586 opt_mark(sp_head * sp,List<sp_instr> * leads)1587 virtual uint opt_mark(sp_head *sp, List<sp_instr> *leads) 1588 { 1589 marked= 1; 1590 return UINT_MAX; 1591 } 1592 1593 }; // class sp_instr_preturn : public sp_instr 1594 1595 1596 class sp_instr_freturn : public sp_instr 1597 { 1598 sp_instr_freturn(const sp_instr_freturn &); /**< Prevent use of these */ 1599 void operator=(sp_instr_freturn &); 1600 1601 public: 1602 sp_instr_freturn(uint ip,sp_pcontext * ctx,Item * val,const Type_handler * handler,LEX * lex)1603 sp_instr_freturn(uint ip, sp_pcontext *ctx, 1604 Item *val, const Type_handler *handler, LEX *lex) 1605 : sp_instr(ip, ctx), m_value(val), m_type_handler(handler), 1606 m_lex_keeper(lex, TRUE) 1607 {} 1608 ~sp_instr_freturn()1609 virtual ~sp_instr_freturn() 1610 {} 1611 1612 virtual int execute(THD *thd, uint *nextp); 1613 1614 virtual int exec_core(THD *thd, uint *nextp); 1615 1616 virtual void print(String *str); 1617 opt_mark(sp_head * sp,List<sp_instr> * leads)1618 virtual uint opt_mark(sp_head *sp, List<sp_instr> *leads) 1619 { 1620 marked= 1; 1621 return UINT_MAX; 1622 } 1623 1624 protected: 1625 1626 Item *m_value; 1627 const Type_handler *m_type_handler; 1628 sp_lex_keeper m_lex_keeper; 1629 1630 }; // class sp_instr_freturn : public sp_instr 1631 1632 1633 class sp_instr_hpush_jump : public sp_instr_jump 1634 { 1635 sp_instr_hpush_jump(const sp_instr_hpush_jump &); /**< Prevent use of these */ 1636 void operator=(sp_instr_hpush_jump &); 1637 1638 public: 1639 sp_instr_hpush_jump(uint ip,sp_pcontext * ctx,sp_handler * handler)1640 sp_instr_hpush_jump(uint ip, 1641 sp_pcontext *ctx, 1642 sp_handler *handler) 1643 :sp_instr_jump(ip, ctx), 1644 m_handler(handler), 1645 m_opt_hpop(0), 1646 m_frame(ctx->current_var_count()) 1647 { 1648 DBUG_ASSERT(m_handler->condition_values.elements == 0); 1649 } 1650 ~sp_instr_hpush_jump()1651 virtual ~sp_instr_hpush_jump() 1652 { 1653 m_handler->condition_values.empty(); 1654 m_handler= NULL; 1655 } 1656 1657 virtual int execute(THD *thd, uint *nextp); 1658 1659 virtual void print(String *str); 1660 1661 virtual uint opt_mark(sp_head *sp, List<sp_instr> *leads); 1662 1663 /** Override sp_instr_jump's shortcut; we stop here. */ opt_shortcut_jump(sp_head * sp,sp_instr * start)1664 virtual uint opt_shortcut_jump(sp_head *sp, sp_instr *start) 1665 { 1666 return m_ip; 1667 } 1668 backpatch(uint dest,sp_pcontext * dst_ctx)1669 virtual void backpatch(uint dest, sp_pcontext *dst_ctx) 1670 { 1671 DBUG_ASSERT(!m_dest || !m_opt_hpop); 1672 if (!m_dest) 1673 m_dest= dest; 1674 else 1675 m_opt_hpop= dest; 1676 } 1677 add_condition(sp_condition_value * condition_value)1678 void add_condition(sp_condition_value *condition_value) 1679 { m_handler->condition_values.push_back(condition_value); } 1680 get_handler()1681 sp_handler *get_handler() 1682 { return m_handler; } 1683 1684 private: 1685 /// Handler. 1686 sp_handler *m_handler; 1687 1688 /// hpop marking end of handler scope. 1689 uint m_opt_hpop; 1690 1691 // This attribute is needed for SHOW PROCEDURE CODE only (i.e. it's needed in 1692 // debug version only). It's used in print(). 1693 uint m_frame; 1694 1695 }; // class sp_instr_hpush_jump : public sp_instr_jump 1696 1697 1698 class sp_instr_hpop : public sp_instr 1699 { 1700 sp_instr_hpop(const sp_instr_hpop &); /**< Prevent use of these */ 1701 void operator=(sp_instr_hpop &); 1702 1703 public: 1704 sp_instr_hpop(uint ip,sp_pcontext * ctx,uint count)1705 sp_instr_hpop(uint ip, sp_pcontext *ctx, uint count) 1706 : sp_instr(ip, ctx), m_count(count) 1707 {} 1708 ~sp_instr_hpop()1709 virtual ~sp_instr_hpop() 1710 {} 1711 update_count(uint count)1712 void update_count(uint count) 1713 { 1714 m_count= count; 1715 } 1716 1717 virtual int execute(THD *thd, uint *nextp); 1718 1719 virtual void print(String *str); 1720 1721 private: 1722 1723 uint m_count; 1724 1725 }; // class sp_instr_hpop : public sp_instr 1726 1727 1728 class sp_instr_hreturn : public sp_instr_jump 1729 { 1730 sp_instr_hreturn(const sp_instr_hreturn &); /**< Prevent use of these */ 1731 void operator=(sp_instr_hreturn &); 1732 1733 public: 1734 sp_instr_hreturn(uint ip,sp_pcontext * ctx)1735 sp_instr_hreturn(uint ip, sp_pcontext *ctx) 1736 :sp_instr_jump(ip, ctx), 1737 m_frame(ctx->current_var_count()) 1738 {} 1739 ~sp_instr_hreturn()1740 virtual ~sp_instr_hreturn() 1741 {} 1742 1743 virtual int execute(THD *thd, uint *nextp); 1744 1745 virtual void print(String *str); 1746 1747 /* This instruction will not be short cut optimized. */ opt_shortcut_jump(sp_head * sp,sp_instr * start)1748 virtual uint opt_shortcut_jump(sp_head *sp, sp_instr *start) 1749 { 1750 return m_ip; 1751 } 1752 1753 virtual uint opt_mark(sp_head *sp, List<sp_instr> *leads); 1754 1755 private: 1756 1757 uint m_frame; 1758 1759 }; // class sp_instr_hreturn : public sp_instr_jump 1760 1761 1762 /** This is DECLARE CURSOR */ 1763 class sp_instr_cpush : public sp_instr, 1764 public sp_cursor 1765 { 1766 sp_instr_cpush(const sp_instr_cpush &); /**< Prevent use of these */ 1767 void operator=(sp_instr_cpush &); 1768 1769 public: 1770 sp_instr_cpush(uint ip,sp_pcontext * ctx,LEX * lex,uint offset)1771 sp_instr_cpush(uint ip, sp_pcontext *ctx, LEX *lex, uint offset) 1772 : sp_instr(ip, ctx), m_lex_keeper(lex, TRUE), m_cursor(offset) 1773 {} 1774 ~sp_instr_cpush()1775 virtual ~sp_instr_cpush() 1776 {} 1777 1778 virtual int execute(THD *thd, uint *nextp); 1779 1780 virtual void print(String *str); 1781 1782 /** 1783 This call is used to cleanup the instruction when a sensitive 1784 cursor is closed. For now stored procedures always use materialized 1785 cursors and the call is not used. 1786 */ cleanup_stmt()1787 virtual void cleanup_stmt() { /* no op */ } 1788 private: 1789 1790 sp_lex_keeper m_lex_keeper; 1791 uint m_cursor; /**< Frame offset (for debugging) */ 1792 1793 }; // class sp_instr_cpush : public sp_instr 1794 1795 1796 class sp_instr_cpop : public sp_instr 1797 { 1798 sp_instr_cpop(const sp_instr_cpop &); /**< Prevent use of these */ 1799 void operator=(sp_instr_cpop &); 1800 1801 public: 1802 sp_instr_cpop(uint ip,sp_pcontext * ctx,uint count)1803 sp_instr_cpop(uint ip, sp_pcontext *ctx, uint count) 1804 : sp_instr(ip, ctx), m_count(count) 1805 {} 1806 ~sp_instr_cpop()1807 virtual ~sp_instr_cpop() 1808 {} 1809 update_count(uint count)1810 void update_count(uint count) 1811 { 1812 m_count= count; 1813 } 1814 1815 virtual int execute(THD *thd, uint *nextp); 1816 1817 virtual void print(String *str); 1818 1819 private: 1820 1821 uint m_count; 1822 1823 }; // class sp_instr_cpop : public sp_instr 1824 1825 1826 class sp_instr_copen : public sp_instr 1827 { 1828 sp_instr_copen(const sp_instr_copen &); /**< Prevent use of these */ 1829 void operator=(sp_instr_copen &); 1830 1831 public: 1832 sp_instr_copen(uint ip,sp_pcontext * ctx,uint c)1833 sp_instr_copen(uint ip, sp_pcontext *ctx, uint c) 1834 : sp_instr(ip, ctx), m_cursor(c) 1835 {} 1836 ~sp_instr_copen()1837 virtual ~sp_instr_copen() 1838 {} 1839 1840 virtual int execute(THD *thd, uint *nextp); 1841 1842 virtual int exec_core(THD *thd, uint *nextp); 1843 1844 virtual void print(String *str); 1845 1846 private: 1847 1848 uint m_cursor; ///< Stack index 1849 1850 }; // class sp_instr_copen : public sp_instr_stmt 1851 1852 1853 /** 1854 Initialize the structure of a cursor%ROWTYPE variable 1855 from the LEX containing the cursor SELECT statement. 1856 */ 1857 class sp_instr_cursor_copy_struct: public sp_instr 1858 { 1859 /**< Prevent use of these */ 1860 sp_instr_cursor_copy_struct(const sp_instr_cursor_copy_struct &); 1861 void operator=(sp_instr_cursor_copy_struct &); 1862 sp_lex_keeper m_lex_keeper; 1863 uint m_cursor; 1864 uint m_var; 1865 public: sp_instr_cursor_copy_struct(uint ip,sp_pcontext * ctx,uint coffs,sp_lex_cursor * lex,uint voffs)1866 sp_instr_cursor_copy_struct(uint ip, sp_pcontext *ctx, uint coffs, 1867 sp_lex_cursor *lex, uint voffs) 1868 : sp_instr(ip, ctx), m_lex_keeper(lex, FALSE), 1869 m_cursor(coffs), 1870 m_var(voffs) 1871 {} ~sp_instr_cursor_copy_struct()1872 virtual ~sp_instr_cursor_copy_struct() 1873 {} 1874 virtual int execute(THD *thd, uint *nextp); 1875 virtual int exec_core(THD *thd, uint *nextp); 1876 virtual void print(String *str); 1877 }; 1878 1879 1880 class sp_instr_cclose : public sp_instr 1881 { 1882 sp_instr_cclose(const sp_instr_cclose &); /**< Prevent use of these */ 1883 void operator=(sp_instr_cclose &); 1884 1885 public: 1886 sp_instr_cclose(uint ip,sp_pcontext * ctx,uint c)1887 sp_instr_cclose(uint ip, sp_pcontext *ctx, uint c) 1888 : sp_instr(ip, ctx), m_cursor(c) 1889 {} 1890 ~sp_instr_cclose()1891 virtual ~sp_instr_cclose() 1892 {} 1893 1894 virtual int execute(THD *thd, uint *nextp); 1895 1896 virtual void print(String *str); 1897 1898 private: 1899 1900 uint m_cursor; 1901 1902 }; // class sp_instr_cclose : public sp_instr 1903 1904 1905 class sp_instr_cfetch : public sp_instr 1906 { 1907 sp_instr_cfetch(const sp_instr_cfetch &); /**< Prevent use of these */ 1908 void operator=(sp_instr_cfetch &); 1909 1910 public: 1911 sp_instr_cfetch(uint ip,sp_pcontext * ctx,uint c,bool error_on_no_data)1912 sp_instr_cfetch(uint ip, sp_pcontext *ctx, uint c, bool error_on_no_data) 1913 : sp_instr(ip, ctx), m_cursor(c), m_error_on_no_data(error_on_no_data) 1914 { 1915 m_varlist.empty(); 1916 } 1917 ~sp_instr_cfetch()1918 virtual ~sp_instr_cfetch() 1919 {} 1920 1921 virtual int execute(THD *thd, uint *nextp); 1922 1923 virtual void print(String *str); 1924 add_to_varlist(sp_variable * var)1925 void add_to_varlist(sp_variable *var) 1926 { 1927 m_varlist.push_back(var); 1928 } 1929 1930 private: 1931 1932 uint m_cursor; 1933 List<sp_variable> m_varlist; 1934 bool m_error_on_no_data; 1935 1936 }; // class sp_instr_cfetch : public sp_instr 1937 1938 /* 1939 This class is created for the special fetch instruction 1940 FETCH GROUP NEXT ROW, used in the user-defined aggregate 1941 functions 1942 */ 1943 1944 class sp_instr_agg_cfetch : public sp_instr 1945 { 1946 sp_instr_agg_cfetch(const sp_instr_cfetch &); /**< Prevent use of these */ 1947 void operator=(sp_instr_cfetch &); 1948 1949 public: 1950 sp_instr_agg_cfetch(uint ip,sp_pcontext * ctx)1951 sp_instr_agg_cfetch(uint ip, sp_pcontext *ctx) 1952 : sp_instr(ip, ctx){} 1953 ~sp_instr_agg_cfetch()1954 virtual ~sp_instr_agg_cfetch() 1955 {} 1956 1957 virtual int execute(THD *thd, uint *nextp); 1958 1959 virtual void print(String *str); 1960 }; // class sp_instr_agg_cfetch : public sp_instr 1961 1962 1963 1964 1965 class sp_instr_error : public sp_instr 1966 { 1967 sp_instr_error(const sp_instr_error &); /**< Prevent use of these */ 1968 void operator=(sp_instr_error &); 1969 1970 public: 1971 sp_instr_error(uint ip,sp_pcontext * ctx,int errcode)1972 sp_instr_error(uint ip, sp_pcontext *ctx, int errcode) 1973 : sp_instr(ip, ctx), m_errcode(errcode) 1974 {} 1975 ~sp_instr_error()1976 virtual ~sp_instr_error() 1977 {} 1978 1979 virtual int execute(THD *thd, uint *nextp); 1980 1981 virtual void print(String *str); 1982 opt_mark(sp_head * sp,List<sp_instr> * leads)1983 virtual uint opt_mark(sp_head *sp, List<sp_instr> *leads) 1984 { 1985 marked= 1; 1986 return UINT_MAX; 1987 } 1988 1989 private: 1990 1991 int m_errcode; 1992 1993 }; // class sp_instr_error : public sp_instr 1994 1995 1996 class sp_instr_set_case_expr : public sp_instr_opt_meta 1997 { 1998 public: 1999 sp_instr_set_case_expr(uint ip,sp_pcontext * ctx,uint case_expr_id,Item * case_expr,LEX * lex)2000 sp_instr_set_case_expr(uint ip, sp_pcontext *ctx, uint case_expr_id, 2001 Item *case_expr, LEX *lex) 2002 : sp_instr_opt_meta(ip, ctx), 2003 m_case_expr_id(case_expr_id), m_case_expr(case_expr), 2004 m_lex_keeper(lex, TRUE) 2005 {} 2006 ~sp_instr_set_case_expr()2007 virtual ~sp_instr_set_case_expr() 2008 {} 2009 2010 virtual int execute(THD *thd, uint *nextp); 2011 2012 virtual int exec_core(THD *thd, uint *nextp); 2013 2014 virtual void print(String *str); 2015 2016 virtual uint opt_mark(sp_head *sp, List<sp_instr> *leads); 2017 2018 virtual void opt_move(uint dst, List<sp_instr> *ibp); 2019 set_destination(uint old_dest,uint new_dest)2020 virtual void set_destination(uint old_dest, uint new_dest) 2021 { 2022 if (m_cont_dest == old_dest) 2023 m_cont_dest= new_dest; 2024 } 2025 2026 private: 2027 2028 uint m_case_expr_id; 2029 Item *m_case_expr; 2030 sp_lex_keeper m_lex_keeper; 2031 2032 }; // class sp_instr_set_case_expr : public sp_instr_opt_meta 2033 2034 2035 #ifndef NO_EMBEDDED_ACCESS_CHECKS 2036 bool 2037 sp_change_security_context(THD *thd, sp_head *sp, 2038 Security_context **backup); 2039 void 2040 sp_restore_security_context(THD *thd, Security_context *backup); 2041 2042 bool 2043 set_routine_security_ctx(THD *thd, sp_head *sp, Security_context **save_ctx); 2044 #endif /* NO_EMBEDDED_ACCESS_CHECKS */ 2045 2046 TABLE_LIST * 2047 sp_add_to_query_tables(THD *thd, LEX *lex, 2048 const LEX_CSTRING *db, const LEX_CSTRING *name, 2049 thr_lock_type locktype, 2050 enum_mdl_type mdl_type); 2051 2052 /** 2053 @} (end of group Stored_Routines) 2054 */ 2055 2056 #endif /* _SP_HEAD_H_ */ 2057