Event Triggers - A.K.A The Real Mess. · sql drop (CASCADE) Prevent Table Rewrite (except at night)...

43
Event Triggers A.K.A The Real Mess. Dimitri Fontaine [email protected] February, 3rd 2013 Dimitri Fontaine [email protected] Event Triggers February, 3rd 2013 1 / 32

Transcript of Event Triggers - A.K.A The Real Mess. · sql drop (CASCADE) Prevent Table Rewrite (except at night)...

Page 1: Event Triggers - A.K.A The Real Mess. · sql drop (CASCADE) Prevent Table Rewrite (except at night) (unless full moon) Create Table If Not Exists, at INSERT time Integrated Extension

Event TriggersA.K.A The Real Mess.

Dimitri Fontaine [email protected]

February, 3rd 2013

Dimitri Fontaine [email protected] Event Triggers February, 3rd 2013 1 / 32

Page 2: Event Triggers - A.K.A The Real Mess. · sql drop (CASCADE) Prevent Table Rewrite (except at night) (unless full moon) Create Table If Not Exists, at INSERT time Integrated Extension

Dimitri Fontaine

2ndQuadrant FrancePostgreSQL Major Contributor

pgloader, prefix, skytools, debian, . . .

CREATE EXTENSION

CREATE EVENT TRIGGER

Bi-Directional Replication

Partitionning

Dimitri Fontaine [email protected] Event Triggers February, 3rd 2013 2 / 32

Page 3: Event Triggers - A.K.A The Real Mess. · sql drop (CASCADE) Prevent Table Rewrite (except at night) (unless full moon) Create Table If Not Exists, at INSERT time Integrated Extension

Dimitri Fontaine

2ndQuadrant FrancePostgreSQL Major Contributor

pgloader, prefix, skytools, debian, . . .

CREATE EXTENSION

CREATE EVENT TRIGGER

Bi-Directional Replication

Partitionning

Dimitri Fontaine [email protected] Event Triggers February, 3rd 2013 2 / 32

Page 4: Event Triggers - A.K.A The Real Mess. · sql drop (CASCADE) Prevent Table Rewrite (except at night) (unless full moon) Create Table If Not Exists, at INSERT time Integrated Extension

Dimitri Fontaine

2ndQuadrant FrancePostgreSQL Major Contributor

pgloader, prefix, skytools, debian, . . .

CREATE EXTENSION

CREATE EVENT TRIGGER

Bi-Directional Replication

Partitionning

Dimitri Fontaine [email protected] Event Triggers February, 3rd 2013 2 / 32

Page 5: Event Triggers - A.K.A The Real Mess. · sql drop (CASCADE) Prevent Table Rewrite (except at night) (unless full moon) Create Table If Not Exists, at INSERT time Integrated Extension

Dimitri Fontaine

2ndQuadrant FrancePostgreSQL Major Contributor

pgloader, prefix, skytools, debian, . . .

CREATE EXTENSION

CREATE EVENT TRIGGER

Bi-Directional Replication

Partitionning

Dimitri Fontaine [email protected] Event Triggers February, 3rd 2013 2 / 32

Page 6: Event Triggers - A.K.A The Real Mess. · sql drop (CASCADE) Prevent Table Rewrite (except at night) (unless full moon) Create Table If Not Exists, at INSERT time Integrated Extension

Event Triggers

So, Event Triggers, what do you mean?

Dimitri Fontaine [email protected] Event Triggers February, 3rd 2013 3 / 32

Page 7: Event Triggers - A.K.A The Real Mess. · sql drop (CASCADE) Prevent Table Rewrite (except at night) (unless full moon) Create Table If Not Exists, at INSERT time Integrated Extension

SQL primer 1/3

It always starts simple

create table foo(a text, b int);

select a, b

from relation r

where a > ’2013’

Dimitri Fontaine [email protected] Event Triggers February, 3rd 2013 4 / 32

Page 8: Event Triggers - A.K.A The Real Mess. · sql drop (CASCADE) Prevent Table Rewrite (except at night) (unless full moon) Create Table If Not Exists, at INSERT time Integrated Extension

SQL primer 2/3

It always starts simple enough

create table foo(a int, b int);

select a, b

