index updating now can rename indices on Pg v8+, for efficiency with large data sets
authorivan <ivan>
Fri, 29 Jun 2007 01:12:18 +0000 (01:12 +0000)
committerivan <ivan>
Fri, 29 Jun 2007 01:12:18 +0000 (01:12 +0000)
Changes
DBSchema.pm
DBSchema/Table.pm

diff --git a/Changes b/Changes
index d83e8f1..d7cc9cb 100644 (file)
--- a/Changes
+++ b/Changes
@@ -2,7 +2,7 @@ Revision history for Perl extension DBIx::DBSchema.
 
 0.33 unreleased
         - Overhaul of index representation: indices (both normal and unique)
-          are now named DBSchema::Index objects
+          are now named DBIx::DBSchema::Index objects
         - update_schema now handles indices!
         - Bump version numbers in Table.pm, Column.pm and DBD.pm
         - Pg reverse-engineering fix for column order in multi-column indices,
index 12eda6d..43baaaf 100644 (file)
@@ -292,7 +292,7 @@ sub sql_update_schema {
   # should eventually drop tables not in $new
 
   warn join("\n", @r). "\n"
-    if $DEBUG;
+    if $DEBUG > 1;
 
   @r;
   
@@ -500,13 +500,6 @@ or deal with deleted or modified columns yet.
 
 Need to port and test with additional databases
 
-On schema updates, index changes are not as efficent as they could be,
-especially with large data sets.  Specifically, we don't currently recognize
-existing indices with different/"wrong" names that we could use "ALTER INDEX
-name RENAME TO new_name" on, and instead drop the "wrongly named" index and
-re-build a new one.  Since these are indices and not columns, its not a huge
-deal, everything turns out right in the end, though inefficient.
-
 Each DBIx::DBSchema object should have a name which corresponds to its name
 within the SQL database engine (DBI data source).
 
index b6296ec..3679965 100644 (file)
@@ -566,6 +566,8 @@ sub sql_alter_table {
   my $table = $self->name;
 
   my @r = ();
+  my @r_later = ();
+  my $tempnum = 1;
 
   ###
   # columns
@@ -609,6 +611,30 @@ sub sql_alter_table {
       warn "index $table.$old is identical; not changing\n" if $DEBUG > 1;
       delete $old_indices{$old};
       delete $new_indices{$old};
+
+    } elsif ( $driver eq 'Pg' and $dbh->{'pg_server_version'} >= 80000 ) {
+
+      my @same = grep { $old_indices{$old}->cmp_noname( $new_indices{$_} ) }
+                      keys %new_indices;
+
+      if ( @same ) {
+
+        #warn if there's more than one?
+        my $same = shift @same;
+
+        warn "index $table.$old is identical to $same; renaming\n"
+          if $DEBUG > 1;
+
+        my $temp = 'dbs_temp'.$tempnum++;
+
+        push @r, "ALTER INDEX $old RENAME TO $temp";
+        push @r_later, "ALTER INDEX $temp RENAME TO $same";
+
+        delete $old_indices{$old};
+        delete $new_indices{$same};
+
+      }
+
     }
 
   }
@@ -629,6 +655,8 @@ sub sql_alter_table {
   ###
   # return the statements
   ###
+  
+  push @r, @r_later;
 
   warn join('', map "$_\n", @r)
     if $DEBUG && @r;