diff --git a/src/Type/Doctrine/Query/QueryResultTypeWalker.php b/src/Type/Doctrine/Query/QueryResultTypeWalker.php index 55375c5f..1292ed8d 100644 --- a/src/Type/Doctrine/Query/QueryResultTypeWalker.php +++ b/src/Type/Doctrine/Query/QueryResultTypeWalker.php @@ -1261,7 +1261,19 @@ public function walkArithmeticFactor($factor): string $primary = $factor->arithmeticPrimary; $type = $this->unmarshalType($this->walkArithmeticPrimary($primary)); - $type = TypeUtils::generalizeType($type, GeneralizePrecision::lessSpecific()); + + if ($type instanceof ConstantIntegerType && $factor->sign === false) { + $type = new ConstantIntegerType($type->getValue() * -1); + + } elseif ($type instanceof IntegerRangeType && $factor->sign === false) { + $type = IntegerRangeType::fromInterval( + $type->getMax() === null ? null : $type->getMax() * -1, + $type->getMin() === null ? null : $type->getMin() * -1 + ); + + } elseif ($type instanceof ConstantFloatType && $factor->sign === false) { + $type = new ConstantFloatType($type->getValue() * -1); + } return $this->marshalType($type); } diff --git a/tests/Type/Doctrine/Query/QueryResultTypeWalkerTest.php b/tests/Type/Doctrine/Query/QueryResultTypeWalkerTest.php index f2f349ed..e5e9aad9 100644 --- a/tests/Type/Doctrine/Query/QueryResultTypeWalkerTest.php +++ b/tests/Type/Doctrine/Query/QueryResultTypeWalkerTest.php @@ -82,6 +82,7 @@ public static function setUpBeforeClass(): void $dataOne = [ 'intColumn' => [1, 2], + 'floatColumn' => [0.1, 2.0], 'stringColumn' => ['A', 'B'], 'stringNullColumn' => ['A', null], ]; @@ -108,10 +109,11 @@ public static function setUpBeforeClass(): void $id = 1; foreach (self::combinations($dataOne) as $combination) { - [$intColumn, $stringColumn, $stringNullColumn] = $combination; + [$intColumn, $floatColumn, $stringColumn, $stringNullColumn] = $combination; $one = new One(); $one->id = (string) $id++; $one->intColumn = $intColumn; + $one->floatColumn = $floatColumn; $one->stringColumn = $stringColumn; $one->stringNullColumn = $stringNullColumn; $embedded = new Embedded(); @@ -1189,7 +1191,7 @@ public function getTestData(): iterable yield 'arithmetic' => [ $this->constantArray([ [new ConstantStringType('intColumn'), new IntegerType()], - [new ConstantIntegerType(1), $this->intStringified()], + [new ConstantIntegerType(1), TypeCombinator::union(new ConstantIntegerType(1), new ConstantStringType('1'))], [new ConstantIntegerType(2), $this->intStringified()], [new ConstantIntegerType(3), TypeCombinator::addNull($this->intStringified())], [new ConstantIntegerType(4), $this->intStringified()], @@ -1614,6 +1616,20 @@ public function getTestData(): iterable FROM QueryResult\Entities\One o ', ]; + + yield 'unary minus' => [ + $this->constantArray([ + [new ConstantStringType('minusInt'), $this->numericStringOrInt()], // should be nullable + [new ConstantStringType('minusFloat'), TypeCombinator::union(new FloatType(), $this->numericStringOrInt())], // should be nullable && should not include int + [new ConstantStringType('minusIntRange'), TypeCombinator::union(IntegerRangeType::fromInterval(null, 0), $this->numericString())], + ]), + ' + SELECT -o.intColumn as minusInt, + -o.floatColumn as minusFloat, + -COUNT(o.intColumn) as minusIntRange + FROM QueryResult\Entities\One o + ', + ]; } /** diff --git a/tests/Type/Doctrine/data/QueryResult/Entities/One.php b/tests/Type/Doctrine/data/QueryResult/Entities/One.php index 5605c945..81811618 100644 --- a/tests/Type/Doctrine/data/QueryResult/Entities/One.php +++ b/tests/Type/Doctrine/data/QueryResult/Entities/One.php @@ -31,6 +31,13 @@ class One */ public $intColumn; + /** + * @Column(type="float") + * + * @var float + */ + public $floatColumn; + /** * @Column(type="string") *