from relation r

where a > ’2013’

Dimitri Fontaine [email protected] Event Triggers February, 3rd 2013 5 / 32

Page 9: Event Triggers - A.K.A The Real Mess. · sql drop (CASCADE) Prevent Table Rewrite (except at night) (unless full moon) Create Table If Not Exists, at INSERT time Integrated Extension

SQL primer 3/3

It always starts simple... then we try handling time

create table foo(a date, b int);

select a, b

from relation r

where a > ’2013’

Dimitri Fontaine [email protected] Event Triggers February, 3rd 2013 6 / 32

Page 10: Event Triggers - A.K.A The Real Mess. · sql drop (CASCADE) Prevent Table Rewrite (except at night) (unless full moon) Create Table If Not Exists, at INSERT time Integrated Extension

SQL primer: Extensions

create extension hstore;

create table testhstore (h hstore);

select count(*)

from testhstore

where h @> ’wait=>CC, public=>t’;

Dimitri Fontaine [email protected] Event Triggers February, 3rd 2013 7 / 32

Page 11: Event Triggers - A.K.A The Real Mess. · sql drop (CASCADE) Prevent Table Rewrite (except at night) (unless full moon) Create Table If Not Exists, at INSERT time Integrated Extension

PostgreSQL supports Extensions

Data Type Specific Indexing and Query Support

Functions, Aggregates, Window Functions

Data Types with Input/Output functions

Casts (implicit, assignment only)

Operators

Operator Class, Operator Family

and more...

Dimitri Fontaine [email protected] Event Triggers February, 3rd 2013 8 / 32

Page 12: Event Triggers - A.K.A The Real Mess. · sql drop (CASCADE) Prevent Table Rewrite (except at night) (unless full moon) Create Table If Not Exists, at INSERT time Integrated Extension

Physical Model Optimisations, Business Logic

With PostgreSQL you can tweak INSERT, UPDATE, DELETE

Maintain a Materialized View

Apply crossing threshold discounts

Trigger external actions on some events

NOTIFY some other application parts (e.g. cache)

Queue events to process later (Use PGQ)

Replicate data (Slony, Londiste, Bucardo...)

Dimitri Fontaine [email protected] Event Triggers February, 3rd 2013 9 / 32

Page 13: Event Triggers - A.K.A The Real Mess. · sql drop (CASCADE) Prevent Table Rewrite (except at night) (unless full moon) Create Table If Not Exists, at INSERT time Integrated Extension

Physical Model Optimisations, Business Logic

With PostgreSQL you can tweak INSERT, UPDATE, DELETE

Maintain a Materialized View

Apply crossing threshold discounts

Trigger external actions on some events

NOTIFY some other application parts (e.g. cache)

Queue events to process later (Use PGQ)

Replicate data (Slony, Londiste, Bucardo...)

Dimitri Fontaine [email protected] Event Triggers February, 3rd 2013 9 / 32

Page 14: Event Triggers - A.K.A The Real Mess. · sql drop (CASCADE) Prevent Table Rewrite (except at night) (unless full moon) Create Table If Not Exists, at INSERT time Integrated Extension

Physical Model Optimisations, Business Logic

With PostgreSQL you can tweak INSERT, UPDATE, DELETE

Maintain a Materialized View

Apply crossing threshold discounts

Trigger external actions on some events

NOTIFY some other application parts (e.g. cache)

Queue events to process later (Use PGQ)

Replicate data (Slony, Londiste, Bucardo...)

Dimitri Fontaine [email protected] Event Triggers February, 3rd 2013 9 / 32

Page 15: Event Triggers - A.K.A The Real Mess. · sql drop (CASCADE) Prevent Table Rewrite (except at night) (unless full moon) Create Table If Not Exists, at INSERT time Integrated Extension

Data Modification Trigger Example 1/2

CREATE TABLE main_table (a int, b int);

CREATE FUNCTION trigger_func()

RETURNS trigger

LANGUAGE plpgsql AS ’

BEGIN

RAISE NOTICE ’’trigger_func(%) called: action = %, when = %, level = %’’,

TG_ARGV[0], TG_OP, TG_WHEN, TG_LEVEL;

RETURN NULL;

