PL/Perl portability fix: absorb relevant -D switches from Perl.
authorTom Lane
Mon, 31 Jul 2017 16:38:35 +0000 (12:38 -0400)
committerTom Lane
Mon, 31 Jul 2017 16:38:35 +0000 (12:38 -0400)
Back-patch of commit 3c163a7fc76debbbdad1bdd3c43721cffe72f4db,
which see for more info.

Also throw in commit b4cc35fbb709bd6fcae8998f041fd731c9acbf42,
so Coverity doesn't whine about the back branches.

Ashutosh Sharma, some adjustments by me

Discussion: https://postgr.es/m/CANFyU97OVQ3+Mzfmt3MhuUm5NwPU=-FtbNH5Eb7nZL9ua8=rcA@mail.gmail.com

config/perl.m4
configure
configure.in
src/Makefile.global.in
src/pl/plperl/GNUmakefile
src/pl/plperl/plperl.c
src/tools/msvc/Mkvcbuild.pm

index bed2eae57fe21af61dd764408ae3c038eee7fa16..9706c4de6aca951b9187c0b3f689faf581084ddf 100644 (file)
@@ -49,6 +49,31 @@ AC_DEFUN([PGAC_CHECK_PERL_CONFIGS],
 [m4_foreach([pgac_item], [$1], [PGAC_CHECK_PERL_CONFIG(pgac_item)])])
 
 
+# PGAC_CHECK_PERL_EMBED_CCFLAGS
+# -----------------------------
+# We selectively extract stuff from $Config{ccflags}.  We don't really need
+# anything except -D switches, and other sorts of compiler switches can
+# actively break things if Perl was compiled with a different compiler.
+# Moreover, although Perl likes to put stuff like -D_LARGEFILE_SOURCE and
+# -D_FILE_OFFSET_BITS=64 here, it would be fatal to try to compile PL/Perl
+# to a different libc ABI than core Postgres uses.  The available information
+# says that all the symbols that affect Perl's own ABI begin with letters,
+# so it should be sufficient to adopt -D switches for symbols not beginning
+# with underscore.
+# For debugging purposes, let's have the configure output report the raw
+# ccflags value as well as the set of flags we chose to adopt.
+AC_DEFUN([PGAC_CHECK_PERL_EMBED_CCFLAGS],
+[AC_REQUIRE([PGAC_PATH_PERL])
+AC_MSG_CHECKING([for CFLAGS recommended by Perl])
+perl_ccflags=`$PERL -MConfig -e ['print $Config{ccflags}']`
+AC_MSG_RESULT([$perl_ccflags])
+AC_MSG_CHECKING([for CFLAGS to compile embedded Perl])
+perl_embed_ccflags=`$PERL -MConfig -e ['foreach $f (split(" ",$Config{ccflags})) {print $f, " " if ($f =~ /^-D[^_]/)}']`
+AC_SUBST(perl_embed_ccflags)dnl
+AC_MSG_RESULT([$perl_embed_ccflags])
+])# PGAC_CHECK_PERL_EMBED_CCFLAGS
+
+
 # PGAC_CHECK_PERL_EMBED_LDFLAGS
 # -----------------------------
 # We are after Embed's ldopts, but without the subset mentioned in
index 7396a735ccee61e67500500d1a174c8fdee23b25..095c7c8f4ee945e766638d1e246e6b894b36964c 100755 (executable)
--- a/configure
+++ b/configure
@@ -682,6 +682,7 @@ python_version
 python_majorversion
 PYTHON
 perl_embed_ldflags
+perl_embed_ccflags
 perl_useshrplib
 perl_privlibexp
 perl_archlibexp
