Skip to content

Commit 1913498

Browse files
committed
Merge #386 - Fixed differentiating between analyze and explain statements
Ref: phpmyadmin/phpmyadmin#17482 Pull-request: #386 Signed-off-by: William Desportes <[email protected]>
2 parents a9cd167 + f987fcd commit 1913498

11 files changed

+1473
-27
lines changed

phpstan-baseline.neon

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -532,7 +532,12 @@ parameters:
532532

533533
-
534534
message: "#^Cannot access property \\$idx on PhpMyAdmin\\\\SqlParser\\\\TokensList\\|null\\.$#"
535-
count: 8
535+
count: 12
536+
path: src/Parser.php
537+
538+
-
539+
message: "#^Cannot access property \\$keyword on PhpMyAdmin\\\\SqlParser\\\\Token\\|null\\.$#"
540+
count: 2
536541
path: src/Parser.php
537542

538543
-
@@ -542,7 +547,7 @@ parameters:
542547

543548
-
544549
message: "#^Cannot call method getNextOfType\\(\\) on PhpMyAdmin\\\\SqlParser\\\\TokensList\\|null\\.$#"
545-
count: 2
550+
count: 4
546551
path: src/Parser.php
547552

548553
-
@@ -960,11 +965,6 @@ parameters:
960965
count: 1
961966
path: src/Utils/Query.php
962967

963-
-
964-
message: "#^Method PhpMyAdmin\\\\SqlParser\\\\Utils\\\\Query\\:\\:getFlags\\(\\) should return array\\{distinct\\?\\: bool, drop_database\\?\\: bool, group\\?\\: bool, having\\?\\: bool, is_affected\\?\\: bool, is_analyse\\?\\: bool, is_count\\?\\: bool, is_delete\\?\\: bool, \\.\\.\\.\\} but returns non\\-empty\\-array\\<literal\\-string&non\\-falsy\\-string, bool\\|\\(literal\\-string&non\\-falsy\\-string\\)\\>\\.$#"
965-
count: 1
966-
path: src/Utils/Query.php
967-
968968
-
969969
message: "#^Parameter \\#1 \\$component of static method PhpMyAdmin\\\\SqlParser\\\\Components\\\\Expression\\:\\:build\\(\\) expects array\\<PhpMyAdmin\\\\SqlParser\\\\Components\\\\Expression\\>\\|PhpMyAdmin\\\\SqlParser\\\\Components\\\\Expression, object given\\.$#"
970970
count: 1

psalm-baseline.xml

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<?xml version="1.0" encoding="UTF-8"?>
2-
<files psalm-version="4.27.0@faf106e717c37b8c81721845dba9de3d8deed8ff">
2+
<files psalm-version="4.30.0@d0bc6e25d89f649e4f36a534f330f8bb4643dd69">
33
<file src="src/Component.php">
44
<MixedReturnStatement occurrences="1">
55
<code>static::build($this)</code>
@@ -785,10 +785,12 @@
785785
<InvalidStringClass occurrences="1">
786786
<code>new $class($this, $this-&gt;list)</code>
787787
</InvalidStringClass>
788-
<MixedArrayOffset occurrences="1">
788+
<MixedArrayOffset occurrences="2">
789+
<code>static::$STATEMENT_PARSERS[$statementName ?? $token-&gt;keyword]</code>
789790
<code>static::$STATEMENT_PARSERS[$token-&gt;keyword]</code>
790791
</MixedArrayOffset>
791-
<MixedArrayTypeCoercion occurrences="1">
792+
<MixedArrayTypeCoercion occurrences="2">
793+
<code>static::$STATEMENT_PARSERS[$statementName ?? $token-&gt;keyword]</code>
792794
<code>static::$STATEMENT_PARSERS[$token-&gt;keyword]</code>
793795
</MixedArrayTypeCoercion>
794796
<ParamNameMismatch occurrences="1">
@@ -803,29 +805,41 @@
803805
<PossiblyNullArrayAccess occurrences="1">
804806
<code>$list-&gt;tokens[$list-&gt;idx]</code>
805807
</PossiblyNullArrayAccess>
806-
<PossiblyNullArrayOffset occurrences="1">
808+
<PossiblyNullArrayOffset occurrences="2">
807809
<code>$list-&gt;tokens</code>
810+
<code>static::$STATEMENT_PARSERS</code>
808811
</PossiblyNullArrayOffset>
809-
<PossiblyNullOperand occurrences="2">
812+
<PossiblyNullOperand occurrences="3">
813+
<code>$list-&gt;idx</code>
810814
<code>$list-&gt;idx</code>
811815
<code>$prevLastIdx</code>
812816
</PossiblyNullOperand>
813-
<PossiblyNullPropertyAssignment occurrences="1">
817+
<PossiblyNullPropertyAssignment occurrences="2">
818+
<code>$list</code>
814819
<code>$list</code>
815820
</PossiblyNullPropertyAssignment>
816-
<PossiblyNullPropertyFetch occurrences="7">
821+
<PossiblyNullPropertyAssignmentValue occurrences="1">
822+
<code>$lastIdx</code>
823+
</PossiblyNullPropertyAssignmentValue>
824+
<PossiblyNullPropertyFetch occurrences="9">
825+
<code>$first-&gt;keyword</code>
817826
<code>$list-&gt;count</code>
818827
<code>$list-&gt;idx</code>
819828
<code>$list-&gt;tokens</code>
829+
<code>$second-&gt;keyword</code>
820830
<code>$token-&gt;keyword</code>
821831
<code>$token-&gt;token</code>
822832
<code>$token-&gt;type</code>
823833
<code>$token-&gt;value</code>
824834
</PossiblyNullPropertyFetch>
825-
<PossiblyNullReference occurrences="2">
835+
<PossiblyNullReference occurrences="3">
836+
<code>getNextOfType</code>
826837
<code>getNextOfType</code>
827838
<code>getNextOfType</code>
828839
</PossiblyNullReference>
840+
<UnnecessaryVarAnnotation occurrences="1">
841+
<code>string</code>
842+
</UnnecessaryVarAnnotation>
829843
</file>
830844
<file src="src/Statement.php">
831845
<DocblockTypeContradiction occurrences="2">

