0

I'm new to Postgres functions and triggers.

I'm trying to create a function that takes the count of values from another table and updates.

But I'm struggling to grasp how the trigger and the function works in tandem in Postgres along with authentication in Supabase. Any help would be appreciated.

CREATE OR REPLACE FUNCTION public.count_created_todos()
RETURNS TRIGGER AS $$
BEGIN
    update public.user set created_todos = (SELECT COUNT(*) FROM public.todo WHERE public.todo.created_by = auth.users.id);
END;
$$ language plpgsql security definer;
DROP TRIGGER IF EXISTS update_count_created_todos ON public.todo;
CREATE TRIGGER update_count_created_todos AFTER INSERT ON public.todo
FOR EACH ROW EXECUTE PROCEDURE count_created_todos();

I couldn't get it working.

1
  • Welcome to the SO community. The community will help you with issues, but there are some expectation of you. Please spend a few minuets to Take the Tour and review How to Ask. Then update your question to include table definition(s) (DDL), sample data, and expected results. All as formatted text or even better a fiddle, but - no images. As far as it not working, exactly how is it failing, what does it actually do. If an error then post the complete message. Commented Feb 16, 2024 at 17:34

1 Answer 1

0

Since you didn't show the user / todo tables, we can only suppose.

Attention to Postgres CREATE TRIGGER::

CREATE [ OR REPLACE ] [ CONSTRAINT ] TRIGGER name { BEFORE | AFTER | INSTEAD OF } { event [ OR ... ] }
    ON table_name
    [ FROM referenced_table_name ]
    [ NOT DEFERRABLE | [ DEFERRABLE ] [ INITIALLY IMMEDIATE | INITIALLY DEFERRED ] ]
    [ REFERENCING { { OLD | NEW } TABLE [ AS ] transition_relation_name } [ ... ] ]
    [ FOR [ EACH ] { ROW | STATEMENT } ]
    [ WHEN ( condition ) ]
    EXECUTE { FUNCTION | PROCEDURE } function_name ( arguments )

Lookout for :

referencing new table as NEW

Try out this example and see if it suits you. Your mileage may vary.

-- newtable definition

-- DROP table created_todos ;
-- drop table TODO;

-- drop function f_updateTodoCounts;
-- drop function f_insertTodoCounts;

CREATE TABLE todo (
    u_created_by integer not null,
    todowhat integer not null,
    primary key( u_created_by, todowhat ) 
);


CREATE TABLE created_todos (
    u_created_by integer ,
    num_of_todos integer ,
    primary key ( u_created_by )
);


create function f_insertTodoCounts() returns trigger
as $f_insertTodoCounts$
declare 
   u_cb INTEGER;
   
begin
    
    select count(td.*) 
    into u_cb 
    from created_todos td , new N
    where N.u_created_by = td.u_created_by;
    
    if u_cb < 1 then 
        insert into created_todos
        select I.u_created_by ,1
        from NEW I;
    else
        update created_todos CT
        set num_of_todos = cnt_todos
        from ( select count(T.todowhat) cnt_todos, T.u_created_by
            from todo T  
            group by T.u_created_by) TD
        where TD.u_created_by = CT.u_created_by
;
    end if;
    return new;
end;
$f_insertTodoCounts$ language plpgsql;

create function f_updateTodoCounts() returns trigger
as $f_updateTodoCounts$
begin
    update created_todos CT
        set num_of_todos = cnt_todos
    from ( select count(1) cnt_todos, u_created_by
            from todo T inner join NEW I on (I.u_created_by = T.u_created_by) ) TD
    where TD.u_created_by = CT.u_created_by;
    return new;
end;
$f_updateTodoCounts$ language plpgsql;


create trigger insTodoCounts
   after insert on todo
   referencing new table as NEW
   for each row 
   execute function f_insertTodoCounts();

create trigger updTodoCounts
   after update on todo
   referencing new table as NEW
   for each row
   execute function  f_updateTodoCounts();
  
insert into todo values ( 1 ,1 );
insert into todo values (2,1 );
insert into todo values (1,2);
insert into todo values (1,3);
insert into todo values  (1,4);
insert into todo values  (1,5);
insert into todo values  (1,6);
insert into todo values  (2,5);
insert into todo values  (3,5);
insert into todo values  (4,7);

select * from created_todos;


Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.