Skip to content

Commit 55ea1a0

Browse files
dereuromarkJamison Bryant
authored andcommitted
Fix TEXT column variants not round-tripping correctly (#1032)
When using migration_diff, TEXT column variants (TINYTEXT, MEDIUMTEXT, LONGTEXT) were not being properly mapped back from the database. The BLOB type handling already used rawType to distinguish BLOB variants, but TEXT variants were missing equivalent handling. This adds similar rawType-based mapping for TEXT columns in mapColumnType() and includes round-trip tests. Fixes #1029
1 parent a492413 commit 55ea1a0

File tree

2 files changed

+45
-0
lines changed

2 files changed

+45
-0
lines changed

src/Db/Adapter/MysqlAdapter.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -594,6 +594,20 @@ protected function mapColumnType(array $columnData): array
594594
}
595595
}
596596
// else: keep as binary or varbinary (actual BINARY/VARBINARY column)
597+
} elseif ($type === TableSchema::TYPE_TEXT) {
598+
// CakePHP returns TEXT columns as 'text' with specific lengths
599+
// Check the raw MySQL type to distinguish TEXT variants
600+
$rawType = $columnData['rawType'] ?? '';
601+
if (str_contains($rawType, 'tinytext')) {
602+
$length = static::TEXT_TINY;
603+
} elseif (str_contains($rawType, 'mediumtext')) {
604+
$length = static::TEXT_MEDIUM;
605+
} elseif (str_contains($rawType, 'longtext')) {
606+
$length = static::TEXT_LONG;
607+
} else {
608+
// Regular TEXT - use null to indicate default TEXT type
609+
$length = null;
610+
}
597611
}
598612

599613
return [$type, $length];

tests/TestCase/Db/Adapter/MysqlAdapterTest.php

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1369,6 +1369,37 @@ public function testBlobRoundTrip(string $type, ?int $limit, string $expectedTyp
13691369
$this->adapter->dropTable('blob_round_trip_test');
13701370
}
13711371

1372+
public static function textRoundTripData()
1373+
{
1374+
return [
1375+
// type, limit, expected type after round-trip, expected limit after round-trip
1376+
['text', null, 'text', null],
1377+
['text', MysqlAdapter::TEXT_TINY, 'text', MysqlAdapter::TEXT_TINY],
1378+
['text', MysqlAdapter::TEXT_MEDIUM, 'text', MysqlAdapter::TEXT_MEDIUM],
1379+
['text', MysqlAdapter::TEXT_LONG, 'text', MysqlAdapter::TEXT_LONG],
1380+
];
1381+
}
1382+
1383+
#[DataProvider('textRoundTripData')]
1384+
public function testTextRoundTrip(string $type, ?int $limit, string $expectedType, ?int $expectedLimit)
1385+
{
1386+
// Create a table with a TEXT column
1387+
$table = new Table('text_round_trip_test', [], $this->adapter);
1388+
$table->addColumn('text_col', $type, ['limit' => $limit])
1389+
->save();
1390+
1391+
// Read the column back from the database
1392+
$columns = $this->adapter->getColumns('text_round_trip_test');
1393+
1394+
$textColumn = $columns[1];
1395+
$this->assertNotNull($textColumn, 'TEXT column not found');
1396+
$this->assertSame($expectedType, $textColumn->getType(), 'Type mismatch after round-trip');
1397+
$this->assertSame($expectedLimit, $textColumn->getLimit(), 'Limit mismatch after round-trip');
1398+
1399+
// Clean up
1400+
$this->adapter->dropTable('text_round_trip_test');
1401+
}
1402+
13721403
public function testTimestampInvalidLimit()
13731404
{
13741405
$this->adapter->connect();

0 commit comments

Comments
 (0)