ソースを参照

Fix incorrectly quoted identifiers in order clauses

When order clauses are strings, we cannot safely quote identifiers as
they can be hard to find. If an order by string contains spaces assume
the developer knows what they are doing.

Refs #6805
Mark Story 10 年 前
コミット
c8863e2edb
2 ファイル変更21 行追加1 行削除
  1. 4 1
      src/Database/IdentifierQuoter.php
  2. 17 0
      tests/TestCase/Database/QueryTest.php

+ 4 - 1
src/Database/IdentifierQuoter.php

@@ -206,6 +206,9 @@ class IdentifierQuoter
     /**
     /**
      * Quotes identifiers in "order by" expression objects
      * Quotes identifiers in "order by" expression objects
      *
      *
+     * Strings with spaces are treated as literal expressions
+     * and will not have identifiers quoted.
+     *
      * @param \Cake\Database\Expression\OrderByExpression $expression The expression to quote.
      * @param \Cake\Database\Expression\OrderByExpression $expression The expression to quote.
      * @return void
      * @return void
      */
      */
@@ -216,7 +219,7 @@ class IdentifierQuoter
                 $field = $this->_driver->quoteIdentifier($field);
                 $field = $this->_driver->quoteIdentifier($field);
                 return $part;
                 return $part;
             }
             }
-            if (is_string($part)) {
+            if (is_string($part) && strpos($part, ' ') === false) {
                 return $this->_driver->quoteIdentifier($part);
                 return $this->_driver->quoteIdentifier($part);
             }
             }
             return $part;
             return $part;

+ 17 - 0
tests/TestCase/Database/QueryTest.php

@@ -1436,6 +1436,23 @@ class QueryTest extends TestCase
     }
     }
 
 
     /**
     /**
+     * Test that order() being a string works.
+     *
+     * @return void
+     */
+    public function testSelectOrderByString()
+    {
+        $query = new Query($this->connection);
+        $query->select(['id'])
+            ->from('articles')
+            ->order('id asc');
+        $result = $query->execute();
+        $this->assertEquals(['id' => 1], $result->fetch('assoc'));
+        $this->assertEquals(['id' => 2], $result->fetch('assoc'));
+        $this->assertEquals(['id' => 3], $result->fetch('assoc'));
+    }
+
+    /**
      * Tests that group by fields can be passed similar to select fields
      * Tests that group by fields can be passed similar to select fields
      * and that it sends the correct query to the database
      * and that it sends the correct query to the database
      *
      *