From: William Wolf Date: Sat, 2 Jun 2012 04:07:46 +0000 (-0400) Subject: Fix Pg diff issue with drop constraint on primary keys X-Git-Tag: v0.011017~25 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=bc9b1c11fd7d2faea1251b36a028d8a614dd6bee;p=dbsrgits%2FSQL-Translator.git Fix Pg diff issue with drop constraint on primary keys --- diff --git a/AUTHORS b/AUTHORS index 8e1cff9..9f55f2a 100644 --- a/AUTHORS +++ b/AUTHORS @@ -54,6 +54,7 @@ The following people have contributed to the SQLFairy project: - Tina Müller - Vincent Bachelier - Wallace Reis +- William Wolf - Ying Zhang If you would like to contribute to the project, you can send patches diff --git a/Changes b/Changes index f8e590e..b9d3707 100644 --- a/Changes +++ b/Changes @@ -3,6 +3,7 @@ * Allow both single and double quotes for values in MySQL parser * Fix diff for altering two things per column - add ; at the end * Call all diff methods in list context (it can be merged later) +* Fix Pg diff issue with drop constraint on primary keys # ---------------------------------------------------------- # 0.11016 2012-10-09 diff --git a/lib/SQL/Translator/Producer/PostgreSQL.pm b/lib/SQL/Translator/Producer/PostgreSQL.pm index 16307bf..ad1f98c 100644 --- a/lib/SQL/Translator/Producer/PostgreSQL.pm +++ b/lib/SQL/Translator/Producer/PostgreSQL.pm @@ -968,17 +968,25 @@ sub alter_drop_constraint { my $qc = $options->{quote_field_names} || ''; $generator->quote_chars([$qt]); + # attention: Postgres has a very special naming structure for naming + # foreign keys and primary keys. It names them using the name of the + # table as prefix and fkey or pkey as suffix, concatenated by an underscore + my $c_name; + if( $c->name ) { + # Already has a name, just quote it + $c_name = $qc . $c->name . $qc; + } elsif ( $c->type eq FOREIGN_KEY ) { + # Doesn't have a name, and is foreign key, append '_fkey' + $c_name = $qc . $c->table->name . '_' . + ($c->fields)[0] . '_fkey' . $qc; + } elsif ( $c->type eq PRIMARY_KEY ) { + # Doesn't have a name, and is primary key, append '_pkey' + $c_name = $qc . $c->table->name . '_pkey' . $qc; + } + return sprintf( 'ALTER TABLE %s DROP CONSTRAINT %s', - $generator->quote($c->table->name), - # attention: Postgres has a very special naming structure - # for naming foreign keys, it names them uses the name of - # the table as prefix and fkey as suffix, concatenated by a underscore - $c->type eq FOREIGN_KEY - ? $c->name - ? $qc . $c->name . $qc - : $qc . $c->table->name . '_' . ($c->fields)[0] . '_fkey' . $qc - : $qc . $c->name . $qc + $qt . $c->table->name . $qt, $c_name ); } diff --git a/t/47postgres-producer.t b/t/47postgres-producer.t index 506cd09..0e6e681 100644 --- a/t/47postgres-producer.t +++ b/t/47postgres-producer.t @@ -14,7 +14,7 @@ use FindBin qw/$Bin/; #============================================================================= BEGIN { - maybe_plan(53, + maybe_plan(57, 'SQL::Translator::Producer::PostgreSQL', 'Test::Differences', ) @@ -143,13 +143,45 @@ for my $name ( 'foo', undef ) { } else { is($fk_constraint_fk_ref->[0], 'ALTER TABLE mytable ADD FOREIGN KEY (myfield) - REFERENCES mytable2 (myfield_2) DEFERRABLE', 'Create named Foreign Key Constraint works'); + REFERENCES mytable2 (myfield_2) DEFERRABLE', 'Create un-named Foreign Key Constraint works'); my $alter_fk_constraint = SQL::Translator::Producer::PostgreSQL::alter_drop_constraint($fk_constraint); - is($alter_fk_constraint, 'ALTER TABLE mytable DROP CONSTRAINT mytable_myfield_fkey', 'Alter drop named Foreign Key constraint works'); + is($alter_fk_constraint, 'ALTER TABLE mytable DROP CONSTRAINT mytable_myfield_fkey', 'Alter drop un-named Foreign Key constraint works'); } } +# check named, and unnamed primary keys +for my $name ( 'foo', undef ) { + my $pk_constraint = SQL::Translator::Schema::Constraint->new( + table => $table, + name => $name, + fields => [qw(myfield)], + type => 'PRIMARY_KEY', + ); + my $pk_constraint_2 = SQL::Translator::Schema::Constraint->new( + table => $table, + name => $name, + fields => [qw(myfield)], + type => 'PRIMARY_KEY', + ); + + my ($pk_constraint_def_ref, $pk_constraint_pk_ref ) = SQL::Translator::Producer::PostgreSQL::create_constraint($pk_constraint); + + if ( $name ) { + is($pk_constraint_def_ref->[0], "CONSTRAINT $name PRIMARY KEY (myfield)", 'Create Primary Key Constraint works'); + + # ToDo: may we should check if the constraint name was valid, or if next + # unused_name created has choosen a different one + my $alter_pk_constraint = SQL::Translator::Producer::PostgreSQL::alter_drop_constraint($pk_constraint); + is($alter_pk_constraint, "ALTER TABLE mytable DROP CONSTRAINT $name", 'Alter drop Primary Key constraint works'); + } + else { + is($pk_constraint_def_ref->[0], 'PRIMARY KEY (myfield)', 'Create un-named Primary Key Constraint works'); + + my $alter_pk_constraint = SQL::Translator::Producer::PostgreSQL::alter_drop_constraint($pk_constraint); + is($alter_pk_constraint, 'ALTER TABLE mytable DROP CONSTRAINT mytable_pkey', 'Alter drop un-named Foreign Key constraint works'); + } +} my $alter_field = SQL::Translator::Producer::PostgreSQL::alter_field($field1, $field2);