Bug #4975
RETURNS RECORD can crash the server
Start date:
Due date:
% Done:
0%
Estimated time:
Resolution:
fixed
Description
A trivial "RETURNS RECORD" function can crash the server. An example:
CREATE OR REPLACE FUNCTION php_record(integer) RETURNS record LANGUAGE plphp AS $$ $ret['f1']=$argsr0; $ret['f2']="hello"; $ret['f3']="world"; return $ret; $$;
Calling this function as
SELECT * FROM php_record(1) AS (f1 integer, f2 text, f3 text);
crashes the server and leaves a coredump with the following backtrace:
#0 pg_detoast_datum (datum=0x7f7f7f7f) at /pg/source/00orig/src/backend/utils/fmgr/fmgr.c:1798 1798 if (VARATT_IS_EXTENDED(datum)) (gdb) bt #0 pg_detoast_datum (datum=0x7f7f7f7f) at /pg/source/00orig/src/backend/utils/fmgr/fmgr.c:1798 #4964 0x08145f6d in [[ExecMakeTableFunctionResult]] (funcexpr=0x83b9140, econtext=0x83b8d88, expectedDesc=0x83b8f20, returnDesc=0x7f7f7f7f) at /pg/source/00orig/src/backend/executor/execQual.c:1339 #4965 0x08152759 in [[FunctionNext]] (node=0x83b8cfc) at /pg/source/00orig/src/backend/executor/nodeFunctionscan.c:71 #4966 0x08147df2 in [[ExecScan]] (node=0x83b8cfc, accessMtd=0x81526c0 <FunctionNext>) at /pg/source/00orig/src/backend/executor/execScan.c:68 #4967 0x081522e4 in [[ExecFunctionScan]] (node=0x83b8cfc) at /pg/source/00orig/src/backend/executor/nodeFunctionscan.c:115 #4968 0x0814215f in [[ExecProcNode]] (node=0x83b8cfc) at /pg/source/00orig/src/backend/executor/execProcnode.c:343 #4969 0x08140bac in [[ExecutorRun]] (queryDesc=0x83b8808, direction=ForwardScanDirection, count=0) at /pg/source/00orig/src/backend/executor/execMain.c:1110 #4970 0x081cda04 in [[PortalRunSelect]] (portal=0x83b662c, forward=1 '\001', count=0, dest=0x83ac394) at /pg/source/00orig/src/backend/tcop/pquery.c:794 #4971 0x081ce88e in [[PortalRun]] (portal=0x83b662c, count=2147483647, dest=0x83ac394, altdest=0x83ac394, completionTag=0xbf8e6958 "") at /pg/source/00orig/src/backend/tcop/pquery.c:646 #4972 0x081ca4fe in exec_simple_query ( query_string=0x83ac17c "SELECT * FROM php_record(1) AS (f1 integer, f2 text, f3 text);") at /pg/source/00orig/src/backend/tcop/postgres.c:1002
The problem here seems to be that the result value is allocated in a context that is freed prior to Postgres having the opportunity to read it.