diff --git a/src/Schema/Grammars/GrammarTable.php b/src/Schema/Grammars/GrammarTable.php index ea43814..ddd3914 100644 --- a/src/Schema/Grammars/GrammarTable.php +++ b/src/Schema/Grammars/GrammarTable.php @@ -5,6 +5,7 @@ namespace Tpetry\PostgresqlEnhanced\Schema\Grammars; use Illuminate\Database\Schema\Blueprint; +use Illuminate\Support\Facades\App; use Illuminate\Support\Fluent; trait GrammarTable @@ -16,6 +17,34 @@ trait GrammarTable */ public function compileAdd(Blueprint $blueprint, Fluent $command): array { + if (version_compare(App::version(), '11.15.0', '>=')) { + $sql = []; + + $column = $command->column; + $attributes = $column->getAttributes(); + + if (\array_key_exists('initial', $attributes)) { + if (\array_key_exists('default', $attributes)) { + $sql[] = sprintf('alter table %s alter column %s set default %s', + $this->wrapTable($blueprint), + $this->wrap($column), + $this->getDefaultValue($column['default']) + ); + } else { + $sql[] = sprintf('alter table %s alter column %s drop default', + $this->wrapTable($blueprint), + $this->wrap($column), + ); + } + + $column['default'] = $column['initial']; + } + + $sql[] = parent::compileAdd($blueprint, $command); + + return array_reverse($sql); + } + $sql = []; foreach (array_reverse($blueprint->getAddedColumns()) as $column) { diff --git a/src/Schema/Grammars/GrammarTypes.php b/src/Schema/Grammars/GrammarTypes.php index 65794bb..6c355d0 100644 --- a/src/Schema/Grammars/GrammarTypes.php +++ b/src/Schema/Grammars/GrammarTypes.php @@ -7,6 +7,7 @@ use Illuminate\Database\Connection; use Illuminate\Database\Schema\Blueprint as BaseBlueprint; use Illuminate\Support\Arr; +use Illuminate\Support\Facades\App; use Illuminate\Support\Fluent; use Spatie\Regex\Regex; @@ -17,6 +18,43 @@ trait GrammarTypes */ public function compileChange(BaseBlueprint $blueprint, Fluent $command, Connection $connection): array { + if (version_compare(App::version(), '11.15.0', '>=')) { + $queries = []; + + $changedColumn = $command->column; + + $compression = $changedColumn['compression']; + $changedColumn->offsetUnset('compression'); + + $sql = parent::compileChange($blueprint, $command, $connection); + $regex = Regex::match('/^ALTER table (?P.*?) alter (column )?(?P.*?) type (?P\w+)(?P,.*)?/i', $sql); + + if (filled($changedColumn['using']) && $regex->hasMatch()) { + $using = match ($connection->getSchemaGrammar()->isExpression($changedColumn['using'])) { + true => $connection->getSchemaGrammar()->getValue($changedColumn['using']), + false => $changedColumn['using'], + }; + + $queries[] = match (filled($modifiers = $regex->groupOr('modifiers', ''))) { + true => "alter table {$regex->group('table')} alter column {$regex->group('column')} type {$regex->group('type')} using {$using}{$modifiers}", + false => "alter table {$regex->group('table')} alter column {$regex->group('column')} type {$regex->group('type')} using {$using}", + }; + } else { + $queries[] = $sql; + } + + if (filled($compression)) { + $queries[] = sprintf( + 'alter table %s alter %s set compression %s', + $this->wrapTable($blueprint->getTable()), + $this->wrap($changedColumn['name']), + $this->wrap($compression), + ); + } + + return $queries; + } + $queries = []; // The table prefix is accessed differently based on Laravel version. In old version the $prefix was public, @@ -32,13 +70,7 @@ public function compileChange(BaseBlueprint $blueprint, Fluent $command, Connect Arr::except($changedColumn->toArray(), ['compression']), ); - // Remove Compression modifier because Laravel 11 won't work correctly with it (migrator builts incorrectly SQL). - $_modifiers = $this->modifiers; - $this->modifiers = array_filter($this->modifiers, fn ($str) => !\in_array($str, ['Compression'])); - $changes = Arr::wrap(parent::compileChange($blueprintColumn, $command, $connection)); - $this->modifiers = $_modifiers; - - foreach ($changes as $sql) { + foreach (Arr::wrap(parent::compileChange($blueprintColumn, $command, $connection)) as $sql) { $regex = Regex::match('/^ALTER table (?P
.*?) alter (column )?(?P.*?) type (?P\w+)(?P,.*)?/i', $sql); if (filled($changedColumn['using']) && $regex->hasMatch()) { diff --git a/tests/Migration/TableTest.php b/tests/Migration/TableTest.php index 316d047..799c478 100644 --- a/tests/Migration/TableTest.php +++ b/tests/Migration/TableTest.php @@ -4,6 +4,7 @@ namespace Tpetry\PostgresqlEnhanced\Tests\Migration; +use Composer\Semver\Comparator; use Tpetry\PostgresqlEnhanced\Schema\Blueprint; use Tpetry\PostgresqlEnhanced\Support\Facades\Schema; use Tpetry\PostgresqlEnhanced\Tests\TestCase; @@ -44,4 +45,29 @@ public function testAddColumnInitialWithDefault(): void 'alter table "test" alter column "col_437065" set default \'val_121964\'', ], array_column($queries, 'query')); } + + public function testAddColumnsInitialWithDefault(): void + { + $queries = $this->withQueryLog(function (): void { + Schema::table('test', function (Blueprint $table): void { + $table->text('col_123')->initial('val_098'); + $table->text('col_456')->initial('val_765')->default('val_432'); + }); + }); + + if (Comparator::greaterThanOrEqualTo($this->app->version(), '11.15')) { + $this->assertEquals([ + 'alter table "test" add column "col_123" text not null default \'val_098\'', + 'alter table "test" alter column "col_123" drop default', + 'alter table "test" add column "col_456" text not null default \'val_765\'', + 'alter table "test" alter column "col_456" set default \'val_432\'', + ], array_column($queries, 'query')); + } else { + $this->assertEquals([ + 'alter table "test" add column "col_123" text not null default \'val_098\', add column "col_456" text not null default \'val_765\'', + 'alter table "test" alter column "col_123" drop default', + 'alter table "test" alter column "col_456" set default \'val_432\'', + ], array_column($queries, 'query')); + } + } }