2008-06-23 19:54:30 +02:00
|
|
|
#! /usr/bin/perl -w
|
|
|
|
#-------------------------------------------------------------------------
|
|
|
|
#
|
|
|
|
# Gen_fmgrtab.pl
|
2010-01-05 02:06:57 +01:00
|
|
|
# Perl script that generates fmgroids.h and fmgrtab.c from pg_proc.h
|
2008-06-23 19:54:30 +02:00
|
|
|
#
|
2012-01-02 00:01:58 +01:00
|
|
|
# Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group
|
2008-06-23 19:54:30 +02:00
|
|
|
# Portions Copyright (c) 1994, Regents of the University of California
|
|
|
|
#
|
|
|
|
#
|
|
|
|
# IDENTIFICATION
|
2010-09-20 22:08:53 +02:00
|
|
|
# src/backend/utils/Gen_fmgrtab.pl
|
2008-06-23 19:54:30 +02:00
|
|
|
#
|
|
|
|
#-------------------------------------------------------------------------
|
|
|
|
|
2010-01-05 02:06:57 +01:00
|
|
|
use Catalog;
|
|
|
|
|
2008-06-23 19:54:30 +02:00
|
|
|
use strict;
|
|
|
|
use warnings;
|
|
|
|
|
|
|
|
# Collect arguments
|
2012-07-05 03:47:49 +02:00
|
|
|
my $infile; # pg_proc.h
|
2010-01-05 02:06:57 +01:00
|
|
|
my $output_path = '';
|
|
|
|
while (@ARGV)
|
2008-06-23 19:54:30 +02:00
|
|
|
{
|
2012-07-05 03:47:49 +02:00
|
|
|
my $arg = shift @ARGV;
|
|
|
|
if ($arg !~ /^-/)
|
|
|
|
{
|
|
|
|
$infile = $arg;
|
|
|
|
}
|
|
|
|
elsif ($arg =~ /^-o/)
|
|
|
|
{
|
|
|
|
$output_path = length($arg) > 2 ? substr($arg, 2) : shift @ARGV;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
usage();
|
|
|
|
}
|
2008-06-23 19:54:30 +02:00
|
|
|
}
|
|
|
|
|
2010-01-05 02:06:57 +01:00
|
|
|
# Make sure output_path ends in a slash.
|
|
|
|
if ($output_path ne '' && substr($output_path, -1) ne '/')
|
|
|
|
{
|
2012-07-05 03:47:49 +02:00
|
|
|
$output_path .= '/';
|
2010-01-05 02:06:57 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
# Read all the data from the include/catalog files.
|
|
|
|
my $catalogs = Catalog::Catalogs($infile);
|
|
|
|
|
|
|
|
# Collect the raw data from pg_proc.h.
|
2008-06-23 19:54:30 +02:00
|
|
|
my @fmgr = ();
|
2010-01-05 02:06:57 +01:00
|
|
|
my @attnames;
|
2012-07-05 03:47:49 +02:00
|
|
|
foreach my $column (@{ $catalogs->{pg_proc}->{columns} })
|
2010-01-05 02:06:57 +01:00
|
|
|
{
|
2012-07-05 03:47:49 +02:00
|
|
|
push @attnames, keys %$column;
|
2010-01-05 02:06:57 +01:00
|
|
|
}
|
2008-06-23 19:54:30 +02:00
|
|
|
|
2010-01-05 02:06:57 +01:00
|
|
|
my $data = $catalogs->{pg_proc}->{data};
|
|
|
|
foreach my $row (@$data)
|
2008-06-23 19:54:30 +02:00
|
|
|
{
|
2012-07-05 03:47:49 +02:00
|
|
|
|
|
|
|
# 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 => $row->{oid},
|
|
|
|
strict => $row->{proisstrict},
|
|
|
|
retset => $row->{proretset},
|
|
|
|
nargs => $row->{pronargs},
|
|
|
|
prosrc => $row->{prosrc}, };
|
|
|
|
|
|
|
|
# Hack to work around memory leak in some versions of Perl
|
|
|
|
$row = undef;
|
2008-06-23 19:54:30 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
# Emit headers for both files
|
2012-07-05 03:47:49 +02:00
|
|
|
my $tmpext = ".tmp$$";
|
2010-01-05 21:23:32 +01:00
|
|
|
my $oidsfile = $output_path . 'fmgroids.h';
|
2012-07-05 03:47:49 +02:00
|
|
|
my $tabfile = $output_path . 'fmgrtab.c';
|
2010-01-05 21:23:32 +01:00
|
|
|
|
|
|
|
open H, '>', $oidsfile . $tmpext or die "Could not open $oidsfile$tmpext: $!";
|
2012-07-05 03:47:49 +02:00
|
|
|
open T, '>', $tabfile . $tmpext or die "Could not open $tabfile$tmpext: $!";
|
2010-01-05 21:23:32 +01:00
|
|
|
|
2010-11-23 21:27:50 +01:00
|
|
|
print H
|
2008-06-23 19:54:30 +02:00
|
|
|
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.
|
|
|
|
*
|
2012-07-06 18:28:18 +02:00
|
|
|
* Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group
|
2008-06-23 19:54:30 +02:00
|
|
|
* 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.
|
|
|
|
*/
|
|
|
|
|;
|
|
|
|
|
|
|
|
print T
|
|
|
|
qq|/*-------------------------------------------------------------------------
|
|
|
|
*
|
|
|
|
* fmgrtab.c
|
|
|
|
* The function manager's table of internal functions.
|
|
|
|
*
|
2012-07-06 18:28:18 +02:00
|
|
|
* Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group
|
2008-06-23 19:54:30 +02:00
|
|
|
* 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;
|
2012-07-05 03:47:49 +02:00
|
|
|
foreach my $s (sort { $a->{oid} <=> $b->{oid} } @fmgr)
|
2008-06-23 19:54:30 +02:00
|
|
|
{
|
2012-07-05 03:47:49 +02:00
|
|
|
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";
|
2008-06-23 19:54:30 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
# Create the fmgr_builtins table
|
|
|
|
print T "\nconst FmgrBuiltin fmgr_builtins[] = {\n";
|
|
|
|
my %bmap;
|
|
|
|
$bmap{'t'} = 'true';
|
|
|
|
$bmap{'f'} = 'false';
|
2012-07-05 03:47:49 +02:00
|
|
|
foreach my $s (sort { $a->{oid} <=> $b->{oid} } @fmgr)
|
2008-06-23 19:54:30 +02:00
|
|
|
{
|
2012-07-05 03:47:49 +02:00
|
|
|
print T
|
|
|
|
" { $s->{oid}, \"$s->{prosrc}\", $s->{nargs}, $bmap{$s->{strict}}, $bmap{$s->{retset}}, $s->{prosrc} },\n";
|
2008-06-23 19:54:30 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
# And add the file footers.
|
|
|
|
print H "\n#endif /* FMGROIDS_H */\n";
|
|
|
|
|
|
|
|
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;
|
|
|
|
|;
|
|
|
|
|
2010-01-05 21:23:32 +01:00
|
|
|
close(H);
|
2008-06-23 19:54:30 +02:00
|
|
|
close(T);
|
|
|
|
|
|
|
|
# Finally, rename the completed files into place.
|
2010-01-05 21:23:32 +01:00
|
|
|
Catalog::RenameTempFile($oidsfile, $tmpext);
|
2012-07-05 03:47:49 +02:00
|
|
|
Catalog::RenameTempFile($tabfile, $tmpext);
|
2010-01-05 02:06:57 +01:00
|
|
|
|
|
|
|
sub usage
|
|
|
|
{
|
2012-07-05 03:47:49 +02:00
|
|
|
die <<EOM;
|
2010-01-05 02:06:57 +01:00
|
|
|
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
|
|
|
|
}
|
2008-06-23 19:54:30 +02:00
|
|
|
|
|
|
|
exit 0;
|