No functional indexes added to schema for PostgreSQL #5351
Open
Description
Bug Report
Q | A |
---|---|
Version | 3.3.5 |
Summary
DBAL doesn't recognize functional indexes created in PostgreSQL databases.
Current behaviour
\Doctrine\DBAL\Schema\Table::hasIndex()
returns FALSE for functional indexes because they have no column associated so no column name is available.
How to reproduce
CREATE INDEX "idx_msindte_content" ON "mshop_index_text" USING GIN (to_tsvector(\'english\', "content"))
\Doctrine\DBAL\Schema\Table::hasIndex('idx_msindte_content') // returns FALSE
The problem is that PostgreSQL returns 0
in the pg_index.indkey
column for functional indexes because they have no column associated (https://github.com/doctrine/dbal/blob/3.3.x/src/Platforms/PostgreSQLPlatform.php#L349-L358):
relname | indisunique | indisprimary | indkey | indrelid | where
------------------------------+-------------+--------------+---------+----------+-------
idx_msindte_pid_sid_lid_name | f | f | 2 3 4 6 | 201159 |
unq_msindte_pid_sid_lid_url | t | f | 2 3 4 5 | 201159 |
idx_msindte_content | f | f | 0 | 201159 |
mshop_index_text_pkey | t | t | 1 | 201159 |
(4 rows)
Then, this statement returns no row (https://github.com/doctrine/dbal/blob/3.3.x/src/Schema/PostgreSQLSchemaManager.php#L249-L253):
SELECT attnum, attname FROM pg_attribute WHERE attrelid=201159 AND attnum IN (0) ORDER BY attnum ASC;
attnum | attname
--------+---------
(0 rows)
Because the pg_attribute
table has no column name for index 0
:
SELECT attnum, attname FROM pg_attribute WHERE attrelid=201159 ORDER BY attnum ASC;
attnum | attname
--------+----------
-7 | tableoid
-6 | cmax
-5 | xmax
-4 | cmin
-3 | xmin
-1 | ctid
1 | id
2 | prodid
3 | siteid
4 | langid
5 | url
6 | name
7 | content
8 | mtime
(14 rows)
Expected behaviour
\Doctrine\DBAL\Schema\Table::hasIndex('idx_msindte_content') // should return TRUE
Possible solution
Add this code after https://github.com/doctrine/dbal/blob/3.3.x/src/Schema/PostgreSQLSchemaManager.php#L248:
if( $colNumbers === [0] ) {
$buffer[] = [
'key_name' => $row['relname'],
'column_name' => '',
'non_unique' => ! $row['indisunique'],
'primary' => $row['indisprimary'],
'where' => $row['where'],
];
continue;
}