END;’;

Dimitri Fontaine [email protected] Event Triggers February, 3rd 2013 10 / 32

Page 16: Event Triggers - A.K.A The Real Mess. · sql drop (CASCADE) Prevent Table Rewrite (except at night) (unless full moon) Create Table If Not Exists, at INSERT time Integrated Extension

Data Modification Trigger Example 2/2

CREATE TRIGGER before_ins_stmt_trig

BEFORE INSERT ON main_table

FOR EACH STATEMENT

EXECUTE PROCEDURE trigger_func(’before_ins_stmt’);

CREATE TRIGGER after_ins_stmt_trig

AFTER INSERT ON main_table

FOR EACH STATEMENT

EXECUTE PROCEDURE trigger_func(’after_ins_stmt’);

Dimitri Fontaine [email protected] Event Triggers February, 3rd 2013 11 / 32

Page 17: Event Triggers - A.K.A The Real Mess. · sql drop (CASCADE) Prevent Table Rewrite (except at night) (unless full moon) Create Table If Not Exists, at INSERT time Integrated Extension

SQL DDL primer

Data Definition Language

create table foo

(

id serial primary key,

f1 text

);

alter table foo

add column f2 text check (upper(f2) = f2);

Dimitri Fontaine [email protected] Event Triggers February, 3rd 2013 12 / 32

Page 18: Event Triggers - A.K.A The Real Mess. · sql drop (CASCADE) Prevent Table Rewrite (except at night) (unless full moon) Create Table If Not Exists, at INSERT time Integrated Extension

SQL DDL primer

Here’s what foo looks like now

~# \d foo

Table "public.foo"

Column | Type | Modifiers

--------+---------+--------------------------------------------------

id | integer | not null default nextval(’foo_id_seq’::regclass)

f1 | text |

f2 | text |

Indexes:

"foo_pkey" PRIMARY KEY, btree (id)

Check constraints:

"foo_f2_check" CHECK (upper(f2) = f2)

Dimitri Fontaine [email protected] Event Triggers February, 3rd 2013 13 / 32

Page 19: Event Triggers - A.K.A The Real Mess. · sql drop (CASCADE) Prevent Table Rewrite (except at night) (unless full moon) Create Table If Not Exists, at INSERT time Integrated Extension

What if you could tweak DDL too

Some DDL Trigger use cases

Audit trail

Replication Triggers

Implement Local Policies

Divert Execution

Limited Granting of DDL privileges with Security Definer triggerfunctions

Dimitri Fontaine [email protected] Event Triggers February, 3rd 2013 14 / 32

Page 20: Event Triggers - A.K.A The Real Mess. · sql drop (CASCADE) Prevent Table Rewrite (except at night) (unless full moon) Create Table If Not Exists, at INSERT time Integrated Extension

What if you could tweak DDL too

Some Event Trigger use cases

sql drop (CASCADE)

Prevent Table Rewrite (except at night) (unless full moon)

Create Table If Not Exists, at INSERT time

Integrated Extension Package Management

Dimitri Fontaine [email protected] Event Triggers February, 3rd 2013 15 / 32

Page 21: Event Triggers - A.K.A The Real Mess. · sql drop (CASCADE) Prevent Table Rewrite (except at night) (unless full moon) Create Table If Not Exists, at INSERT time Integrated Extension

What if you could tweak DDL too

Some Event Trigger use cases

sql drop (CASCADE)

Prevent Table Rewrite (except at night) (unless full moon)

Create Table If Not Exists, at INSERT time

Integrated Extension Package Management

Dimitri Fontaine [email protected] Event Triggers February, 3rd 2013 15 / 32

Page 22: Event Triggers - A.K.A The Real Mess. · sql drop (CASCADE) Prevent Table Rewrite (except at night) (unless full moon) Create Table If Not Exists, at INSERT time Integrated Extension

What if you could tweak DDL too

Some Event Trigger use cases

sql drop (CASCADE)

Prevent Table Rewrite (except at night) (unless full moon)

Create Table If Not Exists, at INSERT time

Integrated Extension Package Management

Dimitri Fontaine [email protected] Event Triggers February, 3rd 2013 15 / 32

