50#include "utils/fmgroids.h"
227 errmsg(
"\"%s\" is a table",
229 errdetail(
"Tables cannot have INSTEAD OF triggers.")));
238 errmsg(
"\"%s\" is a table",
240 errdetail(
"Tables cannot have INSTEAD OF triggers.")));
258 if (
stmt->transitionRels !=
NIL)
261 errmsg(
"\"%s\" is a partitioned table",
263 errdetail(
"ROW triggers with transition tables are not supported on partitioned tables.")));
275 errmsg(
"\"%s\" is a view",
277 errdetail(
"Views cannot have row-level BEFORE or AFTER triggers.")));
282 errmsg(
"\"%s\" is a view",
284 errdetail(
"Views cannot have TRUNCATE triggers.")));
292 errmsg(
"\"%s\" is a foreign table",
294 errdetail(
"Foreign tables cannot have INSTEAD OF triggers.")));
301 if (
stmt->isconstraint)
304 errmsg(
"\"%s\" is a foreign table",
306 errdetail(
"Foreign tables cannot have constraint triggers.")));
311 errmsg(
"relation \"%s\" cannot have triggers",
318 errmsg(
"permission denied: \"%s\" is a system catalog",
321 if (
stmt->isconstraint)
375 tgtype |=
stmt->timing;
376 tgtype |=
stmt->events;
382 errmsg(
"TRUNCATE FOR EACH ROW triggers are not supported")));
390 errmsg(
"INSTEAD OF triggers must be FOR EACH ROW")));
391 if (
stmt->whenClause)
394 errmsg(
"INSTEAD OF triggers cannot have WHEN conditions")));
398 errmsg(
"INSTEAD OF triggers cannot have column lists")));
415 if (
stmt->transitionRels !=
NIL)
427 errmsg(
"ROW variable naming in the REFERENCING clause is not supported"),
428 errhint(
"Use OLD TABLE or NEW TABLE for naming transition tables.")));
439 errmsg(
"\"%s\" is a foreign table",
441 errdetail(
"Triggers on foreign tables cannot have transition tables.")));
446 errmsg(
"\"%s\" is a view",
448 errdetail(
"Triggers on views cannot have transition tables.")));
461 if (rel->
rd_rel->relispartition)
464 errmsg(
"ROW triggers with transition tables are not supported on partitions")));
468 errmsg(
"ROW triggers with transition tables are not supported on inheritance children")));
474 errmsg(
"transition table name can only be specified for an AFTER trigger")));
479 errmsg(
"TRUNCATE triggers with transition tables are not supported")));
496 errmsg(
"transition tables cannot be specified for triggers with more than one event")));
507 errmsg(
"transition tables cannot be specified for triggers with column lists")));
524 errmsg(
"NEW TABLE can only be specified for an INSERT or UPDATE trigger")));
529 errmsg(
"NEW TABLE cannot be specified multiple times")));
539 errmsg(
"OLD TABLE can only be specified for a DELETE or UPDATE trigger")));
544 errmsg(
"OLD TABLE cannot be specified multiple times")));
554 errmsg(
"OLD TABLE name and NEW TABLE name cannot be the same")));
565 if (!whenClause &&
stmt->whenClause)
618 errmsg(
"statement trigger's WHEN condition cannot reference column values"),
623 errmsg(
"INSERT trigger's WHEN condition cannot reference OLD values"),
631 errmsg(
"statement trigger's WHEN condition cannot reference column values"),
636 errmsg(
"DELETE trigger's WHEN condition cannot reference NEW values"),
641 errmsg(
"BEFORE trigger's WHEN condition cannot reference NEW system columns"),
650 errmsg(
"BEFORE trigger's WHEN condition cannot reference NEW generated columns"),
651 errdetail(
"A whole-row reference is used and the table contains generated columns."),
658 errmsg(
"BEFORE trigger's WHEN condition cannot reference NEW generated columns"),
659 errdetail(
"Column \"%s\" is a generated column.",
665 elog(
ERROR,
"trigger WHEN condition cannot contain references to other relations");
677 else if (!whenClause)
705 errmsg(
"function %s must return type %s",
766 errmsg(
"trigger \"%s\" for relation \"%s\" already exists",
779 errmsg(
"trigger \"%s\" for relation \"%s\" is an internal or a child trigger",
798 errmsg(
"trigger \"%s\" for relation \"%s\" is a constraint trigger",
859 trigname =
stmt->trigname;
865 memset(nulls,
false,
sizeof(nulls));
905 char *d = args +
strlen(args);
936 foreach(cell,
stmt->columns)
947 errmsg(
"column \"%s\" of relation \"%s\" does not exist",
951 for (
j =
i - 1;
j >= 0;
j--)
956 errmsg(
"column \"%s\" specified more than once",
1019 elog(
ERROR,
"cache lookup failed for relation %u",
1115 if (columns !=
NULL)
1121 for (
i = 0;
i < ncolumns;
i++)
1253 elog(
ERROR,
"trigger %u already has a parent trigger",
1315 elog(
ERROR,
"could not find tuple for trigger %u", trigOid);
1330 errmsg(
"relation \"%s\" cannot have triggers",
1337 errmsg(
"permission denied: \"%s\" is a system catalog",
1402 errmsg(
"trigger \"%s\" for table \"%s\" does not exist",
1437 errmsg(
"relation \"%s\" cannot have triggers",
1447 errmsg(
"permission denied: \"%s\" is a system catalog",
1528 errmsg(
"cannot rename trigger \"%s\" on table \"%s\"",
1530 errhint(
"Rename the trigger on the partitioned table \"%s\" instead.",
1543 for (
int i = 0;
i < partdesc->
nparts;
i++)
1556 errmsg(
"trigger \"%s\" for table \"%s\" does not exist",
1613 errmsg(
"trigger \"%s\" for relation \"%s\" already exists",
1630 errmsg(
"renamed trigger \"%s\" on relation \"%s\"",
1690 for (
int i = 0;
i < partdesc->
nparts;
i++)
1776 errmsg(
"permission denied: \"%s\" is a system trigger",
1834 if (tgname && !found)
1837 errmsg(
"trigger \"%s\" for table \"%s\" does not exist",
1927 if (
build->tgnattr > 0)
1935 if (
build->tgnargs > 0)
1942 tgrel->rd_att, &isnull));
1944 elog(
ERROR,
"tgargs is null in trigger for relation \"%s\"",
1948 for (
i = 0;
i <
build->tgnargs;
i++)
1958 tgrel->rd_att, &isnull);
1966 tgrel->rd_att, &isnull);
1974 tgrel->rd_att, &isnull);
2150 if (trigdesc ==
NULL)
2161 while (--(
trigger->tgnargs) >= 0)
2220 if (
trig1->tgisinternal !=
trig2->tgisinternal)
2224 if (
trig1->tgconstrrelid !=
trig2->tgconstrrelid)
2226 if (
trig1->tgconstrindid !=
trig2->tgconstrindid)
2228 if (
trig1->tgconstraint !=
trig2->tgconstraint)
2230 if (
trig1->tgdeferrable !=
trig2->tgdeferrable)
2232 if (
trig1->tginitdeferred !=
trig2->tginitdeferred)
2238 if (
trig1->tgnattr > 0 &&
2242 for (
j = 0;
j <
trig1->tgnargs;
j++)
2279 if (trigdesc !=
NULL)
2387 errmsg(
"trigger function %u returned null value",
2388 fcinfo->flinfo->fn_oid)));
2407 trigdesc =
relinfo->ri_TrigDesc;
2409 if (trigdesc ==
NULL)
2447 errmsg(
"BEFORE STATEMENT trigger cannot return a value")));
2504 if (newtuple ==
NULL)
2510 else if (newtuple != oldtuple)
2525 errmsg(
"moving row to another partition during a BEFORE FOR EACH ROW trigger is not supported"),
2526 errdetail(
"Before executing trigger \"%s\", the row was to be in partition \"%s.%s\".",
2549 if (
relinfo->ri_FdwRoutine && transition_capture &&
2555 errmsg(
"cannot collect transition tuples from child foreign tables")));
2608 if (newtuple ==
NULL)
2614 else if (newtuple != oldtuple)
2636 trigdesc =
relinfo->ri_TrigDesc;
2638 if (trigdesc ==
NULL)
2676 errmsg(
"BEFORE STATEMENT trigger cannot return a value")));
2782 if (newtuple ==
NULL)
2810 if (
relinfo->ri_FdwRoutine && transition_capture &&
2816 errmsg(
"cannot collect transition tuples from child foreign tables")));
2902 trigdesc =
relinfo->ri_TrigDesc;
2904 if (trigdesc ==
NULL)
2948 errmsg(
"BEFORE STATEMENT trigger cannot return a value")));
3097 if (newtuple ==
NULL)
3105 else if (newtuple != oldtuple)
3156 if (
relinfo->ri_FdwRoutine && transition_capture &&
3163 errmsg(
"cannot collect transition tuples from child foreign tables")));
3167 (transition_capture &&
3260 if (newtuple ==
NULL)
3264 else if (newtuple != oldtuple)
3286 trigdesc =
relinfo->ri_TrigDesc;
3288 if (trigdesc ==
NULL)
3322 errmsg(
"BEFORE STATEMENT trigger cannot return a value")));
3400 errmsg(
"tuple to be updated was already modified by an operation triggered by the current command"),
3401 errhint(
"Consider using an AFTER trigger instead of a BEFORE trigger to propagate changes to other rows.")));
3443 errmsg(
"could not serialize access due to concurrent update")));
3444 elog(
ERROR,
"unexpected table_tuple_lock status: %u",
test);
3451 errmsg(
"could not serialize access due to concurrent delete")));
3456 elog(
ERROR,
"attempted to lock invisible tuple");
3460 elog(
ERROR,
"unrecognized table_tuple_lock status: %u",
test);
3472 elog(
ERROR,
"failed to fetch tuple for trigger");
3681#define AFTER_TRIGGER_OFFSET 0x07FFFFFF
3682#define AFTER_TRIGGER_DONE 0x80000000
3683#define AFTER_TRIGGER_IN_PROGRESS 0x40000000
3685#define AFTER_TRIGGER_FDW_REUSE 0x00000000
3686#define AFTER_TRIGGER_FDW_FETCH 0x20000000
3687#define AFTER_TRIGGER_1CTID 0x10000000
3688#define AFTER_TRIGGER_2CTID 0x30000000
3689#define AFTER_TRIGGER_CP_UPDATE 0x08000000
3690#define AFTER_TRIGGER_TUP_BITS 0x38000000
3742#define SizeofTriggerEvent(evt) \
3743 (((evt)->ate_flags & AFTER_TRIGGER_TUP_BITS) == AFTER_TRIGGER_CP_UPDATE ? \
3744 sizeof(AfterTriggerEventData) : \
3745 (((evt)->ate_flags & AFTER_TRIGGER_TUP_BITS) == AFTER_TRIGGER_2CTID ? \
3746 sizeof(AfterTriggerEventDataNoOids) : \
3747 (((evt)->ate_flags & AFTER_TRIGGER_TUP_BITS) == AFTER_TRIGGER_1CTID ? \
3748 sizeof(AfterTriggerEventDataOneCtid) : \
3749 sizeof(AfterTriggerEventDataZeroCtids))))
3751#define GetTriggerSharedData(evt) \
3752 ((AfterTriggerShared) ((char *) (evt) + ((evt)->ate_flags & AFTER_TRIGGER_OFFSET)))
3770#define CHUNK_DATA_START(cptr) ((char *) (cptr) + MAXALIGN(sizeof(AfterTriggerEventChunk)))
3781#define for_each_chunk(cptr, evtlist) \
3782 for (cptr = (evtlist).head; cptr != NULL; cptr = cptr->next)
3783#define for_each_event(eptr, cptr) \
3784 for (eptr = (AfterTriggerEvent) CHUNK_DATA_START(cptr); \
3785 (char *) eptr < (cptr)->freeptr; \
3786 eptr = (AfterTriggerEvent) (((char *) eptr) + SizeofTriggerEvent(eptr)))
3788#define for_each_event_chunk(eptr, cptr, evtlist) \
3789 for_each_chunk(cptr, evtlist) for_each_event(eptr, cptr)
3792#define for_each_chunk_from(cptr) \
3793 for (; cptr != NULL; cptr = cptr->next)
3794#define for_each_event_from(eptr, cptr) \
3796 (char *) eptr < (cptr)->freeptr; \
3797 eptr = (AfterTriggerEvent) (((char *) eptr) + SizeofTriggerEvent(eptr)))
4027 for (
i = 0;
i <
state->numstates;
i++)
4029 if (
state->trigstates[
i].sct_tgoid == tgoid)
4030 return state->trigstates[
i].sct_tgisdeferred;
4034 if (
state->all_isset)
4035 return state->all_isdeferred;
4100 "AfterTriggerEvents",
4118#define MIN_CHUNK_SIZE 1024
4119#define MAX_CHUNK_SIZE (1024*1024)
4121#if MAX_CHUNK_SIZE > (AFTER_TRIGGER_OFFSET+1)
4122#error MAX_CHUNK_SIZE must not exceed AFTER_TRIGGER_OFFSET
4277 foreach(
lc,
qs->tables)
4281 if (
table->after_trig_done &&
4282 table->after_trig_events.tail == target)
4286 table->after_trig_events.tailfree =
NULL;
4291 qs->events.head = target->
next;
4345 int save_sec_context;
4356 if (trigdesc ==
NULL)
4387 elog(
ERROR,
"failed to fetch tuple1 for AFTER trigger");
4393 elog(
ERROR,
"failed to fetch tuple2 for AFTER trigger");
4434 elog(
ERROR,
"failed to fetch tuple1 for AFTER trigger");
4476 elog(
ERROR,
"failed to fetch tuple2 for AFTER trigger");
4670 errmsg(
"cannot fire deferred trigger within security-restricted operation")));
4724 "AfterTriggerTupleContext",
4753 rel =
rInfo->ri_RelationDesc;
4756 trigdesc =
rInfo->ri_TrigDesc;
4758 finfo =
rInfo->ri_TrigFunctions;
4759 instr =
rInfo->ri_TrigInstrument;
4801 trigdesc, finfo, instr,
4883 foreach(
lc,
qs->tables)
4886 if (
table->relid == relid &&
table->cmdType == cmdType &&
4894 table->relid = relid;
4895 table->cmdType = cmdType;
4912 if (!
table->storeslot)
4928 return table->storeslot;
4970 if (trigdesc ==
NULL)
4996 elog(
ERROR,
"unexpected CmdType: %d", (
int) cmdType);
5006 elog(
ERROR,
"MakeTransitionCaptureState() called outside of query");
5236 ts =
qs->fdw_tuplestore;
5237 qs->fdw_tuplestore =
NULL;
5242 tables =
qs->tables;
5247 ts =
table->old_tuplestore;
5251 ts =
table->new_tuplestore;
5255 if (
table->storeslot)
5599 if (tuplestore ==
NULL)
5621 elog(
ERROR,
"invalid after-trigger event code: %d", event);
5679 qs->events.tailfree =
NULL;
5680 qs->fdw_tuplestore =
NULL;
5707 state->numalloc = numalloc;
5752 state->trigstates[
state->numstates].sct_tgoid = tgoid;
5825 foreach(
lc,
stmt->constraints)
5837 errmsg(
"cross-database references are not implemented: \"%s.%s.%s\"",
5883 if (con->condeferrable)
5885 else if (
stmt->deferred)
5888 errmsg(
"constraint \"%s\" is not deferrable",
5911 errmsg(
"constraint \"%s\" does not exist",
5998 for (
i = 0;
i <
state->numstates;
i++)
6000 if (
state->trigstates[
i].sct_tgoid == tgoid)
6002 state->trigstates[
i].sct_tgisdeferred =
stmt->deferred;
6026 if (!
stmt->deferred)
6181 char relkind = rel->
rd_rel->relkind;
6193 elog(
ERROR,
"AfterTriggerSaveEvent() called outside of query");
6218 transition_capture);
6234 transition_capture);
6246 if (trigdesc ==
NULL ||
6359 elog(
ERROR,
"invalid after-trigger event code: %d", event);
6426 if (fdw_tuplestore ==
NULL)
6537 transition_capture !=
NULL)
6590 elog(
ERROR,
"before_stmt_triggers_fired() called outside of query");
6604 result =
table->before_trig_done;
6605 table->before_trig_done =
true;
6643 if (
table->after_trig_done)
6654 if (
table->after_trig_events.tail)
6696 table->after_trig_done =
true;
6697 table->after_trig_events =
qs->events;
6739 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 errdetail(const char *fmt,...)
int errhint(const char *fmt,...)
int errcode(int sqlerrcode)
int errmsg(const char *fmt,...)
#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)
ParseNamespaceItem * addRangeTableEntryForRelation(ParseState *pstate, Relation rel, int lockmode, Alias *alias, bool inh, bool inFromCl)
void addNSItemToQuery(ParseState *pstate, ParseNamespaceItem *nsitem, bool addToJoinList, bool addToRelNameSpace, bool addToVarNameSpace)
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)
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[]
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(int 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)
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)
ObjectAddress CreateTrigger(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 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)
ObjectAddress CreateTriggerFiringOn(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)
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)
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()