Problem/Motivation

Follow-up of #2982755: Random failure in SchemaTest::testSchemaChangePrimaryKey with order of composite primary key.

After renaming one of the fields, the \Drupal\Core\Database\Driver\pgsql\DatabaseSchema::findPrimaryKeyColumns() method returns the correct keys but in the wrong order.

The problem does not apply to the new version of PostgreSQL. Tests were successful in version 9.5. The number of tests run simultaneously matters (concurrency: 1). Everything confirms alexpott's suggestion that the reason is in the SELECT query.

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);
}

Comments

Krzysztof Domański created an issue. See original summary.

krzysztof domański’s picture