PostgreSQL Source Code git master
Loading...
Searching...
No Matches
funcapi.h File Reference
#include "access/tupdesc.h"
#include "executor/executor.h"
#include "executor/tuptable.h"
#include "fmgr.h"
Include dependency graph for funcapi.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  AttInMetadata
 
struct  FuncCallContext
 

Macros

#define TupleGetDatum(_slot, _tuple)   HeapTupleGetDatum(_tuple)
 
#define MAT_SRF_USE_EXPECTED_DESC   0x01 /* use expectedDesc as tupdesc. */
 
#define MAT_SRF_BLESS
 
#define SRF_IS_FIRSTCALL()   (fcinfo->flinfo->fn_extra == NULL)
 
#define SRF_FIRSTCALL_INIT()   init_MultiFuncCall(fcinfo)
 
#define SRF_PERCALL_SETUP()   per_MultiFuncCall(fcinfo)
 
#define SRF_RETURN_NEXT(_funcctx, _result)
 
#define SRF_RETURN_NEXT_NULL(_funcctx)
 
#define SRF_RETURN_DONE(_funcctx)
 

Typedefs

typedef struct AttInMetadata AttInMetadata
 
typedef struct FuncCallContext FuncCallContext
 
typedef enum TypeFuncClass TypeFuncClass
 

Enumerations

enum  TypeFuncClass {
  TYPEFUNC_SCALAR , TYPEFUNC_COMPOSITE , TYPEFUNC_COMPOSITE_DOMAIN , TYPEFUNC_RECORD ,
  TYPEFUNC_OTHER
}
 

Functions

TypeFuncClass get_call_result_type (FunctionCallInfo fcinfo, Oid *resultTypeId, TupleDesc *resultTupleDesc)
 
TypeFuncClass get_expr_result_type (Node *expr, Oid *resultTypeId, TupleDesc *resultTupleDesc)
 
TypeFuncClass get_func_result_type (Oid functionId, Oid *resultTypeId, TupleDesc *resultTupleDesc)
 
TupleDesc get_expr_result_tupdesc (Node *expr, bool noError)
 
bool resolve_polymorphic_argtypes (int numargs, Oid *argtypes, char *argmodes, Node *call_expr)
 
int get_func_arg_info (HeapTuple procTup, Oid **p_argtypes, char ***p_argnames, char **p_argmodes)
 
int get_func_input_arg_names (Datum proargnames, Datum proargmodes, char ***arg_names)
 
int get_func_trftypes (HeapTuple procTup, Oid **p_trftypes)
 
charget_func_result_name (Oid functionId)
 
TupleDesc build_function_result_tupdesc_d (char prokind, Datum proallargtypes, Datum proargmodes, Datum proargnames)
 
TupleDesc build_function_result_tupdesc_t (HeapTuple procTuple)
 
TupleDesc RelationNameGetTupleDesc (const char *relname)
 
TupleDesc TypeGetTupleDesc (Oid typeoid, List *colaliases)
 
TupleDesc BlessTupleDesc (TupleDesc tupdesc)
 
AttInMetadataTupleDescGetAttInMetadata (TupleDesc tupdesc)
 
HeapTuple BuildTupleFromCStrings (AttInMetadata *attinmeta, char **values)
 
Datum HeapTupleHeaderGetDatum (HeapTupleHeader tuple)
 
static Datum HeapTupleGetDatum (const HeapTupleData *tuple)
 
void InitMaterializedSRF (FunctionCallInfo fcinfo, bits32 flags)
 
FuncCallContextinit_MultiFuncCall (PG_FUNCTION_ARGS)
 
FuncCallContextper_MultiFuncCall (PG_FUNCTION_ARGS)
 
void end_MultiFuncCall (PG_FUNCTION_ARGS, FuncCallContext *funcctx)
 
int extract_variadic_args (FunctionCallInfo fcinfo, int variadic_start, bool convert_unknown, Datum **args, Oid **types, bool **nulls)
 

Macro Definition Documentation

◆ MAT_SRF_BLESS

#define MAT_SRF_BLESS
Value:
0x02 /* "Bless" a tuple descriptor with
* BlessTupleDesc(). */

Definition at line 297 of file funcapi.h.

312{ \
313 ReturnSetInfo *rsi; \
314 (_funcctx)->call_cntr++; \
315 rsi = (ReturnSetInfo *) fcinfo->resultinfo; \
316 rsi->isDone = ExprMultipleResult; \
318 } while (0)
319
320#define SRF_RETURN_NEXT_NULL(_funcctx) \
321 do { \
322 ReturnSetInfo *rsi; \
323 (_funcctx)->call_cntr++; \
324 rsi = (ReturnSetInfo *) fcinfo->resultinfo; \
325 rsi->isDone = ExprMultipleResult; \
326 PG_RETURN_NULL(); \
327 } while (0)
328
329#define SRF_RETURN_DONE(_funcctx) \
330 do { \
331 ReturnSetInfo *rsi; \
332 end_MultiFuncCall(fcinfo, _funcctx); \
333 rsi = (ReturnSetInfo *) fcinfo->resultinfo; \
334 rsi->isDone = ExprEndResult; \
335 PG_RETURN_NULL(); \
336 } while (0)
337
338/*----------
339 * Support to ease writing of functions dealing with VARIADIC inputs
340 *----------
341 *
342 * This function extracts a set of argument values, types and NULL markers
343 * for a given input function. This returns a set of data:
344 * - **values includes the set of Datum values extracted.
345 * - **types the data type OID for each element.
346 * - **nulls tracks if an element is NULL.
347 *
348 * variadic_start indicates the argument number where the VARIADIC argument
349 * starts.
350 * convert_unknown set to true will enforce the conversion of arguments
351 * with unknown data type to text.
352 *
353 * The return result is the number of elements stored, or -1 in the case of
354 * "VARIADIC NULL".
355 */
357 bool convert_unknown, Datum **args,
358 Oid **types, bool **nulls);
359
360#endif /* FUNCAPI_H */
struct typedefs * types
Definition ecpg.c:30
@ ExprMultipleResult
Definition execnodes.h:339
int extract_variadic_args(FunctionCallInfo fcinfo, int variadic_start, bool convert_unknown, Datum **args, Oid **types, bool **nulls)
Definition funcapi.c:2011
uint64_t Datum
Definition postgres.h:70
unsigned int Oid
static int fb(int x)

◆ MAT_SRF_USE_EXPECTED_DESC

#define MAT_SRF_USE_EXPECTED_DESC   0x01 /* use expectedDesc as tupdesc. */

Definition at line 296 of file funcapi.h.

◆ SRF_FIRSTCALL_INIT

#define SRF_FIRSTCALL_INIT ( )    init_MultiFuncCall(fcinfo)

Definition at line 306 of file funcapi.h.

◆ SRF_IS_FIRSTCALL

#define SRF_IS_FIRSTCALL ( )    (fcinfo->flinfo->fn_extra == NULL)

Definition at line 304 of file funcapi.h.

◆ SRF_PERCALL_SETUP

#define SRF_PERCALL_SETUP ( )    per_MultiFuncCall(fcinfo)

Definition at line 308 of file funcapi.h.

◆ SRF_RETURN_DONE

#define SRF_RETURN_DONE (   _funcctx)
Value:
do { \
rsi = (ReturnSetInfo *) fcinfo->resultinfo; \
rsi->isDone = ExprEndResult; \
} while (0)
@ ExprEndResult
Definition execnodes.h:340

Definition at line 328 of file funcapi.h.

330 { \
331 ReturnSetInfo *rsi; \
333 rsi = (ReturnSetInfo *) fcinfo->resultinfo; \
334 rsi->isDone = ExprEndResult; \

◆ SRF_RETURN_NEXT

#define SRF_RETURN_NEXT (   _funcctx,
  _result 
)
Value:
do { \
ReturnSetInfo *rsi; \
(_funcctx)->call_cntr++; \
rsi = (ReturnSetInfo *) fcinfo->resultinfo; \
rsi->isDone = ExprMultipleResult; \
} while (0)

Definition at line 310 of file funcapi.h.

