mirror of
				https://github.com/MariaDB/server.git
				synced 2025-10-31 15:50:51 +03:00 
			
		
		
		
	 c76d5768a7
			
		
	
	c76d5768a7
	
	
	
		
			
			Have to init. all local variables in their frames, not just once at the beginning of invocation.
		
			
				
	
	
		
			304 lines
		
	
	
		
			5.4 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			304 lines
		
	
	
		
			5.4 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /* -*- C++ -*- */
 | |
| /* Copyright (C) 2002 MySQL AB
 | |
| 
 | |
|    This program is free software; you can redistribute it and/or modify
 | |
|    it under the terms of the GNU General Public License as published by
 | |
|    the Free Software Foundation; either version 2 of the License, or
 | |
|    (at your option) any later version.
 | |
| 
 | |
|    This program is distributed in the hope that it will be useful,
 | |
|    but WITHOUT ANY WARRANTY; without even the implied warranty of
 | |
|    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | |
|    GNU General Public License for more details.
 | |
| 
 | |
|    You should have received a copy of the GNU General Public License
 | |
|    along with this program; if not, write to the Free Software
 | |
|    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
 | |
| 
 | |
| #ifndef _SP_PCONTEXT_H_
 | |
| #define _SP_PCONTEXT_H_
 | |
| 
 | |
| #ifdef USE_PRAGMA_INTERFACE
 | |
| #pragma interface			/* gcc class implementation */
 | |
| #endif
 | |
| 
 | |
| typedef enum
 | |
| {
 | |
|   sp_param_in,
 | |
|   sp_param_out,
 | |
|   sp_param_inout
 | |
| } sp_param_mode_t;
 | |
| 
 | |
| typedef struct sp_pvar
 | |
| {
 | |
|   LEX_STRING name;
 | |
|   enum enum_field_types type;
 | |
|   sp_param_mode_t mode;
 | |
|   uint offset;			// Offset in current frame
 | |
|   Item *dflt;
 | |
| } sp_pvar_t;
 | |
| 
 | |
| 
 | |
| #define SP_LAB_REF   0		// Unresolved reference (for goto)
 | |
| #define SP_LAB_GOTO  1		// Free goto label
 | |
| #define SP_LAB_BEGIN 2		// Label at BEGIN
 | |
| #define SP_LAB_ITER  3		// Label at iteration control
 | |
| 
 | |
| typedef struct sp_label
 | |
| {
 | |
|   char *name;
 | |
|   uint ip;			// Instruction index
 | |
|   int type;			// begin/iter or ref/free 
 | |
|   sp_pcontext *ctx;             // The label's context
 | |
| } sp_label_t;
 | |
| 
 | |
| typedef struct sp_cond_type
 | |
| {
 | |
|   enum { number, state, warning, notfound, exception } type;
 | |
|   char sqlstate[6];
 | |
|   uint mysqlerr;
 | |
| } sp_cond_type_t;
 | |
| 
 | |
| /* Sanity check for SQLSTATEs. Will not check if it's really an existing
 | |
|  * state (there are just too many), but will check length bad characters.
 | |
|  */
 | |
| extern bool
 | |
| sp_cond_check(LEX_STRING *sqlstate);
 | |
| 
 | |
| typedef struct sp_cond
 | |
| {
 | |
|   LEX_STRING name;
 | |
|   sp_cond_type_t *val;
 | |
| } sp_cond_t;
 | |
| 
 | |
| 
 | |
| /*
 | |
|   This seems to be an "SP parsing context" or something.
 | |
| */
 | |
| 
 | |
| class sp_pcontext : public Sql_alloc
 | |
