mirror of https://github.com/postgres/postgres
in pg_proc. Also make it not emit duplicate extern declarations, and make it a bit more bulletproof in some other small ways. Likewise fix the equally hard-wired, and utterly undocumented, knowledge in the MSVC build scripts. For testing purposes and perhaps other uses in future, pull out that portion of the MSVC scripts into a standalone perl script equivalent to Gen_fmgrtab.sh, and make it generate actually identical output, rather than just more-or-less-the-same output. Motivated by looking at Pavel's variadic function patch. Whether or not that gets accepted, we can be sure that pg_proc's column set will change again in the future; it's time to not have to deal with this gotcha.REL8_5_ALPHA1_BRANCH
parent
dab421d2f0
commit
eeee06919f
@ -0,0 +1,194 @@ |
||||
#! /usr/bin/perl -w |
||||
#------------------------------------------------------------------------- |
||||
# |
||||
# 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. |
||||
# |
||||
# Portions Copyright (c) 1996-2008, 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.1 2008/06/23 17:54:29 tgl Exp $ |
||||
# |
||||
#------------------------------------------------------------------------- |
||||
|
||||
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>) |
||||
{ |
||||
if (m/#define Anum_pg_proc_proname\s+(\d+)/) { |
||||
$proname = $1; |
||||
} |
||||
if (m/#define Anum_pg_proc_prolang\s+(\d+)/) { |
||||
$prolang = $1; |
||||
} |
||||
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; |
||||
} |
||||
} |
||||
close(I); |
||||
|
||||
# Collect the raw data |
||||
my @fmgr = (); |
||||
|
||||
open(I, $infile) || die "Could not open $infile: $!"; |
||||
while (<I>) |
||||
{ |
||||
next unless (/^DATA/); |
||||
s/^[^O]*OID[^=]*=[ \t]*//; |
||||
s/\(//; |
||||
s/"[^"]*"/"xxx"/g; |
||||
my @p = split; |
||||
next if ($p[$prolang] ne "12"); |
||||
push @fmgr, |
||||
{ |
||||
oid => $p[0], |
||||
proname => $p[$proname], |
||||
strict => $p[$proisstrict], |
||||
retset => $p[$proretset], |
||||
nargs => $p[$pronargs], |
||||
prosrc => $p[$prosrc], |
||||
}; |
||||
} |
||||
close(I); |
||||
|
||||
# Emit headers for both files |
||||
open(H, '>', "$$-fmgroids.h") || die "Could not open $$-fmgroids.h: $!"; |
||||
print H |
||||
qq|/*------------------------------------------------------------------------- |
||||
* |
||||
* 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-2008, 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 $0 |
||||
* from $infile |
||||
* |
||||
*------------------------------------------------------------------------- |
||||
*/ |
||||
#ifndef FMGROIDS_H |
||||
#define FMGROIDS_H |
||||
|
||||
/* |
||||
* Constant macros for the OIDs of entries in pg_proc. |
||||
* |
||||
* NOTE: macros are named after the prosrc value, ie the actual C name |
||||
* of the implementing function, not the proname which may be overloaded. |
||||
* For example, we want to be able to assign different macro names to both |
||||
* char_text() and name_text() even though these both appear with proname |
||||
* 'text'. If the same C function appears in more than one pg_proc entry, |
||||
* its equivalent macro will be defined with the lowest OID among those |
||||
* entries. |
||||
*/ |
||||
|; |
||||
|
||||
open(T, '>', "$$-fmgrtab.c") || die "Could not open $$-fmgrtab.c: $!"; |
||||
print T |
||||
qq|/*------------------------------------------------------------------------- |
||||
* |
||||
* fmgrtab.c |
||||
* The function manager's table of internal functions. |
||||
* |
||||
* Portions Copyright (c) 1996-2008, 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 $0 |
||||
* from $infile |
||||
* |
||||
*------------------------------------------------------------------------- |
||||
*/ |
||||
|
||||
#include "postgres.h" |
||||
|
||||
#include "utils/fmgrtab.h" |
||||
|
||||
|; |
||||
|
||||
# Emit #define's and extern's -- only one per prosrc value |
||||
my %seenit; |
||||
foreach my $s (sort {$a->{oid} <=> $b->{oid}} @fmgr) |
||||
{ |
||||
next if $seenit{$s->{prosrc}}; |
||||
$seenit{$s->{prosrc}} = 1; |
||||
print H "#define F_" . uc $s->{prosrc} . " $s->{oid}\n"; |
||||
print T "extern Datum $s->{prosrc} (PG_FUNCTION_ARGS);\n"; |
||||
} |
||||
|
||||
# Create the fmgr_builtins table |
||||
print T "\nconst FmgrBuiltin fmgr_builtins[] = {\n"; |
||||
my %bmap; |
||||
$bmap{'t'} = 'true'; |
||||
$bmap{'f'} = 'false'; |
||||
foreach my $s (sort {$a->{oid} <=> $b->{oid}} @fmgr) |
||||
{ |
||||
print T |
||||
" { $s->{oid}, \"$s->{prosrc}\", $s->{nargs}, $bmap{$s->{strict}}, $bmap{$s->{retset}}, $s->{prosrc} },\n"; |
||||
} |
||||
|
||||
# And add the file footers. |
||||
print H "\n#endif /* FMGROIDS_H */\n"; |
||||
close(H); |
||||
|
||||
print T |
||||
qq| /* dummy entry is easier than getting rid of comma after last real one */ |
||||
/* (not that there has ever been anything wrong with *having* a |
||||
comma after the last field in an array initializer) */ |
||||
{ 0, NULL, 0, false, false, NULL } |
||||
}; |
||||
|
||||
/* Note fmgr_nbuiltins excludes the dummy entry */ |
||||
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: $!"; |
||||
|
||||
exit 0; |
||||
Loading…
Reference in new issue