Getting rid of aggregate_dummy() - Mailing list pgsql-hackers

From Tom Lane
Subject Getting rid of aggregate_dummy()
Date
Msg-id 533989.1604263665@sss.pgh.pa.us
Whole thread Raw
Responses Re: Getting rid of aggregate_dummy()  (Heikki Linnakangas <hlinnaka@iki.fi>)
Re: Getting rid of aggregate_dummy()  (Isaac Morland <isaac.morland@gmail.com>)
List pgsql-hackers
While fooling with Gen_fmgrtab.pl for a nearby patch [1], I noticed
that fmgrtab.c had a lot of entries pointing at aggregate_dummy,
which seemed rather useless.  So I experimented with removing them.

It turns out that nodeWindowAgg.c is carelessly expecting them to be
there, because it does fmgr_info_cxt() on the target window function
even if it will never call it because it's a plain aggregate.
But that's pretty trivial to fix, just need to relocate that call.

With that, we don't actually need aggregate_dummy() to exist at
all, because it's never referenced.  Having "aggregate_dummy"
as the prosrc value for an aggregate function is now just a
random convention; any other string would do as well.  (We could
save a few bytes in pg_proc by choosing a shorter string, but
probably it's better to stick to the existing convention.)

Anyway, this saves about 3KB in fmgrtab.o, without any downside
that I can see.  If someone accidentally called an aggregate as
a normal function, they'd now get a different error message,
namely "internal function "aggregate_dummy" is not in internal lookup
table" instead of "aggregate function NNN called as normal function".
That doesn't really seem like a problem.

The attached patch is a delta over the one in [1].

            regards, tom lane

[1] https://www.postgresql.org/message-id/472274.1604258384%40sss.pgh.pa.us

diff --git a/src/backend/catalog/pg_aggregate.c b/src/backend/catalog/pg_aggregate.c
index 0cf1da6ebb..7664bb6285 100644
--- a/src/backend/catalog/pg_aggregate.c
+++ b/src/backend/catalog/pg_aggregate.c
@@ -620,7 +620,7 @@ AggregateCreate(const char *aggName,
                              GetUserId(),    /* proowner */
                              INTERNALlanguageId,    /* languageObjectId */
                              InvalidOid,    /* no validator */
-                             "aggregate_dummy", /* placeholder proc */
+                             "aggregate_dummy", /* placeholder (no such proc) */
                              NULL,    /* probin */
                              PROKIND_AGGREGATE,
                              false, /* security invoker (currently not
diff --git a/src/backend/executor/nodeAgg.c b/src/backend/executor/nodeAgg.c
index 75e5bbf209..d87677d659 100644
--- a/src/backend/executor/nodeAgg.c
+++ b/src/backend/executor/nodeAgg.c
@@ -4935,24 +4935,6 @@ AggRegisterCallback(FunctionCallInfo fcinfo,
 }


-/*
- * aggregate_dummy - dummy execution routine for aggregate functions
- *
- * This function is listed as the implementation (prosrc field) of pg_proc
- * entries for aggregate functions.  Its only purpose is to throw an error
- * if someone mistakenly executes such a function in the normal way.
- *
- * Perhaps someday we could assign real meaning to the prosrc field of
- * an aggregate?
- */
-Datum
-aggregate_dummy(PG_FUNCTION_ARGS)
-{
-    elog(ERROR, "aggregate function %u called as normal function",
-         fcinfo->flinfo->fn_oid);
-    return (Datum) 0;            /* keep compiler quiet */
-}
-
 /* ----------------------------------------------------------------
  *                        Parallel Query Support
  * ----------------------------------------------------------------
diff --git a/src/backend/executor/nodeWindowAgg.c b/src/backend/executor/nodeWindowAgg.c
index 4cc7da268d..de58df3d3f 100644
--- a/src/backend/executor/nodeWindowAgg.c
+++ b/src/backend/executor/nodeWindowAgg.c
@@ -2446,11 +2446,6 @@ ExecInitWindowAgg(WindowAgg *node, EState *estate, int eflags)
         perfuncstate->wfuncstate = wfuncstate;
         perfuncstate->wfunc = wfunc;
         perfuncstate->numArguments = list_length(wfuncstate->args);
-
-        fmgr_info_cxt(wfunc->winfnoid, &perfuncstate->flinfo,
-                      econtext->ecxt_per_query_memory);
-        fmgr_info_set_expr((Node *) wfunc, &perfuncstate->flinfo);
-
         perfuncstate->winCollation = wfunc->inputcollid;

         get_typlenbyval(wfunc->wintype,
@@ -2479,6 +2474,11 @@ ExecInitWindowAgg(WindowAgg *node, EState *estate, int eflags)
             winobj->argstates = wfuncstate->args;
             winobj->localmem = NULL;
             perfuncstate->winobj = winobj;
+
+            /* It's a real window function, so set up to call it. */
+            fmgr_info_cxt(wfunc->winfnoid, &perfuncstate->flinfo,
+                          econtext->ecxt_per_query_memory);
+            fmgr_info_set_expr((Node *) wfunc, &perfuncstate->flinfo);
         }
     }

diff --git a/src/backend/utils/Gen_fmgrtab.pl b/src/backend/utils/Gen_fmgrtab.pl
index 1edd5195d7..34e27950e7 100644
--- a/src/backend/utils/Gen_fmgrtab.pl
+++ b/src/backend/utils/Gen_fmgrtab.pl
@@ -75,6 +75,7 @@ foreach my $row (@{ $catalog_data{pg_proc} })
         oid    => $bki_values{oid},
         name   => $bki_values{proname},
         lang   => $bki_values{prolang},
+        kind   => $bki_values{prokind},
         strict => $bki_values{proisstrict},
         retset => $bki_values{proretset},
         nargs  => $bki_values{pronargs},
@@ -195,8 +196,10 @@ foreach my $s (sort { $a->{oid} <=> $b->{oid} } @fmgr)
     $sqlname .= "_" . $s->{args} if ($proname_counts{ $s->{name} } > 1);
     $sqlname =~ tr/ /_/;
     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} })
+    # We want only one extern per internal-language, non-aggregate function
+    if (   $s->{lang} eq 'internal'
+        && $s->{kind} ne 'a'
+        && !$seenit{ $s->{prosrc} })
     {
         $seenit{ $s->{prosrc} } = 1;
         print $pfh "extern Datum $s->{prosrc}(PG_FUNCTION_ARGS);\n";
@@ -214,6 +217,8 @@ my $fmgr_count       = 0;
 foreach my $s (sort { $a->{oid} <=> $b->{oid} } @fmgr)
 {
     next if $s->{lang} ne 'internal';
+    # We do not need entries for aggregate functions
+    next if $s->{kind} eq 'a';

     print $tfh ",\n" if ($fmgr_count > 0);
     print $tfh

pgsql-hackers by date:

Previous
From: Tom Lane
Date:
Subject: Getting Gen_fmgrtab.pl to generate macros for all pg_proc entries
Next
From: Daniel Gustafsson
Date:
Subject: Re: Support for NSS as a libpq TLS backend