mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +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:
@ -3166,6 +3166,8 @@ public:
|
||||
sp_rcontext *spcont; // SP runtime context
|
||||
sp_cache *sp_proc_cache;
|
||||
sp_cache *sp_func_cache;
|
||||
sp_cache *sp_package_spec_cache;
|
||||
sp_cache *sp_package_body_cache;
|
||||
|
||||
/** number of name_const() substitutions, see sp_head.cc:subst_spvars() */
|
||||
uint query_name_consts;
|
||||
@ -5902,6 +5904,7 @@ public:
|
||||
};
|
||||
|
||||
class my_var_sp: public my_var {
|
||||
const Sp_rcontext_handler *m_rcontext_handler;
|
||||
const Type_handler *m_type_handler;
|
||||
public:
|
||||
uint offset;
|
||||
@ -5910,13 +5913,17 @@ public:
|
||||
runtime context is used for variable handling.
|
||||
*/
|
||||
sp_head *sp;
|
||||
my_var_sp(const LEX_CSTRING *j, uint o, const Type_handler *type_handler,
|
||||
my_var_sp(const Sp_rcontext_handler *rcontext_handler,
|
||||
const LEX_CSTRING *j, uint o, const Type_handler *type_handler,
|
||||
sp_head *s)
|
||||
: my_var(j, LOCAL_VAR), m_type_handler(type_handler), offset(o), sp(s) { }
|
||||
: my_var(j, LOCAL_VAR),
|
||||
m_rcontext_handler(rcontext_handler),
|
||||
m_type_handler(type_handler), offset(o), sp(s) { }
|
||||
~my_var_sp() { }
|
||||
bool set(THD *thd, Item *val);
|
||||
my_var_sp *get_my_var_sp() { return this; }
|
||||
const Type_handler *type_handler() const { return m_type_handler; }
|
||||
sp_rcontext *get_rcontext(sp_rcontext *local_ctx) const;
|
||||
};
|
||||
|
||||
/*
|
||||
@ -5927,9 +5934,11 @@ class my_var_sp_row_field: public my_var_sp
|
||||
{
|
||||
uint m_field_offset;
|
||||
public:
|
||||
my_var_sp_row_field(const LEX_CSTRING *varname, const LEX_CSTRING *fieldname,
|
||||
my_var_sp_row_field(const Sp_rcontext_handler *rcontext_handler,
|
||||
const LEX_CSTRING *varname, const LEX_CSTRING *fieldname,
|
||||
uint var_idx, uint field_idx, sp_head *s)
|
||||
:my_var_sp(varname, var_idx, &type_handler_double/*Not really used*/, s),
|
||||
:my_var_sp(rcontext_handler, varname, var_idx,
|
||||
&type_handler_double/*Not really used*/, s),
|
||||
m_field_offset(field_idx)
|
||||
{ }
|
||||
bool set(THD *thd, Item *val);
|
||||
@ -6304,6 +6313,9 @@ public:
|
||||
Database_qualified_name(const LEX_CSTRING *db, const LEX_CSTRING *name)
|
||||
:m_db(*db), m_name(*name)
|
||||
{ }
|
||||
Database_qualified_name(const LEX_CSTRING &db, const LEX_CSTRING &name)
|
||||
:m_db(db), m_name(name)
|
||||
{ }
|
||||
Database_qualified_name(const char *db, size_t db_length,
|
||||
const char *name, size_t name_length)
|
||||
{
|
||||
@ -6353,6 +6365,34 @@ public:
|
||||
DBUG_SLOW_ASSERT(ok_for_lower_case_names(m_db.str));
|
||||
return false;
|
||||
}
|
||||
|
||||
bool make_package_routine_name(MEM_ROOT *mem_root,
|
||||
const LEX_CSTRING &package,
|
||||
const LEX_CSTRING &routine)
|
||||
{
|
||||
char *tmp;
|
||||
size_t length= package.length + 1 + routine.length + 1;
|
||||
if (!(tmp= (char *) alloc_root(mem_root, length)))
|
||||
return true;
|
||||
m_name.length= my_snprintf(tmp, length, "%.*s.%.*s",
|
||||
(int) package.length, package.str,
|
||||
(int) routine.length, routine.str);
|
||||
m_name.str= tmp;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool make_package_routine_name(MEM_ROOT *mem_root,
|
||||
const LEX_CSTRING &db,
|
||||
const LEX_CSTRING &package,
|
||||
const LEX_CSTRING &routine)
|
||||
{
|
||||
if (make_package_routine_name(mem_root, package, routine))
|
||||
return true;
|
||||
if (!(m_db.str= strmake_root(mem_root, db.str, db.length)))
|
||||
return true;
|
||||
m_db.length= db.length;
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user