Skip to content

Commit

Permalink
fix: support expression in computed/virtual/stored columns (#48976)
Browse files Browse the repository at this point in the history
  • Loading branch information
tpetry committed Nov 13, 2023
1 parent 20085fe commit 3cb7ed2
Show file tree
Hide file tree
Showing 8 changed files with 57 additions and 7 deletions.
4 changes: 2 additions & 2 deletions src/Illuminate/Database/Schema/Grammars/MySqlGrammar.php
Expand Up @@ -1071,7 +1071,7 @@ protected function modifyVirtualAs(Blueprint $blueprint, Fluent $column)
}

if (! is_null($virtualAs = $column->virtualAs)) {
return " as ({$virtualAs})";
return " as ({$this->getValue($virtualAs)})";
}
}

Expand All @@ -1093,7 +1093,7 @@ protected function modifyStoredAs(Blueprint $blueprint, Fluent $column)
}

if (! is_null($storedAs = $column->storedAs)) {
return " as ({$storedAs}) stored";
return " as ({$this->getValue($storedAs)}) stored";
}
}

Expand Down
4 changes: 2 additions & 2 deletions src/Illuminate/Database/Schema/Grammars/PostgresGrammar.php
Expand Up @@ -1183,7 +1183,7 @@ protected function modifyVirtualAs(Blueprint $blueprint, Fluent $column)
}

if (! is_null($column->virtualAs)) {
return " generated always as ({$column->virtualAs})";
return " generated always as ({$this->getValue($column->virtualAs)})";
}
}

Expand All @@ -1207,7 +1207,7 @@ protected function modifyStoredAs(Blueprint $blueprint, Fluent $column)
}

if (! is_null($column->storedAs)) {
return " generated always as ({$column->storedAs}) stored";
return " generated always as ({$this->getValue($column->storedAs)}) stored";
}
}

Expand Down
4 changes: 2 additions & 2 deletions src/Illuminate/Database/Schema/Grammars/SQLiteGrammar.php
Expand Up @@ -937,7 +937,7 @@ protected function modifyVirtualAs(Blueprint $blueprint, Fluent $column)
}

if (! is_null($virtualAs = $column->virtualAs)) {
return " as ({$virtualAs})";
return " as ({$this->getValue($virtualAs)})";
}
}

Expand All @@ -959,7 +959,7 @@ protected function modifyStoredAs(Blueprint $blueprint, Fluent $column)
}

if (! is_null($storedAs = $column->storedAs)) {
return " as ({$column->storedAs}) stored";
return " as ({$this->getValue($column->storedAs)}) stored";
}
}

Expand Down
Expand Up @@ -964,7 +964,7 @@ public function typeMultiPolygon(Fluent $column)
*/
protected function typeComputed(Fluent $column)
{
return "as ({$column->expression})";
return "as ({$this->getValue($column->expression)})";
}

