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)
     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,
             is_nullable AS null, column_default AS default,
             character_maximum_length AS char_length,
             character_maximum_length AS char_length,
             d.description as comment,
             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
         FROM information_schema.columns c
         INNER JOIN pg_catalog.pg_namespace ns ON (ns.nspname = table_schema)
         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)
         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_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_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 = ?
         WHERE table_name = ? AND table_schema = ? AND table_catalog = ?
         ORDER BY ordinal_position';
         ORDER BY ordinal_position';
 
 
@@ -144,8 +147,7 @@ class PostgresSchema extends BaseSchema
                 $row['default'] = 0;
                 $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['autoIncrement'] = true;
         }
         }
         $field += [
         $field += [
@@ -193,9 +195,7 @@ class PostgresSchema extends BaseSchema
             c2.relname,
             c2.relname,
             a.attname,
             a.attname,
             i.indisprimary,
             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,
         FROM pg_catalog.pg_class AS c,
             pg_catalog.pg_class AS c2,
             pg_catalog.pg_class AS c2,
             pg_catalog.pg_index AS i,
             pg_catalog.pg_index AS i,
@@ -268,19 +268,6 @@ class PostgresSchema extends BaseSchema
         }
         }
         $constraint['columns'][] = $row['attname'];
         $constraint['columns'][] = $row['attname'];
         $table->addConstraint($name, $constraint);
         $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,
                 'precision' => null,
                 'unsigned' => null,
                 'unsigned' => null,
                 'comment' => null,
                 'comment' => null,
-                'autoIncrement' => true,
+                'autoIncrement' => false,
             ],
             ],
             'title' => [
             'title' => [
                 'type' => 'string',
                 'type' => 'string',
@@ -381,8 +381,8 @@ SQL;
         $connection->execute('DROP TABLE schema_composite');
         $connection->execute('DROP TABLE schema_composite');
 
 
         $this->assertEquals(['id', 'site_id'], $result->primaryKey());
         $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->assertTrue($result->column('id')['autoIncrement'], 'id should be autoincrement');
+        $this->assertNull($result->column('site_id')['autoIncrement'], 'site_id should not be autoincrement');
     }
     }
 
 
     /**
     /**