Skip to content
Permalink
Browse files

Clean up serial column detection.

Use more postgres catalog data to correctly identify serial columns.
This also means we can remove additional hacky code around guessing
serial columns.

Refs #7871
  • Loading branch information...
markstory committed Dec 20, 2015
1 parent 00fdc44 commit 034b9e53eb4e2a6928a6f2f1dd4cfc080cf88db5
Showing with 10 additions and 23 deletions.
  1. +8 −21 src/Database/Schema/PostgresSchema.php
  2. +2 −2 tests/TestCase/Database/Schema/PostgresSchemaTest.php
@@ -37,17 +37,20 @@ public function listTablesSql($config)
*/
public function describeColumnSql($tableName, $config)
{
$sql =
'SELECT DISTINCT table_schema AS schema, column_name AS name, data_type AS type,
$sql = 'SELECT DISTINCT table_schema AS schema,
column_name AS name,
data_type AS type,
is_nullable AS null, column_default AS default,
character_maximum_length AS char_length,
d.description as comment,
ordinal_position
ordinal_position,
pg_get_serial_sequence(attr.attrelid::regclass::text, attr.attname) IS NOT NULL AS has_serial
FROM information_schema.columns c
INNER JOIN pg_catalog.pg_namespace ns ON (ns.nspname = table_schema)
INNER JOIN pg_catalog.pg_class cl ON (cl.relnamespace = ns.oid AND cl.relname = table_name)
LEFT JOIN pg_catalog.pg_index i ON (i.indrelid = cl.oid AND i.indkey[0] = c.ordinal_position)
LEFT JOIN pg_catalog.pg_description d on (cl.oid = d.objoid AND d.objsubid = c.ordinal_position)
LEFT JOIN pg_catalog.pg_attribute attr ON (cl.oid = attr.attrelid AND column_name = attr.attname)
WHERE table_name = ? AND table_schema = ? AND table_catalog = ?
ORDER BY ordinal_position';
@@ -144,8 +147,7 @@ public function convertColumnDescription(Table $table, $row)
$row['default'] = 0;
}
}
// Sniff out serial types.
if (in_array($field['type'], ['integer', 'biginteger']) && strpos($row['default'], 'nextval(') === 0) {
if (!empty($row['has_serial'])) {
$field['autoIncrement'] = true;
}
$field += [
@@ -193,9 +195,7 @@ public function describeIndexSql($tableName, $config)
c2.relname,
a.attname,
i.indisprimary,
i.indisunique,
i.indisvalid,
pg_catalog.pg_get_indexdef(i.indexrelid, 0, true) AS statement
i.indisunique
FROM pg_catalog.pg_class AS c,
pg_catalog.pg_class AS c2,
pg_catalog.pg_index AS i,
@@ -268,19 +268,6 @@ protected function _convertConstraint($table, $name, $type, $row)
}
$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 &&
count($columns) === 1 &&
in_array($columnDef['type'], ['integer', 'biginteger'])
) {
$columnDef['autoIncrement'] = true;
$table->addColumn($columns[0], $columnDef);
}
}
/**
@@ -288,7 +288,7 @@ public function testDescribeTable()
'precision' => null,
'unsigned' => null,
'comment' => null,
'autoIncrement' => true,
'autoIncrement' => false,
],
'title' => [
'type' => 'string',
@@ -381,8 +381,8 @@ public function testDescribeTableCompositeKey()
$connection->execute('DROP TABLE schema_composite');
$this->assertEquals(['id', 'site_id'], $result->primaryKey());
$this->assertNull($result->column('site_id')['autoIncrement'], 'site_id should not be autoincrement');
$this->assertTrue($result->column('id')['autoIncrement'], 'id should be autoincrement');
$this->assertNull($result->column('site_id')['autoIncrement'], 'site_id should not be autoincrement');
}
/**

0 comments on commit 034b9e5

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