312 { \
313 ReturnSetInfo *rsi; \
314 (_funcctx)->call_cntr++; \
315 rsi = (ReturnSetInfo *) fcinfo->resultinfo; \
316 rsi->isDone = ExprMultipleResult; \

◆ SRF_RETURN_NEXT_NULL

#define SRF_RETURN_NEXT_NULL (   _funcctx)
Value:
do { \
ReturnSetInfo *rsi; \
(_funcctx)->call_cntr++; \
rsi = (ReturnSetInfo *) fcinfo->resultinfo; \
rsi->isDone = ExprMultipleResult; \
} while (0)

Definition at line 319 of file funcapi.h.

321 { \
322 ReturnSetInfo *rsi; \
323 (_funcctx)->call_cntr++; \
324 rsi = (ReturnSetInfo *) fcinfo->resultinfo; \
325 rsi->isDone = ExprMultipleResult; \

◆ TupleGetDatum

#define TupleGetDatum (   _slot,
  _tuple 
)    HeapTupleGetDatum(_tuple)

Definition at line 236 of file funcapi.h.

Typedef Documentation

◆ AttInMetadata

◆ FuncCallContext

◆ TypeFuncClass

Enumeration Type Documentation

◆ TypeFuncClass

Enumerator
TYPEFUNC_SCALAR 
TYPEFUNC_COMPOSITE 
TYPEFUNC_COMPOSITE_DOMAIN 
TYPEFUNC_RECORD 
TYPEFUNC_OTHER 

Definition at line 146 of file funcapi.h.

147{
148 TYPEFUNC_SCALAR, /* scalar result type */
149 TYPEFUNC_COMPOSITE, /* determinable rowtype result */
150 TYPEFUNC_COMPOSITE_DOMAIN, /* domain over determinable rowtype result */
151 TYPEFUNC_RECORD, /* indeterminate rowtype result */
152 TYPEFUNC_OTHER, /* bogus type, eg pseudotype */
TypeFuncClass
Definition funcapi.h:147
@ TYPEFUNC_SCALAR
Definition funcapi.h:148
@ TYPEFUNC_COMPOSITE
Definition funcapi.h:149
@ TYPEFUNC_RECORD
Definition funcapi.h:151
@ TYPEFUNC_COMPOSITE_DOMAIN
Definition funcapi.h:150
@ TYPEFUNC_OTHER
Definition funcapi.h:152

Function Documentation

◆ BlessTupleDesc()

TupleDesc BlessTupleDesc ( TupleDesc  tupdesc)
extern

Definition at line 2338 of file execTuples.c.

2339{
2340 /* Did someone forget to call TupleDescFinalize()? */
2341 Assert(tupdesc->firstNonCachedOffsetAttr >= 0);
2342
2343 if (tupdesc->tdtypeid == RECORDOID &&
2344 tupdesc->tdtypmod < 0)
2346
2347 return tupdesc; /* just for notational convenience */
2348}
#define Assert(condition)
Definition c.h:945
int firstNonCachedOffsetAttr
Definition tupdesc.h:154
int32 tdtypmod
Definition tupdesc.h:152
void assign_record_type_typmod(TupleDesc tupDesc)
Definition typcache.c:2067

References Assert, assign_record_type_typmod(), fb(), TupleDescData::firstNonCachedOffsetAttr, TupleDescData::tdtypeid, and TupleDescData::tdtypmod.

Referenced by aclexplode(), BeginCopyTo(), brin_metapage_info(), bt_page_items_bytea(), bt_page_items_internal(), exec_eval_datum(), ExecEvalWholeRowVar(), ExecInitExprRec(), ExecInitFunctionScan(), get_expr_result_type(), hash_bitmap_info(), hash_metapage_info(), hash_page_items(), hash_page_stats(), init_execution_state(), InitMaterializedSRF(), pg_buffercache_os_pages_internal(), pg_buffercache_pages(), pg_get_catalog_foreign_keys(), pg_get_publication_tables(), pg_get_sequence_data(), pg_lock_status(), pg_prepared_xact(), pg_stat_file(), pg_stat_get_archiver(), pg_stat_get_backend_subxact(), pg_stat_get_replication_slot(), pg_stat_get_subscription_stats(), pg_stat_wal_build_tuple(), pg_stats_ext_mcvlist_items(), pg_visibility_tupdesc(), pg_walfile_name_offset(), pgstathashindex(), PLy_output_setup_record(), setup_firstcall(), ssl_extension_info(), test_custom_stats_fixed_report(), test_custom_stats_var_report(), test_enc_conversion(), test_predtest(), and TupleDescGetAttInMetadata().

◆ build_function_result_tupdesc_d()

TupleDesc build_function_result_tupdesc_d ( char  prokind,
Datum  proallargtypes,
Datum  proargmodes,
Datum  proargnames 
)
extern

Definition at line 1754 of file funcapi.c.

1758{
1759 TupleDesc desc;
1760 ArrayType *arr;
1761 int numargs;
1762 Oid *argtypes;
1763 char *argmodes;
1764 Datum *argnames = NULL;
1766 char **outargnames;
1767 int numoutargs;
1768 int nargnames;
1769 int i;
1770
1771 /* Can't have output args if columns are null */
1774 return NULL;
1775
1776 /*
1777 * We expect the arrays to be 1-D arrays of the right types; verify that.
1778 * For the OID and char arrays, we don't need to use deconstruct_array()
1779 * since the array data is just going to look like a C array of values.
1780 */
1781 arr = DatumGetArrayTypeP(proallargtypes); /* ensure not toasted */
1782 numargs = ARR_DIMS(arr)[0];
1783 if (ARR_NDIM(arr) != 1 ||
1784 numargs < 0 ||
1785 ARR_HASNULL(arr) ||
1786 ARR_ELEMTYPE(arr) != OIDOID)
1787 elog(ERROR, "proallargtypes is not a 1-D Oid array or it contains nulls");
1788 argtypes = (Oid *) ARR_DATA_PTR(arr);
1789 arr = DatumGetArrayTypeP(proargmodes); /* ensure not toasted */
1790 if (ARR_NDIM(arr) != 1 ||
1791 ARR_DIMS(arr)[0] != numargs ||
1792 ARR_HASNULL(arr) ||
1793 ARR_ELEMTYPE(arr) != CHAROID)
1794 elog(ERROR, "proargmodes is not a 1-D char array of length %d or it contains nulls",
1795 numargs);
1796 argmodes = (char *) ARR_DATA_PTR(arr);
1798 {
1799 arr = DatumGetArrayTypeP(proargnames); /* ensure not toasted */
1800 if (ARR_NDIM(arr) != 1 ||
1801 ARR_DIMS(arr)[0] != numargs ||
1802 ARR_HASNULL(arr) ||
1803 ARR_ELEMTYPE(arr) != TEXTOID)
1804 elog(ERROR, "proargnames is not a 1-D text array of length %d or it contains nulls",
1805 numargs);
1806 deconstruct_array_builtin(arr, TEXTOID, &argnames, NULL, &nargnames);
1807 Assert(nargnames == numargs);
1808 }
1809
1810 /* zero elements probably shouldn't happen, but handle it gracefully */
1811 if (numargs <= 0)
1812 return NULL;
1813
1814 /* extract output-argument types and names */
1815 outargtypes = (Oid *) palloc(numargs * sizeof(Oid));
1816 outargnames = (char **) palloc(numargs * sizeof(char *));
1817 numoutargs = 0;
1818 for (i = 0; i < numargs; i++)
1819 {
1820 char *pname;
1821
1822 if (argmodes[i] == PROARGMODE_IN ||
1824 continue;
1828 outargtypes[numoutargs] = argtypes[i];
1829 if (argnames)
1830 pname = TextDatumGetCString(argnames[i]);
1831 else
1832 pname = NULL;
1833 if (pname == NULL || pname[0] == '\0')
1834 {
1835 /* Parameter is not named, so gin up a column name */
1836 pname = psprintf("column%d", numoutargs + 1);
1837 }
1839 numoutargs++;
1840 }
1841
1842 /*
1843 * If there is no output argument, or only one, the function does not
1844 * return tuples.
1845 */
1846 if (numoutargs < 2 && prokind != PROKIND_PROCEDURE)
1847 return NULL;
1848
1850 for (i = 0; i < numoutargs; i++)
1851 {
1852 TupleDescInitEntry(desc, i + 1,
1853 outargnames[i],
1854 outargtypes[i],
1855 -1,
1856 0);
1857 }
1858
1859 TupleDescFinalize(desc);
1860
1861 return desc;
1862}
#define ARR_NDIM(a)
Definition array.h:290
#define ARR_DATA_PTR(a)
Definition array.h:322
#define DatumGetArrayTypeP(X)
Definition array.h:261
#define ARR_ELEMTYPE(a)
Definition array.h:292
#define ARR_DIMS(a)
Definition array.h:294
#define ARR_HASNULL(a)
Definition array.h:291
void deconstruct_array_builtin(const ArrayType *array, Oid elmtype, Datum **elemsp, bool **nullsp, int *nelemsp)
#define TextDatumGetCString(d)
Definition builtins.h:99
#define ERROR
Definition elog.h:39
#define elog(elevel,...)
Definition elog.h:226
int i
Definition isn.c:77
void * palloc(Size size)
Definition mcxt.c:1387
static Datum PointerGetDatum(const void *X)
Definition postgres.h:342
char * psprintf(const char *fmt,...)
Definition psprintf.c:43
TupleDesc CreateTemplateTupleDesc(int natts)
Definition tupdesc.c:165
void TupleDescFinalize(TupleDesc tupdesc)
Definition tupdesc.c:508
void TupleDescInitEntry(TupleDesc desc, AttrNumber attributeNumber, const char *attributeName, Oid oidtypeid, int32 typmod, int attdim)
Definition tupdesc.c:897

References ARR_DATA_PTR, ARR_DIMS, ARR_ELEMTYPE, ARR_HASNULL, ARR_NDIM, Assert, CreateTemplateTupleDesc(), DatumGetArrayTypeP, deconstruct_array_builtin(), elog, ERROR, fb(), i, palloc(), PointerGetDatum(), psprintf(), TextDatumGetCString, TupleDescFinalize(), and TupleDescInitEntry().

Referenced by build_function_result_tupdesc_t(), and ProcedureCreate().

◆ build_function_result_tupdesc_t()

TupleDesc build_function_result_tupdesc_t ( HeapTuple  procTuple)
extern

Definition at line 1708 of file funcapi.c.

1709{
1714 bool isnull;
1715
1716 /* Return NULL if the function isn't declared to return RECORD */
1717 if (procform->prorettype != RECORDOID)
1718 return NULL;
1719
1720 /* If there are no OUT parameters, return NULL */
1723 return NULL;
1724
1725 /* Get the data out of the tuple */
1732 &isnull);
1733 if (isnull)
1734 proargnames = PointerGetDatum(NULL); /* just to be sure */
1735
1739 proargnames);
1740}
TupleDesc build_function_result_tupdesc_d(char prokind, Datum proallargtypes, Datum proargmodes, Datum proargnames)
Definition funcapi.c:1754
bool heap_attisnull(HeapTuple tup, int attnum, TupleDesc tupleDesc)
Definition heaptuple.c:456
static void * GETSTRUCT(const HeapTupleData *tuple)
END_CATALOG_STRUCT typedef FormData_pg_proc * Form_pg_proc
Definition pg_proc.h:140
Datum SysCacheGetAttrNotNull(SysCacheIdentifier cacheId, HeapTuple tup, AttrNumber attributeNumber)
Definition syscache.c:625
Datum SysCacheGetAttr(SysCacheIdentifier cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)
Definition syscache.c:595

References build_function_result_tupdesc_d(), fb(), Form_pg_proc, GETSTRUCT(), heap_attisnull(), PointerGetDatum(), SysCacheGetAttr(), and SysCacheGetAttrNotNull().

Referenced by CallStmtResultDesc(), internal_get_result_type(), and ProcedureCreate().

◆ BuildTupleFromCStrings()

HeapTuple BuildTupleFromCStrings ( AttInMetadata attinmeta,
char **  values 
)
extern

Definition at line 2405 of file execTuples.c.

2406{
2407 TupleDesc tupdesc = attinmeta->tupdesc;
2408 int natts = tupdesc->natts;
2409 Datum *dvalues;
2410 bool *nulls;
2411 int i;
2412 HeapTuple tuple;
2413
2414 dvalues = (Datum *) palloc(natts * sizeof(Datum));
2415 nulls = (bool *) palloc(natts * sizeof(bool));
2416
2417 /*
2418 * Call the "in" function for each non-dropped attribute, even for nulls,
2419 * to support domains.
2420 */
2421 for (i = 0; i < natts; i++)
2422 {
2423 if (!TupleDescCompactAttr(tupdesc, i)->attisdropped)
2424 {
2425 /* Non-dropped attributes */
2426 dvalues[i] = InputFunctionCall(&attinmeta->attinfuncs[i],
2427 values[i],
2428 attinmeta->attioparams[i],
2429 attinmeta->atttypmods[i]);
2430 if (values[i] != NULL)
2431 nulls[i] = false;
2432 else
2433 nulls[i] = true;
2434 }
2435 else
2436 {
2437 /* Handle dropped attributes by setting to NULL */
2438 dvalues[i] = (Datum) 0;
2439 nulls[i] = true;
2440 }
2441 }
2442
2443 /*
2444 * Form a tuple
2445 */
2446 tuple = heap_form_tuple(tupdesc, dvalues, nulls);
2447
2448 /*
2449 * Release locally palloc'd space. XXX would probably be good to pfree
2450 * values of pass-by-reference datums, as well.
2451 */
2452 pfree(dvalues);
2453 pfree(nulls);
2454
2455 return tuple;
2456}
static Datum values[MAXATTR]
Definition bootstrap.c:188
Datum InputFunctionCall(FmgrInfo *flinfo, char *str, Oid typioparam, int32 typmod)
Definition fmgr.c:1532
HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, const Datum *values, const bool *isnull)
Definition heaptuple.c:1037
void pfree(void *pointer)
Definition mcxt.c:1616
FmgrInfo * attinfuncs
Definition funcapi.h:41
TupleDesc tupdesc
Definition funcapi.h:38
Oid * attioparams
Definition funcapi.h:44
int32 * atttypmods
Definition funcapi.h:47
bool attisdropped
Definition tupdesc.h:78
static CompactAttribute * TupleDescCompactAttr(TupleDesc tupdesc, int i)
Definition tupdesc.h:193

