From 978129f28e0cba0b6364df672fbd1ae88e3397c4 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Mon, 30 May 2005 23:09:07 +0000 Subject: Document get_call_result_type() and friends; mark TypeGetTupleDesc() and RelationNameGetTupleDesc() as deprecated; remove uses of the latter in the contrib library. Along the way, clean up crosstab() code and documentation a little. --- doc/src/sgml/xfunc.sgml | 100 +++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 82 insertions(+), 18 deletions(-) (limited to 'doc/src') diff --git a/doc/src/sgml/xfunc.sgml b/doc/src/sgml/xfunc.sgml index 079773d0d46..0781bf4dba6 100644 --- a/doc/src/sgml/xfunc.sgml +++ b/doc/src/sgml/xfunc.sgml @@ -1,5 +1,5 @@ @@ -2324,21 +2324,68 @@ CREATE FUNCTION c_overpaid(emp, integer) RETURNS boolean - Several helper functions are available for setting up the initial - TupleDesc. If you want to use a named composite type, - you can fetch the information from the system catalogs. Use + Several helper functions are available for setting up the needed + TupleDesc. The recommended way to do this in most + functions returning composite values is to call + +TypeFuncClass get_call_result_type(FunctionCallInfo fcinfo, + Oid *resultTypeId, + TupleDesc *resultTupleDesc) + + passing the same fcinfo struct passed to the calling function + itself. (This of course requires that you use the version-1 + calling conventions.) resultTypeId can be specified + as NULL or as the address of a local variable to receive the + function's result type OID. resultTupleDesc should be the + address of a local TupleDesc variable. Check that the + result is TYPEFUNC_COMPOSITE; if so, + resultTupleDesc has been filled with the needed + TupleDesc. (If it is not, you can report an error along + the lines of function returning record called in context that + cannot accept type record.) + + + + + get_call_result_type can resolve the actual type of a + polymorphic function result; so it is useful in functions that return + scalar polymorphic results, not only functions that return composites. + The resultTypeId output is primarily useful for functions + returning polymorphic scalars. + + + + + + get_call_result_type has a sibling + get_expr_result_type, which can be used to resolve the + expected output type for a function call represented by an expression + tree. This can be used when trying to determine the result type from + outside the function itself. There is also + get_func_result_type, which can be used when only the + function's OID is available. However these functions are not able + to deal with functions declared to return record, and + get_func_result_type cannot resolve polymorphic types, + so you should preferentially use get_call_result_type. + + + + + Older, now-deprecated functions for obtaining + TupleDescs are TupleDesc RelationNameGetTupleDesc(const char *relname) - to get a TupleDesc for a named relation, or + to get a TupleDesc for the row type of a named relation, + and TupleDesc TypeGetTupleDesc(Oid typeoid, List *colaliases) to get a TupleDesc based on a type OID. This can be used to get a TupleDesc for a base or - composite type. When writing a function that returns - record, the expected TupleDesc - must be passed in by the caller. + composite type. It will not work for a function that returns + record, however, and it cannot resolve polymorphic + types. @@ -2587,12 +2634,13 @@ my_set_returning_function(PG_FUNCTION_ARGS) - A complete example of a simple SRF returning a composite type looks like: + A complete example of a simple SRF returning a composite type + looks like: -PG_FUNCTION_INFO_V1(testpassbyval); +PG_FUNCTION_INFO_V1(retcomposite); Datum -testpassbyval(PG_FUNCTION_ARGS) +retcomposite(PG_FUNCTION_ARGS) { FuncCallContext *funcctx; int call_cntr; @@ -2614,8 +2662,12 @@ testpassbyval(PG_FUNCTION_ARGS) /* total number of tuples to be returned */ funcctx->max_calls = PG_GETARG_UINT32(0); - /* Build a tuple description for a __testpassbyval tuple */ - tupdesc = RelationNameGetTupleDesc("__testpassbyval"); + /* Build a tuple descriptor for our result type */ + if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("function returning record called in context " + "that cannot accept type record"))); /* * generate attribute metadata needed later to produce tuples from raw @@ -2675,14 +2727,25 @@ testpassbyval(PG_FUNCTION_ARGS) } - The SQL code to declare this function is: + One way to declare this function in SQL is: -CREATE TYPE __testpassbyval AS (f1 integer, f2 integer, f3 integer); +CREATE TYPE __retcomposite AS (f1 integer, f2 integer, f3 integer); -CREATE OR REPLACE FUNCTION testpassbyval(integer, integer) RETURNS SETOF __testpassbyval - AS 'filename', 'testpassbyval' +CREATE OR REPLACE FUNCTION retcomposite(integer, integer) + RETURNS SETOF __retcomposite + AS 'filename', 'retcomposite' + LANGUAGE C IMMUTABLE STRICT; + + A different way is to use OUT parameters: + +CREATE OR REPLACE FUNCTION retcomposite(IN integer, IN integer, + OUT f1 integer, OUT f2 integer, OUT f3 integer) + RETURNS SETOF record + AS 'filename', 'retcomposite' LANGUAGE C IMMUTABLE STRICT; + Notice that in this method the output type of the function is formally + an anonymous record type. @@ -2711,7 +2774,8 @@ CREATE OR REPLACE FUNCTION testpassbyval(integer, integer) RETURNS SETOF __testp information is not available. The structure flinfo is normally accessed as fcinfo->flinfo. The parameter argnum - is zero based. + is zero based. get_call_result_type can also be used + as an alternative to get_fn_expr_rettype. -- cgit v1.2.3