Closed
Description
- Laravel Version: 9.43.0
- PHP Version: 8.0
- Database Driver & Version: MySQL 8.0
Description:
Some unexpected type changes occurs when trying to rename a column with one of the following types:
Schema::create('bars', function (Blueprint $table) {
$table->mediumInteger('foo');
});
Schema::table('bars', function (Blueprint $table) {
$table->renameColumn('foo', 'bar'); // changes the name but also changes its type to INT
});
Column type | Expected | Actual | Notes |
---|---|---|---|
timestamp('foo', 2) |
TIMESTAMP(2) |
DATETIME |
Changes type and removes precision |
mediumInteger('foo') |
MEDIUMINT |
INT |
Changes type |
tinyInteger('foo') |
TINYINT |
TINYINT(1) |
Changes type to Boolean |
dateTime('foo', 2) |
DATETIME(2) |
DATETIME |
Removes precision |
time('foo', 2) |
TIME(2) |
TIME |
Removes precision |
year('foo') |
YEAR |
DATE |
Changes type #38506 |
double('foo') |
DOUBLE(8, 2) |
DOUBLE PRECISION |
Removes total and places |
float('foo') |
DOUBLE(8, 2) |
DOUBLE PRECISION |
Removes total and places |
set('foo', ['bar', 'qux']) |
SET('bar', 'qux') |
LONGTEXT COMMENT '(DC2Type:simple_array)' |
Changes the type and adds a comment |
enum('foo', ['bar', 'qux']) |
ENUM('bar', 'qux') |
VARCHAR(255) |
Documented on Laravel docs as not supported |
Additional notes:
- I just tested MySQL, but I believe there are similar issues on other databases.
- Some modifiers are also get removed when renaming a column like
useCurrentOnUpdate
andinvisible
. I didn't check all of them. - The
nullable
modifier compiles todefault null
when renaming. I'm not sure if there is a difference betweenINT NULL
andINT DEFAULT NULL
on MySQL. Also when usingnullable()->default(4)
modifiers together, we expectINT NULL DEFAULT 4
but we getINT DEFAULT 4
instead. - Renaming all spatial column types (
geometry
,point
,lineString
,polygon
,geometryCollection
,multiPoint
,multiLineString
andmultiPolygon
) throws an exception. - Obviously all dependent column types like
unsignedMediumInteger
,unsignedTinyInteger
,mediumIncrements
,tinyIncrements
etc. have the same problem.
Conclusion
I tried to list all issues of renameColumn
, but some of these are also apply to modifying columns using change
and some other unexpected behavior occurs when using change
. I tried to fix some of them (#44101, #41320 and #43541) but still have issues like #44912. I wish we could get rid of doctrine/dbal
and do column renaming and modifying natively (on Laravel 10 maybe?) or via a new Laravel first-party package, specially with many deprecations on upcoming doctrine/dbal
v4: https://github.com/doctrine/dbal/blob/4.0.x/UPGRADE.md
Steps To Reproduce:
- Rename a column with one of types listed above.
You may use the following test to reproduce the issue;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\DB;
use Tests\TestCase;
class RenameColumnTest extends TestCase
{
use RefreshDatabase;
public function test_rename_column()
{
$connection = DB::connection('mysql');
$connection->getSchemaBuilder()->create('bars', function (Blueprint $table) {
$table->timestamp('foo', 2)->nullable()->useCurrentOnUpdate();
$table->mediumInteger('baz')->nullable()->default(4);
});
$blueprint = new Blueprint('bars', function (Blueprint $table) {
$table->renameColumn('foo', 'bar');
$table->renameColumn('baz', 'qux');
});
$queries = $blueprint->toSql($connection, $connection->getSchemaGrammar());
$expected = [
'ALTER TABLE bars CHANGE foo bar TIMESTAMP(2) ON UPDATE CURRENT_TIMESTAMP(2) NULL',
'ALTER TABLE bars CHANGE baz qux MEDIUMINT NULL DEFAULT 4',
];
$this->assertEquals($expected, $queries);
}
}
Metadata
Metadata
Assignees
Labels
No labels