aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2020-11-02 11:57:28 -0500
committerTom Lane <tgl@sss.pgh.pa.us>2020-11-02 11:57:28 -0500
commit8e1f37c07aafd4bb7aa6e1e1982010af11f8b5c7 (patch)
tree93e0b3994b9a79e4f3342d2a4f74c3547ca7e3d8 /src
parentfd2997565c6f66837440dd57f5e52b56aa964d14 (diff)
downloadpostgresql-8e1f37c07aafd4bb7aa6e1e1982010af11f8b5c7.tar.gz
postgresql-8e1f37c07aafd4bb7aa6e1e1982010af11f8b5c7.zip
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
Diffstat (limited to 'src')
-rw-r--r--src/backend/optimizer/util/clauses.c2
-rw-r--r--src/backend/utils/Gen_fmgrtab.pl51
-rw-r--r--src/backend/utils/adt/ruleutils.c2
3 files changed, 28 insertions, 27 deletions
diff --git a/src/backend/optimizer/util/clauses.c b/src/backend/optimizer/util/clauses.c
index e7d814651b1..85ef873caaf 100644
--- a/src/backend/optimizer/util/clauses.c
+++ b/src/backend/optimizer/util/clauses.c
@@ -779,7 +779,7 @@ contain_volatile_functions_not_nextval(Node *clause)
static bool
contain_volatile_functions_not_nextval_checker(Oid func_id, void *context)
{
- return (func_id != F_NEXTVAL_OID &&
+ return (func_id != F_NEXTVAL &&
func_volatile(func_id) == PROVOLATILE_VOLATILE);
}
diff --git a/src/backend/utils/Gen_fmgrtab.pl b/src/backend/utils/Gen_fmgrtab.pl
index b7c7b4c8fae..8228ad6db60 100644
--- a/src/backend/utils/Gen_fmgrtab.pl
+++ b/src/backend/utils/Gen_fmgrtab.pl
@@ -64,22 +64,26 @@ foreach my $datfile (@ARGV)
# Collect certain fields from pg_proc.dat.
my @fmgr = ();
+my %proname_counts;
foreach my $row (@{ $catalog_data{pg_proc} })
{
my %bki_values = %$row;
- # Select out just the rows for internal-language procedures.
- next if $bki_values{prolang} ne 'internal';
-
push @fmgr,
{
oid => $bki_values{oid},
+ name => $bki_values{proname},
+ lang => $bki_values{prolang},
strict => $bki_values{proisstrict},
retset => $bki_values{proretset},
nargs => $bki_values{pronargs},
+ args => $bki_values{proargtypes},
prosrc => $bki_values{prosrc},
};
+
+ # Count so that we can detect overloaded pronames.
+ $proname_counts{ $bki_values{proname} }++;
}
# Emit headers for both files
@@ -122,13 +126,10 @@ print $ofh <<OFH;
/*
* 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.
+ * F_XXX macros are named after the proname field; if that is not unique,
+ * we append the proargtypes field, replacing spaces with underscores.
+ * For example, we have F_OIDEQ because that proname is unique, but
+ * F_POW_FLOAT8_FLOAT8 (among others) because that proname is not.
*/
OFH
@@ -186,14 +187,20 @@ print $tfh <<TFH;
TFH
-# Emit #define's and extern's -- only one per prosrc value
+# Emit fmgroids.h and fmgrprotos.h entries in OID order.
my %seenit;
foreach my $s (sort { $a->{oid} <=> $b->{oid} } @fmgr)
{
- next if $seenit{ $s->{prosrc} };
- $seenit{ $s->{prosrc} } = 1;
- print $ofh "#define F_" . uc $s->{prosrc} . " $s->{oid}\n";
- print $pfh "extern Datum $s->{prosrc}(PG_FUNCTION_ARGS);\n";
+ my $sqlname = $s->{name};
+ $sqlname .= "_" . $s->{args} if ($proname_counts{ $s->{name} } > 1);
+ $sqlname =~ s/\s+/_/g;
+ print $ofh "#define F_" . uc $sqlname . " $s->{oid}\n";
+ # We want only one extern per internal-language function
+ if ($s->{lang} eq 'internal' && !$seenit{ $s->{prosrc} })
+ {
+ $seenit{ $s->{prosrc} } = 1;
+ print $pfh "extern Datum $s->{prosrc}(PG_FUNCTION_ARGS);\n";
+ }
}
# Create the fmgr_builtins table, collect data for fmgr_builtin_oid_index
@@ -206,22 +213,16 @@ my $last_builtin_oid = 0;
my $fmgr_count = 0;
foreach my $s (sort { $a->{oid} <=> $b->{oid} } @fmgr)
{
+ next if $s->{lang} ne 'internal';
+
+ print $tfh ",\n" if ($fmgr_count > 0);
print $tfh
" { $s->{oid}, $s->{nargs}, $bmap{$s->{strict}}, $bmap{$s->{retset}}, \"$s->{prosrc}\", $s->{prosrc} }";
$fmgr_builtin_oid_index[ $s->{oid} ] = $fmgr_count++;
$last_builtin_oid = $s->{oid};
-
- if ($fmgr_count <= $#fmgr)
- {
- print $tfh ",\n";
- }
- else
- {
- print $tfh "\n";
- }
}
-print $tfh "};\n";
+print $tfh "\n};\n";
printf $tfh qq|
const int fmgr_nbuiltins = (sizeof(fmgr_builtins) / sizeof(FmgrBuiltin));
diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c
index 6c656586e85..74461932529 100644
--- a/src/backend/utils/adt/ruleutils.c
+++ b/src/backend/utils/adt/ruleutils.c
@@ -10144,7 +10144,7 @@ get_from_clause_item(Node *jtnode, Query *query, deparse_context *context)
RangeTblFunction *rtfunc = (RangeTblFunction *) lfirst(lc);
if (!IsA(rtfunc->funcexpr, FuncExpr) ||
- ((FuncExpr *) rtfunc->funcexpr)->funcid != F_ARRAY_UNNEST ||
+ ((FuncExpr *) rtfunc->funcexpr)->funcid != F_UNNEST_ANYARRAY ||
rtfunc->funccolnames != NIL)
{
all_unnest = false;