Coverage Report

Created: 2026-09-28 06:55

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/postgres/src/backend/utils/fmgr/fmgr.c
Line
Count
Source
1
/*-------------------------------------------------------------------------
2
 *
3
 * fmgr.c
4
 *    The Postgres function manager.
5
 *
6
 * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group
7
 * Portions Copyright (c) 1994, Regents of the University of California
8
 *
9
 *
10
 * IDENTIFICATION
11
 *    src/backend/utils/fmgr/fmgr.c
12
 *
13
 *-------------------------------------------------------------------------
14
 */
15
16
#include "postgres.h"
17
18
#include "access/detoast.h"
19
#include "access/htup_details.h"
20
#include "catalog/pg_language.h"
21
#include "catalog/pg_proc.h"
22
#include "catalog/pg_type.h"
23
#include "executor/functions.h"
24
#include "lib/stringinfo.h"
25
#include "miscadmin.h"
26
#include "nodes/makefuncs.h"
27
#include "nodes/miscnodes.h"
28
#include "nodes/nodeFuncs.h"
29
#include "pgstat.h"
30
#include "utils/acl.h"
31
#include "utils/builtins.h"
32
#include "utils/fmgrtab.h"
33
#include "utils/guc.h"
34
#include "utils/hsearch.h"
35
#include "utils/lsyscache.h"
36
#include "utils/syscache.h"
37
38
/*
39
 * Hooks for function calls
40
 */
41
PGDLLIMPORT needs_fmgr_hook_type needs_fmgr_hook = NULL;
42
PGDLLIMPORT fmgr_hook_type fmgr_hook = NULL;
43
44
/*
45
 * Hashtable for fast lookup of external C functions
46
 */
47
typedef struct
48
{
49
  /* fn_oid is the hash key and so must be first! */
50
  Oid     fn_oid;     /* OID of an external C function */
51
  TransactionId fn_xmin;    /* for checking up-to-dateness */
52
  ItemPointerData fn_tid;
53
  PGFunction  user_fn;    /* the function's address */
54
  const Pg_finfo_record *inforec; /* address of its info record */
55
} CFuncHashTabEntry;
56
57
static HTAB *CFuncHash = NULL;
58
59
60
static void fmgr_info_cxt_security(Oid functionId, FmgrInfo *finfo, MemoryContext mcxt,
61
                   bool ignore_security);
62
static void fmgr_info_C_lang(Oid functionId, FmgrInfo *finfo, HeapTuple procedureTuple);
63
static void fmgr_info_other_lang(Oid functionId, FmgrInfo *finfo, HeapTuple procedureTuple);
64
static CFuncHashTabEntry *lookup_C_func(HeapTuple procedureTuple);
65
static void record_C_func(HeapTuple procedureTuple,
66
              PGFunction user_fn, const Pg_finfo_record *inforec);
67
68
/* extern so it's callable via JIT */
69
extern Datum fmgr_security_definer(PG_FUNCTION_ARGS);
70
71
72
/*
73
 * Lookup routines for builtin-function table.  We can search by either Oid
74
 * or name, but search by Oid is much faster.
75
 */
76
77
static const FmgrBuiltin *
78
fmgr_isbuiltin(Oid id)
79
0
{
80
0
  uint16    index;
81
82
  /* fast lookup only possible if original oid still assigned */
83
0
  if (id > fmgr_last_builtin_oid)
84
0
    return NULL;
85
86
  /*
87
   * Lookup function data. If there's a miss in that range it's likely a
88
   * nonexistent function, returning NULL here will trigger an ERROR later.
89
   */
90
0
  index = fmgr_builtin_oid_index[id];
91
0
  if (index == InvalidOidBuiltinMapping)
92
0
    return NULL;
93
94
0
  return &fmgr_builtins[index];
95
0
}
96
97
/*
98
 * Lookup a builtin by name.  Note there can be more than one entry in
99
 * the array with the same name, but they should all point to the same
100
 * routine.
101
 */
102
static const FmgrBuiltin *
103
fmgr_lookupByName(const char *name)
104
0
{
105
0
  int     i;
106
107
0
  for (i = 0; i < fmgr_nbuiltins; i++)
108
0
  {
109
0
    if (strcmp(name, fmgr_builtins[i].funcName) == 0)
110
0
      return fmgr_builtins + i;
111
0
  }
112
0
  return NULL;
113
0
}
114
115
/*
116
 * This routine fills a FmgrInfo struct, given the OID
117
 * of the function to be called.
118
 *
119
 * The caller's CurrentMemoryContext is used as the fn_mcxt of the info
120
 * struct; this means that any subsidiary data attached to the info struct
121
 * (either by fmgr_info itself, or later on by a function call handler)
122
 * will be allocated in that context.  The caller must ensure that this
123
 * context is at least as long-lived as the info struct itself.  This is
124
 * not a problem in typical cases where the info struct is on the stack or
125
 * in freshly-palloc'd space.  However, if one intends to store an info
126
 * struct in a long-lived table, it's better to use fmgr_info_cxt.
127
 */
128
void
129
fmgr_info(Oid functionId, FmgrInfo *finfo)
130
0
{
131
0
  fmgr_info_cxt_security(functionId, finfo, CurrentMemoryContext, false);
132
0
}
133
134
/*
135
 * Fill a FmgrInfo struct, specifying a memory context in which its
136
 * subsidiary data should go.
137
 */
138
void
139
fmgr_info_cxt(Oid functionId, FmgrInfo *finfo, MemoryContext mcxt)
140
0
{
141
0
  fmgr_info_cxt_security(functionId, finfo, mcxt, false);
142
0
}
143
144
/*
145
 * This one does the actual work.  ignore_security is ordinarily false
146
 * but is set to true when we need to avoid recursion.
147
 */
148
static void
149
fmgr_info_cxt_security(Oid functionId, FmgrInfo *finfo, MemoryContext mcxt,
150
             bool ignore_security)
151
0
{
152
0
  const FmgrBuiltin *fbp;
153
0
  HeapTuple procedureTuple;
154
0
  Form_pg_proc procedureStruct;
155
0
  Datum   prosrcdatum;
156
0
  char     *prosrc;
157
158
  /*
159
   * fn_oid *must* be filled in last.  Some code assumes that if fn_oid is
160
   * valid, the whole struct is valid.  Some FmgrInfo struct's do survive
161
   * elogs.
162
   */
163
0
  finfo->fn_oid = InvalidOid;
164
0
  finfo->fn_extra = NULL;
165
0
  finfo->fn_mcxt = mcxt;
166
0
  finfo->fn_expr = NULL;   /* caller may set this later */
167
168
0
  if ((fbp = fmgr_isbuiltin(functionId)) != NULL)
169
0
  {
170
    /*
171
     * Fast path for builtin functions: don't bother consulting pg_proc
172
     */
173
0
    finfo->fn_nargs = fbp->nargs;
174
0
    finfo->fn_strict = fbp->strict;
175
0
    finfo->fn_retset = fbp->retset;
176
0
    finfo->fn_stats = TRACK_FUNC_ALL; /* ie, never track */
177
0
    finfo->fn_addr = fbp->func;
178
0
    finfo->fn_oid = functionId;
179
0
    return;
180
0
  }
181
182
  /* Otherwise we need the pg_proc entry */
183
0
  procedureTuple = SearchSysCache1(PROCOID, ObjectIdGetDatum(functionId));
184
0
  if (!HeapTupleIsValid(procedureTuple))
185
0
    elog(ERROR, "cache lookup failed for function %u", functionId);
186
0
  procedureStruct = (Form_pg_proc) GETSTRUCT(procedureTuple);
187
188
0
  finfo->fn_nargs = procedureStruct->pronargs;
189
0
  finfo->fn_strict = procedureStruct->proisstrict;
190
0
  finfo->fn_retset = procedureStruct->proretset;
191
192
  /*
193
   * If it has prosecdef set, non-null proconfig, or if a plugin wants to
194
   * hook function entry/exit, use fmgr_security_definer call handler ---
195
   * unless we are being called again by fmgr_security_definer or
196
   * fmgr_info_other_lang.
197
   *
198
   * When using fmgr_security_definer, function stats tracking is always
199
   * disabled at the outer level, and instead we set the flag properly in
200
   * fmgr_security_definer's private flinfo and implement the tracking
201
   * inside fmgr_security_definer.  This loses the ability to charge the
202
   * overhead of fmgr_security_definer to the function, but gains the
203
   * ability to set the track_functions GUC as a local GUC parameter of an
204
   * interesting function and have the right things happen.
205
   */
206
0
  if (!ignore_security &&
207
0
    (procedureStruct->prosecdef ||
208
0
     !heap_attisnull(procedureTuple, Anum_pg_proc_proconfig, NULL) ||
209
0
     FmgrHookIsNeeded(functionId)))
210
0
  {
211
0
    finfo->fn_addr = fmgr_security_definer;
212
0
    finfo->fn_stats = TRACK_FUNC_ALL; /* ie, never track */
213
0
    finfo->fn_oid = functionId;
214
0
    ReleaseSysCache(procedureTuple);
215
0
    return;
216
0
  }
217
218
0
  switch (procedureStruct->prolang)
219
0
  {
220
0
    case INTERNALlanguageId:
221
222
      /*
223
       * For an ordinary builtin function, we should never get here
224
       * because the fmgr_isbuiltin() search above will have succeeded.
225
       * However, if the user has done a CREATE FUNCTION to create an
226
       * alias for a builtin function, we can end up here.  In that case
227
       * we have to look up the function by name.  The name of the
228
       * internal function is stored in prosrc (it doesn't have to be
229
       * the same as the name of the alias!)
230
       */
231
0
      prosrcdatum = SysCacheGetAttrNotNull(PROCOID, procedureTuple,
232
0
                         Anum_pg_proc_prosrc);
233
0
      prosrc = TextDatumGetCString(prosrcdatum);
234
0
      fbp = fmgr_lookupByName(prosrc);
235
0
      if (fbp == NULL)
236
0
        ereport(ERROR,
237
0
            (errcode(ERRCODE_UNDEFINED_FUNCTION),
238
0
             errmsg("internal function \"%s\" is not in internal lookup table",
239
0
                prosrc)));
240
0
      pfree(prosrc);
241
      /* Should we check that nargs, strict, retset match the table? */
242
0
      finfo->fn_addr = fbp->func;
243
      /* note this policy is also assumed in fast path above */
244
0
      finfo->fn_stats = TRACK_FUNC_ALL; /* ie, never track */
245
0
      break;
246
247
0
    case ClanguageId:
248
0
      fmgr_info_C_lang(functionId, finfo, procedureTuple);
249
0
      finfo->fn_stats = TRACK_FUNC_PL;  /* ie, track if ALL */
250
0
      break;
251
252
0
    case SQLlanguageId:
253
0
      finfo->fn_addr = fmgr_sql;
254
0
      finfo->fn_stats = TRACK_FUNC_PL;  /* ie, track if ALL */
255
0
      break;
256
257
0
    default:
258
0
      fmgr_info_other_lang(functionId, finfo, procedureTuple);
259
0
      finfo->fn_stats = TRACK_FUNC_OFF; /* ie, track if not OFF */
260
0
      break;
261
0
  }
262
263
0
  finfo->fn_oid = functionId;
264
0
  ReleaseSysCache(procedureTuple);
265
0
}
266
267
/*
268
 * Return module and C function name providing implementation of functionId.
269
 *
270
 * If *mod == NULL and *fn == NULL, no C symbol is known to implement
271
 * function.
272
 *
273
 * If *mod == NULL and *fn != NULL, the function is implemented by a symbol in
274
 * the main binary.
275
 *
276
 * If *mod != NULL and *fn != NULL the function is implemented in an extension
277
 * shared object.
278
 *
279
 * The returned module and function names are pstrdup'ed into the current
280
 * memory context.
281
 */