Page 23: Event Triggers - A.K.A The Real Mess. · sql drop (CASCADE) Prevent Table Rewrite (except at night) (unless full moon) Create Table If Not Exists, at INSERT time Integrated Extension

What if you could tweak DDL too

Some Event Trigger use cases

sql drop (CASCADE)

Prevent Table Rewrite (except at night) (unless full moon)

Create Table If Not Exists, at INSERT time

Integrated Extension Package Management

Dimitri Fontaine [email protected] Event Triggers February, 3rd 2013 15 / 32

Page 24: Event Triggers - A.K.A The Real Mess. · sql drop (CASCADE) Prevent Table Rewrite (except at night) (unless full moon) Create Table If Not Exists, at INSERT time Integrated Extension

Event Trigger Primer

CREATE OR REPLACE FUNCTION abort_any_command()

RETURNS event_trigger

LANGUAGE plpgsql

AS ’

BEGIN

RAISE EXCEPTION ’’command % is disabled’’, tg_tag;

END;

’;

CREATE EVENT TRIGGER abort_ddl ON ddl_command_start

EXECUTE PROCEDURE abort_any_command();

Dimitri Fontaine [email protected] Event Triggers February, 3rd 2013 16 / 32

Page 25: Event Triggers - A.K.A The Real Mess. · sql drop (CASCADE) Prevent Table Rewrite (except at night) (unless full moon) Create Table If Not Exists, at INSERT time Integrated Extension

Event Trigger Primer

Of course, the usual ALTER and DROP commands

ALTER EVENT TRIGGER abort_ddl DISABLE;

ALTER EVENT TRIGGER abort_ddl ENABLE replica|always;

ALTER EVENT TRIGGER abort_ddl OWNER TO bob;

ALTER EVENT TRIGGER abort_ddl RENAME TO assimilated;

DROP EVENT TRIGGER abort_ddl;

Dimitri Fontaine [email protected] Event Triggers February, 3rd 2013 17 / 32

Page 26: Event Triggers - A.K.A The Real Mess. · sql drop (CASCADE) Prevent Table Rewrite (except at night) (unless full moon) Create Table If Not Exists, at INSERT time Integrated Extension

Events

Limited Number of Events Supported now

ddl command start

ddl command end

sql drop currently in review

Dimitri Fontaine [email protected] Event Triggers February, 3rd 2013 18 / 32

Page 27: Event Triggers - A.K.A The Real Mess. · sql drop (CASCADE) Prevent Table Rewrite (except at night) (unless full moon) Create Table If Not Exists, at INSERT time Integrated Extension

Tags 1/3

~# create table bar(a int, b int);

CREATE TABLE

~# create function add1(int) returns int

language sql as ’select \$1+1’;

CREATE FUNCTION

~# drop function add1(int);

DROP FUNCTION

Dimitri Fontaine [email protected] Event Triggers February, 3rd 2013 19 / 32

Page 28: Event Triggers - A.K.A The Real Mess. · sql drop (CASCADE) Prevent Table Rewrite (except at night) (unless full moon) Create Table If Not Exists, at INSERT time Integrated Extension

Tags 2/3

create function test_event_trigger()

returns event_trigger as ’

BEGIN

RAISE NOTICE ’’test_event_trigger: % %’’, tg_event, tg_tag;

END

’ language plpgsql;

create function test_event_trigger_drop_function()

returns event_trigger as ’

BEGIN

drop function test_event_trigger() cascade;

END

’ language plpgsql;

Dimitri Fontaine [email protected] Event Triggers February, 3rd 2013 20 / 32

Page 29: Event Triggers - A.K.A The Real Mess. · sql drop (CASCADE) Prevent Table Rewrite (except at night) (unless full moon) Create Table If Not Exists, at INSERT time Integrated Extension

Tags 3/3

And now let’s have some fun

create event trigger drop_test_b on "ddl_command_start"

execute procedure test_event_trigger();

create event trigger drop_test_a on "ddl_command_start"

when tag in (’create table’)

execute procedure test_event_trigger_drop_function();

create table event_trigger_fire1 (a int);

Dimitri Fontaine [email protected] Event Triggers February, 3rd 2013 21 / 32

