Skip to content

Commit 93ab20e

Browse files
Merge pull request #557 from MoonE/kill
Allow parsing KILL statement
2 parents 140a2b7 + 00255a8 commit 93ab20e

File tree

10 files changed

+424
-1
lines changed

10 files changed

+424
-1
lines changed

src/Parser.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ class Parser extends Core
4343
'BACKUP' => 'PhpMyAdmin\\SqlParser\\Statements\\BackupStatement',
4444
'CHECK' => 'PhpMyAdmin\\SqlParser\\Statements\\CheckStatement',
4545
'CHECKSUM' => 'PhpMyAdmin\\SqlParser\\Statements\\ChecksumStatement',
46+
'KILL' => 'PhpMyAdmin\\SqlParser\\Statements\\KillStatement',
4647
'OPTIMIZE' => 'PhpMyAdmin\\SqlParser\\Statements\\OptimizeStatement',
4748
'REPAIR' => 'PhpMyAdmin\\SqlParser\\Statements\\RepairStatement',
4849
'RESTORE' => 'PhpMyAdmin\\SqlParser\\Statements\\RestoreStatement',
@@ -210,6 +211,10 @@ class Parser extends Core
210211
'class' => 'PhpMyAdmin\\SqlParser\\Components\\JoinKeyword',
211212
'field' => 'join',
212213
],
214+
'KILL' => [
215+
'class' => 'PhpMyAdmin\\SqlParser\\Components\\Expression',
216+
'field' => 'processListId',
217+
],
213218
'LEFT JOIN' => [
214219
'class' => 'PhpMyAdmin\\SqlParser\\Components\\JoinKeyword',
215220
'field' => 'join',

src/Statements/KillStatement.php

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace PhpMyAdmin\SqlParser\Statements;
6+
7+
use PhpMyAdmin\SqlParser\Components\Expression;
8+
use PhpMyAdmin\SqlParser\Components\OptionsArray;
9+
use PhpMyAdmin\SqlParser\Statement;
10+
11+
use function trim;
12+
13+
/**
14+
* `KILL` statement.
15+
*
16+
* KILL [CONNECTION | QUERY] processlist_id
17+
*/
18+
class KillStatement extends Statement
19+
{
20+
/**
21+
* Options of this statement.
22+
*
23+
* @var array<string, int|array<int, int|string>>
24+
* @psalm-var array<string, (positive-int|array{positive-int, ('var'|'var='|'expr'|'expr=')})>
25+
*/
26+
public static $OPTIONS = [
27+
'CONNECTION' => 1,
28+
'QUERY' => 1,
29+
];
30+
31+
/** @var Expression|null */
32+
public $processListId = null;
33+
34+
public function build(): string
35+
{
36+
$option = $this->options === null || $this->options->isEmpty()
37+
? ''
38+
: ' ' . OptionsArray::build($this->options);
39+
$expression = $this->processListId === null ? '' : ' ' . Expression::build($this->processListId);
40+
41+
return trim('KILL' . $option . $expression);
42+
}
43+
}

src/Utils/Query.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
use PhpMyAdmin\SqlParser\Statements\DropStatement;
1919
use PhpMyAdmin\SqlParser\Statements\ExplainStatement;
2020
use PhpMyAdmin\SqlParser\Statements\InsertStatement;
21+
use PhpMyAdmin\SqlParser\Statements\KillStatement;
2122
use PhpMyAdmin\SqlParser\Statements\LoadStatement;
2223
use PhpMyAdmin\SqlParser\Statements\OptimizeStatement;
2324
use PhpMyAdmin\SqlParser\Statements\RenameStatement;
@@ -65,7 +66,7 @@
6566
* limit?: bool,
6667
* offset?: bool,
6768
* order?: bool,
68-
* querytype: ('ALTER'|'ANALYZE'|'CALL'|'CHECK'|'CHECKSUM'|'CREATE'|'DELETE'|'DROP'|'EXPLAIN'|'INSERT'|'LOAD'|'OPTIMIZE'|'REPAIR'|'REPLACE'|'SELECT'|'SET'|'SHOW'|'UPDATE'|false),
69+
* querytype: ('ALTER'|'ANALYZE'|'CALL'|'CHECK'|'CHECKSUM'|'CREATE'|'DELETE'|'DROP'|'EXPLAIN'|'INSERT'|'KILL'|'LOAD'|'OPTIMIZE'|'REPAIR'|'REPLACE'|'SELECT'|'SET'|'SHOW'|'UPDATE'|false),
6970
* reload?: bool,
7071
* select_from?: bool,
7172
* union?: bool
@@ -431,6 +432,8 @@ public static function getFlags($statement, $all = false)
431432
$flags['is_affected'] = true;
432433
} elseif ($statement instanceof SetStatement) {
433434
$flags['querytype'] = 'SET';
435+
} elseif ($statement instanceof KillStatement) {
436+
$flags['querytype'] = 'KILL';
434437
}
435438

