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