Trigger für jede SQL-Abfrage möglich?

Kurze Demo:

Zuerst einmal als Superuser:

test=# create database rhaupt;CREATE DATABASE
Time: 304,252 ms
test=# \c rhaupt;You are now connected to database "rhaupt" as user "kretschmer".
rhaupt=# create user rhaupt1;CREATE ROLE
Time: 0,380 ms
rhaupt=*# create user rhaupt2;
CREATE ROLE
Time: 0,125 ms
rhaupt=*# revoke all on schema public from rhaupt1;
REVOKE
Time: 0,437 ms
rhaupt=*# revoke all on schema public from rhaupt2;
REVOKE
Time: 0,155 ms
rhaupt=*# create table foo (user_id text default session_user, value int);CREATE TABLE
Time: 5,338 ms
rhaupt=*# create function insert_foo(int) returns bool as $$begin insert into foo(user_id,value) values (default, $1); return true;end;$$language plpgsql security definer;
CREATE FUNCTION
Time: 1,284 ms
rhaupt=*# create function get_foo() returns setof int as $$begin return query select value from foo where user_id=session_user; end;$$language plpgsql security definer;
CREATE FUNCTION
Time: 0,536 ms
rhaupt=*# commit;
COMMIT
Time: 0,460 ms

Wichtig ist, daß man mit session_user da hantiert, da augfrund security definer der current_user ja der Superuser (Ersteller) ist. bedingt natürlich, daß jeder Mandant in der DB als eigener User angelegt ist, aber das ist ja kein Problem.

Nun in einer anderen Session:

kretschmer@tux:~$ psql -U rhaupt1 rhaupt;
Timing is on.                            
psql (9.2.0)                             
Type "help" for help.                    

rhaupt=> select * from foo;
ERROR:  permission denied for relation foo
Time: 0,832 ms
rhaupt=*> select insert_foo(1);
 insert_foo
------------
 t
(1 row)

Time: 1,326 ms
rhaupt=*> select get_foo();
 get_foo
---------
       1
(1 row)

Time: 1,481 ms
rhaupt=*> \q
kretschmer@tux:~$ psql -U rhaupt2 rhaupt;
Timing is on.
psql (9.2.0)
Type "help" for help.

rhaupt=> select get_foo();
 get_foo
---------
(0 rows)

Time: 2,262 ms
rhaupt=*> select insert_foo(2);
 insert_foo
------------
 t
(1 row)

Time: 0,495 ms
rhaupt=*> select get_foo();
 get_foo
---------
       2
(1 row)

Time: 0,201 ms
rhaupt=*>

So hat man eine extra Schicht eingezogen und trennt schön die einzelnen Mandanten. Als Superuser hast natürlich alle rechte, wieder die erste Session:

rhaupt=# select * from foo;
 user_id | value
---------+-------
 rhaupt2 |     2
 rhaupt1 |     1
(2 rows)

(ich hatte erst das commit vergessen, daher nun andere reihenfolge…)

.oO( ich muß mal wieder compilieren, 9.2.0, aber das ist hier lokal nur meine Spielwiese)