References AttInMetadata::attinfuncs, AttInMetadata::attioparams, CompactAttribute::attisdropped, AttInMetadata::atttypmods, fb(), heap_form_tuple(), i, InputFunctionCall(), TupleDescData::natts, palloc(), pfree(), AttInMetadata::tupdesc, TupleDescCompactAttr(), and values.

Referenced by bt_metap(), bt_multi_page_stats(), bt_page_stats_internal(), build_pgstattuple_type(), build_tuplestore_recursively(), crosstab(), dblink_get_pkey(), get_crosstab_tuplestore(), libpqrcv_processTuples(), materializeQueryResult(), materializeResult(), pg_get_keywords(), pg_get_multixact_members(), pgp_armor_headers(), pgrowlocks(), pgstatindex_impl(), pltcl_build_tuple_result(), prs_process_call(), show_all_settings(), storeRow(), ts_process_call(), tt_process_call(), and xpath_table().

◆ end_MultiFuncCall()

void end_MultiFuncCall ( PG_FUNCTION_ARGS  ,
FuncCallContext funcctx 
)
extern

Definition at line 220 of file funcapi.c.

221{
222 ReturnSetInfo *rsi = (ReturnSetInfo *) fcinfo->resultinfo;
223
224 /* Deregister the shutdown callback */
225 UnregisterExprContextCallback(rsi->econtext,
227 PointerGetDatum(fcinfo->flinfo));
228
229 /* But use it to do the real work */
231}
void UnregisterExprContextCallback(ExprContext *econtext, ExprContextCallbackFunction function, Datum arg)
Definition execUtils.c:994
static void shutdown_MultiFuncCall(Datum arg)
Definition funcapi.c:238

References ReturnSetInfo::econtext, PointerGetDatum(), shutdown_MultiFuncCall(), and UnregisterExprContextCallback().

◆ extract_variadic_args()

int extract_variadic_args ( FunctionCallInfo  fcinfo,
int  variadic_start,
bool  convert_unknown,
Datum **  args,
Oid **  types,
bool **  nulls 
)
extern

Definition at line 2011 of file funcapi.c.

2014{
2015 bool variadic = get_fn_expr_variadic(fcinfo->flinfo);
2016 Datum *args_res;
2017 bool *nulls_res;
2018 Oid *types_res;
2019 int nargs,
2020 i;
2021
2022 *args = NULL;
2023 *types = NULL;
2024 *nulls = NULL;
2025
2026 if (variadic)
2027 {
2029 Oid element_type;
2030 bool typbyval;
2031 char typalign;
2032 int16 typlen;
2033
2034 Assert(PG_NARGS() == variadic_start + 1);
2035
2037 return -1;
2038
2040 element_type = ARR_ELEMTYPE(array_in);
2041
2042 get_typlenbyvalalign(element_type,
2043 &typlen, &typbyval, &typalign);
2044 deconstruct_array(array_in, element_type, typlen, typbyval,
2046 &nargs);
2047
2048 /* All the elements of the array have the same type */
2049 types_res = (Oid *) palloc0(nargs * sizeof(Oid));
2050 for (i = 0; i < nargs; i++)
2051 types_res[i] = element_type;
2052 }
2053 else
2054 {
2055 nargs = PG_NARGS() - variadic_start;
2056 Assert(nargs > 0);
2057 nulls_res = (bool *) palloc0(nargs * sizeof(bool));
2058 args_res = (Datum *) palloc0(nargs * sizeof(Datum));
2059 types_res = (Oid *) palloc0(nargs * sizeof(Oid));
2060
2061 for (i = 0; i < nargs; i++)
2062 {
2065 i + variadic_start);
2066
2067 /*
2068 * Turn a constant (more or less literal) value that's of unknown
2069 * type into text if required. Unknowns come in as a cstring
2070 * pointer. Note: for functions declared as taking type "any", the
2071 * parser will not do any type conversion on unknown-type literals
2072 * (that is, undecorated strings or NULLs).
2073 */
2074 if (convert_unknown &&
2075 types_res[i] == UNKNOWNOID &&
2077 {
2078 types_res[i] = TEXTOID;
2079
2081 args_res[i] = (Datum) 0;
2082 else
2083 args_res[i] =
2085 }
2086 else
2087 {
2088 /* no conversion needed, just take the datum as given */
2090 }
2091
2092 if (!OidIsValid(types_res[i]) ||
2094 ereport(ERROR,
2096 errmsg("could not determine data type for argument %d",
2097 i + 1)));
2098 }
2099 }
2100
2101 /* Fill in results */
2102 *args = args_res;
2103 *nulls = nulls_res;
2104 *types = types_res;
2105
2106 return nargs;
2107}
#define PG_GETARG_ARRAYTYPE_P(n)
Definition array.h:263
Datum array_in(PG_FUNCTION_ARGS)
Definition arrayfuncs.c:181
void deconstruct_array(const ArrayType *array, Oid elmtype, int elmlen, bool elmbyval, char elmalign, Datum **elemsp, bool **nullsp, int *nelemsp)
#define CStringGetTextDatum(s)
Definition builtins.h:98
int16_t int16
Definition c.h:613
#define OidIsValid(objectId)
Definition c.h:860
int errcode(int sqlerrcode)
Definition elog.c:874
#define ereport(elevel,...)
Definition elog.h:150
bool get_fn_expr_arg_stable(FmgrInfo *flinfo, int argnum)
Definition fmgr.c:1941
bool get_fn_expr_variadic(FmgrInfo *flinfo)
Definition fmgr.c:2010
Oid get_fn_expr_argtype(FmgrInfo *flinfo, int argnum)
Definition fmgr.c:1876
#define PG_GETARG_POINTER(n)
Definition fmgr.h:277
#define PG_ARGISNULL(n)
Definition fmgr.h:209
#define PG_GETARG_DATUM(n)
Definition fmgr.h:268
#define PG_NARGS()
Definition fmgr.h:203
void get_typlenbyvalalign(Oid typid, int16 *typlen, bool *typbyval, char *typalign)
Definition lsyscache.c:2491
void * palloc0(Size size)
Definition mcxt.c:1417
static char * errmsg
char typalign
Definition pg_type.h:178
FmgrInfo * flinfo
Definition fmgr.h:87

References ARR_ELEMTYPE, array_in(), Assert, CStringGetTextDatum, deconstruct_array(), ereport, errcode(), errmsg, ERROR, fb(), FunctionCallInfoBaseData::flinfo, get_fn_expr_arg_stable(), get_fn_expr_argtype(), get_fn_expr_variadic(), get_typlenbyvalalign(), i, OidIsValid, palloc0(), PG_ARGISNULL, PG_GETARG_ARRAYTYPE_P, PG_GETARG_DATUM, PG_GETARG_POINTER, PG_NARGS, typalign, and types.

Referenced by json_build_array(), json_build_object(), jsonb_build_array(), jsonb_build_object(), and stats_fill_fcinfo_from_arg_pairs().

◆ get_call_result_type()

TypeFuncClass get_call_result_type ( FunctionCallInfo  fcinfo,
Oid resultTypeId,
TupleDesc resultTupleDesc 
)
extern

Definition at line 276 of file funcapi.c.

