mirror of
				https://github.com/MariaDB/server.git
				synced 2025-11-03 14:33:32 +03:00 
			
		
		
		
	
		
			
				
	
	
		
			305 lines
		
	
	
		
			5.3 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			305 lines
		
	
	
		
			5.3 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 __GNUC__
 | 
						|
#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
 | 
						|
  my_bool isset;
 | 
						|
  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;
 | 
						|
 | 
						|
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_isset(uint i, my_bool val)
 | 
						|
  {
 | 
						|
    sp_pvar_t *p= find_pvar(i);
 | 
						|
 | 
						|
    if (p)
 | 
						|
      p->isset= val;
 | 
						|
  }
 | 
						|
 | 
						|
  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
 | 
						|
  add_handler()
 | 
						|
  {
 | 
						|
    m_handlers+= 1;
 | 
						|
  }
 | 
						|
 | 
						|
  inline uint
 | 
						|
  max_handlers()
 | 
						|
  {
 | 
						|
    return m_hsubsize + m_handlers;
 | 
						|
  }
 | 
						|
 | 
						|
  inline void
 | 
						|
  push_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
 | 
						|
 | 
						|
  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_ */
 |