diff --git a/includes/database/pgsql/schema.inc b/includes/database/pgsql/schema.inc
index f05cc08680b3038b776e6b0b5d309a78a2231d0b..b7a8fe4b41acd0eee5b6cb82c8273b63bb9e1228 100644
--- a/includes/database/pgsql/schema.inc
+++ b/includes/database/pgsql/schema.inc
@@ -74,6 +74,39 @@ public function queryTableInformation($table) {
     return $this->tableInformation[$key];
   }
 
+  /**
+   * Fetch the list of CHECK constraints used on a field.
+   *
+   * We introspect the database to collect the information required by field
+   * alteration.
+   *
+   * @param $table
+   *   The non-prefixed name of the table.
+   * @param $field
+   *   The name of the field.
+   * @return
+   *   An array of all the checks for the field.
+   */
+  public function queryFieldInformation($table, $field) {
+    $prefixInfo = $this->getPrefixInfo($table, TRUE);
+
+    // Split the key into schema and table for querying.
+    $schema = $prefixInfo['schema'];
+    $table_name = $prefixInfo['table'];
+
+    $field_information = (object) array(
+        'checks' => array(),
+    );
+    $checks = $this->connection->query("SELECT conname FROM pg_class cl INNER JOIN pg_constraint co ON co.conrelid = cl.oid INNER JOIN pg_attribute attr ON attr.attrelid = cl.oid AND attr.attnum = ANY (co.conkey) INNER JOIN pg_namespace ns ON cl.relnamespace = ns.oid WHERE co.contype = 'c' AND ns.nspname = :schema AND cl.relname = :table AND attr.attname = :column", array(
+      ':schema' => $schema,
+      ':table' => $table_name,
+      ':column' => $field,
+    ));
+    $field_information = $checks->fetchCol();
+
+    return $field_information;
+  }
+
   /**
    * Generate SQL to create a new table from a Drupal schema definition.
    *
@@ -469,13 +502,7 @@ public function changeField($table, $field, $field_new, $spec, $new_keys = array
       throw new DatabaseSchemaObjectExistsException(t("Cannot rename field %table.%name to %name_new: target field already exists.", array('%table' => $table, '%name' => $field, '%name_new' => $field_new)));
     }
 
-    $spec += array('size' => 'normal');
-
-    // Map type definition to the PostgreSQL type.
-    if (!isset($spec['pgsql_type'])) {
-      $map = $this->getFieldTypeMap();
-      $spec['pgsql_type'] = $map[$spec['type'] . ':' . $spec['size']];
-    }
+    $spec = $this->processField($spec);
 
     // We need to typecast the new column to best be able to transfer the data
     // Schema_pgsql::getFieldTypeMap() will return possibilities that are not
@@ -487,6 +514,20 @@ public function changeField($table, $field, $field_new, $spec, $new_keys = array
       $typecast = $spec['pgsql_type'];
     }
 
+    if (in_array($spec['pgsql_type'], array('varchar', 'character', 'text')) && isset($spec['length'])) {
+      $typecast .= '(' . $spec['length'] . ')';
+    }
+    elseif (isset($spec['precision']) && isset($spec['scale'])) {
+      $typecast .= '(' . $spec['precision'] . ', ' . $spec['scale'] . ')';
+    }
+
+    // Remove old check constraints.
+    $field_info = $this->queryFieldInformation($table, $field);
+
+    foreach ($field_info as $check) {
+      $this->connection->query('ALTER TABLE {' . $table . '} DROP CONSTRAINT "' . $check . '"');
+    }
+
     $this->connection->query('ALTER TABLE {' . $table . '} ALTER "' . $field . '" TYPE ' . $typecast . ' USING "' . $field . '"::' . $typecast);
 
     if (isset($spec['not null'])) {
@@ -516,6 +557,11 @@ public function changeField($table, $field, $field_new, $spec, $new_keys = array
       $this->connection->query('ALTER TABLE {' . $table . '} RENAME "' . $field . '" TO "' . $field_new . '"');
     }
 
+    // Add unsigned check if necessary.
+    if (!empty($spec['unsigned'])) {
+      $this->connection->query('ALTER TABLE {' . $table . '} ADD CHECK ("' . $field_new . '" >= 0)');
+    }
+
     // Change description if necessary.
     if (!empty($spec['description'])) {
       $this->connection->query('COMMENT ON COLUMN {' . $table . '}."' . $field_new . '" IS ' . $this->prepareComment($spec['description']));