Commit f64612e9 authored by Steve Müller's avatar Steve Müller Committed by Benjamin Eberlei

fix parsing backtick quoted statement fragments

parent 7195d201
...@@ -36,6 +36,7 @@ class SQLParserUtils ...@@ -36,6 +36,7 @@ class SQLParserUtils
// Quote characters within string literals can be preceded by a backslash. // Quote characters within string literals can be preceded by a backslash.
const ESCAPED_SINGLE_QUOTED_TEXT = "'(?:[^'\\\\]|\\\\'|\\\\\\\\)*'"; const ESCAPED_SINGLE_QUOTED_TEXT = "'(?:[^'\\\\]|\\\\'|\\\\\\\\)*'";
const ESCAPED_DOUBLE_QUOTED_TEXT = '"(?:[^"\\\\]|\\\\"|\\\\\\\\)*"'; const ESCAPED_DOUBLE_QUOTED_TEXT = '"(?:[^"\\\\]|\\\\"|\\\\\\\\)*"';
const ESCAPED_BACKTICK_QUOTED_TEXT = '`(?:[^`\\\\]|\\\\`|\\\\\\\\)*`';
/** /**
* Gets an array of the placeholders in an sql statements as keys and their positions in the query string. * Gets an array of the placeholders in an sql statements as keys and their positions in the query string.
...@@ -194,8 +195,10 @@ class SQLParserUtils ...@@ -194,8 +195,10 @@ class SQLParserUtils
*/ */
static private function getUnquotedStatementFragments($statement) static private function getUnquotedStatementFragments($statement)
{ {
$literal = self::ESCAPED_SINGLE_QUOTED_TEXT . '|' . self::ESCAPED_DOUBLE_QUOTED_TEXT; $literal = self::ESCAPED_SINGLE_QUOTED_TEXT . '|' .
preg_match_all("/([^'\"]+)(?:$literal)?/s", $statement, $fragments, PREG_OFFSET_CAPTURE); self::ESCAPED_DOUBLE_QUOTED_TEXT . '|' .
self::ESCAPED_BACKTICK_QUOTED_TEXT;
preg_match_all("/([^'\"`]+)(?:$literal)?/s", $statement, $fragments, PREG_OFFSET_CAPTURE);
return $fragments[1]; return $fragments[1];
} }
......
...@@ -26,8 +26,10 @@ class SQLParserUtilsTest extends \Doctrine\Tests\DbalTestCase ...@@ -26,8 +26,10 @@ class SQLParserUtilsTest extends \Doctrine\Tests\DbalTestCase
array('SELECT ? FROM ?', true, array(7, 14)), array('SELECT ? FROM ?', true, array(7, 14)),
array('SELECT "?" FROM foo', true, array()), array('SELECT "?" FROM foo', true, array()),
array("SELECT '?' FROM foo", true, array()), array("SELECT '?' FROM foo", true, array()),
array("SELECT `?` FROM foo", true, array()), // Ticket DBAL-552
array('SELECT "?" FROM foo WHERE bar = ?', true, array(32)), array('SELECT "?" FROM foo WHERE bar = ?', true, array(32)),
array("SELECT '?' FROM foo WHERE bar = ?", true, array(32)), array("SELECT '?' FROM foo WHERE bar = ?", true, array(32)),
array("SELECT `?` FROM foo WHERE bar = ?", true, array(32)), // Ticket DBAL-552
array( array(
<<<'SQLDATA' <<<'SQLDATA'
SELECT * FROM foo WHERE bar = 'it\'s a trap? \\' OR bar = ? SELECT * FROM foo WHERE bar = 'it\'s a trap? \\' OR bar = ?
...@@ -45,7 +47,8 @@ SQLDATA ...@@ -45,7 +47,8 @@ SQLDATA
array('SELECT @rank := 1', false, array()), // Ticket DBAL-398 array('SELECT @rank := 1', false, array()), // Ticket DBAL-398
array('SELECT @rank := 1 AS rank, :foo AS foo FROM :bar', false, array(27 => 'foo', 44 => 'bar')), // Ticket DBAL-398 array('SELECT @rank := 1 AS rank, :foo AS foo FROM :bar', false, array(27 => 'foo', 44 => 'bar')), // Ticket DBAL-398
array('SELECT * FROM Foo WHERE bar > :start_date AND baz > :start_date', false, array(30 => 'start_date', 52 => 'start_date')), // Ticket GH-113 array('SELECT * FROM Foo WHERE bar > :start_date AND baz > :start_date', false, array(30 => 'start_date', 52 => 'start_date')), // Ticket GH-113
array('SELECT foo::date as date FROM Foo WHERE bar > :start_date AND baz > :start_date', false, array(46 => 'start_date', 68 => 'start_date')) // Ticket GH-259 array('SELECT foo::date as date FROM Foo WHERE bar > :start_date AND baz > :start_date', false, array(46 => 'start_date', 68 => 'start_date')), // Ticket GH-259
array('SELECT `d.ns:col_name` FROM my_table d WHERE `d.date` >= :param1', false, array(57 => 'param1')), // Ticket DBAL-552
); );
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment