Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Derived type in PostgreSQL

Is it possible to create a "derived type" from a type? Like extends in Java.

For instance I need these types:

create type mytype as (
    f1 int,
    --many other fields...
    fn varchar(10)
);

create type mytype_extended as (
    f1 int,
    --many other fields...
    fn varchar(10),

    fx int --one field more
);

You can see that this is redundant. If in the future I'll change mytype, I'll need to change mytype_extended too.

I tried this:

create type mytype as (
    f1 int,
    --many other fields...
    fn varchar(10)
);

create type mytype_extended as (
    mt mytype,

    fx int --one field more
);

but this leads mytype_extended to have just 2 fields, mt (a complex type, I think) and fx, instead of f1, f2... fn, fx.

Is there a way to accomplish this?

like image 495
bluish Avatar asked Feb 03 '15 08:02

bluish


People also ask

What are types in PostgreSQL?

The following types (or spellings thereof) are specified by SQL : bigint , bit , bit varying , boolean , char , character varying , character , varchar , date , double precision , integer , interval , numeric , decimal , real , smallint , time (with or without time zone), timestamp (with or without time zone), xml .

What is composite type in PostgreSQL?

A composite type represents the structure of a row or record; it is essentially just a list of field names and their data types. PostgreSQL allows composite types to be used in many of the same ways that simple types can be used. For example, a column of a table can be declared to be of a composite type.

What is inheritance in PostgreSQL?

Inheritance in PostgreSQL allows you to create a child table based on another table, and the child table will include all of the columns in the parent table. Let's take a database that's used to store blueprints for different types of homes.

What is record data type in PostgreSQL?

PostgreSQL uses record type variables which simply act as placeholders for rows of a result set, similar to a row type variable. However, unlike row type variables, they do not have a predefined structure. Their structure is only determined after assigning a row to them.


1 Answers

In PostgreSQL, there is no direct type inheritance, but you have a few options:

1. Table inheritance

You can create inherited tables to create inherited types (PostgreSQL will always create a composite type for every table, with the same name):

create table supertable (
  foo   int,
  bar   text
);

create table subtable (
  baz   int
) inherits (supertable);

2. Construct views using each other

Because views are (in reality) tables (with rules), a type is created for each of them too:

create view superview
  as select null::int  foo,
            null::text bar;

create view subview
  as select superview.*,
            null::int  baz
     from   superview;

3. Type composition

This is what, you've tried. You have more control with this one in general:

create type supertype as (
  foo   int,
  bar   text
);

create type subtype as (
  super supertype,
  baz   int
);

-- resolve composition manually
select get_foo(v),        -- this will call get_foo(subtype)
       get_foo((v).super) -- this will call get_foo(supertype)
from   (values (((1, '2'), 3)::subtype)) v(v);

+1 True type inheritance?

PostgreSQL's documentation explicitly says, that table inheritance is not the standard's type inheritance:

SQL:1999 and later define a type inheritance feature, which differs in many respects from the features described here.

Nevertheless, inherited table's auto-created types really work like true inherited types (they can be used, where the super type can be used):

-- if there is a get_foo(supertable) function,
-- but there is no get_foo(subtable) function:

select get_foo((1, '2')::supertable);  -- will call get_foo(supertable)
select get_foo((1, '2', 3)::subtable); -- will also call get_foo(supertable)

SQLFiddle

like image 82
pozs Avatar answered Sep 19 '22 05:09

pozs