@ -2266,6 +2266,90 @@ print_function_arguments(StringInfo buf, HeapTuple proctup,
return argsprinted ;
}
static bool
is_input_argument ( int nth , const char * argmodes )
{
return ( ! argmodes
| | argmodes [ nth ] = = PROARGMODE_IN
| | argmodes [ nth ] = = PROARGMODE_INOUT
| | argmodes [ nth ] = = PROARGMODE_VARIADIC ) ;
}
/*
* Get textual representation of a function argument ' s default value . The
* second argument of this function is the argument number among all arguments
* ( i . e . proallargtypes , * not * proargtypes ) , starting with 1 , because that ' s
* how information_schema . sql uses it .
*/
Datum
pg_get_function_arg_default ( PG_FUNCTION_ARGS )
{
Oid funcid = PG_GETARG_OID ( 0 ) ;
int32 nth_arg = PG_GETARG_INT32 ( 1 ) ;
HeapTuple proctup ;
Form_pg_proc proc ;
int numargs ;
Oid * argtypes ;
char * * argnames ;
char * argmodes ;
int i ;
List * argdefaults ;
Node * node ;
char * str ;
int nth_inputarg ;
Datum proargdefaults ;
bool isnull ;
int nth_default ;
proctup = SearchSysCache1 ( PROCOID , ObjectIdGetDatum ( funcid ) ) ;
if ( ! HeapTupleIsValid ( proctup ) )
elog ( ERROR , " cache lookup failed for function %u " , funcid ) ;
numargs = get_func_arg_info ( proctup , & argtypes , & argnames , & argmodes ) ;
if ( nth_arg < 1 | | nth_arg > numargs | | ! is_input_argument ( nth_arg - 1 , argmodes ) )
{
ReleaseSysCache ( proctup ) ;
PG_RETURN_NULL ( ) ;
}
nth_inputarg = 0 ;
for ( i = 0 ; i < nth_arg ; i + + )
if ( is_input_argument ( i , argmodes ) )
nth_inputarg + + ;
proargdefaults = SysCacheGetAttr ( PROCOID , proctup ,
Anum_pg_proc_proargdefaults ,
& isnull ) ;
if ( isnull )
{
ReleaseSysCache ( proctup ) ;
PG_RETURN_NULL ( ) ;
}
str = TextDatumGetCString ( proargdefaults ) ;
argdefaults = ( List * ) stringToNode ( str ) ;
Assert ( IsA ( argdefaults , List ) ) ;
pfree ( str ) ;
proc = ( Form_pg_proc ) GETSTRUCT ( proctup ) ;
/* Calculate index into proargdefaults: proargdefaults corresponds to the
* last N input arguments , where N = pronargdefaults . */
nth_default = nth_inputarg - 1 - ( proc - > pronargs - proc - > pronargdefaults ) ;
if ( nth_default < 0 | | nth_default > = list_length ( argdefaults ) )
{
ReleaseSysCache ( proctup ) ;
PG_RETURN_NULL ( ) ;
}
node = list_nth ( argdefaults , nth_default ) ;
str = deparse_expression ( node , NIL , false , false ) ;
ReleaseSysCache ( proctup ) ;
PG_RETURN_TEXT_P ( string_to_text ( str ) ) ;
}
/*
* deparse_expression - General utility for deparsing expressions