Handling NULLs and Empty values in PL/Perl

Perl has a very simple concept of truth: everything that is a non-empty, non-zero value is true!
It’s that simple!

The problem with PL/Perl, the PostgreSQL internal language, is that SQL provides NULL values, that somehow are equivalent to Perl undef values. But unlike Perl, in SQL an empty string or a 0 value is not NULL!
This implies that if you pass a NULL value to a PL/Perl function (or piece of code), Perl will evaluate them as undef, and this is good. The problem is that SQL values 0 and '' (empty string) will be treated by Perl as false values while they are not.
Luckily, the rule is simple: use Perl’s defined operator to see if a value is NULL in the SQL sense.
Let’s see this with a very trivial code example:

CREATE OR REPLACE FUNCTION
plperl_catch_nulls( int, text )
RETURNS VOID
AS $CODE$
   my $arg = 1;

  for ( @_ ) {
      elog(INFO, "Input argument number $arg [$_] is false (as Perl)" ) if ! $_;
      elog(INFO, "Input argument number $arg [$_] is NULL (as SQL)" ) if ! defined $_;
      elog(INFO, "Input argument number $arg is valid [$_]" ) if defined( $_ ) && $_;
      $arg++;
  }


$CODE$
LANGUAGE plperl;



Let’s try the function with a few different set of arguments:

testdb=> select plperl_catch_nulls( 19, 'Hello World!' );
INFO:  Input argument number 1 is valid [19]
INFO:  Input argument number 1 is valid [Hello World!]
 plperl_catch_nulls
--------------------

(1 row)

testdb=> select plperl_catch_nulls( 0, '' );
INFO:  Input argument number 1 [0] is false (as Perl)
INFO:  Input argument number 1 [] is false (as Perl)
 plperl_catch_nulls
--------------------

(1 row)

testdb=> select plperl_catch_nulls( NULL, NULL );
INFO:  Input argument number 1 [] is false (as Perl)
INFO:  Input argument number 1 [] is NULL (as SQL)
INFO:  Input argument number 1 [] is false (as Perl)
INFO:  Input argument number 1 [] is NULL (as SQL)
 plperl_catch_nulls
--------------------

(1 row)



As you can see, when the argument is NULL the branches false (as Perl) and NULL (as SQL) are both triggered, while not NULL values are triggered only by the defined branch.
If you like the ease of thinking of Perl, and do not want to go deep into the NULL/defined stuff, you can define your function as STRICT that makes PostgreSQL preventing the function invocation when at least one argument is NULL.

The article Handling NULLs and Empty values in PL/Perl has been posted by Luca Ferrari on January 17, 2023