Thanks to visit codestin.com
Credit goes to doxygen.postgresql.org

PostgreSQL Source Code git master
event_trigger.h File Reference
Include dependency graph for event_trigger.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  EventTriggerData
 

Macros

#define AT_REWRITE_ALTER_PERSISTENCE   0x01
 
#define AT_REWRITE_DEFAULT_VAL   0x02
 
#define AT_REWRITE_COLUMN_REWRITE   0x04
 
#define AT_REWRITE_ACCESS_METHOD   0x08
 
#define CALLED_AS_EVENT_TRIGGER(fcinfo)    ((fcinfo)->context != NULL && IsA((fcinfo)->context, EventTriggerData))
 

Typedefs

typedef struct EventTriggerData EventTriggerData
 

Functions

Oid CreateEventTrigger (CreateEventTrigStmt *stmt)
 
Oid get_event_trigger_oid (const char *trigname, bool missing_ok)
 
Oid AlterEventTrigger (AlterEventTrigStmt *stmt)
 
ObjectAddress AlterEventTriggerOwner (const char *name, Oid newOwnerId)
 
void AlterEventTriggerOwner_oid (Oid, Oid newOwnerId)
 
bool EventTriggerSupportsObjectType (ObjectType obtype)
 
bool EventTriggerSupportsObject (const ObjectAddress *object)
 
void EventTriggerDDLCommandStart (Node *parsetree)
 
void EventTriggerDDLCommandEnd (Node *parsetree)
 
void EventTriggerSQLDrop (Node *parsetree)
 
void EventTriggerTableRewrite (Node *parsetree, Oid tableOid, int reason)
 
void EventTriggerOnLogin (void)
 
bool EventTriggerBeginCompleteQuery (void)
 
void EventTriggerEndCompleteQuery (void)
 
bool trackDroppedObjectsNeeded (void)
 
void EventTriggerSQLDropAddObject (const ObjectAddress *object, bool original, bool normal)
 
void EventTriggerInhibitCommandCollection (void)
 
void EventTriggerUndoInhibitCommandCollection (void)
 
void EventTriggerCollectSimpleCommand (ObjectAddress address, ObjectAddress secondaryObject, Node *parsetree)
 
void EventTriggerAlterTableStart (Node *parsetree)
 
void EventTriggerAlterTableRelid (Oid objectId)
 
void EventTriggerCollectAlterTableSubcmd (Node *subcmd, ObjectAddress address)
 
void EventTriggerAlterTableEnd (void)
 
void EventTriggerCollectGrant (InternalGrant *istmt)
 
void EventTriggerCollectAlterOpFam (AlterOpFamilyStmt *stmt, Oid opfamoid, List *operators, List *procedures)
 
void EventTriggerCollectCreateOpClass (CreateOpClassStmt *stmt, Oid opcoid, List *operators, List *procedures)
 
void EventTriggerCollectAlterTSConfig (AlterTSConfigurationStmt *stmt, Oid cfgId, Oid *dictIds, int ndicts)
 
void EventTriggerCollectAlterDefPrivs (AlterDefaultPrivilegesStmt *stmt)
 

Variables

PGDLLIMPORT bool event_triggers
 

Macro Definition Documentation

◆ AT_REWRITE_ACCESS_METHOD

#define AT_REWRITE_ACCESS_METHOD   0x08

Definition at line 43 of file event_trigger.h.

◆ AT_REWRITE_ALTER_PERSISTENCE

#define AT_REWRITE_ALTER_PERSISTENCE   0x01

Definition at line 40 of file event_trigger.h.

◆ AT_REWRITE_COLUMN_REWRITE

#define AT_REWRITE_COLUMN_REWRITE   0x04

Definition at line 42 of file event_trigger.h.

◆ AT_REWRITE_DEFAULT_VAL

#define AT_REWRITE_DEFAULT_VAL   0x02

Definition at line 41 of file event_trigger.h.

◆ CALLED_AS_EVENT_TRIGGER

#define CALLED_AS_EVENT_TRIGGER (   fcinfo)     ((fcinfo)->context != NULL && IsA((fcinfo)->context, EventTriggerData))

Definition at line 49 of file event_trigger.h.

Typedef Documentation

◆ EventTriggerData

Function Documentation

◆ AlterEventTrigger()

Oid AlterEventTrigger ( AlterEventTrigStmt stmt)

Definition at line 427 of file event_trigger.c.

428{
429 Relation tgrel;
430 HeapTuple tup;
431 Oid trigoid;
432 Form_pg_event_trigger evtForm;
433 char tgenabled = stmt->tgenabled;
434
435 tgrel = table_open(EventTriggerRelationId, RowExclusiveLock);
436
437 tup = SearchSysCacheCopy1(EVENTTRIGGERNAME,
438 CStringGetDatum(stmt->trigname));
439 if (!HeapTupleIsValid(tup))
441 (errcode(ERRCODE_UNDEFINED_OBJECT),
442 errmsg("event trigger \"%s\" does not exist",
443 stmt->trigname)));
444
445 evtForm = (Form_pg_event_trigger) GETSTRUCT(tup);
446 trigoid = evtForm->oid;
447
448 if (!object_ownercheck(EventTriggerRelationId, trigoid, GetUserId()))
450 stmt->trigname);
451
452 /* tuple is a copy, so we can modify it below */
453 evtForm->evtenabled = tgenabled;
454
455 CatalogTupleUpdate(tgrel, &tup->t_self, tup);
456
457 /*
458 * Login event triggers have an additional flag in pg_database to enable
459 * faster lookups in hot codepaths. Set the flag unless already True.
460 */
461 if (namestrcmp(&evtForm->evtevent, "login") == 0 &&
462 tgenabled != TRIGGER_DISABLED)
464
465 InvokeObjectPostAlterHook(EventTriggerRelationId,
466 trigoid, 0);
467
468 /* clean up */
469 heap_freetuple(tup);
471
472 return trigoid;
473}
@ ACLCHECK_NOT_OWNER
Definition: acl.h:185
void aclcheck_error(AclResult aclerr, ObjectType objtype, const char *objectname)
Definition: aclchk.c:2652
bool object_ownercheck(Oid classid, Oid objectid, Oid roleid)
Definition: aclchk.c:4088
int errcode(int sqlerrcode)
Definition: elog.c:854
int errmsg(const char *fmt,...)
Definition: elog.c:1071
#define ERROR
Definition: elog.h:39
#define ereport(elevel,...)
Definition: elog.h:150
static void SetDatabaseHasLoginEventTriggers(void)
void heap_freetuple(HeapTuple htup)
Definition: heaptuple.c:1435
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
static void * GETSTRUCT(const HeapTupleData *tuple)
Definition: htup_details.h:728
#define stmt
Definition: indent_codes.h:59
void CatalogTupleUpdate(Relation heapRel, ItemPointer otid, HeapTuple tup)
Definition: indexing.c:313
#define RowExclusiveLock
Definition: lockdefs.h:38
Oid GetUserId(void)
Definition: miscinit.c:469
int namestrcmp(Name name, const char *str)
Definition: name.c:247
#define InvokeObjectPostAlterHook(classId, objectId, subId)
Definition: objectaccess.h:197
@ OBJECT_EVENT_TRIGGER
Definition: parsenodes.h:2336
FormData_pg_event_trigger * Form_pg_event_trigger
static Datum CStringGetDatum(const char *X)
Definition: postgres.h:360
unsigned int Oid
Definition: postgres_ext.h:32
ItemPointerData t_self
Definition: htup.h:65
#define SearchSysCacheCopy1(cacheId, key1)
Definition: syscache.h:91
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:126
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:40
#define TRIGGER_DISABLED
Definition: trigger.h:152