@@ -7601,6 +7602,18 @@ test "$PORTNAME" = "win32" && perl_useshrplib=`echo $perl_useshrplib | sed 's,\\
 { $as_echo "$as_me:$LINENO: result: $perl_useshrplib" >&5
 $as_echo "$perl_useshrplib" >&6; }
 
+{ $as_echo "$as_me:$LINENO: checking for CFLAGS recommended by Perl" >&5
+$as_echo_n "checking for CFLAGS recommended by Perl... " >&6; }
+perl_ccflags=`$PERL -MConfig -e 'print $Config{ccflags}'`
+{ $as_echo "$as_me:$LINENO: result: $perl_ccflags" >&5
+$as_echo "$perl_ccflags" >&6; }
+{ $as_echo "$as_me:$LINENO: checking for CFLAGS to compile embedded Perl" >&5
+$as_echo_n "checking for CFLAGS to compile embedded Perl... " >&6; }
+perl_embed_ccflags=`$PERL -MConfig -e 'foreach $f (split(" ",$Config{ccflags})) {print $f, " " if ($f =~ /^-D[^_]/)}'`
+{ $as_echo "$as_me:$LINENO: result: $perl_embed_ccflags" >&5
+$as_echo "$perl_embed_ccflags" >&6; }
+
+
 { $as_echo "$as_me:$LINENO: checking for flags to link embedded Perl" >&5
 $as_echo_n "checking for flags to link embedded Perl... " >&6; }
 if test "$PORTNAME" = "win32" ; then
index ef66ba6ac9300c5a4c7e0c8e9f98c7d83e228e4f..be2afda5ec3e245ac62b5cf84b816222958a7142 100644 (file)
@@ -850,6 +850,7 @@ if test "$with_perl" = yes; then
     AC_MSG_ERROR([Perl not found])
   fi
   PGAC_CHECK_PERL_CONFIGS([archlibexp,privlibexp,useshrplib])
+  PGAC_CHECK_PERL_EMBED_CCFLAGS
   PGAC_CHECK_PERL_EMBED_LDFLAGS
 fi
 
index 057e9ec398eaa9540a8722f6a96cd29611b5c31a..41f18ada29044d454d296a55f651ef7cd85158fd 100644 (file)
@@ -277,6 +277,7 @@ endif
 perl_archlibexp        = @perl_archlibexp@
 perl_privlibexp        = @perl_privlibexp@
 perl_useshrplib        = @perl_useshrplib@
+perl_embed_ccflags = @perl_embed_ccflags@
 perl_embed_ldflags = @perl_embed_ldflags@
 
 # Miscellaneous
index e0e31ecfbf8ce980daea7b2eab2522762688599d..32d49cdaa1514398f8b78c5d18e2d8bc7893c5d3 100644 (file)
@@ -22,7 +22,11 @@ override CPPFLAGS += -DPLPERL_HAVE_UID_GID
 override CFLAGS += -Wno-comment
 endif
 
-override CPPFLAGS := -I. -I$(srcdir) $(CPPFLAGS) -I$(perl_archlibexp)/CORE
+# Note: we need to make sure that the CORE directory is included last,
+# probably because it sometimes contains some header files with names
+# that clash with some of ours, or with some that we include, notably on
+# Windows.
+override CPPFLAGS := -I. -I$(srcdir) $(CPPFLAGS) $(perl_embed_ccflags) -I$(perl_archlibexp)/CORE
 
 rpathdir = $(perl_archlibexp)/CORE
 
index 7e578584ed4703901c383061a3b26efe7c97f23f..7902e8baf94dbd6e017fa7803b74f8a923dc8a85 100644 (file)
@@ -3056,12 +3056,18 @@ plperl_return_next_internal(SV *sv)
 
        /*
         * This is the first call to return_next in the current PL/Perl
-        * function call, so memoize some lookups
+        * function call, so identify the output tuple descriptor and create a
+        * tuplestore to hold the result rows.
         */
        if (prodesc->fn_retistuple)
            (void) get_call_result_type(fcinfo, NULL, &tupdesc);
        else
+       {
            tupdesc = rsi->expectedDesc;
+           /* Protect assumption below that we return exactly one column */
+           if (tupdesc == NULL || tupdesc->natts != 1)
+               elog(ERROR, "expected single-column result descriptor for non-composite SETOF result");
+       }
 
        /*
         * Make sure the tuple_store and ret_tdesc are sufficiently
@@ -3111,20 +3117,20 @@ plperl_return_next_internal(SV *sv)
    }
    else
    {
-       Datum       ret;
-       bool        isNull;
+       Datum       ret[1];
+       bool        isNull[1];
 
-       ret = plperl_sv_to_datum(sv,
-                                prodesc->result_oid,
-                                -1,
-                                fcinfo,
-                                &prodesc->result_in_func,
-                                prodesc->result_typioparam,
-                                &isNull);
+       ret[0] = plperl_sv_to_datum(sv,
+                                   prodesc->result_oid,
+                                   -1,
+                                   fcinfo,
+                                   &prodesc->result_in_func,
+                                   prodesc->result_typioparam,
+                                   &isNull[0]);
 
        tuplestore_putvalues(current_call_data->tuple_store,
                             current_call_data->ret_tdesc,
-                            &ret, &isNull);
+                            ret, isNull);
    }
 
    MemoryContextSwitchTo(old_cxt);
index 603922a553ddb7a75a0fd9f302f0e18f2dae8865..2c4c7eef7e8a617192b0d611b8d60e9d4c7f2df2 100644 (file)
@@ -140,7 +140,26 @@ sub mkvcbuild
        my $plperl =
          $solution->AddProject('plperl', 'dll', 'PLs', 'src\pl\plperl');
        $plperl->AddIncludeDir($solution->{options}->{perl} . '/lib/CORE');
-       $plperl->AddDefine('PLPERL_HAVE_UID_GID');
+
+       # Add defines from Perl's ccflags; see PGAC_CHECK_PERL_EMBED_CCFLAGS
+       my @perl_embed_ccflags;
+       foreach my $f (split(" ",$Config{ccflags}))
+       {
+           if ($f =~ /^-D[^_]/)
+           {
+               $f =~ s/\-D//;
+               push(@perl_embed_ccflags, $f);
+           }
+       }
+
+       # XXX this probably is redundant now?
+       push(@perl_embed_ccflags, 'PLPERL_HAVE_UID_GID');
+
+       foreach my $f (@perl_embed_ccflags)
+       {
+           $plperl->AddDefine($f);
+       }
+
        foreach my $xs ('SPI.xs', 'Util.xs')
        {
            (my $xsc = $xs) =~ s/\.xs/.c/;