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.
|
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...
|
- Storing, caching, dropping...
|
||||||
|
|
||||||
As seen above, the entired definition string, including the "CREATE
|
As seen above, the entired definition string, including the "CREATE
|
||||||
PROCEDURE" is kept. The procedure definition string is stored in the
|
PROCEDURE" (or "FUNCTION") is kept. The procedure definition string is
|
||||||
table mysql.proc with the name as the key.
|
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.
|
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
|
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}.
|
encapsulated in the files sp.{cc,h}.
|
||||||
|
|
||||||
|
|
||||||
- CALL
|
- CALLing a procedure
|
||||||
|
|
||||||
A CALL is parsed just like any statement. The resulting Lex has the
|
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
|
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.
|
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 procedure name is pushed to Lex->value_list.
|
||||||
The sql_command code for the result of parsing a is
|
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()
|
Dropping is done by simply getting the procedure with the sp_find()
|
||||||
function and calling sp_drop() (both in sp.{cc,h}).
|
function and calling sp_drop() (both in sp.{cc,h}).
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
Stored Procedures implemented 2003-02-02:
|
Stored Procedures implemented 2003-02-02:
|
||||||
|
|
||||||
|
|
||||||
Summary of Not Yet Implemented:
|
Summary of Not Yet Implemented:
|
||||||
|
|
||||||
- FUNCTIONs
|
- FUNCTIONs
|
||||||
@ -11,6 +12,7 @@ Summary of Not Yet Implemented:
|
|||||||
- DECLARE CURSOR ...
|
- DECLARE CURSOR ...
|
||||||
- FOR-loops (as it requires cursors)
|
- FOR-loops (as it requires cursors)
|
||||||
|
|
||||||
|
|
||||||
Summary of what's implemented:
|
Summary of what's implemented:
|
||||||
|
|
||||||
- SQL PROCEDURES (CREATE/DROP)
|
- SQL PROCEDURES (CREATE/DROP)
|
||||||
@ -19,6 +21,7 @@ Summary of what's implemented:
|
|||||||
- BEGIN/END, SET, CASE, IF, LOOP, WHILE, REPEAT, ITERATE, LEAVE
|
- BEGIN/END, SET, CASE, IF, LOOP, WHILE, REPEAT, ITERATE, LEAVE
|
||||||
- SELECT INTO local variables
|
- SELECT INTO local variables
|
||||||
|
|
||||||
|
|
||||||
List of what's implemented:
|
List of what's implemented:
|
||||||
|
|
||||||
- CREATE PROCEDURE name ( args ) body
|
- CREATE PROCEDURE name ( args ) body
|
||||||
@ -52,9 +55,26 @@ List of what's implemented:
|
|||||||
- SET of local variables
|
- SET of local variables
|
||||||
Implemented as part of the pre-existing SET syntax. This allows an
|
Implemented as part of the pre-existing SET syntax. This allows an
|
||||||
extended syntax of "SET a=x, b=y, ..." where different variable types
|
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
|
- The flow control constructs: CASE, IF, LOOP, WHILE, ITERATE and LEAVE
|
||||||
are fully implemented.
|
are fully implemented.
|
||||||
- SELECT ... INTO local variables (as well as global session variables)
|
- SELECT ... INTO local variables (as well as global session variables)
|
||||||
is implemented. (Note: This is not SQL-99 feature, but common in other
|
is implemented. (Note: This is not SQL-99 feature, but common in other
|
||||||
databases.)
|
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
|
// the in-memory cache for SPs. (And store newly prepared SPs there of
|
||||||
// course.)
|
// course.)
|
||||||
sp_head *
|
sp_head *
|
||||||
sp_find(THD *thd, Item_string *iname)
|
sp_find_procedure(THD *thd, Item_string *iname)
|
||||||
{
|
{
|
||||||
extern int yyparse(void *thd);
|
extern int yyparse(void *thd);
|
||||||
LEX *tmplex;
|
LEX *tmplex;
|
||||||
@ -92,7 +92,7 @@ sp_create_procedure(THD *thd, char *name, uint namelen, char *def, uint deflen)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
sp_drop(THD *thd, char *name, uint namelen)
|
sp_drop_procedure(THD *thd, char *name, uint namelen)
|
||||||
{
|
{
|
||||||
TABLE *table;
|
TABLE *table;
|
||||||
TABLE_LIST tables;
|
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.
|
// Finds a stored procedure given its name. Returns NULL if not found.
|
||||||
//
|
//
|
||||||
sp_head *
|
sp_head *
|
||||||
sp_find(THD *thd, Item_string *name);
|
sp_find_procedure(THD *thd, Item_string *name);
|
||||||
|
|
||||||
int
|
int
|
||||||
sp_create_procedure(THD *thd, char *name, uint namelen, char *def, uint deflen);
|
sp_create_procedure(THD *thd, char *name, uint namelen, char *def, uint deflen);
|
||||||
|
|
||||||
int
|
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_ */
|
#endif /* _SP_H_ */
|
||||||
|
@ -2833,7 +2833,7 @@ mysql_execute_command(THD *thd)
|
|||||||
sp_head *sp;
|
sp_head *sp;
|
||||||
|
|
||||||
s= (Item_string*)lex->value_list.head();
|
s= (Item_string*)lex->value_list.head();
|
||||||
sp= sp_find(thd, s);
|
sp= sp_find_procedure(thd, s);
|
||||||
if (! sp)
|
if (! sp)
|
||||||
{
|
{
|
||||||
send_error(thd, ER_SP_DOES_NOT_EXIST);
|
send_error(thd, ER_SP_DOES_NOT_EXIST);
|
||||||
@ -2862,7 +2862,7 @@ mysql_execute_command(THD *thd)
|
|||||||
sp_head *sp;
|
sp_head *sp;
|
||||||
|
|
||||||
s= (Item_string*)lex->value_list.head();
|
s= (Item_string*)lex->value_list.head();
|
||||||
sp= sp_find(thd, s);
|
sp= sp_find_procedure(thd, s);
|
||||||
if (! sp)
|
if (! sp)
|
||||||
{
|
{
|
||||||
send_error(thd, ER_SP_DOES_NOT_EXIST);
|
send_error(thd, ER_SP_DOES_NOT_EXIST);
|
||||||
@ -2882,7 +2882,7 @@ mysql_execute_command(THD *thd)
|
|||||||
sp_head *sp;
|
sp_head *sp;
|
||||||
|
|
||||||
s = (Item_string*)lex->value_list.head();
|
s = (Item_string*)lex->value_list.head();
|
||||||
sp = sp_find(thd, s);
|
sp = sp_find_procedure(thd, s);
|
||||||
if (! sp)
|
if (! sp)
|
||||||
{
|
{
|
||||||
send_error(thd, ER_SP_DOES_NOT_EXIST);
|
send_error(thd, ER_SP_DOES_NOT_EXIST);
|
||||||
@ -2892,7 +2892,7 @@ mysql_execute_command(THD *thd)
|
|||||||
{
|
{
|
||||||
String *name = s->const_string();
|
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)
|
if (res != 0)
|
||||||
{
|
{
|
||||||
send_error(thd, ER_SP_DROP_FAILED);
|
send_error(thd, ER_SP_DROP_FAILED);
|
||||||
|
Reference in New Issue
Block a user