References aclcheck_error(), ACLCHECK_NOT_OWNER, CatalogTupleUpdate(), CStringGetDatum(), ereport, errcode(), errmsg(), ERROR, GETSTRUCT(), GetUserId(), heap_freetuple(), HeapTupleIsValid, InvokeObjectPostAlterHook, namestrcmp(), OBJECT_EVENT_TRIGGER, object_ownercheck(), RowExclusiveLock, SearchSysCacheCopy1, SetDatabaseHasLoginEventTriggers(), stmt, HeapTupleData::t_self, table_close(), table_open(), and TRIGGER_DISABLED.

Referenced by standard_ProcessUtility().

◆ AlterEventTriggerOwner()

ObjectAddress AlterEventTriggerOwner ( const char *  name,
Oid  newOwnerId 
)

Definition at line 479 of file event_trigger.c.

480{
481 Oid evtOid;
482 HeapTuple tup;
483 Form_pg_event_trigger evtForm;
484 Relation rel;
485 ObjectAddress address;
486
487 rel = table_open(EventTriggerRelationId, RowExclusiveLock);
488
489 tup = SearchSysCacheCopy1(EVENTTRIGGERNAME, CStringGetDatum(name));
490
491 if (!HeapTupleIsValid(tup))
493 (errcode(ERRCODE_UNDEFINED_OBJECT),
494 errmsg("event trigger \"%s\" does not exist", name)));
495
496 evtForm = (Form_pg_event_trigger) GETSTRUCT(tup);
497 evtOid = evtForm->oid;
498
499 AlterEventTriggerOwner_internal(rel, tup, newOwnerId);
500
501 ObjectAddressSet(address, EventTriggerRelationId, evtOid);
502
503 heap_freetuple(tup);
504
506
507 return address;
508}
static void AlterEventTriggerOwner_internal(Relation rel, HeapTuple tup, Oid newOwnerId)
#define ObjectAddressSet(addr, class_id, object_id)
Definition: objectaddress.h:40
const char * name

References AlterEventTriggerOwner_internal(), CStringGetDatum(), ereport, errcode(), errmsg(), ERROR, GETSTRUCT(), heap_freetuple(), HeapTupleIsValid, name, ObjectAddressSet, RowExclusiveLock, SearchSysCacheCopy1, table_close(), and table_open().

Referenced by ExecAlterOwnerStmt().

◆ AlterEventTriggerOwner_oid()

void AlterEventTriggerOwner_oid ( Oid  trigOid,
Oid  newOwnerId 
)

Definition at line 514 of file event_trigger.c.

515{
516 HeapTuple tup;
517 Relation rel;
518
519 rel = table_open(EventTriggerRelationId, RowExclusiveLock);
520
521 tup = SearchSysCacheCopy1(EVENTTRIGGEROID, ObjectIdGetDatum(trigOid));
522
523 if (!HeapTupleIsValid(tup))
525 (errcode(ERRCODE_UNDEFINED_OBJECT),
526 errmsg("event trigger with OID %u does not exist", trigOid)));
527
528 AlterEventTriggerOwner_internal(rel, tup, newOwnerId);
529
530 heap_freetuple(tup);
531
533}
static Datum ObjectIdGetDatum(Oid X)
Definition: postgres.h:262

References AlterEventTriggerOwner_internal(), ereport, errcode(), errmsg(), ERROR, heap_freetuple(), HeapTupleIsValid, ObjectIdGetDatum(), RowExclusiveLock, SearchSysCacheCopy1, table_close(), and table_open().

Referenced by shdepReassignOwned_Owner().

◆ CreateEventTrigger()

Oid CreateEventTrigger ( CreateEventTrigStmt stmt)

Definition at line 124 of file event_trigger.c.

125{
126 HeapTuple tuple;
127 Oid funcoid;
128 Oid funcrettype;
129 Oid evtowner = GetUserId();
130 ListCell *lc;
131 List *tags = NULL;
132
133 /*
134 * It would be nice to allow database owners or even regular users to do
135 * this, but there are obvious privilege escalation risks which would have
136 * to somehow be plugged first.
137 */
138 if (!superuser())
140 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
141 errmsg("permission denied to create event trigger \"%s\"",
142 stmt->trigname),
143 errhint("Must be superuser to create an event trigger.")));
144
145 /* Validate event name. */
146 if (strcmp(stmt->eventname, "ddl_command_start") != 0 &&
147 strcmp(stmt->eventname, "ddl_command_end") != 0 &&
148 strcmp(stmt->eventname, "sql_drop") != 0 &&
149 strcmp(stmt->eventname, "login") != 0 &&
150 strcmp(stmt->eventname, "table_rewrite") != 0)
152 (errcode(ERRCODE_SYNTAX_ERROR),
153 errmsg("unrecognized event name \"%s\"",
154 stmt->eventname)));
155
156 /* Validate filter conditions. */
157 foreach(lc, stmt->whenclause)
158 {
159 DefElem *def = (DefElem *) lfirst(lc);
160
161 if (strcmp(def->defname, "tag") == 0)
162 {
163 if (tags != NULL)
165 tags = (List *) def->arg;
166 }
167 else
169 (errcode(ERRCODE_SYNTAX_ERROR),
170 errmsg("unrecognized filter variable \"%s\"", def->defname)));
171 }
172
173 /* Validate tag list, if any. */
174 if ((strcmp(stmt->eventname, "ddl_command_start") == 0 ||
175 strcmp(stmt->eventname, "ddl_command_end") == 0 ||
176 strcmp(stmt->eventname, "sql_drop") == 0)
177 && tags != NULL)
178 validate_ddl_tags("tag", tags);
179 else if (strcmp(stmt->eventname, "table_rewrite") == 0
180 && tags != NULL)
181 validate_table_rewrite_tags("tag", tags);
182 else if (strcmp(stmt->eventname, "login") == 0 && tags != NULL)
184 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
185 errmsg("tag filtering is not supported for login event triggers")));
186
187 /*
188 * Give user a nice error message if an event trigger of the same name
189 * already exists.
190 */
191 tuple = SearchSysCache1(EVENTTRIGGERNAME, CStringGetDatum(stmt->trigname));
192 if (HeapTupleIsValid(tuple))
195 errmsg("event trigger \"%s\" already exists",
196 stmt->trigname)));
197
198 /* Find and validate the trigger function. */
199 funcoid = LookupFuncName(stmt->funcname, 0, NULL, false);
200 funcrettype = get_func_rettype(funcoid);
201 if (funcrettype != EVENT_TRIGGEROID)
203 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
204 errmsg("function %s must return type %s",
205 NameListToString(stmt->funcname), "event_trigger")));
206
207 /* Insert catalog entries. */
208 return insert_event_trigger_tuple(stmt->trigname, stmt->eventname,
209 evtowner, funcoid, tags);
210}
int errhint(const char *fmt,...)
Definition: elog.c:1321
static void validate_table_rewrite_tags(const char *filtervar, List *taglist)
static void validate_ddl_tags(const char *filtervar, List *taglist)
static void error_duplicate_filter_variable(const char *defname)
static Oid insert_event_trigger_tuple(const char *trigname, const char *eventname, Oid evtOwner, Oid funcoid, List *taglist)
Oid get_func_rettype(Oid funcid)
Definition: lsyscache.c:1822
char * NameListToString(const List *names)
Definition: namespace.c:3661
Oid LookupFuncName(List *funcname, int nargs, const Oid *argtypes, bool missing_ok)
Definition: parse_func.c:2260
#define lfirst(lc)
Definition: pg_list.h:172
#define ERRCODE_DUPLICATE_OBJECT
Definition: streamutil.c:30
char * defname
Definition: parsenodes.h:841
Node * arg
Definition: parsenodes.h:842
Definition: pg_list.h:54
bool superuser(void)
Definition: superuser.c:46
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:220

