PostgreSQL Source Code  git master
plsample.c File Reference
#include "postgres.h"
#include "catalog/pg_proc.h"
#include "catalog/pg_type.h"
#include "commands/event_trigger.h"
#include "commands/trigger.h"
#include "funcapi.h"
#include "utils/builtins.h"
#include "utils/lsyscache.h"
#include "utils/syscache.h"
Include dependency graph for plsample.c:

Go to the source code of this file.

Functions

 PG_FUNCTION_INFO_V1 (plsample_call_handler)
 
static Datum plsample_func_handler (PG_FUNCTION_ARGS)
 
Datum plsample_call_handler (PG_FUNCTION_ARGS)
 

Variables

 PG_MODULE_MAGIC
 

Function Documentation

◆ PG_FUNCTION_INFO_V1()

PG_FUNCTION_INFO_V1 ( plsample_call_handler  )

◆ plsample_call_handler()

Datum plsample_call_handler ( PG_FUNCTION_ARGS  )

Definition at line 37 of file plsample.c.

References CALLED_AS_EVENT_TRIGGER, CALLED_AS_TRIGGER, PG_END_TRY, PG_FINALLY, PG_TRY, and plsample_func_handler().

38 {
39  Datum retval = (Datum) 0;
40 
41  PG_TRY();
42  {
43  /*
44  * Determine if called as function or trigger and call appropriate
45  * subhandler.
46  */
47  if (CALLED_AS_TRIGGER(fcinfo))
48  {
49  /*
50  * This function has been called as a trigger function, where
51  * (TriggerData *) fcinfo->context includes the information of the
52  * context.
53  */
54  }
55  else if (CALLED_AS_EVENT_TRIGGER(fcinfo))
56  {
57  /*
58  * This function is called as an event trigger function, where
59  * (EventTriggerData *) fcinfo->context includes the information
60  * of the context.
61  */
62  }
63  else
64  {
65  /* Regular function handler */
66  retval = plsample_func_handler(fcinfo);
67  }
68  }
69  PG_FINALLY();
70  {
71  }
72  PG_END_TRY();
73 
74  return retval;
75 }
#define CALLED_AS_EVENT_TRIGGER(fcinfo)
Definition: event_trigger.h:40
static Datum plsample_func_handler(PG_FUNCTION_ARGS)
Definition: plsample.c:83
#define PG_FINALLY()
Definition: elog.h:312
uintptr_t Datum
Definition: postgres.h:367
#define CALLED_AS_TRIGGER(fcinfo)
Definition: trigger.h:25
#define PG_TRY()
Definition: elog.h:295
#define PG_END_TRY()
Definition: elog.h:320

◆ plsample_func_handler()

static Datum plsample_func_handler ( PG_FUNCTION_ARGS  )
static

Definition at line 83 of file plsample.c.

References ALLOCSET_SMALL_SIZES, AllocSetContextCreate, DatumGetCString, DirectFunctionCall1, elog, ereport, errmsg(), ERROR, fmgr_info_cxt(), get_func_arg_info(), GETSTRUCT, getTypeIOParam(), HeapTupleIsValid, i, InputFunctionCall(), NameStr, NOTICE, ObjectIdGetDatum, OutputFunctionCall(), palloc0(), PG_RETURN_DATUM, PG_RETURN_NULL, PROCOID, proname, pstrdup(), ReleaseSysCache(), SearchSysCache(), SearchSysCache1(), SysCacheGetAttr(), textout(), TopMemoryContext, TYPEOID, and value.

Referenced by plsample_call_handler().