282
void
283
fmgr_symbol(Oid functionId, char **mod, char **fn)
284
0
{
285
0
  HeapTuple procedureTuple;
286
0
  Form_pg_proc procedureStruct;
287
0
  Datum   prosrcattr;
288
0
  Datum   probinattr;
289
290
0
  procedureTuple = SearchSysCache1(PROCOID, ObjectIdGetDatum(functionId));
291
0
  if (!HeapTupleIsValid(procedureTuple))
292
0
    elog(ERROR, "cache lookup failed for function %u", functionId);
293
0
  procedureStruct = (Form_pg_proc) GETSTRUCT(procedureTuple);
294
295
0
  if (procedureStruct->prosecdef ||
296
0
    !heap_attisnull(procedureTuple, Anum_pg_proc_proconfig, NULL) ||
297
0
    FmgrHookIsNeeded(functionId))
298
0
  {
299
0
    *mod = NULL;     /* core binary */
300
0
    *fn = pstrdup("fmgr_security_definer");
301
0
    ReleaseSysCache(procedureTuple);
302
0
    return;
303
0
  }
304
305
  /* see fmgr_info_cxt_security for the individual cases */
306
0
  switch (procedureStruct->prolang)
307
0
  {
308
0
    case INTERNALlanguageId:
309
0
      prosrcattr = SysCacheGetAttrNotNull(PROCOID, procedureTuple,
310
0
                        Anum_pg_proc_prosrc);
311
312
0
      *mod = NULL;   /* core binary */
313
0
      *fn = TextDatumGetCString(prosrcattr);
314
0
      break;
315
316
0
    case ClanguageId:
317
0
      prosrcattr = SysCacheGetAttrNotNull(PROCOID, procedureTuple,
318
0
                        Anum_pg_proc_prosrc);
319
320
0
      probinattr = SysCacheGetAttrNotNull(PROCOID, procedureTuple,
321
0
                        Anum_pg_proc_probin);
322
323
      /*
324
       * No need to check symbol presence / API version here, already
325
       * checked in fmgr_info_cxt_security.
326
       */
327
0
      *mod = TextDatumGetCString(probinattr);
328
0
      *fn = TextDatumGetCString(prosrcattr);
329
0
      break;
330
331
0
    case SQLlanguageId:
332
0
      *mod = NULL;   /* core binary */
333
0
      *fn = pstrdup("fmgr_sql");
334
0
      break;
335
336
0
    default:
337
0
      *mod = NULL;
338
0
      *fn = NULL;     /* unknown, pass pointer */
339
0
      break;
340
0
  }
341
342
0
  ReleaseSysCache(procedureTuple);
343
0
}
344
345
346
/*
347
 * Special fmgr_info processing for C-language functions.  Note that
348
 * finfo->fn_oid is not valid yet.
349
 */
350
static void
351
fmgr_info_C_lang(Oid functionId, FmgrInfo *finfo, HeapTuple procedureTuple)
352
0
{
353
0
  CFuncHashTabEntry *hashentry;
354
0
  PGFunction  user_fn;
355
0
  const Pg_finfo_record *inforec;
356
357
  /*
358
   * See if we have the function address cached already
359
   */
360
0
  hashentry = lookup_C_func(procedureTuple);
361
0
  if (hashentry)
362
0
  {
363
0
    user_fn = hashentry->user_fn;
364
0
    inforec = hashentry->inforec;
365
0
  }
366
0
  else
367
0
  {
368
0
    Datum   prosrcattr,
369
0
          probinattr;
370
0
    char     *prosrcstring,
371
0
           *probinstring;
372
0
    void     *libraryhandle;
373
374
    /*
375
     * Get prosrc and probin strings (link symbol and library filename).
376
     * While in general these columns might be null, that's not allowed
377
     * for C-language functions.
378
     */
379
0
    prosrcattr = SysCacheGetAttrNotNull(PROCOID, procedureTuple,
380
0
                      Anum_pg_proc_prosrc);
381
0
    prosrcstring = TextDatumGetCString(prosrcattr);
382
383
0
    probinattr = SysCacheGetAttrNotNull(PROCOID, procedureTuple,
384
0
                      Anum_pg_proc_probin);
385
0
    probinstring = TextDatumGetCString(probinattr);
386
387
    /* Look up the function itself */
388
0
    user_fn = load_external_function(probinstring, prosrcstring, true,
389
0
                     &libraryhandle);
390
391
    /* Get the function information record (real or default) */
392
0
    inforec = fetch_finfo_record(libraryhandle, prosrcstring);
393
394
    /* Cache the addresses for later calls */
395
0
    record_C_func(procedureTuple, user_fn, inforec);
396
397
0
    pfree(prosrcstring);
398
0
    pfree(probinstring);
399
0
  }
400
401
0
  switch (inforec->api_version)
402
0
  {
403
0
    case 1:
404
      /* New style: call directly */
405
0
      finfo->fn_addr = user_fn;
406
0
      break;
407
0
    default:
408
      /* Shouldn't get here if fetch_finfo_record did its job */
409
0
      elog(ERROR, "unrecognized function API version: %d",
410
0
         inforec->api_version);
411
0
      break;
412
0
  }
413
0
}
414
415
/*
416
 * Special fmgr_info processing for other-language functions.  Note
417
 * that finfo->fn_oid is not valid yet.
418
 */
419
static void
420
fmgr_info_other_lang(Oid functionId, FmgrInfo *finfo, HeapTuple procedureTuple)
421
0
{
422
0
  Form_pg_proc procedureStruct = (Form_pg_proc) GETSTRUCT(procedureTuple);
423
0
  Oid     language = procedureStruct->prolang;
424
0
  HeapTuple languageTuple;
425
0
  Form_pg_language languageStruct;
426
0
  FmgrInfo  plfinfo;
427
428
0
  languageTuple = SearchSysCache1(LANGOID, ObjectIdGetDatum(language));
429
0
  if (!HeapTupleIsValid(languageTuple))
430
0
    elog(ERROR, "cache lookup failed for language %u", language);
431
0
  languageStruct = (Form_pg_language) GETSTRUCT(languageTuple);
432
433
  /*
434
   * Look up the language's call handler function, ignoring any attributes
435
   * that would normally cause insertion of fmgr_security_definer.  We need
436
   * to get back a bare pointer to the actual C-language function.
437
   */
438
0
  fmgr_info_cxt_security(languageStruct->lanplcallfoid, &plfinfo,
439
0
               CurrentMemoryContext, true);
440
0
  finfo->fn_addr = plfinfo.fn_addr;
441
442
0
  ReleaseSysCache(languageTuple);
443
0
}
444
445
/*
446
 * Fetch and validate the information record for the given external function.
447
 * The function is specified by a handle for the containing library
448
 * (obtained from load_external_function) as well as the function name.
449
 *
450
 * If no info function exists for the given name an error is raised.
451
 *
452
 * This function is broken out of fmgr_info_C_lang so that fmgr_c_validator
453
 * can validate the information record for a function not yet entered into
454
 * pg_proc.
455
 */
456
const Pg_finfo_record *
457
fetch_finfo_record(void *filehandle, const char *funcname)
458
0
{
459
0
  char     *infofuncname;
460
0
  PGFInfoFunction infofunc;
461
0
  const Pg_finfo_record *inforec;
462
463
0
  infofuncname = psprintf("pg_finfo_%s", funcname);
464
465
  /* Try to look up the info function */
466
0
  infofunc = (PGFInfoFunction) lookup_external_function(filehandle,
467
0
                              infofuncname);
468
0
  if (infofunc == NULL)
469
0
  {
470
0
    ereport(ERROR,
471
0
        (errcode(ERRCODE_UNDEFINED_FUNCTION),
472
0
         errmsg("could not find function information for function \"%s\"",
473
0
            funcname),
474
0
         errhint("SQL-callable functions need an accompanying PG_FUNCTION_INFO_V1(funcname).")));
475
0
    return NULL;     /* silence compiler */
476
0
  }
477
478
  /* Found, so call it */
479
0
  inforec = (*infofunc) ();
480
481
  /* Validate result as best we can */
482
0
  if (inforec == NULL)
483
0
    elog(ERROR, "null result from info function \"%s\"", infofuncname);
484
0
  switch (inforec->api_version)
485
0
  {
486
0
    case 1:
487
      /* OK, no additional fields to validate */
488
0
      break;
489
0
    default:
490
0
      ereport(ERROR,
491
0
          (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
492
0
           errmsg("unrecognized API version %d reported by info function \"%s\"",
493
0
              inforec->api_version, infofuncname)));
494
0
      break;
495
0
  }
496
497
0
  pfree(infofuncname);
498
0
  return inforec;
499
0
}
500
501
502
/*-------------------------------------------------------------------------
503
 *    Routines for caching lookup information for external C functions.
504
 *
505
 * The routines in dfmgr.c are relatively slow, so we try to avoid running
506
 * them more than once per external function per session.  We use a hash table
507
 * with the function OID as the lookup key.
508
 *-------------------------------------------------------------------------
509
 */
510
511
/*
512
 * lookup_C_func: try to find a C function in the hash table
513
 *
514
 * If an entry exists and is up to date, return it; else return NULL
515
 */
516
static CFuncHashTabEntry *
517
lookup_C_func(HeapTuple procedureTuple)
518
0
{
519
0
  Oid     fn_oid = ((Form_pg_proc) GETSTRUCT(procedureTuple))->oid;
520
0
  CFuncHashTabEntry *entry;
521
522
0
  if (CFuncHash == NULL)
523
0
    return NULL;     /* no table yet */
524
0
  entry = (CFuncHashTabEntry *)
525
0
    hash_search(CFuncHash,
526
0
          &fn_oid,
527
0
          HASH_FIND,
528
0
          NULL);
529
0
  if (entry == NULL)
530
0
    return NULL;     /* no such entry */
531
0
  if (entry->fn_xmin == HeapTupleHeaderGetRawXmin(procedureTuple->t_data) &&
532
0
    ItemPointerEquals(&entry->fn_tid, &procedureTuple->t_self))
533
0
    return entry;     /* OK */
534
0
  return NULL;       /* entry is out of date */
535
0
}
536
537
/*
538
 * record_C_func: enter (or update) info about a C function in the hash table
539
 */
540
static void
541
record_C_func(HeapTuple procedureTuple,
542
        PGFunction user_fn, const Pg_finfo_record *inforec)
