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