| {
 | |
|   sp_pcontext(const sp_pcontext &); /* Prevent use of these */
 | |
|   void operator=(sp_pcontext &);
 | |
| 
 | |
|  public:
 | |
| 
 | |
|   sp_pcontext(sp_pcontext *prev);
 | |
| 
 | |
|   // Free memory
 | |
|   void
 | |
|   destroy();
 | |
| 
 | |
|   sp_pcontext *
 | |
|   push_context();
 | |
| 
 | |
|   // Returns the previous context, not the one we pop
 | |
|   sp_pcontext *
 | |
|   pop_context();
 | |
| 
 | |
|   sp_pcontext *
 | |
|   parent_context()
 | |
|   {
 | |
|     return m_parent;
 | |
|   }
 | |
| 
 | |
|   uint
 | |
|   diff_handlers(sp_pcontext *ctx);
 | |
| 
 | |
|   uint
 | |
|   diff_cursors(sp_pcontext *ctx);
 | |
| 
 | |
| 
 | |
|   //
 | |
|   // Parameters and variables
 | |
|   //
 | |
| 
 | |
|   inline uint
 | |
|   max_pvars()
 | |
|   {
 | |
|     return m_psubsize + m_pvar.elements;
 | |
|   }
 | |
| 
 | |
|   inline uint
 | |
|   current_pvars()
 | |
|   {
 | |
|     return m_poffset + m_pvar.elements;
 | |
|   }
 | |
| 
 | |
|   inline uint
 | |
|   context_pvars()
 | |
|   {
 | |
|     return m_pvar.elements;
 | |
|   }
 | |
| 
 | |
|   inline uint
 | |
|   pvar_context2index(uint i)
 | |
|   {
 | |
|     return m_poffset + i;
 | |
|   }
 | |
| 
 | |
|   inline void
 | |
|   set_type(uint i, enum enum_field_types type)
 | |
|   {
 | |
|     sp_pvar_t *p= find_pvar(i);
 | |
| 
 | |
|     if (p)
 | |
|       p->type= type;
 | |
|   }
 | |
| 
 | |
|   inline void
 | |
|   set_default(uint i, Item *it)
 | |
|   {
 | |
|     sp_pvar_t *p= find_pvar(i);
 | |
| 
 | |
|     if (p)
 | |
|       p->dflt= it;
 | |
|   }
 | |
| 
 | |
|   void
 | |
|   push_pvar(LEX_STRING *name, enum enum_field_types type, sp_param_mode_t mode);
 | |
| 
 | |
|   // Pop the last 'num' slots of the frame
 | |
|   inline void
 | |
|   pop_pvar(uint num = 1)
 | |
|   {
 | |
|     while (num--)
 | |
|       pop_dynamic(&m_pvar);
 | |
|   }
 | |
| 
 | |
|   // Find by name
 | |
|   sp_pvar_t *
 | |
|   find_pvar(LEX_STRING *name, my_bool scoped=0);
 | |
| 
 | |
|   // Find by index
 | |
|   sp_pvar_t *
 | |
|   find_pvar(uint i)
 | |
|   {
 | |
|     sp_pvar_t *p;
 | |
| 
 | |
|     if (i < m_pvar.elements)
 | |
|       get_dynamic(&m_pvar, (gptr)&p, i);
 | |
|     else
 | |
|       p= NULL;
 | |
|     return p;
 | |
|   }
 | |
| 
 | |
|   //
 | |
|   // Labels
 | |
|   //
 | |
| 
 | |
|   sp_label_t *
 | |
|   push_label(char *name, uint ip);
 | |
| 
 | |
|   sp_label_t *
 | |
|   find_label(char *name);
 | |
| 
 | |
|   inline sp_label_t *
 | |
|   last_label()
 | |
|   {
 | |
|     sp_label_t *lab= m_label.head();
 | |
| 
 | |
|     if (!lab && m_parent)
 | |
|       lab= m_parent->last_label();
 | |
|     return lab;
 | |
|   }
 | |
| 
 | |
|   inline sp_label_t *
 | |
|   pop_label()
 | |
|   {
 | |
|     return m_label.pop();
 | |
|   }
 | |
| 
 | |
|   //
 | |
|   // Conditions
 | |
|   //
 | |
| 
 | |
|   void
 | |
|   push_cond(LEX_STRING *name, sp_cond_type_t *val);
 | |
| 
 | |
|   inline void
 | |
|   pop_cond(uint num)
 | |
|   {
 | |
|     while (num--)
 | |
|       pop_dynamic(&m_cond);
 | |
|   }
 | |
| 
 | |
|   sp_cond_type_t *
 | |
|   find_cond(LEX_STRING *name, my_bool scoped=0);
 | |
| 
 | |
|   //
 | |
|   // Handlers
 | |
|   //
 | |
| 
 | |
|   inline void
 | |
|   push_handler(sp_cond_type_t *cond)
 | |
|   {
 | |
|     insert_dynamic(&m_handler, (gptr)&cond);
 | |
|   }
 | |
| 
 | |
|   bool
 | |
|   find_handler(sp_cond_type *cond);
 | |
| 
 | |
|   inline uint
 | |
|   max_handlers()
 | |
|   {
 | |
|     return m_hsubsize + m_handlers;
 | |
|   }
 | |
| 
 | |
|   inline void
 | |
|   add_handlers(uint n)
 | |
|   {
 | |
|     m_handlers+= n;
 | |
|   }
 | |
| 
 | |
|   //
 | |
|   // Cursors
 | |
|   //
 | |
| 
 | |
|   void
 | |
|   push_cursor(LEX_STRING *name);
 | |
| 
 | |
|   my_bool
 | |
|   find_cursor(LEX_STRING *name, uint *poff, my_bool scoped=0);
 | |
| 
 | |
|   inline uint
 | |
|   max_cursors()
 | |
|   {
 | |
|     return m_csubsize + m_cursor.elements;
 | |
|   }
 | |
| 
 | |
|   inline uint
 | |
|   current_cursors()
 | |
|   {
 | |
|     return m_coffset + m_cursor.elements;
 | |
|   }
 | |
| 
 | |
| protected:
 | |
| 
 | |
|   // The maximum sub context's framesizes
 | |
|   uint m_psubsize;		
 | |
|   uint m_csubsize;
 | |
|   uint m_hsubsize;
 | |
|   uint m_handlers;		// No. of handlers in this context
 | |
| 
 | |
| private:
 | |
| 
 | |
|   sp_pcontext *m_parent;	// Parent context
 | |
| 
 | |
|   uint m_poffset;		// Variable offset for this context
 | |
|   uint m_coffset;		// Cursor offset for this context
 | |
| 
 | |
|   DYNAMIC_ARRAY m_pvar;		// Parameters/variables
 | |
|   DYNAMIC_ARRAY m_cond;		// Conditions
 | |
|   DYNAMIC_ARRAY m_cursor;	// Cursors
 | |
|   DYNAMIC_ARRAY m_handler;	// Handlers, for checking of duplicates
 | |
| 
 | |
|   List<sp_label_t> m_label;	// The label list
 | |
| 
 | |
|   List<sp_pcontext> m_children;	// Children contexts, used for destruction
 | |
| 
 | |
| }; // class sp_pcontext : public Sql_alloc
 | |
| 
 | |
| 
 | |
| #endif /* _SP_PCONTEXT_H_ */
 |