~ubuntu-branches/ubuntu/natty/postgresql-8.4/natty-updates

« back to all changes in this revision

Viewing changes to src/backend/utils/fmgr/fmgr.c

  • Committer: Bazaar Package Importer
  • Author(s): Martin Pitt
  • Date: 2009-03-20 12:00:13 UTC
  • Revision ID: james.westby@ubuntu.com-20090320120013-hogj7egc5mjncc5g
Tags: upstream-8.4~0cvs20090328
ImportĀ upstreamĀ versionĀ 8.4~0cvs20090328

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*-------------------------------------------------------------------------
 
2
 *
 
3
 * fmgr.c
 
4
 *        The Postgres function manager.
 
5
 *
 
6
 * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
 
7
 * Portions Copyright (c) 1994, Regents of the University of California
 
8
 *
 
9
 *
 
10
 * IDENTIFICATION
 
11
 *        $PostgreSQL$
 
12
 *
 
13
 *-------------------------------------------------------------------------
 
14
 */
 
15
 
 
16
#include "postgres.h"
 
17
 
 
18
#include "access/tuptoaster.h"
 
19
#include "catalog/pg_language.h"
 
20
#include "catalog/pg_proc.h"
 
21
#include "executor/functions.h"
 
22
#include "executor/spi.h"
 
23
#include "lib/stringinfo.h"
 
24
#include "miscadmin.h"
 
25
#include "nodes/nodeFuncs.h"
 
26
#include "pgstat.h"
 
27
#include "utils/builtins.h"
 
28
#include "utils/fmgrtab.h"
 
29
#include "utils/guc.h"
 
30
#include "utils/lsyscache.h"
 
31
#include "utils/syscache.h"
 
32
 
 
33
 
 
34
/*
 
35
 * Declaration for old-style function pointer type.  This is now used only
 
36
 * in fmgr_oldstyle() and is no longer exported.
 
37
 *
 
38
 * The m68k SVR4 ABI defines that pointers are returned in %a0 instead of
 
39
 * %d0. So if a function pointer is declared to return a pointer, the
 
40
 * compiler may look only into %a0, but if the called function was declared
 
41
 * to return an integer type, it puts its value only into %d0. So the
 
42
 * caller doesn't pick up the correct return value. The solution is to
 
43
 * declare the function pointer to return int, so the compiler picks up the
 
44
 * return value from %d0. (Functions returning pointers put their value
 
45
 * *additionally* into %d0 for compatibility.) The price is that there are
 
46
 * some warnings about int->pointer conversions ... which we can suppress
 
47
 * with suitably ugly casts in fmgr_oldstyle().
 
48
 */
 
49
#if (defined(__mc68000__) || (defined(__m68k__))) && defined(__ELF__)
 
50
typedef int32 (*func_ptr) ();
 
51
#else
 
52
typedef char *(*func_ptr) ();
 
53
#endif
 
54
 
 
55
/*
 
56
 * For an oldstyle function, fn_extra points to a record like this:
 
57
 */
 
58
typedef struct
 
59
{
 
60
        func_ptr        func;                   /* Address of the oldstyle function */
 
61
        bool            arg_toastable[FUNC_MAX_ARGS];   /* is n'th arg of a toastable
 
62
                                                                                                 * datatype? */
 
63
} Oldstyle_fnextra;
 
64
 
 
65
/*
 
66
 * Hashtable for fast lookup of external C functions
 
67
 */
 
68
typedef struct
 
69
{
 
70
        /* fn_oid is the hash key and so must be first! */
 
71
        Oid                     fn_oid;                 /* OID of an external C function */
 
72
        TransactionId fn_xmin;          /* for checking up-to-dateness */
 
73
        ItemPointerData fn_tid;
 
74
        PGFunction      user_fn;                /* the function's address */
 
75
        const Pg_finfo_record *inforec;         /* address of its info record */
 
76
} CFuncHashTabEntry;
 
77
 
 
78
static HTAB *CFuncHash = NULL;
 
79
 
 
80
 
 
81
static void fmgr_info_cxt_security(Oid functionId, FmgrInfo *finfo, MemoryContext mcxt,
 
82
                                           bool ignore_security);
 
83
static void fmgr_info_C_lang(Oid functionId, FmgrInfo *finfo, HeapTuple procedureTuple);
 
84
static void fmgr_info_other_lang(Oid functionId, FmgrInfo *finfo, HeapTuple procedureTuple);
 
85
static CFuncHashTabEntry *lookup_C_func(HeapTuple procedureTuple);
 
86
static void record_C_func(HeapTuple procedureTuple,
 
87
                          PGFunction user_fn, const Pg_finfo_record *inforec);
 
88
static Datum fmgr_oldstyle(PG_FUNCTION_ARGS);
 
89
static Datum fmgr_security_definer(PG_FUNCTION_ARGS);
 
90
 
 
91
 
 
92
/*
 
93
 * Lookup routines for builtin-function table.  We can search by either Oid
 
94
 * or name, but search by Oid is much faster.
 
95
 */
 
96
 
 
97
static const FmgrBuiltin *
 
98
fmgr_isbuiltin(Oid id)
 
99
{
 
100
        int                     low = 0;
 
101
        int                     high = fmgr_nbuiltins - 1;
 
102
 
 
103
        /*
 
104
         * Loop invariant: low is the first index that could contain target entry,
 
105
         * and high is the last index that could contain it.
 
106
         */
 
107
        while (low <= high)
 
108
        {
 
109
                int                     i = (high + low) / 2;
 
110
                const FmgrBuiltin *ptr = &fmgr_builtins[i];
 
111
 
 
112
                if (id == ptr->foid)
 
113
                        return ptr;
 
114
                else if (id > ptr->foid)
 
115
                        low = i + 1;
 
116
                else
 
117
                        high = i - 1;
 
118
        }
 
119
        return NULL;
 
120
}
 
121
 
 
122
/*
 
123
 * Lookup a builtin by name.  Note there can be more than one entry in
 
124
 * the array with the same name, but they should all point to the same
 
125
 * routine.
 
126
 */
 
127
static const FmgrBuiltin *
 
128
fmgr_lookupByName(const char *name)
 
129
{
 
130
        int                     i;
 
131
 
 
132
        for (i = 0; i < fmgr_nbuiltins; i++)
 
133
        {
 
134
                if (strcmp(name, fmgr_builtins[i].funcName) == 0)
 
135
                        return fmgr_builtins + i;
 
136
        }
 
137
        return NULL;
 
138
}
 
139
 
 
140
/*
 
141
 * This routine fills a FmgrInfo struct, given the OID
 
142
 * of the function to be called.
 
143
 *
 
144
 * The caller's CurrentMemoryContext is used as the fn_mcxt of the info
 
145
 * struct; this means that any subsidiary data attached to the info struct
 
146
 * (either by fmgr_info itself, or later on by a function call handler)
 
147
 * will be allocated in that context.  The caller must ensure that this
 
148
 * context is at least as long-lived as the info struct itself.  This is
 
149
 * not a problem in typical cases where the info struct is on the stack or
 
150
 * in freshly-palloc'd space.  However, if one intends to store an info
 
151
 * struct in a long-lived table, it's better to use fmgr_info_cxt.
 
152
 */
 
153
void
 
154
fmgr_info(Oid functionId, FmgrInfo *finfo)
 
155
{
 
156
        fmgr_info_cxt(functionId, finfo, CurrentMemoryContext);
 
157
}
 
158
 
 
159
/*
 
160
 * Fill a FmgrInfo struct, specifying a memory context in which its
 
161
 * subsidiary data should go.
 
162
 */
 
163
void
 
164
fmgr_info_cxt(Oid functionId, FmgrInfo *finfo, MemoryContext mcxt)
 
165
{
 
166
        fmgr_info_cxt_security(functionId, finfo, mcxt, false);
 
167
}
 
168
 
 
169
/*
 
170
 * This one does the actual work.  ignore_security is ordinarily false
 
171
 * but is set to true by fmgr_security_definer to avoid recursion.
 
172
 */
 
173
static void
 
174
fmgr_info_cxt_security(Oid functionId, FmgrInfo *finfo, MemoryContext mcxt,
 
175
                                           bool ignore_security)
 
176
{
 
177
        const FmgrBuiltin *fbp;
 
178
        HeapTuple       procedureTuple;
 
179
        Form_pg_proc procedureStruct;
 
180
        Datum           prosrcdatum;
 
181
        bool            isnull;
 
182
        char       *prosrc;
 
183
 
 
184
        /*
 
185
         * fn_oid *must* be filled in last.  Some code assumes that if fn_oid is
 
186
         * valid, the whole struct is valid.  Some FmgrInfo struct's do survive
 
187
         * elogs.
 
188
         */
 
189
        finfo->fn_oid = InvalidOid;
 
190
        finfo->fn_extra = NULL;
 
191
        finfo->fn_mcxt = mcxt;
 
192
        finfo->fn_expr = NULL;          /* caller may set this later */
 
193
 
 
194
        if ((fbp = fmgr_isbuiltin(functionId)) != NULL)
 
195
        {
 
196
                /*
 
197
                 * Fast path for builtin functions: don't bother consulting pg_proc
 
198
                 */
 
199
                finfo->fn_nargs = fbp->nargs;
 
200
                finfo->fn_strict = fbp->strict;
 
201
                finfo->fn_retset = fbp->retset;
 
202
                finfo->fn_stats = TRACK_FUNC_ALL;       /* ie, never track */
 
203
                finfo->fn_addr = fbp->func;
 
204
                finfo->fn_oid = functionId;
 
205
                return;
 
206
        }
 
207
 
 
208
        /* Otherwise we need the pg_proc entry */
 
209
        procedureTuple = SearchSysCache(PROCOID,
 
210
                                                                        ObjectIdGetDatum(functionId),
 
211
                                                                        0, 0, 0);
 
212
        if (!HeapTupleIsValid(procedureTuple))
 
213
                elog(ERROR, "cache lookup failed for function %u", functionId);
 
214
        procedureStruct = (Form_pg_proc) GETSTRUCT(procedureTuple);
 
215
 
 
216
        finfo->fn_nargs = procedureStruct->pronargs;
 
217
        finfo->fn_strict = procedureStruct->proisstrict;
 
218
        finfo->fn_retset = procedureStruct->proretset;
 
219
 
 
220
        /*
 
221
         * If it has prosecdef set, or non-null proconfig, use
 
222
         * fmgr_security_definer call handler --- unless we are being called
 
223
         * again by fmgr_security_definer.
 
224
         *
 
225
         * When using fmgr_security_definer, function stats tracking is always
 
226
         * disabled at the outer level, and instead we set the flag properly
 
227
         * in fmgr_security_definer's private flinfo and implement the tracking
 
228
         * inside fmgr_security_definer.  This loses the ability to charge the
 
229
         * overhead of fmgr_security_definer to the function, but gains the
 
230
         * ability to set the track_functions GUC as a local GUC parameter of
 
231
         * an interesting function and have the right things happen.
 
232
         */
 
233
        if (!ignore_security &&
 
234
                (procedureStruct->prosecdef ||
 
235
                 !heap_attisnull(procedureTuple, Anum_pg_proc_proconfig)))
 
236
        {
 
237
                finfo->fn_addr = fmgr_security_definer;
 
238
                finfo->fn_stats = TRACK_FUNC_ALL;       /* ie, never track */
 
239
                finfo->fn_oid = functionId;
 
240
                ReleaseSysCache(procedureTuple);
 
241
                return;
 
242
        }
 
243
 
 
244
        switch (procedureStruct->prolang)
 
245
        {
 
246
                case INTERNALlanguageId:
 
247
 
 
248
                        /*
 
249
                         * For an ordinary builtin function, we should never get here
 
250
                         * because the isbuiltin() search above will have succeeded.
 
251
                         * However, if the user has done a CREATE FUNCTION to create an
 
252
                         * alias for a builtin function, we can end up here.  In that case
 
253
                         * we have to look up the function by name.  The name of the
 
254
                         * internal function is stored in prosrc (it doesn't have to be
 
255
                         * the same as the name of the alias!)
 
256
                         */
 
257
                        prosrcdatum = SysCacheGetAttr(PROCOID, procedureTuple,
 
258
                                                                                  Anum_pg_proc_prosrc, &isnull);
 
259
                        if (isnull)
 
260
                                elog(ERROR, "null prosrc");
 
261
                        prosrc = TextDatumGetCString(prosrcdatum);
 
262
                        fbp = fmgr_lookupByName(prosrc);
 
263
                        if (fbp == NULL)
 
264
                                ereport(ERROR,
 
265
                                                (errcode(ERRCODE_UNDEFINED_FUNCTION),
 
266
                                                 errmsg("internal function \"%s\" is not in internal lookup table",
 
267
                                                                prosrc)));
 
268
                        pfree(prosrc);
 
269
                        /* Should we check that nargs, strict, retset match the table? */
 
270
                        finfo->fn_addr = fbp->func;
 
271
                        /* note this policy is also assumed in fast path above */
 
272
                        finfo->fn_stats = TRACK_FUNC_ALL;       /* ie, never track */
 
273
                        break;
 
274
 
 
275
                case ClanguageId:
 
276
                        fmgr_info_C_lang(functionId, finfo, procedureTuple);
 
277
                        finfo->fn_stats = TRACK_FUNC_PL;        /* ie, track if ALL */
 
278
                        break;
 
279
 
 
280
                case SQLlanguageId:
 
281
                        finfo->fn_addr = fmgr_sql;
 
282
                        finfo->fn_stats = TRACK_FUNC_PL;        /* ie, track if ALL */
 
283
                        break;
 
284
 
 
285
                default:
 
286
                        fmgr_info_other_lang(functionId, finfo, procedureTuple);
 
287
                        finfo->fn_stats = TRACK_FUNC_OFF;       /* ie, track if not OFF */
 
288
                        break;
 
289
        }
 
290
 
 
291
        finfo->fn_oid = functionId;
 
292
        ReleaseSysCache(procedureTuple);
 
293
}
 
