2 #-------------------------------------------------------------------------
5 # Perl script that generates fmgroids.h and fmgrtab.c from pg_proc.h
7 # Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group
8 # Portions Copyright (c) 1994, Regents of the University of California
12 # src/backend/utils/Gen_fmgrtab.pl
14 #-------------------------------------------------------------------------
22 my $infile; # pg_proc.h
26 my $arg = shift @ARGV;
33 $output_path = length($arg) > 2 ? substr($arg, 2) : shift @ARGV;
41 # Make sure output_path ends in a slash.
42 if ($output_path ne '' && substr($output_path, -1) ne '/')
47 # Read all the data from the include/catalog files.
48 my $catalogs = Catalog::Catalogs($infile);
50 # Collect the raw data from pg_proc.h.
53 foreach my $column (@{ $catalogs->{pg_proc}->{columns} })
55 push @attnames, keys %$column;
58 my $data = $catalogs->{pg_proc}->{data};
59 foreach my $row (@$data)
62 # To construct fmgroids.h and fmgrtab.c, we need to inspect some
63 # of the individual data fields. Just splitting on whitespace
64 # won't work, because some quoted fields might contain internal
65 # whitespace. We handle this by folding them all to a simple
66 # "xxx". Fortunately, this script doesn't need to look at any
67 # fields that might need quoting, so this simple hack is
69 $row->{bki_values} =~ s/"[^"]*"/"xxx"/g;
70 @{$row}{@attnames} = split /\s+/, $row->{bki_values};
72 # Select out just the rows for internal-language procedures.
73 # Note assumption here that INTERNALlanguageId is 12.
74 next if $row->{prolang} ne '12';
78 strict => $row->{proisstrict},
79 retset => $row->{proretset},
80 nargs => $row->{pronargs},
81 prosrc => $row->{prosrc}, };
83 # Hack to work around memory leak in some versions of Perl
87 # Emit headers for both files
88 my $tmpext = ".tmp$$";
89 my $oidsfile = $output_path . 'fmgroids.h';
90 my $tabfile = $output_path . 'fmgrtab.c';
92 open H, '>', $oidsfile . $tmpext or die "Could not open $oidsfile$tmpext: $!";
93 open T, '>', $tabfile . $tmpext or die "Could not open $tabfile$tmpext: $!";
96 qq|/*-------------------------------------------------------------------------
99 * Macros that define the OIDs of built-in functions.
101 * These macros can be used to avoid a catalog lookup when a specific
102 * fmgr-callable function needs to be referenced.
104 * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group
105 * Portions Copyright (c) 1994, Regents of the University of California
108 * ******************************
109 * *** DO NOT EDIT THIS FILE! ***
110 * ******************************
112 * It has been GENERATED by $0
115 *-------------------------------------------------------------------------
121 * Constant macros for the OIDs of entries in pg_proc.
123 * NOTE: macros are named after the prosrc value, ie the actual C name
124 * of the implementing function, not the proname which may be overloaded.
125 * For example, we want to be able to assign different macro names to both
126 * char_text() and name_text() even though these both appear with proname
127 * 'text'. If the same C function appears in more than one pg_proc entry,
128 * its equivalent macro will be defined with the lowest OID among those
134 qq|/*-------------------------------------------------------------------------
137 * The function manager's table of internal functions.
139 * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group
140 * Portions Copyright (c) 1994, Regents of the University of California
144 * ******************************
145 * *** DO NOT EDIT THIS FILE! ***
146 * ******************************
148 * It has been GENERATED by $0
151 *-------------------------------------------------------------------------
154 #include "postgres.h"
156 #include "utils/fmgrtab.h"
160 # Emit #define's and extern's -- only one per prosrc value
162 foreach my $s (sort { $a->{oid} <=> $b->{oid} } @fmgr)
164 next if $seenit{ $s->{prosrc} };
165 $seenit{ $s->{prosrc} } = 1;
166 print H "#define F_" . uc $s->{prosrc} . " $s->{oid}\n";
167 print T "extern Datum $s->{prosrc} (PG_FUNCTION_ARGS);\n";
170 # Create the fmgr_builtins table
171 print T "\nconst FmgrBuiltin fmgr_builtins[] = {\n";
174 $bmap{'f'} = 'false';
175 foreach my $s (sort { $a->{oid} <=> $b->{oid} } @fmgr)
178 " { $s->{oid}, \"$s->{prosrc}\", $s->{nargs}, $bmap{$s->{strict}}, $bmap{$s->{retset}}, $s->{prosrc} },\n";
181 # And add the file footers.
182 print H "\n#endif /* FMGROIDS_H */\n";
185 qq| /* dummy entry is easier than getting rid of comma after last real one */
186 /* (not that there has ever been anything wrong with *having* a
187 comma after the last field in an array initializer) */
188 { 0, NULL, 0, false, false, NULL }
191 /* Note fmgr_nbuiltins excludes the dummy entry */
192 const int fmgr_nbuiltins = (sizeof(fmgr_builtins) / sizeof(FmgrBuiltin)) - 1;
198 # Finally, rename the completed files into place.
199 Catalog::RenameTempFile($oidsfile, $tmpext);
200 Catalog::RenameTempFile($tabfile, $tmpext);
205 Usage: perl -I [directory of Catalog.pm] Gen_fmgrtab.pl [path to pg_proc.h]
207 Gen_fmgrtab.pl generates fmgroids.h and fmgrtab.c from pg_proc.h
209 Report bugs to <pgsql-bugs\@postgresql.org>.