Index: includes/database/pgsql/install.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/database/pgsql/install.inc,v retrieving revision 1.13 diff -u -p -r1.13 install.inc --- includes/database/pgsql/install.inc 26 Nov 2010 21:36:43 -0000 1.13 +++ includes/database/pgsql/install.inc 19 Dec 2010 05:06:58 -0000 @@ -22,6 +22,10 @@ class DatabaseTasks_pgsql extends Databa 'arguments' => array(), ); $this->tasks[] = array( + 'function' => 'checkBinaryOutput', + 'arguments' => array(), + ); + $this->tasks[] = array( 'function' => 'initializeDatabase', 'arguments' => array(), ); @@ -53,7 +57,8 @@ class DatabaseTasks_pgsql extends Databa $text .= 'Recreate the database with %encoding encoding. See !link for more details.'; $this->fail(st($text, $replacements)); } - } catch (Exception $e) { + } + catch (Exception $e) { $this->fail(st('Drupal could not determine the encoding of the database was set to UTF-8')); } } @@ -76,6 +81,51 @@ class DatabaseTasks_pgsql extends Databa } /** + * Check Binary Output. + * + * Unserializing does not work on Postgresql 9 when bytea_output is 'hex'. + */ + function checkBinaryOutput() { + // PostgreSQL < 9 doesn't support bytea_output, so verify we are running + // at least PostgreSQL 9. + $database_connection = Database::getConnection(); + if (version_compare($database_connection->version(), '9') >= 0) { + if (!$this->checkBinaryOutputSuccess()) { + // First try to alter the database. If it fails, raise an error telling + // the user to do it themselves. + $connection_options = $database_connection->getConnectionOptions(); + // It is safe to include the database name directly here, because this + // code is only called when a connection to the database is already + // established, thus the database name is guaranteed to be a correct + // value. + $query = "ALTER DATABASE \"" . $connection_options['database'] . "\" SET bytea_output = 'escape';"; + try { + db_query($query); + } + catch (Exception $e) { + if (!$this->checkBinaryOutputSuccess()) { + $replacements = array( + '%setting' => 'bytea_output', + '%current_value' => 'hex', + '%needed_value' => 'escape', + '!query' => "" . $query . "", + ); + $this->fail(st("The %setting setting is currently set to '%current_value', but needs to be '%needed_value'. Change this by running the following query: !query", $replacements)); + } + } + } + } + } + + /** + * Verify that a binary data roundtrip returns the original string. + */ + protected function checkBinaryOutputSuccess() { + $bytea_output = db_query("SELECT 'encoding'::bytea AS output")->fetchField(); + return ($bytea_output == 'encoding'); + } + + /** * Make PostgreSQL Drupal friendly. */ function initializeDatabase() {