diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2005-05-30 23:09:07 +0000 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2005-05-30 23:09:07 +0000 |
commit | 978129f28e0cba0b6364df672fbd1ae88e3397c4 (patch) | |
tree | 94dcfb1cb3494d7981dc9d09c10047129577db40 /doc/src | |
parent | b215fae891a7b0e9bcd7126f3aab1c477d4947b1 (diff) |
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.
Diffstat (limited to 'doc/src')
-rw-r--r-- | doc/src/sgml/xfunc.sgml | 100 |
1 files changed, 82 insertions, 18 deletions
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 @@ <!-- -$PostgreSQL: pgsql/doc/src/sgml/xfunc.sgml,v 1.102 2005/03/31 22:46:02 tgl Exp $ +$PostgreSQL: pgsql/doc/src/sgml/xfunc.sgml,v 1.103 2005/05/30 23:09:07 tgl Exp $ --> <sect1 id="xfunc"> @@ -2324,21 +2324,68 @@ CREATE FUNCTION c_overpaid(emp, integer) RETURNS boolean </para> <para> - Several helper functions are available for setting up the initial - <structname>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 + <structname>TupleDesc</>. The recommended way to do this in most + functions returning composite values is to call +<programlisting> +TypeFuncClass get_call_result_type(FunctionCallInfo fcinfo, + Oid *resultTypeId, + TupleDesc *resultTupleDesc) +</programlisting> + passing the same <literal>fcinfo</> struct passed to the calling function + itself. (This of course requires that you use the version-1 + calling conventions.) <varname>resultTypeId</> can be specified + as <literal>NULL</> or as the address of a local variable to receive the + function's result type OID. <varname>resultTupleDesc</> should be the + address of a local <structname>TupleDesc</> variable. Check that the + result is <literal>TYPEFUNC_COMPOSITE</>; if so, + <varname>resultTupleDesc</> has been filled with the needed + <structname>TupleDesc</>. (If it is not, you can report an error along + the lines of <quote>function returning record called in context that + cannot accept type record</quote>.) + </para> + + <tip> + <para> + <function>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 <varname>resultTypeId</> output is primarily useful for functions + returning polymorphic scalars. + </para> + </tip> + + <note> + <para> + <function>get_call_result_type</> has a sibling + <function>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 + <function>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 <structname>record</>, and + <function>get_func_result_type</> cannot resolve polymorphic types, + so you should preferentially use <function>get_call_result_type</>. + </para> + </note> + + <para> + Older, now-deprecated functions for obtaining + <structname>TupleDesc</>s are <programlisting> TupleDesc RelationNameGetTupleDesc(const char *relname) </programlisting> - to get a <structname>TupleDesc</> for a named relation, or + to get a <structname>TupleDesc</> for the row type of a named relation, + and <programlisting> TupleDesc TypeGetTupleDesc(Oid typeoid, List *colaliases) </programlisting> to get a <structname>TupleDesc</> based on a type OID. This can be used to get a <structname>TupleDesc</> for a base or - composite type. When writing a function that returns - <structname>record</>, the expected <structname>TupleDesc</> - must be passed in by the caller. + composite type. It will not work for a function that returns + <structname>record</>, however, and it cannot resolve polymorphic + types. </para> <para> @@ -2587,12 +2634,13 @@ my_set_returning_function(PG_FUNCTION_ARGS) </para> <para> - A complete example of a simple <acronym>SRF</> returning a composite type looks like: + A complete example of a simple <acronym>SRF</> returning a composite type + looks like: <programlisting> -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) } </programlisting> - The SQL code to declare this function is: + One way to declare this function in SQL is: <programlisting> -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 '<replaceable>filename</>', 'testpassbyval' +CREATE OR REPLACE FUNCTION retcomposite(integer, integer) + RETURNS SETOF __retcomposite + AS '<replaceable>filename</>', 'retcomposite' + LANGUAGE C IMMUTABLE STRICT; +</programlisting> + A different way is to use OUT parameters: +<programlisting> +CREATE OR REPLACE FUNCTION retcomposite(IN integer, IN integer, + OUT f1 integer, OUT f2 integer, OUT f3 integer) + RETURNS SETOF record + AS '<replaceable>filename</>', 'retcomposite' LANGUAGE C IMMUTABLE STRICT; </programlisting> + Notice that in this method the output type of the function is formally + an anonymous <structname>record</> type. </para> <para> @@ -2711,7 +2774,8 @@ CREATE OR REPLACE FUNCTION testpassbyval(integer, integer) RETURNS SETOF __testp information is not available. The structure <literal>flinfo</> is normally accessed as <literal>fcinfo->flinfo</>. The parameter <literal>argnum</> - is zero based. + is zero based. <function>get_call_result_type</> can also be used + as an alternative to <function>get_fn_expr_rettype</>. </para> <para> |