Skip to content

PostgreSQL listTableColumns() not returning view columns since version 3.4.0 #5821

@amcsi

Description

@amcsi

Bug Report

Q A
Version 3.4.0

Summary

In DBAL version 3.3.* when you did \Doctrine\DBAL\Schema\PostgreSQLSchemaManager::listTableColumns() on a view table, it would list the columns fine.

Current behaviour

But since version 3.4.0 that would return zero columns (for view tables).

How to reproduce

  1. Create a normal table in PostgreSQL.
  2. Create a view table that reads from that normal table.
  3. Perform \Doctrine\DBAL\Schema\PostgreSQLSchemaManager::listTableColumns() on that view table.

Expected behaviour

All the columns of the view table should be listed.

Additional details

I believe I know what SQL bit is causing the breakage.

Here is what I believe the offending commit is that caused the breakage:
194c6eb

Below are the SQL scripts compared using dw.vw_time_tracking as the example view table. If you compare them and rearrange them a bit, you'll see that the bad SQL query in 3.4.0 includes c.relkind = 'r' as a new filter which filters out view table columns; removing that filter makes the query return all the columns as expected like in 3.3.*.

This breakage was not mentioned in the merged PR with the breaking change commit (#5268), and nothing was mentioned about this breaking SQL change nor anything about views.

I also see no separate method to list columns of views, so I believe I am calling what should be the right method to list the view table's columns.

Also note that although version 3.5.0 rearranged \Doctrine\DBAL\Schema\PostgreSQLSchemaManager a bit, the offending c.relkind = 'r' filter is still there and is still causing the same breakage.

So here are the good and bad SQL columns:

-- 3.3.* good
SELECT a.attnum,
       quote_ident(a.attname)                                                                AS field,
       t.typname                                                                             AS type,
       format_type(a.atttypid, a.atttypmod)                                                  AS complete_type,
       (SELECT tc.collcollate FROM pg_catalog.pg_collation tc WHERE tc.oid = a.attcollation) AS collation,
       (SELECT t1.typname FROM pg_catalog.pg_type t1 WHERE t1.oid = t.typbasetype)           AS domain_type,
       (SELECT format_type(t2.typbasetype, t2.typtypmod)
        FROM pg_catalog.pg_type t2
        WHERE t2.typtype = 'd'
          AND t2.oid = a.atttypid)                                                           AS domain_complete_type,
       a.attnotnull                                                                          AS isnotnull,
       (SELECT 't'
        FROM pg_index
        WHERE c.oid = pg_index.indrelid
          AND pg_index.indkey[0] = a.attnum
          AND pg_index.indisprimary = 't')                                                   AS pri,
       (SELECT pg_get_expr(adbin, adrelid)
        FROM pg_attrdef
        WHERE c.oid = pg_attrdef.adrelid
          AND pg_attrdef.adnum = a.attnum)                                                   AS default,
       (SELECT pg_description.description
        FROM pg_description
        WHERE pg_description.objoid = c.oid
          AND a.attnum = pg_description.objsubid)                                            AS comment
FROM pg_attribute a,
     pg_class c,
     pg_type t,
     pg_namespace n
WHERE n.nspname NOT IN ('pg_catalog', 'information_schema', 'pg_toast')
  AND c.relname = 'vw_time_tracking'
  AND n.nspname = 'dw'
  AND a.attnum > 0
  AND a.attrelid = c.oid
  AND a.atttypid = t.oid
  AND n.oid = c.relnamespace
ORDER BY a.attnum;

-- 3.4.0 bad
SELECT a.attnum,
       quote_ident(a.attname)                                                                AS field,
       t.typname                                                                             AS type,
       format_type(a.atttypid, a.atttypmod)                                                  AS complete_type,
       (SELECT tc.collcollate FROM pg_catalog.pg_collation tc WHERE tc.oid = a.attcollation) AS collation,
       (SELECT t1.typname FROM pg_catalog.pg_type t1 WHERE t1.oid = t.typbasetype)           AS domain_type,
       (SELECT format_type(t2.typbasetype, t2.typtypmod)
        FROM pg_catalog.pg_type t2
        WHERE t2.typtype = 'd'
          AND t2.oid = a.atttypid)                                                           AS domain_complete_type,
       a.attnotnull                                                                          AS isnotnull,
       (SELECT 't'
        FROM pg_index
        WHERE c.oid = pg_index.indrelid
          AND pg_index.indkey[0] = a.attnum
          AND pg_index.indisprimary = 't')                                                   AS pri,
       (SELECT pg_get_expr(adbin, adrelid)
        FROM pg_attrdef
        WHERE c.oid = pg_attrdef.adrelid
          AND pg_attrdef.adnum = a.attnum)                                                   AS default,
       (SELECT pg_description.description
        FROM pg_description
        WHERE pg_description.objoid = c.oid
          AND a.attnum = pg_description.objsubid)                                            AS comment
FROM pg_attribute a,
     pg_class c,
     pg_type t,
     pg_namespace n
WHERE a.attnum > 0
  AND a.attrelid = c.oid
  AND a.atttypid = t.oid
  AND n.oid = c.relnamespace
  AND c.relkind = 'r'
  AND c.relname = 'vw_time_tracking'
  AND n.nspname = 'dw'
ORDER BY a.attnum;

SQL queries rearranged and compared with a diff:

image

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions