Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

On conflict delete postgres

I am trying to toggle a relation in a single query where it deletes the relation if it already exists, otherwise it creates it. I could add a third column with a bool that toggles it but I would rather delete it.

Schema

CREATE TABLE IF NOT EXISTS thread_subscription (
    profile_id     INTEGER REFERENCES profile (id),
    thread_id      INTEGER REFERENCES thread (id),
    UNIQUE(profile_id,thread_id)
)

Query

INSERT INTO thread_subscription (profile_id,thread_id) 
VALUES ($1,$2) ON CONFLICT (profile_id,thead_id) 
DO DELETE FROM thread_subscription 
WHERE profile_id = $1 AND thread_id = $2;
like image 791
als9xd Avatar asked Oct 15 '25 15:10

als9xd


1 Answers

So your intent is to run an INSERT order on a table, and you expect that on duplicate keys it will actually DELETE the related record. While technically feasible, I would not recommend this set up, because this is action at a distance, which is hard to debug.

The same type of functionnality however could be achieved with a Postgres function. This makes the intent explicit when it comes to toggling the subscription, and does not interfere with standard database statements (INSERT).

Here is the code for the function : it takes two parameters as input, verifies if a record is already there in the subscriptions table, and then performs the relevant operation ; it returns 0 on DELETE and 1 on INSERT. You can see this db fiddle for a full demo of how it works.

CREATE OR REPLACE FUNCTION toggle_subscription(
    pid NUMERIC, 
    tid NUMERIC
) 
RETURNS NUMERIC AS $$
DECLARE
    row_exists NUMERIC;
BEGIN

    SELECT 1 
    INTO row_exists 
    FROM thread_subscription 
    WHERE profile_id = pid and thread_id = tid;

    IF (row_exists > 0) THEN
        DELETE FROM thread_subscription WHERE profile_id = pid and thread_id = tid;
        RETURN 0;
    ELSE
        INSERT INTO thread_subscription(profile_id, thread_id) VALUES(pid, tid);
        RETURN 1;
    END IF;

END; 
$$
LANGUAGE plpgsql;
like image 154
GMB Avatar answered Oct 18 '25 06:10

GMB



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!