summaryrefslogtreecommitdiff
path: root/sql/sp_head.cc
diff options
context:
space:
mode:
authorOleksandr Byelkin <sanja@mariadb.com>2017-01-17 13:09:04 +0100
committerOleksandr Byelkin <sanja@mariadb.com>2017-09-04 16:45:02 +0200
commit17589989eec9cf4e9f7084505710a42929efe115 (patch)
tree8b4d2564d65bdc7656ec741aa7b6b5237d2b5387 /sql/sp_head.cc
parentbe45f083e6e7d8da6dbf2349d9c59673d7e61139 (diff)
downloadmariadb-git-17589989eec9cf4e9f7084505710a42929efe115.tar.gz
MDEV-10972: Insert from select / view / union -- repeatable crash in 10.1, 10.2 Linux/Mac/Windows
save thd->select_number between parsing and executions (in case it was not complete executed due to errors (for example epsent table))
Diffstat (limited to 'sql/sp_head.cc')
-rw-r--r--sql/sp_head.cc20
1 files changed, 19 insertions, 1 deletions
diff --git a/sql/sp_head.cc b/sql/sp_head.cc
index bf25d45ffaf..ae274ee8714 100644
--- a/sql/sp_head.cc
+++ b/sql/sp_head.cc
@@ -598,7 +598,7 @@ sp_head::sp_head()
m_flags(0),
m_sp_cache_version(0),
m_creation_ctx(0),
- unsafe_flags(0),
+ unsafe_flags(0), m_select_number(1),
m_recursion_level(0),
m_next_cached_sp(0),
m_cont_level(0)
@@ -2100,8 +2100,26 @@ sp_head::execute_procedure(THD *thd, List<Item> *args)
if (!err_status)
{
+ /*
+ Normally the counter is not reset between parsing and first execution,
+ but it is possible in case of error to have parsing on one CALL and
+ first execution (where VIEW will be parsed and added). So we store the
+ counter after parsing and restore it before execution just to avoid
+ repeating SELECT numbers.
+ */
+ thd->select_number= m_select_number;
+
err_status= execute(thd, TRUE);
DBUG_PRINT("info", ("execute returned %d", (int) err_status));
+ /*
+ This execution of the SP was aborted with an error (e.g. "Table not
+ found"). However it might still have consumed some numbers from the
+ thd->select_number counter. The next sp->exec() call must not use the
+ consumed numbers, so we remember the first free number (We know that
+ nobody will use it as this execution has stopped with an error).
+ */
+ if (err_status)
+ set_select_number(thd->select_number);
}
if (save_log_general)