294
 
 
295
/*
 
296
 * Special fmgr_info processing for C-language functions.  Note that
 
297
 * finfo->fn_oid is not valid yet.
 
298
 */
 
299
static void
 
300
fmgr_info_C_lang(Oid functionId, FmgrInfo *finfo, HeapTuple procedureTuple)
 
301
{
 
302
        Form_pg_proc procedureStruct = (Form_pg_proc) GETSTRUCT(procedureTuple);
 
303
        CFuncHashTabEntry *hashentry;
 
304
        PGFunction      user_fn;
 
305
        const Pg_finfo_record *inforec;
 
306
        Oldstyle_fnextra *fnextra;
 
307
        bool            isnull;
 
308
        int                     i;
 
309
 
 
310
        /*
 
311
         * See if we have the function address cached already
 
312
         */
 
313
        hashentry = lookup_C_func(procedureTuple);
 
314
        if (hashentry)
 
315
        {
 
316
                user_fn = hashentry->user_fn;
 
317
                inforec = hashentry->inforec;
 
318
        }
 
319
        else
 
320
        {
 
321
                Datum           prosrcattr,
 
322
                                        probinattr;
 
323
                char       *prosrcstring,
 
324
                                   *probinstring;
 
325
                void       *libraryhandle;
 
326
 
 
327
                /*
 
328
                 * Get prosrc and probin strings (link symbol and library filename).
 
329
                 * While in general these columns might be null, that's not allowed
 
330
                 * for C-language functions.
 
331
                 */
 
332
                prosrcattr = SysCacheGetAttr(PROCOID, procedureTuple,
 
333
                                                                         Anum_pg_proc_prosrc, &isnull);
 
334
                if (isnull)
 
335
                        elog(ERROR, "null prosrc for C function %u", functionId);
 
336
                prosrcstring = TextDatumGetCString(prosrcattr);
 
337
 
 
338
                probinattr = SysCacheGetAttr(PROCOID, procedureTuple,
 
339
                                                                         Anum_pg_proc_probin, &isnull);
 
340
                if (isnull)
 
341
                        elog(ERROR, "null probin for C function %u", functionId);
 
342
                probinstring = TextDatumGetCString(probinattr);
 
343
 
 
344
                /* Look up the function itself */
 
345
                user_fn = load_external_function(probinstring, prosrcstring, true,
 
346
                                                                                 &libraryhandle);
 
347
 
 
348
                /* Get the function information record (real or default) */
 
349
                inforec = fetch_finfo_record(libraryhandle, prosrcstring);
 
350
 
 
351
                /* Cache the addresses for later calls */
 
352
                record_C_func(procedureTuple, user_fn, inforec);
 
353
 
 
354
                pfree(prosrcstring);
 
355
                pfree(probinstring);
 
356
        }
 
357
 
 
358
        switch (inforec->api_version)
 
359
        {
 
360
                case 0:
 
361
                        /* Old style: need to use a handler */
 
362
                        finfo->fn_addr = fmgr_oldstyle;
 
363
                        fnextra = (Oldstyle_fnextra *)
 
364
                                MemoryContextAllocZero(finfo->fn_mcxt,
 
365
                                                                           sizeof(Oldstyle_fnextra));
 
366
                        finfo->fn_extra = (void *) fnextra;
 
367
                        fnextra->func = (func_ptr) user_fn;
 
368
                        for (i = 0; i < procedureStruct->pronargs; i++)
 
369
                        {
 
370
                                fnextra->arg_toastable[i] =
 
371
                                        TypeIsToastable(procedureStruct->proargtypes.values[i]);
 
372
                        }
 
373
                        break;
 
374
                case 1:
 
375
                        /* New style: call directly */
 
376
                        finfo->fn_addr = user_fn;
 
377
                        break;
 
378
                default:
 
379
                        /* Shouldn't get here if fetch_finfo_record did its job */
 
380
                        elog(ERROR, "unrecognized function API version: %d",
 
381
                                 inforec->api_version);
 
382
                        break;
 
383
        }
 
384
}
 
385
 
 
386
/*
 
387
 * Special fmgr_info processing for other-language functions.  Note
 
388
 * that finfo->fn_oid is not valid yet.
 
389
 */
 
390
static void
 
391
fmgr_info_other_lang(Oid functionId, FmgrInfo *finfo, HeapTuple procedureTuple)
 
392
{
 
393
        Form_pg_proc procedureStruct = (Form_pg_proc) GETSTRUCT(procedureTuple);
 
394
        Oid                     language = procedureStruct->prolang;
 
395
        HeapTuple       languageTuple;
 
396
        Form_pg_language languageStruct;
 
397
        FmgrInfo        plfinfo;
 
398
 
 
399
        languageTuple = SearchSysCache(LANGOID,
 
400
                                                                   ObjectIdGetDatum(language),
 
401
                                                                   0, 0, 0);
 
402
        if (!HeapTupleIsValid(languageTuple))
 
403
                elog(ERROR, "cache lookup failed for language %u", language);
 
404
        languageStruct = (Form_pg_language) GETSTRUCT(languageTuple);
 
405
 
 
406
        fmgr_info(languageStruct->lanplcallfoid, &plfinfo);
 
407
        finfo->fn_addr = plfinfo.fn_addr;
 
408
 
 
409
        /*
 
410
         * If lookup of the PL handler function produced nonnull fn_extra,
 
411
         * complain --- it must be an oldstyle function! We no longer support
 
412
         * oldstyle PL handlers.
 
413
         */
 
414
        if (plfinfo.fn_extra != NULL)
 
415
                elog(ERROR, "language %u has old-style handler", language);
 
416
 
 
417
        ReleaseSysCache(languageTuple);
 
418
}
 
419
 
 
420
/*
 
421
 * Fetch and validate the information record for the given external function.
 
422
 * The function is specified by a handle for the containing library
 
423
 * (obtained from load_external_function) as well as the function name.
 
424
 *
 
425
 * If no info function exists for the given name, it is not an error.
 
426
 * Instead we return a default info record for a version-0 function.
 
427
 * We want to raise an error here only if the info function returns
 
428
 * something bogus.
 
429
 *
 
430
 * This function is broken out of fmgr_info_C_lang so that fmgr_c_validator
 
431
 * can validate the information record for a function not yet entered into
 
432
 * pg_proc.
 
433
 */
 
434
const Pg_finfo_record *
 
435
fetch_finfo_record(void *filehandle, char *funcname)
 
436
{
 
437
        char       *infofuncname;
 
438
        PGFInfoFunction infofunc;
 
439
        const Pg_finfo_record *inforec;
 
440
        static Pg_finfo_record default_inforec = {0};
 
441
 
 
442
        /* Compute name of info func */
 
443
        infofuncname = (char *) palloc(strlen(funcname) + 10);
 
444
        strcpy(infofuncname, "pg_finfo_");
 
445
        strcat(infofuncname, funcname);
 
446
 
 
447
        /* Try to look up the info function */
 
448
        infofunc = (PGFInfoFunction) lookup_external_function(filehandle,
 
449
                                                                                                                  infofuncname);
 
450
        if (infofunc == NULL)
 
451
        {
 
452
                /* Not found --- assume version 0 */
 
453
                pfree(infofuncname);
 
454
                return &default_inforec;
 
455
        }
 
456
 
 
457
        /* Found, so call it */
 
458
        inforec = (*infofunc) ();
 
459
 
 
460
        /* Validate result as best we can */
 
461
        if (inforec == NULL)
 
462
                elog(ERROR, "null result from info function \"%s\"", infofuncname);
 
463
        switch (inforec->api_version)
 
464
        {
 
465
                case 0:
 
466
                case 1:
 
467
                        /* OK, no additional fields to validate */
 
468
                        break;
 
469
                default:
 
470
                        ereport(ERROR,
 
471
                                        (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
 
472
                                         errmsg("unrecognized API version %d reported by info function \"%s\"",
 
473
                                                        inforec->api_version, infofuncname)));
 
474
                        break;
 
475
        }
 
476
 
 
477
        pfree(infofuncname);
 
478
        return inforec;
 
479
}
 
480
 
 
481
 
 
482
/*-------------------------------------------------------------------------
 
483
 *              Routines for caching lookup information for external C functions.
 
484
 *
 
485
 * The routines in dfmgr.c are relatively slow, so we try to avoid running
 
486
 * them more than once per external function per session.  We use a hash table
 
487
 * with the function OID as the lookup key.
 
488
 *-------------------------------------------------------------------------
 
489
 */
 
490
 
 
491
/*
 
492
 * lookup_C_func: try to find a C function in the hash table
 
493
 *
 
494
 * If an entry exists and is up to date, return it; else return NULL
 
495
 */
 
496
static CFuncHashTabEntry *
 
497
lookup_C_func(HeapTuple procedureTuple)
 
498
{
 
499
        Oid                     fn_oid = HeapTupleGetOid(procedureTuple);
 
500
        CFuncHashTabEntry *entry;
 
501
 
 
502
        if (CFuncHash == NULL)
 
503
                return NULL;                    /* no table yet */
 
504
        entry = (CFuncHashTabEntry *)
 
505
                hash_search(CFuncHash,
 
506
                                        &fn_oid,
 
507
                                        HASH_FIND,
 
508
                                        NULL);
 
509
        if (entry == NULL)
 
510
                return NULL;                    /* no such entry */
 
511
        if (entry->fn_xmin == HeapTupleHeaderGetXmin(procedureTuple->t_data) &&
 
512
                ItemPointerEquals(&entry->fn_tid, &procedureTuple->t_self))
 
513
                return entry;                   /* OK */
 
514
        return NULL;                            /* entry is out of date */
 
515
}
 
516
 
 
517
/*
 
518
 * record_C_func: enter (or update) info about a C function in the hash table
 
519
 */
 
520
static void
 
521
record_C_func(HeapTuple procedureTuple,
 
522
                          PGFunction user_fn, const Pg_finfo_record *inforec)
 
523
{
 
524
        Oid                     fn_oid = HeapTupleGetOid(procedureTuple);
 
525
        CFuncHashTabEntry *entry;
 
526
        bool            found;
 
527
 
 
528
        /* Create the hash table if it doesn't exist yet */
 
529
        if (CFuncHash == NULL)
 
530
        {
 
531
                HASHCTL         hash_ctl;
 
532
 
 
533
                MemSet(&hash_ctl, 0, sizeof(hash_ctl));
 
534
                hash_ctl.keysize = sizeof(Oid);
 
535
                hash_ctl.entrysize = sizeof(CFuncHashTabEntry);
 
536
                hash_ctl.hash = oid_hash;
 
537
                CFuncHash = hash_create("CFuncHash",
 
538
                                                                100,
 
539
                                                                &hash_ctl,
 
540
                                                                HASH_ELEM | HASH_FUNCTION);
 
541
        }
 
542
 
 
543
        entry = (CFuncHashTabEntry *)
 
544
                hash_search(CFuncHash,
 
545
                                        &fn_oid,
 
546
                                        HASH_ENTER,
 
547
                                        &found);
 
548
        /* OID is already filled in */
 
549
        entry->fn_xmin = HeapTupleHeaderGetXmin(procedureTuple->t_data);
 
550
        entry->fn_tid = procedureTuple->t_self;
 
551
        entry->user_fn = user_fn;
 
552
        entry->inforec = inforec;
 
553
}
 
554
 
 
555
/*
 
556
 * clear_external_function_hash: remove entries for a library being closed
 
557
 *
 
558
 * Presently we just zap the entire hash table, but later it might be worth
 
559
 * the effort to remove only the entries associated with the given handle.
 
560
 */
 
561
void
 
562
clear_external_function_hash(void *filehandle)
 
563
{
 
564
        if (CFuncHash)
 
565
                hash_destroy(CFuncHash);
 
566
        CFuncHash = NULL;
 
567
}
 
568
 
 
569
 
 
570
/*
 
571
 * Copy an FmgrInfo struct
 
572
 *
 
573
 * This is inherently somewhat bogus since we can't reliably duplicate
 
574
 * language-dependent subsidiary info.  We cheat by zeroing fn_extra,
 
575
 * instead, meaning that subsidiary info will have to be recomputed.
 
576
 */
 
577
void
 
578
fmgr_info_copy(FmgrInfo *dstinfo, FmgrInfo *srcinfo,
 
579
                           MemoryContext destcxt)
 
580
{
 
581
        memcpy(dstinfo, srcinfo, sizeof(FmgrInfo));
 
582
        dstinfo->fn_mcxt = destcxt;
 
583
        if (dstinfo->fn_addr == fmgr_oldstyle)
 
584
        {
 
585
                /* For oldstyle functions we must copy fn_extra */
 
586
                Oldstyle_fnextra *fnextra;
 
587
 
 
588
                fnextra = (Oldstyle_fnextra *)
 
589
                        MemoryContextAlloc(destcxt, sizeof(Oldstyle_fnextra));
 
590
                memcpy(fnextra, srcinfo->fn_extra, sizeof(Oldstyle_fnextra));
 
591
                dstinfo->fn_extra = (void *) fnextra;
 
592
        }
 
593
        else
 
594
                dstinfo->fn_extra = NULL;
 
595
}
 
596
 
 
597
 
 
598
/*
 
599
 * Specialized lookup routine for fmgr_internal_validator: given the alleged
 
600
 * name of an internal function, return the OID of the function.
 
601
 * If the name is not recognized, return InvalidOid.
 
602
 */
 
603
Oid
 
604
fmgr_internal_function(const char *proname)
 