279{
280 return internal_get_result_type(fcinfo->flinfo->fn_oid,
281 fcinfo->flinfo->fn_expr,
282 (ReturnSetInfo *) fcinfo->resultinfo,
285}
static TypeFuncClass internal_get_result_type(Oid funcid, Node *call_expr, ReturnSetInfo *rsinfo, Oid *resultTypeId, TupleDesc *resultTupleDesc)
Definition funcapi.c:432
Node * fn_expr
Definition fmgr.h:66
Oid fn_oid
Definition fmgr.h:59

References fb(), FunctionCallInfoBaseData::flinfo, FmgrInfo::fn_expr, FmgrInfo::fn_oid, internal_get_result_type(), and FunctionCallInfoBaseData::resultinfo.

Referenced by brin_metapage_info(), bt_metap(), bt_multi_page_stats(), bt_page_items_bytea(), bt_page_items_internal(), bt_page_stats_internal(), build_pgstattuple_type(), compute_function_hashkey(), copy_replication_slot(), crosstab(), get_record_type_from_query(), gin_leafpage_items(), gin_metapage_info(), gin_page_opaque_info(), gist_page_opaque_info(), hash_bitmap_info(), hash_metapage_info(), hash_page_items(), hash_page_stats(), heap_page_items(), heap_tuple_infomask_flags(), InitMaterializedSRF(), materializeResult(), page_header(), pg_backup_stop(), pg_buffercache_evict(), pg_buffercache_evict_all(), pg_buffercache_evict_relation(), pg_buffercache_mark_dirty(), pg_buffercache_mark_dirty_all(), pg_buffercache_mark_dirty_relation(), pg_buffercache_os_pages_internal(), pg_buffercache_pages(), pg_buffercache_summary(), pg_control_checkpoint(), pg_control_init(), pg_control_recovery(), pg_control_system(), pg_create_logical_replication_slot(), pg_create_physical_replication_slot(), pg_get_catalog_foreign_keys(), pg_get_keywords(), pg_get_logical_snapshot_info(), pg_get_logical_snapshot_meta(), pg_get_multixact_members(), pg_get_multixact_stats(), pg_get_object_address(), pg_get_wal_record_info(), pg_get_wal_summarizer_state(), pg_identify_object(), pg_identify_object_as_address(), pg_input_error_info(), pg_last_committed_xact(), pg_partition_tree(), pg_replication_slot_advance(), pg_sequence_parameters(), pg_split_walfile_name(), pg_stat_get_recovery(), pg_stat_get_wal_receiver(), pg_stat_statements_info(), pg_stats_ext_mcvlist_items(), pg_timezone_abbrevs_abbrevs(), pg_timezone_abbrevs_zone(), pg_visibility_map_summary(), pg_xact_commit_timestamp_origin(), pgp_armor_headers(), pgstatginindex_internal(), pgstathashindex(), pgstatindex_impl(), pgstattuple_approx_internal(), plperl_return_next_internal(), plperl_sv_to_datum(), plpgsql_exec_function(), pltcl_func_handler(), PLy_exec_function(), prs_setup_firstcall(), setup_firstcall(), sql_compile_callback(), ssl_extension_info(), storeRow(), test_custom_stats_var_report(), test_enc_conversion(), test_saslprep(), test_saslprep_ranges(), ts_setup_firstcall(), tsvector_unnest(), and tt_setup_firstcall().

◆ get_expr_result_tupdesc()

TupleDesc get_expr_result_tupdesc ( Node expr,
bool  noError 
)
extern

Definition at line 553 of file funcapi.c.

554{
557
559
562 return tupleDesc;
563
564 if (!noError)
565 {
566 Oid exprTypeId = exprType(expr);
567
568 if (exprTypeId != RECORDOID)
571 errmsg("type %s is not composite",
573 else
576 errmsg("record type has not been registered")));
577 }
578
579 return NULL;
580}
char * format_type_be(Oid type_oid)
TypeFuncClass get_expr_result_type(Node *expr, Oid *resultTypeId, TupleDesc *resultTupleDesc)
Definition funcapi.c:299
Oid exprType(const Node *expr)
Definition nodeFuncs.c:42

References ereport, errcode(), errmsg, ERROR, exprType(), fb(), format_type_be(), get_expr_result_type(), TYPEFUNC_COMPOSITE, and TYPEFUNC_COMPOSITE_DOMAIN.

Referenced by expandRecordVariable(), ExpandRowReference(), get_name_for_var_field(), get_rte_attribute_is_dropped(), ParseComplexProjection(), and process_function_rte_ref().

◆ get_expr_result_type()

TypeFuncClass get_expr_result_type ( Node expr,
Oid resultTypeId,
TupleDesc resultTupleDesc 
)
extern

Definition at line 299 of file funcapi.c.

302{
303 TypeFuncClass result;
304
305 if (expr && IsA(expr, FuncExpr))
306 result = internal_get_result_type(((FuncExpr *) expr)->funcid,
307 expr,
308 NULL,
311 else if (expr && IsA(expr, OpExpr))
312 result = internal_get_result_type(get_opcode(((OpExpr *) expr)->opno),
313 expr,
314 NULL,
317 else if (expr && IsA(expr, RowExpr) &&
318 ((RowExpr *) expr)->row_typeid == RECORDOID)
319 {
320 /* We can resolve the record type by generating the tupdesc directly */
321 RowExpr *rexpr = (RowExpr *) expr;
322 TupleDesc tupdesc;
323 AttrNumber i = 1;
324 ListCell *lcc,
325 *lcn;
326
327 tupdesc = CreateTemplateTupleDesc(list_length(rexpr->args));
328 Assert(list_length(rexpr->args) == list_length(rexpr->colnames));
329 forboth(lcc, rexpr->args, lcn, rexpr->colnames)
330 {
331 Node *col = (Node *) lfirst(lcc);
332 char *colname = strVal(lfirst(lcn));
333
334 TupleDescInitEntry(tupdesc, i,
335 colname,
336 exprType(col),
338 0);
341 i++;
342 }
343 TupleDescFinalize(tupdesc);
344
345 if (resultTypeId)
346 *resultTypeId = rexpr->row_typeid;
347 if (resultTupleDesc)
349 return TYPEFUNC_COMPOSITE;
350 }
351 else if (expr && IsA(expr, Const) &&
352 ((Const *) expr)->consttype == RECORDOID &&
353 !((Const *) expr)->constisnull)
354 {
355 /*
356 * When EXPLAIN'ing some queries with SEARCH/CYCLE clauses, we may
357 * need to resolve field names of a RECORD-type Const. The datum
358 * should contain a typmod that will tell us that.
359 */
360 HeapTupleHeader rec;
361 Oid tupType;
363
364 rec = DatumGetHeapTupleHeader(((Const *) expr)->constvalue);
367 if (resultTypeId)
369 if (tupType != RECORDOID || tupTypmod >= 0)
370 {
371 /* Should be able to look it up */
372 if (resultTupleDesc)
374 tupTypmod);
375 return TYPEFUNC_COMPOSITE;
376 }
377 else
378 {
379 /* This shouldn't really happen ... */
380 if (resultTupleDesc)
382 return TYPEFUNC_RECORD;
383 }
384 }
385 else
386 {
387 /* handle as a generic expression; no chance to resolve RECORD */
388 Oid typid = exprType(expr);
389 Oid base_typid;
390
391 if (resultTypeId)
392 *resultTypeId = typid;
393 if (resultTupleDesc)
395 result = get_type_func_class(typid, &base_typid);
396 if ((result == TYPEFUNC_COMPOSITE ||
397 result == TYPEFUNC_COMPOSITE_DOMAIN) &&
400 }
401
402 return result;
403}
int16 AttrNumber
Definition attnum.h:21
int32_t int32
Definition c.h:614
TupleDesc BlessTupleDesc(TupleDesc tupdesc)
#define DatumGetHeapTupleHeader(X)
Definition fmgr.h:296
static TypeFuncClass get_type_func_class(Oid typid, Oid *base_typeid)
Definition funcapi.c:1331
static int32 HeapTupleHeaderGetTypMod(const HeapTupleHeaderData *tup)
static Oid HeapTupleHeaderGetTypeId(const HeapTupleHeaderData *tup)
RegProcedure get_opcode(Oid opno)
Definition lsyscache.c:1505
int32 exprTypmod(const Node *expr)
Definition nodeFuncs.c:304
Oid exprCollation(const Node *expr)
Definition nodeFuncs.c:826
#define IsA(nodeptr, _type_)
Definition nodes.h:164
#define lfirst(lc)
Definition pg_list.h:172
static int list_length(const List *l)
Definition pg_list.h:152
#define forboth(cell1, list1, cell2, list2)
Definition pg_list.h:518
Definition nodes.h:135
List * args
Definition primnodes.h:1449
void TupleDescInitEntryCollation(TupleDesc desc, AttrNumber attributeNumber, Oid collationid)
Definition tupdesc.c:1081
TupleDesc lookup_rowtype_tupdesc_copy(Oid type_id, int32 typmod)
Definition typcache.c:1981
#define strVal(v)
Definition value.h:82

References RowExpr::args, Assert, BlessTupleDesc(), CreateTemplateTupleDesc(), DatumGetHeapTupleHeader, exprCollation(), exprType(), exprTypmod(), fb(), forboth, get_opcode(), get_type_func_class(), HeapTupleHeaderGetTypeId(), HeapTupleHeaderGetTypMod(), i, internal_get_result_type(), IsA, lfirst, list_length(), lookup_rowtype_tupdesc_copy(), strVal, TupleDescFinalize(), TupleDescInitEntry(), TupleDescInitEntryCollation(), TYPEFUNC_COMPOSITE, TYPEFUNC_COMPOSITE_DOMAIN, and TYPEFUNC_RECORD.

Referenced by addRangeTableEntryForFunction(), ExecInitFunctionScan(), expandRTE(), get_expr_result_tupdesc(), init_sexpr(), inline_function(), inline_sql_function_in_from(), and pull_up_constant_function().

◆ get_func_arg_info()

int get_func_arg_info ( HeapTuple  procTup,
Oid **  p_argtypes,
char ***  p_argnames,
char **  p_argmodes 
)
extern

Definition at line 1382 of file funcapi.c.

1384{
1389 bool isNull;
1390 ArrayType *arr;
1391 int numargs;
1392 Datum *elems;
1393 int nelems;
1394 int i;
1395
1396 /* First discover the total number of parameters and get their types */
1399 &isNull);
1400 if (!isNull)
1401 {
1402 /*
1403 * We expect the arrays to be 1-D arrays of the right types; verify
1404 * that. For the OID and char arrays, we don't need to use
1405 * deconstruct_array() since the array data is just going to look like
1406 * a C array of values.
1407 */
1408 arr = DatumGetArrayTypeP(proallargtypes); /* ensure not toasted */
1409 numargs = ARR_DIMS(arr)[0];
1410 if (ARR_NDIM(arr) != 1 ||
1411 numargs < 0 ||
1412 ARR_HASNULL(arr) ||
1413 ARR_ELEMTYPE(arr) != OIDOID)
1414 elog(ERROR, "proallargtypes is not a 1-D Oid array or it contains nulls");
1415 Assert(numargs >= procStruct->pronargs);
1416 *p_argtypes = (Oid *) palloc(numargs * sizeof(Oid));
1418 numargs * sizeof(Oid));
1419 }
1420 else
1421 {
1422 /* If no proallargtypes, use proargtypes */
1423 numargs = procStruct->proargtypes.dim1;
1424 Assert(numargs == procStruct->pronargs);
1425 *p_argtypes = (Oid *) palloc(numargs * sizeof(Oid));
1426 memcpy(*p_argtypes, procStruct->proargtypes.values,
1427 numargs * sizeof(Oid));
1428 }
1429
1430 /* Get argument names, if available */
1433 &isNull);
1434 if (isNull)
1435 *p_argnames = NULL;
1436 else
1437 {
1439 &elems, NULL, &nelems);
1440 if (nelems != numargs) /* should not happen */
1441 elog(ERROR, "proargnames must have the same number of elements as the function has arguments");
1442 *p_argnames = palloc_array(char *, numargs);
1443 for (i = 0; i < numargs; i++)
1444 (*p_argnames)[i] = TextDatumGetCString(elems[i]);
1445 }
1446
1447 /* Get argument modes, if available */
1450 &isNull);
1451 if (isNull)
1452 *p_argmodes = NULL;
1453 else
1454 {
1455 arr = DatumGetArrayTypeP(proargmodes); /* ensure not toasted */
1456 if (ARR_NDIM(arr) != 1 ||
1457 ARR_DIMS(arr)[0] != numargs ||
1458 ARR_HASNULL(arr) ||
1459 ARR_ELEMTYPE(arr) != CHAROID)
1460 elog(ERROR, "proargmodes is not a 1-D char array of length %d or it contains nulls",
1461 numargs);
1462 *p_argmodes = (char *) palloc(numargs * sizeof(char));
1464 numargs * sizeof(char));
1465 }
1466
1467 return numargs;
1468}
#define palloc_array(type, count)
Definition fe_memutils.h:76

