Commit f2d6ec93 authored by pem@mysql.com's avatar pem@mysql.com

Some new stuff in the Docs/sp-* files, and renamed a few functions in preparation

for future work.
parent b43d7af6
...@@ -166,11 +166,28 @@ calling a PROCEDURE. ...@@ -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. ...@@ -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. ...@@ -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}).
......
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: ...@@ -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: ...@@ -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: ...@@ -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 @@ ...@@ -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) ...@@ -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;
......
...@@ -22,12 +22,23 @@ ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment