diff options
Diffstat (limited to 'src/backend/utils/Gen_fmgrtab.pl')
| -rw-r--r-- | src/backend/utils/Gen_fmgrtab.pl | 125 |
1 files changed, 69 insertions, 56 deletions
diff --git a/src/backend/utils/Gen_fmgrtab.pl b/src/backend/utils/Gen_fmgrtab.pl index 1ba7d9d362..5b281e874e 100644 --- a/src/backend/utils/Gen_fmgrtab.pl +++ b/src/backend/utils/Gen_fmgrtab.pl @@ -2,85 +2,89 @@ #------------------------------------------------------------------------- # # Gen_fmgrtab.pl -# Perl equivalent of Gen_fmgrtab.sh -# -# Usage: perl Gen_fmgrtab.pl path-to-pg_proc.h -# -# The reason for implementing this functionality twice is that we don't -# require people to have perl to build from a tarball, but on the other -# hand Windows can't deal with shell scripts. +# Perl script that generates fmgroids.h and fmgrtab.c from pg_proc.h # # Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group # Portions Copyright (c) 1994, Regents of the University of California # # # IDENTIFICATION -# $PostgreSQL: pgsql/src/backend/utils/Gen_fmgrtab.pl,v 1.3 2010/01/02 16:57:53 momjian Exp $ +# $PostgreSQL: pgsql/src/backend/utils/Gen_fmgrtab.pl,v 1.4 2010/01/05 01:06:56 tgl Exp $ # #------------------------------------------------------------------------- +use Catalog; + use strict; use warnings; # Collect arguments -my $infile = shift; -defined($infile) || die "$0: missing required argument: pg_proc.h\n"; - -# Note: see Gen_fmgrtab.sh for detailed commentary on what this is doing - -# Collect column numbers for pg_proc columns we need -my ($proname, $prolang, $proisstrict, $proretset, $pronargs, $prosrc); - -open(I, $infile) || die "Could not open $infile: $!"; -while (<I>) +my $infile; # pg_proc.h +my $output_path = ''; +while (@ARGV) { - if (m/#define Anum_pg_proc_proname\s+(\d+)/) { - $proname = $1; + my $arg = shift @ARGV; + if ($arg !~ /^-/) + { + $infile = $arg; } - if (m/#define Anum_pg_proc_prolang\s+(\d+)/) { - $prolang = $1; + elsif ($arg =~ /^-o/) + { + $output_path = length($arg) > 2 ? substr($arg, 2) : shift @ARGV; } - if (m/#define Anum_pg_proc_proisstrict\s+(\d+)/) { - $proisstrict = $1; - } - if (m/#define Anum_pg_proc_proretset\s+(\d+)/) { - $proretset = $1; - } - if (m/#define Anum_pg_proc_pronargs\s+(\d+)/) { - $pronargs = $1; - } - if (m/#define Anum_pg_proc_prosrc\s+(\d+)/) { - $prosrc = $1; + else + { + usage(); } } -close(I); -# Collect the raw data +# Make sure output_path ends in a slash. +if ($output_path ne '' && substr($output_path, -1) ne '/') +{ + $output_path .= '/'; +} + +# Read all the data from the include/catalog files. +my $catalogs = Catalog::Catalogs($infile); + +# Collect the raw data from pg_proc.h. my @fmgr = (); +my @attnames; +foreach my $column ( @{ $catalogs->{pg_proc}->{columns} } ) +{ + push @attnames, keys %$column; +} -open(I, $infile) || die "Could not open $infile: $!"; -while (<I>) +my $data = $catalogs->{pg_proc}->{data}; +foreach my $row (@$data) { - next unless (/^DATA/); - s/^[^O]*OID[^=]*=[ \t]*//; - s/\(//; - s/"[^"]*"/"xxx"/g; - my @p = split; - next if ($p[$prolang] ne "12"); + + # To construct fmgroids.h and fmgrtab.c, we need to inspect some + # of the individual data fields. Just splitting on whitespace + # won't work, because some quoted fields might contain internal + # whitespace. We handle this by folding them all to a simple + # "xxx". Fortunately, this script doesn't need to look at any + # fields that might need quoting, so this simple hack is + # sufficient. + $row->{bki_values} =~ s/"[^"]*"/"xxx"/g; + @{$row}{@attnames} = split /\s+/, $row->{bki_values}; + + # Select out just the rows for internal-language procedures. + # Note assumption here that INTERNALlanguageId is 12. + next if $row->{prolang} ne '12'; + push @fmgr, { - oid => $p[0], - proname => $p[$proname], - strict => $p[$proisstrict], - retset => $p[$proretset], - nargs => $p[$pronargs], - prosrc => $p[$prosrc], + oid => $row->{oid}, + strict => $row->{proisstrict}, + retset => $row->{proretset}, + nargs => $row->{pronargs}, + prosrc => $row->{prosrc}, }; } -close(I); # Emit headers for both files -open(H, '>', "$$-fmgroids.h") || die "Could not open $$-fmgroids.h: $!"; +open H, '>', $output_path . 'fmgroids.h.tmp' || die "Could not open fmgroids.h.tmp: $!"; print H qq|/*------------------------------------------------------------------------- * @@ -119,7 +123,7 @@ qq|/*------------------------------------------------------------------------- */ |; -open(T, '>', "$$-fmgrtab.c") || die "Could not open $$-fmgrtab.c: $!"; +open T, '>', $output_path . 'fmgrtab.c.tmp' || die "Could not open fmgrtab.c.tmp: $!"; print T qq|/*------------------------------------------------------------------------- * @@ -186,9 +190,18 @@ const int fmgr_nbuiltins = (sizeof(fmgr_builtins) / sizeof(FmgrBuiltin)) - 1; close(T); # Finally, rename the completed files into place. -rename "$$-fmgroids.h", "fmgroids.h" - || die "Could not rename $$-fmgroids.h to fmgroids.h: $!"; -rename "$$-fmgrtab.c", "fmgrtab.c" - || die "Could not rename $$-fmgrtab.c to fmgrtab.c: $!"; +Catalog::RenameTempFile($output_path . 'fmgroids.h'); +Catalog::RenameTempFile($output_path . 'fmgrtab.c'); + +sub usage +{ + die <<EOM; +Usage: perl -I [directory of Catalog.pm] Gen_fmgrtab.pl [path to pg_proc.h] + +Gen_fmgrtab.pl generates fmgroids.h and fmgrtab.c from pg_proc.h + +Report bugs to <pgsql-bugs\@postgresql.org>. +EOM +} exit 0; |
