Revert "Issue #1079762 by mradcliffe, bzrudi71: DatabaseSchema_pgsql::queryTableInformation() is slow"

This reverts commit 868639ce81.
8.3.x
Nathaniel Catchpole 2016-10-28 12:49:21 +01:00
parent 868639ce81
commit 7e98e88a5f
1 changed files with 22 additions and 47 deletions

View File

@ -38,13 +38,6 @@ class Schema extends DatabaseSchema {
*/
protected $maxIdentifierLength;
/**
* PostgreSQL's temporary namespace name.
*
* @var string
*/
protected $tempNamespaceName;
/**
* Make sure to limit identifiers according to PostgreSQL compiled in length.
*
@ -104,36 +97,38 @@ class Schema extends DatabaseSchema {
$key = 'public.' . $key;
}
else {
$key = $this->getTempNamespaceName() . '.' . $key;
$schema = $this->connection->query('SELECT nspname FROM pg_namespace WHERE oid = pg_my_temp_schema()')->fetchField();
$key = $schema . '.' . $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(),
);
// Don't use {} around information_schema.columns table.
$this->connection->addSavepoint();
try {
// The bytea columns and sequences for a table can be found in
// pg_attribute, which is significantly faster than querying the
// information_schema. The data type of a field can be found by lookup
// of the attribute ID, and the default value must be extracted from the
// node tree for the attribute definition instead of the historical
// human-readable column, adsrc.
$sql = <<<'EOD'
SELECT pg_attribute.attname AS column_name, format_type(pg_attribute.atttypid, pg_attribute.atttypmod) AS data_type, pg_get_expr(pg_attrdef.adbin, pg_attribute.attrelid) AS column_default
FROM pg_attribute
LEFT JOIN pg_attrdef ON pg_attrdef.adrelid = pg_attribute.attrelid AND pg_attrdef.adnum = pg_attribute.attnum
WHERE pg_attribute.attnum > 0
AND NOT pg_attribute.attisdropped
AND pg_attribute.attrelid = :key::regclass
AND (format_type(pg_attribute.atttypid, pg_attribute.atttypmod) = 'bytea'
OR pg_attrdef.adsrc LIKE 'nextval%')
EOD;
$result = $this->connection->query($sql, [
':key' => $key,
]);
// Check if the table information exists in the PostgreSQL metadata.
$table_information_exists = (bool) $this->connection->query("SELECT 1 FROM pg_class WHERE relname = :table", array(':table' => $table_name))->fetchField();
// If the table information does not yet exist in the PostgreSQL
// metadata, then return the default table information here, so that it
// will not be cached.
if (!$table_information_exists) {
$this->connection->releaseSavepoint();
return $table_information;
}
else {
$result = $this->connection->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%',
));
}
}
catch (\Exception $e) {
$this->connection->rollbackSavepoint();
@ -141,13 +136,6 @@ EOD;
}
$this->connection->releaseSavepoint();
// If the table information does not yet exist in the PostgreSQL
// metadata, then return the default table information here, so that it
// will not be cached.
if (empty($result)) {
return $table_information;
}
foreach ($result as $column) {
if ($column->data_type == 'bytea') {
$table_information->blob_fields[$column->column_name] = TRUE;
@ -165,19 +153,6 @@ EOD;
return $this->tableInformation[$key];
}
/**
* Gets PostgreSQL's temporary namespace name.
*
* @return string
* PostgreSQL's temporary namespace name.
*/
protected function getTempNamespaceName() {
if (!isset($this->tempNamespaceName)) {
$this->tempNamespaceName = $this->connection->query('SELECT nspname FROM pg_namespace WHERE oid = pg_my_temp_schema()')->fetchField();
}
return $this->tempNamespaceName;
}
/**
* Resets information about table blobs, sequences and serial fields.
*