Coverage Report

Created: 2025-09-27 06:52

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