revno: 3398.2.11
committer: Alexander Nozdrin <alexander.nozdrin@oracle.com>
branch nick: mysql-trunk-alik-38806.2
timestamp: Wed 2011-08-24 19:33:15 +0400
message:
WL#5986: Stored programs: make SQL-handlers closer to the standard).
Patch for the following bugs:
- Bug#11763171: 55852 - Possibly inappropriate handler activation.
- Bug#11749343: 38806 - Wrong scope for SQL HANDLERS in SP.
The problem was that SQL-handler resolution was done in a hackish way, which
has nothing do with the SQL Standard requirements.
The following terms are used below:
- "handler" is an alias for "SQL-handler";
- "scope" is an alias for "parsing scope", which is in turn an alias for
"BEGIN .. END block";
- "parsing context" -- an instance of sp_pcontext class;
- "runtime context" -- an instance of sp_rcontext class;
SQL-handlers were resolved using stack of stored program calls (runtime context
stack). Information about scopes is not preserved in the runtime context. Thus,
there was no way to ensure proper SQL-handler resolution if there were more
than one scope.
In other words, user-visible problem was that SQL-handlers were not properly
chosen if there were several BEGIN .. END blocks with SQL-handlers inside them.
For more information about the standard way to resolve handlers, see WL#5986
and the mentioned bugs.
The general idea of the patch is to resolve handlers in runtime using the
parsing context of the instruction that raised SQL-condition(s).
Here are some background information and steps that describes the patch:
- An SP instruction has a pointer to its parsing context. So, it's possible
to get instruction's parsing context when instruction raised
SQL-condition(s).
- A method to find the right handler should be moved to sp_pcontext class.
This method should firstly look through the handlers declared in the
current parsing context, then call the parent parsing context.
- When an appropriate SQL-handler is found, we need to find its entering IP
(instruction pointer). I.e. we need to get the pointer to the first
SP-instruction of that handler. This information is available only in the
runtime context.
- Runtime contexts may has pointers to data in parsing contexts, but not vice
versa.
- Thus, we need to establish a link between a handler in the parsing context,
and that handler in the runtime context. That means, we need some
identification of handlers.
- Before this patch, there has been no class/object to store information about
declared SQL-handler. SQL-handlers were represented by SQL-condition-values.
- It is not possible to identify handlers by theis condition values, because
there might be several handlers using the same condition value. It happens,
when there is a named condition and a few handlers for that condition in
different scopes.
- This patch introduces sp_handler class, which has two attributes:
- handler type (only EXIT and CONTINUE are now supported);
- list of condition values, which are caugh by this handler;
- The parsing context stores an array of sp_handler instances.
- The runtime context has a map between a pointer to sp_handler-object, and
its entering instruction pointer. That map is filled/refreshed by means of
hpush/hpop instructions.
Programming-wise, the following things have been changed:
- sp_active_handler_t has been removed, sp_rcontext::m_in_handlers[]
is now an array of uint's.
- sp.test has been fixed because it contained tests for wrong
behaviour.
- new tests have been added to sp-error.test
- a new variant of sp_pcontext::find_handler() has been introduced,
which does all the job to find appropriate SQL-handler for the
given SQL-condition in the current frame/scope.
- "active" handlers (or handlers "in use") are no longer needed for
handler resolution, because it was a hackish (and incorrect) attempt
to implement stacked handler resolution. The scoped resolution rules
guarantee that handlers will not be activated recursively.
SP-code polishing/cleanup:
- remove entering-instruction-pointer from sp_handler, use it in sp_pcontext
to store handler definitions;
- introduce private sp_rcontext::sp_handler_entry, which contains entering ip
for a handler;
- get rid of macros SP_HANDLER_xxx, replace them by
sp_handler::enum_type enum;
- a few other renames;