sp_rcontext.h 4.78 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
/* -*- 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_

21 22 23 24 25
#ifdef __GNUC__
#pragma interface			/* gcc class implementation */
#endif

struct sp_cond_type;
unknown's avatar
unknown committed
26
class sp_cursor;
27
struct sp_pvar;
28
class sp_lex_keeper;
29 30 31 32 33 34 35 36 37 38 39 40 41 42

#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;

43 44 45 46 47 48 49
class sp_rcontext : public Sql_alloc
{
  sp_rcontext(const sp_rcontext &); /* Prevent use of these */
  void operator=(sp_rcontext &);

 public:

50 51
  bool in_handler;

52
  sp_rcontext(uint fsize, uint hmax, uint cmax);
53 54 55 56 57

  ~sp_rcontext()
  {
    // Not needed?
    //sql_element_free(m_frame);
58
    //m_saved.empty();
59 60 61 62 63
  }

  inline void
  push_item(Item *i)
  {
64
    if (m_count < m_fsize)
65 66 67 68 69 70 71 72 73 74
      m_frame[m_count++] = i;
  }

  inline void
  set_item(uint idx, Item *i)
  {
    if (idx < m_count)
      m_frame[idx] = i;
  }

75 76
  /* Returns 0 on success, -1 on (eval) failure */
  int
77 78
  set_item_eval(uint idx, Item *i, enum_field_types type);

79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
  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];
  }

97 98 99 100 101 102 103 104 105 106 107 108
  inline void
  set_result(Item *it)
  {
    m_result= it;
  }

  inline Item *
  get_result()
  {
    return m_result;
  }

109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125
  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.
126
  bool
unknown's avatar
unknown committed
127
  find_handler(uint sql_errno,MYSQL_ERROR::enum_warning_level level);
128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166

  // 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);

167
  void
168
  push_cursor(sp_lex_keeper *lex_keeper);
169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184

  void
  pop_cursors(uint count);

  void
  pop_all_cursors()
  {
    pop_cursors(m_ccount);
  }

  inline sp_cursor *
  get_cursor(uint i)
  {
    return m_cstack[i];
  }

185 186 187
private:

  uint m_count;
188
  uint m_fsize;
189 190
  Item **m_frame;
  int  *m_outs;
191

192
  Item *m_result;		// For FUNCTIONs
193

194 195 196 197 198 199
  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
200

201 202 203
  sp_cursor **m_cstack;
  uint m_ccount;

204 205
}; // class sp_rcontext : public Sql_alloc

206 207 208 209 210

class sp_cursor : public Sql_alloc
{
public:

211 212
  sp_cursor(sp_lex_keeper *lex_keeper)
    : m_lex_keeper(lex_keeper), m_prot(NULL), m_isopen(0), m_current_row(NULL)
213 214 215 216 217 218 219 220 221 222 223
  {
    /* 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.
224
  sp_lex_keeper *
225 226
  pre_open(THD *thd);
  void
227
  post_open(THD *thd, my_bool was_opened);
228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243

  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
244
  sp_lex_keeper *m_lex_keeper;
245 246
  Protocol_cursor *m_prot;
  my_bool m_isopen;
247
  my_bool m_nseof;		// Original no_send_eof
248 249 250 251 252 253 254 255
  Protocol *m_oprot;		// Original protcol
  MYSQL_ROWS *m_current_row;
  
  void
  destroy();

}; // class sp_cursor : public Sql_alloc

256
#endif /* _SP_RCONTEXT_H_ */