5454use function get_class ;
5555use function gettype ;
5656use function is_int ;
57+ use function is_numeric ;
5758use function is_object ;
5859use function is_string ;
5960use function method_exists ;
@@ -566,14 +567,14 @@ public function walkFunction($function): string
566567 $ type = $ firstExprType ;
567568 $ typeNoNull = TypeCombinator::removeNull ($ type );
568569
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
575572 }
576573
574+ $ type = TypeCombinator::containsNull ($ type )
575+ ? TypeCombinator::addNull (IntegerRangeType::fromInterval (0 , null ))
576+ : IntegerRangeType::fromInterval (0 , null );
577+
577578 if (TypeCombinator::containsNull ($ firstExprType ) || TypeCombinator::containsNull ($ secondExprType )) {
578579 $ type = TypeCombinator::addNull ($ type );
579580 }
@@ -586,8 +587,6 @@ public function walkFunction($function): string
586587 $ type = TypeCombinator::addNull ($ type );
587588 }
588589
589- // TODO more invalid usages
590-
591590 return $ this ->marshalType ($ this ->generalizeLiteralType ($ type , false ));
592591
593592 case $ function instanceof AST \Functions \SqrtFunction:
@@ -746,6 +745,10 @@ private function inferAvgFunction(AST\Functions\AvgFunction $function): Type
746745 return $ this ->createNumericString ($ nullable );
747746 }
748747
748+ if ($ exprTypeNoNull ->isString ()->yes () && !$ exprTypeNoNull ->isNumericString ()->yes ()) {
749+ return $ this ->createFloat ($ nullable );
750+ }
751+
749752 return $ this ->generalizeLiteralType ($ exprType , $ nullable );
750753 }
751754
@@ -780,6 +783,10 @@ private function inferSumFunction(AST\Functions\SumFunction $function): Type
780783 $ driver = $ this ->em ->getConnection ()->getDriver ();
781784
782785 if ($ driver instanceof Sqlite3Driver || $ driver instanceof PdoSqliteDriver) {
786+ if ($ exprTypeNoNull ->isString ()->yes () && !$ exprTypeNoNull ->isNumericString ()->yes ()) {
787+ return $ this ->createFloat ($ nullable );
788+ }
789+
783790 return $ this ->generalizeLiteralType ($ exprType , $ nullable );
784791 }
785792
@@ -788,6 +795,10 @@ private function inferSumFunction(AST\Functions\SumFunction $function): Type
788795 return $ this ->createNumericString ($ nullable );
789796 }
790797
798+ if ($ exprTypeNoNull ->isString ()->yes () && !$ exprTypeNoNull ->isNumericString ()->yes ()) {
799+ return $ this ->createFloat ($ nullable );
800+ }
801+
791802 return $ this ->generalizeLiteralType ($ exprType , $ nullable );
792803 }
793804
@@ -1382,12 +1393,21 @@ public function walkInParameter($inParam): string
13821393 public function walkLiteral ($ literal ): string
13831394 {
13841395 $ driver = $ this ->em ->getConnection ()->getDriver ();
1396+ $ isMysql = $ driver instanceof MysqliDriver || $ driver instanceof PdoMysqlDriver;
13851397
13861398 switch ($ literal ->type ) {
13871399 case AST \Literal::STRING :
13881400 $ value = $ literal ->value ;
13891401 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+ }
13911411 break ;
13921412
13931413 case AST \Literal::BOOLEAN :
@@ -1678,27 +1698,41 @@ private function inferDivisionType(array $termTypes): Type
16781698 return new MixedType ();
16791699 }
16801700
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 );
16841711 }
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 ()])) {
16861719 return $ this ->createFloat ($ nullable );
16871720 }
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 );
16931732 }
16941733 }
16951734
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 ();
17021736 }
17031737
17041738 /**
0 commit comments