References DefElem::arg, CStringGetDatum(), DefElem::defname, ereport, errcode(), ERRCODE_DUPLICATE_OBJECT, errhint(), errmsg(), ERROR, error_duplicate_filter_variable(), get_func_rettype(), GetUserId(), HeapTupleIsValid, insert_event_trigger_tuple(), lfirst, LookupFuncName(), NameListToString(), SearchSysCache1(), stmt, superuser(), validate_ddl_tags(), and validate_table_rewrite_tags().

Referenced by standard_ProcessUtility().

◆ EventTriggerAlterTableEnd()

void EventTriggerAlterTableEnd ( void  )

Definition at line 1840 of file event_trigger.c.

1841{
1842 CollectedCommand *parent;
1843
1844 /* ignore if event trigger context not set, or collection disabled */
1847 return;
1848
1850
1851 /* If no subcommands, don't collect */
1853 {
1854 MemoryContext oldcxt;
1855
1857
1861
1862 MemoryContextSwitchTo(oldcxt);
1863 }
1864 else
1866
1868}
static EventTriggerQueryState * currentEventTriggerState
Definition: event_trigger.c:83
List * lappend(List *list, void *datum)
Definition: list.c:339
void pfree(void *pointer)
Definition: mcxt.c:1594
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:124
#define NIL
Definition: pg_list.h:68
union CollectedCommand::@129 d
struct CollectedCommand::@129::@131 alterTable
struct CollectedCommand * parent
CollectedCommand * currentCommand
Definition: event_trigger.c:77

References CollectedCommand::alterTable, EventTriggerQueryState::commandCollectionInhibited, EventTriggerQueryState::commandList, EventTriggerQueryState::currentCommand, currentEventTriggerState, EventTriggerQueryState::cxt, CollectedCommand::d, lappend(), MemoryContextSwitchTo(), NIL, CollectedCommand::parent, pfree(), and CollectedCommand::subcmds.

Referenced by AlterTableMoveAll(), ProcessUtilityForAlterTable(), and ProcessUtilitySlow().

◆ EventTriggerAlterTableRelid()

◆ EventTriggerAlterTableStart()

void EventTriggerAlterTableStart ( Node parsetree)

Definition at line 1753 of file event_trigger.c.

1754{
1755 MemoryContext oldcxt;
1756 CollectedCommand *command;
1757
1758 /* ignore if event trigger context not set, or collection disabled */
1761 return;
1762
1764
1765 command = palloc(sizeof(CollectedCommand));
1766
1767 command->type = SCT_AlterTable;
1769
1770 command->d.alterTable.classId = RelationRelationId;
1771 command->d.alterTable.objectId = InvalidOid;
1772 command->d.alterTable.subcmds = NIL;
1773 command->parsetree = copyObject(parsetree);
1774
1777
1778 MemoryContextSwitchTo(oldcxt);
1779}
@ SCT_AlterTable
bool creating_extension
Definition: extension.c:77
void * palloc(Size size)
Definition: mcxt.c:1365
#define copyObject(obj)
Definition: nodes.h:232
#define InvalidOid
Definition: postgres_ext.h:37
CollectedCommandType type

References CollectedCommand::alterTable, CollectedCommand::classId, EventTriggerQueryState::commandCollectionInhibited, copyObject, creating_extension, EventTriggerQueryState::currentCommand, currentEventTriggerState, EventTriggerQueryState::cxt, CollectedCommand::d, CollectedCommand::in_extension, InvalidOid, MemoryContextSwitchTo(), NIL, CollectedCommand::objectId, palloc(), CollectedCommand::parent, CollectedCommand::parsetree, SCT_AlterTable, CollectedCommand::subcmds, and CollectedCommand::type.

Referenced by AlterTableMoveAll(), ProcessUtilityForAlterTable(), and ProcessUtilitySlow().

◆ EventTriggerBeginCompleteQuery()

bool EventTriggerBeginCompleteQuery ( void  )

Definition at line 1183 of file event_trigger.c.

1184{
1186 MemoryContext cxt;
1187
1188 /*
1189 * Currently, sql_drop, table_rewrite, ddl_command_end events are the only
1190 * reason to have event trigger state at all; so if there are none, don't
1191 * install one.
1192 */
1194 return false;
1195
1197 "event trigger state",
1200 state->cxt = cxt;
1201 slist_init(&(state->SQLDropList));
1202 state->in_sql_drop = false;
1203 state->table_rewrite_oid = InvalidOid;
1204
1205 state->commandCollectionInhibited = currentEventTriggerState ?
1207 state->currentCommand = NULL;
1208 state->commandList = NIL;
1209 state->previous = currentEventTriggerState;
1211
1212 return true;
1213}
bool trackDroppedObjectsNeeded(void)
static void slist_init(slist_head *head)
Definition: ilist.h:986
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition: mcxt.c:1229
MemoryContext TopMemoryContext
Definition: mcxt.c:166
#define AllocSetContextCreate
Definition: memutils.h:129
#define ALLOCSET_DEFAULT_SIZES
Definition: memutils.h:160
Definition: regguts.h:323

References ALLOCSET_DEFAULT_SIZES, AllocSetContextCreate, EventTriggerQueryState::commandCollectionInhibited, currentEventTriggerState, InvalidOid, MemoryContextAlloc(), NIL, slist_init(), TopMemoryContext, and trackDroppedObjectsNeeded().

Referenced by ProcessUtilitySlow().

◆ EventTriggerCollectAlterDefPrivs()

void EventTriggerCollectAlterDefPrivs ( AlterDefaultPrivilegesStmt stmt)

Definition at line 2024 of file event_trigger.c.

2025{
2026 MemoryContext oldcxt;
2027 CollectedCommand *command;
2028
2029 /* ignore if event trigger context not set, or collection disabled */
2032 return;
2033
2035
2036 command = palloc0(sizeof(CollectedCommand));
2038 command->d.defprivs.objtype = stmt->action->objtype;
2040 command->parsetree = (Node *) copyObject(stmt);
2041
2044 MemoryContextSwitchTo(oldcxt);
2045}
@ SCT_AlterDefaultPrivileges
void * palloc0(Size size)
Definition: mcxt.c:1395
struct CollectedCommand::@129::@136 defprivs
Definition: nodes.h:135

References EventTriggerQueryState::commandCollectionInhibited, EventTriggerQueryState::commandList, copyObject, creating_extension, currentEventTriggerState, EventTriggerQueryState::cxt, CollectedCommand::d, CollectedCommand::defprivs, CollectedCommand::in_extension, lappend(), MemoryContextSwitchTo(), CollectedCommand::objtype, palloc0(), CollectedCommand::parsetree, SCT_AlterDefaultPrivileges, stmt, and CollectedCommand::type.

