2 #-------------------------------------------------------------------------
5 # Perl script that generates fmgroids.h, fmgrprotos.h, and fmgrtab.c
8 # Portions Copyright (c) 1996-2024, PostgreSQL Global Development Group
9 # Portions Copyright (c) 1994, Regents of the University of California
13 # src/backend/utils/Gen_fmgrtab.pl
15 #-------------------------------------------------------------------------
20 use warnings FATAL
=> 'all';
27 'output:s' => \
$output_path,
28 'include-path:s' => \
$include_path) || usage
();
30 # Make sure output_path ends in a slash.
31 if ($output_path ne '' && substr($output_path, -1) ne '/')
36 # Sanity check arguments.
37 die "No input files.\n" unless @ARGV;
38 die "--include-path must be specified.\n" unless $include_path;
40 # Read all the input files into internal data structures.
41 # Note: We pass data file names as arguments and then look for matching
42 # headers to parse the schema from. This is backwards from genbki.pl,
43 # but the Makefile dependencies look more sensible this way.
44 # We currently only need pg_proc, but retain the possibility of reading
45 # more than one data file.
48 foreach my $datfile (@ARGV)
50 $datfile =~ /(.+)\.dat$/
51 or die "Input files need to be data (.dat) files.\n";
54 die "There in no header file corresponding to $datfile"
57 my $catalog = Catalog
::ParseHeader
($header);
58 my $catname = $catalog->{catname
};
59 my $schema = $catalog->{columns
};
61 $catalogs{$catname} = $catalog;
62 $catalog_data{$catname} = Catalog
::ParseData
($datfile, $schema, 0);
65 # Collect certain fields from pg_proc.dat.
69 foreach my $row (@
{ $catalog_data{pg_proc
} })
71 my %bki_values = %$row;
75 oid
=> $bki_values{oid
},
76 name
=> $bki_values{proname
},
77 lang
=> $bki_values{prolang
},
78 kind
=> $bki_values{prokind
},
79 strict
=> $bki_values{proisstrict
},
80 retset
=> $bki_values{proretset
},
81 nargs
=> $bki_values{pronargs
},
82 args
=> $bki_values{proargtypes
},
83 prosrc
=> $bki_values{prosrc
},
86 # Count so that we can detect overloaded pronames.
87 $proname_counts{ $bki_values{proname
} }++;
90 # Emit headers for both files
91 my $tmpext = ".tmp$$";
92 my $oidsfile = $output_path . 'fmgroids.h';
93 my $protosfile = $output_path . 'fmgrprotos.h';
94 my $tabfile = $output_path . 'fmgrtab.c';
96 open my $ofh, '>', $oidsfile . $tmpext
97 or die "Could not open $oidsfile$tmpext: $!";
98 open my $pfh, '>', $protosfile . $tmpext
99 or die "Could not open $protosfile$tmpext: $!";
100 open my $tfh, '>', $tabfile . $tmpext
101 or die "Could not open $tabfile$tmpext: $!";
104 /*-------------------------------------------------------------------------
107 * Macros that define the OIDs of built-in functions.
109 * These macros can be used to avoid a catalog lookup when a specific
110 * fmgr-callable function needs to be referenced.
112 * Portions Copyright (c) 1996-2024, PostgreSQL Global Development Group
113 * Portions Copyright (c) 1994, Regents of the University of California
116 * ******************************
117 * *** DO NOT EDIT THIS FILE! ***
118 * ******************************
120 * It has been GENERATED by src/backend/utils/Gen_fmgrtab.pl
122 *-------------------------------------------------------------------------
128 * Constant macros for the OIDs of entries in pg_proc.
130 * F_XXX macros are named after the proname field; if that is not unique,
131 * we append the proargtypes field, replacing spaces with underscores.
132 * For example, we have F_OIDEQ because that proname is unique, but
133 * F_POW_FLOAT8_FLOAT8 (among others) because that proname is not.
138 /*-------------------------------------------------------------------------
141 * Prototypes for built-in functions.
143 * Portions Copyright (c) 1996-2024, PostgreSQL Global Development Group
144 * Portions Copyright (c) 1994, Regents of the University of California
147 * ******************************
148 * *** DO NOT EDIT THIS FILE! ***
149 * ******************************
151 * It has been GENERATED by src/backend/utils/Gen_fmgrtab.pl
153 *-------------------------------------------------------------------------
164 /*-------------------------------------------------------------------------
167 * The function manager's table of internal functions.
169 * Portions Copyright (c) 1996-2024, PostgreSQL Global Development Group
170 * Portions Copyright (c) 1994, Regents of the University of California
174 * ******************************
175 * *** DO NOT EDIT THIS FILE! ***
176 * ******************************
178 * It has been GENERATED by src/backend/utils/Gen_fmgrtab.pl
180 *-------------------------------------------------------------------------
183 #include "postgres.h"
185 #include "utils/fmgrtab.h"
186 #include "utils/fmgrprotos.h"
190 # Emit fmgroids.h and fmgrprotos.h entries in OID order.
192 foreach my $s (sort { $a->{oid
} <=> $b->{oid
} } @fmgr)
194 my $sqlname = $s->{name
};
195 $sqlname .= "_" . $s->{args
} if ($proname_counts{ $s->{name
} } > 1);
196 $sqlname =~ s/\s+/_/g;
197 print $ofh "#define F_" . uc $sqlname . " $s->{oid}\n";
198 # We want only one extern per internal-language, non-aggregate function
199 if ( $s->{lang
} eq 'internal'
201 && !$seenit{ $s->{prosrc
} })
203 $seenit{ $s->{prosrc
} } = 1;
204 print $pfh "extern Datum $s->{prosrc}(PG_FUNCTION_ARGS);\n";
208 # Create the fmgr_builtins table, collect data for fmgr_builtin_oid_index
209 print $tfh "\nconst FmgrBuiltin fmgr_builtins[] = {\n";
212 $bmap{'f'} = 'false';
213 my @fmgr_builtin_oid_index;
214 my $last_builtin_oid = 0;
217 foreach my $s (sort { $a->{oid
} <=> $b->{oid
} } @fmgr)
219 next if $s->{lang
} ne 'internal';
220 # We do not need entries for aggregate functions
221 next if $s->{kind
} eq 'a';
223 print $tfh ",\n" if ($fmgr_count > 0);
225 " { $s->{oid}, $s->{nargs}, $bmap{$s->{strict}}, $bmap{$s->{retset}}, \"$s->{prosrc}\", $s->{prosrc} }";
227 $fmgr_builtin_oid_index[ $s->{oid
} ] = $fmgr_count++;
228 $last_builtin_oid = $s->{oid
};
233 const
int fmgr_nbuiltins
= (sizeof
(fmgr_builtins
) / sizeof
(FmgrBuiltin
));
235 const Oid fmgr_last_builtin_oid
= %u;
236 |, $last_builtin_oid;
239 # Create fmgr_builtin_oid_index table.
241 const uint16 fmgr_builtin_oid_index
[%u] = {
242 |, $last_builtin_oid + 1;
244 for (my $i = 0; $i <= $last_builtin_oid; $i++)
246 my $oid = $fmgr_builtin_oid_index[$i];
248 # fmgr_builtin_oid_index is sparse, map nonexistent functions to
249 # InvalidOidBuiltinMapping
250 if (not defined $oid)
252 $oid = 'InvalidOidBuiltinMapping';
255 if ($i == $last_builtin_oid)
257 print $tfh " $oid\n";
261 print $tfh " $oid,\n";
267 # And add the file footers.
268 print $ofh "\n#endif\t\t\t\t\t\t\t/* FMGROIDS_H */\n";
269 print $pfh "\n#endif\t\t\t\t\t\t\t/* FMGRPROTOS_H */\n";
275 # Finally, rename the completed files into place.
276 Catalog
::RenameTempFile
($oidsfile, $tmpext);
277 Catalog
::RenameTempFile
($protosfile, $tmpext);
278 Catalog
::RenameTempFile
($tabfile, $tmpext);
283 Usage: perl -I [directory of Catalog.pm] Gen_fmgrtab.pl [--include-path/-i <path>] [path to pg_proc.dat]
286 --output Output directory (default '.')
287 --include-path Include path in source tree
289 Gen_fmgrtab.pl generates fmgroids.h, fmgrprotos.h, and fmgrtab.c from
292 Report bugs to <pgsql-bugs\@lists.postgresql.org>.