mirror of
https://github.com/MariaDB/server.git
synced 2025-08-01 03:47:19 +03:00
MDEV-11952 Oracle-style packages: stage#5
- CREATE PACKAGE [BODY] statements are now entirely written to mysql.proc with type='PACKAGE' and type='PACKAGE BODY'. - CREATE PACKAGE BODY now supports IF NOT EXISTS - DROP PACKAGE BODY now supports IF EXISTS - CREATE OR REPLACE PACKAGE [BODY] is now supported - CREATE PACKAGE [BODY] now support the DEFINER clause: CREATE DEFINER user@host PACKAGE pkg ... END; CREATE DEFINER user@host PACKAGE BODY pkg ... END; - CREATE PACKAGE [BODY] now supports SQL SECURITY and COMMENT clauses, e.g.: CREATE PACKAGE p1 SQL SECURITY INVOKER COMMENT "comment" AS ... END; - Package routines are now created from the package CREATE PACKAGE BODY statement and don't produce individual records in mysql.proc. - CREATE PACKAGE BODY now supports package-wide variables. Package variables can be read and set inside package routines. Package variables are stored in a separate sp_rcontext, which is cached in THD on the first packate routine call. - CREATE PACKAGE BODY now supports the initialization section. - All public routines (i.e. declared in CREATE PACKAGE) must have implementations in CREATE PACKAGE BODY - Only public package routines are available outside of the package - {CREATE|DROP} PACKAGE [BODY] now respects CREATE ROUTINE and ALTER ROUTINE privileges - "GRANT EXECUTE ON PACKAGE BODY pkg" is now supported - SHOW CREATE PACKAGE [BODY] is now supported - SHOW PACKAGE [BODY] STATUS is now supported - CREATE and DROP for PACKAGE [BODY] now works for non-current databases - mysqldump now supports packages - "SHOW {PROCEDURE|FUNCTION) CODE pkg.routine" now works for package routines - "SHOW PACKAGE BODY CODE pkg" now works (the package initialization section) - A new package body level MDL was added - Recursive calls for package procedures are now possible - Routine forward declarations in CREATE PACKATE BODY are now supported. - Package body variables now work as SP OUT parameters - Package body variables now work as SELECT INTO targets - Package body variables now support ROW, %ROWTYPE, %TYPE
This commit is contained in:
106
sql/sql_acl.cc
106
sql/sql_acl.cc
@ -607,6 +607,7 @@ static MEM_ROOT acl_memroot, grant_memroot;
|
||||
static bool initialized=0;
|
||||
static bool allow_all_hosts=1;
|
||||
static HASH acl_check_hosts, column_priv_hash, proc_priv_hash, func_priv_hash;
|
||||
static HASH package_spec_priv_hash, package_body_priv_hash;
|
||||
static DYNAMIC_ARRAY acl_wild_hosts;
|
||||
static Hash_filo<acl_entry> *acl_cache;
|
||||
static uint grant_version=0; /* Version of priv tables. incremented by acl_load */
|
||||
@ -650,6 +651,18 @@ HASH *Sp_handler_function::get_priv_hash() const
|
||||
}
|
||||
|
||||
|
||||
HASH *Sp_handler_package_spec::get_priv_hash() const
|
||||
{
|
||||
return &package_spec_priv_hash;
|
||||
}
|
||||
|
||||
|
||||
HASH *Sp_handler_package_body::get_priv_hash() const
|
||||
{
|
||||
return &package_body_priv_hash;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Enumeration of ACL/GRANT tables in the mysql database
|
||||
*/
|
||||
@ -1312,6 +1325,8 @@ enum enum_acl_lists
|
||||
COLUMN_PRIVILEGES_HASH,
|
||||
PROC_PRIVILEGES_HASH,
|
||||
FUNC_PRIVILEGES_HASH,
|
||||
PACKAGE_SPEC_PRIVILEGES_HASH,
|
||||
PACKAGE_BODY_PRIVILEGES_HASH,
|
||||
PROXY_USERS_ACL,
|
||||
ROLES_MAPPINGS_HASH
|
||||
};
|
||||
@ -5401,7 +5416,10 @@ table_error:
|
||||
******************************************************************/
|
||||
struct PRIVS_TO_MERGE
|
||||
{
|
||||
enum what { ALL, GLOBAL, DB, TABLE_COLUMN, PROC, FUNC } what;
|
||||
enum what
|
||||
{
|
||||
ALL, GLOBAL, DB, TABLE_COLUMN, PROC, FUNC, PACKAGE_SPEC, PACKAGE_BODY
|
||||
} what;
|
||||
const char *db, *name;
|
||||
};
|
||||
|
||||
@ -5413,6 +5431,10 @@ static enum PRIVS_TO_MERGE::what sp_privs_to_merge(stored_procedure_type type)
|
||||
return PRIVS_TO_MERGE::FUNC;
|
||||
case TYPE_ENUM_PROCEDURE:
|
||||
return PRIVS_TO_MERGE::PROC;
|
||||
case TYPE_ENUM_PACKAGE:
|
||||
return PRIVS_TO_MERGE::PACKAGE_SPEC;
|
||||
case TYPE_ENUM_PACKAGE_BODY:
|
||||
return PRIVS_TO_MERGE::PACKAGE_BODY;
|
||||
case TYPE_ENUM_TRIGGER:
|
||||
case TYPE_ENUM_PROXY:
|
||||
break;
|
||||
@ -6231,7 +6253,14 @@ static int merge_role_privileges(ACL_ROLE *role __attribute__((unused)),
|
||||
if (all || data->what == PRIVS_TO_MERGE::FUNC)
|
||||
changed|= merge_role_routine_grant_privileges(grantee,
|
||||
data->db, data->name, &role_hash, &func_priv_hash);
|
||||
|
||||
if (all || data->what == PRIVS_TO_MERGE::PACKAGE_SPEC)
|
||||
changed|= merge_role_routine_grant_privileges(grantee,
|
||||
data->db, data->name, &role_hash,
|
||||
&package_spec_priv_hash);
|
||||
if (all || data->what == PRIVS_TO_MERGE::PACKAGE_BODY)
|
||||
changed|= merge_role_routine_grant_privileges(grantee,
|
||||
data->db, data->name, &role_hash,
|
||||
&package_body_priv_hash);
|
||||
return !changed; // don't recurse into the subgraph if privs didn't change
|
||||
}
|
||||
|
||||
@ -7116,6 +7145,8 @@ void grant_free(void)
|
||||
my_hash_free(&column_priv_hash);
|
||||
my_hash_free(&proc_priv_hash);
|
||||
my_hash_free(&func_priv_hash);
|
||||
my_hash_free(&package_spec_priv_hash);
|
||||
my_hash_free(&package_body_priv_hash);
|
||||
free_root(&grant_memroot,MYF(0));
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
@ -7182,6 +7213,10 @@ static bool grant_load(THD *thd,
|
||||
0,0,0, (my_hash_get_key) get_grant_table, 0,0);
|
||||
(void) my_hash_init(&func_priv_hash, &my_charset_utf8_bin,
|
||||
0,0,0, (my_hash_get_key) get_grant_table, 0,0);
|
||||
(void) my_hash_init(&package_spec_priv_hash, &my_charset_utf8_bin,
|
||||
0,0,0, (my_hash_get_key) get_grant_table, 0,0);
|
||||
(void) my_hash_init(&package_body_priv_hash, &my_charset_utf8_bin,
|
||||
0,0,0, (my_hash_get_key) get_grant_table, 0,0);
|
||||
init_sql_alloc(&grant_memroot, "GRANT", ACL_ALLOC_BLOCK_SIZE, 0, MYF(0));
|
||||
|
||||
t_table= tables_priv.table();
|
||||
@ -7331,6 +7366,7 @@ static my_bool propagate_role_grants_action(void *role_ptr,
|
||||
bool grant_reload(THD *thd)
|
||||
{
|
||||
HASH old_column_priv_hash, old_proc_priv_hash, old_func_priv_hash;
|
||||
HASH old_package_spec_priv_hash, old_package_body_priv_hash;
|
||||
MEM_ROOT old_mem;
|
||||
int result;
|
||||
DBUG_ENTER("grant_reload");
|
||||
@ -7350,6 +7386,8 @@ bool grant_reload(THD *thd)
|
||||
old_column_priv_hash= column_priv_hash;
|
||||
old_proc_priv_hash= proc_priv_hash;
|
||||
old_func_priv_hash= func_priv_hash;
|
||||
old_package_spec_priv_hash= package_spec_priv_hash;
|
||||
old_package_body_priv_hash= package_body_priv_hash;
|
||||
|
||||
/*
|
||||
Create a new memory pool but save the current memory pool to make an undo
|
||||
@ -7367,6 +7405,8 @@ bool grant_reload(THD *thd)
|
||||
column_priv_hash= old_column_priv_hash; /* purecov: deadcode */
|
||||
proc_priv_hash= old_proc_priv_hash;
|
||||
func_priv_hash= old_func_priv_hash;
|
||||
package_spec_priv_hash= old_package_spec_priv_hash;
|
||||
package_body_priv_hash= old_package_body_priv_hash;
|
||||
grant_memroot= old_mem; /* purecov: deadcode */
|
||||
}
|
||||
else
|
||||
@ -7374,6 +7414,8 @@ bool grant_reload(THD *thd)
|
||||
my_hash_free(&old_column_priv_hash);
|
||||
my_hash_free(&old_proc_priv_hash);
|
||||
my_hash_free(&old_func_priv_hash);
|
||||
my_hash_free(&old_package_spec_priv_hash);
|
||||
my_hash_free(&old_package_body_priv_hash);
|
||||
free_root(&old_mem,MYF(0));
|
||||
}
|
||||
|
||||
@ -8002,7 +8044,9 @@ bool check_grant_db(THD *thd, const char *db)
|
||||
|
||||
if (error)
|
||||
error= check_grant_db_routine(thd, db, &proc_priv_hash) &&
|
||||
check_grant_db_routine(thd, db, &func_priv_hash);
|
||||
check_grant_db_routine(thd, db, &func_priv_hash) &&
|
||||
check_grant_db_routine(thd, db, &package_spec_priv_hash) &&
|
||||
check_grant_db_routine(thd, db, &package_body_priv_hash);
|
||||
|
||||
mysql_rwlock_unlock(&LOCK_grant);
|
||||
|
||||
@ -8399,6 +8443,14 @@ static bool print_grants_for_role(THD *thd, ACL_ROLE * role)
|
||||
buff, sizeof(buff)))
|
||||
return TRUE;
|
||||
|
||||
if (show_routine_grants(thd, role->user.str, "", &sp_handler_package_spec,
|
||||
buff, sizeof(buff)))
|
||||
return TRUE;
|
||||
|
||||
if (show_routine_grants(thd, role->user.str, "", &sp_handler_package_body,
|
||||
buff, sizeof(buff)))
|
||||
return TRUE;
|
||||
|
||||
return FALSE;
|
||||
|
||||
}
|
||||
@ -8624,6 +8676,14 @@ bool mysql_show_grants(THD *thd, LEX_USER *lex_user)
|
||||
buff, sizeof(buff)))
|
||||
goto end;
|
||||
|
||||
if (show_routine_grants(thd, username, hostname, &sp_handler_package_spec,
|
||||
buff, sizeof(buff)))
|
||||
goto end;
|
||||
|
||||
if (show_routine_grants(thd, username, hostname, &sp_handler_package_body,
|
||||
buff, sizeof(buff)))
|
||||
goto end;
|
||||
|
||||
if (show_proxy_grants(thd, username, hostname, buff, sizeof(buff)))
|
||||
goto end;
|
||||
}
|
||||
@ -9559,6 +9619,14 @@ static int handle_grant_struct(enum enum_acl_lists struct_no, bool drop,
|
||||
grant_name_hash= &func_priv_hash;
|
||||
elements= grant_name_hash->records;
|
||||
break;
|
||||
case PACKAGE_SPEC_PRIVILEGES_HASH:
|
||||
grant_name_hash= &package_spec_priv_hash;
|
||||
elements= grant_name_hash->records;
|
||||
break;
|
||||
case PACKAGE_BODY_PRIVILEGES_HASH:
|
||||
grant_name_hash= &package_body_priv_hash;
|
||||
elements= grant_name_hash->records;
|
||||
break;
|
||||
case PROXY_USERS_ACL:
|
||||
elements= acl_proxy_users.elements;
|
||||
break;
|
||||
@ -9597,6 +9665,8 @@ static int handle_grant_struct(enum enum_acl_lists struct_no, bool drop,
|
||||
case COLUMN_PRIVILEGES_HASH:
|
||||
case PROC_PRIVILEGES_HASH:
|
||||
case FUNC_PRIVILEGES_HASH:
|
||||
case PACKAGE_SPEC_PRIVILEGES_HASH:
|
||||
case PACKAGE_BODY_PRIVILEGES_HASH:
|
||||
grant_name= (GRANT_NAME*) my_hash_element(grant_name_hash, idx);
|
||||
user= grant_name->user;
|
||||
host= grant_name->host.hostname;
|
||||
@ -9679,6 +9749,8 @@ static int handle_grant_struct(enum enum_acl_lists struct_no, bool drop,
|
||||
case COLUMN_PRIVILEGES_HASH:
|
||||
case PROC_PRIVILEGES_HASH:
|
||||
case FUNC_PRIVILEGES_HASH:
|
||||
case PACKAGE_SPEC_PRIVILEGES_HASH:
|
||||
case PACKAGE_BODY_PRIVILEGES_HASH:
|
||||
my_hash_delete(grant_name_hash, (uchar*) grant_name);
|
||||
/*
|
||||
In our HASH implementation on deletion one elements
|
||||
@ -9724,6 +9796,8 @@ static int handle_grant_struct(enum enum_acl_lists struct_no, bool drop,
|
||||
case COLUMN_PRIVILEGES_HASH:
|
||||
case PROC_PRIVILEGES_HASH:
|
||||
case FUNC_PRIVILEGES_HASH:
|
||||
case PACKAGE_SPEC_PRIVILEGES_HASH:
|
||||
case PACKAGE_BODY_PRIVILEGES_HASH:
|
||||
{
|
||||
/*
|
||||
Save old hash key and its length to be able to properly update
|
||||
@ -9906,6 +9980,26 @@ static int handle_grant_data(THD *thd, Grant_tables& tables, bool drop,
|
||||
if (search_only)
|
||||
goto end;
|
||||
}
|
||||
/* Handle package spec array. */
|
||||
if ((handle_grant_struct(PACKAGE_SPEC_PRIVILEGES_HASH,
|
||||
drop, user_from, user_to) || found)
|
||||
&& ! result)
|
||||
{
|
||||
result= 1; /* At least one record/element found. */
|
||||
/* If search is requested, we do not need to search further. */
|
||||
if (search_only)
|
||||
goto end;
|
||||
}
|
||||
/* Handle package body array. */
|
||||
if ((handle_grant_struct(PACKAGE_BODY_PRIVILEGES_HASH,
|
||||
drop, user_from, user_to) || found)
|
||||
&& ! result)
|
||||
{
|
||||
result= 1; /* At least one record/element found. */
|
||||
/* If search is requested, we do not need to search further. */
|
||||
if (search_only)
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
/* Handle tables table. */
|
||||
@ -10632,7 +10726,9 @@ bool mysql_revoke_all(THD *thd, List <LEX_USER> &list)
|
||||
|
||||
/* Remove procedure access */
|
||||
if (mysql_revoke_sp_privs(thd, &tables, &sp_handler_function, lex_user) ||
|
||||
mysql_revoke_sp_privs(thd, &tables, &sp_handler_procedure, lex_user))
|
||||
mysql_revoke_sp_privs(thd, &tables, &sp_handler_procedure, lex_user) ||
|
||||
mysql_revoke_sp_privs(thd, &tables, &sp_handler_package_spec, lex_user) ||
|
||||
mysql_revoke_sp_privs(thd, &tables, &sp_handler_package_body, lex_user))
|
||||
result= -1;
|
||||
|
||||
ACL_USER_BASE *user_or_role;
|
||||
@ -11177,6 +11273,8 @@ SHOW_VAR acl_statistics[] = {
|
||||
{"database_grants", (char*)&acl_dbs.elements, SHOW_UINT},
|
||||
{"function_grants", (char*)&func_priv_hash.records, SHOW_ULONG},
|
||||
{"procedure_grants", (char*)&proc_priv_hash.records, SHOW_ULONG},
|
||||
{"package_spec_grants", (char*)&package_spec_priv_hash.records, SHOW_ULONG},
|
||||
{"package_body_grants", (char*)&package_body_priv_hash.records, SHOW_ULONG},
|
||||
{"proxy_users", (char*)&acl_proxy_users.elements, SHOW_UINT},
|
||||
{"role_grants", (char*)&acl_roles_mappings.records, SHOW_ULONG},
|
||||
{"roles", (char*)&acl_roles.records, SHOW_ULONG},
|
||||
|
Reference in New Issue
Block a user