Skip to content

Commit 8e1f37c

Browse files
committed
Rethink the generation rule for fmgroids.h macros.
Traditionally, the names of fmgroids.h macros for pg_proc OIDs have been constructed from the prosrc field. But sometimes the same C function underlies multiple pg_proc entries, forcing us to make an arbitrary choice of which OID to reference; the other entries are then not namable via fmgroids.h. Moreover, we could not have macros at all for pg_proc entries that aren't for C-coded functions. Instead, use the proname field, and append the proargtypes field (replacing inter-argument spaces with underscores) if proname is not unique. Special-casing unique entries such as F_OIDEQ removes the need to change a lot of code. Indeed, I can only find two places in the tree that need to be adjusted; while this changes quite a few existing entries in fmgroids.h, few of them are referenced from C code. With this patch, all entries in pg_proc.dat have macros in fmgroids.h. Discussion: https://postgr.es/m/472274.1604258384@sss.pgh.pa.us
1 parent fd29975 commit 8e1f37c

File tree

3 files changed

+28
-27
lines changed

3 files changed

+28
-27
lines changed

src/backend/optimizer/util/clauses.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -779,7 +779,7 @@ contain_volatile_functions_not_nextval(Node *clause)
779779
static bool
780780
contain_volatile_functions_not_nextval_checker(Oid func_id, void *context)
781781
{
782-
return (func_id != F_NEXTVAL_OID &&
782+
return (func_id != F_NEXTVAL &&
783783
func_volatile(func_id) == PROVOLATILE_VOLATILE);
784784
}
785785

src/backend/utils/Gen_fmgrtab.pl

Lines changed: 26 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -64,22 +64,26 @@
6464

6565
# Collect certain fields from pg_proc.dat.
6666
my @fmgr = ();
67+
my %proname_counts;
6768

6869
foreach my $row (@{ $catalog_data{pg_proc} })
6970
{
7071
my %bki_values = %$row;
7172

72-
# Select out just the rows for internal-language procedures.
73-
next if $bki_values{prolang} ne 'internal';
74-
7573
push @fmgr,
7674
{
7775
oid => $bki_values{oid},
76+
name => $bki_values{proname},
77+
lang => $bki_values{prolang},
7878
strict => $bki_values{proisstrict},
7979
retset => $bki_values{proretset},
8080
nargs => $bki_values{pronargs},
81+
args => $bki_values{proargtypes},
8182
prosrc => $bki_values{prosrc},
8283
};
84+
85+
# Count so that we can detect overloaded pronames.
86+
$proname_counts{ $bki_values{proname} }++;
8387
}
8488

8589
# Emit headers for both files
@@ -122,13 +126,10 @@
122126
/*
123127
* Constant macros for the OIDs of entries in pg_proc.
124128
*
125-
* NOTE: macros are named after the prosrc value, ie the actual C name
126-
* of the implementing function, not the proname which may be overloaded.
127-
* For example, we want to be able to assign different macro names to both
128-
* char_text() and name_text() even though these both appear with proname
129-
* 'text'. If the same C function appears in more than one pg_proc entry,
130-
* its equivalent macro will be defined with the lowest OID among those
131-
* entries.
129+
* F_XXX macros are named after the proname field; if that is not unique,
130+
* we append the proargtypes field, replacing spaces with underscores.
131+
* For example, we have F_OIDEQ because that proname is unique, but
132+
* F_POW_FLOAT8_FLOAT8 (among others) because that proname is not.
132133
*/
133134
OFH
134135

@@ -186,14 +187,20 @@
186187
187188
TFH
188189

189-
# Emit #define's and extern's -- only one per prosrc value
190+
# Emit fmgroids.h and fmgrprotos.h entries in OID order.
190191
my %seenit;
191192
foreach my $s (sort { $a->{oid} <=> $b->{oid} } @fmgr)
192193
{
193-
next if $seenit{ $s->{prosrc} };
194-
$seenit{ $s->{prosrc} } = 1;
195-
print $ofh "#define F_" . uc $s->{prosrc} . " $s->{oid}\n";
196-
print $pfh "extern Datum $s->{prosrc}(PG_FUNCTION_ARGS);\n";
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 function
199+
if ($s->{lang} eq 'internal' && !$seenit{ $s->{prosrc} })
200+
{
201+
$seenit{ $s->{prosrc} } = 1;
202+
print $pfh "extern Datum $s->{prosrc}(PG_FUNCTION_ARGS);\n";
203+
}
197204
}
198205

199206
# Create the fmgr_builtins table, collect data for fmgr_builtin_oid_index
@@ -206,22 +213,16 @@
206213
my $fmgr_count = 0;
207214
foreach my $s (sort { $a->{oid} <=> $b->{oid} } @fmgr)
208215
{
216+
next if $s->{lang} ne 'internal';
217+
218+
print $tfh ",\n" if ($fmgr_count > 0);
209219
print $tfh
210220
" { $s->{oid}, $s->{nargs}, $bmap{$s->{strict}}, $bmap{$s->{retset}}, \"$s->{prosrc}\", $s->{prosrc} }";
211221

212222
$fmgr_builtin_oid_index[ $s->{oid} ] = $fmgr_count++;
213223
$last_builtin_oid = $s->{oid};
214-
215-
if ($fmgr_count <= $#fmgr)
216-
{
217-
print $tfh ",\n";
218-
}
219-
else
220-
{
221-
print $tfh "\n";
222-
}
223224
}
224-
print $tfh "};\n";
225+
print $tfh "\n};\n";
225226

226227
printf $tfh qq|
227228
const int fmgr_nbuiltins = (sizeof(fmgr_builtins) / sizeof(FmgrBuiltin));

src/backend/utils/adt/ruleutils.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10144,7 +10144,7 @@ get_from_clause_item(Node *jtnode, Query *query, deparse_context *context)
1014410144
RangeTblFunction *rtfunc = (RangeTblFunction *) lfirst(lc);
1014510145

1014610146
if (!IsA(rtfunc->funcexpr, FuncExpr) ||
10147-
((FuncExpr *) rtfunc->funcexpr)->funcid != F_ARRAY_UNNEST ||
10147+
((FuncExpr *) rtfunc->funcexpr)->funcid != F_UNNEST_ANYARRAY ||
1014810148
rtfunc->funccolnames != NIL)
1014910149
{
1015010150
all_unnest = false;

0 commit comments

Comments
 (0)