Eine aufbereitete Darstellung der Quelle

 
     
 
 
Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 

Benutzer

Quelle  plperl_trigger.out   Sprache: unbekannt

 
Spracherkennung für: .out vermutete Sprache: Unknown {[0] [0] [0]} [Methode: Schwerpunktbildung, einfache Gewichte, sechs Dimensionen]

-- test plperl triggers
CREATE TYPE rowcomp as (i int);
CREATE TYPE rowcompnest as (rfoo rowcomp);
CREATE TABLE trigger_test (
        i int,
        v varchar,
  foo rowcompnest
);
CREATE TABLE trigger_test_generated (
    i int,
    j int GENERATED ALWAYS AS (i * 2) STORED,
    k int GENERATED ALWAYS AS (i * 3) VIRTUAL
);
CREATE OR REPLACE FUNCTION trigger_data() RETURNS trigger LANGUAGE plperl AS $$

  # make sure keys are sorted for consistent results - perl no longer
  # hashes in  repeatable fashion across runs

  sub str {
   my $val = shift;

   if (!defined $val)
   {
    return 'NULL';
   }
   elsif (ref $val eq 'HASH')
   {
  my $str = '';
  foreach my $rowkey (sort keys %$val)
  {
    $str .= ", " if $str;
    my $rowval = str($val->{$rowkey});
    $str .= "'$rowkey' => $rowval";
  }
  return '{'. $str .'}';
   }
   elsif (ref $val eq 'ARRAY')
   {
    my $str = '';
    for my $argval (@$val)
    {
     $str .= ", " if $str;
     $str .= str($argval);
    }
    return '['. $str .']';
   }
   else
   {
    return "'$val'";
   }
  }

  foreach my $key (sort keys %$_TD)
  {

    my $val = $_TD->{$key};

 # relid is variable, so we can not use it repeatably
 $val = "bogus:12345" if $key eq 'relid';

 elog(NOTICE, "\$_TD->\{$key\} = ". str($val));
  }
  return undef; # allow statement to proceed;
