diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2008-07-18 03:32:53 +0000 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2008-07-18 03:32:53 +0000 |
commit | 69a785b8bfe076847f72317a41964821e85ccfd6 (patch) | |
tree | 8089a0c1e3b1075d81f49a82ab73b443dbe7d564 /src/backend/utils/adt/ruleutils.c | |
parent | a8fb90cf2db614f3c1d4331bfaafd9a1953148e9 (diff) | |
download | postgresql-69a785b8bfe076847f72317a41964821e85ccfd6.tar.gz postgresql-69a785b8bfe076847f72317a41964821e85ccfd6.zip |
Implement SQL-spec RETURNS TABLE syntax for functions.
(Unlike the original submission, this patch treats TABLE output parameters
as being entirely equivalent to OUT parameters -- tgl)
Pavel Stehule
Diffstat (limited to 'src/backend/utils/adt/ruleutils.c')
-rw-r--r-- | src/backend/utils/adt/ruleutils.c | 145 |
1 files changed, 144 insertions, 1 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 |