My Project
|
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_ */