Skip to content

Commit 5a278bb

Browse files
committed
Avoid index name clashing with UNIQUE KEY
When we create a foreign key constraint for MySQL we also create an index, if there is not already an index beginning with the field in question. UNIQUEness constaint are implemented by indices, and so we should also skip adding an index if one already exists. To avoid changing existing fully-working schemas, this change only skips index creation if one with the same name already exists. This case currently fails with a duplicate key error in MySQL, eg., ERROR 1061 (42000): Duplicate key name 'foo'
1 parent b4874ba commit 5a278bb

2 files changed

Lines changed: 10 additions & 1 deletion

File tree

lib/SQL/Translator/Producer/MySQL.pm

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -460,6 +460,16 @@ sub create_table
460460
#
461461
my @constraint_defs;
462462
my @constraints = $table->get_constraints;
463+
464+
# Mark fields which are first in a UNIQUE constraint as indexed if the
465+
# constraint name is the same as the field. This is to prevent a duplicate
466+
# index being created to support foreign keys.
467+
for my $c ( @constraints ) {
468+
if ($c->type eq UNIQUE && $c->name eq ($c->fields())[0]) {
469+
$indexed_fields{ ($c->fields())[0] } = 1;
470+
}
471+
}
472+
463473
for my $c ( @constraints ) {
464474
my $constr = create_constraint($c, $options);
465475
push @constraint_defs, $constr if($constr);

t/38-mysql-producer.t

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -280,7 +280,6 @@ my @stmts = (
280280
`id` integer NOT NULL,
281281
`foo` integer NULL,
282282
`foo2` integer NULL,
283-
INDEX (`foo`),
284283
UNIQUE `foo` (`foo`, `foo2`),
285284
PRIMARY KEY (`id`),
286285
CONSTRAINT `foo` FOREIGN KEY (`foo`) REFERENCES `thing` (`id`)

0 commit comments

Comments
 (0)