Skip to content
Permalink
Browse files

Use postgres catalog to fetch column names.

Matching column names with regex is not reliable in postgres. Instead
use pg_catalog.attribute to access the correct column names. We need to
handle N rows for a single index as the array to string functions do not
preserve the column order in the index.

Refs #7871
  • Loading branch information...
markstory committed Dec 19, 2015
1 parent 4dcc6da commit ef27fb4118796056068aea8bc72ca689be35d9f4
Showing with 24 additions and 26 deletions.
  1. +24 −26 src/Database/Schema/PostgresSchema.php
@@ -191,13 +191,15 @@ public function describeIndexSql($tableName, $config)
{
$sql = 'SELECT
c2.relname,
a.attname,
i.indisprimary,
i.indisunique,
i.indisvalid,
pg_catalog.pg_get_indexdef(i.indexrelid, 0, true) AS statement
FROM pg_catalog.pg_class AS c,
pg_catalog.pg_class AS c2,
pg_catalog.pg_index AS i
pg_catalog.pg_index AS i,
pg_catalog.pg_attribute AS a
WHERE c.oid = (
SELECT c.oid
FROM pg_catalog.pg_class c
@@ -206,8 +208,10 @@ public function describeIndexSql($tableName, $config)
AND n.nspname = ?
)
AND c.oid = i.indrelid
AND c.oid = a.attrelid
AND a.attnum = ANY(i.indkey)
AND i.indexrelid = c2.oid
ORDER BY i.indisprimary DESC, i.indisunique DESC, c2.relname';
ORDER BY i.indisprimary DESC, i.indisunique DESC, c2.relname, a.attnum';
$schema = 'public';
if (!empty($config['schema'])) {
@@ -229,16 +233,20 @@ public function convertIndexDescription(Table $table, $row)
if ($row['indisunique'] && $type === Table::INDEX_INDEX) {
$type = Table::CONSTRAINT_UNIQUE;
}
preg_match('/\(([^\)]+?)\s*(?:ASC|DESC)?(?:NULLS FIRST|LAST)?\)/', $row['statement'], $matches);
$columns = $this->_convertColumnList($matches[1]);
if ($type === Table::CONSTRAINT_PRIMARY || $type === Table::CONSTRAINT_UNIQUE) {
$table->addConstraint($name, [
'type' => $type,
'columns' => $columns
]);
$constraint = $table->constraint($name);
if (!$constraint) {
$constraint = [
'type' => $type,
'columns' => []
];
}
$constraint['columns'][] = $row['attname'];
$table->addConstraint($name, $constraint);
// If there is only one column in the primary key and it is integery,
// make it autoincrement.
$columns = $constraint['columns'];
$columnDef = $table->column($columns[0]);
if ($type === Table::CONSTRAINT_PRIMARY &&
@@ -250,25 +258,15 @@ public function convertIndexDescription(Table $table, $row)
}
return;
}
$table->addIndex($name, [
'type' => $type,
'columns' => $columns
]);
}
/**
* Convert a column list into a clean array.
*
* @param string $columns comma separated column list.
* @return array
*/
protected function _convertColumnList($columns)
{
$columns = explode(', ', $columns);
foreach ($columns as &$column) {
$column = trim($column, '"');
$index = $table->index($name);
if (!$index) {
$index = [
'type' => $type,
'columns' => []
];
}
return $columns;
$index['columns'][] = $row['attname'];
$table->addIndex($name, $index);
}
/**

0 comments on commit ef27fb4

Please sign in to comment.
You can’t perform that action at this time.