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 EventTriggerSupportsObjectClass (ObjectClass objclass)
 
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 37 of file event_trigger.h.

◆ AT_REWRITE_ALTER_PERSISTENCE

#define AT_REWRITE_ALTER_PERSISTENCE   0x01

Definition at line 34 of file event_trigger.h.

◆ AT_REWRITE_COLUMN_REWRITE

#define AT_REWRITE_COLUMN_REWRITE   0x04

Definition at line 36 of file event_trigger.h.

◆ AT_REWRITE_DEFAULT_VAL

#define AT_REWRITE_DEFAULT_VAL   0x02

Definition at line 35 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 43 of file event_trigger.h.

Typedef Documentation

◆ EventTriggerData

Function Documentation

◆ AlterEventTrigger()

Oid AlterEventTrigger ( AlterEventTrigStmt stmt)

Definition at line 416 of file event_trigger.c.

417 {
418  Relation tgrel;
419  HeapTuple tup;
420  Oid trigoid;
421  Form_pg_event_trigger evtForm;
422  char tgenabled = stmt->tgenabled;
423 
424  tgrel = table_open(EventTriggerRelationId, RowExclusiveLock);
425 
426  tup = SearchSysCacheCopy1(EVENTTRIGGERNAME,
427  CStringGetDatum(stmt->trigname));
428  if (!HeapTupleIsValid(tup))
429  ereport(ERROR,
430  (errcode(ERRCODE_UNDEFINED_OBJECT),
431  errmsg("event trigger \"%s\" does not exist",
432  stmt->trigname)));
433 
434  evtForm = (Form_pg_event_trigger) GETSTRUCT(tup);
435  trigoid = evtForm->oid;
436 
437  if (!object_ownercheck(EventTriggerRelationId, trigoid, GetUserId()))
439  stmt->trigname);
440 
441  /* tuple is a copy, so we can modify it below */
442  evtForm->evtenabled = tgenabled;
443 
444  CatalogTupleUpdate(tgrel, &tup->t_self, tup);
445 
446  /*
447  * Login event triggers have an additional flag in pg_database to enable
448  * faster lookups in hot codepaths. Set the flag unless already True.
449  */
450  if (namestrcmp(&evtForm->evtevent, "login") == 0 &&
451  tgenabled != TRIGGER_DISABLED)
453 
454  InvokeObjectPostAlterHook(EventTriggerRelationId,
455  trigoid, 0);
456 
457  /* clean up */
458  heap_freetuple(tup);
460 
461  return trigoid;
462 }
@ ACLCHECK_NOT_OWNER
Definition: acl.h:185
void aclcheck_error(AclResult aclerr, ObjectType objtype, const char *objectname)
Definition: aclchk.c:2688
bool object_ownercheck(Oid classid, Oid objectid, Oid roleid)
Definition: aclchk.c:4130
int errcode(int sqlerrcode)
Definition: elog.c:859
int errmsg(const char *fmt,...)
Definition: elog.c:1072
#define ERROR
Definition: elog.h:39
#define ereport(elevel,...)
Definition: elog.h:149
static void SetDatatabaseHasLoginEventTriggers(void)
void heap_freetuple(HeapTuple htup)
Definition: heaptuple.c:1434
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
#define GETSTRUCT(TUP)
Definition: htup_details.h:653
#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:514
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:2123
FormData_pg_event_trigger * Form_pg_event_trigger
static Datum CStringGetDatum(const char *X)
Definition: postgres.h:350
unsigned int Oid
Definition: postgres_ext.h:31
ItemPointerData t_self
Definition: htup.h:65
#define SearchSysCacheCopy1(cacheId, key1)
Definition: syscache.h:86
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, SetDatatabaseHasLoginEventTriggers(), 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 468 of file event_trigger.c.

469 {
470  Oid evtOid;
471  HeapTuple tup;
472  Form_pg_event_trigger evtForm;
473  Relation rel;
474  ObjectAddress address;
475 
476  rel = table_open(EventTriggerRelationId, RowExclusiveLock);
477 
478  tup = SearchSysCacheCopy1(EVENTTRIGGERNAME, CStringGetDatum(name));
479 
480  if (!HeapTupleIsValid(tup))
481  ereport(ERROR,
482  (errcode(ERRCODE_UNDEFINED_OBJECT),
483  errmsg("event trigger \"%s\" does not exist", name)));
484 
485  evtForm = (Form_pg_event_trigger) GETSTRUCT(tup);
486  evtOid = evtForm->oid;
487 
488  AlterEventTriggerOwner_internal(rel, tup, newOwnerId);
489 
490  ObjectAddressSet(address, EventTriggerRelationId, evtOid);
491 
492  heap_freetuple(tup);
493 
495 
496  return address;
497 }
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 503 of file event_trigger.c.

504 {
505  HeapTuple tup;
506  Relation rel;
507 
508  rel = table_open(EventTriggerRelationId, RowExclusiveLock);
509 
510  tup = SearchSysCacheCopy1(EVENTTRIGGEROID, ObjectIdGetDatum(trigOid));
511 
512  if (!HeapTupleIsValid(tup))
513  ereport(ERROR,
514  (errcode(ERRCODE_UNDEFINED_OBJECT),
515  errmsg("event trigger with OID %u does not exist", trigOid)));
516 
517  AlterEventTriggerOwner_internal(rel, tup, newOwnerId);
518 
519  heap_freetuple(tup);
520 
522 }
static Datum ObjectIdGetDatum(Oid X)
Definition: postgres.h:252

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

Referenced by shdepReassignOwned().

◆ CreateEventTrigger()

Oid CreateEventTrigger ( CreateEventTrigStmt stmt)

Definition at line 116 of file event_trigger.c.

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

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 1803 of file event_trigger.c.

