Skip to content

Commit 5164466

Browse files
authored
Merge pull request #220 from deliciousbrains/ix-on-duplicate-key-values-trimming
Fix ON DUPLICATE VALUES trimming of whitespace
2 parents 30a5d65 + 6713347 commit 5164466

3 files changed

Lines changed: 46 additions & 8 deletions

File tree

src/PHPSQLParser/processors/ValuesProcessor.php

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -68,18 +68,18 @@ public function process($tokens) {
6868
$base_expr = '';
6969

7070
foreach ($tokens['VALUES'] as $k => $v) {
71+
if ($this->isCommentToken($v)) {
72+
$parsed[] = parent::processComment($v);
73+
continue;
74+
}
75+
76+
$base_expr .= $v;
77+
$trim = trim($v);
78+
7179
if ($this->isWhitespaceToken($v)) {
7280
continue;
7381
}
7482

75-
if ($this->isCommentToken($v)) {
76-
$parsed[] = parent::processComment($v);
77-
continue;
78-
}
79-
80-
$base_expr .= $v;
81-
$trim = trim($v);
82-
8383
$upper = strtoupper($trim);
8484
switch ($upper) {
8585

tests/cases/parser/issue219.php

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<?php
2+
/**
3+
* issueX.php
4+
*
5+
* Test case for PHPSQLParser.
6+
*
7+
*
8+
*/
9+
namespace PHPSQLParser\Test\Parser;
10+
11+
use PHPSQLParser\PHPSQLParser;
12+
13+
class issue219Test extends \PHPUnit_Framework_TestCase {
14+
15+
/**
16+
* https://github.com/greenlion/PHP-SQL-Parser/issues/219
17+
*/
18+
public function testIssu219() {
19+
$sql = "INSERT INTO `wp_options` (`option_name`, `option_value`, `autoload`) VALUES ('some_key', 'some_value', 'yes') ON DUPLICATE KEY UPDATE `option_name` = VALUES(`option_name`), `option_value` = VALUES(`option_value`), `autoload` = VALUES(`autoload`);";
20+
21+
$parser = new PHPSQLParser();
22+
23+
// The issue only happens when calculating positions
24+
// As the parsed elements after ON DUPLICATE KEY UPDATE are trimmed, e.g. option_name`=VALUES(`option_name`)
25+
/*
26+
* PHPSQLParser\exceptions\UnableToCalculatePositionException: cannot calculate position of `option_name`=VALUES(`option_name`) within `option_name` = VALUES(`option_name`), `option_value` = VALUES(`option_value`), `autoload` = VALUES(`autoload`);
27+
*/
28+
$parser->parse( $sql, true );
29+
$parsed = $parser->parsed;
30+
31+
$this->assertNotFalse( $parsed );
32+
$this->assertTrue( is_array( $parsed ) );
33+
$expected = getExpectedValue( dirname( __FILE__ ), 'issue219.serialized', false );
34+
$this->assertEquals( $expected, serialize( $parsed ) );
35+
}
36+
}
37+
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
a:2:{s:6:"INSERT";a:3:{i:0;a:3:{s:9:"expr_type";s:8:"reserved";s:9:"base_expr";s:4:"INTO";s:8:"position";i:7;}i:1;a:6:{s:9:"expr_type";s:5:"table";s:5:"table";s:12:"`wp_options`";s:9:"no_quotes";a:2:{s:5:"delim";b:0;s:5:"parts";a:1:{i:0;s:10:"wp_options";}}s:5:"alias";b:0;s:9:"base_expr";s:12:"`wp_options`";s:8:"position";i:12;}i:2;a:4:{s:9:"expr_type";s:11:"column-list";s:9:"base_expr";s:43:"(`option_name`, `option_value`, `autoload`)";s:8:"sub_tree";a:3:{i:0;a:4:{s:9:"expr_type";s:6:"colref";s:9:"base_expr";s:13:"`option_name`";s:9:"no_quotes";a:2:{s:5:"delim";b:0;s:5:"parts";a:1:{i:0;s:11:"option_name";}}s:8:"position";i:26;}i:1;a:4:{s:9:"expr_type";s:6:"colref";s:9:"base_expr";s:14:"`option_value`";s:9:"no_quotes";a:2:{s:5:"delim";b:0;s:5:"parts";a:1:{i:0;s:12:"option_value";}}s:8:"position";i:41;}i:2;a:4:{s:9:"expr_type";s:6:"colref";s:9:"base_expr";s:10:"`autoload`";s:9:"no_quotes";a:2:{s:5:"delim";b:0;s:5:"parts";a:1:{i:0;s:8:"autoload";}}s:8:"position";i:57;}}s:8:"position";i:25;}}s:6:"VALUES";a:8:{i:0;a:5:{s:9:"expr_type";s:6:"record";s:9:"base_expr";s:33:"('some_key', 'some_value', 'yes')";s:4:"data";a:3:{i:0;a:4:{s:9:"expr_type";s:5:"const";s:9:"base_expr";s:10:"'some_key'";s:8:"sub_tree";b:0;s:8:"position";i:77;}i:1;a:4:{s:9:"expr_type";s:5:"const";s:9:"base_expr";s:12:"'some_value'";s:8:"sub_tree";b:0;s:8:"position";i:89;}i:2;a:4:{s:9:"expr_type";s:5:"const";s:9:"base_expr";s:5:"'yes'";s:8:"sub_tree";b:0;s:8:"position";i:103;}}s:5:"delim";b:0;s:8:"position";i:76;}i:1;a:3:{s:9:"expr_type";s:8:"reserved";s:9:"base_expr";s:2:"ON";s:8:"position";i:110;}i:2;a:3:{s:9:"expr_type";s:8:"reserved";s:9:"base_expr";s:9:"DUPLICATE";s:8:"position";i:113;}i:3;a:3:{s:9:"expr_type";s:8:"reserved";s:9:"base_expr";s:3:"KEY";s:8:"position";i:123;}i:4;a:3:{s:9:"expr_type";s:8:"reserved";s:9:"base_expr";s:6:"UPDATE";s:8:"position";i:127;}i:5;a:5:{s:9:"expr_type";s:10:"expression";s:9:"base_expr";s:37:"`option_name` = VALUES(`option_name`)";s:8:"sub_tree";a:4:{i:0;a:5:{s:9:"expr_type";s:6:"colref";s:9:"base_expr";s:13:"`option_name`";s:9:"no_quotes";a:2:{s:5:"delim";b:0;s:5:"parts";a:1:{i:0;s:11:"option_name";}}s:8:"sub_tree";b:0;s:8:"position";i:134;}i:1;a:4:{s:9:"expr_type";s:8:"operator";s:9:"base_expr";s:1:"=";s:8:"sub_tree";b:0;s:8:"position";i:148;}i:2;a:4:{s:9:"expr_type";s:8:"reserved";s:9:"base_expr";s:6:"VALUES";s:8:"sub_tree";b:0;s:8:"position";i:150;}i:3;a:4:{s:9:"expr_type";s:18:"bracket_expression";s:9:"base_expr";s:15:"(`option_name`)";s:8:"sub_tree";a:1:{i:0;a:5:{s:9:"expr_type";s:6:"colref";s:9:"base_expr";s:13:"`option_name`";s:9:"no_quotes";a:2:{s:5:"delim";b:0;s:5:"parts";a:1:{i:0;s:11:"option_name";}}s:8:"sub_tree";b:0;s:8:"position";i:157;}}s:8:"position";i:156;}}s:5:"delim";s:1:",";s:8:"position";i:134;}i:6;a:5:{s:9:"expr_type";s:10:"expression";s:9:"base_expr";s:39:"`option_value` = VALUES(`option_value`)";s:8:"sub_tree";a:4:{i:0;a:5:{s:9:"expr_type";s:6:"colref";s:9:"base_expr";s:14:"`option_value`";s:9:"no_quotes";a:2:{s:5:"delim";b:0;s:5:"parts";a:1:{i:0;s:12:"option_value";}}s:8:"sub_tree";b:0;s:8:"position";i:173;}i:1;a:4:{s:9:"expr_type";s:8:"operator";s:9:"base_expr";s:1:"=";s:8:"sub_tree";b:0;s:8:"position";i:188;}i:2;a:4:{s:9:"expr_type";s:8:"reserved";s:9:"base_expr";s:6:"VALUES";s:8:"sub_tree";b:0;s:8:"position";i:190;}i:3;a:4:{s:9:"expr_type";s:18:"bracket_expression";s:9:"base_expr";s:16:"(`option_value`)";s:8:"sub_tree";a:1:{i:0;a:5:{s:9:"expr_type";s:6:"colref";s:9:"base_expr";s:14:"`option_value`";s:9:"no_quotes";a:2:{s:5:"delim";b:0;s:5:"parts";a:1:{i:0;s:12:"option_value";}}s:8:"sub_tree";b:0;s:8:"position";i:197;}}s:8:"position";i:196;}}s:5:"delim";s:1:",";s:8:"position";i:173;}i:7;a:5:{s:9:"expr_type";s:10:"expression";s:9:"base_expr";s:31:"`autoload` = VALUES(`autoload`)";s:8:"sub_tree";a:4:{i:0;a:5:{s:9:"expr_type";s:6:"colref";s:9:"base_expr";s:10:"`autoload`";s:9:"no_quotes";a:2:{s:5:"delim";b:0;s:5:"parts";a:1:{i:0;s:8:"autoload";}}s:8:"sub_tree";b:0;s:8:"position";i:214;}i:1;a:4:{s:9:"expr_type";s:8:"operator";s:9:"base_expr";s:1:"=";s:8:"sub_tree";b:0;s:8:"position";i:225;}i:2;a:4:{s:9:"expr_type";s:8:"reserved";s:9:"base_expr";s:6:"VALUES";s:8:"sub_tree";b:0;s:8:"position";i:227;}i:3;a:4:{s:9:"expr_type";s:18:"bracket_expression";s:9:"base_expr";s:12:"(`autoload`)";s:8:"sub_tree";a:1:{i:0;a:5:{s:9:"expr_type";s:6:"colref";s:9:"base_expr";s:10:"`autoload`";s:9:"no_quotes";a:2:{s:5:"delim";b:0;s:5:"parts";a:1:{i:0;s:8:"autoload";}}s:8:"sub_tree";b:0;s:8:"position";i:234;}}s:8:"position";i:233;}}s:5:"delim";b:0;s:8:"position";i:214;}}}

0 commit comments

Comments
 (0)