summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/Context.php10
-rw-r--r--src/Lexer.php57
-rw-r--r--src/Token.php12
-rw-r--r--tests/Lexer/LexerTest.php2
-rw-r--r--tests/data/lexer/lexLabel1.in11
-rw-r--r--tests/data/lexer/lexLabel1.out31
-rw-r--r--tests/data/lexer/lexLabel2.in11
-rw-r--r--tests/data/lexer/lexLabel2.out31
8 files changed, 164 insertions, 1 deletions
diff --git a/src/Context.php b/src/Context.php
index 0bdc696..3685857 100644
--- a/src/Context.php
+++ b/src/Context.php
@@ -30,6 +30,16 @@ abstract class Context
const KEYWORD_MAX_LENGTH = 30;
/**
+ * The maximum length of a label.
+ *
+ * @see static::$TOKEN_LABEL
+ * Ref: https://dev.mysql.com/doc/refman/5.7/en/statement-labels.html
+ *
+ * @var int
+ */
+ const LABEL_MAX_LENGTH = 16;
+
+ /**
* The maximum length of an operator.
*
* @see static::$TOKEN_OPERATOR
diff --git a/src/Lexer.php b/src/Lexer.php
index 7fb2356..9de2a7a 100644
--- a/src/Lexer.php
+++ b/src/Lexer.php
@@ -76,7 +76,7 @@ class Lexer
'parseDelimiter', 'parseWhitespace', 'parseNumber',
'parseComment', 'parseOperator', 'parseBool', 'parseString',
- 'parseSymbol', 'parseKeyword', 'parseUnknown'
+ 'parseSymbol', 'parseKeyword', 'parseLabel', 'parseUnknown'
);
/**
@@ -442,6 +442,61 @@ class Lexer
}
/**
+ * Parses a label.
+ *
+ * @return Token
+ */
+ public function parseLabel()
+ {
+ $token = '';
+
+ /**
+ * Value to be returned.
+ *
+ * @var Token $ret
+ */
+ $ret = null;
+
+ /**
+ * The value of `$this->last` where `$token` ends in `$this->str`.
+ *
+ * @var int $iEnd
+ */
+ $iEnd = $this->last;
+
+ /**
+ * Whether last parsed character is a whitespace.
+ *
+ * @var bool $lastSpace
+ */
+ $lastSpace = false;
+
+ for ($j = 1; $j < Context::LABEL_MAX_LENGTH && $this->last < $this->len; ++$j, ++$this->last) {
+ // Composed keywords shouldn't have more than one whitespace between
+ // keywords.
+ if (Context::isWhitespace($this->str[$this->last])) {
+ if ($lastSpace) {
+ --$j; // The size of the keyword didn't increase.
+ continue;
+ } else {
+ $lastSpace = true;
+ }
+ } elseif ($this->str[$this->last] === ':') {
+ $token .= $this->str[$this->last];
+ $ret = new Token($token, Token::TYPE_LABEL);
+ $iEnd = $this->last;
+ break;
+ } else {
+ $lastSpace = false;
+ }
+ $token .= $this->str[$this->last];
+ }
+
+ $this->last = $iEnd;
+ return $ret;
+ }
+
+ /**
* Parses an operator.
*
* @return Token
diff --git a/src/Token.php b/src/Token.php
index 3181a44..e5001ef 100644
--- a/src/Token.php
+++ b/src/Token.php
@@ -119,6 +119,18 @@ class Token
*/
const TYPE_DELIMITER = 9;
+ /**
+ * Labels in LOOP statement, ITERATE statement etc.
+ * For example (only for begin label):
+ * begin_label: BEGIN [statement_list] END [end_label]
+ * begin_label: LOOP [statement_list] END LOOP [end_label]
+ * begin_label: REPEAT [statement_list] ... END REPEAT [end_label]
+ * begin_label: WHILE ... DO [statement_list] END WHILE [end_label]
+ *
+ * @var int
+ */
+ const TYPE_LABEL = 10;
+
// Flags that describe the tokens in more detail.
// All keywords must have flag 1 so `Context::isKeyword` method doesn't
// require strict comparison.
diff --git a/tests/Lexer/LexerTest.php b/tests/Lexer/LexerTest.php
index 9c22768..0bcd3f7 100644
--- a/tests/Lexer/LexerTest.php
+++ b/tests/Lexer/LexerTest.php
@@ -80,6 +80,8 @@ class LexerTest extends TestCase
array('lexer/lexSymbolErr3'),
array('lexer/lexSymbolUser'),
array('lexer/lexWhitespace'),
+ array('lexer/lexLabel1'),
+ array('lexer/lexLabel2'),
);
}
}
diff --git a/tests/data/lexer/lexLabel1.in b/tests/data/lexer/lexLabel1.in
new file mode 100644
index 0000000..41420e6
--- /dev/null
+++ b/tests/data/lexer/lexLabel1.in
@@ -0,0 +1,11 @@
+CREATE PROCEDURE doiterate(p1 INT)
+BEGIN
+ label1 : LOOP
+ SET p1 = p1 + 1;
+ IF p1 < 10 THEN
+ ITERATE label1;
+ END IF;
+ LEAVE label1;
+ END LOOP label1;
+ SET @x = p1;
+END \ No newline at end of file
diff --git a/tests/data/lexer/lexLabel1.out b/tests/data/lexer/lexLabel1.out
new file mode 100644
index 0000000..17d5996
--- /dev/null
+++ b/tests/data/lexer/lexLabel1.out
@@ -0,0 +1,31 @@
+a:4:{s:5:"query";s:187:"CREATE PROCEDURE doiterate(p1 INT)
+BEGIN
+ label1 : LOOP
+ SET p1 = p1 + 1;
+ IF p1 < 10 THEN
+ ITERATE label1;
+ END IF;
+ LEAVE label1;
+ END LOOP label1;
+ SET @x = p1;
+END";s:5:"lexer";O:15:"SqlParser\Lexer":8:{s:6:"strict";b:0;s:3:"str";s:187:"CREATE PROCEDURE doiterate(p1 INT)
+BEGIN
+ label1 : LOOP
+ SET p1 = p1 + 1;
+ IF p1 < 10 THEN
+ ITERATE label1;
+ END IF;
+ LEAVE label1;
+ END LOOP label1;
+ SET @x = p1;
+END";s:3:"len";i:187;s:4:"last";i:187;s:4:"list";O:20:"SqlParser\TokensList":3:{s:6:"tokens";a:73:{i:0;O:15:"SqlParser\Token":5:{s:5:"token";s:6:"CREATE";s:5:"value";s:6:"CREATE";s:4:"type";i:1;s:5:"flags";i:3;s:8:"position";i:0;}i:1;O:15:"SqlParser\Token":5:{s:5:"token";s:1:" ";s:5:"value";s:1:" ";s:4:"type";i:3;s:5:"flags";i:0;s:8:"position";i:6;}i:2;O:15:"SqlParser\Token":5:{s:5:"token";s:9:"PROCEDURE";s:5:"value";s:9:"PROCEDURE";s:4:"type";i:1;s:5:"flags";i:3;s:8:"position";i:7;}i:3;O:15:"SqlParser\Token":5:{s:5:"token";s:1:" ";s:5:"value";s:1:" ";s:4:"type";i:3;s:5:"flags";i:0;s:8:"position";i:16;}i:4;O:15:"SqlParser\Token":5:{s:5:"token";s:9:"doiterate";s:5:"value";s:9:"doiterate";s:4:"type";i:0;s:5:"flags";i:0;s:8:"position";i:17;}i:5;O:15:"SqlParser\Token":5:{s:5:"token";s:1:"(";s:5:"value";s:1:"(";s:4:"type";i:2;s:5:"flags";i:16;s:8:"position";i:26;}i:6;O:15:"SqlParser\Token":5:{s:5:"token";s:2:"p1";s:5:"value";s:2:"p1";s:4:"type";i:0;s:5:"flags";i:0;s:8:"position";i:27;}i:7;O:15:"SqlParser\Token":5:{s:5:"token";s:1:" ";s:5:"value";s:1:" ";s:4:"type";i:3;s:5:"flags";i:0;s:8:"position";i:29;}i:8;O:15:"SqlParser\Token":5:{s:5:"token";s:3:"INT";s:5:"value";s:3:"INT";s:4:"type";i:1;s:5:"flags";i:11;s:8:"position";i:30;}i:9;O:15:"SqlParser\Token":5:{s:5:"token";s:1:")";s:5:"value";s:1:")";s:4:"type";i:2;s:5:"flags";i:16;s:8:"position";i:33;}i:10;O:15:"SqlParser\Token":5:{s:5:"token";s:1:"
+";s:5:"value";s:1:" ";s:4:"type";i:3;s:5:"flags";i:0;s:8:"position";i:34;}i:11;O:15:"SqlParser\Token":5:{s:5:"token";s:5:"BEGIN";s:5:"value";s:5:"BEGIN";s:4:"type";i:1;s:5:"flags";i:1;s:8:"position";i:35;}i:12;O:15:"SqlParser\Token":5:{s:5:"token";s:3:"
+ ";s:5:"value";s:1:" ";s:4:"type";i:3;s:5:"flags";i:0;s:8:"position";i:40;}i:13;O:15:"SqlParser\Token":5:{s:5:"token";s:8:"label1 :";s:5:"value";s:8:"label1 :";s:4:"type";i:10;s:5:"flags";i:0;s:8:"position";i:43;}i:14;O:15:"SqlParser\Token":5:{s:5:"token";s:1:" ";s:5:"value";s:1:" ";s:4:"type";i:3;s:5:"flags";i:0;s:8:"position";i:51;}i:15;O:15:"SqlParser\Token":5:{s:5:"token";s:4:"LOOP";s:5:"value";s:4:"LOOP";s:4:"type";i:1;s:5:"flags";i:3;s:8:"position";i:52;}i:16;O:15:"SqlParser\Token":5:{s:5:"token";s:5:"
+ ";s:5:"value";s:1:" ";s:4:"type";i:3;s:5:"flags";i:0;s:8:"position";i:56;}i:17;O:15:"SqlParser\Token":5:{s:5:"token";s:3:"SET";s:5:"value";s:3:"SET";s:4:"type";i:1;s:5:"flags";i:11;s:8:"position";i:61;}i:18;O:15:"SqlParser\Token":5:{s:5:"token";s:1:" ";s:5:"value";s:1:" ";s:4:"type";i:3;s:5:"flags";i:0;s:8:"position";i:64;}i:19;O:15:"SqlParser\Token":5:{s:5:"token";s:2:"p1";s:5:"value";s:2:"p1";s:4:"type";i:0;s:5:"flags";i:0;s:8:"position";i:65;}i:20;O:15:"SqlParser\Token":5:{s:5:"token";s:1:" ";s:5:"value";s:1:" ";s:4:"type";i:3;s:5:"flags";i:0;s:8:"position";i:67;}i:21;O:15:"SqlParser\Token":5:{s:5:"token";s:1:"=";s:5:"value";s:1:"=";s:4:"type";i:2;s:5:"flags";i:2;s:8:"position";i:68;}i:22;O:15:"SqlParser\Token":5:{s:5:"token";s:1:" ";s:5:"value";s:1:" ";s:4:"type";i:3;s:5:"flags";i:0;s:8:"position";i:69;}i:23;O:15:"SqlParser\Token":5:{s:5:"token";s:2:"p1";s:5:"value";s:2:"p1";s:4:"type";i:0;s:5:"flags";i:0;s:8:"position";i:70;}i:24;O:15:"SqlParser\Token":5:{s:5:"token";s:1:" ";s:5:"value";s:1:" ";s:4:"type";i:3;s:5:"flags";i:0;s:8:"position";i:72;}i:25;O:15:"SqlParser\Token":5:{s:5:"token";s:1:"+";s:5:"value";s:1:"+";s:4:"type";i:2;s:5:"flags";i:1;s:8:"position";i:73;}i:26;O:15:"SqlParser\Token":5:{s:5:"token";s:1:" ";s:5:"value";s:1:" ";s:4:"type";i:3;s:5:"flags";i:0;s:8:"position";i:74;}i:27;O:15:"SqlParser\Token":5:{s:5:"token";s:1:"1";s:5:"value";i:1;s:4:"type";i:6;s:5:"flags";i:0;s:8:"position";i:75;}i:28;O:15:"SqlParser\Token":5:{s:5:"token";s:1:";";s:5:"value";s:1:";";s:4:"type";i:9;s:5:"flags";i:0;s:8:"position";i:76;}i:29;O:15:"SqlParser\Token":5:{s:5:"token";s:5:"
+ ";s:5:"value";s:1:" ";s:4:"type";i:3;s:5:"flags";i:0;s:8:"position";i:77;}i:30;O:15:"SqlParser\Token":5:{s:5:"token";s:2:"IF";s:5:"value";s:2:"IF";s:4:"type";i:1;s:5:"flags";i:35;s:8:"position";i:82;}i:31;O:15:"SqlParser\Token":5:{s:5:"token";s:1:" ";s:5:"value";s:1:" ";s:4:"type";i:3;s:5:"flags";i:0;s:8:"position";i:84;}i:32;O:15:"SqlParser\Token":5:{s:5:"token";s:2:"p1";s:5:"value";s:2:"p1";s:4:"type";i:0;s:5:"flags";i:0;s:8:"position";i:85;}i:33;O:15:"SqlParser\Token":5:{s:5:"token";s:1:" ";s:5:"value";s:1:" ";s:4:"type";i:3;s:5:"flags";i:0;s:8:"position";i:87;}i:34;O:15:"SqlParser\Token":5:{s:5:"token";s:1:"<";s:5:"value";s:1:"<";s:4:"type";i:2;s:5:"flags";i:2;s:8:"position";i:88;}i:35;O:15:"SqlParser\Token":5:{s:5:"token";s:1:" ";s:5:"value";s:1:" ";s:4:"type";i:3;s:5:"flags";i:0;s:8:"position";i:89;}i:36;O:15:"SqlParser\Token":5:{s:5:"token";s:2:"10";s:5:"value";i:10;s:4:"type";i:6;s:5:"flags";i:0;s:8:"position";i:90;}i:37;O:15:"SqlParser\Token":5:{s:5:"token";s:1:" ";s:5:"value";s:1:" ";s:4:"type";i:3;s:5:"flags";i:0;s:8:"position";i:92;}i:38;O:15:"SqlParser\Token":5:{s:5:"token";s:4:"THEN";s:5:"value";s:4:"THEN";s:4:"type";i:1;s:5:"flags";i:3;s:8:"position";i:93;}i:39;O:15:"SqlParser\Token":5:{s:5:"token";s:7:"
+ ";s:5:"value";s:1:" ";s:4:"type";i:3;s:5:"flags";i:0;s:8:"position";i:97;}i:40;O:15:"SqlParser\Token":5:{s:5:"token";s:7:"ITERATE";s:5:"value";s:7:"ITERATE";s:4:"type";i:1;s:5:"flags";i:3;s:8:"position";i:104;}i:41;O:15:"SqlParser\Token":5:{s:5:"token";s:1:" ";s:5:"value";s:1:" ";s:4:"type";i:3;s:5:"flags";i:0;s:8:"position";i:111;}i:42;O:15:"SqlParser\Token":5:{s:5:"token";s:6:"label1";s:5:"value";s:6:"label1";s:4:"type";i:0;s:5:"flags";i:0;s:8:"position";i:112;}i:43;O:15:"SqlParser\Token":5:{s:5:"token";s:1:";";s:5:"value";s:1:";";s:4:"type";i:9;s:5:"flags";i:0;s:8:"position";i:118;}i:44;O:15:"SqlParser\Token":5:{s:5:"token";s:5:"
+ ";s:5:"value";s:1:" ";s:4:"type";i:3;s:5:"flags";i:0;s:8:"position";i:119;}i:45;O:15:"SqlParser\Token":5:{s:5:"token";s:3:"END";s:5:"value";s:3:"END";s:4:"type";i:1;s:5:"flags";i:1;s:8:"position";i:124;}i:46;O:15:"SqlParser\Token":5:{s:5:"token";s:1:" ";s:5:"value";s:1:" ";s:4:"type";i:3;s:5:"flags";i:0;s:8:"position";i:127;}i:47;O:15:"SqlParser\Token":5:{s:5:"token";s:2:"IF";s:5:"value";s:2:"IF";s:4:"type";i:1;s:5:"flags";i:35;s:8:"position";i:128;}i:48;O:15:"SqlParser\Token":5:{s:5:"token";s:1:";";s:5:"value";s:1:";";s:4:"type";i:9;s:5:"flags";i:0;s:8:"position";i:130;}i:49;O:15:"SqlParser\Token":5:{s:5:"token";s:5:"
+ ";s:5:"value";s:1:" ";s:4:"type";i:3;s:5:"flags";i:0;s:8:"position";i:131;}i:50;O:15:"SqlParser\Token":5:{s:5:"token";s:5:"LEAVE";s:5:"value";s:5:"LEAVE";s:4:"type";i:1;s:5:"flags";i:3;s:8:"position";i:136;}i:51;O:15:"SqlParser\Token":5:{s:5:"token";s:1:" ";s:5:"value";s:1:" ";s:4:"type";i:3;s:5:"flags";i:0;s:8:"position";i:141;}i:52;O:15:"SqlParser\Token":5:{s:5:"token";s:6:"label1";s:5:"value";s:6:"label1";s:4:"type";i:0;s:5:"flags";i:0;s:8:"position";i:142;}i:53;O:15:"SqlParser\Token":5:{s:5:"token";s:1:";";s:5:"value";s:1:";";s:4:"type";i:9;s:5:"flags";i:0;s:8:"position";i:148;}i:54;O:15:"SqlParser\Token":5:{s:5:"token";s:3:"
+ ";s:5:"value";s:1:" ";s:4:"type";i:3;s:5:"flags";i:0;s:8:"position";i:149;}i:55;O:15:"SqlParser\Token":5:{s:5:"token";s:3:"END";s:5:"value";s:3:"END";s:4:"type";i:1;s:5:"flags";i:1;s:8:"position";i:152;}i:56;O:15:"SqlParser\Token":5:{s:5:"token";s:1:" ";s:5:"value";s:1:" ";s:4:"type";i:3;s:5:"flags";i:0;s:8:"position";i:155;}i:57;O:15:"SqlParser\Token":5:{s:5:"token";s:4:"LOOP";s:5:"value";s:4:"LOOP";s:4:"type";i:1;s:5:"flags";i:3;s:8:"position";i:156;}i:58;O:15:"SqlParser\Token":5:{s:5:"token";s:1:" ";s:5:"value";s:1:" ";s:4:"type";i:3;s:5:"flags";i:0;s:8:"position";i:160;}i:59;O:15:"SqlParser\Token":5:{s:5:"token";s:6:"label1";s:5:"value";s:6:"label1";s:4:"type";i:0;s:5:"flags";i:0;s:8:"position";i:161;}i:60;O:15:"SqlParser\Token":5:{s:5:"token";s:1:";";s:5:"value";s:1:";";s:4:"type";i:9;s:5:"flags";i:0;s:8:"position";i:167;}i:61;O:15:"SqlParser\Token":5:{s:5:"token";s:3:"
+ ";s:5:"value";s:1:" ";s:4:"type";i:3;s:5:"flags";i:0;s:8:"position";i:168;}i:62;O:15:"SqlParser\Token":5:{s:5:"token";s:3:"SET";s:5:"value";s:3:"SET";s:4:"type";i:1;s:5:"flags";i:11;s:8:"position";i:171;}i:63;O:15:"SqlParser\Token":5:{s:5:"token";s:1:" ";s:5:"value";s:1:" ";s:4:"type";i:3;s:5:"flags";i:0;s:8:"position";i:174;}i:64;O:15:"SqlParser\Token":5:{s:5:"token";s:2:"@x";s:5:"value";s:1:"x";s:4:"type";i:8;s:5:"flags";i:1;s:8:"position";i:175;}i:65;O:15:"SqlParser\Token":5:{s:5:"token";s:1:" ";s:5:"value";s:1:" ";s:4:"type";i:3;s:5:"flags";i:0;s:8:"position";i:177;}i:66;O:15:"SqlParser\Token":5:{s:5:"token";s:1:"=";s:5:"value";s:1:"=";s:4:"type";i:2;s:5:"flags";i:2;s:8:"position";i:178;}i:67;O:15:"SqlParser\Token":5:{s:5:"token";s:1:" ";s:5:"value";s:1:" ";s:4:"type";i:3;s:5:"flags";i:0;s:8:"position";i:179;}i:68;O:15:"SqlParser\Token":5:{s:5:"token";s:2:"p1";s:5:"value";s:2:"p1";s:4:"type";i:0;s:5:"flags";i:0;s:8:"position";i:180;}i:69;O:15:"SqlParser\Token":5:{s:5:"token";s:1:";";s:5:"value";s:1:";";s:4:"type";i:9;s:5:"flags";i:0;s:8:"position";i:182;}i:70;O:15:"SqlParser\Token":5:{s:5:"token";s:1:"
+";s:5:"value";s:1:" ";s:4:"type";i:3;s:5:"flags";i:0;s:8:"position";i:183;}i:71;O:15:"SqlParser\Token":5:{s:5:"token";s:3:"END";s:5:"value";s:3:"END";s:4:"type";i:1;s:5:"flags";i:1;s:8:"position";i:184;}i:72;O:15:"SqlParser\Token":5:{s:5:"token";N;s:5:"value";N;s:4:"type";i:9;s:5:"flags";i:0;s:8:"position";N;}}s:5:"count";i:73;s:3:"idx";i:74;}s:9:"delimiter";s:1:";";s:12:"delimiterLen";i:1;s:6:"errors";a:0:{}}s:6:"parser";O:16:"SqlParser\Parser":5:{s:4:"list";r:8;s:6:"strict";b:0;s:6:"errors";a:0:{}s:10:"statements";a:1:{i:0;O:36:"SqlParser\Statements\CreateStatement":17:{s:4:"name";O:31:"SqlParser\Components\Expression":7:{s:8:"database";N;s:5:"table";s:9:"doiterate";s:6:"column";N;s:4:"expr";s:9:"doiterate";s:5:"alias";N;s:8:"function";N;s:8:"subquery";N;}s:13:"entityOptions";O:33:"SqlParser\Components\OptionsArray":1:{s:7:"options";a:0:{}}s:6:"fields";N;s:6:"select";N;s:4:"like";N;s:11:"partitionBy";N;s:13:"partitionsNum";N;s:14:"subpartitionBy";N;s:16:"subpartitionsNum";N;s:10:"partitions";N;s:5:"table";N;s:6:"return";N;s:10:"parameters";a:1:{i:0;O:40:"SqlParser\Components\ParameterDefinition":3:{s:4:"name";s:2:"p1";s:5:"inOut";N;s:4:"type";O:29:"SqlParser\Components\DataType":3:{s:4:"name";s:3:"INT";s:10:"parameters";a:0:{}s:7:"options";O:33:"SqlParser\Components\OptionsArray":1:{s:7:"options";a:0:{}}}}}s:4:"body";a:62:{i:0;r:76;i:1;r:82;i:2;r:88;i:3;r:94;i:4;r:100;i:5;r:106;i:6;r:112;i:7;r:118;i:8;r:124;i:9;r:130;i:10;r:136;i:11;r:142;i:12;r:148;i:13;r:154;i:14;r:160;i:15;r:166;i:16;r:172;i:17;r:178;i:18;r:184;i:19;r:190;i:20;r:196;i:21;r:202;i:22;r:208;i:23;r:214;i:24;r:220;i:25;r:226;i:26;r:232;i:27;r:238;i:28;r:244;i:29;r:250;i:30;r:256;i:31;r:262;i:32;r:268;i:33;r:274;i:34;r:280;i:35;r:286;i:36;r:292;i:37;r:298;i:38;r:304;i:39;r:310;i:40;r:316;i:41;r:322;i:42;r:328;i:43;r:334;i:44;r:340;i:45;r:346;i:46;r:352;i:47;r:358;i:48;r:364;i:49;r:370;i:50;r:376;i:51;r:382;i:52;r:388;i:53;r:394;i:54;r:400;i:55;r:406;i:56;r:412;i:57;r:418;i:58;r:424;i:59;r:430;i:60;r:436;i:61;r:442;}s:7:"options";O:33:"SqlParser\Components\OptionsArray":1:{s:7:"options";a:1:{i:6;s:9:"PROCEDURE";}}s:5:"first";i:0;s:4:"last";i:73;}}s:8:"brackets";i:0;}s:6:"errors";a:2:{s:5:"lexer";a:0:{}s:6:"parser";a:0:{}}} \ No newline at end of file
diff --git a/tests/data/lexer/lexLabel2.in b/tests/data/lexer/lexLabel2.in
new file mode 100644
index 0000000..3e98477
--- /dev/null
+++ b/tests/data/lexer/lexLabel2.in
@@ -0,0 +1,11 @@
+CREATE PROCEDURE doiterate(p1 INT)
+BEGIN
+ label1: LOOP
+ SET p1 = p1 + 1;
+ IF p1 < 10 THEN
+ ITERATE label1;
+ END IF;
+ LEAVE label1;
+ END LOOP label1;
+ SET @x = p1;
+END \ No newline at end of file
diff --git a/tests/data/lexer/lexLabel2.out b/tests/data/lexer/lexLabel2.out
new file mode 100644
index 0000000..b22d04b
--- /dev/null
+++ b/tests/data/lexer/lexLabel2.out
@@ -0,0 +1,31 @@
+a:4:{s:5:"query";s:186:"CREATE PROCEDURE doiterate(p1 INT)
+BEGIN
+ label1: LOOP
+ SET p1 = p1 + 1;
+ IF p1 < 10 THEN
+ ITERATE label1;
+ END IF;
+ LEAVE label1;
+ END LOOP label1;
+ SET @x = p1;
+END";s:5:"lexer";O:15:"SqlParser\Lexer":8:{s:6:"strict";b:0;s:3:"str";s:186:"CREATE PROCEDURE doiterate(p1 INT)
+BEGIN
+ label1: LOOP
+ SET p1 = p1 + 1;
+ IF p1 < 10 THEN
+ ITERATE label1;
+ END IF;
+ LEAVE label1;
+ END LOOP label1;
+ SET @x = p1;
+END";s:3:"len";i:186;s:4:"last";i:186;s:4:"list";O:20:"SqlParser\TokensList":3:{s:6:"tokens";a:73:{i:0;O:15:"SqlParser\Token":5:{s:5:"token";s:6:"CREATE";s:5:"value";s:6:"CREATE";s:4:"type";i:1;s:5:"flags";i:3;s:8:"position";i:0;}i:1;O:15:"SqlParser\Token":5:{s:5:"token";s:1:" ";s:5:"value";s:1:" ";s:4:"type";i:3;s:5:"flags";i:0;s:8:"position";i:6;}i:2;O:15:"SqlParser\Token":5:{s:5:"token";s:9:"PROCEDURE";s:5:"value";s:9:"PROCEDURE";s:4:"type";i:1;s:5:"flags";i:3;s:8:"position";i:7;}i:3;O:15:"SqlParser\Token":5:{s:5:"token";s:1:" ";s:5:"value";s:1:" ";s:4:"type";i:3;s:5:"flags";i:0;s:8:"position";i:16;}i:4;O:15:"SqlParser\Token":5:{s:5:"token";s:9:"doiterate";s:5:"value";s:9:"doiterate";s:4:"type";i:0;s:5:"flags";i:0;s:8:"position";i:17;}i:5;O:15:"SqlParser\Token":5:{s:5:"token";s:1:"(";s:5:"value";s:1:"(";s:4:"type";i:2;s:5:"flags";i:16;s:8:"position";i:26;}i:6;O:15:"SqlParser\Token":5:{s:5:"token";s:2:"p1";s:5:"value";s:2:"p1";s:4:"type";i:0;s:5:"flags";i:0;s:8:"position";i:27;}i:7;O:15:"SqlParser\Token":5:{s:5:"token";s:1:" ";s:5:"value";s:1:" ";s:4:"type";i:3;s:5:"flags";i:0;s:8:"position";i:29;}i:8;O:15:"SqlParser\Token":5:{s:5:"token";s:3:"INT";s:5:"value";s:3:"INT";s:4:"type";i:1;s:5:"flags";i:11;s:8:"position";i:30;}i:9;O:15:"SqlParser\Token":5:{s:5:"token";s:1:")";s:5:"value";s:1:")";s:4:"type";i:2;s:5:"flags";i:16;s:8:"position";i:33;}i:10;O:15:"SqlParser\Token":5:{s:5:"token";s:1:"
+";s:5:"value";s:1:" ";s:4:"type";i:3;s:5:"flags";i:0;s:8:"position";i:34;}i:11;O:15:"SqlParser\Token":5:{s:5:"token";s:5:"BEGIN";s:5:"value";s:5:"BEGIN";s:4:"type";i:1;s:5:"flags";i:1;s:8:"position";i:35;}i:12;O:15:"SqlParser\Token":5:{s:5:"token";s:3:"
+ ";s:5:"value";s:1:" ";s:4:"type";i:3;s:5:"flags";i:0;s:8:"position";i:40;}i:13;O:15:"SqlParser\Token":5:{s:5:"token";s:7:"label1:";s:5:"value";s:7:"label1:";s:4:"type";i:10;s:5:"flags";i:0;s:8:"position";i:43;}i:14;O:15:"SqlParser\Token":5:{s:5:"token";s:1:" ";s:5:"value";s:1:" ";s:4:"type";i:3;s:5:"flags";i:0;s:8:"position";i:50;}i:15;O:15:"SqlParser\Token":5:{s:5:"token";s:4:"LOOP";s:5:"value";s:4:"LOOP";s:4:"type";i:1;s:5:"flags";i:3;s:8:"position";i:51;}i:16;O:15:"SqlParser\Token":5:{s:5:"token";s:5:"
+ ";s:5:"value";s:1:" ";s:4:"type";i:3;s:5:"flags";i:0;s:8:"position";i:55;}i:17;O:15:"SqlParser\Token":5:{s:5:"token";s:3:"SET";s:5:"value";s:3:"SET";s:4:"type";i:1;s:5:"flags";i:11;s:8:"position";i:60;}i:18;O:15:"SqlParser\Token":5:{s:5:"token";s:1:" ";s:5:"value";s:1:" ";s:4:"type";i:3;s:5:"flags";i:0;s:8:"position";i:63;}i:19;O:15:"SqlParser\Token":5:{s:5:"token";s:2:"p1";s:5:"value";s:2:"p1";s:4:"type";i:0;s:5:"flags";i:0;s:8:"position";i:64;}i:20;O:15:"SqlParser\Token":5:{s:5:"token";s:1:" ";s:5:"value";s:1:" ";s:4:"type";i:3;s:5:"flags";i:0;s:8:"position";i:66;}i:21;O:15:"SqlParser\Token":5:{s:5:"token";s:1:"=";s:5:"value";s:1:"=";s:4:"type";i:2;s:5:"flags";i:2;s:8:"position";i:67;}i:22;O:15:"SqlParser\Token":5:{s:5:"token";s:1:" ";s:5:"value";s:1:" ";s:4:"type";i:3;s:5:"flags";i:0;s:8:"position";i:68;}i:23;O:15:"SqlParser\Token":5:{s:5:"token";s:2:"p1";s:5:"value";s:2:"p1";s:4:"type";i:0;s:5:"flags";i:0;s:8:"position";i:69;}i:24;O:15:"SqlParser\Token":5:{s:5:"token";s:1:" ";s:5:"value";s:1:" ";s:4:"type";i:3;s:5:"flags";i:0;s:8:"position";i:71;}i:25;O:15:"SqlParser\Token":5:{s:5:"token";s:1:"+";s:5:"value";s:1:"+";s:4:"type";i:2;s:5:"flags";i:1;s:8:"position";i:72;}i:26;O:15:"SqlParser\Token":5:{s:5:"token";s:1:" ";s:5:"value";s:1:" ";s:4:"type";i:3;s:5:"flags";i:0;s:8:"position";i:73;}i:27;O:15:"SqlParser\Token":5:{s:5:"token";s:1:"1";s:5:"value";i:1;s:4:"type";i:6;s:5:"flags";i:0;s:8:"position";i:74;}i:28;O:15:"SqlParser\Token":5:{s:5:"token";s:1:";";s:5:"value";s:1:";";s:4:"type";i:9;s:5:"flags";i:0;s:8:"position";i:75;}i:29;O:15:"SqlParser\Token":5:{s:5:"token";s:5:"
+ ";s:5:"value";s:1:" ";s:4:"type";i:3;s:5:"flags";i:0;s:8:"position";i:76;}i:30;O:15:"SqlParser\Token":5:{s:5:"token";s:2:"IF";s:5:"value";s:2:"IF";s:4:"type";i:1;s:5:"flags";i:35;s:8:"position";i:81;}i:31;O:15:"SqlParser\Token":5:{s:5:"token";s:1:" ";s:5:"value";s:1:" ";s:4:"type";i:3;s:5:"flags";i:0;s:8:"position";i:83;}i:32;O:15:"SqlParser\Token":5:{s:5:"token";s:2:"p1";s:5:"value";s:2:"p1";s:4:"type";i:0;s:5:"flags";i:0;s:8:"position";i:84;}i:33;O:15:"SqlParser\Token":5:{s:5:"token";s:1:" ";s:5:"value";s:1:" ";s:4:"type";i:3;s:5:"flags";i:0;s:8:"position";i:86;}i:34;O:15:"SqlParser\Token":5:{s:5:"token";s:1:"<";s:5:"value";s:1:"<";s:4:"type";i:2;s:5:"flags";i:2;s:8:"position";i:87;}i:35;O:15:"SqlParser\Token":5:{s:5:"token";s:1:" ";s:5:"value";s:1:" ";s:4:"type";i:3;s:5:"flags";i:0;s:8:"position";i:88;}i:36;O:15:"SqlParser\Token":5:{s:5:"token";s:2:"10";s:5:"value";i:10;s:4:"type";i:6;s:5:"flags";i:0;s:8:"position";i:89;}i:37;O:15:"SqlParser\Token":5:{s:5:"token";s:1:" ";s:5:"value";s:1:" ";s:4:"type";i:3;s:5:"flags";i:0;s:8:"position";i:91;}i:38;O:15:"SqlParser\Token":5:{s:5:"token";s:4:"THEN";s:5:"value";s:4:"THEN";s:4:"type";i:1;s:5:"flags";i:3;s:8:"position";i:92;}i:39;O:15:"SqlParser\Token":5:{s:5:"token";s:7:"
+ ";s:5:"value";s:1:" ";s:4:"type";i:3;s:5:"flags";i:0;s:8:"position";i:96;}i:40;O:15:"SqlParser\Token":5:{s:5:"token";s:7:"ITERATE";s:5:"value";s:7:"ITERATE";s:4:"type";i:1;s:5:"flags";i:3;s:8:"position";i:103;}i:41;O:15:"SqlParser\Token":5:{s:5:"token";s:1:" ";s:5:"value";s:1:" ";s:4:"type";i:3;s:5:"flags";i:0;s:8:"position";i:110;}i:42;O:15:"SqlParser\Token":5:{s:5:"token";s:6:"label1";s:5:"value";s:6:"label1";s:4:"type";i:0;s:5:"flags";i:0;s:8:"position";i:111;}i:43;O:15:"SqlParser\Token":5:{s:5:"token";s:1:";";s:5:"value";s:1:";";s:4:"type";i:9;s:5:"flags";i:0;s:8:"position";i:117;}i:44;O:15:"SqlParser\Token":5:{s:5:"token";s:5:"
+ ";s:5:"value";s:1:" ";s:4:"type";i:3;s:5:"flags";i:0;s:8:"position";i:118;}i:45;O:15:"SqlParser\Token":5:{s:5:"token";s:3:"END";s:5:"value";s:3:"END";s:4:"type";i:1;s:5:"flags";i:1;s:8:"position";i:123;}i:46;O:15:"SqlParser\Token":5:{s:5:"token";s:1:" ";s:5:"value";s:1:" ";s:4:"type";i:3;s:5:"flags";i:0;s:8:"position";i:126;}i:47;O:15:"SqlParser\Token":5:{s:5:"token";s:2:"IF";s:5:"value";s:2:"IF";s:4:"type";i:1;s:5:"flags";i:35;s:8:"position";i:127;}i:48;O:15:"SqlParser\Token":5:{s:5:"token";s:1:";";s:5:"value";s:1:";";s:4:"type";i:9;s:5:"flags";i:0;s:8:"position";i:129;}i:49;O:15:"SqlParser\Token":5:{s:5:"token";s:5:"
+ ";s:5:"value";s:1:" ";s:4:"type";i:3;s:5:"flags";i:0;s:8:"position";i:130;}i:50;O:15:"SqlParser\Token":5:{s:5:"token";s:5:"LEAVE";s:5:"value";s:5:"LEAVE";s:4:"type";i:1;s:5:"flags";i:3;s:8:"position";i:135;}i:51;O:15:"SqlParser\Token":5:{s:5:"token";s:1:" ";s:5:"value";s:1:" ";s:4:"type";i:3;s:5:"flags";i:0;s:8:"position";i:140;}i:52;O:15:"SqlParser\Token":5:{s:5:"token";s:6:"label1";s:5:"value";s:6:"label1";s:4:"type";i:0;s:5:"flags";i:0;s:8:"position";i:141;}i:53;O:15:"SqlParser\Token":5:{s:5:"token";s:1:";";s:5:"value";s:1:";";s:4:"type";i:9;s:5:"flags";i:0;s:8:"position";i:147;}i:54;O:15:"SqlParser\Token":5:{s:5:"token";s:3:"
+ ";s:5:"value";s:1:" ";s:4:"type";i:3;s:5:"flags";i:0;s:8:"position";i:148;}i:55;O:15:"SqlParser\Token":5:{s:5:"token";s:3:"END";s:5:"value";s:3:"END";s:4:"type";i:1;s:5:"flags";i:1;s:8:"position";i:151;}i:56;O:15:"SqlParser\Token":5:{s:5:"token";s:1:" ";s:5:"value";s:1:" ";s:4:"type";i:3;s:5:"flags";i:0;s:8:"position";i:154;}i:57;O:15:"SqlParser\Token":5:{s:5:"token";s:4:"LOOP";s:5:"value";s:4:"LOOP";s:4:"type";i:1;s:5:"flags";i:3;s:8:"position";i:155;}i:58;O:15:"SqlParser\Token":5:{s:5:"token";s:1:" ";s:5:"value";s:1:" ";s:4:"type";i:3;s:5:"flags";i:0;s:8:"position";i:159;}i:59;O:15:"SqlParser\Token":5:{s:5:"token";s:6:"label1";s:5:"value";s:6:"label1";s:4:"type";i:0;s:5:"flags";i:0;s:8:"position";i:160;}i:60;O:15:"SqlParser\Token":5:{s:5:"token";s:1:";";s:5:"value";s:1:";";s:4:"type";i:9;s:5:"flags";i:0;s:8:"position";i:166;}i:61;O:15:"SqlParser\Token":5:{s:5:"token";s:3:"
+ ";s:5:"value";s:1:" ";s:4:"type";i:3;s:5:"flags";i:0;s:8:"position";i:167;}i:62;O:15:"SqlParser\Token":5:{s:5:"token";s:3:"SET";s:5:"value";s:3:"SET";s:4:"type";i:1;s:5:"flags";i:11;s:8:"position";i:170;}i:63;O:15:"SqlParser\Token":5:{s:5:"token";s:1:" ";s:5:"value";s:1:" ";s:4:"type";i:3;s:5:"flags";i:0;s:8:"position";i:173;}i:64;O:15:"SqlParser\Token":5:{s:5:"token";s:2:"@x";s:5:"value";s:1:"x";s:4:"type";i:8;s:5:"flags";i:1;s:8:"position";i:174;}i:65;O:15:"SqlParser\Token":5:{s:5:"token";s:1:" ";s:5:"value";s:1:" ";s:4:"type";i:3;s:5:"flags";i:0;s:8:"position";i:176;}i:66;O:15:"SqlParser\Token":5:{s:5:"token";s:1:"=";s:5:"value";s:1:"=";s:4:"type";i:2;s:5:"flags";i:2;s:8:"position";i:177;}i:67;O:15:"SqlParser\Token":5:{s:5:"token";s:1:" ";s:5:"value";s:1:" ";s:4:"type";i:3;s:5:"flags";i:0;s:8:"position";i:178;}i:68;O:15:"SqlParser\Token":5:{s:5:"token";s:2:"p1";s:5:"value";s:2:"p1";s:4:"type";i:0;s:5:"flags";i:0;s:8:"position";i:179;}i:69;O:15:"SqlParser\Token":5:{s:5:"token";s:1:";";s:5:"value";s:1:";";s:4:"type";i:9;s:5:"flags";i:0;s:8:"position";i:181;}i:70;O:15:"SqlParser\Token":5:{s:5:"token";s:1:"
+";s:5:"value";s:1:" ";s:4:"type";i:3;s:5:"flags";i:0;s:8:"position";i:182;}i:71;O:15:"SqlParser\Token":5:{s:5:"token";s:3:"END";s:5:"value";s:3:"END";s:4:"type";i:1;s:5:"flags";i:1;s:8:"position";i:183;}i:72;O:15:"SqlParser\Token":5:{s:5:"token";N;s:5:"value";N;s:4:"type";i:9;s:5:"flags";i:0;s:8:"position";N;}}s:5:"count";i:73;s:3:"idx";i:74;}s:9:"delimiter";s:1:";";s:12:"delimiterLen";i:1;s:6:"errors";a:0:{}}s:6:"parser";O:16:"SqlParser\Parser":5:{s:4:"list";r:8;s:6:"strict";b:0;s:6:"errors";a:0:{}s:10:"statements";a:1:{i:0;O:36:"SqlParser\Statements\CreateStatement":17:{s:4:"name";O:31:"SqlParser\Components\Expression":7:{s:8:"database";N;s:5:"table";s:9:"doiterate";s:6:"column";N;s:4:"expr";s:9:"doiterate";s:5:"alias";N;s:8:"function";N;s:8:"subquery";N;}s:13:"entityOptions";O:33:"SqlParser\Components\OptionsArray":1:{s:7:"options";a:0:{}}s:6:"fields";N;s:6:"select";N;s:4:"like";N;s:11:"partitionBy";N;s:13:"partitionsNum";N;s:14:"subpartitionBy";N;s:16:"subpartitionsNum";N;s:10:"partitions";N;s:5:"table";N;s:6:"return";N;s:10:"parameters";a:1:{i:0;O:40:"SqlParser\Components\ParameterDefinition":3:{s:4:"name";s:2:"p1";s:5:"inOut";N;s:4:"type";O:29:"SqlParser\Components\DataType":3:{s:4:"name";s:3:"INT";s:10:"parameters";a:0:{}s:7:"options";O:33:"SqlParser\Components\OptionsArray":1:{s:7:"options";a:0:{}}}}}s:4:"body";a:62:{i:0;r:76;i:1;r:82;i:2;r:88;i:3;r:94;i:4;r:100;i:5;r:106;i:6;r:112;i:7;r:118;i:8;r:124;i:9;r:130;i:10;r:136;i:11;r:142;i:12;r:148;i:13;r:154;i:14;r:160;i:15;r:166;i:16;r:172;i:17;r:178;i:18;r:184;i:19;r:190;i:20;r:196;i:21;r:202;i:22;r:208;i:23;r:214;i:24;r:220;i:25;r:226;i:26;r:232;i:27;r:238;i:28;r:244;i:29;r:250;i:30;r:256;i:31;r:262;i:32;r:268;i:33;r:274;i:34;r:280;i:35;r:286;i:36;r:292;i:37;r:298;i:38;r:304;i:39;r:310;i:40;r:316;i:41;r:322;i:42;r:328;i:43;r:334;i:44;r:340;i:45;r:346;i:46;r:352;i:47;r:358;i:48;r:364;i:49;r:370;i:50;r:376;i:51;r:382;i:52;r:388;i:53;r:394;i:54;r:400;i:55;r:406;i:56;r:412;i:57;r:418;i:58;r:424;i:59;r:430;i:60;r:436;i:61;r:442;}s:7:"options";O:33:"SqlParser\Components\OptionsArray":1:{s:7:"options";a:1:{i:6;s:9:"PROCEDURE";}}s:5:"first";i:0;s:4:"last";i:73;}}s:8:"brackets";i:0;}s:6:"errors";a:2:{s:5:"lexer";a:0:{}s:6:"parser";a:0:{}}} \ No newline at end of file