Skip to content

Commit

Permalink
Allow parsing KILL statement
Browse files Browse the repository at this point in the history
Signed-off-by: Maximilian Krög <[email protected]>
  • Loading branch information
MoonE committed May 1, 2024
1 parent 29f982a commit 00255a8
Show file tree
Hide file tree
Showing 10 changed files with 424 additions and 1 deletion.
5 changes: 5 additions & 0 deletions src/Parser.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ class Parser extends Core
'BACKUP' => 'PhpMyAdmin\\SqlParser\\Statements\\BackupStatement',
'CHECK' => 'PhpMyAdmin\\SqlParser\\Statements\\CheckStatement',
'CHECKSUM' => 'PhpMyAdmin\\SqlParser\\Statements\\ChecksumStatement',
'KILL' => 'PhpMyAdmin\\SqlParser\\Statements\\KillStatement',
'OPTIMIZE' => 'PhpMyAdmin\\SqlParser\\Statements\\OptimizeStatement',
'REPAIR' => 'PhpMyAdmin\\SqlParser\\Statements\\RepairStatement',
'RESTORE' => 'PhpMyAdmin\\SqlParser\\Statements\\RestoreStatement',
Expand Down Expand Up @@ -210,6 +211,10 @@ class Parser extends Core
'class' => 'PhpMyAdmin\\SqlParser\\Components\\JoinKeyword',
'field' => 'join',
],
'KILL' => [
'class' => 'PhpMyAdmin\\SqlParser\\Components\\Expression',
'field' => 'processListId',
],
'LEFT JOIN' => [
'class' => 'PhpMyAdmin\\SqlParser\\Components\\JoinKeyword',
'field' => 'join',
Expand Down
43 changes: 43 additions & 0 deletions src/Statements/KillStatement.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<?php

declare(strict_types=1);

namespace PhpMyAdmin\SqlParser\Statements;

use PhpMyAdmin\SqlParser\Components\Expression;
use PhpMyAdmin\SqlParser\Components\OptionsArray;
use PhpMyAdmin\SqlParser\Statement;

use function trim;

/**
* `KILL` statement.
*
* KILL [CONNECTION | QUERY] processlist_id
*/
class KillStatement extends Statement
{
/**
* Options of this statement.
*
* @var array<string, int|array<int, int|string>>
* @psalm-var array<string, (positive-int|array{positive-int, ('var'|'var='|'expr'|'expr=')})>
*/
public static $OPTIONS = [
'CONNECTION' => 1,
'QUERY' => 1,
];

/** @var Expression|null */
public $processListId = null;

public function build(): string
{
$option = $this->options === null || $this->options->isEmpty()
? ''
: ' ' . OptionsArray::build($this->options);
$expression = $this->processListId === null ? '' : ' ' . Expression::build($this->processListId);

return trim('KILL' . $option . $expression);
}
}
5 changes: 4 additions & 1 deletion src/Utils/Query.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
use PhpMyAdmin\SqlParser\Statements\DropStatement;
use PhpMyAdmin\SqlParser\Statements\ExplainStatement;
use PhpMyAdmin\SqlParser\Statements\InsertStatement;
use PhpMyAdmin\SqlParser\Statements\KillStatement;
use PhpMyAdmin\SqlParser\Statements\LoadStatement;
use PhpMyAdmin\SqlParser\Statements\OptimizeStatement;
use PhpMyAdmin\SqlParser\Statements\RenameStatement;
Expand Down Expand Up @@ -65,7 +66,7 @@
* limit?: bool,
* offset?: bool,
* order?: bool,
* querytype: ('ALTER'|'ANALYZE'|'CALL'|'CHECK'|'CHECKSUM'|'CREATE'|'DELETE'|'DROP'|'EXPLAIN'|'INSERT'|'LOAD'|'OPTIMIZE'|'REPAIR'|'REPLACE'|'SELECT'|'SET'|'SHOW'|'UPDATE'|false),
* querytype: ('ALTER'|'ANALYZE'|'CALL'|'CHECK'|'CHECKSUM'|'CREATE'|'DELETE'|'DROP'|'EXPLAIN'|'INSERT'|'KILL'|'LOAD'|'OPTIMIZE'|'REPAIR'|'REPLACE'|'SELECT'|'SET'|'SHOW'|'UPDATE'|false),
* reload?: bool,
* select_from?: bool,
* union?: bool
Expand Down Expand Up @@ -431,6 +432,8 @@ public static function getFlags($statement, $all = false)
$flags['is_affected'] = true;
} elseif ($statement instanceof SetStatement) {
$flags['querytype'] = 'SET';
} elseif ($statement instanceof KillStatement) {
$flags['querytype'] = 'KILL';
}

