| 1 | /* -*- C++ -*- */ | 
|---|
| 2 | /* Copyright (c) 2002, 2010, 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 as published by | 
|---|
| 6 | the Free Software Foundation; version 2 of the License. | 
|---|
| 7 |  | 
|---|
| 8 | This program is distributed in the hope that it will be useful, | 
|---|
| 9 | but WITHOUT ANY WARRANTY; without even the implied warranty of | 
|---|
| 10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
|---|
| 11 | GNU General Public License for more details. | 
|---|
| 12 |  | 
|---|
| 13 | You should have received a copy of the GNU General Public License | 
|---|
| 14 | along with this program; if not, write to the Free Software | 
|---|
| 15 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA */ | 
|---|
| 16 |  | 
|---|
| 17 | #ifndef _SP_H_ | 
|---|
| 18 | #define _SP_H_ | 
|---|
| 19 |  | 
|---|
| 20 | #include "my_global.h"                          /* NO_EMBEDDED_ACCESS_CHECKS */ | 
|---|
| 21 | #include "sql_string.h"                         // LEX_STRING | 
|---|
| 22 | #include "sql_cmd.h" | 
|---|
| 23 | #include "mdl.h" | 
|---|
| 24 |  | 
|---|
| 25 | class Field; | 
|---|
| 26 | class Open_tables_backup; | 
|---|
| 27 | class Open_tables_state; | 
|---|
| 28 | class Query_arena; | 
|---|
| 29 | class Query_tables_list; | 
|---|
| 30 | class Sroutine_hash_entry; | 
|---|
| 31 | class THD; | 
|---|
| 32 | class sp_cache; | 
|---|
| 33 | class sp_head; | 
|---|
| 34 | class sp_package; | 
|---|
| 35 | class sp_pcontext; | 
|---|
| 36 | class sp_name; | 
|---|
| 37 | class Database_qualified_name; | 
|---|
| 38 | struct st_sp_chistics; | 
|---|
| 39 | class Stored_program_creation_ctx; | 
|---|
| 40 | struct LEX; | 
|---|
| 41 | struct TABLE; | 
|---|
| 42 | struct TABLE_LIST; | 
|---|
| 43 | typedef struct st_hash HASH; | 
|---|
| 44 | template <typename T> class SQL_I_List; | 
|---|
| 45 |  | 
|---|
| 46 | /* | 
|---|
| 47 | Values for the type enum. This reflects the order of the enum declaration | 
|---|
| 48 | in the CREATE TABLE command. | 
|---|
| 49 | */ | 
|---|
| 50 | enum stored_procedure_type | 
|---|
| 51 | { | 
|---|
| 52 | TYPE_ENUM_FUNCTION=1, | 
|---|
| 53 | TYPE_ENUM_PROCEDURE=2, | 
|---|
| 54 | TYPE_ENUM_PACKAGE=3, | 
|---|
| 55 | TYPE_ENUM_PACKAGE_BODY=4, | 
|---|
| 56 | TYPE_ENUM_TRIGGER=5, | 
|---|
| 57 | TYPE_ENUM_PROXY=6 | 
|---|
| 58 | }; | 
|---|
| 59 |  | 
|---|
| 60 |  | 
|---|
| 61 | class Sp_handler | 
|---|
| 62 | { | 
|---|
| 63 | bool sp_resolve_package_routine_explicit(THD *thd, | 
|---|
| 64 | sp_head *caller, | 
|---|
| 65 | sp_name *name, | 
|---|
| 66 | const Sp_handler **pkg_routine_hndlr, | 
|---|
| 67 | Database_qualified_name *pkgname) | 
|---|
| 68 | const; | 
|---|
| 69 | bool sp_resolve_package_routine_implicit(THD *thd, | 
|---|
| 70 | sp_head *caller, | 
|---|
| 71 | sp_name *name, | 
|---|
| 72 | const Sp_handler **pkg_routine_hndlr, | 
|---|
| 73 | Database_qualified_name *pkgname) | 
|---|
| 74 | const; | 
|---|
| 75 | protected: | 
|---|
| 76 | int db_find_routine_aux(THD *thd, const Database_qualified_name *name, | 
|---|
| 77 | TABLE *table) const; | 
|---|
| 78 | int db_find_routine(THD *thd, const Database_qualified_name *name, | 
|---|
| 79 | sp_head **sphp) const; | 
|---|
| 80 | int db_find_and_cache_routine(THD *thd, | 
|---|
| 81 | const Database_qualified_name *name, | 
|---|
| 82 | sp_head **sp) const; | 
|---|
| 83 | int db_load_routine(THD *thd, const Database_qualified_name *name, | 
|---|
| 84 | sp_head **sphp, | 
|---|
| 85 | sql_mode_t sql_mode, | 
|---|
| 86 | const LEX_CSTRING ¶ms, | 
|---|
| 87 | const LEX_CSTRING &returns, | 
|---|
| 88 | const LEX_CSTRING &body, | 
|---|
| 89 | const st_sp_chistics &chistics, | 
|---|
| 90 | const AUTHID &definer, | 
|---|
| 91 | longlong created, longlong modified, | 
|---|
| 92 | sp_package *parent, | 
|---|
| 93 | Stored_program_creation_ctx *creation_ctx) const; | 
|---|
| 94 | int sp_drop_routine_internal(THD *thd, | 
|---|
| 95 | const Database_qualified_name *name, | 
|---|
| 96 | TABLE *table) const; | 
|---|
| 97 |  | 
|---|
| 98 | sp_head *sp_clone_and_link_routine(THD *thd, | 
|---|
| 99 | const Database_qualified_name *name, | 
|---|
| 100 | sp_head *sp) const; | 
|---|
| 101 | int sp_cache_package_routine(THD *thd, | 
|---|
| 102 | const LEX_CSTRING &pkgname_cstr, | 
|---|
| 103 | const Database_qualified_name *name, | 
|---|
| 104 | bool lookup_only, sp_head **sp) const; | 
|---|
| 105 | int sp_cache_package_routine(THD *thd, | 
|---|
| 106 | const Database_qualified_name *name, | 
|---|
| 107 | bool lookup_only, sp_head **sp) const; | 
|---|
| 108 | sp_head *sp_find_package_routine(THD *thd, | 
|---|
| 109 | const LEX_CSTRING pkgname_str, | 
|---|
| 110 | const Database_qualified_name *name, | 
|---|
| 111 | bool cache_only) const; | 
|---|
| 112 | sp_head *sp_find_package_routine(THD *thd, | 
|---|
| 113 | const Database_qualified_name *name, | 
|---|
| 114 | bool cache_only) const; | 
|---|
| 115 | public: // TODO: make it private or protected | 
|---|
| 116 | virtual int sp_find_and_drop_routine(THD *thd, TABLE *table, | 
|---|
| 117 | const Database_qualified_name *name) | 
|---|
| 118 | const; | 
|---|
| 119 |  | 
|---|
| 120 | public: | 
|---|
| 121 | virtual ~Sp_handler() {} | 
|---|
| 122 | static const Sp_handler *handler(enum enum_sql_command cmd); | 
|---|
| 123 | static const Sp_handler *handler(stored_procedure_type type); | 
|---|
| 124 | static const Sp_handler *handler(MDL_key::enum_mdl_namespace ns); | 
|---|
| 125 | /* | 
|---|
| 126 | Return a handler only those SP objects that store | 
|---|
| 127 | definitions in the mysql.proc system table | 
|---|
| 128 | */ | 
|---|
| 129 | static const Sp_handler *handler_mysql_proc(stored_procedure_type type) | 
|---|
| 130 | { | 
|---|
| 131 | const Sp_handler *sph= handler(type); | 
|---|
| 132 | return sph ? sph->sp_handler_mysql_proc() : NULL; | 
|---|
| 133 | } | 
|---|
| 134 |  | 
|---|
| 135 | static bool eq_routine_name(const LEX_CSTRING &name1, | 
|---|
| 136 | const LEX_CSTRING &name2) | 
|---|
| 137 | { | 
|---|
| 138 | return my_strnncoll(system_charset_info, | 
|---|
| 139 | (const uchar *) name1.str, name1.length, | 
|---|
| 140 | (const uchar *) name2.str, name2.length) == 0; | 
|---|
| 141 | } | 
|---|
| 142 | const char *type_str() const { return type_lex_cstring().str; } | 
|---|
| 143 | virtual const char *show_create_routine_col1_caption() const | 
|---|
| 144 | { | 
|---|
| 145 | DBUG_ASSERT(0); | 
|---|
| 146 | return ""; | 
|---|
| 147 | } | 
|---|
| 148 | virtual const char *show_create_routine_col3_caption() const | 
|---|
| 149 | { | 
|---|
| 150 | DBUG_ASSERT(0); | 
|---|
| 151 | return ""; | 
|---|
| 152 | } | 
|---|
| 153 | virtual const Sp_handler *package_routine_handler() const | 
|---|
| 154 | { | 
|---|
| 155 | return this; | 
|---|
| 156 | } | 
|---|
| 157 | virtual stored_procedure_type type() const= 0; | 
|---|
| 158 | virtual LEX_CSTRING type_lex_cstring() const= 0; | 
|---|
| 159 | virtual LEX_CSTRING empty_body_lex_cstring(sql_mode_t mode) const | 
|---|
| 160 | { | 
|---|
| 161 | static LEX_CSTRING m_empty_body= {STRING_WITH_LEN( "???")}; | 
|---|
| 162 | DBUG_ASSERT(0); | 
|---|
| 163 | return m_empty_body; | 
|---|
| 164 | } | 
|---|
| 165 | virtual MDL_key::enum_mdl_namespace get_mdl_type() const= 0; | 
|---|
| 166 | virtual const Sp_handler *sp_handler_mysql_proc() const { return this; } | 
|---|
| 167 | virtual sp_cache **get_cache(THD *) const { return NULL; } | 
|---|
| 168 | #ifndef NO_EMBEDDED_ACCESS_CHECKS | 
|---|
| 169 | virtual HASH *get_priv_hash() const { return NULL; } | 
|---|
| 170 | #endif | 
|---|
| 171 | virtual ulong recursion_depth(THD *thd) const { return 0; } | 
|---|
| 172 | /** | 
|---|
| 173 | Return appropriate error about recursion limit reaching | 
|---|
| 174 |  | 
|---|
| 175 | @param thd  Thread handle | 
|---|
| 176 | @param sp   SP routine | 
|---|
| 177 |  | 
|---|
| 178 | @remark For functions and triggers we return error about | 
|---|
| 179 | prohibited recursion. For stored procedures we | 
|---|
| 180 | return about reaching recursion limit. | 
|---|
| 181 | */ | 
|---|
| 182 | virtual void recursion_level_error(THD *thd, const sp_head *sp) const | 
|---|
| 183 | { | 
|---|
| 184 | my_error(ER_SP_NO_RECURSION, MYF(0)); | 
|---|
| 185 | } | 
|---|
| 186 | virtual bool add_instr_freturn(THD *thd, sp_head *sp, | 
|---|
| 187 | sp_pcontext *spcont, | 
|---|
| 188 | Item *item, LEX *lex) const; | 
|---|
| 189 | virtual bool add_instr_preturn(THD *thd, sp_head *sp, | 
|---|
| 190 | sp_pcontext *spcont) const; | 
|---|
| 191 |  | 
|---|
| 192 | void add_used_routine(Query_tables_list *prelocking_ctx, | 
|---|
| 193 | Query_arena *arena, | 
|---|
| 194 | const Database_qualified_name *name) const; | 
|---|
| 195 |  | 
|---|
| 196 | bool sp_resolve_package_routine(THD *thd, | 
|---|
| 197 | sp_head *caller, | 
|---|
| 198 | sp_name *name, | 
|---|
| 199 | const Sp_handler **pkg_routine_handler, | 
|---|
| 200 | Database_qualified_name *pkgname) const; | 
|---|
| 201 | virtual sp_head *sp_find_routine(THD *thd, | 
|---|
| 202 | const Database_qualified_name *name, | 
|---|
| 203 | bool cache_only) const; | 
|---|
| 204 | virtual int sp_cache_routine(THD *thd, const Database_qualified_name *name, | 
|---|
| 205 | bool lookup_only, sp_head **sp) const; | 
|---|
| 206 |  | 
|---|
| 207 | int sp_cache_routine_reentrant(THD *thd, | 
|---|
| 208 | const Database_qualified_name *nm, | 
|---|
| 209 | sp_head **sp) const; | 
|---|
| 210 |  | 
|---|
| 211 | bool sp_exist_routines(THD *thd, TABLE_LIST *procs) const; | 
|---|
| 212 | bool sp_show_create_routine(THD *thd, | 
|---|
| 213 | const Database_qualified_name *name) const; | 
|---|
| 214 |  | 
|---|
| 215 | bool sp_create_routine(THD *thd, const sp_head *sp) const; | 
|---|
| 216 |  | 
|---|
| 217 | int sp_update_routine(THD *thd, const Database_qualified_name *name, | 
|---|
| 218 | const st_sp_chistics *chistics) const; | 
|---|
| 219 |  | 
|---|
| 220 | int sp_drop_routine(THD *thd, const Database_qualified_name *name) const; | 
|---|
| 221 |  | 
|---|
| 222 | sp_head *sp_load_for_information_schema(THD *thd, TABLE *proc_table, | 
|---|
| 223 | const LEX_CSTRING &db, | 
|---|
| 224 | const LEX_CSTRING &name, | 
|---|
| 225 | const LEX_CSTRING ¶ms, | 
|---|
| 226 | const LEX_CSTRING &returns, | 
|---|
| 227 | sql_mode_t sql_mode, | 
|---|
| 228 | bool *free_sp_head) const; | 
|---|
| 229 |  | 
|---|
| 230 | /* | 
|---|
| 231 | Make a SHOW CREATE statement. | 
|---|
| 232 | @retval   true on error | 
|---|
| 233 | @retval   false on success | 
|---|
| 234 | */ | 
|---|
| 235 | virtual bool show_create_sp(THD *thd, String *buf, | 
|---|
| 236 | const LEX_CSTRING &db, | 
|---|
| 237 | const LEX_CSTRING &name, | 
|---|
| 238 | const LEX_CSTRING ¶ms, | 
|---|
| 239 | const LEX_CSTRING &returns, | 
|---|
| 240 | const LEX_CSTRING &body, | 
|---|
| 241 | const st_sp_chistics &chistics, | 
|---|
| 242 | const AUTHID &definer, | 
|---|
| 243 | const DDL_options_st ddl_options, | 
|---|
| 244 | sql_mode_t sql_mode) const; | 
|---|
| 245 |  | 
|---|
| 246 | }; | 
|---|
| 247 |  | 
|---|
| 248 |  | 
|---|
| 249 | class Sp_handler_procedure: public Sp_handler | 
|---|
| 250 | { | 
|---|
| 251 | public: | 
|---|
| 252 | stored_procedure_type type() const { return TYPE_ENUM_PROCEDURE; } | 
|---|
| 253 | LEX_CSTRING type_lex_cstring() const | 
|---|
| 254 | { | 
|---|
| 255 | static LEX_CSTRING m_type_str= { STRING_WITH_LEN( "PROCEDURE")}; | 
|---|
| 256 | return m_type_str; | 
|---|
| 257 | } | 
|---|
| 258 | LEX_CSTRING empty_body_lex_cstring(sql_mode_t mode) const; | 
|---|
| 259 | const char *show_create_routine_col1_caption() const | 
|---|
| 260 | { | 
|---|
| 261 | return "Procedure"; | 
|---|
| 262 | } | 
|---|
| 263 | const char *show_create_routine_col3_caption() const | 
|---|
| 264 | { | 
|---|
| 265 | return "Create Procedure"; | 
|---|
| 266 | } | 
|---|
| 267 | MDL_key::enum_mdl_namespace get_mdl_type() const | 
|---|
| 268 | { | 
|---|
| 269 | return MDL_key::PROCEDURE; | 
|---|
| 270 | } | 
|---|
| 271 | const Sp_handler *package_routine_handler() const; | 
|---|
| 272 | sp_cache **get_cache(THD *) const; | 
|---|
| 273 | #ifndef NO_EMBEDDED_ACCESS_CHECKS | 
|---|
| 274 | HASH *get_priv_hash() const; | 
|---|
| 275 | #endif | 
|---|
| 276 | ulong recursion_depth(THD *thd) const; | 
|---|
| 277 | void recursion_level_error(THD *thd, const sp_head *sp) const; | 
|---|
| 278 | bool add_instr_preturn(THD *thd, sp_head *sp, sp_pcontext *spcont) const; | 
|---|
| 279 | }; | 
|---|
| 280 |  | 
|---|
| 281 |  | 
|---|
| 282 | class Sp_handler_package_procedure: public Sp_handler_procedure | 
|---|
| 283 | { | 
|---|
| 284 | public: | 
|---|
| 285 | int sp_cache_routine(THD *thd, const Database_qualified_name *name, | 
|---|
| 286 | bool lookup_only, sp_head **sp) const | 
|---|
| 287 | { | 
|---|
| 288 | return sp_cache_package_routine(thd, name, lookup_only, sp); | 
|---|
| 289 | } | 
|---|
| 290 | sp_head *sp_find_routine(THD *thd, | 
|---|
| 291 | const Database_qualified_name *name, | 
|---|
| 292 | bool cache_only) const | 
|---|
| 293 | { | 
|---|
| 294 | return sp_find_package_routine(thd, name, cache_only); | 
|---|
| 295 | } | 
|---|
| 296 | }; | 
|---|
| 297 |  | 
|---|
| 298 |  | 
|---|
| 299 | class Sp_handler_function: public Sp_handler | 
|---|
| 300 | { | 
|---|
| 301 | public: | 
|---|
| 302 | stored_procedure_type type() const { return TYPE_ENUM_FUNCTION; } | 
|---|
| 303 | LEX_CSTRING type_lex_cstring() const | 
|---|
| 304 | { | 
|---|
| 305 | static LEX_CSTRING m_type_str= { STRING_WITH_LEN( "FUNCTION")}; | 
|---|
| 306 | return m_type_str; | 
|---|
| 307 | } | 
|---|
| 308 | LEX_CSTRING empty_body_lex_cstring(sql_mode_t mode) const; | 
|---|
| 309 | const char *show_create_routine_col1_caption() const | 
|---|
| 310 | { | 
|---|
| 311 | return "Function"; | 
|---|
| 312 | } | 
|---|
| 313 | const char *show_create_routine_col3_caption() const | 
|---|
| 314 | { | 
|---|
| 315 | return "Create Function"; | 
|---|
| 316 | } | 
|---|
| 317 | MDL_key::enum_mdl_namespace get_mdl_type() const | 
|---|
| 318 | { | 
|---|
| 319 | return MDL_key::FUNCTION; | 
|---|
| 320 | } | 
|---|
| 321 | const Sp_handler *package_routine_handler() const; | 
|---|
| 322 | sp_cache **get_cache(THD *) const; | 
|---|
| 323 | #ifndef NO_EMBEDDED_ACCESS_CHECKS | 
|---|
| 324 | HASH *get_priv_hash() const; | 
|---|
| 325 | #endif | 
|---|
| 326 | bool add_instr_freturn(THD *thd, sp_head *sp, sp_pcontext *spcont, | 
|---|
| 327 | Item *item, LEX *lex) const; | 
|---|
| 328 | }; | 
|---|
| 329 |  | 
|---|
| 330 |  | 
|---|
| 331 | class Sp_handler_package_function: public Sp_handler_function | 
|---|
| 332 | { | 
|---|
| 333 | public: | 
|---|
| 334 | int sp_cache_routine(THD *thd, const Database_qualified_name *name, | 
|---|
| 335 | bool lookup_only, sp_head **sp) const | 
|---|
| 336 | { | 
|---|
| 337 | return sp_cache_package_routine(thd, name, lookup_only, sp); | 
|---|
| 338 | } | 
|---|
| 339 | sp_head *sp_find_routine(THD *thd, | 
|---|
| 340 | const Database_qualified_name *name, | 
|---|
| 341 | bool cache_only) const | 
|---|
| 342 | { | 
|---|
| 343 | return sp_find_package_routine(thd, name, cache_only); | 
|---|
| 344 | } | 
|---|
| 345 | }; | 
|---|
| 346 |  | 
|---|
| 347 |  | 
|---|
| 348 | class Sp_handler_package: public Sp_handler | 
|---|
| 349 | { | 
|---|
| 350 | public: | 
|---|
| 351 | bool show_create_sp(THD *thd, String *buf, | 
|---|
| 352 | const LEX_CSTRING &db, | 
|---|
| 353 | const LEX_CSTRING &name, | 
|---|
| 354 | const LEX_CSTRING ¶ms, | 
|---|
| 355 | const LEX_CSTRING &returns, | 
|---|
| 356 | const LEX_CSTRING &body, | 
|---|
| 357 | const st_sp_chistics &chistics, | 
|---|
| 358 | const AUTHID &definer, | 
|---|
| 359 | const DDL_options_st ddl_options, | 
|---|
| 360 | sql_mode_t sql_mode) const; | 
|---|
| 361 | }; | 
|---|
| 362 |  | 
|---|
| 363 |  | 
|---|
| 364 | class Sp_handler_package_spec: public Sp_handler_package | 
|---|
| 365 | { | 
|---|
| 366 | public: // TODO: make it private or protected | 
|---|
| 367 | int sp_find_and_drop_routine(THD *thd, TABLE *table, | 
|---|
| 368 | const Database_qualified_name *name) | 
|---|
| 369 | const; | 
|---|
| 370 | public: | 
|---|
| 371 | stored_procedure_type type() const { return TYPE_ENUM_PACKAGE; } | 
|---|
| 372 | LEX_CSTRING type_lex_cstring() const | 
|---|
| 373 | { | 
|---|
| 374 | static LEX_CSTRING m_type_str= {STRING_WITH_LEN( "PACKAGE")}; | 
|---|
| 375 | return m_type_str; | 
|---|
| 376 | } | 
|---|
| 377 | LEX_CSTRING empty_body_lex_cstring(sql_mode_t mode) const | 
|---|
| 378 | { | 
|---|
| 379 | static LEX_CSTRING m_empty_body= {STRING_WITH_LEN( "BEGIN END")}; | 
|---|
| 380 | return m_empty_body; | 
|---|
| 381 | } | 
|---|
| 382 | const char *show_create_routine_col1_caption() const | 
|---|
| 383 | { | 
|---|
| 384 | return "Package"; | 
|---|
| 385 | } | 
|---|
| 386 | const char *show_create_routine_col3_caption() const | 
|---|
| 387 | { | 
|---|
| 388 | return "Create Package"; | 
|---|
| 389 | } | 
|---|
| 390 | MDL_key::enum_mdl_namespace get_mdl_type() const | 
|---|
| 391 | { | 
|---|
| 392 | return MDL_key::PACKAGE_BODY; | 
|---|
| 393 | } | 
|---|
| 394 | sp_cache **get_cache(THD *) const; | 
|---|
| 395 | #ifndef NO_EMBEDDED_ACCESS_CHECKS | 
|---|
| 396 | HASH *get_priv_hash() const; | 
|---|
| 397 | #endif | 
|---|
| 398 | }; | 
|---|
| 399 |  | 
|---|
| 400 |  | 
|---|
| 401 | class Sp_handler_package_body: public Sp_handler_package | 
|---|
| 402 | { | 
|---|
| 403 | public: | 
|---|
| 404 | stored_procedure_type type() const { return TYPE_ENUM_PACKAGE_BODY; } | 
|---|
| 405 | LEX_CSTRING type_lex_cstring() const | 
|---|
| 406 | { | 
|---|
| 407 | static LEX_CSTRING m_type_str= {STRING_WITH_LEN( "PACKAGE BODY")}; | 
|---|
| 408 | return m_type_str; | 
|---|
| 409 | } | 
|---|
| 410 | LEX_CSTRING empty_body_lex_cstring(sql_mode_t mode) const | 
|---|
| 411 | { | 
|---|
| 412 | static LEX_CSTRING m_empty_body= {STRING_WITH_LEN( "BEGIN END")}; | 
|---|
| 413 | return m_empty_body; | 
|---|
| 414 | } | 
|---|
| 415 | const char *show_create_routine_col1_caption() const | 
|---|
| 416 | { | 
|---|
| 417 | return "Package body"; | 
|---|
| 418 | } | 
|---|
| 419 | const char *show_create_routine_col3_caption() const | 
|---|
| 420 | { | 
|---|
| 421 | return "Create Package Body"; | 
|---|
| 422 | } | 
|---|
| 423 | MDL_key::enum_mdl_namespace get_mdl_type() const | 
|---|
| 424 | { | 
|---|
| 425 | return MDL_key::PACKAGE_BODY; | 
|---|
| 426 | } | 
|---|
| 427 | sp_cache **get_cache(THD *) const; | 
|---|
| 428 | #ifndef NO_EMBEDDED_ACCESS_CHECKS | 
|---|
| 429 | HASH *get_priv_hash() const; | 
|---|
| 430 | #endif | 
|---|
| 431 | }; | 
|---|
| 432 |  | 
|---|
| 433 |  | 
|---|
| 434 | class Sp_handler_trigger: public Sp_handler | 
|---|
| 435 | { | 
|---|
| 436 | public: | 
|---|
| 437 | stored_procedure_type type() const { return TYPE_ENUM_TRIGGER; } | 
|---|
| 438 | LEX_CSTRING type_lex_cstring() const | 
|---|
| 439 | { | 
|---|
| 440 | static LEX_CSTRING m_type_str= { STRING_WITH_LEN( "TRIGGER")}; | 
|---|
| 441 | return m_type_str; | 
|---|
| 442 | } | 
|---|
| 443 | MDL_key::enum_mdl_namespace get_mdl_type() const | 
|---|
| 444 | { | 
|---|
| 445 | DBUG_ASSERT(0); | 
|---|
| 446 | return MDL_key::TRIGGER; | 
|---|
| 447 | } | 
|---|
| 448 | const Sp_handler *sp_handler_mysql_proc() const { return NULL; } | 
|---|
| 449 | }; | 
|---|
| 450 |  | 
|---|
| 451 |  | 
|---|
| 452 | extern MYSQL_PLUGIN_IMPORT Sp_handler_function sp_handler_function; | 
|---|
| 453 | extern MYSQL_PLUGIN_IMPORT Sp_handler_procedure sp_handler_procedure; | 
|---|
| 454 | extern MYSQL_PLUGIN_IMPORT Sp_handler_package_spec sp_handler_package_spec; | 
|---|
| 455 | extern MYSQL_PLUGIN_IMPORT Sp_handler_package_body sp_handler_package_body; | 
|---|
| 456 | extern MYSQL_PLUGIN_IMPORT Sp_handler_package_function sp_handler_package_function; | 
|---|
| 457 | extern MYSQL_PLUGIN_IMPORT Sp_handler_package_procedure sp_handler_package_procedure; | 
|---|
| 458 | extern MYSQL_PLUGIN_IMPORT Sp_handler_trigger sp_handler_trigger; | 
|---|
| 459 |  | 
|---|
| 460 |  | 
|---|
| 461 | inline const Sp_handler *Sp_handler::handler(enum_sql_command cmd) | 
|---|
| 462 | { | 
|---|
| 463 | switch (cmd) { | 
|---|
| 464 | case SQLCOM_CREATE_PROCEDURE: | 
|---|
| 465 | case SQLCOM_ALTER_PROCEDURE: | 
|---|
| 466 | case SQLCOM_DROP_PROCEDURE: | 
|---|
| 467 | case SQLCOM_SHOW_PROC_CODE: | 
|---|
| 468 | case SQLCOM_SHOW_CREATE_PROC: | 
|---|
| 469 | case SQLCOM_SHOW_STATUS_PROC: | 
|---|
| 470 | return &sp_handler_procedure; | 
|---|
| 471 | case SQLCOM_CREATE_SPFUNCTION: | 
|---|
| 472 | case SQLCOM_ALTER_FUNCTION: | 
|---|
| 473 | case SQLCOM_DROP_FUNCTION: | 
|---|
| 474 | case SQLCOM_SHOW_FUNC_CODE: | 
|---|
| 475 | case SQLCOM_SHOW_CREATE_FUNC: | 
|---|
| 476 | case SQLCOM_SHOW_STATUS_FUNC: | 
|---|
| 477 | return &sp_handler_function; | 
|---|
| 478 | case SQLCOM_CREATE_PACKAGE: | 
|---|
| 479 | case SQLCOM_DROP_PACKAGE: | 
|---|
| 480 | case SQLCOM_SHOW_CREATE_PACKAGE: | 
|---|
| 481 | case SQLCOM_SHOW_STATUS_PACKAGE: | 
|---|
| 482 | return &sp_handler_package_spec; | 
|---|
| 483 | case SQLCOM_CREATE_PACKAGE_BODY: | 
|---|
| 484 | case SQLCOM_DROP_PACKAGE_BODY: | 
|---|
| 485 | case SQLCOM_SHOW_CREATE_PACKAGE_BODY: | 
|---|
| 486 | case SQLCOM_SHOW_STATUS_PACKAGE_BODY: | 
|---|
| 487 | case SQLCOM_SHOW_PACKAGE_BODY_CODE: | 
|---|
| 488 | return &sp_handler_package_body; | 
|---|
| 489 | default: | 
|---|
| 490 | break; | 
|---|
| 491 | } | 
|---|
| 492 | return NULL; | 
|---|
| 493 | } | 
|---|
| 494 |  | 
|---|
| 495 |  | 
|---|
| 496 | inline const Sp_handler *Sp_handler::handler(stored_procedure_type type) | 
|---|
| 497 | { | 
|---|
| 498 | switch (type) { | 
|---|
| 499 | case TYPE_ENUM_PROCEDURE: | 
|---|
| 500 | return &sp_handler_procedure; | 
|---|
| 501 | case TYPE_ENUM_FUNCTION: | 
|---|
| 502 | return &sp_handler_function; | 
|---|
| 503 | case TYPE_ENUM_PACKAGE: | 
|---|
| 504 | return &sp_handler_package_spec; | 
|---|
| 505 | case TYPE_ENUM_PACKAGE_BODY: | 
|---|
| 506 | return &sp_handler_package_body; | 
|---|
| 507 | case TYPE_ENUM_TRIGGER: | 
|---|
| 508 | return &sp_handler_trigger; | 
|---|
| 509 | case TYPE_ENUM_PROXY: | 
|---|
| 510 | break; | 
|---|
| 511 | } | 
|---|
| 512 | return NULL; | 
|---|
| 513 | } | 
|---|
| 514 |  | 
|---|
| 515 |  | 
|---|
| 516 | inline const Sp_handler *Sp_handler::handler(MDL_key::enum_mdl_namespace type) | 
|---|
| 517 | { | 
|---|
| 518 | switch (type) { | 
|---|
| 519 | case MDL_key::FUNCTION: | 
|---|
| 520 | return &sp_handler_function; | 
|---|
| 521 | case MDL_key::PROCEDURE: | 
|---|
| 522 | return &sp_handler_procedure; | 
|---|
| 523 | case MDL_key::PACKAGE_BODY: | 
|---|
| 524 | return &sp_handler_package_body; | 
|---|
| 525 | case MDL_key::GLOBAL: | 
|---|
| 526 | case MDL_key::SCHEMA: | 
|---|
| 527 | case MDL_key::TABLE: | 
|---|
| 528 | case MDL_key::TRIGGER: | 
|---|
| 529 | case MDL_key::EVENT: | 
|---|
| 530 | case MDL_key::COMMIT: | 
|---|
| 531 | case MDL_key::USER_LOCK: | 
|---|
| 532 | case MDL_key::NAMESPACE_END: | 
|---|
| 533 | break; | 
|---|
| 534 | } | 
|---|
| 535 | return NULL; | 
|---|
| 536 | } | 
|---|
| 537 |  | 
|---|
| 538 |  | 
|---|
| 539 | /* Tells what SP_DEFAULT_ACCESS should be mapped to */ | 
|---|
| 540 | #define SP_DEFAULT_ACCESS_MAPPING SP_CONTAINS_SQL | 
|---|
| 541 |  | 
|---|
| 542 | // Return codes from sp_create_*, sp_drop_*, and sp_show_*: | 
|---|
| 543 | #define SP_OK                 0 | 
|---|
| 544 | #define SP_KEY_NOT_FOUND     -1 | 
|---|
| 545 | #define SP_OPEN_TABLE_FAILED -2 | 
|---|
| 546 | #define SP_WRITE_ROW_FAILED  -3 | 
|---|
| 547 | #define SP_DELETE_ROW_FAILED -4 | 
|---|
| 548 | #define SP_GET_FIELD_FAILED  -5 | 
|---|
| 549 | #define SP_PARSE_ERROR       -6 | 
|---|
| 550 | #define SP_INTERNAL_ERROR    -7 | 
|---|
| 551 | #define SP_NO_DB_ERROR       -8 | 
|---|
| 552 | #define SP_BAD_IDENTIFIER    -9 | 
|---|
| 553 | #define SP_BODY_TOO_LONG    -10 | 
|---|
| 554 | #define SP_FLD_STORE_FAILED -11 | 
|---|
| 555 |  | 
|---|
| 556 | /* DB storage of Stored PROCEDUREs and FUNCTIONs */ | 
|---|
| 557 | enum | 
|---|
| 558 | { | 
|---|
| 559 | MYSQL_PROC_FIELD_DB = 0, | 
|---|
| 560 | MYSQL_PROC_FIELD_NAME, | 
|---|
| 561 | MYSQL_PROC_MYSQL_TYPE, | 
|---|
| 562 | MYSQL_PROC_FIELD_SPECIFIC_NAME, | 
|---|
| 563 | MYSQL_PROC_FIELD_LANGUAGE, | 
|---|
| 564 | MYSQL_PROC_FIELD_ACCESS, | 
|---|
| 565 | MYSQL_PROC_FIELD_DETERMINISTIC, | 
|---|
| 566 | MYSQL_PROC_FIELD_SECURITY_TYPE, | 
|---|
| 567 | MYSQL_PROC_FIELD_PARAM_LIST, | 
|---|
| 568 | MYSQL_PROC_FIELD_RETURNS, | 
|---|
| 569 | MYSQL_PROC_FIELD_BODY, | 
|---|
| 570 | MYSQL_PROC_FIELD_DEFINER, | 
|---|
| 571 | MYSQL_PROC_FIELD_CREATED, | 
|---|
| 572 | MYSQL_PROC_FIELD_MODIFIED, | 
|---|
| 573 | MYSQL_PROC_FIELD_SQL_MODE, | 
|---|
| 574 | , | 
|---|
| 575 | MYSQL_PROC_FIELD_CHARACTER_SET_CLIENT, | 
|---|
| 576 | MYSQL_PROC_FIELD_COLLATION_CONNECTION, | 
|---|
| 577 | MYSQL_PROC_FIELD_DB_COLLATION, | 
|---|
| 578 | MYSQL_PROC_FIELD_BODY_UTF8, | 
|---|
| 579 | MYSQL_PROC_FIELD_AGGREGATE, | 
|---|
| 580 | MYSQL_PROC_FIELD_COUNT | 
|---|
| 581 | }; | 
|---|
| 582 |  | 
|---|
| 583 | /* Drop all routines in database 'db' */ | 
|---|
| 584 | int | 
|---|
| 585 | sp_drop_db_routines(THD *thd, const char *db); | 
|---|
| 586 |  | 
|---|
| 587 | /** | 
|---|
| 588 | Acquires exclusive metadata lock on all stored routines in the | 
|---|
| 589 | given database. | 
|---|
| 590 |  | 
|---|
| 591 | @param  thd  Thread handler | 
|---|
| 592 | @param  db   Database name | 
|---|
| 593 |  | 
|---|
| 594 | @retval  false  Success | 
|---|
| 595 | @retval  true   Failure | 
|---|
| 596 | */ | 
|---|
| 597 | bool lock_db_routines(THD *thd, const char *db); | 
|---|
| 598 |  | 
|---|
| 599 | /** | 
|---|
| 600 | Structure that represents element in the set of stored routines | 
|---|
| 601 | used by statement or routine. | 
|---|
| 602 | */ | 
|---|
| 603 |  | 
|---|
| 604 | class Sroutine_hash_entry | 
|---|
| 605 | { | 
|---|
| 606 | public: | 
|---|
| 607 | /** | 
|---|
| 608 | Metadata lock request for routine. | 
|---|
| 609 | MDL_key in this request is also used as a key for set. | 
|---|
| 610 | */ | 
|---|
| 611 | MDL_request mdl_request; | 
|---|
| 612 | /** | 
|---|
| 613 | Next element in list linking all routines in set. See also comments | 
|---|
| 614 | for LEX::sroutine/sroutine_list and sp_head::m_sroutines. | 
|---|
| 615 | */ | 
|---|
| 616 | Sroutine_hash_entry *next; | 
|---|
| 617 | /** | 
|---|
| 618 | Uppermost view which directly or indirectly uses this routine. | 
|---|
| 619 | 0 if routine is not used in view. Note that it also can be 0 if | 
|---|
| 620 | statement uses routine both via view and directly. | 
|---|
| 621 | */ | 
|---|
| 622 | TABLE_LIST *belong_to_view; | 
|---|
| 623 | /** | 
|---|
| 624 | This is for prepared statement validation purposes. | 
|---|
| 625 | A statement looks up and pre-loads all its stored functions | 
|---|
| 626 | at prepare. Later on, if a function is gone from the cache, | 
|---|
| 627 | execute may fail. | 
|---|
| 628 | Remember the version of sp_head at prepare to be able to | 
|---|
| 629 | invalidate the prepared statement at execute if it | 
|---|
| 630 | changes. | 
|---|
| 631 | */ | 
|---|
| 632 | ulong m_sp_cache_version; | 
|---|
| 633 |  | 
|---|
| 634 | const Sp_handler *m_handler; | 
|---|
| 635 |  | 
|---|
| 636 | int sp_cache_routine(THD *thd, bool lookup_only, sp_head **sp) const; | 
|---|
| 637 | }; | 
|---|
| 638 |  | 
|---|
| 639 |  | 
|---|
| 640 | bool sp_add_used_routine(Query_tables_list *prelocking_ctx, Query_arena *arena, | 
|---|
| 641 | const MDL_key *key, | 
|---|
| 642 | const Sp_handler *handler, | 
|---|
| 643 | TABLE_LIST *belong_to_view); | 
|---|
| 644 | void sp_remove_not_own_routines(Query_tables_list *prelocking_ctx); | 
|---|
| 645 | bool sp_update_sp_used_routines(HASH *dst, HASH *src); | 
|---|
| 646 | void sp_update_stmt_used_routines(THD *thd, Query_tables_list *prelocking_ctx, | 
|---|
| 647 | HASH *src, TABLE_LIST *belong_to_view); | 
|---|
| 648 | void sp_update_stmt_used_routines(THD *thd, Query_tables_list *prelocking_ctx, | 
|---|
| 649 | SQL_I_List<Sroutine_hash_entry> *src, | 
|---|
| 650 | TABLE_LIST *belong_to_view); | 
|---|
| 651 |  | 
|---|
| 652 | extern "C"uchar* sp_sroutine_key(const uchar *ptr, size_t *plen, | 
|---|
| 653 | my_bool first); | 
|---|
| 654 |  | 
|---|
| 655 | /* | 
|---|
| 656 | Routines which allow open/lock and close mysql.proc table even when | 
|---|
| 657 | we already have some tables open and locked. | 
|---|
| 658 | */ | 
|---|
| 659 | TABLE *open_proc_table_for_read(THD *thd, Open_tables_backup *backup); | 
|---|
| 660 |  | 
|---|
| 661 | bool load_charset(MEM_ROOT *mem_root, | 
|---|
| 662 | Field *field, | 
|---|
| 663 | CHARSET_INFO *dflt_cs, | 
|---|
| 664 | CHARSET_INFO **cs); | 
|---|
| 665 |  | 
|---|
| 666 | bool load_collation(MEM_ROOT *mem_root, | 
|---|
| 667 | Field *field, | 
|---|
| 668 | CHARSET_INFO *dflt_cl, | 
|---|
| 669 | CHARSET_INFO **cl); | 
|---|
| 670 |  | 
|---|
| 671 | void sp_returns_type(THD *thd, | 
|---|
| 672 | String &result, | 
|---|
| 673 | const sp_head *sp); | 
|---|
| 674 |  | 
|---|
| 675 | #endif /* _SP_H_ */ | 
|---|
| 676 |  | 
|---|