diff options
Diffstat (limited to 'src/backend/utils/Gen_fmgrtab.pl')
-rw-r--r-- | src/backend/utils/Gen_fmgrtab.pl | 296 |
1 files changed, 296 insertions, 0 deletions
diff --git a/src/backend/utils/Gen_fmgrtab.pl b/src/backend/utils/Gen_fmgrtab.pl new file mode 100644 index 0000000..881568d --- /dev/null +++ b/src/backend/utils/Gen_fmgrtab.pl @@ -0,0 +1,296 @@ +#! /usr/bin/perl +#------------------------------------------------------------------------- +# +# Gen_fmgrtab.pl +# Perl script that generates fmgroids.h, fmgrprotos.h, and fmgrtab.c +# from pg_proc.dat +# +# Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group +# Portions Copyright (c) 1994, Regents of the University of California +# +# +# IDENTIFICATION +# src/backend/utils/Gen_fmgrtab.pl +# +#------------------------------------------------------------------------- + +use Catalog; + +use strict; +use warnings; +use Getopt::Long; + +my $output_path = ''; +my $include_path; + +GetOptions( + 'output:s' => \$output_path, + 'include-path:s' => \$include_path) || usage(); + +# Make sure output_path ends in a slash. +if ($output_path ne '' && substr($output_path, -1) ne '/') +{ + $output_path .= '/'; +} + +# Sanity check arguments. +die "No input files.\n" unless @ARGV; +die "--include-path must be specified.\n" unless $include_path; + +# Read all the input files into internal data structures. +# Note: We pass data file names as arguments and then look for matching +# headers to parse the schema from. This is backwards from genbki.pl, +# but the Makefile dependencies look more sensible this way. +# We currently only need pg_proc, but retain the possibility of reading +# more than one data file. +my %catalogs; +my %catalog_data; +foreach my $datfile (@ARGV) +{ + $datfile =~ /(.+)\.dat$/ + or die "Input files need to be data (.dat) files.\n"; + + my $header = "$1.h"; + die "There in no header file corresponding to $datfile" + if !-e $header; + + my $catalog = Catalog::ParseHeader($header); + my $catname = $catalog->{catname}; + my $schema = $catalog->{columns}; + + $catalogs{$catname} = $catalog; + $catalog_data{$catname} = Catalog::ParseData($datfile, $schema, 0); +} + +# Collect certain fields from pg_proc.dat. +my @fmgr = (); +my %proname_counts; + +foreach my $row (@{ $catalog_data{pg_proc} }) +{ + my %bki_values = %$row; + + push @fmgr, + { + oid => $bki_values{oid}, + name => $bki_values{proname}, + lang => $bki_values{prolang}, + kind => $bki_values{prokind}, + strict => $bki_values{proisstrict}, + retset => $bki_values{proretset}, + nargs => $bki_values{pronargs}, + args => $bki_values{proargtypes}, + prosrc => $bki_values{prosrc}, + }; + + # Count so that we can detect overloaded pronames. + $proname_counts{ $bki_values{proname} }++; +} + +# Emit headers for both files +my $tmpext = ".tmp$$"; +my $oidsfile = $output_path . 'fmgroids.h'; +my $protosfile = $output_path . 'fmgrprotos.h'; +my $tabfile = $output_path . 'fmgrtab.c'; + +open my $ofh, '>', $oidsfile . $tmpext + or die "Could not open $oidsfile$tmpext: $!"; +open my $pfh, '>', $protosfile . $tmpext + or die "Could not open $protosfile$tmpext: $!"; +open my $tfh, '>', $tabfile . $tmpext + or die "Could not open $tabfile$tmpext: $!"; + +print $ofh <<OFH; +/*------------------------------------------------------------------------- + * + * fmgroids.h + * Macros that define the OIDs of built-in functions. + * + * These macros can be used to avoid a catalog lookup when a specific + * fmgr-callable function needs to be referenced. + * + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * NOTES + * ****************************** + * *** DO NOT EDIT THIS FILE! *** + * ****************************** + * + * It has been GENERATED by src/backend/utils/Gen_fmgrtab.pl + * + *------------------------------------------------------------------------- + */ +#ifndef FMGROIDS_H +#define FMGROIDS_H + +/* + * Constant macros for the OIDs of entries in pg_proc. + * + * F_XXX macros are named after the proname field; if that is not unique, + * we append the proargtypes field, replacing spaces with underscores. + * For example, we have F_OIDEQ because that proname is unique, but + * F_POW_FLOAT8_FLOAT8 (among others) because that proname is not. + */ +OFH + +print $pfh <<PFH; +/*------------------------------------------------------------------------- + * + * fmgrprotos.h + * Prototypes for built-in functions. + * + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * NOTES + * ****************************** + * *** DO NOT EDIT THIS FILE! *** + * ****************************** + * + * It has been GENERATED by src/backend/utils/Gen_fmgrtab.pl + * + *------------------------------------------------------------------------- + */ + +#ifndef FMGRPROTOS_H +#define FMGRPROTOS_H + +#include "fmgr.h" + +PFH + +print $tfh <<TFH; +/*------------------------------------------------------------------------- + * + * fmgrtab.c + * The function manager's table of internal functions. + * + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * NOTES + * + * ****************************** + * *** DO NOT EDIT THIS FILE! *** + * ****************************** + * + * It has been GENERATED by src/backend/utils/Gen_fmgrtab.pl + * + *------------------------------------------------------------------------- + */ + +#include "postgres.h" + +#include "access/transam.h" +#include "utils/fmgrtab.h" +#include "utils/fmgrprotos.h" + +TFH + +# Emit fmgroids.h and fmgrprotos.h entries in OID order. +my %seenit; +foreach my $s (sort { $a->{oid} <=> $b->{oid} } @fmgr) +{ + my $sqlname = $s->{name}; + $sqlname .= "_" . $s->{args} if ($proname_counts{ $s->{name} } > 1); + $sqlname =~ s/\s+/_/g; + print $ofh "#define F_" . uc $sqlname . " $s->{oid}\n"; + # We want only one extern per internal-language, non-aggregate function + if ( $s->{lang} eq 'internal' + && $s->{kind} ne 'a' + && !$seenit{ $s->{prosrc} }) + { + $seenit{ $s->{prosrc} } = 1; + print $pfh "extern Datum $s->{prosrc}(PG_FUNCTION_ARGS);\n"; + } +} + +# Create the fmgr_builtins table, collect data for fmgr_builtin_oid_index +print $tfh "\nconst FmgrBuiltin fmgr_builtins[] = {\n"; +my %bmap; +$bmap{'t'} = 'true'; +$bmap{'f'} = 'false'; +my @fmgr_builtin_oid_index; +my $last_builtin_oid = 0; +my $fmgr_count = 0; +foreach my $s (sort { $a->{oid} <=> $b->{oid} } @fmgr) +{ + next if $s->{lang} ne 'internal'; + # We do not need entries for aggregate functions + next if $s->{kind} eq 'a'; + + print $tfh ",\n" if ($fmgr_count > 0); + print $tfh + " { $s->{oid}, $s->{nargs}, $bmap{$s->{strict}}, $bmap{$s->{retset}}, \"$s->{prosrc}\", $s->{prosrc} }"; + + $fmgr_builtin_oid_index[ $s->{oid} ] = $fmgr_count++; + $last_builtin_oid = $s->{oid}; +} +print $tfh "\n};\n"; + +printf $tfh qq| +const int fmgr_nbuiltins = (sizeof(fmgr_builtins) / sizeof(FmgrBuiltin)); + +const Oid fmgr_last_builtin_oid = %u; +|, $last_builtin_oid; + + +# Create fmgr_builtin_oid_index table. +printf $tfh qq| +const uint16 fmgr_builtin_oid_index[%u] = { +|, $last_builtin_oid + 1; + +for (my $i = 0; $i <= $last_builtin_oid; $i++) +{ + my $oid = $fmgr_builtin_oid_index[$i]; + + # fmgr_builtin_oid_index is sparse, map nonexistent functions to + # InvalidOidBuiltinMapping + if (not defined $oid) + { + $oid = 'InvalidOidBuiltinMapping'; + } + + if ($i == $last_builtin_oid) + { + print $tfh " $oid\n"; + } + else + { + print $tfh " $oid,\n"; + } +} +print $tfh "};\n"; + + +# And add the file footers. +print $ofh "\n#endif\t\t\t\t\t\t\t/* FMGROIDS_H */\n"; +print $pfh "\n#endif\t\t\t\t\t\t\t/* FMGRPROTOS_H */\n"; + +close($ofh); +close($pfh); +close($tfh); + +# Finally, rename the completed files into place. +Catalog::RenameTempFile($oidsfile, $tmpext); +Catalog::RenameTempFile($protosfile, $tmpext); +Catalog::RenameTempFile($tabfile, $tmpext); + +sub usage +{ + die <<EOM; +Usage: perl -I [directory of Catalog.pm] Gen_fmgrtab.pl [--include-path/-i <path>] [path to pg_proc.dat] + +Options: + --output Output directory (default '.') + --include-path Include path in source tree + +Gen_fmgrtab.pl generates fmgroids.h, fmgrprotos.h, and fmgrtab.c from +pg_proc.dat + +Report bugs to <pgsql-bugs\@lists.postgresql.org>. +EOM +} + +exit 0; |