Add trigger support to PostgreSQL producer and parser (including trigger scope)
[dbsrgits/SQL-Translator.git] / lib / SQL / Translator / Parser / PostgreSQL.pm
index b3f91d7..8bb119b 100644 (file)
@@ -106,7 +106,7 @@ $::RD_HINT   = 1; # Give out hints to help fix problems.
 
 $GRAMMAR = q!
 
-{ my ( %tables, @views, $table_order, $field_order, @table_comments) }
+{ my ( %tables, @views, @triggers, $table_order, $field_order, @table_comments) }
 
 #
 # The "eofile" rule makes the parser fail if any "statement" rule
@@ -114,7 +114,13 @@ $GRAMMAR = q!
 # won't cause the failure needed to know that the parse, as a whole,
 # failed. -ky
 #
-startrule : statement(s) eofile { { tables => \%tables, views => \@views } }
+startrule : statement(s) eofile {
+    {
+        tables => \%tables,
+        views => \@views,
+        triggers => \@triggers,
+    }
+}
 
 eofile : /^\Z/
 
@@ -262,6 +268,34 @@ create : CREATE or_replace(?) temporary(?) VIEW view_id view_fields(?) /AS/i vie
         }
     }
 
+trigger_name : name_with_opt_quotes
+
+trigger_scope : /FOR/i /EACH/i /(ROW|STATEMENT)/i { $return = lc $1 }
+
+before_or_after : /(before|after)/i { $return = lc $1 }
+
+trigger_action : /.+/
+
+database_event : /insert|update|delete/i
+database_events : database_event(s /OR/)
+
+create : CREATE /TRIGGER/i trigger_name before_or_after database_events /ON/i table_id trigger_scope(?) trigger_action
+    {
+        # Hack to pass roundtrip tests which have trigger statements terminated by double semicolon
+        # and expect the returned data to have the same
+        my $action = $item{trigger_action};
+        $action =~ s/;$//;
+
+        push @triggers, {
+            name => $item{trigger_name},
+            perform_action_when => $item{before_or_after},
+            database_events => $item{database_events},
+            on_table => $item{table_id}{table_name},
+            scope => $item{'trigger_scope(?)'}[0],
+            action => $action,
+        }
+    }
+
 #
 # Create anything else (e.g., domain, etc.)
 #
@@ -493,6 +527,7 @@ double_quote: /"/
 
 index_name : name_with_opt_quotes
 
+
 data_type : pg_data_type parens_value_list(?)
     {
         my $data_type = $item[1];
@@ -1088,6 +1123,10 @@ sub parse {
       $view->extra ( temporary => 1 ) if $vinfo->{is_temporary};
     }
 
+    for my $trigger (@{ $result->{triggers} }) {
+        $schema->add_trigger( %$trigger );
+    }
+
     return 1;
 }