543
0
{
544
0
  Oid     fn_oid = ((Form_pg_proc) GETSTRUCT(procedureTuple))->oid;
545
0
  CFuncHashTabEntry *entry;
546
0
  bool    found;
547
548
  /* Create the hash table if it doesn't exist yet */
549
0
  if (CFuncHash == NULL)
550
0
  {
551
0
    HASHCTL   hash_ctl;
552
553
0
    hash_ctl.keysize = sizeof(Oid);
554
0
    hash_ctl.entrysize = sizeof(CFuncHashTabEntry);
555
0
    CFuncHash = hash_create("CFuncHash",
556
0
                100,
557
0
                &hash_ctl,
558
0
                HASH_ELEM | HASH_BLOBS);
559
0
  }
560
561
0
  entry = (CFuncHashTabEntry *)
562
0
    hash_search(CFuncHash,
563
0
          &fn_oid,
564
0
          HASH_ENTER,
565
0
          &found);
566
  /* OID is already filled in */
567
0
  entry->fn_xmin = HeapTupleHeaderGetRawXmin(procedureTuple->t_data);
568
0
  entry->fn_tid = procedureTuple->t_self;
569
0
  entry->user_fn = user_fn;
570
0
  entry->inforec = inforec;
571
0
}
572
573
574
/*
575
 * Copy an FmgrInfo struct
576
 *
577
 * This is inherently somewhat bogus since we can't reliably duplicate
578
 * language-dependent subsidiary info.  We cheat by zeroing fn_extra,
579
 * instead, meaning that subsidiary info will have to be recomputed.
580
 */
581
void
582
fmgr_info_copy(FmgrInfo *dstinfo, FmgrInfo *srcinfo,
583
         MemoryContext destcxt)
584
0
{
585
0
  memcpy(dstinfo, srcinfo, sizeof(FmgrInfo));
586
0
  dstinfo->fn_mcxt = destcxt;
587
0
  dstinfo->fn_extra = NULL;
588
0
}
589
590
591
/*
592
 * Specialized lookup routine for fmgr_internal_validator: given the alleged
593
 * name of an internal function, return the OID of the function.
594
 * If the name is not recognized, return InvalidOid.
595
 */
596
Oid
597
fmgr_internal_function(const char *proname)
598
0
{
599
0
  const FmgrBuiltin *fbp = fmgr_lookupByName(proname);
600
601
0
  if (fbp == NULL)
602
0
    return InvalidOid;
603
0
  return fbp->foid;
604
0
}
605
606
607
/*
608
 * Support for security-definer and proconfig-using functions.  We support
609
 * both of these features using the same call handler, because they are
610
 * often used together and it would be inefficient (as well as notationally
611
 * messy) to have two levels of call handler involved.
612
 */
613
struct fmgr_security_definer_cache
614
{
615
  FmgrInfo  flinfo;     /* lookup info for target function */
616
  Oid     userid;     /* userid to set, or InvalidOid */
617
  List     *configNames;  /* GUC names to set, or NIL */
618
  List     *configHandles;  /* GUC handles to set, or NIL */
619
  List     *configValues; /* GUC values to set, or NIL */
620
  Datum   arg;      /* passthrough argument for plugin modules */
621
};
622
623
/*
624
 * Function handler for security-definer/proconfig/plugin-hooked functions.
625
 * We extract the OID of the actual function and do a fmgr lookup again.
626
 * Then we fetch the pg_proc row and copy the owner ID and proconfig fields.
627
 * (All this info is cached for the duration of the current query.)
628
 * To execute a call, we temporarily replace the flinfo with the cached
629
 * and looked-up one, while keeping the outer fcinfo (which contains all
630
 * the actual arguments, etc.) intact.  This is not re-entrant, but then
631
 * the fcinfo itself can't be used reentrantly anyway.
632
 */
633
extern Datum
634
fmgr_security_definer(PG_FUNCTION_ARGS)
635
0
{
636
0
  Datum   result;
637
0
  struct fmgr_security_definer_cache *volatile fcache;
638
0
  FmgrInfo   *save_flinfo;
639
0
  Oid     save_userid;
640
0
  int     save_sec_context;
641
0
  ListCell   *lc1,
642
0
         *lc2,
643
0
         *lc3;
644
0
  int     save_nestlevel;
645
0
  PgStat_FunctionCallUsage fcusage;
646
647
0
  if (!fcinfo->flinfo->fn_extra)
648
0
  {
649
0
    HeapTuple tuple;
650
0
    Form_pg_proc procedureStruct;
651
0
    Datum   datum;
652
0
    bool    isnull;
653
0
    MemoryContext oldcxt;
654
655
0
    fcache = MemoryContextAllocZero(fcinfo->flinfo->fn_mcxt,
656
0
                    sizeof(*fcache));
657
658
0
    fmgr_info_cxt_security(fcinfo->flinfo->fn_oid, &fcache->flinfo,
659
0
                 fcinfo->flinfo->fn_mcxt, true);
660
0
    fcache->flinfo.fn_expr = fcinfo->flinfo->fn_expr;
661
662
0
    tuple = SearchSysCache1(PROCOID,
663
0
                ObjectIdGetDatum(fcinfo->flinfo->fn_oid));
664
0
    if (!HeapTupleIsValid(tuple))
665
0
      elog(ERROR, "cache lookup failed for function %u",
666
0
         fcinfo->flinfo->fn_oid);
667
0
    procedureStruct = (Form_pg_proc) GETSTRUCT(tuple);
668
669
0
    if (procedureStruct->prosecdef)
670
0
      fcache->userid = procedureStruct->proowner;
671
672
0
    datum = SysCacheGetAttr(PROCOID, tuple, Anum_pg_proc_proconfig,
673
0
                &isnull);
674
0
    if (!isnull)
675
0
    {
676
0
      ArrayType  *array;
677
0
      ListCell   *lc;
678
679
0
      oldcxt = MemoryContextSwitchTo(fcinfo->flinfo->fn_mcxt);
680
0
      array = DatumGetArrayTypeP(datum);
681
0
      TransformGUCArray(array, &fcache->configNames,
682
0
                &fcache->configValues);
683
684
      /* transform names to config handles to avoid lookup cost */
685
0
      fcache->configHandles = NIL;
686
0
      foreach(lc, fcache->configNames)
687
0
      {
688
0
        char     *name = (char *) lfirst(lc);
689
690
0
        fcache->configHandles = lappend(fcache->configHandles,
691
0
                        get_config_handle(name));
692
0
      }
693
694
0
      MemoryContextSwitchTo(oldcxt);
695
0
    }
696
697
0
    ReleaseSysCache(tuple);
698
699
0
    fcinfo->flinfo->fn_extra = fcache;
700
0
  }
701
0
  else
702
0
    fcache = fcinfo->flinfo->fn_extra;
703
704
  /* GetUserIdAndSecContext is cheap enough that no harm in a wasted call */
705
0
  GetUserIdAndSecContext(&save_userid, &save_sec_context);
706
0
  if (fcache->configNames != NIL) /* Need a new GUC nesting level */
707
0
    save_nestlevel = NewGUCNestLevel();
708
0
  else
709
0
    save_nestlevel = 0;   /* keep compiler quiet */
710
711
0
  if (OidIsValid(fcache->userid))
712
0
    SetUserIdAndSecContext(fcache->userid,
713
0
                 save_sec_context | SECURITY_LOCAL_USERID_CHANGE);
714
715
0
  forthree(lc1, fcache->configNames,
716
0
       lc2, fcache->configHandles,
717
0
       lc3, fcache->configValues)
718
0
  {
719
0
    GucContext  context = superuser() ? PGC_SUSET : PGC_USERSET;
720
0
    GucSource source = PGC_S_SESSION;
721
0
    GucAction action = GUC_ACTION_SAVE;
722
0
    char     *name = lfirst(lc1);
723
0
    config_handle *handle = lfirst(lc2);
724
0
    char     *value = lfirst(lc3);
725
726
0
    (void) set_config_with_handle(name, handle, value,
727
0
                    context, source, GetUserId(),
728
0
                    action, true, 0, false);
729
0
  }
730
731
  /* function manager hook */
732
0
  if (fmgr_hook)
733
0
    (*fmgr_hook) (FHET_START, &fcache->flinfo, &fcache->arg);
734
735
  /*
736
   * We don't need to restore GUC or userid settings on error, because the
737
   * ensuing xact or subxact abort will do that.  The PG_TRY block is only
738
   * needed to clean up the flinfo link.
739
   */
740
0
  save_flinfo = fcinfo->flinfo;
741
742
0
  PG_TRY();
743
0
  {
744
0
    fcinfo->flinfo = &fcache->flinfo;
745
746
    /* See notes in fmgr_info_cxt_security */
747
0
    pgstat_init_function_usage(fcinfo, &fcusage);
748
749
0
    result = FunctionCallInvoke(fcinfo);
750
751
    /*
752
     * We could be calling either a regular or a set-returning function,
753
     * so we have to test to see what finalize flag to use.
754
     */
755
0
    pgstat_end_function_usage(&fcusage,
756
0
                  (fcinfo->resultinfo == NULL ||
757
0
                   !IsA(fcinfo->resultinfo, ReturnSetInfo) ||
758
0
                   ((ReturnSetInfo *) fcinfo->resultinfo)->isDone != ExprMultipleResult));
759
0
  }
760
0
  PG_CATCH();
761
0
  {
762
0
    fcinfo->flinfo = save_flinfo;
763
0
    if (fmgr_hook)
764
0
      (*fmgr_hook) (FHET_ABORT, &fcache->flinfo, &fcache->arg);
765
0
    PG_RE_THROW();
766
0
  }
767
0
  PG_END_TRY();
768
769
0
  fcinfo->flinfo = save_flinfo;
770
771
0
  if (fcache->configNames != NIL)
772
0
    AtEOXact_GUC(true, save_nestlevel);
773
0
  if (OidIsValid(fcache->userid))
774
0
    SetUserIdAndSecContext(save_userid, save_sec_context);
775
0
  if (fmgr_hook)
776
0
    (*fmgr_hook) (FHET_END, &fcache->flinfo, &fcache->arg);
777
778
0
  return result;
779
0
}
780
781
782
/*-------------------------------------------------------------------------
783
 *    Support routines for callers of fmgr-compatible functions
784
 *-------------------------------------------------------------------------
785
 */
786
787
/*
788
 * These are for invocation of a specifically named function with a
789
 * directly-computed parameter list.  Note that neither arguments nor result
790
 * are allowed to be NULL.  Also, the function cannot be one that needs to
791
 * look at FmgrInfo, since there won't be any.
792
 */
