mirror of
				https://github.com/MariaDB/server.git
				synced 2025-11-03 14:33:32 +03:00 
			
		
		
		
	and some SP-related cleanups. - We don't have separate stage for calculation of list of tables to be prelocked and doing implicit LOCK/UNLOCK any more. Instead we calculate this list at open_tables() and do implicit LOCK in lock_tables() (and UNLOCK in close_thread_tables()). Also now we support cases when same table (with same alias) is used several times in the same query in SP. - Cleaned up execution of SP. Moved all common code which handles LEX and does preparations before statement execution or complex expression evaluation to auxilary sp_lex_keeper class. Now all statements in SP (and corresponding instructions) that evaluate expression which can contain subquery have their own LEX.
		
			
				
	
	
		
			257 lines
		
	
	
		
			4.8 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			257 lines
		
	
	
		
			4.8 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_RCONTEXT_H_
 | 
						|
#define _SP_RCONTEXT_H_
 | 
						|
 | 
						|
#ifdef __GNUC__
 | 
						|
#pragma interface			/* gcc class implementation */
 | 
						|
#endif
 | 
						|
 | 
						|
struct sp_cond_type;
 | 
						|
class sp_cursor;
 | 
						|
struct sp_pvar;
 | 
						|
class sp_lex_keeper;
 | 
						|
 | 
						|
#define SP_HANDLER_NONE      0
 | 
						|
#define SP_HANDLER_EXIT      1
 | 
						|
#define SP_HANDLER_CONTINUE  2
 | 
						|
#define SP_HANDLER_UNDO      3
 | 
						|
 | 
						|
typedef struct
 | 
						|
{
 | 
						|
  struct sp_cond_type *cond;
 | 
						|
  uint handler;			// Location of handler
 | 
						|
  int type;
 | 
						|
  uint foffset;			// Frame offset for the handlers declare level
 | 
						|
} sp_handler_t;
 | 
						|
 | 
						|
class sp_rcontext : public Sql_alloc
 | 
						|
{
 | 
						|
  sp_rcontext(const sp_rcontext &); /* Prevent use of these */
 | 
						|
  void operator=(sp_rcontext &);
 | 
						|
 | 
						|
 public:
 | 
						|
 | 
						|
  bool in_handler;
 | 
						|
 | 
						|
  sp_rcontext(uint fsize, uint hmax, uint cmax);
 | 
						|
 | 
						|
  ~sp_rcontext()
 | 
						|
  {
 | 
						|
    // Not needed?
 | 
						|
    //sql_element_free(m_frame);
 | 
						|
    //m_saved.empty();
 | 
						|
  }
 | 
						|
 | 
						|
  inline void
 | 
						|
  push_item(Item *i)
 | 
						|
  {
 | 
						|
    if (m_count < m_fsize)
 | 
						|
      m_frame[m_count++] = i;
 | 
						|
  }
 | 
						|
 | 
						|
  inline void
 | 
						|
  set_item(uint idx, Item *i)
 | 
						|
  {
 | 
						|
    if (idx < m_count)
 | 
						|
      m_frame[idx] = i;
 | 
						|
  }
 | 
						|
 | 
						|
  /* Returns 0 on success, -1 on (eval) failure */
 | 
						|
  int
 | 
						|
  set_item_eval(uint idx, Item *i, enum_field_types type);
 | 
						|
 | 
						|
  inline Item *
 | 
						|
  get_item(uint idx)
 | 
						|
  {
 | 
						|
    return m_frame[idx];
 | 
						|
  }
 | 
						|
 | 
						|
  inline void
 | 
						|
  set_oindex(uint idx, int oidx)
 | 
						|
  {
 | 
						|
    m_outs[idx] = oidx;
 | 
						|
  }
 | 
						|
 | 
						|
  inline int
 | 
						|
  get_oindex(uint idx)
 | 
						|
  {
 | 
						|
    return m_outs[idx];
 | 
						|
  }
 | 
						|
 | 
						|
  inline void
 | 
						|
  set_result(Item *it)
 | 
						|
  {
 | 
						|
    m_result= it;
 | 
						|
  }
 | 
						|
 | 
						|
  inline Item *
 | 
						|
  get_result()
 | 
						|
  {
 | 
						|
    return m_result;
 | 
						|
  }
 | 
						|
 | 
						|
  inline void
 | 
						|
  push_handler(struct sp_cond_type *cond, uint h, int type, uint f)
 | 
						|
  {
 | 
						|
    m_handler[m_hcount].cond= cond;
 | 
						|
    m_handler[m_hcount].handler= h;
 | 
						|
    m_handler[m_hcount].type= type;
 | 
						|
    m_handler[m_hcount].foffset= f;
 | 
						|
    m_hcount+= 1;
 | 
						|
  }
 | 
						|
 | 
						|
  inline void
 | 
						|
  pop_handlers(uint count)
 | 
						|
  {
 | 
						|
    m_hcount-= count;
 | 
						|
  }
 | 
						|
 | 
						|
  // Returns 1 if a handler was found, 0 otherwise.
 | 
						|
  bool
 | 
						|
  find_handler(uint sql_errno,MYSQL_ERROR::enum_warning_level level);
 | 
						|
 | 
						|
  // Returns handler type and sets *ip to location if one was found
 | 
						|
  inline int
 | 
						|
  found_handler(uint *ip, uint *fp)
 | 
						|
  {
 | 
						|
    if (m_hfound < 0)
 | 
						|
      return SP_HANDLER_NONE;
 | 
						|
    *ip= m_handler[m_hfound].handler;
 | 
						|
    *fp= m_handler[m_hfound].foffset;
 | 
						|
    return m_handler[m_hfound].type;
 | 
						|
  }
 | 
						|
 | 
						|
  // Clears the handler find state
 | 
						|
  inline void
 | 
						|
  clear_handler()
 | 
						|
  {
 | 
						|
    m_hfound= -1;
 | 
						|
  }
 | 
						|
 | 
						|
  inline void
 | 
						|
  push_hstack(uint h)
 | 
						|
  {
 | 
						|
    m_hstack[m_hsp++]= h;
 | 
						|
  }
 | 
						|
 | 
						|
  inline uint
 | 
						|
  pop_hstack()
 | 
						|
  {
 | 
						|
    return m_hstack[--m_hsp];
 | 
						|
  }
 | 
						|
 | 
						|
  // Save variables starting at fp and up
 | 
						|
  void
 | 
						|
  save_variables(uint fp);
 | 
						|
 | 
						|
  // Restore variables down to fp
 | 
						|
  void
 | 
						|
  restore_variables(uint fp);
 | 
						|
 | 
						|
  void
 | 
						|
  push_cursor(sp_lex_keeper *lex_keeper);
 | 
						|
 | 
						|
  void
 | 
						|
  pop_cursors(uint count);
 | 
						|
 | 
						|
  void
 | 
						|
  pop_all_cursors()
 | 
						|
  {
 | 
						|
    pop_cursors(m_ccount);
 | 
						|
  }
 | 
						|
 | 
						|
  inline sp_cursor *
 | 
						|
  get_cursor(uint i)
 | 
						|
  {
 | 
						|
    return m_cstack[i];
 | 
						|
  }
 | 
						|
 | 
						|
private:
 | 
						|
 | 
						|
  uint m_count;
 | 
						|
  uint m_fsize;
 | 
						|
  Item **m_frame;
 | 
						|
  int  *m_outs;
 | 
						|
 | 
						|
  Item *m_result;		// For FUNCTIONs
 | 
						|
 | 
						|
  sp_handler_t *m_handler;
 | 
						|
  uint m_hcount;
 | 
						|
  uint *m_hstack;
 | 
						|
  uint m_hsp;
 | 
						|
  int m_hfound;			// Set by find_handler; -1 if not found
 | 
						|
  List<Item> m_saved;		// Saved variables
 | 
						|
 | 
						|
  sp_cursor **m_cstack;
 | 
						|
  uint m_ccount;
 | 
						|
 | 
						|
}; // class sp_rcontext : public Sql_alloc
 | 
						|
 | 
						|
 | 
						|
