WL#962: Added simple, read-only, non-scrolling, asensitive cursors in SPs, using the

(updated) Protocol_cursor class.
Also did some bug fixes.


Docs/sp-imp-spec.txt:
  Added CURSOR docs (and fixed typos)
Docs/sp-implemented.txt:
  Updated for CURSORs
include/mysqld_error.h:
  New error codes/messages for CURSORs
libmysqld/Makefile.am:
  SP cursors now needs this.
mysql-test/r/sp-error.result:
  New tests for cursors.
mysql-test/r/sp.result:
  New tests for cursors.
mysql-test/t/sp-error.test:
  New tests for cursors.
mysql-test/t/sp.test:
  New tests for cursors.
sql/protocol.cc:
  We now always have Protocol_cursor (SPs use it)
sql/protocol.h:
  Fixed bugs in Protocol_cursor (for SPs)
sql/protocol_cursor.cc:
  Fixed bugs in Protocol_cursor (for SPs)
sql/share/czech/errmsg.txt:
  New error codes/messages for CURSORs
sql/share/danish/errmsg.txt:
  New error codes/messages for CURSORs
sql/share/dutch/errmsg.txt:
  New error codes/messages for CURSORs
sql/share/english/errmsg.txt:
  New error codes/messages for CURSORs
sql/share/estonian/errmsg.txt:
  New error codes/messages for CURSORs
sql/share/french/errmsg.txt:
  New error codes/messages for CURSORs
sql/share/german/errmsg.txt:
  New error codes/messages for CURSORs
sql/share/greek/errmsg.txt:
  New error codes/messages for CURSORs
sql/share/hungarian/errmsg.txt:
  New error codes/messages for CURSORs
sql/share/italian/errmsg.txt:
  New error codes/messages for CURSORs
sql/share/japanese/errmsg.txt:
  New error codes/messages for CURSORs
sql/share/korean/errmsg.txt:
  New error codes/messages for CURSORs
sql/share/norwegian-ny/errmsg.txt:
  New error codes/messages for CURSORs
sql/share/norwegian/errmsg.txt:
  New error codes/messages for CURSORs
sql/share/polish/errmsg.txt:
  New error codes/messages for CURSORs
sql/share/portuguese/errmsg.txt:
  New error codes/messages for CURSORs
sql/share/romanian/errmsg.txt:
  New error codes/messages for CURSORs
sql/share/russian/errmsg.txt:
  New error codes/messages for CURSORs
sql/share/serbian/errmsg.txt:
  New error codes/messages for CURSORs
sql/share/slovak/errmsg.txt:
  New error codes/messages for CURSORs
sql/share/spanish/errmsg.txt:
  New error codes/messages for CURSORs
sql/share/swedish/errmsg.txt:
  New error codes/messages for CURSORs
sql/share/ukrainian/errmsg.txt:
  New error codes/messages for CURSORs
sql/sp_head.cc:
  Added cursor support.
  Also fixed problems with item_lists, where pointers and ref_pointer_arrays.
sql/sp_head.h:
  Added cursor support
sql/sp_pcontext.cc:
  Added cursor support
sql/sp_pcontext.h:
  Added cursor support
sql/sp_rcontext.cc:
  Added cursor support, in particular the new sp_cursor class.
sql/sp_rcontext.h:
  Added cursor support, in particular the new sp_cursor class.
sql/sql_lex.h:
  We sometimes need to copy item_lists in LEX when executing substatements in SPs
sql/sql_yacc.yy:
  Added minimal cursor support (not the full syntax yet).
This commit is contained in:
unknown 2003-10-10 16:57:21 +02:00
commit 04c6b9b8d8
42 changed files with 1290 additions and 71 deletions

View file