605
{
 
606
        const FmgrBuiltin *fbp = fmgr_lookupByName(proname);
 
607
 
 
608
        if (fbp == NULL)
 
609
                return InvalidOid;
 
610
        return fbp->foid;
 
611
}
 
612
 
 
613
 
 
614
/*
 
615
 * Handler for old-style "C" language functions
 
616
 */
 
617
static Datum
 
618
fmgr_oldstyle(PG_FUNCTION_ARGS)
 
619
{
 
620
        Oldstyle_fnextra *fnextra;
 
621
        int                     n_arguments = fcinfo->nargs;
 
622
        int                     i;
 
623
        bool            isnull;
 
624
        func_ptr        user_fn;
 
625
        char       *returnValue;
 
626
 
 
627
        if (fcinfo->flinfo == NULL || fcinfo->flinfo->fn_extra == NULL)
 
628
                elog(ERROR, "fmgr_oldstyle received NULL pointer");
 
629
        fnextra = (Oldstyle_fnextra *) fcinfo->flinfo->fn_extra;
 
630
 
 
631
        /*
 
632
         * Result is NULL if any argument is NULL, but we still call the function
 
633
         * (peculiar, but that's the way it worked before, and after all this is a
 
634
         * backwards-compatibility wrapper).  Note, however, that we'll never get
 
635
         * here with NULL arguments if the function is marked strict.
 
636
         *
 
637
         * We also need to detoast any TOAST-ed inputs, since it's unlikely that
 
638
         * an old-style function knows about TOASTing.
 
639
         */
 
640
        isnull = false;
 
641
        for (i = 0; i < n_arguments; i++)
 
642
        {
 
643
                if (PG_ARGISNULL(i))
 
644
                        isnull = true;
 
645
                else if (fnextra->arg_toastable[i])
 
646
                        fcinfo->arg[i] = PointerGetDatum(PG_DETOAST_DATUM(fcinfo->arg[i]));
 
647
        }
 
648
        fcinfo->isnull = isnull;
 
649
 
 
650
        user_fn = fnextra->func;
 
651
 
 
652
        switch (n_arguments)
 
653
        {
 
654
                case 0:
 
655
                        returnValue = (char *) (*user_fn) ();
 
656
                        break;
 
657
                case 1:
 
658
 
 
659
                        /*
 
660
                         * nullvalue() used to use isNull to check if arg is NULL; perhaps
 
661
                         * there are other functions still out there that also rely on
 
662
                         * this undocumented hack?
 
663
                         */
 
664
                        returnValue = (char *) (*user_fn) (fcinfo->arg[0],
 
665
                                                                                           &fcinfo->isnull);
 
666
                        break;
 
667
                case 2:
 
668
                        returnValue = (char *) (*user_fn) (fcinfo->arg[0],
 
669
                                                                                           fcinfo->arg[1]);
 
670
                        break;
 
671
                case 3:
 
672
                        returnValue = (char *) (*user_fn) (fcinfo->arg[0],
 
673
                                                                                           fcinfo->arg[1],
 
674
                                                                                           fcinfo->arg[2]);
 
675
                        break;
 
676
                case 4:
 
677
                        returnValue = (char *) (*user_fn) (fcinfo->arg[0],
 
678
                                                                                           fcinfo->arg[1],
 
679
                                                                                           fcinfo->arg[2],
 
680
                                                                                           fcinfo->arg[3]);
 
681
                        break;
 
682
                case 5:
 
683
                        returnValue = (char *) (*user_fn) (fcinfo->arg[0],
 
684
                                                                                           fcinfo->arg[1],
 
685
                                                                                           fcinfo->arg[2],
 
686
                                                                                           fcinfo->arg[3],
 
687
                                                                                           fcinfo->arg[4]);
 
688
                        break;
 
689
                case 6:
 
690
                        returnValue = (char *) (*user_fn) (fcinfo->arg[0],
 
691
                                                                                           fcinfo->arg[1],
 
692
                                                                                           fcinfo->arg[2],
 
693
                                                                                           fcinfo->arg[3],
 
694
                                                                                           fcinfo->arg[4],
 
695
                                                                                           fcinfo->arg[5]);
 
696
                        break;
 
697
                case 7:
 
698
                        returnValue = (char *) (*user_fn) (fcinfo->arg[0],
 
699
                                                                                           fcinfo->arg[1],
 
700
                                                                                           fcinfo->arg[2],
 
701
                                                                                           fcinfo->arg[3],
 
702
                                                                                           fcinfo->arg[4],
 
703
                                                                                           fcinfo->arg[5],
 
704
                                                                                           fcinfo->arg[6]);
 
705
                        break;
 
706
                case 8:
 
707
                        returnValue = (char *) (*user_fn) (fcinfo->arg[0],
 
708
                                                                                           fcinfo->arg[1],
 
709
                                                                                           fcinfo->arg[2],
 
710
                                                                                           fcinfo->arg[3],
 
711
                                                                                           fcinfo->arg[4],
 
712
                                                                                           fcinfo->arg[5],
 
713
                                                                                           fcinfo->arg[6],
 
714
                                                                                           fcinfo->arg[7]);
 
715
                        break;
 
716
                case 9:
 
717
                        returnValue = (char *) (*user_fn) (fcinfo->arg[0],
 
718
                                                                                           fcinfo->arg[1],
 
719
                                                                                           fcinfo->arg[2],
 
720
                                                                                           fcinfo->arg[3],
 
721
                                                                                           fcinfo->arg[4],
 
722
                                                                                           fcinfo->arg[5],
 
723
                                                                                           fcinfo->arg[6],
 
724
                                                                                           fcinfo->arg[7],
 
725
                                                                                           fcinfo->arg[8]);
 
726
                        break;
 
727
                case 10:
 
728
                        returnValue = (char *) (*user_fn) (fcinfo->arg[0],
 
729
                                                                                           fcinfo->arg[1],
 
730
                                                                                           fcinfo->arg[2],
 
731
                                                                                           fcinfo->arg[3],
 
732
                                                                                           fcinfo->arg[4],
 
733
                                                                                           fcinfo->arg[5],
 
734
                                                                                           fcinfo->arg[6],
 
735
                                                                                           fcinfo->arg[7],
 
736
                                                                                           fcinfo->arg[8],
 
737
                                                                                           fcinfo->arg[9]);
 
738
                        break;
 
739
                case 11:
 
740
                        returnValue = (char *) (*user_fn) (fcinfo->arg[0],
 
741
                                                                                           fcinfo->arg[1],
 
742
                                                                                           fcinfo->arg[2],
 
743
                                                                                           fcinfo->arg[3],
 
744
                                                                                           fcinfo->arg[4],
 
745
                                                                                           fcinfo->arg[5],
 
746
                                                                                           fcinfo->arg[6],
 
747
                                                                                           fcinfo->arg[7],
 
748
                                                                                           fcinfo->arg[8],
 
749
                                                                                           fcinfo->arg[9],
 
750
                                                                                           fcinfo->arg[10]);
 
751
                        break;
 
752
                case 12:
 
753
                        returnValue = (char *) (*user_fn) (fcinfo->arg[0],
 
754
                                                                                           fcinfo->arg[1],
 
755
                                                                                           fcinfo->arg[2],
 
756
                                                                                           fcinfo->arg[3],
 
757
                                                                                           fcinfo->arg[4],
 
758
                                                                                           fcinfo->arg[5],
 
759
                                                                                           fcinfo->arg[6],
 
760
                                                                                           fcinfo->arg[7],
 
761
                                                                                           fcinfo->arg[8],
 
762
                                                                                           fcinfo->arg[9],
 
763
                                                                                           fcinfo->arg[10],
 
764
                                                                                           fcinfo->arg[11]);
 
765
                        break;
 
766
                case 13:
 
767
                        returnValue = (char *) (*user_fn) (fcinfo->arg[0],
 
768
                                                                                           fcinfo->arg[1],
 
769
                                                                                           fcinfo->arg[2],
 
770
                                                                                           fcinfo->arg[3],
 
771
                                                                                           fcinfo->arg[4],
 
772
                                                                                           fcinfo->arg[5],
 
773
                                                                                           fcinfo->arg[6],
 
774
                                                                                           fcinfo->arg[7],
 
775
                                                                                           fcinfo->arg[8],
 
776
                                                                                           fcinfo->arg[9],
 
777
                                                                                           fcinfo->arg[10],
 
778
                                                                                           fcinfo->arg[11],
 
779
                                                                                           fcinfo->arg[12]);
 
780
                        break;
 
781
                case 14:
 
782
                        returnValue = (char *) (*user_fn) (fcinfo->arg[0],
 
783
                                                                                           fcinfo->arg[1],
 
784
                                                                                           fcinfo->arg[2],
 
785
                                                                                           fcinfo->arg[3],
 
786
                                                                                           fcinfo->arg[4],
 
787
                                                                                           fcinfo->arg[5],
 
788
                                                                                           fcinfo->arg[6],
 
789
                                                                                           fcinfo->arg[7],
 
790
                                                                                           fcinfo->arg[8],
 
791
                                                                                           fcinfo->arg[9],
 
792
                                                                                           fcinfo->arg[10],
 
793
                                                                                           fcinfo->arg[11],
 
794
                                                                                           fcinfo->arg[12],
 
795
                                                                                           fcinfo->arg[13]);
 
796
                        break;
 
797
                case 15:
 
798
                        returnValue = (char *) (*user_fn) (fcinfo->arg[0],
 
799
                                                                                           fcinfo->arg[1],
 
800
                                                                                           fcinfo->arg[2],
 
801
                                                                                           fcinfo->arg[3],
 
802
                                                                                           fcinfo->arg[4],
 
803
                                                                                           fcinfo->arg[5],
 
804
                                                                                           fcinfo->arg[6],
 
805
                                                                                           fcinfo->arg[7],
 
806
                                                                                           fcinfo->arg[8],
 
807
                                                                                           fcinfo->arg[9],
 
808
                                                                                           fcinfo->arg[10],
 
809
                                                                                           fcinfo->arg[11],
 
810
                                                                                           fcinfo->arg[12],
 
811
                                                                                           fcinfo->arg[13],
 
812
                                                                                           fcinfo->arg[14]);
 
813
                        break;
 
814
                case 16:
 
815
                        returnValue = (char *) (*user_fn) (fcinfo->arg[0],
 
816
                                                                                           fcinfo->arg[1],
 
817
                                                                                           fcinfo->arg[2],
 
818
                                                                                           fcinfo->arg[3],
 
819
                                                                                           fcinfo->arg[4],
 
820
                                                                                           fcinfo->arg[5],
 
821
                                                                                           fcinfo->arg[6],
 
822
                                                                                           fcinfo->arg[7],
 
823
                                                                                           fcinfo->arg[8],
 
824
                                                                                           fcinfo->arg[9],
 
825
                                                                                           fcinfo->arg[10],
 
826
                                                                                           fcinfo->arg[11],
 
827
                                                                                           fcinfo->arg[12],
 
828
                                                                                           fcinfo->arg[13],
 
829
                                                                                           fcinfo->arg[14],
 
830
                                                                                           fcinfo->arg[15]);
 
831
                        break;
 
832
                default:
 
833
 
 
834
                        /*
 
835
                         * Increasing FUNC_MAX_ARGS doesn't automatically add cases to the
 
836
                         * above code, so mention the actual value in this error not
 
837
                         * FUNC_MAX_ARGS.  You could add cases to the above if you needed
 
838
                         * to support old-style functions with many arguments, but making
 
839
                         * 'em be new-style is probably a better idea.
 
840
                         */
 
841
                        ereport(ERROR,
 
842
                                        (errcode(ERRCODE_TOO_MANY_ARGUMENTS),
 
843
                         errmsg("function %u has too many arguments (%d, maximum is %d)",
 
844
                                        fcinfo->flinfo->fn_oid, n_arguments, 16)));
 
845
                        returnValue = NULL; /* keep compiler quiet */
 
846
                        break;
 
847
        }
 
848
 
 
849
        return PointerGetDatum(returnValue);
 
850
}
 
851
 
 
852
 
 
853
/*
 
854
 * Support for security-definer and proconfig-using functions.  We support
 
855
 * both of these features using the same call handler, because they are
 
856
 * often used together and it would be inefficient (as well as notationally
 
857
 * messy) to have two levels of call handler involved.
 
858
 */
 
859
struct fmgr_security_definer_cache
 
860
{
 
861
        FmgrInfo        flinfo;                 /* lookup info for target function */
 
862
        Oid                     userid;                 /* userid to set, or InvalidOid */
 
863
        ArrayType  *proconfig;          /* GUC values to set, or NULL */
 
864
};
 
865
 
 
866
/*
 
867
 * Function handler for security-definer/proconfig functions.  We extract the
 
868
 * OID of the actual function and do a fmgr lookup again.  Then we fetch the
 
869
 * pg_proc row and copy the owner ID and proconfig fields.      (All this info
 
870
 * is cached for the duration of the current query.)  To execute a call,
 
871
 * we temporarily replace the flinfo with the cached/looked-up one, while
 
872
 * keeping the outer fcinfo (which contains all the actual arguments, etc.)
 
873
 * intact.      This is not re-entrant, but then the fcinfo itself can't be used
 
874
 * re-entrantly anyway.
 
875
 */
 
876
static Datum
 
877
fmgr_security_definer(PG_FUNCTION_ARGS)
 