Referenced by ProcessUtilitySlow().

◆ EventTriggerCollectAlterOpFam()

void EventTriggerCollectAlterOpFam ( AlterOpFamilyStmt stmt,
Oid  opfamoid,
List operators,
List procedures 
)

Definition at line 1922 of file event_trigger.c.

1924{
1925 MemoryContext oldcxt;
1926 CollectedCommand *command;
1927
1928 /* ignore if event trigger context not set, or collection disabled */
1931 return;
1932
1934
1935 command = palloc(sizeof(CollectedCommand));
1936 command->type = SCT_AlterOpFamily;
1939 OperatorFamilyRelationId, opfamoid);
1940 command->d.opfam.operators = operators;
1941 command->d.opfam.procedures = procedures;
1942 command->parsetree = (Node *) copyObject(stmt);
1943
1946
1947 MemoryContextSwitchTo(oldcxt);
1948}
@ SCT_AlterOpFamily
struct CollectedCommand::@129::@133 opfam
ObjectAddress address

References CollectedCommand::address, EventTriggerQueryState::commandCollectionInhibited, EventTriggerQueryState::commandList, copyObject, creating_extension, currentEventTriggerState, EventTriggerQueryState::cxt, CollectedCommand::d, CollectedCommand::in_extension, lappend(), MemoryContextSwitchTo(), ObjectAddressSet, CollectedCommand::operators, CollectedCommand::opfam, palloc(), CollectedCommand::parsetree, CollectedCommand::procedures, SCT_AlterOpFamily, stmt, and CollectedCommand::type.

Referenced by AlterOpFamilyAdd(), and AlterOpFamilyDrop().

◆ EventTriggerCollectAlterTableSubcmd()

void EventTriggerCollectAlterTableSubcmd ( Node subcmd,
ObjectAddress  address 
)

Definition at line 1805 of file event_trigger.c.

1806{
1807 MemoryContext oldcxt;
1809
1810 /* ignore if event trigger context not set, or collection disabled */
1813 return;
1814
1815 Assert(IsA(subcmd, AlterTableCmd));
1818
1820
1821 newsub = palloc(sizeof(CollectedATSubcmd));
1822 newsub->address = address;
1823 newsub->parsetree = copyObject(subcmd);
1824
1827
1828 MemoryContextSwitchTo(oldcxt);
1829}
#define OidIsValid(objectId)
Definition: c.h:775
Assert(PointerIsAligned(start, uint64))
#define IsA(nodeptr, _type_)
Definition: nodes.h:164
static color newsub(struct colormap *cm, color co)
Definition: regc_color.c:389

References CollectedCommand::alterTable, Assert(), EventTriggerQueryState::commandCollectionInhibited, copyObject, EventTriggerQueryState::currentCommand, currentEventTriggerState, EventTriggerQueryState::cxt, CollectedCommand::d, IsA, lappend(), MemoryContextSwitchTo(), newsub(), CollectedCommand::objectId, OidIsValid, palloc(), and CollectedCommand::subcmds.

Referenced by ATExecCmd().

◆ EventTriggerCollectAlterTSConfig()

void EventTriggerCollectAlterTSConfig ( AlterTSConfigurationStmt stmt,
Oid  cfgId,
Oid dictIds,
int  ndicts 
)

Definition at line 1989 of file event_trigger.c.

1991{
1992 MemoryContext oldcxt;
1993 CollectedCommand *command;
1994
1995 /* ignore if event trigger context not set, or collection disabled */
1998 return;
1999
2001
2002 command = palloc0(sizeof(CollectedCommand));
2003 command->type = SCT_AlterTSConfig;
2006 TSConfigRelationId, cfgId);
2007 command->d.atscfg.dictIds = palloc(sizeof(Oid) * ndicts);
2008 memcpy(command->d.atscfg.dictIds, dictIds, sizeof(Oid) * ndicts);
2009 command->d.atscfg.ndicts = ndicts;
2010 command->parsetree = (Node *) copyObject(stmt);
2011
2014
2015 MemoryContextSwitchTo(oldcxt);
2016}
@ SCT_AlterTSConfig
struct CollectedCommand::@129::@135 atscfg

References CollectedCommand::address, CollectedCommand::atscfg, EventTriggerQueryState::commandCollectionInhibited, EventTriggerQueryState::commandList, copyObject, creating_extension, currentEventTriggerState, EventTriggerQueryState::cxt, CollectedCommand::d, CollectedCommand::dictIds, CollectedCommand::in_extension, lappend(), MemoryContextSwitchTo(), CollectedCommand::ndicts, ObjectAddressSet, palloc(), palloc0(), CollectedCommand::parsetree, SCT_AlterTSConfig, stmt, and CollectedCommand::type.

Referenced by DropConfigurationMapping(), and MakeConfigurationMapping().

◆ EventTriggerCollectCreateOpClass()

void EventTriggerCollectCreateOpClass ( CreateOpClassStmt stmt,
Oid  opcoid,
List operators,
List procedures 
)

Definition at line 1955 of file event_trigger.c.

1957{
1958 MemoryContext oldcxt;
1959 CollectedCommand *command;
1960
1961 /* ignore if event trigger context not set, or collection disabled */
1964 return;
1965
1967
1968 command = palloc0(sizeof(CollectedCommand));
1969 command->type = SCT_CreateOpClass;
1972 OperatorClassRelationId, opcoid);
1973 command->d.createopc.operators = operators;
1974 command->d.createopc.procedures = procedures;
1975 command->parsetree = (Node *) copyObject(stmt);
1976
1979
1980 MemoryContextSwitchTo(oldcxt);
1981}
@ SCT_CreateOpClass
struct CollectedCommand::@129::@134 createopc

References CollectedCommand::address, EventTriggerQueryState::commandCollectionInhibited, EventTriggerQueryState::commandList, copyObject, CollectedCommand::createopc, creating_extension, currentEventTriggerState, EventTriggerQueryState::cxt, CollectedCommand::d, CollectedCommand::in_extension, lappend(), MemoryContextSwitchTo(), ObjectAddressSet, CollectedCommand::operators, palloc0(), CollectedCommand::parsetree, CollectedCommand::procedures, SCT_CreateOpClass, stmt, and CollectedCommand::type.

Referenced by DefineOpClass().

◆ EventTriggerCollectGrant()

void EventTriggerCollectGrant ( InternalGrant istmt)

Definition at line 1878 of file event_trigger.c.

1879{
1880 MemoryContext oldcxt;
1881 CollectedCommand *command;
1882 InternalGrant *icopy;
1883 ListCell *cell;
1884
1885 /* ignore if event trigger context not set, or collection disabled */
1888 return;
1889
1891
1892 /*
1893 * This is tedious, but necessary.
1894 */
1895 icopy = palloc(sizeof(InternalGrant));
1896 memcpy(icopy, istmt, sizeof(InternalGrant));
1897 icopy->objects = list_copy(istmt->objects);
1898 icopy->grantees = list_copy(istmt->grantees);
1899 icopy->col_privs = NIL;
1900 foreach(cell, istmt->col_privs)
1901 icopy->col_privs = lappend(icopy->col_privs, copyObject(lfirst(cell)));
1902
1903 /* Now collect it, using the copied InternalGrant */
1904 command = palloc(sizeof(CollectedCommand));
1905 command->type = SCT_Grant;
1907 command->d.grant.istmt = icopy;
1908 command->parsetree = NULL;
1909
1912
1913 MemoryContextSwitchTo(oldcxt);
1914}
@ SCT_Grant
List * list_copy(const List *oldlist)
Definition: list.c:1573
InternalGrant * istmt
struct CollectedCommand::@129::@132 grant

