54
54
use function get_class ;
55
55
use function gettype ;
56
56
use function is_int ;
57
+ use function is_numeric ;
57
58
use function is_object ;
58
59
use function is_string ;
59
60
use function method_exists ;
@@ -566,14 +567,14 @@ public function walkFunction($function): string
566
567
$ type = $ firstExprType ;
567
568
$ typeNoNull = TypeCombinator::removeNull ($ type );
568
569
569
- // TODO simplify?
570
-
571
- if ($ typeNoNull ->isInteger ()->yes ()) {
572
- $ type = TypeCombinator::containsNull ($ type )
573
- ? TypeCombinator::addNull (IntegerRangeType::fromInterval (0 , null ))
574
- : IntegerRangeType::fromInterval (0 , null );
570
+ if (!$ typeNoNull ->isInteger ()->yes ()) {
571
+ return $ this ->marshalType (new MixedType ()); // dont try to deal with non-integer chaos
575
572
}
576
573
574
+ $ type = TypeCombinator::containsNull ($ type )
575
+ ? TypeCombinator::addNull (IntegerRangeType::fromInterval (0 , null ))
576
+ : IntegerRangeType::fromInterval (0 , null );
577
+
577
578
if (TypeCombinator::containsNull ($ firstExprType ) || TypeCombinator::containsNull ($ secondExprType )) {
578
579
$ type = TypeCombinator::addNull ($ type );
579
580
}
@@ -586,8 +587,6 @@ public function walkFunction($function): string
586
587
$ type = TypeCombinator::addNull ($ type );
587
588
}
588
589
589
- // TODO more invalid usages
590
-
591
590
return $ this ->marshalType ($ this ->generalizeLiteralType ($ type , false ));
592
591
593
592
case $ function instanceof AST \Functions \SqrtFunction:
@@ -746,6 +745,10 @@ private function inferAvgFunction(AST\Functions\AvgFunction $function): Type
746
745
return $ this ->createNumericString ($ nullable );
747
746
}
748
747
748
+ if ($ exprTypeNoNull ->isString ()->yes () && !$ exprTypeNoNull ->isNumericString ()->yes ()) {
749
+ return $ this ->createFloat ($ nullable );
750
+ }
751
+
749
752
return $ this ->generalizeLiteralType ($ exprType , $ nullable );
750
753
}
751
754
@@ -780,6 +783,10 @@ private function inferSumFunction(AST\Functions\SumFunction $function): Type
780
783
$ driver = $ this ->em ->getConnection ()->getDriver ();
781
784
782
785
if ($ driver instanceof Sqlite3Driver || $ driver instanceof PdoSqliteDriver) {
786
+ if ($ exprTypeNoNull ->isString ()->yes () && !$ exprTypeNoNull ->isNumericString ()->yes ()) {
787
+ return $ this ->createFloat ($ nullable );
788
+ }
789
+
783
790
return $ this ->generalizeLiteralType ($ exprType , $ nullable );
784
791
}
785
792
@@ -788,6 +795,10 @@ private function inferSumFunction(AST\Functions\SumFunction $function): Type
788
795
return $ this ->createNumericString ($ nullable );
789
796
}
790
797
798
+ if ($ exprTypeNoNull ->isString ()->yes () && !$ exprTypeNoNull ->isNumericString ()->yes ()) {
799
+ return $ this ->createFloat ($ nullable );
800
+ }
801
+
791
802
return $ this ->generalizeLiteralType ($ exprType , $ nullable );
792
803
}
793
804
@@ -1382,12 +1393,21 @@ public function walkInParameter($inParam): string
1382
1393
public function walkLiteral ($ literal ): string
1383
1394
{
1384
1395
$ driver = $ this ->em ->getConnection ()->getDriver ();
1396
+ $ isMysql = $ driver instanceof MysqliDriver || $ driver instanceof PdoMysqlDriver;
1385
1397
1386
1398
switch ($ literal ->type ) {
1387
1399
case AST \Literal::STRING :
1388
1400
$ value = $ literal ->value ;
1389
1401
assert (is_string ($ value ));
1390
- $ type = new ConstantStringType ($ value );
1402
+ if (is_numeric ($ value )) {
1403
+ if (strpos ($ value , '. ' ) === false && strpos ($ value , 'e ' ) === false && !$ isMysql ) {
1404
+ $ type = new ConstantIntegerType ((int ) $ value );
1405
+ } else {
1406
+ $ type = new ConstantFloatType ((float ) $ value );
1407
+ }
1408
+ } else {
1409
+ $ type = new ConstantStringType ($ value );
1410
+ }
1391
1411
break ;
1392
1412
1393
1413
case AST \Literal::BOOLEAN :
@@ -1678,27 +1698,41 @@ private function inferDivisionType(array $termTypes): Type
1678
1698
return new MixedType ();
1679
1699
}
1680
1700
1681
- if ($ this ->containsOnlyTypes ($ unionWithoutNull , [new IntegerType (), new FloatType (), $ this ->createNumericString (false )])) {
1682
- if ($ driver instanceof PdoPgSQLDriver) {
1683
- return $ this ->createNumericString ($ nullable );
1701
+ if ($ driver instanceof PdoPgSQLDriver) {
1702
+ return $ this ->createNumericString ($ nullable );
1703
+ }
1704
+
1705
+ if ($ driver instanceof SQLite3Driver || $ driver instanceof PdoSqliteDriver) {
1706
+ if ($ this ->containsOnlyTypes ($ unionWithoutNull , [new IntegerType (), new FloatType ()])) {
1707
+ return $ this ->createFloat ($ nullable );
1708
+ }
1709
+ if ($ this ->containsOnlyTypes ($ unionWithoutNull , [new IntegerType (), new StringType ()])) {
1710
+ return $ this ->createInteger (true );
1684
1711
}
1685
- if ($ driver instanceof SQLite3Driver || $ driver instanceof PdoSqliteDriver) {
1712
+ if ($ this ->containsOnlyTypes ($ unionWithoutNull , [new FloatType (), new StringType ()])) {
1713
+ return $ this ->createFloat (true );
1714
+ }
1715
+ }
1716
+
1717
+ if ($ driver instanceof MysqliDriver || $ driver instanceof PdoMysqlDriver || $ driver instanceof PgSQLDriver) {
1718
+ if ($ this ->containsOnlyTypes ($ unionWithoutNull , [new IntegerType (), new FloatType ()])) {
1686
1719
return $ this ->createFloat ($ nullable );
1687
1720
}
1688
- if ($ driver instanceof MysqliDriver || $ driver instanceof PdoMysqlDriver || $ driver instanceof PgSQLDriver) {
1689
- return TypeCombinator::union ( // float vs decimal
1690
- $ this ->createNumericString ($ nullable ),
1691
- $ this ->createFloat ($ nullable )
1692
- );
1721
+
1722
+ if ($ this ->containsOnlyTypes ($ unionWithoutNull , [new IntegerType (), $ this ->createNumericString (false )])) {
1723
+ return $ this ->createNumericString ($ nullable );
1724
+ }
1725
+
1726
+ if ($ this ->containsOnlyTypes ($ unionWithoutNull , [new IntegerType (), new StringType ()])) {
1727
+ return $ this ->createFloat (true );
1728
+ }
1729
+
1730
+ if ($ this ->containsOnlyTypes ($ unionWithoutNull , [new FloatType (), new StringType ()])) {
1731
+ return $ this ->createFloat (true );
1693
1732
}
1694
1733
}
1695
1734
1696
- // incompatible types, not trying to be precise here, very chaotic behaviour + postgre fails
1697
- return TypeCombinator::union (
1698
- $ this ->createNumericString (true ),
1699
- $ this ->createFloat (true ),
1700
- $ this ->createInteger (true )
1701
- );
1735
+ return new MixedType ();
1702
1736
}
1703
1737
1704
1738
/**
0 commit comments