436439
if (

tests/Parser/KillStatementTest.php

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace PhpMyAdmin\SqlParser\Tests\Parser;
6+
7+
use PhpMyAdmin\SqlParser\Parser;
8+
use PhpMyAdmin\SqlParser\Statements\KillStatement;
9+
use PhpMyAdmin\SqlParser\Tests\TestCase;
10+
11+
class KillStatementTest extends TestCase
12+
{
13+
/**
14+
* @dataProvider killProvider
15+
*/
16+
public function testKill(string $test): void
17+
{
18+
$this->runParserTest($test);
19+
}
20+
21+
/**
22+
* @return string[][]
23+
*/
24+
public function killProvider(): array
25+
{
26+
return [
27+
['parser/parseKill'],
28+
['parser/parseKillConnection'],
29+
['parser/parseKillQuery'],
30+
];
31+
}
32+
33+
/**
34+
* @dataProvider buildKillProvider
35+
*/
36+
public function testBuildKill(string $sql): void
37+
{
38+
$parser = new Parser($sql);
39+
$this->assertCount(1, $parser->statements);
40+
$statement = $parser->statements[0];
41+
$this->assertInstanceOf(KillStatement::class, $statement);
42+
$builtSql = $statement->build();
43+
$this->assertEquals($sql, $builtSql);
44+
}
45+
46+
/**
47+
* @return array<int, array<int, string>>
48+
* @psalm-return list<list<string>>
49+
*/
50+
public function buildKillProvider(): array
51+
{
52+
return [
53+
['KILL (SELECT 3 + 4)'],
54+
['KILL QUERY 3'],
55+
['KILL CONNECTION 3'],
56+
['KILL'],
57+
];
58+
}
59+
}

tests/data/parser/parseKill.in

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
KILL 1

tests/data/parser/parseKill.out

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
{
2+
"query": "KILL 1",
3+
"lexer": {
4+
"@type": "PhpMyAdmin\\SqlParser\\Lexer",
5+
"str": "KILL 1",
6+
"len": 6,
7+
"last": 6,
8+
"list": {
9+
"@type": "PhpMyAdmin\\SqlParser\\TokensList",
10+
"tokens": [
11+
{
12+
"@type": "PhpMyAdmin\\SqlParser\\Token",
13+
"token": "KILL",
14+
"value": "KILL",
15+
"keyword": "KILL",
16+
"type": 1,
17+
"flags": 3,
18+
"position": 0
19+
},
20+
{
21+
"@type": "PhpMyAdmin\\SqlParser\\Token",
22+
"token": " ",
23+
"value": " ",
24+
"keyword": null,
25+
"type": 3,
26+
"flags": 0,
27+
"position": 4
28+
},
29+
{
30+
"@type": "PhpMyAdmin\\SqlParser\\Token",
31+
"token": "1",
32+
"value": 1,
33+
"keyword": null,
34+
"type": 6,
35+
"flags": 0,
36+
"position": 5
37+
},
38+
{
39+
"@type": "PhpMyAdmin\\SqlParser\\Token",
40+
"token": null,
41+
"value": null,
42+
"keyword": null,
43+
"type": 9,
44+
"flags": 0,
45+
"position": null
46+
}
47+
],
48+
"count": 4,
49+
"idx": 4
50+
},
51+
"delimiter": ";",
52+
"delimiterLen": 1,
53+
"strict": false,
54+
"errors": []
55+
},
56+
"parser": {
57+
"@type": "PhpMyAdmin\\SqlParser\\Parser",
58+
"list": {
59+
"@type": "@1"
60+
},
61+
"statements": [
62+
{
63+
"@type": "PhpMyAdmin\\SqlParser\\Statements\\KillStatement",
64+
"processListId": {
65+
"@type": "PhpMyAdmin\\SqlParser\\Components\\Expression",
66+
"database": null,
67+
"table": null,
68+
"column": null,
69+
"expr": "1",
70+
"alias": null,
71+
"function": null,
72+
"subquery": null
73+
},
74+
"options": {
75+
"@type": "PhpMyAdmin\\SqlParser\\Components\\OptionsArray",
76+
"options": []
77+
},
78+
"first": 0,
79+
"last": 2
80+
}
81+
],
82+
"brackets": 0,
83+
"strict": false,
84+
"errors": []
85+
},
86+
"errors": {
87+
"lexer": [],
88+
"parser": []
89+
}
90+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
KILL CONNECTION 1
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
{
2+
"query": "KILL CONNECTION 1",
3+
"lexer": {
4+
"@type": "PhpMyAdmin\\SqlParser\\Lexer",
5+
"str": "KILL CONNECTION 1",
6+
"len": 17,
7+
"last": 17,
8+
"list": {
9+
"@type": "PhpMyAdmin\\SqlParser\\TokensList",
10+
"tokens": [
11+
{
12+
"@type": "PhpMyAdmin\\SqlParser\\Token",
13+
"token": "KILL",
14+
"value": "KILL",
15+
"keyword": "KILL",
16+
"type": 1,
17+
"flags": 3,
18+
"position": 0
19+
},
20+
{
21+
"@type": "PhpMyAdmin\\SqlParser\\Token",
22+
"token": " ",
23+
"value": " ",
24+
"keyword": null,
25+
"type": 3,
26+
"flags": 0,
27+
"position": 4
28+
},
29+
{
30+
"@type": "PhpMyAdmin\\SqlParser\\Token",
31+
"token": "CONNECTION",
32+
"value": "CONNECTION",
33+
"keyword": "CONNECTION",
34+
"type": 1,
35+
"flags": 1,
36+
"position": 5
37+
},
38+
{
39+
"@type": "PhpMyAdmin\\SqlParser\\Token",
40+
"token": " ",
41+
"value": " ",
42+
"keyword": null,
43+
"type": 3,
44+
"flags": 0,
45+
"position": 15
46+
},
47+
{
48+
"@type": "PhpMyAdmin\\SqlParser\\Token",
49+
"token": "1",
50+
"value": 1,
51+
"keyword": null,
52+
"type": 6,
53+
"flags": 0,
54+
"position": 16
55+
},
56+
{
57+
"@type": "PhpMyAdmin\\SqlParser\\Token",
58+
"token": null,
59+
"value": null,
60+
"keyword": null,
61+
"type": 9,
62+
"flags": 0,
63+
"position": null
64+
}
65+
],
66+
"count": 6,
67+
"idx": 6
68+
},
69+
"delimiter": ";",
70+
"delimiterLen": 1,
71+
"strict": false,
72+
"errors": []
73+
},
74+
"parser": {
75+
"@type": "PhpMyAdmin\\SqlParser\\Parser",
76+
"list": {
77+
"@type": "@1"
78+
},
79+
"statements": [
80+
{
81+
"@type": "PhpMyAdmin\\SqlParser\\Statements\\KillStatement",
82+
"processListId": {
83+
"@type": "PhpMyAdmin\\SqlParser\\Components\\Expression",
84+
"database": null,
85+
"table": null,
86+
"column": null,
87+
"expr": "1",
88+
"alias": null,
89+
"function": null,
90+
"subquery": null
91+
},
92+
"options": {
93+
"@type": "PhpMyAdmin\\SqlParser\\Components\\OptionsArray",
94+
"options": {
95+
"1": "CONNECTION"
96+
}
97+
},
98+
"first": 0,
99+
"last": 4
100+
}
101+
],
102+
"brackets": 0,
103+
"strict": false,
104+
"errors": []
105+
},
106+
"errors": {
107+
"lexer": [],
108+
"parser": []
109+
}
110+
}

tests/data/parser/parseKillQuery.in

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
KILL QUERY 1

0 commit comments

Comments
 (0)