@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $ PostgreSQL : pgsql / src / backend / utils / fmgr / fmgr . c , v 1.124 2009 / 01 / 01 17 : 23 : 51 momjian Exp $
* $ PostgreSQL : pgsql / src / backend / utils / fmgr / fmgr . c , v 1.125 2009 / 01 / 07 20 : 38 : 56 tgl Exp $
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
*/
@ -19,6 +19,7 @@
# include "catalog/pg_language.h"
# include "catalog/pg_proc.h"
# include "executor/functions.h"
# include "executor/spi.h"
# include "lib/stringinfo.h"
# include "miscadmin.h"
# include "nodes/nodeFuncs.h"
@ -1846,16 +1847,25 @@ OidFunctionCall9(Oid functionId, Datum arg1, Datum arg2,
* the caller should assume the result is NULL , but we ' ll call the input
* function anyway if it ' s not strict . So this is almost but not quite
* the same as FunctionCall3 .
*
* One important difference from the bare function call is that we will
* push any active SPI context , allowing SPI - using I / O functions to be
* called from other SPI functions without extra notation . This is a hack ,
* but the alternative of expecting all SPI functions to do SPI_push / SPI_pop
* around I / O calls seems worse .
*/
Datum
InputFunctionCall ( FmgrInfo * flinfo , char * str , Oid typioparam , int32 typmod )
{
FunctionCallInfoData fcinfo ;
Datum result ;
bool pushed ;
if ( str = = NULL & & flinfo - > fn_strict )
return ( Datum ) 0 ; /* just return null result */
pushed = SPI_push_conditional ( ) ;
InitFunctionCallInfoData ( fcinfo , flinfo , 3 , NULL , NULL ) ;
fcinfo . arg [ 0 ] = CStringGetDatum ( str ) ;
@ -1881,6 +1891,8 @@ InputFunctionCall(FmgrInfo *flinfo, char *str, Oid typioparam, int32 typmod)
fcinfo . flinfo - > fn_oid ) ;
}
SPI_pop_conditional ( pushed ) ;
return result ;
}
@ -1889,13 +1901,22 @@ InputFunctionCall(FmgrInfo *flinfo, char *str, Oid typioparam, int32 typmod)
*
* Do not call this on NULL datums .
*
* This is mere window dressing for FunctionCall1 , but its use is recommended
* anyway so that code invoking output functions can be identified easily .
* This is almost just window dressing for FunctionCall1 , but it includes
* SPI context pushing for the same reasons as InputFunctionCall .
*/
char *
OutputFunctionCall ( FmgrInfo * flinfo , Datum val )
{
return DatumGetCString ( FunctionCall1 ( flinfo , val ) ) ;
char * result ;
bool pushed ;
pushed = SPI_push_conditional ( ) ;
result = DatumGetCString ( FunctionCall1 ( flinfo , val ) ) ;
SPI_pop_conditional ( pushed ) ;
return result ;
}
/*
@ -1904,7 +1925,8 @@ OutputFunctionCall(FmgrInfo *flinfo, Datum val)
* " buf " may be NULL to indicate we are reading a NULL . In this case
* the caller should assume the result is NULL , but we ' ll call the receive
* function anyway if it ' s not strict . So this is almost but not quite
* the same as FunctionCall3 .
* the same as FunctionCall3 . Also , this includes SPI context pushing for
* the same reasons as InputFunctionCall .
*/
Datum
ReceiveFunctionCall ( FmgrInfo * flinfo , StringInfo buf ,
@ -1912,10 +1934,13 @@ ReceiveFunctionCall(FmgrInfo *flinfo, StringInfo buf,
{
FunctionCallInfoData fcinfo ;
Datum result ;
bool pushed ;
if ( buf = = NULL & & flinfo - > fn_strict )
return ( Datum ) 0 ; /* just return null result */
pushed = SPI_push_conditional ( ) ;
InitFunctionCallInfoData ( fcinfo , flinfo , 3 , NULL , NULL ) ;
fcinfo . arg [ 0 ] = PointerGetDatum ( buf ) ;
@ -1941,6 +1966,8 @@ ReceiveFunctionCall(FmgrInfo *flinfo, StringInfo buf,
fcinfo . flinfo - > fn_oid ) ;
}
SPI_pop_conditional ( pushed ) ;
return result ;
}
@ -1949,14 +1976,24 @@ ReceiveFunctionCall(FmgrInfo *flinfo, StringInfo buf,
*
* Do not call this on NULL datums .
*
* This is little more than window dressing for FunctionCall1 , but its use is
* recommended anyway so that code invoking output functions can be identified
* easily . Note however that it does guarantee a non - toasted result .
* This is little more than window dressing for FunctionCall1 , but it does
* guarantee a non - toasted result , which strictly speaking the underlying
* function doesn ' t . Also , this includes SPI context pushing for the same
* reasons as InputFunctionCall .
*/
bytea *
SendFunctionCall ( FmgrInfo * flinfo , Datum val )
{
return DatumGetByteaP ( FunctionCall1 ( flinfo , val ) ) ;
bytea * result ;
bool pushed ;
pushed = SPI_push_conditional ( ) ;
result = DatumGetByteaP ( FunctionCall1 ( flinfo , val ) ) ;
SPI_pop_conditional ( pushed ) ;
return result ;
}
/*