diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2020-11-02 11:57:28 -0500 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2020-11-02 11:57:28 -0500 |
commit | 8e1f37c07aafd4bb7aa6e1e1982010af11f8b5c7 (patch) | |
tree | 93e0b3994b9a79e4f3342d2a4f74c3547ca7e3d8 /src | |
parent | fd2997565c6f66837440dd57f5e52b56aa964d14 (diff) | |
download | postgresql-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.c | 2 | ||||
-rw-r--r-- | src/backend/utils/Gen_fmgrtab.pl | 51 | ||||
-rw-r--r-- | src/backend/utils/adt/ruleutils.c | 2 |
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; |