summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mysql-test/r/sp.result24
-rw-r--r--mysql-test/t/sp.test29
-rw-r--r--scripts/mysql_create_system_tables.sh6
-rw-r--r--scripts/mysql_fix_privilege_tables.sql16
-rw-r--r--sql/lex.h4
-rw-r--r--sql/sp.cc55
-rw-r--r--sql/sp_head.cc2
-rw-r--r--sql/sql_lex.h19
-rw-r--r--sql/sql_yacc.yy27
9 files changed, 146 insertions, 36 deletions
diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result
index 7544fbe5d60..3a3a72708a4 100644
--- a/mysql-test/r/sp.result
+++ b/mysql-test/r/sp.result
@@ -877,10 +877,17 @@ drop table t3|
drop procedure cur2|
create procedure chistics()
language sql
+modifies sql data
not deterministic
sql security definer
comment 'Characteristics procedure test'
- insert into t1 values ("chistics", 1)|
+ insert into t1 values ("chistics", 1)|
+show create procedure chistics|
+Procedure sql_mode Create Procedure
+chistics CREATE PROCEDURE `test`.`chistics`()
+ MODIFIES SQL DATA
+ COMMENT 'Characteristics procedure test'
+insert into t1 values ("chistics", 1)
call chistics()|
select * from t1|
id data
@@ -890,6 +897,7 @@ alter procedure chistics sql security invoker name chistics2|
show create procedure chistics2|
Procedure sql_mode Create Procedure
chistics2 CREATE PROCEDURE `test`.`chistics2`()
+ MODIFIES SQL DATA
SQL SECURITY INVOKER
COMMENT 'Characteristics procedure test'
insert into t1 values ("chistics", 1)
@@ -899,14 +907,24 @@ language sql
deterministic
sql security invoker
comment 'Characteristics procedure test'
- return 42|
+ return 42|
+show create function chistics|
+Function sql_mode Create Function
+chistics CREATE FUNCTION `test`.`chistics`() RETURNS int
+ DETERMINISTIC
+ SQL SECURITY INVOKER
+ COMMENT 'Characteristics procedure test'
+return 42
select chistics()|
chistics()
42
-alter function chistics name chistics2 comment 'Characteristics function test'|
+alter function chistics name chistics2
+no sql
+comment 'Characteristics function test'|
show create function chistics2|
Function sql_mode Create Function
chistics2 CREATE FUNCTION `test`.`chistics2`() RETURNS int
+ NO SQL
DETERMINISTIC
SQL SECURITY INVOKER
COMMENT 'Characteristics function test'
diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test
index a3101ff9488..c3c044a7808 100644
--- a/mysql-test/t/sp.test
+++ b/mysql-test/t/sp.test
@@ -978,12 +978,14 @@ drop procedure cur2|
# The few characteristics we parse
create procedure chistics()
- language sql
- not deterministic
- sql security definer
- comment 'Characteristics procedure test'
- insert into t1 values ("chistics", 1)|
-
+ language sql
+ modifies sql data
+ not deterministic
+ sql security definer
+ comment 'Characteristics procedure test'
+ insert into t1 values ("chistics", 1)|
+
+show create procedure chistics|
# Call it, just to make sure.
call chistics()|
select * from t1|
@@ -993,15 +995,18 @@ show create procedure chistics2|
drop procedure chistics2|
create function chistics() returns int
- language sql
- deterministic
- sql security invoker
- comment 'Characteristics procedure test'
- return 42|
+ language sql
+ deterministic
+ sql security invoker
+ comment 'Characteristics procedure test'
+ return 42|
+show create function chistics|
# Call it, just to make sure.
select chistics()|
-alter function chistics name chistics2 comment 'Characteristics function test'|
+alter function chistics name chistics2
+ no sql
+ comment 'Characteristics function test'|
show create function chistics2|
drop function chistics2|
diff --git a/scripts/mysql_create_system_tables.sh b/scripts/mysql_create_system_tables.sh
index 5a2a45c4b3d..7a4da55f851 100644
--- a/scripts/mysql_create_system_tables.sh
+++ b/scripts/mysql_create_system_tables.sh
@@ -644,7 +644,11 @@ then
c_p="$c_p type enum('FUNCTION','PROCEDURE') NOT NULL,"
c_p="$c_p specific_name char(64) DEFAULT '' NOT NULL,"
c_p="$c_p language enum('SQL') DEFAULT 'SQL' NOT NULL,"
- c_p="$c_p sql_data_access enum('CONTAINS_SQL') DEFAULT 'CONTAINS_SQL' NOT NULL,"
+ c_p="$c_p sql_data_access enum('CONTAINS_SQL',"
+ c_p="$c_p 'NO_SQL',"
+ c_p="$c_p 'READS_SQL_DATA',"
+ c_p="$c_p 'MODIFIES_SQL_DATA'"
+ c_p="$c_p ) DEFAULT 'CONTAINS_SQL' NOT NULL,"
c_p="$c_p is_deterministic enum('YES','NO') DEFAULT 'NO' NOT NULL,"
c_p="$c_p security_type enum('INVOKER','DEFINER') DEFAULT 'DEFINER' NOT NULL,"
c_p="$c_p param_list blob DEFAULT '' NOT NULL,"
diff --git a/scripts/mysql_fix_privilege_tables.sql b/scripts/mysql_fix_privilege_tables.sql
index 3c01b69f57e..cae6a1d07b9 100644
--- a/scripts/mysql_fix_privilege_tables.sql
+++ b/scripts/mysql_fix_privilege_tables.sql
@@ -254,7 +254,11 @@ CREATE TABLE IF NOT EXISTS proc (
type enum('FUNCTION','PROCEDURE') NOT NULL,
specific_name char(64) DEFAULT '' NOT NULL,
language enum('SQL') DEFAULT 'SQL' NOT NULL,
- sql_data_access enum('CONTAINS_SQL') DEFAULT 'CONTAINS_SQL' NOT NULL,
+ sql_data_access enum('CONTAINS_SQL',
+ 'NO_SQL',
+ 'READS_SQL_DATA',
+ 'MODIFIES_SQL_DATA'
+ ) DEFAULT 'CONTAINS_SQL' NOT NULL,
is_deterministic enum('YES','NO') DEFAULT 'NO' NOT NULL,
security_type enum('INVOKER','DEFINER') DEFAULT 'DEFINER' NOT NULL,
param_list blob DEFAULT '' NOT NULL,
@@ -289,6 +293,12 @@ CREATE TABLE IF NOT EXISTS proc (
PRIMARY KEY (db,name,type)
) comment='Stored Procedures';
-# Correct the name fields to not binary
+# Correct the name fields to not binary, and expand sql_data_access
ALTER TABLE proc MODIFY name char(64) DEFAULT '' NOT NULL,
- MODIFY specific_name char(64) DEFAULT '' NOT NULL;
+ MODIFY specific_name char(64) DEFAULT '' NOT NULL,
+ MODIFY sql_data_access
+ enum('CONTAINS_SQL',
+ 'NO_SQL',
+ 'READS_SQL_DATA',
+ 'MODIFIES_SQL_DATA'
+ ) DEFAULT 'CONTAINS_SQL' NOT NULL;
diff --git a/sql/lex.h b/sql/lex.h
index 4ab557692d1..89daf46218c 100644
--- a/sql/lex.h
+++ b/sql/lex.h
@@ -121,6 +121,7 @@ static SYMBOL symbols[] = {
{ "CONDITION", SYM(CONDITION_SYM)},
{ "CONNECTION", SYM(CONNECTION_SYM)},
{ "CONSTRAINT", SYM(CONSTRAINT)},
+ { "CONTAINS", SYM(CONTAINS_SYM)},
{ "CONTINUE", SYM(CONTINUE_SYM)},
{ "CONVERT", SYM(CONVERT_SYM)},
{ "CREATE", SYM(CREATE)},
@@ -315,6 +316,7 @@ static SYMBOL symbols[] = {
{ "MIN_ROWS", SYM(MIN_ROWS)},
{ "MOD", SYM(MOD_SYM)},
{ "MODE", SYM(MODE_SYM)},
+ { "MODIFIES", SYM(MODIFIES_SYM)},
{ "MODIFY", SYM(MODIFY_SYM)},
{ "MONTH", SYM(MONTH_SYM)},
{ "MULTILINESTRING", SYM(MULTILINESTRING)},
@@ -371,6 +373,7 @@ static SYMBOL symbols[] = {
{ "RAID_CHUNKSIZE", SYM(RAID_CHUNKSIZE)},
{ "RAID_TYPE", SYM(RAID_TYPE)},
{ "READ", SYM(READ_SYM)},
+ { "READS", SYM(READS_SYM)},
{ "REAL", SYM(REAL)},
{ "REFERENCES", SYM(REFERENCES)},
{ "REGEXP", SYM(REGEXP)},
@@ -556,7 +559,6 @@ static SYMBOL sql_functions[] = {
{ "CONCAT", SYM(CONCAT)},
{ "CONCAT_WS", SYM(CONCAT_WS)},
{ "CONNECTION_ID", F_SYM(FUNC_ARG0),0,CREATE_FUNC(create_func_connection_id)},
- { "CONTAINS", F_SYM(FUNC_ARG2),0,CREATE_FUNC_GEOM(create_func_contains)},
{ "CONV", F_SYM(FUNC_ARG3),0,CREATE_FUNC(create_func_conv)},
{ "CONVERT_TZ", SYM(CONVERT_TZ_SYM)},
{ "COUNT", SYM(COUNT_SYM)},
diff --git a/sql/sp.cc b/sql/sp.cc
index 6475b64eb18..8211d06376c 100644
--- a/sql/sp.cc
+++ b/sql/sp.cc
@@ -165,13 +165,36 @@ db_find_routine(THD *thd, int type, sp_name *name, sp_head **sphp)
goto done;
}
+ bzero((char *)&chistics, sizeof(chistics));
+ if ((ptr= get_field(&thd->mem_root,
+ table->field[MYSQL_PROC_FIELD_ACCESS])) == NULL)
+ {
+ ret= SP_GET_FIELD_FAILED;
+ goto done;
+ }
+ switch (ptr[0]) {
+ case 'N':
+ chistics.daccess= SP_NO_SQL;
+ break;
+ case 'C':
+ chistics.daccess= SP_CONTAINS_SQL;
+ break;
+ case 'R':
+ chistics.daccess= SP_READS_SQL_DATA;
+ break;
+ case 'M':
+ chistics.daccess= SP_MODIFIES_SQL_DATA;
+ break;
+ default:
+ chistics.daccess= SP_CONTAINS_SQL;
+ }
+
if ((ptr= get_field(&thd->mem_root,
table->field[MYSQL_PROC_FIELD_DETERMINISTIC])) == NULL)
{
ret= SP_GET_FIELD_FAILED;
goto done;
}
- bzero((char *)&chistics, sizeof(chistics));
chistics.detistic= (ptr[0] == 'N' ? FALSE : TRUE);
if ((ptr= get_field(&thd->mem_root,
@@ -180,7 +203,7 @@ db_find_routine(THD *thd, int type, sp_name *name, sp_head **sphp)
ret= SP_GET_FIELD_FAILED;
goto done;
}
- chistics.suid= (ptr[0] == 'I' ? IS_NOT_SUID : IS_SUID);
+ chistics.suid= (ptr[0] == 'I' ? SP_IS_NOT_SUID : SP_IS_SUID);
if ((params= get_field(&thd->mem_root,
table->field[MYSQL_PROC_FIELD_PARAM_LIST])) == NULL)
@@ -356,9 +379,12 @@ db_create_routine(THD *thd, int type, sp_head *sp)
store((longlong)type);
table->field[MYSQL_PROC_FIELD_SPECIFIC_NAME]->
store(sp->m_name.str, sp->m_name.length, system_charset_info);
+ if (sp->m_chistics->daccess != SP_DEFAULT_ACCESS)
+ table->field[MYSQL_PROC_FIELD_ACCESS]->
+ store((longlong)sp->m_chistics->daccess);
table->field[MYSQL_PROC_FIELD_DETERMINISTIC]->
store((longlong)(sp->m_chistics->detistic ? 1 : 2));
- if (sp->m_chistics->suid != IS_DEFAULT_SUID)
+ if (sp->m_chistics->suid != SP_IS_DEFAULT_SUID)
table->field[MYSQL_PROC_FIELD_SECURITY_TYPE]->
store((longlong)sp->m_chistics->suid);
table->field[MYSQL_PROC_FIELD_PARAM_LIST]->
@@ -433,12 +459,16 @@ db_update_routine(THD *thd, int type, sp_name *name,
store_record(table,record[1]);
table->timestamp_on_update_now = 0; // Don't update create time now.
((Field_timestamp *)table->field[MYSQL_PROC_FIELD_MODIFIED])->set_time();
- if (chistics->suid != IS_DEFAULT_SUID)
- table->field[MYSQL_PROC_FIELD_SECURITY_TYPE]->store((longlong)chistics->suid);
+ if (chistics->suid != SP_IS_DEFAULT_SUID)
+ table->field[MYSQL_PROC_FIELD_SECURITY_TYPE]->
+ store((longlong)chistics->suid);
if (newname)
table->field[MYSQL_PROC_FIELD_NAME]->store(newname,
newnamelen,
system_charset_info);
+ if (chistics->daccess != SP_DEFAULT_ACCESS)
+ table->field[MYSQL_PROC_FIELD_ACCESS]->
+ store((longlong)chistics->daccess);
if (chistics->comment.str)
table->field[MYSQL_PROC_FIELD_COMMENT]->store(chistics->comment.str,
chistics->comment.length,
@@ -1027,9 +1057,20 @@ create_string(THD *thd, String *buf,
buf->append(returns, returnslen);
}
buf->append('\n');
+ switch (chistics->daccess) {
+ case SP_NO_SQL:
+ buf->append(" NO SQL\n");
+ break;
+ case SP_READS_SQL_DATA:
+ buf->append(" READS SQL DATA\n");
+ break;
+ case SP_MODIFIES_SQL_DATA:
+ buf->append(" MODIFIES SQL DATA\n");
+ break;
+ }
if (chistics->detistic)
- buf->append( " DETERMINISTIC\n", 18);
- if (chistics->suid == IS_NOT_SUID)
+ buf->append(" DETERMINISTIC\n", 18);
+ if (chistics->suid == SP_IS_NOT_SUID)
buf->append(" SQL SECURITY INVOKER\n", 25);
if (chistics->comment.length)
{
diff --git a/sql/sp_head.cc b/sql/sp_head.cc
index 6a17bc189c3..82f8e88d889 100644
--- a/sql/sp_head.cc
+++ b/sql/sp_head.cc
@@ -1815,7 +1815,7 @@ sp_instr_error::print(String *str)
void
sp_change_security_context(THD *thd, sp_head *sp, st_sp_security_context *ctxp)
{
- ctxp->changed= (sp->m_chistics->suid != IS_NOT_SUID &&
+ ctxp->changed= (sp->m_chistics->suid != SP_IS_NOT_SUID &&
(strcmp(sp->m_definer_user.str, thd->priv_user) ||
strcmp(sp->m_definer_host.str, thd->priv_host)));
diff --git a/sql/sql_lex.h b/sql/sql_lex.h
index 72d28aa4526..af5b0896fa5 100644
--- a/sql/sql_lex.h
+++ b/sql/sql_lex.h
@@ -94,11 +94,23 @@ enum enum_sql_command {
#define DESCRIBE_NORMAL 1
#define DESCRIBE_EXTENDED 2
-enum suid_behaviour
+enum enum_sp_suid_behaviour
{
- IS_DEFAULT_SUID= 0, IS_NOT_SUID, IS_SUID
+ SP_IS_DEFAULT_SUID= 0,
+ SP_IS_NOT_SUID,
+ SP_IS_SUID
};
+enum enum_sp_data_access
+{
+ SP_DEFAULT_ACCESS= 0,
+ SP_CONTAINS_SQL,
+ SP_NO_SQL,
+ SP_READS_SQL_DATA,
+ SP_MODIFIES_SQL_DATA
+};
+
+
#define DERIVED_SUBQUERY 1
#define DERIVED_VIEW 2
@@ -599,8 +611,9 @@ typedef struct st_alter_info
struct st_sp_chistics
{
LEX_STRING comment;
- enum suid_behaviour suid;
+ enum enum_sp_suid_behaviour suid;
bool detistic;
+ enum enum_sp_data_access daccess;
};
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index 31016b59c6f..d2964df008b 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -225,6 +225,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%token CONDITION_SYM
%token CONNECTION_SYM
%token CONSTRAINT
+%token CONTAINS_SYM
%token CONTINUE_SYM
%token CONVERT_SYM
%token CURRENT_USER
@@ -368,6 +369,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%token RAID_CHUNKS
%token RAID_CHUNKSIZE
%token READ_SYM
+%token READS_SYM
%token REAL_NUM
%token REFERENCES
%token REGEXP
@@ -560,6 +562,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%token MINUTE_SECOND_SYM
%token MINUTE_SYM
%token MODE_SYM
+%token MODIFIES_SYM
%token MODIFY_SYM
%token MONTH_SYM
%token MLINEFROMTEXT
@@ -1378,8 +1381,20 @@ sp_c_chistics:
/* Characteristics for both create and alter */
sp_chistic:
- COMMENT_SYM TEXT_STRING_sys { Lex->sp_chistics.comment= $2; }
- | sp_suid { }
+ COMMENT_SYM TEXT_STRING_sys
+ { Lex->sp_chistics.comment= $2; }
+ | LANGUAGE_SYM SQL_SYM
+ { /* Just parse it, we only have one language for now. */ }
+ | NO_SYM SQL_SYM
+ { Lex->sp_chistics.daccess= SP_NO_SQL; }
+ | CONTAINS_SYM SQL_SYM
+ { Lex->sp_chistics.daccess= SP_CONTAINS_SQL; }
+ | READS_SYM SQL_SYM DATA_SYM
+ { Lex->sp_chistics.daccess= SP_READS_SQL_DATA; }
+ | MODIFIES_SYM SQL_SYM DATA_SYM
+ { Lex->sp_chistics.daccess= SP_MODIFIES_SQL_DATA; }
+ | sp_suid
+ { }
;
/* Alter characteristics */
@@ -1391,7 +1406,6 @@ sp_a_chistic:
/* Create characteristics */
sp_c_chistic:
sp_chistic { }
- | LANGUAGE_SYM SQL_SYM { }
| DETERMINISTIC_SYM { Lex->sp_chistics.detistic= TRUE; }
| NOT DETERMINISTIC_SYM { Lex->sp_chistics.detistic= FALSE; }
;
@@ -1399,11 +1413,11 @@ sp_c_chistic:
sp_suid:
SQL_SYM SECURITY_SYM DEFINER_SYM
{
- Lex->sp_chistics.suid= IS_SUID;
+ Lex->sp_chistics.suid= SP_IS_SUID;
}
| SQL_SYM SECURITY_SYM INVOKER_SYM
{
- Lex->sp_chistics.suid= IS_NOT_SUID;
+ Lex->sp_chistics.suid= SP_IS_NOT_SUID;
}
;
@@ -4237,6 +4251,8 @@ simple_expr:
{ $$= new Item_func_concat(* $3); }
| CONCAT_WS '(' expr ',' expr_list ')'
{ $$= new Item_func_concat_ws($3, *$5); }
+ | CONTAINS_SYM '(' expr ',' expr ')'
+ { $$= create_func_contains($3, $5); }
| CONVERT_TZ_SYM '(' expr ',' expr ',' expr ')'
{
Lex->time_zone_tables_used= &fake_time_zone_tables_list;
@@ -6780,6 +6796,7 @@ keyword:
| COMMIT_SYM {}
| COMPRESSED_SYM {}
| CONCURRENT {}
+ | CONTAINS_SYM {}
| CUBE_SYM {}
| DATA_SYM {}
| DATETIME {}