diff --git includes/database/pgsql/schema.inc includes/database/pgsql/schema.inc
index afe3a56..18cebf5 100644
--- includes/database/pgsql/schema.inc
+++ includes/database/pgsql/schema.inc
@@ -295,6 +295,7 @@ class DatabaseSchema_pgsql extends DatabaseSchema {
     // Ensure the new table name does not include schema syntax.
     $prefixInfo = $this->getPrefixInfo($new_name);
     $this->connection->query('ALTER TABLE {' . $table . '} RENAME TO ' . $prefixInfo['table']);
+    // TODO: rename sequences (is this really necessary?)
   }
 
   public function dropTable($table) {
@@ -471,16 +472,30 @@ class DatabaseSchema_pgsql extends DatabaseSchema {
       $typecast = 'int';
     }
 
+    $this->connection->query('ALTER TABLE {' . $table . '} ALTER "' . $field . '" TYPE ' . $typecast . ' USING "' . $field . '"::' . $typecast);
 
-    $this->connection->query("ALTER TABLE {" . $table . "} ALTER $field SET $field_new = CAST(" . $field . "_old as " . $typecast . ")");
-
-    $this->addField($table, "$field_new", $spec);
-
-    $this->dropField($table, $field . '_old');
+    // If changing to a serial, create sequence.
+    if (in_array($map[$spec['type'] . ':' . $spec['size']], array('serial', 'bigserial'))) {
+      // NB. type "serial" is known to postgres, but *only* during table creation, not when altering!
+      $seq = "{" . $table . "}_" . $field_new . "_seq";
+      $this->connection->query("CREATE SEQUENCE " . $seq);
+      // set sequence to maximal field value in order not to conflict with existing ids
+      $this->connection->query("SELECT setval('" . $seq . "', MAX(" . $field . ")) FROM {" . $table . "}");      
+      $this->connection->query('ALTER TABLE {' . $table . '} ALTER "' . $field . '" SET DEFAULT nextval(\'' . $seq . '\')');
+    }
+    // TODO: if changing NOT TO BE serial any more, delete sequence and default value
+    
+    // NB. it is not possible right now to change the NULL/NOT NULL nature of fields
 
     // Rename the column if necessary.
     if ($field != $field_new) {
-      $this->connection->query('ALTER TABLE {' . $table . '} RENAME "' . $field . '" TO "' . $field_new . '_old"');
+      $this->connection->query('ALTER TABLE {' . $table . '} RENAME "' . $field . '" TO "' . $field_new . '"');
+    }
+    // TODO: rename any indexes, if necessary
+
+    // Change description if necessary.
+    if (!empty($spec['description'])) {
+      $this->connection->query('COMMENT ON COLUMN {' . $table . '}.' . $field_new . ' IS ' . $this->prepareComment($spec['description']));
     }
 
     if (isset($new_keys)) {
diff --git modules/simpletest/tests/schema.test modules/simpletest/tests/schema.test
index 53e8ea7..faf6e66 100644
--- modules/simpletest/tests/schema.test
+++ modules/simpletest/tests/schema.test
@@ -69,13 +69,24 @@ class SchemaTestCase extends DrupalWebTestCase {
     // Test for created index and test for the boolean result of indexExists().
     $index_exists = Database::getConnection()->schema()->indexExists('test_table', 'test_field');
     $this->assertIdentical($index_exists, TRUE, t('Index created.'));
+    
+    // retype id to serial and set default value in order to allow for insertion
+    db_change_field('test_table', 'id', 'id2', array('type' => 'serial', 'description' => 'Changed column description.'));
+    db_field_set_default('test_table', 'test_field', 1);
 
     // Rename the table.
     db_rename_table('test_table', 'test_table2');
 
     // Index should be renamed.
     $index_exists = Database::getConnection()->schema()->indexExists('test_table2', 'test_field');
-    $this->assertTrue($index_exists, t('Index was renamed.'));
+    $this->assertTrue($index_exists, t('Index was renamed after table rename.'));
+
+    // check that insert into serial column works after table rename
+    $this->assertTrue($this->tryInsert("test_table2", "id2", TRUE), t('Insert into serialized column after table rename succeeded.'));
+
+    // rename and retype column
+    db_change_field('test_table2', 'id2', 'id', array('type' => 'int', 'not null' => TRUE));
+    // NB. for pgsql, we cannot check from here that the sequence is deleted
 
     // We need the default so that we can insert after the rename.
     db_field_set_default('test_table2', 'test_field', 0);
@@ -84,7 +95,7 @@ class SchemaTestCase extends DrupalWebTestCase {
 
     // We should have successfully inserted exactly two rows.
     $count = db_query('SELECT COUNT(*) FROM {test_table2}')->fetchField();
-    $this->assertEqual($count, 2, t('Two fields were successfully inserted.'));
+    $this->assertEqual($count, 3, t('Two fields were successfully inserted.'));
 
     // Try to drop the table.
     db_drop_table('test_table2');
@@ -109,19 +120,46 @@ class SchemaTestCase extends DrupalWebTestCase {
     $this->assertTrue($this->tryInsert(), t('Insert with a serial succeeded.'));
     $max2 = db_query('SELECT MAX(test_serial) FROM {test_table}')->fetchField();
     $this->assertTrue($max2 > $max1, t('The serial is monotone.'));
+    
+    // insert with existing test_serial value given, expect unique violation
+    try {
+       db_insert($table)->fields(array("id" => mt_rand(10, 20), "test_serial" => $max2))->execute();
+      $val = TRUE;
+    }
+    catch (Exception $e) {
+      $val = FALSE;
+    }
+    $this->assertFalse($val, t('Unique constraint works on primary key column.'));
+    
+    // rename test_serial to test_serial2, check that index is renamed
+    db_change_field('test_table', 'test_serial', 'test_serial2', array());
+    $index_exists = Database::getConnection()->schema()->indexExists('test_table2', 'test_field');
+    $this->assertTrue($index_exists, t('Index was renamed after column rename.'));
+
+    // TODO: howto drop test_serial's primary key?
+    
+    // TODO: insert with same id given, expect no violation
+    
+    // TODO: drop serial character, insert with no id given, expect error
+    
+    // TODO: drop null constraint, insert with no id given, check that id is null
+    
+    // TODO: add null constraint, expect error
 
     $count = db_query('SELECT COUNT(*) FROM {test_table}')->fetchField();
     $this->assertEqual($count, 2, t('There were two rows.'));
   }
 
-  function tryInsert($table = 'test_table') {
+  function tryInsert($table = 'test_table', $col="id", $debug=FALSE) {
     try {
        db_insert($table)
-         ->fields(array('id' => mt_rand(10, 20)))
+         ->fields(array($col => mt_rand(10, 20)))
          ->execute();
       return TRUE;
     }
     catch (Exception $e) {
+      if ($debug)
+        debug($e);
       return FALSE;
     }
   }
