summaryrefslogtreecommitdiff
path: root/sql/sp_pcontext.h
diff options
context:
space:
mode:
authorhalfspawn <j.brauge@qualiac.com>2017-02-14 14:43:11 +0100
committerAlexander Barkov <bar@mariadb.org>2017-04-05 15:02:57 +0400
commitaf7f287b3b53742e32dd489c8e7187f336a222a9 (patch)
tree55e6e237c398763cdab7468313054db87e48990f /sql/sp_pcontext.h
parentd836f52be520c3d9cf6c7041aa332cb8c43e3d79 (diff)
downloadmariadb-git-af7f287b3b53742e32dd489c8e7187f336a222a9.tar.gz
MDEV-10697 GOTO statement
Diffstat (limited to 'sql/sp_pcontext.h')
-rw-r--r--sql/sp_pcontext.h55
1 files changed, 49 insertions, 6 deletions
diff --git a/sql/sp_pcontext.h b/sql/sp_pcontext.h
index 00cc81964eb..85d0afa8feb 100644
--- a/sql/sp_pcontext.h
+++ b/sql/sp_pcontext.h
@@ -94,6 +94,7 @@ public:
/// IF/WHILE/REPEAT/LOOP, when such statement is rewritten into a
/// combination of low-level jump/jump_if instructions and labels.
+
class sp_label : public Sql_alloc
{
public:
@@ -106,7 +107,10 @@ public:
BEGIN,
/// Label at iteration control
- ITERATION
+ ITERATION,
+
+ /// Label for jump
+ GOTO
};
/// Name of the label.
@@ -132,6 +136,7 @@ public:
{ }
};
+
///////////////////////////////////////////////////////////////////////////
/// This class represents condition-value term in DECLARE CONDITION or
@@ -507,15 +512,29 @@ public:
/////////////////////////////////////////////////////////////////////////
sp_label *push_label(THD *thd, const LEX_STRING name, uint ip,
- sp_label::enum_type type);
+ sp_label::enum_type type, List<sp_label> * list);
+
+ sp_label *push_label(THD *thd, LEX_STRING name, uint ip,
+ sp_label::enum_type type)
+ { return push_label(thd, name, ip, type, &m_labels); }
+
+ sp_label *push_goto_label(THD *thd, LEX_STRING name, uint ip,
+ sp_label::enum_type type)
+ { return push_label(thd, name, ip, type, &m_goto_labels); }
sp_label *push_label(THD *thd, const LEX_STRING name, uint ip)
- {
- return push_label(thd, name, ip, sp_label::IMPLICIT);
- }
+ { return push_label(thd, name, ip, sp_label::IMPLICIT); }
+
+ sp_label *push_goto_label(THD *thd, const LEX_STRING name, uint ip)
+ { return push_goto_label(thd, name, ip, sp_label::GOTO); }
sp_label *find_label(const LEX_STRING name);
+ sp_label *find_goto_label(const LEX_STRING name, bool recusive);
+
+ sp_label *find_goto_label(const LEX_STRING name)
+ { return find_goto_label(name, true); }
+
sp_label *find_label_current_loop_start();
sp_label *last_label()
@@ -528,6 +547,11 @@ public:
return label;
}
+ sp_label *last_goto_label()
+ {
+ return m_goto_labels.head();
+ }
+
sp_label *pop_label()
{ return m_labels.pop(); }
@@ -697,8 +721,27 @@ private:
/// Stack of SQL-handlers.
Dynamic_array<sp_handler *> m_handlers;
- /// List of labels.
+ /*
+ In the below example the label <<lab>> has two meanings:
+ - GOTO lab : must go before the beginning of the loop
+ - CONTINUE lab : must go to the beginning of the loop
+ We solve this by storing block labels and goto labels into separate lists.
+
+ BEGIN
+ <<lab>>
+ FOR i IN a..10 LOOP
+ ...
+ GOTO lab;
+ ...
+ CONTINUE lab;
+ ...
+ END LOOP;
+ END;
+ */
+ /// List of block labels
List<sp_label> m_labels;
+ /// List of goto labels
+ List<sp_label> m_goto_labels;
/// Children contexts, used for destruction.
Dynamic_array<sp_pcontext *> m_children;