793
Datum
794
DirectFunctionCall1Coll(PGFunction func, Oid collation, Datum arg1)
795
0
{
796
0
  LOCAL_FCINFO(fcinfo, 1);
797
0
  Datum   result;
798
799
0
  InitFunctionCallInfoData(*fcinfo, NULL, 1, collation, NULL, NULL);
800
801
0
  fcinfo->args[0].value = arg1;
802
0
  fcinfo->args[0].isnull = false;
803
804
0
  result = (*func) (fcinfo);
805
806
  /* Check for null result, since caller is clearly not expecting one */
807
0
  if (fcinfo->isnull)
808
0
    elog(ERROR, "function %p returned NULL", (void *) func);
809
810
0
  return result;
811
0
}
812
813
Datum
814
DirectFunctionCall2Coll(PGFunction func, Oid collation, Datum arg1, Datum arg2)
815
0
{
816
0
  LOCAL_FCINFO(fcinfo, 2);
817
0
  Datum   result;
818
819
0
  InitFunctionCallInfoData(*fcinfo, NULL, 2, collation, NULL, NULL);
820
821
0
  fcinfo->args[0].value = arg1;
822
0
  fcinfo->args[0].isnull = false;
823
0
  fcinfo->args[1].value = arg2;
824
0
  fcinfo->args[1].isnull = false;
825
826
0
  result = (*func) (fcinfo);
827
828
  /* Check for null result, since caller is clearly not expecting one */
829
0
  if (fcinfo->isnull)
830
0
    elog(ERROR, "function %p returned NULL", (void *) func);
831
832
0
  return result;
833
0
}
834
835
Datum
836
DirectFunctionCall3Coll(PGFunction func, Oid collation, Datum arg1, Datum arg2,
837
            Datum arg3)
838
0
{
839
0
  LOCAL_FCINFO(fcinfo, 3);
840
0
  Datum   result;
841
842
0
  InitFunctionCallInfoData(*fcinfo, NULL, 3, collation, NULL, NULL);
843
844
0
  fcinfo->args[0].value = arg1;
845
0
  fcinfo->args[0].isnull = false;
846
0
  fcinfo->args[1].value = arg2;
847
0
  fcinfo->args[1].isnull = false;
848
0
  fcinfo->args[2].value = arg3;
849
0
  fcinfo->args[2].isnull = false;
850
851
0
  result = (*func) (fcinfo);
852
853
  /* Check for null result, since caller is clearly not expecting one */
854
0
  if (fcinfo->isnull)
855
0
    elog(ERROR, "function %p returned NULL", (void *) func);
856
857
0
  return result;
858
0
}
859
860
Datum
861
DirectFunctionCall4Coll(PGFunction func, Oid collation, Datum arg1, Datum arg2,
862
            Datum arg3, Datum arg4)
863
0
{
864
0
  LOCAL_FCINFO(fcinfo, 4);
865
0
  Datum   result;
866
867
0
  InitFunctionCallInfoData(*fcinfo, NULL, 4, collation, NULL, NULL);
868
869
0
  fcinfo->args[0].value = arg1;
870
0
  fcinfo->args[0].isnull = false;
871
0
  fcinfo->args[1].value = arg2;
872
0
  fcinfo->args[1].isnull = false;
873
0
  fcinfo->args[2].value = arg3;
874
0
  fcinfo->args[2].isnull = false;
875
0
  fcinfo->args[3].value = arg4;
876
0
  fcinfo->args[3].isnull = false;
877
878
0
  result = (*func) (fcinfo);
879
880
  /* Check for null result, since caller is clearly not expecting one */
881
0
  if (fcinfo->isnull)
882
0
    elog(ERROR, "function %p returned NULL", (void *) func);
883
884
0
  return result;
885
0
}
886
887
Datum
888
DirectFunctionCall5Coll(PGFunction func, Oid collation, Datum arg1, Datum arg2,
889
            Datum arg3, Datum arg4, Datum arg5)
890
0
{
891
0
  LOCAL_FCINFO(fcinfo, 5);
892
0
  Datum   result;
893
894
0
  InitFunctionCallInfoData(*fcinfo, NULL, 5, collation, NULL, NULL);
895
896
0
  fcinfo->args[0].value = arg1;
897
0
  fcinfo->args[0].isnull = false;
898
0
  fcinfo->args[1].value = arg2;
899
0
  fcinfo->args[1].isnull = false;
900
0
  fcinfo->args[2].value = arg3;
901
0
  fcinfo->args[2].isnull = false;
902
0
  fcinfo->args[3].value = arg4;
903
0
  fcinfo->args[3].isnull = false;
904
0
  fcinfo->args[4].value = arg5;
905
0
  fcinfo->args[4].isnull = false;
906
907
0
  result = (*func) (fcinfo);
908
909
  /* Check for null result, since caller is clearly not expecting one */
910
0
  if (fcinfo->isnull)
911
0
    elog(ERROR, "function %p returned NULL", (void *) func);
912
913
0
  return result;
914
0
}
915
916
Datum
917
DirectFunctionCall6Coll(PGFunction func, Oid collation, Datum arg1, Datum arg2,
918
            Datum arg3, Datum arg4, Datum arg5,
919
            Datum arg6)
920
0
{
921
0
  LOCAL_FCINFO(fcinfo, 6);
922
0
  Datum   result;
923
924
0
  InitFunctionCallInfoData(*fcinfo, NULL, 6, collation, NULL, NULL);
925
926
0
  fcinfo->args[0].value = arg1;
927
0
  fcinfo->args[0].isnull = false;
928
0
  fcinfo->args[1].value = arg2;
929
0
  fcinfo->args[1].isnull = false;
930
0
  fcinfo->args[2].value = arg3;
931
0
  fcinfo->args[2].isnull = false;
932
0
  fcinfo->args[3].value = arg4;
933
0
  fcinfo->args[3].isnull = false;
934
0
  fcinfo->args[4].value = arg5;
935
0
  fcinfo->args[4].isnull = false;
936
0
  fcinfo->args[5].value = arg6;
937
0
  fcinfo->args[5].isnull = false;
938
939
0
  result = (*func) (fcinfo);
940
941
  /* Check for null result, since caller is clearly not expecting one */
942
0
  if (fcinfo->isnull)
943
0
    elog(ERROR, "function %p returned NULL", (void *) func);
944
945
0
  return result;
946
0
}
947
948
Datum
949
DirectFunctionCall7Coll(PGFunction func, Oid collation, Datum arg1, Datum arg2,
950
            Datum arg3, Datum arg4, Datum arg5,
951
            Datum arg6, Datum arg7)
952
0
{
953
0
  LOCAL_FCINFO(fcinfo, 7);
954
0
  Datum   result;
955
956
0
  InitFunctionCallInfoData(*fcinfo, NULL, 7, collation, NULL, NULL);
957
958
0
  fcinfo->args[0].value = arg1;
959
0
  fcinfo->args[0].isnull = false;
960
0
  fcinfo->args[1].value = arg2;
961
0
  fcinfo->args[1].isnull = false;
962
0
  fcinfo->args[2].value = arg3;
963
0
  fcinfo->args[2].isnull = false;
964
0
  fcinfo->args[3].value = arg4;
965
0
  fcinfo->args[3].isnull = false;
966
0
  fcinfo->args[4].value = arg5;
967
0
  fcinfo->args[4].isnull = false;
968
0
  fcinfo->args[5].value = arg6;
969
0
  fcinfo->args[5].isnull = false;
970
0
  fcinfo->args[6].value = arg7;
971
0
  fcinfo->args[6].isnull = false;
972
973
0
  result = (*func) (fcinfo);
974
975
  /* Check for null result, since caller is clearly not expecting one */
976
0
  if (fcinfo->isnull)
977
0
    elog(ERROR, "function %p returned NULL", (void *) func);
978
979
0
  return result;
980
0
}
981
982
Datum
983
DirectFunctionCall8Coll(PGFunction func, Oid collation, Datum arg1, Datum arg2,
984
            Datum arg3, Datum arg4, Datum arg5,
985
            Datum arg6, Datum arg7, Datum arg8)
986
0
{
987
0
  LOCAL_FCINFO(fcinfo, 8);
988
0
  Datum   result;
989
990
0
  InitFunctionCallInfoData(*fcinfo, NULL, 8, collation, NULL, NULL);
991
992
0
  fcinfo->args[0].value = arg1;
993
0
  fcinfo->args[0].isnull = false;
994
0
  fcinfo->args[1].value = arg2;
995
0
  fcinfo->args[1].isnull = false;
996
0
  fcinfo->args[2].value = arg3;
997
0
  fcinfo->args[2].isnull = false;
998
0
  fcinfo->args[3].value = arg4;
999
0
  fcinfo->args[3].isnull = false;
1000
0
  fcinfo->args[4].value = arg5;
1001
0
  fcinfo->args[4].isnull = false;
1002
0
  fcinfo->args[5].value = arg6;
1003
0
  fcinfo->args[5].isnull = false;
1004
0
  fcinfo->args[6].value = arg7;
1005
0
  fcinfo->args[6].isnull = false;
1006
0
  fcinfo->args[7].value = arg8;
1007
0
  fcinfo->args[7].isnull = false;
1008
1009
0
  result = (*func) (fcinfo);
1010
1011
  /* Check for null result, since caller is clearly not expecting one */
1012
0
  if (fcinfo->isnull)
1013
0
    elog(ERROR, "function %p returned NULL", (void *) func);
1014
1015
0
  return result;
1016
0
}
1017
1018
Datum
1019
DirectFunctionCall9Coll(PGFunction func, Oid collation, Datum arg1, Datum arg2,
1020
            Datum arg3, Datum arg4, Datum arg5,
1021
            Datum arg6, Datum arg7, Datum arg8,
1022
            Datum arg9)
1023
0
{
1024
0
  LOCAL_FCINFO(fcinfo, 9);
1025
0
  Datum   result;
1026
1027
0
  InitFunctionCallInfoData(*fcinfo, NULL, 9, collation, NULL, NULL);
1028
1029
0
  fcinfo->args[0].value = arg1;
1030
0
  fcinfo->args[0].isnull = false;
1031
0
  fcinfo->args[1].value = arg2;
1032
0
  fcinfo->args[1].isnull = false;
1033
0
  fcinfo->args[2].value = arg3;
1034
0
  fcinfo->args[2].isnull = false;
1035
0
  fcinfo->args[3].value = arg4;
1036
0
  fcinfo->args[3].isnull = false;
1037
0
  fcinfo->args[4].value = arg5;
1038
0
  fcinfo->args[4].isnull = false;
1039
0
  fcinfo->args[5].value = arg6;
1040
0
  fcinfo->args[5].isnull = false;
1041
0
  fcinfo->args[6].value = arg7;
1042
0
  fcinfo->args[6].isnull = false;
1043
0
  fcinfo->args[7].value = arg8;
1044
0
  fcinfo->args[7].isnull = false;
1045
0
  fcinfo->args[8].value = arg9;
1046
0
  fcinfo->args[8].isnull = false;
1047
1048
0
  result = (*func) (fcinfo);
1049
1050
  /* Check for null result, since caller is clearly not expecting one */
1051
0
  if (fcinfo->isnull)
1052
0
    elog(ERROR, "function %p returned NULL", (void *) func);
1053
1054
0
  return result;
1055
0
}
1056
1057
/*
1058
 * These functions work like the DirectFunctionCall functions except that
1059
 * they use the flinfo parameter to initialise the fcinfo for the call.
1060
 * It's recommended that the callee only use the fn_extra and fn_mcxt
1061
 * fields, as other fields will typically describe the calling function
1062
 * not the callee.  Conversely, the calling function should not have
1063
 * used fn_extra, unless its use is known to be compatible with the callee's.
1064
 */
