SET search_path = revision, public;

CREATE TABLE object_revision_relation
(
    CONSTRAINT object_revision_relation_pkey PRIMARY KEY (object_id, commit_id),
    CONSTRAINT relation_no_description_id CHECK (description_id = 0),
    CONSTRAINT relation_no_geometry_id CHECK (geometry_id = 0),
    CONSTRAINT relation_valid_master_object_id CHECK (master_object_id <> 0),
    CONSTRAINT relation_valid_slave_object_id CHECK (slave_object_id <> 0)
)
INHERITS (object_revision);



CREATE INDEX object_revision_relation_attributes_id_idx
    ON object_revision_relation USING btree (attributes_id);

CREATE INDEX object_revision_relation_commit_id_idx
    ON object_revision_relation USING btree (commit_id);

CREATE INDEX object_revision_relation_master_object_id_idx
    ON object_revision_relation USING btree (master_object_id);

CREATE UNIQUE INDEX object_revision_relation_next_commit_object_ids_idx
    ON object_revision_relation USING btree (next_commit_id, object_id)
    WHERE next_commit_id > 0;

CREATE UNIQUE INDEX object_revision_relation_next_stable_commit_object_ids_idx
    ON object_revision_relation USING btree (next_stable_commit_id, object_id)
    WHERE next_stable_commit_id > 0;

CREATE INDEX object_revision_relation_slave_object_id_idx
    ON object_revision_relation USING btree (slave_object_id);


CREATE TABLE object_revision_with_geometry
(
    CONSTRAINT object_revision_with_geometry_pkey PRIMARY KEY (object_id, commit_id),
    CONSTRAINT geom_valid_geometry_id CHECK (geometry_id > 0),
    CONSTRAINT geom_no_master_object_id CHECK (master_object_id = 0),
    CONSTRAINT geom_no_slave_object_id CHECK (slave_object_id = 0)
)
INHERITS (object_revision);



CREATE INDEX object_revision_with_geometry_attributes_id_idx
    ON object_revision_with_geometry USING btree (attributes_id);

CREATE INDEX object_revision_with_geometry_commit_id_idx
    ON object_revision_with_geometry USING btree (commit_id);

CREATE INDEX object_revision_with_geometry_geometry_id_idx
    ON object_revision_with_geometry USING btree (geometry_id);

CREATE UNIQUE INDEX object_revision_with_geometry_next_commit_object_ids_idx
    ON object_revision_with_geometry USING btree (next_commit_id, object_id)
    WHERE next_commit_id > 0;

CREATE UNIQUE INDEX object_revision_with_geometry_next_stable_commit_object_ids_idx
    ON object_revision_with_geometry USING btree (next_stable_commit_id, object_id)
    WHERE next_stable_commit_id > 0;


CREATE TABLE object_revision_without_geometry
(
    CONSTRAINT object_revision_without_geometry_pkey PRIMARY KEY (object_id, commit_id),
    CONSTRAINT no_geometry_id CHECK (geometry_id = 0),
    CONSTRAINT no_master_object_id CHECK (master_object_id = 0),
    CONSTRAINT no_slave_object_id CHECK (slave_object_id = 0)
)
INHERITS (object_revision);



CREATE INDEX object_revision_without_geometry_attributes_id_idx
    ON object_revision_without_geometry USING btree (attributes_id);

CREATE INDEX object_revision_without_geometry_commit_id_idx
    ON object_revision_without_geometry USING btree (commit_id);

CREATE UNIQUE INDEX object_revision_without_geometry_next_commit_object_ids_idx
    ON object_revision_without_geometry USING btree (next_commit_id, object_id)
    WHERE next_commit_id > 0;

CREATE UNIQUE INDEX object_revision_without_geometry_next_stable_commit_object_ids_idx
    ON object_revision_without_geometry USING btree (next_stable_commit_id, object_id)
    WHERE next_stable_commit_id > 0;


CREATE OR REPLACE FUNCTION object_revision_insert_trigger()
  RETURNS trigger AS
$BODY$
BEGIN
    IF (NEW.geometry_id > 0) THEN
        INSERT INTO revision.object_revision_with_geometry VALUES (NEW.*);
    ELSIF (NEW.slave_object_id <> 0) THEN
        INSERT INTO revision.object_revision_relation VALUES (NEW.*);
    ELSE
        INSERT INTO revision.object_revision_without_geometry VALUES (NEW.*);
    END IF;
    RETURN NULL;
END;
$BODY$
  LANGUAGE plpgsql VOLATILE;




CREATE TRIGGER object_revision_on_insert
    BEFORE INSERT ON object_revision
    FOR EACH ROW EXECUTE PROCEDURE object_revision_insert_trigger();


CREATE UNLOGGED TABLE rels_tmp AS (SELECT * FROM object_revision WHERE slave_object_id <> 0);
DELETE FROM object_revision WHERE slave_object_id <> 0;
INSERT INTO object_revision_relation SELECT * FROM rels_tmp;
DROP TABLE rels_tmp;

CREATE UNLOGGED TABLE geom_tmp AS (SELECT * FROM object_revision WHERE geometry_id > 0);
DELETE FROM object_revision WHERE geometry_id > 0;
INSERT INTO object_revision_with_geometry SELECT * FROM geom_tmp;
DROP TABLE geom_tmp;

CREATE UNLOGGED TABLE nogeom_tmp AS (SELECT * FROM object_revision WHERE geometry_id = 0 and slave_object_id = 0);
DELETE FROM object_revision WHERE geometry_id = 0 and slave_object_id = 0;
INSERT INTO object_revision_without_geometry SELECT * FROM nogeom_tmp;
DROP TABLE nogeom_tmp;

DROP INDEX object_revision_attributes_id_idx;
DROP INDEX object_revision_geometry_id_idx;
DROP INDEX object_revision_next_commit_object_ids_idx;
DROP INDEX object_revision_next_stable_commit_object_ids_idx;
DROP INDEX object_revision_commit_id_idx;
DROP INDEX object_revision_master_object_id_idx;
DROP INDEX object_revision_slave_object_id_idx;

SET search_path = public;
