summaryrefslogtreecommitdiff
path: root/sql/sp_head.cc
diff options
context:
space:
mode:
authorunknown <konstantin@mysql.com>2005-12-07 00:57:15 +0300
committerunknown <konstantin@mysql.com>2005-12-07 00:57:15 +0300
commit8c2d8ac7503e75d775a3ba78f9c6c4dbbac94266 (patch)
tree8b27e95ca2d3ce79ee1dea5d6db8dc8ac9c515ea /sql/sp_head.cc
parent3d1e9eae43a2cd353278b18da37c0ab28d88357d (diff)
downloadmariadb-git-8c2d8ac7503e75d775a3ba78f9c6c4dbbac94266.tar.gz
A fix and a test case for Bug#15392 "Server crashes during
prepared statement execute mysql-test/r/sp.result: Test results fixed: a fix for Bug#15392 mysql-test/t/sp.test: A test case for Bug#15392 "Server crashes during prepared statement execute". No test case for error in Item_func_set_user_var::update as the only possible one is OOM. sql/sp_head.cc: A fix for Bug#15392 "Server crashes during prepared statement execute": the bug was caused by mysql_change_db() call which was overwriting the error state of 'ret'. Later in the code, suv->fix_fields() would discover thd->net.report_error and return it without completing its work. As the return value of fix_fields() was ignored, the server would afterwards crash in suv->update(). The fix makes sure that a possible internal error is raised in reset_lex_and_exec_core and then is handled in sp_head::execute_procedure.
Diffstat (limited to 'sql/sp_head.cc')
-rw-r--r--sql/sp_head.cc21
1 files changed, 11 insertions, 10 deletions
diff --git a/sql/sp_head.cc b/sql/sp_head.cc
index ff4f898924c..fcd220353fc 100644
--- a/sql/sp_head.cc
+++ b/sql/sp_head.cc
@@ -1137,10 +1137,12 @@ int sp_head::execute(THD *thd)
original thd->db will then have been freed */
if (dbchanged)
{
- /* No access check when changing back to where we came from.
- (It would generate an error from mysql_change_db() when olddb=="") */
+ /*
+ No access check when changing back to where we came from.
+ (It would generate an error from mysql_change_db() when olddb=="")
+ */
if (! thd->killed)
- ret= mysql_change_db(thd, olddb, 1);
+ ret|= (int) mysql_change_db(thd, olddb, 1);
}
m_flags&= ~IS_INVOKED;
DBUG_PRINT("info", ("first free for 0x%lx --: 0x%lx->0x%lx, level: %lu, flags %x",
@@ -1519,13 +1521,12 @@ int sp_head::execute_procedure(THD *thd, List<Item> *args)
suv= new Item_func_set_user_var(guv->get_name(), item);
/*
- we do not check suv->fixed, because it can't be fixed after
- creation
+ Item_func_set_user_var is not fixed after construction,
+ call fix_fields().
*/
- suv->fix_fields(thd, &item);
- suv->fix_length_and_dec();
- suv->check();
- suv->update();
+ if ((ret= test(!suv || suv->fix_fields(thd, &item) ||
+ suv->check() || suv->update())))
+ break;
}
}
}
@@ -2097,7 +2098,7 @@ sp_lex_keeper::reset_lex_and_exec_core(THD *thd, uint *nextp,
cleanup_items() is called in sp_head::execute()
*/
- return res;
+ return res || thd->net.report_error;
}