diff options
author | unknown <pem@mysql.comhem.se> | 2004-10-14 18:07:09 +0200 |
---|---|---|
committer | unknown <pem@mysql.comhem.se> | 2004-10-14 18:07:09 +0200 |
commit | a750003f574abd30a8183efd3aced152e71ad6a7 (patch) | |
tree | 60fbcabd11aa23d99818bc782b6d0eedaf744703 | |
parent | b57122b39ed33d6d43ab6f866784524980f58561 (diff) | |
download | mariadb-git-a750003f574abd30a8183efd3aced152e71ad6a7.tar.gz |
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.)
-rw-r--r-- | mysql-test/r/sp.result | 24 | ||||
-rw-r--r-- | mysql-test/t/sp.test | 29 | ||||
-rw-r--r-- | scripts/mysql_create_system_tables.sh | 6 | ||||
-rw-r--r-- | scripts/mysql_fix_privilege_tables.sql | 16 | ||||
-rw-r--r-- | sql/lex.h | 4 | ||||
-rw-r--r-- | sql/sp.cc | 55 | ||||
-rw-r--r-- | sql/sp_head.cc | 2 | ||||
-rw-r--r-- | sql/sql_lex.h | 19 | ||||
-rw-r--r-- | sql/sql_yacc.yy | 27 |
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 {} |