mirror of
https://github.com/MariaDB/server.git
synced 2025-08-01 03:47:19 +03:00
Some new stuff in the Docs/sp-* files, and renamed a few functions in preparation
for future work.
This commit is contained in:
@ -166,11 +166,28 @@ calling a PROCEDURE.
|
||||
expressions or statements.
|
||||
|
||||
|
||||
- Parsing CREATE FUNCTION ...
|
||||
|
||||
Creating a functions is essensially the same thing as for a PROCEDURE,
|
||||
with the addition that a FUNCTION has a return type and a RETURN
|
||||
statement, but no OUT or INOUT parameters.
|
||||
|
||||
[QQ - More details here; sp_head needs a result slot and a type flag
|
||||
indicating if it's a function or procedure]
|
||||
|
||||
|
||||
- Storing, caching, dropping...
|
||||
|
||||
As seen above, the entired definition string, including the "CREATE
|
||||
PROCEDURE" is kept. The procedure definition string is stored in the
|
||||
table mysql.proc with the name as the key.
|
||||
PROCEDURE" (or "FUNCTION") is kept. The procedure definition string is
|
||||
stored in the table mysql.proc with the name and type as the key, the
|
||||
type being one of the enum ("procedure","function").
|
||||
|
||||
A PROCEDURE is just stored int the mysql.proc table. A FUNCTION has an
|
||||
additional requirement. They will be called in expressions with the same
|
||||
syntax as UDFs, so UDFs and stored FUNCTIONs share the namespace. Thus,
|
||||
we must make sure that we do not have UDFs and FUNCTIONs with the same
|
||||
name (even if they are storded in different places).
|
||||
|
||||
This means that we can reparse the procedure as many time as we want.
|
||||
The first time, the resulting Lex is used to store the procedure in
|
||||
@ -198,7 +215,7 @@ calling a PROCEDURE.
|
||||
encapsulated in the files sp.{cc,h}.
|
||||
|
||||
|
||||
- CALL
|
||||
- CALLing a procedure
|
||||
|
||||
A CALL is parsed just like any statement. The resulting Lex has the
|
||||
sql_command SQLCOM_CALL, the procedure's name and the parameters are
|
||||
@ -244,11 +261,26 @@ calling a PROCEDURE.
|
||||
For this the support function, sp_head.cc:eval_func_item() is needed.
|
||||
|
||||
|
||||
- Parsing DROP PROCEDURE
|
||||
- Calling a FUNCTION
|
||||
|
||||
Functions don't have an explicit call keyword like procedures. Instead,
|
||||
they appear in expressions with the conventional syntax "fun(arg, ...)".
|
||||
The problem is that we already have User Defined Functions (UDFs) which
|
||||
are called the same way. A UDF is detected by the lexical analyzer (not
|
||||
the parser!), in the find_keyword() function, and returns a UDF_*_FUNC
|
||||
or UDA_*_SUM token with the udf_func object as the yylval.
|
||||
|
||||
So, stored functions must be handled in a simpilar way, and as a
|
||||
consequence, UDFs and functions must not have the same name.
|
||||
|
||||
[QQ - Details of how function calls works here]
|
||||
|
||||
|
||||
- Parsing DROP PROCEDURE/FUNCTION
|
||||
|
||||
The procedure name is pushed to Lex->value_list.
|
||||
The sql_command code for the result of parsing a is
|
||||
SQLCOM_DROP_PROCEDURE.
|
||||
SQLCOM_DROP_PROCEDURE/SQLCOM_DROP_FUNCTION.
|
||||
|
||||
Dropping is done by simply getting the procedure with the sp_find()
|
||||
function and calling sp_drop() (both in sp.{cc,h}).
|
||||
|
@ -1,5 +1,6 @@
|
||||
Stored Procedures implemented 2003-02-02:
|
||||
|
||||
|
||||
Summary of Not Yet Implemented:
|
||||
|
||||
- FUNCTIONs
|
||||
@ -11,6 +12,7 @@ Summary of Not Yet Implemented:
|
||||
- DECLARE CURSOR ...
|
||||
- FOR-loops (as it requires cursors)
|
||||
|
||||
|
||||
Summary of what's implemented:
|
||||
|
||||
- SQL PROCEDURES (CREATE/DROP)
|
||||
@ -19,6 +21,7 @@ Summary of what's implemented:
|
||||
- BEGIN/END, SET, CASE, IF, LOOP, WHILE, REPEAT, ITERATE, LEAVE
|
||||
- SELECT INTO local variables
|
||||
|
||||
|
||||
List of what's implemented:
|
||||
|
||||
- CREATE PROCEDURE name ( args ) body
|
||||
@ -52,9 +55,26 @@ List of what's implemented:
|
||||
- SET of local variables
|
||||
Implemented as part of the pre-existing SET syntax. This allows an
|
||||
extended syntax of "SET a=x, b=y, ..." where different variable types
|
||||
(SP local and global) can be mixed.
|
||||
(SP local and global) can be mixed. This also allows combinations
|
||||
of local variables and some options that only make sense for
|
||||
global/system variables; in that case the options are accepted but
|
||||
ignored.
|
||||
- The flow control constructs: CASE, IF, LOOP, WHILE, ITERATE and LEAVE
|
||||
are fully implemented.
|
||||
- SELECT ... INTO local variables (as well as global session variables)
|
||||
is implemented. (Note: This is not SQL-99 feature, but common in other
|
||||
databases.)
|
||||
|
||||
|
||||
Open questions:
|
||||
|
||||
- What is the expected result when creating a procedure with a name that
|
||||
already exists? An error or overwrite?
|
||||
- Do PROCEDUREs and FUNCTIONs share namespace or not? I think not, but the
|
||||
we need to flag the type in the mysql.proc table and the name alone is
|
||||
not a unique key any more, or, we have separate tables.
|
||||
(Unfortunately, mysql.func is already taken. Use "sfunc" and maybe even
|
||||
rename "proc" into "sproc" while we still can, for consistency?)
|
||||
- SQL-99 variables and parameters are typed. For the present we don't do
|
||||
any type checking, since this is the way MySQL works. I still don't know
|
||||
if we should keep it this way, or implement type checking.
|
||||
|
@ -24,7 +24,7 @@
|
||||
// the in-memory cache for SPs. (And store newly prepared SPs there of
|
||||
// course.)
|
||||
sp_head *
|
||||
sp_find(THD *thd, Item_string *iname)
|
||||
sp_find_procedure(THD *thd, Item_string *iname)
|
||||
{
|
||||
extern int yyparse(void *thd);
|
||||
LEX *tmplex;
|
||||
@ -92,7 +92,7 @@ sp_create_procedure(THD *thd, char *name, uint namelen, char *def, uint deflen)
|
||||
}
|
||||
|
||||
int
|
||||
sp_drop(THD *thd, char *name, uint namelen)
|
||||
sp_drop_procedure(THD *thd, char *name, uint namelen)
|
||||
{
|
||||
TABLE *table;
|
||||
TABLE_LIST tables;
|
||||
|
15
sql/sp.h
15
sql/sp.h
@ -22,12 +22,23 @@
|
||||
// Finds a stored procedure given its name. Returns NULL if not found.
|
||||
//
|
||||
sp_head *
|
||||
sp_find(THD *thd, Item_string *name);
|
||||
sp_find_procedure(THD *thd, Item_string *name);
|
||||
|
||||
int
|
||||
sp_create_procedure(THD *thd, char *name, uint namelen, char *def, uint deflen);
|
||||
|
||||
int
|
||||
sp_drop(THD *thd, char *name, uint namelen);
|
||||
sp_drop_procedure(THD *thd, char *name, uint namelen);
|
||||
|
||||
#if 0
|
||||
sp_head *
|
||||
sp_find_function(THD *thd, Item_string *name);
|
||||
|
||||
int
|
||||
sp_create_function(THD *thd, char *name, uint namelen, char *def, uint deflen);
|
||||
|
||||
int
|
||||
sp_drop_function(THD *thd, char *name, uint namelen);
|
||||
#endif
|
||||
|
||||
#endif /* _SP_H_ */
|
||||
|
@ -2833,7 +2833,7 @@ mysql_execute_command(THD *thd)
|
||||
sp_head *sp;
|
||||
|
||||
s= (Item_string*)lex->value_list.head();
|
||||
sp= sp_find(thd, s);
|
||||
sp= sp_find_procedure(thd, s);
|
||||
if (! sp)
|
||||
{
|
||||
send_error(thd, ER_SP_DOES_NOT_EXIST);
|
||||
@ -2862,7 +2862,7 @@ mysql_execute_command(THD *thd)
|
||||
sp_head *sp;
|
||||
|
||||
s= (Item_string*)lex->value_list.head();
|
||||
sp= sp_find(thd, s);
|
||||
sp= sp_find_procedure(thd, s);
|
||||
if (! sp)
|
||||
{
|
||||
send_error(thd, ER_SP_DOES_NOT_EXIST);
|
||||
@ -2882,7 +2882,7 @@ mysql_execute_command(THD *thd)
|
||||
sp_head *sp;
|
||||
|
||||
s = (Item_string*)lex->value_list.head();
|
||||
sp = sp_find(thd, s);
|
||||
sp = sp_find_procedure(thd, s);
|
||||
if (! sp)
|
||||
{
|
||||
send_error(thd, ER_SP_DOES_NOT_EXIST);
|
||||
@ -2892,7 +2892,7 @@ mysql_execute_command(THD *thd)
|
||||
{
|
||||
String *name = s->const_string();
|
||||
|
||||
res= sp_drop(thd, name->c_ptr(), name->length());
|
||||
res= sp_drop_procedure(thd, name->c_ptr(), name->length());
|
||||
if (res != 0)
|
||||
{
|
||||
send_error(thd, ER_SP_DROP_FAILED);
|
||||
|
Reference in New Issue
Block a user