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