Thread

  1. Buildfarm misses running some contrib TAP tests

    Tom Lane <tgl@sss.pgh.pa.us> — 2026-04-07T23:08:34Z

    I noticed by accident that my buildfarm animal indri stopped running
    certain contrib TAP tests this morning.  In [1] it's running
    
    contrib-amcheck-check (00:00:12)
    contrib-auto_explain-check (00:00:02)
    contrib-basebackup_to_shell-check (00:00:01)
    contrib-bloom-check (00:00:05)
    contrib-oid2name-check (00:00:01)
    contrib-pg_stat_statements-check (00:00:02)
    contrib-postgres_fdw-check (00:00:07)
    contrib-test_decoding-check (00:00:07)
    contrib-vacuumlo-check (00:00:01)
    
    but in the very next run [2] we see
    
    contrib-amcheck-check (00:00:12)
    contrib-auto_explain-check (00:00:01)
    contrib-basebackup_to_shell-check (00:00:02)
    contrib-bloom-check (00:00:05)
    contrib-oid2name-check (00:00:00)
    contrib-pg_stash_advice-check (00:00:03)
    contrib-pg_stat_statements-check (00:00:02)
    contrib-pg_visibility-check (00:00:03)
    contrib-test_decoding-check (00:00:08)
    
    What became of postgres_fdw and vacuumlo?  And why wasn't
    pg_visibility being run before?  And why are dblink and pg_prewarm
    visible in neither list?  Apparently the addition of pg_stash_advice
    changed something here, but what?
    
    Looking at some other BF animals shows that it's not just indri: other
    autoconf-based animals are showing misbehavior of this sort as well.
    
    I poked at this by adding some debug printouts, and determined that
    what is going wrong is the test to see if we built the module:
    
    		# can't test it if we haven't built it
    		next unless scalar glob("$testdir/*.o $testdir/*.obj");
    
    It's failing, sometimes, on modules that definitely do contain object
    files.  We've had run-ins with "scalar glob()" before [3], and when
    I finally looked at "man perlfunc" what I read is
    
           glob EXPR
           glob
               In list context, returns a (possibly empty) list of filename
               expansions on the value of EXPR such as the standard Unix shell
               /bin/csh would do.  In scalar context, glob iterates through such
               filename expansions, returning undef when the list is exhausted.
    
    I'm not entirely sure what "iterates" means in this context, but
    what seems to be happening on my Linux box is that you get undef
    unless there is exactly one file matching the glob pattern.
    
    I can't explain why we're not seeing more consistent behavior
    out of the buildfarm, like never running postgres_fdw at all.
    I wonder if the glob() infrastructure has some buggy internal state.
    But the attached patch gives me better results.
    
    			regards, tom lane
    
    [1] https://buildfarm.postgresql.org/cgi-bin/show_log.pl?nm=indri&dt=2026-04-07%2013%3A42%3A46
    [2] https://buildfarm.postgresql.org/cgi-bin/show_log.pl?nm=indri&dt=2026-04-07%2014%3A17%3A01
    [3] https://www.postgresql.org/message-id/200085.1741127335%40sss.pgh.pa.us
    
    
  2. Re: Buildfarm misses running some contrib TAP tests

    Tom Lane <tgl@sss.pgh.pa.us> — 2026-04-07T23:46:19Z

    I wrote:
    > I'm not entirely sure what "iterates" means in this context, but
    > what seems to be happening on my Linux box is that you get undef
    > unless there is exactly one file matching the glob pattern.
    > I can't explain why we're not seeing more consistent behavior
    > out of the buildfarm, like never running postgres_fdw at all.
    > I wonder if the glob() infrastructure has some buggy internal state.
    
    Oh ... apparently, what it thinks that means is that successive
    calls will return file names out of the previous "scalar glob"
    call, until it finally returns undef, and then the next call
    starts a new scan.  This simple test program:
    
    use strict;
    use warnings;
    
    my $pgsql = '/home/postgres/pgsql';
    
    	foreach my $testdir (glob("$pgsql/contrib/*"))
    	{
    		next unless -d "$testdir/t";
    		print "examining $testdir\n";
    
    		my @gresult = glob("$testdir/*.o $testdir/*.obj");
    		print 'sizeof glob = ' . scalar @gresult . "\n";
    
    		# can't test it if we haven't built it
    		my $scal = scalar glob("$testdir/*.o $testdir/*.obj");
    		$scal = '<undefined>' if not defined($scal);
    		print 'scalar glob = ' . $scal . "\n";
    	}
    
    1;
    
    gives me
    
    examining /home/postgres/pgsql/contrib/amcheck
    sizeof glob = 4
    scalar glob = /home/postgres/pgsql/contrib/amcheck/verify_common.o
    examining /home/postgres/pgsql/contrib/auto_explain
    sizeof glob = 1
    scalar glob = /home/postgres/pgsql/contrib/amcheck/verify_gin.o
    examining /home/postgres/pgsql/contrib/basebackup_to_shell
    sizeof glob = 1
    scalar glob = /home/postgres/pgsql/contrib/amcheck/verify_heapam.o
    examining /home/postgres/pgsql/contrib/bloom
    sizeof glob = 6
    scalar glob = /home/postgres/pgsql/contrib/amcheck/verify_nbtree.o
    examining /home/postgres/pgsql/contrib/dblink
    sizeof glob = 1
    scalar glob = <undefined>
    examining /home/postgres/pgsql/contrib/oid2name
    sizeof glob = 1
    scalar glob = /home/postgres/pgsql/contrib/oid2name/oid2name.o
    examining /home/postgres/pgsql/contrib/pg_prewarm
    sizeof glob = 2
    scalar glob = <undefined>
    examining /home/postgres/pgsql/contrib/pg_stash_advice
    sizeof glob = 3
    scalar glob = /home/postgres/pgsql/contrib/pg_stash_advice/pg_stash_advice.o
    examining /home/postgres/pgsql/contrib/pg_stat_statements
    sizeof glob = 1
    scalar glob = /home/postgres/pgsql/contrib/pg_stash_advice/stashfuncs.o
    examining /home/postgres/pgsql/contrib/pg_visibility
    sizeof glob = 1
    scalar glob = /home/postgres/pgsql/contrib/pg_stash_advice/stashpersist.o
    examining /home/postgres/pgsql/contrib/postgres_fdw
    sizeof glob = 5
    scalar glob = <undefined>
    examining /home/postgres/pgsql/contrib/sepgsql
    sizeof glob = 0
    scalar glob = <undefined>
    examining /home/postgres/pgsql/contrib/test_decoding
    sizeof glob = 1
    scalar glob = /home/postgres/pgsql/contrib/test_decoding/test_decoding.o
    examining /home/postgres/pgsql/contrib/vacuumlo
    sizeof glob = 1
    scalar glob = <undefined>
    
    So we are getting results that depend mainly on how many .o files
    there were in some previous contrib directory.  That explains how
    come pg_stash_advice managed to change the behavior of later
    modules.
    
    			regards, tom lane
    
    
    
    
  3. Re: Buildfarm misses running some contrib TAP tests

    Andrew Dunstan <andrew@dunslane.net> — 2026-04-08T12:50:11Z

    On 2026-04-07 Tu 7:46 PM, Tom Lane wrote:
    > I wrote:
    >> I'm not entirely sure what "iterates" means in this context, but
    >> what seems to be happening on my Linux box is that you get undef
    >> unless there is exactly one file matching the glob pattern.
    >> I can't explain why we're not seeing more consistent behavior
    >> out of the buildfarm, like never running postgres_fdw at all.
    >> I wonder if the glob() infrastructure has some buggy internal state.
    > Oh ... apparently, what it thinks that means is that successive
    > calls will return file names out of the previous "scalar glob"
    > call, until it finally returns undef, and then the next call
    > starts a new scan.  This simple test program:
    >
    > use strict;
    > use warnings;
    >
    > my $pgsql = '/home/postgres/pgsql';
    >
    > 	foreach my $testdir (glob("$pgsql/contrib/*"))
    > 	{
    > 		next unless -d "$testdir/t";
    > 		print "examining $testdir\n";
    >
    > 		my @gresult = glob("$testdir/*.o $testdir/*.obj");
    > 		print 'sizeof glob = ' . scalar @gresult . "\n";
    >
    > 		# can't test it if we haven't built it
    > 		my $scal = scalar glob("$testdir/*.o $testdir/*.obj");
    > 		$scal = '<undefined>' if not defined($scal);
    > 		print 'scalar glob = ' . $scal . "\n";
    > 	}
    >
    > 1;
    >
    > gives me
    >
    > examining /home/postgres/pgsql/contrib/amcheck
    > sizeof glob = 4
    > scalar glob = /home/postgres/pgsql/contrib/amcheck/verify_common.o
    > examining /home/postgres/pgsql/contrib/auto_explain
    > sizeof glob = 1
    > scalar glob = /home/postgres/pgsql/contrib/amcheck/verify_gin.o
    > examining /home/postgres/pgsql/contrib/basebackup_to_shell
    > sizeof glob = 1
    > scalar glob = /home/postgres/pgsql/contrib/amcheck/verify_heapam.o
    > examining /home/postgres/pgsql/contrib/bloom
    > sizeof glob = 6
    > scalar glob = /home/postgres/pgsql/contrib/amcheck/verify_nbtree.o
    > examining /home/postgres/pgsql/contrib/dblink
    > sizeof glob = 1
    > scalar glob = <undefined>
    > examining /home/postgres/pgsql/contrib/oid2name
    > sizeof glob = 1
    > scalar glob = /home/postgres/pgsql/contrib/oid2name/oid2name.o
    > examining /home/postgres/pgsql/contrib/pg_prewarm
    > sizeof glob = 2
    > scalar glob = <undefined>
    > examining /home/postgres/pgsql/contrib/pg_stash_advice
    > sizeof glob = 3
    > scalar glob = /home/postgres/pgsql/contrib/pg_stash_advice/pg_stash_advice.o
    > examining /home/postgres/pgsql/contrib/pg_stat_statements
    > sizeof glob = 1
    > scalar glob = /home/postgres/pgsql/contrib/pg_stash_advice/stashfuncs.o
    > examining /home/postgres/pgsql/contrib/pg_visibility
    > sizeof glob = 1
    > scalar glob = /home/postgres/pgsql/contrib/pg_stash_advice/stashpersist.o
    > examining /home/postgres/pgsql/contrib/postgres_fdw
    > sizeof glob = 5
    > scalar glob = <undefined>
    > examining /home/postgres/pgsql/contrib/sepgsql
    > sizeof glob = 0
    > scalar glob = <undefined>
    > examining /home/postgres/pgsql/contrib/test_decoding
    > sizeof glob = 1
    > scalar glob = /home/postgres/pgsql/contrib/test_decoding/test_decoding.o
    > examining /home/postgres/pgsql/contrib/vacuumlo
    > sizeof glob = 1
    > scalar glob = <undefined>
    >
    > So we are getting results that depend mainly on how many .o files
    > there were in some previous contrib directory.  That explains how
    > come pg_stash_advice managed to change the behavior of later
    > modules.
    >
    > 			
    
    
    Ugh. That's slightly embarrassing. So I guess the solution is not to use 
    glob in scalar context here.
    
    Will fix.
    
    
    cheers
    
    
    andrew
    
    --
    Andrew Dunstan
    EDB:https://www.enterprisedb.com