52#include "utils/fmgroids.h"
229 errmsg(
"\"%s\" is a table",
231 errdetail(
"Tables cannot have INSTEAD OF triggers.")));
240 errmsg(
"\"%s\" is a table",
242 errdetail(
"Tables cannot have INSTEAD OF triggers.")));
260 if (
stmt->transitionRels !=
NIL)
263 errmsg(
"\"%s\" is a partitioned table",
265 errdetail(
"ROW triggers with transition tables are not supported on partitioned tables.")));
277 errmsg(
"\"%s\" is a view",
279 errdetail(
"Views cannot have row-level BEFORE or AFTER triggers.")));
284 errmsg(
"\"%s\" is a view",
286 errdetail(
"Views cannot have TRUNCATE triggers.")));
294 errmsg(
"\"%s\" is a foreign table",
296 errdetail(
"Foreign tables cannot have INSTEAD OF triggers.")));
303 if (
stmt->isconstraint)
306 errmsg(
"\"%s\" is a foreign table",
308 errdetail(
"Foreign tables cannot have constraint triggers.")));
313 errmsg(
"relation \"%s\" cannot have triggers",
320 errmsg(
"permission denied: \"%s\" is a system catalog",
323 if (
stmt->isconstraint)
377 tgtype |=
stmt->timing;
378 tgtype |=
stmt->events;
384 errmsg(
"TRUNCATE FOR EACH ROW triggers are not supported")));
392 errmsg(
"INSTEAD OF triggers must be FOR EACH ROW")));
393 if (
stmt->whenClause)
396 errmsg(
"INSTEAD OF triggers cannot have WHEN conditions")));
400 errmsg(
"INSTEAD OF triggers cannot have column lists")));
417 if (
stmt->transitionRels !=
NIL)
429 errmsg(
"ROW variable naming in the REFERENCING clause is not supported"),
430 errhint(
"Use OLD TABLE or NEW TABLE for naming transition tables.")));
441 errmsg(
"\"%s\" is a foreign table",
443 errdetail(
"Triggers on foreign tables cannot have transition tables.")));
448 errmsg(
"\"%s\" is a view",
450 errdetail(
"Triggers on views cannot have transition tables.")));
463 if (rel->
rd_rel->relispartition)
466 errmsg(
"ROW triggers with transition tables are not supported on partitions")));
470 errmsg(
"ROW triggers with transition tables are not supported on inheritance children")));
476 errmsg(
"transition table name can only be specified for an AFTER trigger")));
481 errmsg(
"TRUNCATE triggers with transition tables are not supported")));
498 errmsg(
"transition tables cannot be specified for triggers with more than one event")));
509 errmsg(
"transition tables cannot be specified for triggers with column lists")));
526 errmsg(
"NEW TABLE can only be specified for an INSERT or UPDATE trigger")));
531 errmsg(
"NEW TABLE cannot be specified multiple times")));
541 errmsg(
"OLD TABLE can only be specified for a DELETE or UPDATE trigger")));
546 errmsg(
"OLD TABLE cannot be specified multiple times")));
556 errmsg(
"OLD TABLE name and NEW TABLE name cannot be the same")));
567 if (!whenClause &&
stmt->whenClause)
620 errmsg(
"statement trigger's WHEN condition cannot reference column values"),
625 errmsg(
"INSERT trigger's WHEN condition cannot reference OLD values"),
633 errmsg(
"statement trigger's WHEN condition cannot reference column values"),
638 errmsg(
"DELETE trigger's WHEN condition cannot reference NEW values"),
643 errmsg(
"BEFORE trigger's WHEN condition cannot reference NEW system columns"),
652 errmsg(
"BEFORE trigger's WHEN condition cannot reference NEW generated columns"),
653 errdetail(
"A whole-row reference is used and the table contains generated columns."),
660 errmsg(
"BEFORE trigger's WHEN condition cannot reference NEW generated columns"),
661 errdetail(
"Column \"%s\" is a generated column.",
667 elog(
ERROR,
"trigger WHEN condition cannot contain references to other relations");
679 else if (!whenClause)
707 errmsg(
"function %s must return type %s",
768 errmsg(
"trigger \"%s\" for relation \"%s\" already exists",
781 errmsg(
"trigger \"%s\" for relation \"%s\" is an internal or a child trigger",
800 errmsg(
"trigger \"%s\" for relation \"%s\" is a constraint trigger",
861 trigname =
stmt->trigname;
867 memset(nulls,
false,
sizeof(nulls));
907 char *d = args +
strlen(args);
938 foreach(cell,
stmt->columns)
949 errmsg(
"column \"%s\" of relation \"%s\" does not exist",
953 for (
j =
i - 1;
j >= 0;
j--)
958 errmsg(
"column \"%s\" specified more than once",
1021 elog(
ERROR,
"cache lookup failed for relation %u",
1117 if (columns !=
NULL)
1123 for (
i = 0;
i < ncolumns;
i++)
1255 elog(
ERROR,
"trigger %u already has a parent trigger",
1317 elog(
ERROR,
"could not find tuple for trigger %u", trigOid);
1332 errmsg(
"relation \"%s\" cannot have triggers",
1339 errmsg(
"permission denied: \"%s\" is a system catalog",
1404 errmsg(
"trigger \"%s\" for table \"%s\" does not exist",
1439 errmsg(
"relation \"%s\" cannot have triggers",
1449 errmsg(
"permission denied: \"%s\" is a system catalog",
1530 errmsg(
"cannot rename trigger \"%s\" on table \"%s\"",
1532 errhint(
"Rename the trigger on the partitioned table \"%s\" instead.",
1545 for (
int i = 0;
i < partdesc->
nparts;
i++)
1558 errmsg(
"trigger \"%s\" for table \"%s\" does not exist",
1615 errmsg(
"trigger \"%s\" for relation \"%s\" already exists",
1632 errmsg(
"renamed trigger \"%s\" on relation \"%s\"",
1692 for (
int i = 0;
i < partdesc->
nparts;
i++)
1778 errmsg(
"permission denied: \"%s\" is a system trigger",
1836 if (tgname && !found)
1839 errmsg(
"trigger \"%s\" for table \"%s\" does not exist",
1929 if (
build->tgnattr > 0)
1937 if (
build->tgnargs > 0)
1944 tgrel->rd_att, &isnull));
1946 elog(
ERROR,
"tgargs is null in trigger for relation \"%s\"",
1950 for (
i = 0;
i <
build->tgnargs;
i++)
1960 tgrel->rd_att, &isnull);
1968 tgrel->rd_att, &isnull);
1976 tgrel->rd_att, &isnull);
2152 if (trigdesc ==
NULL)
2163 while (--(
trigger->tgnargs) >= 0)
2222 if (
trig1->tgisinternal !=
trig2->tgisinternal)
2226 if (
trig1->tgconstrrelid !=
trig2->tgconstrrelid)
2228 if (
trig1->tgconstrindid !=
trig2->tgconstrindid)
2230 if (
trig1->tgconstraint !=
trig2->tgconstraint)
2232 if (
trig1->tgdeferrable !=
trig2->tgdeferrable)
2234 if (
trig1->tginitdeferred !=
trig2->tginitdeferred)
2240 if (
trig1->tgnattr > 0 &&
2244 for (
j = 0;
j <
trig1->tgnargs;
j++)
2281 if (trigdesc !=
NULL)
2389 errmsg(
"trigger function %u returned null value",
2390 fcinfo->flinfo->fn_oid)));
2409 trigdesc =
relinfo->ri_TrigDesc;
2411 if (trigdesc ==
NULL)
2449 errmsg(
"BEFORE STATEMENT trigger cannot return a value")));
2506 if (newtuple ==
NULL)
2512 else if (newtuple != oldtuple)
2527 errmsg(
"moving row to another partition during a BEFORE FOR EACH ROW trigger is not supported"),
2528 errdetail(
"Before executing trigger \"%s\", the row was to be in partition \"%s.%s\".",
2551 if (
relinfo->ri_FdwRoutine && transition_capture &&
2557 errmsg(
"cannot collect transition tuples from child foreign tables")));
2610 if (newtuple ==
NULL)
2616 else if (newtuple != oldtuple)
2638 trigdesc =
relinfo->ri_TrigDesc;
2640 if (trigdesc ==
NULL)
2678 errmsg(
"BEFORE STATEMENT trigger cannot return a value")));
2784 if (newtuple ==
NULL)
2812 if (
relinfo->ri_FdwRoutine && transition_capture &&
2818 errmsg(
"cannot collect transition tuples from child foreign tables")));
2904 trigdesc =
relinfo->ri_TrigDesc;
2906 if (trigdesc ==
NULL)
2950 errmsg(
"BEFORE STATEMENT trigger cannot return a value")));
3099 if (newtuple ==
NULL)
3107 else if (newtuple != oldtuple)
3158 if (
relinfo->ri_FdwRoutine && transition_capture &&
3165 errmsg(
"cannot collect transition tuples from child foreign tables")));
3169 (transition_capture &&
3262 if (newtuple ==
NULL)
3266 else if (newtuple != oldtuple)
3288 trigdesc =
relinfo->ri_TrigDesc;
3290 if (trigdesc ==
NULL)
3324 errmsg(
"BEFORE STATEMENT trigger cannot return a value")));
3402 errmsg(
"tuple to be updated was already modified by an operation triggered by the current command"),
3403 errhint(
"Consider using an AFTER trigger instead of a BEFORE trigger to propagate changes to other rows.")));
3445 errmsg(
"could not serialize access due to concurrent update")));
3446 elog(
ERROR,
"unexpected table_tuple_lock status: %u",
test);
3453 errmsg(
"could not serialize access due to concurrent delete")));
3458 elog(
ERROR,
"attempted to lock invisible tuple");
3462 elog(
ERROR,
"unrecognized table_tuple_lock status: %u",
test);
3474 elog(
ERROR,
"failed to fetch tuple for trigger");
3683#define AFTER_TRIGGER_OFFSET 0x07FFFFFF
3684#define AFTER_TRIGGER_DONE 0x80000000
3685#define AFTER_TRIGGER_IN_PROGRESS 0x40000000
3687#define AFTER_TRIGGER_FDW_REUSE 0x00000000
3688#define AFTER_TRIGGER_FDW_FETCH 0x20000000
3689#define AFTER_TRIGGER_1CTID 0x10000000
3690#define AFTER_TRIGGER_2CTID 0x30000000
3691#define AFTER_TRIGGER_CP_UPDATE 0x08000000
3692#define AFTER_TRIGGER_TUP_BITS 0x38000000
3744#define SizeofTriggerEvent(evt) \
3745 (((evt)->ate_flags & AFTER_TRIGGER_TUP_BITS) == AFTER_TRIGGER_CP_UPDATE ? \
3746 sizeof(AfterTriggerEventData) : \
3747 (((evt)->ate_flags & AFTER_TRIGGER_TUP_BITS) == AFTER_TRIGGER_2CTID ? \
3748 sizeof(AfterTriggerEventDataNoOids) : \
3749 (((evt)->ate_flags & AFTER_TRIGGER_TUP_BITS) == AFTER_TRIGGER_1CTID ? \
3750 sizeof(AfterTriggerEventDataOneCtid) : \
3751 sizeof(AfterTriggerEventDataZeroCtids))))
3753#define GetTriggerSharedData(evt) \
3754 ((AfterTriggerShared) ((char *) (evt) + ((evt)->ate_flags & AFTER_TRIGGER_OFFSET)))
3772#define CHUNK_DATA_START(cptr) ((char *) (cptr) + MAXALIGN(sizeof(AfterTriggerEventChunk)))
3783#define for_each_chunk(cptr, evtlist) \
3784 for (cptr = (evtlist).head; cptr != NULL; cptr = cptr->next)
3785#define for_each_event(eptr, cptr) \
3786 for (eptr = (AfterTriggerEvent) CHUNK_DATA_START(cptr); \
3787 (char *) eptr < (cptr)->freeptr; \
3788 eptr = (AfterTriggerEvent) (((char *) eptr) + SizeofTriggerEvent(eptr)))
3790#define for_each_event_chunk(eptr, cptr, evtlist) \
3791 for_each_chunk(cptr, evtlist) for_each_event(eptr, cptr)
3794#define for_each_chunk_from(cptr) \
3795 for (; cptr != NULL; cptr = cptr->next)
3796#define for_each_event_from(eptr, cptr) \
3798 (char *) eptr < (cptr)->freeptr; \
3799 eptr = (AfterTriggerEvent) (((char *) eptr) + SizeofTriggerEvent(eptr)))
4029 for (
i = 0;
i <
state->numstates;
i++)
4031 if (
state->trigstates[
i].sct_tgoid == tgoid)
4032 return state->trigstates[
i].sct_tgisdeferred;
4036 if (
state->all_isset)
4037 return state->all_isdeferred;
4092 chunk = events->
tail;
4093 if (chunk ==
NULL ||
4094 chunk->endfree - chunk->freeptr <
needed)
4102 "AfterTriggerEvents",
4120#define MIN_CHUNK_SIZE 1024
4121#define MAX_CHUNK_SIZE (1024*1024)
4123#if MAX_CHUNK_SIZE > (AFTER_TRIGGER_OFFSET+1)
4124#error MAX_CHUNK_SIZE must not exceed AFTER_TRIGGER_OFFSET
4132 chunksize = chunk->endptr - (
char *) chunk;
4134 if ((chunk->endptr - chunk->endfree) <=
4144 chunk->endptr = chunk->endfree = (
char *) chunk +
chunksize;
4150 events->
head = chunk;
4154 events->
tail = chunk;
4178 if ((
char *)
newshared >= chunk->endptr)
4210 while ((chunk = events->
head) !=
NULL)
4279 foreach(
lc,
qs->tables)
4283 if (
table->after_trig_done &&
4284 table->after_trig_events.tail == target)
4288 table->after_trig_events.tailfree =
NULL;
4293 qs->events.head = target->
next;
4347 int save_sec_context;
4358 if (trigdesc ==
NULL)
4389 elog(
ERROR,
"failed to fetch tuple1 for AFTER trigger");
4395 elog(
ERROR,
"failed to fetch tuple2 for AFTER trigger");
4436 elog(
ERROR,
"failed to fetch tuple1 for AFTER trigger");
4478 elog(
ERROR,
"failed to fetch tuple2 for AFTER trigger");
4672 errmsg(
"cannot fire deferred trigger within security-restricted operation")));
4726 "AfterTriggerTupleContext",
4755 rel =
rInfo->ri_RelationDesc;
4758 trigdesc =
rInfo->ri_TrigDesc;
4760 finfo =
rInfo->ri_TrigFunctions;
4761 instr =
rInfo->ri_TrigInstrument;
4803 trigdesc, finfo, instr,
4831 if (chunk == events->
tail)
4885 foreach(
lc,
qs->tables)
4888 if (
table->relid == relid &&
table->cmdType == cmdType &&
4896 table->relid = relid;
4897 table->cmdType = cmdType;
4914 if (!
table->storeslot)
4930 return table->storeslot;
4972 if (trigdesc ==
NULL)
4998 elog(
ERROR,
"unexpected CmdType: %d", (
int) cmdType);
5008 elog(
ERROR,
"MakeTransitionCaptureState() called outside of query");
5238 ts =
qs->fdw_tuplestore;
5239 qs->fdw_tuplestore =
NULL;
5244 tables =
qs->tables;
5249 ts =
table->old_tuplestore;
5253 ts =
table->new_tuplestore;
5257 if (
table->storeslot)
5601 if (tuplestore ==
NULL)
5623 elog(
ERROR,
"invalid after-trigger event code: %d", event);
5681 qs->events.tailfree =
NULL;
5682 qs->fdw_tuplestore =
NULL;
5709 state->numalloc = numalloc;
5754 state->trigstates[
state->numstates].sct_tgoid = tgoid;
5827 foreach(
lc,
stmt->constraints)
5839 errmsg(
"cross-database references are not implemented: \"%s.%s.%s\"",
5885 if (con->condeferrable)
5887 else if (
stmt->deferred)
5890 errmsg(
"constraint \"%s\" is not deferrable",
5913 errmsg(
"constraint \"%s\" does not exist",
6000 for (
i = 0;
i <
state->numstates;
i++)
6002 if (
state->trigstates[
i].sct_tgoid == tgoid)
6004 state->trigstates[
i].sct_tgisdeferred =
stmt->deferred;
6028 if (!
stmt->deferred)
6183 char relkind = rel->
rd_rel->relkind;
6195 elog(
ERROR,
"AfterTriggerSaveEvent() called outside of query");
6220 transition_capture);
6236 transition_capture);
6248 if (trigdesc ==
NULL ||
6361 elog(
ERROR,
"invalid after-trigger event code: %d", event);
6428 if (fdw_tuplestore ==
NULL)
6539 transition_capture !=
NULL)
6592 elog(
ERROR,
"before_stmt_triggers_fired() called outside of query");
6606 result =
table->before_trig_done;
6607 table->before_trig_done =
true;
6645 if (
table->after_trig_done)
6656 if (
table->after_trig_events.tail)
6658 chunk =
table->after_trig_events.tail;
6663 chunk =
qs->events.head;
6698 table->after_trig_done =
true;
6699 table->after_trig_events =
qs->events;
6741 for (
int i = 0;
i < tupdesc->
natts;
i++)
void aclcheck_error(AclResult aclerr, ObjectType objtype, const char *objectname)
AclResult object_aclcheck(Oid classid, Oid objectid, Oid roleid, AclMode mode)
bool object_ownercheck(Oid classid, Oid objectid, Oid roleid)
AclResult pg_class_aclcheck(Oid table_oid, Oid roleid, AclMode mode)
#define InvalidAttrNumber
bool bms_equal(const Bitmapset *a, const Bitmapset *b)
bool bms_is_member(int x, const Bitmapset *a)
Bitmapset * bms_copy(const Bitmapset *a)
static Datum values[MAXATTR]
#define CStringGetTextDatum(s)
#define TextDatumGetCString(d)
Datum byteain(PG_FUNCTION_ARGS)
#define Assert(condition)
#define FLEXIBLE_ARRAY_MEMBER
#define OidIsValid(objectId)
bool IsSystemRelation(Relation relation)
Oid GetNewOidWithIndex(Relation relation, Oid indexId, AttrNumber oidcolumn)
bool IsSystemClass(Oid relid, Form_pg_class reltuple)
void recordDependencyOnExpr(const ObjectAddress *depender, Node *expr, List *rtable, DependencyType behavior)
@ DEPENDENCY_PARTITION_PRI
@ DEPENDENCY_PARTITION_SEC
int errcode(int sqlerrcode)
int errhint(const char *fmt,...) pg_attribute_printf(1
int errdetail(const char *fmt,...) pg_attribute_printf(1
#define ereport(elevel,...)
ExprState * ExecPrepareQual(List *qual, EState *estate)
LockTupleMode ExecUpdateLockMode(EState *estate, ResultRelInfo *relinfo)
ResultRelInfo * ExecGetTriggerResultRel(EState *estate, Oid relid, ResultRelInfo *rootRelInfo)
bool ExecPartitionCheck(ResultRelInfo *resultRelInfo, TupleTableSlot *slot, EState *estate, bool emitError)
TupleTableSlot * EvalPlanQual(EPQState *epqstate, Relation relation, Index rti, TupleTableSlot *inputslot)
void ExecCloseResultRelations(EState *estate)
void ExecResetTupleTable(List *tupleTable, bool shouldFree)
TupleTableSlot * MakeSingleTupleTableSlot(TupleDesc tupdesc, const TupleTableSlotOps *tts_ops)
const TupleTableSlotOps TTSOpsVirtual
void ExecDropSingleTupleTableSlot(TupleTableSlot *slot)
HeapTuple ExecFetchSlotHeapTuple(TupleTableSlot *slot, bool materialize, bool *shouldFree)
const TupleTableSlotOps TTSOpsMinimalTuple
void ExecForceStoreHeapTuple(HeapTuple tuple, TupleTableSlot *slot, bool shouldFree)
TupleTableSlot * ExecGetTriggerNewSlot(EState *estate, ResultRelInfo *relInfo)
TupleConversionMap * ExecGetChildToRootMap(ResultRelInfo *resultRelInfo)
TupleTableSlot * ExecGetTriggerOldSlot(EState *estate, ResultRelInfo *relInfo)
void FreeExecutorState(EState *estate)
Bitmapset * ExecGetAllUpdatedCols(ResultRelInfo *relinfo, EState *estate)
EState * CreateExecutorState(void)
#define GetPerTupleExprContext(estate)
#define GetPerTupleMemoryContext(estate)
static bool ExecQual(ExprState *state, ExprContext *econtext)
#define palloc_object(type)
#define palloc0_object(type)
void fmgr_info(Oid functionId, FmgrInfo *finfo)
#define DatumGetByteaPP(X)
#define InitFunctionCallInfoData(Fcinfo, Flinfo, Nargs, Collation, Context, Resultinfo)
#define DirectFunctionCall1(func, arg1)
#define LOCAL_FCINFO(name, nargs)
#define FunctionCallInvoke(fcinfo)
#define PG_RETURN_INT32(x)
void systable_endscan(SysScanDesc sysscan)
HeapTuple systable_getnext(SysScanDesc sysscan)
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
bool allowSystemTableMods
HeapTuple heap_copytuple(HeapTuple tuple)
HeapTuple heap_modify_tuple_by_cols(HeapTuple tuple, TupleDesc tupleDesc, int nCols, const int *replCols, const Datum *replValues, const bool *replIsnull)
HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, const Datum *values, const bool *isnull)
bool heap_attisnull(HeapTuple tup, int attnum, TupleDesc tupleDesc)
void heap_freetuple(HeapTuple htup)
#define HeapTupleIsValid(tuple)
static void * GETSTRUCT(const HeapTupleData *tuple)
static Datum fastgetattr(HeapTuple tup, int attnum, TupleDesc tupleDesc, bool *isnull)
void CatalogTupleUpdate(Relation heapRel, const ItemPointerData *otid, HeapTuple tup)
void CatalogTupleInsert(Relation heapRel, HeapTuple tup)
void CatalogTupleDelete(Relation heapRel, const ItemPointerData *tid)
void InstrStartNode(Instrumentation *instr)
void InstrStopNode(Instrumentation *instr, double nTuples)
int2vector * buildint2vector(const int16 *int2s, int n)
void CacheInvalidateRelcache(Relation relation)
void CacheInvalidateRelcacheByTuple(HeapTuple classTuple)
static void ItemPointerSetInvalid(ItemPointerData *pointer)
static void ItemPointerCopy(const ItemPointerData *fromPointer, ItemPointerData *toPointer)
static bool ItemPointerIsValid(const ItemPointerData *pointer)
List * lappend(List *list, void *datum)
List * lappend_oid(List *list, Oid datum)
void list_free(List *list)
bool list_member_oid(const List *list, Oid datum)
void list_free_deep(List *list)
void LockRelationOid(Oid relid, LOCKMODE lockmode)
#define AccessExclusiveLock
#define ShareRowExclusiveLock
char * get_rel_name(Oid relid)
char * get_database_name(Oid dbid)
char get_rel_relkind(Oid relid)
char * get_namespace_name(Oid nspid)
Oid get_func_rettype(Oid funcid)
Alias * makeAlias(const char *aliasname, List *colnames)
List * make_ands_implicit(Expr *clause)
void * MemoryContextAlloc(MemoryContext context, Size size)
void MemoryContextReset(MemoryContext context)
void * MemoryContextAllocZero(MemoryContext context, Size size)
MemoryContext TopTransactionContext
char * pstrdup(const char *in)
void * repalloc(void *pointer, Size size)
void pfree(void *pointer)
MemoryContext CurTransactionContext
MemoryContext CurrentMemoryContext
MemoryContext CacheMemoryContext
void MemoryContextDelete(MemoryContext context)
#define AllocSetContextCreate
#define ALLOCSET_DEFAULT_SIZES
#define ALLOCSET_SMALL_SIZES
#define SECURITY_LOCAL_USERID_CHANGE
void GetUserIdAndSecContext(Oid *userid, int *sec_context)
bool InSecurityRestrictedOperation(void)
void SetUserIdAndSecContext(Oid userid, int sec_context)
Datum nameout(PG_FUNCTION_ARGS)
void namestrcpy(Name name, const char *str)
Datum namein(PG_FUNCTION_ARGS)
char * NameListToString(const List *names)
Oid LookupExplicitNamespace(const char *nspname, bool missing_ok)
List * fetch_search_path(bool includeImplicit)
Oid RangeVarGetRelidExtended(const RangeVar *relation, LOCKMODE lockmode, uint32 flags, RangeVarGetRelidCallback callback, void *callback_arg)
#define RangeVarGetRelid(relation, lockmode, missing_ok)
TupleTableSlot * ExecGetUpdateNewTuple(ResultRelInfo *relinfo, TupleTableSlot *planSlot, TupleTableSlot *oldSlot)
#define InvokeObjectPostAlterHook(classId, objectId, subId)
#define InvokeObjectPostCreateHookArg(classId, objectId, subId, is_internal)
ObjectType get_relkind_objtype(char relkind)
#define ObjectAddressSet(addr, class_id, object_id)
char * nodeToString(const void *obj)
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Node * transformWhereClause(ParseState *pstate, Node *clause, ParseExprKind exprKind, const char *constructName)
void assign_expr_collations(ParseState *pstate, Node *expr)
Oid LookupFuncName(List *funcname, int nargs, const Oid *argtypes, bool missing_ok)
void free_parsestate(ParseState *pstate)
int parser_errposition(ParseState *pstate, int location)
ParseState * make_parsestate(ParseState *parentParseState)
void addNSItemToQuery(ParseState *pstate, ParseNamespaceItem *nsitem, bool addToJoinList, bool addToRelNameSpace, bool addToVarNameSpace)
ParseNamespaceItem * addRangeTableEntryForRelation(ParseState *pstate, Relation rel, LOCKMODE lockmode, Alias *alias, bool inh, bool inFromCl)
int attnameAttNum(Relation rd, const char *attname, bool sysColOK)
PartitionDesc RelationGetPartitionDesc(Relation rel, bool omit_detached)
List * map_partition_varattnos(List *expr, int fromrel_varno, Relation to_rel, Relation from_rel)
Oid get_partition_parent(Oid relid, bool even_if_detached)
int errdetail_relkind_not_supported(char relkind)
FormData_pg_class * Form_pg_class
Oid CreateConstraintEntry(const char *constraintName, Oid constraintNamespace, char constraintType, bool isDeferrable, bool isDeferred, bool isEnforced, bool isValidated, Oid parentConstrId, Oid relId, const int16 *constraintKey, int constraintNKeys, int constraintNTotalKeys, Oid domainId, Oid indexRelId, Oid foreignRelId, const int16 *foreignKey, const Oid *pfEqOp, const Oid *ppEqOp, const Oid *ffEqOp, int foreignNKeys, char foreignUpdateType, char foreignDeleteType, const int16 *fkDeleteSetCols, int numFkDeleteSetCols, char foreignMatchType, const Oid *exclOp, Node *conExpr, const char *conBin, bool conIsLocal, int16 conInhCount, bool conNoInherit, bool conPeriod, bool is_internal)
END_CATALOG_STRUCT typedef FormData_pg_constraint * Form_pg_constraint
void recordDependencyOn(const ObjectAddress *depender, const ObjectAddress *referenced, DependencyType behavior)
long deleteDependencyRecordsForClass(Oid classId, Oid objectId, Oid refclassId, char deptype)
long deleteDependencyRecordsFor(Oid classId, Oid objectId, bool skipExtensionDeps)
List * find_all_inheritors(Oid parentrelId, LOCKMODE lockmode, List **numparents)
bool has_superclass(Oid relationId)
#define lfirst_node(type, lc)
static int list_length(const List *l)
#define list_make1_oid(x1)
static const struct lconv_member_info table[]
END_CATALOG_STRUCT typedef FormData_pg_trigger * Form_pg_trigger
#define ERRCODE_T_R_SERIALIZATION_FAILURE
void pgstat_init_function_usage(FunctionCallInfo fcinfo, PgStat_FunctionCallUsage *fcu)
void pgstat_end_function_usage(PgStat_FunctionCallUsage *fcu, bool finalize)
void ResetPlanCache(void)
static Datum PointerGetDatum(const void *X)
static Datum Int16GetDatum(int16 X)
static Datum BoolGetDatum(bool X)
static Datum ObjectIdGetDatum(Oid X)
static char * DatumGetCString(Datum X)
static Datum NameGetDatum(const NameData *X)
static Pointer DatumGetPointer(Datum X)
static Datum CStringGetDatum(const char *X)
static Datum CharGetDatum(char X)
void * stringToNode(const char *str)
#define RelationHasReferenceCountZero(relation)
#define RelationGetRelid(relation)
#define RelationGetDescr(relation)
#define RelationGetRelationName(relation)
#define RelationGetNamespace(relation)
ResourceOwner CurrentResourceOwner
ResourceOwner CurTransactionResourceOwner
Node * expand_generated_columns_in_expr(Node *node, Relation rel, int rt_index)
void ChangeVarNodes(Node *node, int rt_index, int new_index, int sublevels_up)
bool RI_FKey_pk_upd_check_required(Trigger *trigger, Relation pk_rel, TupleTableSlot *oldslot, TupleTableSlot *newslot)
bool RI_FKey_fk_upd_check_required(Trigger *trigger, Relation fk_rel, TupleTableSlot *oldslot, TupleTableSlot *newslot)
int RI_FKey_trigger_type(Oid tgfoid)
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Snapshot GetTransactionSnapshot(void)
void PushActiveSnapshot(Snapshot snapshot)
void PopActiveSnapshot(void)
void relation_close(Relation relation, LOCKMODE lockmode)
Relation relation_open(Oid relationId, LOCKMODE lockmode)
#define BTEqualStrategyNumber
#define ERRCODE_DUPLICATE_OBJECT
struct AfterTriggerEventChunk * next
ItemPointerData ate_ctid1
ItemPointerData ate_ctid2
ItemPointerData ate_ctid1
ItemPointerData ate_ctid2
ItemPointerData ate_ctid1
AfterTriggerEventChunk * head
AfterTriggerEventChunk * tail
struct AfterTriggersTableData * ats_table
Bitmapset * ats_modifiedcols
AfterTriggersQueryData * query_stack
AfterTriggersTransData * trans_stack
AfterTriggerEventList events
Tuplestorestate * fdw_tuplestore
AfterTriggerEventList events
Tuplestorestate * new_tuplestore
TupleTableSlot * storeslot
Tuplestorestate * old_tuplestore
AfterTriggerEventList after_trig_events
AfterTriggerEventList events
MemoryContext es_query_cxt
TupleTableSlot * ecxt_innertuple
TupleTableSlot * ecxt_outertuple
const char * p_sourcetext
SetConstraintTriggerData trigstates[FLEXIBLE_ARRAY_MEMBER]
TupleTableSlot * tcs_original_insert_tuple
bool tcs_update_new_table
bool tcs_delete_old_table
bool tcs_insert_new_table
bool tcs_update_old_table
struct AfterTriggersTableData * tcs_insert_private
struct AfterTriggersTableData * tcs_update_private
struct AfterTriggersTableData * tcs_delete_private
Tuplestorestate * tg_oldtable
Tuplestorestate * tg_newtable
bool trig_delete_before_row
bool trig_update_instead_row
bool trig_delete_instead_row
bool trig_update_after_row
bool trig_insert_instead_row
bool trig_update_new_table
bool trig_insert_after_row
bool trig_update_after_statement
bool trig_update_before_row
bool trig_truncate_before_statement
bool trig_insert_new_table
bool trig_update_before_statement
bool trig_truncate_after_statement
bool trig_insert_before_statement
bool trig_delete_old_table
bool trig_delete_after_row
bool trig_insert_before_row
bool trig_delete_after_statement
bool trig_delete_before_statement
bool trig_update_old_table
bool trig_insert_after_statement
bool has_generated_virtual
#define FirstLowInvalidHeapAttributeNumber
void ReleaseSysCache(HeapTuple tuple)
HeapTuple SearchSysCache1(SysCacheIdentifier cacheId, Datum key1)
#define SearchSysCacheCopy1(cacheId, key1)
void table_close(Relation relation, LOCKMODE lockmode)
Relation table_open(Oid relationId, LOCKMODE lockmode)
Relation table_openrv(const RangeVar *relation, LOCKMODE lockmode)
static TM_Result table_tuple_lock(Relation rel, ItemPointer tid, Snapshot snapshot, TupleTableSlot *slot, CommandId cid, LockTupleMode mode, LockWaitPolicy wait_policy, uint8 flags, TM_FailureData *tmfd)
#define TUPLE_LOCK_FLAG_FIND_LAST_VERSION
static bool table_tuple_fetch_row_version(Relation rel, ItemPointer tid, Snapshot snapshot, TupleTableSlot *slot)
static SetConstraintState SetConstraintStateCopy(SetConstraintState origstate)
static void cancel_prior_stmt_triggers(Oid relid, CmdType cmdType, int tgevent)
static AfterTriggersData afterTriggers
#define AFTER_TRIGGER_FDW_FETCH
static SetConstraintState SetConstraintStateAddItem(SetConstraintState state, Oid tgoid, bool tgisdeferred)
#define AFTER_TRIGGER_IN_PROGRESS
static void renametrig_internal(Relation tgrel, Relation targetrel, HeapTuple trigtup, const char *newname, const char *expected_name)
bool ExecBRUpdateTriggers(EState *estate, EPQState *epqstate, ResultRelInfo *relinfo, ItemPointer tupleid, HeapTuple fdw_trigtuple, TupleTableSlot *newslot, TM_Result *tmresult, TM_FailureData *tmfd, bool is_merge_update)
TransitionCaptureState * MakeTransitionCaptureState(TriggerDesc *trigdesc, Oid relid, CmdType cmdType)
static bool GetTupleForTrigger(EState *estate, EPQState *epqstate, ResultRelInfo *relinfo, ItemPointer tid, LockTupleMode lockmode, TupleTableSlot *oldslot, bool do_epq_recheck, TupleTableSlot **epqslot, TM_Result *tmresultp, TM_FailureData *tmfdp)
void AfterTriggerBeginXact(void)
void ExecARDeleteTriggers(EState *estate, ResultRelInfo *relinfo, ItemPointer tupleid, HeapTuple fdw_trigtuple, TransitionCaptureState *transition_capture, bool is_crosspart_update)
void ExecBSInsertTriggers(EState *estate, ResultRelInfo *relinfo)
static void afterTriggerDeleteHeadEventChunk(AfterTriggersQueryData *qs)
static AfterTriggersTableData * GetAfterTriggersTableData(Oid relid, CmdType cmdType)
static Bitmapset * afterTriggerCopyBitmap(Bitmapset *src)
#define CHUNK_DATA_START(cptr)
static void RangeVarCallbackForRenameTrigger(const RangeVar *rv, Oid relid, Oid oldrelid, void *arg)
bool ExecBRInsertTriggers(EState *estate, ResultRelInfo *relinfo, TupleTableSlot *slot)
void AfterTriggerEndSubXact(bool isCommit)
void ExecBSTruncateTriggers(EState *estate, ResultRelInfo *relinfo)
#define AFTER_TRIGGER_TUP_BITS
static bool TriggerEnabled(EState *estate, ResultRelInfo *relinfo, Trigger *trigger, TriggerEvent event, Bitmapset *modifiedCols, TupleTableSlot *oldslot, TupleTableSlot *newslot)
void FreeTriggerDesc(TriggerDesc *trigdesc)
bool ExecIRDeleteTriggers(EState *estate, ResultRelInfo *relinfo, HeapTuple trigtuple)
#define AFTER_TRIGGER_1CTID
Datum pg_trigger_depth(PG_FUNCTION_ARGS)
void ExecBSDeleteTriggers(EState *estate, ResultRelInfo *relinfo)
ObjectAddress CreateTriggerFiringOn(const CreateTrigStmt *stmt, const char *queryString, Oid relOid, Oid refRelOid, Oid constraintOid, Oid indexOid, Oid funcoid, Oid parentTriggerOid, Node *whenClause, bool isInternal, bool in_partition, char trigger_fires_when)
void EnableDisableTrigger(Relation rel, const char *tgname, Oid tgparent, char fires_when, bool skip_system, bool recurse, LOCKMODE lockmode)
static void AfterTriggerFreeQuery(AfterTriggersQueryData *qs)
static HeapTuple ExecCallTriggerFunc(TriggerData *trigdata, int tgindx, FmgrInfo *finfo, Instrumentation *instr, MemoryContext per_tuple_context)
static void afterTriggerFreeEventList(AfterTriggerEventList *events)
const char * FindTriggerIncompatibleWithInheritance(TriggerDesc *trigdesc)
bool ExecIRInsertTriggers(EState *estate, ResultRelInfo *relinfo, TupleTableSlot *slot)
#define GetTriggerSharedData(evt)
static int MyTriggerDepth
#define for_each_chunk_from(cptr)
static bool afterTriggerMarkEvents(AfterTriggerEventList *events, AfterTriggerEventList *move_list, bool immediate_only)
static Tuplestorestate * GetAfterTriggersTransitionTable(int event, TupleTableSlot *oldslot, TupleTableSlot *newslot, TransitionCaptureState *transition_capture)
void ExecASTruncateTriggers(EState *estate, ResultRelInfo *relinfo)
static bool afterTriggerInvokeEvents(AfterTriggerEventList *events, CommandId firing_id, EState *estate, bool delete_ok)
void ExecARUpdateTriggers(EState *estate, ResultRelInfo *relinfo, ResultRelInfo *src_partinfo, ResultRelInfo *dst_partinfo, ItemPointer tupleid, HeapTuple fdw_trigtuple, TupleTableSlot *newslot, List *recheckIndexes, TransitionCaptureState *transition_capture, bool is_crosspart_update)
struct AfterTriggerSharedData * AfterTriggerShared
void AfterTriggerSetState(ConstraintsSetStmt *stmt)
bool ExecBRDeleteTriggers(EState *estate, EPQState *epqstate, ResultRelInfo *relinfo, ItemPointer tupleid, HeapTuple fdw_trigtuple, TupleTableSlot **epqslot, TM_Result *tmresult, TM_FailureData *tmfd, bool is_merge_delete)
Oid get_trigger_oid(Oid relid, const char *trigname, bool missing_ok)
static bool before_stmt_triggers_fired(Oid relid, CmdType cmdType)
static void afterTriggerAddEvent(AfterTriggerEventList *events, AfterTriggerEvent event, AfterTriggerShared evtshared)
struct SetConstraintTriggerData * SetConstraintTrigger
#define AFTER_TRIGGER_2CTID
#define SizeofTriggerEvent(evt)
int SessionReplicationRole
static bool afterTriggerCheckState(AfterTriggerShared evtshared)
static void AfterTriggerExecute(EState *estate, AfterTriggerEvent event, ResultRelInfo *relInfo, ResultRelInfo *src_relInfo, ResultRelInfo *dst_relInfo, TriggerDesc *trigdesc, FmgrInfo *finfo, Instrumentation *instr, MemoryContext per_tuple_context, TupleTableSlot *trig_tuple_slot1, TupleTableSlot *trig_tuple_slot2)
void ExecASUpdateTriggers(EState *estate, ResultRelInfo *relinfo, TransitionCaptureState *transition_capture)
static SetConstraintState SetConstraintStateCreate(int numalloc)
void ExecASDeleteTriggers(EState *estate, ResultRelInfo *relinfo, TransitionCaptureState *transition_capture)
ObjectAddress renametrig(RenameStmt *stmt)
void AfterTriggerFireDeferred(void)
static void TransitionTableAddTuple(EState *estate, int event, TransitionCaptureState *transition_capture, ResultRelInfo *relinfo, TupleTableSlot *slot, TupleTableSlot *original_insert_tuple, Tuplestorestate *tuplestore)
void ExecARInsertTriggers(EState *estate, ResultRelInfo *relinfo, TupleTableSlot *slot, List *recheckIndexes, TransitionCaptureState *transition_capture)
void TriggerSetParentTrigger(Relation trigRel, Oid childTrigId, Oid parentTrigId, Oid childTableId)
static void afterTriggerRestoreEventList(AfterTriggerEventList *events, const AfterTriggerEventList *old_events)
static void SetTriggerFlags(TriggerDesc *trigdesc, Trigger *trigger)
#define for_each_event_from(eptr, cptr)
static void renametrig_partition(Relation tgrel, Oid partitionId, Oid parentTriggerOid, const char *newname, const char *expected_name)
void ExecASInsertTriggers(EState *estate, ResultRelInfo *relinfo, TransitionCaptureState *transition_capture)
static Tuplestorestate * GetCurrentFDWTuplestore(void)
TriggerDesc * CopyTriggerDesc(TriggerDesc *trigdesc)
void assign_session_replication_role(int newval, void *extra)
bool ExecIRUpdateTriggers(EState *estate, ResultRelInfo *relinfo, HeapTuple trigtuple, TupleTableSlot *newslot)
void AfterTriggerEndXact(bool isCommit)
bool AfterTriggerPendingOnRel(Oid relid)
#define AFTER_TRIGGER_FDW_REUSE
void RelationBuildTriggers(Relation relation)
void AfterTriggerBeginSubXact(void)
static void AfterTriggerSaveEvent(EState *estate, ResultRelInfo *relinfo, ResultRelInfo *src_partinfo, ResultRelInfo *dst_partinfo, int event, bool row_trigger, TupleTableSlot *oldslot, TupleTableSlot *newslot, List *recheckIndexes, Bitmapset *modifiedCols, TransitionCaptureState *transition_capture, bool is_crosspart_update)
static HeapTuple check_modified_virtual_generated(TupleDesc tupdesc, HeapTuple tuple)
ObjectAddress CreateTrigger(const CreateTrigStmt *stmt, const char *queryString, Oid relOid, Oid refRelOid, Oid constraintOid, Oid indexOid, Oid funcoid, Oid parentTriggerOid, Node *whenClause, bool isInternal, bool in_partition)
static TupleTableSlot * GetAfterTriggersStoreSlot(AfterTriggersTableData *table, TupleDesc tupdesc)
#define AFTER_TRIGGER_CP_UPDATE
void AfterTriggerEndQuery(EState *estate)
void RemoveTriggerById(Oid trigOid)
#define AFTER_TRIGGER_DONE
#define for_each_event_chunk(eptr, cptr, evtlist)
SetConstraintStateData * SetConstraintState
static void AfterTriggerEnlargeQueryState(void)
#define for_each_event(eptr, cptr)
struct AfterTriggerEventData * AfterTriggerEvent
#define for_each_chunk(cptr, evtlist)
void ExecBSUpdateTriggers(EState *estate, ResultRelInfo *relinfo)
void AfterTriggerBeginQuery(void)
#define AFTER_TRIGGER_DEFERRABLE
#define TRIGGER_FIRED_FOR_STATEMENT(event)
#define TRIGGER_EVENT_UPDATE
#define TRIGGER_FIRED_BY_DELETE(event)
#define SESSION_REPLICATION_ROLE_REPLICA
#define TRIGGER_EVENT_DELETE
#define TRIGGER_FIRES_ON_ORIGIN
#define TRIGGER_EVENT_OPMASK
#define TRIGGER_FIRES_ON_REPLICA
#define AFTER_TRIGGER_INITDEFERRED
#define TRIGGER_EVENT_INSTEAD
#define TRIGGER_EVENT_ROW
#define TRIGGER_FIRED_AFTER(event)
#define TRIGGER_EVENT_BEFORE
#define TRIGGER_FIRED_BY_INSERT(event)
#define SESSION_REPLICATION_ROLE_ORIGIN
#define TRIGGER_EVENT_INSERT
#define TRIGGER_FIRED_BY_UPDATE(event)
#define TRIGGER_EVENT_TRUNCATE
TupleTableSlot * execute_attr_map_slot(AttrMap *attrMap, TupleTableSlot *in_slot, TupleTableSlot *out_slot)
TupleDesc CreateTupleDescCopy(TupleDesc tupdesc)
static FormData_pg_attribute * TupleDescAttr(TupleDesc tupdesc, int i)
bool tuplestore_gettupleslot(Tuplestorestate *state, bool forward, bool copy, TupleTableSlot *slot)
void tuplestore_puttupleslot(Tuplestorestate *state, TupleTableSlot *slot)
Tuplestorestate * tuplestore_begin_heap(bool randomAccess, bool interXact, int maxKBytes)
void tuplestore_end(Tuplestorestate *state)
static TupleTableSlot * ExecClearTuple(TupleTableSlot *slot)
static TupleTableSlot * ExecCopySlot(TupleTableSlot *dstslot, TupleTableSlot *srcslot)
static void ExecMaterializeSlot(TupleTableSlot *slot)
List * pull_var_clause(Node *node, int flags)
static char * VARDATA_ANY(const void *PTR)
int GetCurrentTransactionNestLevel(void)
void CommandCounterIncrement(void)
bool IsSubTransaction(void)
#define IsolationUsesXactSnapshot()