PostgreSQL Source Code  git master
fastpath.h File Reference
#include "lib/stringinfo.h"
Include dependency graph for fastpath.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

void HandleFunctionRequest (StringInfo msgBuf)
 

Function Documentation

◆ HandleFunctionRequest()

void HandleFunctionRequest ( StringInfo  msgBuf)

Definition at line 189 of file fastpath.c.

190 {
191  LOCAL_FCINFO(fcinfo, FUNC_MAX_ARGS);
192  Oid fid;
193  AclResult aclresult;
194  int16 rformat;
195  Datum retval;
196  struct fp_info my_fp;
197  struct fp_info *fip;
198  bool callit;
199  bool was_logged = false;
200  char msec_str[32];
201 
202  /*
203  * We only accept COMMIT/ABORT if we are in an aborted transaction, and
204  * COMMIT/ABORT cannot be executed through the fastpath interface.
205  */
207  ereport(ERROR,
208  (errcode(ERRCODE_IN_FAILED_SQL_TRANSACTION),
209  errmsg("current transaction is aborted, "
210  "commands ignored until end of transaction block")));
211 
212  /*
213  * Now that we know we are in a valid transaction, set snapshot in case
214  * needed by function itself or one of the datatype I/O routines.
215  */
217 
218  /*
219  * Begin parsing the buffer contents.
220  */
221  fid = (Oid) pq_getmsgint(msgBuf, 4); /* function oid */
222 
223  /*
224  * There used to be a lame attempt at caching lookup info here. Now we
225  * just do the lookups on every call.
226  */
227  fip = &my_fp;
228  fetch_fp_info(fid, fip);
229 
230  /* Log as soon as we have the function OID and name */
231  if (log_statement == LOGSTMT_ALL)
232  {
233  ereport(LOG,
234  (errmsg("fastpath function call: \"%s\" (OID %u)",
235  fip->fname, fid)));
236  was_logged = true;
237  }
238 
239  /*
240  * Check permission to access and call function. Since we didn't go
241  * through a normal name lookup, we need to check schema usage too.
242  */
243  aclresult = object_aclcheck(NamespaceRelationId, fip->namespace, GetUserId(), ACL_USAGE);
244  if (aclresult != ACLCHECK_OK)
245  aclcheck_error(aclresult, OBJECT_SCHEMA,
246  get_namespace_name(fip->namespace));
247  InvokeNamespaceSearchHook(fip->namespace, true);
248 
249  aclresult = object_aclcheck(ProcedureRelationId, fid, GetUserId(), ACL_EXECUTE);
250  if (aclresult != ACLCHECK_OK)
251  aclcheck_error(aclresult, OBJECT_FUNCTION,
252  get_func_name(fid));
254 
255  /*
256  * Prepare function call info block and insert arguments.
257  *
258  * Note: for now we pass collation = InvalidOid, so collation-sensitive
259  * functions can't be called this way. Perhaps we should pass
260  * DEFAULT_COLLATION_OID, instead?
261  */
262  InitFunctionCallInfoData(*fcinfo, &fip->flinfo, 0, InvalidOid, NULL, NULL);
263 
264  rformat = parse_fcall_arguments(msgBuf, fip, fcinfo);
265 
266  /* Verify we reached the end of the message where expected. */
267  pq_getmsgend(msgBuf);
268 
269  /*
270  * If func is strict, must not call it for null args.
271  */
272  callit = true;
273  if (fip->flinfo.fn_strict)
274  {
275  int i;
276 
277  for (i = 0; i < fcinfo->nargs; i++)
278  {
279  if (fcinfo->args[i].isnull)
280  {
281  callit = false;
282  break;
283  }
284  }
285  }
286 
287  if (callit)
288  {
289  /* Okay, do it ... */
290  retval = FunctionCallInvoke(fcinfo);
291  }
292  else
293  {
294  fcinfo->isnull = true;
295  retval = (Datum) 0;
296  }
297 
298  /* ensure we do at least one CHECK_FOR_INTERRUPTS per function call */
300 
301  SendFunctionResult(retval, fcinfo->isnull, fip->rettype, rformat);
302 
303  /* We no longer need the snapshot */
305 
306  /*
307  * Emit duration logging if appropriate.
308  */
309  switch (check_log_duration(msec_str, was_logged))
310  {
311  case 1:
312  ereport(LOG,
313  (errmsg("duration: %s ms", msec_str)));
314  break;
315  case 2:
316  ereport(LOG,
317  (errmsg("duration: %s ms fastpath function call: \"%s\" (OID %u)",
318  msec_str, fip->fname, fid)));
319  break;
320  }
321 }
AclResult
Definition: acl.h:182
@ ACLCHECK_OK
Definition: acl.h:183
void aclcheck_error(AclResult aclerr, ObjectType objtype, const char *objectname)
Definition: aclchk.c:2679
AclResult object_aclcheck(Oid classid, Oid objectid, Oid roleid, AclMode mode)
Definition: aclchk.c:3783
signed short int16
Definition: c.h:477
int errcode(int sqlerrcode)
Definition: elog.c:858
int errmsg(const char *fmt,...)
Definition: elog.c:1069
#define LOG
Definition: elog.h:31
#define ERROR
Definition: elog.h:39
#define ereport(elevel,...)
Definition: elog.h:149
static void fetch_fp_info(Oid func_id, struct fp_info *fip)
Definition: fastpath.c:120
static int16 parse_fcall_arguments(StringInfo msgBuf, struct fp_info *fip, FunctionCallInfo fcinfo)
Definition: fastpath.c:330
static void SendFunctionResult(Datum retval, bool isnull, Oid rettype, int16 format)
Definition: fastpath.c:68
#define InitFunctionCallInfoData(Fcinfo, Flinfo, Nargs, Collation, Context, Resultinfo)
Definition: fmgr.h:150
#define LOCAL_FCINFO(name, nargs)
Definition: fmgr.h:110
#define FunctionCallInvoke(fcinfo)
Definition: fmgr.h:172
int i
Definition: isn.c:73
char * get_namespace_name(Oid nspid)
Definition: lsyscache.c:3331
char * get_func_name(Oid funcid)
Definition: lsyscache.c:1590
#define CHECK_FOR_INTERRUPTS()
Definition: miscadmin.h:121
Oid GetUserId(void)
Definition: miscinit.c:502
#define InvokeNamespaceSearchHook(objectId, ereport_on_violation)
Definition: objectaccess.h:208
#define InvokeFunctionExecuteHook(objectId)
Definition: objectaccess.h:213
#define ACL_USAGE
Definition: parsenodes.h:91
@ OBJECT_SCHEMA
Definition: parsenodes.h:2005
@ OBJECT_FUNCTION
Definition: parsenodes.h:1988
#define ACL_EXECUTE
Definition: parsenodes.h:90
#define FUNC_MAX_ARGS
int log_statement
Definition: postgres.c:89
int check_log_duration(char *msec_str, bool was_logged)
Definition: postgres.c:2338
uintptr_t Datum
Definition: postgres.h:64
#define InvalidOid
Definition: postgres_ext.h:36
unsigned int Oid
Definition: postgres_ext.h:31
unsigned int pq_getmsgint(StringInfo msg, int b)
Definition: pqformat.c:418
void pq_getmsgend(StringInfo msg)
Definition: pqformat.c:638
Snapshot GetTransactionSnapshot(void)
Definition: snapmgr.c:251
void PushActiveSnapshot(Snapshot snapshot)
Definition: snapmgr.c:683
void PopActiveSnapshot(void)
Definition: snapmgr.c:778
bool fn_strict
Definition: fmgr.h:61
Oid rettype
Definition: fastpath.c:53
char fname[NAMEDATALEN]
Definition: fastpath.c:56
FmgrInfo flinfo
Definition: fastpath.c:52
@ LOGSTMT_ALL
Definition: tcopprot.h:41
bool IsAbortedTransactionBlockState(void)
Definition: xact.c:398

References ACL_EXECUTE, ACL_USAGE, aclcheck_error(), ACLCHECK_OK, CHECK_FOR_INTERRUPTS, check_log_duration(), ereport, errcode(), errmsg(), ERROR, fetch_fp_info(), fp_info::flinfo, FmgrInfo::fn_strict, fp_info::fname, FUNC_MAX_ARGS, FunctionCallInvoke, get_func_name(), get_namespace_name(), GetTransactionSnapshot(), GetUserId(), i, InitFunctionCallInfoData, InvalidOid, InvokeFunctionExecuteHook, InvokeNamespaceSearchHook, IsAbortedTransactionBlockState(), LOCAL_FCINFO, LOG, log_statement, LOGSTMT_ALL, object_aclcheck(), OBJECT_FUNCTION, OBJECT_SCHEMA, parse_fcall_arguments(), PopActiveSnapshot(), pq_getmsgend(), pq_getmsgint(), PushActiveSnapshot(), fp_info::rettype, and SendFunctionResult().

Referenced by PostgresMain().