From: Andrew Dunstan Date: Sun, 15 Jan 2012 21:15:04 +0000 (-0500) Subject: Improve efficiency of recent changes to plperl's sv2cstr(). X-Git-Tag: REL9_2_BETA1~580 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=01d83ffdcae92f75dbfd41de0b4213d241edd394;p=postgresql Improve efficiency of recent changes to plperl's sv2cstr(). Along the way, add a missing dependency in the GNUmakefile. Alex Hunsaker, with a slight adjustment by me. --- diff --git a/src/pl/plperl/GNUmakefile b/src/pl/plperl/GNUmakefile index 0f3bd99570..188d7d234b 100644 --- a/src/pl/plperl/GNUmakefile +++ b/src/pl/plperl/GNUmakefile @@ -72,11 +72,11 @@ perlchunks.h: $(PERLCHUNKS) all: all-lib -SPI.c: SPI.xs +SPI.c: SPI.xs plperl_helpers.h @if [ x"$(perl_privlibexp)" = x"" ]; then echo "configure switch --with-perl was not specified."; exit 1; fi $(PERL) $(XSUBPPDIR)/ExtUtils/xsubpp -typemap $(perl_privlibexp)/ExtUtils/typemap $< >$@ -Util.c: Util.xs +Util.c: Util.xs plperl_helpers.h @if [ x"$(perl_privlibexp)" = x"" ]; then echo "configure switch --with-perl was not specified."; exit 1; fi $(PERL) $(XSUBPPDIR)/ExtUtils/xsubpp -typemap $(perl_privlibexp)/ExtUtils/typemap $< >$@ diff --git a/src/pl/plperl/expected/plperl_elog.out b/src/pl/plperl/expected/plperl_elog.out index 02497d9e02..60eade8ddd 100644 --- a/src/pl/plperl/expected/plperl_elog.out +++ b/src/pl/plperl/expected/plperl_elog.out @@ -58,3 +58,7 @@ select uses_global(); uses_global worked (1 row) +-- make sure we don't choke on readonly values +do language plperl $$ elog(NOTICE, ${^TAINT}); $$; +NOTICE: 0 +CONTEXT: PL/Perl anonymous code block diff --git a/src/pl/plperl/plperl_helpers.h b/src/pl/plperl/plperl_helpers.h index 800a408ac4..35e1257457 100644 --- a/src/pl/plperl/plperl_helpers.h +++ b/src/pl/plperl/plperl_helpers.h @@ -47,28 +47,35 @@ sv2cstr(SV *sv) { char *val, *res; STRLEN len; - SV *nsv; /* * get a utf8 encoded char * out of perl. *note* it may not be valid utf8! * * SvPVutf8() croaks nastily on certain things, like typeglobs and * readonly objects such as $^V. That's a perl bug - it's not supposed to - * happen. To avoid crashing the backend, we make a copy of the - * sv before passing it to SvPVutf8(). The copy is garbage collected + * happen. To avoid crashing the backend, we make a copy of the sv before + * passing it to SvPVutf8(). The copy is garbage collected * when we're done with it. */ - nsv = newSVsv(sv); - val = SvPVutf8(nsv, len); + if (SvREADONLY(sv) || + isGV_with_GP(sv) || + (SvTYPE(sv) > SVt_PVLV && SvTYPE(sv) != SVt_PVFM)) + sv = newSVsv(sv); + else + /* increase the reference count so we cant just SvREFCNT_dec() it when + * we are done */ + SvREFCNT_inc(sv); + + val = SvPVutf8(sv, len); /* * we use perl's length in the event we had an embedded null byte to ensure * we error out properly */ - res = utf_u2e(val, len); + res = utf_u2e(val, len); /* safe now to garbage collect the new SV */ - SvREFCNT_dec(nsv); + SvREFCNT_dec(sv); return res; } diff --git a/src/pl/plperl/sql/plperl_elog.sql b/src/pl/plperl/sql/plperl_elog.sql index 4f1c014efb..40896a48f4 100644 --- a/src/pl/plperl/sql/plperl_elog.sql +++ b/src/pl/plperl/sql/plperl_elog.sql @@ -43,3 +43,6 @@ create or replace function uses_global() returns text language plperl as $$ $$; select uses_global(); + +-- make sure we don't choke on readonly values +do language plperl $$ elog(NOTICE, ${^TAINT}); $$;