References InternalGrant::col_privs, EventTriggerQueryState::commandCollectionInhibited, EventTriggerQueryState::commandList, copyObject, creating_extension, currentEventTriggerState, EventTriggerQueryState::cxt, CollectedCommand::d, CollectedCommand::grant, InternalGrant::grantees, CollectedCommand::in_extension, CollectedCommand::istmt, lappend(), lfirst, list_copy(), MemoryContextSwitchTo(), NIL, InternalGrant::objects, palloc(), CollectedCommand::parsetree, SCT_Grant, and CollectedCommand::type.

Referenced by ExecGrantStmt_oids().

◆ EventTriggerCollectSimpleCommand()

void EventTriggerCollectSimpleCommand ( ObjectAddress  address,
ObjectAddress  secondaryObject,
Node parsetree 
)

Definition at line 1715 of file event_trigger.c.

1718{
1719 MemoryContext oldcxt;
1720 CollectedCommand *command;
1721
1722 /* ignore if event trigger context not set, or collection disabled */
1725 return;
1726
1728
1729 command = palloc(sizeof(CollectedCommand));
1730
1731 command->type = SCT_Simple;
1733
1734 command->d.simple.address = address;
1735 command->d.simple.secondaryObject = secondaryObject;
1736 command->parsetree = copyObject(parsetree);
1737
1739 command);
1740
1741 MemoryContextSwitchTo(oldcxt);
1742}
@ SCT_Simple
struct CollectedCommand::@129::@130 simple
ObjectAddress secondaryObject

References CollectedCommand::address, EventTriggerQueryState::commandCollectionInhibited, EventTriggerQueryState::commandList, copyObject, creating_extension, currentEventTriggerState, EventTriggerQueryState::cxt, CollectedCommand::d, CollectedCommand::in_extension, lappend(), MemoryContextSwitchTo(), palloc(), CollectedCommand::parsetree, SCT_Simple, CollectedCommand::secondaryObject, CollectedCommand::simple, and CollectedCommand::type.

Referenced by AlterPublicationOptions(), CreateOpFamily(), CreateSchemaCommand(), ProcessUtilitySlow(), PublicationAddSchemas(), PublicationAddTables(), reindex_index(), and ReindexRelationConcurrently().

◆ EventTriggerDDLCommandEnd()

void EventTriggerDDLCommandEnd ( Node parsetree)

Definition at line 776 of file event_trigger.c.

777{
778 List *runlist;
779 EventTriggerData trigdata;
780
781 /*
782 * See EventTriggerDDLCommandStart for a discussion about why event
783 * triggers are disabled in single user mode or via GUC.
784 */
786 return;
787
788 /*
789 * Also do nothing if our state isn't set up, which it won't be if there
790 * weren't any relevant event triggers at the start of the current DDL
791 * command. This test might therefore seem optional, but it's important
792 * because EventTriggerCommonSetup might find triggers that didn't exist
793 * at the time the command started. Although this function itself
794 * wouldn't crash, the event trigger functions would presumably call
795 * pg_event_trigger_ddl_commands which would fail. Better to do nothing
796 * until the next command.
797 */
799 return;
800
801 runlist = EventTriggerCommonSetup(parsetree,
802 EVT_DDLCommandEnd, "ddl_command_end",
803 &trigdata, false);
804 if (runlist == NIL)
805 return;
806
807 /*
808 * Make sure anything the main command did will be visible to the event
809 * triggers.
810 */
812
813 /* Run the triggers. */
814 EventTriggerInvoke(runlist, &trigdata);
815
816 /* Cleanup. */
817 list_free(runlist);
818}
bool event_triggers
Definition: event_trigger.c:86
static List * EventTriggerCommonSetup(Node *parsetree, EventTriggerEvent event, const char *eventstr, EventTriggerData *trigdata, bool unfiltered)
static void EventTriggerInvoke(List *fn_oid_list, EventTriggerData *trigdata)
@ EVT_DDLCommandEnd
Definition: evtcache.h:23
bool IsUnderPostmaster
Definition: globals.c:120
void list_free(List *list)
Definition: list.c:1546
void CommandCounterIncrement(void)
Definition: xact.c:1100

References CommandCounterIncrement(), currentEventTriggerState, event_triggers, EventTriggerCommonSetup(), EventTriggerInvoke(), EVT_DDLCommandEnd, IsUnderPostmaster, list_free(), and NIL.

Referenced by ProcessUtilitySlow().

◆ EventTriggerDDLCommandStart()

void EventTriggerDDLCommandStart ( Node parsetree)

Definition at line 725 of file event_trigger.c.

726{
727 List *runlist;
728 EventTriggerData trigdata;
729
730 /*
731 * Event Triggers are completely disabled in standalone mode. There are
732 * (at least) two reasons for this:
733 *
734 * 1. A sufficiently broken event trigger might not only render the
735 * database unusable, but prevent disabling itself to fix the situation.
736 * In this scenario, restarting in standalone mode provides an escape
737 * hatch.
738 *
739 * 2. BuildEventTriggerCache relies on systable_beginscan_ordered, and
740 * therefore will malfunction if pg_event_trigger's indexes are damaged.
741 * To allow recovery from a damaged index, we need some operating mode
742 * wherein event triggers are disabled. (Or we could implement
743 * heapscan-and-sort logic for that case, but having disaster recovery
744 * scenarios depend on code that's otherwise untested isn't appetizing.)
745 *
746 * Additionally, event triggers can be disabled with a superuser-only GUC
747 * to make fixing database easier as per 1 above.
748 */
750 return;
751
752 runlist = EventTriggerCommonSetup(parsetree,
754 "ddl_command_start",
755 &trigdata, false);
756 if (runlist == NIL)
757 return;
758
759 /* Run the triggers. */
760 EventTriggerInvoke(runlist, &trigdata);
761
762 /* Cleanup. */
763 list_free(runlist);
764
765 /*
766 * Make sure anything the event triggers did will be visible to the main
767 * command.
768 */
770}
@ EVT_DDLCommandStart
Definition: evtcache.h:22

References CommandCounterIncrement(), event_triggers, EventTriggerCommonSetup(), EventTriggerInvoke(), EVT_DDLCommandStart, IsUnderPostmaster, list_free(), and NIL.

Referenced by ProcessUtilitySlow().

◆ EventTriggerEndCompleteQuery()

void EventTriggerEndCompleteQuery ( void  )

Definition at line 1227 of file event_trigger.c.

1228{
1229 EventTriggerQueryState *prevstate;
1230
1232
1233 /* this avoids the need for retail pfree of SQLDropList items: */
1235
1236 currentEventTriggerState = prevstate;
1237}
void MemoryContextDelete(MemoryContext context)
Definition: mcxt.c:469
struct EventTriggerQueryState * previous
Definition: event_trigger.c:80

References currentEventTriggerState, EventTriggerQueryState::cxt, MemoryContextDelete(), and EventTriggerQueryState::previous.

Referenced by ProcessUtilitySlow().