@ -11,7 +11,7 @@
which dispatches on the command code (in Lex) to the corresponding code for
executing that particular query.
There are thre structures involved in the execution of a query which are of
There are three structures involved in the execution of a query which are of
interest to the stored procedure implementation:
- Lex (mentioned above) is the "compiled" query, that is the output from
@ -186,7 +186,7 @@
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
A PROCEDURE is just stored in 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
@ -293,7 +293,7 @@
So, stored functions must be handled in a simpilar way, and as a
consequence, UDFs and functions must not have the same name.
- Detecting and parsing a FUNCTION invokation
- Detecting and parsing a FUNCTION invocation
The existance of UDFs are checked during the lexical analysis (in
sql_lex.cc:find_keyword()). This has the drawback that they must
@ -319,7 +319,7 @@
"on-the-fly" during the execution of *another* statement.
This makes things a lot more complicated compared to CALL:
- We can't read and parse the FUNCTION from the mysql.proc table at the
point of invokation; the server requires that all tables used are
point of invocation; the server requires that all tables used are
opened and locked at the beginning of the query execution.
One "obvious" solution would be to simply push "mysql.proc" to the list
of tables used by the query, but this implies a "join" with this table
@ -478,6 +478,67 @@
7 sp_instr_hpop(2)
- Cursors
For stored procedures to be really useful, you want to have cursors.
MySQL doesn't yet have "real" cursor support (with API and ODBC support,
allowing updating, arbitrary scrolling, etc), but a simple asensitive,
non-scrolling, read-only cursor can be implemented in SPs using the
class Protocol_cursor.
This class intecepts the creation and sending of results sets and instead
stores it in-memory, as MYSQL_FIELDS and MYSQL_ROWS (as in the client API).
To support this, we need the usual name binding support in sp_pcontext
(similar to variables and conditions) to keep track on declared cursor
names, and a corresponding run-time mechanism in sp_rcontext.
Cursors are lexically scoped like everything with a body or BEGIN/END
block, so they are pushed and poped as usual (see conditions and variables
above).
The basic operations on a cursor are OPEN, FETCH and CLOSE, which will
each have a corresponding instruction. In addition, we need instructions
to push a new cursor (this will encapsulate the LEX of the SELECT statement
of the cursor), and a pop instruction:
- sp_instr_cpush
Push a cursor to the sp_rcontext. This instruction contains the LEX
for the select statement
- sp_instr_cpop
Pop a number of cursors from the sp_rcontext.
- sp_instr_copen
Open a cursor: This will execute the select and get the result set
in a sepeate memroot.
- sp_instr_cfetch
Fetch the next row from the in-memory result set. The instruction
contains a list of the variables (frame offsets) to set.
- sp_instr_cclose
Free the result set.
A cursor is a separate class, sp_cursor (defined in sp_rcontex.h) which
encapsulates the basic operations used by the above instructions.
This class contains the LEX, Protocol_cursor object, and its memroot,
as well as the cursor's current state.
Compiling and executing is fairly straight-forward. sp_instr_copen is
a subclass of sp_instr_stmt and uses its mechanism to execute a
substatement.
- Example:
begin
declare x int;
declare c cursor for select a from t1;
open c;
fetch c into x;
close c;
end
Pos. Instruction
0 sp_instr_cpush('select a from ...')
1 sp_instr_copen(0) # The 0'th cursor
2 sp_instr_cfetch(0) # Contains the variable list
3 sp_instr_cclose(0)
4 sp_instr_cpop(1)
- Class and function APIs
This is an outline of the key types. Some types and other details
in the actual files have been omitted for readability.
@ -569,6 +630,18 @@
// Returns the handler count
uint handlers();
// Push a cursor
void push_cursor(LEX_STRING *name);
// Find a cursor
my_bool find_cursor(LEX_STRING *name, uint *poff);
// Pop 'num' cursors
void pop_cursor(uint num);
// Return the number of cursors
uint cursors();
}
@ -589,8 +662,9 @@
class sp_rcontext
{
// 'fsize' is the max size of the context, 'hmax' the number of handlers
sp_rcontext(uint fsize, uint hmax);
// 'fsize' is the max size of the context, 'hmax' the number of handlers,
// 'cmax' the number of cursors
sp_rcontext(uint fsize, uint hmax, , uint cmax);
// Push value (parameter) 'i' to the frame
void push_item(Item *i);
@ -645,6 +719,18 @@
// Restore saved variables from to frame index 'fp' and up.
void restore_variables(uint fp);
// Push a cursor for the statement (lex)
void push_cursor(LEX *lex);
// Pop 'count' cursors
void pop_cursors(uint count);
// Pop all cursors
void pop_all_cursors();
// Get the 'i'th cursor
sp_cursor *get_cursor(uint i);
}
@ -709,6 +795,7 @@
bool suid, char *comment, uint commentlen);
}
- Instructions
- The base class:
@ -816,6 +903,55 @@
int execute(THD *thd, uint *nextp);
}
- Push a CURSOR
class sp_instr_cpush : public sp_instr_stmt
{
// Push a cursor for statement 'lex'
sp_instr_cpush(uint ip, LEX *lex)
int execute(THD *thd, uint *nextp);
}
- Pop CURSORs
class sp_instr_cpop : public sp_instr_stmt
{
// Pop 'count' cursors
sp_instr_cpop(uint ip, uint count)
int execute(THD *thd, uint *nextp);
}
- Open a CURSOR
class sp_instr_copen : public sp_instr_stmt
{
// Open the 'c'th cursor
sp_instr_copen(uint ip, uint c);
int execute(THD *thd, uint *nextp);
}
- Close a CURSOR
class sp_instr_cclose : public sp_instr
{
// Close the 'c'th cursor
sp_instr_cclose(uint ip, uint c);
int execute(THD *thd, uint *nextp);
}
- Fetch a row with CURSOR
class sp_instr_cfetch : public sp_instr
{
// Fetch next with the 'c'th cursor
sp_instr_cfetch(uint ip, uint c);
int execute(THD *thd, uint *nextp);
// Add a target variable for the fetch
void add_to_varlist(struct sp_pvar *var);
}
- Utility functions: sp.h
#define SP_OK 0

View file

@ -8,8 +8,7 @@ Summary of Not Yet Implemented:
- Access control
- Routine characteristics (mostly used for external languages)
- SQL-99 COMMIT (related to BEGIN/END)
- DECLARE CURSOR ...
- FOR-loops (as it requires cursors)
- FOR-loops
- CASCADE/RESTRICT for ALTER and DROP
- ALTER/DROP METHOD (as it implies User Defined Types)
- SIGNAL and RESIGNAL, and UNDO handlers
@ -25,6 +24,7 @@ Summary of what's implemented:
- "Non-query" FUNCTIONs only
- Prepared SP caching
- CONDITIONs and HANDLERs
- Simple read-only CURSORs.
List of what's implemented:
@ -86,6 +86,11 @@ List of what's implemented:
The semantics of CONDITIONs is expanded to allow catching MySQL error
codes as well. UNDO handlers are not implemented (since we don't have
SQL-99 style transaction control yet).
- Simple read-only CURSORs are implemented, but not yet any of the
optional arguments to DECLARE (SCROLL, SENSITIVE, etc) or FETCH
(NEXT, PRIOR, etc). Cursors are ASENSITIVE, READ-ONLY, non-SCROLLing.
(The additional syntax will be added for completeness, but for the
most part unsupported with the current underlying cursor mechanism.)
Closed questions: