MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
sp.cc
1 /*
2  Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
3 
4  This program is free software; you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation; version 2 of the License.
7 
8  This program is distributed in the hope that it will be useful,
9  but WITHOUT ANY WARRANTY; without even the implied warranty of
10  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  GNU General Public License for more details.
12 
13  You should have received a copy of the GNU General Public License
14  along with this program; if not, write to the Free Software
15  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
16 */
17 
18 #include "sql_priv.h"
19 #include "unireg.h"
20 #include "sql_base.h" // close_thread_tables
21 #include "sql_parse.h" // parse_sql
22 #include "key.h" // key_copy
23 #include "sql_show.h" // append_definer, append_identifier
24 #include "sql_db.h" // get_default_db_collation, mysql_opt_change_db,
25  // mysql_change_db, check_db_dir_existence,
26  // load_db_opt_by_name
27 #include "sql_table.h" // write_bin_log
28 #include "sql_acl.h" // SUPER_ACL
29 #include "sp_head.h"
30 #include "sp_cache.h"
31 #include "lock.h" // lock_object_name
32 #include "sp.h"
33 
34 #include <my_user.h>
35 
36 static bool
37 create_string(THD *thd, String *buf,
38  enum_sp_type sp_type,
39  const char *db, ulong dblen,
40  const char *name, ulong namelen,
41  const char *params, ulong paramslen,
42  const char *returns, ulong returnslen,
43  const char *body, ulong bodylen,
44  st_sp_chistics *chistics,
45  const LEX_STRING *definer_user,
46  const LEX_STRING *definer_host,
47  sql_mode_t sql_mode);
48 
49 static int
50 db_load_routine(THD *thd, enum_sp_type type, sp_name *name, sp_head **sphp,
51  sql_mode_t sql_mode, const char *params, const char *returns,
52  const char *body, st_sp_chistics &chistics,
53  const char *definer, longlong created, longlong modified,
54  Stored_program_creation_ctx *creation_ctx);
55 
56 static const
57 TABLE_FIELD_TYPE proc_table_fields[MYSQL_PROC_FIELD_COUNT] =
58 {
59  {
60  { C_STRING_WITH_LEN("db") },
61  { C_STRING_WITH_LEN("char(64)") },
62  { C_STRING_WITH_LEN("utf8") }
63  },
64  {
65  { C_STRING_WITH_LEN("name") },
66  { C_STRING_WITH_LEN("char(64)") },
67  { C_STRING_WITH_LEN("utf8") }
68  },
69  {
70  { C_STRING_WITH_LEN("type") },
71  { C_STRING_WITH_LEN("enum('FUNCTION','PROCEDURE')") },
72  { NULL, 0 }
73  },
74  {
75  { C_STRING_WITH_LEN("specific_name") },
76  { C_STRING_WITH_LEN("char(64)") },
77  { C_STRING_WITH_LEN("utf8") }
78  },
79  {
80  { C_STRING_WITH_LEN("language") },
81  { C_STRING_WITH_LEN("enum('SQL')") },
82  { NULL, 0 }
83  },
84  {
85  { C_STRING_WITH_LEN("sql_data_access") },
86  { C_STRING_WITH_LEN("enum('CONTAINS_SQL','NO_SQL','READS_SQL_DATA','MODIFIES_SQL_DATA')") },
87  { NULL, 0 }
88  },
89  {
90  { C_STRING_WITH_LEN("is_deterministic") },
91  { C_STRING_WITH_LEN("enum('YES','NO')") },
92  { NULL, 0 }
93  },
94  {
95  { C_STRING_WITH_LEN("security_type") },
96  { C_STRING_WITH_LEN("enum('INVOKER','DEFINER')") },
97  { NULL, 0 }
98  },
99  {
100  { C_STRING_WITH_LEN("param_list") },
101  { C_STRING_WITH_LEN("blob") },
102  { NULL, 0 }
103  },
104 
105  {
106  { C_STRING_WITH_LEN("returns") },
107  { C_STRING_WITH_LEN("longblob") },
108  { NULL, 0 }
109  },
110  {
111  { C_STRING_WITH_LEN("body") },
112  { C_STRING_WITH_LEN("longblob") },
113  { NULL, 0 }
114  },
115  {
116  { C_STRING_WITH_LEN("definer") },
117  { C_STRING_WITH_LEN("char(77)") },
118  { C_STRING_WITH_LEN("utf8") }
119  },
120  {
121  { C_STRING_WITH_LEN("created") },
122  { C_STRING_WITH_LEN("timestamp") },
123  { NULL, 0 }
124  },
125  {
126  { C_STRING_WITH_LEN("modified") },
127  { C_STRING_WITH_LEN("timestamp") },
128  { NULL, 0 }
129  },
130  {
131  { C_STRING_WITH_LEN("sql_mode") },
132  { C_STRING_WITH_LEN("set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES',"
133  "'IGNORE_SPACE','NOT_USED','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION',"
134  "'NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB',"
135  "'NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40',"
136  "'ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES',"
137  "'STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES',"
138  "'ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER',"
139  "'HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH')") },
140  { NULL, 0 }
141  },
142  {
143  { C_STRING_WITH_LEN("comment") },
144  { C_STRING_WITH_LEN("text") },
145  { C_STRING_WITH_LEN("utf8") }
146  },
147  {
148  { C_STRING_WITH_LEN("character_set_client") },
149  { C_STRING_WITH_LEN("char(32)") },
150  { C_STRING_WITH_LEN("utf8") }
151  },
152  {
153  { C_STRING_WITH_LEN("collation_connection") },
154  { C_STRING_WITH_LEN("char(32)") },
155  { C_STRING_WITH_LEN("utf8") }
156  },
157  {
158  { C_STRING_WITH_LEN("db_collation") },
159  { C_STRING_WITH_LEN("char(32)") },
160  { C_STRING_WITH_LEN("utf8") }
161  },
162  {
163  { C_STRING_WITH_LEN("body_utf8") },
164  { C_STRING_WITH_LEN("longblob") },
165  { NULL, 0 }
166  }
167 };
168 
169 static const TABLE_FIELD_DEF
170  proc_table_def= {MYSQL_PROC_FIELD_COUNT, proc_table_fields};
171 
172 /*************************************************************************/
173 
180  public Sql_alloc
181 {
182 public:
184  load_from_db(THD *thd, const sp_name *name, TABLE *proc_tbl);
185 
186 public:
187  virtual Stored_program_creation_ctx *clone(MEM_ROOT *mem_root)
188  {
189  return new (mem_root) Stored_routine_creation_ctx(m_client_cs,
191  m_db_cl);
192  }
193 
194 protected:
195  virtual Object_creation_ctx *create_backup_ctx(THD *thd) const
196  {
197  DBUG_ENTER("Stored_routine_creation_ctx::create_backup_ctx");
198  DBUG_RETURN(new Stored_routine_creation_ctx(thd));
199  }
200 
201 private:
204  { }
205 
206  Stored_routine_creation_ctx(const CHARSET_INFO *client_cs,
207  const CHARSET_INFO *connection_cl,
208  const CHARSET_INFO *db_cl)
209  : Stored_program_creation_ctx(client_cs, connection_cl, db_cl)
210  { }
211 };
212 
213 /**************************************************************************
214  Stored_routine_creation_ctx implementation.
215 **************************************************************************/
216 
217 bool load_charset(MEM_ROOT *mem_root,
218  Field *field,
219  const CHARSET_INFO *dflt_cs,
220  const CHARSET_INFO **cs)
221 {
222  String cs_name;
223 
224  if (get_field(mem_root, field, &cs_name))
225  {
226  *cs= dflt_cs;
227  return TRUE;
228  }
229 
230  *cs= get_charset_by_csname(cs_name.c_ptr(), MY_CS_PRIMARY, MYF(0));
231 
232  if (*cs == NULL)
233  {
234  *cs= dflt_cs;
235  return TRUE;
236  }
237 
238  return FALSE;
239 }
240 
241 /*************************************************************************/
242 
243 bool load_collation(MEM_ROOT *mem_root,
244  Field *field,
245  const CHARSET_INFO *dflt_cl,
246  const CHARSET_INFO **cl)
247 {
248  String cl_name;
249 
250  if (get_field(mem_root, field, &cl_name))
251  {
252  *cl= dflt_cl;
253  return TRUE;
254  }
255 
256  *cl= get_charset_by_name(cl_name.c_ptr(), MYF(0));
257 
258  if (*cl == NULL)
259  {
260  *cl= dflt_cl;
261  return TRUE;
262  }
263 
264  return FALSE;
265 }
266 
267 /*************************************************************************/
268 
270 Stored_routine_creation_ctx::load_from_db(THD *thd,
271  const sp_name *name,
272  TABLE *proc_tbl)
273 {
274  /* Load character set/collation attributes. */
275 
276  const CHARSET_INFO *client_cs;
277  const CHARSET_INFO *connection_cl;
278  const CHARSET_INFO *db_cl;
279 
280  const char *db_name= thd->strmake(name->m_db.str, name->m_db.length);
281  const char *sr_name= thd->strmake(name->m_name.str, name->m_name.length);
282 
283  bool invalid_creation_ctx= FALSE;
284 
285  if (load_charset(thd->mem_root,
286  proc_tbl->field[MYSQL_PROC_FIELD_CHARACTER_SET_CLIENT],
287  thd->variables.character_set_client,
288  &client_cs))
289  {
290  sql_print_warning("Stored routine '%s'.'%s': invalid value "
291  "in column mysql.proc.character_set_client.",
292  (const char *) db_name,
293  (const char *) sr_name);
294 
295  invalid_creation_ctx= TRUE;
296  }
297 
298  if (load_collation(thd->mem_root,
299  proc_tbl->field[MYSQL_PROC_FIELD_COLLATION_CONNECTION],
300  thd->variables.collation_connection,
301  &connection_cl))
302  {
303  sql_print_warning("Stored routine '%s'.'%s': invalid value "
304  "in column mysql.proc.collation_connection.",
305  (const char *) db_name,
306  (const char *) sr_name);
307 
308  invalid_creation_ctx= TRUE;
309  }
310 
311  if (load_collation(thd->mem_root,
312  proc_tbl->field[MYSQL_PROC_FIELD_DB_COLLATION],
313  NULL,
314  &db_cl))
315  {
316  sql_print_warning("Stored routine '%s'.'%s': invalid value "
317  "in column mysql.proc.db_collation.",
318  (const char *) db_name,
319  (const char *) sr_name);
320 
321  invalid_creation_ctx= TRUE;
322  }
323 
324  if (invalid_creation_ctx)
325  {
326  push_warning_printf(thd,
327  Sql_condition::WARN_LEVEL_WARN,
328  ER_SR_INVALID_CREATION_CTX,
329  ER(ER_SR_INVALID_CREATION_CTX),
330  (const char *) db_name,
331  (const char *) sr_name);
332  }
333 
334  /*
335  If we failed to retrieve the database collation, load the default one
336  from the disk.
337  */
338 
339  if (!db_cl)
340  db_cl= get_default_db_collation(thd, name->m_db.str);
341 
342  /* Create the context. */
343 
344  return new Stored_routine_creation_ctx(client_cs, connection_cl, db_cl);
345 }
346 
347 /*************************************************************************/
348 
350 {
351 private:
352  bool m_print_once;
353 
354 public:
355  Proc_table_intact() : m_print_once(TRUE) {}
356 
357 protected:
358  void report_error(uint code, const char *fmt, ...);
359 };
360 
361 
367 void Proc_table_intact::report_error(uint code, const char *fmt, ...)
368 {
369  va_list args;
370  char buf[512];
371 
372  va_start(args, fmt);
373  my_vsnprintf(buf, sizeof(buf), fmt, args);
374  va_end(args);
375 
376  if (code)
377  my_message(code, buf, MYF(0));
378  else
379  my_error(ER_CANNOT_LOAD_FROM_TABLE_V2, MYF(0), "mysql", "proc");
380 
381  if (m_print_once)
382  {
383  m_print_once= FALSE;
384  sql_print_error("%s", buf);
385  }
386 };
387 
388 
390 static Proc_table_intact proc_table_intact;
391 
392 
407 TABLE *open_proc_table_for_read(THD *thd, Open_tables_backup *backup)
408 {
410 
411  DBUG_ENTER("open_proc_table_for_read");
412 
413  table.init_one_table("mysql", 5, "proc", 4, "proc", TL_READ);
414 
415  if (open_system_tables_for_read(thd, &table, backup))
416  DBUG_RETURN(NULL);
417 
418  if (!table.table->key_info)
419  {
420  my_error(ER_TABLE_CORRUPT, MYF(0), table.table->s->db.str,
421  table.table->s->table_name.str);
422  goto err;
423  }
424 
425  if (!proc_table_intact.check(table.table, &proc_table_def))
426  DBUG_RETURN(table.table);
427 
428 err:
429  close_system_tables(thd, backup);
430  DBUG_RETURN(NULL);
431 }
432 
433 
448 static TABLE *open_proc_table_for_update(THD *thd)
449 {
450  TABLE_LIST table_list;
451  TABLE *table;
452  MDL_savepoint mdl_savepoint= thd->mdl_context.mdl_savepoint();
453  DBUG_ENTER("open_proc_table_for_update");
454 
455  table_list.init_one_table("mysql", 5, "proc", 4, "proc", TL_WRITE);
456 
457  if (!(table= open_system_table_for_update(thd, &table_list)))
458  DBUG_RETURN(NULL);
459 
460  if (!proc_table_intact.check(table, &proc_table_def))
461  DBUG_RETURN(table);
462 
463  close_thread_tables(thd);
464  thd->mdl_context.rollback_to_savepoint(mdl_savepoint);
465 
466  DBUG_RETURN(NULL);
467 }
468 
469 
480 static void recursion_level_error(THD *thd, sp_head *sp)
481 {
482  if (sp->m_type == SP_TYPE_PROCEDURE)
483  {
484  my_error(ER_SP_RECURSION_LIMIT, MYF(0),
485  static_cast<int>(thd->variables.max_sp_recursion_depth),
486  sp->m_name.str);
487  }
488  else
489  my_error(ER_SP_NO_RECURSION, MYF(0));
490 }
491 
492 
507 static int
508 db_find_routine_aux(THD *thd, enum_sp_type type, sp_name *name, TABLE *table)
509 {
510  uchar key[MAX_KEY_LENGTH]; // db, name, optional key length type
511  DBUG_ENTER("db_find_routine_aux");
512  DBUG_PRINT("enter", ("type: %d name: %.*s",
513  type, (int) name->m_name.length, name->m_name.str));
514 
515  /*
516  Create key to find row. We have to use field->store() to be able to
517  handle VARCHAR and CHAR fields.
518  Assumption here is that the three first fields in the table are
519  'db', 'name' and 'type' and the first key is the primary key over the
520  same fields.
521  */
522  if (name->m_name.length > table->field[1]->field_length)
523  DBUG_RETURN(SP_KEY_NOT_FOUND);
524  table->field[0]->store(name->m_db.str, name->m_db.length, &my_charset_bin);
525  table->field[1]->store(name->m_name.str, name->m_name.length,
526  &my_charset_bin);
527  table->field[2]->store((longlong) type, TRUE);
528  key_copy(key, table->record[0], table->key_info,
529  table->key_info->key_length);
530 
531  if (table->file->ha_index_read_idx_map(table->record[0], 0, key, HA_WHOLE_KEY,
532  HA_READ_KEY_EXACT))
533  DBUG_RETURN(SP_KEY_NOT_FOUND);
534 
535  DBUG_RETURN(SP_OK);
536 }
537 
538 
559 static int
560 db_find_routine(THD *thd, enum_sp_type type, sp_name *name, sp_head **sphp)
561 {
562  TABLE *table;
563  const char *params, *returns, *body;
564  int ret;
565  const char *definer;
566  longlong created;
567  longlong modified;
568  st_sp_chistics chistics;
569  char *ptr;
570  uint length;
571  char buff[65];
572  String str(buff, sizeof(buff), &my_charset_bin);
573  bool saved_time_zone_used= thd->time_zone_used;
574  sql_mode_t sql_mode, saved_mode= thd->variables.sql_mode;
575  Open_tables_backup open_tables_state_backup;
576  Stored_program_creation_ctx *creation_ctx;
577 
578  DBUG_ENTER("db_find_routine");
579  DBUG_PRINT("enter", ("type: %d name: %.*s",
580  type, (int) name->m_name.length, name->m_name.str));
581 
582  *sphp= 0; // In case of errors
583  if (!(table= open_proc_table_for_read(thd, &open_tables_state_backup)))
584  DBUG_RETURN(SP_OPEN_TABLE_FAILED);
585 
586  /* Reset sql_mode during data dictionary operations. */
587  thd->variables.sql_mode= 0;
588 
589  if ((ret= db_find_routine_aux(thd, type, name, table)) != SP_OK)
590  goto done;
591 
592  if (table->s->fields < MYSQL_PROC_FIELD_COUNT)
593  {
594  ret= SP_GET_FIELD_FAILED;
595  goto done;
596  }
597 
598  memset(&chistics, 0, sizeof(chistics));
599  if ((ptr= get_field(thd->mem_root,
600  table->field[MYSQL_PROC_FIELD_ACCESS])) == NULL)
601  {
602  ret= SP_GET_FIELD_FAILED;
603  goto done;
604  }
605  switch (ptr[0]) {
606  case 'N':
607  chistics.daccess= SP_NO_SQL;
608  break;
609  case 'C':
610  chistics.daccess= SP_CONTAINS_SQL;
611  break;
612  case 'R':
613  chistics.daccess= SP_READS_SQL_DATA;
614  break;
615  case 'M':
616  chistics.daccess= SP_MODIFIES_SQL_DATA;
617  break;
618  default:
619  chistics.daccess= SP_DEFAULT_ACCESS_MAPPING;
620  }
621 
622  if ((ptr= get_field(thd->mem_root,
623  table->field[MYSQL_PROC_FIELD_DETERMINISTIC])) == NULL)
624  {
625  ret= SP_GET_FIELD_FAILED;
626  goto done;
627  }
628  chistics.detistic= (ptr[0] == 'N' ? FALSE : TRUE);
629 
630  if ((ptr= get_field(thd->mem_root,
631  table->field[MYSQL_PROC_FIELD_SECURITY_TYPE])) == NULL)
632  {
633  ret= SP_GET_FIELD_FAILED;
634  goto done;
635  }
636  chistics.suid= (ptr[0] == 'I' ? SP_IS_NOT_SUID : SP_IS_SUID);
637 
638  if ((params= get_field(thd->mem_root,
639  table->field[MYSQL_PROC_FIELD_PARAM_LIST])) == NULL)
640  {
641  params= "";
642  }
643 
644  if (type == SP_TYPE_PROCEDURE)
645  returns= "";
646  else if ((returns= get_field(thd->mem_root,
647  table->field[MYSQL_PROC_FIELD_RETURNS])) == NULL)
648  {
649  ret= SP_GET_FIELD_FAILED;
650  goto done;
651  }
652 
653  if ((body= get_field(thd->mem_root,
654  table->field[MYSQL_PROC_FIELD_BODY])) == NULL)
655  {
656  ret= SP_GET_FIELD_FAILED;
657  goto done;
658  }
659 
660  // Get additional information
661  if ((definer= get_field(thd->mem_root,
662  table->field[MYSQL_PROC_FIELD_DEFINER])) == NULL)
663  {
664  ret= SP_GET_FIELD_FAILED;
665  goto done;
666  }
667 
668  modified= table->field[MYSQL_PROC_FIELD_MODIFIED]->val_int();
669  created= table->field[MYSQL_PROC_FIELD_CREATED]->val_int();
670 
671  sql_mode= (sql_mode_t) table->field[MYSQL_PROC_FIELD_SQL_MODE]->val_int();
672 
673  table->field[MYSQL_PROC_FIELD_COMMENT]->val_str(&str, &str);
674 
675  ptr= 0;
676  if ((length= str.length()))
677  ptr= thd->strmake(str.ptr(), length);
678  chistics.comment.str= ptr;
679  chistics.comment.length= length;
680 
681  creation_ctx= Stored_routine_creation_ctx::load_from_db(thd, name, table);
682 
683  close_system_tables(thd, &open_tables_state_backup);
684  table= 0;
685 
686  ret= db_load_routine(thd, type, name, sphp,
687  sql_mode, params, returns, body, chistics,
688  definer, created, modified, creation_ctx);
689  done:
690  /*
691  Restore the time zone flag as the timezone usage in proc table
692  does not affect replication.
693  */
694  thd->time_zone_used= saved_time_zone_used;
695  if (table)
696  close_system_tables(thd, &open_tables_state_backup);
697  thd->variables.sql_mode= saved_mode;
698  DBUG_RETURN(ret);
699 }
700 
701 
706 struct Silence_deprecated_warning : public Internal_error_handler
707 {
708 public:
709  virtual bool handle_condition(THD *thd,
710  uint sql_errno,
711  const char* sqlstate,
712  Sql_condition::enum_warning_level level,
713  const char* msg,
714  Sql_condition ** cond_hdl);
715 };
716 
717 bool
718 Silence_deprecated_warning::handle_condition(
719  THD *,
720  uint sql_errno,
721  const char*,
722  Sql_condition::enum_warning_level level,
723  const char*,
724  Sql_condition ** cond_hdl)
725 {
726  *cond_hdl= NULL;
727  if (sql_errno == ER_WARN_DEPRECATED_SYNTAX &&
728  level == Sql_condition::WARN_LEVEL_WARN)
729  return TRUE;
730 
731  return FALSE;
732 }
733 
734 
748 static sp_head *sp_compile(THD *thd, String *defstr, sql_mode_t sql_mode,
749  Stored_program_creation_ctx *creation_ctx)
750 {
751  sp_head *sp;
752  sql_mode_t old_sql_mode= thd->variables.sql_mode;
753  ha_rows old_select_limit= thd->variables.select_limit;
754  sp_rcontext *sp_runtime_ctx_saved= thd->sp_runtime_ctx;
755  Silence_deprecated_warning warning_handler;
756  Parser_state parser_state;
757  PSI_statement_locker *parent_locker= thd->m_statement_psi;
758 
759  thd->variables.sql_mode= sql_mode;
760  thd->variables.select_limit= HA_POS_ERROR;
761 
762  if (parser_state.init(thd, defstr->c_ptr(), defstr->length()))
763  {
764  thd->variables.sql_mode= old_sql_mode;
765  thd->variables.select_limit= old_select_limit;
766  return NULL;
767  }
768 
769  lex_start(thd);
770  thd->push_internal_handler(&warning_handler);
771  thd->sp_runtime_ctx= NULL;
772 
773  thd->m_statement_psi= NULL;
774  if (parse_sql(thd, & parser_state, creation_ctx) || thd->lex == NULL)
775  {
776  sp= thd->lex->sphead;
777  delete sp;
778  sp= 0;
779  }
780  else
781  {
782  sp= thd->lex->sphead;
783  }
784  thd->m_statement_psi= parent_locker;
785 
786  thd->pop_internal_handler();
787  thd->sp_runtime_ctx= sp_runtime_ctx_saved;
788  thd->variables.sql_mode= old_sql_mode;
789  thd->variables.select_limit= old_select_limit;
790  return sp;
791 }
792 
793 
794 class Bad_db_error_handler : public Internal_error_handler
795 {
796 public:
798  :m_error_caught(false)
799  {}
800 
801  virtual bool handle_condition(THD *thd,
802  uint sql_errno,
803  const char* sqlstate,
804  Sql_condition::enum_warning_level level,
805  const char* message,
806  Sql_condition ** cond_hdl);
807 
808  bool error_caught() const { return m_error_caught; }
809 
810 private:
811  bool m_error_caught;
812 };
813 
814 bool
815 Bad_db_error_handler::handle_condition(THD *thd,
816  uint sql_errno,
817  const char* sqlstate,
818  Sql_condition::enum_warning_level level,
819  const char* message,
820  Sql_condition ** cond_hdl)
821 {
822  if (sql_errno == ER_BAD_DB_ERROR)
823  {
824  m_error_caught= true;
825  return true;
826  }
827  return false;
828 }
829 
830 
831 static int
832 db_load_routine(THD *thd, enum_sp_type type, sp_name *name, sp_head **sphp,
833  sql_mode_t sql_mode, const char *params, const char *returns,
834  const char *body, st_sp_chistics &chistics,
835  const char *definer, longlong created, longlong modified,
836  Stored_program_creation_ctx *creation_ctx)
837 {
838  LEX *old_lex= thd->lex, newlex;
839  String defstr;
840  char saved_cur_db_name_buf[NAME_LEN+1];
841  LEX_STRING saved_cur_db_name=
842  { saved_cur_db_name_buf, sizeof(saved_cur_db_name_buf) };
843  bool cur_db_changed;
844  Bad_db_error_handler db_not_exists_handler;
845  char definer_user_name_holder[USERNAME_LENGTH + 1];
846  LEX_STRING definer_user_name= { definer_user_name_holder,
847  USERNAME_LENGTH };
848 
849  char definer_host_name_holder[HOSTNAME_LENGTH + 1];
850  LEX_STRING definer_host_name= { definer_host_name_holder, HOSTNAME_LENGTH };
851 
852  int ret= 0;
853 
854  thd->lex= &newlex;
855  newlex.current_select= NULL;
856 
857  parse_user(definer, strlen(definer),
858  definer_user_name.str, &definer_user_name.length,
859  definer_host_name.str, &definer_host_name.length);
860 
861  defstr.set_charset(creation_ctx->get_client_cs());
862 
863  /*
864  We have to add DEFINER clause and provide proper routine characterstics in
865  routine definition statement that we build here to be able to use this
866  definition for SHOW CREATE PROCEDURE later.
867  */
868 
869  if (!create_string(thd, &defstr,
870  type,
871  NULL, 0,
872  name->m_name.str, name->m_name.length,
873  params, strlen(params),
874  returns, strlen(returns),
875  body, strlen(body),
876  &chistics, &definer_user_name, &definer_host_name,
877  sql_mode))
878  {
879  ret= SP_INTERNAL_ERROR;
880  goto end;
881  }
882 
883  thd->push_internal_handler(&db_not_exists_handler);
884  /*
885  Change the current database (if needed).
886 
887  TODO: why do we force switch here?
888  */
889 
890  if (mysql_opt_change_db(thd, &name->m_db, &saved_cur_db_name, TRUE,
891  &cur_db_changed))
892  {
893  ret= SP_INTERNAL_ERROR;
894  thd->pop_internal_handler();
895  goto end;
896  }
897  thd->pop_internal_handler();
898  if (db_not_exists_handler.error_caught())
899  {
900  ret= SP_INTERNAL_ERROR;
901  my_error(ER_BAD_DB_ERROR, MYF(0), name->m_db.str);
902 
903  goto end;
904  }
905 
906  {
907  *sphp= sp_compile(thd, &defstr, sql_mode, creation_ctx);
908  /*
909  Force switching back to the saved current database (if changed),
910  because it may be NULL. In this case, mysql_change_db() would
911  generate an error.
912  */
913 
914  if (cur_db_changed && mysql_change_db(thd, &saved_cur_db_name, TRUE))
915  {
916  ret= SP_INTERNAL_ERROR;
917  goto end;
918  }
919 
920  if (!*sphp)
921  {
922  ret= SP_PARSE_ERROR;
923  goto end;
924  }
925 
926  (*sphp)->set_definer(&definer_user_name, &definer_host_name);
927  (*sphp)->set_info(created, modified, &chistics, sql_mode);
928  (*sphp)->set_creation_ctx(creation_ctx);
929  (*sphp)->optimize();
930  /*
931  Not strictly necessary to invoke this method here, since we know
932  that we've parsed CREATE PROCEDURE/FUNCTION and not an
933  UPDATE/DELETE/INSERT/REPLACE/LOAD/CREATE TABLE, but we try to
934  maintain the invariant that this method is called for each
935  distinct statement, in case its logic is extended with other
936  types of analyses in future.
937  */
938  newlex.set_trg_event_type_for_tables();
939  }
940 
941 end:
942  thd->lex->sphead= NULL;
943  lex_end(thd->lex);
944  thd->lex= old_lex;
945  return ret;
946 }
947 
948 
949 static void
950 sp_returns_type(THD *thd, String &result, sp_head *sp)
951 {
952  TABLE table;
953  TABLE_SHARE share;
954  Field *field;
955  memset(&table, 0, sizeof(table));
956  memset(&share, 0, sizeof(share));
957  table.in_use= thd;
958  table.s = &share;
959  field= sp->create_result_field(0, 0, &table);
960  field->sql_type(result);
961 
962  if (field->has_charset())
963  {
964  result.append(STRING_WITH_LEN(" CHARSET "));
965  result.append(field->charset()->csname);
966  if (!(field->charset()->state & MY_CS_PRIMARY))
967  {
968  result.append(STRING_WITH_LEN(" COLLATE "));
969  result.append(field->charset()->name);
970  }
971  }
972 
973  delete field;
974 }
975 
976 
998 int sp_create_routine(THD *thd, sp_head *sp)
999 {
1000  int ret;
1001  TABLE *table;
1002  char definer[USER_HOST_BUFF_SIZE];
1003  sql_mode_t saved_mode= thd->variables.sql_mode;
1004  MDL_key::enum_mdl_namespace mdl_type= (sp->m_type == SP_TYPE_FUNCTION) ?
1005  MDL_key::FUNCTION : MDL_key::PROCEDURE;
1006 
1007  const CHARSET_INFO *db_cs= get_default_db_collation(thd, sp->m_db.str);
1008 
1009  enum_check_fields saved_count_cuted_fields;
1010 
1011  bool store_failed= FALSE;
1012 
1013  bool save_binlog_row_based;
1014 
1015  DBUG_ENTER("sp_create_routine");
1016  DBUG_PRINT("enter", ("type: %d name: %.*s",sp->m_type,
1017  (int) sp->m_name.length, sp->m_name.str));
1018  String retstr(64);
1019  retstr.set_charset(system_charset_info);
1020 
1021  DBUG_ASSERT(sp->m_type == SP_TYPE_PROCEDURE ||
1022  sp->m_type == SP_TYPE_FUNCTION);
1023 
1024  /* Grab an exclusive MDL lock. */
1025  if (lock_object_name(thd, mdl_type, sp->m_db.str, sp->m_name.str))
1026  DBUG_RETURN(SP_OPEN_TABLE_FAILED);
1027 
1028  /* Reset sql_mode during data dictionary operations. */
1029  thd->variables.sql_mode= 0;
1030 
1031  /*
1032  This statement will be replicated as a statement, even when using
1033  row-based replication. The flag will be reset at the end of the
1034  statement.
1035  */
1036  if ((save_binlog_row_based= thd->is_current_stmt_binlog_format_row()))
1037  thd->clear_current_stmt_binlog_format_row();
1038 
1039  saved_count_cuted_fields= thd->count_cuted_fields;
1040  thd->count_cuted_fields= CHECK_FIELD_WARN;
1041 
1042  if (!(table= open_proc_table_for_update(thd)))
1043  ret= SP_OPEN_TABLE_FAILED;
1044  else
1045  {
1046  restore_record(table, s->default_values); // Get default values for fields
1047 
1048  /* NOTE: all needed privilege checks have been already done. */
1049  strxnmov(definer, sizeof(definer)-1, thd->lex->definer->user.str, "@",
1050  thd->lex->definer->host.str, NullS);
1051 
1052  if (table->s->fields < MYSQL_PROC_FIELD_COUNT)
1053  {
1054  ret= SP_GET_FIELD_FAILED;
1055  goto done;
1056  }
1057 
1058  if (system_charset_info->cset->numchars(system_charset_info,
1059  sp->m_name.str,
1060  sp->m_name.str+sp->m_name.length) >
1061  table->field[MYSQL_PROC_FIELD_NAME]->char_length())
1062  {
1063  ret= SP_BAD_IDENTIFIER;
1064  goto done;
1065  }
1066  if (sp->m_body.length > table->field[MYSQL_PROC_FIELD_BODY]->field_length)
1067  {
1068  ret= SP_BODY_TOO_LONG;
1069  goto done;
1070  }
1071 
1072  store_failed=
1073  table->field[MYSQL_PROC_FIELD_DB]->
1074  store(sp->m_db.str, sp->m_db.length, system_charset_info);
1075 
1076  store_failed= store_failed ||
1077  table->field[MYSQL_PROC_FIELD_NAME]->
1078  store(sp->m_name.str, sp->m_name.length, system_charset_info);
1079 
1080  store_failed= store_failed ||
1081  table->field[MYSQL_PROC_MYSQL_TYPE]->
1082  store((longlong)sp->m_type, TRUE);
1083 
1084  store_failed= store_failed ||
1085  table->field[MYSQL_PROC_FIELD_SPECIFIC_NAME]->
1086  store(sp->m_name.str, sp->m_name.length, system_charset_info);
1087 
1088  if (sp->m_chistics->daccess != SP_DEFAULT_ACCESS)
1089  {
1090  store_failed= store_failed ||
1091  table->field[MYSQL_PROC_FIELD_ACCESS]->
1092  store((longlong)sp->m_chistics->daccess, TRUE);
1093  }
1094 
1095  store_failed= store_failed ||
1096  table->field[MYSQL_PROC_FIELD_DETERMINISTIC]->
1097  store((longlong)(sp->m_chistics->detistic ? 1 : 2), TRUE);
1098 
1099  if (sp->m_chistics->suid != SP_IS_DEFAULT_SUID)
1100  {
1101  store_failed= store_failed ||
1102  table->field[MYSQL_PROC_FIELD_SECURITY_TYPE]->
1103  store((longlong)sp->m_chistics->suid, TRUE);
1104  }
1105 
1106  store_failed= store_failed ||
1107  table->field[MYSQL_PROC_FIELD_PARAM_LIST]->
1108  store(sp->m_params.str, sp->m_params.length, system_charset_info);
1109 
1110  if (sp->m_type == SP_TYPE_FUNCTION)
1111  {
1112  sp_returns_type(thd, retstr, sp);
1113 
1114  store_failed= store_failed ||
1115  table->field[MYSQL_PROC_FIELD_RETURNS]->
1116  store(retstr.ptr(), retstr.length(), system_charset_info);
1117  }
1118 
1119  store_failed= store_failed ||
1120  table->field[MYSQL_PROC_FIELD_BODY]->
1121  store(sp->m_body.str, sp->m_body.length, system_charset_info);
1122 
1123  store_failed= store_failed ||
1124  table->field[MYSQL_PROC_FIELD_DEFINER]->
1125  store(definer, (uint)strlen(definer), system_charset_info);
1126 
1127  Item_func_now_local::store_in(table->field[MYSQL_PROC_FIELD_CREATED]);
1128  Item_func_now_local::store_in(table->field[MYSQL_PROC_FIELD_MODIFIED]);
1129 
1130  store_failed= store_failed ||
1131  table->field[MYSQL_PROC_FIELD_SQL_MODE]->
1132  store((longlong)saved_mode, TRUE);
1133 
1134  if (sp->m_chistics->comment.str)
1135  {
1136  store_failed= store_failed ||
1137  table->field[MYSQL_PROC_FIELD_COMMENT]->
1138  store(sp->m_chistics->comment.str, sp->m_chistics->comment.length,
1139  system_charset_info);
1140  }
1141 
1142  if ((sp->m_type == SP_TYPE_FUNCTION) &&
1143  !trust_function_creators && mysql_bin_log.is_open())
1144  {
1145  if (!sp->m_chistics->detistic)
1146  {
1147  /*
1148  Note that this test is not perfect; one could use
1149  a non-deterministic read-only function in an update statement.
1150  */
1151  enum enum_sp_data_access access=
1152  (sp->m_chistics->daccess == SP_DEFAULT_ACCESS) ?
1153  SP_DEFAULT_ACCESS_MAPPING : sp->m_chistics->daccess;
1154  if (access == SP_CONTAINS_SQL ||
1155  access == SP_MODIFIES_SQL_DATA)
1156  {
1157  my_message(ER_BINLOG_UNSAFE_ROUTINE,
1158  ER(ER_BINLOG_UNSAFE_ROUTINE), MYF(0));
1159  ret= SP_INTERNAL_ERROR;
1160  goto done;
1161  }
1162  }
1163  if (!(thd->security_ctx->master_access & SUPER_ACL))
1164  {
1165  my_message(ER_BINLOG_CREATE_ROUTINE_NEED_SUPER,
1166  ER(ER_BINLOG_CREATE_ROUTINE_NEED_SUPER), MYF(0));
1167  ret= SP_INTERNAL_ERROR;
1168  goto done;
1169  }
1170  }
1171 
1172  table->field[MYSQL_PROC_FIELD_CHARACTER_SET_CLIENT]->set_notnull();
1173  store_failed= store_failed ||
1174  table->field[MYSQL_PROC_FIELD_CHARACTER_SET_CLIENT]->store(
1175  thd->charset()->csname,
1176  strlen(thd->charset()->csname),
1177  system_charset_info);
1178 
1179  table->field[MYSQL_PROC_FIELD_COLLATION_CONNECTION]->set_notnull();
1180  store_failed= store_failed ||
1181  table->field[MYSQL_PROC_FIELD_COLLATION_CONNECTION]->store(
1182  thd->variables.collation_connection->name,
1183  strlen(thd->variables.collation_connection->name),
1184  system_charset_info);
1185 
1186  table->field[MYSQL_PROC_FIELD_DB_COLLATION]->set_notnull();
1187  store_failed= store_failed ||
1188  table->field[MYSQL_PROC_FIELD_DB_COLLATION]->store(
1189  db_cs->name, strlen(db_cs->name), system_charset_info);
1190 
1191  table->field[MYSQL_PROC_FIELD_BODY_UTF8]->set_notnull();
1192  store_failed= store_failed ||
1193  table->field[MYSQL_PROC_FIELD_BODY_UTF8]->store(
1194  sp->m_body_utf8.str, sp->m_body_utf8.length, system_charset_info);
1195 
1196  if (store_failed)
1197  {
1198  ret= SP_FLD_STORE_FAILED;
1199  goto done;
1200  }
1201 
1202  ret= SP_OK;
1203  if (table->file->ha_write_row(table->record[0]))
1204  ret= SP_WRITE_ROW_FAILED;
1205  if (ret == SP_OK)
1206  sp_cache_invalidate();
1207 
1208  if (ret == SP_OK && mysql_bin_log.is_open())
1209  {
1210  thd->clear_error();
1211 
1212  String log_query;
1213  log_query.set_charset(system_charset_info);
1214 
1215  if (!create_string(thd, &log_query,
1216  sp->m_type,
1217  (sp->m_explicit_name ? sp->m_db.str : NULL),
1218  (sp->m_explicit_name ? sp->m_db.length : 0),
1219  sp->m_name.str, sp->m_name.length,
1220  sp->m_params.str, sp->m_params.length,
1221  retstr.c_ptr(), retstr.length(),
1222  sp->m_body.str, sp->m_body.length,
1223  sp->m_chistics, &(thd->lex->definer->user),
1224  &(thd->lex->definer->host),
1225  saved_mode))
1226  {
1227  ret= SP_INTERNAL_ERROR;
1228  goto done;
1229  }
1230  /* restore sql_mode when binloging */
1231  thd->variables.sql_mode= saved_mode;
1232  thd->add_to_binlog_accessed_dbs(sp->m_db.str);
1233  /* Such a statement can always go directly to binlog, no trans cache */
1234  if (thd->binlog_query(THD::STMT_QUERY_TYPE,
1235  log_query.c_ptr(), log_query.length(),
1236  FALSE, FALSE, FALSE, 0))
1237  ret= SP_INTERNAL_ERROR;
1238  thd->variables.sql_mode= 0;
1239  }
1240  }
1241 
1242 done:
1243  thd->count_cuted_fields= saved_count_cuted_fields;
1244  thd->variables.sql_mode= saved_mode;
1245  /* Restore the state of binlog format */
1246  DBUG_ASSERT(!thd->is_current_stmt_binlog_format_row());
1247  if (save_binlog_row_based)
1248  thd->set_current_stmt_binlog_format_row();
1249  DBUG_RETURN(ret);
1250 }
1251 
1252 
1268 int sp_drop_routine(THD *thd, enum_sp_type type, sp_name *name)
1269 {
1270  TABLE *table;
1271  int ret;
1272  bool save_binlog_row_based;
1273  MDL_key::enum_mdl_namespace mdl_type= (type == SP_TYPE_FUNCTION) ?
1274  MDL_key::FUNCTION : MDL_key::PROCEDURE;
1275  DBUG_ENTER("sp_drop_routine");
1276  DBUG_PRINT("enter", ("type: %d name: %.*s",
1277  type, (int) name->m_name.length, name->m_name.str));
1278 
1279  DBUG_ASSERT(type == SP_TYPE_PROCEDURE || type == SP_TYPE_FUNCTION);
1280 
1281  /* Grab an exclusive MDL lock. */
1282  if (lock_object_name(thd, mdl_type, name->m_db.str, name->m_name.str))
1283  DBUG_RETURN(SP_DELETE_ROW_FAILED);
1284 
1285  if (!(table= open_proc_table_for_update(thd)))
1286  DBUG_RETURN(SP_OPEN_TABLE_FAILED);
1287 
1288  /*
1289  This statement will be replicated as a statement, even when using
1290  row-based replication. The flag will be reset at the end of the
1291  statement.
1292  */
1293  if ((save_binlog_row_based= thd->is_current_stmt_binlog_format_row()))
1294  thd->clear_current_stmt_binlog_format_row();
1295 
1296  if ((ret= db_find_routine_aux(thd, type, name, table)) == SP_OK)
1297  {
1298  if (table->file->ha_delete_row(table->record[0]))
1299  ret= SP_DELETE_ROW_FAILED;
1300  }
1301 
1302  if (ret == SP_OK)
1303  {
1304  thd->add_to_binlog_accessed_dbs(name->m_db.str);
1305  if (write_bin_log(thd, TRUE, thd->query(), thd->query_length()))
1306  ret= SP_INTERNAL_ERROR;
1307  sp_cache_invalidate();
1308 
1309  /*
1310  A lame workaround for lack of cache flush:
1311  make sure the routine is at least gone from the
1312  local cache.
1313  */
1314  {
1315  sp_head *sp;
1316  sp_cache **spc= (type == SP_TYPE_FUNCTION ?
1317  &thd->sp_func_cache : &thd->sp_proc_cache);
1318  sp= sp_cache_lookup(spc, name);
1319  if (sp)
1320  sp_cache_flush_obsolete(spc, &sp);
1321  }
1322  }
1323  /* Restore the state of binlog format */
1324  DBUG_ASSERT(!thd->is_current_stmt_binlog_format_row());
1325  if (save_binlog_row_based)
1326  thd->set_current_stmt_binlog_format_row();
1327  DBUG_RETURN(ret);
1328 }
1329 
1330 
1348 int sp_update_routine(THD *thd, enum_sp_type type, sp_name *name,
1349  st_sp_chistics *chistics)
1350 {
1351  TABLE *table;
1352  int ret;
1353  bool save_binlog_row_based;
1354  MDL_key::enum_mdl_namespace mdl_type= (type == SP_TYPE_FUNCTION) ?
1355  MDL_key::FUNCTION : MDL_key::PROCEDURE;
1356  DBUG_ENTER("sp_update_routine");
1357  DBUG_PRINT("enter", ("type: %d name: %.*s",
1358  type, (int) name->m_name.length, name->m_name.str));
1359 
1360  DBUG_ASSERT(type == SP_TYPE_PROCEDURE || type == SP_TYPE_FUNCTION);
1361 
1362  /* Grab an exclusive MDL lock. */
1363  if (lock_object_name(thd, mdl_type, name->m_db.str, name->m_name.str))
1364  DBUG_RETURN(SP_OPEN_TABLE_FAILED);
1365 
1366  if (!(table= open_proc_table_for_update(thd)))
1367  DBUG_RETURN(SP_OPEN_TABLE_FAILED);
1368 
1369  /*
1370  This statement will be replicated as a statement, even when using
1371  row-based replication. The flag will be reset at the end of the
1372  statement.
1373  */
1374  if ((save_binlog_row_based= thd->is_current_stmt_binlog_format_row()))
1375  thd->clear_current_stmt_binlog_format_row();
1376 
1377  if ((ret= db_find_routine_aux(thd, type, name, table)) == SP_OK)
1378  {
1379  if (type == SP_TYPE_FUNCTION && ! trust_function_creators &&
1380  mysql_bin_log.is_open() &&
1381  (chistics->daccess == SP_CONTAINS_SQL ||
1382  chistics->daccess == SP_MODIFIES_SQL_DATA))
1383  {
1384  char *ptr;
1385  bool is_deterministic;
1386  ptr= get_field(thd->mem_root,
1387  table->field[MYSQL_PROC_FIELD_DETERMINISTIC]);
1388  if (ptr == NULL)
1389  {
1390  ret= SP_INTERNAL_ERROR;
1391  goto err;
1392  }
1393  is_deterministic= ptr[0] == 'N' ? FALSE : TRUE;
1394  if (!is_deterministic)
1395  {
1396  my_message(ER_BINLOG_UNSAFE_ROUTINE,
1397  ER(ER_BINLOG_UNSAFE_ROUTINE), MYF(0));
1398  ret= SP_INTERNAL_ERROR;
1399  goto err;
1400  }
1401  }
1402 
1403  store_record(table,record[1]);
1404  Item_func_now_local::store_in(table->field[MYSQL_PROC_FIELD_MODIFIED]);
1405  if (chistics->suid != SP_IS_DEFAULT_SUID)
1406  table->field[MYSQL_PROC_FIELD_SECURITY_TYPE]->
1407  store((longlong)chistics->suid, TRUE);
1408  if (chistics->daccess != SP_DEFAULT_ACCESS)
1409  table->field[MYSQL_PROC_FIELD_ACCESS]->
1410  store((longlong)chistics->daccess, TRUE);
1411  if (chistics->comment.str)
1412  table->field[MYSQL_PROC_FIELD_COMMENT]->store(chistics->comment.str,
1413  chistics->comment.length,
1414  system_charset_info);
1415  if ((ret= table->file->ha_update_row(table->record[1],table->record[0])) &&
1416  ret != HA_ERR_RECORD_IS_THE_SAME)
1417  ret= SP_WRITE_ROW_FAILED;
1418  else
1419  ret= 0;
1420  }
1421 
1422  if (ret == SP_OK)
1423  {
1424  if (write_bin_log(thd, TRUE, thd->query(), thd->query_length()))
1425  ret= SP_INTERNAL_ERROR;
1426  sp_cache_invalidate();
1427  }
1428 err:
1429  /* Restore the state of binlog format */
1430  DBUG_ASSERT(!thd->is_current_stmt_binlog_format_row());
1431  if (save_binlog_row_based)
1432  thd->set_current_stmt_binlog_format_row();
1433  DBUG_RETURN(ret);
1434 }
1435 
1436 
1441 class Lock_db_routines_error_handler : public Internal_error_handler
1442 {
1443 public:
1444  bool handle_condition(THD *thd,
1445  uint sql_errno,
1446  const char* sqlstate,
1447  Sql_condition::enum_warning_level level,
1448  const char* msg,
1449  Sql_condition ** cond_hdl)
1450  {
1451  if (sql_errno == ER_NO_SUCH_TABLE ||
1452  sql_errno == ER_CANNOT_LOAD_FROM_TABLE_V2 ||
1453  sql_errno == ER_COL_COUNT_DOESNT_MATCH_PLEASE_UPDATE ||
1454  sql_errno == ER_COL_COUNT_DOESNT_MATCH_CORRUPTED_V2)
1455  return true;
1456  return false;
1457  }
1458 };
1459 
1460 
1470 bool lock_db_routines(THD *thd, char *db)
1471 {
1472  TABLE *table;
1473  uint key_len;
1474  Open_tables_backup open_tables_state_backup;
1475  MDL_request_list mdl_requests;
1476  Lock_db_routines_error_handler err_handler;
1477  DBUG_ENTER("lock_db_routines");
1478 
1479  /*
1480  mysql.proc will be re-opened during deletion, so we can ignore
1481  errors when opening the table here. The error handler is
1482  used to avoid getting the same warning twice.
1483  */
1484  thd->push_internal_handler(&err_handler);
1485  table= open_proc_table_for_read(thd, &open_tables_state_backup);
1486  thd->pop_internal_handler();
1487  if (!table)
1488  {
1489  /*
1490  DROP DATABASE should not fail even if mysql.proc does not exist
1491  or is outdated. We therefore only abort mysql_rm_db() if we
1492  have errors not handled by the error handler.
1493  */
1494  DBUG_RETURN(thd->is_error() || thd->killed);
1495  }
1496 
1497  table->field[MYSQL_PROC_FIELD_DB]->store(db, strlen(db), system_charset_info);
1498  key_len= table->key_info->key_part[0].store_length;
1499  int nxtres= table->file->ha_index_init(0, 1);
1500  if (nxtres)
1501  {
1502  table->file->print_error(nxtres, MYF(0));
1503  close_system_tables(thd, &open_tables_state_backup);
1504  DBUG_RETURN(true);
1505  }
1506 
1507  if (! table->file->ha_index_read_map(table->record[0],
1508  table->field[MYSQL_PROC_FIELD_DB]->ptr,
1509  (key_part_map)1, HA_READ_KEY_EXACT))
1510  {
1511  do
1512  {
1513  char *sp_name= get_field(thd->mem_root,
1514  table->field[MYSQL_PROC_FIELD_NAME]);
1515  longlong sp_type= table->field[MYSQL_PROC_MYSQL_TYPE]->val_int();
1516  MDL_request *mdl_request= new (thd->mem_root) MDL_request;
1517  mdl_request->init(sp_type == SP_TYPE_FUNCTION ?
1518  MDL_key::FUNCTION : MDL_key::PROCEDURE,
1519  db, sp_name, MDL_EXCLUSIVE, MDL_TRANSACTION);
1520  mdl_requests.push_front(mdl_request);
1521  } while (! (nxtres= table->file->ha_index_next_same(table->record[0],
1522  table->field[MYSQL_PROC_FIELD_DB]->ptr,
1523  key_len)));
1524  }
1525  table->file->ha_index_end();
1526  if (nxtres != 0 && nxtres != HA_ERR_END_OF_FILE)
1527  {
1528  table->file->print_error(nxtres, MYF(0));
1529  close_system_tables(thd, &open_tables_state_backup);
1530  DBUG_RETURN(true);
1531  }
1532  close_system_tables(thd, &open_tables_state_backup);
1533 
1534  /* We should already hold a global IX lock and a schema X lock. */
1535  DBUG_ASSERT(thd->mdl_context.is_lock_owner(MDL_key::GLOBAL, "", "",
1536  MDL_INTENTION_EXCLUSIVE) &&
1537  thd->mdl_context.is_lock_owner(MDL_key::SCHEMA, db, "",
1538  MDL_EXCLUSIVE));
1539  DBUG_RETURN(thd->mdl_context.acquire_locks(&mdl_requests,
1540  thd->variables.lock_wait_timeout));
1541 }
1542 
1543 
1554 int
1555 sp_drop_db_routines(THD *thd, char *db)
1556 {
1557  TABLE *table;
1558  int ret;
1559  uint key_len;
1560  MDL_savepoint mdl_savepoint= thd->mdl_context.mdl_savepoint();
1561  DBUG_ENTER("sp_drop_db_routines");
1562  DBUG_PRINT("enter", ("db: %s", db));
1563 
1564  ret= SP_OPEN_TABLE_FAILED;
1565  if (!(table= open_proc_table_for_update(thd)))
1566  goto err;
1567 
1568  table->field[MYSQL_PROC_FIELD_DB]->store(db, strlen(db), system_charset_info);
1569  key_len= table->key_info->key_part[0].store_length;
1570 
1571  ret= SP_OK;
1572  if (table->file->ha_index_init(0, 1))
1573  {
1574  ret= SP_KEY_NOT_FOUND;
1575  goto err_idx_init;
1576  }
1577 
1578  if (! table->file->ha_index_read_map(table->record[0],
1579  (uchar *)table->field[MYSQL_PROC_FIELD_DB]->ptr,
1580  (key_part_map)1, HA_READ_KEY_EXACT))
1581  {
1582  int nxtres;
1583  bool deleted= FALSE;
1584 
1585  do
1586  {
1587  if (! table->file->ha_delete_row(table->record[0]))
1588  deleted= TRUE; /* We deleted something */
1589  else
1590  {
1591  ret= SP_DELETE_ROW_FAILED;
1592  nxtres= 0;
1593  break;
1594  }
1595  } while (! (nxtres= table->file->ha_index_next_same(table->record[0],
1596  (uchar *)table->field[MYSQL_PROC_FIELD_DB]->ptr,
1597  key_len)));
1598  if (nxtres != HA_ERR_END_OF_FILE)
1599  ret= SP_KEY_NOT_FOUND;
1600  if (deleted)
1601  sp_cache_invalidate();
1602  }
1603  table->file->ha_index_end();
1604 
1605 err_idx_init:
1606  close_thread_tables(thd);
1607  /*
1608  Make sure to only release the MDL lock on mysql.proc, not other
1609  metadata locks DROP DATABASE might have acquired.
1610  */
1611  thd->mdl_context.rollback_to_savepoint(mdl_savepoint);
1612 
1613 err:
1614  DBUG_RETURN(ret);
1615 }
1616 
1617 
1634 bool sp_show_create_routine(THD *thd, enum_sp_type type, sp_name *name)
1635 {
1636  sp_head *sp;
1637 
1638  DBUG_ENTER("sp_show_create_routine");
1639  DBUG_PRINT("enter", ("name: %.*s",
1640  (int) name->m_name.length,
1641  name->m_name.str));
1642 
1643  DBUG_ASSERT(type == SP_TYPE_PROCEDURE || type == SP_TYPE_FUNCTION);
1644 
1645  /*
1646  @todo: Consider using prelocking for this code as well. Currently
1647  SHOW CREATE PROCEDURE/FUNCTION is a dirty read of the data
1648  dictionary, i.e. takes no metadata locks.
1649  It is "safe" to do as long as it doesn't affect the results
1650  of the binary log or the query cache, which currently it does not.
1651  */
1652  if (sp_cache_routine(thd, type, name, FALSE, &sp))
1653  DBUG_RETURN(TRUE);
1654 
1655  if (sp == NULL || sp->show_create_routine(thd, type))
1656  {
1657  /*
1658  If we have insufficient privileges, pretend the routine
1659  does not exist.
1660  */
1661  my_error(ER_SP_DOES_NOT_EXIST, MYF(0),
1662  type == SP_TYPE_FUNCTION ? "FUNCTION" : "PROCEDURE",
1663  name->m_name.str);
1664  DBUG_RETURN(TRUE);
1665  }
1666 
1667  DBUG_RETURN(FALSE);
1668 }
1669 
1670 
1688 sp_head *sp_find_routine(THD *thd, enum_sp_type type, sp_name *name,
1689  sp_cache **cp, bool cache_only)
1690 {
1691  sp_head *sp;
1692  ulong depth= (type == SP_TYPE_PROCEDURE ?
1693  thd->variables.max_sp_recursion_depth :
1694  0);
1695  DBUG_ENTER("sp_find_routine");
1696  DBUG_PRINT("enter", ("name: %.*s.%.*s type: %d cache only %d",
1697  (int) name->m_db.length, name->m_db.str,
1698  (int) name->m_name.length, name->m_name.str,
1699  type, cache_only));
1700 
1701  if ((sp= sp_cache_lookup(cp, name)))
1702  {
1703  ulong level;
1704  sp_head *new_sp;
1705  const char *returns= "";
1706  char definer[USER_HOST_BUFF_SIZE];
1707 
1708  /*
1709  String buffer for RETURNS data type must have system charset;
1710  64 -- size of "returns" column of mysql.proc.
1711  */
1712  String retstr(64);
1713  retstr.set_charset(sp->get_creation_ctx()->get_client_cs());
1714 
1715  DBUG_PRINT("info", ("found: 0x%lx", (ulong)sp));
1716  if (sp->m_first_free_instance)
1717  {
1718  DBUG_PRINT("info", ("first free: 0x%lx level: %lu flags %x",
1719  (ulong)sp->m_first_free_instance,
1722  DBUG_ASSERT(!(sp->m_first_free_instance->m_flags & sp_head::IS_INVOKED));
1723  if (sp->m_first_free_instance->m_recursion_level > depth)
1724  {
1725  recursion_level_error(thd, sp);
1726  DBUG_RETURN(0);
1727  }
1728  DBUG_RETURN(sp->m_first_free_instance);
1729  }
1730  /*
1731  Actually depth could be +1 than the actual value in case a SP calls
1732  SHOW CREATE PROCEDURE. Hence, the linked list could hold up to one more
1733  instance.
1734  */
1735 
1736  level= sp->m_last_cached_sp->m_recursion_level + 1;
1737  if (level > depth)
1738  {
1739  recursion_level_error(thd, sp);
1740  DBUG_RETURN(0);
1741  }
1742 
1743  strxmov(definer, sp->m_definer_user.str, "@",
1744  sp->m_definer_host.str, NullS);
1745  if (type == SP_TYPE_FUNCTION)
1746  {
1747  sp_returns_type(thd, retstr, sp);
1748  returns= retstr.ptr();
1749  }
1750  if (db_load_routine(thd, type, name, &new_sp,
1751  sp->m_sql_mode, sp->m_params.str, returns,
1752  sp->m_body.str, *sp->m_chistics, definer,
1753  sp->m_created, sp->m_modified,
1754  sp->get_creation_ctx()) == SP_OK)
1755  {
1756  sp->m_last_cached_sp->m_next_cached_sp= new_sp;
1757  new_sp->m_recursion_level= level;
1758  new_sp->m_first_instance= sp;
1759  sp->m_last_cached_sp= sp->m_first_free_instance= new_sp;
1760  DBUG_PRINT("info", ("added level: 0x%lx, level: %lu, flags %x",
1761  (ulong)new_sp, new_sp->m_recursion_level,
1762  new_sp->m_flags));
1763  DBUG_RETURN(new_sp);
1764  }
1765  DBUG_RETURN(0);
1766  }
1767  if (!cache_only)
1768  {
1769  if (db_find_routine(thd, type, name, &sp) == SP_OK)
1770  {
1771  sp_cache_insert(cp, sp);
1772  DBUG_PRINT("info", ("added new: 0x%lx, level: %lu, flags %x",
1773  (ulong)sp, sp->m_recursion_level,
1774  sp->m_flags));
1775  }
1776  }
1777  DBUG_RETURN(sp);
1778 }
1779 
1780 
1795 bool
1796 sp_exist_routines(THD *thd, TABLE_LIST *routines, bool is_proc)
1797 {
1798  TABLE_LIST *routine;
1799  bool sp_object_found;
1800  DBUG_ENTER("sp_exists_routine");
1801  for (routine= routines; routine; routine= routine->next_global)
1802  {
1803  sp_name *name;
1804  LEX_STRING lex_db;
1805  LEX_STRING lex_name;
1806  lex_db.length= strlen(routine->db);
1807  lex_name.length= strlen(routine->table_name);
1808  lex_db.str= thd->strmake(routine->db, lex_db.length);
1809  lex_name.str= thd->strmake(routine->table_name, lex_name.length);
1810  name= new sp_name(lex_db, lex_name, true);
1811  name->init_qname(thd);
1812  sp_object_found= is_proc ? sp_find_routine(thd, SP_TYPE_PROCEDURE,
1813  name, &thd->sp_proc_cache,
1814  FALSE) != NULL :
1815  sp_find_routine(thd, SP_TYPE_FUNCTION,
1816  name, &thd->sp_func_cache,
1817  FALSE) != NULL;
1818  thd->get_stmt_da()->clear_warning_info(thd->query_id);
1819  if (! sp_object_found)
1820  {
1821  my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "FUNCTION or PROCEDURE",
1822  routine->table_name);
1823  DBUG_RETURN(TRUE);
1824  }
1825  }
1826  DBUG_RETURN(FALSE);
1827 }
1828 
1829 
1830 extern "C" uchar* sp_sroutine_key(const uchar *ptr, size_t *plen,
1831  my_bool first)
1832 {
1834  *plen= rn->mdl_request.key.length();
1835  return (uchar *)rn->mdl_request.key.ptr();
1836 }
1837 
1838 
1872 bool sp_add_used_routine(Query_tables_list *prelocking_ctx, Query_arena *arena,
1873  const MDL_key *key, TABLE_LIST *belong_to_view)
1874 {
1875  my_hash_init_opt(&prelocking_ctx->sroutines, system_charset_info,
1876  Query_tables_list::START_SROUTINES_HASH_SIZE,
1877  0, 0, sp_sroutine_key, 0, 0);
1878 
1879  if (!my_hash_search(&prelocking_ctx->sroutines, key->ptr(), key->length()))
1880  {
1881  Sroutine_hash_entry *rn=
1882  (Sroutine_hash_entry *)arena->alloc(sizeof(Sroutine_hash_entry));
1883  if (!rn) // OOM. Error will be reported using fatal_error().
1884  return FALSE;
1885  rn->mdl_request.init(key, MDL_SHARED, MDL_TRANSACTION);
1886  if (my_hash_insert(&prelocking_ctx->sroutines, (uchar *)rn))
1887  return FALSE;
1888  prelocking_ctx->sroutines_list.link_in_list(rn, &rn->next);
1889  rn->belong_to_view= belong_to_view;
1890  rn->m_sp_cache_version= 0;
1891  return TRUE;
1892  }
1893  return FALSE;
1894 }
1895 
1896 
1915 void sp_add_used_routine(Query_tables_list *prelocking_ctx, Query_arena *arena,
1916  sp_name *rt, enum_sp_type rt_type)
1917 {
1918  MDL_key key((rt_type == SP_TYPE_FUNCTION) ? MDL_key::FUNCTION :
1919  MDL_key::PROCEDURE,
1920  rt->m_db.str, rt->m_name.str);
1921  (void)sp_add_used_routine(prelocking_ctx, arena, &key, 0);
1922  prelocking_ctx->sroutines_list_own_last= prelocking_ctx->sroutines_list.next;
1923  prelocking_ctx->sroutines_list_own_elements=
1924  prelocking_ctx->sroutines_list.elements;
1925 }
1926 
1927 
1935 void sp_remove_not_own_routines(Query_tables_list *prelocking_ctx)
1936 {
1937  Sroutine_hash_entry *not_own_rt, *next_rt;
1938  for (not_own_rt= *prelocking_ctx->sroutines_list_own_last;
1939  not_own_rt; not_own_rt= next_rt)
1940  {
1941  /*
1942  It is safe to obtain not_own_rt->next after calling hash_delete() now
1943  but we want to be more future-proof.
1944  */
1945  next_rt= not_own_rt->next;
1946  my_hash_delete(&prelocking_ctx->sroutines, (uchar *)not_own_rt);
1947  }
1948 
1949  *prelocking_ctx->sroutines_list_own_last= NULL;
1950  prelocking_ctx->sroutines_list.next= prelocking_ctx->sroutines_list_own_last;
1951  prelocking_ctx->sroutines_list.elements=
1952  prelocking_ctx->sroutines_list_own_elements;
1953 }
1954 
1955 
1970 void
1971 sp_update_stmt_used_routines(THD *thd, Query_tables_list *prelocking_ctx,
1972  HASH *src, TABLE_LIST *belong_to_view)
1973 {
1974  for (uint i=0 ; i < src->records ; i++)
1975  {
1976  Sroutine_hash_entry *rt= (Sroutine_hash_entry *)my_hash_element(src, i);
1977  (void)sp_add_used_routine(prelocking_ctx, thd->stmt_arena,
1978  &rt->mdl_request.key, belong_to_view);
1979  }
1980 }
1981 
1982 
1997 void sp_update_stmt_used_routines(THD *thd, Query_tables_list *prelocking_ctx,
1999  TABLE_LIST *belong_to_view)
2000 {
2001  for (Sroutine_hash_entry *rt= src->first; rt; rt= rt->next)
2002  (void)sp_add_used_routine(prelocking_ctx, thd->stmt_arena,
2003  &rt->mdl_request.key, belong_to_view);
2004 }
2005 
2006 
2012 int sp_cache_routine(THD *thd, Sroutine_hash_entry *rt,
2013  bool lookup_only, sp_head **sp)
2014 {
2015  char qname_buff[NAME_LEN*2+1+1];
2016  sp_name name(&rt->mdl_request.key, qname_buff);
2017  MDL_key::enum_mdl_namespace mdl_type= rt->mdl_request.key.mdl_namespace();
2018  enum_sp_type type= (mdl_type == MDL_key::FUNCTION) ?
2019  SP_TYPE_FUNCTION : SP_TYPE_PROCEDURE;
2020 
2021  /*
2022  Check that we have an MDL lock on this routine, unless it's a top-level
2023  CALL. The assert below should be unambiguous: the first element
2024  in sroutines_list has an MDL lock unless it's a top-level call, or a
2025  trigger, but triggers can't occur here (see the preceding assert).
2026  */
2027  DBUG_ASSERT(rt->mdl_request.ticket || rt == thd->lex->sroutines_list.first);
2028 
2029  return sp_cache_routine(thd, type, &name, lookup_only, sp);
2030 }
2031 
2032 
2053 int sp_cache_routine(THD *thd, enum_sp_type type, sp_name *name,
2054  bool lookup_only, sp_head **sp)
2055 {
2056  int ret= 0;
2057  sp_cache **spc= (type == SP_TYPE_FUNCTION) ?
2058  &thd->sp_func_cache : &thd->sp_proc_cache;
2059 
2060  DBUG_ENTER("sp_cache_routine");
2061 
2062  DBUG_ASSERT(type == SP_TYPE_FUNCTION || type == SP_TYPE_PROCEDURE);
2063 
2064 
2065  *sp= sp_cache_lookup(spc, name);
2066 
2067  if (lookup_only)
2068  DBUG_RETURN(SP_OK);
2069 
2070  if (*sp)
2071  {
2072  sp_cache_flush_obsolete(spc, sp);
2073  if (*sp)
2074  DBUG_RETURN(SP_OK);
2075  }
2076 
2077  switch ((ret= db_find_routine(thd, type, name, sp)))
2078  {
2079  case SP_OK:
2080  sp_cache_insert(spc, *sp);
2081  break;
2082  case SP_KEY_NOT_FOUND:
2083  ret= SP_OK;
2084  break;
2085  default:
2086  /* Query might have been killed, don't set error. */
2087  if (thd->killed)
2088  break;
2089  /*
2090  Any error when loading an existing routine is either some problem
2091  with the mysql.proc table, or a parse error because the contents
2092  has been tampered with (in which case we clear that error).
2093  */
2094  if (ret == SP_PARSE_ERROR)
2095  thd->clear_error();
2096  /*
2097  If we cleared the parse error, or when db_find_routine() flagged
2098  an error with it's return value without calling my_error(), we
2099  set the generic "mysql.proc table corrupt" error here.
2100  */
2101  if (! thd->is_error())
2102  {
2103  /*
2104  SP allows full NAME_LEN chars thus he have to allocate enough
2105  size in bytes. Otherwise there is stack overrun could happen
2106  if multibyte sequence is `name`. `db` is still safe because the
2107  rest of the server checks agains NAME_LEN bytes and not chars.
2108  Hence, the overrun happens only if the name is in length > 32 and
2109  uses multibyte (cyrillic, greek, etc.)
2110  */
2111  char n[NAME_LEN*2+2];
2112 
2113  /* m_qname.str is not always \0 terminated */
2114  memcpy(n, name->m_qname.str, name->m_qname.length);
2115  n[name->m_qname.length]= '\0';
2116  my_error(ER_SP_PROC_TABLE_CORRUPT, MYF(0), n, ret);
2117  }
2118  break;
2119  }
2120  DBUG_RETURN(ret);
2121 }
2122 
2123 
2130 static bool create_string(THD *thd, String *buf,
2131  enum_sp_type type,
2132  const char *db, ulong dblen,
2133  const char *name, ulong namelen,
2134  const char *params, ulong paramslen,
2135  const char *returns, ulong returnslen,
2136  const char *body, ulong bodylen,
2137  st_sp_chistics *chistics,
2138  const LEX_STRING *definer_user,
2139  const LEX_STRING *definer_host,
2140  sql_mode_t sql_mode)
2141 {
2142  sql_mode_t old_sql_mode= thd->variables.sql_mode;
2143  /* Make some room to begin with */
2144  if (buf->alloc(100 + dblen + 1 + namelen + paramslen + returnslen + bodylen +
2145  chistics->comment.length + 10 /* length of " DEFINER= "*/ +
2146  USER_HOST_BUFF_SIZE))
2147  return FALSE;
2148 
2149  thd->variables.sql_mode= sql_mode;
2150  buf->append(STRING_WITH_LEN("CREATE "));
2151  append_definer(thd, buf, definer_user, definer_host);
2152  if (type == SP_TYPE_FUNCTION)
2153  buf->append(STRING_WITH_LEN("FUNCTION "));
2154  else
2155  buf->append(STRING_WITH_LEN("PROCEDURE "));
2156  if (dblen > 0)
2157  {
2158  append_identifier(thd, buf, db, dblen);
2159  buf->append('.');
2160  }
2161  append_identifier(thd, buf, name, namelen);
2162  buf->append('(');
2163  buf->append(params, paramslen);
2164  buf->append(')');
2165  if (type == SP_TYPE_FUNCTION)
2166  {
2167  buf->append(STRING_WITH_LEN(" RETURNS "));
2168  buf->append(returns, returnslen);
2169  }
2170  buf->append('\n');
2171  switch (chistics->daccess) {
2172  case SP_NO_SQL:
2173  buf->append(STRING_WITH_LEN(" NO SQL\n"));
2174  break;
2175  case SP_READS_SQL_DATA:
2176  buf->append(STRING_WITH_LEN(" READS SQL DATA\n"));
2177  break;
2178  case SP_MODIFIES_SQL_DATA:
2179  buf->append(STRING_WITH_LEN(" MODIFIES SQL DATA\n"));
2180  break;
2181  case SP_DEFAULT_ACCESS:
2182  case SP_CONTAINS_SQL:
2183  /* Do nothing */
2184  break;
2185  }
2186  if (chistics->detistic)
2187  buf->append(STRING_WITH_LEN(" DETERMINISTIC\n"));
2188  if (chistics->suid == SP_IS_NOT_SUID)
2189  buf->append(STRING_WITH_LEN(" SQL SECURITY INVOKER\n"));
2190  if (chistics->comment.length)
2191  {
2192  buf->append(STRING_WITH_LEN(" COMMENT "));
2193  append_unescaped(buf, chistics->comment.str, chistics->comment.length);
2194  buf->append('\n');
2195  }
2196  buf->append(body, bodylen);
2197  thd->variables.sql_mode= old_sql_mode;
2198  return TRUE;
2199 }
2200 
2201 
2222 sp_head *
2223 sp_load_for_information_schema(THD *thd, TABLE *proc_table, String *db,
2224  String *name, sql_mode_t sql_mode,
2225  enum_sp_type type,
2226  const char *returns, const char *params,
2227  bool *free_sp_head)
2228 {
2229  const char *sp_body;
2230  String defstr;
2231  struct st_sp_chistics sp_chistics;
2232  const LEX_STRING definer_user= {(char*)STRING_WITH_LEN("")};
2233  const LEX_STRING definer_host= {(char*)STRING_WITH_LEN("")};
2234  LEX_STRING sp_db_str;
2235  LEX_STRING sp_name_str;
2236  sp_head *sp;
2237  sp_cache **spc= (type == SP_TYPE_FUNCTION) ?
2238  &thd->sp_func_cache : &thd->sp_proc_cache;
2239  sp_db_str.str= db->c_ptr();
2240  sp_db_str.length= db->length();
2241  sp_name_str.str= name->c_ptr();
2242  sp_name_str.length= name->length();
2243  sp_name sp_name_obj(sp_db_str, sp_name_str, true);
2244  sp_name_obj.init_qname(thd);
2245  *free_sp_head= 0;
2246  if ((sp= sp_cache_lookup(spc, &sp_name_obj)))
2247  {
2248  return sp;
2249  }
2250 
2251  LEX *old_lex= thd->lex, newlex;
2252  Stored_program_creation_ctx *creation_ctx=
2253  Stored_routine_creation_ctx::load_from_db(thd, &sp_name_obj, proc_table);
2254  sp_body= (type == SP_TYPE_FUNCTION) ? "RETURN NULL" : "BEGIN END";
2255  memset(&sp_chistics, 0, sizeof(sp_chistics));
2256  defstr.set_charset(creation_ctx->get_client_cs());
2257  if (!create_string(thd, &defstr, type,
2258  sp_db_str.str, sp_db_str.length,
2259  sp_name_obj.m_name.str, sp_name_obj.m_name.length,
2260  params, strlen(params),
2261  returns, strlen(returns),
2262  sp_body, strlen(sp_body),
2263  &sp_chistics, &definer_user, &definer_host, sql_mode))
2264  return 0;
2265 
2266  thd->lex= &newlex;
2267  newlex.current_select= NULL;
2268  sp= sp_compile(thd, &defstr, sql_mode, creation_ctx);
2269  *free_sp_head= 1;
2270  thd->lex->sphead= NULL;
2271  lex_end(thd->lex);
2272  thd->lex= old_lex;
2273  return sp;
2274 }
2275 
2276 
2293 sp_head *sp_start_parsing(THD *thd,
2294  enum_sp_type sp_type,
2295  sp_name *sp_name)
2296 {
2297  // The order is important:
2298  // 1. new sp_head()
2299 
2300  sp_head *sp= new sp_head(sp_type);
2301 
2302  if (!sp)
2303  return NULL;
2304 
2305  // 2. start_parsing_sp_body()
2306 
2307  sp->m_parser_data.start_parsing_sp_body(thd, sp);
2308 
2309  // 3. finish initialization.
2310 
2311  sp->m_root_parsing_ctx= new (thd->mem_root) sp_pcontext();
2312 
2313  if (!sp->m_root_parsing_ctx)
2314  return NULL;
2315 
2316  thd->lex->set_sp_current_parsing_ctx(sp->m_root_parsing_ctx);
2317 
2318  // 4. set name.
2319 
2320  sp->init_sp_name(thd, sp_name);
2321 
2322  return sp;
2323 }
2324 
2325 
2333 void sp_finish_parsing(THD *thd)
2334 {
2335  sp_head *sp= thd->lex->sphead;
2336 
2337  DBUG_ASSERT(sp);
2338 
2339  sp->set_body_end(thd);
2340 
2342 }
2343 
2344 
2346 Item_result sp_map_result_type(enum enum_field_types type)
2347 {
2348  switch (type) {
2349  case MYSQL_TYPE_BIT:
2350  case MYSQL_TYPE_TINY:
2351  case MYSQL_TYPE_SHORT:
2352  case MYSQL_TYPE_LONG:
2353  case MYSQL_TYPE_LONGLONG:
2354  case MYSQL_TYPE_INT24:
2355  return INT_RESULT;
2356  case MYSQL_TYPE_DECIMAL:
2357  case MYSQL_TYPE_NEWDECIMAL:
2358  return DECIMAL_RESULT;
2359  case MYSQL_TYPE_FLOAT:
2360  case MYSQL_TYPE_DOUBLE:
2361  return REAL_RESULT;
2362  default:
2363  return STRING_RESULT;
2364  }
2365 }
2366 
2367 
2369 Item::Type sp_map_item_type(enum enum_field_types type)
2370 {
2371  switch (type) {
2372  case MYSQL_TYPE_BIT:
2373  case MYSQL_TYPE_TINY:
2374  case MYSQL_TYPE_SHORT:
2375  case MYSQL_TYPE_LONG:
2376  case MYSQL_TYPE_LONGLONG:
2377  case MYSQL_TYPE_INT24:
2378  return Item::INT_ITEM;
2379  case MYSQL_TYPE_DECIMAL:
2380  case MYSQL_TYPE_NEWDECIMAL:
2381  return Item::DECIMAL_ITEM;
2382  case MYSQL_TYPE_FLOAT:
2383  case MYSQL_TYPE_DOUBLE:
2384  return Item::REAL_ITEM;
2385  default:
2386  return Item::STRING_ITEM;
2387  }
2388 }
2389 
2390 
2400 uint sp_get_flags_for_command(LEX *lex)
2401 {
2402  uint flags;
2403 
2404  switch (lex->sql_command) {
2405  case SQLCOM_SELECT:
2406  if (lex->result)
2407  {
2408  flags= 0; /* This is a SELECT with INTO clause */
2409  break;
2410  }
2411  /* fallthrough */
2412  case SQLCOM_ANALYZE:
2413  case SQLCOM_OPTIMIZE:
2414  case SQLCOM_PRELOAD_KEYS:
2415  case SQLCOM_ASSIGN_TO_KEYCACHE:
2416  case SQLCOM_CHECKSUM:
2417  case SQLCOM_CHECK:
2418  case SQLCOM_HA_READ:
2419  case SQLCOM_SHOW_BINLOGS:
2420  case SQLCOM_SHOW_BINLOG_EVENTS:
2421  case SQLCOM_SHOW_RELAYLOG_EVENTS:
2422  case SQLCOM_SHOW_CHARSETS:
2423  case SQLCOM_SHOW_COLLATIONS:
2424  case SQLCOM_SHOW_CREATE:
2425  case SQLCOM_SHOW_CREATE_DB:
2426  case SQLCOM_SHOW_CREATE_FUNC:
2427  case SQLCOM_SHOW_CREATE_PROC:
2428  case SQLCOM_SHOW_CREATE_EVENT:
2429  case SQLCOM_SHOW_CREATE_TRIGGER:
2430  case SQLCOM_SHOW_DATABASES:
2431  case SQLCOM_SHOW_ERRORS:
2432  case SQLCOM_SHOW_FIELDS:
2433  case SQLCOM_SHOW_FUNC_CODE:
2434  case SQLCOM_SHOW_GRANTS:
2435  case SQLCOM_SHOW_ENGINE_STATUS:
2436  case SQLCOM_SHOW_ENGINE_LOGS:
2437  case SQLCOM_SHOW_ENGINE_MUTEX:
2438  case SQLCOM_SHOW_EVENTS:
2439  case SQLCOM_SHOW_KEYS:
2440  case SQLCOM_SHOW_MASTER_STAT:
2441  case SQLCOM_SHOW_OPEN_TABLES:
2442  case SQLCOM_SHOW_PRIVILEGES:
2443  case SQLCOM_SHOW_PROCESSLIST:
2444  case SQLCOM_SHOW_PROC_CODE:
2445  case SQLCOM_SHOW_SLAVE_HOSTS:
2446  case SQLCOM_SHOW_SLAVE_STAT:
2447  case SQLCOM_SHOW_STATUS:
2448  case SQLCOM_SHOW_STATUS_FUNC:
2449  case SQLCOM_SHOW_STATUS_PROC:
2450  case SQLCOM_SHOW_STORAGE_ENGINES:
2451  case SQLCOM_SHOW_TABLES:
2452  case SQLCOM_SHOW_TABLE_STATUS:
2453  case SQLCOM_SHOW_VARIABLES:
2454  case SQLCOM_SHOW_WARNS:
2455  case SQLCOM_REPAIR:
2456  flags= sp_head::MULTI_RESULTS;
2457  break;
2458  /*
2459  EXECUTE statement may return a result set, but doesn't have to.
2460  We can't, however, know it in advance, and therefore must add
2461  this statement here. This is ok, as is equivalent to a result-set
2462  statement within an IF condition.
2463  */
2464  case SQLCOM_EXECUTE:
2465  flags= sp_head::MULTI_RESULTS | sp_head::CONTAINS_DYNAMIC_SQL;
2466  break;
2467  case SQLCOM_PREPARE:
2468  case SQLCOM_DEALLOCATE_PREPARE:
2469  flags= sp_head::CONTAINS_DYNAMIC_SQL;
2470  break;
2471  case SQLCOM_CREATE_TABLE:
2472  if (lex->create_info.options & HA_LEX_CREATE_TMP_TABLE)
2473  flags= 0;
2474  else
2475  flags= sp_head::HAS_COMMIT_OR_ROLLBACK;
2476  break;
2477  case SQLCOM_DROP_TABLE:
2478  if (lex->drop_temporary)
2479  flags= 0;
2480  else
2481  flags= sp_head::HAS_COMMIT_OR_ROLLBACK;
2482  break;
2483  case SQLCOM_FLUSH:
2484  flags= sp_head::HAS_SQLCOM_FLUSH;
2485  break;
2486  case SQLCOM_RESET:
2487  flags= sp_head::HAS_SQLCOM_RESET;
2488  break;
2489  case SQLCOM_CREATE_INDEX:
2490  case SQLCOM_CREATE_DB:
2491  case SQLCOM_CREATE_VIEW:
2492  case SQLCOM_CREATE_TRIGGER:
2493  case SQLCOM_CREATE_USER:
2494  case SQLCOM_ALTER_TABLE:
2495  case SQLCOM_GRANT:
2496  case SQLCOM_REVOKE:
2497  case SQLCOM_BEGIN:
2498  case SQLCOM_RENAME_TABLE:
2499  case SQLCOM_RENAME_USER:
2500  case SQLCOM_DROP_INDEX:
2501  case SQLCOM_DROP_DB:
2502  case SQLCOM_REVOKE_ALL:
2503  case SQLCOM_DROP_USER:
2504  case SQLCOM_DROP_VIEW:
2505  case SQLCOM_DROP_TRIGGER:
2506  case SQLCOM_TRUNCATE:
2507  case SQLCOM_COMMIT:
2508  case SQLCOM_ROLLBACK:
2509  case SQLCOM_LOAD:
2510  case SQLCOM_LOCK_TABLES:
2511  case SQLCOM_CREATE_PROCEDURE:
2512  case SQLCOM_CREATE_SPFUNCTION:
2513  case SQLCOM_ALTER_PROCEDURE:
2514  case SQLCOM_ALTER_FUNCTION:
2515  case SQLCOM_DROP_PROCEDURE:
2516  case SQLCOM_DROP_FUNCTION:
2517  case SQLCOM_CREATE_EVENT:
2518  case SQLCOM_ALTER_EVENT:
2519  case SQLCOM_DROP_EVENT:
2520  case SQLCOM_INSTALL_PLUGIN:
2521  case SQLCOM_UNINSTALL_PLUGIN:
2522  flags= sp_head::HAS_COMMIT_OR_ROLLBACK;
2523  break;
2524  default:
2525  flags= lex->describe ? sp_head::MULTI_RESULTS : 0;
2526  break;
2527  }
2528  return flags;
2529 }
2530 
2531 
2543 bool sp_check_name(LEX_STRING *ident)
2544 {
2545  if (!ident || !ident->str || !ident->str[0] ||
2546  ident->str[ident->length-1] == ' ')
2547  {
2548  my_error(ER_SP_WRONG_NAME, MYF(0), ident->str);
2549  return true;
2550  }
2551 
2552  if (check_string_char_length(ident, "", NAME_CHAR_LEN,
2553  system_charset_info, 1))
2554  {
2555  my_error(ER_TOO_LONG_IDENT, MYF(0), ident->str);
2556  return true;
2557  }
2558 
2559  return false;
2560 }
2561 
2562 
2567 TABLE_LIST *sp_add_to_query_tables(THD *thd, LEX *lex,
2568  const char *db, const char *name,
2569  thr_lock_type locktype,
2570  enum_mdl_type mdl_type)
2571 {
2572  TABLE_LIST *table= (TABLE_LIST *)thd->calloc(sizeof(TABLE_LIST));
2573 
2574  if (!table)
2575  return NULL;
2576 
2577  table->db_length= strlen(db);
2578  table->db= thd->strmake(db, table->db_length);
2579  table->table_name_length= strlen(name);
2580  table->table_name= thd->strmake(name, table->table_name_length);
2581  table->alias= thd->strdup(name);
2582  table->lock_type= locktype;
2583  table->select_lex= lex->current_select;
2584  table->cacheable_table= 1;
2585  table->mdl_request.init(MDL_key::TABLE, table->db, table->table_name,
2586  mdl_type, MDL_TRANSACTION);
2587 
2588  lex->add_to_query_tables(table);
2589 
2590  return table;
2591 }
2592 
2593 
2605 Item *sp_prepare_func_item(THD* thd, Item **it_addr)
2606 {
2607  it_addr= (*it_addr)->this_item_addr(thd, it_addr);
2608 
2609  if (!(*it_addr)->fixed &&
2610  ((*it_addr)->fix_fields(thd, it_addr) ||
2611  (*it_addr)->check_cols(1)))
2612  {
2613  DBUG_PRINT("info", ("fix_fields() failed"));
2614  return NULL;
2615  }
2616 
2617  return *it_addr;
2618 }
2619 
2620 
2633 bool sp_eval_expr(THD *thd, Field *result_field, Item **expr_item_ptr)
2634 {
2635  Item *expr_item;
2636  enum_check_fields save_count_cuted_fields= thd->count_cuted_fields;
2637  bool save_abort_on_warning= thd->abort_on_warning;
2638  unsigned int stmt_unsafe_rollback_flags=
2639  thd->transaction.stmt.get_unsafe_rollback_flags();
2640 
2641  if (!*expr_item_ptr)
2642  goto error;
2643 
2644  if (!(expr_item= sp_prepare_func_item(thd, expr_item_ptr)))
2645  goto error;
2646 
2647  /*
2648  Set THD flags to emit warnings/errors in case of overflow/type errors
2649  during saving the item into the field.
2650 
2651  Save original values and restore them after save.
2652  */
2653 
2654  thd->count_cuted_fields= CHECK_FIELD_ERROR_FOR_NULL;
2655  thd->abort_on_warning= thd->is_strict_mode();
2656  thd->transaction.stmt.reset_unsafe_rollback_flags();
2657 
2658  /* Save the value in the field. Convert the value if needed. */
2659 
2660  expr_item->save_in_field(result_field, 0);
2661 
2662  thd->count_cuted_fields= save_count_cuted_fields;
2663  thd->abort_on_warning= save_abort_on_warning;
2664  thd->transaction.stmt.set_unsafe_rollback_flags(stmt_unsafe_rollback_flags);
2665 
2666  if (!thd->is_error())
2667  return false;
2668 
2669 error:
2670  /*
2671  In case of error during evaluation, leave the result field set to NULL.
2672  Sic: we can't do it in the beginning of the function because the
2673  result field might be needed for its own re-evaluation, e.g. case of
2674  set x = x + 1;
2675  */
2676  result_field->set_null();
2677  return true;
2678 }
2679 
2680 
2694 String *sp_get_item_value(THD *thd, Item *item, String *str)
2695 {
2696  switch (item->result_type()) {
2697  case REAL_RESULT:
2698  case INT_RESULT:
2699  case DECIMAL_RESULT:
2700  if (item->field_type() != MYSQL_TYPE_BIT)
2701  return item->val_str(str);
2702  else {/* Bit type is handled as binary string */}
2703  case STRING_RESULT:
2704  {
2705  String *result= item->val_str(str);
2706 
2707  if (!result)
2708  return NULL;
2709 
2710  {
2711  char buf_holder[STRING_BUFFER_USUAL_SIZE];
2712  String buf(buf_holder, sizeof(buf_holder), result->charset());
2713  const CHARSET_INFO *cs= thd->variables.character_set_client;
2714 
2715  /* We must reset length of the buffer, because of String specificity. */
2716  buf.length(0);
2717 
2718  buf.append('_');
2719  buf.append(result->charset()->csname);
2720  if (cs->escape_with_backslash_is_dangerous)
2721  buf.append(' ');
2722  append_query_string(thd, cs, result, &buf);
2723  buf.append(" COLLATE '");
2724  buf.append(item->collation.collation->name);
2725  buf.append('\'');
2726  str->copy(buf);
2727 
2728  return str;
2729  }
2730  }
2731 
2732  case ROW_RESULT:
2733  default:
2734  return NULL;
2735  }
2736 }