I have a trigger that runs on insert or update of a table but for the life of me, I can't find the source for that function... where should I be looking?
The SQL for the trigger:
CREATE TRIGGER my_trigger
BEFORE INSERT OR UPDATE OF search_data
ON public.mytable
FOR EACH ROW
EXECUTE FUNCTION tsvector_update_trigger('search_vector', 'pg_catalog.english', 'search_data');
How do I get the source for the tsvector_update_trigger function? I'm looking in pgadmin right now and can't seem to find it but can also use psql.
Any help appreciated!
Related
Good evening . I'm working on a chat application using nodejs, prisma, postgresql. I would like 24 hours after the last message is created on a specific chat to be immediately deleted from the postgresql database. For this, I created a trigger:
--function creation
create or replace function chat_expired() returns trigger as $delete_account$
begin
delete from chat where current_timestamp - last.messages.createAt = 24*60*60;
return new;
end;
$delete_account$ language plpgsql ;
-- trigger creation
create trigger messages_added
after update
on chat --I get error on this line
for each row
execute procedure chat_expired();
from postgresql query tool but when I execute I get the error the cat relationship does not exist at the trigger definition level. I guess it's because the chat table hasn't been defined in my query tool space; but I didn't set it because the chat table was already created from prisma immigrations. So I deleted the folder of my prisma migrations, then I created a new migration and I modified the .sql file manually in order to insert my trigger there thus thinking that prisma would also create a trigger for me at the same time as database tables:
--function creation
create or replace function "chat_expired"() returns trigger as $delete_account$
begin
delete from "Chat" where current_timestamp - last.chatMessage.createdAt = 3*60;
return new;
end;
$delete_account$ language plpgsql ;
-- trigger creation
create trigger "messages_added"
after update
on "chat"
for each row
execute procedure "chat_expired"();
Notes: The previous code contains a few more quotes than the first code. But it instead prevented the migration from applying and I got the error
Error: P3006
Migration `20220905231003_initial_migration` failed to apply cleanly to the shadow database.
Error code: P1014
Error:
The underlying table for model `(not available)` does not exist.
which was only resolved after I removed the manually added rows. So I don't know how to create a trigger on a postgresql database managed by prisma. I've been thinking about the solution for several weeks. I even looked at this stackoverflow question and also this one but nothing. Thanks !
Prisma doesn't have support for triggers yet. Prisma has an excellent article on the topic. They advice writing Prisma middleware to achieve "triggers". There is also a feature request for it.
So the thing is I am developing a contrib module and want to capture table name inside that contrib module.
question:
Is there any way to capture a table name during create table or insert table?
I have seen some of the triggers but not able to make it (I don't think there is any create table trigger). In case it is possible tell me a way to achieve it.
I though of extracting meta-data using pg_class but not helping it seems because I have to give explicitly a rel-name (table name) in where clause
do you think any other way to achieve it? Please elaborate if any and please let me know.
Here is some example which will make you understand a bit about the things I want to achieve.
creating a table:
create table new_table(name varchar , new integer);
insert into new_table values('abcdefghijkl' , 5004);
create table new_table1(name1 varchar , new1 integer) ;
insert into new_table1 values('mnopqrst' , 5005);
creating extension:
create extension table_name-extract;
select extract_tablename();
So my extension should extract a table name, means I should know table name with the built-in datatype I have declared.
Here what I expect as a output:
select extract_tablename();
table-name datatype-name
new_table name new
new_table1 name1 new1
You don't really need an extension to track the execution of DDL statements.
For that you can use an event trigger
The manual also has an example on how to write an event trigger using PL/pgSQL
CREATE OR REPLACE FUNCTION snitch()
RETURNS event_trigger
AS $$
BEGIN
RAISE NOTICE 'snitch: % %', tg_event, tg_tag;
END;
$$ LANGUAGE plpgsql;
CREATE EVENT TRIGGER snitch ON ddl_command_start
EXECUTE PROCEDURE snitch();
Inside the trigger function you would need to store the table name in some configuration table so that the information is not lost.
Of course you can package your trigger and "log table" (as a configuration table) into an extension if you want.
Another option is to enable DDL logging using
log_statement=ddl
in postgresql.conf - then you have all DDL statements in the Postgres logfile.
How would I edit a trigger function in postgresql using psql? I have tried the using \ef trigger_name and every single time I try that it does not stick. Do I have to drop all of the triggers that refer to that trigger function before attempting to update it? I have been looking at the docs for a while and I did not find anything saying that I must to that? I have tried typing in the CREATE OR REPLACE... by hand into psql and that did not work.
I would like to know if a trigger on a system table of PostgreSQL can be executed when I create a table
I need to add 2 functions on each table of my database and I would like to do it dynamically
Thanks
This can be done with an event trigger:
CREATE OR REPLACE FUNCTION on_create_table_func()
RETURNS event_trigger AS $$
BEGIN
-- your code here
END
$$
LANGUAGE plpgsql;
CREATE EVENT TRIGGER
on_create_table ON ddl_command_end
WHEN TAG IN ('CREATE TABLE')
EXECUTE PROCEDURE on_create_table_func();
Note that there is no way to directly execute any query on the newly created table, or even get its name.
I don't know what you mean by "add 2 functions on each table" since functions don't belong to a specific table, but if you need to perform an operation specific for the new tables, this might not be for you.
I know it's an old question but now it has been implemented in version 9.3, or at least partially
http://www.postgresql.org/docs/9.3/static/event-trigger-definition.html
You're looking for "DDL Triggers". They're not implemented in PostgreSQL. Neither you can add triggers to system tables. Look at this forum entry:
Adding ddl audit trigger
How do I only create a trigger if it does not exist?
When I do create or replace, I get a syntax error so I am looking for a way to test for the existence of a trigger.
I can always select * from pg_trigger, but I am sure there is a more suitable way.
Thanks
Postgres can conditionally drop a trigger - see the docs. Do this before creating the trigger, then it will always work.
DROP TRIGGER IF EXISTS mytrigger ON mytable;
As Jack points out in the comments, this feature has only been available since 8.2; this has been out for more than four years though, so it should be available in your version.
CREATE TRIGGER (NameOfTrigger) AFTER INSERT OR UPDATE ON (NameOfTable)
DROP TRIGGER IF EXISTS (NameOfTrigger) ON (NameOfTable);