1 /*
2    Copyright (c) 2002, 2018, Oracle and/or its affiliates.
3    Copyright (c) 2009, 2020, MariaDB
4 
5    This program is free software; you can redistribute it and/or modify
6    it under the terms of the GNU General Public License as published by
7    the Free Software Foundation; version 2 of the License.
8 
9    This program is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12    GNU General Public License for more details.
13 
14    You should have received a copy of the GNU General Public License
15    along with this program; if not, write to the Free Software
16    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335  USA */
17 
18 #include "mariadb.h"
19 #include "sql_priv.h"
20 #include "unireg.h"
21 #include "sp.h"
22 #include "sql_base.h"                           // close_thread_tables
23 #include "sql_lex.h"                            // empty_clex_str
24 #include "sql_parse.h"                          // parse_sql
25 #include "key.h"                                // key_copy
26 #include "sql_show.h"             // append_definer, append_identifier
27 #include "sql_db.h" // get_default_db_collation, mysql_opt_change_db,
28                     // mysql_change_db, check_db_dir_existence,
29                     // load_db_opt_by_name
30 #include "sql_table.h"                          // write_bin_log
31 #include "sql_acl.h"                       // SUPER_ACL
32 #include "sp_head.h"
33 #include "sp_cache.h"
34 #include "lock.h"                               // lock_object_name
35 
36 #include <my_user.h>
37 
get_cache(THD * thd) const38 sp_cache **Sp_handler_procedure::get_cache(THD *thd) const
39 {
40   return &thd->sp_proc_cache;
41 }
42 
get_cache(THD * thd) const43 sp_cache **Sp_handler_function::get_cache(THD *thd) const
44 {
45   return &thd->sp_func_cache;
46 }
47 
get_cache(THD * thd) const48 sp_cache **Sp_handler_package_spec::get_cache(THD *thd) const
49 {
50   return &thd->sp_package_spec_cache;
51 }
52 
get_cache(THD * thd) const53 sp_cache **Sp_handler_package_body::get_cache(THD *thd) const
54 {
55   return &thd->sp_package_body_cache;
56 }
57 
58 
recursion_depth(THD * thd) const59 ulong Sp_handler_procedure::recursion_depth(THD *thd) const
60 {
61   return thd->variables.max_sp_recursion_depth;
62 }
63 
64 
add_instr_freturn(THD * thd,sp_head * sp,sp_pcontext * spcont,Item * item,LEX * lex) const65 bool Sp_handler::add_instr_freturn(THD *thd, sp_head *sp,
66                                    sp_pcontext *spcont,
67                                    Item *item, LEX *lex) const
68 {
69   my_error(ER_SP_BADRETURN, MYF(0));
70   return true;
71 }
72 
73 
add_instr_preturn(THD * thd,sp_head * sp,sp_pcontext * spcont) const74 bool Sp_handler::add_instr_preturn(THD *thd, sp_head *sp,
75                                    sp_pcontext *spcont) const
76 {
77   thd->parse_error();
78   return true;
79 }
80 
81 
add_instr_freturn(THD * thd,sp_head * sp,sp_pcontext * spcont,Item * item,LEX * lex) const82 bool Sp_handler_function::add_instr_freturn(THD *thd, sp_head *sp,
83                                             sp_pcontext *spcont,
84                                             Item *item, LEX *lex) const
85 {
86   return sp->add_instr_freturn(thd, spcont, item, lex);
87 }
88 
89 
add_instr_preturn(THD * thd,sp_head * sp,sp_pcontext * spcont) const90 bool Sp_handler_procedure::add_instr_preturn(THD *thd, sp_head *sp,
91                                              sp_pcontext *spcont) const
92 {
93   return sp->add_instr_preturn(thd, spcont);
94 }
95 
96 
97 Sp_handler_procedure sp_handler_procedure;
98 Sp_handler_function sp_handler_function;
99 Sp_handler_package_spec sp_handler_package_spec;
100 Sp_handler_package_body sp_handler_package_body;
101 Sp_handler_trigger sp_handler_trigger;
102 Sp_handler_package_procedure sp_handler_package_procedure;
103 Sp_handler_package_function sp_handler_package_function;
104 
105 
package_routine_handler() const106 const Sp_handler *Sp_handler_procedure::package_routine_handler() const
107 {
108   return &sp_handler_package_procedure;
109 }
110 
111 
package_routine_handler() const112 const Sp_handler *Sp_handler_function::package_routine_handler() const
113 {
114   return &sp_handler_package_function;
115 }
116 
117 
118 static const
119 TABLE_FIELD_TYPE proc_table_fields[MYSQL_PROC_FIELD_COUNT] =
120 {
121   {
122     { STRING_WITH_LEN("db") },
123     { STRING_WITH_LEN("char(64)") },
124     { STRING_WITH_LEN("utf8") }
125   },
126   {
127     { STRING_WITH_LEN("name") },
128     { STRING_WITH_LEN("char(64)") },
129     { STRING_WITH_LEN("utf8") }
130   },
131   {
132     { STRING_WITH_LEN("type") },
133     { STRING_WITH_LEN("enum('FUNCTION','PROCEDURE')") },
134     { NULL, 0 }
135   },
136   {
137     { STRING_WITH_LEN("specific_name") },
138     { STRING_WITH_LEN("char(64)") },
139     { STRING_WITH_LEN("utf8") }
140   },
141   {
142     { STRING_WITH_LEN("language") },
143     { STRING_WITH_LEN("enum('SQL')") },
144     { NULL, 0 }
145   },
146   {
147     { STRING_WITH_LEN("sql_data_access") },
148     { STRING_WITH_LEN("enum('CONTAINS_SQL','NO_SQL','READS_SQL_DATA','MODIFIES_SQL_DATA')") },
149     { NULL, 0 }
150   },
151   {
152     { STRING_WITH_LEN("is_deterministic") },
153     { STRING_WITH_LEN("enum('YES','NO')") },
154     { NULL, 0 }
155   },
156   {
157     { STRING_WITH_LEN("security_type") },
158     { STRING_WITH_LEN("enum('INVOKER','DEFINER')") },
159     { NULL, 0 }
160   },
161   {
162     { STRING_WITH_LEN("param_list") },
163     { STRING_WITH_LEN("blob") },
164     { NULL, 0 }
165   },
166 
167   {
168     { STRING_WITH_LEN("returns") },
169     { STRING_WITH_LEN("longblob") },
170     { NULL, 0 }
171   },
172   {
173     { STRING_WITH_LEN("body") },
174     { STRING_WITH_LEN("longblob") },
175     { NULL, 0 }
176   },
177   {
178     { STRING_WITH_LEN("definer") },
179     { STRING_WITH_LEN("char(") },
180     { STRING_WITH_LEN("utf8") }
181   },
182   {
183     { STRING_WITH_LEN("created") },
184     { STRING_WITH_LEN("timestamp") },
185     { NULL, 0 }
186   },
187   {
188     { STRING_WITH_LEN("modified") },
189     { STRING_WITH_LEN("timestamp") },
190     { NULL, 0 }
191   },
192   {
193     { STRING_WITH_LEN("sql_mode") },
194     { STRING_WITH_LEN("set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES',"
195     "'IGNORE_SPACE','IGNORE_BAD_TABLE_OPTIONS','ONLY_FULL_GROUP_BY',"
196     "'NO_UNSIGNED_SUBTRACTION',"
197     "'NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB',"
198     "'NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40',"
199     "'ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES',"
200     "'STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES',"
201     "'ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER',"
202     "'HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH',"
203     "'EMPTY_STRING_IS_NULL','SIMULTANEOUS_ASSIGNMENT')") },
204     { NULL, 0 }
205   },
206   {
207     { STRING_WITH_LEN("comment") },
208     { STRING_WITH_LEN("text") },
209     { STRING_WITH_LEN("utf8") }
210   },
211   {
212     { STRING_WITH_LEN("character_set_client") },
213     { STRING_WITH_LEN("char(32)") },
214     { STRING_WITH_LEN("utf8") }
215   },
216   {
217     { STRING_WITH_LEN("collation_connection") },
218     { STRING_WITH_LEN("char(32)") },
219     { STRING_WITH_LEN("utf8") }
220   },
221   {
222     { STRING_WITH_LEN("db_collation") },
223     { STRING_WITH_LEN("char(32)") },
224     { STRING_WITH_LEN("utf8") }
225   },
226   {
227     { STRING_WITH_LEN("body_utf8") },
228     { STRING_WITH_LEN("longblob") },
229     { NULL, 0 }
230   },
231   {
232     { STRING_WITH_LEN("aggregate") },
233     { STRING_WITH_LEN("enum('NONE','GROUP')") },
234     { NULL, 0 }
235   }
236 };
237 
238 static const TABLE_FIELD_DEF
239 proc_table_def= {MYSQL_PROC_FIELD_COUNT, proc_table_fields, 0, (uint*) 0 };
240 
241 /*************************************************************************/
242 
243 /**
244   Stored_routine_creation_ctx -- creation context of stored routines
245   (stored procedures and functions).
246 */
247 
248 class Stored_routine_creation_ctx : public Stored_program_creation_ctx,
249                                     public Sql_alloc
250 {
251 public:
252   static Stored_routine_creation_ctx *
253   load_from_db(THD *thd, const Database_qualified_name *name, TABLE *proc_tbl);
254 
255 public:
clone(MEM_ROOT * mem_root)256   virtual Stored_program_creation_ctx *clone(MEM_ROOT *mem_root)
257   {
258     return new (mem_root) Stored_routine_creation_ctx(m_client_cs,
259                                                       m_connection_cl,
260                                                       m_db_cl);
261   }
262 
263 protected:
create_backup_ctx(THD * thd) const264   virtual Object_creation_ctx *create_backup_ctx(THD *thd) const
265   {
266     DBUG_ENTER("Stored_routine_creation_ctx::create_backup_ctx");
267     DBUG_RETURN(new Stored_routine_creation_ctx(thd));
268   }
269 
270 private:
Stored_routine_creation_ctx(THD * thd)271   Stored_routine_creation_ctx(THD *thd)
272     : Stored_program_creation_ctx(thd)
273   { }
274 
Stored_routine_creation_ctx(CHARSET_INFO * client_cs,CHARSET_INFO * connection_cl,CHARSET_INFO * db_cl)275   Stored_routine_creation_ctx(CHARSET_INFO *client_cs,
276                               CHARSET_INFO *connection_cl,
277                               CHARSET_INFO *db_cl)
278     : Stored_program_creation_ctx(client_cs, connection_cl, db_cl)
279   { }
280 };
281 
282 /**************************************************************************
283   Stored_routine_creation_ctx implementation.
284 **************************************************************************/
285 
load_charset(MEM_ROOT * mem_root,Field * field,CHARSET_INFO * dflt_cs,CHARSET_INFO ** cs)286 bool load_charset(MEM_ROOT *mem_root,
287                   Field *field,
288                   CHARSET_INFO *dflt_cs,
289                   CHARSET_INFO **cs)
290 {
291   LEX_CSTRING cs_name;
292 
293   if (field->val_str_nopad(mem_root, &cs_name))
294   {
295     *cs= dflt_cs;
296     return TRUE;
297   }
298 
299   DBUG_ASSERT(cs_name.str[cs_name.length] == 0);
300   *cs= get_charset_by_csname(cs_name.str, MY_CS_PRIMARY, MYF(0));
301 
302   if (*cs == NULL)
303   {
304     *cs= dflt_cs;
305     return TRUE;
306   }
307 
308   return FALSE;
309 }
310 
311 /*************************************************************************/
312 
load_collation(MEM_ROOT * mem_root,Field * field,CHARSET_INFO * dflt_cl,CHARSET_INFO ** cl)313 bool load_collation(MEM_ROOT *mem_root,
314                     Field *field,
315                     CHARSET_INFO *dflt_cl,
316                     CHARSET_INFO **cl)
317 {
318   LEX_CSTRING cl_name;
319 
320   if (field->val_str_nopad(mem_root, &cl_name))
321   {
322     *cl= dflt_cl;
323     return TRUE;
324   }
325 
326   DBUG_ASSERT(cl_name.str[cl_name.length] == 0);
327   *cl= get_charset_by_name(cl_name.str, MYF(0));
328 
329   if (*cl == NULL)
330   {
331     *cl= dflt_cl;
332     return TRUE;
333   }
334 
335   return FALSE;
336 }
337 
338 /*************************************************************************/
339 
340 Stored_routine_creation_ctx *
load_from_db(THD * thd,const Database_qualified_name * name,TABLE * proc_tbl)341 Stored_routine_creation_ctx::load_from_db(THD *thd,
342                                           const Database_qualified_name *name,
343                                           TABLE *proc_tbl)
344 {
345   /* Load character set/collation attributes. */
346 
347   CHARSET_INFO *client_cs;
348   CHARSET_INFO *connection_cl;
349   CHARSET_INFO *db_cl;
350 
351   const char *db_name= thd->strmake(name->m_db.str, name->m_db.length);
352   const char *sr_name= thd->strmake(name->m_name.str, name->m_name.length);
353 
354   bool invalid_creation_ctx= FALSE;
355 
356   if (load_charset(thd->mem_root,
357                    proc_tbl->field[MYSQL_PROC_FIELD_CHARACTER_SET_CLIENT],
358                    thd->variables.character_set_client,
359                    &client_cs))
360   {
361     sql_print_warning("Stored routine '%s'.'%s': invalid value "
362                       "in column mysql.proc.character_set_client.",
363                       (const char *) db_name,
364                       (const char *) sr_name);
365 
366     invalid_creation_ctx= TRUE;
367   }
368 
369   if (load_collation(thd->mem_root,
370                      proc_tbl->field[MYSQL_PROC_FIELD_COLLATION_CONNECTION],
371                      thd->variables.collation_connection,
372                      &connection_cl))
373   {
374     sql_print_warning("Stored routine '%s'.'%s': invalid value "
375                       "in column mysql.proc.collation_connection.",
376                       (const char *) db_name,
377                       (const char *) sr_name);
378 
379     invalid_creation_ctx= TRUE;
380   }
381 
382   if (load_collation(thd->mem_root,
383                      proc_tbl->field[MYSQL_PROC_FIELD_DB_COLLATION],
384                      NULL,
385                      &db_cl))
386   {
387     sql_print_warning("Stored routine '%s'.'%s': invalid value "
388                       "in column mysql.proc.db_collation.",
389                       (const char *) db_name,
390                       (const char *) sr_name);
391 
392     invalid_creation_ctx= TRUE;
393   }
394 
395   if (invalid_creation_ctx)
396   {
397     push_warning_printf(thd,
398                         Sql_condition::WARN_LEVEL_WARN,
399                         ER_SR_INVALID_CREATION_CTX,
400                         ER_THD(thd, ER_SR_INVALID_CREATION_CTX),
401                         (const char *) db_name,
402                         (const char *) sr_name);
403   }
404 
405   /*
406     If we failed to retrieve the database collation, load the default one
407     from the disk.
408   */
409 
410   if (!db_cl)
411     db_cl= get_default_db_collation(thd, name->m_db.str);
412 
413   /* Create the context. */
414 
415   return new Stored_routine_creation_ctx(client_cs, connection_cl, db_cl);
416 }
417 
418 /*************************************************************************/
419 
420 class Proc_table_intact : public Table_check_intact
421 {
422 private:
423   bool m_print_once;
424 
425 public:
Proc_table_intact()426   Proc_table_intact() : m_print_once(TRUE) { has_keys= TRUE; }
427 
428 protected:
429   void report_error(uint code, const char *fmt, ...);
430 };
431 
432 
433 /**
434   Report failure to validate the mysql.proc table definition.
435   Print a message to the error log only once.
436 */
437 
report_error(uint code,const char * fmt,...)438 void Proc_table_intact::report_error(uint code, const char *fmt, ...)
439 {
440   va_list args;
441   char buf[512];
442 
443   va_start(args, fmt);
444   my_vsnprintf(buf, sizeof(buf), fmt, args);
445   va_end(args);
446 
447   if (code)
448     my_message(code, buf, MYF(0));
449   else
450     my_error(ER_CANNOT_LOAD_FROM_TABLE_V2, MYF(0), "mysql", "proc");
451 
452   if (m_print_once)
453   {
454     m_print_once= FALSE;
455     sql_print_error("%s", buf);
456   }
457 };
458 
459 
460 /** Single instance used to control printing to the error log. */
461 static Proc_table_intact proc_table_intact;
462 
463 
464 /**
465   Open the mysql.proc table for read.
466 
467   @param thd     Thread context
468   @param backup  Pointer to Open_tables_state instance where information about
469                  currently open tables will be saved, and from which will be
470                  restored when we will end work with mysql.proc.
471 
472   @retval
473     0	Error
474   @retval
475     \#	Pointer to TABLE object of mysql.proc
476 */
477 
open_proc_table_for_read(THD * thd,Open_tables_backup * backup)478 TABLE *open_proc_table_for_read(THD *thd, Open_tables_backup *backup)
479 {
480   TABLE_LIST table;
481 
482   DBUG_ENTER("open_proc_table_for_read");
483 
484   table.init_one_table(&MYSQL_SCHEMA_NAME, &MYSQL_PROC_NAME, NULL, TL_READ);
485 
486   if (open_system_tables_for_read(thd, &table, backup))
487     DBUG_RETURN(NULL);
488 
489   if (!proc_table_intact.check(table.table, &proc_table_def))
490     DBUG_RETURN(table.table);
491 
492   close_system_tables(thd, backup);
493 
494   DBUG_RETURN(NULL);
495 }
496 
497 
498 /**
499   Open the mysql.proc table for update.
500 
501   @param thd  Thread context
502 
503   @note
504     Table opened with this call should closed using close_thread_tables().
505 
506   @retval
507     0	Error
508   @retval
509     \#	Pointer to TABLE object of mysql.proc
510 */
511 
open_proc_table_for_update(THD * thd)512 static TABLE *open_proc_table_for_update(THD *thd)
513 {
514   TABLE_LIST table_list;
515   TABLE *table;
516   MDL_savepoint mdl_savepoint= thd->mdl_context.mdl_savepoint();
517   DBUG_ENTER("open_proc_table_for_update");
518 
519   table_list.init_one_table(&MYSQL_SCHEMA_NAME, &MYSQL_PROC_NAME, NULL, TL_WRITE);
520 
521   if (!(table= open_system_table_for_update(thd, &table_list)))
522     DBUG_RETURN(NULL);
523 
524   if (!proc_table_intact.check(table, &proc_table_def))
525     DBUG_RETURN(table);
526 
527   close_thread_tables(thd);
528   thd->mdl_context.rollback_to_savepoint(mdl_savepoint);
529 
530   DBUG_RETURN(NULL);
531 }
532 
533 
534 /**
535   Find row in open mysql.proc table representing stored routine.
536 
537   @param thd    Thread context
538   @param name   Name of routine
539   @param table  TABLE object for open mysql.proc table.
540 
541   @retval
542     SP_OK             Routine found
543   @retval
544     SP_KEY_NOT_FOUND  No routine with given name
545 */
546 
547 int
db_find_routine_aux(THD * thd,const Database_qualified_name * name,TABLE * table) const548 Sp_handler::db_find_routine_aux(THD *thd,
549                                 const Database_qualified_name *name,
550                                 TABLE *table) const
551 {
552   uchar key[MAX_KEY_LENGTH];	// db, name, optional key length type
553   DBUG_ENTER("db_find_routine_aux");
554   DBUG_PRINT("enter", ("type: %s  name: %.*s",
555 		       type_str(),
556 		       (int) name->m_name.length, name->m_name.str));
557 
558   /*
559     Create key to find row. We have to use field->store() to be able to
560     handle VARCHAR and CHAR fields.
561     Assumption here is that the three first fields in the table are
562     'db', 'name' and 'type' and the first key is the primary key over the
563     same fields.
564   */
565   if (name->m_name.length > table->field[1]->field_length)
566     DBUG_RETURN(SP_KEY_NOT_FOUND);
567   table->field[0]->store(name->m_db, &my_charset_bin);
568   table->field[1]->store(name->m_name, &my_charset_bin);
569   table->field[2]->store((longlong) type(), true);
570   key_copy(key, table->record[0], table->key_info,
571            table->key_info->key_length);
572 
573   if (table->file->ha_index_read_idx_map(table->record[0], 0, key,
574                                          HA_WHOLE_KEY,
575                                          HA_READ_KEY_EXACT))
576     DBUG_RETURN(SP_KEY_NOT_FOUND);
577 
578   DBUG_RETURN(SP_OK);
579 }
580 
581 
read_from_mysql_proc_row(THD * thd,TABLE * table)582 bool st_sp_chistics::read_from_mysql_proc_row(THD *thd, TABLE *table)
583 {
584   LEX_CSTRING str;
585 
586   if (table->field[MYSQL_PROC_FIELD_ACCESS]->val_str_nopad(thd->mem_root,
587                                                            &str))
588     return true;
589 
590   switch (str.str[0]) {
591   case 'N':
592     daccess= SP_NO_SQL;
593     break;
594   case 'C':
595     daccess= SP_CONTAINS_SQL;
596     break;
597   case 'R':
598     daccess= SP_READS_SQL_DATA;
599     break;
600   case 'M':
601     daccess= SP_MODIFIES_SQL_DATA;
602     break;
603   default:
604     daccess= SP_DEFAULT_ACCESS_MAPPING;
605   }
606 
607   if (table->field[MYSQL_PROC_FIELD_DETERMINISTIC]->val_str_nopad(thd->mem_root,
608                                                                   &str))
609     return true;
610   detistic= str.str[0] == 'N' ? false : true;
611 
612   if (table->field[MYSQL_PROC_FIELD_SECURITY_TYPE]->val_str_nopad(thd->mem_root,
613                                                                   &str))
614     return true;
615   suid= str.str[0] == 'I' ? SP_IS_NOT_SUID : SP_IS_SUID;
616 
617   if (table->field[MYSQL_PROC_FIELD_AGGREGATE]->val_str_nopad(thd->mem_root,
618                                                               &str))
619     return true;
620 
621   switch (str.str[0]) {
622   case 'N':
623     agg_type= NOT_AGGREGATE;
624     break;
625   case 'G':
626     agg_type= GROUP_AGGREGATE;
627     break;
628   default:
629     agg_type= DEFAULT_AGGREGATE;
630   }
631 
632 
633   if (table->field[MYSQL_PROC_FIELD_COMMENT]->val_str_nopad(thd->mem_root,
634                                                             &comment))
635     return true;
636 
637   return false;
638 }
639 
640 
read_from_mysql_proc_row(THD * thd,TABLE * table)641 bool AUTHID::read_from_mysql_proc_row(THD *thd, TABLE *table)
642 {
643   LEX_CSTRING str;
644   if (table->field[MYSQL_PROC_FIELD_DEFINER]->val_str_nopad(thd->mem_root,
645                                                             &str))
646     return true;
647   parse(str.str, str.length);
648   if (user.str[user.length])
649     ((char *) user.str)[user.length]= '\0'; // 0-terminate if was truncated
650   return false;
651 }
652 
653 
654 /**
655   Find routine definition in mysql.proc table and create corresponding
656   sp_head object for it.
657 
658   @param thd   Thread context
659   @param name  Name of routine
660   @param sphp  Out parameter in which pointer to created sp_head
661                object is returned (0 in case of error).
662 
663   @note
664     This function may damage current LEX during execution, so it is good
665     idea to create temporary LEX and make it active before calling it.
666 
667   @retval
668     0       Success
669   @retval
670     non-0   Error (may be one of special codes like SP_KEY_NOT_FOUND)
671 */
672 
673 int
db_find_routine(THD * thd,const Database_qualified_name * name,sp_head ** sphp) const674 Sp_handler::db_find_routine(THD *thd,
675                             const Database_qualified_name *name,
676                             sp_head **sphp) const
677 {
678   TABLE *table;
679   LEX_CSTRING params, returns, body;
680   int ret;
681   longlong created;
682   longlong modified;
683   Sp_chistics chistics;
684   bool saved_time_zone_used= thd->time_zone_used;
685   sql_mode_t sql_mode, saved_mode= thd->variables.sql_mode;
686   Open_tables_backup open_tables_state_backup;
687   Stored_program_creation_ctx *creation_ctx;
688   AUTHID definer;
689 
690   DBUG_ENTER("db_find_routine");
691   DBUG_PRINT("enter", ("type: %s name: %.*s",
692 		       type_str(),
693 		       (int) name->m_name.length, name->m_name.str));
694 
695   *sphp= 0;                                     // In case of errors
696   if (!(table= open_proc_table_for_read(thd, &open_tables_state_backup)))
697     DBUG_RETURN(SP_OPEN_TABLE_FAILED);
698 
699   /* Reset sql_mode during data dictionary operations. */
700   thd->variables.sql_mode= 0;
701 
702   if ((ret= db_find_routine_aux(thd, name, table)) != SP_OK)
703     goto done;
704 
705   if (table->s->fields < MYSQL_PROC_FIELD_COUNT)
706   {
707     ret= SP_GET_FIELD_FAILED;
708     goto done;
709   }
710 
711   if (chistics.read_from_mysql_proc_row(thd, table) ||
712       definer.read_from_mysql_proc_row(thd, table))
713   {
714     ret= SP_GET_FIELD_FAILED;
715     goto done;
716   }
717 
718   table->field[MYSQL_PROC_FIELD_PARAM_LIST]->val_str_nopad(thd->mem_root,
719                                                            &params);
720   if (type() != TYPE_ENUM_FUNCTION)
721     returns= empty_clex_str;
722   else if (table->field[MYSQL_PROC_FIELD_RETURNS]->val_str_nopad(thd->mem_root,
723                                                                  &returns))
724   {
725     ret= SP_GET_FIELD_FAILED;
726     goto done;
727   }
728 
729   if (table->field[MYSQL_PROC_FIELD_BODY]->val_str_nopad(thd->mem_root,
730                                                          &body))
731   {
732     ret= SP_GET_FIELD_FAILED;
733     goto done;
734   }
735 
736   // Get additional information
737   modified= table->field[MYSQL_PROC_FIELD_MODIFIED]->val_int();
738   created= table->field[MYSQL_PROC_FIELD_CREATED]->val_int();
739   sql_mode= (sql_mode_t) table->field[MYSQL_PROC_FIELD_SQL_MODE]->val_int();
740 
741   creation_ctx= Stored_routine_creation_ctx::load_from_db(thd, name, table);
742 
743   close_system_tables(thd, &open_tables_state_backup);
744   table= 0;
745 
746   ret= db_load_routine(thd, name, sphp,
747                        sql_mode, params, returns, body, chistics, definer,
748                        created, modified, NULL, creation_ctx);
749  done:
750   /*
751     Restore the time zone flag as the timezone usage in proc table
752     does not affect replication.
753   */
754   thd->time_zone_used= saved_time_zone_used;
755   if (table)
756     close_system_tables(thd, &open_tables_state_backup);
757   thd->variables.sql_mode= saved_mode;
758   DBUG_RETURN(ret);
759 }
760 
761 
762 int
db_find_and_cache_routine(THD * thd,const Database_qualified_name * name,sp_head ** sp) const763 Sp_handler::db_find_and_cache_routine(THD *thd,
764                                       const Database_qualified_name *name,
765                                       sp_head **sp) const
766 {
767   int rc= db_find_routine(thd, name, sp);
768   if (rc == SP_OK)
769   {
770     sp_cache_insert(get_cache(thd), *sp);
771     DBUG_PRINT("info", ("added new: %p, level: %lu, flags %x",
772                         sp[0], sp[0]->m_recursion_level,
773                         sp[0]->m_flags));
774   }
775   return rc;
776 }
777 
778 
779 /**
780   Silence DEPRECATED SYNTAX warnings when loading a stored procedure
781   into the cache.
782 */
783 
784 struct Silence_deprecated_warning : public Internal_error_handler
785 {
786 public:
787   virtual bool handle_condition(THD *thd,
788                                 uint sql_errno,
789                                 const char* sqlstate,
790                                 Sql_condition::enum_warning_level *level,
791                                 const char* msg,
792                                 Sql_condition ** cond_hdl);
793 };
794 
795 bool
handle_condition(THD *,uint sql_errno,const char *,Sql_condition::enum_warning_level * level,const char *,Sql_condition ** cond_hdl)796 Silence_deprecated_warning::handle_condition(
797   THD *,
798   uint sql_errno,
799   const char*,
800   Sql_condition::enum_warning_level *level,
801   const char*,
802   Sql_condition ** cond_hdl)
803 {
804   *cond_hdl= NULL;
805   if (sql_errno == ER_WARN_DEPRECATED_SYNTAX &&
806       *level == Sql_condition::WARN_LEVEL_WARN)
807     return TRUE;
808 
809   return FALSE;
810 }
811 
812 
813 /**
814   @brief    The function parses input strings and returns SP stucture.
815 
816   @param[in]      thd               Thread handler
817   @param[in]      defstr            CREATE... string
818   @param[in]      sql_mode          SQL mode
819   @param[in]      parent            The owner package for package routines,
820                                     or NULL for standalone routines.
821   @param[in]      creation_ctx      Creation context of stored routines
822 
823   @return     Pointer on sp_head struct
824     @retval   #                     Pointer on sp_head struct
825     @retval   0                     error
826 */
827 
sp_compile(THD * thd,String * defstr,sql_mode_t sql_mode,sp_package * parent,Stored_program_creation_ctx * creation_ctx)828 static sp_head *sp_compile(THD *thd, String *defstr, sql_mode_t sql_mode,
829                            sp_package *parent,
830                            Stored_program_creation_ctx *creation_ctx)
831 {
832   sp_head *sp;
833   sql_mode_t old_sql_mode= thd->variables.sql_mode;
834   ha_rows old_select_limit= thd->variables.select_limit;
835   sp_rcontext *old_spcont= thd->spcont;
836   Silence_deprecated_warning warning_handler;
837   Parser_state parser_state;
838 
839   thd->variables.sql_mode= sql_mode;
840   thd->variables.select_limit= HA_POS_ERROR;
841 
842   if (parser_state.init(thd, defstr->c_ptr_safe(), defstr->length()))
843   {
844     thd->variables.sql_mode= old_sql_mode;
845     thd->variables.select_limit= old_select_limit;
846     return NULL;
847   }
848 
849   lex_start(thd);
850   thd->lex->sphead= parent;
851   thd->push_internal_handler(&warning_handler);
852   thd->spcont= 0;
853 
854   if (parse_sql(thd, & parser_state, creation_ctx) || thd->lex == NULL)
855   {
856     sp= thd->lex->sphead;
857     sp_head::destroy(sp);
858     sp= 0;
859   }
860   else
861   {
862     sp= thd->lex->sphead;
863   }
864 
865   thd->pop_internal_handler();
866   thd->spcont= old_spcont;
867   thd->variables.sql_mode= old_sql_mode;
868   thd->variables.select_limit= old_select_limit;
869   return sp;
870 }
871 
872 
873 class Bad_db_error_handler : public Internal_error_handler
874 {
875 public:
Bad_db_error_handler()876   Bad_db_error_handler()
877     :m_error_caught(false)
878   {}
879 
880   virtual bool handle_condition(THD *thd,
881                                 uint sql_errno,
882                                 const char* sqlstate,
883                                 Sql_condition::enum_warning_level *level,
884                                 const char* message,
885                                 Sql_condition ** cond_hdl);
886 
error_caught() const887   bool error_caught() const { return m_error_caught; }
888 
889 private:
890   bool m_error_caught;
891 };
892 
893 bool
handle_condition(THD * thd,uint sql_errno,const char * sqlstate,Sql_condition::enum_warning_level * level,const char * message,Sql_condition ** cond_hdl)894 Bad_db_error_handler::handle_condition(THD *thd,
895                                        uint sql_errno,
896                                        const char* sqlstate,
897                                        Sql_condition::enum_warning_level
898                                        *level,
899                                        const char* message,
900                                        Sql_condition ** cond_hdl)
901 {
902   if (sql_errno == ER_BAD_DB_ERROR)
903   {
904     m_error_caught= true;
905     return true;
906   }
907   return false;
908 }
909 
910 
911 int
db_load_routine(THD * thd,const Database_qualified_name * name,sp_head ** sphp,sql_mode_t sql_mode,const LEX_CSTRING & params,const LEX_CSTRING & returns,const LEX_CSTRING & body,const st_sp_chistics & chistics,const AUTHID & definer,longlong created,longlong modified,sp_package * parent,Stored_program_creation_ctx * creation_ctx) const912 Sp_handler::db_load_routine(THD *thd, const Database_qualified_name *name,
913                             sp_head **sphp,
914                             sql_mode_t sql_mode,
915                             const LEX_CSTRING &params,
916                             const LEX_CSTRING &returns,
917                             const LEX_CSTRING &body,
918                             const st_sp_chistics &chistics,
919                             const AUTHID &definer,
920                             longlong created, longlong modified,
921                             sp_package *parent,
922                             Stored_program_creation_ctx *creation_ctx) const
923 {
924   LEX *old_lex= thd->lex, newlex;
925   String defstr;
926   char saved_cur_db_name_buf[SAFE_NAME_LEN+1];
927   LEX_STRING saved_cur_db_name=
928     { saved_cur_db_name_buf, sizeof(saved_cur_db_name_buf) };
929   bool cur_db_changed;
930   Bad_db_error_handler db_not_exists_handler;
931 
932   int ret= 0;
933 
934   thd->lex= &newlex;
935   newlex.current_select= NULL;
936 
937   defstr.set_charset(creation_ctx->get_client_cs());
938 
939   /*
940     We have to add DEFINER clause and provide proper routine characterstics in
941     routine definition statement that we build here to be able to use this
942     definition for SHOW CREATE PROCEDURE later.
943    */
944 
945   if (show_create_sp(thd, &defstr,
946                      null_clex_str, name->m_name,
947                      params, returns, body,
948                      chistics, definer, DDL_options(), sql_mode))
949   {
950     ret= SP_INTERNAL_ERROR;
951     goto end;
952   }
953 
954   thd->push_internal_handler(&db_not_exists_handler);
955   /*
956     Change the current database (if needed).
957 
958     TODO: why do we force switch here?
959   */
960 
961   if (mysql_opt_change_db(thd, &name->m_db, &saved_cur_db_name, TRUE,
962                           &cur_db_changed))
963   {
964     ret= SP_INTERNAL_ERROR;
965     thd->pop_internal_handler();
966     goto end;
967   }
968   thd->pop_internal_handler();
969   if (db_not_exists_handler.error_caught())
970   {
971     ret= SP_INTERNAL_ERROR;
972     my_error(ER_BAD_DB_ERROR, MYF(0), name->m_db.str);
973 
974     goto end;
975   }
976 
977   {
978     *sphp= sp_compile(thd, &defstr, sql_mode, parent, creation_ctx);
979     /*
980       Force switching back to the saved current database (if changed),
981       because it may be NULL. In this case, mysql_change_db() would
982       generate an error.
983     */
984 
985     if (cur_db_changed && mysql_change_db(thd,
986                                           (LEX_CSTRING*) &saved_cur_db_name,
987                                           TRUE))
988     {
989       ret= SP_INTERNAL_ERROR;
990       goto end;
991     }
992 
993     if (!*sphp)
994     {
995       ret= SP_PARSE_ERROR;
996       goto end;
997     }
998 
999     (*sphp)->set_definer(&definer.user, &definer.host);
1000     (*sphp)->set_info(created, modified, chistics, sql_mode);
1001     (*sphp)->set_creation_ctx(creation_ctx);
1002     (*sphp)->optimize();
1003 
1004     if (type() == TYPE_ENUM_PACKAGE_BODY)
1005     {
1006       sp_package *package= (*sphp)->get_package();
1007       List_iterator<LEX> it(package->m_routine_implementations);
1008       for (LEX *lex; (lex= it++); )
1009       {
1010         DBUG_ASSERT(lex->sphead);
1011         lex->sphead->set_definer(&definer.user, &definer.host);
1012         lex->sphead->set_suid(package->suid());
1013         lex->sphead->m_sql_mode= sql_mode;
1014         lex->sphead->set_creation_ctx(creation_ctx);
1015         lex->sphead->optimize();
1016       }
1017     }
1018 
1019     /*
1020       Not strictly necessary to invoke this method here, since we know
1021       that we've parsed CREATE PROCEDURE/FUNCTION and not an
1022       UPDATE/DELETE/INSERT/REPLACE/LOAD/CREATE TABLE, but we try to
1023       maintain the invariant that this method is called for each
1024       distinct statement, in case its logic is extended with other
1025       types of analyses in future.
1026     */
1027     newlex.set_trg_event_type_for_tables();
1028   }
1029 
1030 end:
1031   thd->lex->sphead= NULL;
1032   lex_end(thd->lex);
1033   thd->lex= old_lex;
1034   return ret;
1035 }
1036 
1037 
1038 void
sp_returns_type(THD * thd,String & result,const sp_head * sp)1039 sp_returns_type(THD *thd, String &result, const sp_head *sp)
1040 {
1041   TABLE table;
1042   TABLE_SHARE share;
1043   Field *field;
1044   bzero((char*) &table, sizeof(table));
1045   bzero((char*) &share, sizeof(share));
1046   table.in_use= thd;
1047   table.s = &share;
1048   field= sp->create_result_field(0, 0, &table);
1049   field->sql_type(result);
1050 
1051   if (field->has_charset())
1052   {
1053     result.append(STRING_WITH_LEN(" CHARSET "));
1054     result.append(field->charset()->csname);
1055     if (!(field->charset()->state & MY_CS_PRIMARY))
1056     {
1057       result.append(STRING_WITH_LEN(" COLLATE "));
1058       result.append(field->charset()->name);
1059     }
1060   }
1061 
1062   delete field;
1063 }
1064 
1065 
1066 /**
1067   Delete the record for the stored routine object from mysql.proc,
1068   which is already opened, locked, and positioned to the record with the
1069   record to be deleted.
1070 
1071   The operation deletes the record for the current record in "table"
1072   and invalidates the stored-routine cache.
1073 
1074   @param thd    Thread context.
1075   @param name   Stored routine name.
1076   @param table  A pointer to the opened mysql.proc table
1077 
1078   @returns      Error code.
1079   @return       SP_OK on success, or SP_DELETE_ROW_FAILED on error.
1080   used to indicate about errors.
1081 */
1082 
1083 int
sp_drop_routine_internal(THD * thd,const Database_qualified_name * name,TABLE * table) const1084 Sp_handler::sp_drop_routine_internal(THD *thd,
1085                                      const Database_qualified_name *name,
1086                                      TABLE *table) const
1087 {
1088   DBUG_ENTER("sp_drop_routine_internal");
1089 
1090   if (table->file->ha_delete_row(table->record[0]))
1091     DBUG_RETURN(SP_DELETE_ROW_FAILED);
1092 
1093   /* Make change permanent and avoid 'table is marked as crashed' errors */
1094   table->file->extra(HA_EXTRA_FLUSH);
1095 
1096   sp_cache_invalidate();
1097   /*
1098     A lame workaround for lack of cache flush:
1099     make sure the routine is at least gone from the
1100     local cache.
1101   */
1102   sp_head *sp;
1103   sp_cache **spc= get_cache(thd);
1104   DBUG_ASSERT(spc);
1105   if ((sp= sp_cache_lookup(spc, name)))
1106     sp_cache_flush_obsolete(spc, &sp);
1107   DBUG_RETURN(SP_OK);
1108 }
1109 
1110 
1111 int
sp_find_and_drop_routine(THD * thd,TABLE * table,const Database_qualified_name * name) const1112 Sp_handler::sp_find_and_drop_routine(THD *thd, TABLE *table,
1113                                      const Database_qualified_name *name) const
1114 {
1115   int ret;
1116   if ((ret= db_find_routine_aux(thd, name, table)) != SP_OK)
1117     return ret;
1118   return sp_drop_routine_internal(thd, name, table);
1119 }
1120 
1121 
1122 int
1123 Sp_handler_package_spec::
sp_find_and_drop_routine(THD * thd,TABLE * table,const Database_qualified_name * name) const1124   sp_find_and_drop_routine(THD *thd, TABLE *table,
1125                            const Database_qualified_name *name) const
1126 {
1127   int ret;
1128   if ((ret= db_find_routine_aux(thd, name, table)) != SP_OK)
1129     return ret;
1130   /*
1131     When we do "DROP PACKAGE pkg", we should also perform
1132     "DROP PACKAGE BODY pkg" automatically.
1133   */
1134   ret= sp_handler_package_body.sp_find_and_drop_routine(thd, table, name);
1135   if (ret != SP_KEY_NOT_FOUND && ret != SP_OK)
1136   {
1137     /*
1138       - SP_KEY_NOT_FOUND means that "CREATE PACKAGE pkg" did not
1139         have a correspoinding "CREATE PACKAGE BODY pkg" yet.
1140       - SP_OK means that "CREATE PACKAGE pkg" had a correspoinding
1141         "CREATE PACKAGE BODY pkg", which was successfully dropped.
1142     */
1143     return ret; // Other codes mean an unexpecte error
1144   }
1145   return Sp_handler::sp_find_and_drop_routine(thd, table, name);
1146 }
1147 
1148 
1149 /**
1150   Write stored-routine object into mysql.proc.
1151 
1152   This operation stores attributes of the stored procedure/function into
1153   the mysql.proc.
1154 
1155   @param thd  Thread context.
1156   @param sp   Stored routine object to store.
1157 
1158   @note Opens and closes the thread tables. Therefore assumes
1159   that there are no locked tables in this thread at the time of
1160   invocation.
1161   Unlike some other DDL statements, *does* close the tables
1162   in the end, since the call to this function is normally
1163   followed by an implicit grant (sp_grant_privileges())
1164   and this subsequent call opens and closes mysql.procs_priv.
1165 
1166   @return Error status.
1167     @retval FALSE on success
1168     @retval TRUE on error
1169 */
1170 
1171 bool
sp_create_routine(THD * thd,const sp_head * sp) const1172 Sp_handler::sp_create_routine(THD *thd, const sp_head *sp) const
1173 {
1174   LEX *lex= thd->lex;
1175   bool ret= TRUE;
1176   TABLE *table;
1177   char definer_buf[USER_HOST_BUFF_SIZE];
1178   LEX_CSTRING definer;
1179   sql_mode_t saved_mode= thd->variables.sql_mode;
1180 
1181   CHARSET_INFO *db_cs= get_default_db_collation(thd, sp->m_db.str);
1182 
1183   bool store_failed= FALSE;
1184   DBUG_ENTER("sp_create_routine");
1185   DBUG_PRINT("enter", ("type: %s  name: %.*s",
1186                        type_str(),
1187                        (int) sp->m_name.length,
1188                        sp->m_name.str));
1189   MDL_key::enum_mdl_namespace mdl_type= get_mdl_type();
1190   LEX_CSTRING returns= empty_clex_str;
1191   String retstr(64);
1192   retstr.set_charset(system_charset_info);
1193 
1194   /* Grab an exclusive MDL lock. */
1195   if (lock_object_name(thd, mdl_type, sp->m_db.str, sp->m_name.str))
1196   {
1197     my_error(ER_BAD_DB_ERROR, MYF(0), sp->m_db.str);
1198     DBUG_RETURN(TRUE);
1199   }
1200 
1201   /*
1202     Check that a database directory with this name
1203     exists. Design note: This won't work on virtual databases
1204     like information_schema.
1205   */
1206   if (check_db_dir_existence(sp->m_db.str))
1207   {
1208     my_error(ER_BAD_DB_ERROR, MYF(0), sp->m_db.str);
1209     DBUG_RETURN(TRUE);
1210   }
1211 
1212 
1213   /* Reset sql_mode during data dictionary operations. */
1214   thd->variables.sql_mode= 0;
1215 
1216   Check_level_instant_set check_level_save(thd, CHECK_FIELD_WARN);
1217 
1218   if (!(table= open_proc_table_for_update(thd)))
1219   {
1220     my_error(ER_SP_STORE_FAILED, MYF(0), type_str(), sp->m_name.str);
1221     goto done;
1222   }
1223   else
1224   {
1225     /* Checking if the routine already exists */
1226     if (db_find_routine_aux(thd, sp, table) == SP_OK)
1227     {
1228       if (lex->create_info.or_replace())
1229       {
1230         switch (type()) {
1231         case TYPE_ENUM_PACKAGE:
1232           // Drop together with its PACKAGE BODY mysql.proc record
1233           if (sp_handler_package_spec.sp_find_and_drop_routine(thd, table, sp))
1234             goto done;
1235           break;
1236         case TYPE_ENUM_PACKAGE_BODY:
1237         case TYPE_ENUM_FUNCTION:
1238         case TYPE_ENUM_PROCEDURE:
1239           if (sp_drop_routine_internal(thd, sp, table))
1240             goto done;
1241           break;
1242         case TYPE_ENUM_TRIGGER:
1243         case TYPE_ENUM_PROXY:
1244           DBUG_ASSERT(0);
1245           ret= SP_OK;
1246         }
1247       }
1248       else if (lex->create_info.if_not_exists())
1249       {
1250         push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE,
1251                             ER_SP_ALREADY_EXISTS,
1252                             ER_THD(thd, ER_SP_ALREADY_EXISTS),
1253                             type_str(), sp->m_name.str);
1254 
1255         ret= FALSE;
1256 
1257         // Setting retstr as it is used for logging.
1258         if (type() == TYPE_ENUM_FUNCTION)
1259         {
1260           sp_returns_type(thd, retstr, sp);
1261           returns= retstr.lex_cstring();
1262         }
1263         goto log;
1264       }
1265       else
1266       {
1267         my_error(ER_SP_ALREADY_EXISTS, MYF(0), type_str(), sp->m_name.str);
1268         goto done;
1269       }
1270     }
1271 
1272     restore_record(table, s->default_values); // Get default values for fields
1273 
1274     /* NOTE: all needed privilege checks have been already done. */
1275     thd->lex->definer->set_lex_string(&definer, definer_buf);
1276 
1277     if (table->s->fields < MYSQL_PROC_FIELD_COUNT)
1278     {
1279       my_error(ER_SP_STORE_FAILED, MYF(0), type_str(), sp->m_name.str);
1280       goto done;
1281     }
1282 
1283     if (system_charset_info->cset->numchars(system_charset_info,
1284                                             sp->m_name.str,
1285                                             sp->m_name.str+sp->m_name.length) >
1286         table->field[MYSQL_PROC_FIELD_NAME]->char_length())
1287     {
1288       my_error(ER_TOO_LONG_IDENT, MYF(0), sp->m_name.str);
1289       goto done;
1290     }
1291     if (sp->m_body.length > table->field[MYSQL_PROC_FIELD_BODY]->field_length)
1292     {
1293       my_error(ER_TOO_LONG_BODY, MYF(0), sp->m_name.str);
1294       goto done;
1295     }
1296 
1297     store_failed=
1298       table->field[MYSQL_PROC_FIELD_DB]->
1299         store(sp->m_db, system_charset_info);
1300 
1301     store_failed= store_failed ||
1302       table->field[MYSQL_PROC_FIELD_NAME]->
1303         store(sp->m_name, system_charset_info);
1304 
1305     if (sp->agg_type() != DEFAULT_AGGREGATE)
1306     {
1307       store_failed= store_failed ||
1308         table->field[MYSQL_PROC_FIELD_AGGREGATE]->
1309           store((longlong)sp->agg_type(),TRUE);
1310     }
1311 
1312     store_failed= store_failed ||
1313       table->field[MYSQL_PROC_MYSQL_TYPE]->
1314         store((longlong) type(), true);
1315 
1316     store_failed= store_failed ||
1317       table->field[MYSQL_PROC_FIELD_SPECIFIC_NAME]->
1318         store(sp->m_name, system_charset_info);
1319 
1320     if (sp->daccess() != SP_DEFAULT_ACCESS)
1321     {
1322       store_failed= store_failed ||
1323         table->field[MYSQL_PROC_FIELD_ACCESS]->
1324           store((longlong)sp->daccess(), TRUE);
1325     }
1326 
1327     store_failed= store_failed ||
1328       table->field[MYSQL_PROC_FIELD_DETERMINISTIC]->
1329         store((longlong)(sp->detistic() ? 1 : 2), TRUE);
1330 
1331     if (sp->suid() != SP_IS_DEFAULT_SUID)
1332     {
1333       store_failed= store_failed ||
1334         table->field[MYSQL_PROC_FIELD_SECURITY_TYPE]->
1335           store((longlong)sp->suid(), TRUE);
1336     }
1337 
1338     store_failed= store_failed ||
1339       table->field[MYSQL_PROC_FIELD_PARAM_LIST]->
1340         store(sp->m_params, system_charset_info);
1341 
1342     if (type() == TYPE_ENUM_FUNCTION)
1343     {
1344       sp_returns_type(thd, retstr, sp);
1345       returns= retstr.lex_cstring();
1346 
1347       store_failed= store_failed ||
1348         table->field[MYSQL_PROC_FIELD_RETURNS]->
1349           store(retstr.ptr(), retstr.length(), system_charset_info);
1350     }
1351 
1352     store_failed= store_failed ||
1353       table->field[MYSQL_PROC_FIELD_BODY]->
1354         store(sp->m_body, system_charset_info);
1355 
1356     store_failed= store_failed ||
1357       table->field[MYSQL_PROC_FIELD_DEFINER]->
1358         store(definer, system_charset_info);
1359 
1360     ((Field_timestamp *)table->field[MYSQL_PROC_FIELD_CREATED])->set_time();
1361     ((Field_timestamp *)table->field[MYSQL_PROC_FIELD_MODIFIED])->set_time();
1362 
1363     store_failed= store_failed ||
1364       table->field[MYSQL_PROC_FIELD_SQL_MODE]->
1365         store((longlong)saved_mode, TRUE);
1366 
1367     if (sp->comment().str)
1368     {
1369       store_failed= store_failed ||
1370         table->field[MYSQL_PROC_FIELD_COMMENT]->
1371           store(sp->comment(), system_charset_info);
1372     }
1373 
1374     if (type() == TYPE_ENUM_FUNCTION &&
1375         !trust_function_creators && mysql_bin_log.is_open())
1376     {
1377       if (!sp->detistic())
1378       {
1379 	/*
1380 	  Note that this test is not perfect; one could use
1381 	  a non-deterministic read-only function in an update statement.
1382 	*/
1383 	enum enum_sp_data_access access=
1384 	  (sp->daccess() == SP_DEFAULT_ACCESS) ?
1385 	  SP_DEFAULT_ACCESS_MAPPING : sp->daccess();
1386 	if (access == SP_CONTAINS_SQL ||
1387 	    access == SP_MODIFIES_SQL_DATA)
1388 	{
1389           my_error(ER_BINLOG_UNSAFE_ROUTINE, MYF(0));
1390 	  goto done;
1391 	}
1392       }
1393       if (!(thd->security_ctx->master_access & SUPER_ACL))
1394       {
1395         my_error(ER_BINLOG_CREATE_ROUTINE_NEED_SUPER,MYF(0));
1396 	goto done;
1397       }
1398     }
1399 
1400     table->field[MYSQL_PROC_FIELD_CHARACTER_SET_CLIENT]->set_notnull();
1401     store_failed= store_failed ||
1402       table->field[MYSQL_PROC_FIELD_CHARACTER_SET_CLIENT]->store(
1403         thd->charset()->csname,
1404         strlen(thd->charset()->csname),
1405         system_charset_info);
1406 
1407     table->field[MYSQL_PROC_FIELD_COLLATION_CONNECTION]->set_notnull();
1408     store_failed= store_failed ||
1409       table->field[MYSQL_PROC_FIELD_COLLATION_CONNECTION]->store(
1410         thd->variables.collation_connection->name,
1411         strlen(thd->variables.collation_connection->name),
1412         system_charset_info);
1413 
1414     table->field[MYSQL_PROC_FIELD_DB_COLLATION]->set_notnull();
1415     store_failed= store_failed ||
1416       table->field[MYSQL_PROC_FIELD_DB_COLLATION]->store(
1417         db_cs->name, strlen(db_cs->name), system_charset_info);
1418 
1419     table->field[MYSQL_PROC_FIELD_BODY_UTF8]->set_notnull();
1420     store_failed= store_failed ||
1421       table->field[MYSQL_PROC_FIELD_BODY_UTF8]->store(
1422         sp->m_body_utf8, system_charset_info);
1423 
1424     if (store_failed)
1425     {
1426       my_error(ER_CANT_CREATE_SROUTINE, MYF(0), sp->m_name.str);
1427       goto done;
1428     }
1429 
1430     if (table->file->ha_write_row(table->record[0]))
1431     {
1432       my_error(ER_SP_ALREADY_EXISTS, MYF(0), type_str(), sp->m_name.str);
1433       goto done;
1434     }
1435     /* Make change permanent and avoid 'table is marked as crashed' errors */
1436     table->file->extra(HA_EXTRA_FLUSH);
1437 
1438     sp_cache_invalidate();
1439   }
1440 
1441 log:
1442   if (mysql_bin_log.is_open())
1443   {
1444     thd->clear_error();
1445 
1446     StringBuffer<128> log_query(thd->variables.character_set_client);
1447     DBUG_ASSERT(log_query.charset()->mbminlen == 1);
1448 
1449     if (show_create_sp(thd, &log_query,
1450                        sp->m_explicit_name ? sp->m_db : null_clex_str,
1451                        sp->m_name,
1452                        sp->m_params, returns, sp->m_body,
1453                        sp->chistics(),
1454                        thd->lex->definer[0],
1455                        thd->lex->create_info,
1456                        saved_mode))
1457     {
1458       my_error(ER_OUT_OF_RESOURCES, MYF(0));
1459       goto done;
1460     }
1461     /* restore sql_mode when binloging */
1462     thd->variables.sql_mode= saved_mode;
1463     /* Such a statement can always go directly to binlog, no trans cache */
1464     if (thd->binlog_query(THD::STMT_QUERY_TYPE,
1465                           log_query.ptr(), log_query.length(),
1466                           FALSE, FALSE, FALSE, 0) > 0)
1467     {
1468       my_error(ER_ERROR_ON_WRITE, MYF(MY_WME), "binary log", -1);
1469       goto done;
1470     }
1471     thd->variables.sql_mode= 0;
1472   }
1473   ret= FALSE;
1474 
1475 done:
1476   thd->variables.sql_mode= saved_mode;
1477   DBUG_ASSERT(!thd->is_current_stmt_binlog_format_row());
1478   DBUG_RETURN(ret);
1479 }
1480 
1481 
1482 static bool
append_suid(String * buf,enum_sp_suid_behaviour suid)1483 append_suid(String *buf, enum_sp_suid_behaviour suid)
1484 {
1485   return suid == SP_IS_NOT_SUID &&
1486          buf->append(STRING_WITH_LEN("    SQL SECURITY INVOKER\n"));
1487 }
1488 
1489 
1490 static bool
append_comment(String * buf,const LEX_CSTRING & comment)1491 append_comment(String *buf, const LEX_CSTRING &comment)
1492 {
1493   if (!comment.length)
1494     return false;
1495   if (buf->append(STRING_WITH_LEN("    COMMENT ")))
1496     return true;
1497   append_unescaped(buf, comment.str, comment.length);
1498   return buf->append('\n');
1499 }
1500 
1501 
1502 static bool
append_package_chistics(String * buf,const st_sp_chistics & chistics)1503 append_package_chistics(String *buf, const st_sp_chistics &chistics)
1504 {
1505   return append_suid(buf, chistics.suid) ||
1506          append_comment(buf, chistics.comment);
1507 }
1508 
1509 
1510 bool
show_create_sp(THD * thd,String * buf,const LEX_CSTRING & db,const LEX_CSTRING & name,const LEX_CSTRING & params,const LEX_CSTRING & returns,const LEX_CSTRING & body,const st_sp_chistics & chistics,const AUTHID & definer,const DDL_options_st ddl_options,sql_mode_t sql_mode) const1511 Sp_handler_package::show_create_sp(THD *thd, String *buf,
1512                                    const LEX_CSTRING &db,
1513                                    const LEX_CSTRING &name,
1514                                    const LEX_CSTRING &params,
1515                                    const LEX_CSTRING &returns,
1516                                    const LEX_CSTRING &body,
1517                                    const st_sp_chistics &chistics,
1518                                    const AUTHID &definer,
1519                                    const DDL_options_st ddl_options,
1520                                    sql_mode_t sql_mode) const
1521 {
1522   sql_mode_t old_sql_mode= thd->variables.sql_mode;
1523   thd->variables.sql_mode= sql_mode;
1524   bool rc=
1525     buf->append(STRING_WITH_LEN("CREATE ")) ||
1526     (ddl_options.or_replace() &&
1527      buf->append(STRING_WITH_LEN("OR REPLACE "))) ||
1528     append_definer(thd, buf, &definer.user, &definer.host) ||
1529     buf->append(type_lex_cstring()) ||
1530     buf->append(" ", 1) ||
1531     (ddl_options.if_not_exists() &&
1532      buf->append(STRING_WITH_LEN("IF NOT EXISTS "))) ||
1533     (db.length > 0 &&
1534      (append_identifier(thd, buf, db.str, db.length) ||
1535       buf->append('.'))) ||
1536     append_identifier(thd, buf, name.str, name.length) ||
1537     append_package_chistics(buf, chistics) ||
1538     buf->append(" ", 1) ||
1539     buf->append(body.str, body.length);
1540   thd->variables.sql_mode= old_sql_mode;
1541   return rc;
1542 }
1543 
1544 
1545 /**
1546   Delete the record for the stored routine object from mysql.proc
1547   and do binary logging.
1548 
1549   The operation deletes the record for the stored routine specified by name
1550   from the mysql.proc table and invalidates the stored-routine cache.
1551 
1552   @param thd  Thread context.
1553   @param name Stored routine name.
1554 
1555   @return Error code. SP_OK is returned on success. Other SP_ constants are
1556   used to indicate about errors.
1557 */
1558 
1559 int
sp_drop_routine(THD * thd,const Database_qualified_name * name) const1560 Sp_handler::sp_drop_routine(THD *thd,
1561                             const Database_qualified_name *name) const
1562 {
1563   TABLE *table;
1564   int ret;
1565   DBUG_ENTER("sp_drop_routine");
1566   DBUG_PRINT("enter", ("type: %s  name: %.*s",
1567 		       type_str(),
1568 		       (int) name->m_name.length, name->m_name.str));
1569   MDL_key::enum_mdl_namespace mdl_type= get_mdl_type();
1570 
1571   /* Grab an exclusive MDL lock. */
1572   if (lock_object_name(thd, mdl_type, name->m_db.str, name->m_name.str))
1573     DBUG_RETURN(SP_DELETE_ROW_FAILED);
1574 
1575   if (!(table= open_proc_table_for_update(thd)))
1576     DBUG_RETURN(SP_OPEN_TABLE_FAILED);
1577 
1578   if ((ret= sp_find_and_drop_routine(thd, table, name)) == SP_OK &&
1579       write_bin_log(thd, TRUE, thd->query(), thd->query_length()))
1580     ret= SP_INTERNAL_ERROR;
1581   /*
1582     This statement will be replicated as a statement, even when using
1583     row-based replication.  The flag will be reset at the end of the
1584     statement.
1585   */
1586   DBUG_ASSERT(!thd->is_current_stmt_binlog_format_row());
1587   DBUG_RETURN(ret);
1588 }
1589 
1590 
1591 /**
1592   Find and updated the record for the stored routine object in mysql.proc.
1593 
1594   The operation finds the record for the stored routine specified by name
1595   in the mysql.proc table and updates it with new attributes. After
1596   successful update, the cache is invalidated.
1597 
1598   @param thd      Thread context.
1599   @param name     Stored routine name.
1600   @param chistics New values of stored routine attributes to write.
1601 
1602   @return Error code. SP_OK is returned on success. Other SP_ constants are
1603   used to indicate about errors.
1604 */
1605 
1606 int
sp_update_routine(THD * thd,const Database_qualified_name * name,const st_sp_chistics * chistics) const1607 Sp_handler::sp_update_routine(THD *thd, const Database_qualified_name *name,
1608                               const st_sp_chistics *chistics) const
1609 {
1610   TABLE *table;
1611   int ret;
1612   DBUG_ENTER("sp_update_routine");
1613   DBUG_PRINT("enter", ("type: %s  name: %.*s",
1614                        type_str(),
1615                        (int) name->m_name.length, name->m_name.str));
1616   MDL_key::enum_mdl_namespace mdl_type= get_mdl_type();
1617 
1618   /* Grab an exclusive MDL lock. */
1619   if (lock_object_name(thd, mdl_type, name->m_db.str, name->m_name.str))
1620     DBUG_RETURN(SP_OPEN_TABLE_FAILED);
1621 
1622   if (!(table= open_proc_table_for_update(thd)))
1623     DBUG_RETURN(SP_OPEN_TABLE_FAILED);
1624 
1625   if ((ret= db_find_routine_aux(thd, name, table)) == SP_OK)
1626   {
1627     if (type() == TYPE_ENUM_FUNCTION && ! trust_function_creators &&
1628         mysql_bin_log.is_open() &&
1629         (chistics->daccess == SP_CONTAINS_SQL ||
1630          chistics->daccess == SP_MODIFIES_SQL_DATA))
1631     {
1632       char *ptr;
1633       bool is_deterministic;
1634       ptr= get_field(thd->mem_root,
1635                      table->field[MYSQL_PROC_FIELD_DETERMINISTIC]);
1636       if (ptr == NULL)
1637       {
1638         ret= SP_INTERNAL_ERROR;
1639         goto err;
1640       }
1641       is_deterministic= ptr[0] == 'N' ? FALSE : TRUE;
1642       if (!is_deterministic)
1643       {
1644         my_message(ER_BINLOG_UNSAFE_ROUTINE,
1645                    ER_THD(thd, ER_BINLOG_UNSAFE_ROUTINE), MYF(0));
1646         ret= SP_INTERNAL_ERROR;
1647         goto err;
1648       }
1649     }
1650 
1651     store_record(table,record[1]);
1652     ((Field_timestamp *)table->field[MYSQL_PROC_FIELD_MODIFIED])->set_time();
1653     if (chistics->suid != SP_IS_DEFAULT_SUID)
1654       table->field[MYSQL_PROC_FIELD_SECURITY_TYPE]->
1655 	store((longlong)chistics->suid, TRUE);
1656     if (chistics->daccess != SP_DEFAULT_ACCESS)
1657       table->field[MYSQL_PROC_FIELD_ACCESS]->
1658 	store((longlong)chistics->daccess, TRUE);
1659     if (chistics->comment.str)
1660       table->field[MYSQL_PROC_FIELD_COMMENT]->store(chistics->comment,
1661 						    system_charset_info);
1662     if (chistics->agg_type != DEFAULT_AGGREGATE)
1663       table->field[MYSQL_PROC_FIELD_AGGREGATE]->
1664          store((longlong)chistics->agg_type, TRUE);
1665     if ((ret= table->file->ha_update_row(table->record[1],table->record[0])) &&
1666         ret != HA_ERR_RECORD_IS_THE_SAME)
1667       ret= SP_WRITE_ROW_FAILED;
1668     else
1669       ret= 0;
1670     /* Make change permanent and avoid 'table is marked as crashed' errors */
1671     table->file->extra(HA_EXTRA_FLUSH);
1672   }
1673 
1674   if (ret == SP_OK)
1675   {
1676     if (write_bin_log(thd, TRUE, thd->query(), thd->query_length()))
1677       ret= SP_INTERNAL_ERROR;
1678     sp_cache_invalidate();
1679   }
1680 err:
1681   DBUG_ASSERT(!thd->is_current_stmt_binlog_format_row());
1682   DBUG_RETURN(ret);
1683 }
1684 
1685 
1686 /**
1687   This internal handler is used to trap errors from opening mysql.proc.
1688 */
1689 
1690 class Lock_db_routines_error_handler : public Internal_error_handler
1691 {
1692 public:
handle_condition(THD * thd,uint sql_errno,const char * sqlstate,Sql_condition::enum_warning_level * level,const char * msg,Sql_condition ** cond_hdl)1693   bool handle_condition(THD *thd,
1694                         uint sql_errno,
1695                         const char* sqlstate,
1696                         Sql_condition::enum_warning_level *level,
1697                         const char* msg,
1698                         Sql_condition ** cond_hdl)
1699   {
1700     if (sql_errno == ER_NO_SUCH_TABLE ||
1701         sql_errno == ER_NO_SUCH_TABLE_IN_ENGINE ||
1702         sql_errno == ER_CANNOT_LOAD_FROM_TABLE_V2 ||
1703         sql_errno == ER_COL_COUNT_DOESNT_MATCH_PLEASE_UPDATE ||
1704         sql_errno == ER_COL_COUNT_DOESNT_MATCH_CORRUPTED_V2)
1705       return true;
1706     return false;
1707   }
1708 };
1709 
1710 
1711 /**
1712    Acquires exclusive metadata lock on all stored routines in the
1713    given database.
1714 
1715    @note Will also return false (=success) if mysql.proc can't be opened
1716          or is outdated. This allows DROP DATABASE to continue in these
1717          cases.
1718  */
1719 
lock_db_routines(THD * thd,const char * db)1720 bool lock_db_routines(THD *thd, const char *db)
1721 {
1722   TABLE *table;
1723   uint key_len;
1724   Open_tables_backup open_tables_state_backup;
1725   MDL_request_list mdl_requests;
1726   Lock_db_routines_error_handler err_handler;
1727   uchar keybuf[MAX_KEY_LENGTH];
1728   DBUG_ENTER("lock_db_routines");
1729 
1730   DBUG_SLOW_ASSERT(ok_for_lower_case_names(db));
1731 
1732   /*
1733     mysql.proc will be re-opened during deletion, so we can ignore
1734     errors when opening the table here. The error handler is
1735     used to avoid getting the same warning twice.
1736   */
1737   thd->push_internal_handler(&err_handler);
1738   table= open_proc_table_for_read(thd, &open_tables_state_backup);
1739   thd->pop_internal_handler();
1740   if (!table)
1741   {
1742     /*
1743       DROP DATABASE should not fail even if mysql.proc does not exist
1744       or is outdated. We therefore only abort mysql_rm_db() if we
1745       have errors not handled by the error handler.
1746     */
1747     DBUG_RETURN(thd->is_error() || thd->killed);
1748   }
1749 
1750   table->field[MYSQL_PROC_FIELD_DB]->store(db, strlen(db), system_charset_info);
1751   key_len= table->key_info->key_part[0].store_length;
1752   table->field[MYSQL_PROC_FIELD_DB]->get_key_image(keybuf, key_len, Field::itRAW);
1753   int nxtres= table->file->ha_index_init(0, 1);
1754   if (nxtres)
1755   {
1756     table->file->print_error(nxtres, MYF(0));
1757     close_system_tables(thd, &open_tables_state_backup);
1758     DBUG_RETURN(true);
1759   }
1760 
1761   if (! table->file->ha_index_read_map(table->record[0], keybuf, (key_part_map)1,
1762                                        HA_READ_KEY_EXACT))
1763   {
1764     do
1765     {
1766       char *sp_name= get_field(thd->mem_root,
1767                                table->field[MYSQL_PROC_FIELD_NAME]);
1768       if (sp_name == NULL) // skip invalid sp names (hand-edited mysql.proc?)
1769         continue;
1770 
1771       longlong sp_type= table->field[MYSQL_PROC_MYSQL_TYPE]->val_int();
1772       MDL_request *mdl_request= new (thd->mem_root) MDL_request;
1773       const Sp_handler *sph= Sp_handler::handler((stored_procedure_type)
1774                                                  sp_type);
1775       if (!sph)
1776         sph= &sp_handler_procedure;
1777       mdl_request->init(sph->get_mdl_type(), db, sp_name,
1778                         MDL_EXCLUSIVE, MDL_TRANSACTION);
1779       mdl_requests.push_front(mdl_request);
1780     } while (! (nxtres= table->file->ha_index_next_same(table->record[0], keybuf, key_len)));
1781   }
1782   table->file->ha_index_end();
1783   if (nxtres != 0 && nxtres != HA_ERR_END_OF_FILE)
1784   {
1785     table->file->print_error(nxtres, MYF(0));
1786     close_system_tables(thd, &open_tables_state_backup);
1787     DBUG_RETURN(true);
1788   }
1789   close_system_tables(thd, &open_tables_state_backup);
1790 
1791   /* We should already hold a global IX lock and a schema X lock. */
1792   DBUG_ASSERT(thd->mdl_context.is_lock_owner(MDL_key::GLOBAL, "", "",
1793                                              MDL_INTENTION_EXCLUSIVE) &&
1794               thd->mdl_context.is_lock_owner(MDL_key::SCHEMA, db, "",
1795                                              MDL_EXCLUSIVE));
1796   DBUG_RETURN(thd->mdl_context.acquire_locks(&mdl_requests,
1797                                              thd->variables.lock_wait_timeout));
1798 }
1799 
1800 
1801 /**
1802   Drop all routines in database 'db'
1803 
1804   @note Close the thread tables, the calling code might want to
1805   delete from other system tables afterwards.
1806 */
1807 
1808 int
sp_drop_db_routines(THD * thd,const char * db)1809 sp_drop_db_routines(THD *thd, const char *db)
1810 {
1811   TABLE *table;
1812   int ret;
1813   uint key_len;
1814   MDL_savepoint mdl_savepoint= thd->mdl_context.mdl_savepoint();
1815   uchar keybuf[MAX_KEY_LENGTH];
1816   DBUG_ENTER("sp_drop_db_routines");
1817   DBUG_PRINT("enter", ("db: %s", db));
1818 
1819   ret= SP_OPEN_TABLE_FAILED;
1820   if (!(table= open_proc_table_for_update(thd)))
1821     goto err;
1822 
1823   table->field[MYSQL_PROC_FIELD_DB]->store(db, strlen(db), system_charset_info);
1824   key_len= table->key_info->key_part[0].store_length;
1825   table->field[MYSQL_PROC_FIELD_DB]->get_key_image(keybuf, key_len, Field::itRAW);
1826 
1827   ret= SP_OK;
1828   if (table->file->ha_index_init(0, 1))
1829   {
1830     ret= SP_KEY_NOT_FOUND;
1831     goto err_idx_init;
1832   }
1833   if (!table->file->ha_index_read_map(table->record[0], keybuf, (key_part_map)1,
1834                                       HA_READ_KEY_EXACT))
1835   {
1836     int nxtres;
1837     bool deleted= FALSE;
1838 
1839     do
1840     {
1841       if (! table->file->ha_delete_row(table->record[0]))
1842 	deleted= TRUE;		/* We deleted something */
1843       else
1844       {
1845 	ret= SP_DELETE_ROW_FAILED;
1846 	nxtres= 0;
1847 	break;
1848       }
1849     } while (!(nxtres= table->file->ha_index_next_same(table->record[0],
1850                                                        keybuf, key_len)));
1851     if (nxtres != HA_ERR_END_OF_FILE)
1852       ret= SP_KEY_NOT_FOUND;
1853     if (deleted)
1854     {
1855       sp_cache_invalidate();
1856       /* Make change permanent and avoid 'table is marked as crashed' errors */
1857       table->file->extra(HA_EXTRA_FLUSH);
1858     }
1859   }
1860   table->file->ha_index_end();
1861 
1862 err_idx_init:
1863   close_thread_tables(thd);
1864   /*
1865     Make sure to only release the MDL lock on mysql.proc, not other
1866     metadata locks DROP DATABASE might have acquired.
1867   */
1868   thd->mdl_context.rollback_to_savepoint(mdl_savepoint);
1869 
1870 err:
1871   DBUG_RETURN(ret);
1872 }
1873 
1874 
1875 /**
1876   Implement SHOW CREATE statement for stored routines.
1877 
1878   The operation finds the stored routine object specified by name and then
1879   calls sp_head::show_create_routine() for the object.
1880 
1881   @param thd  Thread context.
1882   @param name Stored routine name.
1883 
1884   @return Error status.
1885     @retval FALSE on success
1886     @retval TRUE on error
1887 */
1888 
1889 bool
sp_show_create_routine(THD * thd,const Database_qualified_name * name) const1890 Sp_handler::sp_show_create_routine(THD *thd,
1891                                    const Database_qualified_name *name) const
1892 {
1893   DBUG_ENTER("sp_show_create_routine");
1894   DBUG_PRINT("enter", ("type: %s name: %.*s",
1895                        type_str(),
1896                        (int) name->m_name.length,
1897                        name->m_name.str));
1898   /*
1899     @todo: Consider using prelocking for this code as well. Currently
1900     SHOW CREATE PROCEDURE/FUNCTION is a dirty read of the data
1901     dictionary, i.e. takes no metadata locks.
1902     It is "safe" to do as long as it doesn't affect the results
1903     of the binary log or the query cache, which currently it does not.
1904   */
1905   sp_head *sp= 0;
1906 
1907   DBUG_EXECUTE_IF("cache_sp_in_show_create",
1908     /* Some tests need just need a way to cache SP without other side-effects.*/
1909     sp_cache_routine(thd, name, false, &sp);
1910     sp->show_create_routine(thd, this);
1911     DBUG_RETURN(false);
1912   );
1913 
1914   bool free_sp= db_find_routine(thd, name, &sp) == SP_OK;
1915   bool ret= !sp || sp->show_create_routine(thd, this);
1916   if (ret)
1917   {
1918     /*
1919       If we have insufficient privileges, pretend the routine
1920       does not exist.
1921     */
1922     my_error(ER_SP_DOES_NOT_EXIST, MYF(0), type_str(), name->m_name.str);
1923   }
1924   if (free_sp)
1925     sp_head::destroy(sp);
1926   DBUG_RETURN(ret);
1927 }
1928 
1929 
1930 /*
1931   A helper class to split package name from a dot-qualified name
1932   and return it as a 0-terminated string
1933     'pkg.name' -> 'pkg\0'
1934 */
1935 
1936 class Prefix_name_buf: public LEX_CSTRING
1937 {
1938   char m_buf[SAFE_NAME_LEN + 1];
1939 public:
Prefix_name_buf(const THD * thd,const LEX_CSTRING & name)1940   Prefix_name_buf(const THD *thd, const LEX_CSTRING &name)
1941   {
1942     const char *end;
1943     if (!(end= strrchr(name.str, '.')))
1944     {
1945       static_cast<LEX_CSTRING*>(this)[0]= null_clex_str;
1946     }
1947     else
1948     {
1949       str= m_buf;
1950       length= end - name.str;
1951       set_if_smaller(length, sizeof(m_buf) - 1);
1952       memcpy(m_buf, name.str, length);
1953       m_buf[length]= '\0';
1954     }
1955   }
1956 };
1957 
1958 
1959 /*
1960   In case of recursions, we create multiple copies of the same SP.
1961   This methods checks the current recursion depth.
1962   In case if the recursion limit exceeded, it throws an error
1963   and returns NULL.
1964   Otherwise, depending on the current recursion level, it:
1965   - either returns the original SP,
1966   - or makes and returns a new clone of SP
1967 */
1968 
1969 sp_head *
sp_clone_and_link_routine(THD * thd,const Database_qualified_name * name,sp_head * sp) const1970 Sp_handler::sp_clone_and_link_routine(THD *thd,
1971                                       const Database_qualified_name *name,
1972                                       sp_head *sp) const
1973 {
1974   DBUG_ENTER("sp_link_routine");
1975   int rc;
1976   ulong level;
1977   sp_head *new_sp;
1978   LEX_CSTRING returns= empty_clex_str;
1979   Database_qualified_name lname(name->m_db, name->m_name);
1980 #ifndef DBUG_OFF
1981   uint parent_subroutine_count=
1982     !sp->m_parent ? 0 :
1983      sp->m_parent->m_routine_declarations.elements +
1984      sp->m_parent->m_routine_implementations.elements;
1985 #endif
1986 
1987   /*
1988     String buffer for RETURNS data type must have system charset;
1989     64 -- size of "returns" column of mysql.proc.
1990   */
1991   String retstr(64);
1992   retstr.set_charset(sp->get_creation_ctx()->get_client_cs());
1993 
1994   DBUG_PRINT("info", ("found: %p", sp));
1995   if (sp->m_first_free_instance)
1996   {
1997     DBUG_PRINT("info", ("first free: %p  level: %lu  flags %x",
1998                         sp->m_first_free_instance,
1999                         sp->m_first_free_instance->m_recursion_level,
2000                         sp->m_first_free_instance->m_flags));
2001     DBUG_ASSERT(!(sp->m_first_free_instance->m_flags & sp_head::IS_INVOKED));
2002     if (sp->m_first_free_instance->m_recursion_level > recursion_depth(thd))
2003     {
2004       recursion_level_error(thd, sp);
2005       DBUG_RETURN(0);
2006     }
2007     DBUG_RETURN(sp->m_first_free_instance);
2008   }
2009   /*
2010     Actually depth could be +1 than the actual value in case a SP calls
2011     SHOW CREATE PROCEDURE. Hence, the linked list could hold up to one more
2012     instance.
2013   */
2014 
2015   level= sp->m_last_cached_sp->m_recursion_level + 1;
2016   if (level > recursion_depth(thd))
2017   {
2018     recursion_level_error(thd, sp);
2019     DBUG_RETURN(0);
2020   }
2021 
2022   if (type() == TYPE_ENUM_FUNCTION)
2023   {
2024     sp_returns_type(thd, retstr, sp);
2025     returns= retstr.lex_cstring();
2026   }
2027 
2028   if (sp->m_parent)
2029   {
2030     /*
2031       If we're cloning a recursively called package routine,
2032       we need to take some special measures:
2033       1. Cut the package name prefix from the routine name: 'pkg1.p1' -> 'p1',
2034          to have db_load_routine() generate and parse a query like this:
2035            CREATE PROCEDURE p1 ...;
2036          rather than:
2037            CREATE PROCEDURE pkg1.p1 ...;
2038          The latter would be misinterpreted by the parser as a standalone
2039          routine 'p1' in the database 'pkg1', which is not what we need.
2040       2. We pass m_parent to db_load_routine() to have it set
2041          thd->lex->sphead to sp->m_parent before calling parse_sql().
2042       These two measures allow to parse a package subroutine using
2043       the grammar for standalone routines, e.g.:
2044         CREATE PROCEDURE p1 ... END;
2045       instead of going through a more complex query, e.g.:
2046         CREATE PACKAGE BODY pkg1 AS
2047           PROCEDURE p1 ... END;
2048         END;
2049     */
2050     size_t prefix_length= sp->m_parent->m_name.length + 1;
2051     DBUG_ASSERT(prefix_length < lname.m_name.length);
2052     DBUG_ASSERT(lname.m_name.str[sp->m_parent->m_name.length] == '.');
2053     lname.m_name.str+= prefix_length;
2054     lname.m_name.length-= prefix_length;
2055     sp->m_parent->m_is_cloning_routine= true;
2056   }
2057 
2058 
2059   rc= db_load_routine(thd, &lname, &new_sp,
2060                       sp->m_sql_mode, sp->m_params, returns,
2061                       sp->m_body, sp->chistics(),
2062                       sp->m_definer,
2063                       sp->m_created, sp->m_modified,
2064                       sp->m_parent,
2065                       sp->get_creation_ctx());
2066   if (sp->m_parent)
2067     sp->m_parent->m_is_cloning_routine= false;
2068 
2069   if (rc == SP_OK)
2070   {
2071 #ifndef DBUG_OFF
2072     /*
2073       We've just called the parser to clone the routine.
2074       In case of a package routine, make sure that the parser
2075       has not added any new subroutines directly to the parent package.
2076       The cloned subroutine instances get linked below to the first instance,
2077       they must have no direct links from the parent package.
2078     */
2079     DBUG_ASSERT(!sp->m_parent ||
2080                 parent_subroutine_count ==
2081                 sp->m_parent->m_routine_declarations.elements +
2082                 sp->m_parent->m_routine_implementations.elements);
2083 #endif
2084     sp->m_last_cached_sp->m_next_cached_sp= new_sp;
2085     new_sp->m_recursion_level= level;
2086     new_sp->m_first_instance= sp;
2087     sp->m_last_cached_sp= sp->m_first_free_instance= new_sp;
2088     DBUG_PRINT("info", ("added level: %p, level: %lu, flags %x",
2089                         new_sp, new_sp->m_recursion_level,
2090                         new_sp->m_flags));
2091     DBUG_RETURN(new_sp);
2092   }
2093   DBUG_RETURN(0);
2094 }
2095 
2096 
2097 /**
2098   Obtain object representing stored procedure/function by its name from
2099   stored procedures cache and looking into mysql.proc if needed.
2100 
2101   @param thd          thread context
2102   @param name         name of procedure
2103   @param cp           hash to look routine in
2104   @param cache_only   if true perform cache-only lookup
2105                       (Don't look in mysql.proc).
2106 
2107   @retval
2108     NonNULL pointer to sp_head object for the procedure
2109   @retval
2110     NULL    in case of error.
2111 */
2112 
2113 sp_head *
sp_find_routine(THD * thd,const Database_qualified_name * name,bool cache_only) const2114 Sp_handler::sp_find_routine(THD *thd, const Database_qualified_name *name,
2115                             bool cache_only) const
2116 {
2117   DBUG_ENTER("Sp_handler::sp_find_routine");
2118   DBUG_PRINT("enter", ("name:  %.*s.%.*s  type: %s  cache only %d",
2119                        (int) name->m_db.length, name->m_db.str,
2120                        (int) name->m_name.length, name->m_name.str,
2121                        type_str(), cache_only));
2122   sp_cache **cp= get_cache(thd);
2123   sp_head *sp;
2124 
2125   if ((sp= sp_cache_lookup(cp, name)))
2126     DBUG_RETURN(sp_clone_and_link_routine(thd, name, sp));
2127   if (!cache_only)
2128     db_find_and_cache_routine(thd, name, &sp);
2129   DBUG_RETURN(sp);
2130 }
2131 
2132 
2133 /**
2134   Find a package routine.
2135   See sp_cache_routine() for more information on parameters and return value.
2136 
2137   @param thd         - current THD
2138   @param pkgname_str - package name
2139   @param name        - a mixed qualified name, with:
2140                        * name->m_db set to the database, e.g. "dbname"
2141                        * name->m_name set to a package-qualified name,
2142                          e.g. "pkgname.spname".
2143   @param cache_only  - don't load mysql.proc if not cached
2144   @retval non-NULL   - a pointer to an sp_head object
2145   @retval NULL       - an error happened.
2146 */
2147 
2148 sp_head *
sp_find_package_routine(THD * thd,const LEX_CSTRING pkgname_str,const Database_qualified_name * name,bool cache_only) const2149 Sp_handler::sp_find_package_routine(THD *thd,
2150                                     const LEX_CSTRING pkgname_str,
2151                                     const Database_qualified_name *name,
2152                                     bool cache_only) const
2153 {
2154   DBUG_ENTER("sp_find_package_routine");
2155   Database_qualified_name pkgname(&name->m_db, &pkgname_str);
2156   sp_head *ph= sp_cache_lookup(&thd->sp_package_body_cache, &pkgname);
2157   if (!ph && !cache_only)
2158     sp_handler_package_body.db_find_and_cache_routine(thd, &pkgname, &ph);
2159   if (ph)
2160   {
2161     LEX_CSTRING tmp= name->m_name;
2162     const char *dot= strrchr(tmp.str, '.');
2163     size_t prefix_length= dot ? dot - tmp.str + 1 : 0;
2164     sp_package *pkg= ph->get_package();
2165     tmp.str+= prefix_length;
2166     tmp.length-= prefix_length;
2167     LEX *plex= pkg ? pkg->m_routine_implementations.find(tmp, type()) : NULL;
2168     sp_head *sp= plex ? plex->sphead : NULL;
2169     if (sp)
2170       DBUG_RETURN(sp_clone_and_link_routine(thd, name, sp));
2171   }
2172   DBUG_RETURN(NULL);
2173 }
2174 
2175 
2176 /**
2177   Find a package routine.
2178   See sp_cache_routine() for more information on parameters and return value.
2179 
2180   @param thd        - current THD
2181   @param name       - Qualified name with the following format:
2182                       * name->m_db is set to the database name, e.g. "dbname"
2183                       * name->m_name is set to a package-qualified name,
2184                         e.g. "pkgname.spname", as a single string with a
2185                         dot character as a separator.
2186   @param cache_only - don't load mysql.proc if not cached
2187   @retval non-NULL  - a pointer to an sp_head object
2188   @retval NULL      - an error happened
2189 */
2190 
2191 sp_head *
sp_find_package_routine(THD * thd,const Database_qualified_name * name,bool cache_only) const2192 Sp_handler::sp_find_package_routine(THD *thd,
2193                                     const Database_qualified_name *name,
2194                                     bool cache_only) const
2195 {
2196   DBUG_ENTER("Sp_handler::sp_find_package_routine");
2197   Prefix_name_buf pkgname(thd, name->m_name);
2198   DBUG_ASSERT(pkgname.length);
2199   DBUG_RETURN(sp_find_package_routine(thd, pkgname, name, cache_only));
2200 }
2201 
2202 
2203 /**
2204   This is used by sql_acl.cc:mysql_routine_grant() and is used to find
2205   the routines in 'routines'.
2206 
2207   @param thd Thread handler
2208   @param routines List of needles in the hay stack
2209 
2210   @return
2211     @retval FALSE Found.
2212     @retval TRUE  Not found
2213 */
2214 
2215 bool
sp_exist_routines(THD * thd,TABLE_LIST * routines) const2216 Sp_handler::sp_exist_routines(THD *thd, TABLE_LIST *routines) const
2217 {
2218   TABLE_LIST *routine;
2219   bool sp_object_found;
2220   DBUG_ENTER("sp_exists_routine");
2221   for (routine= routines; routine; routine= routine->next_global)
2222   {
2223     sp_name *name;
2224     LEX_CSTRING lex_db;
2225     LEX_CSTRING lex_name;
2226     thd->make_lex_string(&lex_db, routine->db.str, routine->db.length);
2227     thd->make_lex_string(&lex_name, routine->table_name.str,
2228                          routine->table_name.length);
2229     name= new sp_name(&lex_db, &lex_name, true);
2230     sp_object_found= sp_find_routine(thd, name, false) != NULL;
2231     thd->get_stmt_da()->clear_warning_info(thd->query_id);
2232     if (! sp_object_found)
2233     {
2234       my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "FUNCTION or PROCEDURE",
2235                routine->table_name.str);
2236       DBUG_RETURN(TRUE);
2237     }
2238   }
2239   DBUG_RETURN(FALSE);
2240 }
2241 
2242 
sp_sroutine_key(const uchar * ptr,size_t * plen,my_bool first)2243 extern "C" uchar* sp_sroutine_key(const uchar *ptr, size_t *plen,
2244                                   my_bool first)
2245 {
2246   Sroutine_hash_entry *rn= (Sroutine_hash_entry *)ptr;
2247   *plen= rn->mdl_request.key.length();
2248   return (uchar *)rn->mdl_request.key.ptr();
2249 }
2250 
2251 
2252 /**
2253   Auxilary function that adds new element to the set of stored routines
2254   used by statement.
2255 
2256   In case when statement uses stored routines but does not need
2257   prelocking (i.e. it does not use any tables) we will access the
2258   elements of Query_tables_list::sroutines set on prepared statement
2259   re-execution. Because of this we have to allocate memory for both
2260   hash element and copy of its key in persistent arena.
2261 
2262   @param prelocking_ctx  Prelocking context of the statement
2263   @param arena           Arena in which memory for new element will be
2264                          allocated
2265   @param key             Key for the hash representing set
2266   @param belong_to_view  Uppermost view which uses this routine
2267                          (0 if routine is not used by view)
2268 
2269   @note
2270     Will also add element to end of 'Query_tables_list::sroutines_list' list.
2271 
2272   @todo
2273     When we will got rid of these accesses on re-executions we will be
2274     able to allocate memory for hash elements in non-persitent arena
2275     and directly use key values from sp_head::m_sroutines sets instead
2276     of making their copies.
2277 
2278   @retval
2279     TRUE   new element was added.
2280   @retval
2281     FALSE  element was not added (because it is already present in
2282     the set).
2283 */
2284 
sp_add_used_routine(Query_tables_list * prelocking_ctx,Query_arena * arena,const MDL_key * key,const Sp_handler * handler,TABLE_LIST * belong_to_view)2285 bool sp_add_used_routine(Query_tables_list *prelocking_ctx, Query_arena *arena,
2286                          const MDL_key *key,
2287                          const Sp_handler *handler,
2288                          TABLE_LIST *belong_to_view)
2289 {
2290   my_hash_init_opt(&prelocking_ctx->sroutines, system_charset_info,
2291                    Query_tables_list::START_SROUTINES_HASH_SIZE,
2292                    0, 0, sp_sroutine_key, 0, 0);
2293 
2294   if (!my_hash_search(&prelocking_ctx->sroutines, key->ptr(), key->length()))
2295   {
2296     Sroutine_hash_entry *rn=
2297       (Sroutine_hash_entry *)arena->alloc(sizeof(Sroutine_hash_entry));
2298     if (unlikely(!rn)) // OOM. Error will be reported using fatal_error().
2299       return FALSE;
2300     rn->mdl_request.init(key, MDL_SHARED, MDL_TRANSACTION);
2301     if (my_hash_insert(&prelocking_ctx->sroutines, (uchar *)rn))
2302       return FALSE;
2303     prelocking_ctx->sroutines_list.link_in_list(rn, &rn->next);
2304     rn->belong_to_view= belong_to_view;
2305     rn->m_handler= handler;
2306     rn->m_sp_cache_version= 0;
2307     return TRUE;
2308   }
2309   return FALSE;
2310 }
2311 
2312 
2313 /*
2314   Find and cache a routine in a parser-safe reentrant mode.
2315 
2316   If sp_head is not in the cache,
2317   its loaded from mysql.proc, parsed using parse_sql(), and cached.
2318   Note, as it is called from inside parse_sql() itself,
2319   we need to preserve and restore the parser state.
2320 
2321   It's used during parsing of CREATE PACKAGE BODY,
2322   to load the corresponding CREATE PACKAGE.
2323 */
2324 
2325 int
sp_cache_routine_reentrant(THD * thd,const Database_qualified_name * name,sp_head ** sp) const2326 Sp_handler::sp_cache_routine_reentrant(THD *thd,
2327                                        const Database_qualified_name *name,
2328                                        sp_head **sp) const
2329 {
2330   int ret;
2331   Parser_state *oldps= thd->m_parser_state;
2332   thd->m_parser_state= NULL;
2333   ret= sp_cache_routine(thd, name, false, sp);
2334   thd->m_parser_state= oldps;
2335   return ret;
2336 }
2337 
2338 
2339 /**
2340   Check if a routine has a declaration in the CREATE PACKAGE statement,
2341   by looking up in thd->sp_package_spec_cache, and by loading from mysql.proc
2342   if needed.
2343 
2344     @param thd      current thd
2345     @param db       the database name
2346     @param package  the package name
2347     @param name     the routine name
2348     @param type     the routine type
2349     @retval         true, if the routine has a declaration
2350     @retval         false, if the routine does not have a declaration
2351 
2352   This function can be called in arbitrary context:
2353   - inside a package routine
2354   - inside a standalone routine
2355   - inside a anonymous block
2356   - outside of any routines
2357 
2358   The state of the package specification (i.e. the CREATE PACKAGE statement)
2359   for "package" before the call of this function is not known:
2360    it can be cached, or not cached.
2361   After the call of this function, the package specification is always cached,
2362   unless a fatal error happens.
2363 */
2364 
2365 static bool
is_package_public_routine(THD * thd,const LEX_CSTRING & db,const LEX_CSTRING & package,const LEX_CSTRING & routine,stored_procedure_type type)2366 is_package_public_routine(THD *thd,
2367                           const LEX_CSTRING &db,
2368                           const LEX_CSTRING &package,
2369                           const LEX_CSTRING &routine,
2370                           stored_procedure_type type)
2371 {
2372   sp_head *sp= NULL;
2373   Database_qualified_name tmp(db, package);
2374   bool ret= sp_handler_package_spec.
2375               sp_cache_routine_reentrant(thd, &tmp, &sp);
2376   sp_package *spec= (!ret && sp) ? sp->get_package() : NULL;
2377   return spec && spec->m_routine_declarations.find(routine, type);
2378 }
2379 
2380 
2381 /**
2382   Check if a routine has a declaration in the CREATE PACKAGE statement
2383   by looking up in sp_package_spec_cache.
2384 
2385     @param thd      current thd
2386     @param db       the database name
2387     @param pkgname  the package name
2388     @param name     the routine name
2389     @param type     the routine type
2390     @retval         true, if the routine has a declaration
2391     @retval         false, if the routine does not have a declaration
2392 
2393   This function is called in the middle of CREATE PACKAGE BODY parsing,
2394   to lookup the current package routines.
2395   The package specification (i.e. the CREATE PACKAGE statement) for
2396   the current package body must already be loaded and cached at this point.
2397 */
2398 
2399 static bool
is_package_public_routine_quick(THD * thd,const LEX_CSTRING & db,const LEX_CSTRING & pkgname,const LEX_CSTRING & name,stored_procedure_type type)2400 is_package_public_routine_quick(THD *thd,
2401                                 const LEX_CSTRING &db,
2402                                 const LEX_CSTRING &pkgname,
2403                                 const LEX_CSTRING &name,
2404                                 stored_procedure_type type)
2405 {
2406   Database_qualified_name tmp(db, pkgname);
2407   sp_head *sp= sp_cache_lookup(&thd->sp_package_spec_cache, &tmp);
2408   sp_package *pkg= sp ? sp->get_package() : NULL;
2409   DBUG_ASSERT(pkg); // Must already be cached
2410   return pkg && pkg->m_routine_declarations.find(name, type);
2411 }
2412 
2413 
2414 /**
2415   Check if a qualified name, e.g. "CALL name1.name2",
2416   refers to a known routine in the package body "pkg".
2417 */
2418 
2419 static bool
is_package_body_routine(THD * thd,sp_package * pkg,const LEX_CSTRING & name1,const LEX_CSTRING & name2,stored_procedure_type type)2420 is_package_body_routine(THD *thd, sp_package *pkg,
2421                         const LEX_CSTRING &name1,
2422                         const LEX_CSTRING &name2,
2423                         stored_procedure_type type)
2424 {
2425   return Sp_handler::eq_routine_name(pkg->m_name, name1) &&
2426          (pkg->m_routine_declarations.find(name2, type) ||
2427           pkg->m_routine_implementations.find(name2, type));
2428 }
2429 
2430 
2431 /**
2432   Resolve a qualified routine reference xxx.yyy(), between:
2433   - A standalone routine: xxx.yyy
2434   - A package routine:    current_database.xxx.yyy
2435 */
2436 
2437 bool Sp_handler::
sp_resolve_package_routine_explicit(THD * thd,sp_head * caller,sp_name * name,const Sp_handler ** pkg_routine_handler,Database_qualified_name * pkgname) const2438   sp_resolve_package_routine_explicit(THD *thd,
2439                                       sp_head *caller,
2440                                       sp_name *name,
2441                                       const Sp_handler **pkg_routine_handler,
2442                                       Database_qualified_name *pkgname) const
2443 {
2444   sp_package *pkg;
2445 
2446   /*
2447     If a qualified routine name was used, e.g. xxx.yyy(),
2448     we possibly have a call to a package routine.
2449     Rewrite name if name->m_db (xxx) is a known package,
2450     and name->m_name (yyy) is a known routine in this package.
2451   */
2452   LEX_CSTRING tmpdb= thd->db;
2453   if (is_package_public_routine(thd, tmpdb, name->m_db, name->m_name, type()) ||
2454       // Check if a package routine calls a private routine
2455       (caller && caller->m_parent &&
2456        is_package_body_routine(thd, caller->m_parent,
2457                                name->m_db, name->m_name, type())) ||
2458       // Check if a package initialization sections calls a private routine
2459       (caller && (pkg= caller->get_package()) &&
2460        is_package_body_routine(thd, pkg, name->m_db, name->m_name, type())))
2461   {
2462     pkgname->m_db= tmpdb;
2463     pkgname->m_name= name->m_db;
2464     *pkg_routine_handler= package_routine_handler();
2465     return name->make_package_routine_name(thd->mem_root, tmpdb,
2466                                            name->m_db, name->m_name);
2467   }
2468   return false;
2469 }
2470 
2471 
2472 /**
2473   Resolve a non-qualified routine reference yyy(), between:
2474   - A standalone routine: current_database.yyy
2475   - A package routine:    current_database.current_package.yyy
2476 */
2477 
2478 bool Sp_handler::
sp_resolve_package_routine_implicit(THD * thd,sp_head * caller,sp_name * name,const Sp_handler ** pkg_routine_handler,Database_qualified_name * pkgname) const2479   sp_resolve_package_routine_implicit(THD *thd,
2480                                       sp_head *caller,
2481                                       sp_name *name,
2482                                       const Sp_handler **pkg_routine_handler,
2483                                       Database_qualified_name *pkgname) const
2484 {
2485   sp_package *pkg;
2486 
2487   if (!caller || !caller->m_name.length)
2488   {
2489     /*
2490       We are either in a an anonymous block,
2491       or not in a routine at all.
2492     */
2493     return false; // A standalone routine is called
2494   }
2495 
2496   if (caller->m_parent)
2497   {
2498     // A package routine calls a non-qualified routine
2499     int ret= SP_OK;
2500     Prefix_name_buf pkgstr(thd, caller->m_name);
2501     DBUG_ASSERT(pkgstr.length);
2502     LEX_CSTRING tmpname; // Non-qualified m_name
2503     tmpname.str= caller->m_name.str + pkgstr.length + 1;
2504     tmpname.length= caller->m_name.length - pkgstr.length - 1;
2505 
2506     /*
2507       We're here if a package routine calls another non-qualified
2508       function or procedure, e.g. yyy().
2509       We need to distinguish two cases:
2510       - yyy() is another routine from the same package
2511       - yyy() is a standalone routine from the same database
2512       To detect if yyy() is a package (rather than a standalone) routine,
2513       we check if:
2514       - yyy() recursively calls itself
2515       - yyy() is earlier implemented in the current CREATE PACKAGE BODY
2516       - yyy() has a forward declaration
2517       - yyy() is declared in the corresponding CREATE PACKAGE
2518     */
2519     if (eq_routine_name(tmpname, name->m_name) ||
2520         caller->m_parent->m_routine_implementations.find(name->m_name, type()) ||
2521         caller->m_parent->m_routine_declarations.find(name->m_name, type()) ||
2522         is_package_public_routine_quick(thd, caller->m_db,
2523                                         pkgstr, name->m_name, type()))
2524     {
2525       DBUG_ASSERT(ret == SP_OK);
2526       pkgname->copy(thd->mem_root, caller->m_db, pkgstr);
2527       *pkg_routine_handler= package_routine_handler();
2528       if (name->make_package_routine_name(thd->mem_root, pkgstr, name->m_name))
2529         return true;
2530     }
2531     return ret != SP_OK;
2532   }
2533 
2534   if ((pkg= caller->get_package()) &&
2535        pkg->m_routine_implementations.find(name->m_name, type()))
2536   {
2537     pkgname->m_db= caller->m_db;
2538     pkgname->m_name= caller->m_name;
2539     // Package initialization section is calling a non-qualified routine
2540     *pkg_routine_handler= package_routine_handler();
2541     return name->make_package_routine_name(thd->mem_root,
2542                                            caller->m_name, name->m_name);
2543   }
2544 
2545   return false; // A standalone routine is called
2546 
2547 }
2548 
2549 
2550 /**
2551   Detect cases when a package routine (rather than a standalone routine)
2552   is called, and rewrite sp_name accordingly.
2553 
2554   @param thd              Current thd
2555   @param caller           The caller routine (or NULL if outside of a routine)
2556   @param [IN/OUT] name    The called routine name
2557   @param [OUT]    pkgname If the routine is found to be a package routine,
2558                           pkgname is populated with the package name.
2559                           Otherwise, it's not touched.
2560   @retval         false   on success
2561   @retval         true    on error (e.g. EOM, could not read CREATE PACKAGE)
2562 */
2563 
2564 bool
sp_resolve_package_routine(THD * thd,sp_head * caller,sp_name * name,const Sp_handler ** pkg_routine_handler,Database_qualified_name * pkgname) const2565 Sp_handler::sp_resolve_package_routine(THD *thd,
2566                                        sp_head *caller,
2567                                        sp_name *name,
2568                                        const Sp_handler **pkg_routine_handler,
2569                                        Database_qualified_name *pkgname) const
2570 {
2571   if (!thd->db.length || !(thd->variables.sql_mode & MODE_ORACLE))
2572     return false;
2573 
2574   return name->m_explicit_name ?
2575          sp_resolve_package_routine_explicit(thd, caller, name,
2576                                              pkg_routine_handler, pkgname) :
2577          sp_resolve_package_routine_implicit(thd, caller, name,
2578                                              pkg_routine_handler, pkgname);
2579 }
2580 
2581 
2582 /**
2583   Add routine which is explicitly used by statement to the set of stored
2584   routines used by this statement.
2585 
2586   To be friendly towards prepared statements one should pass
2587   persistent arena as second argument.
2588 
2589   @param prelocking_ctx  Prelocking context of the statement
2590   @param arena           Arena in which memory for new element of the set
2591                          will be allocated
2592   @param rt              Routine name
2593 
2594   @note
2595     Will also add element to end of 'Query_tables_list::sroutines_list' list
2596     (and will take into account that this is an explicitly used routine).
2597 */
2598 
add_used_routine(Query_tables_list * prelocking_ctx,Query_arena * arena,const Database_qualified_name * rt) const2599 void Sp_handler::add_used_routine(Query_tables_list *prelocking_ctx,
2600                                   Query_arena *arena,
2601                                   const Database_qualified_name *rt) const
2602 {
2603   MDL_key key(get_mdl_type(), rt->m_db.str, rt->m_name.str);
2604   (void) sp_add_used_routine(prelocking_ctx, arena, &key, this, 0);
2605   prelocking_ctx->sroutines_list_own_last= prelocking_ctx->sroutines_list.next;
2606   prelocking_ctx->sroutines_list_own_elements=
2607                     prelocking_ctx->sroutines_list.elements;
2608 }
2609 
2610 
2611 /**
2612   Remove routines which are only indirectly used by statement from
2613   the set of routines used by this statement.
2614 
2615   @param prelocking_ctx  Prelocking context of the statement
2616 */
2617 
sp_remove_not_own_routines(Query_tables_list * prelocking_ctx)2618 void sp_remove_not_own_routines(Query_tables_list *prelocking_ctx)
2619 {
2620   Sroutine_hash_entry *not_own_rt, *next_rt;
2621   for (not_own_rt= *prelocking_ctx->sroutines_list_own_last;
2622        not_own_rt; not_own_rt= next_rt)
2623   {
2624     /*
2625       It is safe to obtain not_own_rt->next after calling hash_delete() now
2626       but we want to be more future-proof.
2627     */
2628     next_rt= not_own_rt->next;
2629     my_hash_delete(&prelocking_ctx->sroutines, (uchar *)not_own_rt);
2630   }
2631 
2632   *prelocking_ctx->sroutines_list_own_last= NULL;
2633   prelocking_ctx->sroutines_list.next= prelocking_ctx->sroutines_list_own_last;
2634   prelocking_ctx->sroutines_list.elements=
2635                     prelocking_ctx->sroutines_list_own_elements;
2636 }
2637 
2638 
2639 /**
2640   Merge contents of two hashes representing sets of routines used
2641   by statements or by other routines.
2642 
2643   @param dst   hash to which elements should be added
2644   @param src   hash from which elements merged
2645 
2646   @note
2647     This procedure won't create new Sroutine_hash_entry objects,
2648     instead it will simply add elements from source to destination
2649     hash. Thus time of life of elements in destination hash becomes
2650     dependant on time of life of elements from source hash. It also
2651     won't touch lists linking elements in source and destination
2652     hashes.
2653 
2654   @returns
2655     @return TRUE Failure
2656     @return FALSE Success
2657 */
2658 
sp_update_sp_used_routines(HASH * dst,HASH * src)2659 bool sp_update_sp_used_routines(HASH *dst, HASH *src)
2660 {
2661   for (uint i=0 ; i < src->records ; i++)
2662   {
2663     Sroutine_hash_entry *rt= (Sroutine_hash_entry *)my_hash_element(src, i);
2664     if (!my_hash_search(dst, (uchar *)rt->mdl_request.key.ptr(),
2665                         rt->mdl_request.key.length()))
2666     {
2667       if (my_hash_insert(dst, (uchar *)rt))
2668         return TRUE;
2669     }
2670   }
2671   return FALSE;
2672 }
2673 
2674 
2675 /**
2676   Add contents of hash representing set of routines to the set of
2677   routines used by statement.
2678 
2679   @param thd             Thread context
2680   @param prelocking_ctx  Prelocking context of the statement
2681   @param src             Hash representing set from which routines will
2682                          be added
2683   @param belong_to_view  Uppermost view which uses these routines, 0 if none
2684 
2685   @note It will also add elements to end of
2686         'Query_tables_list::sroutines_list' list.
2687 */
2688 
2689 void
sp_update_stmt_used_routines(THD * thd,Query_tables_list * prelocking_ctx,HASH * src,TABLE_LIST * belong_to_view)2690 sp_update_stmt_used_routines(THD *thd, Query_tables_list *prelocking_ctx,
2691                              HASH *src, TABLE_LIST *belong_to_view)
2692 {
2693   for (uint i=0 ; i < src->records ; i++)
2694   {
2695     Sroutine_hash_entry *rt= (Sroutine_hash_entry *)my_hash_element(src, i);
2696     (void)sp_add_used_routine(prelocking_ctx, thd->stmt_arena,
2697                               &rt->mdl_request.key, rt->m_handler,
2698                               belong_to_view);
2699   }
2700 }
2701 
2702 
2703 /**
2704   Add contents of list representing set of routines to the set of
2705   routines used by statement.
2706 
2707   @param thd             Thread context
2708   @param prelocking_ctx  Prelocking context of the statement
2709   @param src             List representing set from which routines will
2710                          be added
2711   @param belong_to_view  Uppermost view which uses these routines, 0 if none
2712 
2713   @note It will also add elements to end of
2714         'Query_tables_list::sroutines_list' list.
2715 */
2716 
sp_update_stmt_used_routines(THD * thd,Query_tables_list * prelocking_ctx,SQL_I_List<Sroutine_hash_entry> * src,TABLE_LIST * belong_to_view)2717 void sp_update_stmt_used_routines(THD *thd, Query_tables_list *prelocking_ctx,
2718                                   SQL_I_List<Sroutine_hash_entry> *src,
2719                                   TABLE_LIST *belong_to_view)
2720 {
2721   for (Sroutine_hash_entry *rt= src->first; rt; rt= rt->next)
2722     (void)sp_add_used_routine(prelocking_ctx, thd->stmt_arena,
2723                               &rt->mdl_request.key, rt->m_handler,
2724                               belong_to_view);
2725 }
2726 
2727 
2728 /**
2729   A helper wrapper around sp_cache_routine() to use from
2730   prelocking until 'sp_name' is eradicated as a class.
2731 */
2732 
sp_cache_routine(THD * thd,bool lookup_only,sp_head ** sp) const2733 int Sroutine_hash_entry::sp_cache_routine(THD *thd,
2734                                           bool lookup_only,
2735                                           sp_head **sp) const
2736 {
2737   char qname_buff[NAME_LEN*2+1+1];
2738   sp_name name(&mdl_request.key, qname_buff);
2739   /*
2740     Check that we have an MDL lock on this routine, unless it's a top-level
2741     CALL. The assert below should be unambiguous: the first element
2742     in sroutines_list has an MDL lock unless it's a top-level call, or a
2743     trigger, but triggers can't occur here (see the preceding assert).
2744   */
2745   DBUG_ASSERT(mdl_request.ticket || this == thd->lex->sroutines_list.first);
2746 
2747   return m_handler->sp_cache_routine(thd, &name, lookup_only, sp);
2748 }
2749 
2750 
2751 /**
2752   Ensure that routine is present in cache by loading it from the mysql.proc
2753   table if needed. If the routine is present but old, reload it.
2754   Emit an appropriate error if there was a problem during
2755   loading.
2756 
2757   @param[in]  thd   Thread context.
2758   @param[in]  name  Name of routine.
2759   @param[in]  lookup_only Only check that the routine is in the cache.
2760                     If it's not, don't try to load. If it is present,
2761                     but old, don't try to reload.
2762   @param[out] sp    Pointer to sp_head object for routine, NULL if routine was
2763                     not found.
2764 
2765   @retval 0      Either routine is found and was succesfully loaded into cache
2766                  or it does not exist.
2767   @retval non-0  Error while loading routine from mysql,proc table.
2768 */
2769 
sp_cache_routine(THD * thd,const Database_qualified_name * name,bool lookup_only,sp_head ** sp) const2770 int Sp_handler::sp_cache_routine(THD *thd,
2771                                  const Database_qualified_name *name,
2772                                  bool lookup_only,
2773                                  sp_head **sp) const
2774 {
2775   int ret= 0;
2776   sp_cache **spc= get_cache(thd);
2777 
2778   DBUG_ENTER("Sp_handler::sp_cache_routine");
2779 
2780   DBUG_ASSERT(spc);
2781 
2782   *sp= sp_cache_lookup(spc, name);
2783 
2784   if (lookup_only)
2785     DBUG_RETURN(SP_OK);
2786 
2787   if (*sp)
2788   {
2789     sp_cache_flush_obsolete(spc, sp);
2790     if (*sp)
2791       DBUG_RETURN(SP_OK);
2792   }
2793 
2794   switch ((ret= db_find_and_cache_routine(thd, name, sp)))
2795   {
2796     case SP_OK:
2797       break;
2798     case SP_KEY_NOT_FOUND:
2799       ret= SP_OK;
2800       break;
2801     default:
2802       /* Query might have been killed, don't set error. */
2803       if (thd->killed)
2804         break;
2805       /*
2806         Any error when loading an existing routine is either some problem
2807         with the mysql.proc table, or a parse error because the contents
2808         has been tampered with (in which case we clear that error).
2809       */
2810       if (ret == SP_PARSE_ERROR)
2811         thd->clear_error();
2812       /*
2813         If we cleared the parse error, or when db_find_routine() flagged
2814         an error with it's return value without calling my_error(), we
2815         set the generic "mysql.proc table corrupt" error here.
2816       */
2817       if (!thd->is_error())
2818       {
2819         my_error(ER_SP_PROC_TABLE_CORRUPT, MYF(0),
2820                  ErrConvDQName(name).ptr(), ret);
2821       }
2822       break;
2823   }
2824   DBUG_RETURN(ret);
2825 }
2826 
2827 
2828 /**
2829   Cache a package routine using its package name and a qualified name.
2830   See sp_cache_routine() for more information on parameters and return values.
2831 
2832   @param thd         - current THD
2833   @param pkgname_str - package name, e.g. "pkgname"
2834   @param name        - name with the following format:
2835                        * name->m_db is a database name, e.g. "dbname"
2836                        * name->m_name is a package-qualified name,
2837                          e.g. "pkgname.spname"
2838   @param lookup_only - don't load mysql.proc if not cached
2839   @param [OUT] sp    - the result is returned here.
2840   @retval false      - loaded or does not exists
2841   @retval true       - error while loading mysql.proc
2842 */
2843 
2844 int
sp_cache_package_routine(THD * thd,const LEX_CSTRING & pkgname_cstr,const Database_qualified_name * name,bool lookup_only,sp_head ** sp) const2845 Sp_handler::sp_cache_package_routine(THD *thd,
2846                                      const LEX_CSTRING &pkgname_cstr,
2847                                      const Database_qualified_name *name,
2848                                      bool lookup_only, sp_head **sp) const
2849 {
2850   DBUG_ENTER("sp_cache_package_routine");
2851   DBUG_ASSERT(type() == TYPE_ENUM_FUNCTION || type() == TYPE_ENUM_PROCEDURE);
2852   sp_name pkgname(&name->m_db, &pkgname_cstr, false);
2853   sp_head *ph= NULL;
2854   int ret= sp_handler_package_body.sp_cache_routine(thd, &pkgname,
2855                                                     lookup_only,
2856                                                     &ph);
2857   if (!ret)
2858   {
2859     sp_package *pkg= ph ? ph->get_package() : NULL;
2860     LEX_CSTRING tmp= name->m_name;
2861     const char *dot= strrchr(tmp.str, '.');
2862     size_t prefix_length= dot ? dot - tmp.str + 1 : 0;
2863     tmp.str+= prefix_length;
2864     tmp.length-= prefix_length;
2865     LEX *rlex= pkg ? pkg->m_routine_implementations.find(tmp, type()) : NULL;
2866     *sp= rlex ? rlex->sphead : NULL;
2867   }
2868 
2869   DBUG_RETURN(ret);
2870 }
2871 
2872 
2873 /**
2874   Cache a package routine by its fully qualified name.
2875   See sp_cache_routine() for more information on parameters and return values.
2876 
2877   @param thd       - current THD
2878   @param name      - name with the following format:
2879                      * name->m_db is a database name, e.g. "dbname"
2880                      * name->m_name is a package-qualified name,
2881                        e.g. "pkgname.spname"
2882   @param lookup_only - don't load mysql.proc if not cached
2883   @param [OUT] sp    -  the result is returned here
2884   @retval false      - loaded or does not exists
2885   @retval true       - error while loading mysql.proc
2886 */
2887 
sp_cache_package_routine(THD * thd,const Database_qualified_name * name,bool lookup_only,sp_head ** sp) const2888 int Sp_handler::sp_cache_package_routine(THD *thd,
2889                                          const Database_qualified_name *name,
2890                                          bool lookup_only, sp_head **sp) const
2891 {
2892   DBUG_ENTER("Sp_handler::sp_cache_package_routine");
2893   Prefix_name_buf pkgname(thd, name->m_name);
2894   DBUG_ASSERT(pkgname.length);
2895   DBUG_RETURN(sp_cache_package_routine(thd, pkgname, name, lookup_only, sp));
2896 }
2897 
2898 
2899 /**
2900   Generates the CREATE... string from the table information.
2901 
2902   @return
2903     Returns false on success, true on (alloc) failure.
2904 */
2905 
2906 bool
show_create_sp(THD * thd,String * buf,const LEX_CSTRING & db,const LEX_CSTRING & name,const LEX_CSTRING & params,const LEX_CSTRING & returns,const LEX_CSTRING & body,const st_sp_chistics & chistics,const AUTHID & definer,const DDL_options_st ddl_options,sql_mode_t sql_mode) const2907 Sp_handler::show_create_sp(THD *thd, String *buf,
2908                            const LEX_CSTRING &db,
2909                            const LEX_CSTRING &name,
2910                            const LEX_CSTRING &params,
2911                            const LEX_CSTRING &returns,
2912                            const LEX_CSTRING &body,
2913                            const st_sp_chistics &chistics,
2914                            const AUTHID &definer,
2915                            const DDL_options_st ddl_options,
2916                            sql_mode_t sql_mode) const
2917 {
2918   sql_mode_t old_sql_mode= thd->variables.sql_mode;
2919   size_t agglen= (chistics.agg_type == GROUP_AGGREGATE)? 10 : 0;
2920   LEX_CSTRING tmp;
2921 
2922   /* Make some room to begin with */
2923   if (buf->alloc(100 + db.length + 1 + name.length +
2924                  params.length + returns.length +
2925                  chistics.comment.length + 10 /* length of " DEFINER= "*/ +
2926                  agglen + USER_HOST_BUFF_SIZE))
2927     return true;
2928 
2929   thd->variables.sql_mode= sql_mode;
2930   buf->append(STRING_WITH_LEN("CREATE "));
2931   if (ddl_options.or_replace())
2932     buf->append(STRING_WITH_LEN("OR REPLACE "));
2933   append_definer(thd, buf, &definer.user, &definer.host);
2934   if (chistics.agg_type == GROUP_AGGREGATE)
2935     buf->append(STRING_WITH_LEN("AGGREGATE "));
2936   tmp= type_lex_cstring();
2937   buf->append(&tmp);
2938   buf->append(STRING_WITH_LEN(" "));
2939   if (ddl_options.if_not_exists())
2940     buf->append(STRING_WITH_LEN("IF NOT EXISTS "));
2941 
2942   if (db.length > 0)
2943   {
2944     append_identifier(thd, buf, &db);
2945     buf->append('.');
2946   }
2947   append_identifier(thd, buf, &name);
2948   buf->append('(');
2949   buf->append(&params);
2950   buf->append(')');
2951   if (type() == TYPE_ENUM_FUNCTION)
2952   {
2953     if (sql_mode & MODE_ORACLE)
2954       buf->append(STRING_WITH_LEN(" RETURN "));
2955     else
2956       buf->append(STRING_WITH_LEN(" RETURNS "));
2957     buf->append(returns.str, returns.length);   // Not \0 terminated
2958   }
2959   buf->append('\n');
2960   switch (chistics.daccess) {
2961   case SP_NO_SQL:
2962     buf->append(STRING_WITH_LEN("    NO SQL\n"));
2963     break;
2964   case SP_READS_SQL_DATA:
2965     buf->append(STRING_WITH_LEN("    READS SQL DATA\n"));
2966     break;
2967   case SP_MODIFIES_SQL_DATA:
2968     buf->append(STRING_WITH_LEN("    MODIFIES SQL DATA\n"));
2969     break;
2970   case SP_DEFAULT_ACCESS:
2971   case SP_CONTAINS_SQL:
2972     /* Do nothing */
2973     break;
2974   }
2975   if (chistics.detistic)
2976     buf->append(STRING_WITH_LEN("    DETERMINISTIC\n"));
2977   append_suid(buf, chistics.suid);
2978   append_comment(buf, chistics.comment);
2979   buf->append(body.str, body.length);           // Not \0 terminated
2980   thd->variables.sql_mode= old_sql_mode;
2981   return false;
2982 }
2983 
2984 
2985 /**
2986   @brief    The function loads sp_head struct for information schema purposes
2987             (used for I_S ROUTINES & PARAMETERS tables).
2988 
2989   @param[in]      thd               thread handler
2990   @param[in]      proc_table        mysql.proc table structurte
2991   @param[in]      db                database name
2992   @param[in]      name              sp name
2993   @param[in]      sql_mode          SQL mode
2994   @param[in]      type              Routine type
2995   @param[in]      returns           'returns' string
2996   @param[in]      params            parameters definition string
2997   @param[out]     free_sp_head      returns 1 if we need to free sp_head struct
2998                                     otherwise returns 0
2999 
3000   @return     Pointer on sp_head struct
3001     @retval   #                     Pointer on sp_head struct
3002     @retval   0                     error
3003 */
3004 
3005 sp_head *
sp_load_for_information_schema(THD * thd,TABLE * proc_table,const LEX_CSTRING & db,const LEX_CSTRING & name,const LEX_CSTRING & params,const LEX_CSTRING & returns,sql_mode_t sql_mode,bool * free_sp_head) const3006 Sp_handler::sp_load_for_information_schema(THD *thd, TABLE *proc_table,
3007                                            const LEX_CSTRING &db,
3008                                            const LEX_CSTRING &name,
3009                                            const LEX_CSTRING &params,
3010                                            const LEX_CSTRING &returns,
3011                                            sql_mode_t sql_mode,
3012                                            bool *free_sp_head) const
3013 {
3014   String defstr;
3015   const AUTHID definer= {{STRING_WITH_LEN("")}, {STRING_WITH_LEN("")}};
3016   sp_head *sp;
3017   sp_cache **spc= get_cache(thd);
3018   sp_name sp_name_obj(&db, &name, true); // This can change "name"
3019   *free_sp_head= 0;
3020   if ((sp= sp_cache_lookup(spc, &sp_name_obj)))
3021   {
3022     return sp;
3023   }
3024 
3025   LEX *old_lex= thd->lex, newlex;
3026   Stored_program_creation_ctx *creation_ctx=
3027     Stored_routine_creation_ctx::load_from_db(thd, &sp_name_obj, proc_table);
3028   defstr.set_charset(creation_ctx->get_client_cs());
3029   if (show_create_sp(thd, &defstr,
3030                      sp_name_obj.m_db, sp_name_obj.m_name,
3031                      params, returns, empty_body_lex_cstring(sql_mode),
3032                      Sp_chistics(), definer, DDL_options(), sql_mode))
3033     return 0;
3034 
3035   thd->lex= &newlex;
3036   newlex.current_select= NULL;
3037   sp= sp_compile(thd, &defstr, sql_mode, NULL, creation_ctx);
3038   *free_sp_head= 1;
3039   thd->lex->sphead= NULL;
3040   lex_end(thd->lex);
3041   thd->lex= old_lex;
3042   return sp;
3043 }
3044 
3045 
empty_body_lex_cstring(sql_mode_t mode) const3046 LEX_CSTRING Sp_handler_procedure::empty_body_lex_cstring(sql_mode_t mode) const
3047 {
3048   static LEX_CSTRING m_empty_body_std= {STRING_WITH_LEN("BEGIN END")};
3049   static LEX_CSTRING m_empty_body_ora= {STRING_WITH_LEN("AS BEGIN NULL; END")};
3050   return mode & MODE_ORACLE ? m_empty_body_ora : m_empty_body_std;
3051 }
3052 
3053 
empty_body_lex_cstring(sql_mode_t mode) const3054 LEX_CSTRING Sp_handler_function::empty_body_lex_cstring(sql_mode_t mode) const
3055 {
3056   static LEX_CSTRING m_empty_body_std= {STRING_WITH_LEN("RETURN NULL")};
3057   static LEX_CSTRING m_empty_body_ora= {STRING_WITH_LEN("AS BEGIN RETURN NULL; END")};
3058   return mode & MODE_ORACLE ? m_empty_body_ora : m_empty_body_std;
3059 }
3060