Skip to content

Commit c4f7b22

Browse files
committed
Fixed a bug that didn't parse comments properly.
getFirstStatement util doesn't ignore MySQL specific query anymore (between comments). Misc coding style fixes. Fixed tests.
1 parent 9130cca commit c4f7b22

8 files changed

Lines changed: 79 additions & 31 deletions

File tree

src/Context.php

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -297,13 +297,13 @@ public static function isComment($str)
297297
$len = strlen($str);
298298
if ($str[0] === '#') {
299299
return Token::FLAG_COMMENT_BASH;
300-
} elseif (($len > 1) && ((($str[0] === '/') && ($str[1] === '*'))
301-
|| (($str[0] === '*') && ($str[1] === '/')))
302-
) {
300+
} elseif (($len > 1) && ($str[0] === '/') && ($str[1] === '*')) {
301+
return (($len > 2) && ($str[2] == '!')) ?
302+
Token::FLAG_COMMENT_MYSQL_CMD : Token::FLAG_COMMENT_C;
303+
} elseif (($len > 1) && ($str[0] === '*') && ($str[1] === '/')) {
303304
return Token::FLAG_COMMENT_C;
304305
} elseif (($len > 2) && ($str[0] === '-')
305-
&& ($str[1] === '-') && ($str[2] !== "\n")
306-
&& (static::isWhitespace($str[2]))
306+
&& ($str[1] === '-') && (static::isWhitespace($str[2]))
307307
) {
308308
return Token::FLAG_COMMENT_SQL;
309309
}

src/Lexer.php

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -506,7 +506,7 @@ public function parseComment()
506506
while ((++$this->last < $this->len) && ($this->str[$this->last] !== "\n")) {
507507
$token .= $this->str[$this->last];
508508
}
509-
$token .= $this->str[$this->last];
509+
$token .= "\n"; // Adding the line ending.
510510
return new Token($token, Token::TYPE_COMMENT, Token::FLAG_COMMENT_BASH);
511511
}
512512

@@ -519,11 +519,14 @@ public function parseComment()
519519
// It is a MySQL-specific command.
520520
$flags |= Token::FLAG_COMMENT_MYSQL_CMD;
521521
}
522-
while ((++$this->last < $this->len) &&
523-
(($this->str[$this->last - 1] !== '*') || ($this->str[$this->last] !== '/'))) {
522+
while ((++$this->last < $this->len)
523+
&& (($this->str[$this->last - 1] !== '*') || ($this->str[$this->last] !== '/'))
524+
) {
525+
$token .= $this->str[$this->last];
526+
}
527+
if ($this->last < $this->len) {
524528
$token .= $this->str[$this->last];
525529
}
526-
$token .= $this->str[$this->last];
527530
return new Token($token, Token::TYPE_COMMENT, $flags);
528531
}
529532
}
@@ -532,14 +535,12 @@ public function parseComment()
532535
if (++$this->last < $this->len) {
533536
$token .= $this->str[$this->last];
534537
if (Context::isComment($token)) {
538+
// Checking if this comment did not end already (```--\n```).
535539
if ($this->str[$this->last] !== "\n") {
536-
// Checking if this comment did not end already (```--\n```).
537540
while ((++$this->last < $this->len) && ($this->str[$this->last] !== "\n")) {
538541
$token .= $this->str[$this->last];
539542
}
540-
541-
// Adding the line ending.
542-
$token .= "\n";
543+
$token .= "\n"; // Adding the line ending.
543544
}
544545
return new Token($token, Token::TYPE_COMMENT, Token::FLAG_COMMENT_SQL);
545546
}
@@ -779,13 +780,17 @@ public function parseSymbol()
779780
$token = '';
780781
}
781782