References ARR_DATA_PTR, ARR_DIMS, ARR_ELEMTYPE, ARR_HASNULL, ARR_NDIM, Assert, DatumGetArrayTypeP, deconstruct_array_builtin(), elog, ERROR, fb(), Form_pg_proc, GETSTRUCT(), i, palloc(), palloc_array, SysCacheGetAttr(), and TextDatumGetCString.

Referenced by make_callstmt_target(), MatchNamedCall(), pg_get_function_arg_default(), plperl_validator(), plpgsql_compile_callback(), plpgsql_validator(), plsample_func_handler(), PLy_procedure_create(), print_function_arguments(), and print_function_sqlbody().

◆ get_func_input_arg_names()

int get_func_input_arg_names ( Datum  proargnames,
Datum  proargmodes,
char ***  arg_names 
)
extern

Definition at line 1525 of file funcapi.c.

1527{
1528 ArrayType *arr;
1529 int numargs;
1530 Datum *argnames;
1531 char *argmodes;
1532 char **inargnames;
1533 int numinargs;
1534 int i;
1535
1536 /* Do nothing if null proargnames */
1538 {
1539 *arg_names = NULL;
1540 return 0;
1541 }
1542
1543 /*
1544 * We expect the arrays to be 1-D arrays of the right types; verify that.
1545 * For proargmodes, we don't need to use deconstruct_array() since the
1546 * array data is just going to look like a C array of values.
1547 */
1548 arr = DatumGetArrayTypeP(proargnames); /* ensure not toasted */
1549 if (ARR_NDIM(arr) != 1 ||
1550 ARR_HASNULL(arr) ||
1551 ARR_ELEMTYPE(arr) != TEXTOID)
1552 elog(ERROR, "proargnames is not a 1-D text array or it contains nulls");
1553 deconstruct_array_builtin(arr, TEXTOID, &argnames, NULL, &numargs);
1555 {
1556 arr = DatumGetArrayTypeP(proargmodes); /* ensure not toasted */
1557 if (ARR_NDIM(arr) != 1 ||
1558 ARR_DIMS(arr)[0] != numargs ||
1559 ARR_HASNULL(arr) ||
1560 ARR_ELEMTYPE(arr) != CHAROID)
1561 elog(ERROR, "proargmodes is not a 1-D char array of length %d or it contains nulls",
1562 numargs);
1563 argmodes = (char *) ARR_DATA_PTR(arr);
1564 }
1565 else
1566 argmodes = NULL;
1567
1568 /* zero elements probably shouldn't happen, but handle it gracefully */
1569 if (numargs <= 0)
1570 {
1571 *arg_names = NULL;
1572 return 0;
1573 }
1574
1575 /* extract input-argument names */
1576 inargnames = (char **) palloc(numargs * sizeof(char *));
1577 numinargs = 0;
1578 for (i = 0; i < numargs; i++)
1579 {
1580 if (argmodes == NULL ||
1581 argmodes[i] == PROARGMODE_IN ||
1584 {
1585 char *pname = TextDatumGetCString(argnames[i]);
1586
1587 if (pname[0] != '\0')
1589 else
1591 numinargs++;
1592 }
1593 }
1594
1596 return numinargs;
1597}

References ARR_DATA_PTR, ARR_DIMS, ARR_ELEMTYPE, ARR_HASNULL, ARR_NDIM, DatumGetArrayTypeP, deconstruct_array_builtin(), elog, ERROR, fb(), i, palloc(), PointerGetDatum(), and TextDatumGetCString.

Referenced by prepare_sql_fn_parse_info(), and ProcedureCreate().

◆ get_func_result_name()

char * get_func_result_name ( Oid  functionId)
extern

Definition at line 1610 of file funcapi.c.

1611{
1612 char *result;
1616 ArrayType *arr;
1617 int numargs;
1618 char *argmodes;
1619 Datum *argnames;
1620 int numoutargs;
1621 int nargnames;
1622 int i;
1623
1624 /* First fetch the function's pg_proc row */
1627 elog(ERROR, "cache lookup failed for function %u", functionId);
1628
1629 /* If there are no named OUT parameters, return NULL */
1632 result = NULL;
1633 else
1634 {
1635 /* Get the data out of the tuple */
1640
1641 /*
1642 * We expect the arrays to be 1-D arrays of the right types; verify
1643 * that. For the char array, we don't need to use deconstruct_array()
1644 * since the array data is just going to look like a C array of
1645 * values.
1646 */
1647 arr = DatumGetArrayTypeP(proargmodes); /* ensure not toasted */
1648 numargs = ARR_DIMS(arr)[0];
1649 if (ARR_NDIM(arr) != 1 ||
1650 numargs < 0 ||
1651 ARR_HASNULL(arr) ||
1652 ARR_ELEMTYPE(arr) != CHAROID)
1653 elog(ERROR, "proargmodes is not a 1-D char array or it contains nulls");
1654 argmodes = (char *) ARR_DATA_PTR(arr);
1655 arr = DatumGetArrayTypeP(proargnames); /* ensure not toasted */
1656 if (ARR_NDIM(arr) != 1 ||
1657 ARR_DIMS(arr)[0] != numargs ||
1658 ARR_HASNULL(arr) ||
1659 ARR_ELEMTYPE(arr) != TEXTOID)
1660 elog(ERROR, "proargnames is not a 1-D text array of length %d or it contains nulls",
1661 numargs);
1662 deconstruct_array_builtin(arr, TEXTOID, &argnames, NULL, &nargnames);
1663 Assert(nargnames == numargs);
1664
1665 /* scan for output argument(s) */
1666 result = NULL;
1667 numoutargs = 0;
1668 for (i = 0; i < numargs; i++)
1669 {
1670 if (argmodes[i] == PROARGMODE_IN ||
1672 continue;
1676 if (++numoutargs > 1)
1677 {
1678 /* multiple out args, so forget it */
1679 result = NULL;
1680 break;
1681 }
1682 result = TextDatumGetCString(argnames[i]);
1683 if (result == NULL || result[0] == '\0')
1684 {
1685 /* Parameter is not named, so forget it */
1686 result = NULL;
1687 break;
1688 }
1689 }
1690 }
1691
1693
1694 return result;
1695}
#define HeapTupleIsValid(tuple)
Definition htup.h:78
static Datum ObjectIdGetDatum(Oid X)
Definition postgres.h:252
void ReleaseSysCache(HeapTuple tuple)
Definition syscache.c:264
HeapTuple SearchSysCache1(SysCacheIdentifier cacheId, Datum key1)
Definition syscache.c:220

References ARR_DATA_PTR, ARR_DIMS, ARR_ELEMTYPE, ARR_HASNULL, ARR_NDIM, Assert, DatumGetArrayTypeP, deconstruct_array_builtin(), elog, ERROR, fb(), heap_attisnull(), HeapTupleIsValid, i, ObjectIdGetDatum(), ReleaseSysCache(), SearchSysCache1(), SysCacheGetAttrNotNull(), and TextDatumGetCString.

Referenced by chooseScalarFunctionAlias().

◆ get_func_result_type()

TypeFuncClass get_func_result_type ( Oid  functionId,
Oid resultTypeId,
TupleDesc resultTupleDesc 
)
extern

Definition at line 412 of file funcapi.c.

415{
417 NULL,
418 NULL,
421}

References fb(), and internal_get_result_type().

Referenced by fmgr_sql_validator().

◆ get_func_trftypes()

int get_func_trftypes ( HeapTuple  procTup,
Oid **  p_trftypes 
)
extern

Definition at line 1478 of file funcapi.c.

1480{
1482 ArrayType *arr;
1483 int nelems;
1484 bool isNull;
1485
1488 &isNull);
1489 if (!isNull)
1490 {
1491 /*
1492 * We expect the arrays to be 1-D arrays of the right types; verify
1493 * that. For the OID and char arrays, we don't need to use
1494 * deconstruct_array() since the array data is just going to look like
1495 * a C array of values.
1496 */
1497 arr = DatumGetArrayTypeP(protrftypes); /* ensure not toasted */
1498 nelems = ARR_DIMS(arr)[0];
1499 if (ARR_NDIM(arr) != 1 ||
1500 nelems < 0 ||
1501 ARR_HASNULL(arr) ||
1502 ARR_ELEMTYPE(arr) != OIDOID)
1503 elog(ERROR, "protrftypes is not a 1-D Oid array or it contains nulls");
1504 *p_trftypes = (Oid *) palloc(nelems * sizeof(Oid));
1506 nelems * sizeof(Oid));
1507
1508 return nelems;
1509 }
1510 else
1511 return 0;
1512}

