Browse Source

Support type inference from `TypedResultInterface` in case expressions.

This allows to infer the case expression's result type from the `then()`
and `else()` values when using expressions like `sum()` that provide a
result type themselves.
ndm2 4 years ago
parent
commit
f6d2238239

+ 3 - 0
src/Database/Expression/CaseExpressionTrait.php

@@ -20,6 +20,7 @@ use Cake\Chronos\Date;
 use Cake\Chronos\MutableDate;
 use Cake\Database\ExpressionInterface;
 use Cake\Database\Query;
+use Cake\Database\TypedResultInterface;
 use Cake\Database\ValueBinder;
 use DateTimeInterface;
 
@@ -67,6 +68,8 @@ trait CaseExpressionTrait
             $value instanceof IdentifierExpression
         ) {
             $type = $this->_typeMap->type($value->getIdentifier());
+        } elseif ($value instanceof TypedResultInterface) {
+            $type = $value->getReturnType();
         }
 
         return $type;

+ 4 - 0
tests/TestCase/Database/Expression/CaseStatementExpressionTest.php

@@ -21,6 +21,7 @@ use Cake\Chronos\Date as ChronosDate;
 use Cake\Chronos\MutableDate as ChronosMutableDate;
 use Cake\Database\Expression\CaseStatementExpression;
 use Cake\Database\Expression\ComparisonExpression;
+use Cake\Database\Expression\FunctionExpression;
 use Cake\Database\Expression\IdentifierExpression;
 use Cake\Database\Expression\QueryExpression;
 use Cake\Database\Expression\WhenThenExpression;
@@ -218,6 +219,7 @@ class CaseStatementExpressionTest extends TestCase
             [ChronosDate::now(), 'date'],
             [Chronos::now(), 'datetime'],
             [new IdentifierExpression('Table.column'), null],
+            [new FunctionExpression('SUM', ['Table.column' => 'literal'], [], 'integer'), null],
             [new stdClass(), null],
             [null, null],
         ];
@@ -252,6 +254,7 @@ class CaseStatementExpressionTest extends TestCase
             [ChronosDate::now(), 'date'],
             [Chronos::now(), 'datetime'],
             [new IdentifierExpression('Table.column'), null],
+            [new FunctionExpression('SUM', ['Table.column' => 'literal'], [], 'integer'), null],
             [['Table.column' => true], null],
             [new stdClass(), null],
         ];
@@ -287,6 +290,7 @@ class CaseStatementExpressionTest extends TestCase
             [ChronosDate::now(), 'date'],
             [Chronos::now(), 'datetime'],
             [new IdentifierExpression('Table.column'), 'boolean'],
+            [new FunctionExpression('SUM', ['Table.column' => 'literal'], [], 'integer'), 'integer'],
             [new stdClass(), null],
             [null, null],
         ];