Page 30: Event Triggers - A.K.A The Real Mess. · sql drop (CASCADE) Prevent Table Rewrite (except at night) (unless full moon) Create Table If Not Exists, at INSERT time Integrated Extension

Event Triggers Information

Currently given as magic variables available in PLpgSQL

We have

TG EVENT

TG TAG

We want to add

TG OPERATION

TG OBTYPENAME

TG OBJECTID

TG OBJECTNAME

TG SCHEMANAME

Dimitri Fontaine [email protected] Event Triggers February, 3rd 2013 22 / 32

Page 31: Event Triggers - A.K.A The Real Mess. · sql drop (CASCADE) Prevent Table Rewrite (except at night) (unless full moon) Create Table If Not Exists, at INSERT time Integrated Extension

What about generated commands?

Current proposal is TG CONTEXT. See the worked out tracking examples athttp://www.postgresql.org/message-id/m2han7xyzp.fsf@

2ndQuadrant.fr

create event trigger track_table on ddl_command_trace

when tag in (’create table’, ’alter table’, ’drop table’)

and context in (’toplevel’, ’generated’, ’subcommand’)

execute procedure public.track_table_activity();

Dimitri Fontaine [email protected] Event Triggers February, 3rd 2013 23 / 32

Page 32: Event Triggers - A.K.A The Real Mess. · sql drop (CASCADE) Prevent Table Rewrite (except at night) (unless full moon) Create Table If Not Exists, at INSERT time Integrated Extension

Command String Normalisation 1/4

And still some more

create schema baz

authorization dim

create table distributors

(

did serial primary key,

name varchar(40),

f2 text check (upper(f2) = f2),

unique(name) with (fillfactor=70)

)

with (fillfactor=70);

Dimitri Fontaine [email protected] Event Triggers February, 3rd 2013 24 / 32

Page 33: Event Triggers - A.K.A The Real Mess. · sql drop (CASCADE) Prevent Table Rewrite (except at night) (unless full moon) Create Table If Not Exists, at INSERT time Integrated Extension

Command String Normalisation 2/4

NOTICE: snitch event: ddl_command_end, context: GENERATED,

tag: CREATE SEQUENCE, operation: CREATE,

type: SEQUENCE

NOTICE: oid: 41633, schema: baz, name: distributors_did_seq

NOTICE: command: CREATE SEQUENCE baz.distributors_did_seq;

NOTICE: snitch event: ddl_command_end, context: SUBCOMMAND,

tag: CREATE TABLE, operation: CREATE, type: TABLE

NOTICE: oid: 41635, schema: baz, name: distributors

NOTICE: command: CREATE TABLE baz.distributors

(did integer,

name pg_catalog.varchar,

f2 text,

CHECK ((upper(f2) = f2))) WITH (fillfactor=70);

Dimitri Fontaine [email protected] Event Triggers February, 3rd 2013 25 / 32

Page 34: Event Triggers - A.K.A The Real Mess. · sql drop (CASCADE) Prevent Table Rewrite (except at night) (unless full moon) Create Table If Not Exists, at INSERT time Integrated Extension

Command String Normalisation 3/4

NOTICE: snitch event: ddl_command_end, context: GENERATED,

tag: CREATE INDEX, operation: CREATE, type: INDEX

NOTICE: oid: 41643, schema: baz, name: distributors_pkey

NOTICE: command: CREATE UNIQUE INDEX distributors_pkey

ON baz.distributors USING btree (did);

NOTICE: snitch event: ddl_command_end, context: GENERATED,

tag: CREATE INDEX, operation: CREATE, type: INDEX

NOTICE: oid: 41645, schema: baz, name: distributors_name_key

NOTICE: command: CREATE UNIQUE INDEX distributors_name_key

ON baz.distributors USING btree (name)

WITH (fillfactor=70);

Dimitri Fontaine [email protected] Event Triggers February, 3rd 2013 26 / 32

Page 35: Event Triggers - A.K.A The Real Mess. · sql drop (CASCADE) Prevent Table Rewrite (except at night) (unless full moon) Create Table If Not Exists, at INSERT time Integrated Extension

Command String Normalisation 4/4

NOTICE: snitch event: ddl_command_end, context: GENERATED,

