summaryrefslogtreecommitdiff
path: root/sql/sp_rcontext.h
diff options
context:
space:
mode:
Diffstat (limited to 'sql/sp_rcontext.h')
-rw-r--r--sql/sp_rcontext.h335
1 files changed, 335 insertions, 0 deletions
diff --git a/sql/sp_rcontext.h b/sql/sp_rcontext.h
new file mode 100644
index 00000000000..5e03aa60d23
--- /dev/null
+++ b/sql/sp_rcontext.h
@@ -0,0 +1,335 @@
+/* -*- 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 USE_PRAGMA_INTERFACE
+#pragma interface /* gcc class implementation */
+#endif
+
+struct sp_cond_type;
+class sp_cursor;
+struct sp_variable;
+class sp_lex_keeper;
+class sp_instr_cpush;
+
+#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;
+
+
+/*
+ This class is a runtime context of a Stored Routine. It is used in an
+ execution and is intended to contain all dynamic objects (i.e. objects, which
+ can be changed during execution), such as:
+ - stored routine variables;
+ - cursors;
+ - handlers;
+
+ Runtime context is used with sp_head class. sp_head class is intended to
+ contain all static things, related to the stored routines (code, for example).
+ sp_head instance creates runtime context for the execution of a stored
+ routine.
+
+ There is a parsing context (an instance of sp_pcontext class), which is used
+ on parsing stage. However, now it contains some necessary for an execution
+ things, such as definition of used stored routine variables. That's why
+ runtime context needs a reference to the parsing context.
+*/
+
+class sp_rcontext : public Sql_alloc
+{
+ sp_rcontext(const sp_rcontext &); /* Prevent use of these */
+ void operator=(sp_rcontext &);
+
+ public:
+
+ /*
+ Arena used to (re) allocate items on . E.g. reallocate INOUT/OUT
+ SP parameters when they don't fit into prealloced items. This
+ is common situation with String items. It is used mainly in
+ sp_eval_func_item().
+ */
+ Query_arena *callers_arena;
+
+#ifndef DBUG_OFF
+ /*
+ The routine for which this runtime context is created. Used for checking
+ if correct runtime context is used for variable handling.
+ */
+ sp_head *sp;
+#endif
+
+ sp_rcontext(sp_pcontext *root_parsing_ctx, Field *return_value_fld,
+ sp_rcontext *prev_runtime_ctx);
+ bool init(THD *thd);
+
+ ~sp_rcontext();
+
+ int
+ set_variable(THD *thd, uint var_idx, Item **value);
+
+ Item *
+ get_item(uint var_idx);
+
+ Item **
+ get_item_addr(uint var_idx);
+
+ bool
+ set_return_value(THD *thd, Item **return_value_item);
+
+ inline bool
+ is_return_value_set() const
+ {
+ return m_return_value_set;
+ }
+
+ 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);
+
+ // If there is an error handler for this error, handle it and return TRUE.
+ bool
+ handle_error(uint sql_errno,
+ MYSQL_ERROR::enum_warning_level level,
+ THD *thd);
+
+ // 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;
+ }
+
+ // Returns true if we found a handler in this context
+ inline bool
+ found_handler_here()
+ {
+ return (m_hfound >= 0);
+ }
+
+ // 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];
+ }
+
+ inline void
+ enter_handler(int hid)
+ {
+ m_in_handler[m_ihsp++]= hid;
+ }
+
+ inline void
+ exit_handler()
+ {
+ m_ihsp-= 1;
+ }
+
+ void
+ push_cursor(sp_lex_keeper *lex_keeper, sp_instr_cpush *i);
+
+ void
+ pop_cursors(uint count);
+
+ void
+ pop_all_cursors()
+ {
+ pop_cursors(m_ccount);
+ }
+
+ inline sp_cursor *
+ get_cursor(uint i)
+ {
+ return m_cstack[i];
+ }
+
+ /*
+ CASE expressions support.
+ */
+
+ int
+ set_case_expr(THD *thd, int case_expr_id, Item **case_expr_item_ptr);
+
+ Item *
+ get_case_expr(int case_expr_id);
+
+ Item **
+ get_case_expr_addr(int case_expr_id);
+
+private:
+ sp_pcontext *m_root_parsing_ctx;
+
+ /* Virtual table for storing variables. */
+ TABLE *m_var_table;
+
+ /*
+ Collection of Item_field proxies, each of them points to the corresponding
+ field in m_var_table.
+ */
+ Item **m_var_items;
+
+ /*
+ This is a pointer to a field, which should contain return value for stored
+ functions (only). For stored procedures, this pointer is NULL.
+ */
+ Field *m_return_value_fld;
+
+ /*
+ Indicates whether the return value (in m_return_value_fld) has been set
+ during execution.
+ */
+ bool m_return_value_set;
+
+ sp_handler_t *m_handler; // Visible handlers
+ uint m_hcount; // Stack pointer for m_handler
+ uint *m_hstack; // Return stack for continue handlers
+ uint m_hsp; // Stack pointer for m_hstack
+ uint *m_in_handler; // Active handler, for recursion check
+ uint m_ihsp; // Stack pointer for m_in_handler
+ int m_hfound; // Set by find_handler; -1 if not found
+
+ sp_cursor **m_cstack;
+ uint m_ccount;
+
+ Item_cache **m_case_expr_holders;
+
+ /* Previous runtime context (NULL if none) */
+ sp_rcontext *m_prev_runtime_ctx;
+
+private:
+ bool init_var_table(THD *thd);
+ bool init_var_items();
+
+ Item_cache *create_case_expr_holder(THD *thd, Item_result result_type);
+
+ int set_variable(THD *thd, Field *field, Item **value);
+}; // class sp_rcontext : public Sql_alloc
+
+
+/*
+ An interceptor of cursor result set used to implement
+ FETCH <cname> INTO <varlist>.
+*/
+
+class Select_fetch_into_spvars: public select_result_interceptor
+{
+ List<struct sp_variable> *spvar_list;
+ uint field_count;
+public:
+ Select_fetch_into_spvars() {} /* Remove gcc warning */
+ uint get_field_count() { return field_count; }
+ void set_spvar_list(List<struct sp_variable> *vars) { spvar_list= vars; }
+
+ virtual bool send_eof() { return FALSE; }
+ virtual bool send_data(List<Item> &items);
+ virtual int prepare(List<Item> &list, SELECT_LEX_UNIT *u);
+};
+
+
+/* A mediator between stored procedures and server side cursors */
+
+class sp_cursor : public Sql_alloc
+{
+public:
+
+ sp_cursor(sp_lex_keeper *lex_keeper, sp_instr_cpush *i);
+
+ virtual ~sp_cursor()
+ {
+ destroy();
+ }
+
+ sp_lex_keeper *
+ get_lex_keeper() { return m_lex_keeper; }
+
+ int
+ open(THD *thd);
+
+ int
+ close(THD *thd);
+
+ inline my_bool
+ is_open()
+ {
+ return test(server_side_cursor);
+ }
+
+ int
+ fetch(THD *, List<struct sp_variable> *vars);
+
+ inline sp_instr_cpush *
+ get_instr()
+ {
+ return m_i;
+ }
+
+private:
+
+ Select_fetch_into_spvars result;
+ sp_lex_keeper *m_lex_keeper;
+ Server_side_cursor *server_side_cursor;
+ sp_instr_cpush *m_i; // My push instruction
+ void
+ destroy();
+
+}; // class sp_cursor : public Sql_alloc
+
+#endif /* _SP_RCONTEXT_H_ */