Skip to content

Commit 85b7ca8

Browse files
authored
[11.x] SQLite Error: "General error: 1 no such table" after adding a foreign key when using a table prefix. (#52578)
* Added removal of the table prefix when defining a foreign key. * Code style fixed.
1 parent 4153267 commit 85b7ca8

File tree

2 files changed

+177
-1
lines changed

2 files changed

+177
-1
lines changed

src/Illuminate/Database/Schema/BlueprintState.php

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ public function __construct(Blueprint $blueprint, Connection $connection, Gramma
105105

106106
$this->foreignKeys = collect($schema->getForeignKeys($table))->map(fn ($foreignKey) => new ForeignKeyDefinition([
107107
'columns' => $foreignKey['columns'],
108-
'on' => $foreignKey['foreign_table'],
108+
'on' => $this->withoutTablePrefix($foreignKey['foreign_table']),
109109
'references' => $foreignKey['foreign_columns'],
110110
'onUpdate' => $foreignKey['on_update'],
111111
'onDelete' => $foreignKey['on_delete'],
@@ -251,4 +251,19 @@ public function update(Fluent $command)
251251
break;
252252
}
253253
}
254+
255+
/**
256+
* Remove the table prefix from a table name, if it exists.
257+
*
258+
* @param string $table
259+
* @return string
260+
*/
261+
protected function withoutTablePrefix(string $table)
262+
{
263+
$prefix = $this->connection->getTablePrefix();
264+
265+
return str_starts_with($table, $prefix)
266+
? substr($table, strlen($prefix))
267+
: $table;
268+
}
254269
}

tests/Database/DatabaseSQLiteSchemaGrammarTest.php

Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,12 @@
77
use Illuminate\Database\Query\Expression;
88
use Illuminate\Database\Query\Processors\SQLiteProcessor;
99
use Illuminate\Database\Schema\Blueprint;
10+
use Illuminate\Database\Schema\BlueprintState;
11+
use Illuminate\Database\Schema\ColumnDefinition;
1012
use Illuminate\Database\Schema\ForeignIdColumnDefinition;
13+
use Illuminate\Database\Schema\ForeignKeyDefinition;
1114
use Illuminate\Database\Schema\Grammars\SQLiteGrammar;
15+
use Illuminate\Database\Schema\IndexDefinition;
1216
use Illuminate\Database\Schema\SQLiteBuilder;
1317
use Mockery as m;
1418
use PHPUnit\Framework\TestCase;
@@ -998,6 +1002,163 @@ public function testDroppingColumnsWorks()
9981002
$this->assertEquals(['alter table "users" drop column "name"'], $blueprint->toSql($this->getConnection(), $this->getGrammar()));
9991003
}
10001004

1005+
public function testBlueprintInitialState()
1006+
{
1007+
$db = new Manager;
1008+
1009+
$db->addConnection([
1010+
'driver' => 'sqlite',
1011+
'database' => ':memory:',
1012+
'prefix' => 'prefix_',
1013+
]);
1014+
1015+
$connection = $db->getConnection();
1016+
$grammar = new SQLiteGrammar();
1017+
$grammar->setConnection($connection);
1018+
$grammar->setTablePrefix($connection->getTablePrefix());
1019+
1020+
$schema = $connection->getSchemaBuilder();
1021+
1022+
$schema->create('users', function (Blueprint $table) {
1023+
$table->string('name');
1024+
$table->string('email');
1025+
});
1026+
1027+
$schema->create('posts', function (Blueprint $table) {
1028+
$table->increments('id');
1029+
$table->foreignId('user_id')->constrained('users')->cascadeOnDelete();
1030+
$table->integer('parent_id')->nullable()->index('parent_id');
1031+
$table->string('status')->default('A');
1032+
$table->boolean('is_active')->virtualAs('"status" = \'A\'');
1033+
$table->boolean('has_parent')->storedAs('"parent_id" IS NOT NULL');
1034+
$table->string('title')->collation('RTRIM');
1035+
});
1036+
1037+
$blueprint = new Blueprint('posts', null, $connection->getTablePrefix());
1038+
$state = new BlueprintState($blueprint, $connection, $grammar);
1039+
1040+
$this->assertCount(7, $state->getColumns());
1041+
$this->assertCount(1, $state->getIndexes());
1042+
$this->assertCount(1, $state->getForeignKeys());
1043+
$this->assertSame(['id'], $state->getPrimaryKey()->get('columns'));
1044+
$this->assertSame(
1045+
[
1046+
[
1047+
'name' => 'id',
1048+
'type' => 'integer',
1049+
'full_type_definition' => 'integer',
1050+
'nullable' => false,
1051+
'default' => null,
1052+
'autoIncrement' => true,
1053+
'collation' => null,
1054+
'comment' => null,
1055+
'virtualAs' => null,
1056+
'storedAs' => null,
1057+
],
1058+
[
1059+
'name' => 'user_id',
1060+
'type' => 'integer',
1061+
'full_type_definition' => 'integer',
1062+
'nullable' => false,
1063+
'default' => null,
1064+
'autoIncrement' => false,
1065+
'collation' => null,
1066+
'comment' => null,
1067+
'virtualAs' => null,
1068+
'storedAs' => null,
1069+
],
1070+
[
1071+
'name' => 'parent_id',
1072+
'type' => 'integer',
1073+
'full_type_definition' => 'integer',
1074+
'nullable' => true,
1075+
'default' => null,
1076+
'autoIncrement' => false,
1077+
'collation' => null,
1078+
'comment' => null,
1079+
'virtualAs' => null,
1080+
'storedAs' => null,
1081+
],
1082+
[
1083+
'name' => 'status',
1084+
'type' => 'varchar',
1085+
'full_type_definition' => 'varchar',
1086+
'nullable' => false,
1087+
'default' => "'A'",
1088+
'autoIncrement' => false,
1089+
'collation' => null,
1090+
'comment' => null,
1091+
'virtualAs' => null,
1092+
'storedAs' => null,
1093+
],
1094+
[
1095+
'name' => 'is_active',
1096+
'type' => 'tinyint',
1097+
'full_type_definition' => 'tinyint(1)',
1098+
'nullable' => true,
1099+
'default' => null,
1100+
'autoIncrement' => false,
1101+
'collation' => null,
1102+
'comment' => null,
1103+
'virtualAs' => '"status" = \'A\'',
1104+
'storedAs' => null,
1105+
],
1106+
[
1107+
'name' => 'has_parent',
1108+
'type' => 'tinyint',
1109+
'full_type_definition' => 'tinyint(1)',
1110+
'nullable' => true,
1111+
'default' => null,
1112+
'autoIncrement' => false,
1113+
'collation' => null,
1114+
'comment' => null,
1115+
'virtualAs' => null,
1116+
'storedAs' => '"parent_id" IS NOT NULL',
1117+
],
1118+
[
1119+
'name' => 'title',
1120+
'type' => 'varchar',
1121+
'full_type_definition' => 'varchar',
1122+
'nullable' => false,
1123+
'default' => null,
1124+
'autoIncrement' => false,
1125+
'collation' => 'rtrim',
1126+
'comment' => null,
1127+
'virtualAs' => null,
1128+
'storedAs' => null,
1129+
],
1130+
],
1131+
array_map(
1132+
fn (ColumnDefinition $definition) => array_replace($definition->toArray(), [
1133+
'default' => $definition->value('default') ? $definition->value('default')->getValue($grammar) : $definition->value('default'),
1134+
]),
1135+
$state->getColumns()
1136+
)
1137+
);
1138+
$this->assertSame(
1139+
[
1140+
[
1141+
'name' => 'index',
1142+
'index' => 'parent_id',
1143+
'columns' => ['parent_id'],
1144+
],
1145+
],
1146+
array_map(fn (IndexDefinition $definition) => $definition->toArray(), $state->getIndexes())
1147+
);
1148+
$this->assertSame(
1149+
[
1150+
[
1151+
'columns' => ['user_id'],
1152+
'on' => 'users',
1153+
'references' => ['id'],
1154+
'onUpdate' => 'no action',
1155+
'onDelete' => 'cascade',
1156+
],
1157+
],
1158+
array_map(fn (ForeignKeyDefinition $definition) => $definition->toArray(), $state->getForeignKeys())
1159+
);
1160+
}
1161+
10011162
protected function getConnection()
10021163
{
10031164
$connection = m::mock(Connection::class);

0 commit comments

Comments
 (0)