Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[8.x] Solve the Primary Key issue in databases with sql_require_primary_key enabled #37715

Merged
merged 3 commits into from
Jun 18, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/Illuminate/Database/Schema/Blueprint.php
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ protected function addImpliedCommands(Grammar $grammar)
protected function addFluentIndexes()
{
foreach ($this->columns as $column) {
foreach (['primary', 'unique', 'index', 'spatialIndex'] as $index) {
foreach (['unique', 'index', 'spatialIndex'] as $index) {
// If the index has been specified on the given column, but is simply equal
// to "true" (boolean), no name has been specified for this index so the
// index method can be called without a name and it will generate one.
Expand Down
40 changes: 27 additions & 13 deletions src/Illuminate/Database/Schema/Grammars/MySqlGrammar.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ class MySqlGrammar extends Grammar
* @var string[]
*/
protected $modifiers = [
'Unsigned', 'Charset', 'Collate', 'VirtualAs', 'StoredAs', 'Nullable',
'Primary', 'Unsigned', 'Charset', 'Collate', 'VirtualAs', 'StoredAs', 'Nullable',
'Srid', 'Default', 'Increment', 'Comment', 'After', 'First',
];

Expand Down Expand Up @@ -927,30 +927,30 @@ protected function typeComputed(Fluent $column)
}

/**
* Get the SQL for a generated virtual column modifier.
* Get the SQL for a primary column modifier.
*
* @param \Illuminate\Database\Schema\Blueprint $blueprint
* @param \Illuminate\Support\Fluent $column
* @return string|null
*/
protected function modifyVirtualAs(Blueprint $blueprint, Fluent $column)
public function modifyPrimary(Blueprint $blueprint, Fluent $column)
{
if (! is_null($column->virtualAs)) {
return " as ({$column->virtualAs})";
if (! $column->autoIncrement && ! is_null($column->primary)) {
return ' primary key';
}
}

/**
* Get the SQL for a generated stored column modifier.
* Get the SQL for an auto-increment column modifier.
*
* @param \Illuminate\Database\Schema\Blueprint $blueprint
* @param \Illuminate\Support\Fluent $column
* @return string|null
*/
protected function modifyStoredAs(Blueprint $blueprint, Fluent $column)
protected function modifyIncrement(Blueprint $blueprint, Fluent $column)
{
if (! is_null($column->storedAs)) {
return " as ({$column->storedAs}) stored";
if (in_array($column->type, $this->serials) && $column->autoIncrement) {
return ' auto_increment primary key';
}
}

Expand Down Expand Up @@ -1029,16 +1029,30 @@ protected function modifyDefault(Blueprint $blueprint, Fluent $column)
}

/**
* Get the SQL for an auto-increment column modifier.
* Get the SQL for a generated virtual column modifier.
*
* @param \Illuminate\Database\Schema\Blueprint $blueprint
* @param \Illuminate\Support\Fluent $column
* @return string|null
*/
protected function modifyIncrement(Blueprint $blueprint, Fluent $column)
protected function modifyVirtualAs(Blueprint $blueprint, Fluent $column)
{
if (in_array($column->type, $this->serials) && $column->autoIncrement) {
return ' auto_increment primary key';
if (! is_null($column->virtualAs)) {
return " as ({$column->virtualAs})";
}
}

/**
* Get the SQL for a generated stored column modifier.
*
* @param \Illuminate\Database\Schema\Blueprint $blueprint
* @param \Illuminate\Support\Fluent $column
* @return string|null
*/
protected function modifyStoredAs(Blueprint $blueprint, Fluent $column)
{
if (! is_null($column->storedAs)) {
return " as ({$column->storedAs}) stored";
}
}

Expand Down
16 changes: 15 additions & 1 deletion src/Illuminate/Database/Schema/Grammars/PostgresGrammar.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ class PostgresGrammar extends Grammar
*
* @var string[]
*/
protected $modifiers = ['Collate', 'Increment', 'Nullable', 'Default', 'VirtualAs', 'StoredAs'];
protected $modifiers = ['Primary', 'Collate', 'Increment', 'Nullable', 'Default', 'VirtualAs', 'StoredAs'];

/**
* The columns available as serials.
Expand Down Expand Up @@ -979,6 +979,20 @@ protected function modifyNullable(Blueprint $blueprint, Fluent $column)
return $column->nullable ? ' null' : ' not null';
}

/**
* Get the SQL for a primary column modifier.
*
* @param \Illuminate\Database\Schema\Blueprint $blueprint
* @param \Illuminate\Support\Fluent $column
* @return string|null
*/
public function modifyPrimary(Blueprint $blueprint, Fluent $column)
{
if (! $column->autoIncrement && ! is_null($column->primary)) {
return ' primary key';
}
}

/**
* Get the SQL for a default column modifier.
*
Expand Down
45 changes: 29 additions & 16 deletions src/Illuminate/Database/Schema/Grammars/SQLiteGrammar.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ class SQLiteGrammar extends Grammar
*
* @var string[]
*/
protected $modifiers = ['VirtualAs', 'StoredAs', 'Nullable', 'Default', 'Increment'];
protected $modifiers = ['Primary', 'VirtualAs', 'StoredAs', 'Nullable', 'Default', 'Increment'];

/**
* The columns available as serials.
Expand Down Expand Up @@ -55,12 +55,11 @@ public function compileColumnListing($table)
*/
public function compileCreate(Blueprint $blueprint, Fluent $command)
{
return sprintf('%s table %s (%s%s%s)',
return sprintf('%s table %s (%s%s)',
$blueprint->temporary ? 'create temporary' : 'create',
$this->wrapTable($blueprint),
implode(', ', $this->getColumns($blueprint)),
(string) $this->addForeignKeys($blueprint),
(string) $this->addPrimaryKeys($blueprint)
(string) $this->addForeignKeys($blueprint)
);
}

Expand Down Expand Up @@ -849,30 +848,30 @@ protected function typeComputed(Fluent $column)
}

/**
* Get the SQL for a generated virtual column modifier.
* Get the SQL for a primary column modifier.
*
* @param \Illuminate\Database\Schema\Blueprint $blueprint
* @param \Illuminate\Support\Fluent $column
* @return string|null
*/
protected function modifyVirtualAs(Blueprint $blueprint, Fluent $column)
public function modifyPrimary(Blueprint $blueprint, Fluent $column)
{
if (! is_null($column->virtualAs)) {
return " as ({$column->virtualAs})";
if (! $column->autoIncrement && ! is_null($column->primary)) {
return ' primary key';
}
}

/**
* Get the SQL for a generated stored column modifier.
* Get the SQL for an auto-increment column modifier.
*
* @param \Illuminate\Database\Schema\Blueprint $blueprint
* @param \Illuminate\Support\Fluent $column
* @return string|null
*/
protected function modifyStoredAs(Blueprint $blueprint, Fluent $column)
protected function modifyIncrement(Blueprint $blueprint, Fluent $column)
{
if (! is_null($column->storedAs)) {
return " as ({$column->storedAs}) stored";
if (in_array($column->type, $this->serials) && $column->autoIncrement) {
return ' primary key autoincrement';
}
}

Expand Down Expand Up @@ -909,16 +908,30 @@ protected function modifyDefault(Blueprint $blueprint, Fluent $column)
}

/**
* Get the SQL for an auto-increment column modifier.
* Get the SQL for a generated virtual column modifier.
*
* @param \Illuminate\Database\Schema\Blueprint $blueprint
* @param \Illuminate\Support\Fluent $column
* @return string|null
*/
protected function modifyIncrement(Blueprint $blueprint, Fluent $column)
protected function modifyVirtualAs(Blueprint $blueprint, Fluent $column)
{
if (in_array($column->type, $this->serials) && $column->autoIncrement) {
return ' primary key autoincrement';
if (! is_null($column->virtualAs)) {
return " as ({$column->virtualAs})";
}
}

/**
* Get the SQL for a generated stored column modifier.
*
* @param \Illuminate\Database\Schema\Blueprint $blueprint
* @param \Illuminate\Support\Fluent $column
* @return string|null
*/
protected function modifyStoredAs(Blueprint $blueprint, Fluent $column)
{
if (! is_null($column->storedAs)) {
return " as ({$column->storedAs}) stored";
}
}
}
16 changes: 15 additions & 1 deletion src/Illuminate/Database/Schema/Grammars/SqlServerGrammar.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ class SqlServerGrammar extends Grammar
*
* @var string[]
*/
protected $modifiers = ['Increment', 'Collate', 'Nullable', 'Default', 'Persisted'];
protected $modifiers = ['Primary', 'Increment', 'Collate', 'Nullable', 'Default', 'Persisted'];

/**
* The columns available as serials.
Expand Down Expand Up @@ -832,6 +832,20 @@ protected function typeComputed(Fluent $column)
return "as ({$column->expression})";
}

/**
* Get the SQL for a primary column modifier.
*
* @param \Illuminate\Database\Schema\Blueprint $blueprint
* @param \Illuminate\Support\Fluent $column
* @return string|null
*/
public function modifyPrimary(Blueprint $blueprint, Fluent $column)
{
if (! $column->autoIncrement && ! is_null($column->primary)) {
return ' primary key';
}
}

/**
* Get the SQL for a collation column modifier.
*
Expand Down
17 changes: 17 additions & 0 deletions tests/Database/DatabaseMySqlSchemaGrammarTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,23 @@ public function testBasicCreateTable()
$this->assertSame('alter table `users` add `id` int unsigned not null auto_increment primary key, add `email` varchar(255) not null', $statements[0]);
}

public function testBasicCreateWithPrimaryKey()
{
$blueprint = new Blueprint('users');
$blueprint->create();
$blueprint->string('foo')->primary();

$conn = $this->getConnection();
$conn->shouldReceive('getConfig')->once()->with('charset')->andReturn('utf8');
$conn->shouldReceive('getConfig')->once()->with('collation')->andReturn('utf8_unicode_ci');
$conn->shouldReceive('getConfig')->once()->with('engine')->andReturn(null);

$statements = $blueprint->toSql($conn, $this->getGrammar());

$this->assertCount(1, $statements);
$this->assertSame("create table `users` (`foo` varchar(255) primary key not null) default character set utf8 collate 'utf8_unicode_ci'", $statements[0]);
}

public function testAutoIncrementStartingValue()
{
$blueprint = new Blueprint('users');
Expand Down
11 changes: 11 additions & 0 deletions tests/Database/DatabasePostgresSchemaGrammarTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,17 @@ public function testBasicCreateTable()
$this->assertSame('alter table "users" add column "id" serial primary key not null, add column "email" varchar(255) not null', $statements[0]);
}

public function testBasicCreateWithPrimaryKey()
{
$blueprint = new Blueprint('users');
$blueprint->create();
$blueprint->string('foo')->primary();
$statements = $blueprint->toSql($this->getConnection(), $this->getGrammar());

$this->assertCount(1, $statements);
$this->assertSame('create table "users" ("foo" varchar(255) primary key not null)', $statements[0]);
}

public function testCreateTableWithAutoIncrementStartingValue()
{
$blueprint = new Blueprint('users');
Expand Down
4 changes: 2 additions & 2 deletions tests/Database/DatabaseSQLiteSchemaGrammarTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ public function testAddingPrimaryKey()
$statements = $blueprint->toSql($this->getConnection(), $this->getGrammar());

$this->assertCount(1, $statements);
$this->assertSame('create table "users" ("foo" varchar not null, primary key ("foo"))', $statements[0]);
$this->assertSame('create table "users" ("foo" varchar primary key not null)', $statements[0]);
}

public function testAddingForeignKey()
Expand All @@ -209,7 +209,7 @@ public function testAddingForeignKey()
$statements = $blueprint->toSql($this->getConnection(), $this->getGrammar());

$this->assertCount(1, $statements);
$this->assertSame('create table "users" ("foo" varchar not null, "order_id" varchar not null, foreign key("order_id") references "orders"("id"), primary key ("foo"))', $statements[0]);
$this->assertSame('create table "users" ("foo" varchar primary key not null, "order_id" varchar not null, foreign key("order_id") references "orders"("id"))', $statements[0]);
}

public function testAddingUniqueKey()
Expand Down
11 changes: 11 additions & 0 deletions tests/Database/DatabaseSqlServerSchemaGrammarTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,17 @@ public function testBasicCreateTable()
$this->assertSame('create table "prefix_users" ("id" int identity primary key not null, "email" nvarchar(255) not null)', $statements[0]);
}

public function testBasicCreateWithPrimaryKey()
{
$blueprint = new Blueprint('users');
$blueprint->create();
$blueprint->string('foo')->primary();
$statements = $blueprint->toSql($this->getConnection(), $this->getGrammar());

$this->assertCount(1, $statements);
$this->assertSame('create table "users" ("foo" nvarchar(255) primary key not null)', $statements[0]);
}

public function testCreateTemporaryTable()
{
$blueprint = new Blueprint('users');
Expand Down