My Project
sp_pcontext.h
00001 /* -*- C++ -*- */
00002 /* Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
00003 
00004    This program is free software; you can redistribute it and/or modify
00005    it under the terms of the GNU General Public License as published by
00006    the Free Software Foundation; version 2 of the License.
00007 
00008    This program is distributed in the hope that it will be useful,
00009    but WITHOUT ANY WARRANTY; without even the implied warranty of
00010    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00011    GNU General Public License for more details.
00012 
00013    You should have received a copy of the GNU General Public License
00014    along with this program; if not, write to the Free Software Foundation,
00015    51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA */
00016 
00017 #ifndef _SP_PCONTEXT_H_
00018 #define _SP_PCONTEXT_H_
00019 
00020 #include "sql_string.h"                         // LEX_STRING
00021 #include "mysql_com.h"                          // enum_field_types
00022 #include "field.h"                              // Create_field
00023 #include "sql_array.h"                          // Dynamic_array
00024 
00025 
00028 
00029 class sp_variable : public Sql_alloc
00030 {
00031 public:
00032   enum enum_mode
00033   {
00034     MODE_IN,
00035     MODE_OUT,
00036     MODE_INOUT
00037   };
00038 
00040   LEX_STRING name;
00041 
00043   enum enum_field_types type;
00044 
00046   enum_mode mode;
00047 
00053   uint offset;
00054 
00056   Item *default_value;
00057 
00059   Create_field field_def;
00060 
00061 public:
00062   sp_variable(LEX_STRING _name, enum_field_types _type, enum_mode _mode,
00063               uint _offset)
00064    :Sql_alloc(),
00065     name(_name),
00066     type(_type),
00067     mode(_mode),
00068     offset(_offset),
00069     default_value(NULL)
00070   { }
00071 };
00072 
00074 
00081 
00082 class sp_label : public Sql_alloc
00083 {
00084 public:
00085   enum enum_type
00086   {
00088     IMPLICIT,
00089 
00091     BEGIN,
00092 
00094     ITERATION
00095   };
00096 
00098   LEX_STRING name;
00099 
00101   uint ip;
00102 
00104   enum_type type;
00105 
00107   class sp_pcontext *ctx;
00108 
00109 public:
00110   sp_label(LEX_STRING _name, uint _ip, enum_type _type, sp_pcontext *_ctx)
00111    :Sql_alloc(),
00112     name(_name),
00113     ip(_ip),
00114     type(_type),
00115     ctx(_ctx)
00116   { }
00117 };
00118 
00120 
00127 
00128 class sp_condition_value : public Sql_alloc
00129 {
00130 public:
00131   enum enum_type
00132   {
00133     ERROR_CODE,
00134     SQLSTATE,
00135     WARNING,
00136     NOT_FOUND,
00137     EXCEPTION
00138   };
00139 
00141   enum_type type;
00142 
00144   char sql_state[SQLSTATE_LENGTH+1];
00145 
00147   uint mysqlerr;
00148 
00149 public:
00150   sp_condition_value(uint _mysqlerr)
00151    :Sql_alloc(),
00152     type(ERROR_CODE),
00153     mysqlerr(_mysqlerr)
00154   { }
00155 
00156   sp_condition_value(const char *_sql_state)
00157    :Sql_alloc(),
00158     type(SQLSTATE)
00159   {
00160     memcpy(sql_state, _sql_state, SQLSTATE_LENGTH);
00161     sql_state[SQLSTATE_LENGTH]= 0;
00162   }
00163 
00164   sp_condition_value(enum_type _type)
00165    :Sql_alloc(),
00166     type(_type)
00167   {
00168     DBUG_ASSERT(type != ERROR_CODE && type != SQLSTATE);
00169   }
00170 
00176   bool equals(const sp_condition_value *cv) const;
00177 };
00178 
00180 
00183 
00184 class sp_condition : public Sql_alloc
00185 {
00186 public:
00188   LEX_STRING name;
00189 
00191   sp_condition_value *value;
00192 
00193 public:
00194   sp_condition(LEX_STRING _name, sp_condition_value *_value)
00195    :Sql_alloc(),
00196     name(_name),
00197     value(_value)
00198   { }
00199 };
00200 
00202 
00204 
00205 class sp_handler : public Sql_alloc
00206 {
00207 public:
00210   enum enum_type
00211   {
00212     EXIT,
00213     CONTINUE
00214   };
00215 
00217   enum_type type;
00218 
00220   sp_pcontext *scope;
00221 
00223   List<sp_condition_value> condition_values;
00224 
00225 public:
00230   sp_handler(enum_type _type, sp_pcontext *_scope)
00231    :Sql_alloc(),
00232     type(_type),
00233     scope(_scope)
00234   { }
00235 };
00236 
00238 
00261 
00262 class sp_pcontext : public Sql_alloc
00263 {
00264 public:
00265   enum enum_scope
00266   {
00268     REGULAR_SCOPE,
00269 
00271     HANDLER_SCOPE
00272   };
00273 
00274 public:
00275   sp_pcontext();
00276   ~sp_pcontext();
00277 
00278 
00280 
00284   sp_pcontext *push_context(THD *thd, enum_scope scope);
00285 
00288   sp_pcontext *pop_context();
00289 
00290   sp_pcontext *parent_context() const
00291   { return m_parent; }
00292 
00293   int get_level() const
00294   { return m_level; }
00295 
00306   uint diff_handlers(const sp_pcontext *ctx, bool exclusive) const;
00307 
00318   uint diff_cursors(const sp_pcontext *ctx, bool exclusive) const;
00319 
00321   // SP-variables (parameters and variables).
00323 
00327   uint max_var_index() const
00328   { return m_max_var_index; }
00329 
00332   uint current_var_count() const
00333   { return m_var_offset + m_vars.elements(); }
00334 
00336   uint context_var_count() const
00337   { return m_vars.elements(); }
00338 
00340   uint var_context2runtime(uint i) const
00341   { return m_var_offset + i; }
00342 
00351   sp_variable *add_variable(THD *thd,
00352                             LEX_STRING name,
00353                             enum enum_field_types type,
00354                             sp_variable::enum_mode mode);
00355 
00360   void retrieve_field_definitions(List<Create_field> *field_def_lst) const;
00361 
00373   sp_variable *find_variable(LEX_STRING name, bool current_scope_only) const;
00374 
00385   sp_variable *find_variable(uint offset) const;
00386 
00390   void declare_var_boundary(uint n)
00391   { m_pboundary= n; }
00392 
00394   // CASE expressions.
00396 
00397   int get_num_case_exprs() const
00398   { return m_num_case_exprs; }
00399 
00400   int push_case_expr_id()
00401   {
00402     if (m_case_expr_ids.append(m_num_case_exprs))
00403       return -1;
00404 
00405     return m_num_case_exprs++;
00406   }
00407 
00408   void pop_case_expr_id()
00409   { m_case_expr_ids.pop(); }
00410 
00411   int get_current_case_expr_id() const
00412   { return *m_case_expr_ids.back(); }
00413 
00415   // Labels.
00417 
00418   sp_label *push_label(THD *thd, LEX_STRING name, uint ip);
00419 
00420   sp_label *find_label(LEX_STRING name);
00421 
00422   sp_label *last_label()
00423   {
00424     sp_label *label= m_labels.head();
00425 
00426     if (!label && m_parent)
00427       label= m_parent->last_label();
00428 
00429     return label;
00430   }
00431 
00432   sp_label *pop_label()
00433   { return m_labels.pop(); }
00434 
00436   // Conditions.
00438 
00439   bool add_condition(THD *thd, LEX_STRING name, sp_condition_value *value);
00440 
00442   sp_condition_value *find_condition(LEX_STRING name,
00443                                      bool current_scope_only) const;
00444 
00446   // Handlers.
00448 
00449   sp_handler *add_handler(THD* thd, sp_handler::enum_type type);
00450 
00466   bool check_duplicate_handler(const sp_condition_value *cond_value) const;
00467 
00476   sp_handler *find_handler(const char *sql_state,
00477                            uint sql_errno,
00478                            Sql_condition::enum_warning_level level) const;
00479 
00481   // Cursors.
00483 
00484   bool add_cursor(LEX_STRING name);
00485 
00487   bool find_cursor(LEX_STRING name, uint *poff, bool current_scope_only) const;
00488 
00490   const LEX_STRING *find_cursor(uint offset) const;
00491 
00492   uint max_cursor_index() const
00493   { return m_max_cursor_index + m_cursors.elements(); }
00494 
00495   uint current_cursor_count() const
00496   { return m_cursor_offset + m_cursors.elements(); }
00497 
00498 private:
00502   sp_pcontext(sp_pcontext *prev, enum_scope scope);
00503 
00504   void init(uint var_offset, uint cursor_offset, int num_case_expressions);
00505 
00506   /* Prevent use of these */
00507   sp_pcontext(const sp_pcontext &);
00508   void operator=(sp_pcontext &);
00509 
00510 private:
00512   int m_level;
00513 
00521   uint m_max_var_index;
00522 
00524   uint m_max_cursor_index;
00525 
00527   sp_pcontext *m_parent;
00528 
00535   uint m_var_offset;
00536 
00538   uint m_cursor_offset;
00539 
00544   uint m_pboundary;
00545 
00546   int m_num_case_exprs;
00547 
00549   Dynamic_array<sp_variable *> m_vars;
00550 
00552   Dynamic_array<int> m_case_expr_ids;
00553 
00555   Dynamic_array<sp_condition *> m_conditions;
00556 
00558   Dynamic_array<LEX_STRING> m_cursors;
00559 
00561   Dynamic_array<sp_handler *> m_handlers;
00562 
00564   List<sp_label> m_labels;
00565 
00567   Dynamic_array<sp_pcontext *> m_children;
00568 
00570   enum_scope m_scope;
00571 }; // class sp_pcontext : public Sql_alloc
00572 
00573 
00574 #endif /* _SP_PCONTEXT_H_ */
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines