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