◆ EventTriggerInhibitCommandCollection()

void EventTriggerInhibitCommandCollection ( void  )

◆ EventTriggerOnLogin()

void EventTriggerOnLogin ( void  )

Definition at line 897 of file event_trigger.c.

898{
899 List *runlist;
900 EventTriggerData trigdata;
901
902 /*
903 * See EventTriggerDDLCommandStart for a discussion about why event
904 * triggers are disabled in single user mode or via a GUC. We also need a
905 * database connection (some background workers don't have it).
906 */
909 return;
910
912 runlist = EventTriggerCommonSetup(NULL,
913 EVT_Login, "login",
914 &trigdata, false);
915
916 if (runlist != NIL)
917 {
918 /*
919 * Event trigger execution may require an active snapshot.
920 */
922
923 /* Run the triggers. */
924 EventTriggerInvoke(runlist, &trigdata);
925
926 /* Cleanup. */
927 list_free(runlist);
928
930 }
931
932 /*
933 * There is no active login event trigger, but our
934 * pg_database.dathasloginevt is set. Try to unset this flag. We use the
935 * lock to prevent concurrent SetDatabaseHasLoginEventTriggers(), but we
936 * don't want to hang the connection waiting on the lock. Thus, we are
937 * just trying to acquire the lock conditionally.
938 */
939 else if (ConditionalLockSharedObject(DatabaseRelationId, MyDatabaseId,
941 {
942 /*
943 * The lock is held. Now we need to recheck that login event triggers
944 * list is still empty. Once the list is empty, we know that even if
945 * there is a backend which concurrently inserts/enables a login event
946 * trigger, it will update pg_database.dathasloginevt *afterwards*.
947 */
948 runlist = EventTriggerCommonSetup(NULL,
949 EVT_Login, "login",
950 &trigdata, true);
951
952 if (runlist == NIL)
953 {
954 Relation pg_db = table_open(DatabaseRelationId, RowExclusiveLock);
955 HeapTuple tuple;
956 void *state;
958 ScanKeyData key[1];
959
960 /* Fetch a copy of the tuple to scribble on */
961 ScanKeyInit(&key[0],
962 Anum_pg_database_oid,
963 BTEqualStrategyNumber, F_OIDEQ,
965
966 systable_inplace_update_begin(pg_db, DatabaseOidIndexId, true,
967 NULL, 1, key, &tuple, &state);
968
969 if (!HeapTupleIsValid(tuple))
970 elog(ERROR, "could not find tuple for database %u", MyDatabaseId);
971
972 db = (Form_pg_database) GETSTRUCT(tuple);
973 if (db->dathasloginevt)
974 {
975 db->dathasloginevt = false;
976
977 /*
978 * Do an "in place" update of the pg_database tuple. Doing
979 * this instead of regular updates serves two purposes. First,
980 * that avoids possible waiting on the row-level lock. Second,
981 * that avoids dealing with TOAST.
982 */
984 }
985 else
988 heap_freetuple(tuple);
989 }
990 else
991 {
992 list_free(runlist);
993 }
994 }
996}
#define elog(elevel,...)
Definition: elog.h:226
@ EVT_Login
Definition: evtcache.h:26
void systable_inplace_update_cancel(void *state)
Definition: genam.c:902
void systable_inplace_update_begin(Relation relation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, const ScanKeyData *key, HeapTuple *oldtupcopy, void **state)
Definition: genam.c:807
void systable_inplace_update_finish(void *state, HeapTuple tuple)
Definition: genam.c:883
bool MyDatabaseHasLoginEventTriggers
Definition: globals.c:98
Oid MyDatabaseId
Definition: globals.c:94
bool ConditionalLockSharedObject(Oid classid, Oid objid, uint16 objsubid, LOCKMODE lockmode)
Definition: lmgr.c:1112
#define AccessExclusiveLock
Definition: lockdefs.h:43
FormData_pg_database * Form_pg_database
Definition: pg_database.h:96
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
Snapshot GetTransactionSnapshot(void)
Definition: snapmgr.c:271
void PushActiveSnapshot(Snapshot snapshot)
Definition: snapmgr.c:680
void PopActiveSnapshot(void)
Definition: snapmgr.c:773
#define BTEqualStrategyNumber
Definition: stratnum.h:31
void StartTransactionCommand(void)
Definition: xact.c:3071
void CommitTransactionCommand(void)
Definition: xact.c:3169

References AccessExclusiveLock, BTEqualStrategyNumber, CommitTransactionCommand(), ConditionalLockSharedObject(), elog, ERROR, event_triggers, EventTriggerCommonSetup(), EventTriggerInvoke(), EVT_Login, GETSTRUCT(), GetTransactionSnapshot(), heap_freetuple(), HeapTupleIsValid, IsUnderPostmaster, sort-test::key, list_free(), MyDatabaseHasLoginEventTriggers, MyDatabaseId, NIL, ObjectIdGetDatum(), OidIsValid, PopActiveSnapshot(), PushActiveSnapshot(), RowExclusiveLock, ScanKeyInit(), StartTransactionCommand(), systable_inplace_update_begin(), systable_inplace_update_cancel(), systable_inplace_update_finish(), table_close(), and table_open().

Referenced by PostgresMain().

◆ EventTriggerSQLDrop()

void EventTriggerSQLDrop ( Node parsetree)

Definition at line 824 of file event_trigger.c.

825{
826 List *runlist;
827 EventTriggerData trigdata;
828
829 /*
830 * See EventTriggerDDLCommandStart for a discussion about why event
831 * triggers are disabled in single user mode or via a GUC.
832 */
834 return;
835
836 /*
837 * Use current state to determine whether this event fires at all. If
838 * there are no triggers for the sql_drop event, then we don't have
839 * anything to do here. Note that dropped object collection is disabled
840 * if this is the case, so even if we were to try to run, the list would
841 * be empty.
842 */
845 return;
846
847 runlist = EventTriggerCommonSetup(parsetree,
848 EVT_SQLDrop, "sql_drop",
849 &trigdata, false);
850
851 /*
852 * Nothing to do if run list is empty. Note this typically can't happen,
853 * because if there are no sql_drop events, then objects-to-drop wouldn't
854 * have been collected in the first place and we would have quit above.
855 * But it could occur if event triggers were dropped partway through.
856 */
857 if (runlist == NIL)
858 return;
859
860 /*
861 * Make sure anything the main command did will be visible to the event
862 * triggers.
863 */
865
866 /*
867 * Make sure pg_event_trigger_dropped_objects only works when running
868 * these triggers. Use PG_TRY to ensure in_sql_drop is reset even when
869 * one trigger fails. (This is perhaps not necessary, as the currentState
870 * variable will be removed shortly by our caller, but it seems better to
871 * play safe.)
872 */
874
875 /* Run the triggers. */
876 PG_TRY();
877 {
878 EventTriggerInvoke(runlist, &trigdata);
879 }
880 PG_FINALLY();
881 {
883 }
884 PG_END_TRY();
885
886 /* Cleanup. */
887 list_free(runlist);
888}
#define PG_TRY(...)
Definition: elog.h:372
#define PG_END_TRY(...)
Definition: elog.h:397
#define PG_FINALLY(...)
Definition: elog.h:389
@ EVT_SQLDrop
Definition: evtcache.h:24
static bool slist_is_empty(const slist_head *head)
Definition: ilist.h:995

References CommandCounterIncrement(), currentEventTriggerState, event_triggers, EventTriggerCommonSetup(), EventTriggerInvoke(), EVT_SQLDrop, EventTriggerQueryState::in_sql_drop, IsUnderPostmaster, list_free(), NIL, PG_END_TRY, PG_FINALLY, PG_TRY, slist_is_empty(), and EventTriggerQueryState::SQLDropList.

Referenced by ProcessUtilitySlow().

◆ EventTriggerSQLDropAddObject()

void EventTriggerSQLDropAddObject ( const ObjectAddress object,
bool  original,
bool  normal 
)

Definition at line 1277 of file event_trigger.c.

1278{
1279 SQLDropObject *obj;
1280 MemoryContext oldcxt;
1281
1283 return;
1284
1286
1288
1289 obj = palloc0(sizeof(SQLDropObject));
1290 obj->address = *object;
1291 obj->original = original;
1292 obj->normal = normal;
1293
1294 if (object->classId == NamespaceRelationId)
1295 {
1296 /* Special handling is needed for temp namespaces */
1297 if (isTempNamespace(object->objectId))
1298 obj->istemp = true;
1299 else if (isAnyTempNamespace(object->objectId))
1300 {
1301 /* don't report temp schemas except my own */
1302 pfree(obj);
1303 MemoryContextSwitchTo(oldcxt);
1304 return;
1305 }
1306 obj->objname = get_namespace_name(object->objectId);
1307 }
1308 else if (object->classId == AttrDefaultRelationId)
1309 {
1310 /* We treat a column default as temp if its table is temp */
1311 ObjectAddress colobject;
1312
1313 colobject = GetAttrDefaultColumnAddress(object->objectId);
1314 if (OidIsValid(colobject.objectId))
1315 {
1316 if (!obtain_object_name_namespace(&colobject, obj))
1317 {
1318 pfree(obj);
1319 MemoryContextSwitchTo(oldcxt);
1320 return;
1321 }
1322 }
1323 }
1324 else if (object->classId == TriggerRelationId)
1325 {
1326 /* Similarly, a trigger is temp if its table is temp */
1327 /* Sadly, there's no lsyscache.c support for trigger objects */
1328 Relation pg_trigger_rel;
1329 ScanKeyData skey[1];
1330 SysScanDesc sscan;
1331 HeapTuple tuple;
1332 Oid relid;
1333
1334 /* Fetch the trigger's table OID the hard way */
1335 pg_trigger_rel = table_open(TriggerRelationId, AccessShareLock);
1336 ScanKeyInit(&skey[0],
1337 Anum_pg_trigger_oid,
1338 BTEqualStrategyNumber, F_OIDEQ,
1339 ObjectIdGetDatum(object->objectId));
1340 sscan = systable_beginscan(pg_trigger_rel, TriggerOidIndexId, true,
1341 NULL, 1, skey);
1342 tuple = systable_getnext(sscan);
1343 if (HeapTupleIsValid(tuple))
1344 relid = ((Form_pg_trigger) GETSTRUCT(tuple))->tgrelid;
1345 else
1346 relid = InvalidOid; /* shouldn't happen */
1347 systable_endscan(sscan);
1348 table_close(pg_trigger_rel, AccessShareLock);
1349 /* Do nothing if we didn't find the trigger */
1350 if (OidIsValid(relid))
1351 {
1352 ObjectAddress relobject;
1353
1354 relobject.classId = RelationRelationId;
1355 relobject.objectId = relid;
1356 /* Arbitrarily set objectSubId nonzero so as not to fill objname */
1357 relobject.objectSubId = 1;
1358 if (!obtain_object_name_namespace(&relobject, obj))
1359 {
1360 pfree(obj);
1361 MemoryContextSwitchTo(oldcxt);
1362 return;
1363 }
1364 }
1365 }
1366 else if (object->classId == PolicyRelationId)
1367 {
1368 /* Similarly, a policy is temp if its table is temp */
1369 /* Sadly, there's no lsyscache.c support for policy objects */
1370 Relation pg_policy_rel;
1371 ScanKeyData skey[1];
1372 SysScanDesc sscan;
1373 HeapTuple tuple;
1374 Oid relid;
1375
1376 /* Fetch the policy's table OID the hard way */
1377 pg_policy_rel = table_open(PolicyRelationId, AccessShareLock);
1378 ScanKeyInit(&skey[0],
1379 Anum_pg_policy_oid,
1380 BTEqualStrategyNumber, F_OIDEQ,
1381 ObjectIdGetDatum(object->objectId));
1382 sscan = systable_beginscan(pg_policy_rel, PolicyOidIndexId, true,
1383 NULL, 1, skey);
1384 tuple = systable_getnext(sscan);
1385 if (HeapTupleIsValid(tuple))
1386 relid = ((Form_pg_policy) GETSTRUCT(tuple))->polrelid;
1387 else
1388 relid = InvalidOid; /* shouldn't happen */
1389 systable_endscan(sscan);
1390 table_close(pg_policy_rel, AccessShareLock);
1391 /* Do nothing if we didn't find the policy */
1392 if (OidIsValid(relid))
1393 {
1394 ObjectAddress relobject;
1395
1396 relobject.classId = RelationRelationId;
1397 relobject.objectId = relid;
1398 /* Arbitrarily set objectSubId nonzero so as not to fill objname */
1399 relobject.objectSubId = 1;
1400 if (!obtain_object_name_namespace(&relobject, obj))
1401 {
1402 pfree(obj);
1403 MemoryContextSwitchTo(oldcxt);
1404 return;
1405 }
1406 }
1407 }
1408 else
1409 {
1410 /* Generic handling for all other object classes */
1411 if (!obtain_object_name_namespace(object, obj))
1412 {
1413 /* don't report temp objects except my own */
1414 pfree(obj);
1415 MemoryContextSwitchTo(oldcxt);
1416 return;
1417 }
1418 }
1419
1420 /* object identity, objname and objargs */
1421 obj->objidentity =
1423 false);
1424
1425 /* object type */
1426 obj->objecttype = getObjectTypeDescription(&obj->address, false);
1427
1429
1430 MemoryContextSwitchTo(oldcxt);
1431}
static bool obtain_object_name_namespace(const ObjectAddress *object, SQLDropObject *obj)
bool EventTriggerSupportsObject(const ObjectAddress *object)
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:603
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:514
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:388
static void slist_push_head(slist_head *head, slist_node *node)
Definition: ilist.h:1006
#define AccessShareLock
Definition: lockdefs.h:36
char * get_namespace_name(Oid nspid)
Definition: lsyscache.c:3533
bool isTempNamespace(Oid namespaceId)
Definition: namespace.c:3716
bool isAnyTempNamespace(Oid namespaceId)
Definition: namespace.c:3754
char * getObjectTypeDescription(const ObjectAddress *object, bool missing_ok)
char * getObjectIdentityParts(const ObjectAddress *object, List **objname, List **objargs, bool missing_ok)
ObjectAddress GetAttrDefaultColumnAddress(Oid attrdefoid)
Definition: pg_attrdef.c:320
FormData_pg_policy * Form_pg_policy
Definition: pg_policy.h:51
FormData_pg_trigger * Form_pg_trigger
Definition: pg_trigger.h:80
ObjectAddress address
Definition: event_trigger.c:91
slist_node next
const char * objidentity
Definition: event_trigger.c:94
const char * objecttype
Definition: event_trigger.c:95
List * addrnames
Definition: event_trigger.c:96
const char * objname
Definition: event_trigger.c:93

References AccessShareLock, SQLDropObject::addrargs, SQLDropObject::address, SQLDropObject::addrnames, Assert(), BTEqualStrategyNumber, ObjectAddress::classId, currentEventTriggerState, EventTriggerQueryState::cxt, EventTriggerSupportsObject(), get_namespace_name(), GetAttrDefaultColumnAddress(), getObjectIdentityParts(), getObjectTypeDescription(), GETSTRUCT(), HeapTupleIsValid, InvalidOid, isAnyTempNamespace(), SQLDropObject::istemp, isTempNamespace(), MemoryContextSwitchTo(), SQLDropObject::next, SQLDropObject::normal, ObjectAddress::objectId, ObjectIdGetDatum(), ObjectAddress::objectSubId, SQLDropObject::objecttype, SQLDropObject::objidentity, SQLDropObject::objname, obtain_object_name_namespace(), OidIsValid, SQLDropObject::original, palloc0(), pfree(), ScanKeyInit(), slist_push_head(), EventTriggerQueryState::SQLDropList, systable_beginscan(), systable_endscan(), systable_getnext(), table_close(), and table_open().

Referenced by deleteObjectsInList(), and DropSubscription().

◆ EventTriggerSupportsObject()

bool EventTriggerSupportsObject ( const ObjectAddress object)

Definition at line 1157 of file event_trigger.c.

1158{
1159 switch (object->classId)
1160 {
1161 case DatabaseRelationId:
1162 case TableSpaceRelationId:
1163 case AuthIdRelationId:
1164 case AuthMemRelationId:
1165 case ParameterAclRelationId:
1166 /* no support for global objects (except subscriptions) */
1167 return false;
1168 case EventTriggerRelationId:
1169 /* no support for event triggers on event triggers */
1170 return false;
1171 default:
1172 return true;
1173 }
1174}

References ObjectAddress::classId.

Referenced by deleteObjectsInList(), and EventTriggerSQLDropAddObject().

◆ EventTriggerSupportsObjectType()

bool EventTriggerSupportsObjectType ( ObjectType  obtype)

Definition at line 1133 of file event_trigger.c.

1134{
1135 switch (obtype)
1136 {
1137 case OBJECT_DATABASE:
1138 case OBJECT_TABLESPACE:
1139 case OBJECT_ROLE:
1141 /* no support for global objects (except subscriptions) */
1142 return false;
1144 /* no support for event triggers on event triggers */
1145 return false;
1146 default:
1147 return true;
1148 }
1149}
@ OBJECT_TABLESPACE
Definition: parsenodes.h:2364
@ OBJECT_ROLE
Definition: parsenodes.h:2355
@ OBJECT_DATABASE
Definition: parsenodes.h:2331
@ OBJECT_PARAMETER_ACL
Definition: parsenodes.h:2349

References OBJECT_DATABASE, OBJECT_EVENT_TRIGGER, OBJECT_PARAMETER_ACL, OBJECT_ROLE, and OBJECT_TABLESPACE.

Referenced by ExecGrantStmt_oids(), and standard_ProcessUtility().

◆ EventTriggerTableRewrite()

void EventTriggerTableRewrite ( Node parsetree,
Oid  tableOid,
int  reason 
)

Definition at line 1003 of file event_trigger.c.

1004{
1005 List *runlist;
1006 EventTriggerData trigdata;
1007
1008 /*
1009 * See EventTriggerDDLCommandStart for a discussion about why event
1010 * triggers are disabled in single user mode or via a GUC.
1011 */
1013 return;
1014
1015 /*
1016 * Also do nothing if our state isn't set up, which it won't be if there
1017 * weren't any relevant event triggers at the start of the current DDL
1018 * command. This test might therefore seem optional, but it's
1019 * *necessary*, because EventTriggerCommonSetup might find triggers that
1020 * didn't exist at the time the command started.
1021 */
1023 return;
1024
1025 runlist = EventTriggerCommonSetup(parsetree,
1027 "table_rewrite",
1028 &trigdata, false);
1029 if (runlist == NIL)
1030 return;
1031
1032 /*
1033 * Make sure pg_event_trigger_table_rewrite_oid only works when running
1034 * these triggers. Use PG_TRY to ensure table_rewrite_oid is reset even
1035 * when one trigger fails. (This is perhaps not necessary, as the
1036 * currentState variable will be removed shortly by our caller, but it
1037 * seems better to play safe.)
1038 */
1041
1042 /* Run the triggers. */
1043 PG_TRY();
1044 {
1045 EventTriggerInvoke(runlist, &trigdata);
1046 }
1047 PG_FINALLY();
1048 {
1051 }
1052 PG_END_TRY();
1053
1054 /* Cleanup. */
1055 list_free(runlist);
1056
1057 /*
1058 * Make sure anything the event triggers did will be visible to the main
1059 * command.
1060 */
1062}
@ EVT_TableRewrite
Definition: evtcache.h:25

References CommandCounterIncrement(), currentEventTriggerState, event_triggers, EventTriggerCommonSetup(), EventTriggerInvoke(), EVT_TableRewrite, InvalidOid, IsUnderPostmaster, list_free(), NIL, PG_END_TRY, PG_FINALLY, PG_TRY, EventTriggerQueryState::table_rewrite_oid, and EventTriggerQueryState::table_rewrite_reason.

Referenced by ATRewriteTables().

◆ EventTriggerUndoInhibitCommandCollection()

void EventTriggerUndoInhibitCommandCollection ( void  )

Definition at line 1693 of file event_trigger.c.

1694{
1696 return;
1697
1699}

References EventTriggerQueryState::commandCollectionInhibited, and currentEventTriggerState.

Referenced by ProcessUtilitySlow().

◆ get_event_trigger_oid()

Oid get_event_trigger_oid ( const char *  trigname,
bool  missing_ok 
)

Definition at line 579 of file event_trigger.c.

580{
581 Oid oid;
582
583 oid = GetSysCacheOid1(EVENTTRIGGERNAME, Anum_pg_event_trigger_oid,
584 CStringGetDatum(trigname));
585 if (!OidIsValid(oid) && !missing_ok)
587 (errcode(ERRCODE_UNDEFINED_OBJECT),
588 errmsg("event trigger \"%s\" does not exist", trigname)));
589 return oid;
590}
#define GetSysCacheOid1(cacheId, oidcol, key1)
Definition: syscache.h:109

References CStringGetDatum(), ereport, errcode(), errmsg(), ERROR, GetSysCacheOid1, and OidIsValid.

Referenced by get_object_address_unqualified().

◆ trackDroppedObjectsNeeded()

bool trackDroppedObjectsNeeded ( void  )

Definition at line 1245 of file event_trigger.c.

1246{
1247 /*
1248 * true if any sql_drop, table_rewrite, ddl_command_end event trigger
1249 * exists
1250 */
1251 return (EventCacheLookup(EVT_SQLDrop) != NIL) ||
1254}
List * EventCacheLookup(EventTriggerEvent event)
Definition: evtcache.c:63

References EventCacheLookup(), EVT_DDLCommandEnd, EVT_SQLDrop, EVT_TableRewrite, and NIL.

Referenced by deleteObjectsInList(), and EventTriggerBeginCompleteQuery().

Variable Documentation

◆ event_triggers