This patch reverts a change introduced by Bug 6951, which incorrectly
set thd->abort_on_warning for stored procedures.
As per internal discussions about the SQL_MODE=TRADITIONAL,
the correct behavior is to *not* abort on warnings even inside an INSERT/UPDATE
trigger.
Tests for Stored Procedures, Stored Functions, Triggers involving SQL_MODE
have been included or revised, to reflect the intended behavior.
(reposting approved patch, to work around source control issues, no review needed)
erroneous check
Problem: Actually there were two problems in the server code. The check
for SQLCOM_FLUSH in SF/Triggers were not according to the existing
architecture which uses sp_get_flags_for_command() from sp_head.cc .
This function was also missing a check for SQLCOM_FLUSH which has a
problem combined with prelocking. This changeset fixes both of these
deficiencies as well as the erroneous check in
sp_head::is_not_allowed_in_function() which was a copy&paste error.
can be not replicable.
Now CREATE statements for writing in the binlog are created as follows:
- the beginning of the statement is re-created;
- the rest of the statement is copied from the original query.
The problem appears when there is a version-specific comment (produced by
mysqldump), started in the re-created part of the statement and closed in the
copied part -- there is closing comment-parenthesis, but there is no opening
one.
The proper fix could be to re-create original statement, but we can not
implement it in 5.0. So, for 5.0 the fix is just to cut closing
comment-parenthesis. This technique is also used for SHOW CREATE PROCEDURE
statement (so we are able to reuse existing code).
Fix for BUG#16676: Database CHARSET not used for stored procedures
The problem in BUG#16211 is that CHARSET-clause of the return type for
stored functions is just ignored.
The problem in BUG#16676 is that if character set is not explicitly
specified for sp-variable, the server character set is used instead
of the database one.
The fix has two parts:
- always store CHARSET-clause of the return type along with the
type definition in mysql.proc.returns column. "Always" means that
CHARSET-clause is appended even if it has not been explicitly
specified in CREATE FUNCTION statement (this affects BUG#16211 only).
Storing CHARSET-clause if it is not specified is essential to avoid
changing character set if the database character set is altered in
the future.
NOTE: this change is not backward compatible with the previous releases.
- use database default character set if CHARSET-clause is not explicitly
specified (this affects both BUG#16211 and BUG#16676).
NOTE: this also breaks backward compatibility.
context.
Routine arguments were evaluated in the security context of the routine
itself, not in the caller's context.
The bug is fixed the following way:
- Item_func_sp::find_and_check_access() has been split into two
functions: Item_func_sp::find_and_check_access() itself only
finds the function and check that the caller have EXECUTE privilege
on it. New function set_routine_security_ctx() changes security
context for SUID routines and checks that definer have EXECUTE
privilege too.
- new function sp_head::execute_trigger() is called from
Table_triggers_list::process_triggers() instead of
sp_head::execute_function(), and is effectively just as the
sp_head::execute_function() is, with all non-trigger related code
removed, and added trigger-specific security context switch.
- call to Item_func_sp::find_and_check_access() stays outside
of sp_head::execute_function(), and there is a code in
sql_parse.cc before the call to sp_head::execute_procedure() that
checks that the caller have EXECUTE privilege, but both
sp_head::execute_function() and sp_head::execute_procedure() call
set_routine_security_ctx() after evaluating their parameters,
and restore the context after the body is executed.
Bug#19022 "Memory bug when switching db during trigger execution"
Bug#17199 "Problem when view calls function from another database."
Bug#18444 "Fully qualified stored function names don't work correctly in
SELECT statements"
Documentation note: this patch introduces a change in behaviour of prepared
statements.
This patch adds a few new invariants with regard to how THD::db should
be used. These invariants should be preserved in future:
- one should never refer to THD::db by pointer and always make a deep copy
(strmake, strdup)
- one should never compare two databases by pointer, but use strncmp or
my_strncasecmp
- TABLE_LIST object table->db should be always initialized in the parser or
by creator of the object.
For prepared statements it means that if the current database is changed
after a statement is prepared, the database that was current at prepare
remains active. This also means that you can not prepare a statement that
implicitly refers to the current database if the latter is not set.
This is not documented, and therefore needs documentation. This is NOT a
change in behavior for almost all SQL statements except:
- ALTER TABLE t1 RENAME t2
- OPTIMIZE TABLE t1
- ANALYZE TABLE t1
- TRUNCATE TABLE t1 --
until this patch t1 or t2 could be evaluated at the first execution of
prepared statement.
CURRENT_DATABASE() still works OK and is evaluated at every execution
of prepared statement.
Note, that in stored routines this is not an issue as the default
database is the database of the stored procedure and "use" statement
is prohibited in stored routines.
This patch makes obsolete the use of check_db_used (it was never used in the
old code too) and all other places that check for table->db and assign it
from THD::db if it's NULL, except the parser.
How this patch was created: THD::{db,db_length} were replaced with a
LEX_STRING, THD::db. All the places that refer to THD::{db,db_length} were
manually checked and:
- if the place uses thd->db by pointer, it was fixed to make a deep copy
- if a place compared two db pointers, it was fixed to compare them by value
(via strcmp/my_strcasecmp, whatever was approproate)
Then this intermediate patch was used to write a smaller patch that does the
same thing but without a rename.
TODO in 5.1:
- remove check_db_used
- deploy THD::set_db in mysql_change_db
See also comments to individual files.
with PREPARE fails with weird error".
More generally, re-executing a stored procedure with a complex SP cursor query
could lead to a crash.
The cause of the problem was that SP cursor queries were not optimized
properly at first execution: their parse tree belongs to sp_instr_cpush,
not sp_instr_copen, and thus the tree was tagged "EXECUTED" when the
cursor was declared, not when it was opened. This led to loss of optimization
transformations performed at first execution, as sp_instr_copen saw that the
query is already "EXECUTED" and therefore either not ran first-execution
related blocks or wrongly rolled back the transformations caused by
first-execution code.
The fix is to update the state of the parsed tree only when the tree is
executed, as opposed to when the instruction containing the tree is executed.
Assignment if i->state is moved to reset_lex_and_exec_core.
Stored procedure execution sometimes placed the address of auto variables
in the list of Item changes to undo in THD::rollback_item_tree_changes().
This could cause stack corruption.
from within triggers
Add support for passing NEW.x as INOUT and OUT parameters to stored
procedures. Passing NEW.x as INOUT parameter requires SELECT and
UPDATE privileges on that column, and passing it as OUT parameter
requires only UPDATE privilege.
hog memory".
During each invocation of stored function or trigger some objects which
lifetime is one function call (e.g. sp_rcontext) were allocated on
arena/memroot of calling statement. This led to consumption of fixed amount
of memory for each function/trigger invocation and so statements which
involve lot of them were hogging memory. This in its return led to OOM
crashes or freezes.
This fix introduces new memroot and arena for objects which lifetime is
whole duration of function call. So all memory consumed by such objects
is freed at the end of function call.
Removed sp-goto.test, sp-goto.result and all (disabled) GOTO code.
Also removed some related code that's not needed any more (no possible
unresolved label references any more, so no need to check for them).
NB: Keeping the ER_SP_GOTO_IN_HNDLR in errmsg.txt; it might become useful
in the future, and removing it (and thus re-enumerating error codes)
might upset things. (Anything referring to explicit error codes.)
Also added comments, and fixing some coding style (mostly in comments too).
There are no functional changes, so no tests or documentation needed.
(This was originally part of a bugfix, but it was decided to not include this
in that patch; instead it's done separately.)
Basically, this fix contains a test case and removing of a workaround
for replication. This fix became possible after pushing WL#2897
(Complete definer support in stored routines).
The idea is to add DEFINER-clause in CREATE PROCEDURE and CREATE FUNCTION
statements. Almost all support of definer in stored routines had been already
done before this patch.
NOTE: this patch changes behaviour of dumping stored routines in mysqldump.
Before this patch, mysqldump did not dump DEFINER-clause for stored routines
and this was documented behaviour. In order to get full information about stored
routines, one should have dumped mysql.proc table. This patch changes this
behaviour, so that DEFINER-clause is dumped.
Since DEFINER-clause is not supported in CREATE PROCEDURE | FUNCTION statements
before this patch, the clause is covered by additional version-specific comments.
if the function, invoked in a non-binlogged caller (e.g. SELECT, DO), failed half-way on the master,
slave would stop and complain that error code between him and master mismatch.
To solve this, when a stored function is invoked in a non-binlogged caller (e.g. SELECT, DO), we binlog the function
call as SELECT instead of as DO (see revision comment of sp_head.cc for more).
And: minor wording change in the help text.
This cset will cause conflicts in 5.1, I'll merge.
After trying multiple inheritance (to messy and hard make it work) and
sublassing jump_if_not (worked, but ugly), decided to on this solution
instead:
Inserting an abstract sp_instr_opt_meta class as parent for all instructions
with destinations makes it possible to handle a continuation pointer for
sp_instr_set_case_expr too.
Note: No special test case; the fix is captured by the changed behaviour of
bug14643_2, and bug14498_4 (formerly disabled), in sp.test.
Second version.
The problem was that the optimizer didn't work correctly with forwards jumps
to "no-op" hpop and cpop instructions.
Don't generate "no-op" instructions (hpop 0 and cpop 0), it isn't actually
necessary.
functions".
We should ignore alias when we check if table was already marked as temporary
when we calculate set of tables to be prelocked. Otherwise we will erroneously
treat tables which are used in same routine and have same name but different
alias as non-temporary.
There are two main idea of this fix:
- introduce a common function for server and client to split user value
(<user name>@<host name>) into user name and host name parts;
- dump DEFINER clause in correct format in mysqldump.
- Fixed tests
- Optimized new code
- Fixed some unlikely core dumps
- Better bug fixes for:
- #14397 - OPTIMIZE TABLE with an open HANDLER causes a crash
- #14850 (ERROR 1062 when a quering a view using a Group By on a column that can be null