diff --git a/includes/database/pgsql/schema.inc b/includes/database/pgsql/schema.inc
index afad997a4c4e9789cff9e7b2c563c42fcb77bdc7..cbbf36dc9e488ab00a71ad5802e239b41b6b37d0 100644
--- a/includes/database/pgsql/schema.inc
+++ b/includes/database/pgsql/schema.inc
@@ -84,12 +84,7 @@ protected function createFieldSql($name, $spec) {
       unset($spec['not null']);
     }
     if (!empty($spec['unsigned'])) {
-      if ($spec['type'] == 'serial') {
-        $sql .= " CHECK ($name >= 0)";
-      }
-      else {
-        $sql .= '_unsigned';
-      }
+      $sql .= " CHECK ($name >= 0)";
     }
 
     if (!empty($spec['length'])) {
@@ -125,6 +120,25 @@ protected function processField($field) {
       $map = $this->getFieldTypeMap();
       $field['pgsql_type'] = $map[$field['type'] . ':' . $field['size']];
     }
+    if (!empty($field['unsigned'])) {
+      // Unsigned datatypes are not supported in PostgreSQL 8.3. In MySQL,
+      // they are used to ensure a positive number is inserted and it also
+      // doubles the maximum integer size that can be stored in a field. 
+      // The PostgreSQL schema in Drupal creates a check constraint 
+      // to ensure that a value inserted is >= 0. To provide the extra 
+      // integer capacity, here, we bump up the column field size.
+      if (!isset($map)) {
+        $map = $this->getFieldTypeMap();
+      }
+      switch ($field['pgsql_type']) {
+        case 'smallint':
+          $field['pgsql_type'] = $map['int:medium'];
+          break;
+        case 'int' :
+          $field['pgsql_type'] = $map['int:big'];
+          break;
+      }
+    }
     if ($field['type'] == 'serial') {
       unset($field['not null']);
     }
diff --git a/modules/system/system.install b/modules/system/system.install
index b224e2e0618f9c09bed510b7c1a3b574991e6a1c..c83fcf2d84b60d01caa166799dad4a45552c5202 100644
--- a/modules/system/system.install
+++ b/modules/system/system.install
@@ -289,22 +289,11 @@ function system_requirements($phase) {
  */
 function system_install() {
   if (db_driver() == 'pgsql') {
-    // We create some custom types and functions using global names instead of
-    // prefixing them like we do with table names. If this function is ever
-    // called again (for example, by the test framework when creating prefixed
-    // test databases), the global names will already exist. We therefore avoid
-    // trying to create them again in that case.
-
-    // Create unsigned types.
-    if (!db_result(db_query("SELECT COUNT(*) FROM pg_constraint WHERE conname = 'int_unsigned_check'"))) {
-      db_query("CREATE DOMAIN int_unsigned integer CHECK (VALUE >= 0)");
-    }
-    if (!db_result(db_query("SELECT COUNT(*) FROM pg_constraint WHERE conname = 'smallint_unsigned_check'"))) {
-      db_query("CREATE DOMAIN smallint_unsigned smallint CHECK (VALUE >= 0)");
-    }
-    if (!db_result(db_query("SELECT COUNT(*) FROM pg_constraint WHERE conname = 'bigint_unsigned_check'"))) {
-      db_query("CREATE DOMAIN bigint_unsigned bigint CHECK (VALUE >= 0)");
-    }
+    // We create some functions using global names instead of prefixing them
+    // like we do with table names. If this function is ever called again (for
+    // example, by the test framework when creating prefixed test databases), 
+    // the global names will already exist. We therefore avoid trying to create
+    // them again in that case.
 
     // Create functions.
     db_query('CREATE OR REPLACE FUNCTION "greatest"(numeric, numeric) RETURNS numeric AS
@@ -1730,7 +1719,7 @@ function system_update_6019() {
 
       // Replace unique index dst_language with a unique constraint. The
       // result is the same but the unique key fits our current schema
-      // structure. Also, the postgres documentation implies that
+      // structure. Also, the PostgreSQL documentation implies that
       // unique constraints are preferable to unique indexes. See
       // http://www.postgresql.org/docs/8.2/interactive/indexes-unique.html.
       if (db_table_exists('url_alias')) {
@@ -3142,6 +3131,40 @@ function system_update_7015() {
   return $ret;
 }
 
+/**
+ * Remove custom datatype *_unsigned in PostgreSQL.
+ */
+function system_update_7016() {
+  $ret = array();
+  // Only run these queries if the driver used is pgsql.
+  if (db_driver() == 'pgsql') {
+    $result = db_query("SELECT c.relname AS table, a.attname AS field, 
+                        pg_catalog.format_type(a.atttypid, a.atttypmod) AS type 
+                        FROM pg_catalog.pg_attribute a 
+                        LEFT JOIN pg_class c ON (c.oid =  a.attrelid) 
+                        WHERE pg_catalog.pg_table_is_visible(c.oid) AND c.relkind = 'r' 
+                        AND pg_catalog.format_type(a.atttypid, a.atttypmod) LIKE '%unsigned%'");
+    while ($row = db_fetch_object($result)) {
+      switch ($row->type) {
+        case 'smallint_unsigned':
+          $datatype = 'int';
+          break;
+        case 'int_unsigned':
+        case 'bigint_unsigned':
+        default:
+          $datatype = 'bigint';
+          break;
+      }
+      $ret[] = update_sql('ALTER TABLE ' . $row->table . ' ALTER COLUMN ' . $row->field . ' TYPE ' . $datatype); 
+      $ret[] = update_sql('ALTER TABLE ' . $row->table . ' ADD CHECK (' . $row->field . ' >= 0)');
+    }
+    $ret[] = update_sql('DROP DOMAIN smallint_unsigned');
+    $ret[] = update_sql('DROP DOMAIN int_unsigned');
+    $ret[] = update_sql('DROP DOMAIN bigint_unsigned');
+  }
+  return $ret;
+}
+
 /**
  * @} End of "defgroup updates-6.x-to-7.x"
  * The next series of updates should start at 8000.