Updated Drupal to 8.6. This goes with the following updates because it's possible...
[yaffs-website] / web / core / lib / Drupal / Core / Database / Driver / pgsql / Schema.php
index 96dea950f0342e6e765c7a51355b3ccd651f8507..8d01d5e9bd1dc957b58b82c6e68bf4ed94bbfab0 100644 (file)
@@ -2,7 +2,6 @@
 
 namespace Drupal\Core\Database\Driver\pgsql;
 
-use Drupal\Component\Utility\Unicode;
 use Drupal\Core\Database\SchemaObjectExistsException;
 use Drupal\Core\Database\SchemaObjectDoesNotExistException;
 use Drupal\Core\Database\Schema as DatabaseSchema;
@@ -250,7 +249,8 @@ EOD;
     }
 
     $sql_keys = [];
-    if (isset($table['primary key']) && is_array($table['primary key'])) {
+    if (!empty($table['primary key']) && is_array($table['primary key'])) {
+      $this->ensureNotNullPrimaryKey($table['primary key'], $table['fields']);
       $sql_keys[] = 'CONSTRAINT ' . $this->ensureIdentifiersLength($name, '', 'pkey') . ' PRIMARY KEY (' . $this->createPrimaryKeySql($table['primary key']) . ')';
     }
     if (isset($table['unique keys']) && is_array($table['unique keys'])) {
@@ -350,7 +350,7 @@ EOD;
     // Set the correct database-engine specific datatype.
     // In case one is already provided, force it to lowercase.
     if (isset($field['pgsql_type'])) {
-      $field['pgsql_type'] = Unicode::strtolower($field['pgsql_type']);
+      $field['pgsql_type'] = mb_strtolower($field['pgsql_type']);
     }
     else {
       $map = $this->getFieldTypeMap();
@@ -358,7 +358,7 @@ EOD;
     }
 
     if (!empty($field['unsigned'])) {
-      // Unsigned datatypes are not supported in PostgreSQL 9.1. In MySQL,
+      // Unsigned data types are not supported in PostgreSQL 9.1. 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
@@ -552,7 +552,10 @@ EOD;
     }
 
     // Fields that are part of a PRIMARY KEY must be added as NOT NULL.
-    $is_primary_key = isset($keys_new['primary key']) && in_array($field, $keys_new['primary key'], TRUE);
+    $is_primary_key = isset($new_keys['primary key']) && in_array($field, $new_keys['primary key'], TRUE);
+    if ($is_primary_key) {
+      $this->ensureNotNullPrimaryKey($new_keys['primary key'], [$field => $spec]);
+    }
 
     $fixnull = FALSE;
     if (!empty($spec['not null']) && !isset($spec['default']) && !$is_primary_key) {
@@ -562,14 +565,22 @@ EOD;
     $query = 'ALTER TABLE {' . $table . '} ADD COLUMN ';
     $query .= $this->createFieldSql($field, $this->processField($spec));
     $this->connection->query($query);
-    if (isset($spec['initial'])) {
+    if (isset($spec['initial_from_field'])) {
+      if (isset($spec['initial'])) {
+        $expression = 'COALESCE(' . $spec['initial_from_field'] . ', :default_initial_value)';
+        $arguments = [':default_initial_value' => $spec['initial']];
+      }
+      else {
+        $expression = $spec['initial_from_field'];
+        $arguments = [];
+      }
       $this->connection->update($table)
-        ->fields([$field => $spec['initial']])
+        ->expression($field, $expression, $arguments)
         ->execute();
     }
-    if (isset($spec['initial_from_field'])) {
+    elseif (isset($spec['initial'])) {
       $this->connection->update($table)
-        ->expression($field, $spec['initial_from_field'])
+        ->fields([$field => $spec['initial']])
         ->execute();
     }
     if ($fixnull) {
@@ -708,6 +719,29 @@ EOD;
     return TRUE;
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  protected function findPrimaryKeyColumns($table) {
+    if (!$this->tableExists($table)) {
+      return FALSE;
+    }
+
+    // Fetch the 'indkey' column from 'pg_index' to figure out the order of the
+    // primary key.
+    // @todo Use 'array_position()' to be able to perform the ordering in SQL
+    //   directly when 9.5 is the minimum  PostgreSQL version.
+    $result = $this->connection->query("SELECT a.attname, i.indkey FROM pg_index i JOIN pg_attribute a ON a.attrelid = i.indrelid AND a.attnum = ANY(i.indkey) WHERE i.indrelid = '{" . $table . "}'::regclass AND i.indisprimary")->fetchAllKeyed();
+    if (!$result) {
+      return [];
+    }
+
+    $order = explode(' ', reset($result));
+    $columns = array_combine($order, array_keys($result));
+    ksort($columns);
+    return array_values($columns);
+  }
+
   /**
    * {@inheritdoc}
    */
@@ -774,6 +808,9 @@ EOD;
     if (($field != $field_new) && $this->fieldExists($table, $field_new)) {
       throw new SchemaObjectExistsException(t("Cannot rename field @table.@name to @name_new: target field already exists.", ['@table' => $table, '@name' => $field, '@name_new' => $field_new]));
     }
+    if (isset($new_keys['primary key']) && in_array($field_new, $new_keys['primary key'], TRUE)) {
+      $this->ensureNotNullPrimaryKey($new_keys['primary key'], [$field_new => $spec]);
+    }
 
     $spec = $this->processField($spec);