Browse Source

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
Mark Story 10 years ago
parent
commit
034b9e53eb

+ 8 - 21
src/Database/Schema/PostgresSchema.php

@@ -37,17 +37,20 @@ class PostgresSchema extends BaseSchema
      */
     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 @@ class PostgresSchema extends BaseSchema
                 $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 @@ class PostgresSchema extends BaseSchema
             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 @@ class PostgresSchema extends BaseSchema
         }
         $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);
-        }
     }
 
     /**

+ 2 - 2
tests/TestCase/Database/Schema/PostgresSchemaTest.php

@@ -288,7 +288,7 @@ SQL;
                 'precision' => null,
                 'unsigned' => null,
                 'comment' => null,
-                'autoIncrement' => true,
+                'autoIncrement' => false,
             ],
             'title' => [
                 'type' => 'string',
@@ -381,8 +381,8 @@ SQL;
         $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');
     }
 
     /**