Postgres - Using table as a type

Create table address, which will be used as a type:
CREATE TABLE address (state STATE, city VARCHAR, street VARCHAR, zipcode VARCHAR) WITH (OIDS=FALSE);

Create the table which will use the type address:
CREATE TABLE person (name VARCHAR, address ADDRESS);

INSERT:
INSERT INTO person VALUES ('John Doe', ROW('AZ','PHOENIX','300 BOYLSTON AVE E','98102'));
INSERT INTO person (name, address.state, address.city, address.street, address.zipcode) VALUES ('John Doe','AZ','PHOENIX','300 BOYLSTON AVE E','98102');


SELECT:
SELECT name, address FROM person;
John Doe|(AZ,PHOENIX,300 BOYLSTON AVE E,98102)

SELECT name, (address).state, (address).city, (address).street, (address).zipcode FROM person;
John Doe|AZ|PHOENIX|300 BOYLSTON AVE E|98102


UPDATE:
UPDATE person SET address.street='302 BOYLSTON AVE E' WHERE (address).zipcode='98102';
UPDATE person SET address=ROW('AZ', 'PHOENIX', '303 BOYLSTON AVE E','98102') WHERE name='John Doe';

*Observe that we didn't use parentheses in "SET address.street="

Now we'll INSERT values on person using a FUNCTION!

Create the function:
CREATE OR REPLACE FUNCTION person_add (_name VARCHAR, _address ADDRESS) RETURNS VOID AS
$$
 INSERT INTO person VALUES ($1, $2);
$$
LANGUAGE SQL;


INSERT:
SELECT person_add('John Doe', ROW('AZ', 'PHOENIX', '300 BOYLSTON AVE E','98102'));

This is amazing that, with Postgres, we can use any table as a type, but (always have a but) if u need to use some constraints it will not work well :(

CREATE TABLE address (
 state STATE NOT NULL,
 city VARCHAR NOT NULL,
 street VARCHAR NOT NULL,
 zipcode VARCHAR,
 CONSTRAINT city_fkey FOREIGN KEY (state, city ) REFERENCES city (state, city ) MATCH SIMPLE ON UPDATE CASCADE ON DELETE RESTRICT)
WITH (OIDS=FALSE);


If we create this table instead of the first one, the NOT NULL CONSTRAINTS and FOREIGN KEY city_fkey won't be verify during the insertion.


This examples is valid on Postgres 9.1

Comentários