summaryrefslogtreecommitdiff
path: root/src/backend/utils/Gen_fmgrtab.sh
blob: f9371bb2f86bf20c97e498761d75e7cf5b93086f (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
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
#! /bin/sh
#-------------------------------------------------------------------------
#
# Gen_fmgrtab.sh
#    shell script to generate fmgroids.h and fmgrtab.c from pg_proc.h
#
# NOTE: if you change this, you need to fix Gen_fmgrtab.pl too!
#
# Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
# Portions Copyright (c) 1994, Regents of the University of California
#
#
# IDENTIFICATION
#    $PostgreSQL: pgsql/src/backend/utils/Gen_fmgrtab.sh,v 1.41 2009/01/01 17:23:48 momjian Exp $
#
#-------------------------------------------------------------------------

CMDNAME=`basename $0`

if [ x"$AWK" = x"" ]; then
	AWK=awk
fi

cleanup(){
    [ x"$noclean" != x"t" ] && rm -f "$SORTEDFILE" "$$-$OIDSFILE" "$$-$TABLEFILE"
}

noclean=

#
# Process command line switches.
#
while [ $# -gt 0 ]
do
    case $1 in
        --noclean)
            noclean=t
            ;;
        --help)
            echo "$CMDNAME generates fmgroids.h and fmgrtab.c from pg_proc.h."
            echo
            echo "Usage:"
            echo "  $CMDNAME inputfile"
            echo
            echo "The environment variable AWK determines which Awk program"
            echo "to use. The default is \`awk'."
            echo
            echo "Report bugs to <pgsql-bugs@postgresql.org>."
            exit 0
            ;;
        -*)
            echo "$CMDNAME: invalid option: $1"
            exit 1
            ;;
        *)
            INFILE=$1
            ;;
    esac
    shift
done


if [ x"$INFILE" = x ] ; then
    echo "$CMDNAME: no input file"
    exit 1
fi

SORTEDFILE="$$-fmgr.data"
OIDSFILE=fmgroids.h
TABLEFILE=fmgrtab.c


trap 'echo "Caught signal." ; cleanup ; exit 1' 1 2 15

#
# Collect the column numbers of the pg_proc columns we need.  Because we will
# be looking at data that includes the OID as the first column, add one to
# each column number.
#
proname=`egrep '^#define Anum_pg_proc_proname[ 	]' $INFILE | $AWK '{print $3+1}'`
prolang=`egrep '^#define Anum_pg_proc_prolang[ 	]' $INFILE | $AWK '{print $3+1}'`
proisstrict=`egrep '^#define Anum_pg_proc_proisstrict[ 	]' $INFILE | $AWK '{print $3+1}'`
proretset=`egrep '^#define Anum_pg_proc_proretset[ 	]' $INFILE | $AWK '{print $3+1}'`
pronargs=`egrep '^#define Anum_pg_proc_pronargs[ 	]' $INFILE | $AWK '{print $3+1}'`
prosrc=`egrep '^#define Anum_pg_proc_prosrc[ 	]' $INFILE | $AWK '{print $3+1}'`

#
# Generate the file containing raw pg_proc data.  We do three things here:
# 1. Strip off the DATA macro call, leaving procedure OID as $1
# and all the pg_proc field values as $2, $3, etc on each line.
# 2. Fold quoted fields to simple "xxx".  We need this because such fields
# may contain whitespace, which would confuse awk's counting of fields.
# Fortunately, this script doesn't need to look at any fields that might
# need quoting, so this simple hack is sufficient.
# 3. Select out just the rows for internal-language procedures.
#
# Note assumption here that INTERNALlanguageId == 12.
#
egrep '^DATA' $INFILE | \
sed 	-e 's/^[^O]*OID[^=]*=[ 	]*//' \
	-e 's/(//' \
	-e 's/"[^"]*"/"xxx"/g' | \
$AWK "\$$prolang == \"12\" { print }" | \
sort -n > $SORTEDFILE

if [ $? -ne 0 ]; then
    cleanup
    echo "$CMDNAME failed"
    exit 1
fi


cpp_define=`echo $OIDSFILE | tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ | sed -e 's/[^ABCDEFGHIJKLMNOPQRSTUVWXYZ]/_/g'`

#
# Generate fmgroids.h
#
cat > "$$-$OIDSFILE" <<FuNkYfMgRsTuFf
/*-------------------------------------------------------------------------
 *
 * $OIDSFILE
 *    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-2009, 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 $CMDNAME
 *	from $INFILE
 *
 *-------------------------------------------------------------------------
 */
#ifndef $cpp_define
#define $cpp_define

/*
 *	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.
 */
FuNkYfMgRsTuFf

tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' < $SORTEDFILE | \
$AWK "{ if (seenit[\$$prosrc]++ == 0)
	printf \"#define F_%s %s\\n\", \$$prosrc, \$1; }" >> "$$-$OIDSFILE"

if [ $? -ne 0 ]; then
    cleanup
    echo "$CMDNAME failed"
    exit 1
fi

cat >> "$$-$OIDSFILE" <<FuNkYfMgRsTuFf

#endif /* $cpp_define */
FuNkYfMgRsTuFf

#
# Generate fmgr's built-in-function table.
#
# Print out the function declarations, then the table that refers to them.
#
cat > "$$-$TABLEFILE" <<FuNkYfMgRtAbStUfF
/*-------------------------------------------------------------------------
 *
 * $TABLEFILE
 *    The function manager's table of internal functions.
 *
 * Portions Copyright (c) 1996-2009, 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 $CMDNAME
 *	from $INFILE
 *
 *-------------------------------------------------------------------------
 */

#include "postgres.h"

#include "utils/fmgrtab.h"

FuNkYfMgRtAbStUfF

$AWK "{ if (seenit[\$$prosrc]++ == 0)
	print \"extern Datum\", \$$prosrc, \"(PG_FUNCTION_ARGS);\"; }" $SORTEDFILE >> "$$-$TABLEFILE"

if [ $? -ne 0 ]; then
    cleanup
    echo "$CMDNAME failed"
    exit 1
fi


cat >> "$$-$TABLEFILE" <<FuNkYfMgRtAbStUfF

const FmgrBuiltin fmgr_builtins[] = {
FuNkYfMgRtAbStUfF

# Note: using awk arrays to translate from pg_proc values to fmgrtab values
# may seem tedious, but avoid the temptation to write a quick x?y:z
# conditional expression instead.  Not all awks have conditional expressions.

$AWK "BEGIN {
    Bool[\"t\"] = \"true\";
    Bool[\"f\"] = \"false\";
}
{ printf (\"  { %d, \\\"%s\\\", %d, %s, %s, %s },\\n\"),
	\$1, \$$prosrc, \$$pronargs, Bool[\$$proisstrict], Bool[\$$proretset], \$$prosrc ;
}" $SORTEDFILE >> "$$-$TABLEFILE"

if [ $? -ne 0 ]; then
    cleanup
    echo "$CMDNAME failed"
    exit 1
fi

cat >> "$$-$TABLEFILE" <<FuNkYfMgRtAbStUfF
  /* 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;
FuNkYfMgRtAbStUfF

# We use the temporary files to avoid problems with concurrent runs
# (which can happen during parallel make).
mv "$$-$OIDSFILE" $OIDSFILE
mv "$$-$TABLEFILE" $TABLEFILE

cleanup
exit 0