PostgreSQL Source Code git master
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
pl_handler.c
Go to the documentation of this file.
1/*-------------------------------------------------------------------------
2 *
3 * pl_handler.c - Handler for the PL/pgSQL
4 * procedural language
5 *
6 * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group
7 * Portions Copyright (c) 1994, Regents of the University of California
8 *
9 *
10 * IDENTIFICATION
11 * src/pl/plpgsql/src/pl_handler.c
12 *
13 *-------------------------------------------------------------------------
14 */
15
16#include "postgres.h"
17
18#include "access/htup_details.h"
19#include "catalog/pg_proc.h"
20#include "catalog/pg_type.h"
21#include "funcapi.h"
22#include "miscadmin.h"
23#include "plpgsql.h"
24#include "utils/builtins.h"
25#include "utils/guc.h"
26#include "utils/lsyscache.h"
27#include "utils/syscache.h"
28#include "utils/varlena.h"
29
30static bool plpgsql_extra_checks_check_hook(char **newvalue, void **extra, GucSource source);
31static void plpgsql_extra_warnings_assign_hook(const char *newvalue, void *extra);
32static void plpgsql_extra_errors_assign_hook(const char *newvalue, void *extra);
33
35 .name = "plpgsql",
36 .version = PG_VERSION
37);
38
39/* Custom GUC variable */
41 {"error", PLPGSQL_RESOLVE_ERROR, false},
42 {"use_variable", PLPGSQL_RESOLVE_VARIABLE, false},
43 {"use_column", PLPGSQL_RESOLVE_COLUMN, false},
44 {NULL, 0, false}
45};
46
48
50
52
54static char *plpgsql_extra_errors_string = NULL;
57
58/* Hook for plugins */
60
61
62static bool
63plpgsql_extra_checks_check_hook(char **newvalue, void **extra, GucSource source)
64{
65 char *rawstring;
66 List *elemlist;
67 ListCell *l;
68 int extrachecks = 0;
69 int *myextra;
70
71 if (pg_strcasecmp(*newvalue, "all") == 0)
72 extrachecks = PLPGSQL_XCHECK_ALL;
73 else if (pg_strcasecmp(*newvalue, "none") == 0)
74 extrachecks = PLPGSQL_XCHECK_NONE;
75 else
76 {
77 /* Need a modifiable copy of string */
78 rawstring = pstrdup(*newvalue);
79
80 /* Parse string into list of identifiers */
81 if (!SplitIdentifierString(rawstring, ',', &elemlist))
82 {
83 /* syntax error in list */
84 GUC_check_errdetail("List syntax is invalid.");
85 pfree(rawstring);
86 list_free(elemlist);
87 return false;
88 }
89
90 foreach(l, elemlist)
91 {
92 char *tok = (char *) lfirst(l);
93
94 if (pg_strcasecmp(tok, "shadowed_variables") == 0)
95 extrachecks |= PLPGSQL_XCHECK_SHADOWVAR;
96 else if (pg_strcasecmp(tok, "too_many_rows") == 0)
97 extrachecks |= PLPGSQL_XCHECK_TOOMANYROWS;
98 else if (pg_strcasecmp(tok, "strict_multi_assignment") == 0)
100 else if (pg_strcasecmp(tok, "all") == 0 || pg_strcasecmp(tok, "none") == 0)
101 {
102 GUC_check_errdetail("Key word \"%s\" cannot be combined with other key words.", tok);
103 pfree(rawstring);
104 list_free(elemlist);
105 return false;
106 }
107 else
108 {
109 GUC_check_errdetail("Unrecognized key word: \"%s\".", tok);
110 pfree(rawstring);
111 list_free(elemlist);
112 return false;
113 }
114 }
115
116 pfree(rawstring);
117 list_free(elemlist);
118 }
119
120 myextra = (int *) guc_malloc(LOG, sizeof(int));
121 if (!myextra)
122 return false;
123 *myextra = extrachecks;
124 *extra = myextra;
125
126 return true;
127}
128
129static void
130plpgsql_extra_warnings_assign_hook(const char *newvalue, void *extra)
131{
132 plpgsql_extra_warnings = *((int *) extra);
133}
134
135static void
136plpgsql_extra_errors_assign_hook(const char *newvalue, void *extra)
137{
138 plpgsql_extra_errors = *((int *) extra);
139}
140
141
142/*
143 * _PG_init() - library load-time initialization
144 *
145 * DO NOT make this static nor change its name!
146 */
147void
149{
150 /* Be sure we do initialization only once (should be redundant now) */
151 static bool inited = false;
152
153 if (inited)
154 return;
155
157
158 DefineCustomEnumVariable("plpgsql.variable_conflict",
159 gettext_noop("Sets handling of conflicts between PL/pgSQL variable names and table column names."),
160 NULL,
164 PGC_SUSET, 0,
165 NULL, NULL, NULL);
166
167 DefineCustomBoolVariable("plpgsql.print_strict_params",
168 gettext_noop("Print information about parameters in the DETAIL part of the error messages generated on INTO ... STRICT failures."),
169 NULL,
171 false,
172 PGC_USERSET, 0,
173 NULL, NULL, NULL);
174
175 DefineCustomBoolVariable("plpgsql.check_asserts",
176 gettext_noop("Perform checks given in ASSERT statements."),
177 NULL,
179 true,
180 PGC_USERSET, 0,
181 NULL, NULL, NULL);
182
183 DefineCustomStringVariable("plpgsql.extra_warnings",
184 gettext_noop("List of programming constructs that should produce a warning."),
185 NULL,
187 "none",
191 NULL);
192
193 DefineCustomStringVariable("plpgsql.extra_errors",
194 gettext_noop("List of programming constructs that should produce an error."),
195 NULL,
197 "none",
201 NULL);
202
203 MarkGUCPrefixReserved("plpgsql");
204
207
208 /* Set up a rendezvous point with optional instrumentation plugin */
210
211 inited = true;
212}
213
214/* ----------
215 * plpgsql_call_handler
216 *
217 * The PostgreSQL function manager and trigger manager
218 * call this function for execution of PL/pgSQL procedures.
219 * ----------
220 */
222
223Datum
225{
226 bool nonatomic;
227 PLpgSQL_function *func;
228 PLpgSQL_execstate *save_cur_estate;
229 ResourceOwner procedure_resowner;
230 volatile Datum retval = (Datum) 0;
231 int rc;
232
233 nonatomic = fcinfo->context &&
234 IsA(fcinfo->context, CallContext) &&
235 !castNode(CallContext, fcinfo->context)->atomic;
236
237 /*
238 * Connect to SPI manager
239 */
240 SPI_connect_ext(nonatomic ? SPI_OPT_NONATOMIC : 0);
241
242 /* Find or compile the function */
243 func = plpgsql_compile(fcinfo, false);
244
245 /* Must save and restore prior value of cur_estate */
246 save_cur_estate = func->cur_estate;
247
248 /* Mark the function as busy, so it can't be deleted from under us */
249 func->cfunc.use_count++;
250
251 /*
252 * If we'll need a procedure-lifespan resowner to execute any CALL or DO
253 * statements, create it now. Since this resowner is not tied to any
254 * parent, failing to free it would result in process-lifespan leaks.
255 * Therefore, be very wary of adding any code between here and the PG_TRY
256 * block.
257 */
258 procedure_resowner =
259 (nonatomic && func->requires_procedure_resowner) ?
260 ResourceOwnerCreate(NULL, "PL/pgSQL procedure resources") : NULL;
261
262 PG_TRY();
263 {
264 /*
265 * Determine if called as function or trigger and call appropriate
266 * subhandler
267 */
268 if (CALLED_AS_TRIGGER(fcinfo))
270 (TriggerData *) fcinfo->context));
271 else if (CALLED_AS_EVENT_TRIGGER(fcinfo))
272 {
274 (EventTriggerData *) fcinfo->context);
275 /* there's no return value in this case */
276 }
277 else
278 retval = plpgsql_exec_function(func, fcinfo,
279 NULL, NULL,
280 procedure_resowner,
281 !nonatomic);
282 }
283 PG_FINALLY();
284 {
285 /* Decrement use-count, restore cur_estate */
286 func->cfunc.use_count--;
287 func->cur_estate = save_cur_estate;
288
289 /* Be sure to release the procedure resowner if any */
290 if (procedure_resowner)
291 {
292 ReleaseAllPlanCacheRefsInOwner(procedure_resowner);
293 ResourceOwnerDelete(procedure_resowner);
294 }
295 }
296 PG_END_TRY();
297
298 /*
299 * Disconnect from SPI manager
300 */
301 if ((rc = SPI_finish()) != SPI_OK_FINISH)
302 elog(ERROR, "SPI_finish failed: %s", SPI_result_code_string(rc));
303
304 return retval;
305}
306
307/* ----------
308 * plpgsql_inline_handler
309 *
310 * Called by PostgreSQL to execute an anonymous code block
311 * ----------
312 */
314
315Datum
317{
318 LOCAL_FCINFO(fake_fcinfo, 0);
320 PLpgSQL_function *func;
321 FmgrInfo flinfo;
322 EState *simple_eval_estate;
323 ResourceOwner simple_eval_resowner;
324 Datum retval;
325 int rc;
326
327 /*
328 * Connect to SPI manager
329 */
330 SPI_connect_ext(codeblock->atomic ? 0 : SPI_OPT_NONATOMIC);
331
332 /* Compile the anonymous code block */
333 func = plpgsql_compile_inline(codeblock->source_text);
334
335 /* Mark the function as busy, just pro forma */
336 func->cfunc.use_count++;
337
338 /*
339 * Set up a fake fcinfo with just enough info to satisfy
340 * plpgsql_exec_function(). In particular note that this sets things up
341 * with no arguments passed.
342 */
343 MemSet(fake_fcinfo, 0, SizeForFunctionCallInfo(0));
344 MemSet(&flinfo, 0, sizeof(flinfo));
345 fake_fcinfo->flinfo = &flinfo;
346 flinfo.fn_oid = InvalidOid;
348
349 /*
350 * Create a private EState and resowner for simple-expression execution.
351 * Notice that these are NOT tied to transaction-level resources; they
352 * must survive any COMMIT/ROLLBACK the DO block executes, since we will
353 * unconditionally try to clean them up below. (Hence, be wary of adding
354 * anything that could fail between here and the PG_TRY block.) See the
355 * comments for shared_simple_eval_estate.
356 *
357 * Because this resowner isn't tied to the calling transaction, we can
358 * also use it as the "procedure" resowner for any CALL statements. That
359 * helps reduce the opportunities for failure here.
360 */
361 simple_eval_estate = CreateExecutorState();
362 simple_eval_resowner =
363 ResourceOwnerCreate(NULL, "PL/pgSQL DO block simple expressions");
364
365 /* And run the function */
366 PG_TRY();
367 {
368 retval = plpgsql_exec_function(func, fake_fcinfo,
369 simple_eval_estate,
370 simple_eval_resowner,
371 simple_eval_resowner, /* see above */
372 codeblock->atomic);
373 }
374 PG_CATCH();
375 {
376 /*
377 * We need to clean up what would otherwise be long-lived resources
378 * accumulated by the failed DO block, principally cached plans for
379 * statements (which can be flushed by plpgsql_free_function_memory),
380 * execution trees for simple expressions, which are in the private
381 * EState, and cached-plan refcounts held by the private resowner.
382 *
383 * Before releasing the private EState, we must clean up any
384 * simple_econtext_stack entries pointing into it, which we can do by
385 * invoking the subxact callback. (It will be called again later if
386 * some outer control level does a subtransaction abort, but no harm
387 * is done.) We cheat a bit knowing that plpgsql_subxact_cb does not
388 * pay attention to its parentSubid argument.
389 */
392 0, NULL);
393
394 /* Clean up the private EState and resowner */
395 FreeExecutorState(simple_eval_estate);
396 ReleaseAllPlanCacheRefsInOwner(simple_eval_resowner);
397 ResourceOwnerDelete(simple_eval_resowner);
398
399 /* Function should now have no remaining use-counts ... */
400 func->cfunc.use_count--;
401 Assert(func->cfunc.use_count == 0);
402
403 /* ... so we can free subsidiary storage */
405
406 /* And propagate the error */
407 PG_RE_THROW();
408 }
409 PG_END_TRY();
410
411 /* Clean up the private EState and resowner */
412 FreeExecutorState(simple_eval_estate);
413 ReleaseAllPlanCacheRefsInOwner(simple_eval_resowner);
414 ResourceOwnerDelete(simple_eval_resowner);
415
416 /* Function should now have no remaining use-counts ... */
417 func->cfunc.use_count--;
418 Assert(func->cfunc.use_count == 0);
419
420 /* ... so we can free subsidiary storage */
422
423 /*
424 * Disconnect from SPI manager
425 */
426 if ((rc = SPI_finish()) != SPI_OK_FINISH)
427 elog(ERROR, "SPI_finish failed: %s", SPI_result_code_string(rc));
428
429 return retval;
430}
431
432/* ----------
433 * plpgsql_validator
434 *
435 * This function attempts to validate a PL/pgSQL function at
436 * CREATE FUNCTION time.
437 * ----------
438 */
440
441Datum
443{
444 Oid funcoid = PG_GETARG_OID(0);
445 HeapTuple tuple;
446 Form_pg_proc proc;
447 char functyptype;
448 int numargs;
449 Oid *argtypes;
450 char **argnames;
451 char *argmodes;
452 bool is_dml_trigger = false;
453 bool is_event_trigger = false;
454 int i;
455
456 if (!CheckFunctionValidatorAccess(fcinfo->flinfo->fn_oid, funcoid))
458
459 /* Get the new function's pg_proc entry */
460 tuple = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcoid));
461 if (!HeapTupleIsValid(tuple))
462 elog(ERROR, "cache lookup failed for function %u", funcoid);
463 proc = (Form_pg_proc) GETSTRUCT(tuple);
464
465 functyptype = get_typtype(proc->prorettype);
466
467 /* Disallow pseudotype result */
468 /* except for TRIGGER, EVTTRIGGER, RECORD, VOID, or polymorphic */
469 if (functyptype == TYPTYPE_PSEUDO)
470 {
471 if (proc->prorettype == TRIGGEROID)
472 is_dml_trigger = true;
473 else if (proc->prorettype == EVENT_TRIGGEROID)
474 is_event_trigger = true;
475 else if (proc->prorettype != RECORDOID &&
476 proc->prorettype != VOIDOID &&
477 !IsPolymorphicType(proc->prorettype))
479 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
480 errmsg("PL/pgSQL functions cannot return type %s",
481 format_type_be(proc->prorettype))));
482 }
483
484 /* Disallow pseudotypes in arguments (either IN or OUT) */
485 /* except for RECORD and polymorphic */
486 numargs = get_func_arg_info(tuple,
487 &argtypes, &argnames, &argmodes);
488 for (i = 0; i < numargs; i++)
489 {
490 if (get_typtype(argtypes[i]) == TYPTYPE_PSEUDO)
491 {
492 if (argtypes[i] != RECORDOID &&
493 !IsPolymorphicType(argtypes[i]))
495 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
496 errmsg("PL/pgSQL functions cannot accept type %s",
497 format_type_be(argtypes[i]))));
498 }
499 }
500
501 /* Postpone body checks if !check_function_bodies */
503 {
504 LOCAL_FCINFO(fake_fcinfo, 0);
505 FmgrInfo flinfo;
506 int rc;
507 TriggerData trigdata;
508 EventTriggerData etrigdata;
509
510 /*
511 * Connect to SPI manager (is this needed for compilation?)
512 */
513 SPI_connect();
514
515 /*
516 * Set up a fake fcinfo with just enough info to satisfy
517 * plpgsql_compile().
518 */
519 MemSet(fake_fcinfo, 0, SizeForFunctionCallInfo(0));
520 MemSet(&flinfo, 0, sizeof(flinfo));
521 fake_fcinfo->flinfo = &flinfo;
522 flinfo.fn_oid = funcoid;
524 if (is_dml_trigger)
525 {
526 MemSet(&trigdata, 0, sizeof(trigdata));
527 trigdata.type = T_TriggerData;
528 fake_fcinfo->context = (Node *) &trigdata;
529 }
530 else if (is_event_trigger)
531 {
532 MemSet(&etrigdata, 0, sizeof(etrigdata));
533 etrigdata.type = T_EventTriggerData;
534 fake_fcinfo->context = (Node *) &etrigdata;
535 }
536
537 /* Test-compile the function */
538 plpgsql_compile(fake_fcinfo, true);
539
540 /*
541 * Disconnect from SPI manager
542 */
543 if ((rc = SPI_finish()) != SPI_OK_FINISH)
544 elog(ERROR, "SPI_finish failed: %s", SPI_result_code_string(rc));
545 }
546
547 ReleaseSysCache(tuple);
548
550}
#define gettext_noop(x)
Definition: c.h:1167
#define MemSet(start, val, len)
Definition: c.h:991
void ** find_rendezvous_variable(const char *varName)
Definition: dfmgr.c:657
int errcode(int sqlerrcode)
Definition: elog.c:854
int errmsg(const char *fmt,...)
Definition: elog.c:1071
#define LOG
Definition: elog.h:31
#define PG_RE_THROW()
Definition: elog.h:404
#define PG_TRY(...)
Definition: elog.h:371
#define PG_END_TRY(...)
Definition: elog.h:396
#define ERROR
Definition: elog.h:39
#define PG_CATCH(...)
Definition: elog.h:381
#define TEXTDOMAIN
Definition: elog.h:152
#define elog(elevel,...)
Definition: elog.h:225
#define PG_FINALLY(...)
Definition: elog.h:388
#define ereport(elevel,...)
Definition: elog.h:149
#define CALLED_AS_EVENT_TRIGGER(fcinfo)
Definition: event_trigger.h:49
void FreeExecutorState(EState *estate)
Definition: execUtils.c:193
EState * CreateExecutorState(void)
Definition: execUtils.c:88
bool CheckFunctionValidatorAccess(Oid validatorOid, Oid functionOid)
Definition: fmgr.c:2145
#define PG_RETURN_VOID()
Definition: fmgr.h:349
#define PG_GETARG_OID(n)
Definition: fmgr.h:275
#define SizeForFunctionCallInfo(nargs)
Definition: fmgr.h:102
#define PG_GETARG_DATUM(n)
Definition: fmgr.h:268
#define LOCAL_FCINFO(name, nargs)
Definition: fmgr.h:110
#define PG_FUNCTION_ARGS
Definition: fmgr.h:193
char * format_type_be(Oid type_oid)
Definition: format_type.c:343
int get_func_arg_info(HeapTuple procTup, Oid **p_argtypes, char ***p_argnames, char **p_argmodes)
Definition: funcapi.c:1379
void DefineCustomEnumVariable(const char *name, const char *short_desc, const char *long_desc, int *valueAddr, int bootValue, const struct config_enum_entry *options, GucContext context, int flags, GucEnumCheckHook check_hook, GucEnumAssignHook assign_hook, GucShowHook show_hook)
Definition: guc.c:5244
void DefineCustomStringVariable(const char *name, const char *short_desc, const char *long_desc, char **valueAddr, const char *bootValue, GucContext context, int flags, GucStringCheckHook check_hook, GucStringAssignHook assign_hook, GucShowHook show_hook)
Definition: guc.c:5219
void * guc_malloc(int elevel, size_t size)
Definition: guc.c:638
void DefineCustomBoolVariable(const char *name, const char *short_desc, const char *long_desc, bool *valueAddr, bool bootValue, GucContext context, int flags, GucBoolCheckHook check_hook, GucBoolAssignHook assign_hook, GucShowHook show_hook)
Definition: guc.c:5133
void MarkGUCPrefixReserved(const char *className)
Definition: guc.c:5280
#define GUC_check_errdetail
Definition: guc.h:481
#define GUC_LIST_INPUT
Definition: guc.h:214
GucSource
Definition: guc.h:112
@ PGC_SUSET
Definition: guc.h:78
@ PGC_USERSET
Definition: guc.h:79
bool check_function_bodies
Definition: guc_tables.c:528
Assert(PointerIsAligned(start, uint64))
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
static void * GETSTRUCT(const HeapTupleData *tuple)
Definition: htup_details.h:728
int i
Definition: isn.c:77
void list_free(List *list)
Definition: list.c:1546
char get_typtype(Oid typid)
Definition: lsyscache.c:2769
char * pstrdup(const char *in)
Definition: mcxt.c:2325
void pfree(void *pointer)
Definition: mcxt.c:2150
MemoryContext CurrentMemoryContext
Definition: mcxt.c:159
void pg_bindtextdomain(const char *domain)
Definition: miscinit.c:1939
#define IsA(nodeptr, _type_)
Definition: nodes.h:164
#define castNode(_type_, nodeptr)
Definition: nodes.h:182
#define lfirst(lc)
Definition: pg_list.h:172
FormData_pg_proc * Form_pg_proc
Definition: pg_proc.h:136
static rewind_source * source
Definition: pg_rewind.c:89
PLpgSQL_function * plpgsql_compile(FunctionCallInfo fcinfo, bool forValidator)
Definition: pl_comp.c:106
PLpgSQL_function * plpgsql_compile_inline(char *proc_source)
Definition: pl_comp.c:729
Datum plpgsql_exec_function(PLpgSQL_function *func, FunctionCallInfo fcinfo, EState *simple_eval_estate, ResourceOwner simple_eval_resowner, ResourceOwner procedure_resowner, bool atomic)
Definition: pl_exec.c:493
HeapTuple plpgsql_exec_trigger(PLpgSQL_function *func, TriggerData *trigdata)
Definition: pl_exec.c:935
void plpgsql_subxact_cb(SubXactEvent event, SubTransactionId mySubid, SubTransactionId parentSubid, void *arg)
Definition: pl_exec.c:8753
void plpgsql_exec_event_trigger(PLpgSQL_function *func, EventTriggerData *trigdata)
Definition: pl_exec.c:1175
void plpgsql_xact_cb(XactEvent event, void *arg)
Definition: pl_exec.c:8711
void plpgsql_free_function_memory(PLpgSQL_function *func)
Definition: pl_funcs.c:716
int plpgsql_variable_conflict
Definition: pl_handler.c:47
static void plpgsql_extra_errors_assign_hook(const char *newvalue, void *extra)
Definition: pl_handler.c:136
bool plpgsql_check_asserts
Definition: pl_handler.c:51
static const struct config_enum_entry variable_conflict_options[]
Definition: pl_handler.c:40
int plpgsql_extra_warnings
Definition: pl_handler.c:55
Datum plpgsql_call_handler(PG_FUNCTION_ARGS)
Definition: pl_handler.c:224
void _PG_init(void)
Definition: pl_handler.c:148
static char * plpgsql_extra_errors_string
Definition: pl_handler.c:54
Datum plpgsql_inline_handler(PG_FUNCTION_ARGS)
Definition: pl_handler.c:316
PG_FUNCTION_INFO_V1(plpgsql_call_handler)
PG_MODULE_MAGIC_EXT(.name="plpgsql",.version=PG_VERSION)
bool plpgsql_print_strict_params
Definition: pl_handler.c:49
PLpgSQL_plugin ** plpgsql_plugin_ptr
Definition: pl_handler.c:59
static void plpgsql_extra_warnings_assign_hook(const char *newvalue, void *extra)
Definition: pl_handler.c:130
int plpgsql_extra_errors
Definition: pl_handler.c:56
static bool plpgsql_extra_checks_check_hook(char **newvalue, void **extra, GucSource source)
Definition: pl_handler.c:63
static char * plpgsql_extra_warnings_string
Definition: pl_handler.c:53
Datum plpgsql_validator(PG_FUNCTION_ARGS)
Definition: pl_handler.c:442
void ReleaseAllPlanCacheRefsInOwner(ResourceOwner owner)
Definition: plancache.c:2494
#define PLPGSQL_XCHECK_SHADOWVAR
Definition: plpgsql.h:1195
#define PLPGSQL_XCHECK_ALL
Definition: plpgsql.h:1198
@ PLPGSQL_RESOLVE_COLUMN
Definition: plpgsql.h:188
@ PLPGSQL_RESOLVE_ERROR
Definition: plpgsql.h:186
@ PLPGSQL_RESOLVE_VARIABLE
Definition: plpgsql.h:187
#define PLPGSQL_XCHECK_NONE
Definition: plpgsql.h:1194
#define PLPGSQL_XCHECK_TOOMANYROWS
Definition: plpgsql.h:1196
#define PLPGSQL_XCHECK_STRICTMULTIASSIGNMENT
Definition: plpgsql.h:1197
int pg_strcasecmp(const char *s1, const char *s2)
Definition: pgstrcasecmp.c:36
static Datum PointerGetDatum(const void *X)
Definition: postgres.h:327
uintptr_t Datum
Definition: postgres.h:69
static Datum ObjectIdGetDatum(Oid X)
Definition: postgres.h:257
static Pointer DatumGetPointer(Datum X)
Definition: postgres.h:317
#define InvalidOid
Definition: postgres_ext.h:35
unsigned int Oid
Definition: postgres_ext.h:30
ResourceOwner ResourceOwnerCreate(ResourceOwner parent, const char *name)
Definition: resowner.c:421
void ResourceOwnerDelete(ResourceOwner owner)
Definition: resowner.c:871
const char * SPI_result_code_string(int code)
Definition: spi.c:1974
int SPI_connect(void)
Definition: spi.c:95
int SPI_finish(void)
Definition: spi.c:183
int SPI_connect_ext(int options)
Definition: spi.c:101
#define SPI_OPT_NONATOMIC
Definition: spi.h:102
#define SPI_OK_FINISH
Definition: spi.h:83
uint64 use_count
Definition: funccache.h:117
Definition: fmgr.h:57
MemoryContext fn_mcxt
Definition: fmgr.h:65
Oid fn_oid
Definition: fmgr.h:59
char * source_text
Definition: parsenodes.h:3581
Definition: pg_list.h:54
Definition: nodes.h:135
bool requires_procedure_resowner
Definition: plpgsql.h:1002
CachedFunction cfunc
Definition: plpgsql.h:960
struct PLpgSQL_execstate * cur_estate
Definition: plpgsql.h:1006
NodeTag type
Definition: trigger.h:33
Definition: guc.h:174
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:269
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:221
#define CALLED_AS_TRIGGER(fcinfo)
Definition: trigger.h:26
bool SplitIdentifierString(char *rawstring, char separator, List **namelist)
Definition: varlena.c:3525
const char * name
SubTransactionId GetCurrentSubTransactionId(void)
Definition: xact.c:791
void RegisterXactCallback(XactCallback callback, void *arg)
Definition: xact.c:3804
void RegisterSubXactCallback(SubXactCallback callback, void *arg)
Definition: xact.c:3864
@ SUBXACT_EVENT_ABORT_SUB
Definition: xact.h:144