84 {
85  HeapTuple pl_tuple;
86  Datum ret;
87  char *source;
88  bool isnull;
89  FmgrInfo *arg_out_func;
90  Form_pg_type type_struct;
91  HeapTuple type_tuple;
92  Form_pg_proc pl_struct;
93  volatile MemoryContext proc_cxt = NULL;
94  Oid *argtypes;
95  char **argnames;
96  char *argmodes;
97  char *proname;
98  Form_pg_type pg_type_entry;
99  Oid result_typioparam;
100  Oid prorettype;
101  FmgrInfo result_in_func;
102  int numargs;
103 
104  /* Fetch the source text of the function. */
105  pl_tuple = SearchSysCache(PROCOID,
106  ObjectIdGetDatum(fcinfo->flinfo->fn_oid), 0, 0, 0);
107  if (!HeapTupleIsValid(pl_tuple))
108  elog(ERROR, "cache lookup failed for function %u",
109  fcinfo->flinfo->fn_oid);
110 
111  /*
112  * Extract and print the source text of the function. This can be used as
113  * a base for the function validation and execution.
114  */
115  pl_struct = (Form_pg_proc) GETSTRUCT(pl_tuple);
116  proname = pstrdup(NameStr(pl_struct->proname));
117  ret = SysCacheGetAttr(PROCOID, pl_tuple, Anum_pg_proc_prosrc, &isnull);
118  if (isnull)
119  elog(ERROR, "could not find source text of function \"%s\"",
120  proname);
122  ereport(NOTICE,
123  (errmsg("source text of function \"%s\": %s",
124  proname, source)));
125 
126  /*
127  * Allocate a context that will hold all the Postgres data for the
128  * procedure.
129  */
131  "PL/Sample function",
133 
134  arg_out_func = (FmgrInfo *) palloc0(fcinfo->nargs * sizeof(FmgrInfo));
135  numargs = get_func_arg_info(pl_tuple, &argtypes, &argnames, &argmodes);
136 
137  /*
138  * Iterate through all of the function arguments, printing each input
139  * value.
140  */
141  for (int i = 0; i < numargs; i++)
142  {
143  Oid argtype = pl_struct->proargtypes.values[i];
144  char *value;
145 
146  type_tuple = SearchSysCache1(TYPEOID, ObjectIdGetDatum(argtype));
147  if (!HeapTupleIsValid(type_tuple))
148  elog(ERROR, "cache lookup failed for type %u", argtype);
149 
150  type_struct = (Form_pg_type) GETSTRUCT(type_tuple);
151  fmgr_info_cxt(type_struct->typoutput, &(arg_out_func[i]), proc_cxt);
152  ReleaseSysCache(type_tuple);
153 
154  value = OutputFunctionCall(&arg_out_func[i], fcinfo->args[i].value);
155  ereport(NOTICE,
156  (errmsg("argument: %d; name: %s; value: %s",
157  i, argnames[i], value)));
158  }
159 
160  /* Type of the result */
161  prorettype = pl_struct->prorettype;
162  ReleaseSysCache(pl_tuple);
163 
164  /*
165  * Get the required information for input conversion of the return value.
166  *
167  * If the function uses VOID as result, it is better to return NULL.
168  * Anyway, let's be honest. This is just a template, so there is not much
169  * we can do here. This returns NULL except if the result type is text,
170  * where the result is the source text of the function.
171  */
172  if (prorettype != TEXTOID)
173  PG_RETURN_NULL();
174 
175  type_tuple = SearchSysCache1(TYPEOID,
176  ObjectIdGetDatum(prorettype));
177  if (!HeapTupleIsValid(type_tuple))
178  elog(ERROR, "cache lookup failed for type %u", prorettype);
179  pg_type_entry = (Form_pg_type) GETSTRUCT(type_tuple);
180  result_typioparam = getTypeIOParam(type_tuple);
181 
182  fmgr_info_cxt(pg_type_entry->typinput, &result_in_func, proc_cxt);
183  ReleaseSysCache(type_tuple);
184 
185  ret = InputFunctionCall(&result_in_func, source, result_typioparam, -1);
186  PG_RETURN_DATUM(ret);
187 }
HeapTuple SearchSysCache(int cacheId, Datum key1, Datum key2, Datum key3, Datum key4)
Definition: syscache.c:1103
Definition: fmgr.h:56
#define AllocSetContextCreate
Definition: memutils.h:170
NameData proname
Definition: pg_proc.h:35
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
char * pstrdup(const char *in)
Definition: mcxt.c:1187
Datum textout(PG_FUNCTION_ARGS)
Definition: varlena.c:569
#define ALLOCSET_SMALL_SIZES
Definition: memutils.h:202
int get_func_arg_info(HeapTuple procTup, Oid **p_argtypes, char ***p_argnames, char **p_argmodes)
Definition: funcapi.c:1094
#define DirectFunctionCall1(func, arg1)
Definition: fmgr.h:624
unsigned int Oid
Definition: postgres_ext.h:31
char * OutputFunctionCall(FmgrInfo *flinfo, Datum val)
Definition: fmgr.c:1577
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
#define DatumGetCString(X)
Definition: postgres.h:566
void fmgr_info_cxt(Oid functionId, FmgrInfo *finfo, MemoryContext mcxt)
Definition: fmgr.c:136
MemoryContext TopMemoryContext
Definition: mcxt.c:44
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1116
void * palloc0(Size size)
Definition: mcxt.c:981
uintptr_t Datum
Definition: postgres.h:367
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1164
#define PG_RETURN_DATUM(x)
Definition: fmgr.h:352
Datum SysCacheGetAttr(int cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)
Definition: syscache.c:1377
FormData_pg_proc * Form_pg_proc
Definition: pg_proc.h:133
Datum InputFunctionCall(FmgrInfo *flinfo, char *str, Oid typioparam, int32 typmod)
Definition: fmgr.c:1533
static struct @143 value
#define ereport(elevel,...)
Definition: elog.h:144
#define NOTICE
Definition: elog.h:37
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
FormData_pg_type * Form_pg_type
Definition: pg_type.h:255
int errmsg(const char *fmt,...)
Definition: elog.c:821
#define elog(elevel,...)
Definition: elog.h:214
int i
Oid getTypeIOParam(HeapTuple typeTuple)
Definition: lsyscache.c:2191
#define NameStr(name)
Definition: c.h:623
#define PG_RETURN_NULL()
Definition: fmgr.h:344

Variable Documentation

◆ PG_MODULE_MAGIC

PG_MODULE_MAGIC

Definition at line 27 of file plsample.c.