878
{
 
879
        Datum           result;
 
880
        struct fmgr_security_definer_cache *volatile fcache;
 
881
        FmgrInfo   *save_flinfo;
 
882
        Oid                     save_userid;
 
883
        bool            save_secdefcxt;
 
884
        volatile int save_nestlevel;
 
885
        PgStat_FunctionCallUsage fcusage;
 
886
 
 
887
        if (!fcinfo->flinfo->fn_extra)
 
888
        {
 
889
                HeapTuple       tuple;
 
890
                Form_pg_proc procedureStruct;
 
891
                Datum           datum;
 
892
                bool            isnull;
 
893
                MemoryContext oldcxt;
 
894
 
 
895
                fcache = MemoryContextAllocZero(fcinfo->flinfo->fn_mcxt,
 
896
                                                                                sizeof(*fcache));
 
897
 
 
898
                fmgr_info_cxt_security(fcinfo->flinfo->fn_oid, &fcache->flinfo,
 
899
                                                           fcinfo->flinfo->fn_mcxt, true);
 
900
                fcache->flinfo.fn_expr = fcinfo->flinfo->fn_expr;
 
901
 
 
902
                tuple = SearchSysCache(PROCOID,
 
903
                                                           ObjectIdGetDatum(fcinfo->flinfo->fn_oid),
 
904
                                                           0, 0, 0);
 
905
                if (!HeapTupleIsValid(tuple))
 
906
                        elog(ERROR, "cache lookup failed for function %u",
 
907
                                 fcinfo->flinfo->fn_oid);
 
908
                procedureStruct = (Form_pg_proc) GETSTRUCT(tuple);
 
909
 
 
910
                if (procedureStruct->prosecdef)
 
911
                        fcache->userid = procedureStruct->proowner;
 
912
 
 
913
                datum = SysCacheGetAttr(PROCOID, tuple, Anum_pg_proc_proconfig,
 
914
                                                                &isnull);
 
915
                if (!isnull)
 
916
                {
 
917
                        oldcxt = MemoryContextSwitchTo(fcinfo->flinfo->fn_mcxt);
 
918
                        fcache->proconfig = DatumGetArrayTypePCopy(datum);
 
919
                        MemoryContextSwitchTo(oldcxt);
 
920
                }
 
921
 
 
922
                ReleaseSysCache(tuple);
 
923
 
 
924
                fcinfo->flinfo->fn_extra = fcache;
 
925
        }
 
926
        else
 
927
                fcache = fcinfo->flinfo->fn_extra;
 
928
 
 
929
        /* GetUserIdAndContext is cheap enough that no harm in a wasted call */
 
930
        GetUserIdAndContext(&save_userid, &save_secdefcxt);
 
931
        if (fcache->proconfig)          /* Need a new GUC nesting level */
 
932
                save_nestlevel = NewGUCNestLevel();
 
933
        else
 
934
                save_nestlevel = 0;             /* keep compiler quiet */
 
935
 
 
936
        if (OidIsValid(fcache->userid))
 
937
                SetUserIdAndContext(fcache->userid, true);
 
938
 
 
939
        if (fcache->proconfig)
 
940
        {
 
941
                ProcessGUCArray(fcache->proconfig,
 
942
                                                (superuser() ? PGC_SUSET : PGC_USERSET),
 
943
                                                PGC_S_SESSION,
 
944
                                                GUC_ACTION_SAVE);
 
945
        }
 
946
 
 
947
        /*
 
948
         * We don't need to restore GUC or userid settings on error, because the
 
949
         * ensuing xact or subxact abort will do that.  The PG_TRY block is only
 
950
         * needed to clean up the flinfo link.
 
951
         */
 
952
        save_flinfo = fcinfo->flinfo;
 
953
 
 
954
        PG_TRY();
 
955
        {
 
956
                fcinfo->flinfo = &fcache->flinfo;
 
957
 
 
958
                /* See notes in fmgr_info_cxt_security */
 
959
                pgstat_init_function_usage(fcinfo, &fcusage);
 
960
 
 
961
                result = FunctionCallInvoke(fcinfo);
 
962
 
 
963
                /*
 
964
                 * We could be calling either a regular or a set-returning function,
 
965
                 * so we have to test to see what finalize flag to use.
 
966
                 */
 
967
                pgstat_end_function_usage(&fcusage,
 
968
                                                                  (fcinfo->resultinfo == NULL ||
 
969
                                                                   !IsA(fcinfo->resultinfo, ReturnSetInfo) ||
 
970
                                                                   ((ReturnSetInfo *) fcinfo->resultinfo)->isDone != ExprMultipleResult));
 
971
        }
 
972
        PG_CATCH();
 
973
        {
 
974
                fcinfo->flinfo = save_flinfo;
 
975
                PG_RE_THROW();
 
976
        }
 
977
        PG_END_TRY();
 
978
 
 
979
        fcinfo->flinfo = save_flinfo;
 
980
 
 
981
        if (fcache->proconfig)
 
982
                AtEOXact_GUC(true, save_nestlevel);
 
983
        if (OidIsValid(fcache->userid))
 
984
                SetUserIdAndContext(save_userid, save_secdefcxt);
 
985
 
 
986
        return result;
 
987
}
 
988
 
 
989
 
 
990
/*-------------------------------------------------------------------------
 
991
 *              Support routines for callers of fmgr-compatible functions
 
992
 *-------------------------------------------------------------------------
 
993
 */
 
994
 
 
995
/*
 
996
 * These are for invocation of a specifically named function with a
 
997
 * directly-computed parameter list.  Note that neither arguments nor result
 
998
 * are allowed to be NULL.      Also, the function cannot be one that needs to
 
999
 * look at FmgrInfo, since there won't be any.
 
1000
 */
 
1001
Datum
 
1002
DirectFunctionCall1(PGFunction func, Datum arg1)
 
1003
{
 
1004
        FunctionCallInfoData fcinfo;
 
1005
        Datum           result;
 
1006
 
 
1007
        InitFunctionCallInfoData(fcinfo, NULL, 1, NULL, NULL);
 
1008
 
 
1009
        fcinfo.arg[0] = arg1;
 
1010
        fcinfo.argnull[0] = false;
 
1011
 
 
1012
        result = (*func) (&fcinfo);
 
1013
 
 
1014
        /* Check for null result, since caller is clearly not expecting one */
 
1015
        if (fcinfo.isnull)
 
1016
                elog(ERROR, "function %p returned NULL", (void *) func);
 
1017
 
 
1018
        return result;
 
1019
}
 
1020
 
 
1021
Datum
 
1022
DirectFunctionCall2(PGFunction func, Datum arg1, Datum arg2)
 
1023
{
 
1024
        FunctionCallInfoData fcinfo;
 
1025
        Datum           result;
 
1026
 
 
1027
        InitFunctionCallInfoData(fcinfo, NULL, 2, NULL, NULL);
 
1028
 
 
1029
        fcinfo.arg[0] = arg1;
 
1030
        fcinfo.arg[1] = arg2;
 
1031
        fcinfo.argnull[0] = false;
 
1032
        fcinfo.argnull[1] = false;
 
1033
 
 
1034
        result = (*func) (&fcinfo);
 
1035
 
 
1036
        /* Check for null result, since caller is clearly not expecting one */
 
1037
        if (fcinfo.isnull)
 
1038
                elog(ERROR, "function %p returned NULL", (void *) func);
 
1039
 
 
1040
        return result;
 
1041
}
 
1042
 
 
1043
Datum
 
1044
DirectFunctionCall3(PGFunction func, Datum arg1, Datum arg2,
 
1045
                                        Datum arg3)
 
1046
{
 
1047
        FunctionCallInfoData fcinfo;
 
1048
        Datum           result;
 
1049
 
 
1050
        InitFunctionCallInfoData(fcinfo, NULL, 3, NULL, NULL);
 
1051
 
 
1052
        fcinfo.arg[0] = arg1;
 
1053
        fcinfo.arg[1] = arg2;
 
1054
        fcinfo.arg[2] = arg3;
 
1055
        fcinfo.argnull[0] = false;
 
1056
        fcinfo.argnull[1] = false;
 
1057
        fcinfo.argnull[2] = false;
 
1058
 
 
1059
        result = (*func) (&fcinfo);
 
1060
 
 
1061
        /* Check for null result, since caller is clearly not expecting one */
 
1062
        if (fcinfo.isnull)
 
1063
                elog(ERROR, "function %p returned NULL", (void *) func);
 
1064
 
 
1065
        return result;
 
1066
}
 
1067
 
 
1068
Datum
 
1069
DirectFunctionCall4(PGFunction func, Datum arg1, Datum arg2,
 
1070
                                        Datum arg3, Datum arg4)
 
1071
{
 
1072
        FunctionCallInfoData fcinfo;
 
1073
        Datum           result;
 
1074
 
 
1075
        InitFunctionCallInfoData(fcinfo, NULL, 4, NULL, NULL);
 
1076
 
 
1077
        fcinfo.arg[0] = arg1;
 
1078
        fcinfo.arg[1] = arg2;
 
1079
        fcinfo.arg[2] = arg3;
 
1080
        fcinfo.arg[3] = arg4;
 
1081
        fcinfo.argnull[0] = false;
 
1082
        fcinfo.argnull[1] = false;
 
1083
        fcinfo.argnull[2] = false;
 
1084
        fcinfo.argnull[3] = false;
 
1085
 
 
1086
        result = (*func) (&fcinfo);
 
1087
 
 
1088
        /* Check for null result, since caller is clearly not expecting one */
 
1089
        if (fcinfo.isnull)
 
1090
                elog(ERROR, "function %p returned NULL", (void *) func);
 
1091
 
 
1092
        return result;
 
1093
}
 
1094
 
 
1095
Datum
 
1096
DirectFunctionCall5(PGFunction func, Datum arg1, Datum arg2,
 
1097
                                        Datum arg3, Datum arg4, Datum arg5)
 
1098
{
 
1099
        FunctionCallInfoData fcinfo;
 
1100
        Datum           result;
 
1101
 
 
1102
        InitFunctionCallInfoData(fcinfo, NULL, 5, NULL, NULL);
 
1103
 
 
1104
        fcinfo.arg[0] = arg1;
 
1105
        fcinfo.arg[1] = arg2;
 
1106
        fcinfo.arg[2] = arg3;
 
1107
        fcinfo.arg[3] = arg4;
 
1108
        fcinfo.arg[4] = arg5;
 
1109
        fcinfo.argnull[0] = false;
 
1110
        fcinfo.argnull[1] = false;
 
1111
        fcinfo.argnull[2] = false;
 
1112
        fcinfo.argnull[3] = false;
 
1113
        fcinfo.argnull[4] = false;
 
1114
 
 
1115
        result = (*func) (&fcinfo);
 
1116
 
 
1117
        /* Check for null result, since caller is clearly not expecting one */
 
1118
        if (fcinfo.isnull)
 
1119
                elog(ERROR, "function %p returned NULL", (void *) func);
 
1120
 
 
1121
        return result;
 
1122
}
 
1123
 
 
1124
Datum
 
1125
DirectFunctionCall6(PGFunction func, Datum arg1, Datum arg2,
 
1126
                                        Datum arg3, Datum arg4, Datum arg5,
 
1127
                                        Datum arg6)
 
1128
{
 
1129
        FunctionCallInfoData fcinfo;
 
1130
        Datum           result;
 
1131
 
 
1132
        InitFunctionCallInfoData(fcinfo, NULL, 6, NULL, NULL);
 
1133
 
 
1134
        fcinfo.arg[0] = arg1;
 
1135
        fcinfo.arg[1] = arg2;
 
1136
        fcinfo.arg[2] = arg3;
 
1137
        fcinfo.arg[3] = arg4;
 
1138
        fcinfo.arg[4] = arg5;
 
1139
        fcinfo.arg[5] = arg6;
 
1140
        fcinfo.argnull[0] = false;
 
1141
        fcinfo.argnull[1] = false;
 
1142
        fcinfo.argnull[2] = false;
 
1143
        fcinfo.argnull[3] = false;
 
1144
        fcinfo.argnull[4] = false;
 
1145
        fcinfo.argnull[5] = false;
 
1146
 
 
1147
        result = (*func) (&fcinfo);
 
1148
 
 
1149
        /* Check for null result, since caller is clearly not expecting one */
 
1150
        if (fcinfo.isnull)
 
1151
                elog(ERROR, "function %p returned NULL", (void *) func);
 
1152
 
 
1153
        return result;
 
1154
}
 
1155
 
 
1156
Datum
 
1157
DirectFunctionCall7(PGFunction func, Datum arg1, Datum arg2,
 
1158
                                        Datum arg3, Datum arg4, Datum arg5,
 
1159
                                        Datum arg6, Datum arg7)
 
1160
{
 
1161
        FunctionCallInfoData fcinfo;
 
1162
        Datum           result;
 
1163
 
 
1164
        InitFunctionCallInfoData(fcinfo, NULL, 7, NULL, NULL);
 
1165
 
 
1166
        fcinfo.arg[0] = arg1;
 
1167
        fcinfo.arg[1] = arg2;
 
1168
        fcinfo.arg[2] = arg3;
 
1169
        fcinfo.arg[3] = arg4;
 
1170
        fcinfo.arg[4] = arg5;
 
1171
        fcinfo.arg[5] = arg6;
 
1172
        fcinfo.arg[6] = arg7;
 
1173
        fcinfo.argnull[0] = false;
 
1174
        fcinfo.argnull[1] = false;
 
1175
        fcinfo.argnull[2] = false;
 
1176
        fcinfo.argnull[3] = false;
 
1177
        fcinfo.argnull[4] = false;
 
1178
        fcinfo.argnull[5] = false;
 
1179
        fcinfo.argnull[6] = false;
 
1180
 
 
1181
        result = (*func) (&fcinfo);
 
1182
 
 
1183
        /* Check for null result, since caller is clearly not expecting one */
 
1184
        if (fcinfo.isnull)
 
1185
                elog(ERROR, "function %p returned NULL", (void *) func);
 
1186
 
 
1187
        return result;
 
1188
}
 