1065
1066
Datum
1067
CallerFInfoFunctionCall1(PGFunction func, FmgrInfo *flinfo, Oid collation, Datum arg1)
1068
0
{
1069
0
  LOCAL_FCINFO(fcinfo, 1);
1070
0
  Datum   result;
1071
1072
0
  InitFunctionCallInfoData(*fcinfo, flinfo, 1, collation, NULL, NULL);
1073
1074
0
  fcinfo->args[0].value = arg1;
1075
0
  fcinfo->args[0].isnull = false;
1076
1077
0
  result = (*func) (fcinfo);
1078
1079
  /* Check for null result, since caller is clearly not expecting one */
1080
0
  if (fcinfo->isnull)
1081
0
    elog(ERROR, "function %p returned NULL", (void *) func);
1082
1083
0
  return result;
1084
0
}
1085
1086
Datum
1087
CallerFInfoFunctionCall2(PGFunction func, FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2)
1088
0
{
1089
0
  LOCAL_FCINFO(fcinfo, 2);
1090
0
  Datum   result;
1091
1092
0
  InitFunctionCallInfoData(*fcinfo, flinfo, 2, collation, NULL, NULL);
1093
1094
0
  fcinfo->args[0].value = arg1;
1095
0
  fcinfo->args[0].isnull = false;
1096
0
  fcinfo->args[1].value = arg2;
1097
0
  fcinfo->args[1].isnull = false;
1098
1099
0
  result = (*func) (fcinfo);
1100
1101
  /* Check for null result, since caller is clearly not expecting one */
1102
0
  if (fcinfo->isnull)
1103
0
    elog(ERROR, "function %p returned NULL", (void *) func);
1104
1105
0
  return result;
1106
0
}
1107
1108
/*
1109
 * These are for invocation of a previously-looked-up function with a
1110
 * directly-computed parameter list.  Note that neither arguments nor result
1111
 * are allowed to be NULL.
1112
 */
1113
Datum
1114
FunctionCall0Coll(FmgrInfo *flinfo, Oid collation)
1115
0
{
1116
0
  LOCAL_FCINFO(fcinfo, 0);
1117
0
  Datum   result;
1118
1119
0
  InitFunctionCallInfoData(*fcinfo, flinfo, 0, collation, NULL, NULL);
1120
1121
0
  result = FunctionCallInvoke(fcinfo);
1122
1123
  /* Check for null result, since caller is clearly not expecting one */
1124
0
  if (fcinfo->isnull)
1125
0
    elog(ERROR, "function %u returned NULL", flinfo->fn_oid);
1126
1127
0
  return result;
1128
0
}
1129
1130
Datum
1131
FunctionCall1Coll(FmgrInfo *flinfo, Oid collation, Datum arg1)
1132
0
{
1133
0
  LOCAL_FCINFO(fcinfo, 1);
1134
0
  Datum   result;
1135
1136
0
  InitFunctionCallInfoData(*fcinfo, flinfo, 1, collation, NULL, NULL);
1137
1138
0
  fcinfo->args[0].value = arg1;
1139
0
  fcinfo->args[0].isnull = false;
1140
1141
0
  result = FunctionCallInvoke(fcinfo);
1142
1143
  /* Check for null result, since caller is clearly not expecting one */
1144
0
  if (fcinfo->isnull)
1145
0
    elog(ERROR, "function %u returned NULL", flinfo->fn_oid);
1146
1147
0
  return result;
1148
0
}
1149
1150
Datum
1151
FunctionCall2Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2)
1152
0
{
1153
0
  LOCAL_FCINFO(fcinfo, 2);
1154
0
  Datum   result;
1155
1156
0
  InitFunctionCallInfoData(*fcinfo, flinfo, 2, collation, NULL, NULL);
1157
1158
0
  fcinfo->args[0].value = arg1;
1159
0
  fcinfo->args[0].isnull = false;
1160
0
  fcinfo->args[1].value = arg2;
1161
0
  fcinfo->args[1].isnull = false;
1162
1163
0
  result = FunctionCallInvoke(fcinfo);
1164
1165
  /* Check for null result, since caller is clearly not expecting one */
1166
0
  if (fcinfo->isnull)
1167
0
    elog(ERROR, "function %u returned NULL", flinfo->fn_oid);
1168
1169
0
  return result;
1170
0
}
1171
1172
Datum
1173
FunctionCall3Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2,
1174
          Datum arg3)
1175
0
{
1176
0
  LOCAL_FCINFO(fcinfo, 3);
1177
0
  Datum   result;
1178
1179
0
  InitFunctionCallInfoData(*fcinfo, flinfo, 3, collation, NULL, NULL);
1180
1181
0
  fcinfo->args[0].value = arg1;
1182
0
  fcinfo->args[0].isnull = false;
1183
0
  fcinfo->args[1].value = arg2;
1184
0
  fcinfo->args[1].isnull = false;
1185
0
  fcinfo->args[2].value = arg3;
1186
0
  fcinfo->args[2].isnull = false;
1187
1188
0
  result = FunctionCallInvoke(fcinfo);
1189
1190
  /* Check for null result, since caller is clearly not expecting one */
1191
0
  if (fcinfo->isnull)
1192
0
    elog(ERROR, "function %u returned NULL", flinfo->fn_oid);
1193
1194
0
  return result;
1195
0
}
1196
1197
Datum
1198
FunctionCall4Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2,
1199
          Datum arg3, Datum arg4)
1200
0
{
1201
0
  LOCAL_FCINFO(fcinfo, 4);
1202
0
  Datum   result;
1203
1204
0
  InitFunctionCallInfoData(*fcinfo, flinfo, 4, collation, NULL, NULL);
1205
1206
0
  fcinfo->args[0].value = arg1;
1207
0
  fcinfo->args[0].isnull = false;
1208
0
  fcinfo->args[1].value = arg2;
1209
0
  fcinfo->args[1].isnull = false;
1210
0
  fcinfo->args[2].value = arg3;
1211
0
  fcinfo->args[2].isnull = false;
1212
0
  fcinfo->args[3].value = arg4;
1213
0
  fcinfo->args[3].isnull = false;
1214
1215
0
  result = FunctionCallInvoke(fcinfo);
1216
1217
  /* Check for null result, since caller is clearly not expecting one */
1218
0
  if (fcinfo->isnull)
1219
0
    elog(ERROR, "function %u returned NULL", flinfo->fn_oid);
1220
1221
0
  return result;
1222
0
}
1223
1224
Datum
1225
FunctionCall5Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2,
1226
          Datum arg3, Datum arg4, Datum arg5)
1227
0
{
1228
0
  LOCAL_FCINFO(fcinfo, 5);
1229
0
  Datum   result;
1230
1231
0
  InitFunctionCallInfoData(*fcinfo, flinfo, 5, collation, NULL, NULL);
1232
1233
0
  fcinfo->args[0].value = arg1;
1234
0
  fcinfo->args[0].isnull = false;
1235
0
  fcinfo->args[1].value = arg2;
1236
0
  fcinfo->args[1].isnull = false;
1237
0
  fcinfo->args[2].value = arg3;
1238
0
  fcinfo->args[2].isnull = false;
1239
0
  fcinfo->args[3].value = arg4;
1240
0
  fcinfo->args[3].isnull = false;
1241
0
  fcinfo->args[4].value = arg5;
1242
0
  fcinfo->args[4].isnull = false;
1243
1244
0
  result = FunctionCallInvoke(fcinfo);
1245
1246
  /* Check for null result, since caller is clearly not expecting one */
1247
0
  if (fcinfo->isnull)
1248
0
    elog(ERROR, "function %u returned NULL", flinfo->fn_oid);
1249
1250
0
  return result;
1251
0
}
1252
1253
Datum
1254
FunctionCall6Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2,
1255
          Datum arg3, Datum arg4, Datum arg5,
1256
          Datum arg6)
1257
0
{
1258
0
  LOCAL_FCINFO(fcinfo, 6);
1259
0
  Datum   result;
1260
1261
0
  InitFunctionCallInfoData(*fcinfo, flinfo, 6, collation, NULL, NULL);
1262
1263
0
  fcinfo->args[0].value = arg1;
1264
0
  fcinfo->args[0].isnull = false;
1265
0
  fcinfo->args[1].value = arg2;
1266
0
  fcinfo->args[1].isnull = false;
1267
0
  fcinfo->args[2].value = arg3;
1268
0
  fcinfo->args[2].isnull = false;
1269
0
  fcinfo->args[3].value = arg4;
1270
0
  fcinfo->args[3].isnull = false;
1271
0
  fcinfo->args[4].value = arg5;
1272
0
  fcinfo->args[4].isnull = false;
1273
0
  fcinfo->args[5].value = arg6;
1274
0
  fcinfo->args[5].isnull = false;
1275
1276
0
  result = FunctionCallInvoke(fcinfo);
1277
1278
  /* Check for null result, since caller is clearly not expecting one */
1279
0
  if (fcinfo->isnull)
1280
0
    elog(ERROR, "function %u returned NULL", flinfo->fn_oid);
1281
1282
0
  return result;
1283
0
}
1284
1285
Datum
1286
FunctionCall7Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2,
1287
          Datum arg3, Datum arg4, Datum arg5,
1288
          Datum arg6, Datum arg7)
1289
0
{
1290
0
  LOCAL_FCINFO(fcinfo, 7);
1291
0
  Datum   result;
1292
1293
0
  InitFunctionCallInfoData(*fcinfo, flinfo, 7, collation, NULL, NULL);
1294
1295
0
  fcinfo->args[0].value = arg1;
1296
0
  fcinfo->args[0].isnull = false;
1297
0
  fcinfo->args[1].value = arg2;
1298
0
  fcinfo->args[1].isnull = false;
1299
0
  fcinfo->args[2].value = arg3;
1300
0
  fcinfo->args[2].isnull = false;
1301
0
  fcinfo->args[3].value = arg4;
1302
0
  fcinfo->args[3].isnull = false;
1303
0
  fcinfo->args[4].value = arg5;
1304
0
  fcinfo->args[4].isnull = false;
1305
0
  fcinfo->args[5].value = arg6;
1306
0
  fcinfo->args[5].isnull = false;
1307
0
  fcinfo->args[6].value = arg7;
1308
0
  fcinfo->args[6].isnull = false;
1309
1310
0
  result = FunctionCallInvoke(fcinfo);
1311
1312
  /* Check for null result, since caller is clearly not expecting one */
1313
0
  if (fcinfo->isnull)
1314
0
    elog(ERROR, "function %u returned NULL", flinfo->fn_oid);
1315
1316
0
  return result;
1317
0
}
1318
1319
Datum
1320
FunctionCall8Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2,
1321
          Datum arg3, Datum arg4, Datum arg5,
1322
          Datum arg6, Datum arg7, Datum arg8)
