Commit 4043c0f3 authored by pem@mysql.comhem.se's avatar pem@mysql.comhem.se

Implemented the stored procedure data access characteristics:

NO SQL
CONTAINS SQL (default)
READS SQL DATA
MODIFIES SQL DATA

These are needed as hints for the replication.
(Before this, we did have the default in the mysql.proc table, but no support in the parser.)
parent 7f55e8ea
......@@ -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)|
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)
......@@ -900,13 +908,23 @@ deterministic
sql security invoker
comment 'Characteristics procedure test'
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'
......
......@@ -979,11 +979,13 @@ drop procedure cur2|
# The few characteristics we parse
create procedure chistics()
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|
......@@ -999,9 +1001,12 @@ create function chistics() returns int
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|
......
......@@ -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,"
......
......@@ -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;
......@@ -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)},
......
......@@ -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)
{
......
......@@ -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)));
......
......@@ -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;
};
......
......@@ -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 {}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment