Skip to content

Commit

Permalink
Avoid index name clashing with UNIQUE KEY
Browse files Browse the repository at this point in the history
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'
  • Loading branch information
davel committed Apr 8, 2020
1 parent b4874ba commit 5a278bb
Show file tree
Hide file tree
Showing 2 changed files with 10 additions and 1 deletion.
10 changes: 10 additions & 0 deletions lib/SQL/Translator/Producer/MySQL.pm
Original file line number Diff line number Diff line change
Expand Up @@ -460,6 +460,16 @@ sub create_table
#
my @constraint_defs;
my @constraints = $table->get_constraints;

# Mark fields which are first in a UNIQUE constraint as indexed if the
# constraint name is the same as the field. This is to prevent a duplicate
# index being created to support foreign keys.
for my $c ( @constraints ) {
if ($c->type eq UNIQUE && $c->name eq ($c->fields())[0]) {
$indexed_fields{ ($c->fields())[0] } = 1;
}
}

for my $c ( @constraints ) {
my $constr = create_constraint($c, $options);
push @constraint_defs, $constr if($constr);
Expand Down
1 change: 0 additions & 1 deletion t/38-mysql-producer.t
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,6 @@ my @stmts = (
`id` integer NOT NULL,
`foo` integer NULL,
`foo2` integer NULL,
INDEX (`foo`),
UNIQUE `foo` (`foo`, `foo2`),
PRIMARY KEY (`id`),
CONSTRAINT `foo` FOREIGN KEY (`foo`) REFERENCES `thing` (`id`)
Expand Down

0 comments on commit 5a278bb

Please sign in to comment.