1

I have 2 tables, connected with inheritance.
I want to delete some rows from the child table. The deletion part works but it deletes rows from the parent as well:

CREATE OR REPLACE FUNCTION earthquakes_trigger()
RETURNS TRIGGER AS $$
BEGIN
    INSERT INTO earthquakes VALUES (NEW.*);
    DELETE FROM ONLY earthquakes WHERE datetime < (now() - '2 days'::interval);
    RETURN NULL;
END;
$$
LANGUAGE plpgsql;

CREATE TRIGGER earthquakes_trigger
        BEFORE INSERT ON earthquakes_ovr
        FOR EACH ROW EXECUTE PROCEDURE earthquakes_trigger();

Parent table : earthquakes_ovr
Child table: earthquakes

I also tried to break up the trigger function, and have the deletion part as trigger function on the child, but that didn't work either.

2 Answers 2

1

As you can see that is not the case, when the tables are not linked in anyway

CREATE tABLE earthquakes_ovr ("datetime" timestamp)
INSERT INTO earthquakes_ovr VALUES (NOW() - INTERVAL '6 DAYS')
INSERT INTO earthquakes_ovr VALUES (now() - INTERVAL'4 days')
CREATE UNLOGGED TABLE  earthquakes AS SELECT * FROM earthquakes_ovr
    CREATE OR REPLACE FUNCTION earthquakes_trigger()
    RETURNS TRIGGER AS $$
    BEGIN
        INSERT INTO earthquakes VALUES (NEW.*);
        DELETE FROM ONLY earthquakes WHERE datetime < (now() - '2 days'::interval);
        RETURN NEW;
    END;
    $$
    LANGUAGE plpgsql;
    
    CREATE TRIGGER earthquakes_trigger
            BEFORE INSERT ON earthquakes_ovr
            FOR EACH ROW EXECUTE PROCEDURE earthquakes_trigger();
INSERT INTO earthquakes_ovr VALUES (now())
SELECT * FROM earthquakes_ovr
| datetime                   |
| :------------------------- |
| 2021-04-18 00:11:15.191671 |
| 2021-04-20 00:11:15.203608 |
| 2021-04-24 00:11:15.267616 |
SELECT * FROM earthquakes
| datetime                   |
| :------------------------- |
| 2021-04-24 00:11:15.267616 |

db<>fiddle here

0
0

While targeting the child table directly (earthquakes in your case), rows form the parent table are not affected. You got that backwards, the ONLY keyword has no effect here (is just noise):

DELETE FROM ONLY earthquakes ...

The manual on DELETE:

If ONLY is specified before the table name, matching rows are deleted from the named table only. If ONLY is not specified, matching rows are also deleted from any tables inheriting from the named table.

ONLY can make sense targeting the parent table (earthquakes_ovr in your case).

Consider a partitioned table instead of inheritance. Then you don't need to re-route inserts to the parent table manually. The manual on INSERT:

If the specified table is a partitioned table, each row is routed to the appropriate partition and inserted into it.

1
  • Well , I initially had it as DELETE but it didn't work so I'm probably missing something that is obvious . Thank you for your help. Commented Apr 24, 2021 at 11:37

Not the answer you're looking for? Browse other questions tagged or ask your own question.