Skip to content

Commit e65364a

Browse files
authored
Merge pull request #21 from dmitr1y/bugfix/round-single-argument
Fix: MySQL function ROUND() can take 1 or 2 arguments.
2 parents 54dcd11 + 01ab3ac commit e65364a

File tree

2 files changed

+48
-7
lines changed

2 files changed

+48
-7
lines changed

src/Processor/Expression/FunctionEvaluator.php

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,11 @@
22
namespace Vimeo\MysqlEngine\Processor\Expression;
33

44
use Vimeo\MysqlEngine\FakePdoInterface;
5+
use Vimeo\MysqlEngine\Processor\ProcessorException;
56
use Vimeo\MysqlEngine\Processor\QueryResult;
67
use Vimeo\MysqlEngine\Processor\Scope;
7-
use Vimeo\MysqlEngine\Processor\ProcessorException;
88
use Vimeo\MysqlEngine\Query\Expression\ColumnExpression;
9+
use Vimeo\MysqlEngine\Query\Expression\ConstantExpression;
910
use Vimeo\MysqlEngine\Query\Expression\Expression;
1011
use Vimeo\MysqlEngine\Query\Expression\FunctionExpression;
1112
use Vimeo\MysqlEngine\Query\Expression\IntervalOperatorExpression;
@@ -235,6 +236,19 @@ public static function getColumnSchema(
235236
return Evaluator::getColumnSchema($expr->args[0], $scope, $columns);
236237

237238
case 'ROUND':
239+
$precision = 0;
240+
241+
if (isset($expr->args[1])) {
242+
/** @var ConstantExpression $arg */
243+
$arg = $expr->args[1];
244+
245+
$precision = (int)$arg->value;
246+
}
247+
248+
if ($precision === 0) {
249+
return new Column\IntColumn(false, 10);
250+
}
251+
238252
return Evaluator::getColumnSchema($expr->args[0], $scope, $columns);
239253

240254
case 'DATEDIFF':
@@ -1239,24 +1253,31 @@ private static function sqlDay(
12391253

12401254
/**
12411255
* @param array<string, mixed> $row
1256+
*
1257+
* @return float|int
12421258
*/
12431259
private static function sqlRound(
12441260
FakePdoInterface $conn,
12451261
Scope $scope,
12461262
FunctionExpression $expr,
12471263
array $row,
12481264
QueryResult $result
1249-
) : float {
1265+
) {
12501266
$args = $expr->args;
12511267

1252-
if (\count($args) !== 2) {
1253-
throw new ProcessorException("MySQL ROUND() function must be called with one arguments");
1268+
if (\count($args) !== 1 && \count($args) !== 2) {
1269+
throw new ProcessorException("MySQL ROUND() function must be called with one or two arguments");
1270+
}
1271+
1272+
$number = (float)Evaluator::evaluate($conn, $scope, $args[0], $row, $result);
1273+
1274+
if (!isset($args[1])) {
1275+
return \round($number);
12541276
}
12551277

1256-
$first = Evaluator::evaluate($conn, $scope, $args[0], $row, $result);
1257-
$second = Evaluator::evaluate($conn, $scope, $args[1], $row, $result);
1278+
$precision = (int)Evaluator::evaluate($conn, $scope, $args[1], $row, $result);
12581279

1259-
return \round($first, $second);
1280+
return \round($number, $precision);
12601281
}
12611282

12621283
private static function getPhpIntervalFromExpression(

tests/EndToEndTest.php

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -542,6 +542,26 @@ public function testDecimalArithhmetic()
542542
);
543543
}
544544

545+
public function testRound()
546+
{
547+
$pdo = self::getPdo('mysql:foo');
548+
$pdo->setAttribute(\PDO::ATTR_EMULATE_PREPARES, false);
549+
550+
$query = $pdo->prepare('SELECT ROUND(3.141592) AS a, ROUND(3.141592, 2) AS b');
551+
552+
$query->execute();
553+
554+
$this->assertSame(
555+
[
556+
[
557+
'a' => 3,
558+
'b' => 3.14,
559+
],
560+
],
561+
$query->fetchAll(\PDO::FETCH_ASSOC)
562+
);
563+
}
564+
545565
public function testIsInFullSubquery()
546566
{
547567
$pdo = self::getConnectionToFullDB(false);

0 commit comments

Comments
 (0)