1323
0
{
1324
0
  LOCAL_FCINFO(fcinfo, 8);
1325
0
  Datum   result;
1326
1327
0
  InitFunctionCallInfoData(*fcinfo, flinfo, 8, collation, NULL, NULL);
1328
1329
0
  fcinfo->args[0].value = arg1;
1330
0
  fcinfo->args[0].isnull = false;
1331
0
  fcinfo->args[1].value = arg2;
1332
0
  fcinfo->args[1].isnull = false;
1333
0
  fcinfo->args[2].value = arg3;
1334
0
  fcinfo->args[2].isnull = false;
1335
0
  fcinfo->args[3].value = arg4;
1336
0
  fcinfo->args[3].isnull = false;
1337
0
  fcinfo->args[4].value = arg5;
1338
0
  fcinfo->args[4].isnull = false;
1339
0
  fcinfo->args[5].value = arg6;
1340
0
  fcinfo->args[5].isnull = false;
1341
0
  fcinfo->args[6].value = arg7;
1342
0
  fcinfo->args[6].isnull = false;
1343
0
  fcinfo->args[7].value = arg8;
1344
0
  fcinfo->args[7].isnull = false;
1345
1346
0
  result = FunctionCallInvoke(fcinfo);
1347
1348
  /* Check for null result, since caller is clearly not expecting one */
1349
0
  if (fcinfo->isnull)
1350
0
    elog(ERROR, "function %u returned NULL", flinfo->fn_oid);
1351
1352
0
  return result;
1353
0
}
1354
1355
Datum
1356
FunctionCall9Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2,
1357
          Datum arg3, Datum arg4, Datum arg5,
1358
          Datum arg6, Datum arg7, Datum arg8,
1359
          Datum arg9)
1360
0
{
1361
0
  LOCAL_FCINFO(fcinfo, 9);
1362
0
  Datum   result;
1363
1364
0
  InitFunctionCallInfoData(*fcinfo, flinfo, 9, collation, NULL, NULL);
1365
1366
0
  fcinfo->args[0].value = arg1;
1367
0
  fcinfo->args[0].isnull = false;
1368
0
  fcinfo->args[1].value = arg2;
1369
0
  fcinfo->args[1].isnull = false;
1370
0
  fcinfo->args[2].value = arg3;
1371
0
  fcinfo->args[2].isnull = false;
1372
0
  fcinfo->args[3].value = arg4;
1373
0
  fcinfo->args[3].isnull = false;
1374
0
  fcinfo->args[4].value = arg5;
1375
0
  fcinfo->args[4].isnull = false;
1376
0
  fcinfo->args[5].value = arg6;
1377
0
  fcinfo->args[5].isnull = false;
1378
0
  fcinfo->args[6].value = arg7;
1379
0
  fcinfo->args[6].isnull = false;
1380
0
  fcinfo->args[7].value = arg8;
1381
0
  fcinfo->args[7].isnull = false;
1382
0
  fcinfo->args[8].value = arg9;
1383
0
  fcinfo->args[8].isnull = false;
1384
1385
0
  result = FunctionCallInvoke(fcinfo);
1386
1387
  /* Check for null result, since caller is clearly not expecting one */
1388
0
  if (fcinfo->isnull)
1389
0
    elog(ERROR, "function %u returned NULL", flinfo->fn_oid);
1390
1391
0
  return result;
1392
0
}
1393
1394
1395
/*
1396
 * These are for invocation of a function identified by OID with a
1397
 * directly-computed parameter list.  Note that neither arguments nor result
1398
 * are allowed to be NULL.  These are essentially fmgr_info() followed
1399
 * by FunctionCallN().  If the same function is to be invoked repeatedly,
1400
 * do the fmgr_info() once and then use FunctionCallN().
1401
 */
1402
Datum
1403
OidFunctionCall0Coll(Oid functionId, Oid collation)
1404
0
{
1405
0
  FmgrInfo  flinfo;
1406
1407
0
  fmgr_info(functionId, &flinfo);
1408
1409
0
  return FunctionCall0Coll(&flinfo, collation);
1410
0
}
1411
1412
Datum
1413
OidFunctionCall1Coll(Oid functionId, Oid collation, Datum arg1)
1414
0
{
1415
0
  FmgrInfo  flinfo;
1416
1417
0
  fmgr_info(functionId, &flinfo);
1418
1419
0
  return FunctionCall1Coll(&flinfo, collation, arg1);
1420
0
}
1421
1422
Datum
1423
OidFunctionCall2Coll(Oid functionId, Oid collation, Datum arg1, Datum arg2)
1424
0
{
1425
0
  FmgrInfo  flinfo;
1426
1427
0
  fmgr_info(functionId, &flinfo);
1428
1429
0
  return FunctionCall2Coll(&flinfo, collation, arg1, arg2);
1430
0
}
1431
1432
Datum
1433
OidFunctionCall3Coll(Oid functionId, Oid collation, Datum arg1, Datum arg2,
1434
           Datum arg3)
1435
0
{
1436
0
  FmgrInfo  flinfo;
1437
1438
0
  fmgr_info(functionId, &flinfo);
1439
1440
0
  return FunctionCall3Coll(&flinfo, collation, arg1, arg2, arg3);
1441
0
}
1442
1443
Datum
1444
OidFunctionCall4Coll(Oid functionId, Oid collation, Datum arg1, Datum arg2,
1445
           Datum arg3, Datum arg4)
1446
0
{
1447
0
  FmgrInfo  flinfo;
1448
1449
0
  fmgr_info(functionId, &flinfo);
1450
1451
0
  return FunctionCall4Coll(&flinfo, collation, arg1, arg2, arg3, arg4);
1452
0
}
1453
1454
Datum
1455
OidFunctionCall5Coll(Oid functionId, Oid collation, Datum arg1, Datum arg2,
1456
           Datum arg3, Datum arg4, Datum arg5)
1457
0
{
1458
0
  FmgrInfo  flinfo;
1459
1460
0
  fmgr_info(functionId, &flinfo);
1461
1462
0
  return FunctionCall5Coll(&flinfo, collation, arg1, arg2, arg3, arg4, arg5);
1463
0
}
1464
1465
Datum
1466
OidFunctionCall6Coll(Oid functionId, Oid collation, Datum arg1, Datum arg2,
1467
           Datum arg3, Datum arg4, Datum arg5,
1468
           Datum arg6)
1469
0
{
1470
0
  FmgrInfo  flinfo;
1471
1472
0
  fmgr_info(functionId, &flinfo);
1473
1474
0
  return FunctionCall6Coll(&flinfo, collation, arg1, arg2, arg3, arg4, arg5,
1475
0
               arg6);
1476
0
}
1477
1478
Datum
1479
OidFunctionCall7Coll(Oid functionId, Oid collation, Datum arg1, Datum arg2,
1480
           Datum arg3, Datum arg4, Datum arg5,
1481
           Datum arg6, Datum arg7)
1482
0
{
1483
0
  FmgrInfo  flinfo;
1484
1485
0
  fmgr_info(functionId, &flinfo);
1486
1487
0
  return FunctionCall7Coll(&flinfo, collation, arg1, arg2, arg3, arg4, arg5,
1488
0
               arg6, arg7);
1489
0
}
1490
1491
Datum
1492
OidFunctionCall8Coll(Oid functionId, Oid collation, Datum arg1, Datum arg2,
1493
           Datum arg3, Datum arg4, Datum arg5,
1494
           Datum arg6, Datum arg7, Datum arg8)
1495
0
{
1496
0
  FmgrInfo  flinfo;
1497
1498
0
  fmgr_info(functionId, &flinfo);
1499
1500
0
  return FunctionCall8Coll(&flinfo, collation, arg1, arg2, arg3, arg4, arg5,
1501
0
               arg6, arg7, arg8);
1502
0
}
1503
1504
Datum
1505
OidFunctionCall9Coll(Oid functionId, Oid collation, Datum arg1, Datum arg2,
1506
           Datum arg3, Datum arg4, Datum arg5,
1507
           Datum arg6, Datum arg7, Datum arg8,
1508
           Datum arg9)
1509
0
{
1510
0
  FmgrInfo  flinfo;
1511
1512
0
  fmgr_info(functionId, &flinfo);
1513
1514
0
  return FunctionCall9Coll(&flinfo, collation, arg1, arg2, arg3, arg4, arg5,
1515
0
               arg6, arg7, arg8, arg9);
1516
0
}
1517
1518
1519
/*
1520
 * Special cases for convenient invocation of datatype I/O functions.
1521
 */
1522
1523
/*
1524
 * Call a previously-looked-up datatype input function.
1525
 *
1526
 * "str" may be NULL to indicate we are reading a NULL.  In this case
1527
 * the caller should assume the result is NULL, but we'll call the input
1528
 * function anyway if it's not strict.  So this is almost but not quite
1529
 * the same as FunctionCall3.
1530
 */
1531
Datum
1532
InputFunctionCall(FmgrInfo *flinfo, const char *str, Oid typioparam, int32 typmod)
1533
0
{
1534
0
  LOCAL_FCINFO(fcinfo, 3);
1535
0
  Datum   result;
1536
1537
0
  if (str == NULL && flinfo->fn_strict)
1538
0
    return (Datum) 0;   /* just return null result */
1539
1540
0
  InitFunctionCallInfoData(*fcinfo, flinfo, 3, InvalidOid, NULL, NULL);
1541
1542
0
  fcinfo->args[0].value = CStringGetDatum(str);
1543
0
  fcinfo->args[0].isnull = false;
1544
0
  fcinfo->args[1].value = ObjectIdGetDatum(typioparam);
1545
0
  fcinfo->args[1].isnull = false;
1546
0
  fcinfo->args[2].value = Int32GetDatum(typmod);
1547
0
  fcinfo->args[2].isnull = false;
1548
1549
0
  result = FunctionCallInvoke(fcinfo);
1550
1551
  /* Should get null result if and only if str is NULL */
1552
0
  if (str == NULL)
1553
0
  {
1554
0
    if (!fcinfo->isnull)
1555
0
      elog(ERROR, "input function %u returned non-NULL",
1556
0
         flinfo->fn_oid);
1557
0
  }
1558
0
  else
1559
0
  {
1560
0
    if (fcinfo->isnull)
1561
0
      elog(ERROR, "input function %u returned NULL",
1562
0
         flinfo->fn_oid);
1563
0
  }
1564
1565
0
  return result;
1566
0
}
1567
1568
/*
1569
 * Call a previously-looked-up datatype input function, with non-exception
1570
 * handling of "soft" errors.
1571
 *
1572
 * This is basically like InputFunctionCall, but the converted Datum is
1573
 * returned into *result while the function result is true for success or
1574
 * false for failure.  Also, the caller may pass an ErrorSaveContext node.
1575
 *
1576
 * If escontext points to an ErrorSaveContext, any "soft" errors detected by
1577
 * the input function will be reported by filling the escontext struct and
1578
 * returning false.  (The caller can choose to test SOFT_ERROR_OCCURRED(),
1579
 * but checking the function result instead is usually cheaper.)
1580
 *
1581
 * If escontext does not point to an ErrorSaveContext, errors are reported
1582
 * via ereport(ERROR), so that there is no functional difference from
1583
 * InputFunctionCall; the result will always be true if control returns.
1584
 */
1585
bool
1586
InputFunctionCallSafe(FmgrInfo *flinfo, const char *str,
1587
            Oid typioparam, int32 typmod,
1588
            Node *escontext,
1589
            Datum *result)
