I encountered a core dump running PL/Perl installcheck with a very
recent git HEAD of PostgreSQL and a not quite so recent git HEAD of perl.

The cause is a subtle difference between SvTYPE(sv) == SVt_RV and
SvROK(sv). The former is checking a low-level implementation detail
while the later is directly checking "does this sv contains a reference".

The attached patch fixes the problem by changing the SvTYPE check to use
SvROK instead. Although I only tripped over one case, the patch changes
all four uses of SvTYPE(sv) == SVt_RV. The remaining uses of SvTYPE are ok.

Tim.

diff --git a/src/pl/plperl/plperl.c b/src/pl/plperl/plperl.c
index 956eddb..c1cc8ff 100644
*** a/src/pl/plperl/plperl.c
--- b/src/pl/plperl/plperl.c
*************** plperl_modify_tuple(HV *hvTD, TriggerDat
*** 976,982 ****
  		ereport(ERROR,
  				(errcode(ERRCODE_UNDEFINED_COLUMN),
  				 errmsg("$_TD->{new} does not exist")));
! 	if (!SvOK(*svp) || SvTYPE(*svp) != SVt_RV || SvTYPE(SvRV(*svp)) != SVt_PVHV)
  		ereport(ERROR,
  				(errcode(ERRCODE_DATATYPE_MISMATCH),
  				 errmsg("$_TD->{new} is not a hash reference")));
--- 976,982 ----
  		ereport(ERROR,
  				(errcode(ERRCODE_UNDEFINED_COLUMN),
  				 errmsg("$_TD->{new} does not exist")));
! 	if (!SvOK(*svp) || !SvROK(*svp) || SvTYPE(SvRV(*svp)) != SVt_PVHV)
  		ereport(ERROR,
  				(errcode(ERRCODE_DATATYPE_MISMATCH),
  				 errmsg("$_TD->{new} is not a hash reference")));
*************** plperl_func_handler(PG_FUNCTION_ARGS)
*** 1549,1555 ****
  		 * value is an error, except undef which means return an empty set.
  		 */
  		if (SvOK(perlret) &&
! 			SvTYPE(perlret) == SVt_RV &&
  			SvTYPE(SvRV(perlret)) == SVt_PVAV)
  		{
  			int			i = 0;
--- 1549,1555 ----
  		 * value is an error, except undef which means return an empty set.
  		 */
  		if (SvOK(perlret) &&
! 			SvROK(perlret) &&
  			SvTYPE(SvRV(perlret)) == SVt_PVAV)
  		{
  			int			i = 0;
*************** plperl_func_handler(PG_FUNCTION_ARGS)
*** 1594,1600 ****
  		AttInMetadata *attinmeta;
  		HeapTuple	tup;
  
! 		if (!SvOK(perlret) || SvTYPE(perlret) != SVt_RV ||
  			SvTYPE(SvRV(perlret)) != SVt_PVHV)
  		{
  			ereport(ERROR,
--- 1594,1600 ----
  		AttInMetadata *attinmeta;
  		HeapTuple	tup;
  
! 		if (!SvOK(perlret) || !SvROK(perlret) ||
  			SvTYPE(SvRV(perlret)) != SVt_PVHV)
  		{
  			ereport(ERROR,
*************** plperl_return_next(SV *sv)
*** 2218,2224 ****
  				 errmsg("cannot use return_next in a non-SETOF function")));
  
  	if (prodesc->fn_retistuple &&
! 		!(SvOK(sv) && SvTYPE(sv) == SVt_RV && SvTYPE(SvRV(sv)) == SVt_PVHV))
  		ereport(ERROR,
  				(errcode(ERRCODE_DATATYPE_MISMATCH),
  				 errmsg("SETOF-composite-returning PL/Perl function "
--- 2218,2224 ----
  				 errmsg("cannot use return_next in a non-SETOF function")));
  
  	if (prodesc->fn_retistuple &&
! 		!(SvOK(sv) && SvROK(sv) && SvTYPE(SvRV(sv)) == SVt_PVHV))
  		ereport(ERROR,
  				(errcode(ERRCODE_DATATYPE_MISMATCH),
  				 errmsg("SETOF-composite-returning PL/Perl function "
-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to