Skip to content

Commit

Permalink
Require precision and scale for decimal columns
Browse files Browse the repository at this point in the history
  • Loading branch information
morozov committed Aug 29, 2022
1 parent 5d01655 commit a8fc85e
Show file tree
Hide file tree
Showing 8 changed files with 67 additions and 26 deletions.
18 changes: 18 additions & 0 deletions src/Exception/ColumnPrecisionRequired.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

declare(strict_types=1);

namespace Doctrine\DBAL\Exception;

use Doctrine\DBAL\Exception;

/**
* @psalm-immutable
*/
final class ColumnPrecisionRequired extends Exception
{
public static function new(): self
{
return new self('Column precision is not specified');
}
}
18 changes: 18 additions & 0 deletions src/Exception/ColumnScaleRequired.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

declare(strict_types=1);

namespace Doctrine\DBAL\Exception;

use Doctrine\DBAL\Exception;

/**
* @psalm-immutable
*/
final class ColumnScaleRequired extends Exception
{
public static function new(): self
{
return new self('Column scale is not specified');
}
}
16 changes: 12 additions & 4 deletions src/Platforms/AbstractPlatform.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
use Doctrine\DBAL\Events;
use Doctrine\DBAL\Exception;
use Doctrine\DBAL\Exception\ColumnLengthRequired;
use Doctrine\DBAL\Exception\ColumnPrecisionRequired;
use Doctrine\DBAL\Exception\ColumnScaleRequired;
use Doctrine\DBAL\LockMode;
use Doctrine\DBAL\Platforms\Exception\NoColumnsSpecifiedForTable;
use Doctrine\DBAL\Platforms\Exception\NotSupported;
Expand Down Expand Up @@ -1591,13 +1593,19 @@ public function getColumnDeclarationSQL(string $name, array $column): string
* Returns the SQL snippet that declares a floating point column of arbitrary precision.
*
* @param mixed[] $column
*
* @throws ColumnPrecisionRequired
* @throws ColumnScaleRequired
*/
public function getDecimalTypeDeclarationSQL(array $column): string
{
$column['precision'] = ! isset($column['precision']) || empty($column['precision'])
? 10 : $column['precision'];
$column['scale'] = ! isset($column['scale']) || empty($column['scale'])
? 0 : $column['scale'];
if (! isset($column['precision'])) {
throw ColumnPrecisionRequired::new();
}

if (! isset($column['scale'])) {
throw ColumnScaleRequired::new();
}

return 'NUMERIC(' . $column['precision'] . ', ' . $column['scale'] . ')';
}
Expand Down
2 changes: 1 addition & 1 deletion src/Schema/Comparator.php
Original file line number Diff line number Diff line change
Expand Up @@ -473,7 +473,7 @@ public function diffColumn(Column $column1, Column $column2): array
$changedProperties[] = 'fixed';
}
} elseif ($properties1['type'] instanceof Types\DecimalType) {
if (($properties1['precision'] ?? 10) !== ($properties2['precision'] ?? 10)) {
if ($properties1['precision'] !== $properties2['precision']) {
$changedProperties[] = 'precision';
}

Expand Down
12 changes: 10 additions & 2 deletions tests/Functional/Schema/MySQLSchemaManagerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -344,8 +344,16 @@ public function testListDecimalTypeColumns(): void
$tableName = 'test_list_decimal_columns';
$table = new Table($tableName);

$table->addColumn('col', 'decimal');
$table->addColumn('col_unsigned', 'decimal', ['unsigned' => true]);
$table->addColumn('col', 'decimal', [
'precision' => 10,
'scale' => 6,
]);

$table->addColumn('col_unsigned', 'decimal', [
'precision' => 10,
'scale' => 6,
'unsigned' => true,
]);

$this->dropAndCreateTable($table);

Expand Down
4 changes: 2 additions & 2 deletions tests/Functional/Schema/SQLServerSchemaManagerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,15 @@ public function testDropColumnConstraints(): void
{
$table = new Table('sqlsrv_drop_column');
$table->addColumn('id', 'integer');
$table->addColumn('todrop', 'decimal', ['default' => 10.2]);
$table->addColumn('todrop', 'integer', ['default' => 10]);

$this->schemaManager->createTable($table);

$diff = new TableDiff(
'sqlsrv_drop_column',
[],
[],
['todrop' => new Column('todrop', Type::getType('decimal'))]
['todrop' => new Column('todrop', Type::getType('integer'))]
);

$this->schemaManager->alterTable($diff);
Expand Down
11 changes: 3 additions & 8 deletions tests/Platforms/AbstractMySQLPlatformTestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -731,14 +731,9 @@ protected function getGeneratesAlterTableRenameIndexUsedByForeignKeySQL(): array
*/
public static function getGeneratesDecimalTypeDeclarationSQL(): iterable
{
return [
[[], 'NUMERIC(10, 0)'],
[['unsigned' => true], 'NUMERIC(10, 0) UNSIGNED'],
[['unsigned' => false], 'NUMERIC(10, 0)'],
[['precision' => 5], 'NUMERIC(5, 0)'],
[['scale' => 5], 'NUMERIC(10, 5)'],
[['precision' => 8, 'scale' => 2], 'NUMERIC(8, 2)'],
];
yield [['precision' => 10, 'scale' => 8, 'unsigned' => true], 'NUMERIC(10, 8) UNSIGNED'];

yield from parent::getGeneratesDecimalTypeDeclarationSQL();
}

/**
Expand Down
12 changes: 3 additions & 9 deletions tests/Platforms/AbstractPlatformTestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -1273,18 +1273,12 @@ public function testGeneratesDecimalTypeDeclarationSQL(array $column, string $ex
}

/**
* @return mixed[][]
* @return iterable<array{array<string,mixed>,string}>
*/
public static function getGeneratesDecimalTypeDeclarationSQL(): iterable
{
return [
[[], 'NUMERIC(10, 0)'],
[['unsigned' => true], 'NUMERIC(10, 0)'],
[['unsigned' => false], 'NUMERIC(10, 0)'],
[['precision' => 5], 'NUMERIC(5, 0)'],
[['scale' => 5], 'NUMERIC(10, 5)'],
[['precision' => 8, 'scale' => 2], 'NUMERIC(8, 2)'],
];
yield [['precision' => 10, 'scale' => 0], 'NUMERIC(10, 0)'];
yield [['precision' => 8, 'scale' => 2], 'NUMERIC(8, 2)'];
}

/**
Expand Down

0 comments on commit a8fc85e

Please sign in to comment.