src/Parser.php

Lines changed: 33 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -466,27 +466,48 @@ public function parse()
466466
continue;
467467
}
468468

469-
// Checking if it is a known statement that can be parsed.
470-
if (empty(static::$STATEMENT_PARSERS[$token->keyword])) {
471-
if (! isset(static::$STATEMENT_PARSERS[$token->keyword])) {
472-
// A statement is considered recognized if the parser
473-
// is aware that it is a statement, but it does not have
474-
// a parser for it yet.
475-
$this->error('Unrecognized statement type.', $token);
469+
$lastIdx = $list->idx;
470+
$statementName = null;
471+
472+
if ($token->keyword === 'ANALYZE') {
473+
++$list->idx; // Skip ANALYZE
474+
475+
$first = $list->getNextOfType(Token::TYPE_KEYWORD);
476+
$second = $list->getNextOfType(Token::TYPE_KEYWORD);
477+
478+
// ANALYZE keyword can be an indication of two cases:
479+
// 1 - ANALYZE TABLE statements, in both MariaDB and MySQL
480+
// 2 - Explain statement, in case of MariaDB https://mariadb.com/kb/en/explain-analyze/
481+
// We need to point case 2 to use the EXPLAIN Parser.
482+
$statementName = 'EXPLAIN';
483+
if ($first->keyword === 'TABLE' || $second->keyword === 'TABLE') {
484+
$statementName = 'ANALYZE';
476485
}
477486

478-
// Skipping to the end of this statement.
479-
$list->getNextOfType(Token::TYPE_DELIMITER);
480-
$prevLastIdx = $list->idx;
481-
continue;
487+
$list->idx = $lastIdx;
488+
} else {
489+
// Checking if it is a known statement that can be parsed.
490+
if (empty(static::$STATEMENT_PARSERS[$token->keyword])) {
491+
if (! isset(static::$STATEMENT_PARSERS[$token->keyword])) {
492+
// A statement is considered recognized if the parser
493+
// is aware that it is a statement, but it does not have
494+
// a parser for it yet.
495+
$this->error('Unrecognized statement type.', $token);
496+
}
497+
498+
// Skipping to the end of this statement.
499+
$list->getNextOfType(Token::TYPE_DELIMITER);
500+
$prevLastIdx = $list->idx;
501+
continue;
502+
}
482503
}
483504

484505
/**
485506
* The name of the class that is used for parsing.
486507
*
487508
* @var string
488509
*/
489-
$class = static::$STATEMENT_PARSERS[$token->keyword];
510+
$class = static::$STATEMENT_PARSERS[$statementName ?? $token->keyword];
490511

491512
/**
492513
* Processed statement.
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace PhpMyAdmin\SqlParser\Tests\Parser;
6+
7+
use PhpMyAdmin\SqlParser\Tests\TestCase;
8+
9+
class AnalyzeStatementTest extends TestCase
10+
{
11+
/**
12+
* @dataProvider analyzeProvider
13+
*/
14+
public function testAnalyze(string $test): void
15+
{
16+
$this->runParserTest($test);
17+
}
18+
19+
/**
20+
* @return string[][]
21+
*/
22+
public function analyzeProvider(): array
23+
{
24+
return [
25+
['parser/parseAnalyzeTable'],
26+
['parser/parseAnalyzeTable1'],
27+
];
28+
}
29+
}

tests/Parser/ExplainStatementTest.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ public function explainProvider(): array
2323
{
2424
return [
2525
['parser/parseExplain'],
26+
['parser/parseExplain1'],
2627
];
2728
}
2829
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
ANALYZE TABLE tbl

0 commit comments

Comments
 (0)