if (
Expand Down
59 changes: 59 additions & 0 deletions tests/Parser/KillStatementTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
<?php

declare(strict_types=1);

namespace PhpMyAdmin\SqlParser\Tests\Parser;

use PhpMyAdmin\SqlParser\Parser;
use PhpMyAdmin\SqlParser\Statements\KillStatement;
use PhpMyAdmin\SqlParser\Tests\TestCase;

class KillStatementTest extends TestCase
{
/**
* @dataProvider killProvider
*/
public function testKill(string $test): void
{
$this->runParserTest($test);
}

/**
* @return string[][]
*/
public function killProvider(): array
{
return [
['parser/parseKill'],
['parser/parseKillConnection'],
['parser/parseKillQuery'],
];
}

/**
* @dataProvider buildKillProvider
*/
public function testBuildKill(string $sql): void
{
$parser = new Parser($sql);
$this->assertCount(1, $parser->statements);
$statement = $parser->statements[0];
$this->assertInstanceOf(KillStatement::class, $statement);
$builtSql = $statement->build();
$this->assertEquals($sql, $builtSql);
}

/**
* @return array<int, array<int, string>>
* @psalm-return list<list<string>>
*/
public function buildKillProvider(): array
{
return [
['KILL (SELECT 3 + 4)'],
['KILL QUERY 3'],
['KILL CONNECTION 3'],
['KILL'],
];
}
}
1 change: 1 addition & 0 deletions tests/data/parser/parseKill.in
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
KILL 1
90 changes: 90 additions & 0 deletions tests/data/parser/parseKill.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
{
"query": "KILL 1",
"lexer": {
"@type": "PhpMyAdmin\\SqlParser\\Lexer",
"str": "KILL 1",
"len": 6,
"last": 6,
"list": {
"@type": "PhpMyAdmin\\SqlParser\\TokensList",
"tokens": [
{
"@type": "PhpMyAdmin\\SqlParser\\Token",
"token": "KILL",
"value": "KILL",
"keyword": "KILL",
"type": 1,
"flags": 3,
"position": 0
},
{
"@type": "PhpMyAdmin\\SqlParser\\Token",
"token": " ",
"value": " ",
"keyword": null,
"type": 3,
"flags": 0,
"position": 4
},
{
"@type": "PhpMyAdmin\\SqlParser\\Token",
"token": "1",
"value": 1,
"keyword": null,
"type": 6,
"flags": 0,
"position": 5
},
{
"@type": "PhpMyAdmin\\SqlParser\\Token",
"token": null,
"value": null,
"keyword": null,
"type": 9,
"flags": 0,
"position": null
}
],
"count": 4,
"idx": 4
},
"delimiter": ";",
"delimiterLen": 1,
"strict": false,
"errors": []
},
"parser": {
"@type": "PhpMyAdmin\\SqlParser\\Parser",
"list": {
"@type": "@1"
},
"statements": [
{
"@type": "PhpMyAdmin\\SqlParser\\Statements\\KillStatement",
"processListId": {
"@type": "PhpMyAdmin\\SqlParser\\Components\\Expression",
"database": null,
"table": null,
"column": null,
"expr": "1",
"alias": null,
"function": null,
"subquery": null
},
"options": {
"@type": "PhpMyAdmin\\SqlParser\\Components\\OptionsArray",
"options": []
},
"first": 0,
"last": 2
}
],
"brackets": 0,
"strict": false,
"errors": []
},
"errors": {
"lexer": [],
"parser": []
}
}
1 change: 1 addition & 0 deletions tests/data/parser/parseKillConnection.in
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
KILL CONNECTION 1
110 changes: 110 additions & 0 deletions tests/data/parser/parseKillConnection.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
{
"query": "KILL CONNECTION 1",
"lexer": {
"@type": "PhpMyAdmin\\SqlParser\\Lexer",
"str": "KILL CONNECTION 1",
"len": 17,
"last": 17,
"list": {
"@type": "PhpMyAdmin\\SqlParser\\TokensList",
"tokens": [
{
"@type": "PhpMyAdmin\\SqlParser\\Token",
"token": "KILL",
"value": "KILL",
"keyword": "KILL",
"type": 1,
"flags": 3,
"position": 0
},
{
"@type": "PhpMyAdmin\\SqlParser\\Token",
"token": " ",
"value": " ",
"keyword": null,
"type": 3,
"flags": 0,
"position": 4
},
{
"@type": "PhpMyAdmin\\SqlParser\\Token",
"token": "CONNECTION",
"value": "CONNECTION",
"keyword": "CONNECTION",
"type": 1,
"flags": 1,
"position": 5
},
{
"@type": "PhpMyAdmin\\SqlParser\\Token",
"token": " ",
"value": " ",
"keyword": null,
"type": 3,
"flags": 0,
"position": 15
},
{
"@type": "PhpMyAdmin\\SqlParser\\Token",
"token": "1",
"value": 1,
"keyword": null,
"type": 6,
"flags": 0,
"position": 16
},
{
"@type": "PhpMyAdmin\\SqlParser\\Token",
"token": null,
"value": null,
"keyword": null,
"type": 9,
"flags": 0,
"position": null
}
],
"count": 6,
"idx": 6
},
"delimiter": ";",
"delimiterLen": 1,
"strict": false,
"errors": []
},
"parser": {
"@type": "PhpMyAdmin\\SqlParser\\Parser",
"list": {
"@type": "@1"
},
"statements": [
{
"@type": "PhpMyAdmin\\SqlParser\\Statements\\KillStatement",
"processListId": {
"@type": "PhpMyAdmin\\SqlParser\\Components\\Expression",
"database": null,
"table": null,
"column": null,
"expr": "1",
"alias": null,
"function": null,
"subquery": null
},
"options": {
"@type": "PhpMyAdmin\\SqlParser\\Components\\OptionsArray",
"options": {
"1": "CONNECTION"
}
},
"first": 0,
"last": 4
}
],
"brackets": 0,
"strict": false,
"errors": []
},
"errors": {
"lexer": [],
"parser": []
}
}
1 change: 1 addition & 0 deletions tests/data/parser/parseKillQuery.in
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
KILL QUERY 1
Loading

0 comments on commit 00255a8

Please sign in to comment.