/**
Expand Down
12 changes: 12 additions & 0 deletions tests/Database/DatabaseMySqlSchemaGrammarTest.php
Expand Up @@ -585,6 +585,18 @@ public function testAddingGeneratedColumnWithCharset()
$this->assertSame('alter table `links` add `url` varchar(2083) character set ascii not null, add `url_hash_virtual` varchar(64) character set ascii as (sha2(url, 256)), add `url_hash_stored` varchar(64) character set ascii as (sha2(url, 256)) stored', $statements[0]);
}

public function testAddingGeneratedColumnByExpression()
{
$blueprint = new Blueprint('products');
$blueprint->integer('price');
$blueprint->integer('discounted_virtual')->virtualAs(new Expression('price - 5'));
$blueprint->integer('discounted_stored')->storedAs(new Expression('price - 5'));
$statements = $blueprint->toSql($this->getConnection(), $this->getGrammar());

$this->assertCount(1, $statements);
$this->assertSame('alter table `products` add `price` int not null, add `discounted_virtual` int as (price - 5), add `discounted_stored` int as (price - 5) stored', $statements[0]);
}

public function testAddingInvisibleColumn()
{
$blueprint = new Blueprint('users');
Expand Down
15 changes: 15 additions & 0 deletions tests/Database/DatabasePostgresSchemaGrammarTest.php
Expand Up @@ -3,6 +3,7 @@
namespace Illuminate\Tests\Database;

use Illuminate\Database\Connection;
use Illuminate\Database\Query\Expression;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Schema\Builder;
use Illuminate\Database\Schema\ForeignIdColumnDefinition;
Expand Down Expand Up @@ -957,6 +958,13 @@ public function testAddingVirtualAs()
$statements = $blueprint->toSql($this->getConnection(), $this->getGrammar());
$this->assertCount(1, $statements);
$this->assertSame('alter table "users" add column "foo" integer null, add column "bar" boolean not null generated always as (foo is not null)', $statements[0]);

$blueprint = new Blueprint('users');
$blueprint->integer('foo')->nullable();
$blueprint->boolean('bar')->virtualAs(new Expression('foo is not null'));
$statements = $blueprint->toSql($this->getConnection(), $this->getGrammar());
$this->assertCount(1, $statements);
$this->assertSame('alter table "users" add column "foo" integer null, add column "bar" boolean not null generated always as (foo is not null)', $statements[0]);
}

public function testAddingStoredAs()
Expand All @@ -967,6 +975,13 @@ public function testAddingStoredAs()
$statements = $blueprint->toSql($this->getConnection(), $this->getGrammar());
$this->assertCount(1, $statements);
$this->assertSame('alter table "users" add column "foo" integer null, add column "bar" boolean not null generated always as (foo is not null) stored', $statements[0]);

$blueprint = new Blueprint('users');
$blueprint->integer('foo')->nullable();
$blueprint->boolean('bar')->storedAs(new Expression('foo is not null'));
$statements = $blueprint->toSql($this->getConnection(), $this->getGrammar());
$this->assertCount(1, $statements);
$this->assertSame('alter table "users" add column "foo" integer null, add column "bar" boolean not null generated always as (foo is not null) stored', $statements[0]);
}

public function testAddingIpAddress()
Expand Down
14 changes: 14 additions & 0 deletions tests/Database/DatabaseSQLiteSchemaGrammarTest.php
Expand Up @@ -4,6 +4,7 @@

use Illuminate\Database\Capsule\Manager;
use Illuminate\Database\Connection;
use Illuminate\Database\Query\Expression;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Schema\ForeignIdColumnDefinition;
use Illuminate\Database\Schema\Grammars\SQLiteGrammar;
Expand Down Expand Up @@ -888,6 +889,19 @@ public function testAddingGeneratedColumn()
$this->assertSame($expected, $statements);
}

public function testAddingGeneratedColumnByExpression()
{
$blueprint = new Blueprint('products');
$blueprint->create();
$blueprint->integer('price');
$blueprint->integer('discounted_virtual')->virtualAs(new Expression('"price" - 5'));
$blueprint->integer('discounted_stored')->storedAs(new Expression('"price" - 5'));
$statements = $blueprint->toSql($this->getConnection(), $this->getGrammar());

$this->assertCount(1, $statements);
$this->assertSame('create table "products" ("price" integer not null, "discounted_virtual" integer as ("price" - 5), "discounted_stored" integer as ("price" - 5) stored)', $statements[0]);
}

public function testGrammarsAreMacroable()
{
// compileReplace macro.
Expand Down
9 changes: 9 additions & 0 deletions tests/Database/DatabaseSqlServerSchemaGrammarTest.php
Expand Up @@ -3,6 +3,7 @@
namespace Illuminate\Tests\Database;

use Illuminate\Database\Connection;
use Illuminate\Database\Query\Expression;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Schema\ForeignIdColumnDefinition;
use Illuminate\Database\Schema\Grammars\SqlServerGrammar;
Expand Down Expand Up @@ -911,6 +912,14 @@ public function testAddingGeneratedColumn()
$statements = $blueprint->toSql($this->getConnection(), $this->getGrammar());
$this->assertCount(1, $statements);
$this->assertSame('alter table "products" add "price" int not null, "discounted_virtual" as (price - 5), "discounted_stored" as (price - 5) persisted', $statements[0]);

$blueprint = new Blueprint('products');
$blueprint->integer('price');
$blueprint->computed('discounted_virtual', new Expression('price - 5'));
$blueprint->computed('discounted_stored', new Expression('price - 5'))->persisted();
$statements = $blueprint->toSql($this->getConnection(), $this->getGrammar());
$this->assertCount(1, $statements);
$this->assertSame('alter table "products" add "price" int not null, "discounted_virtual" as (price - 5), "discounted_stored" as (price - 5) persisted', $statements[0]);
}

public function testGrammarsAreMacroable()
Expand Down

0 comments on commit 3cb7ed2

Please sign in to comment.