Browse Source

Merge pull request #6653 from cakephp/issue-6568

Fix empty query expressions for generating invalid SQL
José Lorenzo Rodríguez 10 years ago
parent
commit
74f3fd6df5

+ 8 - 2
src/Database/Expression/QueryExpression.php

@@ -403,8 +403,12 @@ class QueryExpression implements ExpressionInterface, Countable
      */
     public function sql(ValueBinder $generator)
     {
+        $len = $this->count();
+        if ($len === 0) {
+            return '';
+        }
         $conjunction = $this->_conjunction;
-        $template = ($this->count() === 1) ? '%s' : '(%s)';
+        $template = ($len === 1) ? '%s' : '(%s)';
         $parts = [];
         foreach ($this->_conditions as $part) {
             if ($part instanceof Query) {
@@ -412,7 +416,9 @@ class QueryExpression implements ExpressionInterface, Countable
             } elseif ($part instanceof ExpressionInterface) {
                 $part = $part->sql($generator);
             }
-            $parts[] = $part;
+            if (strlen($part)) {
+                $parts[] = $part;
+            }
         }
         return sprintf($template, implode(" $conjunction ", $parts));
     }

+ 52 - 0
tests/TestCase/Database/Expression/QueryExpressionTest.php

@@ -37,4 +37,56 @@ class QueryExpressionTest extends TestCase
         $this->assertInstanceOf($expected, $expr->and([]));
         $this->assertInstanceOf($expected, $expr->or([]));
     }
+
+    /**
+     * Test SQL generation with one element
+     *
+     * @return void
+     */
+    public function testSqlGenerationOneClause()
+    {
+        $expr = new QueryExpression();
+        $binder = new ValueBinder();
+        $expr->add(['Users.username' => 'sally'], ['Users.username' => 'string']);
+
+        $result = $expr->sql($binder);
+        $this->assertEquals('Users.username = :c0', $result);
+    }
+
+    /**
+     * Test SQL generation with many elements
+     *
+     * @return void
+     */
+    public function testSqlGenerationMultipleClauses()
+    {
+        $expr = new QueryExpression();
+        $binder = new ValueBinder();
+        $expr->add(
+            [
+                'Users.username' => 'sally',
+                'Users.active' => 1,
+            ],
+            [
+                'Users.username' => 'string',
+                'Users.active' => 'boolean'
+            ]
+        );
+
+        $result = $expr->sql($binder);
+        $this->assertEquals('(Users.username = :c0 AND Users.active = :c1)', $result);
+    }
+
+    /**
+     * Test that empty expressions don't emit invalid SQL.
+     *
+     * @return void
+     */
+    public function testSqlWhenEmpty()
+    {
+        $expr = new QueryExpression();
+        $binder = new ValueBinder();
+        $result = $expr->sql($binder);
+        $this->assertEquals('', $result);
+    }
 }

+ 18 - 0
tests/TestCase/ORM/QueryTest.php

@@ -1862,6 +1862,24 @@ class QueryTest extends TestCase
     }
 
     /**
+     * Test containing associations that have empty conditions.
+     *
+     * @return void
+     */
+    public function testContainAssociationWithEmptyConditions()
+    {
+        $articles = TableRegistry::get('Articles');
+        $articles->belongsTo('Authors', [
+            'conditions' => function ($exp, $query) {
+                return $exp;
+            }
+        ]);
+        $query = $articles->find('all')->contain(['Authors']);
+        $result = $query->toArray();
+        $this->assertCount(3, $result);
+    }
+
+    /**
      * Tests the formatResults method
      *
      * @return void