1590
0
{
1591
0
  LOCAL_FCINFO(fcinfo, 3);
1592
1593
0
  if (str == NULL && flinfo->fn_strict)
1594
0
  {
1595
0
    *result = (Datum) 0;  /* just return null result */
1596
0
    return true;
1597
0
  }
1598
1599
0
  InitFunctionCallInfoData(*fcinfo, flinfo, 3, InvalidOid, escontext, NULL);
1600
1601
0
  fcinfo->args[0].value = CStringGetDatum(str);
1602
0
  fcinfo->args[0].isnull = false;
1603
0
  fcinfo->args[1].value = ObjectIdGetDatum(typioparam);
1604
0
  fcinfo->args[1].isnull = false;
1605
0
  fcinfo->args[2].value = Int32GetDatum(typmod);
1606
0
  fcinfo->args[2].isnull = false;
1607
1608
0
  *result = FunctionCallInvoke(fcinfo);
1609
1610
  /* Result value is garbage, and could be null, if an error was reported */
1611
0
  if (SOFT_ERROR_OCCURRED(escontext))
1612
0
    return false;
1613
1614
  /* Otherwise, should get null result if and only if str is NULL */
1615
0
  if (str == NULL)
1616
0
  {
1617
0
    if (!fcinfo->isnull)
1618
0
      elog(ERROR, "input function %u returned non-NULL",
1619
0
         flinfo->fn_oid);
1620
0
  }
1621
0
  else
1622
0
  {
1623
0
    if (fcinfo->isnull)
1624
0
      elog(ERROR, "input function %u returned NULL",
1625
0
         flinfo->fn_oid);
1626
0
  }
1627
1628
0
  return true;
1629
0
}
1630
1631
/*
1632
 * Call a directly-named datatype input function, with non-exception
1633
 * handling of "soft" errors.
1634
 *
1635
 * This is like InputFunctionCallSafe, except that it is given a direct
1636
 * pointer to the C function to call.  We assume that that function is
1637
 * strict.  Also, the function cannot be one that needs to
1638
 * look at FmgrInfo, since there won't be any.
1639
 */
1640
bool
1641
DirectInputFunctionCallSafe(PGFunction func, const char *str,
1642
              Oid typioparam, int32 typmod,
1643
              Node *escontext,
1644
              Datum *result)
1645
0
{
1646
0
  LOCAL_FCINFO(fcinfo, 3);
1647
1648
0
  if (str == NULL)
1649
0
  {
1650
0
    *result = (Datum) 0;  /* just return null result */
1651
0
    return true;
1652
0
  }
1653
1654
0
  InitFunctionCallInfoData(*fcinfo, NULL, 3, InvalidOid, escontext, NULL);
1655
1656
0
  fcinfo->args[0].value = CStringGetDatum(str);
1657
0
  fcinfo->args[0].isnull = false;
1658
0
  fcinfo->args[1].value = ObjectIdGetDatum(typioparam);
1659
0
  fcinfo->args[1].isnull = false;
1660
0
  fcinfo->args[2].value = Int32GetDatum(typmod);
1661
0
  fcinfo->args[2].isnull = false;
1662
1663
0
  *result = (*func) (fcinfo);
1664
1665
  /* Result value is garbage, and could be null, if an error was reported */
1666
0
  if (SOFT_ERROR_OCCURRED(escontext))
1667
0
    return false;
1668
1669
  /* Otherwise, shouldn't get null result */
1670
0
  if (fcinfo->isnull)
1671
0
    elog(ERROR, "input function %p returned NULL", (void *) func);
1672
1673
0
  return true;
1674
0
}
1675
1676
/*
1677
 * Call a previously-looked-up datatype output function.
1678
 *
1679
 * Do not call this on NULL datums.
1680
 *
1681
 * This is currently little more than window dressing for FunctionCall1.
1682
 */
1683
char *
1684
OutputFunctionCall(FmgrInfo *flinfo, Datum val)
1685
0
{
1686
0
  return DatumGetCString(FunctionCall1(flinfo, val));
1687
0
}
1688
1689
/*
1690
 * Call a previously-looked-up datatype binary-input function.
1691
 *
1692
 * "buf" may be NULL to indicate we are reading a NULL.  In this case
1693
 * the caller should assume the result is NULL, but we'll call the receive
1694
 * function anyway if it's not strict.  So this is almost but not quite
1695
 * the same as FunctionCall3.
1696
 */
1697
Datum
1698
ReceiveFunctionCall(FmgrInfo *flinfo, StringInfo buf,
1699
          Oid typioparam, int32 typmod)
1700
0
{
1701
0
  LOCAL_FCINFO(fcinfo, 3);
1702
0
  Datum   result;
1703
1704
0
  if (buf == NULL && flinfo->fn_strict)
1705
0
    return (Datum) 0;   /* just return null result */
1706
1707
0
  InitFunctionCallInfoData(*fcinfo, flinfo, 3, InvalidOid, NULL, NULL);
1708
1709
0
  fcinfo->args[0].value = PointerGetDatum(buf);
1710
0
  fcinfo->args[0].isnull = false;
1711
0
  fcinfo->args[1].value = ObjectIdGetDatum(typioparam);
1712
0
  fcinfo->args[1].isnull = false;
1713
0
  fcinfo->args[2].value = Int32GetDatum(typmod);
1714
0
  fcinfo->args[2].isnull = false;
1715
1716
0
  result = FunctionCallInvoke(fcinfo);
1717
1718
  /* Should get null result if and only if buf is NULL */
1719
0
  if (buf == NULL)
1720
0
  {
1721
0
    if (!fcinfo->isnull)
1722
0
      elog(ERROR, "receive function %u returned non-NULL",
1723
0
         flinfo->fn_oid);
1724
0
  }
1725
0
  else
1726
0
  {
1727
0
    if (fcinfo->isnull)
1728
0
      elog(ERROR, "receive function %u returned NULL",
1729
0
         flinfo->fn_oid);
1730
0
  }
1731
1732
0
  return result;
1733
0
}
1734
1735
/*
1736
 * Call a previously-looked-up datatype binary-output function.
1737
 *
1738
 * Do not call this on NULL datums.
1739
 *
1740
 * This is little more than window dressing for FunctionCall1, but it does
1741
 * guarantee a non-toasted result, which strictly speaking the underlying
1742
 * function doesn't.
1743
 */
1744
bytea *
1745
SendFunctionCall(FmgrInfo *flinfo, Datum val)
1746
0
{
1747
0
  return DatumGetByteaP(FunctionCall1(flinfo, val));
1748
0
}
1749
1750
/*
1751
 * As above, for I/O functions identified by OID.  These are only to be used
1752
 * in seldom-executed code paths.  They are not only slow but leak memory.
1753
 */
1754
Datum
1755
OidInputFunctionCall(Oid functionId, const char *str, Oid typioparam, int32 typmod)
1756
0
{
1757
0
  FmgrInfo  flinfo;
1758
1759
0
  fmgr_info(functionId, &flinfo);
1760
0
  return InputFunctionCall(&flinfo, str, typioparam, typmod);
1761
0
}
1762
1763
char *
1764
OidOutputFunctionCall(Oid functionId, Datum val)
1765
0
{
1766
0
  FmgrInfo  flinfo;
1767
1768
0
  fmgr_info(functionId, &flinfo);
1769
0
  return OutputFunctionCall(&flinfo, val);
1770
0
}
1771
1772
Datum
1773
OidReceiveFunctionCall(Oid functionId, StringInfo buf,
1774
             Oid typioparam, int32 typmod)
1775
0
{
1776
0
  FmgrInfo  flinfo;
1777
1778
0
  fmgr_info(functionId, &flinfo);
1779
0
  return ReceiveFunctionCall(&flinfo, buf, typioparam, typmod);
1780
0
}
1781
1782
bytea *
1783
OidSendFunctionCall(Oid functionId, Datum val)
1784
0
{
1785
0
  FmgrInfo  flinfo;
1786
1787
0
  fmgr_info(functionId, &flinfo);
1788
0
  return SendFunctionCall(&flinfo, val);
1789
0
}
1790
1791
1792
/*-------------------------------------------------------------------------
1793
 *    Support routines for toastable datatypes
1794
 *-------------------------------------------------------------------------
1795
 */
1796
1797
varlena *
1798
pg_detoast_datum(varlena *datum)
1799
0
{
1800
0
  if (VARATT_IS_EXTENDED(datum))
1801
0
    return detoast_attr(datum);
1802
0
  else
1803
0
    return datum;
1804
0
}
1805
1806
varlena *
1807
pg_detoast_datum_copy(varlena *datum)
1808
0
{
1809
0
  if (VARATT_IS_EXTENDED(datum))
1810
0
    return detoast_attr(datum);
1811
0
  else
1812
0
  {
1813
    /* Make a modifiable copy of the varlena object */
1814
0
    Size    len = VARSIZE(datum);
1815
0
    varlena    *result = (varlena *) palloc(len);
1816
1817
0
    memcpy(result, datum, len);
1818
0
    return result;
1819
0
  }
1820
0
}
1821
1822
varlena *
1823
pg_detoast_datum_slice(varlena *datum, int32 first, int32 count)
1824
0
{
1825
  /* Only get the specified portion from the toast rel */
1826
0
  return detoast_attr_slice(datum, first, count);
1827
0
}
1828
1829
varlena *
1830
pg_detoast_datum_packed(varlena *datum)
1831
0
{
1832
0
  if (VARATT_IS_COMPRESSED(datum) || VARATT_IS_EXTERNAL(datum))
1833
0
    return detoast_attr(datum);
1834
0
  else
1835
0
    return datum;
1836
0
}
1837
1838
/*-------------------------------------------------------------------------
1839
 *    Support routines for extracting info from fn_expr parse tree
1840
 *
1841
 * These are needed by polymorphic functions, which accept multiple possible
1842
 * input types and need help from the parser to know what they've got.
1843
 * Also, some functions might be interested in whether a parameter is constant.
1844
 * Functions taking VARIADIC ANY also need to know about the VARIADIC keyword.
1845
 *-------------------------------------------------------------------------
1846
 */
1847
1848
/*
1849
 * Get the actual type OID of the function return type
1850
 *
1851
 * Returns InvalidOid if information is not available
1852
 */
1853
Oid
1854
get_fn_expr_rettype(FmgrInfo *flinfo)
1855
0
{
1856
0
  Node     *expr;
1857
1858
  /*
1859
   * can't return anything useful if we have no FmgrInfo or if its fn_expr
1860
   * node has not been initialized
1861
   */
1862
0
  if (!flinfo || !flinfo->fn_expr)
1863
0
    return InvalidOid;
1864
1865
0
  expr = flinfo->fn_expr;
1866
1867
0
  return exprType(expr);
1868
0
}
1869
1870
/*
1871
 * Get the actual type OID of a specific function argument (counting from 0)
1872
 *
1873
 * Returns InvalidOid if information is not available
1874
 */
1875
Oid
1876
get_fn_expr_argtype(FmgrInfo *flinfo, int argnum)
1877
0
{
1878
  /*
1879
   * can't return anything useful if we have no FmgrInfo or if its fn_expr
1880
   * node has not been initialized
1881
   */
1882
0
  if (!flinfo || !flinfo->fn_expr)
1883
0
    return InvalidOid;
1884
1885
0
  return get_call_expr_argtype(flinfo->fn_expr, argnum);
1886
0
}
1887
1888
/*
1889
 * Get the actual type OID of a specific function argument (counting from 0),
1890
 * but working from the calling expression tree instead of FmgrInfo
1891
 *
1892
 * Returns InvalidOid if information is not available
1893
 */
