Skip to content

Commit

Permalink
Merge pull request doctrine#559 from deeky666/fix-sqlanywhere-locate-…
Browse files Browse the repository at this point in the history
…expression

Fix LOCATE expression on SQL Anywhere and SQLite
  • Loading branch information
guilhermeblanco committed Apr 1, 2014
2 parents 3986daf + ba41ca2 commit 0833d00
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 6 deletions.
4 changes: 2 additions & 2 deletions lib/Doctrine/DBAL/Platforms/SQLAnywherePlatform.php
Original file line number Diff line number Diff line change
Expand Up @@ -971,10 +971,10 @@ public function getListViewsSQL($database)
public function getLocateExpression($str, $substr, $startPos = false)
{
if ($startPos == false) {
return 'CHARINDEX(' . $substr . ', ' . $str . ')';
return 'LOCATE(' . $str . ', ' . $substr . ')';
}

return 'CHARINDEX(' . $substr . ', SUBSTR(' . $str . ', ' . ($startPos + 1) . '))';
return 'LOCATE(' . $str . ', ' . $substr . ', ' . $startPos . ')';
}

/**
Expand Down
9 changes: 8 additions & 1 deletion lib/Doctrine/DBAL/Platforms/SqlitePlatform.php
Original file line number Diff line number Diff line change
Expand Up @@ -543,9 +543,16 @@ static public function udfMod($a, $b)
*/
static public function udfLocate($str, $substr, $offset = 0)
{
// SQL's LOCATE function works on 1-based positions, while PHP's strpos works on 0-based positions.
// So we have to make them compatible if an offset is given.
if ($offset > 0) {
$offset -= 1;
}

$pos = strpos($str, $substr, $offset);

if ($pos !== false) {
return $pos+1;
return $pos + 1;
}

return 0;
Expand Down
30 changes: 30 additions & 0 deletions tests/Doctrine/Tests/DBAL/Functional/DataAccessTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -522,6 +522,36 @@ public function testDateArithmetics()
$this->assertEquals('2009-11-01', date('Y-m-d', strtotime($row['sub_month'])), "Adding month should end up on 2009-11-01");
}

public function testLocateExpression()
{
$platform = $this->_conn->getDatabasePlatform();

$sql = 'SELECT ';
$sql .= $platform->getLocateExpression('test_string', "'oo'") .' AS locate1, ';
$sql .= $platform->getLocateExpression('test_string', "'foo'") .' AS locate2, ';
$sql .= $platform->getLocateExpression('test_string', "'bar'") .' AS locate3, ';
$sql .= $platform->getLocateExpression('test_string', 'test_string') .' AS locate4, ';
$sql .= $platform->getLocateExpression("'foo'", 'test_string') .' AS locate5, ';
$sql .= $platform->getLocateExpression("'barfoobaz'", 'test_string') .' AS locate6, ';
$sql .= $platform->getLocateExpression("'bar'", 'test_string') .' AS locate7, ';
$sql .= $platform->getLocateExpression('test_string', "'oo'", 2) .' AS locate8, ';
$sql .= $platform->getLocateExpression('test_string', "'oo'", 3) .' AS locate9 ';
$sql .= 'FROM fetch_table';

$row = $this->_conn->fetchAssoc($sql);
$row = array_change_key_case($row, CASE_LOWER);

$this->assertEquals(2, $row['locate1']);
$this->assertEquals(1, $row['locate2']);
$this->assertEquals(0, $row['locate3']);
$this->assertEquals(1, $row['locate4']);
$this->assertEquals(1, $row['locate5']);
$this->assertEquals(4, $row['locate6']);
$this->assertEquals(0, $row['locate7']);
$this->assertEquals(2, $row['locate8']);
$this->assertEquals(0, $row['locate9']);
}

public function testQuoteSQLInjection()
{
$sql = "SELECT * FROM fetch_table WHERE test_string = " . $this->_conn->quote("bar' OR '1'='1");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -544,9 +544,8 @@ public function testGeneratesSQLSnippets()
$this->assertEquals("H:i:s.u", $this->_platform->getTimeFormatString());
$this->assertEquals('FOR UPDATE BY LOCK', $this->_platform->getForUpdateSQL());
$this->assertEquals('NEWID()', $this->_platform->getGuidExpression());
$this->assertEquals('CHARINDEX(substring_column, string_column)', $this->_platform->getLocateExpression('string_column', 'substring_column'));
$this->assertEquals('CHARINDEX(substring_column, string_column)', $this->_platform->getLocateExpression('string_column', 'substring_column'));
$this->assertEquals('CHARINDEX(substring_column, SUBSTR(string_column, 2))', $this->_platform->getLocateExpression('string_column', 'substring_column', 1));
$this->assertEquals('LOCATE(string_column, substring_column)', $this->_platform->getLocateExpression('string_column', 'substring_column'));
$this->assertEquals('LOCATE(string_column, substring_column, 1)', $this->_platform->getLocateExpression('string_column', 'substring_column', 1));
$this->assertEquals("HASH(column, 'MD5')", $this->_platform->getMd5Expression('column'));
$this->assertEquals('SUBSTRING(column, 5)', $this->_platform->getSubstringExpression('column', 5));
$this->assertEquals('SUBSTRING(column, 5, 2)', $this->_platform->getSubstringExpression('column', 5, 2));
Expand Down

0 comments on commit 0833d00

Please sign in to comment.