@@ -2266,6 +2266,90 @@ print_function_arguments(StringInfo buf, HeapTuple proctup,
22662266return argsprinted ;
22672267}
22682268
2269+ static bool
2270+ is_input_argument (int nth ,const char * argmodes )
2271+ {
2272+ return (!argmodes
2273+ || argmodes [nth ]== PROARGMODE_IN
2274+ || argmodes [nth ]== PROARGMODE_INOUT
2275+ || argmodes [nth ]== PROARGMODE_VARIADIC );
2276+ }
2277+
2278+ /*
2279+ * Get textual representation of a function argument's default value. The
2280+ * second argument of this function is the argument number among all arguments
2281+ * (i.e. proallargtypes, *not* proargtypes), starting with 1, because that's
2282+ * how information_schema.sql uses it.
2283+ */
2284+ Datum
2285+ pg_get_function_arg_default (PG_FUNCTION_ARGS )
2286+ {
2287+ Oid funcid = PG_GETARG_OID (0 );
2288+ int32 nth_arg = PG_GETARG_INT32 (1 );
2289+ HeapTuple proctup ;
2290+ Form_pg_proc proc ;
2291+ int numargs ;
2292+ Oid * argtypes ;
2293+ char * * argnames ;
2294+ char * argmodes ;
2295+ int i ;
2296+ List * argdefaults ;
2297+ Node * node ;
2298+ char * str ;
2299+ int nth_inputarg ;
2300+ Datum proargdefaults ;
2301+ bool isnull ;
2302+ int nth_default ;
2303+
2304+ proctup = SearchSysCache1 (PROCOID ,ObjectIdGetDatum (funcid ));
2305+ if (!HeapTupleIsValid (proctup ))
2306+ elog (ERROR ,"cache lookup failed for function %u" ,funcid );
2307+
2308+ numargs = get_func_arg_info (proctup ,& argtypes ,& argnames ,& argmodes );
2309+ if (nth_arg < 1 || nth_arg > numargs || !is_input_argument (nth_arg - 1 ,argmodes ))
2310+ {
2311+ ReleaseSysCache (proctup );
2312+ PG_RETURN_NULL ();
2313+ }
2314+
2315+ nth_inputarg = 0 ;
2316+ for (i = 0 ;i < nth_arg ;i ++ )
2317+ if (is_input_argument (i ,argmodes ))
2318+ nth_inputarg ++ ;
2319+
2320+ proargdefaults = SysCacheGetAttr (PROCOID ,proctup ,
2321+ Anum_pg_proc_proargdefaults ,
2322+ & isnull );
2323+ if (isnull )
2324+ {
2325+ ReleaseSysCache (proctup );
2326+ PG_RETURN_NULL ();
2327+ }
2328+
2329+ str = TextDatumGetCString (proargdefaults );
2330+ argdefaults = (List * )stringToNode (str );
2331+ Assert (IsA (argdefaults ,List ));
2332+ pfree (str );
2333+
2334+ proc = (Form_pg_proc )GETSTRUCT (proctup );
2335+
2336+ /* Calculate index into proargdefaults: proargdefaults corresponds to the
2337+ * last N input arguments, where N = pronargdefaults. */
2338+ nth_default = nth_inputarg - 1 - (proc -> pronargs - proc -> pronargdefaults );
2339+
2340+ if (nth_default < 0 || nth_default >=list_length (argdefaults ))
2341+ {
2342+ ReleaseSysCache (proctup );
2343+ PG_RETURN_NULL ();
2344+ }
2345+ node = list_nth (argdefaults ,nth_default );
2346+ str = deparse_expression (node ,NIL , false, false);
2347+
2348+ ReleaseSysCache (proctup );
2349+
2350+ PG_RETURN_TEXT_P (string_to_text (str ));
2351+ }
2352+
22692353
22702354/*
22712355 * deparse_expression- General utility for deparsing expressions