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