$$;
CREATE TRIGGER show_trigger_data_trig
BEFORE INSERT OR UPDATE OR DELETE ON trigger_test
FOR EACH ROW EXECUTE PROCEDURE trigger_data(23,'skidoo');
insert into trigger_test values(1,'insert', '("(1)")');
NOTICE:  $_TD->{argc} = '2'
NOTICE:  $_TD->{args} = ['23', 'skidoo']
NOTICE:  $_TD->{event} = 'INSERT'
NOTICE:  $_TD->{level} = 'ROW'
NOTICE:  $_TD->{name} = 'show_trigger_data_trig'
NOTICE:  $_TD->{new} = {'foo' => {'rfoo' => {'i' => '1'}}, 'i' => '1', 'v' => 'insert'}
NOTICE:  $_TD->{relid} = 'bogus:12345'
NOTICE:  $_TD->{relname} = 'trigger_test'
NOTICE:  $_TD->{table_name} = 'trigger_test'
NOTICE:  $_TD->{table_schema} = 'public'
NOTICE:  $_TD->{when} = 'BEFORE'
update trigger_test set v = 'update' where i = 1;
NOTICE:  $_TD->{argc} = '2'
NOTICE:  $_TD->{args} = ['23', 'skidoo']
NOTICE:  $_TD->{event} = 'UPDATE'
NOTICE:  $_TD->{level} = 'ROW'
NOTICE:  $_TD->{name} = 'show_trigger_data_trig'
NOTICE:  $_TD->{new} = {'foo' => {'rfoo' => {'i' => '1'}}, 'i' => '1', 'v' => 'update'}
NOTICE:  $_TD->{old} = {'foo' => {'rfoo' => {'i' => '1'}}, 'i' => '1', 'v' => 'insert'}
NOTICE:  $_TD->{relid} = 'bogus:12345'
NOTICE:  $_TD->{relname} = 'trigger_test'
NOTICE:  $_TD->{table_name} = 'trigger_test'
NOTICE:  $_TD->{table_schema} = 'public'
NOTICE:  $_TD->{when} = 'BEFORE'
delete from trigger_test;
NOTICE:  $_TD->{argc} = '2'
NOTICE:  $_TD->{args} = ['23', 'skidoo']
NOTICE:  $_TD->{event} = 'DELETE'
NOTICE:  $_TD->{level} = 'ROW'
NOTICE:  $_TD->{name} = 'show_trigger_data_trig'
NOTICE:  $_TD->{old} = {'foo' => {'rfoo' => {'i' => '1'}}, 'i' => '1', 'v' => 'update'}
NOTICE:  $_TD->{relid} = 'bogus:12345'
NOTICE:  $_TD->{relname} = 'trigger_test'
NOTICE:  $_TD->{table_name} = 'trigger_test'
NOTICE:  $_TD->{table_schema} = 'public'
NOTICE:  $_TD->{when} = 'BEFORE'
DROP TRIGGER show_trigger_data_trig on trigger_test;
CREATE TRIGGER show_trigger_data_trig_before
BEFORE INSERT OR UPDATE OR DELETE ON trigger_test_generated
FOR EACH ROW EXECUTE PROCEDURE trigger_data();
CREATE TRIGGER show_trigger_data_trig_after
AFTER INSERT OR UPDATE OR DELETE ON trigger_test_generated
FOR EACH ROW EXECUTE PROCEDURE trigger_data();
insert into trigger_test_generated (i) values (1);
NOTICE:  $_TD->{argc} = '0'
NOTICE:  $_TD->{event} = 'INSERT'
NOTICE:  $_TD->{level} = 'ROW'
NOTICE:  $_TD->{name} = 'show_trigger_data_trig_before'
NOTICE:  $_TD->{new} = {'i' => '1'}
NOTICE:  $_TD->{relid} = 'bogus:12345'
NOTICE:  $_TD->{relname} = 'trigger_test_generated'
NOTICE:  $_TD->{table_name} = 'trigger_test_generated'
NOTICE:  $_TD->{table_schema} = 'public'
NOTICE:  $_TD->{when} = 'BEFORE'
NOTICE:  $_TD->{argc} = '0'
NOTICE:  $_TD->{event} = 'INSERT'
NOTICE:  $_TD->{level} = 'ROW'
NOTICE:  $_TD->{name} = 'show_trigger_data_trig_after'
NOTICE:  $_TD->{new} = {'i' => '1', 'j' => '2'}
NOTICE:  $_TD->{relid} = 'bogus:12345'
NOTICE:  $_TD->{relname} = 'trigger_test_generated'
NOTICE:  $_TD->{table_name} = 'trigger_test_generated'
NOTICE:  $_TD->{table_schema} = 'public'
NOTICE:  $_TD->{when} = 'AFTER'
update trigger_test_generated set i = 11 where i = 1;
NOTICE:  $_TD->{argc} = '0'
NOTICE:  $_TD->{event} = 'UPDATE'
NOTICE:  $_TD->{level} = 'ROW'
NOTICE:  $_TD->{name} = 'show_trigger_data_trig_before'
NOTICE:  $_TD->{new} = {'i' => '11'}
NOTICE:  $_TD->{old} = {'i' => '1', 'j' => '2'}
NOTICE:  $_TD->{relid} = 'bogus:12345'
NOTICE:  $_TD->{relname} = 'trigger_test_generated'
NOTICE:  $_TD->{table_name} = 'trigger_test_generated'
NOTICE:  $_TD->{table_schema} = 'public'
NOTICE:  $_TD->{when} = 'BEFORE'
NOTICE:  $_TD->{argc} = '0'
NOTICE:  $_TD->{event} = 'UPDATE'
NOTICE:  $_TD->{level} = 'ROW'
NOTICE:  $_TD->{name} = 'show_trigger_data_trig_after'
NOTICE:  $_TD->{new} = {'i' => '11', 'j' => '22'}
NOTICE:  $_TD->{old} = {'i' => '1', 'j' => '2'}
NOTICE:  $_TD->{relid} = 'bogus:12345'
NOTICE:  $_TD->{relname} = 'trigger_test_generated'
NOTICE:  $_TD->{table_name} = 'trigger_test_generated'
NOTICE:  $_TD->{table_schema} = 'public'
NOTICE:  $_TD->{when} = 'AFTER'
delete from trigger_test_generated;
NOTICE:  $_TD->{argc} = '0'
NOTICE:  $_TD->{event} = 'DELETE'
NOTICE:  $_TD->{level} = 'ROW'
NOTICE:  $_TD->{name} = 'show_trigger_data_trig_before'
NOTICE:  $_TD->{old} = {'i' => '11', 'j' => '22'}
NOTICE:  $_TD->{relid} = 'bogus:12345'
NOTICE:  $_TD->{relname} = 'trigger_test_generated'
NOTICE:  $_TD->{table_name} = 'trigger_test_generated'
NOTICE:  $_TD->{table_schema} = 'public'
NOTICE:  $_TD->{when} = 'BEFORE'
NOTICE:  $_TD->{argc} = '0'
NOTICE:  $_TD->{event} = 'DELETE'
NOTICE:  $_TD->{level} = 'ROW'
NOTICE:  $_TD->{name} = 'show_trigger_data_trig_after'
NOTICE:  $_TD->{old} = {'i' => '11', 'j' => '22'}
NOTICE:  $_TD->{relid} = 'bogus:12345'
NOTICE:  $_TD->{relname} = 'trigger_test_generated'
NOTICE:  $_TD->{table_name} = 'trigger_test_generated'
NOTICE:  $_TD->{table_schema} = 'public'
NOTICE:  $_TD->{when} = 'AFTER'
DROP TRIGGER show_trigger_data_trig_before ON trigger_test_generated;
DROP TRIGGER show_trigger_data_trig_after ON trigger_test_generated;
insert into trigger_test values(1,'insert', '("(1)")');
CREATE VIEW trigger_test_view AS SELECT * FROM trigger_test;
CREATE TRIGGER show_trigger_data_trig
INSTEAD OF INSERT OR UPDATE OR DELETE ON trigger_test_view
FOR EACH ROW EXECUTE PROCEDURE trigger_data(24,'skidoo view');
insert into trigger_test_view values(2,'insert', '("(2)")');
NOTICE:  $_TD->{argc} = '2'
NOTICE:  $_TD->{args} = ['24', 'skidoo view']
NOTICE:  $_TD->{event} = 'INSERT'
NOTICE:  $_TD->{level} = 'ROW'
NOTICE:  $_TD->{name} = 'show_trigger_data_trig'
NOTICE:  $_TD->{new} = {'foo' => {'rfoo' => {'i' => '2'}}, 'i' => '2', 'v' => 'insert'}
NOTICE:  $_TD->{relid} = 'bogus:12345'
NOTICE:  $_TD->{relname} = 'trigger_test_view'
NOTICE:  $_TD->{table_name} = 'trigger_test_view'
NOTICE:  $_TD->{table_schema} = 'public'
NOTICE:  $_TD->{when} = 'INSTEAD OF'
update trigger_test_view set v = 'update', foo = '("(3)")' where i = 1;
NOTICE:  $_TD->{argc} = '2'
NOTICE:  $_TD->{args} = ['24', 'skidoo view']
NOTICE:  $_TD->{event} = 'UPDATE'
NOTICE:  $_TD->{level} = 'ROW'
NOTICE:  $_TD->{name} = 'show_trigger_data_trig'
NOTICE:  $_TD->{new} = {'foo' => {'rfoo' => {'i' => '3'}}, 'i' => '1', 'v' => 'update'}
NOTICE:  $_TD->{old} = {'foo' => {'rfoo' => {'i' => '1'}}, 'i' => '1', 'v' => 'insert'}
NOTICE:  $_TD->{relid} = 'bogus:12345'
NOTICE:  $_TD->{relname} = 'trigger_test_view'
NOTICE:  $_TD->{table_name} = 'trigger_test_view'
NOTICE:  $_TD->{table_schema} = 'public'
NOTICE:  $_TD->{when} = 'INSTEAD OF'
delete from trigger_test_view;
NOTICE:  $_TD->{argc} = '2'
NOTICE:  $_TD->{args} = ['24', 'skidoo view']
NOTICE:  $_TD->{event} = 'DELETE'
NOTICE:  $_TD->{level} = 'ROW'
NOTICE:  $_TD->{name} = 'show_trigger_data_trig'
NOTICE:  $_TD->{old} = {'foo' => {'rfoo' => {'i' => '1'}}, 'i' => '1', 'v' => 'insert'}
NOTICE:  $_TD->{relid} = 'bogus:12345'
NOTICE:  $_TD->{relname} = 'trigger_test_view'
NOTICE:  $_TD->{table_name} = 'trigger_test_view'
NOTICE:  $_TD->{table_schema} = 'public'
NOTICE:  $_TD->{when} = 'INSTEAD OF'
DROP VIEW trigger_test_view;
delete from trigger_test;
DROP FUNCTION trigger_data();
CREATE OR REPLACE FUNCTION valid_id() RETURNS trigger AS $$

    if (($_TD->{new}{i}>=100) || ($_TD->{new}{i}<=0))
    {
        return "SKIP";   # Skip INSERT/UPDATE command
    }
    elsif ($_TD->{new}{v} ne "immortal")
    {
        $_TD->{new}{v} .= "(modified by trigger)";
  $_TD->{new}{foo}{rfoo}{i}++;
        return "MODIFY"; # Modify tuple and proceed INSERT/UPDATE command
    }
    else
    {
        return;          # Proceed INSERT/UPDATE command
    }
