aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils/adt/ruleutils.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2008-07-18 03:32:53 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2008-07-18 03:32:53 +0000
commit69a785b8bfe076847f72317a41964821e85ccfd6 (patch)
tree8089a0c1e3b1075d81f49a82ab73b443dbe7d564 /src/backend/utils/adt/ruleutils.c
parenta8fb90cf2db614f3c1d4331bfaafd9a1953148e9 (diff)
downloadpostgresql-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.c145
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