Commit 70c57c7f authored by zYne's avatar zYne

Firebird LIMIT support updated, severe query parser bug fixed

parent a972f78e
......@@ -4,7 +4,8 @@
*/
class Doctrine_Connection_Firebird extends Doctrine_Connection {
public function modifyLimitQuery($query,$limit,$offset) {
return preg_replace("/([\s(])*SELECT/i","\\1SELECT TOP($from, $count)", $query);
return preg_replace('/^([\s(])*SELECT(?!\s*FIRST\s*\d+)/i',
"SELECT FIRST $limit SKIP $offset", $query);
}
/**
* returns the next value in the given sequence
......
......@@ -380,7 +380,7 @@ class Doctrine_Query extends Doctrine_Hydrate {
*/
public function parseQuery($query) {
$this->clear();
$e = self::bracketExplode($query," ","(",")");
$e = self::sqlExplode($query," ","(",")");
$parts = array();
......@@ -533,6 +533,45 @@ class Doctrine_Query extends Doctrine_Hydrate {
return $term;
}
public static function sqlExplode($str,$d = " ",$e1 = '(',$e2 = ')') {
$str = explode("$d",$str);
$i = 0;
$term = array();
foreach($str as $key => $val) {
if (empty($term[$i])) {
$term[$i] = trim($val);
$s1 = substr_count($term[$i],"$e1");
$s2 = substr_count($term[$i],"$e2");
if(substr($term[$i],0,1) == "(") {
if($s1 == $s2)
$i++;
} else {
if( ! (substr_count($term[$i], "'") & 1) &&
! (substr_count($term[$i], "\"") & 1) &&
! (substr_count($term[$i], "") & 1)
) $i++;
}
} else {
$term[$i] .= "$d".trim($val);
$c1 = substr_count($term[$i],"$e1");
$c2 = substr_count($term[$i],"$e2");
if(substr($term[$i],0,1) == "(") {
if($c1 == $c2)
$i++;
} else {
if( ! (substr_count($term[$i], "'") & 1) &&
! (substr_count($term[$i], "\"") & 1) &&
! (substr_count($term[$i], "") & 1)
) $i++;
}
}
}
return $term;
}
/**
* generateAlias
*
......
......@@ -74,7 +74,7 @@ class Doctrine_RawSql extends Doctrine_Hydrate {
$this->fields = $m[1];
$this->clear();
$e = Doctrine_Query::bracketExplode($query,' ');
$e = Doctrine_Query::sqlExplode($query,' ');
foreach($e as $k => $part):
$low = strtolower($part);
......
......@@ -150,6 +150,75 @@ class Doctrine_RawSql_TestCase extends Doctrine_UnitTestCase {
$this->assertTrue(is_numeric($coll[7]->id));
}
public function testsqlExplode() {
$str = "word1 word2 word3";
$a = Doctrine_Query::sqlExplode($str);
$this->assertEqual($a, array("word1", "word2", "word3"));
$str = "word1 (word2 word3)";
$a = Doctrine_Query::sqlExplode($str);
$this->assertEqual($a, array("word1", "(word2 word3)"));
$str = "word1 'word2 word3'";
$a = Doctrine_Query::sqlExplode($str);
$this->assertEqual($a, array("word1", "'word2 word3'"));
$str = "word1 word2 word3";
$a = Doctrine_Query::sqlExplode($str);
$this->assertEqual($a, array("word1", "word2 word3"));
$str = "word1 \"word2 word3\"";
$a = Doctrine_Query::sqlExplode($str);
$this->assertEqual($a, array("word1", "\"word2 word3\""));
$str = "word1 ((word2) word3)";
$a = Doctrine_Query::sqlExplode($str);
$this->assertEqual($a, array("word1", "((word2) word3)"));
$str = "word1 ( (word2) 'word3')";
$a = Doctrine_Query::sqlExplode($str);
$this->assertEqual($a, array("word1", "( (word2) 'word3')"));
$str = "word1 ( \"(word2) 'word3')";
$a = Doctrine_Query::sqlExplode($str);
$this->assertEqual($a, array("word1", "( \"(word2) 'word3')"));
$str = "word1 ( (word2) 'word3')";
$a = Doctrine_Query::sqlExplode($str);
$this->assertEqual($a, array("word1", "( (word2) 'word3')"));
$str = "word1 ( ()()(word2) 'word3')";
$a = Doctrine_Query::sqlExplode($str);
$this->assertEqual($a, array("word1", "( ()()(word2) 'word3')"));
$str = "word1 'word2)() word3'";
$a = Doctrine_Query::sqlExplode($str);
$this->assertEqual($a, array("word1", "'word2)() word3'"));
$str = "word1 word2)() word3";
$a = Doctrine_Query::sqlExplode($str);
$this->assertEqual($a, array("word1", "word2)() word3"));
$str = "word1 \"word2)() word3\"";
$a = Doctrine_Query::sqlExplode($str);
$this->assertEqual($a, array("word1", "\"word2)() word3\""));
$str = "something (subquery '')";
$a = Doctrine_Query::sqlExplode($str);
$this->assertEqual($a, array("something", "(subquery '')"));
$str = "something (( ))";
$a = Doctrine_Query::sqlExplode($str);
$this->assertEqual($a, array("something", "(( ))"));
}
public function testQueryParser2() {
$query = new Doctrine_RawSql();
$query->parseQuery("SELECT {entity.name} FROM (SELECT entity.name FROM entity WHERE entity.name = 'something') WHERE entity.id = 2 ORDER BY entity.name");
$this->assertEqual($query->getQuery(),
"SELECT entity.name AS entity__name, entity.id AS entity__id FROM (SELECT entity.name FROM entity WHERE entity.name = 'something') WHERE entity.id = 2 ORDER BY entity.name");
}
}
?>
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