? sites/default/modules
? sites/default/settings.php
Index: includes/database/database.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/database/database.inc,v
retrieving revision 1.16
diff -u -p -r1.16 database.inc
--- includes/database/database.inc	25 Oct 2008 02:03:54 -0000	1.16
+++ includes/database/database.inc	29 Oct 2008 08:32:09 -0000
@@ -328,20 +328,111 @@ abstract class DatabaseConnection extend
   }
 
   /**
-   * Create the appropriate sequence name for a given table and serial field.
+   * Return abbreviated representation of the table name, automatically
+   * generated by spliting the table name is its words and getting the
+   * first 4 characters of each word.
+   * 
+   * For example, the table "glossary_entries_categories" will converted
+   * to the "glosentrcate" abbreviation.
    *
-   * This information is exposed to all database drivers, although it is only
-   * useful on some of them.  This method is table prefix-aware.
+   * @param $table
+   *   The table name to be abbreviate.
+   * @param $characters
+   *   Number of characters use for each word. Default is 4.
+   * @return
+   *   An abbreviated representation of the table name.
+   */
+  public function abbreviateTableName($table, $characters = 4) {
+    // Breakdown table name into words.
+    $words = explode('_', $table);
+
+    $return = '';
+    foreach ($words as $word) {
+      $return .= substr($word, 0, $characters);
+    }
+
+    return $return;
+  }
+
+  /**
+   * Return abbreviated representation of the columns used by the object
+   * (index, key, sequence) generated by the concatenation of the first 3
+   * characters of each field. 
+   * 
+   * For example, one index over the "name, level, context" fields be
+   * converted to the "namlevcon" abbreviation. 
+   *
+   * @param $fields
+   *   The array of columns name to be abbreviate.
+   * @param $characters
+   *   Number of characters use for each word. Default is 3.
+   * @return
+   *   An abbreviated representation of the columns used by the object.
+   */
+  public function abbreviateColumnsName($fields, $characters = 3) {
+    // Standardize $fields to an array.
+    if (is_string($fields)) {
+      $fields = array($fields);
+    }
+
+    // Remove '_' if exists.
+    $words = array();
+    foreach ($fields as $field) {
+      // Special case: field in array format for SUBSTR handling.
+      if (is_array($field)) {
+        $words[] = strtr($field[0], '_', '');
+      }
+      else {
+        $words[] = strtr($field, '_', '');
+      }
+    }
+
+    $return = '';    
+    foreach ($words as $word) {
+      $return .= substr($word, 0, $characters);
+    }
+
+    return $return;
+  }
+
+  /**
+   * Return an abbreviated string as constraint name. 
    *
    * @param $table
-   *   The table name to use for the sequence.
-   * @param $field
-   *   The field name to use for the sequence.
-   * @return
-   *   A table prefix-parsed string for the sequence name.
-   */
-  public function makeSequenceName($table, $field) {
-    return $this->prefixTables('{'. $table .'}_'. $field .'_seq');
+   *   The table name to be abbreviate.
+   * @param $fields
+   *   The array of columns name to be abbreviate.
+   * @param $type
+   *   The object type of target constraint, for example:
+   *   - pk: For Primary Keys.
+   *   - uk: For Unique Keys.
+   *   - fk: For Foreign Keys.
+   *   - ck: For Check Constraints.
+   *   - ix: For Indexes.
+   *   - uix: For Unique Indexes.
+   *   - seq: For Sequences.
+   *   - trg: For Triggers.
+   * @param $characters
+   *   Number of characters use for the constraint name. Default is 30.
+   * @return
+   *   An abbreviated string as constraint name. 
+   */
+  public function makeConstraintName($table, $fields, $type, $characters = 30) {
+    $words['tablename'] = $this->prefixTables('{' . $this->abbreviateTableName($table) . '}');
+    $words['columnames'] = $this->abbreviateColumnsName($fields);
+    $words['object_type'] = $type;
+
+    // If any of the calculated names excess the infamous 30cc. the name will
+    // be reduced by removing characters from the "columnames_abbreviated"
+    // part until if fits completely.
+    $return = implode('_', $words);
+    $length = strlen($return);
+    if ($length > $characters) {
+      $words['columnames'] = substr($words['columnames'], 0, -($length - $characters));
+      $return = implode('_', $words);
+    }
+
+    return $return;
   }
 
   /**
@@ -2078,7 +2169,7 @@ function _db_query_process_args($query, 
  *   The name of the autoincrement field.
  */
 function db_last_insert_id($table, $field) {
-  $sequence_name = Database::getActiveConnection()->makeSequenceName($table, $field);
+  $sequence_name = Database::getActiveConnection()->makeConstraintName($table, $field, 'seq');
   return Database::getActiveConnection()->lastInsertId($sequence_name);
 }
 
Index: includes/database/mysql/schema.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/database/mysql/schema.inc,v
retrieving revision 1.4
diff -u -p -r1.4 schema.inc
--- includes/database/mysql/schema.inc	8 Oct 2008 11:09:16 -0000	1.4
+++ includes/database/mysql/schema.inc	29 Oct 2008 08:32:10 -0000
@@ -274,6 +274,8 @@ class DatabaseSchema_mysql extends Datab
   }
 
   public function addPrimaryKey(&$ret, $table, $fields) {
+    // For MySQL, the PRIMARY KEY must be named (or is named by default)
+    // "primary".
     $ret[] = update_sql('ALTER TABLE {' . $table . '} ADD PRIMARY KEY (' . $this->createKeySql($fields) . ')');
   }
 
Index: includes/database/pgsql/database.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/database/pgsql/database.inc,v
retrieving revision 1.4
diff -u -p -r1.4 database.inc
--- includes/database/pgsql/database.inc	25 Oct 2008 02:12:35 -0000	1.4
+++ includes/database/pgsql/database.inc	29 Oct 2008 08:32:10 -0000
@@ -30,6 +30,15 @@ class DatabaseConnection_pgsql extends D
     parent::__construct($dsn, $connection_options['username'], $connection_options['password'], array(PDO::ATTR_STRINGIFY_FETCHES => TRUE));
   }
 
+  // For PostgreSQL, the SERIAL keyword generates one sequence with a
+  // different name schema as tablename_colname_seq.
+  public function makeConstraintName($table, $fields, $type, $characters = 30) {
+    if ($type == 'seq') {
+      return $this->prefixTables('{'. $table .'}_'. $field .'_seq');
+    }
+    return parent::makeConstraintName($table, $fields, $type, $characters);
+  }
+
   public function query($query, Array $args = array(), $options = array()) {
 
     $options += $this->defaultOptions();
