Browse Source

Correct the parameter type used in function expressions.

Only using the non-default types doesn't provide access to the typehints
that were provided during the expression creation. This causes bound
parameters to be incorrect. While this change corrects the type of the bound
parameter it does not fix the selected value's type.

Refs #6739
Mark Story 10 years ago
parent
commit
6639b0d47a

+ 2 - 3
src/Database/Expression/FunctionExpression.php

@@ -95,6 +95,7 @@ class FunctionExpression extends QueryExpression
     public function add($params, $types = [], $prepend = false)
     {
         $put = $prepend ? 'array_unshift' : 'array_push';
+        $typeMap = $this->typeMap()->types($types);
         foreach ($params as $k => $p) {
             if ($p === 'literal') {
                 $put($this->_conditions, $k);
@@ -105,9 +106,7 @@ class FunctionExpression extends QueryExpression
                 $put($this->_conditions, $p);
                 continue;
             }
-
-            $type = isset($types[$k]) ? $types[$k] : null;
-            $put($this->_conditions, ['value' => $p, 'type' => $type]);
+            $put($this->_conditions, ['value' => $p, 'type' => $typeMap->type($k)]);
         }
 
         return $this;

+ 26 - 0
tests/TestCase/ORM/QueryRegressionTest.php

@@ -878,4 +878,30 @@ class QueryRegressionTest extends TestCase
         $this->assertEquals(0, $table->find()->count());
         $this->assertNull($table->find()->last());
     }
+
+    /**
+     * Test that the typemaps used in function expressions
+     * create the correct results.
+     *
+     * @return void
+     */
+    public function testTypemapInFunctions()
+    {
+        $table = TableRegistry::get('Comments');
+        $table->updateAll(['published' => null], ['1 = 1']);
+        $query = $table->find();
+        $query->select([
+            'id',
+            'coalesced' => $query->func()->coalesce(
+                ['published' => 'literal', -1],
+                ['integer']
+            )
+        ]);
+        $result = $query->all()->first();
+        $this->assertSame(
+            '-1',
+            $result['coalesced'],
+            'Output values for functions are not cast yet.'
+        );
+    }
 }

+ 1 - 2
tests/TestCase/ORM/QueryTest.php

@@ -835,8 +835,7 @@ class QueryTest extends TestCase
 
         $this->assertEquals(1, $query->clause('limit'));
 
-        $expected = new QueryExpression(['a > b']);
-        $expected->typeMap($this->fooTypeMap);
+        $expected = new QueryExpression(['a > b'], $this->fooTypeMap);
         $result = $query->clause('join');
         $this->assertEquals([
             'table_a' => ['alias' => 'table_a', 'type' => 'INNER', 'conditions' => $expected]