Skip to content

No functional indexes added to schema for PostgreSQL  #5351

Open
@aimeos

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;
           }

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions