-- Create the extension CREATE EXTENSION plperlu; -- define how the table row returned by the perl function looks like CREATE TYPE poemrow AS ( poemrowid bigint, verserowid bigint, verseline text ); -- Automatic poem generator CREATE OR REPLACE FUNCTION bottlesofbeer(bigint) RETURNS SETOF poemrow AS $$ my ($bottlecount) = @_; if($bottlecount < 0) { $bottlecount = 0; }; my $rowid = 0; my @verselines = ( 'COUNT bottles of beer on the wall, COUNT bottles of beer.', 'Take one down, pass it around!', 'REDUCED bottles of beer on the wall', '' ); my $vcount; while($bottlecount) { my $nextcount = $bottlecount - 1; $vcount = 1; foreach my $rawline (@verselines) { my $line = '' . $rawline; # COPY the line $line =~ s/COUNT/$bottlecount/g; $line =~ s/REDUCED/$nextcount/g; return_next({poemrowid => $rowid, verserowid => $vcount, verseline => $line }); $vcount++; $rowid++; } $bottlecount--; } return_next({poemrowid => $rowid, verserowid => $vcount, verseline => 'No more beer, buy some more!' }); return undef; # We are done here $$ LANGUAGE plperlu; #### ER_DEV_DB=# SELECT * FROM bottlesofbeer(3); poemrowid | verserowid | verseline -----------+------------+--------------------------------------------------- 0 | 1 | 3 bottles of beer on the wall, 3 bottles of beer. 1 | 2 | Take one down, pass it around! 2 | 3 | 2 bottles of beer on the wall 3 | 4 | 4 | 1 | 2 bottles of beer on the wall, 2 bottles of beer. 5 | 2 | Take one down, pass it around! 6 | 3 | 1 bottles of beer on the wall 7 | 4 | 8 | 1 | 1 bottles of beer on the wall, 1 bottles of beer. 9 | 2 | Take one down, pass it around! 10 | 3 | 0 bottles of beer on the wall 11 | 4 | 12 | 5 | No more beer, buy some more! (13 rows) ER_DEV_DB=# SELECT verseline FROM bottlesofbeer(8) WHERE verserowid = 3 ORDER BY poemrowid DESC; verseline ------------------------------- 0 bottles of beer on the wall 1 bottles of beer on the wall 2 bottles of beer on the wall 3 bottles of beer on the wall 4 bottles of beer on the wall 5 bottles of beer on the wall 6 bottles of beer on the wall 7 bottles of beer on the wall (8 rows) #### -- Create a perl trigger function in database schema "pos" CREATE OR REPLACE FUNCTION pos.customersinserttrigger() RETURNS trigger AS $$ use strict; if(defined($_TD->{new}->{'customer_number'}) && $_TD->{new}->{'customer_number'} ne '') { return; } my $selsth = spi_prepare("SELECT max(customer_number) AS max_customer_number FROM pos.customers WHERE customer_number IS NOT NULL"); my $nextnum = 1_000_000; my @lines; { my $retval = spi_exec_prepared($selsth); if($retval->{status} ne 'SPI_OK_SELECT') { elog(ERROR, "Failed to select all rows in pos.customers"); } if($retval->{processed}) { @lines = @{$retval->{rows}}; } spi_freeplan $selsth; } foreach my $line (@lines) { my $tmp = $line->{max_customer_number}; $tmp = 0 + $tmp; if($tmp > $nextnum) { $nextnum = $tmp; } } $nextnum++; $_TD->{new}->{'customer_number'} = $nextnum; return "MODIFY"; # EXECUTE, all updates sucessfull $$ LANGUAGE plperlu; -- Add a trigger to table "customers" in schema "pos" to call our trigger function on every inserted or updated row CREATE TRIGGER insertupdate_customers_trigger BEFORE INSERT OR UPDATE ON pos.customers FOR EACH ROW EXECUTE FUNCTION pos.customersinserttrigger();