Re: BUG #13638: Exception texts from plperl has bad encoding - Mailing list pgsql-bugs

From Alex Hunsaker
Subject Re: BUG #13638: Exception texts from plperl has bad encoding
Date
Msg-id CAFaPBrR-yd0fFAh+tNQ=NQ_HW=xMsbZgS8dnRjF6x6FtnSTJTQ@mail.gmail.com
Whole thread Raw
In response to Re: BUG #13638: Exception texts from plperl has bad encoding  (Tom Lane <tgl@sss.pgh.pa.us>)
Responses Re: BUG #13638: Exception texts from plperl has bad encoding  (Tom Lane <tgl@sss.pgh.pa.us>)
List pgsql-bugs


On Sun, Sep 27, 2015 at 5:46 PM, Tom Lane <tgl@sss.pgh.pa.us> wrote:
Tim Bunce <Tim.Bunce@pobox.com> writes:
> I think you want to call croak_sv(SV) with an SV containing the error
> message and flagged as UTF-8.

I found croak_sv() in the headers for Perl 5.18 (present on OS X Yosemite)
but not in Perl 5.10 (present on RHEL6), much less 5.8 which is the oldest
Perl version we claim to support.  This doesn't look like a workable
answer unless we want to move the compatibility goalposts a long way.

Yeah, I was just looking at that. I couldn't find a good way to support 5.8. Doing:

const char *utf8_str = utf_e2u(str);
SV *sv = get_sv("@", TRUE);
sv_setpvf(sv, "%s", utf8_str);
SvUTF8_on(sv); 
croak(NULL);

Works, but screws up the error line numbers. For example, given the below test in plperl.out:

--
-- Test with a bad type
--
CREATE OR REPLACE FUNCTION perl_spi_prepared_bad(double precision) RETURNS double precision AS $$
  my $x = spi_prepare('SELECT 10.0 * $1 AS a', 'does_not_exist');
  my $q = spi_query_prepared($x,$_[0]);
  my $result;
  while (defined (my $y = spi_fetchrow($q))) {
      $result = $y->{a};
  }
  spi_freeplan($x);
  return $result;
$$ LANGUAGE plperl;

Instead of:
ERROR:  type "does_not_exist" does not exist at line 2.

We get:
ERROR:  type "does_not_exist" does not exist at -e line 56.

I poked at this for a bit and didn't see a way around that.

Attached is a draft patch that at least fixes the issue for 5.10 and up. I guess we don't want to commit the regression test unless we want to add 2 new plperl_elog.out files (one for 5.8 and one for the already existing alt file).

Another thing to note is sv2cstr() can elog(ERROR) if the message has an invalid byte sequence:

create or replace function perl_test_err() returns text
language plperl as $$
  elog(ERROR, "\0");
$$;

-- or
create or replace function perl_test_err() returns text
language plperl as $$
  elog(INFO, "\0");
$$;
select perl_test_err();
ERROR:  invalid byte sequence for encoding "UTF8": 0x00k

Without the PG_TRY block we can't punt these errors back to perl. Maybe that does not matter all that much. After-all we could still have an error converting that new error to utf8 for perl (realistically this probably falls into the impossible category...). Thoughts?

Attached is a patch that does /not/ take into account errors thrown by pg_any_to_server() along the lines of Tom's above suggestion. I added a croak_cstr() function (trying to be in the spirit of the other plperl_helper functions) and converted various croak("%s", e->message); over to it. Tested on 5.8.9 and 5.18.2 from 9.1-stable to 9.4 (9.5 doesn't seem to pass a standard make check on my machine atm, but I don't think there have been any plperl changes).

Note it does not apply cleaning to 9.1-9.3 (trivial rejects), I'm happy to do the leg work if we like this proposed patch.

Attachment

pgsql-bugs by date:

Previous
From: Tom Lane
Date:
Subject: Re: BUG #13638: Exception texts from plperl has bad encoding
Next
From: Michael Paquier
Date:
Subject: Re: BUG #13644: 2xRecovery without new writes, causes archiving failure