References ARR_DATA_PTR, ARR_DIMS, ARR_ELEMTYPE, ARR_HASNULL, ARR_NDIM, DatumGetArrayTypeP, elog, ERROR, fb(), palloc(), and SysCacheGetAttr().

Referenced by print_function_trftypes().

◆ HeapTupleGetDatum()

static Datum HeapTupleGetDatum ( const HeapTupleData tuple)
inlinestatic

Definition at line 230 of file funcapi.h.

231{
232 return HeapTupleHeaderGetDatum(tuple->t_data);
233}
Datum HeapTupleHeaderGetDatum(HeapTupleHeader tuple)
HeapTupleHeader t_data
Definition htup.h:68

References HeapTupleHeaderGetDatum(), and HeapTupleData::t_data.

Referenced by aclexplode(), brin_metapage_info(), bt_metap(), bt_multi_page_stats(), bt_page_print_tuples(), bt_page_stats_internal(), build_pgstattuple_type(), copy_replication_slot(), CopyToJsonOneRow(), dblink_get_pkey(), exec_eval_datum(), ExecEvalConvertRowtype(), ExecEvalFieldStoreForm(), ExecEvalRow(), gin_leafpage_items(), gin_metapage_info(), gin_page_opaque_info(), gist_page_opaque_info(), hash_bitmap_info(), hash_metapage_info(), hash_page_items(), hash_page_stats(), heap_page_items(), heap_tuple_infomask_flags(), hstore_each(), hstore_populate_record(), page_header(), pg_backup_stop(), pg_buffercache_evict(), pg_buffercache_evict_all(), pg_buffercache_evict_relation(), pg_buffercache_mark_dirty(), pg_buffercache_mark_dirty_all(), pg_buffercache_mark_dirty_relation(), pg_buffercache_os_pages_internal(), pg_buffercache_pages(), pg_buffercache_summary(), pg_control_checkpoint(), pg_control_init(), pg_control_recovery(), pg_control_system(), pg_create_logical_replication_slot(), pg_create_physical_replication_slot(), pg_get_catalog_foreign_keys(), pg_get_keywords(), pg_get_logical_snapshot_info(), pg_get_logical_snapshot_meta(), pg_get_multixact_members(), pg_get_multixact_stats(), pg_get_object_address(), pg_get_publication_tables(), pg_get_sequence_data(), pg_get_wal_record_info(), pg_get_wal_summarizer_state(), pg_identify_object(), pg_identify_object_as_address(), pg_input_error_info(), pg_last_committed_xact(), pg_lock_status(), pg_partition_tree(), pg_prepared_xact(), pg_replication_slot_advance(), pg_sequence_parameters(), pg_split_walfile_name(), pg_stat_file(), pg_stat_get_archiver(), pg_stat_get_backend_subxact(), pg_stat_get_recovery(), pg_stat_get_replication_slot(), pg_stat_get_subscription_stats(), pg_stat_get_wal_receiver(), pg_stat_statements_info(), pg_stat_wal_build_tuple(), pg_stats_ext_mcvlist_items(), pg_timezone_abbrevs_abbrevs(), pg_timezone_abbrevs_zone(), pg_visibility(), pg_visibility_map(), pg_visibility_map_rel(), pg_visibility_map_summary(), pg_visibility_rel(), pg_walfile_name_offset(), pg_xact_commit_timestamp_origin(), pgp_armor_headers(), pgstatginindex_internal(), pgstathashindex(), pgstatindex_impl(), pgstattuple_approx_internal(), plperl_hash_to_datum(), plperl_return_next_internal(), pltcl_build_tuple_result(), pltcl_func_handler(), prs_process_call(), show_all_settings(), ssl_extension_info(), test_custom_stats_fixed_report(), test_custom_stats_var_report(), test_enc_conversion(), test_predtest(), test_saslprep(), test_saslprep_ranges(), ts_process_call(), tsvector_unnest(), and tt_process_call().

◆ HeapTupleHeaderGetDatum()

Datum HeapTupleHeaderGetDatum ( HeapTupleHeader  tuple)
extern

Definition at line 2494 of file execTuples.c.

2495{
2496 Datum result;
2497 TupleDesc tupDesc;
2498
2499 /* No work if there are no external TOAST pointers in the tuple */
2500 if (!HeapTupleHeaderHasExternal(tuple))
2501 return PointerGetDatum(tuple);
2502
2503 /* Use the type data saved by heap_form_tuple to look up the rowtype */
2506
2507 /* And do the flattening */
2508 result = toast_flatten_tuple_to_datum(tuple,
2510 tupDesc);
2511
2512 ReleaseTupleDesc(tupDesc);
2513
2514 return result;
2515}
Datum toast_flatten_tuple_to_datum(HeapTupleHeader tup, uint32 tup_len, TupleDesc tupleDesc)
Definition heaptoast.c:449
static uint32 HeapTupleHeaderGetDatumLength(const HeapTupleHeaderData *tup)
#define HeapTupleHeaderHasExternal(tup)
#define ReleaseTupleDesc(tupdesc)
Definition tupdesc.h:238
TupleDesc lookup_rowtype_tupdesc(Oid type_id, int32 typmod)
Definition typcache.c:1947

References HeapTupleHeaderGetDatumLength(), HeapTupleHeaderGetTypeId(), HeapTupleHeaderGetTypMod(), HeapTupleHeaderHasExternal, lookup_rowtype_tupdesc(), PointerGetDatum(), ReleaseTupleDesc, and toast_flatten_tuple_to_datum().

Referenced by HeapTupleGetDatum(), populate_composite(), and populate_recordset_record().

◆ init_MultiFuncCall()

FuncCallContext * init_MultiFuncCall ( PG_FUNCTION_ARGS  )
extern

Definition at line 133 of file funcapi.c.

134{
135 FuncCallContext *retval;
136
137 /*
138 * Bail if we're called in the wrong context
139 */
140 if (fcinfo->resultinfo == NULL || !IsA(fcinfo->resultinfo, ReturnSetInfo))
143 errmsg("set-valued function called in context that cannot accept a set")));
144
145 if (fcinfo->flinfo->fn_extra == NULL)
146 {
147 /*
148 * First call
149 */
150 ReturnSetInfo *rsi = (ReturnSetInfo *) fcinfo->resultinfo;
152
153 /*
154 * Create a suitably long-lived context to hold cross-call data
155 */
156 multi_call_ctx = AllocSetContextCreate(fcinfo->flinfo->fn_mcxt,
157 "SRF multi-call context",
159
160 /*
161 * Allocate suitably long-lived space and zero it
162 */
163 retval = (FuncCallContext *)
165 sizeof(FuncCallContext));
166
167 /*
168 * initialize the elements
169 */
170 retval->call_cntr = 0;
171 retval->max_calls = 0;
172 retval->user_fctx = NULL;
173 retval->attinmeta = NULL;
174 retval->tuple_desc = NULL;
176
177 /*
178 * save the pointer for cross-call use
179 */
180 fcinfo->flinfo->fn_extra = retval;
181
182 /*
183 * Ensure we will get shut down cleanly if the exprcontext is not run
184 * to completion.
185 */
186 RegisterExprContextCallback(rsi->econtext,
188 PointerGetDatum(fcinfo->flinfo));
189 }
190 else
191 {
192 /* second and subsequent calls */
193 elog(ERROR, "init_MultiFuncCall cannot be called more than once");
194
195 /* never reached, but keep compiler happy */
196 retval = NULL;
197 }
198
199 return retval;
200}
void RegisterExprContextCallback(ExprContext *econtext, ExprContextCallbackFunction function, Datum arg)
Definition execUtils.c:968
void * MemoryContextAllocZero(MemoryContext context, Size size)
Definition mcxt.c:1266
#define AllocSetContextCreate
Definition memutils.h:129
#define ALLOCSET_SMALL_SIZES
Definition memutils.h:170
void * user_fctx
Definition funcapi.h:82
uint64 max_calls
Definition funcapi.h:74
uint64 call_cntr
Definition funcapi.h:65
AttInMetadata * attinmeta
Definition funcapi.h:91
MemoryContext multi_call_memory_ctx
Definition funcapi.h:101
TupleDesc tuple_desc
Definition funcapi.h:112

References ALLOCSET_SMALL_SIZES, AllocSetContextCreate, FuncCallContext::attinmeta, FuncCallContext::call_cntr, ReturnSetInfo::econtext, elog, ereport, errcode(), errmsg, ERROR, fb(), IsA, FuncCallContext::max_calls, MemoryContextAllocZero(), FuncCallContext::multi_call_memory_ctx, PointerGetDatum(), RegisterExprContextCallback(), shutdown_MultiFuncCall(), FuncCallContext::tuple_desc, and FuncCallContext::user_fctx.