1189
 
 
1190
Datum
 
1191
DirectFunctionCall8(PGFunction func, Datum arg1, Datum arg2,
 
1192
                                        Datum arg3, Datum arg4, Datum arg5,
 
1193
                                        Datum arg6, Datum arg7, Datum arg8)
 
1194
{
 
1195
        FunctionCallInfoData fcinfo;
 
1196
        Datum           result;
 
1197
 
 
1198
        InitFunctionCallInfoData(fcinfo, NULL, 8, NULL, NULL);
 
1199
 
 
1200
        fcinfo.arg[0] = arg1;
 
1201
        fcinfo.arg[1] = arg2;
 
1202
        fcinfo.arg[2] = arg3;
 
1203
        fcinfo.arg[3] = arg4;
 
1204
        fcinfo.arg[4] = arg5;
 
1205
        fcinfo.arg[5] = arg6;
 
1206
        fcinfo.arg[6] = arg7;
 
1207
        fcinfo.arg[7] = arg8;
 
1208
        fcinfo.argnull[0] = false;
 
1209
        fcinfo.argnull[1] = false;
 
1210
        fcinfo.argnull[2] = false;
 
1211
        fcinfo.argnull[3] = false;
 
1212
        fcinfo.argnull[4] = false;
 
1213
        fcinfo.argnull[5] = false;
 
1214
        fcinfo.argnull[6] = false;
 
1215
        fcinfo.argnull[7] = false;
 
1216
 
 
1217
        result = (*func) (&fcinfo);
 
1218
 
 
1219
        /* Check for null result, since caller is clearly not expecting one */
 
1220
        if (fcinfo.isnull)
 
1221
                elog(ERROR, "function %p returned NULL", (void *) func);
 
1222
 
 
1223
        return result;
 
1224
}
 
1225
 
 
1226
Datum
 
1227
DirectFunctionCall9(PGFunction func, Datum arg1, Datum arg2,
 
1228
                                        Datum arg3, Datum arg4, Datum arg5,
 
1229
                                        Datum arg6, Datum arg7, Datum arg8,
 
1230
                                        Datum arg9)
 
1231
{
 
1232
        FunctionCallInfoData fcinfo;
 
1233
        Datum           result;
 
1234
 
 
1235
        InitFunctionCallInfoData(fcinfo, NULL, 9, NULL, NULL);
 
1236
 
 
1237
        fcinfo.arg[0] = arg1;
 
1238
        fcinfo.arg[1] = arg2;
 
1239
        fcinfo.arg[2] = arg3;
 
1240
        fcinfo.arg[3] = arg4;
 
1241
        fcinfo.arg[4] = arg5;
 
1242
        fcinfo.arg[5] = arg6;
 
1243
        fcinfo.arg[6] = arg7;
 
1244
        fcinfo.arg[7] = arg8;
 
1245
        fcinfo.arg[8] = arg9;
 
1246
        fcinfo.argnull[0] = false;
 
1247
        fcinfo.argnull[1] = false;
 
1248
        fcinfo.argnull[2] = false;
 
1249
        fcinfo.argnull[3] = false;
 
1250
        fcinfo.argnull[4] = false;
 
1251
        fcinfo.argnull[5] = false;
 
1252
        fcinfo.argnull[6] = false;
 
1253
        fcinfo.argnull[7] = false;
 
1254
        fcinfo.argnull[8] = false;
 
1255
 
 
1256
        result = (*func) (&fcinfo);
 
1257
 
 
1258
        /* Check for null result, since caller is clearly not expecting one */
 
1259
        if (fcinfo.isnull)
 
1260
                elog(ERROR, "function %p returned NULL", (void *) func);
 
1261
 
 
1262
        return result;
 
1263
}
 
1264
 
 
1265
 
 
1266
/*
 
1267
 * These are for invocation of a previously-looked-up function with a
 
1268
 * directly-computed parameter list.  Note that neither arguments nor result
 
1269
 * are allowed to be NULL.
 
1270
 */
 
1271
Datum
 
1272
FunctionCall1(FmgrInfo *flinfo, Datum arg1)
 
1273
{
 
1274
        FunctionCallInfoData fcinfo;
 
1275
        Datum           result;
 
1276
 
 
1277
        InitFunctionCallInfoData(fcinfo, flinfo, 1, NULL, NULL);
 
1278
 
 
1279
        fcinfo.arg[0] = arg1;
 
1280
        fcinfo.argnull[0] = false;
 
1281
 
 
1282
        result = FunctionCallInvoke(&fcinfo);
 
1283
 
 
1284
        /* Check for null result, since caller is clearly not expecting one */
 
1285
        if (fcinfo.isnull)
 
1286
                elog(ERROR, "function %u returned NULL", fcinfo.flinfo->fn_oid);
 
1287
 
 
1288
        return result;
 
1289
}
 
1290
 
 
1291
Datum
 
1292
FunctionCall2(FmgrInfo *flinfo, Datum arg1, Datum arg2)
 
1293
{
 
1294
        /*
 
1295
         * XXX if you change this routine, see also the inlined version in
 
1296
         * utils/sort/tuplesort.c!
 
1297
         */
 
1298
        FunctionCallInfoData fcinfo;
 
1299
        Datum           result;
 
1300
 
 
1301
        InitFunctionCallInfoData(fcinfo, flinfo, 2, NULL, NULL);
 
1302
 
 
1303
        fcinfo.arg[0] = arg1;
 
1304
        fcinfo.arg[1] = arg2;
 
1305
        fcinfo.argnull[0] = false;
 
1306
        fcinfo.argnull[1] = false;
 
1307
 
 
1308
        result = FunctionCallInvoke(&fcinfo);
 
1309
 
 
1310
        /* Check for null result, since caller is clearly not expecting one */
 
1311
        if (fcinfo.isnull)
 
1312
                elog(ERROR, "function %u returned NULL", fcinfo.flinfo->fn_oid);
 
1313
 
 
1314
        return result;
 
1315
}
 
1316
 
 
1317
Datum
 
1318
FunctionCall3(FmgrInfo *flinfo, Datum arg1, Datum arg2,
 
1319
                          Datum arg3)
 
1320
{
 
1321
        FunctionCallInfoData fcinfo;
 
1322
        Datum           result;
 
1323
 
 
1324
        InitFunctionCallInfoData(fcinfo, flinfo, 3, NULL, NULL);
 
1325
 
 
1326
        fcinfo.arg[0] = arg1;
 
1327
        fcinfo.arg[1] = arg2;
 
1328
        fcinfo.arg[2] = arg3;
 
1329
        fcinfo.argnull[0] = false;
 
1330
        fcinfo.argnull[1] = false;
 
1331
        fcinfo.argnull[2] = false;
 
1332
 
 
1333
        result = FunctionCallInvoke(&fcinfo);
 
1334
 
 
1335
        /* Check for null result, since caller is clearly not expecting one */
 
1336
        if (fcinfo.isnull)
 
1337
                elog(ERROR, "function %u returned NULL", fcinfo.flinfo->fn_oid);
 
1338
 
 
1339
        return result;
 
1340
}
 
1341
 
 
1342
Datum
 
1343
FunctionCall4(FmgrInfo *flinfo, Datum arg1, Datum arg2,
 
1344
                          Datum arg3, Datum arg4)
 
1345
{
 
1346
        FunctionCallInfoData fcinfo;
 
1347
        Datum           result;
 
1348
 
 
1349
        InitFunctionCallInfoData(fcinfo, flinfo, 4, NULL, NULL);
 
1350
 
 
1351
        fcinfo.arg[0] = arg1;
 
1352
        fcinfo.arg[1] = arg2;
 
1353
        fcinfo.arg[2] = arg3;
 
1354
        fcinfo.arg[3] = arg4;
 
1355
        fcinfo.argnull[0] = false;
 
1356
        fcinfo.argnull[1] = false;
 
1357
        fcinfo.argnull[2] = false;
 
1358
        fcinfo.argnull[3] = false;
 
1359
 
 
1360
        result = FunctionCallInvoke(&fcinfo);
 
1361
 
 
1362
        /* Check for null result, since caller is clearly not expecting one */
 
1363
        if (fcinfo.isnull)
 
1364
                elog(ERROR, "function %u returned NULL", fcinfo.flinfo->fn_oid);
 
1365
 
 
1366
        return result;
 
1367
}
 
1368
 
 
1369
Datum
 
1370
FunctionCall5(FmgrInfo *flinfo, Datum arg1, Datum arg2,
 
1371
                          Datum arg3, Datum arg4, Datum arg5)
 
1372
{
 
1373
        FunctionCallInfoData fcinfo;
 
1374
        Datum           result;
 
1375
 
 
1376
        InitFunctionCallInfoData(fcinfo, flinfo, 5, NULL, NULL);
 
1377
 
 
1378
        fcinfo.arg[0] = arg1;
 
1379
        fcinfo.arg[1] = arg2;
 
1380
        fcinfo.arg[2] = arg3;
 
1381
        fcinfo.arg[3] = arg4;
 
1382
        fcinfo.arg[4] = arg5;
 
1383
        fcinfo.argnull[0] = false;
 
1384
        fcinfo.argnull[1] = false;
 
1385
        fcinfo.argnull[2] = false;
 
1386
        fcinfo.argnull[3] = false;
 
1387
        fcinfo.argnull[4] = false;
 
1388
 
 
1389
        result = FunctionCallInvoke(&fcinfo);
 
1390
 
 
1391
        /* Check for null result, since caller is clearly not expecting one */
 
1392
        if (fcinfo.isnull)
 
1393
                elog(ERROR, "function %u returned NULL", fcinfo.flinfo->fn_oid);
 
1394
 
 
1395
        return result;
 
1396
}
 
1397
 
 
1398
Datum
 
1399
FunctionCall6(FmgrInfo *flinfo, Datum arg1, Datum arg2,
 
1400
                          Datum arg3, Datum arg4, Datum arg5,
 
1401
                          Datum arg6)
 
1402
{
 
1403
        FunctionCallInfoData fcinfo;
 
1404
        Datum           result;
 
1405
 
 
1406
        InitFunctionCallInfoData(fcinfo, flinfo, 6, NULL, NULL);
 
1407
 
 
1408
        fcinfo.arg[0] = arg1;
 
1409
        fcinfo.arg[1] = arg2;
 
1410
        fcinfo.arg[2] = arg3;
 
1411
        fcinfo.arg[3] = arg4;
 
1412
        fcinfo.arg[4] = arg5;
 
1413
        fcinfo.arg[5] = arg6;
 
1414
        fcinfo.argnull[0] = false;
 
1415
        fcinfo.argnull[1] = false;
 
1416
        fcinfo.argnull[2] = false;
 
1417
        fcinfo.argnull[3] = false;
 
1418
        fcinfo.argnull[4] = false;
 
1419
        fcinfo.argnull[5] = false;
 
1420
 
 
1421
        result = FunctionCallInvoke(&fcinfo);
 
1422
 
 
1423
        /* Check for null result, since caller is clearly not expecting one */
 
1424
        if (fcinfo.isnull)
 
1425
                elog(ERROR, "function %u returned NULL", fcinfo.flinfo->fn_oid);
 
1426
 
 
1427
        return result;
 
1428
}
 
1429
 
 
1430
Datum
 
1431
FunctionCall7(FmgrInfo *flinfo, Datum arg1, Datum arg2,
 
1432
                          Datum arg3, Datum arg4, Datum arg5,
 
1433
                          Datum arg6, Datum arg7)
 
1434
{
 
1435
        FunctionCallInfoData fcinfo;
 
1436
        Datum           result;
 
1437
 
 
1438
        InitFunctionCallInfoData(fcinfo, flinfo, 7, NULL, NULL);
 
1439
 
 
1440
        fcinfo.arg[0] = arg1;
 
1441
        fcinfo.arg[1] = arg2;
 
1442
        fcinfo.arg[2] = arg3;
 
1443
        fcinfo.arg[3] = arg4;
 
1444
        fcinfo.arg[4] = arg5;
 
1445
        fcinfo.arg[5] = arg6;
 
1446
        fcinfo.arg[6] = arg7;
 
1447
        fcinfo.argnull[0] = false;
 
1448
        fcinfo.argnull[1] = false;
 
1449
        fcinfo.argnull[2] = false;
 
1450
        fcinfo.argnull[3] = false;
 
1451
        fcinfo.argnull[4] = false;
 
1452
        fcinfo.argnull[5] = false;
 
1453
        fcinfo.argnull[6] = false;
 
1454
 
 
1455
        result = FunctionCallInvoke(&fcinfo);
 
1456
 
 
1457
        /* Check for null result, since caller is clearly not expecting one */
 
1458
        if (fcinfo.isnull)
 
1459
                elog(ERROR, "function %u returned NULL", fcinfo.flinfo->fn_oid);
 
1460
 
 
1461
        return result;
 
1462
}
 
1463
 
 
1464
Datum
 
1465
FunctionCall8(FmgrInfo *flinfo, Datum arg1, Datum arg2,
 
1466
                          Datum arg3, Datum arg4, Datum arg5,
 
1467
                          Datum arg6, Datum arg7, Datum arg8)
 
