diff options
author | Peter Eisentraut <peter_e@gmx.net> | 2013-11-26 23:18:58 -0500 |
---|---|---|
committer | Peter Eisentraut <peter_e@gmx.net> | 2013-11-26 23:21:35 -0500 |
commit | 85ed91ee7da8f560c3443733cbda2862cd25facd (patch) | |
tree | f330d3565041d214dca431f6c3c04b50d3a183c1 /src/backend/utils/adt/ruleutils.c | |
parent | 3803ff985c7940af32912b158322cce399952e76 (diff) | |
download | postgresql-85ed91ee7da8f560c3443733cbda2862cd25facd.tar.gz postgresql-85ed91ee7da8f560c3443733cbda2862cd25facd.zip |
Implement information_schema.parameters.parameter_default column
Reviewed-by: Ali Dar <ali.munir.dar@gmail.com>
Reviewed-by: Amit Khandekar <amit.khandekar@enterprisedb.com>
Reviewed-by: Rodolfo Campero <rodolfo.campero@anachronics.com>
Diffstat (limited to 'src/backend/utils/adt/ruleutils.c')
-rw-r--r-- | src/backend/utils/adt/ruleutils.c | 84 |
1 files changed, 84 insertions, 0 deletions
diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 29a1027a100..348f620f2a4 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -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 |