◆ InitMaterializedSRF()

void InitMaterializedSRF ( FunctionCallInfo  fcinfo,
bits32  flags 
)
extern

Definition at line 76 of file funcapi.c.

77{
78 bool random_access;
80 Tuplestorestate *tupstore;
84
85 /* check to see if caller supports returning a tuplestore */
86 if (rsinfo == NULL || !IsA(rsinfo, ReturnSetInfo))
89 errmsg("set-valued function called in context that cannot accept a set")));
90 if (!(rsinfo->allowedModes & SFRM_Materialize) ||
91 ((flags & MAT_SRF_USE_EXPECTED_DESC) != 0 && rsinfo->expectedDesc == NULL))
94 errmsg("materialize mode required, but it is not allowed in this context")));
95
96 /*
97 * Store the tuplestore and the tuple descriptor in ReturnSetInfo. This
98 * must be done in the per-query memory context.
99 */
100 per_query_ctx = rsinfo->econtext->ecxt_per_query_memory;
102
103 /* build a tuple descriptor for our result type */
104 if ((flags & MAT_SRF_USE_EXPECTED_DESC) != 0)
106 else
107 {
109 elog(ERROR, "return type must be a row type");
110 }
111
112 /* If requested, bless the tuple descriptor */
113 if ((flags & MAT_SRF_BLESS) != 0)
115
116 random_access = (rsinfo->allowedModes & SFRM_Materialize_Random) != 0;
117
118 tupstore = tuplestore_begin_heap(random_access, false, work_mem);
119 rsinfo->returnMode = SFRM_Materialize;
120 rsinfo->setResult = tupstore;
121 rsinfo->setDesc = stored_tupdesc;
123}
@ SFRM_Materialize_Random
Definition execnodes.h:353
@ SFRM_Materialize
Definition execnodes.h:352
TypeFuncClass get_call_result_type(FunctionCallInfo fcinfo, Oid *resultTypeId, TupleDesc *resultTupleDesc)
Definition funcapi.c:276
#define MAT_SRF_BLESS
Definition funcapi.h:297
#define MAT_SRF_USE_EXPECTED_DESC
Definition funcapi.h:296
int work_mem
Definition globals.c:131
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition palloc.h:124
TupleDesc CreateTupleDescCopy(TupleDesc tupdesc)
Definition tupdesc.c:242
Tuplestorestate * tuplestore_begin_heap(bool randomAccess, bool interXact, int maxKBytes)
Definition tuplestore.c:331

References BlessTupleDesc(), CreateTupleDescCopy(), elog, ereport, errcode(), errmsg, ERROR, fb(), get_call_result_type(), IsA, MAT_SRF_BLESS, MAT_SRF_USE_EXPECTED_DESC, MemoryContextSwitchTo(), FunctionCallInfoBaseData::resultinfo, SFRM_Materialize, SFRM_Materialize_Random, tuplestore_begin_heap(), TYPEFUNC_COMPOSITE, and work_mem.

Referenced by brin_page_items(), dblink_get_notify(), each_worker(), each_worker_jsonb(), elements_worker(), elements_worker_jsonb(), get_altertable_subcmdinfo(), GetWALRecordsInfo(), GetWalStats(), gist_page_items(), gist_page_items_bytea(), injection_points_list(), pg_available_extension_versions(), pg_available_extensions(), pg_available_wal_summaries(), pg_buffercache_usage_counts(), pg_config(), pg_cursor(), pg_event_trigger_ddl_commands(), pg_event_trigger_dropped_objects(), pg_extension_update_paths(), pg_get_aios(), pg_get_backend_memory_contexts(), pg_get_dsm_registry_allocations(), pg_get_loaded_modules(), pg_get_replication_slots(), pg_get_shmem_allocations(), pg_get_shmem_allocations_numa(), pg_get_wait_events(), pg_get_wal_block_info(), pg_get_wal_resource_managers(), pg_hba_file_rules(), pg_ident_file_mappings(), pg_logical_slot_get_changes_guts(), pg_ls_dir(), pg_ls_dir_files(), pg_options_to_table(), pg_prepared_statement(), pg_show_replication_origin_status(), pg_stat_get_activity(), pg_stat_get_backend_io(), pg_stat_get_io(), pg_stat_get_lock(), pg_stat_get_progress_info(), pg_stat_get_recovery_prefetch(), pg_stat_get_slru(), pg_stat_get_subscription(), pg_stat_get_wal_senders(), pg_stat_statements_internal(), pg_tablespace_databases(), pg_timezone_names(), pg_wal_summary_contents(), pgrowlocks(), postgres_fdw_get_connections_internal(), show_all_file_settings(), text_to_table(), verify_heapam(), and xpath_table().

◆ per_MultiFuncCall()

FuncCallContext * per_MultiFuncCall ( PG_FUNCTION_ARGS  )
extern

Definition at line 208 of file funcapi.c.

209{
210 FuncCallContext *retval = (FuncCallContext *) fcinfo->flinfo->fn_extra;
211
212 return retval;
213}

◆ RelationNameGetTupleDesc()

TupleDesc RelationNameGetTupleDesc ( const char relname)
extern

Definition at line 1875 of file funcapi.c.

1876{
1878 Relation rel;
1879 TupleDesc tupdesc;
1881
1882 /* Open relation and copy the tuple description */
1886 tupdesc = CreateTupleDescCopy(RelationGetDescr(rel));
1888
1889 return tupdesc;
1890}
#define AccessShareLock
Definition lockdefs.h:36
RangeVar * makeRangeVarFromNameList(const List *names)
Definition namespace.c:3626
NameData relname
Definition pg_class.h:40
List * stringToQualifiedNameList(const char *string, Node *escontext)
Definition regproc.c:1922
#define RelationGetDescr(relation)
Definition rel.h:540
void relation_close(Relation relation, LOCKMODE lockmode)
Definition relation.c:205
Relation relation_openrv(const RangeVar *relation, LOCKMODE lockmode)
Definition relation.c:137
Definition pg_list.h:54

References AccessShareLock, CreateTupleDescCopy(), fb(), makeRangeVarFromNameList(), relation_close(), relation_openrv(), RelationGetDescr, relname, and stringToQualifiedNameList().

◆ resolve_polymorphic_argtypes()

bool resolve_polymorphic_argtypes ( int  numargs,
Oid argtypes,
char argmodes,
Node call_expr 
)
extern

Definition at line 1067 of file funcapi.c.

1069{
1070 bool have_polymorphic_result = false;
1071 bool have_anyelement_result = false;
1072 bool have_anyarray_result = false;
1073 bool have_anyrange_result = false;
1074 bool have_anymultirange_result = false;
1075 bool have_anycompatible_result = false;
1081 int inargno;
1082 int i;
1083
1084 /*
1085 * First pass: resolve polymorphic inputs, check for outputs. As in
1086 * resolve_polymorphic_tupdesc, we rely on the parser to have enforced
1087 * type consistency and coerced ANYCOMPATIBLE args to a common supertype.
1088 */
1089 memset(&poly_actuals, 0, sizeof(poly_actuals));
1090 memset(&anyc_actuals, 0, sizeof(anyc_actuals));
1091 inargno = 0;
1092 for (i = 0; i < numargs; i++)
1093 {
1095
1096 switch (argtypes[i])
1097 {
1098 case ANYELEMENTOID:
1099 case ANYNONARRAYOID:
1100 case ANYENUMOID:
1102 {
1105 }
1106 else
1107 {
1108 if (!OidIsValid(poly_actuals.anyelement_type))
1109 {
1110 poly_actuals.anyelement_type =
1112 if (!OidIsValid(poly_actuals.anyelement_type))
1113 return false;
1114 }
1115 argtypes[i] = poly_actuals.anyelement_type;
1116 }
1117 break;
1118 case ANYARRAYOID:
1120 {
1122 have_anyarray_result = true;
1123 }
1124 else
1125 {
1126 if (!OidIsValid(poly_actuals.anyarray_type))
1127 {
1128 poly_actuals.anyarray_type =
1130 if (!OidIsValid(poly_actuals.anyarray_type))
1131 return false;
1132 }
1133 argtypes[i] = poly_actuals.anyarray_type;
1134 }
1135 break;
1136 case ANYRANGEOID:
1138 {
1140 have_anyrange_result = true;
1141 }
1142 else
1143 {
1144 if (!OidIsValid(poly_actuals.anyrange_type))
1145 {
1146 poly_actuals.anyrange_type =
1148 if (!OidIsValid(poly_actuals.anyrange_type))
1149 return false;
1150 }
1151 argtypes[i] = poly_actuals.anyrange_type;
1152 }
1153 break;
1154 case ANYMULTIRANGEOID:
1156 {
1159 }
1160 else
1161 {
1162 if (!OidIsValid(poly_actuals.anymultirange_type))
1163 {
1164 poly_actuals.anymultirange_type =
1166 if (!OidIsValid(poly_actuals.anymultirange_type))
1167 return false;
1168 }
1169 argtypes[i] = poly_actuals.anymultirange_type;
1170 }
1171 break;
1172 case ANYCOMPATIBLEOID:
1175 {
1178 }
1179 else
1180 {
1181 if (!OidIsValid(anyc_actuals.anyelement_type))
1182 {
1183 anyc_actuals.anyelement_type =
1185 if (!OidIsValid(anyc_actuals.anyelement_type))
1186 return false;
1187 }
1188 argtypes[i] = anyc_actuals.anyelement_type;
1189 }
1190 break;
1193 {
1196 }
1197 else
1198 {
1199 if (!OidIsValid(anyc_actuals.anyarray_type))
1200 {
1201 anyc_actuals.anyarray_type =
1203 if (!OidIsValid(anyc_actuals.anyarray_type))
1204 return false;
1205 }
1206 argtypes[i] = anyc_actuals.anyarray_type;
1207 }
1208 break;
1211 {
1214 }
1215 else
1216 {
1217 if (!OidIsValid(anyc_actuals.anyrange_type))
1218 {
1219 anyc_actuals.anyrange_type =
1221 if (!OidIsValid(anyc_actuals.anyrange_type))
1222 return false;
1223 }
1224 argtypes[i] = anyc_actuals.anyrange_type;
1225 }
1226 break;
1229 {
1232 }
1233 else
1234 {
1235 if (!OidIsValid(anyc_actuals.anymultirange_type))
1236 {
1237 anyc_actuals.anymultirange_type =
1239 if (!OidIsValid(anyc_actuals.anymultirange_type))
1240 return false;
1241 }
1242 argtypes[i] = anyc_actuals.anymultirange_type;
1243 }
1244 break;
1245 default:
1246 break;
1247 }
1249 inargno++;
1250 }
1251
1252 /* Done? */
1254 return true;
1255
1256 /* If needed, deduce one polymorphic type from others */
1257 if (have_anyelement_result && !OidIsValid(poly_actuals.anyelement_type))
1259
1260 if (have_anyarray_result && !OidIsValid(poly_actuals.anyarray_type))
1262
1263 if (have_anyrange_result && !OidIsValid(poly_actuals.anyrange_type))
1265
1266 if (have_anymultirange_result && !OidIsValid(poly_actuals.anymultirange_type))
1268
1269 if (have_anycompatible_result && !OidIsValid(anyc_actuals.anyelement_type))
1271
1274
1277
1280
1281 /* And finally replace the output column types as needed */
1282 for (i = 0; i < numargs; i++)
1283 {
1284 switch (argtypes[i])
1285 {
1286 case ANYELEMENTOID:
1287 case ANYNONARRAYOID:
1288 case ANYENUMOID:
1289 argtypes[i] = poly_actuals.anyelement_type;
1290 break;
1291 case ANYARRAYOID:
1292 argtypes[i] = poly_actuals.anyarray_type;
1293 break;
1294 case ANYRANGEOID:
1295 argtypes[i] = poly_actuals.anyrange_type;
1296 break;
1297 case ANYMULTIRANGEOID:
1298 argtypes[i] = poly_actuals.anymultirange_type;
1299 break;
1300 case ANYCOMPATIBLEOID:
1302 argtypes[i] = anyc_actuals.anyelement_type;
1303 break;
1305 argtypes[i] = anyc_actuals.anyarray_type;
1306 break;
1308 argtypes[i] = anyc_actuals.anyrange_type;
1309 break;
1311 argtypes[i] = anyc_actuals.anymultirange_type;
1312 break;
1313 default:
1314 break;
1315 }
1316 }
1317
1318 return true;
1319}
Oid get_call_expr_argtype(Node *expr, int argnum)
Definition fmgr.c:1895
static void resolve_anyelement_from_others(polymorphic_actuals *actuals)
Definition funcapi.c:591
static void resolve_anyrange_from_others(polymorphic_actuals *actuals)
Definition funcapi.c:683
static void resolve_anymultirange_from_others(polymorphic_actuals *actuals)
Definition funcapi.c:712
static void resolve_anyarray_from_others(polymorphic_actuals *actuals)
Definition funcapi.c:657

