Re: Crash when calling a pl/pgsql function with no row to pass as an argument - Mailing list pgsql-bugs

From Tom Lane
Subject Re: Crash when calling a pl/pgsql function with no row to pass as an argument
Date
Msg-id 16335.1077587350@sss.pgh.pa.us
Whole thread Raw
In response to Crash when calling a pl/pgsql function with no row to pass as an argument  (Chris Campbell <chris@bignerdranch.com>)
List pgsql-bugs
Chris Campbell <chris@bignerdranch.com> writes:
> postmaster crashes if it tries to call a pl/plgsql function that
> requires a table row as an argument, and there is no row produced in
> the query that can be passed in. There is currently an assertion in the
> code to guard against this case, but it's not an error case, so it
> needs to be handled more gracefully than crashing. :)

I'm actually a bit surprised that there's no crash further upstream,
as the executor's code for handling whole-tuple variables is pretty
messy.  But yes, this needs to be fixed.

> Change the assertion protecting against this case in
> src/pl/plpgsql/src/pl_exec.c to an if statement, so that the row
> argument is only copied into the function's arguments if the row
> actually exists.

I think you need to do something to explicitly set up the row value
with NULLs.  Fortunately, exec_move_row will do that if you just pass
it a NULL tuple, so the fix as applied looks like

*** src/pl/plpgsql/src/pl_exec.c.orig    Tue Feb  3 12:34:04 2004
--- src/pl/plpgsql/src/pl_exec.c    Mon Feb 23 20:36:06 2004
***************
*** 262,271 ****
                      HeapTuple    tup;
                      TupleDesc    tupdesc;

!                     Assert(slot != NULL && !fcinfo->argnull[i]);
!                     tup = slot->val;
!                     tupdesc = slot->ttc_tupleDescriptor;
!                     exec_move_row(&estate, NULL, row, tup, tupdesc);
                  }
                  break;

--- 262,279 ----
                      HeapTuple    tup;
                      TupleDesc    tupdesc;

!                     if (!fcinfo->argnull[i])
!                     {
!                         Assert(slot != NULL);
!                         tup = slot->val;
!                         tupdesc = slot->ttc_tupleDescriptor;
!                         exec_move_row(&estate, NULL, row, tup, tupdesc);
!                     }
!                     else
!                     {
!                         /* If arg is null, treat it as an empty row */
!                         exec_move_row(&estate, NULL, row, NULL, NULL);
!                     }
                  }
                  break;


Thanks for the report!

            regards, tom lane

pgsql-bugs by date:

Previous
From: "PostgreSQL Bugs List"
Date:
Subject: BUG #1083: Insert query reordering interacts badly with NEXTVAL()/CURRVAL()
Next
From: Bruno Wolff III
Date:
Subject: Re: BUG #1083: Insert query reordering interacts badly with NEXTVAL()/CURRVAL()