From 0041d80aab9c3285d5245e39f3a75d1cdaa4edc4 Mon Sep 17 00:00:00 2001 From: "mkanat%kerio.com" <> Date: Tue, 3 May 2005 15:35:29 +0000 Subject: Bug 289139: Bugzilla::DB::Schema::Pg needs to re-create indexes when it has to drop them for a rename/alter Patch By Max Kanat-Alexander r=Tomas.Kopal, a=justdave --- Bugzilla/DB/Schema.pm | 67 +++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 62 insertions(+), 5 deletions(-) (limited to 'Bugzilla') diff --git a/Bugzilla/DB/Schema.pm b/Bugzilla/DB/Schema.pm index 19357b888..1b905ac01 100644 --- a/Bugzilla/DB/Schema.pm +++ b/Bugzilla/DB/Schema.pm @@ -1464,21 +1464,39 @@ sub get_alter_column_ddl { # UPDATE the temp column to have the same values as the old column push(@statements, "UPDATE $table SET ${column}_ALTERTEMP = " . " CAST($column AS $type)"); + + # Some databases drop a whole index when a column is dropped, + # some only remove that column from an index. For consistency, + # we manually drop all indexes on the column before dropping the + # column. + my %col_idx = $self->get_indexes_on_column_abstract($table, $column); + foreach my $idx_name (keys %col_idx) { + push(@statements, $self->get_drop_index_ddl($table, $idx_name)); + } + # DROP the old column push(@statements, "ALTER TABLE $table DROP COLUMN $column"); # And rename the temp column to be the new one. push(@statements, "ALTER TABLE $table RENAME COLUMN " . " ${column}_ALTERTEMP TO $column"); - # FIXME - And now, we have to regenerate any indexes that got - # dropped, except for the PK index which will be handled - # below. + # And now, we have to regenerate any indexes that got + # dropped, except for the PK index which will be handled + # below. + foreach my $idx_name (keys %col_idx) { + push(@statements, + $self->get_add_index_ddl($table, $idx_name, $col_idx{$idx_name})); + } } my $default = $new_def->{DEFAULT}; my $default_old = $old_def->{DEFAULT}; + # This first condition prevents "uninitialized value" errors. + if (!defined $default && !defined $default_old) { + # Do Nothing + } # If we went from having a default to not having one - if (!defined $default && defined $default_old) { + elsif (!defined $default && defined $default_old) { push(@statements, "ALTER TABLE $table ALTER COLUMN $column" . " DROP DEFAULT"); } @@ -1637,6 +1655,45 @@ sub get_column_abstract { return undef; } +=item C + + Description: Gets a list of indexes that are on a given column. + Params: $table - The table the column is on. + $column - The name of the column. + Returns: Indexes in the standard format of an INDEX + entry on a table. That is, key-value pairs + where the key is the index name and the value + is the index definition. + If there are no indexes on that column, we return + undef. + +=cut +sub get_indexes_on_column_abstract { + my ($self, $table, $column) = @_; + my %ret_hash; + + my $table_def = $self->get_table_abstract($table); + if ($table_def && exists $table_def->{INDEXES}) { + my %indexes = (@{ $table_def->{INDEXES} }); + foreach my $index_name (keys %indexes) { + my $col_list; + # Get the column list, depending on whether the index + # is in hashref or arrayref format. + if (ref($indexes{$index_name}) eq 'HASH') { + $col_list = $indexes{$index_name}->{FIELDS}; + } else { + $col_list = $indexes{$index_name}; + } + + if(grep($_ eq $column, @$col_list)) { + $ret_hash{$index_name} = dclone($indexes{$index_name}); + } + } + } + + return %ret_hash; +} + sub get_index_abstract { =item C +=item C Description: Renames a column on a table in the Schema object. The column that you are renaming must exist. -- cgit v1.2.3-24-g4f1b