/*
drop table nodes cascade;
drop table domains cascade;
*/


--
-- nodes
--

CREATE TABLE nodes
(
	node_id				serial,
	CONSTRAINT nodes_pkey		PRIMARY KEY (node_id)
)
WITHOUT OIDS;


--
-- next_node()
--

CREATE OR REPLACE FUNCTION next_node()
	RETURNS bigint
AS $$
BEGIN
	INSERT INTO nodes DEFAULT VALUES;
	
	RETURN currval('nodes_node_id_seq');
END;
$$ LANGUAGE plpgsql VOLATILE;


--
-- domains
--

CREATE TABLE domains
(
	domain_id			int NOT NULL DEFAULT next_node(),
	domain_is_public		bool NOT NULL default false,
	CONSTRAINT domains_pkey 	PRIMARY KEY (domain_id),
	CONSTRAINT domains_domain_id_fkey FOREIGN KEY (domain_id)
		REFERENCES nodes (node_id) MATCH SIMPLE
		ON UPDATE CASCADE ON DELETE CASCADE
)
WITHOUT OIDS;


--
-- drop_domain
--

CREATE OR REPLACE RULE drop_domain
AS
	ON DELETE TO domains
	DO INSTEAD DELETE FROM nodes WHERE node_id = OLD.domain_id;


--
-- public domain
--

CREATE OR REPLACE RULE public_domain_delete_protect
AS
	ON DELETE TO domains
	WHERE	domain_is_public = true
	DO INSTEAD NOTHING;


--
-- the bug
--

/*
select version(); -- 8.1.1 on i686-pc-mingw32

insert into domains (domain_is_public) values (true); -- 1 row affected

select * from nodes; -- 1 row
select * from domains; -- 1 row

delete from domains; -- 1 row affected

select * from nodes; -- 0 rows
select * from domains; -- 1 row (ouch!)
*/