1894
Oid
1895
get_call_expr_argtype(Node *expr, int argnum)
1896
0
{
1897
0
  List     *args;
1898
0
  Oid     argtype;
1899
1900
0
  if (expr == NULL)
1901
0
    return InvalidOid;
1902
1903
0
  if (IsA(expr, FuncExpr))
1904
0
    args = ((FuncExpr *) expr)->args;
1905
0
  else if (IsA(expr, OpExpr))
1906
0
    args = ((OpExpr *) expr)->args;
1907
0
  else if (IsA(expr, DistinctExpr))
1908
0
    args = ((DistinctExpr *) expr)->args;
1909
0
  else if (IsA(expr, ScalarArrayOpExpr))
1910
0
    args = ((ScalarArrayOpExpr *) expr)->args;
1911
0
  else if (IsA(expr, NullIfExpr))
1912
0
    args = ((NullIfExpr *) expr)->args;
1913
0
  else if (IsA(expr, WindowFunc))
1914
0
    args = ((WindowFunc *) expr)->args;
1915
0
  else
1916
0
    return InvalidOid;
1917
1918
0
  if (argnum < 0 || argnum >= list_length(args))
1919
0
    return InvalidOid;
1920
1921
0
  argtype = exprType((Node *) list_nth(args, argnum));
1922
1923
  /*
1924
   * special hack for ScalarArrayOpExpr: what the underlying function will
1925
   * actually get passed is the element type of the array.
1926
   */
1927
0
  if (IsA(expr, ScalarArrayOpExpr) &&
1928
0
    argnum == 1)
1929
0
    argtype = get_base_element_type(argtype);
1930
1931
0
  return argtype;
1932
0
}
1933
1934
/*
1935
 * Find out whether a specific function argument is constant for the
1936
 * duration of a query
1937
 *
1938
 * Returns false if information is not available
1939
 */
1940
bool
1941
get_fn_expr_arg_stable(FmgrInfo *flinfo, int argnum)
1942
0
{
1943
  /*
1944
   * can't return anything useful if we have no FmgrInfo or if its fn_expr
1945
   * node has not been initialized
1946
   */
1947
0
  if (!flinfo || !flinfo->fn_expr)
1948
0
    return false;
1949
1950
0
  return get_call_expr_arg_stable(flinfo->fn_expr, argnum);
1951
0
}
1952
1953
/*
1954
 * Find out whether a specific function argument is constant for the
1955
 * duration of a query, but working from the calling expression tree
1956
 *
1957
 * Returns false if information is not available
1958
 */
1959
bool
1960
get_call_expr_arg_stable(Node *expr, int argnum)
1961
0
{
1962
0
  List     *args;
1963
0
  Node     *arg;
1964
1965
0
  if (expr == NULL)
1966
0
    return false;
1967
1968
0
  if (IsA(expr, FuncExpr))
1969
0
    args = ((FuncExpr *) expr)->args;
1970
0
  else if (IsA(expr, OpExpr))
1971
0
    args = ((OpExpr *) expr)->args;
1972
0
  else if (IsA(expr, DistinctExpr))
1973
0
    args = ((DistinctExpr *) expr)->args;
1974
0
  else if (IsA(expr, ScalarArrayOpExpr))
1975
0
    args = ((ScalarArrayOpExpr *) expr)->args;
1976
0
  else if (IsA(expr, NullIfExpr))
1977
0
    args = ((NullIfExpr *) expr)->args;
1978
0
  else if (IsA(expr, WindowFunc))
1979
0
    args = ((WindowFunc *) expr)->args;
1980
0
  else
1981
0
    return false;
1982
1983
0
  if (argnum < 0 || argnum >= list_length(args))
1984
0
    return false;
1985
1986
0
  arg = (Node *) list_nth(args, argnum);
1987
1988
  /*
1989
   * Either a true Const or an external Param will have a value that doesn't
1990
   * change during the execution of the query.  In future we might want to
1991
   * consider other cases too, e.g. now().
1992
   */
1993
0
  if (IsA(arg, Const))
1994
0
    return true;
1995
0
  if (IsA(arg, Param) &&
1996
0
    ((Param *) arg)->paramkind == PARAM_EXTERN)
1997
0
    return true;
1998
1999
0
  return false;
2000
0
}
2001
2002
/*
2003
 * Get the VARIADIC flag from the function invocation
2004
 *
2005
 * Returns false (the default assumption) if information is not available
2006
 *
2007
 * Note this is generally only of interest to VARIADIC ANY functions
2008
 */
2009
bool
2010
get_fn_expr_variadic(FmgrInfo *flinfo)
2011
0
{
2012
0
  Node     *expr;
2013
2014
  /*
2015
   * can't return anything useful if we have no FmgrInfo or if its fn_expr
2016
   * node has not been initialized
2017
   */
2018
0
  if (!flinfo || !flinfo->fn_expr)
2019
0
    return false;
2020
2021
0
  expr = flinfo->fn_expr;
2022
2023
0
  if (IsA(expr, FuncExpr))
2024
0
    return ((FuncExpr *) expr)->funcvariadic;
2025
0
  else
2026
0
    return false;
2027
0
}
2028
2029
/*
2030
 * Set options to FmgrInfo of opclass support function.
2031
 *
2032
 * Opclass support functions are called outside of expressions.  Thanks to that
2033
 * we can use fn_expr to store opclass options as bytea constant.
2034
 */
2035
void
2036
set_fn_opclass_options(FmgrInfo *flinfo, bytea *options)
2037
0
{
2038
0
  flinfo->fn_expr = (Node *) makeConst(BYTEAOID, -1, InvalidOid, -1,
2039
0
                     PointerGetDatum(options),
2040
0
                     options == NULL, false);
2041
0
}
2042
2043
/*
2044
 * Check if options are defined for opclass support function.
2045
 */
2046
bool
2047
has_fn_opclass_options(FmgrInfo *flinfo)
2048
0
{
2049
0
  if (flinfo && flinfo->fn_expr && IsA(flinfo->fn_expr, Const))
2050
0
  {
2051
0
    Const    *expr = (Const *) flinfo->fn_expr;
2052
2053
0
    if (expr->consttype == BYTEAOID)
2054
0
      return !expr->constisnull;
2055
0
  }
2056
0
  return false;
2057
0
}
2058
2059
/*
2060
 * Get options for opclass support function.
2061
 */
2062
bytea *
2063
get_fn_opclass_options(FmgrInfo *flinfo)
2064
0
{
2065
0
  if (flinfo && flinfo->fn_expr && IsA(flinfo->fn_expr, Const))
2066
0
  {
2067
0
    Const    *expr = (Const *) flinfo->fn_expr;
2068
2069
0
    if (expr->consttype == BYTEAOID)
2070
0
      return expr->constisnull ? NULL : DatumGetByteaP(expr->constvalue);
2071
0
  }
2072
2073
0
  ereport(ERROR,
2074
0
      (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
2075
0
       errmsg("operator class options info is absent in function call context")));
2076
2077
0
  return NULL;
2078
0
}
2079
2080
/*-------------------------------------------------------------------------
2081
 *    Support routines for procedural language implementations
2082
 *-------------------------------------------------------------------------
2083
 */
2084
2085
/*
2086
 * Verify that a validator is actually associated with the language of a
2087
 * particular function and that the user has access to both the language and
2088
 * the function.  All validators should call this before doing anything
2089
 * substantial.  Doing so ensures a user cannot achieve anything with explicit
2090
 * calls to validators that he could not achieve with CREATE FUNCTION or by
2091
 * simply calling an existing function.
2092
 *
2093
 * When this function returns false, callers should skip all validation work
2094
 * and call PG_RETURN_VOID().  This never happens at present; it is reserved
2095
 * for future expansion.
2096
 *
2097
 * In particular, checking that the validator corresponds to the function's
2098
 * language allows untrusted language validators to assume they process only
2099
 * superuser-chosen source code.  (Untrusted language call handlers, by
2100
 * definition, do assume that.)  A user lacking the USAGE language privilege
2101
 * would be unable to reach the validator through CREATE FUNCTION, so we check
2102
 * that to block explicit calls as well.  Checking the EXECUTE privilege on
2103
 * the function is often superfluous, because most users can clone the
2104
 * function to get an executable copy.  It is meaningful against users with no
2105
 * database TEMP right and no permanent schema CREATE right, thereby unable to
2106
 * create any function.  Also, if the function tracks persistent state by
2107
 * function OID or name, validating the original function might permit more
2108
 * mischief than creating and validating a clone thereof.
2109
 */
2110
bool
2111
CheckFunctionValidatorAccess(Oid validatorOid, Oid functionOid)
2112
0
{
2113
0
  HeapTuple procTup;
2114
0
  HeapTuple langTup;
2115
0
  Form_pg_proc procStruct;
2116
0
  Form_pg_language langStruct;
2117
0
  AclResult aclresult;
2118
2119
  /*
2120
   * Get the function's pg_proc entry.  Throw a user-facing error for bad
2121
   * OID, because validators can be called with user-specified OIDs.
2122
   */
2123
0
  procTup = SearchSysCache1(PROCOID, ObjectIdGetDatum(functionOid));
2124
0
  if (!HeapTupleIsValid(procTup))
2125
0
    ereport(ERROR,
2126
0
        (errcode(ERRCODE_UNDEFINED_FUNCTION),
2127
0
         errmsg("function with OID %u does not exist", functionOid)));
2128
0
  procStruct = (Form_pg_proc) GETSTRUCT(procTup);
2129
2130
  /*
2131
   * Fetch pg_language entry to know if this is the correct validation
2132
   * function for that pg_proc entry.
2133
   */
2134
0
  langTup = SearchSysCache1(LANGOID, ObjectIdGetDatum(procStruct->prolang));
2135
0
  if (!HeapTupleIsValid(langTup))
2136
0
    elog(ERROR, "cache lookup failed for language %u", procStruct->prolang);
2137
0
  langStruct = (Form_pg_language) GETSTRUCT(langTup);
2138
2139
0
  if (langStruct->lanvalidator != validatorOid)
2140
0
    ereport(ERROR,
2141
0
        (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
2142
0
         errmsg("language validation function %u called for language %u instead of %u",
2143
0
            validatorOid, procStruct->prolang,
2144
0
            langStruct->lanvalidator)));
2145
2146
  /* first validate that we have permissions to use the language */
2147
0
  aclresult = object_aclcheck(LanguageRelationId, procStruct->prolang, GetUserId(),
2148
0
                ACL_USAGE);
2149
0
  if (aclresult != ACLCHECK_OK)
2150
0
    aclcheck_error(aclresult, OBJECT_LANGUAGE,
2151
0
             NameStr(langStruct->lanname));
2152
2153
  /*
2154
   * Check whether we are allowed to execute the function itself. If we can
2155
   * execute it, there should be no possible side-effect of
2156
   * compiling/validation that execution can't have.
2157
   */
2158
0
  aclresult = object_aclcheck(ProcedureRelationId, functionOid, GetUserId(), ACL_EXECUTE);
2159
0
  if (aclresult != ACLCHECK_OK)
2160
0
    aclcheck_error(aclresult, OBJECT_FUNCTION, NameStr(procStruct->proname));
2161
2162
0
  ReleaseSysCache(procTup);
2163
0
  ReleaseSysCache(langTup);
2164
2165
  return true;
2166
0
}