This document summarizes new features in PL/Perl for PostgreSQL 9.0. It introduces new built-in functions for quoting, encoding bytea, and checking if a value looks like a number. It describes improved support for arrays, trusted modules, and executing arbitrary Perl code using DO. The document also covers internal changes like removing the Safe module, new configuration options, and integration with the NYTProf profiler.
11. Trusted require/use
• require/use work for already loaded modules
use strict; # old way: BEGIN { strict->import(); }
• extra pre-loaded modules
use warnings;
use Carp;
use feature qw(say); # for perl 5.10 or later
use utf8; # if server_encoding is utf8
12. CONTEXT: ...
• PL/Perl tracks the context of log messages
- before:
WARNING: ...some warning from perl code...
- now:
WARNING: ...some warning from perl code...
CONTEXT: PL/Perl function "..."
13. DO '...' LANGUAGE plperl;
• Arbitrary chunks of perl code can be executed
directly from psql, or client apps, via DO
• No need to create and run a stored procedure
each time.
DO $$
spi_exec("... $_ ...") for 'a'..'z';
$$ language plperl;
14. Other Changes
• Using $a and $b in sort blocks now works!
• eval { ... } and eval "..."
- can now be used in plperl
• END blocks are now run at end of session
- they can't (currently) access the database
• Warnings from perl are now WARNINGs
- they used to be NOTICE
16. INTERNAL
• The Safe module is no longer used for plperl
- Improved security and reduced call overheads
- Upgrade to latest security patch!
• Validates return values are in server encoding
- ERROR: invalid byte sequence for encoding
• Internal code refactoring and cleanup
18. New plperl.* Config
• Specify perl code to run during initialization:
plperl.on_init = '...perl...'
plperl.on_plperlu_init = '...perl...'
plperl.on_plperl_init = '...perl...'
• Can only be set by superuser or postgres.conf
• Code can't access the database
19. ~ Timeline ~
▾ Perl interpreter created on demand
▿ Options from PERL5OPT env var are processed
▿ PL/Perl support code bootstraps
▿ plperl.on_init code runs
Above may happen in postmaster at startup if
plperl is loaded via shared_preload_libraries
▾ Interpreter is specialised for plperl (or plperlu)
▿ Modules loaded: strict, warnings, features, Carp
▿ Perl operators are restricted (require, open etc.)
▿ DynaLoader package is deleted
▿ plperl.on_plperl_init code runs
▿ Database access is enabled
20. plperl.on_init
• Handy to set global perl configuation
plperl.on_init='use lib qw(/myapp); use ...;'
plperl.on_init='require "plperloninit.pl";'
• SECURITY RISK!
Only load modules you're happy for plperl code to use!
Also check any other modules loaded as dependencies!
Use Devel::TraceLoad to see what's actually loaded:
PERL5OPT='-MDevel::Trace=summary' pg_ctl ...
21. PL/Perl Best Practice
• Include explicit use statements in functions
• Don't assume modules have been pre-loaded
• For plperlu that'll actually load if needed
• For plperl it'll check that module was loaded
- so you'll get an immediate clear failure if not
- for example on a replica with old postgres.conf file
22. plperl.on_plperl_init
• Originally intended for things like
- PGOPTIONS="-c plperl.on_plperl_init='...'"
- to enable debug or profiling for a session
• But...
• Can only be set by superuser or postgres.conf
- sadly, due to SECURITY DEFINER risks.
- You shouldn't write SECURITY DEFINER
functions in plperl if untrusted users can use plperl!
25. Enabling NYTProf
• Via postgres.conf:
plperl.on_init='use PostgreSQL::PLPerl::NYTProf'
• Via environment variable:
PERL5OPT='-MPostgreSQL::PLPerl::NYTProf' pg_ctl ...
• Immediately active. To enable on demand:
NYTPROF=start=no PERL5OPT=... pg_ctl ...
DO 'DB::enable_profile' LANGUAGE plperl;
26. Reporting from NYTProf
• Writes per-backend data files:
$PGDATA/nytprof.out.$pid
• To generate a report:
nytprofhtml --file=$PGDATA/nytprof.out.4321 --open