782-
if (($str = $this->parseString('`')) === null) {
783-
if (($str = static::parseUnknown()) === null) {
784-
$this->error(
785-
__('Variable name was expected.'),
786-
$this->str[$this->last],
787-
$this->last
788-
);
783+
$str = null;
784+
785+
if ($this->last < $this->len) {
786+
if (($str = $this->parseString('`')) === null) {
787+
if (($str = static::parseUnknown()) === null) {
788+
$this->error(
789+
__('Variable name was expected.'),
790+
$this->str[$this->last],
791+
$this->last
792+
);
793+
}
789794
}
790795
}
791796

@@ -823,7 +828,7 @@ public function parseDelimiter()
823828
{
824829
$idx = 0;
825830

826-
while ($idx < $this->delimiterLen) {
831+
while (($idx < $this->delimiterLen) && ($this->last + $idx < $this->len)) {
827832
if ($this->delimiter[$idx] !== $this->str[$this->last + $idx]) {
828833
return null;
829834
}

src/Statement.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -262,7 +262,7 @@ public function parse(Parser $parser, TokensList $list)
262262
// this statement it means it is a new statement, but no
263263
// delimiter was found between them.
264264
$parser->error(
265-
__('A new statement was found, but no delimiter between them.'),
265+
__('A new statement was found, but no delimiter between it and the previous one.'),
266266
$token
267267
);
268268
break;

src/Utils/Query.php

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -743,14 +743,16 @@ public static function getFirstStatement($query, $delimiter = null)
743743
for ($list->idx = 0; $list->idx < $list->count; ++$list->idx) {
744744
$token = $list->tokens[$list->idx];
745745

746-
if ($token->type === Token::TYPE_COMMENT) {
746+
if (($token->type === Token::TYPE_COMMENT)
747+
&& (!($token->flags & Token::FLAG_COMMENT_MYSQL_CMD))
748+
) {
747749
continue;
748750
}
749751

750752
$statement .= $token->token;
751753

752-
if (($token->type === Token::TYPE_DELIMITER) && (!empty($token->value))) {
753-
$delimiter = $token->value;
754+
if (($token->type === Token::TYPE_DELIMITER) && (!empty($token->token))) {
755+
$delimiter = $token->token;
754756
$fullStatement = true;
755757
break;
756758
}
@@ -766,7 +768,7 @@ public static function getFirstStatement($query, $delimiter = null)
766768
// remaining query.
767769
$query = '';
768770
for (++$list->idx; $list->idx < $list->count; ++$list->idx) {
769-
$query .= $list->tokens[$list->idx]->value;
771+
$query .= $list->tokens[$list->idx]->token;
770772
}
771773

772774
return array(trim($statement), $query, $delimiter);

tests/Lexer/IsMethodsTest.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,13 +64,13 @@ public function testIsComment()
6464
$this->assertEquals(Token::FLAG_COMMENT_C, Context::isComment('*/'));
6565
$this->assertEquals(Token::FLAG_COMMENT_SQL, Context::isComment('-- '));
6666
$this->assertEquals(Token::FLAG_COMMENT_SQL, Context::isComment("--\t"));
67+
$this->assertEquals(Token::FLAG_COMMENT_SQL, Context::isComment("--\n"));
6768

6869
$this->assertEquals(Token::FLAG_COMMENT_BASH, Context::isComment('# a comment'));
6970
$this->assertEquals(Token::FLAG_COMMENT_C, Context::isComment('/*comment */'));
7071
$this->assertEquals(Token::FLAG_COMMENT_SQL, Context::isComment('-- my comment'));
7172

72-
$this->assertEquals(Context::isComment("--\n"), null);
73-
$this->assertEquals(Context::isComment('--not a comment'), null);
73+
$this->assertEquals(null, Context::isComment('--not a comment'));
7474
}
7575

7676
public function testIsBool()

tests/Utils/QueryTest.php

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -359,7 +359,7 @@ public function testGetClause()
359359
$parser = new Parser(
360360
'SELECT c.city_id, c.country_id ' .
361361
'FROM `city` ' .
362-
'WHERE city_id < 1 ' .
362+
'WHERE city_id < 1 /* test */' .
363363
'ORDER BY city_id ASC ' .
364364
'LIMIT 0, 1 ' .
365365
'INTO OUTFILE "/dev/null"'
@@ -458,4 +458,43 @@ public function testRepalceClauses()
458458
)
459459
);
460460
}
461+
462+
public function testGetFirstStatement()
463+
{
464+
$query = 'USE saki';
465+
$delimiter = null;
466+
list($statement, $query, $delimiter) =
467+
Query::getFirstStatement($query, $delimiter);
468+
$this->assertEquals(null, $statement);
469+
$this->assertEquals('USE saki', $query);
470+
471+
$query = 'USE sakila; ' .
472+
'/*test comment*/' .
473+
'SELECT * FROM actor; '.
474+
'DELIMITER $$ ' .
475+
'UPDATE actor SET last_name = "abc"$$' .
476+
'/*!SELECT * FROM actor WHERE last_name = "abc"*/$$';
477+
$delimiter = null;
478+
479+
list($statement, $query, $delimiter) =
480+
Query::getFirstStatement($query, $delimiter);
481+
$this->assertEquals('USE sakila;', $statement);
482+
483+
list($statement, $query, $delimiter) =
484+
Query::getFirstStatement($query, $delimiter);
485+
$this->assertEquals('SELECT * FROM actor;', $statement);
486+
487+
list($statement, $query, $delimiter) =
488+
Query::getFirstStatement($query, $delimiter);
489+
$this->assertEquals('DELIMITER $$', $statement);
490+
$this->assertEquals('$$', $delimiter);
491+
492+
list($statement, $query, $delimiter) =
493+
Query::getFirstStatement($query, $delimiter);
494+
$this->assertEquals('UPDATE actor SET last_name = "abc"$$', $statement);
495+
496+
list($statement, $query, $delimiter) =
497+
Query::getFirstStatement($query, $delimiter);
498+
$this->assertEquals('/*!SELECT * FROM actor WHERE last_name = "abc"*/$$', $statement);
499+
}
461500
}

tests/data/bugs/gh9.out

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,4 +31,4 @@ COMMIT;";s:3:"len";i:213;s:4:"last";i:213;s:4:"list";O:20:"SqlParser\TokensList"
3131
";s:5:"value";s:1:" ";s:4:"type";i:3;s:5:"flags";i:0;s:8:"position";i:164;}i:55;O:15:"SqlParser\Token":5:{s:5:"token";s:5:"INDEX";s:5:"value";s:5:"INDEX";s:4:"type";i:1;s:5:"flags";i:19;s:8:"position";i:165;}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:170;}i:57;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:171;}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:172;}i:59;O:15:"SqlParser\Token":5:{s:5:"token";s:10:"`position`";s:5:"value";s:8:"position";s:4:"type";i:8;s:5:"flags";i:2;s:8:"position";i:173;}i:60;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:61;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:184;}i:62;O:15:"SqlParser\Token":5:{s:5:"token";s:1:"
3232
";s:5:"value";s:1:" ";s:4:"type";i:3;s:5:"flags";i:0;s:8:"position";i:185;}i:63;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:186;}i:64;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:187;}i:65;O:15:"SqlParser\Token":5:{s:5:"token";s:6:"ENGINE";s:5:"value";s:6:"ENGINE";s:4:"type";i:1;s:5:"flags";i:1;s:8:"position";i:188;}i:66;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:194;}i:67;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:195;}i:68;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:196;}i:69;O:15:"SqlParser\Token":5:{s:5:"token";s:6:"InnoDB";s:5:"value";s:6:"InnoDB";s:4:"type";i:0;s:5:"flags";i:0;s:8:"position";i:197;}i:70;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:203;}i:71;O:15:"SqlParser\Token":5:{s:5:"token";s:2:"
3333

34-
";s:5:"value";s:1:" ";s:4:"type";i:3;s:5:"flags";i:0;s:8:"position";i:204;}i:72;O:15:"SqlParser\Token":5:{s:5:"token";s:6:"COMMIT";s:5:"value";s:6:"COMMIT";s:4:"type";i:1;s:5:"flags";i:1;s:8:"position";i:206;}i:73;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:212;}i:74;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:75;s:3:"idx";i:75;}s:9:"delimiter";s:1:";";s:12:"delimiterLen";i:1;s:6:"errors";a:0:{}}s:6:"parser";O:16:"SqlParser\Parser":4:{s:4:"list";r:8;s:6:"strict";b:0;s:6:"errors";a:0:{}s:10:"statements";a:3:{i:0;O:36:"SqlParser\Statements\SelectStatement":15:{s:4:"expr";a:1:{i:0;O:31:"SqlParser\Components\Expression":7:{s:8:"database";N;s:5:"table";N;s:6:"column";N;s:4:"expr";s:1:"*";s:5:"alias";N;s:8:"function";N;s:8:"subquery";N;}}s:4:"from";a:1:{i:0;O:31:"SqlParser\Components\Expression":7:{s:8:"database";N;s:5:"table";s:3:"foo";s:6:"column";N;s:4:"expr";s:3:"foo";s:5:"alias";N;s:8:"function";N;s:8:"subquery";N;}}s:9:"partition";N;s:5:"where";a:0:{}s:5:"group";N;s:6:"having";N;s:5:"order";N;s:5:"limit";N;s:9:"procedure";N;s:4:"into";N;s:4:"join";N;s:5:"union";a:0:{}s:7:"options";O:33:"SqlParser\Components\OptionsArray":1:{s:7:"options";a:0:{}}s:5:"first";i:0;s:4:"last";i:9;}i:1;O:36:"SqlParser\Statements\SelectStatement":15:{s:4:"expr";a:1:{i:0;O:31:"SqlParser\Components\Expression":7:{s:8:"database";N;s:5:"table";N;s:6:"column";N;s:4:"expr";s:1:"*";s:5:"alias";N;s:8:"function";N;s:8:"subquery";N;}}s:4:"from";a:1:{i:0;O:31:"SqlParser\Components\Expression":7:{s:8:"database";N;s:5:"table";s:3:"foo";s:6:"column";N;s:4:"expr";s:3:"foo";s:5:"alias";N;s:8:"function";N;s:8:"subquery";N;}}s:9:"partition";N;s:5:"where";a:0:{}s:5:"group";N;s:6:"having";N;s:5:"order";N;s:5:"limit";N;s:9:"procedure";N;s:4:"into";N;s:4:"join";N;s:5:"union";a:0:{}s:7:"options";O:33:"SqlParser\Components\OptionsArray":1:{s:7:"options";a:0:{}}s:5:"first";i:10;s:4:"last";i:19;}i:2;O:41:"SqlParser\Statements\TransactionStatement":6:{s:4:"type";i:1;s:10:"statements";a:1:{i:0;O:36:"SqlParser\Statements\CreateStatement":10:{s:4:"name";O:31:"SqlParser\Components\Expression":7:{s:8:"database";N;s:5:"table";s:2:"tb";s:6:"column";N;s:4:"expr";s:4:"`tb`";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";a:1:{i:0;O:36:"SqlParser\Components\FieldDefinition":6:{s:4:"name";s:3:"uid";s:12:"isConstraint";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:1:{i:4;s:8:"UNSIGNED";}}}s:3:"key";N;s:10:"references";N;s:7:"options";O:33:"SqlParser\Components\OptionsArray":1:{s:7:"options";a:1:{i:1;s:8:"NOT NULL";}}}}s:5:"table";N;s:6:"return";N;s:10:"parameters";N;s:4:"body";a:0:{}s:7:"options";O:33:"SqlParser\Components\OptionsArray":1:{s:7:"options";a:1:{i:6;s:5:"TABLE";}}s:5:"first";i:21;s:4:"last";i:37;}}s:3:"end";O:41:"SqlParser\Statements\TransactionStatement":6:{s:4:"type";i:2;s:10:"statements";N;s:3:"end";N;s:7:"options";O:33:"SqlParser\Components\OptionsArray":1:{s:7:"options";a:1:{i:1;s:6:"COMMIT";}}s:5:"first";i:72;s:4:"last";i:72;}s:7:"options";O:33:"SqlParser\Components\OptionsArray":1:{s:7:"options";a:1:{i:1;s:17:"START TRANSACTION";}}s:5:"first";i:20;s:4:"last";i:20;}}}s:6:"errors";a:2:{s:5:"lexer";a:0:{}s:6:"parser";a:5:{i:0;a:3:{i:0;s:42:"This type of clause was previously parsed.";i:1;r:70;i:2;i:0;}i:1;a:3:{i:0;s:57:"A new statement was found, but no delimiter between them.";i:1;r:130;i:2;i:0;}i:2;a:3:{i:0;s:42:"A comma or a closing bracket was expected.";i:1;r:238;i:2;i:0;}i:3;a:3:{i:0;s:34:"Unexpected beginning of statement.";i:1;r:238;i:2;i:0;}i:4;a:3:{i:0;s:28:"Unrecognized statement type.";i:1;r:250;i:2;i:0;}}}}
34+
";s:5:"value";s:1:" ";s:4:"type";i:3;s:5:"flags";i:0;s:8:"position";i:204;}i:72;O:15:"SqlParser\Token":5:{s:5:"token";s:6:"COMMIT";s:5:"value";s:6:"COMMIT";s:4:"type";i:1;s:5:"flags";i:1;s:8:"position";i:206;}i:73;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:212;}i:74;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:75;s:3:"idx";i:75;}s:9:"delimiter";s:1:";";s:12:"delimiterLen";i:1;s:6:"errors";a:0:{}}s:6:"parser";O:16:"SqlParser\Parser":4:{s:4:"list";r:8;s:6:"strict";b:0;s:6:"errors";a:0:{}s:10:"statements";a:3:{i:0;O:36:"SqlParser\Statements\SelectStatement":15:{s:4:"expr";a:1:{i:0;O:31:"SqlParser\Components\Expression":7:{s:8:"database";N;s:5:"table";N;s:6:"column";N;s:4:"expr";s:1:"*";s:5:"alias";N;s:8:"function";N;s:8:"subquery";N;}}s:4:"from";a:1:{i:0;O:31:"SqlParser\Components\Expression":7:{s:8:"database";N;s:5:"table";s:3:"foo";s:6:"column";N;s:4:"expr";s:3:"foo";s:5:"alias";N;s:8:"function";N;s:8:"subquery";N;}}s:9:"partition";N;s:5:"where";a:0:{}s:5:"group";N;s:6:"having";N;s:5:"order";N;s:5:"limit";N;s:9:"procedure";N;s:4:"into";N;s:4:"join";N;s:5:"union";a:0:{}s:7:"options";O:33:"SqlParser\Components\OptionsArray":1:{s:7:"options";a:0:{}}s:5:"first";i:0;s:4:"last";i:9;}i:1;O:36:"SqlParser\Statements\SelectStatement":15:{s:4:"expr";a:1:{i:0;O:31:"SqlParser\Components\Expression":7:{s:8:"database";N;s:5:"table";N;s:6:"column";N;s:4:"expr";s:1:"*";s:5:"alias";N;s:8:"function";N;s:8:"subquery";N;}}s:4:"from";a:1:{i:0;O:31:"SqlParser\Components\Expression":7:{s:8:"database";N;s:5:"table";s:3:"foo";s:6:"column";N;s:4:"expr";s:3:"foo";s:5:"alias";N;s:8:"function";N;s:8:"subquery";N;}}s:9:"partition";N;s:5:"where";a:0:{}s:5:"group";N;s:6:"having";N;s:5:"order";N;s:5:"limit";N;s:9:"procedure";N;s:4:"into";N;s:4:"join";N;s:5:"union";a:0:{}s:7:"options";O:33:"SqlParser\Components\OptionsArray":1:{s:7:"options";a:0:{}}s:5:"first";i:10;s:4:"last";i:19;}i:2;O:41:"SqlParser\Statements\TransactionStatement":6:{s:4:"type";i:1;s:10:"statements";a:1:{i:0;O:36:"SqlParser\Statements\CreateStatement":10:{s:4:"name";O:31:"SqlParser\Components\Expression":7:{s:8:"database";N;s:5:"table";s:2:"tb";s:6:"column";N;s:4:"expr";s:4:"`tb`";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";a:1:{i:0;O:36:"SqlParser\Components\FieldDefinition":6:{s:4:"name";s:3:"uid";s:12:"isConstraint";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:1:{i:4;s:8:"UNSIGNED";}}}s:3:"key";N;s:10:"references";N;s:7:"options";O:33:"SqlParser\Components\OptionsArray":1:{s:7:"options";a:1:{i:1;s:8:"NOT NULL";}}}}s:5:"table";N;s:6:"return";N;s:10:"parameters";N;s:4:"body";a:0:{}s:7:"options";O:33:"SqlParser\Components\OptionsArray":1:{s:7:"options";a:1:{i:6;s:5:"TABLE";}}s:5:"first";i:21;s:4:"last";i:37;}}s:3:"end";O:41:"SqlParser\Statements\TransactionStatement":6:{s:4:"type";i:2;s:10:"statements";N;s:3:"end";N;s:7:"options";O:33:"SqlParser\Components\OptionsArray":1:{s:7:"options";a:1:{i:1;s:6:"COMMIT";}}s:5:"first";i:72;s:4:"last";i:72;}s:7:"options";O:33:"SqlParser\Components\OptionsArray":1:{s:7:"options";a:1:{i:1;s:17:"START TRANSACTION";}}s:5:"first";i:20;s:4:"last";i:20;}}}s:6:"errors";a:2:{s:5:"lexer";a:0:{}s:6:"parser";a:5:{i:0;a:3:{i:0;s:42:"This type of clause was previously parsed.";i:1;r:70;i:2;i:0;}i:1;a:3:{i:0;s:76:"A new statement was found, but no delimiter between it and the previous one.";i:1;r:130;i:2;i:0;}i:2;a:3:{i:0;s:42:"A comma or a closing bracket was expected.";i:1;r:238;i:2;i:0;}i:3;a:3:{i:0;s:34:"Unexpected beginning of statement.";i:1;r:238;i:2;i:0;}i:4;a:3:{i:0;s:28:"Unrecognized statement type.";i:1;r:250;i:2;i:0;}}}}

0 commit comments

Comments
 (0)