1 /* -*- C++ -*- */ 2 /* Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved. 3 4 This program is free software; you can redistribute it and/or modify 5 it under the terms of the GNU General Public License, version 2.0, 6 as published by the Free Software Foundation. 7 8 This program is also distributed with certain software (including 9 but not limited to OpenSSL) that is licensed under separate terms, 10 as designated in a particular file or component or in included license 11 documentation. The authors of MySQL hereby grant you an additional 12 permission to link the program and your derivative works with the 13 separately licensed software that they have included with MySQL. 14 15 This program is distributed in the hope that it will be useful, 16 but WITHOUT ANY WARRANTY; without even the implied warranty of 17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 GNU General Public License, version 2.0, for more details. 19 20 You should have received a copy of the GNU General Public License 21 along with this program; if not, write to the Free Software Foundation, 22 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA */ 23 24 #ifndef _SP_PCONTEXT_H_ 25 #define _SP_PCONTEXT_H_ 26 27 #include "sql_string.h" // LEX_STRING 28 #include "mysql_com.h" // enum_field_types 29 #include "field.h" // Create_field 30 #include "sql_array.h" // Dynamic_array 31 32 33 /// This class represents a stored program variable or a parameter 34 /// (also referenced as 'SP-variable'). 35 36 class sp_variable : public Sql_alloc 37 { 38 public: 39 enum enum_mode 40 { 41 MODE_IN, 42 MODE_OUT, 43 MODE_INOUT 44 }; 45 46 /// Name of the SP-variable. 47 LEX_STRING name; 48 49 /// Field-type of the SP-variable. 50 enum enum_field_types type; 51 52 /// Mode of the SP-variable. 53 enum_mode mode; 54 55 /// The index to the variable's value in the runtime frame. 56 /// 57 /// It is calculated during parsing and used when creating sp_instr_set 58 /// instructions and Item_splocal items. I.e. values are set/referred by 59 /// array indexing in runtime. 60 uint offset; 61 62 /// Default value of the SP-variable (if any). 63 Item *default_value; 64 65 /// Full type information (field meta-data) of the SP-variable. 66 Create_field field_def; 67 68 public: sp_variable(LEX_STRING _name,enum_field_types _type,enum_mode _mode,uint _offset)69 sp_variable(LEX_STRING _name, enum_field_types _type, enum_mode _mode, 70 uint _offset) 71 :Sql_alloc(), 72 name(_name), 73 type(_type), 74 mode(_mode), 75 offset(_offset), 76 default_value(NULL) 77 { } 78 }; 79 80 /////////////////////////////////////////////////////////////////////////// 81 82 /// This class represents an SQL/PSM label. Can refer to the identifier 83 /// used with the "label_name:" construct which may precede some SQL/PSM 84 /// statements, or to an implicit implementation-dependent identifier which 85 /// the parser inserts before a high-level flow control statement such as 86 /// IF/WHILE/REPEAT/LOOP, when such statement is rewritten into a 87 /// combination of low-level jump/jump_if instructions and labels. 88 89 class sp_label : public Sql_alloc 90 { 91 public: 92 enum enum_type 93 { 94 /// Implicit label generated by parser. 95 IMPLICIT, 96 97 /// Label at BEGIN. 98 BEGIN, 99 100 /// Label at iteration control 101 ITERATION 102 }; 103 104 /// Name of the label. 105 LEX_STRING name; 106 107 /// Instruction pointer of the label. 108 uint ip; 109 110 /// Type of the label. 111 enum_type type; 112 113 /// Scope of the label. 114 class sp_pcontext *ctx; 115 116 public: sp_label(LEX_STRING _name,uint _ip,enum_type _type,sp_pcontext * _ctx)117 sp_label(LEX_STRING _name, uint _ip, enum_type _type, sp_pcontext *_ctx) 118 :Sql_alloc(), 119 name(_name), 120 ip(_ip), 121 type(_type), 122 ctx(_ctx) 123 { } 124 }; 125 126 /////////////////////////////////////////////////////////////////////////// 127 128 /// This class represents condition-value term in DECLARE CONDITION or 129 /// DECLARE HANDLER statements. sp_condition_value has little to do with 130 /// SQL-conditions. 131 /// 132 /// In some sense, this class is a union -- a set of filled attributes 133 /// depends on the sp_condition_value::type value. 134 135 class sp_condition_value : public Sql_alloc 136 { 137 public: 138 enum enum_type 139 { 140 ERROR_CODE, 141 SQLSTATE, 142 WARNING, 143 NOT_FOUND, 144 EXCEPTION 145 }; 146 147 /// Type of the condition value. 148 enum_type type; 149 150 /// SQLSTATE of the condition value. 151 char sql_state[SQLSTATE_LENGTH+1]; 152 153 /// MySQL error code of the condition value. 154 uint mysqlerr; 155 156 public: sp_condition_value(uint _mysqlerr)157 sp_condition_value(uint _mysqlerr) 158 :Sql_alloc(), 159 type(ERROR_CODE), 160 mysqlerr(_mysqlerr) 161 { } 162 sp_condition_value(const char * _sql_state)163 sp_condition_value(const char *_sql_state) 164 :Sql_alloc(), 165 type(SQLSTATE) 166 { 167 memcpy(sql_state, _sql_state, SQLSTATE_LENGTH); 168 sql_state[SQLSTATE_LENGTH]= 0; 169 } 170 sp_condition_value(enum_type _type)171 sp_condition_value(enum_type _type) 172 :Sql_alloc(), 173 type(_type) 174 { 175 DBUG_ASSERT(type != ERROR_CODE && type != SQLSTATE); 176 } 177 178 /// Check if two instances of sp_condition_value are equal or not. 179 /// 180 /// @param cv another instance of sp_condition_value to check. 181 /// 182 /// @return true if the instances are equal, false otherwise. 183 bool equals(const sp_condition_value *cv) const; 184 }; 185 186 /////////////////////////////////////////////////////////////////////////// 187 188 /// This class represents 'DECLARE CONDITION' statement. 189 /// sp_condition has little to do with SQL-conditions. 190 191 class sp_condition : public Sql_alloc 192 { 193 public: 194 /// Name of the condition. 195 LEX_STRING name; 196 197 /// Value of the condition. 198 sp_condition_value *value; 199 200 public: sp_condition(LEX_STRING _name,sp_condition_value * _value)201 sp_condition(LEX_STRING _name, sp_condition_value *_value) 202 :Sql_alloc(), 203 name(_name), 204 value(_value) 205 { } 206 }; 207 208 /////////////////////////////////////////////////////////////////////////// 209 210 /// This class represents 'DECLARE HANDLER' statement. 211 212 class sp_handler : public Sql_alloc 213 { 214 public: 215 /// Enumeration of possible handler types. 216 /// Note: UNDO handlers are not (and have never been) supported. 217 enum enum_type 218 { 219 EXIT, 220 CONTINUE 221 }; 222 223 /// Handler type. 224 enum_type type; 225 226 /// BEGIN..END block of the handler. 227 sp_pcontext *scope; 228 229 /// Conditions caught by this handler. 230 List<sp_condition_value> condition_values; 231 232 public: 233 /// The constructor. 234 /// 235 /// @param _type SQL-handler type. 236 /// @param _scope Handler scope. sp_handler(enum_type _type,sp_pcontext * _scope)237 sp_handler(enum_type _type, sp_pcontext *_scope) 238 :Sql_alloc(), 239 type(_type), 240 scope(_scope) 241 { } 242 }; 243 244 /////////////////////////////////////////////////////////////////////////// 245 246 /// The class represents parse-time context, which keeps track of declared 247 /// variables/parameters, conditions, handlers, cursors and labels. 248 /// 249 /// sp_context objects are organized in a tree according to the following 250 /// rules: 251 /// - one sp_pcontext object corresponds for for each BEGIN..END block; 252 /// - one sp_pcontext object corresponds for each exception handler; 253 /// - one additional sp_pcontext object is created to contain 254 /// Stored Program parameters. 255 /// 256 /// sp_pcontext objects are used both at parse-time and at runtime. 257 /// 258 /// During the parsing stage sp_pcontext objects are used: 259 /// - to look up defined names (e.g. declared variables and visible 260 /// labels); 261 /// - to check for duplicates; 262 /// - for error checking; 263 /// - to calculate offsets to be used at runtime. 264 /// 265 /// During the runtime phase, a tree of sp_pcontext objects is used: 266 /// - for error checking (e.g. to check correct number of parameters); 267 /// - to resolve SQL-handlers. 268 269 class sp_pcontext : public Sql_alloc 270 { 271 public: 272 enum enum_scope 273 { 274 /// REGULAR_SCOPE designates regular BEGIN ... END blocks. 275 REGULAR_SCOPE, 276 277 /// HANDLER_SCOPE designates SQL-handler blocks. 278 HANDLER_SCOPE 279 }; 280 281 public: 282 sp_pcontext(); 283 ~sp_pcontext(); 284 285 286 /// Create and push a new context in the tree. 287 288 /// @param thd thread context. 289 /// @param scope scope of the new parsing context. 290 /// @return the node created. 291 sp_pcontext *push_context(THD *thd, enum_scope scope); 292 293 /// Pop a node from the parsing context tree. 294 /// @return the parent node. 295 sp_pcontext *pop_context(); 296 parent_context()297 sp_pcontext *parent_context() const 298 { return m_parent; } 299 get_level()300 int get_level() const 301 { return m_level; } 302 303 /// Calculate and return the number of handlers to pop between the given 304 /// context and this one. 305 /// 306 /// @param ctx the other parsing context. 307 /// @param exclusive specifies if the last scope should be excluded. 308 /// 309 /// @return the number of handlers to pop between the given context and 310 /// this one. If 'exclusive' is true, don't count the last scope we are 311 /// leaving; this is used for LEAVE where we will jump to the hpop 312 /// instructions. 313 uint diff_handlers(const sp_pcontext *ctx, bool exclusive) const; 314 315 /// Calculate and return the number of cursors to pop between the given 316 /// context and this one. 317 /// 318 /// @param ctx the other parsing context. 319 /// @param exclusive specifies if the last scope should be excluded. 320 /// 321 /// @return the number of cursors to pop between the given context and 322 /// this one. If 'exclusive' is true, don't count the last scope we are 323 /// leaving; this is used for LEAVE where we will jump to the cpop 324 /// instructions. 325 uint diff_cursors(const sp_pcontext *ctx, bool exclusive) const; 326 327 ///////////////////////////////////////////////////////////////////////// 328 // SP-variables (parameters and variables). 329 ///////////////////////////////////////////////////////////////////////// 330 331 /// @return the maximum number of variables used in this and all child 332 /// contexts. For the root parsing context, this gives us the number of 333 /// slots needed for variables during the runtime phase. max_var_index()334 uint max_var_index() const 335 { return m_max_var_index; } 336 337 /// @return the current number of variables used in the parent contexts 338 /// (from the root), including this context. current_var_count()339 uint current_var_count() const 340 { return m_var_offset + m_vars.elements(); } 341 342 /// @return the number of variables in this context alone. context_var_count()343 uint context_var_count() const 344 { return m_vars.elements(); } 345 346 /// @return map index in this parsing context to runtime offset. var_context2runtime(uint i)347 uint var_context2runtime(uint i) const 348 { return m_var_offset + i; } 349 350 /// Add SP-variable to the parsing context. 351 /// 352 /// @param thd Thread context. 353 /// @param name Name of the SP-variable. 354 /// @param type Type of the SP-variable. 355 /// @param mode Mode of the SP-variable. 356 /// 357 /// @return instance of newly added SP-variable. 358 sp_variable *add_variable(THD *thd, 359 LEX_STRING name, 360 enum enum_field_types type, 361 sp_variable::enum_mode mode); 362 363 /// Retrieve full type information about SP-variables in this parsing 364 /// context and its children. 365 /// 366 /// @param field_def_lst[out] Container to store type information. 367 void retrieve_field_definitions(List<Create_field> *field_def_lst) const; 368 369 /// Find SP-variable by name. 370 /// 371 /// The function does a linear search (from newer to older variables, 372 /// in case we have shadowed names). 373 /// 374 /// The function is called only at parsing time. 375 /// 376 /// @param name Variable name. 377 /// @param current_scope_only A flag if we search only in current scope. 378 /// 379 /// @return instance of found SP-variable, or NULL if not found. 380 sp_variable *find_variable(LEX_STRING name, bool current_scope_only) const; 381 382 /// Find SP-variable by the offset in the root parsing context. 383 /// 384 /// The function is used for two things: 385 /// - When evaluating parameters at the beginning, and setting out parameters 386 /// at the end, of invocation. (Top frame only, so no recursion then.) 387 /// - For printing of sp_instr_set. (Debug mode only.) 388 /// 389 /// @param offset Variable offset in the root parsing context. 390 /// 391 /// @return instance of found SP-variable, or NULL if not found. 392 sp_variable *find_variable(uint offset) const; 393 394 /// Set the current scope boundary (for default values). 395 /// 396 /// @param n The number of variables to skip. declare_var_boundary(uint n)397 void declare_var_boundary(uint n) 398 { m_pboundary= n; } 399 400 ///////////////////////////////////////////////////////////////////////// 401 // CASE expressions. 402 ///////////////////////////////////////////////////////////////////////// 403 get_num_case_exprs()404 int get_num_case_exprs() const 405 { return m_num_case_exprs; } 406 push_case_expr_id()407 int push_case_expr_id() 408 { 409 if (m_case_expr_ids.append(m_num_case_exprs)) 410 return -1; 411 412 return m_num_case_exprs++; 413 } 414 pop_case_expr_id()415 void pop_case_expr_id() 416 { m_case_expr_ids.pop(); } 417 get_current_case_expr_id()418 int get_current_case_expr_id() const 419 { return *m_case_expr_ids.back(); } 420 421 ///////////////////////////////////////////////////////////////////////// 422 // Labels. 423 ///////////////////////////////////////////////////////////////////////// 424 425 sp_label *push_label(THD *thd, LEX_STRING name, uint ip); 426 427 sp_label *find_label(LEX_STRING name); 428 last_label()429 sp_label *last_label() 430 { 431 sp_label *label= m_labels.head(); 432 433 if (!label && m_parent) 434 label= m_parent->last_label(); 435 436 return label; 437 } 438 pop_label()439 sp_label *pop_label() 440 { return m_labels.pop(); } 441 442 ///////////////////////////////////////////////////////////////////////// 443 // Conditions. 444 ///////////////////////////////////////////////////////////////////////// 445 446 bool add_condition(THD *thd, LEX_STRING name, sp_condition_value *value); 447 448 /// See comment for find_variable() above. 449 sp_condition_value *find_condition(LEX_STRING name, 450 bool current_scope_only) const; 451 452 ///////////////////////////////////////////////////////////////////////// 453 // Handlers. 454 ///////////////////////////////////////////////////////////////////////// 455 456 sp_handler *add_handler(THD* thd, sp_handler::enum_type type); 457 458 /// This is an auxilary parsing-time function to check if an SQL-handler 459 /// exists in the current parsing context (current scope) for the given 460 /// SQL-condition. This function is used to check for duplicates during 461 /// the parsing phase. 462 /// 463 /// This function can not be used during the runtime phase to check 464 /// SQL-handler existence because it searches for the SQL-handler in the 465 /// current scope only (during runtime, current and parent scopes 466 /// should be checked according to the SQL-handler resolution rules). 467 /// 468 /// @param condition_value the handler condition value 469 /// (not SQL-condition!). 470 /// 471 /// @retval true if such SQL-handler exists. 472 /// @retval false otherwise. 473 bool check_duplicate_handler(const sp_condition_value *cond_value) const; 474 475 /// Find an SQL handler for the given SQL condition according to the 476 /// SQL-handler resolution rules. This function is used at runtime. 477 /// 478 /// @param sql_state The SQL condition state 479 /// @param sql_errno The error code 480 /// @param level The SQL condition level 481 /// 482 /// @return a pointer to the found SQL-handler or NULL. 483 sp_handler *find_handler(const char *sql_state, 484 uint sql_errno, 485 Sql_condition::enum_warning_level level) const; 486 487 ///////////////////////////////////////////////////////////////////////// 488 // Cursors. 489 ///////////////////////////////////////////////////////////////////////// 490 491 bool add_cursor(LEX_STRING name); 492 493 /// See comment for find_variable() above. 494 bool find_cursor(LEX_STRING name, uint *poff, bool current_scope_only) const; 495 496 /// Find cursor by offset (for debugging only). 497 const LEX_STRING *find_cursor(uint offset) const; 498 max_cursor_index()499 uint max_cursor_index() const 500 { return m_max_cursor_index + m_cursors.elements(); } 501 current_cursor_count()502 uint current_cursor_count() const 503 { return m_cursor_offset + m_cursors.elements(); } 504 505 private: 506 /// Constructor for a tree node. 507 /// @param prev the parent parsing context 508 /// @param scope scope of this parsing context 509 sp_pcontext(sp_pcontext *prev, enum_scope scope); 510 511 void init(uint var_offset, uint cursor_offset, int num_case_expressions); 512 513 /* Prevent use of these */ 514 sp_pcontext(const sp_pcontext &); 515 void operator=(sp_pcontext &); 516 517 private: 518 /// Level of the corresponding BEGIN..END block (0 means the topmost block). 519 int m_level; 520 521 /// m_max_var_index -- number of variables (including all types of arguments) 522 /// in this context including all children contexts. 523 /// 524 /// m_max_var_index >= m_vars.elements(). 525 /// 526 /// m_max_var_index of the root parsing context contains number of all 527 /// variables (including arguments) in all enclosed contexts. 528 uint m_max_var_index; 529 530 /// The maximum sub context's framesizes. 531 uint m_max_cursor_index; 532 533 /// Parent context. 534 sp_pcontext *m_parent; 535 536 /// An index of the first SP-variable in this parsing context. The index 537 /// belongs to a runtime table of SP-variables. 538 /// 539 /// Note: 540 /// - m_var_offset is 0 for root parsing context; 541 /// - m_var_offset is different for all nested parsing contexts. 542 uint m_var_offset; 543 544 /// Cursor offset for this context. 545 uint m_cursor_offset; 546 547 /// Boundary for finding variables in this context. This is the number of 548 /// variables currently "invisible" to default clauses. This is normally 0, 549 /// but will be larger during parsing of DECLARE ... DEFAULT, to get the 550 /// scope right for DEFAULT values. 551 uint m_pboundary; 552 553 int m_num_case_exprs; 554 555 /// SP parameters/variables. 556 Dynamic_array<sp_variable *> m_vars; 557 558 /// Stack of CASE expression ids. 559 Dynamic_array<int> m_case_expr_ids; 560 561 /// Stack of SQL-conditions. 562 Dynamic_array<sp_condition *> m_conditions; 563 564 /// Stack of cursors. 565 Dynamic_array<LEX_STRING> m_cursors; 566 567 /// Stack of SQL-handlers. 568 Dynamic_array<sp_handler *> m_handlers; 569 570 /// List of labels. 571 List<sp_label> m_labels; 572 573 /// Children contexts, used for destruction. 574 Dynamic_array<sp_pcontext *> m_children; 575 576 /// Scope of this parsing context. 577 enum_scope m_scope; 578 }; // class sp_pcontext : public Sql_alloc 579 580 581 #endif /* _SP_PCONTEXT_H_ */ 582