Skip to content

Commit f1bd4b9

Browse files
committed
fix!: SchemaBuilder::getForeignKeys was returning incorrect values
1 parent e17aa0a commit f1bd4b9

File tree

3 files changed

+62
-8
lines changed

3 files changed

+62
-8
lines changed

src/Query/Processor.php

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -122,14 +122,22 @@ public function processIndexes($results)
122122
}
123123

124124
/**
125-
* {@inheritDoc}
126-
* @param array{key_name: string}&array<string, mixed> $results
127-
* @return array<array-key, string>
125+
* @inheritDoc
128126
*/
129127
public function processForeignKeys($results)
130128
{
131129
return array_map(function ($result) {
132-
return ((object) $result)->key_name;
130+
$result = (object) $result;
131+
132+
return [
133+
'name' => $result->name,
134+
'columns' => explode(',', $result->columns),
135+
'foreign_schema' => $result->foreign_schema,
136+
'foreign_table' => $result->foreign_table,
137+
'foreign_columns' => explode(',', $result->foreign_columns),
138+
'on_update' => strtolower($result->on_update),
139+
'on_delete' => strtolower($result->on_delete),
140+
];
133141
}, $results);
134142
}
135143
}

src/Schema/Grammar.php

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -81,10 +81,26 @@ public function compileIndexes($table)
8181
*/
8282
public function compileForeignKeys($table)
8383
{
84-
return sprintf(
85-
'select constraint_name as `key_name` from information_schema.table_constraints where constraint_type = "FOREIGN KEY" and table_schema = \'\' and table_name = %s',
86-
$this->quoteString($table),
87-
);
84+
$schema ??= '';
85+
86+
return implode(' ', [
87+
'select',
88+
implode(', ', [
89+
'kc.constraint_name as `name`',
90+
'string_agg(kc.column_name) as `columns`',
91+
'cc.table_schema as `foreign_schema`',
92+
'cc.table_name as `foreign_table`',
93+
'string_agg(cc.column_name) as `foreign_columns`',
94+
'rc.update_rule as `on_update`',
95+
'rc.delete_rule as `on_delete`',
96+
]),
97+
'from information_schema.key_column_usage kc',
98+
'join information_schema.referential_constraints rc on kc.constraint_name = rc.constraint_name',
99+
'join information_schema.constraint_column_usage cc on kc.constraint_name = cc.constraint_name',
100+
'where kc.table_schema = "' . $schema . '"',
101+
'and kc.table_name = ' . $this->quoteString($table),
102+
'group by kc.constraint_name, cc.table_schema, cc.table_name, rc.update_rule, rc.delete_rule'
103+
]);
88104
}
89105

90106
/**

tests/Schema/BuilderTestLast.php

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,36 @@ public function test_getIndexListing(): void
305305
], $sb->getIndexListing($table));
306306
}
307307

308+
public function test_getForeignKeys(): void
309+
{
310+
$conn = $this->getDefaultConnection();
311+
$sb = $conn->getSchemaBuilder();
312+
$table1 = $this->generateTableName(class_basename(__CLASS__). '_1');
313+
$sb->create($table1, function (Blueprint $table) {
314+
$table->uuid('id')->primary();
315+
$table->uuid('something');
316+
$table->index('something');
317+
});
318+
319+
$table2 = $this->generateTableName(class_basename(__CLASS__). '_2');
320+
$sb->create($table2, function (Blueprint $table) use ($table1) {
321+
$table->uuid('table2_id')->primary();
322+
$table->uuid('other_id');
323+
$table->index('other_id');
324+
$table->foreign('other_id')->references('id')->on($table1);
325+
});
326+
327+
$this->assertSame([[
328+
'name' => strtolower($table2) . '_other_id_foreign',
329+
'columns' => ['other_id'],
330+
'foreign_schema' => '',
331+
'foreign_table' => $table1,
332+
'foreign_columns' => ['id'],
333+
'on_update' => "no action",
334+
'on_delete' => "no action",
335+
]], $sb->getForeignKeys($table2));
336+
}
337+
308338
public function test_dropAllTables(): void
309339
{
310340
$conn = $this->getDefaultConnection();

0 commit comments

Comments
 (0)