postgresqlcomposite-types

Postgres composite type drop cascade removes dependant columns only


(Using the below sample code...) I had been puzzled to execute some (reexecutable) scripts (holding/versioning db logic in a source code repo) saying that a clearly defined column foo.foo_b did not exist although it had been successfully executed in the scripts.

Test code that show this:

-- foo.sql type script
drop type if exists foo cascade ;
create type foo as (
    --foo_b bar,  -- (a) not there in first script version
    foo_c char
) ;

-- bar.sql type script
drop type if exists bar cascade ;
create type bar as (
    bar_i int
) ;

-- simple sample code that may cause the strange error

select (null::foo).* ;
--select (null::foo).foo_b ;  -- (a) not there in first script version

executing the script with (a) outcommented (as is):

(0 rows affected)
(0 rows affected)
(0 rows affected)
(0 rows affected)
 foo_c
 -----
 -
(0 rows affected)

executing the script with our new foo_b column in use (removed comment -- prefix from the above 2 (a)-marked lines):

(0 rows affected)
(0 rows affected)
(0 rows affected)
(0 rows affected)
 foo_c
 -----
 -
(0 rows affected)
ERROR: column "foo_b" not found in data type foo
  Position: 9

My original sql was different and actually caused another error of the same cause:

select row( null::bar, 'xxx' )

ERROR: cannot cast type record to foo
  Detail: Input has too many columns.
  Position: 7818

Solution

  • So obviously the fix was that the execution logic must now execute bar.sql before foo.sql, but the error is quite strange and misleading since one would not expect to have dropped the column foo.foo_b like this, but the dependent type foo should have been dropped instead.