References fb(), get_call_expr_argtype(), i, OidIsValid, resolve_anyarray_from_others(), resolve_anyelement_from_others(), resolve_anymultirange_from_others(), and resolve_anyrange_from_others().

Referenced by cfunc_resolve_polymorphic_argtypes().

◆ TupleDescGetAttInMetadata()

AttInMetadata * TupleDescGetAttInMetadata ( TupleDesc  tupdesc)
extern

Definition at line 2356 of file execTuples.c.

2357{
2358 int natts = tupdesc->natts;
2359 int i;
2360 Oid atttypeid;
2363 Oid *attioparams;
2364 int32 *atttypmods;
2365 AttInMetadata *attinmeta;
2366
2367 attinmeta = palloc_object(AttInMetadata);
2368
2369 /* "Bless" the tupledesc so that we can make rowtype datums with it */
2370 attinmeta->tupdesc = BlessTupleDesc(tupdesc);
2371
2372 /*
2373 * Gather info needed later to call the "in" function for each attribute
2374 */
2375 attinfuncinfo = (FmgrInfo *) palloc0(natts * sizeof(FmgrInfo));
2376 attioparams = (Oid *) palloc0(natts * sizeof(Oid));
2377 atttypmods = (int32 *) palloc0(natts * sizeof(int32));
2378
2379 for (i = 0; i < natts; i++)
2380 {
2382
2383 /* Ignore dropped attributes */
2384 if (!att->attisdropped)
2385 {
2386 atttypeid = att->atttypid;
2387 getTypeInputInfo(atttypeid, &attinfuncid, &attioparams[i]);
2389 atttypmods[i] = att->atttypmod;
2390 }
2391 }
2392 attinmeta->attinfuncs = attinfuncinfo;
2393 attinmeta->attioparams = attioparams;
2394 attinmeta->atttypmods = atttypmods;
2395
2396 return attinmeta;
2397}
#define palloc_object(type)
Definition fe_memutils.h:74
void fmgr_info(Oid functionId, FmgrInfo *finfo)
Definition fmgr.c:129
void getTypeInputInfo(Oid type, Oid *typInput, Oid *typIOParam)
Definition lsyscache.c:3096
FormData_pg_attribute * Form_pg_attribute
static FormData_pg_attribute * TupleDescAttr(TupleDesc tupdesc, int i)
Definition tupdesc.h:178

References AttInMetadata::attinfuncs, AttInMetadata::attioparams, AttInMetadata::atttypmods, BlessTupleDesc(), fb(), fmgr_info(), getTypeInputInfo(), i, TupleDescData::natts, palloc0(), palloc_object, AttInMetadata::tupdesc, and TupleDescAttr().

Referenced by bt_metap(), bt_multi_page_stats(), bt_page_stats_internal(), build_pgstattuple_type(), connectby_text(), connectby_text_serial(), create_foreign_modify(), crosstab(), dblink_get_pkey(), get_crosstab_tuplestore(), hash_page_items(), libpqrcv_processTuples(), materializeQueryResult(), materializeResult(), pg_get_keywords(), pg_get_multixact_members(), pg_stats_ext_mcvlist_items(), pgp_armor_headers(), pgrowlocks(), pgstatindex_impl(), pltcl_build_tuple_result(), pltcl_func_handler(), pltcl_init_tuple_store(), postgresAcquireSampleRowsFunc(), postgresBeginDirectModify(), postgresBeginForeignScan(), prs_setup_firstcall(), show_all_settings(), storeRow(), ts_setup_firstcall(), tt_setup_firstcall(), and xpath_table().

◆ TypeGetTupleDesc()

TupleDesc TypeGetTupleDesc ( Oid  typeoid,
List colaliases 
)
extern

Definition at line 1908 of file funcapi.c.

1909{
1912 TupleDesc tupdesc = NULL;
1913
1914 /*
1915 * Build a suitable tupledesc representing the output rows. We
1916 * intentionally do not support TYPEFUNC_COMPOSITE_DOMAIN here, as it's
1917 * unlikely that legacy callers of this obsolete function would be
1918 * prepared to apply domain constraints.
1919 */
1921 {
1922 /* Composite data type, e.g. a table's row type */
1924
1925 if (colaliases != NIL)
1926 {
1927 int natts = tupdesc->natts;
1928 int varattno;
1929
1930 /* does the list length match the number of attributes? */
1931 if (list_length(colaliases) != natts)
1932 ereport(ERROR,
1934 errmsg("number of aliases does not match number of columns")));
1935
1936 /* OK, use the aliases instead */
1937 for (varattno = 0; varattno < natts; varattno++)
1938 {
1939 char *label = strVal(list_nth(colaliases, varattno));
1940 Form_pg_attribute attr = TupleDescAttr(tupdesc, varattno);
1941
1942 if (label != NULL)
1943 namestrcpy(&(attr->attname), label);
1944 }
1945
1946 /* The tuple type is now an anonymous record type */
1947 tupdesc->tdtypeid = RECORDOID;
1948 tupdesc->tdtypmod = -1;
1949 }
1950 }
1951 else if (functypclass == TYPEFUNC_SCALAR)
1952 {
1953 /* Base data type, i.e. scalar */
1954 char *attname;
1955
1956 /* the alias list is required for base types */
1957 if (colaliases == NIL)
1958 ereport(ERROR,
1960 errmsg("no column alias was provided")));
1961
1962 /* the alias list length must be 1 */
1963 if (list_length(colaliases) != 1)
1964 ereport(ERROR,
1966 errmsg("number of aliases does not match number of columns")));
1967
1968 /* OK, get the column alias */
1970
1971 tupdesc = CreateTemplateTupleDesc(1);
1972 TupleDescInitEntry(tupdesc,
1973 (AttrNumber) 1,
1974 attname,
1975 typeoid,
1976 -1,
1977 0);
1978 TupleDescFinalize(tupdesc);
1979 }
1980 else if (functypclass == TYPEFUNC_RECORD)
1981 {
1982 /* XXX can't support this because typmod wasn't passed in ... */
1983 ereport(ERROR,
1985 errmsg("could not determine row description for function returning record")));
1986 }
1987 else
1988 {
1989 /* crummy error message, but parser should have caught this */
1990 elog(ERROR, "function in FROM has unsupported return type");
1991 }
1992
1993 return tupdesc;
1994}
void namestrcpy(Name name, const char *str)
Definition name.c:233
NameData attname
static char * label
#define NIL
Definition pg_list.h:68
static void * list_nth(const List *list, int n)
Definition pg_list.h:299
#define linitial(l)
Definition pg_list.h:178

References attname, CreateTemplateTupleDesc(), elog, ereport, errcode(), errmsg, ERROR, fb(), get_type_func_class(), label, linitial, list_length(), list_nth(), lookup_rowtype_tupdesc_copy(), namestrcpy(), TupleDescData::natts, NIL, strVal, TupleDescData::tdtypeid, TupleDescData::tdtypmod, TupleDescAttr(), TupleDescFinalize(), TupleDescInitEntry(), TYPEFUNC_COMPOSITE, TYPEFUNC_RECORD, and TYPEFUNC_SCALAR.