1468
{
 
1469
        FunctionCallInfoData fcinfo;
 
1470
        Datum           result;
 
1471
 
 
1472
        InitFunctionCallInfoData(fcinfo, flinfo, 8, NULL, NULL);
 
1473
 
 
1474
        fcinfo.arg[0] = arg1;
 
1475
        fcinfo.arg[1] = arg2;
 
1476
        fcinfo.arg[2] = arg3;
 
1477
        fcinfo.arg[3] = arg4;
 
1478
        fcinfo.arg[4] = arg5;
 
1479
        fcinfo.arg[5] = arg6;
 
1480
        fcinfo.arg[6] = arg7;
 
1481
        fcinfo.arg[7] = arg8;
 
1482
        fcinfo.argnull[0] = false;
 
1483
        fcinfo.argnull[1] = false;
 
1484
        fcinfo.argnull[2] = false;
 
1485
        fcinfo.argnull[3] = false;
 
1486
        fcinfo.argnull[4] = false;
 
1487
        fcinfo.argnull[5] = false;
 
1488
        fcinfo.argnull[6] = false;
 
1489
        fcinfo.argnull[7] = false;
 
1490
 
 
1491
        result = FunctionCallInvoke(&fcinfo);
 
1492
 
 
1493
        /* Check for null result, since caller is clearly not expecting one */
 
1494
        if (fcinfo.isnull)
 
1495
                elog(ERROR, "function %u returned NULL", fcinfo.flinfo->fn_oid);
 
1496
 
 
1497
        return result;
 
1498
}
 
1499
 
 
1500
Datum
 
1501
FunctionCall9(FmgrInfo *flinfo, Datum arg1, Datum arg2,
 
1502
                          Datum arg3, Datum arg4, Datum arg5,
 
1503
                          Datum arg6, Datum arg7, Datum arg8,
 
1504
                          Datum arg9)
 
1505
{
 
1506
        FunctionCallInfoData fcinfo;
 
1507
        Datum           result;
 
1508
 
 
1509
        InitFunctionCallInfoData(fcinfo, flinfo, 9, NULL, NULL);
 
1510
 
 
1511
        fcinfo.arg[0] = arg1;
 
1512
        fcinfo.arg[1] = arg2;
 
1513
        fcinfo.arg[2] = arg3;
 
1514
        fcinfo.arg[3] = arg4;
 
1515
        fcinfo.arg[4] = arg5;
 
1516
        fcinfo.arg[5] = arg6;
 
1517
        fcinfo.arg[6] = arg7;
 
1518
        fcinfo.arg[7] = arg8;
 
1519
        fcinfo.arg[8] = arg9;
 
1520
        fcinfo.argnull[0] = false;
 
1521
        fcinfo.argnull[1] = false;
 
1522
        fcinfo.argnull[2] = false;
 
1523
        fcinfo.argnull[3] = false;
 
1524
        fcinfo.argnull[4] = false;
 
1525
        fcinfo.argnull[5] = false;
 
1526
        fcinfo.argnull[6] = false;
 
1527
        fcinfo.argnull[7] = false;
 
1528
        fcinfo.argnull[8] = false;
 
1529
 
 
1530
        result = FunctionCallInvoke(&fcinfo);
 
1531
 
 
1532
        /* Check for null result, since caller is clearly not expecting one */
 
1533
        if (fcinfo.isnull)
 
1534
                elog(ERROR, "function %u returned NULL", fcinfo.flinfo->fn_oid);
 
1535
 
 
1536
        return result;
 
1537
}
 
1538
 
 
1539
 
 
1540
/*
 
1541
 * These are for invocation of a function identified by OID with a
 
1542
 * directly-computed parameter list.  Note that neither arguments nor result
 
1543
 * are allowed to be NULL.      These are essentially fmgr_info() followed
 
1544
 * by FunctionCallN().  If the same function is to be invoked repeatedly,
 
1545
 * do the fmgr_info() once and then use FunctionCallN().
 
1546
 */
 
1547
Datum
 
1548
OidFunctionCall1(Oid functionId, Datum arg1)
 
1549
{
 
1550
        FmgrInfo        flinfo;
 
1551
        FunctionCallInfoData fcinfo;
 
1552
        Datum           result;
 
1553
 
 
1554
        fmgr_info(functionId, &flinfo);
 
1555
 
 
1556
        InitFunctionCallInfoData(fcinfo, &flinfo, 1, NULL, NULL);
 
1557
 
 
1558
        fcinfo.arg[0] = arg1;
 
1559
        fcinfo.argnull[0] = false;
 
1560
 
 
1561
        result = FunctionCallInvoke(&fcinfo);
 
1562
 
 
1563
        /* Check for null result, since caller is clearly not expecting one */
 
1564
        if (fcinfo.isnull)
 
1565
                elog(ERROR, "function %u returned NULL", flinfo.fn_oid);
 
1566
 
 
1567
        return result;
 
1568
}
 
1569
 
 
1570
Datum
 
1571
OidFunctionCall2(Oid functionId, Datum arg1, Datum arg2)
 
1572
{
 
1573
        FmgrInfo        flinfo;
 
1574
        FunctionCallInfoData fcinfo;
 
1575
        Datum           result;
 
1576
 
 
1577
        fmgr_info(functionId, &flinfo);
 
1578
 
 
1579
        InitFunctionCallInfoData(fcinfo, &flinfo, 2, NULL, NULL);
 
1580
 
 
1581
        fcinfo.arg[0] = arg1;
 
1582
        fcinfo.arg[1] = arg2;
 
1583
        fcinfo.argnull[0] = false;
 
1584
        fcinfo.argnull[1] = false;
 
1585
 
 
1586
        result = FunctionCallInvoke(&fcinfo);
 
1587
 
 
1588
        /* Check for null result, since caller is clearly not expecting one */
 
1589
        if (fcinfo.isnull)
 
1590
                elog(ERROR, "function %u returned NULL", flinfo.fn_oid);
 
1591
 
 
1592
        return result;
 
1593
}
 
1594
 
 
1595
Datum
 
1596
OidFunctionCall3(Oid functionId, Datum arg1, Datum arg2,
 
1597
                                 Datum arg3)
 
1598
{
 
1599
        FmgrInfo        flinfo;
 
1600
        FunctionCallInfoData fcinfo;
 
1601
        Datum           result;
 
1602
 
 
1603
        fmgr_info(functionId, &flinfo);
 
1604
 
 
1605
        InitFunctionCallInfoData(fcinfo, &flinfo, 3, NULL, NULL);
 
1606
 
 
1607
        fcinfo.arg[0] = arg1;
 
1608
        fcinfo.arg[1] = arg2;
 
1609
        fcinfo.arg[2] = arg3;
 
1610
        fcinfo.argnull[0] = false;
 
1611
        fcinfo.argnull[1] = false;
 
1612
        fcinfo.argnull[2] = false;
 
1613
 
 
1614
        result = FunctionCallInvoke(&fcinfo);
 
1615
 
 
1616
        /* Check for null result, since caller is clearly not expecting one */
 
1617
        if (fcinfo.isnull)
 
1618
                elog(ERROR, "function %u returned NULL", flinfo.fn_oid);
 
1619
 
 
1620
        return result;
 
1621
}
 
1622
 
 
1623
Datum
 
1624
OidFunctionCall4(Oid functionId, Datum arg1, Datum arg2,
 
1625
                                 Datum arg3, Datum arg4)
 
1626
{
 
1627
        FmgrInfo        flinfo;
 
1628
        FunctionCallInfoData fcinfo;
 
1629
        Datum           result;
 
1630
 
 
1631
        fmgr_info(functionId, &flinfo);
 
1632
 
 
1633
        InitFunctionCallInfoData(fcinfo, &flinfo, 4, NULL, NULL);
 
1634
 
 
1635
        fcinfo.arg[0] = arg1;
 
1636
        fcinfo.arg[1] = arg2;
 
1637
        fcinfo.arg[2] = arg3;
 
1638
        fcinfo.arg[3] = arg4;
 
1639
        fcinfo.argnull[0] = false;
 
1640
        fcinfo.argnull[1] = false;
 
1641
        fcinfo.argnull[2] = false;
 
1642
        fcinfo.argnull[3] = false;
 
1643
 
 
1644
        result = FunctionCallInvoke(&fcinfo);
 
1645
 
 
1646
        /* Check for null result, since caller is clearly not expecting one */
 
1647
        if (fcinfo.isnull)
 
1648
                elog(ERROR, "function %u returned NULL", flinfo.fn_oid);
 
1649
 
 
1650
        return result;
 
1651
}
 
1652
 
 
1653
Datum
 
1654
OidFunctionCall5(Oid functionId, Datum arg1, Datum arg2,
 
1655
                                 Datum arg3, Datum arg4, Datum arg5)
 
1656
{
 
1657
        FmgrInfo        flinfo;
 
1658
        FunctionCallInfoData fcinfo;
 
1659
        Datum           result;
 
1660
 
 
1661
        fmgr_info(functionId, &flinfo);
 
1662
 
 
1663
        InitFunctionCallInfoData(fcinfo, &flinfo, 5, NULL, NULL);
 
1664
 
 
1665
        fcinfo.arg[0] = arg1;
 
1666
        fcinfo.arg[1] = arg2;
 
1667
        fcinfo.arg[2] = arg3;
 
1668
        fcinfo.arg[3] = arg4;
 
1669
        fcinfo.arg[4] = arg5;
 
1670
        fcinfo.argnull[0] = false;
 
1671
        fcinfo.argnull[1] = false;
 
1672
        fcinfo.argnull[2] = false;
 
1673
        fcinfo.argnull[3] = false;
 
1674
        fcinfo.argnull[4] = false;
 
1675
 
 
1676
        result = FunctionCallInvoke(&fcinfo);
 
1677
 
 
1678
        /* Check for null result, since caller is clearly not expecting one */
 
1679
        if (fcinfo.isnull)
 
1680
                elog(ERROR, "function %u returned NULL", flinfo.fn_oid);
 
1681
 
 
1682
        return result;
 
1683
}
 
1684
 
 
1685
Datum
 
1686
OidFunctionCall6(Oid functionId, Datum arg1, Datum arg2,
 
1687
                                 Datum arg3, Datum arg4, Datum arg5,
 
1688
                                 Datum arg6)
 
1689
{
 
1690
        FmgrInfo        flinfo;
 
1691
        FunctionCallInfoData fcinfo;
 
1692
        Datum           result;
 
1693
 
 
1694
        fmgr_info(functionId, &flinfo);
 
1695
 
 
1696
        InitFunctionCallInfoData(fcinfo, &flinfo, 6, NULL, NULL);
 
1697
 
 
1698
        fcinfo.arg[0] = arg1;
 
1699
        fcinfo.arg[1] = arg2;
 
1700
        fcinfo.arg[2] = arg3;
 
1701
        fcinfo.arg[3] = arg4;
 
1702
        fcinfo.arg[4] = arg5;
 
1703
        fcinfo.arg[5] = arg6;
 
1704
        fcinfo.argnull[0] = false;
 
1705
        fcinfo.argnull[1] = false;
 
1706
        fcinfo.argnull[2] = false;
 
1707
        fcinfo.argnull[3] = false;
 
1708
        fcinfo.argnull[4] = false;
 
1709
        fcinfo.argnull[5] = false;
 
1710
 
 
1711
        result = FunctionCallInvoke(&fcinfo);
 
1712
 
 
1713
        /* Check for null result, since caller is clearly not expecting one */
 
1714
        if (fcinfo.isnull)
 
1715
                elog(ERROR, "function %u returned NULL", flinfo.fn_oid);
 
1716
 
 
1717
        return result;
 
1718
}
 
1719
 
 
1720
Datum
 
1721
OidFunctionCall7(Oid functionId, Datum arg1, Datum arg2,
 
1722
                                 Datum arg3, Datum arg4, Datum arg5,
 
1723
                                 Datum arg6, Datum arg7)
 
1724
{
 
1725
        FmgrInfo        flinfo;
 
1726
        FunctionCallInfoData fcinfo;
 
1727
        Datum           result;
 
1728
 
 
1729
        fmgr_info(functionId, &flinfo);
 
1730
 
 
1731
        InitFunctionCallInfoData(fcinfo, &flinfo, 7, NULL, NULL);
 
1732
 
 
1733
        fcinfo.arg[0] = arg1;
 
1734
        fcinfo.arg[1] = arg2;
 
1735
        fcinfo.arg[2] = arg3;
 
1736
        fcinfo.arg[3] = arg4;
 
1737
        fcinfo.arg[4] = arg5;
 
1738
        fcinfo.arg[5] = arg6;
 
1739
        fcinfo.arg[6] = arg7;
 
1740
        fcinfo.argnull[0] = false;
 
1741
        fcinfo.argnull[1] = false;
 
1742
        fcinfo.argnull[2] = false;
 
1743
        fcinfo.argnull[3] = false;
 
1744
        fcinfo.argnull[4] = false;
 
1745
        fcinfo.argnull[5] = false;
 
1746
        fcinfo.argnull[6] = false;
 
1747
 
 
1748
        result = FunctionCallInvoke(&fcinfo);
 
1749
 
 
1750
        /* Check for null result, since caller is clearly not expecting one */
 
1751
        if (fcinfo.isnull)
 
1752
                elog(ERROR, "function %u returned NULL", flinfo.fn_oid);
 
1753
 
 
1754
        return result;
 
1755
}
 
1756
 
 
1757
Datum
 
1758
OidFunctionCall8(Oid functionId, Datum arg1, Datum arg2,
 
1759
                                 Datum arg3, Datum arg4, Datum arg5,
 
1760
                                 Datum arg6, Datum arg7, Datum arg8)
 
