Re: BUG #18172: High memory usage in tSRF function context - Mailing list pgsql-bugs

From Tom Lane
Subject Re: BUG #18172: High memory usage in tSRF function context
Date
Msg-id 1736370.1698463142@sss.pgh.pa.us
Whole thread Raw
In response to BUG #18172: High memory usage in tSRF function context  (PG Bug reporting form <noreply@postgresql.org>)
Responses Re:BUG #18172: High memory usage in tSRF function context  (Sergei Kornilov <sk@zsrv.org>)
List pgsql-bugs
PG Bug reporting form <noreply@postgresql.org> writes:
> While researching several cases of OOM, I discovered an atypically high
> memory consumption in this case:
> ...
> The first query consumes much more memory; note that it refers to a
> non-existent json key. Querying for a key that exists in JSON or checking
> for the existence of a key in where clause corrects memory consumption.

Thanks for the report!  It seems that ExecProjectSet neglected to
think hard about what happens when the SRF returns zero rows, so
it leaks whatever memory the SRF expression might have leaked.
The attached fixes it for me.

            regards, tom lane

diff --git a/src/backend/executor/nodeProjectSet.c b/src/backend/executor/nodeProjectSet.c
index b4bbdc89b1..307ac591be 100644
--- a/src/backend/executor/nodeProjectSet.c
+++ b/src/backend/executor/nodeProjectSet.c
@@ -72,20 +72,22 @@ ExecProjectSet(PlanState *pstate)
             return resultSlot;
     }

-    /*
-     * Reset argument context to free any expression evaluation storage
-     * allocated in the previous tuple cycle.  Note this can't happen until
-     * we're done projecting out tuples from a scan tuple, as ValuePerCall
-     * functions are allowed to reference the arguments for each returned
-     * tuple.
-     */
-    MemoryContextReset(node->argcontext);
-
     /*
      * Get another input tuple and project SRFs from it.
      */
     for (;;)
     {
+        /*
+         * Reset argument context to free any expression evaluation storage
+         * allocated in the previous tuple cycle.  Note this can't happen
+         * until we're done projecting out tuples from a scan tuple, as
+         * ValuePerCall functions are allowed to reference the arguments for
+         * each returned tuple.  However, if we loop around after finding that
+         * no rows are produced from a scan tuple, we should reset, as the SRF
+         * might well leak memory in that case.
+         */
+        MemoryContextReset(node->argcontext);
+
         /*
          * Retrieve tuples from the outer plan until there are no more.
          */

pgsql-bugs by date:

Previous
From: Alexander Korotkov
Date:
Subject: Re: BUG #18170: Unexpected error: no relation entry for relid 3
Next
From: Andrei Lepikhov
Date:
Subject: Re: BUG #18170: Unexpected error: no relation entry for relid 3