mirror of
https://github.com/MariaDB/server.git
synced 2025-01-16 03:52:35 +01:00
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.) mysql-test/r/sp.result: Modified test cases for new data access characteristics. mysql-test/t/sp.test: Modified test cases for new data access characteristics. scripts/mysql_create_system_tables.sh: We now support all the SP data access characteristics (not just CONTAINS SQL). scripts/mysql_fix_privilege_tables.sql: We now support all the SP data access characteristics (not just CONTAINS SQL). sql/lex.h: New tokens for SP data access characteristics. sql/sp.cc: Store, print and support alter of data access characteristics. sql/sp_head.cc: Added SP_ prefix to some symbols. sql/sql_lex.h: Added SP_ prefix to some symbols, and added SP data access enum. sql/sql_yacc.yy: Parse SP data access characteristics. (And allow "alter ... language sql", mostly as a formality, it was accidently put in the wrong clause before.)
This commit is contained in:
parent
b57122b39e
commit
a750003f57
9 changed files with 145 additions and 35 deletions
|
@ -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'
|
||||
|
|
|
@ -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|
|
||||
|
||||
|
|
|
@ -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)},
|
||||
|
|
55
sql/sp.cc
55
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)
|
||||
{
|
||||
|
|
|
@ -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 {}
|
||||
|
|
Loading…
Reference in a new issue