1761
{
 
1762
        FmgrInfo        flinfo;
 
1763
        FunctionCallInfoData fcinfo;
 
1764
        Datum           result;
 
1765
 
 
1766
        fmgr_info(functionId, &flinfo);
 
1767
 
 
1768
        InitFunctionCallInfoData(fcinfo, &flinfo, 8, NULL, NULL);
 
1769
 
 
1770
        fcinfo.arg[0] = arg1;
 
1771
        fcinfo.arg[1] = arg2;
 
1772
        fcinfo.arg[2] = arg3;
 
1773
        fcinfo.arg[3] = arg4;
 
1774
        fcinfo.arg[4] = arg5;
 
1775
        fcinfo.arg[5] = arg6;
 
1776
        fcinfo.arg[6] = arg7;
 
1777
        fcinfo.arg[7] = arg8;
 
1778
        fcinfo.argnull[0] = false;
 
1779
        fcinfo.argnull[1] = false;
 
1780
        fcinfo.argnull[2] = false;
 
1781
        fcinfo.argnull[3] = false;
 
1782
        fcinfo.argnull[4] = false;
 
1783
        fcinfo.argnull[5] = false;
 
1784
        fcinfo.argnull[6] = false;
 
1785
        fcinfo.argnull[7] = false;
 
1786
 
 
1787
        result = FunctionCallInvoke(&fcinfo);
 
1788
 
 
1789
        /* Check for null result, since caller is clearly not expecting one */
 
1790
        if (fcinfo.isnull)
 
1791
                elog(ERROR, "function %u returned NULL", flinfo.fn_oid);
 
1792
 
 
1793
        return result;
 
1794
}
 
1795
 
 
1796
Datum
 
1797
OidFunctionCall9(Oid functionId, Datum arg1, Datum arg2,
 
1798
                                 Datum arg3, Datum arg4, Datum arg5,
 
1799
                                 Datum arg6, Datum arg7, Datum arg8,
 
1800
                                 Datum arg9)
 
1801
{
 
1802
        FmgrInfo        flinfo;
 
1803
        FunctionCallInfoData fcinfo;
 
1804
        Datum           result;
 
1805
 
 
1806
        fmgr_info(functionId, &flinfo);
 
1807
 
 
1808
        InitFunctionCallInfoData(fcinfo, &flinfo, 9, NULL, NULL);
 
1809
 
 
1810
        fcinfo.arg[0] = arg1;
 
1811
        fcinfo.arg[1] = arg2;
 
1812
        fcinfo.arg[2] = arg3;
 
1813
        fcinfo.arg[3] = arg4;
 
1814
        fcinfo.arg[4] = arg5;
 
1815
        fcinfo.arg[5] = arg6;
 
1816
        fcinfo.arg[6] = arg7;
 
1817
        fcinfo.arg[7] = arg8;
 
1818
        fcinfo.arg[8] = arg9;
 
1819
        fcinfo.argnull[0] = false;
 
1820
        fcinfo.argnull[1] = false;
 
1821
        fcinfo.argnull[2] = false;
 
1822
        fcinfo.argnull[3] = false;
 
1823
        fcinfo.argnull[4] = false;
 
1824
        fcinfo.argnull[5] = false;
 
1825
        fcinfo.argnull[6] = false;
 
1826
        fcinfo.argnull[7] = false;
 
1827
        fcinfo.argnull[8] = false;
 
1828
 
 
1829
        result = FunctionCallInvoke(&fcinfo);
 
1830
 
 
1831
        /* Check for null result, since caller is clearly not expecting one */
 
1832
        if (fcinfo.isnull)
 
1833
                elog(ERROR, "function %u returned NULL", flinfo.fn_oid);
 
1834
 
 
1835
        return result;
 
1836
}
 
1837
 
 
1838
 
 
1839
/*
 
1840
 * Special cases for convenient invocation of datatype I/O functions.
 
1841
 */
 
1842
 
 
1843
/*
 
1844
 * Call a previously-looked-up datatype input function.
 
1845
 *
 
1846
 * "str" may be NULL to indicate we are reading a NULL.  In this case
 
1847
 * the caller should assume the result is NULL, but we'll call the input
 
1848
 * function anyway if it's not strict.  So this is almost but not quite
 
1849
 * the same as FunctionCall3.
 
1850
 *
 
1851
 * One important difference from the bare function call is that we will
 
1852
 * push any active SPI context, allowing SPI-using I/O functions to be
 
1853
 * called from other SPI functions without extra notation.  This is a hack,
 
1854
 * but the alternative of expecting all SPI functions to do SPI_push/SPI_pop
 
1855
 * around I/O calls seems worse.
 
1856
 */
 
1857
Datum
 
1858
InputFunctionCall(FmgrInfo *flinfo, char *str, Oid typioparam, int32 typmod)
 
1859
{
 
1860
        FunctionCallInfoData fcinfo;
 
1861
        Datum           result;
 
1862
        bool            pushed;
 
1863
 
 
1864
        if (str == NULL && flinfo->fn_strict)
 
1865
                return (Datum) 0;               /* just return null result */
 
1866
 
 
1867
        pushed = SPI_push_conditional();
 
1868
 
 
1869
        InitFunctionCallInfoData(fcinfo, flinfo, 3, NULL, NULL);
 
1870
 
 
1871
        fcinfo.arg[0] = CStringGetDatum(str);
 
1872
        fcinfo.arg[1] = ObjectIdGetDatum(typioparam);
 
1873
        fcinfo.arg[2] = Int32GetDatum(typmod);
 
1874
        fcinfo.argnull[0] = (str == NULL);
 
1875
        fcinfo.argnull[1] = false;
 
1876
        fcinfo.argnull[2] = false;
 
1877
 
 
1878
        result = FunctionCallInvoke(&fcinfo);
 
1879
 
 
1880
        /* Should get null result if and only if str is NULL */
 
1881
        if (str == NULL)
 
1882
        {
 
1883
                if (!fcinfo.isnull)
 
1884
                        elog(ERROR, "input function %u returned non-NULL",
 
1885
                                 fcinfo.flinfo->fn_oid);
 
1886
        }
 
1887
        else
 
1888
        {
 
1889
                if (fcinfo.isnull)
 
1890
                        elog(ERROR, "input function %u returned NULL",
 
1891
                                 fcinfo.flinfo->fn_oid);
 
1892
        }
 
1893
 
 
1894
        SPI_pop_conditional(pushed);
 
1895
 
 
1896
        return result;
 
1897
}
 
1898
 
 
1899
/*
 
1900
 * Call a previously-looked-up datatype output function.
 
1901
 *
 
1902
 * Do not call this on NULL datums.
 
1903
 *
 
1904
 * This is almost just window dressing for FunctionCall1, but it includes
 
1905
 * SPI context pushing for the same reasons as InputFunctionCall.
 
1906
 */
 
1907
char *
 
1908
OutputFunctionCall(FmgrInfo *flinfo, Datum val)
 
1909
{
 
1910
        char       *result;
 
1911
        bool            pushed;
 
1912
 
 
1913
        pushed = SPI_push_conditional();
 
1914
 
 
1915
        result = DatumGetCString(FunctionCall1(flinfo, val));
 
1916
 
 
1917
        SPI_pop_conditional(pushed);
 
1918
 
 
1919
        return result;
 
1920
}
 
1921
 
 
1922
/*
 
1923
 * Call a previously-looked-up datatype binary-input function.
 
1924
 *
 
1925
 * "buf" may be NULL to indicate we are reading a NULL.  In this case
 
1926
 * the caller should assume the result is NULL, but we'll call the receive
 
1927
 * function anyway if it's not strict.  So this is almost but not quite
 
1928
 * the same as FunctionCall3.  Also, this includes SPI context pushing for
 
1929
 * the same reasons as InputFunctionCall.
 
1930
 */
 
1931
Datum
 
1932
ReceiveFunctionCall(FmgrInfo *flinfo, StringInfo buf,
 
1933
                                        Oid typioparam, int32 typmod)
 
1934
{
 
1935
        FunctionCallInfoData fcinfo;
 
1936
        Datum           result;
 
1937
        bool            pushed;
 
1938
 
 
1939
        if (buf == NULL && flinfo->fn_strict)
 
1940
                return (Datum) 0;               /* just return null result */
 
1941
 
 
1942
        pushed = SPI_push_conditional();
 
1943
 
 
1944
        InitFunctionCallInfoData(fcinfo, flinfo, 3, NULL, NULL);
 
1945
 
 
1946
        fcinfo.arg[0] = PointerGetDatum(buf);
 
1947
        fcinfo.arg[1] = ObjectIdGetDatum(typioparam);
 
1948
        fcinfo.arg[2] = Int32GetDatum(typmod);
 
1949
        fcinfo.argnull[0] = (buf == NULL);
 
1950
        fcinfo.argnull[1] = false;
 
1951
        fcinfo.argnull[2] = false;
 
1952
 
 
1953
        result = FunctionCallInvoke(&fcinfo);
 
1954
 
 
1955
        /* Should get null result if and only if buf is NULL */
 
1956
        if (buf == NULL)
 
1957
        {
 
1958
                if (!fcinfo.isnull)
 
1959
                        elog(ERROR, "receive function %u returned non-NULL",
 
1960
                                 fcinfo.flinfo->fn_oid);
 
1961
        }
 
1962
        else
 
1963
        {
 
1964
                if (fcinfo.isnull)
 
1965
                        elog(ERROR, "receive function %u returned NULL",
 
1966
                                 fcinfo.flinfo->fn_oid);
 
1967
        }
 
1968
 
 
1969
        SPI_pop_conditional(pushed);
 
1970
 
 
1971
        return result;
 
1972
}
 
1973
 
 
1974
/*
 
1975
 * Call a previously-looked-up datatype binary-output function.
 
1976
 *
 
1977
 * Do not call this on NULL datums.
 
1978
 *
 
1979
 * This is little more than window dressing for FunctionCall1, but it does
 
1980
 * guarantee a non-toasted result, which strictly speaking the underlying
 
1981
 * function doesn't.  Also, this includes SPI context pushing for the same
 
1982
 * reasons as InputFunctionCall.
 
1983
 */
 
1984
bytea *
 
1985
SendFunctionCall(FmgrInfo *flinfo, Datum val)
 
1986
{
 
1987
        bytea      *result;
 
1988
        bool            pushed;
 
1989
 
 
1990
        pushed = SPI_push_conditional();
 
1991
 
 
1992
        result = DatumGetByteaP(FunctionCall1(flinfo, val));
 
1993
 
 
1994
        SPI_pop_conditional(pushed);
 
1995
 
 
1996
        return result;
 
1997
}
 
1998
 
 
1999
/*
 
2000
 * As above, for I/O functions identified by OID.  These are only to be used
 
2001
 * in seldom-executed code paths.  They are not only slow but leak memory.
 
2002
 */
 
2003
Datum
 
2004
OidInputFunctionCall(Oid functionId, char *str, Oid typioparam, int32 typmod)
 
2005
{
 
2006
        FmgrInfo        flinfo;
 
2007
 
 
2008
        fmgr_info(functionId, &flinfo);
 
2009
        return InputFunctionCall(&flinfo, str, typioparam, typmod);
 
2010
}
 
2011
 
 
2012
char *
 
2013
OidOutputFunctionCall(Oid functionId, Datum val)
 
2014
{
 
2015
        FmgrInfo        flinfo;
 
2016
 
 
2017
        fmgr_info(functionId, &flinfo);
 
2018
        return OutputFunctionCall(&flinfo, val);
 
2019
}
 
2020
 
 
2021
Datum
 
2022
OidReceiveFunctionCall(Oid functionId, StringInfo buf,
 
2023
                                           Oid typioparam, int32 typmod)
 
2024
{
 
2025
        FmgrInfo        flinfo;
 
2026
 
 
2027
        fmgr_info(functionId, &flinfo);
 
2028
        return ReceiveFunctionCall(&flinfo, buf, typioparam, typmod);
 
2029
}
 
2030
 
 
2031
bytea *
 
2032
OidSendFunctionCall(Oid functionId, Datum val)
 
2033
{
 
2034
        FmgrInfo        flinfo;
 
2035
 
 
2036
        fmgr_info(functionId, &flinfo);
 
2037
        return SendFunctionCall(&flinfo, val);
 
2038
}
 
2039
 
 
2040
 
 
2041
/*
 
2042
 * !!! OLD INTERFACE !!!
 
2043
 *
 
2044
 * fmgr() is the only remaining vestige of the old-style caller support
 
2045
 * functions.  It's no longer used anywhere in the Postgres distribution,
 
2046
 * but we should leave it around for a release or two to ease the transition
 
2047
 * for user-supplied C functions.  OidFunctionCallN() replaces it for new
 
2048
 * code.
 
2049
 *
 
2050
 * DEPRECATED, DO NOT USE IN NEW CODE
 
2051
 */
 
2052
char *
 
2053
fmgr(Oid procedureId,...)
 
2054
{
 
2055
        FmgrInfo        flinfo;
 
2056
        FunctionCallInfoData fcinfo;
 
2057
        int                     n_arguments;
 
2058
        Datum           result;
 
2059
 
 
2060
        fmgr_info(procedureId, &flinfo);
 
2061
 
 
2062
        MemSet(&fcinfo, 0, sizeof(fcinfo));
 
2063
        fcinfo.flinfo = &flinfo;
 
2064
        fcinfo.nargs = flinfo.fn_nargs;
 
2065
        n_arguments = fcinfo.nargs;
 
2066
 
 
2067
        if (n_arguments > 0)
 
2068
        {
 
2069
                va_list         pvar;
 
2070
                int                     i;
 
2071
 
 
2072
                if (n_arguments > FUNC_MAX_ARGS)
 
2073
                        ereport(ERROR,
 
2074
                                        (errcode(ERRCODE_TOO_MANY_ARGUMENTS),
 
2075
                         errmsg("function %u has too many arguments (%d, maximum is %d)",
 
2076
                                        flinfo.fn_oid, n_arguments, FUNC_MAX_ARGS)));
 
2077
                va_start(pvar, procedureId);
 
2078
                for (i = 0; i < n_arguments; i++)
 
2079
                        fcinfo.arg[i] = PointerGetDatum(va_arg(pvar, char *));
 
2080
                va_end(pvar);
 
2081
        }
 
2082
 
 
2083
        result = FunctionCallInvoke(&fcinfo);
 
2084
 
 
2085
        /* Check for null result, since caller is clearly not expecting one */
 
2086
        if (fcinfo.isnull)
 
2087
                elog(ERROR, "function %u returned NULL", flinfo.fn_oid);
 
2088
 
 
2089
        return DatumGetPointer(result);
 
2090
}
 
