Commit 646f479a authored by Steve Müller's avatar Steve Müller

fix parsing SQL Server bracket delimiters in SQL statements

parent 9ec63e25
...@@ -35,6 +35,7 @@ class SQLParserUtils ...@@ -35,6 +35,7 @@ class SQLParserUtils
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 = '`(?:[^`\\\\]|\\\\`?)*`'; const ESCAPED_BACKTICK_QUOTED_TEXT = '`(?:[^`\\\\]|\\\\`?)*`';
const ESCAPED_BRACKET_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.
...@@ -195,8 +196,9 @@ class SQLParserUtils ...@@ -195,8 +196,9 @@ class SQLParserUtils
{ {
$literal = self::ESCAPED_SINGLE_QUOTED_TEXT . '|' . $literal = self::ESCAPED_SINGLE_QUOTED_TEXT . '|' .
self::ESCAPED_DOUBLE_QUOTED_TEXT . '|' . self::ESCAPED_DOUBLE_QUOTED_TEXT . '|' .
self::ESCAPED_BACKTICK_QUOTED_TEXT; self::ESCAPED_BACKTICK_QUOTED_TEXT . '|' .
preg_match_all("/([^'\"`]+)(?:$literal)?/s", $statement, $fragments, PREG_OFFSET_CAPTURE); self::ESCAPED_BRACKET_QUOTED_TEXT;
preg_match_all("/([^'\"`\[]+)(?:$literal)?/s", $statement, $fragments, PREG_OFFSET_CAPTURE);
return $fragments[1]; return $fragments[1];
} }
......
...@@ -27,15 +27,19 @@ class SQLParserUtilsTest extends \Doctrine\Tests\DbalTestCase ...@@ -27,15 +27,19 @@ class SQLParserUtilsTest extends \Doctrine\Tests\DbalTestCase
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", true, array()), // Ticket DBAL-552
array("SELECT [?] FROM foo", true, array()),
array("SELECT 'Doctrine\DBAL?' FROM foo", true, array()), // Ticket DBAL-558 array("SELECT 'Doctrine\DBAL?' FROM foo", true, array()), // Ticket DBAL-558
array('SELECT "Doctrine\DBAL?" FROM foo', true, array()), // Ticket DBAL-558 array('SELECT "Doctrine\DBAL?" FROM foo', true, array()), // Ticket DBAL-558
array('SELECT `Doctrine\DBAL?` FROM foo', true, array()), // Ticket DBAL-558 array('SELECT `Doctrine\DBAL?` FROM foo', true, array()), // Ticket DBAL-558
array('SELECT [Doctrine\DBAL?] FROM foo', true, array()), // Ticket DBAL-558
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("SELECT `?` FROM foo WHERE bar = ?", true, array(32)), // Ticket DBAL-552
array("SELECT [?] FROM foo WHERE bar = ?", true, array(32)),
array("SELECT 'Doctrine\DBAL?' FROM foo WHERE bar = ?", true, array(45)), // Ticket DBAL-558 array("SELECT 'Doctrine\DBAL?' FROM foo WHERE bar = ?", true, array(45)), // Ticket DBAL-558
array('SELECT "Doctrine\DBAL?" FROM foo WHERE bar = ?', true, array(45)), // Ticket DBAL-558 array('SELECT "Doctrine\DBAL?" FROM foo WHERE bar = ?', true, array(45)), // Ticket DBAL-558
array('SELECT `Doctrine\DBAL?` FROM foo WHERE bar = ?', true, array(45)), // Ticket DBAL-558 array('SELECT `Doctrine\DBAL?` FROM foo WHERE bar = ?', true, array(45)), // Ticket DBAL-558
array('SELECT [Doctrine\DBAL?] FROM foo WHERE bar = ?', true, array(45)), // Ticket DBAL-558
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 = ?
...@@ -55,6 +59,7 @@ SQLDATA ...@@ -55,6 +59,7 @@ SQLDATA
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 array('SELECT `d.ns:col_name` FROM my_table d WHERE `d.date` >= :param1', false, array(57 => 'param1')), // Ticket DBAL-552
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