$$ LANGUAGE plperl;
CREATE TRIGGER "test_valid_id_trig" BEFORE INSERT OR UPDATE ON trigger_test
FOR EACH ROW EXECUTE PROCEDURE "valid_id"();
INSERT INTO trigger_test (i, v, foo) VALUES (1,'first line', '("(1)")');
INSERT INTO trigger_test (i, v, foo) VALUES (2,'second line', '("(2)")');
INSERT INTO trigger_test (i, v, foo) VALUES (3,'third line', '("(3)")');
INSERT INTO trigger_test (i, v, foo) VALUES (4,'immortal', '("(4)")');
INSERT INTO trigger_test (i, v) VALUES (101,'bad id');
SELECT * FROM trigger_test;
 i |                v                 |   foo   
---+----------------------------------+---------
 1 | first line(modified by trigger)  | ("(2)")
 2 | second line(modified by trigger) | ("(3)")
 3 | third line(modified by trigger)  | ("(4)")
 4 | immortal                         | ("(4)")
(4 rows)

UPDATE trigger_test SET i = 5 where i=3;
UPDATE trigger_test SET i = 100 where i=1;
SELECT * FROM trigger_test;
 i |                          v                           |   foo   
---+------------------------------------------------------+---------
 1 | first line(modified by trigger)                      | ("(2)")
 2 | second line(modified by trigger)                     | ("(3)")
 4 | immortal                                             | ("(4)")
 5 | third line(modified by trigger)(modified by trigger) | ("(5)")
