From a981b0233622600754aaa287f05c685615353bc6 Mon Sep 17 00:00:00 2001 From: Peter Eisentraut Date: Sat, 6 Nov 2004 14:32:10 +0000 Subject: [PATCH] Reduce formatting entropy --- doc/src/sgml/plperl.sgml | 428 +++++++++++++++++++++++---------------- 1 file changed, 255 insertions(+), 173 deletions(-) diff --git a/doc/src/sgml/plperl.sgml b/doc/src/sgml/plperl.sgml index 7d76b4fc03..3adb8829fe 100644 --- a/doc/src/sgml/plperl.sgml +++ b/doc/src/sgml/plperl.sgml @@ -1,5 +1,5 @@ @@ -37,7 +37,6 @@ $PostgreSQL: pgsql/doc/src/sgml/plperl.sgml,v 2.29 2004/10/15 16:51:48 momjian E PL/Perl during the installation process. (Refer to for more information.) Users of binary packages might find PL/Perl in a separate subpackage. - @@ -85,22 +84,19 @@ $$ LANGUAGE plperl; - If an SQL NULL valuenull - valuein PL/Perl is - passed to a function, the argument value will appear as - undefined in Perl. The above function definition will not - behave very nicely with NULL inputs (in fact, it - will act as though they are zeroes). We could add STRICT - to the function definition to make - PostgreSQL do something more reasonable: if - a NULL value is passed, the function will not be - called at all, but will just return a NULL result - automatically. Alternatively, we could check for undefined inputs in - the function body. For example, suppose that we wanted - perl_max with one NULL and one - non-NULL argument to return the - non-NULL argument, rather than a - NULL value: + If an SQL null valuenull valuein PL/Perl is passed to a function, + the argument value will appear as undefined in Perl. The + above function definition will not behave very nicely with null + inputs (in fact, it will act as though they are zeroes). We could + add STRICT to the function definition to make + PostgreSQL do something more reasonable: + if a null value is passed, the function will not be called at all, + but will just return a null result automatically. Alternatively, + we could check for undefined inputs in the function body. For + example, suppose that we wanted perl_max with + one null and one nonnull argument to return the nonnull argument, + rather than a null value: CREATE FUNCTION perl_max (integer, integer) RETURNS integer AS $$ @@ -114,12 +110,9 @@ CREATE FUNCTION perl_max (integer, integer) RETURNS integer AS $$ return $b; $$ LANGUAGE plperl; - - - - As shown above, to return an SQL NULL value from - a PL/Perl function, return an undefined value. This can be done - whether the function is strict or not. + As shown above, to return an SQL null value from a PL/Perl + function, return an undefined value. This can be done whether the + function is strict or not. @@ -142,26 +135,23 @@ $$ LANGUAGE plperl; SELECT name, empcomp(employee) FROM employee; - - - There is now support for returning a composite-type result value. - - Database Access from PL/Perl - Access to the database itself from your Perl function can be done via - spi_exec_query, or via an experimental module spi_exec_query described + below, or via an experimental module DBD::PgSPI - (also available at CPAN - mirror sites). This module makes available a + (also available at CPAN mirror + sites). This module makes available a DBI-compliant database-handle named - $pg_dbh that can be used to perform queries - with normal DBI syntax.DBI - + $pg_dbh that can be used to perform queries with + normal DBI + syntax.DBI @@ -173,59 +163,56 @@ SELECT name, empcomp(employee) FROM employee; spi_exec_query in PL/Perl + + spi_exec_query(query [, max-rows]) + spi_exec_query(command) + + + Executes an SQL command. Here is an example of a query + (SELECT command) with the optional maximum + number of rows: + +$rv = spi_exec_query('SELECT * FROM my_table', 5); + + This returns up to 5 rows from the table + my_table. If my_table + has a column my_column, it could be accessed + like this: + +$foo = $rv->{rows}[$i]->{my_column}; + + The total number of rows returned can be accessed like this: + +$nrows = @{$rv->{rows}}; + + + + + Here is an example using a different command type: + +$query = "INSERT INTO my_table VALUES (1, 'test')"; +$rv = spi_exec_query($query); + + You can then access the command status (e.g., + SPI_OK_INSERT) like this: + +$res = $rv->{status}; + + To get the number of rows affected, do: + +$nrows = $rv->{rows}; + + + + + + elog in PL/Perl - spi_exec_query( [ SELECT query [, max_rows]] | [non-SELECT query] ) - - - Here is an example of a SELECT query with the optional maximum -number of rows. - -$rv = spi_exec_query('SELECT * from my_table', 5); - - -This returns up to 5 rows from my_table. - - -If my_table has a column my_column, it would be accessed as - -$foo = $rv->{rows}[$i]->{my_column}; - - - -The number of rows actually returned would be: - -$nrows = @{$rv->{rows}}; - - - -Here is an example using a non-SELECT statement. - -$query = "INSERT INTO my_table VALUES (1, 'test')"; -$rv = spi_exec_query($query); - - -You can then access status (SPI_OK_INSERT, e.g.) like this. - -$res = $rv->{status}; - - - - -To get the rows affected, do: - -$nrows = $rv->{rows}; - - - - - - - - elog level, msg + elog(level, msg) Emit a log or error message. Possible levels are @@ -255,102 +242,94 @@ $nrows = $rv->{rows}; - PL/Perl can now return rowsets and composite types, and rowsets of -composite types. - - - - Here is an example of a PL/Perl function returning a rowset of a - row type. Note that a composite type is always represented as a - hash reference. + PL/Perl can also return row sets and composite types, and row sets + of composite types. Here is an example of a PL/Perl function + returning a row set of a row type. Note that a composite type is + always represented as a hash reference. CREATE TABLE test ( - i int, - v varchar + i int, + v varchar ); -INSERT INTO test (i, v) VALUES (1,'first line'); -INSERT INTO test (i, v) VALUES (2,'second line'); -INSERT INTO test (i, v) VALUES (3,'third line'); -INSERT INTO test (i, v) VALUES (4,'immortal'); +INSERT INTO test (i, v) VALUES (1, 'first line'); +INSERT INTO test (i, v) VALUES (2, 'second line'); +INSERT INTO test (i, v) VALUES (3, 'third line'); +INSERT INTO test (i, v) VALUES (4, 'immortal'); -create function test_munge() returns setof test language plperl as $$ +CREATE FUNCTION test_munge() RETURNS SETOF test AS $$ my $res = []; - my $rv = spi_exec_query('select i,v from test;'); + my $rv = spi_exec_query('select i, v from test;'); my $status = $rv->{status}; my $rows = @{$rv->{rows}}; my $processed = $rv->{processed}; - foreach my $rn (0..$rows-1) { + foreach my $rn (0 .. $rows - 1) { my $row = $rv->{rows}[$rn]; $row->{i} += 200 if defined($row->{i}); $row->{v} =~ tr/A-Za-z/a-zA-Z/ if (defined($row->{v})); - push @$res,$row; + push @$res, $row; } return $res; -$$; +$$ LANGUAGE plperl; -select * from test_munge(); +SELECT * FROM test_munge(); - Here is an example of a PL/Perl function returning a composite type: - + Here is an example of a PL/Perl function returning a composite + type: + CREATE TYPE testrowperl AS (f1 integer, f2 text, f3 text); CREATE OR REPLACE FUNCTION perl_row() RETURNS testrowperl AS $$ - - return {f2 => 'hello', f1 => 1, f3 => 'world'}; - + return {f2 => 'hello', f1 => 1, f3 => 'world'}; $$ LANGUAGE plperl; - + - Here is an example of a PL/Perl function returning a rowset of a -composite type. As a rowset is always a reference to an array -and a composite type is always a reference to a hash, a rowset of a -composite type is a reference to an array of hash references. - + Here is an example of a PL/Perl function returning a row set of a + composite type. Since a row set is always a reference to an array + and a composite type is always a reference to a hash, a rowset of a + composite type is a reference to an array of hash references. + CREATE TYPE testsetperl AS (f1 integer, f2 text, f3 text); CREATE OR REPLACE FUNCTION perl_set() RETURNS SETOF testsetperl AS $$ - return[ - {f1 => 1, f2 => 'hello', f3 => 'world'}, - {f1 => 2, f2 => 'hello', f3 => 'postgres'}, - {f1 => 3, f2 => 'hello', f3 => 'plperl'} - ]; + return [ + { f1 => 1, f2 => 'Hello', f3 => 'World' }, + { f1 => 2, f2 => 'Hello', f3 => 'PostgreSQL' }, + { f1 => 3, f2 => 'Hello', f3 => 'PL/Perl' } + ]; $$ LANGUAGE plperl; + Global Values in PL/Perl + - You can use the %_SHARED to store data between function calls. - - -For example: + You can use the global hash %_SHARED to store + data between function calls. For example: -CREATE OR REPLACE FUNCTION set_var(name TEXT, val TEXT) RETURNS TEXT AS $$ +CREATE OR REPLACE FUNCTION set_var(name text, val text) RETURNS text AS $$ if ($_SHARED{$_[0]} = $_[1]) { return 'ok'; } else { - return "Can't set shared variable $_[0] to $_[1]"; + return "can't set shared variable $_[0] to $_[1]"; } $$ LANGUAGE plperl; -CREATE OR REPLACE FUNCTION get_var(name TEXT) RETURNS text AS $$ +CREATE OR REPLACE FUNCTION get_var(name text) RETURNS text AS $$ return $_SHARED{$_[0]}; $$ LANGUAGE plperl; -SELECT set_var('sample', $q$Hello, PL/Perl! How's tricks?$q$); +SELECT set_var('sample', 'Hello, PL/Perl! How's tricks?'); SELECT get_var('sample'); - - - @@ -413,63 +392,166 @@ $$ LANGUAGE plperl; plperlu, execution would succeed. + PL/Perl Triggers - PL/Perl can now be used to write trigger functions using the -$_TD hash reference. - + PL/Perl can be used to write trigger functions. The global hash + reference $_TD contains information about the + current trigger event. The parts of $_TD hash + reference are: - - Some useful parts of the $_TD hash reference are: + + + $_TD->{new}{foo} + + + NEW value of column foo + + + - -$_TD->{new}{foo} # NEW value of column foo -$_TD->{old}{bar} # OLD value of column bar -$_TD{name} # Name of the trigger being called -$_TD{event} # INSERT, UPDATE, DELETE or UNKNOWN -$_TD{when} # BEFORE, AFTER or UNKNOWN -$_TD{level} # ROW, STATEMENT or UNKNOWN -$_TD{relid} # Relation ID of the table on which the trigger occurred. -$_TD{relname} # Name of the table on which the trigger occurred. -@{$_TD{argv}} # Array of arguments to the trigger function. May be empty. -$_TD{argc} # Number of arguments to the trigger. Why is this here? - + + $_TD->{old}{foo} + + + OLD value of column foo + + + + + $_TD{name} + + + Name of the trigger being called + + + + + + $_TD{event} + + + Trigger event: INSERT, UPDATE, DELETE, or UNKNOWN + + + + + + $_TD{when} + + + When the trigger was called: BEFORE, AFTER, or UNKNOWN + + + + + + $_TD{level} + + + The trigger level: ROW, STATEMENT, or UNKNOWN + + + + + + $_TD{relid} + + + OID of the table on which the trigger fired + + + + + + $_TD{relname} + + + Name of the table on which the trigger fired + + + + + + @{$_TD{argv}} + + + Arguments of the trigger function + + + + + + $_TD{argc} + + + Number of arguments of the trigger functions + + + + Triggers can return one of the following: - -return; -- Executes the statement -SKIP; -- Doesn't execute the statement -MODIFY; -- Says it modified a NEW row - + + + + return; + + + Execute the statement + + + + + + "SKIP" + + + Don't execute the statement + + + + + + "MODIFY" + + + Indicates that the NEW rows was modified by + the trigger function + + + + -Here is an example of a trigger function, illustrating some of the -above. + Here is an example of a trigger function, illustrating some of the + above: CREATE TABLE test ( - i int, - v varchar + i int, + v varchar ); CREATE OR REPLACE FUNCTION valid_id() RETURNS trigger AS $$ - if (($_TD->{new}{i}>=100) || ($_TD->{new}{i}<=0)) { - return "SKIP"; # Skip INSERT/UPDATE command + 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)"; - return "MODIFY"; # Modify tuple and proceed INSERT/UPDATE command + return "MODIFY"; # modify row and execute INSERT/UPDATE command } else { - return; # Proceed INSERT/UPDATE command + return; # execute INSERT/UPDATE command } $$ LANGUAGE plperl; -CREATE TRIGGER "test_valid_id_trig" BEFORE INSERT OR UPDATE ON test -FOR EACH ROW EXECUTE PROCEDURE "valid_id"(); +CREATE TRIGGER test_valid_id_trig + BEFORE INSERT OR UPDATE ON test + FOR EACH ROW EXECUTE PROCEDURE valid_id(); @@ -491,19 +573,19 @@ FOR EACH ROW EXECUTE PROCEDURE "valid_id"(); - Full SPI is not yet implemented. + SPI is not yet fully implemented. - - - In the current implementation, if you are fetching or - returning very large datasets, you should be aware that these - will all go into memory. Future features will help with this. - In the meantime, we suggest that you not use pl/perl if you - will fetch or return very large result sets. - - + + + In the current implementation, if you are fetching or returning + very large data sets, you should be aware that these will all go + into memory. Future features will help with this. In the + meantime, we suggest that you not use PL/Perl if you will fetch + or return very large result sets. + +