1804 {
1805  CollectedCommand *parent;
1806 
1807  /* ignore if event trigger context not set, or collection disabled */
1808  if (!currentEventTriggerState ||
1810  return;
1811 
1813 
1814  /* If no subcommands, don't collect */
1816  {
1817  MemoryContext oldcxt;
1818 
1820 
1824 
1825  MemoryContextSwitchTo(oldcxt);
1826  }
1827  else
1829 
1831 }
static EventTriggerQueryState * currentEventTriggerState
Definition: event_trigger.c:77
List * lappend(List *list, void *datum)
Definition: list.c:339
void pfree(void *pointer)
Definition: mcxt.c:1508
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:124
#define NIL
Definition: pg_list.h:68
struct CollectedCommand::@113::@115 alterTable
struct CollectedCommand * parent
union CollectedCommand::@113 d
CollectedCommand * currentCommand
Definition: event_trigger.c:71

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

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

◆ EventTriggerAlterTableRelid()

◆ EventTriggerAlterTableStart()

void EventTriggerAlterTableStart ( Node parsetree)

Definition at line 1716 of file event_trigger.c.

1717 {
1718  MemoryContext oldcxt;
1719  CollectedCommand *command;
1720 
1721  /* ignore if event trigger context not set, or collection disabled */
1722  if (!currentEventTriggerState ||
1724  return;
1725 
1727 
1728  command = palloc(sizeof(CollectedCommand));
1729 
1730  command->type = SCT_AlterTable;
1731  command->in_extension = creating_extension;
1732 
1733  command->d.alterTable.classId = RelationRelationId;
1734  command->d.alterTable.objectId = InvalidOid;
1735  command->d.alterTable.subcmds = NIL;
1736  command->parsetree = copyObject(parsetree);
1737 
1740 
1741  MemoryContextSwitchTo(oldcxt);
1742 }
@ SCT_AlterTable
bool creating_extension
Definition: extension.c:71
void * palloc(Size size)
Definition: mcxt.c:1304
#define copyObject(obj)
Definition: nodes.h:223
#define InvalidOid
Definition: postgres_ext.h:36
CollectedCommandType type

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

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

◆ EventTriggerBeginCompleteQuery()

bool EventTriggerBeginCompleteQuery ( void  )

Definition at line 1274 of file event_trigger.c.

1275 {
1277  MemoryContext cxt;
1278 
1279  /*
1280  * Currently, sql_drop, table_rewrite, ddl_command_end events are the only
1281  * reason to have event trigger state at all; so if there are none, don't
1282  * install one.
1283  */
1285  return false;
1286 
1288  "event trigger state",
1291  state->cxt = cxt;
1292  slist_init(&(state->SQLDropList));
1293  state->in_sql_drop = false;
1294  state->table_rewrite_oid = InvalidOid;
1295 
1296  state->commandCollectionInhibited = currentEventTriggerState ?
1298  state->currentCommand = NULL;
1299  state->commandList = NIL;
1300  state->previous = currentEventTriggerState;
1302 
1303  return true;
1304 }
bool trackDroppedObjectsNeeded(void)
static void slist_init(slist_head *head)
Definition: ilist.h:986
MemoryContext TopMemoryContext
Definition: mcxt.c:137
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition: mcxt.c:1168
#define AllocSetContextCreate
Definition: memutils.h:129
#define ALLOCSET_DEFAULT_SIZES
Definition: memutils.h:153
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 1987 of file event_trigger.c.

1988 {
1989  MemoryContext oldcxt;
1990  CollectedCommand *command;
1991 
1992  /* ignore if event trigger context not set, or collection disabled */
1993  if (!currentEventTriggerState ||
1995  return;
1996 
1998 
1999  command = palloc0(sizeof(CollectedCommand));
2000  command->type = SCT_AlterDefaultPrivileges;
2001  command->d.defprivs.objtype = stmt->action->objtype;
2002  command->in_extension = creating_extension;
2003  command->parsetree = (Node *) copyObject(stmt);
2004 
2007  MemoryContextSwitchTo(oldcxt);
2008 }
@ SCT_AlterDefaultPrivileges
void * palloc0(Size size)
Definition: mcxt.c:1334
struct CollectedCommand::@113::@120 defprivs
Definition: nodes.h:129

References EventTriggerQueryState::commandCollectionInhibited, EventTriggerQueryState::commandList, copyObject, creating_extension, currentEventTriggerState, EventTriggerQueryState::cxt, CollectedCommand::d, CollectedCommand::defprivs, CollectedCommand::in_extension, lappend(), MemoryContextSwitchTo(), 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 1885 of file event_trigger.c.

1887 {
1888  MemoryContext oldcxt;
1889  CollectedCommand *command;
1890 
1891  /* ignore if event trigger context not set, or collection disabled */
1892  if (!currentEventTriggerState ||
1894  return;
1895 
1897 
1898  command = palloc(sizeof(CollectedCommand));
1899  command->type = SCT_AlterOpFamily;
1900  command->in_extension = creating_extension;
1901  ObjectAddressSet(command->d.opfam.address,
1902  OperatorFamilyRelationId, opfamoid);
1903  command->d.opfam.operators = operators;
1904  command->d.opfam.procedures = procedures;
1905  command->parsetree = (Node *) copyObject(stmt);
1906 
1909 
1910  MemoryContextSwitchTo(oldcxt);
1911 }
@ SCT_AlterOpFamily
struct CollectedCommand::@113::@117 opfam

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

Referenced by AlterOpFamilyAdd(), and AlterOpFamilyDrop().

◆ EventTriggerCollectAlterTableSubcmd()

void EventTriggerCollectAlterTableSubcmd ( Node subcmd,
ObjectAddress  address 
)

Definition at line 1768 of file event_trigger.c.

1769 {
1770  MemoryContext oldcxt;
1772 
1773  /* ignore if event trigger context not set, or collection disabled */
1774  if (!currentEventTriggerState ||
1776  return;
1777 
1778  Assert(IsA(subcmd, AlterTableCmd));
1781 
1783 
1784  newsub = palloc(sizeof(CollectedATSubcmd));
1785  newsub->address = address;
1786  newsub->parsetree = copyObject(subcmd);
1787 
1790 
1791  MemoryContextSwitchTo(oldcxt);
1792 }
#define OidIsValid(objectId)
Definition: c.h:762
Assert(fmt[strlen(fmt) - 1] !='\n')
#define IsA(nodeptr, _type_)
Definition: nodes.h:158
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(), OidIsValid, and palloc().

Referenced by ATExecCmd().

◆ EventTriggerCollectAlterTSConfig()

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

Definition at line 1952 of file event_trigger.c.

1954 {
1955  MemoryContext oldcxt;
1956  CollectedCommand *command;
1957 
1958  /* ignore if event trigger context not set, or collection disabled */
1959  if (!currentEventTriggerState ||
1961  return;
1962 
1964 
1965  command = palloc0(sizeof(CollectedCommand));
1966  command->type = SCT_AlterTSConfig;
1967  command->in_extension = creating_extension;
1968  ObjectAddressSet(command->d.atscfg.address,
1969  TSConfigRelationId, cfgId);
1970  command->d.atscfg.dictIds = palloc(sizeof(Oid) * ndicts);
1971  memcpy(command->d.atscfg.dictIds, dictIds, sizeof(Oid) * ndicts);
1972  command->d.atscfg.ndicts = ndicts;
1973  command->parsetree = (Node *) copyObject(stmt);
1974 
1977 
1978  MemoryContextSwitchTo(oldcxt);
1979 }
@ SCT_AlterTSConfig
struct CollectedCommand::@113::@119 atscfg

References CollectedCommand::atscfg, EventTriggerQueryState::commandCollectionInhibited, EventTriggerQueryState::commandList, copyObject, creating_extension, currentEventTriggerState, EventTriggerQueryState::cxt, CollectedCommand::d, CollectedCommand::in_extension, lappend(), MemoryContextSwitchTo(), 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 1918 of file event_trigger.c.

1920 {
1921  MemoryContext oldcxt;
1922  CollectedCommand *command;
1923 
1924  /* ignore if event trigger context not set, or collection disabled */
1925  if (!currentEventTriggerState ||
1927  return;
1928 
1930 
1931  command = palloc0(sizeof(CollectedCommand));
1932  command->type = SCT_CreateOpClass;
1933  command->in_extension = creating_extension;
1934  ObjectAddressSet(command->d.createopc.address,
1935  OperatorClassRelationId, opcoid);
1936  command->d.createopc.operators = operators;
1937  command->d.createopc.procedures = procedures;
1938  command->parsetree = (Node *) copyObject(stmt);
1939 
1942 
1943  MemoryContextSwitchTo(oldcxt);
1944 }
@ SCT_CreateOpClass
struct CollectedCommand::@113::@118 createopc

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

Referenced by DefineOpClass().

◆ EventTriggerCollectGrant()

void EventTriggerCollectGrant ( InternalGrant istmt)

Definition at line 1841 of file event_trigger.c.

1842 {
1843  MemoryContext oldcxt;
1844  CollectedCommand *command;
1845  InternalGrant *icopy;
1846  ListCell *cell;
1847 
1848  /* ignore if event trigger context not set, or collection disabled */
1849  if (!currentEventTriggerState ||
1851  return;
1852 
1854 
1855  /*
1856  * This is tedious, but necessary.
1857  */
1858  icopy = palloc(sizeof(InternalGrant));
1859  memcpy(icopy, istmt, sizeof(InternalGrant));
1860  icopy->objects = list_copy(istmt->objects);
1861  icopy->grantees = list_copy(istmt->grantees);
1862  icopy->col_privs = NIL;
1863  foreach(cell, istmt->col_privs)
1864  icopy->col_privs = lappend(icopy->col_privs, copyObject(lfirst(cell)));
1865 
1866  /* Now collect it, using the copied InternalGrant */
1867  command = palloc(sizeof(CollectedCommand));
1868  command->type = SCT_Grant;
1869  command->in_extension = creating_extension;
1870  command->d.grant.istmt = icopy;
1871  command->parsetree = NULL;
1872 
1875 
1876  MemoryContextSwitchTo(oldcxt);
1877 }
@ SCT_Grant
List * list_copy(const List *oldlist)
Definition: list.c:1573
struct CollectedCommand::@113::@116 grant

References InternalGrant::col_privs, EventTriggerQueryState::commandCollectionInhibited, EventTriggerQueryState::commandList, copyObject, creating_extension, currentEventTriggerState, EventTriggerQueryState::cxt, CollectedCommand::d, CollectedCommand::grant, InternalGrant::grantees, CollectedCommand::in_extension, 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 1678 of file event_trigger.c.

1681 {
1682  MemoryContext oldcxt;
1683  CollectedCommand *command;
1684 
1685  /* ignore if event trigger context not set, or collection disabled */
1686  if (!currentEventTriggerState ||
1688  return;
1689 
1691 
1692  command = palloc(sizeof(CollectedCommand));
1693 
1694  command->type = SCT_Simple;
1695  command->in_extension = creating_extension;
1696 
1697  command->d.simple.address = address;
1698  command->d.simple.secondaryObject = secondaryObject;
1699  command->parsetree = copyObject(parsetree);
1700 
1702  command);
1703 
1704  MemoryContextSwitchTo(oldcxt);
1705 }
@ SCT_Simple
struct CollectedCommand::@113::@114 simple

References EventTriggerQueryState::commandCollectionInhibited, EventTriggerQueryState::commandList, copyObject, creating_extension, currentEventTriggerState, EventTriggerQueryState::cxt, CollectedCommand::d, CollectedCommand::in_extension, lappend(), MemoryContextSwitchTo(), palloc(), CollectedCommand::parsetree, SCT_Simple, 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 765 of file event_trigger.c.

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

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 714 of file event_trigger.c.

715 {
716  List *runlist;
717  EventTriggerData trigdata;
718 
719  /*
720  * Event Triggers are completely disabled in standalone mode. There are
721  * (at least) two reasons for this:
722  *
723  * 1. A sufficiently broken event trigger might not only render the
724  * database unusable, but prevent disabling itself to fix the situation.
725  * In this scenario, restarting in standalone mode provides an escape
726  * hatch.
727  *
728  * 2. BuildEventTriggerCache relies on systable_beginscan_ordered, and
729  * therefore will malfunction if pg_event_trigger's indexes are damaged.
730  * To allow recovery from a damaged index, we need some operating mode
731  * wherein event triggers are disabled. (Or we could implement
732  * heapscan-and-sort logic for that case, but having disaster recovery
733  * scenarios depend on code that's otherwise untested isn't appetizing.)
734  *
735  * Additionally, event triggers can be disabled with a superuser-only GUC
736  * to make fixing database easier as per 1 above.
737  */
739  return;
740 
741  runlist = EventTriggerCommonSetup(parsetree,
743  "ddl_command_start",
744  &trigdata, false);
745  if (runlist == NIL)
746  return;
747 
748  /* Run the triggers. */
749  EventTriggerInvoke(runlist, &trigdata);
750 
751  /* Cleanup. */
752  list_free(runlist);
753 
754  /*
755  * Make sure anything the event triggers did will be visible to the main
756  * command.
757  */
759 }
@ 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 1318 of file event_trigger.c.

1319 {
1320  EventTriggerQueryState *prevstate;
1321 
1322  prevstate = currentEventTriggerState->previous;
1323 
1324  /* this avoids the need for retail pfree of SQLDropList items: */
1326 
1327  currentEventTriggerState = prevstate;
1328 }
void MemoryContextDelete(MemoryContext context)
Definition: mcxt.c:442
struct EventTriggerQueryState * previous
Definition: event_trigger.c:74

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

Referenced by ProcessUtilitySlow().

◆ EventTriggerInhibitCommandCollection()

void EventTriggerInhibitCommandCollection ( void  )

Definition at line 1644 of file event_trigger.c.

1645 {
1647  return;
1648 
1650 }

References EventTriggerQueryState::commandCollectionInhibited, and currentEventTriggerState.

Referenced by ProcessUtilitySlow().

◆ EventTriggerOnLogin()

void EventTriggerOnLogin ( void  )

Definition at line 886 of file event_trigger.c.

887 {
888  List *runlist;
889  EventTriggerData trigdata;
890 
891  /*
892  * See EventTriggerDDLCommandStart for a discussion about why event
893  * triggers are disabled in single user mode or via a GUC. We also need a
894  * database connection (some background workers don't have it).
895  */
898  return;
899 
901  runlist = EventTriggerCommonSetup(NULL,
902  EVT_Login, "login",
903  &trigdata, false);
904 
905  if (runlist != NIL)
906  {
907  /*
908  * Event trigger execution may require an active snapshot.
909  */
911 
912  /* Run the triggers. */
913  EventTriggerInvoke(runlist, &trigdata);
914 
915  /* Cleanup. */
916  list_free(runlist);
917 
919  }
920 
921  /*
922  * There is no active login event trigger, but our
923  * pg_database.dathasloginevt is set. Try to unset this flag. We use the
924  * lock to prevent concurrent SetDatatabaseHasLoginEventTriggers(), but we
925  * don't want to hang the connection waiting on the lock. Thus, we are
926  * just trying to acquire the lock conditionally.
927  */
928  else if (ConditionalLockSharedObject(DatabaseRelationId, MyDatabaseId,
930  {
931  /*
932  * The lock is held. Now we need to recheck that login event triggers
933  * list is still empty. Once the list is empty, we know that even if
934  * there is a backend which concurrently inserts/enables a login event
935  * trigger, it will update pg_database.dathasloginevt *afterwards*.
936  */
937  runlist = EventTriggerCommonSetup(NULL,
938  EVT_Login, "login",
939  &trigdata, true);
940 
941  if (runlist == NIL)
942  {
943  Relation pg_db = table_open(DatabaseRelationId, RowExclusiveLock);
944  HeapTuple tuple;
945  Form_pg_database db;
946  ScanKeyData key[1];
947  SysScanDesc scan;
948 
949  /*
950  * Get the pg_database tuple to scribble on. Note that this does
951  * not directly rely on the syscache to avoid issues with
952  * flattened toast values for the in-place update.
953  */
954  ScanKeyInit(&key[0],
955  Anum_pg_database_oid,
956  BTEqualStrategyNumber, F_OIDEQ,
958 
959  scan = systable_beginscan(pg_db, DatabaseOidIndexId, true,
960  NULL, 1, key);
961  tuple = systable_getnext(scan);
962  tuple = heap_copytuple(tuple);
963  systable_endscan(scan);
964 
965  if (!HeapTupleIsValid(tuple))
966  elog(ERROR, "could not find tuple for database %u", MyDatabaseId);
967 
968  db = (Form_pg_database) GETSTRUCT(tuple);
969  if (db->dathasloginevt)
970  {
971  db->dathasloginevt = false;
972 
973  /*
974  * Do an "in place" update of the pg_database tuple. Doing
975  * this instead of regular updates serves two purposes. First,
976  * that avoids possible waiting on the row-level lock. Second,
977  * that avoids dealing with TOAST.
978  *
979  * It's known that changes made by heap_inplace_update() may
980  * be lost due to concurrent normal updates. However, we are
981  * OK with that. The subsequent connections will still have a
982  * chance to set "dathasloginevt" to false.
983  */
984  heap_inplace_update(pg_db, tuple);
985  }
987  heap_freetuple(tuple);
988  }
989  else
990  {
991  list_free(runlist);
992  }
993  }
995 }
#define elog(elevel,...)
Definition: elog.h:224
@ EVT_Login
Definition: evtcache.h:26
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:596
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:503
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:384
bool MyDatabaseHasLoginEventTriggers
Definition: globals.c:95
Oid MyDatabaseId
Definition: globals.c:91
void heap_inplace_update(Relation relation, HeapTuple tuple)
Definition: heapam.c:5889
HeapTuple heap_copytuple(HeapTuple tuple)
Definition: heaptuple.c:776
bool ConditionalLockSharedObject(Oid classid, Oid objid, uint16 objsubid, LOCKMODE lockmode)
Definition: lmgr.c:1069
#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:216
void PushActiveSnapshot(Snapshot snapshot)
Definition: snapmgr.c:648
void PopActiveSnapshot(void)
Definition: snapmgr.c:743
#define BTEqualStrategyNumber
Definition: stratnum.h:31
void StartTransactionCommand(void)
Definition: xact.c:2955
void CommitTransactionCommand(void)
Definition: xact.c:3053

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

Referenced by PostgresMain().

◆ EventTriggerSQLDrop()

void EventTriggerSQLDrop ( Node parsetree)

Definition at line 813 of file event_trigger.c.

814 {
815  List *runlist;
816  EventTriggerData trigdata;
817 
818  /*
819  * See EventTriggerDDLCommandStart for a discussion about why event
820  * triggers are disabled in single user mode or via a GUC.
821  */
823  return;
824 
825  /*
826  * Use current state to determine whether this event fires at all. If
827  * there are no triggers for the sql_drop event, then we don't have
828  * anything to do here. Note that dropped object collection is disabled
829  * if this is the case, so even if we were to try to run, the list would
830  * be empty.
831  */
834  return;
835 
836  runlist = EventTriggerCommonSetup(parsetree,
837  EVT_SQLDrop, "sql_drop",
838  &trigdata, false);
839 
840  /*
841  * Nothing to do if run list is empty. Note this typically can't happen,
842  * because if there are no sql_drop events, then objects-to-drop wouldn't
843  * have been collected in the first place and we would have quit above.
844  * But it could occur if event triggers were dropped partway through.
845  */
846  if (runlist == NIL)
847  return;
848 
849  /*
850  * Make sure anything the main command did will be visible to the event
851  * triggers.
852  */
854 
855  /*
856  * Make sure pg_event_trigger_dropped_objects only works when running
857  * these triggers. Use PG_TRY to ensure in_sql_drop is reset even when
858  * one trigger fails. (This is perhaps not necessary, as the currentState
859  * variable will be removed shortly by our caller, but it seems better to
860  * play safe.)
861  */
863 
864  /* Run the triggers. */
865  PG_TRY();
866  {
867  EventTriggerInvoke(runlist, &trigdata);
868  }
869  PG_FINALLY();
870  {
872  }
873  PG_END_TRY();
874 
875  /* Cleanup. */
876  list_free(runlist);
877 }
#define PG_TRY(...)
Definition: elog.h:370
#define PG_END_TRY(...)
Definition: elog.h:395
#define PG_FINALLY(...)
Definition: elog.h:387
@ 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 1368 of file event_trigger.c.

1369 {
1370  SQLDropObject *obj;
1371  MemoryContext oldcxt;
1372 
1374  return;
1375 
1377 
1378  /* don't report temp schemas except my own */
1379  if (object->classId == NamespaceRelationId &&
1380  (isAnyTempNamespace(object->objectId) &&
1381  !isTempNamespace(object->objectId)))
1382  return;
1383 
1385 
1386  obj = palloc0(sizeof(SQLDropObject));
1387  obj->address = *object;
1388  obj->original = original;
1389  obj->normal = normal;
1390 
1391  /*
1392  * Obtain schema names from the object's catalog tuple, if one exists;
1393  * this lets us skip objects in temp schemas. We trust that
1394  * ObjectProperty contains all object classes that can be
1395  * schema-qualified.
1396  */
1397  if (is_objectclass_supported(object->classId))
1398  {
1399  Relation catalog;
1400  HeapTuple tuple;
1401 
1402  catalog = table_open(obj->address.classId, AccessShareLock);
1403  tuple = get_catalog_object_by_oid(catalog,
1404  get_object_attnum_oid(object->classId),
1405  obj->address.objectId);
1406 
1407  if (tuple)
1408  {
1410  Datum datum;
1411  bool isnull;
1412 
1414  if (attnum != InvalidAttrNumber)
1415  {
1416  datum = heap_getattr(tuple, attnum,
1417  RelationGetDescr(catalog), &isnull);
1418  if (!isnull)
1419  {
1420  Oid namespaceId;
1421 
1422  namespaceId = DatumGetObjectId(datum);
1423  /* temp objects are only reported if they are my own */
1424  if (isTempNamespace(namespaceId))
1425  {
1426  obj->schemaname = "pg_temp";
1427  obj->istemp = true;
1428  }
1429  else if (isAnyTempNamespace(namespaceId))
1430  {
1431  pfree(obj);
1432  table_close(catalog, AccessShareLock);
1433  MemoryContextSwitchTo(oldcxt);
1434  return;
1435  }
1436  else
1437  {
1438  obj->schemaname = get_namespace_name(namespaceId);
1439  obj->istemp = false;
1440  }
1441  }
1442  }
1443 
1445  obj->address.objectSubId == 0)
1446  {
1448  if (attnum != InvalidAttrNumber)
1449  {
1450  datum = heap_getattr(tuple, attnum,
1451  RelationGetDescr(catalog), &isnull);
1452  if (!isnull)
1453  obj->objname = pstrdup(NameStr(*DatumGetName(datum)));
1454  }
1455  }
1456  }
1457 
1458  table_close(catalog, AccessShareLock);
1459  }
1460  else
1461  {
1462  if (object->classId == NamespaceRelationId &&
1463  isTempNamespace(object->objectId))
1464  obj->istemp = true;
1465  }
1466 
1467  /* object identity, objname and objargs */
1468  obj->objidentity =
1469  getObjectIdentityParts(&obj->address, &obj->addrnames, &obj->addrargs,
1470  false);
1471 
1472  /* object type */
1473  obj->objecttype = getObjectTypeDescription(&obj->address, false);
1474 
1476 
1477  MemoryContextSwitchTo(oldcxt);
1478 }
int16 AttrNumber
Definition: attnum.h:21
#define InvalidAttrNumber
Definition: attnum.h:23
#define NameStr(name)
Definition: c.h:733
ObjectClass getObjectClass(const ObjectAddress *object)
Definition: dependency.c:2784
bool EventTriggerSupportsObjectClass(ObjectClass objclass)
static Datum heap_getattr(HeapTuple tup, int attnum, TupleDesc tupleDesc, bool *isnull)
Definition: htup_details.h:792
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:3322
char * pstrdup(const char *in)
Definition: mcxt.c:1683
bool isTempNamespace(Oid namespaceId)
Definition: namespace.c:3634
bool isAnyTempNamespace(Oid namespaceId)
Definition: namespace.c:3672
bool get_object_namensp_unique(Oid class_id)
HeapTuple get_catalog_object_by_oid(Relation catalog, AttrNumber oidcol, Oid objectId)
AttrNumber get_object_attnum_oid(Oid class_id)
AttrNumber get_object_attnum_namespace(Oid class_id)
AttrNumber get_object_attnum_name(Oid class_id)
char * getObjectTypeDescription(const ObjectAddress *object, bool missing_ok)
char * getObjectIdentityParts(const ObjectAddress *object, List **objname, List **objargs, bool missing_ok)
bool is_objectclass_supported(Oid class_id)
int16 attnum
Definition: pg_attribute.h:74
static Name DatumGetName(Datum X)
Definition: postgres.h:360
uintptr_t Datum
Definition: postgres.h:64
static Oid DatumGetObjectId(Datum X)
Definition: postgres.h:242
#define RelationGetDescr(relation)
Definition: rel.h:531
ObjectAddress address
Definition: event_trigger.c:85
const char * schemaname
Definition: event_trigger.c:86
slist_node next
Definition: event_trigger.c:95
const char * objidentity
Definition: event_trigger.c:88
const char * objecttype
Definition: event_trigger.c:89
List * addrnames
Definition: event_trigger.c:90
const char * objname
Definition: event_trigger.c:87

References AccessShareLock, SQLDropObject::addrargs, SQLDropObject::address, SQLDropObject::addrnames, Assert(), attnum, ObjectAddress::classId, currentEventTriggerState, EventTriggerQueryState::cxt, DatumGetName(), DatumGetObjectId(), EventTriggerSupportsObjectClass(), get_catalog_object_by_oid(), get_namespace_name(), get_object_attnum_name(), get_object_attnum_namespace(), get_object_attnum_oid(), get_object_namensp_unique(), getObjectClass(), getObjectIdentityParts(), getObjectTypeDescription(), heap_getattr(), InvalidAttrNumber, is_objectclass_supported(), isAnyTempNamespace(), SQLDropObject::istemp, isTempNamespace(), MemoryContextSwitchTo(), NameStr, SQLDropObject::next, SQLDropObject::normal, ObjectAddress::objectId, ObjectAddress::objectSubId, SQLDropObject::objecttype, SQLDropObject::objidentity, SQLDropObject::objname, SQLDropObject::original, palloc0(), pfree(), pstrdup(), RelationGetDescr, SQLDropObject::schemaname, slist_push_head(), EventTriggerQueryState::SQLDropList, table_close(), and table_open().

Referenced by deleteObjectsInList(), and DropSubscription().

◆ EventTriggerSupportsObjectClass()

bool EventTriggerSupportsObjectClass ( ObjectClass  objclass)

Definition at line 1206 of file event_trigger.c.

1207 {
1208  switch (objclass)
1209  {
1210  case OCLASS_DATABASE:
1211  case OCLASS_TBLSPACE:
1212  case OCLASS_ROLE:
1214  case OCLASS_PARAMETER_ACL:
1215  /* no support for global objects */
1216  return false;
1217  case OCLASS_EVENT_TRIGGER:
1218  /* no support for event triggers on event triggers */
1219  return false;
1220  case OCLASS_CLASS:
1221  case OCLASS_PROC:
1222  case OCLASS_TYPE:
1223  case OCLASS_CAST:
1224  case OCLASS_COLLATION:
1225  case OCLASS_CONSTRAINT:
1226  case OCLASS_CONVERSION:
1227  case OCLASS_DEFAULT:
1228  case OCLASS_LANGUAGE:
1229  case OCLASS_LARGEOBJECT:
1230  case OCLASS_OPERATOR:
1231  case OCLASS_OPCLASS:
1232  case OCLASS_OPFAMILY:
1233  case OCLASS_AM:
1234  case OCLASS_AMOP:
1235  case OCLASS_AMPROC:
1236  case OCLASS_REWRITE:
1237  case OCLASS_TRIGGER:
1238  case OCLASS_SCHEMA:
1239  case OCLASS_STATISTIC_EXT:
1240  case OCLASS_TSPARSER:
1241  case OCLASS_TSDICT:
1242  case OCLASS_TSTEMPLATE:
1243  case OCLASS_TSCONFIG:
1244  case OCLASS_FDW:
1245  case OCLASS_FOREIGN_SERVER:
1246  case OCLASS_USER_MAPPING:
1247  case OCLASS_DEFACL:
1248  case OCLASS_EXTENSION:
1249  case OCLASS_POLICY:
1250  case OCLASS_PUBLICATION:
1253  case OCLASS_SUBSCRIPTION:
1254  case OCLASS_TRANSFORM:
1255  return true;
1256 
1257  /*
1258  * There's intentionally no default: case here; we want the
1259  * compiler to warn if a new OCLASS hasn't been handled above.
1260  */
1261  }
1262 
1263  /* Shouldn't get here, but if we do, say "no support" */
1264  return false;
1265 }
@ OCLASS_OPERATOR
Definition: dependency.h:100
@ OCLASS_PARAMETER_ACL
Definition: dependency.h:124
@ OCLASS_LARGEOBJECT
Definition: dependency.h:99
@ OCLASS_FDW
Definition: dependency.h:118
@ OCLASS_OPFAMILY
Definition: dependency.h:102
@ OCLASS_DEFACL
Definition: dependency.h:121
@ OCLASS_TSPARSER
Definition: dependency.h:110
@ OCLASS_TRIGGER
Definition: dependency.h:107
@ OCLASS_DEFAULT
Definition: dependency.h:97
@ OCLASS_TSTEMPLATE
Definition: dependency.h:112
@ OCLASS_AMPROC
Definition: dependency.h:105
@ OCLASS_TBLSPACE
Definition: dependency.h:117
@ OCLASS_TSCONFIG
Definition: dependency.h:113
@ OCLASS_TYPE
Definition: dependency.h:92
@ OCLASS_LANGUAGE
Definition: dependency.h:98
@ OCLASS_CAST
Definition: dependency.h:93
@ OCLASS_SUBSCRIPTION
Definition: dependency.h:129
@ OCLASS_PUBLICATION_NAMESPACE
Definition: dependency.h:127
@ OCLASS_EXTENSION
Definition: dependency.h:122
@ OCLASS_COLLATION
Definition: dependency.h:94
@ OCLASS_FOREIGN_SERVER
Definition: dependency.h:119
@ OCLASS_REWRITE
Definition: dependency.h:106
@ OCLASS_STATISTIC_EXT
Definition: dependency.h:109
@ OCLASS_PROC
Definition: dependency.h:91
@ OCLASS_OPCLASS
Definition: dependency.h:101
@ OCLASS_CONVERSION
Definition: dependency.h:96
@ OCLASS_DATABASE
Definition: dependency.h:116
@ OCLASS_ROLE_MEMBERSHIP
Definition: dependency.h:115
@ OCLASS_SCHEMA
Definition: dependency.h:108
@ OCLASS_EVENT_TRIGGER
Definition: dependency.h:123
@ OCLASS_CLASS
Definition: dependency.h:90
@ OCLASS_TRANSFORM
Definition: dependency.h:130
@ OCLASS_ROLE
Definition: dependency.h:114
@ OCLASS_CONSTRAINT
Definition: dependency.h:95
@ OCLASS_POLICY
Definition: dependency.h:125
@ OCLASS_USER_MAPPING
Definition: dependency.h:120
@ OCLASS_PUBLICATION_REL
Definition: dependency.h:128
@ OCLASS_AM
Definition: dependency.h:103
@ OCLASS_TSDICT
Definition: dependency.h:111
@ OCLASS_PUBLICATION
Definition: dependency.h:126
@ OCLASS_AMOP
Definition: dependency.h:104

References OCLASS_AM, OCLASS_AMOP, OCLASS_AMPROC, OCLASS_CAST, OCLASS_CLASS, OCLASS_COLLATION, OCLASS_CONSTRAINT, OCLASS_CONVERSION, OCLASS_DATABASE, OCLASS_DEFACL, OCLASS_DEFAULT, OCLASS_EVENT_TRIGGER, OCLASS_EXTENSION, OCLASS_FDW, OCLASS_FOREIGN_SERVER, OCLASS_LANGUAGE, OCLASS_LARGEOBJECT, OCLASS_OPCLASS, OCLASS_OPERATOR, OCLASS_OPFAMILY, OCLASS_PARAMETER_ACL, OCLASS_POLICY, OCLASS_PROC, OCLASS_PUBLICATION, OCLASS_PUBLICATION_NAMESPACE, OCLASS_PUBLICATION_REL, OCLASS_REWRITE, OCLASS_ROLE, OCLASS_ROLE_MEMBERSHIP, OCLASS_SCHEMA, OCLASS_STATISTIC_EXT, OCLASS_SUBSCRIPTION, OCLASS_TBLSPACE, OCLASS_TRANSFORM, OCLASS_TRIGGER, OCLASS_TSCONFIG, OCLASS_TSDICT, OCLASS_TSPARSER, OCLASS_TSTEMPLATE, OCLASS_TYPE, and OCLASS_USER_MAPPING.

Referenced by deleteObjectsInList(), and EventTriggerSQLDropAddObject().

◆ EventTriggerSupportsObjectType()

bool EventTriggerSupportsObjectType ( ObjectType  obtype)

Definition at line 1130 of file event_trigger.c.

1131 {
1132  switch (obtype)
1133  {
1134  case OBJECT_DATABASE:
1135  case OBJECT_TABLESPACE:
1136  case OBJECT_ROLE:
1137  case OBJECT_PARAMETER_ACL:
1138  /* no support for global objects */
1139  return false;
1140  case OBJECT_EVENT_TRIGGER:
1141  /* no support for event triggers on event triggers */
1142  return false;
1143  case OBJECT_ACCESS_METHOD:
1144  case OBJECT_AGGREGATE:
1145  case OBJECT_AMOP:
1146  case OBJECT_AMPROC:
1147  case OBJECT_ATTRIBUTE:
1148  case OBJECT_CAST:
1149  case OBJECT_COLUMN:
1150  case OBJECT_COLLATION:
1151  case OBJECT_CONVERSION:
1152  case OBJECT_DEFACL:
1153  case OBJECT_DEFAULT:
1154  case OBJECT_DOMAIN:
1155  case OBJECT_DOMCONSTRAINT:
1156  case OBJECT_EXTENSION:
1157  case OBJECT_FDW:
1158  case OBJECT_FOREIGN_SERVER:
1159  case OBJECT_FOREIGN_TABLE:
1160  case OBJECT_FUNCTION:
1161  case OBJECT_INDEX:
1162  case OBJECT_LANGUAGE:
1163  case OBJECT_LARGEOBJECT:
1164  case OBJECT_MATVIEW:
1165  case OBJECT_OPCLASS:
1166  case OBJECT_OPERATOR:
1167  case OBJECT_OPFAMILY:
1168  case OBJECT_POLICY:
1169  case OBJECT_PROCEDURE:
1170  case OBJECT_PUBLICATION:
1173  case OBJECT_ROUTINE:
1174  case OBJECT_RULE:
1175  case OBJECT_SCHEMA:
1176  case OBJECT_SEQUENCE:
1177  case OBJECT_SUBSCRIPTION:
1178  case OBJECT_STATISTIC_EXT:
1179  case OBJECT_TABCONSTRAINT:
1180  case OBJECT_TABLE:
1181  case OBJECT_TRANSFORM:
1182  case OBJECT_TRIGGER:
1184  case OBJECT_TSDICTIONARY:
1185  case OBJECT_TSPARSER:
1186  case OBJECT_TSTEMPLATE:
1187  case OBJECT_TYPE:
1188  case OBJECT_USER_MAPPING:
1189  case OBJECT_VIEW:
1190  return true;
1191 
1192  /*
1193  * There's intentionally no default: case here; we want the
1194  * compiler to warn if a new ObjectType hasn't been handled above.
1195  */
1196  }
1197 
1198  /* Shouldn't get here, but if we do, say "no support" */
1199  return false;
1200 }
@ OBJECT_FDW
Definition: parsenodes.h:2125
@ OBJECT_TSPARSER
Definition: parsenodes.h:2156
@ OBJECT_COLLATION
Definition: parsenodes.h:2116
@ OBJECT_USER_MAPPING
Definition: parsenodes.h:2159
@ OBJECT_ACCESS_METHOD
Definition: parsenodes.h:2109
@ OBJECT_OPCLASS
Definition: parsenodes.h:2133
@ OBJECT_DEFACL
Definition: parsenodes.h:2120
@ OBJECT_AGGREGATE
Definition: parsenodes.h:2110
@ OBJECT_MATVIEW
Definition: parsenodes.h:2132
@ OBJECT_SCHEMA
Definition: parsenodes.h:2145
@ OBJECT_POLICY
Definition: parsenodes.h:2137
@ OBJECT_OPERATOR
Definition: parsenodes.h:2134
@ OBJECT_FOREIGN_TABLE
Definition: parsenodes.h:2127
@ OBJECT_TSCONFIGURATION
Definition: parsenodes.h:2154
@ OBJECT_OPFAMILY
Definition: parsenodes.h:2135
@ OBJECT_DOMAIN
Definition: parsenodes.h:2121
@ OBJECT_COLUMN
Definition: parsenodes.h:2115
@ OBJECT_TABLESPACE
Definition: parsenodes.h:2151
@ OBJECT_ROLE
Definition: parsenodes.h:2142
@ OBJECT_ROUTINE
Definition: parsenodes.h:2143
@ OBJECT_LARGEOBJECT
Definition: parsenodes.h:2131
@ OBJECT_PUBLICATION_NAMESPACE
Definition: parsenodes.h:2140
@ OBJECT_PROCEDURE
Definition: parsenodes.h:2138
@ OBJECT_EXTENSION
Definition: parsenodes.h:2124
@ OBJECT_INDEX
Definition: parsenodes.h:2129
@ OBJECT_DEFAULT
Definition: parsenodes.h:2119
@ OBJECT_DATABASE
Definition: parsenodes.h:2118
@ OBJECT_SEQUENCE
Definition: parsenodes.h:2146
@ OBJECT_TSTEMPLATE
Definition: parsenodes.h:2157
@ OBJECT_LANGUAGE
Definition: parsenodes.h:2130
@ OBJECT_AMOP
Definition: parsenodes.h:2111
@ OBJECT_PUBLICATION_REL
Definition: parsenodes.h:2141
@ OBJECT_FOREIGN_SERVER
Definition: parsenodes.h:2126
@ OBJECT_TSDICTIONARY
Definition: parsenodes.h:2155
@ OBJECT_ATTRIBUTE
Definition: parsenodes.h:2113
@ OBJECT_PUBLICATION
Definition: parsenodes.h:2139
@ OBJECT_RULE
Definition: parsenodes.h:2144
@ OBJECT_CONVERSION
Definition: parsenodes.h:2117
@ OBJECT_AMPROC
Definition: parsenodes.h:2112
@ OBJECT_TABLE
Definition: parsenodes.h:2150
@ OBJECT_VIEW
Definition: parsenodes.h:2160
@ OBJECT_PARAMETER_ACL
Definition: parsenodes.h:2136
@ OBJECT_TYPE
Definition: parsenodes.h:2158
@ OBJECT_FUNCTION
Definition: parsenodes.h:2128
@ OBJECT_TABCONSTRAINT
Definition: parsenodes.h:2149
@ OBJECT_DOMCONSTRAINT
Definition: parsenodes.h:2122
@ OBJECT_SUBSCRIPTION
Definition: parsenodes.h:2147
@ OBJECT_STATISTIC_EXT
Definition: parsenodes.h:2148
@ OBJECT_CAST
Definition: parsenodes.h:2114
@ OBJECT_TRIGGER
Definition: parsenodes.h:2153
@ OBJECT_TRANSFORM
Definition: parsenodes.h:2152

References OBJECT_ACCESS_METHOD, OBJECT_AGGREGATE, OBJECT_AMOP, OBJECT_AMPROC, OBJECT_ATTRIBUTE, OBJECT_CAST, OBJECT_COLLATION, OBJECT_COLUMN, OBJECT_CONVERSION, OBJECT_DATABASE, OBJECT_DEFACL, OBJECT_DEFAULT, OBJECT_DOMAIN, OBJECT_DOMCONSTRAINT, OBJECT_EVENT_TRIGGER, OBJECT_EXTENSION, OBJECT_FDW, OBJECT_FOREIGN_SERVER, OBJECT_FOREIGN_TABLE, OBJECT_FUNCTION, OBJECT_INDEX, OBJECT_LANGUAGE, OBJECT_LARGEOBJECT, OBJECT_MATVIEW, OBJECT_OPCLASS, OBJECT_OPERATOR, OBJECT_OPFAMILY, OBJECT_PARAMETER_ACL, OBJECT_POLICY, OBJECT_PROCEDURE, OBJECT_PUBLICATION, OBJECT_PUBLICATION_NAMESPACE, OBJECT_PUBLICATION_REL, OBJECT_ROLE, OBJECT_ROUTINE, OBJECT_RULE, OBJECT_SCHEMA, OBJECT_SEQUENCE, OBJECT_STATISTIC_EXT, OBJECT_SUBSCRIPTION, OBJECT_TABCONSTRAINT, OBJECT_TABLE, OBJECT_TABLESPACE, OBJECT_TRANSFORM, OBJECT_TRIGGER, OBJECT_TSCONFIGURATION, OBJECT_TSDICTIONARY, OBJECT_TSPARSER, OBJECT_TSTEMPLATE, OBJECT_TYPE, OBJECT_USER_MAPPING, and OBJECT_VIEW.

Referenced by ExecGrantStmt_oids(), and standard_ProcessUtility().

◆ EventTriggerTableRewrite()

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

Definition at line 1002 of file event_trigger.c.

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

1657 {
1659  return;
1660 
1662 }

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 568 of file event_trigger.c.

569 {
570  Oid oid;
571 
572  oid = GetSysCacheOid1(EVENTTRIGGERNAME, Anum_pg_event_trigger_oid,
573  CStringGetDatum(trigname));
574  if (!OidIsValid(oid) && !missing_ok)
575  ereport(ERROR,
576  (errcode(ERRCODE_UNDEFINED_OBJECT),
577  errmsg("event trigger \"%s\" does not exist", trigname)));
578  return oid;
579 }
#define GetSysCacheOid1(cacheId, oidcol, key1)
Definition: syscache.h:104

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

Referenced by get_object_address_unqualified().

◆ trackDroppedObjectsNeeded()

bool trackDroppedObjectsNeeded ( void  )

Definition at line 1336 of file event_trigger.c.

1337 {
1338  /*
1339  * true if any sql_drop, table_rewrite, ddl_command_end event trigger
1340  * exists
1341  */
1342  return (EventCacheLookup(EVT_SQLDrop) != NIL) ||
1345 }
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