(4 rows)

DROP TRIGGER "test_valid_id_trig" ON trigger_test;
CREATE OR REPLACE FUNCTION trigger_recurse() RETURNS trigger AS $$
 use strict;

 if ($_TD->{new}{i} == 10000)
 {
  spi_exec_query("insert into trigger_test (i, v) values (20000, 'child');");

  if ($_TD->{new}{i} != 10000)
  {
   die "recursive trigger modified: ". $_TD->{new}{i};
  }
 }
    return;
$$ LANGUAGE plperl;
CREATE TRIGGER "test_trigger_recurse" BEFORE INSERT ON trigger_test
FOR EACH ROW EXECUTE PROCEDURE "trigger_recurse"();
INSERT INTO trigger_test (i, v) values (10000, 'top');
SELECT * FROM trigger_test;
   i   |                          v                           |   foo   
-------+------------------------------------------------------+---------
     1 | first line(modified by trigger)                      | ("(2)")
     2 | second line(modified by trigger)                     | ("(3)")
     4 | immortal                                             | ("(4)")
     5 | third line(modified by trigger)(modified by trigger) | ("(5)")
 20000 | child                                                | 
 10000 | top                                                  | 
(6 rows)

CREATE OR REPLACE FUNCTION immortal() RETURNS trigger AS $$
    if ($_TD->{old}{v} eq $_TD->{args}[0])
    {
        return "SKIP"; # Skip DELETE command
    }
    else
    {
        return;        # Proceed DELETE command
    };
$$ LANGUAGE plperl;
CREATE TRIGGER "immortal_trig" BEFORE DELETE ON trigger_test
FOR EACH ROW EXECUTE PROCEDURE immortal('immortal');
DELETE FROM trigger_test;
SELECT * FROM trigger_test;
 i |    v     |   foo   
