diff --git a/core/lib/Drupal/Core/Database/Driver/pgsql/Connection.php b/core/lib/Drupal/Core/Database/Driver/pgsql/Connection.php index 8d3a1e1..ff38a22 100644 --- a/core/lib/Drupal/Core/Database/Driver/pgsql/Connection.php +++ b/core/lib/Drupal/Core/Database/Driver/pgsql/Connection.php @@ -70,21 +70,10 @@ public function __construct(\PDO $connection, array $connection_options) { // Force PostgreSQL to use the UTF-8 character set by default. $this->connection->exec("SET NAMES 'UTF8'"); - // Set PostgreSQL init_commands if not already defined. - $connection_options += array( - 'init_commands' => array(), - ); - - $connection_options['init_commands'] += array( - // Set standard_conforming_strings to off so as to treat backslashes as - // escape characters, complying with historical PostgreSQL behavior. In - // PostgreSQL 9.1 and up this is on by default, however Drupal still - // assumes this to be off. - 'standard_conforming_strings' => 'SET standard_conforming_strings = off', - ); - // Execute PostgreSQL init_commands. - $this->connection->exec(implode('; ', $connection_options['init_commands'])); + if (isset($connection_options['init_commands'])) { + $this->connection->exec(implode('; ', $connection_options['init_commands'])); + } } /** diff --git a/core/lib/Drupal/Core/Database/Driver/pgsql/Install/Tasks.php b/core/lib/Drupal/Core/Database/Driver/pgsql/Install/Tasks.php index 1557d41..0b0ecdb 100644 --- a/core/lib/Drupal/Core/Database/Driver/pgsql/Install/Tasks.php +++ b/core/lib/Drupal/Core/Database/Driver/pgsql/Install/Tasks.php @@ -35,6 +35,10 @@ public function __construct() { 'arguments' => array(), ); $this->tasks[] = array( + 'function' => 'checkStandardConformingStrings', + 'arguments' => array(), + ); + $this->tasks[] = array( 'function' => 'initializeDatabase', 'arguments' => array(), ); @@ -185,6 +189,56 @@ protected function checkBinaryOutputSuccess() { } /** + * Check standard_conforming_strings setting. + * + * @todo + */ + function checkStandardConformingStrings() { + $database_connection = Database::getConnection(); + if (!$this->checkStandardConformingStringsSuccess()) { + // 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 standard_conforming_strings = 'off';"; + try { + db_query($query); + } + catch (\Exception $e) { + // Ignore possible errors when the user doesn't have the necessary + // privileges to ALTER the database. + } + + // Close the database connection so that the configuration parameter + // is applied to the current connection. + db_close(); + + // Recheck, if it fails, finally just rely on the end user to do the + // right thing. + if (!$this->checkStandardConformingStringsSuccess()) { + $replacements = array( + '%setting' => 'standard_conforming_strings', + '%current_value' => 'on', + '%needed_value' => 'off', + '!query' => "" . $query . "", + ); + $this->fail(t("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 checkStandardConformingStringsSuccess() { + $standard_conforming_strings = db_query("SHOW standard_conforming_strings")->fetchField(); + return ($standard_conforming_strings == 'off'); + } + + /** * Make PostgreSQL Drupal friendly. */ function initializeDatabase() {