aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils/Gen_fmgrtab.pl
blob: 6f67438d46b865e9c15eceb53b7ce97710e67b4d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
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;