? sites/default/files
? sites/default/settings.php
Index: includes/database/pgsql/database.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/database/pgsql/database.inc,v
retrieving revision 1.15
diff -u -p -r1.15 database.inc
--- includes/database/pgsql/database.inc	26 Dec 2008 11:48:18 -0000	1.15
+++ includes/database/pgsql/database.inc	6 Jan 2009 22:23:09 -0000
@@ -13,6 +13,17 @@
 
 class DatabaseConnection_pgsql extends DatabaseConnection {
 
+  /**
+   * A cache of information about blob columns and sequences of tables.
+   *
+   * This is collected by DatabaseConnection_pgsql->queryTableInformation(),
+   * by introspecting the database.
+   *
+   * @see DatabaseConnection_pgsql->queryTableInformation().
+   * @var array
+   */
+  protected $tableInformation = array();
+
   public function __construct(array $connection_options = array()) {
     // This driver defaults to transaction support, except if explicitly passed FALSE.
     $this->transactionSupport = !isset($connection_options['transactions']) || $connection_options['transactions'] === FALSE;
@@ -31,6 +42,47 @@ class DatabaseConnection_pgsql extends D
     ));
   }
 
+  /**
+   * Fetch the list of blobs and sequences used on a table.
+   *
+   * We introspect the database to collect that information required by insert
+   * and update queries.
+   *
+   * @param $table_name
+   *   The non-prefixed name of the table.
+   * @return
+   *   An object with two member variables:
+   *     * 'blob_fields' that lists all the blob fields in the table.
+   *     * 'sequences' that lists the sequences used in that table.
+   */
+  public function queryTableInformation($table) {
+    // Generate a key to reference this table's information on.
+    $key = $this->prefixTables('{' . $table . '}');
+    if (!strpos($key, '.')) {
+      $key = 'public.' . $key;
+    }
+
+    if (!isset($this->tableInformation[$key])) {
+      // Split the key into schema and table for querying.
+      list($schema,$table_name) = explode('.', $key);
+      $table_information = (object) array(
+        'blob_fields' => array(),
+        'sequences' => array(),
+      );
+      $result = db_query("SELECT column_name, data_type, column_default FROM information_schema.columns WHERE table_schema = :schema AND table_name = :table AND (data_type = 'bytea' OR (numeric_precision IS NOT NULL AND column_default LIKE :default))", array(':schema' => $schema, ':table' => $table_name, ':default' => '%nextval%'));
+      foreach ($result as $column) {
+        if ($column->data_type == 'bytea') {
+          $table_information->blob_fields[$column->column_name] = TRUE;
+        }
+        else if (preg_match("/nextval\('([^']+)'/", $column->column_default, $matches)) {
+          $table_information->sequences[] = $matches[1];
+        }
+      }
+      $this->tableInformation[$key] = $table_information;
+    }
+    return $this->tableInformation[$key];
+  }
+
   public function query($query, array $args = array(), $options = array()) {
 
     $options += $this->defaultOptions();
Index: includes/database/pgsql/query.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/database/pgsql/query.inc,v
retrieving revision 1.7
diff -u -p -r1.7 query.inc
--- includes/database/pgsql/query.inc	20 Dec 2008 18:24:34 -0000	1.7
+++ includes/database/pgsql/query.inc	6 Jan 2009 22:23:09 -0000
@@ -1,7 +1,6 @@
 <?php
 // $Id: query.inc,v 1.7 2008/12/20 18:24:34 dries Exp $
 
-
 /**
  * @ingroup database
  * @{
@@ -26,29 +25,27 @@ class InsertQuery_pgsql extends InsertQu
       return NULL;
     }
 
-    $schema = drupal_get_schema($this->table);
-
     $stmt = $this->connection->prepareQuery((string)$this);
 
+    // Fetch the list of blobs and sequences used on that table.
+    $table_information = $this->connection->queryTableInformation($this->table);
+
     $max_placeholder = 0;
     $blobs = array();
     $blob_cnt = 0;
     foreach ($this->insertValues as &$insert_values) {
       foreach ($this->insertFields as $idx => $field) {
-        switch ($schema['fields'][$field]['type']) {
-          case 'blob':
-            $blobs[$blob_cnt] = fopen('php://memory', 'a');
-            fwrite($blobs[$blob_cnt], $insert_values[$idx]);
-            rewind($blobs[$blob_cnt]);
-
-            $stmt->bindParam(':db_insert_placeholder_' . $max_placeholder++, $blobs[$blob_cnt], PDO::PARAM_LOB);
-
-            ++$blob_cnt;
-
-            break;
-          default:
-            $stmt->bindParam(':db_insert_placeholder_'. $max_placeholder++, $insert_values[$idx]);
-            break;
+        if (isset($table_information->blob_fields[$field])) {
+          $blobs[$blob_cnt] = fopen('php://memory', 'a');
+          fwrite($blobs[$blob_cnt], $insert_values[$idx]);
+          rewind($blobs[$blob_cnt]);
+
+          $stmt->bindParam(':db_insert_placeholder_' . $max_placeholder++, $blobs[$blob_cnt], PDO::PARAM_LOB);
+
+          ++$blob_cnt;
+        }
+        else {
+          $stmt->bindParam(':db_insert_placeholder_'. $max_placeholder++, $insert_values[$idx]);
         }
       }
     }
@@ -58,8 +55,8 @@ class InsertQuery_pgsql extends InsertQu
     // the options array.
     $options = $this->queryOptions;
 
-    if ($schema['fields'][$schema['primary key'][0]]['type'] == 'serial') {
-      $options['sequence_name'] = $this->connection->makeSequenceName($this->table, $schema['primary key'][0]);
+    if (!empty($table_information->sequences)) {
+      $options['sequence_name'] = $table_information->sequences[0];
       $options['return'] = Database::RETURN_INSERT_ID;
     }
     $last_insert_id = $this->connection->query($stmt, array(), $options);
@@ -113,12 +110,13 @@ class UpdateQuery_pgsql extends UpdateQu
     $blobs = array();
     $blob_count = 0;
 
-    $schema = drupal_get_schema($this->table);
-
     // Because we filter $fields the same way here and in __toString(), the
     // placeholders will all match up properly.
     $stmt = $this->connection->prepareQuery((string)$this);
 
+    // Fetch the list of blobs and sequences used on that table.
+    $table_information = $this->connection->queryTableInformation($this->table);
+
     // Expressions take priority over literal fields, so we process those first
     // and remove any literal fields that conflict.
     $fields = $this->fields;
@@ -138,17 +136,15 @@ class UpdateQuery_pgsql extends UpdateQu
     foreach ($fields as $field => &$value) {
       $placeholder = ':db_update_placeholder_' . ($max_placeholder++);
 
-      switch ($schema['fields'][$field]['type']) {
-        case 'blob':
-          $blobs[$blob_count] = fopen('php://memory', 'a');
-          fwrite($blobs[$blob_count], $value);
-          rewind($blobs[$blob_count]);
-          $stmt->bindParam($placeholder, $blobs[$blob_count], PDO::PARAM_LOB);
-          ++$blob_count;
-          break;
-        default:
-          $stmt->bindParam($placeholder, $value);
-          break;
+      if (isset($table_information->blob_fields[$field])) {
+        $blobs[$blob_count] = fopen('php://memory', 'a');
+        fwrite($blobs[$blob_count], $value);
+        rewind($blobs[$blob_count]);
+        $stmt->bindParam($placeholder, $blobs[$blob_count], PDO::PARAM_LOB);
+        ++$blob_count;
+      }
+      else {
+        $stmt->bindParam($placeholder, $value);
       }
     }
 
@@ -165,7 +161,6 @@ class UpdateQuery_pgsql extends UpdateQu
     $options['already_prepared'] = TRUE;
     $this->connection->query($stmt, $options);
 
-    //$stmt->execute(NULL, $this->queryOptions);
     return $stmt->rowCount();
   }
 }
