View Triggers!
JDCon East
March 25, 2011
Copyright © 2011
David Fetter dfetter@vmware.com
All Rights Reserved
...or does it?
What is a View?
What is a View?


• Cached query
What is a View?


• Cached query
• Modified at runtime
What is a Trigger?

• Executable code
• Call and Response
• Scope: row or statement
What is a View Trigger?


• Cached query brings rows
• Code executes on each
Trigger Contexts
                           SCOPE
 WHEN        EVENT
                        ROW      STATEMENT
              INSERT
              UPDATE    TABLES   TABLES/VIEWS
 BEFORE       DELETE

             TRUNCATE     ―        TABLES
              INSERT
              UPDATE    TABLES   TABLES/VIEWS
  AFTER       DELETE

             TRUNCATE     ―           ―
              INSERT
              UPDATE    VIEWS         ―
              DELETE
INSTEAD OF
             TRUNCATE     ―           ―
Why?
Query
Rewrite
RULEs :P
Actually,
Query
Rewrite
SUthis is a family presentation
Like C Pre-Processor
Macros, only Less Fun
No more RULEs! :)
View Triggers Before
•   For each VIEW

    •   Shadow table

    •   3 RULEs

        •   INSERT RULE

        •   UPDATE RULE

        •   DELETE RULE

    •   Trigger on Shadow Table
Shadow Table
CREATE TABLE v_t_shadow (
    old_column,
    old_list,
    old_here,
    new_column,
    new_list,
    new_here,
);
INSERT RULE
CREATE RULE t_v_insert
    ON INSERT TO t_v
    DO INSTEAD
    INSERT INTO t_v_shadow (
        action,
        new_column,
        new_list,
        new_here)
    VALUES (
        'I',
        NEW.t_v_column,
        NEW.list,
        NEW.here
    );
DELETE RULE
CREATE RULE t_v_delete
    ON DELETE TO t_v
    DO INSTEAD
    INSERT INTO t_v_shadow (
        action,
        column,
        list,
        here)
    VALUES (
        'D',
        OLD.t_v_column,
        OLD.list,
        OLD.here
    );
UPDATE RULE
CREATE RULE t_v_update
    ON UPDATE TO t_v
    DO INSTEAD
    INSERT INTO t_v_shadow (
        action,
        column,
        list,
        here)
    VALUES (
        'U',
        OLD.t_v_column,
        OLD.list,
        OLD.here,
        NEW.t_v_column,
        NEW.list,
        NEW.here
    );
Shadow Table Trigger Function
CREATE OR REPLACE FUNCTION shadow_table_t_v()
RETURNS TRIGGER
LANGUAGE plpgsql
AS $$
BEGIN
    IF NEW.action = 'I' THEN
        ...
    ELSIF NEW.action = 'D' THEN
        ...
    ELSIF NEW.action = 'U' THEN
        ...
    END IF;
    RETURN NULL;
END;
$$;
Shadow Trigger
CREATE TRIGGER shadow_table_t_v
    BEFORE
        INSERT OR UPDATE OR DELETE
    ON shadow_t_v
    FOR EACH ROW
    EXECUTE PROCEDURE shadow_trigger_t_v();
•Performance?
 • Not So Much™
•Concurrency?
 • What's that?
With Triggers on Views
With Triggers on Views
• That's
With Triggers on Views
• That's
• All
With Triggers on Views
• That's
• All
• Just
With Triggers on Views
• That's
• All
• Just
•A
With Triggers on Views
• That's
• All
• Just
•A
• Bad
With Triggers on Views
• That's
• All
• Just
•A
• Bad
• Memory
View Triggers Now

• Create trigger function
• Create trigger
• DONE!
Table
CREATE TABLE triangle_victims (
    first_name TEXT,
    last_name TEXT NOT NULL,
    age INTEGER,
    notes TEXT
);
View
CREATE VIEW triangle_victims_v
AS SELECT
    COALESCE(
         first_name || ' ',
         '') ||
    last_name AS "full_name",
    age,
    notes
FROM triangle_victims;
Trigger Function
CREATE OR REPLACE FUNCTION write_triangle_victims_v()
RETURNS TRIGGER
LANGUAGE plpgsql
AS $$
DECLARE
     name_split TEXT[];
BEGIN
     IF TG_OP = 'INSERT' THEN
         name_split = string_to_array(NEW.full_name, ' ');
         INSERT INTO triangle_victims (first_name, last_name, age, notes)
         VALUES (
             array_to_string(
                  name_split[1:array_upper(name_split,1)-1], ' '
             ),
             name_split[array_upper(name_split,1)],
             NEW.age,
             NEW.notes
         );
         RETURN NEW;
     ELSIF TG_OP = 'DELETE' THEN /* Similar code goes here */
     ELSIF TG_OP = 'UPDATE' THEN /* And slightly more complicated here */
     END IF;
END;
$$;
Triangle Shirtwaist Fire

http://en.wikipedia.org/wiki/Triangle_Shirtwaist_Factory_fire

http://law2.umkc.edu/faculty/projects/ftrials/triangle/trianglevictims2.html
•   Questions?
•   Comments?
Thank You!
JDCon East
March 25, 2011
Copyright © 2011
David Fetter dfetter@vmware.com
All Rights Reserved

View triggers pg_east_20110325

Editor's Notes