2091
 
 
2092
 
 
2093
/*-------------------------------------------------------------------------
 
2094
 *              Support routines for standard maybe-pass-by-reference datatypes
 
2095
 *
 
2096
 * int8, float4, and float8 can be passed by value if Datum is wide enough.
 
2097
 * (For backwards-compatibility reasons, we allow pass-by-ref to be chosen
 
2098
 * at compile time even if pass-by-val is possible.)  For the float types,
 
2099
 * we need a support routine even if we are passing by value, because many
 
2100
 * machines pass int and float function parameters/results differently;
 
2101
 * so we need to play weird games with unions.
 
2102
 *
 
2103
 * Note: there is only one switch controlling the pass-by-value option for
 
2104
 * both int8 and float8; this is to avoid making things unduly complicated
 
2105
 * for the timestamp types, which might have either representation.
 
2106
 *-------------------------------------------------------------------------
 
2107
 */
 
2108
 
 
2109
#ifndef USE_FLOAT8_BYVAL                /* controls int8 too */
 
2110
 
 
2111
Datum
 
2112
Int64GetDatum(int64 X)
 
2113
{
 
2114
#ifndef INT64_IS_BUSTED
 
2115
        int64      *retval = (int64 *) palloc(sizeof(int64));
 
2116
 
 
2117
        *retval = X;
 
2118
        return PointerGetDatum(retval);
 
2119
#else                                                   /* INT64_IS_BUSTED */
 
2120
 
 
2121
        /*
 
2122
         * On a machine with no 64-bit-int C datatype, sizeof(int64) will not be
 
2123
         * 8, but we want Int64GetDatum to return an 8-byte object anyway, with
 
2124
         * zeroes in the unused bits.  This is needed so that, for example, hash
 
2125
         * join of int8 will behave properly.
 
2126
         */
 
2127
        int64      *retval = (int64 *) palloc0(Max(sizeof(int64), 8));
 
2128
 
 
2129
        *retval = X;
 
2130
        return PointerGetDatum(retval);
 
2131
#endif   /* INT64_IS_BUSTED */
 
2132
}
 
2133
 
 
2134
#endif /* USE_FLOAT8_BYVAL */
 
2135
 
 
2136
Datum
 
2137
Float4GetDatum(float4 X)
 
2138
{
 
2139
#ifdef USE_FLOAT4_BYVAL
 
2140
        union {
 
2141
                float4  value;
 
2142
                int32   retval;
 
2143
        } myunion;
 
2144
 
 
2145
        myunion.value = X;
 
2146
        return SET_4_BYTES(myunion.retval);
 
2147
#else
 
2148
        float4     *retval = (float4 *) palloc(sizeof(float4));
 
2149
 
 
2150
        *retval = X;
 
2151
        return PointerGetDatum(retval);
 
2152
#endif
 
2153
}
 
2154
 
 
2155
#ifdef USE_FLOAT4_BYVAL
 
2156
 
 
2157
float4
 
2158
DatumGetFloat4(Datum X)
 
2159
{
 
2160
        union {
 
2161
                int32   value;
 
2162
                float4  retval;
 
2163
        } myunion;
 
2164
 
 
2165
        myunion.value = GET_4_BYTES(X);
 
2166
        return myunion.retval;
 
2167
}
 
2168
 
 
2169
#endif /* USE_FLOAT4_BYVAL */
 
2170
 
 
2171
Datum
 
2172
Float8GetDatum(float8 X)
 
2173
{
 
2174
#ifdef USE_FLOAT8_BYVAL
 
2175
        union {
 
2176
                float8  value;
 
2177
                int64   retval;
 
2178
        } myunion;
 
2179
 
 
2180
        myunion.value = X;
 
2181
        return SET_8_BYTES(myunion.retval);
 
2182
#else
 
2183
        float8     *retval = (float8 *) palloc(sizeof(float8));
 
2184
 
 
2185
        *retval = X;
 
2186
        return PointerGetDatum(retval);
 
2187
#endif
 
2188
}
 
2189
 
 
2190
#ifdef USE_FLOAT8_BYVAL
 
2191
 
 
2192
float8
 
2193
DatumGetFloat8(Datum X)
 
2194
{
 
2195
        union {
 
2196
                int64   value;
 
2197
                float8  retval;
 
2198
        } myunion;
 
2199
 
 
2200
        myunion.value = GET_8_BYTES(X);
 
2201
        return myunion.retval;
 
2202
}
 
2203
 
 
2204
#endif /* USE_FLOAT8_BYVAL */
 
2205
 
 
2206
 
 
2207
/*-------------------------------------------------------------------------
 
2208
 *              Support routines for toastable datatypes
 
2209
 *-------------------------------------------------------------------------
 
2210
 */
 
2211
 
 
2212
struct varlena *
 
2213
pg_detoast_datum(struct varlena * datum)
 
2214
{
 
2215
        if (VARATT_IS_EXTENDED(datum))
 
2216
                return heap_tuple_untoast_attr(datum);
 
2217
        else
 
2218
                return datum;
 
2219
}
 
2220
 
 
2221
struct varlena *
 
2222
pg_detoast_datum_copy(struct varlena * datum)
 
2223
{
 
2224
        if (VARATT_IS_EXTENDED(datum))
 
2225
                return heap_tuple_untoast_attr(datum);
 
2226
        else
 
2227
        {
 
2228
                /* Make a modifiable copy of the varlena object */
 
2229
                Size            len = VARSIZE(datum);
 
2230
                struct varlena *result = (struct varlena *) palloc(len);
 
2231
 
 
2232
                memcpy(result, datum, len);
 
2233
                return result;
 
2234
        }
 
2235
}
 
2236
 
 
2237
struct varlena *
 
2238
pg_detoast_datum_slice(struct varlena * datum, int32 first, int32 count)
 
2239
{
 
2240
        /* Only get the specified portion from the toast rel */
 
2241
        return heap_tuple_untoast_attr_slice(datum, first, count);
 
2242
}
 
2243
 
 
2244
struct varlena *
 
2245
pg_detoast_datum_packed(struct varlena * datum)
 
2246
{
 
2247
        if (VARATT_IS_COMPRESSED(datum) || VARATT_IS_EXTERNAL(datum))
 
2248
                return heap_tuple_untoast_attr(datum);
 
2249
        else
 
2250
                return datum;
 
2251
}
 
2252
 
 
2253
/*-------------------------------------------------------------------------
 
2254
 *              Support routines for extracting info from fn_expr parse tree
 
2255
 *
 
2256
 * These are needed by polymorphic functions, which accept multiple possible
 
2257
 * input types and need help from the parser to know what they've got.
 
2258
 * Also, some functions might be interested in whether a parameter is constant.
 
2259
 *-------------------------------------------------------------------------
 
2260
 */
 
2261
 
 
2262
/*
 
2263
 * Get the actual type OID of the function return type
 
2264
 *
 
2265
 * Returns InvalidOid if information is not available
 
2266
 */
 
2267
Oid
 
2268
get_fn_expr_rettype(FmgrInfo *flinfo)
 
2269
{
 
2270
        Node       *expr;
 
2271
 
 
2272
        /*
 
2273
         * can't return anything useful if we have no FmgrInfo or if its fn_expr
 
2274
         * node has not been initialized
 
2275
         */
 
2276
        if (!flinfo || !flinfo->fn_expr)
 
2277
                return InvalidOid;
 
2278
 
 
2279
        expr = flinfo->fn_expr;
 
2280
 
 
2281
        return exprType(expr);
 
2282
}
 
2283
 
 
2284
/*
 
2285
 * Get the actual type OID of a specific function argument (counting from 0)
 
2286
 *
 
2287
 * Returns InvalidOid if information is not available
 
2288
 */
 
2289
Oid
 
2290
get_fn_expr_argtype(FmgrInfo *flinfo, int argnum)
 
2291
{
 
2292
        /*
 
2293
         * can't return anything useful if we have no FmgrInfo or if its fn_expr
 
2294
         * node has not been initialized
 
2295
         */
 
2296
        if (!flinfo || !flinfo->fn_expr)
 
2297
                return InvalidOid;
 
2298
 
 
2299
        return get_call_expr_argtype(flinfo->fn_expr, argnum);
 
2300
}
 
2301
 
 
2302
/*
 
2303
 * Get the actual type OID of a specific function argument (counting from 0),
 
2304
 * but working from the calling expression tree instead of FmgrInfo
 
2305
 *
 
2306
 * Returns InvalidOid if information is not available
 
2307
 */
 
2308
Oid
 
2309
get_call_expr_argtype(Node *expr, int argnum)
 
2310
{
 
2311
        List       *args;
 
2312
        Oid                     argtype;
 
2313
 
 
2314
        if (expr == NULL)
 
2315
                return InvalidOid;
 
2316
 
 
2317
        if (IsA(expr, FuncExpr))
 
2318
                args = ((FuncExpr *) expr)->args;
 
2319
        else if (IsA(expr, OpExpr))
 
2320
                args = ((OpExpr *) expr)->args;
 
2321
        else if (IsA(expr, DistinctExpr))
 
2322
                args = ((DistinctExpr *) expr)->args;
 
2323
        else if (IsA(expr, ScalarArrayOpExpr))
 
2324
                args = ((ScalarArrayOpExpr *) expr)->args;
 
2325
        else if (IsA(expr, ArrayCoerceExpr))
 
2326
                args = list_make1(((ArrayCoerceExpr *) expr)->arg);
 
2327
        else if (IsA(expr, NullIfExpr))
 
2328
                args = ((NullIfExpr *) expr)->args;
 
2329
        else if (IsA(expr, WindowFunc))
 
2330
                args = ((WindowFunc *) expr)->args;
 
2331
        else
 
2332
                return InvalidOid;
 
2333
 
 
2334
        if (argnum < 0 || argnum >= list_length(args))
 
2335
                return InvalidOid;
 
2336
 
 
2337
        argtype = exprType((Node *) list_nth(args, argnum));
 
2338
 
 
2339
        /*
 
2340
         * special hack for ScalarArrayOpExpr and ArrayCoerceExpr: what the
 
2341
         * underlying function will actually get passed is the element type of the
 
2342
         * array.
 
2343
         */
 
2344
        if (IsA(expr, ScalarArrayOpExpr) &&
 
2345
                argnum == 1)
 
2346
                argtype = get_element_type(argtype);
 
2347
        else if (IsA(expr, ArrayCoerceExpr) &&
 
2348
                         argnum == 0)
 
2349
                argtype = get_element_type(argtype);
 
2350
 
 
2351
        return argtype;
 
2352
}
 
2353
 
 
2354
/*
 
2355
 * Find out whether a specific function argument is constant for the
 
2356
 * duration of a query
 
2357
 *
 
2358
 * Returns false if information is not available
 
2359
 */
 
2360
bool
 
2361
get_fn_expr_arg_stable(FmgrInfo *flinfo, int argnum)
 
2362
{
 
2363
        /*
 
2364
         * can't return anything useful if we have no FmgrInfo or if its fn_expr
 
2365
         * node has not been initialized
 
2366
         */
 
2367
        if (!flinfo || !flinfo->fn_expr)
 
2368
                return false;
 
2369
 
 
2370
        return get_call_expr_arg_stable(flinfo->fn_expr, argnum);
 
2371
}
 
2372
 
 
2373
/*
 
2374
 * Find out whether a specific function argument is constant for the
 
2375
 * duration of a query, but working from the calling expression tree
 
2376
 *
 
2377
 * Returns false if information is not available
 
2378
 */
 
2379
bool
 
2380
get_call_expr_arg_stable(Node *expr, int argnum)
 
2381
{
 
2382
        List       *args;
 
2383
        Node       *arg;
 
2384
 
 
2385
        if (expr == NULL)
 
2386
                return false;
 
2387
 
 
2388
        if (IsA(expr, FuncExpr))
 
2389
                args = ((FuncExpr *) expr)->args;
 
2390
        else if (IsA(expr, OpExpr))
 
2391
                args = ((OpExpr *) expr)->args;
 
2392
        else if (IsA(expr, DistinctExpr))
 
2393
                args = ((DistinctExpr *) expr)->args;
 
2394
        else if (IsA(expr, ScalarArrayOpExpr))
 
2395
                args = ((ScalarArrayOpExpr *) expr)->args;
 
2396
        else if (IsA(expr, ArrayCoerceExpr))
 
2397
                args = list_make1(((ArrayCoerceExpr *) expr)->arg);
 
2398
        else if (IsA(expr, NullIfExpr))
 
2399
                args = ((NullIfExpr *) expr)->args;
 
2400
        else if (IsA(expr, WindowFunc))
 
2401
                args = ((WindowFunc *) expr)->args;
 
2402
        else
 
2403
                return false;
 
2404
 
 
2405
        if (argnum < 0 || argnum >= list_length(args))
 
2406
                return false;
 
2407
 
 
2408
        arg = (Node *) list_nth(args, argnum);
 
2409
 
 
2410
        /*
 
2411
         * Either a true Const or an external Param will have a value that
 
2412
         * doesn't change during the execution of the query.  In future we
 
2413
         * might want to consider other cases too, e.g. now().
 
2414
         */
 
2415
        if (IsA(arg, Const))
 
2416
                return true;
 
2417
        if (IsA(arg, Param) &&
 
2418
                ((Param *) arg)->paramkind == PARAM_EXTERN)
 
2419
                return true;
 
2420
 
 
2421
        return false;
 
2422
}