Просмотр исходного кода

ZF-5823
- Improvement to Pdo_Mssql limit() to produce more concise sql when no offset provided

git-svn-id: http://framework.zend.com/svn/framework/standard/trunk@17714 44c647ce-9c0f-0410-b52a-842ac1e357ba

ralph 16 лет назад
Родитель
Сommit
1ced9d40c6
2 измененных файлов с 52 добавлено и 34 удалено
  1. 38 34
      library/Zend/Db/Adapter/Pdo/Mssql.php
  2. 14 0
      tests/Zend/Db/Adapter/Pdo/MssqlTest.php

+ 38 - 34
library/Zend/Db/Adapter/Pdo/Mssql.php

@@ -314,46 +314,50 @@ class Zend_Db_Adapter_Pdo_Mssql extends Zend_Db_Adapter_Pdo_Abstract
             throw new Zend_Db_Adapter_Exception("LIMIT argument offset=$offset is not valid");
         }
 
-        $orderby = stristr($sql, 'ORDER BY');
-        
-        if ($orderby !== false) {
-            $orderParts = explode(',', substr($orderby, 8));
-            $pregReplaceCount = null;
-            $orderbyInverseParts = array();
-            foreach ($orderParts as $orderPart) {
-                $inv = preg_replace('/\s+desc$/i', ' ASC', $orderPart, 1, $pregReplaceCount);
-                if ($pregReplaceCount) {
-                    $orderbyInverseParts[] = $inv;
-                    continue;
-                }
-                $inv = preg_replace('/\s+asc$/i', ' DESC', $orderPart, 1, $pregReplaceCount);
-                if ($pregReplaceCount) {
-                    $orderbyInverseParts[] = $inv;
-                    continue;
-                } else {
-                    $orderbyInverseParts[] = $orderPart . ' DESC';
-                }
-            }
-            
-            $orderbyInverse = 'ORDER BY ' . implode(', ', $orderbyInverseParts);
-        }
-
-        
         $sql = preg_replace(
             '/^SELECT\s+(DISTINCT\s)?/i',
             'SELECT $1TOP ' . ($count+$offset) . ' ',
             $sql
             );
-
-        $sql = 'SELECT * FROM (SELECT TOP ' . $count . ' * FROM (' . $sql . ') AS inner_tbl';
-        if ($orderby !== false) {
-            $sql .= ' ' . $orderbyInverse . ' ';
-        }
-        $sql .= ') AS outer_tbl';
-        if ($orderby !== false) {
-            $sql .= ' ' . $orderby;
+        
+        if ($offset > 0) {
+	        $orderby = stristr($sql, 'ORDER BY');
+	        
+	        if ($orderby !== false) {
+	            $orderParts = explode(',', substr($orderby, 8));
+	            $pregReplaceCount = null;
+	            $orderbyInverseParts = array();
+	            foreach ($orderParts as $orderPart) {
+	                $inv = preg_replace('/\s+desc$/i', ' ASC', $orderPart, 1, $pregReplaceCount);
+	                if ($pregReplaceCount) {
+	                    $orderbyInverseParts[] = $inv;
+	                    continue;
+	                }
+	                $inv = preg_replace('/\s+asc$/i', ' DESC', $orderPart, 1, $pregReplaceCount);
+	                if ($pregReplaceCount) {
+	                    $orderbyInverseParts[] = $inv;
+	                    continue;
+	                } else {
+	                    $orderbyInverseParts[] = $orderPart . ' DESC';
+	                }
+	            }
+	            
+	            $orderbyInverse = 'ORDER BY ' . implode(', ', $orderbyInverseParts);
+	        }
+	
+	        
+	
+	
+	        $sql = 'SELECT * FROM (SELECT TOP ' . $count . ' * FROM (' . $sql . ') AS inner_tbl';
+	        if ($orderby !== false) {
+	            $sql .= ' ' . $orderbyInverse . ' ';
+	        }
+	        $sql .= ') AS outer_tbl';
+	        if ($orderby !== false) {
+	            $sql .= ' ' . $orderby;
+	        }
         }
-
+        
         return $sql;
     }
 

+ 14 - 0
tests/Zend/Db/Adapter/Pdo/MssqlTest.php

@@ -345,6 +345,9 @@ class Zend_Db_Adapter_Pdo_MssqlTest extends Zend_Db_Adapter_Pdo_TestCommon
         $this->assertEquals($expectedProducts, $products);
     }
     
+    /**
+     * @group ZF-4251
+     */
     public function testAdapterLimitWorksWithDistinctClause()
     {
         $this->_db->insert('zfproducts', array('product_name' => 'Unix'));
@@ -364,6 +367,17 @@ class Zend_Db_Adapter_Pdo_MssqlTest extends Zend_Db_Adapter_Pdo_TestCommon
         $this->assertEquals($expectedProducts, $products);
     }
     
+    /**
+     * @group ZF-5823
+     */
+    public function testAdapterLimitWithoutOffsetProducesConciseSql()
+    {
+    	$sql = 'SELECT * FROM foo ORDER BY bar DESC';
+    	$this->assertEquals('SELECT TOP 3 * FROM foo ORDER BY bar DESC', $this->_db->limit($sql, 3));
+    	
+        $sql = 'SELECT DISTINCT * FROM foo ORDER BY bar DESC';
+        $this->assertEquals('SELECT DISTINCT TOP 3 * FROM foo ORDER BY bar DESC', $this->_db->limit($sql, 3));
+    }
     
     public function getDriver()
     {