Browse Source

Strip aliases from update query conditions where possible.

Unlike for delete queries, possible aliases in the conditions of
update queries are not being removed, which will fail for some
database dialects.
ndm2 9 years ago
parent
commit
7ea595f348
2 changed files with 62 additions and 11 deletions
  1. 28 11
      src/Database/SqlDialectTrait.php
  2. 34 0
      tests/TestCase/Database/QueryTest.php

+ 28 - 11
src/Database/SqlDialectTrait.php

@@ -178,6 +178,34 @@ trait SqlDialectTrait
         if (!$hadAlias) {
             return $query;
         }
+
+        return $this->_removeAliasesFromConditions($query);
+    }
+
+    /**
+     * Apply translation steps to update queries.
+     *
+     * Chops out aliases on update query conditions as not all database dialects do support
+     * aliases in update queries.
+     *
+     * Just like for delete queries, joins are currently not supported for update queries.
+     *
+     * @param \Cake\Database\Query $query The query to translate
+     * @return \Cake\Database\Query The modified query
+     */
+    protected function _updateQueryTranslator($query)
+    {
+        return $this->_removeAliasesFromConditions($query);
+    }
+
+    /**
+     * Removes aliases from the `WHERE` clause of a query.
+     *
+     * @param \Cake\Database\Query $query The query to process.
+     * @return \Cake\Database\Query The modified query.
+     */
+    protected function _removeAliasesFromConditions($query)
+    {
         $conditions = $query->clause('where');
         if ($conditions) {
             $conditions->traverse(function ($condition) {
@@ -201,17 +229,6 @@ trait SqlDialectTrait
     }
 
     /**
-     * Apply translation steps to update queries.
-     *
-     * @param \Cake\Database\Query $query The query to translate
-     * @return \Cake\Database\Query The modified query
-     */
-    protected function _updateQueryTranslator($query)
-    {
-        return $query;
-    }
-
-    /**
      * Apply translation steps to insert queries.
      *
      * @param \Cake\Database\Query $query The query to translate

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

@@ -2834,6 +2834,40 @@ class QueryTest extends TestCase
     }
 
     /**
+     * Tests that aliases are stripped from update query conditions
+     * where possible.
+     *
+     * @return void
+     */
+    public function testUpdateStripAliasesFromConditions()
+    {
+        $this->loadFixtures('Authors');
+        $query = new Query($this->connection);
+
+        $query
+            ->update('authors')
+            ->set(['name' => 'name'])
+            ->where([
+                'OR' => [
+                    'a.id' => 1,
+                    'AND' => [
+                        'b.name NOT IN' => ['foo', 'bar'],
+                        'OR' => [
+                            $query->newExpr()->eq(new IdentifierExpression('c.name'), 'zap'),
+                            'd.name' => 'baz'
+                        ]
+                    ]
+                ],
+            ]);
+
+        $this->assertQuotedQuery(
+            'UPDATE <authors> SET <name> = :c0 WHERE \(<id> = :c1 OR \(<name> not in \(:c2,:c3\) AND \(\(<c>\.<name>\) = :c4 OR <name> = :c5\)\)\)',
+            $query->sql(),
+            !$this->autoQuote
+        );
+    }
+
+    /**
      * You cannot call values() before insert() it causes all sorts of pain.
      *
      * @expectedException \Cake\Database\Exception