Index: includes/database/schema.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/database/schema.inc,v
retrieving revision 1.42
diff -u -p -r1.42 schema.inc
--- includes/database/schema.inc	29 Nov 2010 04:45:10 -0000	1.42
+++ includes/database/schema.inc	26 Dec 2010 20:54:55 -0000
@@ -215,18 +215,6 @@ abstract class DatabaseSchema implements
   }
 
   /**
-   * Create names for indexes, primary keys and constraints.
-   *
-   * This prevents using {} around non-table names like indexes and keys.
-   */
-  function prefixNonTable($table) {
-    $args = func_get_args();
-    $info = $this->getPrefixInfo($table);
-    $args[0] = $info['table'];
-    return implode('_', $args);
-  }
-
-  /**
    * Build a condition to match a table name against a standard information_schema.
    *
    * The information_schema is a SQL standard that provides information about the
Index: includes/database/pgsql/schema.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/database/pgsql/schema.inc,v
retrieving revision 1.41
diff -u -p -r1.41 schema.inc
--- includes/database/pgsql/schema.inc	14 Dec 2010 19:33:22 -0000	1.41
+++ includes/database/pgsql/schema.inc	26 Dec 2010 20:54:56 -0000
@@ -75,6 +75,38 @@ class DatabaseSchema_pgsql extends Datab
   }
 
   /**
+   * Create names for indexes, primary keys and constraints.
+   *
+   * Identifier names are limited to 63 characters by default on PostgreSQL,
+   * so we cannot simply concatenate the table name with the name of the
+   * object.
+   *
+   * @param $table
+   *   The name of the table.
+   * @param ...
+   *   A variable number of arguments uniquely identifying the object.
+   */
+  function tableObjectName($table) {
+    $args = func_get_args();
+    $info = $this->getPrefixInfo($table);
+    $args[0] = $info['table'];
+    $long_name = implode('_', $args);
+    // If there is a constraint with the long name, return that.
+    if ((bool) $this->connection->query("SELECT 1 FROM pg_constraint WHERE conname = '$long_name'")->fetchField()) {
+      $object_name = $long_name;
+    }
+    // If there is an index with the long name, return that.
+    elseif ((bool) $this->connection->query("SELECT 1 FROM pg_indexes WHERE indexname = '$long_name'")->fetchField()) {
+      $object_name = $long_name;
+    }
+    // Return the length-safe name
+    else {
+      $object_name = 's' . sha1($long_name);
+    }
+    return $object_name;
+  }
+
+  /**
    * Generate SQL to create a new table from a Drupal schema definition.
    *
    * @param $name
@@ -96,7 +128,7 @@ class DatabaseSchema_pgsql extends Datab
     }
     if (isset($table['unique keys']) && is_array($table['unique keys'])) {
       foreach ($table['unique keys'] as $key_name => $key) {
-        $sql_keys[] = 'CONSTRAINT ' . $this->prefixNonTable($name, $key_name, 'key') . ' UNIQUE (' . implode(', ', $key) . ')';
+        $sql_keys[] = 'CONSTRAINT ' . $this->tableObjectName($name, $key_name, 'key') . ' UNIQUE (' . implode(', ', $key) . ')';
       }
     }
 
@@ -298,7 +330,7 @@ class DatabaseSchema_pgsql extends Datab
     foreach ($indexes as $index) {
       if (preg_match('/^' . preg_quote($old_full_name) . '_(.*)_idx$/', $index->indexname, $matches)) {
         $index_name = $matches[1];
-        $this->connection->query('ALTER INDEX ' . $index->indexname . ' RENAME TO {' . $new_name . '}_' . $index_name . '_idx');
+        $this->connection->query('ALTER INDEX ' . $index->indexname . ' RENAME TO ' . $this->tableObjectName($new_name, $index_name, 'idx'));
       }
     }
 
@@ -383,8 +415,8 @@ class DatabaseSchema_pgsql extends Datab
   }
 
   public function indexExists($table, $name) {
+    $index_name = $this->tableObjectName($table, $name, 'idx');
     // Details http://www.postgresql.org/docs/8.3/interactive/view-pg-indexes.html
-    $index_name = '{' . $table . '}_' . $name . '_idx';
     return (bool) $this->connection->query("SELECT 1 FROM pg_indexes WHERE indexname = '$index_name'")->fetchField();
   }
 
@@ -397,7 +429,7 @@ class DatabaseSchema_pgsql extends Datab
    *   The name of the constraint (typically 'pkey' or '[constraint]_key').
    */
   protected function constraintExists($table, $name) {
-    $constraint_name = '{' . $table . '}_' . $name;
+    $constraint_name = $this->tableObjectName($table, $name);
     return (bool) $this->connection->query("SELECT 1 FROM pg_constraint WHERE conname = '$constraint_name'")->fetchField();
   }
 
@@ -417,7 +449,7 @@ class DatabaseSchema_pgsql extends Datab
       return FALSE;
     }
 
-    $this->connection->query('ALTER TABLE {' . $table . '} DROP CONSTRAINT ' . $this->prefixNonTable($table, 'pkey'));
+    $this->connection->query('ALTER TABLE {' . $table . '} DROP CONSTRAINT ' . $this->tableObjectName($table, 'pkey'));
     return TRUE;
   }
 
@@ -429,7 +461,7 @@ class DatabaseSchema_pgsql extends Datab
       throw new DatabaseSchemaObjectExistsException(t("Cannot add unique key %name to table %table: unique key already exists.", array('%table' => $table, '%name' => $name)));
     }
 
-    $this->connection->query('ALTER TABLE {' . $table . '} ADD CONSTRAINT "' . $this->prefixNonTable($table, $name, 'key') . '" UNIQUE (' . implode(',', $fields) . ')');
+    $this->connection->query('ALTER TABLE {' . $table . '} ADD CONSTRAINT "' . $this->tableObjectName($table, $name, 'key') . '" UNIQUE (' . implode(',', $fields) . ')');
   }
 
   public function dropUniqueKey($table, $name) {
@@ -437,7 +469,7 @@ class DatabaseSchema_pgsql extends Datab
       return FALSE;
     }
 
-    $this->connection->query('ALTER TABLE {' . $table . '} DROP CONSTRAINT "' . $this->prefixNonTable($table, $name, 'key') . '"');
+    $this->connection->query('ALTER TABLE {' . $table . '} DROP CONSTRAINT "' . $this->tableObjectName($table, $name, 'key') . '"');
     return TRUE;
   }
 
@@ -457,7 +489,7 @@ class DatabaseSchema_pgsql extends Datab
       return FALSE;
     }
 
-    $this->connection->query('DROP INDEX ' . $this->prefixNonTable($table, $name, 'idx'));
+    $this->connection->query('DROP INDEX ' . $this->tableObjectName($table, $name, 'idx'));
     return TRUE;
   }
 
@@ -527,7 +559,7 @@ class DatabaseSchema_pgsql extends Datab
   }
 
   protected function _createIndexSql($table, $name, $fields) {
-    $query = 'CREATE INDEX "' . $this->prefixNonTable($table, $name, 'idx') . '" ON {' . $table . '} (';
+    $query = 'CREATE INDEX "' . $this->tableObjectName($table, $name, 'idx') . '" ON {' . $table . '} (';
     $query .= $this->_createKeySql($fields) . ')';
     return $query;
   }
