1
/* Copyright (C) 2002 MySQL AB
3
This program is free software; you can redistribute it and/or modify
4
it under the terms of the GNU General Public License as published by
5
the Free Software Foundation; version 2 of the License.
7
This program is distributed in the hope that it will be useful,
8
but WITHOUT ANY WARRANTY; without even the implied warranty of
9
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10
GNU General Public License for more details.
12
You should have received a copy of the GNU General Public License
13
along with this program; if not, write to the Free Software
14
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
16
#include "mysql_priv.h"
20
#include "sql_trigger.h"
25
create_string(THD *thd, String *buf,
27
const char *db, ulong dblen,
28
const char *name, ulong namelen,
29
const char *params, ulong paramslen,
30
const char *returns, ulong returnslen,
31
const char *body, ulong bodylen,
32
st_sp_chistics *chistics,
33
const LEX_STRING *definer_user,
34
const LEX_STRING *definer_host);
36
db_load_routine(THD *thd, int type, sp_name *name, sp_head **sphp,
37
ulong sql_mode, const char *params, const char *returns,
38
const char *body, st_sp_chistics &chistics,
39
const char *definer, longlong created, longlong modified,
40
Stored_program_creation_ctx *creation_ctx);
44
* DB storage of Stored PROCEDUREs and FUNCTIONs
50
MYSQL_PROC_FIELD_DB = 0,
51
MYSQL_PROC_FIELD_NAME,
52
MYSQL_PROC_MYSQL_TYPE,
53
MYSQL_PROC_FIELD_SPECIFIC_NAME,
54
MYSQL_PROC_FIELD_LANGUAGE,
55
MYSQL_PROC_FIELD_ACCESS,
56
MYSQL_PROC_FIELD_DETERMINISTIC,
57
MYSQL_PROC_FIELD_SECURITY_TYPE,
58
MYSQL_PROC_FIELD_PARAM_LIST,
59
MYSQL_PROC_FIELD_RETURNS,
60
MYSQL_PROC_FIELD_BODY,
61
MYSQL_PROC_FIELD_DEFINER,
62
MYSQL_PROC_FIELD_CREATED,
63
MYSQL_PROC_FIELD_MODIFIED,
64
MYSQL_PROC_FIELD_SQL_MODE,
65
MYSQL_PROC_FIELD_COMMENT,
66
MYSQL_PROC_FIELD_CHARACTER_SET_CLIENT,
67
MYSQL_PROC_FIELD_COLLATION_CONNECTION,
68
MYSQL_PROC_FIELD_DB_COLLATION,
69
MYSQL_PROC_FIELD_BODY_UTF8,
70
MYSQL_PROC_FIELD_COUNT
74
TABLE_FIELD_TYPE proc_table_fields[MYSQL_PROC_FIELD_COUNT] =
77
{ C_STRING_WITH_LEN("db") },
78
{ C_STRING_WITH_LEN("char(64)") },
79
{ C_STRING_WITH_LEN("utf8") }
82
{ C_STRING_WITH_LEN("name") },
83
{ C_STRING_WITH_LEN("char(64)") },
84
{ C_STRING_WITH_LEN("utf8") }
87
{ C_STRING_WITH_LEN("type") },
88
{ C_STRING_WITH_LEN("enum('FUNCTION','PROCEDURE')") },
92
{ C_STRING_WITH_LEN("specific_name") },
93
{ C_STRING_WITH_LEN("char(64)") },
94
{ C_STRING_WITH_LEN("utf8") }
97
{ C_STRING_WITH_LEN("language") },
98
{ C_STRING_WITH_LEN("enum('SQL')") },
102
{ C_STRING_WITH_LEN("sql_data_access") },
103
{ C_STRING_WITH_LEN("enum('CONTAINS_SQL','NO_SQL','READS_SQL_DATA','MODIFIES_SQL_DATA')") },
107
{ C_STRING_WITH_LEN("is_deterministic") },
108
{ C_STRING_WITH_LEN("enum('YES','NO')") },
112
{ C_STRING_WITH_LEN("security_type") },
113
{ C_STRING_WITH_LEN("enum('INVOKER','DEFINER')") },
117
{ C_STRING_WITH_LEN("param_list") },
118
{ C_STRING_WITH_LEN("blob") },
123
{ C_STRING_WITH_LEN("returns") },
124
{ C_STRING_WITH_LEN("longblob") },
128
{ C_STRING_WITH_LEN("body") },
129
{ C_STRING_WITH_LEN("longblob") },
133
{ C_STRING_WITH_LEN("definer") },
134
{ C_STRING_WITH_LEN("char(77)") },
135
{ C_STRING_WITH_LEN("utf8") }
138
{ C_STRING_WITH_LEN("created") },
139
{ C_STRING_WITH_LEN("timestamp") },
143
{ C_STRING_WITH_LEN("modified") },
144
{ C_STRING_WITH_LEN("timestamp") },
148
{ C_STRING_WITH_LEN("sql_mode") },
149
{ C_STRING_WITH_LEN("set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES',"
150
"'IGNORE_SPACE','NOT_USED','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION',"
151
"'NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB',"
152
"'NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40',"
153
"'ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES',"
154
"'STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES',"
155
"'ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER',"
156
"'HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH')") },
160
{ C_STRING_WITH_LEN("comment") },
161
{ C_STRING_WITH_LEN("char(64)") },
162
{ C_STRING_WITH_LEN("utf8") }
165
{ C_STRING_WITH_LEN("character_set_client") },
166
{ C_STRING_WITH_LEN("char(32)") },
167
{ C_STRING_WITH_LEN("utf8") }
170
{ C_STRING_WITH_LEN("collation_connection") },
171
{ C_STRING_WITH_LEN("char(32)") },
172
{ C_STRING_WITH_LEN("utf8") }
175
{ C_STRING_WITH_LEN("db_collation") },
176
{ C_STRING_WITH_LEN("char(32)") },
177
{ C_STRING_WITH_LEN("utf8") }
180
{ C_STRING_WITH_LEN("body_utf8") },
181
{ C_STRING_WITH_LEN("longblob") },
186
static const TABLE_FIELD_DEF
187
proc_table_def= {MYSQL_PROC_FIELD_COUNT, proc_table_fields};
189
/*************************************************************************/
192
Stored_routine_creation_ctx -- creation context of stored routines
193
(stored procedures and functions).
196
class Stored_routine_creation_ctx : public Stored_program_creation_ctx,
200
static Stored_routine_creation_ctx *
201
load_from_db(THD *thd, const sp_name *name, TABLE *proc_tbl);
204
virtual Stored_program_creation_ctx *clone(MEM_ROOT *mem_root)
206
return new (mem_root) Stored_routine_creation_ctx(m_client_cs,
212
virtual Object_creation_ctx *create_backup_ctx(THD *thd) const
214
DBUG_ENTER("Stored_routine_creation_ctx::create_backup_ctx");
215
DBUG_RETURN(new Stored_routine_creation_ctx(thd));
219
Stored_routine_creation_ctx(THD *thd)
220
: Stored_program_creation_ctx(thd)
223
Stored_routine_creation_ctx(CHARSET_INFO *client_cs,
224
CHARSET_INFO *connection_cl,
226
: Stored_program_creation_ctx(client_cs, connection_cl, db_cl)
230
/**************************************************************************
231
Stored_routine_creation_ctx implementation.
232
**************************************************************************/
234
bool load_charset(MEM_ROOT *mem_root,
236
CHARSET_INFO *dflt_cs,
241
if (get_field(mem_root, field, &cs_name))
247
*cs= get_charset_by_csname(cs_name.c_ptr(), MY_CS_PRIMARY, MYF(0));
258
/*************************************************************************/
260
bool load_collation(MEM_ROOT *mem_root,
262
CHARSET_INFO *dflt_cl,
267
if (get_field(mem_root, field, &cl_name))
273
*cl= get_charset_by_name(cl_name.c_ptr(), MYF(0));
284
/*************************************************************************/
286
Stored_routine_creation_ctx *
287
Stored_routine_creation_ctx::load_from_db(THD *thd,
291
/* Load character set/collation attributes. */
293
CHARSET_INFO *client_cs;
294
CHARSET_INFO *connection_cl;
297
const char *db_name= thd->strmake(name->m_db.str, name->m_db.length);
298
const char *sr_name= thd->strmake(name->m_name.str, name->m_name.length);
300
bool invalid_creation_ctx= FALSE;
302
if (load_charset(thd->mem_root,
303
proc_tbl->field[MYSQL_PROC_FIELD_CHARACTER_SET_CLIENT],
304
thd->variables.character_set_client,
307
sql_print_warning("Stored routine '%s'.'%s': invalid value "
308
"in column mysql.proc.character_set_client.",
309
(const char *) db_name,
310
(const char *) sr_name);
312
invalid_creation_ctx= TRUE;
315
if (load_collation(thd->mem_root,
316
proc_tbl->field[MYSQL_PROC_FIELD_COLLATION_CONNECTION],
317
thd->variables.collation_connection,
320
sql_print_warning("Stored routine '%s'.'%s': invalid value "
321
"in column mysql.proc.collation_connection.",
322
(const char *) db_name,
323
(const char *) sr_name);
325
invalid_creation_ctx= TRUE;
328
if (load_collation(thd->mem_root,
329
proc_tbl->field[MYSQL_PROC_FIELD_DB_COLLATION],
333
sql_print_warning("Stored routine '%s'.'%s': invalid value "
334
"in column mysql.proc.db_collation.",
335
(const char *) db_name,
336
(const char *) sr_name);
338
invalid_creation_ctx= TRUE;
341
if (invalid_creation_ctx)
343
push_warning_printf(thd,
344
MYSQL_ERROR::WARN_LEVEL_WARN,
345
ER_SR_INVALID_CREATION_CTX,
346
ER(ER_SR_INVALID_CREATION_CTX),
347
(const char *) db_name,
348
(const char *) sr_name);
352
If we failed to retrieve the database collation, load the default one
357
db_cl= get_default_db_collation(thd, name->m_db.str);
359
/* Create the context. */
361
return new Stored_routine_creation_ctx(client_cs, connection_cl, db_cl);
364
/*************************************************************************/
366
class Proc_table_intact : public Table_check_intact
372
Proc_table_intact() : m_print_once(TRUE) {}
375
void report_error(uint code, const char *fmt, ...);
380
Report failure to validate the mysql.proc table definition.
381
Print a message to the error log only once.
384
void Proc_table_intact::report_error(uint code, const char *fmt, ...)
390
my_vsnprintf(buf, sizeof(buf), fmt, args);
394
my_message(code, buf, MYF(0));
396
my_error(ER_CANNOT_LOAD_FROM_TABLE, MYF(0), "proc");
401
sql_print_error("%s", buf);
406
/** Single instance used to control printing to the error log. */
407
static Proc_table_intact proc_table_intact;
411
Open the mysql.proc table for read.
413
@param thd Thread context
414
@param backup Pointer to Open_tables_state instance where information about
415
currently open tables will be saved, and from which will be
416
restored when we will end work with mysql.proc.
421
\# Pointer to TABLE object of mysql.proc
424
TABLE *open_proc_table_for_read(THD *thd, Open_tables_state *backup)
426
DBUG_ENTER("open_proc_table_for_read");
429
table.init_one_table("mysql", "proc", TL_READ);
431
if (open_system_tables_for_read(thd, &table, backup))
434
if (!proc_table_intact.check(table.table, &proc_table_def))
435
DBUG_RETURN(table.table);
437
close_system_tables(thd, backup);
444
Open the mysql.proc table for update.
446
@param thd Thread context
449
Table opened with this call should closed using close_thread_tables().
454
\# Pointer to TABLE object of mysql.proc
457
static TABLE *open_proc_table_for_update(THD *thd)
459
DBUG_ENTER("open_proc_table_for_update");
462
TABLE_LIST table_list;
463
table_list.init_one_table("mysql", "proc", TL_WRITE);
465
if (!(table= open_system_table_for_update(thd, &table_list)))
468
if (!proc_table_intact.check(table, &proc_table_def))
471
close_thread_tables(thd);
478
Find row in open mysql.proc table representing stored routine.
480
@param thd Thread context
481
@param type Type of routine to find (function or procedure)
482
@param name Name of routine
483
@param table TABLE object for open mysql.proc table.
488
SP_KEY_NOT_FOUND No routine with given name
492
db_find_routine_aux(THD *thd, int type, sp_name *name, TABLE *table)
494
uchar key[MAX_KEY_LENGTH]; // db, name, optional key length type
495
DBUG_ENTER("db_find_routine_aux");
496
DBUG_PRINT("enter", ("type: %d name: %.*s",
497
type, (int) name->m_name.length, name->m_name.str));
500
Create key to find row. We have to use field->store() to be able to
501
handle VARCHAR and CHAR fields.
502
Assumption here is that the three first fields in the table are
503
'db', 'name' and 'type' and the first key is the primary key over the
506
if (name->m_name.length > table->field[1]->field_length)
507
DBUG_RETURN(SP_KEY_NOT_FOUND);
508
table->field[0]->store(name->m_db.str, name->m_db.length, &my_charset_bin);
509
table->field[1]->store(name->m_name.str, name->m_name.length,
511
table->field[2]->store((longlong) type, TRUE);
512
key_copy(key, table->record[0], table->key_info,
513
table->key_info->key_length);
515
if (table->file->index_read_idx_map(table->record[0], 0, key, HA_WHOLE_KEY,
517
DBUG_RETURN(SP_KEY_NOT_FOUND);
524
Find routine definition in mysql.proc table and create corresponding
525
sp_head object for it.
527
@param thd Thread context
528
@param type Type of routine (TYPE_ENUM_PROCEDURE/...)
529
@param name Name of routine
530
@param sphp Out parameter in which pointer to created sp_head
531
object is returned (0 in case of error).
534
This function may damage current LEX during execution, so it is good
535
idea to create temporary LEX and make it active before calling it.
540
non-0 Error (may be one of special codes like SP_KEY_NOT_FOUND)
544
db_find_routine(THD *thd, int type, sp_name *name, sp_head **sphp)
547
const char *params, *returns, *body;
552
st_sp_chistics chistics;
556
String str(buff, sizeof(buff), &my_charset_bin);
557
bool saved_time_zone_used= thd->time_zone_used;
558
ulong sql_mode, saved_mode= thd->variables.sql_mode;
559
Open_tables_state open_tables_state_backup;
560
Stored_program_creation_ctx *creation_ctx;
562
DBUG_ENTER("db_find_routine");
563
DBUG_PRINT("enter", ("type: %d name: %.*s",
564
type, (int) name->m_name.length, name->m_name.str));
566
*sphp= 0; // In case of errors
567
if (!(table= open_proc_table_for_read(thd, &open_tables_state_backup)))
568
DBUG_RETURN(SP_OPEN_TABLE_FAILED);
570
/* Reset sql_mode during data dictionary operations. */
571
thd->variables.sql_mode= 0;
573
if ((ret= db_find_routine_aux(thd, type, name, table)) != SP_OK)
576
if (table->s->fields < MYSQL_PROC_FIELD_COUNT)
578
ret= SP_GET_FIELD_FAILED;
582
bzero((char *)&chistics, sizeof(chistics));
583
if ((ptr= get_field(thd->mem_root,
584
table->field[MYSQL_PROC_FIELD_ACCESS])) == NULL)
586
ret= SP_GET_FIELD_FAILED;
591
chistics.daccess= SP_NO_SQL;
594
chistics.daccess= SP_CONTAINS_SQL;
597
chistics.daccess= SP_READS_SQL_DATA;
600
chistics.daccess= SP_MODIFIES_SQL_DATA;
603
chistics.daccess= SP_DEFAULT_ACCESS_MAPPING;
606
if ((ptr= get_field(thd->mem_root,
607
table->field[MYSQL_PROC_FIELD_DETERMINISTIC])) == NULL)
609
ret= SP_GET_FIELD_FAILED;
612
chistics.detistic= (ptr[0] == 'N' ? FALSE : TRUE);
614
if ((ptr= get_field(thd->mem_root,
615
table->field[MYSQL_PROC_FIELD_SECURITY_TYPE])) == NULL)
617
ret= SP_GET_FIELD_FAILED;
620
chistics.suid= (ptr[0] == 'I' ? SP_IS_NOT_SUID : SP_IS_SUID);
622
if ((params= get_field(thd->mem_root,
623
table->field[MYSQL_PROC_FIELD_PARAM_LIST])) == NULL)
628
if (type == TYPE_ENUM_PROCEDURE)
630
else if ((returns= get_field(thd->mem_root,
631
table->field[MYSQL_PROC_FIELD_RETURNS])) == NULL)
633
ret= SP_GET_FIELD_FAILED;
637
if ((body= get_field(thd->mem_root,
638
table->field[MYSQL_PROC_FIELD_BODY])) == NULL)
640
ret= SP_GET_FIELD_FAILED;
644
// Get additional information
645
if ((definer= get_field(thd->mem_root,
646
table->field[MYSQL_PROC_FIELD_DEFINER])) == NULL)
648
ret= SP_GET_FIELD_FAILED;
652
modified= table->field[MYSQL_PROC_FIELD_MODIFIED]->val_int();
653
created= table->field[MYSQL_PROC_FIELD_CREATED]->val_int();
655
sql_mode= (ulong) table->field[MYSQL_PROC_FIELD_SQL_MODE]->val_int();
657
table->field[MYSQL_PROC_FIELD_COMMENT]->val_str(&str, &str);
660
if ((length= str.length()))
661
ptr= thd->strmake(str.ptr(), length);
662
chistics.comment.str= ptr;
663
chistics.comment.length= length;
665
creation_ctx= Stored_routine_creation_ctx::load_from_db(thd, name, table);
667
close_system_tables(thd, &open_tables_state_backup);
670
ret= db_load_routine(thd, type, name, sphp,
671
sql_mode, params, returns, body, chistics,
672
definer, created, modified, creation_ctx);
675
Restore the time zone flag as the timezone usage in proc table
676
does not affect replication.
678
thd->time_zone_used= saved_time_zone_used;
680
close_system_tables(thd, &open_tables_state_backup);
681
thd->variables.sql_mode= saved_mode;
687
Silence DEPRECATED SYNTAX warnings when loading a stored procedure
690
struct Silence_deprecated_warning : public Internal_error_handler
693
virtual bool handle_error(uint sql_errno, const char *message,
694
MYSQL_ERROR::enum_warning_level level,
699
Silence_deprecated_warning::handle_error(uint sql_errno, const char *message,
700
MYSQL_ERROR::enum_warning_level level,
703
if (sql_errno == ER_WARN_DEPRECATED_SYNTAX &&
704
level == MYSQL_ERROR::WARN_LEVEL_WARN)
712
db_load_routine(THD *thd, int type, sp_name *name, sp_head **sphp,
713
ulong sql_mode, const char *params, const char *returns,
714
const char *body, st_sp_chistics &chistics,
715
const char *definer, longlong created, longlong modified,
716
Stored_program_creation_ctx *creation_ctx)
718
LEX *old_lex= thd->lex, newlex;
720
char saved_cur_db_name_buf[NAME_LEN+1];
721
LEX_STRING saved_cur_db_name=
722
{ saved_cur_db_name_buf, sizeof(saved_cur_db_name_buf) };
724
ulong old_sql_mode= thd->variables.sql_mode;
725
ha_rows old_select_limit= thd->variables.select_limit;
726
sp_rcontext *old_spcont= thd->spcont;
727
Silence_deprecated_warning warning_handler;
729
char definer_user_name_holder[USERNAME_LENGTH + 1];
730
LEX_STRING definer_user_name= { definer_user_name_holder,
733
char definer_host_name_holder[HOSTNAME_LENGTH + 1];
734
LEX_STRING definer_host_name= { definer_host_name_holder, HOSTNAME_LENGTH };
738
thd->variables.sql_mode= sql_mode;
739
thd->variables.select_limit= HA_POS_ERROR;
742
newlex.current_select= NULL;
744
parse_user(definer, strlen(definer),
745
definer_user_name.str, &definer_user_name.length,
746
definer_host_name.str, &definer_host_name.length);
748
defstr.set_charset(creation_ctx->get_client_cs());
751
We have to add DEFINER clause and provide proper routine characterstics in
752
routine definition statement that we build here to be able to use this
753
definition for SHOW CREATE PROCEDURE later.
756
if (!create_string(thd, &defstr,
759
name->m_name.str, name->m_name.length,
760
params, strlen(params),
761
returns, strlen(returns),
763
&chistics, &definer_user_name, &definer_host_name))
765
ret= SP_INTERNAL_ERROR;
770
Change the current database (if needed).
772
TODO: why do we force switch here?
775
if (mysql_opt_change_db(thd, &name->m_db, &saved_cur_db_name, TRUE,
778
ret= SP_INTERNAL_ERROR;
785
Parser_state parser_state(thd, defstr.c_ptr(), defstr.length());
789
thd->push_internal_handler(&warning_handler);
790
ret= parse_sql(thd, & parser_state, creation_ctx) || newlex.sphead == NULL;
791
thd->pop_internal_handler();
794
Force switching back to the saved current database (if changed),
795
because it may be NULL. In this case, mysql_change_db() would
799
if (cur_db_changed && mysql_change_db(thd, &saved_cur_db_name, TRUE))
801
delete newlex.sphead;
802
ret= SP_INTERNAL_ERROR;
808
delete newlex.sphead;
813
*sphp= newlex.sphead;
814
(*sphp)->set_definer(&definer_user_name, &definer_host_name);
815
(*sphp)->set_info(created, modified, &chistics, sql_mode);
816
(*sphp)->set_creation_ctx(creation_ctx);
819
Not strictly necessary to invoke this method here, since we know
820
that we've parsed CREATE PROCEDURE/FUNCTION and not an
821
UPDATE/DELETE/INSERT/REPLACE/LOAD/CREATE TABLE, but we try to
822
maintain the invariant that this method is called for each
823
distinct statement, in case its logic is extended with other
824
types of analyses in future.
826
newlex.set_trg_event_type_for_tables();
831
thd->spcont= old_spcont;
832
thd->variables.sql_mode= old_sql_mode;
833
thd->variables.select_limit= old_select_limit;
840
sp_returns_type(THD *thd, String &result, sp_head *sp)
845
bzero((char*) &table, sizeof(table));
846
bzero((char*) &share, sizeof(share));
849
field= sp->create_result_field(0, 0, &table);
850
field->sql_type(result);
852
if (field->has_charset())
854
result.append(STRING_WITH_LEN(" CHARSET "));
855
result.append(field->charset()->csname);
863
Write stored-routine object into mysql.proc.
865
This operation stores attributes of the stored procedure/function into
868
@param thd Thread context.
869
@param type Stored routine type
870
(TYPE_ENUM_PROCEDURE or TYPE_ENUM_FUNCTION).
871
@param sp Stored routine object to store.
873
@note Opens and closes the thread tables. Therefore assumes
874
that there are no locked tables in this thread at the time of
876
Unlike some other DDL statements, *does* close the tables
877
in the end, since the call to this function is normally
878
followed by an implicit grant (sp_grant_privileges())
879
and this subsequent call opens and closes mysql.procs_priv.
881
@return Error code. SP_OK is returned on success. Other
882
SP_ constants are used to indicate about errors.
886
sp_create_routine(THD *thd, int type, sp_head *sp)
890
char definer[USER_HOST_BUFF_SIZE];
891
ulong saved_mode= thd->variables.sql_mode;
893
CHARSET_INFO *db_cs= get_default_db_collation(thd, sp->m_db.str);
895
enum_check_fields saved_count_cuted_fields;
897
bool store_failed= FALSE;
899
bool save_binlog_row_based;
901
DBUG_ENTER("sp_create_routine");
902
DBUG_PRINT("enter", ("type: %d name: %.*s",type, (int) sp->m_name.length,
905
retstr.set_charset(system_charset_info);
907
DBUG_ASSERT(type == TYPE_ENUM_PROCEDURE ||
908
type == TYPE_ENUM_FUNCTION);
910
/* Reset sql_mode during data dictionary operations. */
911
thd->variables.sql_mode= 0;
914
This statement will be replicated as a statement, even when using
915
row-based replication. The flag will be reset at the end of the
918
save_binlog_row_based= thd->current_stmt_binlog_row_based;
919
thd->clear_current_stmt_binlog_row_based();
921
saved_count_cuted_fields= thd->count_cuted_fields;
922
thd->count_cuted_fields= CHECK_FIELD_WARN;
924
if (!(table= open_proc_table_for_update(thd)))
925
ret= SP_OPEN_TABLE_FAILED;
928
restore_record(table, s->default_values); // Get default values for fields
930
/* NOTE: all needed privilege checks have been already done. */
931
strxnmov(definer, sizeof(definer)-1, thd->lex->definer->user.str, "@",
932
thd->lex->definer->host.str, NullS);
934
if (table->s->fields < MYSQL_PROC_FIELD_COUNT)
936
ret= SP_GET_FIELD_FAILED;
940
if (system_charset_info->cset->numchars(system_charset_info,
942
sp->m_name.str+sp->m_name.length) >
943
table->field[MYSQL_PROC_FIELD_NAME]->char_length())
945
ret= SP_BAD_IDENTIFIER;
948
if (sp->m_body.length > table->field[MYSQL_PROC_FIELD_BODY]->field_length)
950
ret= SP_BODY_TOO_LONG;
955
table->field[MYSQL_PROC_FIELD_DB]->
956
store(sp->m_db.str, sp->m_db.length, system_charset_info);
958
store_failed= store_failed ||
959
table->field[MYSQL_PROC_FIELD_NAME]->
960
store(sp->m_name.str, sp->m_name.length, system_charset_info);
962
store_failed= store_failed ||
963
table->field[MYSQL_PROC_MYSQL_TYPE]->
964
store((longlong)type, TRUE);
966
store_failed= store_failed ||
967
table->field[MYSQL_PROC_FIELD_SPECIFIC_NAME]->
968
store(sp->m_name.str, sp->m_name.length, system_charset_info);
970
if (sp->m_chistics->daccess != SP_DEFAULT_ACCESS)
972
store_failed= store_failed ||
973
table->field[MYSQL_PROC_FIELD_ACCESS]->
974
store((longlong)sp->m_chistics->daccess, TRUE);
977
store_failed= store_failed ||
978
table->field[MYSQL_PROC_FIELD_DETERMINISTIC]->
979
store((longlong)(sp->m_chistics->detistic ? 1 : 2), TRUE);
981
if (sp->m_chistics->suid != SP_IS_DEFAULT_SUID)
983
store_failed= store_failed ||
984
table->field[MYSQL_PROC_FIELD_SECURITY_TYPE]->
985
store((longlong)sp->m_chistics->suid, TRUE);
988
store_failed= store_failed ||
989
table->field[MYSQL_PROC_FIELD_PARAM_LIST]->
990
store(sp->m_params.str, sp->m_params.length, system_charset_info);
992
if (sp->m_type == TYPE_ENUM_FUNCTION)
994
sp_returns_type(thd, retstr, sp);
996
store_failed= store_failed ||
997
table->field[MYSQL_PROC_FIELD_RETURNS]->
998
store(retstr.ptr(), retstr.length(), system_charset_info);
1001
store_failed= store_failed ||
1002
table->field[MYSQL_PROC_FIELD_BODY]->
1003
store(sp->m_body.str, sp->m_body.length, system_charset_info);
1005
store_failed= store_failed ||
1006
table->field[MYSQL_PROC_FIELD_DEFINER]->
1007
store(definer, (uint)strlen(definer), system_charset_info);
1009
((Field_timestamp *)table->field[MYSQL_PROC_FIELD_CREATED])->set_time();
1010
((Field_timestamp *)table->field[MYSQL_PROC_FIELD_MODIFIED])->set_time();
1012
store_failed= store_failed ||
1013
table->field[MYSQL_PROC_FIELD_SQL_MODE]->
1014
store((longlong)saved_mode, TRUE);
1016
if (sp->m_chistics->comment.str)
1018
store_failed= store_failed ||
1019
table->field[MYSQL_PROC_FIELD_COMMENT]->
1020
store(sp->m_chistics->comment.str, sp->m_chistics->comment.length,
1021
system_charset_info);
1024
if ((sp->m_type == TYPE_ENUM_FUNCTION) &&
1025
!trust_function_creators && mysql_bin_log.is_open())
1027
if (!sp->m_chistics->detistic)
1030
Note that this test is not perfect; one could use
1031
a non-deterministic read-only function in an update statement.
1033
enum enum_sp_data_access access=
1034
(sp->m_chistics->daccess == SP_DEFAULT_ACCESS) ?
1035
SP_DEFAULT_ACCESS_MAPPING : sp->m_chistics->daccess;
1036
if (access == SP_CONTAINS_SQL ||
1037
access == SP_MODIFIES_SQL_DATA)
1039
my_message(ER_BINLOG_UNSAFE_ROUTINE,
1040
ER(ER_BINLOG_UNSAFE_ROUTINE), MYF(0));
1041
ret= SP_INTERNAL_ERROR;
1045
if (!(thd->security_ctx->master_access & SUPER_ACL))
1047
my_message(ER_BINLOG_CREATE_ROUTINE_NEED_SUPER,
1048
ER(ER_BINLOG_CREATE_ROUTINE_NEED_SUPER), MYF(0));
1049
ret= SP_INTERNAL_ERROR;
1054
table->field[MYSQL_PROC_FIELD_CHARACTER_SET_CLIENT]->set_notnull();
1055
store_failed= store_failed ||
1056
table->field[MYSQL_PROC_FIELD_CHARACTER_SET_CLIENT]->store(
1057
thd->charset()->csname,
1058
strlen(thd->charset()->csname),
1059
system_charset_info);
1061
table->field[MYSQL_PROC_FIELD_COLLATION_CONNECTION]->set_notnull();
1062
store_failed= store_failed ||
1063
table->field[MYSQL_PROC_FIELD_COLLATION_CONNECTION]->store(
1064
thd->variables.collation_connection->name,
1065
strlen(thd->variables.collation_connection->name),
1066
system_charset_info);
1068
table->field[MYSQL_PROC_FIELD_DB_COLLATION]->set_notnull();
1069
store_failed= store_failed ||
1070
table->field[MYSQL_PROC_FIELD_DB_COLLATION]->store(
1071
db_cs->name, strlen(db_cs->name), system_charset_info);
1073
table->field[MYSQL_PROC_FIELD_BODY_UTF8]->set_notnull();
1074
store_failed= store_failed ||
1075
table->field[MYSQL_PROC_FIELD_BODY_UTF8]->store(
1076
sp->m_body_utf8.str, sp->m_body_utf8.length, system_charset_info);
1080
ret= SP_FLD_STORE_FAILED;
1085
if (table->file->ha_write_row(table->record[0]))
1086
ret= SP_WRITE_ROW_FAILED;
1087
else if (mysql_bin_log.is_open())
1092
log_query.set_charset(system_charset_info);
1094
if (!create_string(thd, &log_query,
1096
(sp->m_explicit_name ? sp->m_db.str : NULL),
1097
(sp->m_explicit_name ? sp->m_db.length : 0),
1098
sp->m_name.str, sp->m_name.length,
1099
sp->m_params.str, sp->m_params.length,
1100
retstr.c_ptr(), retstr.length(),
1101
sp->m_body.str, sp->m_body.length,
1102
sp->m_chistics, &(thd->lex->definer->user),
1103
&(thd->lex->definer->host)))
1105
ret= SP_INTERNAL_ERROR;
1108
/* restore sql_mode when binloging */
1109
thd->variables.sql_mode= saved_mode;
1110
/* Such a statement can always go directly to binlog, no trans cache */
1111
if (thd->binlog_query(THD::MYSQL_QUERY_TYPE,
1112
log_query.c_ptr(), log_query.length(),
1114
ret= SP_INTERNAL_ERROR;
1115
thd->variables.sql_mode= 0;
1121
thd->count_cuted_fields= saved_count_cuted_fields;
1122
thd->variables.sql_mode= saved_mode;
1124
close_thread_tables(thd);
1125
/* Restore the state of binlog format */
1126
thd->current_stmt_binlog_row_based= save_binlog_row_based;
1132
Delete the record for the stored routine object from mysql.proc.
1134
The operation deletes the record for the stored routine specified by name
1135
from the mysql.proc table and invalidates the stored-routine cache.
1137
@param thd Thread context.
1138
@param type Stored routine type
1139
(TYPE_ENUM_PROCEDURE or TYPE_ENUM_FUNCTION)
1140
@param name Stored routine name.
1142
@return Error code. SP_OK is returned on success. Other SP_ constants are
1143
used to indicate about errors.
1147
sp_drop_routine(THD *thd, int type, sp_name *name)
1151
bool save_binlog_row_based;
1152
DBUG_ENTER("sp_drop_routine");
1153
DBUG_PRINT("enter", ("type: %d name: %.*s",
1154
type, (int) name->m_name.length, name->m_name.str));
1156
DBUG_ASSERT(type == TYPE_ENUM_PROCEDURE ||
1157
type == TYPE_ENUM_FUNCTION);
1160
This statement will be replicated as a statement, even when using
1161
row-based replication. The flag will be reset at the end of the
1164
save_binlog_row_based= thd->current_stmt_binlog_row_based;
1165
thd->clear_current_stmt_binlog_row_based();
1167
if (!(table= open_proc_table_for_update(thd)))
1168
DBUG_RETURN(SP_OPEN_TABLE_FAILED);
1169
if ((ret= db_find_routine_aux(thd, type, name, table)) == SP_OK)
1171
if (table->file->ha_delete_row(table->record[0]))
1172
ret= SP_DELETE_ROW_FAILED;
1177
if (write_bin_log(thd, TRUE, thd->query(), thd->query_length()))
1178
ret= SP_INTERNAL_ERROR;
1179
sp_cache_invalidate();
1182
close_thread_tables(thd);
1183
/* Restore the state of binlog format */
1184
thd->current_stmt_binlog_row_based= save_binlog_row_based;
1190
Find and updated the record for the stored routine object in mysql.proc.
1192
The operation finds the record for the stored routine specified by name
1193
in the mysql.proc table and updates it with new attributes. After
1194
successful update, the cache is invalidated.
1196
@param thd Thread context.
1197
@param type Stored routine type
1198
(TYPE_ENUM_PROCEDURE or TYPE_ENUM_FUNCTION)
1199
@param name Stored routine name.
1200
@param chistics New values of stored routine attributes to write.
1202
@return Error code. SP_OK is returned on success. Other SP_ constants are
1203
used to indicate about errors.
1207
sp_update_routine(THD *thd, int type, sp_name *name, st_sp_chistics *chistics)
1211
bool save_binlog_row_based;
1212
DBUG_ENTER("sp_update_routine");
1213
DBUG_PRINT("enter", ("type: %d name: %.*s",
1214
type, (int) name->m_name.length, name->m_name.str));
1216
DBUG_ASSERT(type == TYPE_ENUM_PROCEDURE ||
1217
type == TYPE_ENUM_FUNCTION);
1219
This statement will be replicated as a statement, even when using
1220
row-based replication. The flag will be reset at the end of the
1223
save_binlog_row_based= thd->current_stmt_binlog_row_based;
1224
thd->clear_current_stmt_binlog_row_based();
1226
if (!(table= open_proc_table_for_update(thd)))
1227
DBUG_RETURN(SP_OPEN_TABLE_FAILED);
1228
if ((ret= db_find_routine_aux(thd, type, name, table)) == SP_OK)
1230
store_record(table,record[1]);
1231
table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
1232
((Field_timestamp *)table->field[MYSQL_PROC_FIELD_MODIFIED])->set_time();
1233
if (chistics->suid != SP_IS_DEFAULT_SUID)
1234
table->field[MYSQL_PROC_FIELD_SECURITY_TYPE]->
1235
store((longlong)chistics->suid, TRUE);
1236
if (chistics->daccess != SP_DEFAULT_ACCESS)
1237
table->field[MYSQL_PROC_FIELD_ACCESS]->
1238
store((longlong)chistics->daccess, TRUE);
1239
if (chistics->comment.str)
1240
table->field[MYSQL_PROC_FIELD_COMMENT]->store(chistics->comment.str,
1241
chistics->comment.length,
1242
system_charset_info);
1243
if ((ret= table->file->ha_update_row(table->record[1],table->record[0])) &&
1244
ret != HA_ERR_RECORD_IS_THE_SAME)
1245
ret= SP_WRITE_ROW_FAILED;
1252
if (write_bin_log(thd, TRUE, thd->query(), thd->query_length()))
1253
ret= SP_INTERNAL_ERROR;
1254
sp_cache_invalidate();
1257
close_thread_tables(thd);
1258
/* Restore the state of binlog format */
1259
thd->current_stmt_binlog_row_based= save_binlog_row_based;
1265
Drop all routines in database 'db'
1267
@note Close the thread tables, the calling code might want to
1268
delete from other system tables afterwards.
1272
sp_drop_db_routines(THD *thd, char *db)
1277
DBUG_ENTER("sp_drop_db_routines");
1278
DBUG_PRINT("enter", ("db: %s", db));
1280
ret= SP_OPEN_TABLE_FAILED;
1281
if (!(table= open_proc_table_for_update(thd)))
1284
table->field[MYSQL_PROC_FIELD_DB]->store(db, strlen(db), system_charset_info);
1285
key_len= table->key_info->key_part[0].store_length;
1288
table->file->ha_index_init(0, 1);
1289
if (! table->file->index_read_map(table->record[0],
1290
(uchar *)table->field[MYSQL_PROC_FIELD_DB]->ptr,
1291
(key_part_map)1, HA_READ_KEY_EXACT))
1294
bool deleted= FALSE;
1298
if (! table->file->ha_delete_row(table->record[0]))
1299
deleted= TRUE; /* We deleted something */
1302
ret= SP_DELETE_ROW_FAILED;
1306
} while (! (nxtres= table->file->index_next_same(table->record[0],
1307
(uchar *)table->field[MYSQL_PROC_FIELD_DB]->ptr,
1309
if (nxtres != HA_ERR_END_OF_FILE)
1310
ret= SP_KEY_NOT_FOUND;
1312
sp_cache_invalidate();
1314
table->file->ha_index_end();
1316
close_thread_tables(thd);
1324
Implement SHOW CREATE statement for stored routines.
1326
The operation finds the stored routine object specified by name and then
1327
calls sp_head::show_create_routine() for the object.
1329
@param thd Thread context.
1330
@param type Stored routine type
1331
(TYPE_ENUM_PROCEDURE or TYPE_ENUM_FUNCTION)
1332
@param name Stored routine name.
1334
@return Error status.
1335
@retval FALSE on success
1336
@retval TRUE on error
1340
sp_show_create_routine(THD *thd, int type, sp_name *name)
1342
bool err_status= TRUE;
1344
sp_cache **cache = type == TYPE_ENUM_PROCEDURE ?
1345
&thd->sp_proc_cache : &thd->sp_func_cache;
1347
DBUG_ENTER("sp_show_create_routine");
1348
DBUG_PRINT("enter", ("name: %.*s",
1349
(int) name->m_name.length,
1352
DBUG_ASSERT(type == TYPE_ENUM_PROCEDURE ||
1353
type == TYPE_ENUM_FUNCTION);
1355
if (type == TYPE_ENUM_PROCEDURE)
1358
SHOW CREATE PROCEDURE may require two instances of one sp_head
1359
object when SHOW CREATE PROCEDURE is called for the procedure that
1360
is being executed. Basically, there is no actual recursion, so we
1361
increase the recursion limit for this statement (kind of hack).
1363
SHOW CREATE FUNCTION does not require this because SHOW CREATE
1364
statements are prohibitted within stored functions.
1367
thd->variables.max_sp_recursion_depth++;
1370
if ((sp= sp_find_routine(thd, type, name, cache, FALSE)))
1371
err_status= sp->show_create_routine(thd, type);
1373
if (type == TYPE_ENUM_PROCEDURE)
1374
thd->variables.max_sp_recursion_depth--;
1376
DBUG_RETURN(err_status);
1381
Obtain object representing stored procedure/function by its name from
1382
stored procedures cache and looking into mysql.proc if needed.
1384
@param thd thread context
1385
@param type type of object (TYPE_ENUM_FUNCTION or TYPE_ENUM_PROCEDURE)
1386
@param name name of procedure
1387
@param cp hash to look routine in
1388
@param cache_only if true perform cache-only lookup
1389
(Don't look in mysql.proc).
1392
NonNULL pointer to sp_head object for the procedure
1394
NULL in case of error.
1398
sp_find_routine(THD *thd, int type, sp_name *name, sp_cache **cp,
1402
ulong depth= (type == TYPE_ENUM_PROCEDURE ?
1403
thd->variables.max_sp_recursion_depth :
1405
DBUG_ENTER("sp_find_routine");
1406
DBUG_PRINT("enter", ("name: %.*s.%.*s type: %d cache only %d",
1407
(int) name->m_db.length, name->m_db.str,
1408
(int) name->m_name.length, name->m_name.str,
1411
if ((sp= sp_cache_lookup(cp, name)))
1415
const char *returns= "";
1416
char definer[USER_HOST_BUFF_SIZE];
1419
String buffer for RETURNS data type must have system charset;
1420
64 -- size of "returns" column of mysql.proc.
1423
retstr.set_charset(sp->get_creation_ctx()->get_client_cs());
1425
DBUG_PRINT("info", ("found: 0x%lx", (ulong)sp));
1426
if (sp->m_first_free_instance)
1428
DBUG_PRINT("info", ("first free: 0x%lx level: %lu flags %x",
1429
(ulong)sp->m_first_free_instance,
1430
sp->m_first_free_instance->m_recursion_level,
1431
sp->m_first_free_instance->m_flags));
1432
DBUG_ASSERT(!(sp->m_first_free_instance->m_flags & sp_head::IS_INVOKED));
1433
if (sp->m_first_free_instance->m_recursion_level > depth)
1435
sp->recursion_level_error(thd);
1438
DBUG_RETURN(sp->m_first_free_instance);
1441
Actually depth could be +1 than the actual value in case a SP calls
1442
SHOW CREATE PROCEDURE. Hence, the linked list could hold up to one more
1446
level= sp->m_last_cached_sp->m_recursion_level + 1;
1449
sp->recursion_level_error(thd);
1453
strxmov(definer, sp->m_definer_user.str, "@",
1454
sp->m_definer_host.str, NullS);
1455
if (type == TYPE_ENUM_FUNCTION)
1457
sp_returns_type(thd, retstr, sp);
1458
returns= retstr.ptr();
1460
if (db_load_routine(thd, type, name, &new_sp,
1461
sp->m_sql_mode, sp->m_params.str, returns,
1462
sp->m_body.str, *sp->m_chistics, definer,
1463
sp->m_created, sp->m_modified,
1464
sp->get_creation_ctx()) == SP_OK)
1466
sp->m_last_cached_sp->m_next_cached_sp= new_sp;
1467
new_sp->m_recursion_level= level;
1468
new_sp->m_first_instance= sp;
1469
sp->m_last_cached_sp= sp->m_first_free_instance= new_sp;
1470
DBUG_PRINT("info", ("added level: 0x%lx, level: %lu, flags %x",
1471
(ulong)new_sp, new_sp->m_recursion_level,
1473
DBUG_RETURN(new_sp);
1479
if (db_find_routine(thd, type, name, &sp) == SP_OK)
1481
sp_cache_insert(cp, sp);
1482
DBUG_PRINT("info", ("added new: 0x%lx, level: %lu, flags %x",
1483
(ulong)sp, sp->m_recursion_level,
1492
This is used by sql_acl.cc:mysql_routine_grant() and is used to find
1493
the routines in 'routines'.
1495
@param thd Thread handler
1496
@param routines List of needles in the hay stack
1497
@param any Any of the needles are good enough
1500
@retval FALSE Found.
1501
@retval TRUE Not found
1505
sp_exist_routines(THD *thd, TABLE_LIST *routines, bool any)
1507
TABLE_LIST *routine;
1508
bool sp_object_found;
1509
DBUG_ENTER("sp_exists_routine");
1510
for (routine= routines; routine; routine= routine->next_global)
1514
LEX_STRING lex_name;
1515
lex_db.length= strlen(routine->db);
1516
lex_name.length= strlen(routine->table_name);
1517
lex_db.str= thd->strmake(routine->db, lex_db.length);
1518
lex_name.str= thd->strmake(routine->table_name, lex_name.length);
1519
name= new sp_name(lex_db, lex_name, true);
1520
name->init_qname(thd);
1521
sp_object_found= sp_find_routine(thd, TYPE_ENUM_PROCEDURE, name,
1522
&thd->sp_proc_cache, FALSE) != NULL ||
1523
sp_find_routine(thd, TYPE_ENUM_FUNCTION, name,
1524
&thd->sp_func_cache, FALSE) != NULL;
1525
mysql_reset_errors(thd, TRUE);
1526
if (sp_object_found)
1533
my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "FUNCTION or PROCEDURE",
1534
routine->table_name);
1543
Check if a routine exists in the mysql.proc table, without actually
1544
parsing the definition. (Used for dropping).
1546
@param thd thread context
1547
@param name name of procedure
1552
non-0 Error; SP_OPEN_TABLE_FAILED or SP_KEY_NOT_FOUND
1556
sp_routine_exists_in_table(THD *thd, int type, sp_name *name)
1560
Open_tables_state open_tables_state_backup;
1562
if (!(table= open_proc_table_for_read(thd, &open_tables_state_backup)))
1563
ret= SP_OPEN_TABLE_FAILED;
1566
if ((ret= db_find_routine_aux(thd, type, name, table)) != SP_OK)
1567
ret= SP_KEY_NOT_FOUND;
1568
close_system_tables(thd, &open_tables_state_backup);
1575
Structure that represents element in the set of stored routines
1576
used by statement or routine.
1578
struct Sroutine_hash_entry;
1580
struct Sroutine_hash_entry
1583
Set key consisting of one-byte routine type and quoted routine name.
1587
Next element in list linking all routines in set. See also comments
1588
for LEX::sroutine/sroutine_list and sp_head::m_sroutines.
1590
Sroutine_hash_entry *next;
1592
Uppermost view which directly or indirectly uses this routine.
1593
0 if routine is not used in view. Note that it also can be 0 if
1594
statement uses routine both via view and directly.
1596
TABLE_LIST *belong_to_view;
1600
extern "C" uchar* sp_sroutine_key(const uchar *ptr, size_t *plen,
1603
Sroutine_hash_entry *rn= (Sroutine_hash_entry *)ptr;
1604
*plen= rn->key.length;
1605
return (uchar *)rn->key.str;
1611
- current statement (the one in thd->lex) needs table prelocking
1612
- first routine in thd->lex->sroutines_list needs to execute its body in
1615
@param thd Current thread, thd->lex is the statement to be
1617
@param[out] need_prelocking TRUE - prelocked mode should be activated
1618
before executing the statement;
1619
FALSE - Don't activate prelocking
1620
@param[out] first_no_prelocking TRUE - Tables used by first routine in
1621
thd->lex->sroutines_list should be
1622
prelocked. FALSE - Otherwise.
1625
This function assumes that for any "CALL proc(...)" statement routines_list
1626
will have 'proc' as first element (it may have several, consider e.g.
1627
"proc(sp_func(...)))". This property is currently guaranted by the parser.
1630
void sp_get_prelocking_info(THD *thd, bool *need_prelocking,
1631
bool *first_no_prelocking)
1633
Sroutine_hash_entry *routine;
1634
routine= (Sroutine_hash_entry*)thd->lex->sroutines_list.first;
1636
DBUG_ASSERT(routine);
1637
bool first_is_procedure= (routine->key.str[0] == TYPE_ENUM_PROCEDURE);
1639
*first_no_prelocking= first_is_procedure;
1640
*need_prelocking= !first_is_procedure || test(routine->next);
1645
Auxilary function that adds new element to the set of stored routines
1648
In case when statement uses stored routines but does not need
1649
prelocking (i.e. it does not use any tables) we will access the
1650
elements of LEX::sroutines set on prepared statement re-execution.
1651
Because of this we have to allocate memory for both hash element
1652
and copy of its key in persistent arena.
1654
@param lex LEX representing statement
1655
@param arena Arena in which memory for new element will be
1657
@param key Key for the hash representing set
1658
@param belong_to_view Uppermost view which uses this routine
1659
(0 if routine is not used by view)
1662
Will also add element to end of 'LEX::sroutines_list' list.
1665
When we will got rid of these accesses on re-executions we will be
1666
able to allocate memory for hash elements in non-persitent arena
1667
and directly use key values from sp_head::m_sroutines sets instead
1668
of making their copies.
1671
TRUE new element was added.
1673
FALSE element was not added (because it is already present in
1677
static bool add_used_routine(LEX *lex, Query_arena *arena,
1678
const LEX_STRING *key,
1679
TABLE_LIST *belong_to_view)
1681
hash_init_opt(&lex->sroutines, system_charset_info,
1682
Query_tables_list::START_SROUTINES_HASH_SIZE,
1683
0, 0, sp_sroutine_key, 0, 0);
1685
if (!hash_search(&lex->sroutines, (uchar *)key->str, key->length))
1687
Sroutine_hash_entry *rn=
1688
(Sroutine_hash_entry *)arena->alloc(sizeof(Sroutine_hash_entry) +
1690
if (!rn) // OOM. Error will be reported using fatal_error().
1692
rn->key.length= key->length;
1693
rn->key.str= (char *)rn + sizeof(Sroutine_hash_entry);
1694
memcpy(rn->key.str, key->str, key->length + 1);
1695
if (my_hash_insert(&lex->sroutines, (uchar *)rn))
1697
lex->sroutines_list.link_in_list((uchar *)rn, (uchar **)&rn->next);
1698
rn->belong_to_view= belong_to_view;
1706
Add routine which is explicitly used by statement to the set of stored
1707
routines used by this statement.
1709
To be friendly towards prepared statements one should pass
1710
persistent arena as second argument.
1712
@param lex LEX representing statement
1713
@param arena arena in which memory for new element of the set
1715
@param rt routine name
1716
@param rt_type routine type (one of TYPE_ENUM_PROCEDURE/...)
1719
Will also add element to end of 'LEX::sroutines_list' list (and will
1720
take into account that this is explicitly used routine).
1723
void sp_add_used_routine(LEX *lex, Query_arena *arena,
1724
sp_name *rt, char rt_type)
1726
rt->set_routine_type(rt_type);
1727
(void)add_used_routine(lex, arena, &rt->m_sroutines_key, 0);
1728
lex->sroutines_list_own_last= lex->sroutines_list.next;
1729
lex->sroutines_list_own_elements= lex->sroutines_list.elements;
1734
Remove routines which are only indirectly used by statement from
1735
the set of routines used by this statement.
1737
@param lex LEX representing statement
1740
void sp_remove_not_own_routines(LEX *lex)
1742
Sroutine_hash_entry *not_own_rt, *next_rt;
1743
for (not_own_rt= *(Sroutine_hash_entry **)lex->sroutines_list_own_last;
1744
not_own_rt; not_own_rt= next_rt)
1747
It is safe to obtain not_own_rt->next after calling hash_delete() now
1748
but we want to be more future-proof.
1750
next_rt= not_own_rt->next;
1751
hash_delete(&lex->sroutines, (uchar *)not_own_rt);
1754
*(Sroutine_hash_entry **)lex->sroutines_list_own_last= NULL;
1755
lex->sroutines_list.next= lex->sroutines_list_own_last;
1756
lex->sroutines_list.elements= lex->sroutines_list_own_elements;
1761
Merge contents of two hashes representing sets of routines used
1762
by statements or by other routines.
1764
@param dst hash to which elements should be added
1765
@param src hash from which elements merged
1768
This procedure won't create new Sroutine_hash_entry objects,
1769
instead it will simply add elements from source to destination
1770
hash. Thus time of life of elements in destination hash becomes
1771
dependant on time of life of elements from source hash. It also
1772
won't touch lists linking elements in source and destination
1776
@return TRUE Failure
1777
@return FALSE Success
1780
bool sp_update_sp_used_routines(HASH *dst, HASH *src)
1782
for (uint i=0 ; i < src->records ; i++)
1784
Sroutine_hash_entry *rt= (Sroutine_hash_entry *)hash_element(src, i);
1785
if (!hash_search(dst, (uchar *)rt->key.str, rt->key.length))
1787
if (my_hash_insert(dst, (uchar *)rt))
1796
Add contents of hash representing set of routines to the set of
1797
routines used by statement.
1799
@param thd Thread context
1800
@param lex LEX representing statement
1801
@param src Hash representing set from which routines will
1803
@param belong_to_view Uppermost view which uses these routines, 0 if none
1806
It will also add elements to end of 'LEX::sroutines_list' list.
1810
sp_update_stmt_used_routines(THD *thd, LEX *lex, HASH *src,
1811
TABLE_LIST *belong_to_view)
1813
for (uint i=0 ; i < src->records ; i++)
1815
Sroutine_hash_entry *rt= (Sroutine_hash_entry *)hash_element(src, i);
1816
(void)add_used_routine(lex, thd->stmt_arena, &rt->key, belong_to_view);
1822
Add contents of list representing set of routines to the set of
1823
routines used by statement.
1825
@param thd Thread context
1826
@param lex LEX representing statement
1827
@param src List representing set from which routines will
1829
@param belong_to_view Uppermost view which uses these routines, 0 if none
1832
It will also add elements to end of 'LEX::sroutines_list' list.
1835
static void sp_update_stmt_used_routines(THD *thd, LEX *lex, SQL_LIST *src,
1836
TABLE_LIST *belong_to_view)
1838
for (Sroutine_hash_entry *rt= (Sroutine_hash_entry *)src->first;
1840
(void)add_used_routine(lex, thd->stmt_arena, &rt->key, belong_to_view);
1845
Cache sub-set of routines used by statement, add tables used by these
1846
routines to statement table list. Do the same for all routines used
1849
@param thd thread context
1850
@param lex LEX representing statement
1851
@param start first routine from the list of routines to be cached
1852
(this list defines mentioned sub-set).
1853
@param first_no_prelock If true, don't add tables or cache routines used by
1854
the body of the first routine (i.e. *start)
1855
will be executed in non-prelocked mode.
1856
@param tabs_changed Set to TRUE some tables were added, FALSE otherwise
1859
If some function is missing this won't be reported here.
1860
Instead this fact will be discovered during query execution.
1869
sp_cache_routines_and_add_tables_aux(THD *thd, LEX *lex,
1870
Sroutine_hash_entry *start,
1871
bool first_no_prelock)
1875
DBUG_ENTER("sp_cache_routines_and_add_tables_aux");
1877
for (Sroutine_hash_entry *rt= start; rt; rt= rt->next)
1879
sp_name name(thd, rt->key.str, rt->key.length);
1880
int type= rt->key.str[0];
1883
if (!(sp= sp_cache_lookup((type == TYPE_ENUM_FUNCTION ?
1884
&thd->sp_func_cache : &thd->sp_proc_cache),
1887
switch ((ret= db_find_routine(thd, type, &name, &sp)))
1891
if (type == TYPE_ENUM_FUNCTION)
1892
sp_cache_insert(&thd->sp_func_cache, sp);
1894
sp_cache_insert(&thd->sp_proc_cache, sp);
1897
case SP_KEY_NOT_FOUND:
1901
/* Query might have been killed, don't set error. */
1906
Any error when loading an existing routine is either some problem
1907
with the mysql.proc table, or a parse error because the contents
1908
has been tampered with (in which case we clear that error).
1910
if (ret == SP_PARSE_ERROR)
1913
If we cleared the parse error, or when db_find_routine() flagged
1914
an error with it's return value without calling my_error(), we
1915
set the generic "mysql.proc table corrupt" error here.
1917
if (! thd->is_error())
1920
SP allows full NAME_LEN chars thus he have to allocate enough
1921
size in bytes. Otherwise there is stack overrun could happen
1922
if multibyte sequence is `name`. `db` is still safe because the
1923
rest of the server checks agains NAME_LEN bytes and not chars.
1924
Hence, the overrun happens only if the name is in length > 32 and
1925
uses multibyte (cyrillic, greek, etc.)
1927
char n[NAME_LEN*2+2];
1929
/* m_qname.str is not always \0 terminated */
1930
memcpy(n, name.m_qname.str, name.m_qname.length);
1931
n[name.m_qname.length]= '\0';
1932
my_error(ER_SP_PROC_TABLE_CORRUPT, MYF(0), n, ret);
1939
if (!(first && first_no_prelock))
1941
sp_update_stmt_used_routines(thd, lex, &sp->m_sroutines,
1942
rt->belong_to_view);
1943
(void)sp->add_used_tables_to_table_list(thd, &lex->query_tables_last,
1944
rt->belong_to_view);
1946
sp->propagate_attributes(lex);
1955
Cache all routines from the set of used by statement, add tables used
1956
by those routines to statement table list. Do the same for all routines
1957
used by those routines.
1959
@param thd thread context
1960
@param lex LEX representing statement
1961
@param first_no_prelock If true, don't add tables or cache routines used by
1962
the body of the first routine (i.e. *start)
1971
sp_cache_routines_and_add_tables(THD *thd, LEX *lex, bool first_no_prelock)
1973
return sp_cache_routines_and_add_tables_aux(thd, lex,
1974
(Sroutine_hash_entry *)lex->sroutines_list.first,
1980
Add all routines used by view to the set of routines used by
1983
Add tables used by those routines to statement table list. Do the same
1984
for all routines used by these routines.
1986
@param thd Thread context
1987
@param lex LEX representing statement
1988
@param view Table list element representing view
1997
sp_cache_routines_and_add_tables_for_view(THD *thd, LEX *lex, TABLE_LIST *view)
1999
Sroutine_hash_entry **last_cached_routine_ptr=
2000
(Sroutine_hash_entry **)lex->sroutines_list.next;
2001
sp_update_stmt_used_routines(thd, lex, &view->view->sroutines_list,
2003
return sp_cache_routines_and_add_tables_aux(thd, lex,
2004
*last_cached_routine_ptr, FALSE);
2009
Add triggers for table to the set of routines used by statement.
2010
Add tables used by them to statement table list. Do the same for
2011
all implicitly used routines.
2013
@param thd thread context
2014
@param lex LEX respresenting statement
2015
@param table Table list element for table with trigger
2024
sp_cache_routines_and_add_tables_for_triggers(THD *thd, LEX *lex,
2029
Sroutine_hash_entry **last_cached_routine_ptr=
2030
(Sroutine_hash_entry **)lex->sroutines_list.next;
2032
if (static_cast<int>(table->lock_type) >=
2033
static_cast<int>(TL_WRITE_ALLOW_WRITE))
2035
for (int i= 0; i < (int)TRG_EVENT_MAX; i++)
2037
if (table->trg_event_map &
2038
static_cast<uint8>(1 << static_cast<int>(i)))
2040
for (int j= 0; j < (int)TRG_ACTION_MAX; j++)
2042
/* We can have only one trigger per action type currently */
2043
sp_head *trigger= table->table->triggers->bodies[i][j];
2045
add_used_routine(lex, thd->stmt_arena, &trigger->m_sroutines_key,
2046
table->belong_to_view))
2048
trigger->add_used_tables_to_table_list(thd, &lex->query_tables_last,
2049
table->belong_to_view);
2050
trigger->propagate_attributes(lex);
2051
sp_update_stmt_used_routines(thd, lex,
2052
&trigger->m_sroutines,
2053
table->belong_to_view);
2059
ret= sp_cache_routines_and_add_tables_aux(thd, lex,
2060
*last_cached_routine_ptr,
2067
Generates the CREATE... string from the table information.
2070
Returns TRUE on success, FALSE on (alloc) failure.
2073
create_string(THD *thd, String *buf,
2075
const char *db, ulong dblen,
2076
const char *name, ulong namelen,
2077
const char *params, ulong paramslen,
2078
const char *returns, ulong returnslen,
2079
const char *body, ulong bodylen,
2080
st_sp_chistics *chistics,
2081
const LEX_STRING *definer_user,
2082
const LEX_STRING *definer_host)
2084
/* Make some room to begin with */
2085
if (buf->alloc(100 + dblen + 1 + namelen + paramslen + returnslen + bodylen +
2086
chistics->comment.length + 10 /* length of " DEFINER= "*/ +
2087
USER_HOST_BUFF_SIZE))
2090
buf->append(STRING_WITH_LEN("CREATE "));
2091
append_definer(thd, buf, definer_user, definer_host);
2092
if (type == TYPE_ENUM_FUNCTION)
2093
buf->append(STRING_WITH_LEN("FUNCTION "));
2095
buf->append(STRING_WITH_LEN("PROCEDURE "));
2098
append_identifier(thd, buf, db, dblen);
2101
append_identifier(thd, buf, name, namelen);
2103
buf->append(params, paramslen);
2105
if (type == TYPE_ENUM_FUNCTION)
2107
buf->append(STRING_WITH_LEN(" RETURNS "));
2108
buf->append(returns, returnslen);
2111
switch (chistics->daccess) {
2113
buf->append(STRING_WITH_LEN(" NO SQL\n"));
2115
case SP_READS_SQL_DATA:
2116
buf->append(STRING_WITH_LEN(" READS SQL DATA\n"));
2118
case SP_MODIFIES_SQL_DATA:
2119
buf->append(STRING_WITH_LEN(" MODIFIES SQL DATA\n"));
2121
case SP_DEFAULT_ACCESS:
2122
case SP_CONTAINS_SQL:
2126
if (chistics->detistic)
2127
buf->append(STRING_WITH_LEN(" DETERMINISTIC\n"));
2128
if (chistics->suid == SP_IS_NOT_SUID)
2129
buf->append(STRING_WITH_LEN(" SQL SECURITY INVOKER\n"));
2130
if (chistics->comment.length)
2132
buf->append(STRING_WITH_LEN(" COMMENT "));
2133
append_unescaped(buf, chistics->comment.str, chistics->comment.length);
2136
buf->append(body, bodylen);