Commit 0040261f authored by zYne's avatar zYne

fixes #290

parent 24abb16c
...@@ -97,42 +97,33 @@ class Doctrine_Connection_Mssql extends Doctrine_Connection ...@@ -97,42 +97,33 @@ class Doctrine_Connection_Mssql extends Doctrine_Connection
public function modifyLimitQuery($query, $limit, $offset, $isManip = false) public function modifyLimitQuery($query, $limit, $offset, $isManip = false)
{ {
if ($limit > 0) { if ($limit > 0) {
// we need the starting SELECT clause for later $count = intval($limit);
$select = 'SELECT ';
if (preg_match('/^[[:space:]*SELECT[[:space:]]*DISTINCT/i', $query, $matches) == 1) {
$select .= 'DISTINCT ';
}
$length = strlen($select);
// is there an offset? $offset = intval($offset);
if (! $offset) { if ($offset < 0) {
// no offset, it's a simple TOP count throw new Zend_Db_Adapter_Exception("LIMIT argument offset=$offset is not valid");
return $select . ' TOP ' . $limit . substr($query, $length);
} }
// the total of the count **and** the offset, combined. $orderby = stristr($sql, 'ORDER BY');
// this will be used in the "internal" portion of the if ($orderby !== false) {
// hacked-up statement. $sort = (stripos($orderby, 'desc') !== false) ? 'desc' : 'asc';
$total = $limit + $offset; $order = str_ireplace('ORDER BY', '', $orderby);
$order = trim(preg_replace('/ASC|DESC/i', '', $order));
// build the "real" order for the external portion. }
$order = implode(',', $parts['order']);
$sql = preg_replace('/^SELECT\s/i', 'SELECT TOP ' . ($count+$offset) . ' ', $sql);
// build a "reverse" order for the internal portion.
$reverse = $order; $sql = 'SELECT * FROM (SELECT TOP ' . $count . ' * FROM (' . $sql . ') AS inner_tbl';
$reverse = str_ireplace(" ASC", " \xFF", $reverse); if ($orderby !== false) {
$reverse = str_ireplace(" DESC", " ASC", $reverse); $sql .= ' ORDER BY ' . $order . ' ';
$reverse = str_ireplace(" \xFF", " DESC", $reverse); $sql .= (stripos($sort, 'asc') !== false) ? 'DESC' : 'ASC';
}
// create a main statement that replaces the SELECT $sql .= ') AS outer_tbl';
// with a SELECT TOP if ($orderby !== false) {
$main = $select . ' TOP ' . $total . substr($query, $length); $sql .= ' ORDER BY ' . $order . ' ' . $sort;
}
// build the hacked-up statement.
// do we really need the "as" aliases here? return $sql;
$query = 'SELECT * FROM ('
. 'SELECT TOP ' . $count . ' * FROM (' . $main . ') AS select_limit_rev ORDER BY '. $reverse
. ') AS select_limit ORDER BY ' . $order;
} }
...@@ -145,7 +136,7 @@ class Doctrine_Connection_Mssql extends Doctrine_Connection ...@@ -145,7 +136,7 @@ class Doctrine_Connection_Mssql extends Doctrine_Connection
* @return mixed array/string with version information or MDB2 error object * @return mixed array/string with version information or MDB2 error object
*/ */
public function getServerVersion($native = false) public function getServerVersion($native = false)
{ {
if ($this->serverInfo) { if ($this->serverInfo) {
$serverInfo = $this->serverInfo; $serverInfo = $this->serverInfo;
} else { } else {
......
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