- publishing free software manuals
PostgreSQL Reference Manual - Volume 2 - Programming Guide
by The PostgreSQL Global Development Group
Paperback (6"x9"), 408 pages
ISBN 0954612035
RRP £19.95 ($34.95)

Sales of this book support the PostgreSQL project! Get a printed copy>>>

5.9.11 Polymorphic Arguments and Return Types

C-language functions may be declared to accept and return the polymorphic types anyelement and anyarray. See section 5.2.5 Polymorphic Types for a more detailed explanation of polymorphic functions. When function arguments or return types are defined as polymorphic types, the function author cannot know in advance what data type it will be called with, or need to return. There are two routines provided in ‘fmgr.h’ to allow a version-1 C function to discover the actual data types of its arguments and the type it is expected to return. The routines are called get_fn_expr_rettype(FmgrInfo *flinfo) and get_fn_expr_argtype(FmgrInfo *flinfo, int argnum). They return the result or argument type OID, or InvalidOid if the information is not available. The structure flinfo is normally accessed as fcinfo->flinfo. The parameter argnum is zero based. get_call_result_type can also be used as an alternative to get_fn_expr_rettype.

For example, suppose we want to write a function to accept a single element of any type, and return a one-dimensional array of that type:

PG_FUNCTION_INFO_V1(make_array);
Datum
make_array(PG_FUNCTION_ARGS)
{
  ArrayType *result;
  Oid element_type = get_fn_expr_argtype(fcinfo->flinfo, 0);
  Datum element;
  bool isnull;
  int16 typlen;
  bool typbyval;
  char typalign;
  int ndims;
  int dims[MAXDIM];
  int lbs[MAXDIM];

  if (!OidIsValid(element_type))
    elog(ERROR, "could not determine data type of input");

  /* get the provided element, being careful in case it's
     NULL */
  isnull = PG_ARGISNULL(0);
  if (isnull)
    element = (Datum) 0;
  else
    element = PG_GETARG_DATUM(0);

  /* we have one dimension */
  ndims = 1;
  /* and one element */
  dims[0] = 1;
  /* and lower bound is 1 */
  lbs[0] = 1;

  /* get required info about the element type */
  get_typlenbyvalalign(element_type, &typlen, &typbyval,
                       &typalign);

  /* now build the array */
  result =
      construct_md_array(&element, &isnull, ndims, dims,
                         lbs, element_type, typlen,
                         typbyval, typalign);

  PG_RETURN_ARRAYTYPE_P(result);
}

The following command declares the function make_array in SQL:

CREATE FUNCTION make_array(anyelement) RETURNS anyarray
    AS 'DIRECTORY/funcs', 'make_array'
    LANGUAGE C IMMUTABLE;
ISBN 0954612035PostgreSQL Reference Manual - Volume 2 - Programming GuideSee the print edition