Skip to content

Commit 6d9d426

Browse files
committed
Supports SHOW INDEX syntax
1 parent 514e9b9 commit 6d9d426

File tree

5 files changed

+152
-3
lines changed

5 files changed

+152
-3
lines changed

src/FakePdoStatementTrait.php

+4
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,10 @@ function ($row) {
243243

244244
break;
245245

246+
case Query\ShowIndexQuery::class:
247+
$this->result = Processor\ShowIndexProcessor::process($this->conn, $parsed_query->table);
248+
break;
249+
246250
default:
247251
throw new \UnexpectedValueException('Unsupported operation type ' . $sql);
248252
}

src/Parser/ShowParser.php

+34-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
<?php
22
namespace Vimeo\MysqlEngine\Parser;
33

4+
use Vimeo\MysqlEngine\Query\ShowIndexQuery;
45
use Vimeo\MysqlEngine\TokenType;
56
use Vimeo\MysqlEngine\Query\ShowTablesQuery;
67

@@ -33,18 +34,33 @@ public function __construct(array $tokens, string $sql)
3334
$this->sql = $sql;
3435
}
3536

36-
public function parse() : ShowTablesQuery
37+
/**
38+
* @return ShowTablesQuery|ShowIndexQuery
39+
* @throws ParserException
40+
*/
41+
public function parse()
3742
{
3843
if ($this->tokens[$this->pointer]->value !== 'SHOW') {
3944
throw new ParserException("Parser error: expected SHOW");
4045
}
4146

4247
$this->pointer++;
4348

44-
if ($this->tokens[$this->pointer]->value !== 'TABLES') {
45-
throw new ParserException("Parser error: expected SHOW TABLES");
49+
switch ($this->tokens[$this->pointer]->value) {
50+
case 'TABLES':
51+
return $this->parseShowTables();
52+
case 'INDEX':
53+
case 'INDEXES':
54+
case 'KEYS':
55+
return $this->parseShowIndex();
56+
default:
57+
throw new ParserException("Parser error: expected SHOW TABLES");
4658
}
4759

60+
}
61+
62+
private function parseShowTables()
63+
{
4864
$this->pointer++;
4965

5066
if ($this->tokens[$this->pointer]->value !== 'LIKE') {
@@ -61,4 +77,19 @@ public function parse() : ShowTablesQuery
6177

6278
return new ShowTablesQuery($token->value, $this->sql);
6379
}
80+
81+
private function parseShowIndex()
82+
{
83+
$this->pointer++;
84+
85+
if ($this->tokens[$this->pointer]->value !== 'FROM') {
86+
throw new ParserException("Parser error: expected SHOW INDEX FROM");
87+
}
88+
$this->pointer++;
89+
$token = $this->tokens[$this->pointer];
90+
if ($token === null || $token->type !== TokenType::IDENTIFIER) {
91+
throw new ParserException("Expected table name after FROM");
92+
}
93+
return new ShowIndexQuery($token->value, $this->sql);
94+
}
6495
}

src/Processor/ShowIndexProcessor.php

+58
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
<?php
2+
3+
4+
namespace Vimeo\MysqlEngine\Processor;
5+
6+
7+
use Vimeo\MysqlEngine\FakePdoInterface;
8+
9+
class ShowIndexProcessor extends Processor
10+
{
11+
public static function process(
12+
FakePdoInterface $conn,
13+
string $table
14+
): array
15+
{
16+
$result = [];
17+
[$database, $table] = Processor::parseTableName($conn, $table);
18+
$table_definition = $conn->getServer()->getTableDefinition(
19+
$database,
20+
$table
21+
);
22+
foreach ($table_definition->indexes as $name => $index) {
23+
foreach ($index->columns as $i => $column) {
24+
$result[] = [
25+
'Table' => $table_definition->name,
26+
'Non_unique' => $index->type === 'INDEX' ? 1 : 0,
27+
'Key_name' => $name,
28+
'Seq_in_index' => $i+1,
29+
'Column_name' => $column,
30+
/*
31+
* https://dev.mysql.com/doc/refman/5.6/ja/create-index.html
32+
* index_col_name の指定を ASC または DESC で終了させることができます。
33+
* これらのキーワードは、インデックス値の昇順または降順での格納を指定する将来の拡張のために許可されています。
34+
* 現在、これらは解析されますが、無視されます。インデックス値は、常に昇順で格納されます。
35+
*/
36+
'Collation' => 'A',
37+
/*
38+
* https://dev.mysql.com/doc/refman/5.6/ja/analyze-table.html
39+
* ANALYZE TABLE が未実装のため null
40+
*/
41+
'Cardinality' => null,
42+
// Index には "length" がない(CreateIndex の $cols にはある)ため null
43+
'Sub_part' => null,
44+
// PACK_KEYS が未実装のため null
45+
'Packed' => null,
46+
'Null' => $table_definition->columns[$column]->isNullable ? 'YES' : '',
47+
// Index には $mode がない(CreateIndex にはある)ため null
48+
'Index_type' => null,
49+
// DISABLE KEYS 未実装のため ''
50+
'Comment' => '',
51+
// CREATE TABLE の INDEX COMMENT がスキップされているので ''
52+
'Index_comment' => ''
53+
];
54+
}
55+
}
56+
return $result;
57+
}
58+
}

src/Query/ShowIndexQuery.php

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?php
2+
namespace Vimeo\MysqlEngine\Query;
3+
4+
final class ShowIndexQuery
5+
{
6+
/**
7+
* @var string
8+
*/
9+
public $table;
10+
11+
/**
12+
* @var string
13+
*/
14+
public $sql;
15+
16+
public function __construct(string $table, string $sql)
17+
{
18+
$this->table = $table;
19+
$this->sql = $sql;
20+
}
21+
}

tests/ShowIndexParseTest.php

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<?php
2+
namespace Vimeo\MysqlEngine\Tests;
3+
4+
class ShowIndexParseTest extends \PHPUnit\Framework\TestCase
5+
{
6+
public function testSimpleParse()
7+
{
8+
$query = 'SHOW INDEX FROM foo';
9+
10+
$show_query = \Vimeo\MysqlEngine\Parser\SQLParser::parse($query);
11+
12+
$this->assertInstanceOf(\Vimeo\MysqlEngine\Query\ShowIndexQuery::class, $show_query);
13+
$this->assertSame('foo', $show_query->table);
14+
}
15+
16+
public function testIndexesParse()
17+
{
18+
$query = 'SHOW INDEXES FROM foo';
19+
20+
$show_query = \Vimeo\MysqlEngine\Parser\SQLParser::parse($query);
21+
22+
$this->assertInstanceOf(\Vimeo\MysqlEngine\Query\ShowIndexQuery::class, $show_query);
23+
$this->assertSame('foo', $show_query->table);
24+
}
25+
26+
public function testKeysParse()
27+
{
28+
$query = 'SHOW KEYS FROM foo';
29+
30+
$show_query = \Vimeo\MysqlEngine\Parser\SQLParser::parse($query);
31+
32+
$this->assertInstanceOf(\Vimeo\MysqlEngine\Query\ShowIndexQuery::class, $show_query);
33+
$this->assertSame('foo', $show_query->table);
34+
}
35+
}

0 commit comments

Comments
 (0)