---+----------+---------
 4 | immortal | ("(4)")
(1 row)

CREATE FUNCTION direct_trigger() RETURNS trigger AS $$
    return;
$$ LANGUAGE plperl;
SELECT direct_trigger();
ERROR:  trigger functions can only be called as triggers
CONTEXT:  compilation of PL/Perl function "direct_trigger"
-- check that SQL run in trigger code can see transition tables
CREATE TABLE transition_table_test (id int, name text);
INSERT INTO transition_table_test VALUES (1, 'a');
CREATE FUNCTION transition_table_test_f() RETURNS trigger LANGUAGE plperl AS
$$
    my $cursor = spi_query("SELECT * FROM old_table");
    my $row = spi_fetchrow($cursor);
    defined($row) || die "expected a row";
    elog(INFO, "old: " . $row->{id} . " -> " . $row->{name});
    my $row = spi_fetchrow($cursor);
    !defined($row) || die "expected no more rows";

    my $cursor = spi_query("SELECT * FROM new_table");
    my $row = spi_fetchrow($cursor);
    defined($row) || die "expected a row";
    elog(INFO, "new: " . $row->{id} . " -> " . $row->{name});
    my $row = spi_fetchrow($cursor);
    !defined($row) || die "expected no more rows";

    return undef;
$$;
CREATE TRIGGER a_t AFTER UPDATE ON transition_table_test
  REFERENCING OLD TABLE AS old_table NEW TABLE AS new_table
  FOR EACH STATEMENT EXECUTE PROCEDURE transition_table_test_f();
UPDATE transition_table_test SET name = 'b';
INFO:  old: 1 -> a
INFO:  new: 1 -> b
DROP TABLE transition_table_test;
DROP FUNCTION transition_table_test_f();
-- test plperl command triggers
create or replace function perlsnitch() returns event_trigger language plperl as $$
  elog(NOTICE, "perlsnitch: " . $_TD->{event} . " " . $_TD->{tag} . " ");
$$;
create event trigger perl_a_snitch on ddl_command_start
   execute procedure perlsnitch();
create event trigger perl_b_snitch on ddl_command_end
   execute procedure perlsnitch();
create or replace function foobar() returns int language sql as $$select 1;$$;
NOTICE:  perlsnitch: ddl_command_start CREATE FUNCTION 
NOTICE:  perlsnitch: ddl_command_end CREATE FUNCTION 
alter function foobar() cost 77;
NOTICE:  perlsnitch: ddl_command_start ALTER FUNCTION 
NOTICE:  perlsnitch: ddl_command_end ALTER FUNCTION 
drop function foobar();
NOTICE:  perlsnitch: ddl_command_start DROP FUNCTION 
NOTICE:  perlsnitch: ddl_command_end DROP FUNCTION 
create table foo();
NOTICE:  perlsnitch: ddl_command_start CREATE TABLE 
NOTICE:  perlsnitch: ddl_command_end CREATE TABLE 
drop table foo;
NOTICE:  perlsnitch: ddl_command_start DROP TABLE 
NOTICE:  perlsnitch: ddl_command_end DROP TABLE 
drop event trigger perl_a_snitch;
drop event trigger perl_b_snitch;
-- dealing with generated columns
CREATE FUNCTION generated_test_func1() RETURNS trigger
LANGUAGE plperl
AS $$
$_TD->{new}{j} = 5;  # not allowed
return 'MODIFY';
$$;
CREATE TRIGGER generated_test_trigger1 BEFORE INSERT ON trigger_test_generated
FOR EACH ROW EXECUTE PROCEDURE generated_test_func1();
TRUNCATE trigger_test_generated;
INSERT INTO trigger_test_generated (i) VALUES (1);
ERROR:  cannot set generated column "j"
CONTEXT:  PL/Perl function "generated_test_func1"
SELECT * FROM trigger_test_generated;
 i | j | k 
---+---+---
(0 rows)


[Dauer der Verarbeitung: 0.29 Sekunden, vorverarbeitet 2026-08-08]

                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Open Source Software

     Quellcodebibliothek
     Eigene Quellcodes
     Fremde Quellcodes
     Suchen

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Statistik
#Sources=277311
#Domains=752002