How do I change the owner of an event trigger in postgresql? - postgresql

The documentation states that the command for altering the owner of an event trigger is:
ALTER EVENT TRIGGER name OWNER TO { new_owner | CURRENT_USER | SESSION_USER }
But it errors with:
[42704] ERROR: event trigger "insert_component_relationship" does not exist
I thought that meant I needed to qualify it with the schema name so I tried:
ALTER EVENT TRIGGER schema.name OWNER TO { new_owner }
but that screamed at me as well with:
[42601] ERROR: syntax error at or near "."
Then I just started trying other combinations of commands I thought would work, ex:
ALTER TRIGGER name ON table OWNER TO { new_owner }
ALTER TRIGGER name ON schema.table OWNER TO { new_owner }
To no avail. Under the name parameter on this page seems to suggest that the schema is inferred when it's created but makes no mention of schema qualifying when trying to alter the trigger.
EDIT Actual command run with pseudo values:
ALTER EVENT TRIGGER modify_relationship OWNER TO new_admin_user;
ALTER EVENT TRIGGER products.modify_relationship OWNER TO new_admin_user;

Relatively minor mistake.
Make sure the trigger is an actual event trigger.
Check with the meta-command \dy. If it doesn't show up here, it's probably not an event trigger.
The CREATE TRIGGER statement in PostgreSQL implements a subset of the SQL standard. The following functionalities are currently missing:
Triggers are defined by the SQL standard and there is no mention of ownership on the documentation for them
Altering the ownership of an event trigger is given as a option in the docs for ALTER EVENT TRIGGER
There is no CREATE EVENT TRIGGER statement in the SQL standard.
Thanks to #eurotrash for the comment that led me to the distinction.

Related

Microsoft Azure PostgreSQL Event Trigger vs. SuperUser

I am using Microsoft Azure Database for PostgreSQL with PostgreSQL 10 installed. As I'm trying to work on future tables together with other users I want to enable the other users to alter my tables as well.
I've created a role pgpublish and all users are members of the role. For a new table, which I created, I altered the table owner to the role pgpublish. Now everyone with the role pgpublish is able to alter the table:
ALTER TABLE "MYcoolSchema"."CoolNewTable" OWNER TO pgpublish;
To make this more automatic/generic, I created a trigger function and tried to create an event trigger as explained here.
Unfortunately I can't create the event trigger (The trigger function works fine), as it is stated:
ERROR: permission denied to create event trigger
"trg_create_set_owner" HINT: Must be superuser to create an event trigger.
SQL state: 42501
Is there a workaround for creating event triggers on Microsoft Azure Database for PostgreSQL? How can this look like?
I could run a cron job on another system to scan for new tables and alter the owner of these new tables to pgpublish but this is not cool at all.

Enabling and Disabling a trigger in a Postgres function

I have a trigger on a table and I want to catch the messages that are introduced between an interval. I had created a function who recive an integer() as a parameter.
The pseudocode is something like this:
alter table <table_name> enable trigger <trigger_name>;
PERFORM pg_sleep(<nrofseconds>);
alter table <table_name> disable trigger <trigger_name>;
The problem is that, a Postgres function works as a single transaction and the trigger is enabled, then disabled at the end of execution, when commit is called so it does not track anything.
How can I solve this problem?

postgresql table updated only by trigger

Is it possible, to configure a Postgres database such, that a specific table may only be updated by a trigger. I have history table, updated by trigger, so I want to prevent this table from un unauthorised access. I want history table to be updated only from trigger.
Sure. Both the history table and the table with the trigger belong to a user that has no login rights. Then you grant privileges on the latter table to the application user.
To prevent unauthorized access to a table you can change the owner of the table to the user who should be accessing with the following query:
alter table yourschema.yourtable owner to youruser;
Now you can disable the trigger for all other users using the query:
alter table yourschema.yourtable disable trigger triggername all;
here all means that the trigger is disabled for all the users. Now only the owner will be able to use the trigger to update the table.
A trigger always fires on the event on it is defined. Thus, if an update trigger is defined for updates, no one can bypass the trigger during an update if the trigger is enabled.
If you have different user groups with different privileges accessing your database, then you should map this about users in the database. For instance you can disallow that a user can disable triggers on a table.

Prevent query assigning ID when column has a default

I have a table that has a column defined as id serial. Therefore, it has a default on the column to call a sequencer. Which is what I want. However, my boss (and owner of the company) insists on having full access to the database and likes to write his own queries (including inserts) on this table. And even more unfortunately, he seems to always forgets that these IDs should be auto-generated for him, and he creates the record with max(id) + 1. Then the sequencer is out of sync with the table and the next time someone calls the API we get a 500.
Question: Given that I don't have the ability to lock him out of the database, what is the best way to prevent him from doing this?
My first idea was create a before insert trigger and raise an error if the ID was assigned. Here is what I did:
CREATE OR REPLACE FUNCTION md.tf_no_manual_keys()
RETURNS trigger
LANGUAGE plpgsql
AS $function$
DECLARE
BEGIN
IF NEW.id IS NOT NULL THEN
RAISE EXCEPTION 'ID must be assigned from sequencer';
END IF;
END;
$function$
trigger_no_manual_keys BEFORE INSERT ON vendor FOR EACH ROW EXECUTE PROCEDURE tf_no_manual_keys()
But, this doesn't work because the sequencer has already fired (I didn't think that was the case for a "BEFORE" trigger).
I guess I could always call the trigger on BEFORE INSERT, but that seems like it would use 2 IDs whenever it's called.
I'm using PostgreSQL 9.4
If you have grant privilege on the table you can revoke a role's insert privilege on a certain column:
revoke insert (id) on table t from role_name;
But that will not work if that role is a member of another role that has that privilege.

Triggers in postgresql

I am new to PostgreSQL and I am currently working on triggers but am stuck at one point.
I have two tables Student and Room.
Room id is the primary key in Room and foreign key in Student.
If I am inserting in Student, then it should check in Room whether the new data exist or not.
This is a foreign key check constraint. I hope anyone can help me with it
I dont know your code and I dont get the meaning, but I can answer generally.
In PostgreSQL a trigger is normally defined in two steps:
Define a trigger function using the CREATE FUNCTION
Bind this created trigger function to a table using CREATE TRIGGER
A trigger function is a common function, except that is has a return value type trigger (in addition, it does not take any arguments).
CREATE OR REPLACE FUNCTION trigger_function()
RETURNS trigger
AS $$ ... $$;
binding:
CREATE TRIGGER trigger_name
AFTER INSERT ON table_name
FOR EACH ROW EXECUTE PROCEDURE trigger_function();
In addition, please also consult the excellent PG documentation at PostgreSQL 9.4 Triggers