tag: ALTER SEQUENCE, operation: ALTER, type: SEQUENCE

NOTICE: oid: 41633, schema: baz, name: distributors_did_seq

NOTICE: command: ALTER SEQUENCE baz.distributors_did_seq

OWNED BY baz.distributors.did;

NOTICE: snitch event: ddl_command_end, context: TOPLEVEL,

tag: CREATE SCHEMA, operation: CREATE, type: SCHEMA

NOTICE: oid: 41632, schema: <NULL>, name: baz

NOTICE: command: CREATE SCHEMA baz AUTHORIZATION dim;

CREATE SCHEMA

Dimitri Fontaine [email protected] Event Triggers February, 3rd 2013 27 / 32

Page 36: Event Triggers - A.K.A The Real Mess. · sql drop (CASCADE) Prevent Table Rewrite (except at night) (unless full moon) Create Table If Not Exists, at INSERT time Integrated Extension

TG CONTEXT

How to get at generated commands?

PRO

consider them DDLs

ProcessUtility()

ProcessUtilityContext

CONS

the user didn’t type a command

clean up the code

it’s another kind of event

Dimitri Fontaine [email protected] Event Triggers February, 3rd 2013 28 / 32

Page 37: Event Triggers - A.K.A The Real Mess. · sql drop (CASCADE) Prevent Table Rewrite (except at night) (unless full moon) Create Table If Not Exists, at INSERT time Integrated Extension

Next features

Some features are still on the todo list

INSTEAD OF

table rewrite

create table on insert

add column on update

Dimitri Fontaine [email protected] Event Triggers February, 3rd 2013 29 / 32

Page 38: Event Triggers - A.K.A The Real Mess. · sql drop (CASCADE) Prevent Table Rewrite (except at night) (unless full moon) Create Table If Not Exists, at INSERT time Integrated Extension

Next features

Some features are still on the todo list

INSTEAD OF

table rewrite

create table on insert

add column on update

Dimitri Fontaine [email protected] Event Triggers February, 3rd 2013 29 / 32

Page 39: Event Triggers - A.K.A The Real Mess. · sql drop (CASCADE) Prevent Table Rewrite (except at night) (unless full moon) Create Table If Not Exists, at INSERT time Integrated Extension

Next features

Some features are still on the todo list

INSTEAD OF

table rewrite

create table on insert

add column on update

Dimitri Fontaine [email protected] Event Triggers February, 3rd 2013 29 / 32

Page 40: Event Triggers - A.K.A The Real Mess. · sql drop (CASCADE) Prevent Table Rewrite (except at night) (unless full moon) Create Table If Not Exists, at INSERT time Integrated Extension

Next features

Some features are still on the todo list

INSTEAD OF

table rewrite

create table on insert

add column on update

Dimitri Fontaine [email protected] Event Triggers February, 3rd 2013 29 / 32

Page 41: Event Triggers - A.K.A The Real Mess. · sql drop (CASCADE) Prevent Table Rewrite (except at night) (unless full moon) Create Table If Not Exists, at INSERT time Integrated Extension

Instead Of Event Triggers 1/2

create event trigger my_create_extension

instead of ’create extension’

execute procedure my_create_extension();

Dimitri Fontaine [email protected] Event Triggers February, 3rd 2013 30 / 32

Page 42: Event Triggers - A.K.A The Real Mess. · sql drop (CASCADE) Prevent Table Rewrite (except at night) (unless full moon) Create Table If Not Exists, at INSERT time Integrated Extension

Instead Of Event Triggers 2/2

create function my_create_extension()

returns event_trigger

language plpgsql

as ’

begin

alter event trigger my_create_extension disable;

-- do some stuff here

create extension tg_objectid;

-- do some more stuff here, presumably

end;

’;

Dimitri Fontaine [email protected] Event Triggers February, 3rd 2013 31 / 32

Page 43: Event Triggers - A.K.A The Real Mess. · sql drop (CASCADE) Prevent Table Rewrite (except at night) (unless full moon) Create Table If Not Exists, at INSERT time Integrated Extension

Conclusion

Any Question? Now is the time to ask!

Dimitri Fontaine [email protected] Event Triggers February, 3rd 2013 32 / 32