diff options
Diffstat (limited to 'src/backend/utils')
-rw-r--r-- | src/backend/utils/adt/ruleutils.c | 145 | ||||
-rw-r--r-- | src/backend/utils/fmgr/funcapi.c | 14 |
2 files changed, 152 insertions, 7 deletions
diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index c7f896c524a..b3603c53c16 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -9,7 +9,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/utils/adt/ruleutils.c,v 1.277 2008/07/16 16:55:23 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/utils/adt/ruleutils.c,v 1.278 2008/07/18 03:32:52 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -135,6 +135,8 @@ static char *pg_get_constraintdef_worker(Oid constraintId, bool fullCommand, int prettyFlags); static char *pg_get_expr_worker(text *expr, Oid relid, char *relname, int prettyFlags); +static int print_function_arguments(StringInfo buf, HeapTuple proctup, + bool print_table_args); static void make_ruledef(StringInfo buf, HeapTuple ruletup, TupleDesc rulettc, int prettyFlags); static void make_viewdef(StringInfo buf, HeapTuple ruletup, TupleDesc rulettc, @@ -1396,6 +1398,147 @@ pg_get_serial_sequence(PG_FUNCTION_ARGS) /* + * pg_get_function_arguments + * Get a nicely-formatted list of arguments for a function. + * This is everything that would go between the parentheses in + * CREATE FUNCTION. + */ +Datum +pg_get_function_arguments(PG_FUNCTION_ARGS) +{ + Oid funcid = PG_GETARG_OID(0); + StringInfoData buf; + HeapTuple proctup; + + initStringInfo(&buf); + + proctup = SearchSysCache(PROCOID, + ObjectIdGetDatum(funcid), + 0, 0, 0); + if (!HeapTupleIsValid(proctup)) + elog(ERROR, "cache lookup failed for function %u", funcid); + + (void) print_function_arguments(&buf, proctup, false); + + ReleaseSysCache(proctup); + + PG_RETURN_TEXT_P(string_to_text(buf.data)); +} + +/* + * pg_get_function_result + * Get a nicely-formatted version of the result type of a function. + * This is what would appear after RETURNS in CREATE FUNCTION. + */ +Datum +pg_get_function_result(PG_FUNCTION_ARGS) +{ + Oid funcid = PG_GETARG_OID(0); + StringInfoData buf; + HeapTuple proctup; + Form_pg_proc procform; + int ntabargs = 0; + + initStringInfo(&buf); + + proctup = SearchSysCache(PROCOID, + ObjectIdGetDatum(funcid), + 0, 0, 0); + if (!HeapTupleIsValid(proctup)) + elog(ERROR, "cache lookup failed for function %u", funcid); + procform = (Form_pg_proc) GETSTRUCT(proctup); + + if (procform->proretset) + { + /* It might be a table function; try to print the arguments */ + appendStringInfoString(&buf, "TABLE("); + ntabargs = print_function_arguments(&buf, proctup, true); + if (ntabargs > 0) + appendStringInfoString(&buf, ")"); + else + resetStringInfo(&buf); + } + + if (ntabargs == 0) + { + /* Not a table function, so do the normal thing */ + if (procform->proretset) + appendStringInfoString(&buf, "SETOF "); + appendStringInfoString(&buf, format_type_be(procform->prorettype)); + } + + ReleaseSysCache(proctup); + + PG_RETURN_TEXT_P(string_to_text(buf.data)); +} + +/* + * Common code for pg_get_function_arguments and pg_get_function_result: + * append the desired subset of arguments to buf. We print only TABLE + * arguments when print_table_args is true, and all the others when it's false. + * Function return value is the number of arguments printed. + */ +static int +print_function_arguments(StringInfo buf, HeapTuple proctup, + bool print_table_args) +{ + int numargs; + Oid *argtypes; + char **argnames; + char *argmodes; + int argsprinted; + int i; + + numargs = get_func_arg_info(proctup, + &argtypes, &argnames, &argmodes); + + argsprinted = 0; + for (i = 0; i < numargs; i++) + { + Oid argtype = argtypes[i]; + char *argname = argnames ? argnames[i] : NULL; + char argmode = argmodes ? argmodes[i] : PROARGMODE_IN; + const char *modename; + + if (print_table_args != (argmode == PROARGMODE_TABLE)) + continue; + + switch (argmode) + { + case PROARGMODE_IN: + modename = ""; + break; + case PROARGMODE_INOUT: + modename = "INOUT "; + break; + case PROARGMODE_OUT: + modename = "OUT "; + break; + case PROARGMODE_VARIADIC: + modename = "VARIADIC "; + break; + case PROARGMODE_TABLE: + modename = ""; + break; + default: + elog(ERROR, "invalid parameter mode '%c'", argmode); + modename = NULL; /* keep compiler quiet */ + break; + } + if (argsprinted) + appendStringInfoString(buf, ", "); + appendStringInfoString(buf, modename); + if (argname && argname[0]) + appendStringInfo(buf, "%s ", argname); + appendStringInfoString(buf, format_type_be(argtype)); + argsprinted++; + } + + return argsprinted; +} + + +/* * deparse_expression - General utility for deparsing expressions * * calls deparse_expression_pretty with all prettyPrinting disabled diff --git a/src/backend/utils/fmgr/funcapi.c b/src/backend/utils/fmgr/funcapi.c index 7cba375ee03..6ff1b90ffcd 100644 --- a/src/backend/utils/fmgr/funcapi.c +++ b/src/backend/utils/fmgr/funcapi.c @@ -7,7 +7,7 @@ * Copyright (c) 2002-2008, PostgreSQL Global Development Group * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/utils/fmgr/funcapi.c,v 1.40 2008/07/16 01:30:22 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/utils/fmgr/funcapi.c,v 1.41 2008/07/18 03:32:52 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -550,7 +550,7 @@ resolve_polymorphic_argtypes(int numargs, Oid *argtypes, char *argmodes, case ANYELEMENTOID: case ANYNONARRAYOID: case ANYENUMOID: - if (argmode == PROARGMODE_OUT) + if (argmode == PROARGMODE_OUT || argmode == PROARGMODE_TABLE) have_anyelement_result = true; else { @@ -565,7 +565,7 @@ resolve_polymorphic_argtypes(int numargs, Oid *argtypes, char *argmodes, } break; case ANYARRAYOID: - if (argmode == PROARGMODE_OUT) + if (argmode == PROARGMODE_OUT || argmode == PROARGMODE_TABLE) have_anyarray_result = true; else { @@ -582,7 +582,7 @@ resolve_polymorphic_argtypes(int numargs, Oid *argtypes, char *argmodes, default: break; } - if (argmode != PROARGMODE_OUT) + if (argmode != PROARGMODE_OUT && argmode != PROARGMODE_TABLE) inargno++; } @@ -848,7 +848,8 @@ get_func_result_name(Oid functionId) argmodes[i] == PROARGMODE_VARIADIC) continue; Assert(argmodes[i] == PROARGMODE_OUT || - argmodes[i] == PROARGMODE_INOUT); + argmodes[i] == PROARGMODE_INOUT || + argmodes[i] == PROARGMODE_TABLE); if (++numoutargs > 1) { /* multiple out args, so forget it */ @@ -999,7 +1000,8 @@ build_function_result_tupdesc_d(Datum proallargtypes, argmodes[i] == PROARGMODE_VARIADIC) continue; Assert(argmodes[i] == PROARGMODE_OUT || - argmodes[i] == PROARGMODE_INOUT); + argmodes[i] == PROARGMODE_INOUT || + argmodes[i] == PROARGMODE_TABLE); outargtypes[numoutargs] = argtypes[i]; if (argnames) pname = TextDatumGetCString(argnames[i]); |