diff options
author | halfspawn <j.brauge@qualiac.com> | 2017-02-14 14:43:11 +0100 |
---|---|---|
committer | Alexander Barkov <bar@mariadb.org> | 2017-04-05 15:02:57 +0400 |
commit | af7f287b3b53742e32dd489c8e7187f336a222a9 (patch) | |
tree | 55e6e237c398763cdab7468313054db87e48990f /sql/sp_pcontext.h | |
parent | d836f52be520c3d9cf6c7041aa332cb8c43e3d79 (diff) | |
download | mariadb-git-af7f287b3b53742e32dd489c8e7187f336a222a9.tar.gz |
MDEV-10697 GOTO statement
Diffstat (limited to 'sql/sp_pcontext.h')
-rw-r--r-- | sql/sp_pcontext.h | 55 |
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; |