Situation
I have a database in PostgreSQL 9.5 used to store object locations by time.
I have a main table named "position" with the columns (only relevant):
position_id
position_timestamp
object_id
It is partitioned into 100 child tables on object_id with the condition:
CREATE TABLE position_object_id_00
( CHECK object_id%100 = 0 )
INHERITS ( position );
And so on for the others children. I partitioned with a modulus relation to distribute equally the objects.
Each child is indexed on position_id and object_id
(two different indexes).
The trigger to redirect inserts on children is:
CREATE TRIGGER insert_position_trigger
BEFORE INSERT ON position
FOR EACH ROW EXECUTE PROCEDURE insert_position();
And the procedure insert_position()
looks for the right child table to insert the data, inserts it and then return the NEW object:
CREATE OR REPLACE FUNCTION insert_position() RETURNS TRIGGER AS $insert_position$
DECLARE
BEGIN
--Look for child table
[...]
--Insert data in right child table
[...]
RETURN NEW;
END;
$insert_position$ LANGUAGE plpgsql;
I have a summary table object_last_known_position
with the same columns that is updated with the trigger:
CREATE TRIGGER update_object_last_known_position
AFTER INSERT OR UPDATE ON position
FOR EACH ROW
EXECUTE PROCEDURE update_object_last_known_position();
The procedure update_object_last_known_position()
basically checks if the position_timestamp
is more recent, then delete the older entry and create a new entry with the data passed on the INSERT or UPDATE query (NEW).
Issue
So these two triggers react to the same event: insert on position, one is before, the other is after
Returning new for insert_position()
allows me to use NEW in the trigger update_object_last_known_position()
, and this is absolutely necessary. But doing that, it also insert the data on the master table position. So my data is now duplicated.
I tried to put the two triggers before, they both execute when I insert data if I let it like that, but if I remove the "return new" from the procedure insert_position()
, update_object_last_known_position()
is not executed.
I am stuck with this issue and I didn't find a way to execute both of these triggers without filling the master table position when I insert data.
So if you have any ideas, I will really appreciate :)
Thank you for your help!
EDIT
Solution
Thanks to the answer
I "merged" my two triggers: insert_position()
now calls update_object_last_known_position
directly. For that, I modified update_object_last_known_position
to a stored procedure with a parameter. The parameter is the id of the position insert_position()
just created, so I am able to find it and retrieve information.
(Calling update_object_last_known_position
inside the other trigger means we cannot use NEW
anymore)
And obviously return type for insert_position()
is now NULL
, and everything works fine :)