class sp_cursor : public Sql_alloc
 | 
						|
{
 | 
						|
public:
 | 
						|
 | 
						|
  sp_cursor(sp_lex_keeper *lex_keeper)
 | 
						|
    : m_lex_keeper(lex_keeper), m_prot(NULL), m_isopen(0), m_current_row(NULL)
 | 
						|
  {
 | 
						|
    /* Empty */
 | 
						|
  }
 | 
						|
 | 
						|
  virtual ~sp_cursor()
 | 
						|
  {
 | 
						|
    destroy();
 | 
						|
  }
 | 
						|
 | 
						|
  // We have split this in two to make it easy for sp_instr_copen
 | 
						|
  // to reuse the sp_instr::exec_stmt() code.
 | 
						|
  sp_lex_keeper *
 | 
						|
  pre_open(THD *thd);
 | 
						|
  void
 | 
						|
  post_open(THD *thd, my_bool was_opened);
 | 
						|
 | 
						|
  int
 | 
						|
  close(THD *thd);
 | 
						|
 | 
						|
  inline my_bool
 | 
						|
  is_open()
 | 
						|
  {
 | 
						|
    return m_isopen;
 | 
						|
  }
 | 
						|
 | 
						|
  int
 | 
						|
  fetch(THD *, List<struct sp_pvar> *vars);
 | 
						|
 | 
						|
private:
 | 
						|
 | 
						|
  MEM_ROOT m_mem_root;		// My own mem_root
 | 
						|
  sp_lex_keeper *m_lex_keeper;
 | 
						|
  Protocol_cursor *m_prot;
 | 
						|
  my_bool m_isopen;
 | 
						|
  my_bool m_nseof;		// Original no_send_eof
 | 
						|
  Protocol *m_oprot;		// Original protcol
 | 
						|
  MYSQL_ROWS *m_current_row;
 | 
						|
  
 | 
						|
  void
 | 
						|
  destroy();
 | 
						|
 | 
						|
}; // class sp_cursor : public Sql_alloc
 | 
						|
 | 
						|
#endif /* _SP_RCONTEXT_H_ */
 |