PostgreSQL Source Code  git master
event_trigger.c File Reference
#include "postgres.h"
#include "access/htup_details.h"
#include "access/table.h"
#include "access/xact.h"
#include "catalog/catalog.h"
#include "catalog/dependency.h"
#include "catalog/indexing.h"
#include "catalog/objectaccess.h"
#include "catalog/pg_event_trigger.h"
#include "catalog/pg_namespace.h"
#include "catalog/pg_opclass.h"
#include "catalog/pg_opfamily.h"
#include "catalog/pg_proc.h"
#include "catalog/pg_trigger.h"
#include "catalog/pg_ts_config.h"
#include "catalog/pg_type.h"
#include "commands/dbcommands.h"
#include "commands/event_trigger.h"
#include "commands/extension.h"
#include "commands/trigger.h"
#include "funcapi.h"
#include "lib/ilist.h"
#include "miscadmin.h"
#include "parser/parse_func.h"
#include "pgstat.h"
#include "tcop/deparse_utility.h"
#include "tcop/utility.h"
#include "utils/acl.h"
#include "utils/builtins.h"
#include "utils/evtcache.h"
#include "utils/fmgroids.h"
#include "utils/lsyscache.h"
#include "utils/memutils.h"
#include "utils/rel.h"
#include "utils/syscache.h"
Include dependency graph for event_trigger.c:

Go to the source code of this file.

Data Structures

struct  EventTriggerQueryState
 
struct  SQLDropObject
 

Typedefs

typedef struct EventTriggerQueryState EventTriggerQueryState
 
typedef struct SQLDropObject SQLDropObject
 

Functions

static void AlterEventTriggerOwner_internal (Relation rel, HeapTuple tup, Oid newOwnerId)
 
static void error_duplicate_filter_variable (const char *defname)
 
static Datum filter_list_to_array (List *filterlist)
 
static Oid insert_event_trigger_tuple (const char *trigname, const char *eventname, Oid evtOwner, Oid funcoid, List *taglist)
 
static void validate_ddl_tags (const char *filtervar, List *taglist)
 
static void validate_table_rewrite_tags (const char *filtervar, List *taglist)
 
static void EventTriggerInvoke (List *fn_oid_list, EventTriggerData *trigdata)
 
static const char * stringify_grant_objtype (ObjectType objtype)
 
static const char * stringify_adefprivs_objtype (ObjectType objtype)
 
Oid CreateEventTrigger (CreateEventTrigStmt *stmt)
 
Oid AlterEventTrigger (AlterEventTrigStmt *stmt)
 
ObjectAddress AlterEventTriggerOwner (const char *name, Oid newOwnerId)
 
void AlterEventTriggerOwner_oid (Oid trigOid, Oid newOwnerId)
 
Oid get_event_trigger_oid (const char *trigname, bool missing_ok)
 
static bool filter_event_trigger (CommandTag tag, EventTriggerCacheItem *item)
 
static ListEventTriggerCommonSetup (Node *parsetree, EventTriggerEvent event, const char *eventstr, EventTriggerData *trigdata)
 
void EventTriggerDDLCommandStart (Node *parsetree)
 
void EventTriggerDDLCommandEnd (Node *parsetree)
 
void EventTriggerSQLDrop (Node *parsetree)
 
void EventTriggerTableRewrite (Node *parsetree, Oid tableOid, int reason)
 
bool EventTriggerSupportsObjectType (ObjectType obtype)
 
bool EventTriggerSupportsObjectClass (ObjectClass objclass)
 
bool EventTriggerBeginCompleteQuery (void)
 
void EventTriggerEndCompleteQuery (void)
 
bool trackDroppedObjectsNeeded (void)
 
void EventTriggerSQLDropAddObject (const ObjectAddress *object, bool original, bool normal)
 
Datum pg_event_trigger_dropped_objects (PG_FUNCTION_ARGS)
 
Datum pg_event_trigger_table_rewrite_oid (PG_FUNCTION_ARGS)
 
Datum pg_event_trigger_table_rewrite_reason (PG_FUNCTION_ARGS)
 
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)
 
Datum pg_event_trigger_ddl_commands (PG_FUNCTION_ARGS)
 

Variables

static EventTriggerQueryStatecurrentEventTriggerState = NULL
 
bool event_triggers = true
 

Typedef Documentation

◆ EventTriggerQueryState

◆ SQLDropObject

typedef struct SQLDropObject SQLDropObject

Function Documentation

◆ AlterEventTrigger()

Oid AlterEventTrigger ( AlterEventTrigStmt stmt)

Definition at line 364 of file event_trigger.c.

365 {
366  Relation tgrel;
367  HeapTuple tup;
368  Oid trigoid;
369  Form_pg_event_trigger evtForm;
370  char tgenabled = stmt->tgenabled;
371 
372  tgrel = table_open(EventTriggerRelationId, RowExclusiveLock);
373 
375  CStringGetDatum(stmt->trigname));
376  if (!HeapTupleIsValid(tup))
377  ereport(ERROR,
378  (errcode(ERRCODE_UNDEFINED_OBJECT),
379  errmsg("event trigger \"%s\" does not exist",
380  stmt->trigname)));
381 
382  evtForm = (Form_pg_event_trigger) GETSTRUCT(tup);
383  trigoid = evtForm->oid;
384 
385  if (!object_ownercheck(EventTriggerRelationId, trigoid, GetUserId()))
387  stmt->trigname);
388 
389  /* tuple is a copy, so we can modify it below */
390  evtForm->evtenabled = tgenabled;
391 
392  CatalogTupleUpdate(tgrel, &tup->t_self, tup);
393 
394  InvokeObjectPostAlterHook(EventTriggerRelationId,
395  trigoid, 0);
396 
397  /* clean up */
398  heap_freetuple(tup);
400 
401  return trigoid;
402 }
@ ACLCHECK_NOT_OWNER
Definition: acl.h:184
void aclcheck_error(AclResult aclerr, ObjectType objtype, const char *objectname)
Definition: aclchk.c:2669
bool object_ownercheck(Oid classid, Oid objectid, Oid roleid)
Definition: aclchk.c:3961
int errcode(int sqlerrcode)
Definition: elog.c:858
int errmsg(const char *fmt,...)
Definition: elog.c:1069
#define ERROR
Definition: elog.h:39
#define ereport(elevel,...)
Definition: elog.h:149
void heap_freetuple(HeapTuple htup)
Definition: heaptuple.c:1426
#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:509
#define InvokeObjectPostAlterHook(classId, objectId, subId)
Definition: objectaccess.h:197
@ OBJECT_EVENT_TRIGGER
Definition: parsenodes.h:2134
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:182
@ EVENTTRIGGERNAME
Definition: syscache.h:59
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:126
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:40

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

Referenced by standard_ProcessUtility().

◆ AlterEventTriggerOwner()

ObjectAddress AlterEventTriggerOwner ( const char *  name,
Oid  newOwnerId 
)

Definition at line 408 of file event_trigger.c.

409 {
410  Oid evtOid;
411  HeapTuple tup;
412  Form_pg_event_trigger evtForm;
413  Relation rel;
414  ObjectAddress address;
415 
416  rel = table_open(EventTriggerRelationId, RowExclusiveLock);
417 
419 
420  if (!HeapTupleIsValid(tup))
421  ereport(ERROR,
422  (errcode(ERRCODE_UNDEFINED_OBJECT),
423  errmsg("event trigger \"%s\" does not exist", name)));
424 
425  evtForm = (Form_pg_event_trigger) GETSTRUCT(tup);
426  evtOid = evtForm->oid;
427 
428  AlterEventTriggerOwner_internal(rel, tup, newOwnerId);
429 
430  ObjectAddressSet(address, EventTriggerRelationId, evtOid);
431 
432  heap_freetuple(tup);
433 
435 
436  return address;
437 }
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, EVENTTRIGGERNAME, GETSTRUCT, heap_freetuple(), HeapTupleIsValid, name, ObjectAddressSet, RowExclusiveLock, SearchSysCacheCopy1, table_close(), and table_open().

Referenced by ExecAlterOwnerStmt().

◆ AlterEventTriggerOwner_internal()

static void AlterEventTriggerOwner_internal ( Relation  rel,
HeapTuple  tup,
Oid  newOwnerId 
)
static

Definition at line 468 of file event_trigger.c.

469 {
471 
472  form = (Form_pg_event_trigger) GETSTRUCT(tup);
473 
474  if (form->evtowner == newOwnerId)
475  return;
476 
477  if (!object_ownercheck(EventTriggerRelationId, form->oid, GetUserId()))
479  NameStr(form->evtname));
480 
481  /* New owner must be a superuser */
482  if (!superuser_arg(newOwnerId))
483  ereport(ERROR,
484  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
485  errmsg("permission denied to change owner of event trigger \"%s\"",
486  NameStr(form->evtname)),
487  errhint("The owner of an event trigger must be a superuser.")));
488 
489  form->evtowner = newOwnerId;
490  CatalogTupleUpdate(rel, &tup->t_self, tup);
491 
492  /* Update owner dependency reference */
493  changeDependencyOnOwner(EventTriggerRelationId,
494  form->oid,
495  newOwnerId);
496 
497  InvokeObjectPostAlterHook(EventTriggerRelationId,
498  form->oid, 0);
499 }
#define NameStr(name)
Definition: c.h:735
int errhint(const char *fmt,...)
Definition: elog.c:1316
void changeDependencyOnOwner(Oid classId, Oid objectId, Oid newOwnerId)
Definition: pg_shdepend.c:313
bool superuser_arg(Oid roleid)
Definition: superuser.c:56

References aclcheck_error(), ACLCHECK_NOT_OWNER, CatalogTupleUpdate(), changeDependencyOnOwner(), ereport, errcode(), errhint(), errmsg(), ERROR, GETSTRUCT, GetUserId(), InvokeObjectPostAlterHook, NameStr, OBJECT_EVENT_TRIGGER, object_ownercheck(), superuser_arg(), and HeapTupleData::t_self.

Referenced by AlterEventTriggerOwner(), and AlterEventTriggerOwner_oid().

◆ AlterEventTriggerOwner_oid()

void AlterEventTriggerOwner_oid ( Oid  trigOid,
Oid  newOwnerId 
)

Definition at line 443 of file event_trigger.c.

444 {
445  HeapTuple tup;
446  Relation rel;
447 
448  rel = table_open(EventTriggerRelationId, RowExclusiveLock);
449 
451 
452  if (!HeapTupleIsValid(tup))
453  ereport(ERROR,
454  (errcode(ERRCODE_UNDEFINED_OBJECT),
455  errmsg("event trigger with OID %u does not exist", trigOid)));
456 
457  AlterEventTriggerOwner_internal(rel, tup, newOwnerId);
458 
459  heap_freetuple(tup);
460 
462 }
static Datum ObjectIdGetDatum(Oid X)
Definition: postgres.h:252
@ EVENTTRIGGEROID
Definition: syscache.h:60

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

Referenced by shdepReassignOwned().

◆ CreateEventTrigger()

Oid CreateEventTrigger ( CreateEventTrigStmt stmt)

Definition at line 111 of file event_trigger.c.

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

References DefElem::arg, CStringGetDatum(), DefElem::defname, ereport, errcode(), ERRCODE_DUPLICATE_OBJECT, errhint(), errmsg(), ERROR, error_duplicate_filter_variable(), EVENTTRIGGERNAME, 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().

◆ error_duplicate_filter_variable()

static void error_duplicate_filter_variable ( const char *  defname)
static

Definition at line 247 of file event_trigger.c.

248 {
249  ereport(ERROR,
250  (errcode(ERRCODE_SYNTAX_ERROR),
251  errmsg("filter variable \"%s\" specified more than once",
252  defname)));
253 }

References ereport, errcode(), errmsg(), and ERROR.

Referenced by CreateEventTrigger().

◆ EventTriggerAlterTableEnd()

void EventTriggerAlterTableEnd ( void  )

Definition at line 1614 of file event_trigger.c.

1615 {
1616  CollectedCommand *parent;
1617 
1618  /* ignore if event trigger context not set, or collection disabled */
1619  if (!currentEventTriggerState ||
1621  return;
1622 
1624 
1625  /* If no subcommands, don't collect */
1627  {
1628  MemoryContext oldcxt;
1629 
1631 
1635 
1636  MemoryContextSwitchTo(oldcxt);
1637  }
1638  else
1640 
1642 }
static EventTriggerQueryState * currentEventTriggerState
Definition: event_trigger.c:73
List * lappend(List *list, void *datum)
Definition: list.c:338
void pfree(void *pointer)
Definition: mcxt.c:1456
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:138
#define NIL
Definition: pg_list.h:68
union CollectedCommand::@112 d
struct CollectedCommand * parent
struct CollectedCommand::@112::@114 alterTable
CollectedCommand * currentCommand
Definition: event_trigger.c:67

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

1528 {
1529  MemoryContext oldcxt;
1530  CollectedCommand *command;
1531 
1532  /* ignore if event trigger context not set, or collection disabled */
1533  if (!currentEventTriggerState ||
1535  return;
1536 
1538 
1539  command = palloc(sizeof(CollectedCommand));
1540 
1541  command->type = SCT_AlterTable;
1542  command->in_extension = creating_extension;
1543 
1544  command->d.alterTable.classId = RelationRelationId;
1545  command->d.alterTable.objectId = InvalidOid;
1546  command->d.alterTable.subcmds = NIL;
1547  command->parsetree = copyObject(parsetree);
1548 
1551 
1552  MemoryContextSwitchTo(oldcxt);
1553 }
@ SCT_AlterTable
bool creating_extension
Definition: extension.c:73
void * palloc(Size size)
Definition: mcxt.c:1226
#define copyObject(obj)
Definition: nodes.h:244
#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 1085 of file event_trigger.c.

1086 {
1088  MemoryContext cxt;
1089 
1090  /*
1091  * Currently, sql_drop, table_rewrite, ddl_command_end events are the only
1092  * reason to have event trigger state at all; so if there are none, don't
1093  * install one.
1094  */
1096  return false;
1097 
1099  "event trigger state",
1102  state->cxt = cxt;
1103  slist_init(&(state->SQLDropList));
1104  state->in_sql_drop = false;
1105  state->table_rewrite_oid = InvalidOid;
1106 
1107  state->commandCollectionInhibited = currentEventTriggerState ?
1109  state->currentCommand = NULL;
1110  state->commandList = NIL;
1111  state->previous = currentEventTriggerState;
1113 
1114  return true;
1115 }
bool trackDroppedObjectsNeeded(void)
static void slist_init(slist_head *head)
Definition: ilist.h:986
MemoryContext TopMemoryContext
Definition: mcxt.c:141
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition: mcxt.c:1021
#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 1798 of file event_trigger.c.

1799 {
1800  MemoryContext oldcxt;
1801  CollectedCommand *command;
1802 
1803  /* ignore if event trigger context not set, or collection disabled */
1804  if (!currentEventTriggerState ||
1806  return;
1807 
1809 
1810  command = palloc0(sizeof(CollectedCommand));
1811  command->type = SCT_AlterDefaultPrivileges;
1812  command->d.defprivs.objtype = stmt->action->objtype;
1813  command->in_extension = creating_extension;
1814  command->parsetree = (Node *) copyObject(stmt);
1815 
1818  MemoryContextSwitchTo(oldcxt);
1819 }
@ SCT_AlterDefaultPrivileges
void * palloc0(Size size)
Definition: mcxt.c:1257
struct CollectedCommand::@112::@119 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 1696 of file event_trigger.c.

1698 {
1699  MemoryContext oldcxt;
1700  CollectedCommand *command;
1701 
1702  /* ignore if event trigger context not set, or collection disabled */
1703  if (!currentEventTriggerState ||
1705  return;
1706 
1708 
1709  command = palloc(sizeof(CollectedCommand));
1710  command->type = SCT_AlterOpFamily;
1711  command->in_extension = creating_extension;
1712  ObjectAddressSet(command->d.opfam.address,
1713  OperatorFamilyRelationId, opfamoid);
1714  command->d.opfam.operators = operators;
1715  command->d.opfam.procedures = procedures;
1716  command->parsetree = (Node *) copyObject(stmt);
1717 
1720 
1721  MemoryContextSwitchTo(oldcxt);
1722 }
@ SCT_AlterOpFamily
struct CollectedCommand::@112::@116 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 1579 of file event_trigger.c.

1580 {
1581  MemoryContext oldcxt;
1583 
1584  /* ignore if event trigger context not set, or collection disabled */
1585  if (!currentEventTriggerState ||
1587  return;
1588 
1589  Assert(IsA(subcmd, AlterTableCmd));
1592 
1594 
1595  newsub = palloc(sizeof(CollectedATSubcmd));
1596  newsub->address = address;
1597  newsub->parsetree = copyObject(subcmd);
1598 
1601 
1602  MemoryContextSwitchTo(oldcxt);
1603 }
#define OidIsValid(objectId)
Definition: c.h:764
Assert(fmt[strlen(fmt) - 1] !='\n')
#define IsA(nodeptr, _type_)
Definition: nodes.h:179
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 1763 of file event_trigger.c.

1765 {
1766  MemoryContext oldcxt;
1767  CollectedCommand *command;
1768 
1769  /* ignore if event trigger context not set, or collection disabled */
1770  if (!currentEventTriggerState ||
1772  return;
1773 
1775 
1776  command = palloc0(sizeof(CollectedCommand));
1777  command->type = SCT_AlterTSConfig;
1778  command->in_extension = creating_extension;
1779  ObjectAddressSet(command->d.atscfg.address,
1780  TSConfigRelationId, cfgId);
1781  command->d.atscfg.dictIds = palloc(sizeof(Oid) * ndicts);
1782  memcpy(command->d.atscfg.dictIds, dictIds, sizeof(Oid) * ndicts);
1783  command->d.atscfg.ndicts = ndicts;
1784  command->parsetree = (Node *) copyObject(stmt);
1785 
1788 
1789  MemoryContextSwitchTo(oldcxt);
1790 }
@ SCT_AlterTSConfig
struct CollectedCommand::@112::@118 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 1729 of file event_trigger.c.

1731 {
1732  MemoryContext oldcxt;
1733  CollectedCommand *command;
1734 
1735  /* ignore if event trigger context not set, or collection disabled */
1736  if (!currentEventTriggerState ||
1738  return;
1739 
1741 
1742  command = palloc0(sizeof(CollectedCommand));
1743  command->type = SCT_CreateOpClass;
1744  command->in_extension = creating_extension;
1745  ObjectAddressSet(command->d.createopc.address,
1746  OperatorClassRelationId, opcoid);
1747  command->d.createopc.operators = operators;
1748  command->d.createopc.procedures = procedures;
1749  command->parsetree = (Node *) copyObject(stmt);
1750 
1753 
1754  MemoryContextSwitchTo(oldcxt);
1755 }
@ SCT_CreateOpClass
struct CollectedCommand::@112::@117 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 1652 of file event_trigger.c.

1653 {
1654  MemoryContext oldcxt;
1655  CollectedCommand *command;
1656  InternalGrant *icopy;
1657  ListCell *cell;
1658 
1659  /* ignore if event trigger context not set, or collection disabled */
1660  if (!currentEventTriggerState ||
1662  return;
1663 
1665 
1666  /*
1667  * This is tedious, but necessary.
1668  */
1669  icopy = palloc(sizeof(InternalGrant));
1670  memcpy(icopy, istmt, sizeof(InternalGrant));
1671  icopy->objects = list_copy(istmt->objects);
1672  icopy->grantees = list_copy(istmt->grantees);
1673  icopy->col_privs = NIL;
1674  foreach(cell, istmt->col_privs)
1675  icopy->col_privs = lappend(icopy->col_privs, copyObject(lfirst(cell)));
1676 
1677  /* Now collect it, using the copied InternalGrant */
1678  command = palloc(sizeof(CollectedCommand));
1679  command->type = SCT_Grant;
1680  command->in_extension = creating_extension;
1681  command->d.grant.istmt = icopy;
1682  command->parsetree = NULL;
1683 
1686 
1687  MemoryContextSwitchTo(oldcxt);
1688 }
@ SCT_Grant
List * list_copy(const List *oldlist)
Definition: list.c:1572
struct CollectedCommand::@112::@115 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 1489 of file event_trigger.c.

1492 {
1493  MemoryContext oldcxt;
1494  CollectedCommand *command;
1495 
1496  /* ignore if event trigger context not set, or collection disabled */
1497  if (!currentEventTriggerState ||
1499  return;
1500 
1502 
1503  command = palloc(sizeof(CollectedCommand));
1504 
1505  command->type = SCT_Simple;
1506  command->in_extension = creating_extension;
1507 
1508  command->d.simple.address = address;
1509  command->d.simple.secondaryObject = secondaryObject;
1510  command->parsetree = copyObject(parsetree);
1511 
1513  command);
1514 
1515  MemoryContextSwitchTo(oldcxt);
1516 }
@ SCT_Simple
struct CollectedCommand::@112::@113 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(), and PublicationAddTables().

◆ EventTriggerCommonSetup()

static List* EventTriggerCommonSetup ( Node parsetree,
EventTriggerEvent  event,
const char *  eventstr,
EventTriggerData trigdata 
)
static

Definition at line 558 of file event_trigger.c.

561 {
562  CommandTag tag;
563  List *cachelist;
564  ListCell *lc;
565  List *runlist = NIL;
566 
567  /*
568  * We want the list of command tags for which this procedure is actually
569  * invoked to match up exactly with the list that CREATE EVENT TRIGGER
570  * accepts. This debugging cross-check will throw an error if this
571  * function is invoked for a command tag that CREATE EVENT TRIGGER won't
572  * accept. (Unfortunately, there doesn't seem to be any simple, automated
573  * way to verify that CREATE EVENT TRIGGER doesn't accept extra stuff that
574  * never reaches this control point.)
575  *
576  * If this cross-check fails for you, you probably need to either adjust
577  * standard_ProcessUtility() not to invoke event triggers for the command
578  * type in question, or you need to adjust event_trigger_ok to accept the
579  * relevant command tag.
580  */
581 #ifdef USE_ASSERT_CHECKING
582  {
583  CommandTag dbgtag;
584 
585  dbgtag = CreateCommandTag(parsetree);
586  if (event == EVT_DDLCommandStart ||
587  event == EVT_DDLCommandEnd ||
588  event == EVT_SQLDrop)
589  {
590  if (!command_tag_event_trigger_ok(dbgtag))
591  elog(ERROR, "unexpected command tag \"%s\"", GetCommandTagName(dbgtag));
592  }
593  else if (event == EVT_TableRewrite)
594  {
595  if (!command_tag_table_rewrite_ok(dbgtag))
596  elog(ERROR, "unexpected command tag \"%s\"", GetCommandTagName(dbgtag));
597  }
598  }
599 #endif
600 
601  /* Use cache to find triggers for this event; fast exit if none. */
602  cachelist = EventCacheLookup(event);
603  if (cachelist == NIL)
604  return NIL;
605 
606  /* Get the command tag. */
607  tag = CreateCommandTag(parsetree);
608 
609  /*
610  * Filter list of event triggers by command tag, and copy them into our
611  * memory context. Once we start running the command triggers, or indeed
612  * once we do anything at all that touches the catalogs, an invalidation
613  * might leave cachelist pointing at garbage, so we must do this before we
614  * can do much else.
615  */
616  foreach(lc, cachelist)
617  {
618  EventTriggerCacheItem *item = lfirst(lc);
619 
620  if (filter_event_trigger(tag, item))
621  {
622  /* We must plan to fire this trigger. */
623  runlist = lappend_oid(runlist, item->fnoid);
624  }
625  }
626 
627  /* don't spend any more time on this if no functions to run */
628  if (runlist == NIL)
629  return NIL;
630 
631  trigdata->type = T_EventTriggerData;
632  trigdata->event = eventstr;
633  trigdata->parsetree = parsetree;
634  trigdata->tag = tag;
635 
636  return runlist;
637 }
bool command_tag_event_trigger_ok(CommandTag commandTag)
Definition: cmdtag.c:67
bool command_tag_table_rewrite_ok(CommandTag commandTag)
Definition: cmdtag.c:73
const char * GetCommandTagName(CommandTag commandTag)
Definition: cmdtag.c:48
CommandTag
Definition: cmdtag.h:23
static bool filter_event_trigger(CommandTag tag, EventTriggerCacheItem *item)
List * EventCacheLookup(EventTriggerEvent event)
Definition: evtcache.c:64
@ EVT_SQLDrop
Definition: evtcache.h:24
@ EVT_DDLCommandEnd
Definition: evtcache.h:23
@ EVT_DDLCommandStart
Definition: evtcache.h:22
@ EVT_TableRewrite
Definition: evtcache.h:25
List * lappend_oid(List *list, Oid datum)
Definition: list.c:374
CommandTag tag
Definition: event_trigger.h:29
const char * event
Definition: event_trigger.h:27
CommandTag CreateCommandTag(Node *parsetree)
Definition: utility.c:2364

References command_tag_event_trigger_ok(), command_tag_table_rewrite_ok(), CreateCommandTag(), elog(), ERROR, EventTriggerData::event, EventCacheLookup(), EVT_DDLCommandEnd, EVT_DDLCommandStart, EVT_SQLDrop, EVT_TableRewrite, filter_event_trigger(), EventTriggerCacheItem::fnoid, GetCommandTagName(), lappend_oid(), lfirst, NIL, EventTriggerData::parsetree, EventTriggerData::tag, and EventTriggerData::type.

Referenced by EventTriggerDDLCommandEnd(), EventTriggerDDLCommandStart(), EventTriggerSQLDrop(), and EventTriggerTableRewrite().

◆ EventTriggerDDLCommandEnd()

void EventTriggerDDLCommandEnd ( Node parsetree)

Definition at line 694 of file event_trigger.c.

695 {
696  List *runlist;
697  EventTriggerData trigdata;
698 
699  /*
700  * See EventTriggerDDLCommandStart for a discussion about why event
701  * triggers are disabled in single user mode or via GUC.
702  */
704  return;
705 
706  /*
707  * Also do nothing if our state isn't set up, which it won't be if there
708  * weren't any relevant event triggers at the start of the current DDL
709  * command. This test might therefore seem optional, but it's important
710  * because EventTriggerCommonSetup might find triggers that didn't exist
711  * at the time the command started. Although this function itself
712  * wouldn't crash, the event trigger functions would presumably call
713  * pg_event_trigger_ddl_commands which would fail. Better to do nothing
714  * until the next command.
715  */
717  return;
718 
719  runlist = EventTriggerCommonSetup(parsetree,
720  EVT_DDLCommandEnd, "ddl_command_end",
721  &trigdata);
722  if (runlist == NIL)
723  return;
724 
725  /*
726  * Make sure anything the main command did will be visible to the event
727  * triggers.
728  */
730 
731  /* Run the triggers. */
732  EventTriggerInvoke(runlist, &trigdata);
733 
734  /* Cleanup. */
735  list_free(runlist);
736 }
bool event_triggers
Definition: event_trigger.c:76
static List * EventTriggerCommonSetup(Node *parsetree, EventTriggerEvent event, const char *eventstr, EventTriggerData *trigdata)
static void EventTriggerInvoke(List *fn_oid_list, EventTriggerData *trigdata)
bool IsUnderPostmaster
Definition: globals.c:113
void list_free(List *list)
Definition: list.c:1545
void CommandCounterIncrement(void)
Definition: xact.c:1078

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

644 {
645  List *runlist;
646  EventTriggerData trigdata;
647 
648  /*
649  * Event Triggers are completely disabled in standalone mode. There are
650  * (at least) two reasons for this:
651  *
652  * 1. A sufficiently broken event trigger might not only render the
653  * database unusable, but prevent disabling itself to fix the situation.
654  * In this scenario, restarting in standalone mode provides an escape
655  * hatch.
656  *
657  * 2. BuildEventTriggerCache relies on systable_beginscan_ordered, and
658  * therefore will malfunction if pg_event_trigger's indexes are damaged.
659  * To allow recovery from a damaged index, we need some operating mode
660  * wherein event triggers are disabled. (Or we could implement
661  * heapscan-and-sort logic for that case, but having disaster recovery
662  * scenarios depend on code that's otherwise untested isn't appetizing.)
663  *
664  * Additionally, event triggers can be disabled with a superuser-only GUC
665  * to make fixing database easier as per 1 above.
666  */
668  return;
669 
670  runlist = EventTriggerCommonSetup(parsetree,
672  "ddl_command_start",
673  &trigdata);
674  if (runlist == NIL)
675  return;
676 
677  /* Run the triggers. */
678  EventTriggerInvoke(runlist, &trigdata);
679 
680  /* Cleanup. */
681  list_free(runlist);
682 
683  /*
684  * Make sure anything the event triggers did will be visible to the main
685  * command.
686  */
688 }

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

Referenced by ProcessUtilitySlow().

◆ EventTriggerEndCompleteQuery()

void EventTriggerEndCompleteQuery ( void  )

Definition at line 1129 of file event_trigger.c.

1130 {
1131  EventTriggerQueryState *prevstate;
1132 
1133  prevstate = currentEventTriggerState->previous;
1134 
1135  /* this avoids the need for retail pfree of SQLDropList items: */
1137 
1138  currentEventTriggerState = prevstate;
1139 }
void MemoryContextDelete(MemoryContext context)
Definition: mcxt.c:403
struct EventTriggerQueryState * previous
Definition: event_trigger.c:70

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

Referenced by ProcessUtilitySlow().

◆ EventTriggerInhibitCommandCollection()

void EventTriggerInhibitCommandCollection ( void  )

Definition at line 1455 of file event_trigger.c.

1456 {
1458  return;
1459 
1461 }

References EventTriggerQueryState::commandCollectionInhibited, and currentEventTriggerState.

Referenced by ProcessUtilitySlow().

◆ EventTriggerInvoke()

static void EventTriggerInvoke ( List fn_oid_list,
EventTriggerData trigdata 
)
static

Definition at line 878 of file event_trigger.c.

879 {
880  MemoryContext context;
881  MemoryContext oldcontext;
882  ListCell *lc;
883  bool first = true;
884 
885  /* Guard against stack overflow due to recursive event trigger */
887 
888  /*
889  * Let's evaluate event triggers in their own memory context, so that any
890  * leaks get cleaned up promptly.
891  */
893  "event trigger context",
895  oldcontext = MemoryContextSwitchTo(context);
896 
897  /* Call each event trigger. */
898  foreach(lc, fn_oid_list)
899  {
900  LOCAL_FCINFO(fcinfo, 0);
901  Oid fnoid = lfirst_oid(lc);
902  FmgrInfo flinfo;
903  PgStat_FunctionCallUsage fcusage;
904 
905  elog(DEBUG1, "EventTriggerInvoke %u", fnoid);
906 
907  /*
908  * We want each event trigger to be able to see the results of the
909  * previous event trigger's action. Caller is responsible for any
910  * command-counter increment that is needed between the event trigger
911  * and anything else in the transaction.
912  */
913  if (first)
914  first = false;
915  else
917 
918  /* Look up the function */
919  fmgr_info(fnoid, &flinfo);
920 
921  /* Call the function, passing no arguments but setting a context. */
922  InitFunctionCallInfoData(*fcinfo, &flinfo, 0,
923  InvalidOid, (Node *) trigdata, NULL);
924  pgstat_init_function_usage(fcinfo, &fcusage);
925  FunctionCallInvoke(fcinfo);
926  pgstat_end_function_usage(&fcusage, true);
927 
928  /* Reclaim memory. */
929  MemoryContextReset(context);
930  }
931 
932  /* Restore old memory context and delete the temporary one. */
933  MemoryContextSwitchTo(oldcontext);
934  MemoryContextDelete(context);
935 }
#define DEBUG1
Definition: elog.h:30
void fmgr_info(Oid functionId, FmgrInfo *finfo)
Definition: fmgr.c:127
#define InitFunctionCallInfoData(Fcinfo, Flinfo, Nargs, Collation, Context, Resultinfo)
Definition: fmgr.h:150
#define LOCAL_FCINFO(name, nargs)
Definition: fmgr.h:110
#define FunctionCallInvoke(fcinfo)
Definition: fmgr.h:172
void MemoryContextReset(MemoryContext context)
Definition: mcxt.c:330
MemoryContext CurrentMemoryContext
Definition: mcxt.c:135
#define lfirst_oid(lc)
Definition: pg_list.h:174
void pgstat_init_function_usage(FunctionCallInfo fcinfo, PgStat_FunctionCallUsage *fcu)
void pgstat_end_function_usage(PgStat_FunctionCallUsage *fcu, bool finalize)
void check_stack_depth(void)
Definition: postgres.c:3523
Definition: fmgr.h:57

References ALLOCSET_DEFAULT_SIZES, AllocSetContextCreate, check_stack_depth(), CommandCounterIncrement(), CurrentMemoryContext, DEBUG1, elog(), fmgr_info(), FunctionCallInvoke, InitFunctionCallInfoData, InvalidOid, lfirst_oid, LOCAL_FCINFO, MemoryContextDelete(), MemoryContextReset(), MemoryContextSwitchTo(), pgstat_end_function_usage(), and pgstat_init_function_usage().

Referenced by EventTriggerDDLCommandEnd(), EventTriggerDDLCommandStart(), EventTriggerSQLDrop(), and EventTriggerTableRewrite().

◆ EventTriggerSQLDrop()

void EventTriggerSQLDrop ( Node parsetree)

Definition at line 742 of file event_trigger.c.

743 {
744  List *runlist;
745  EventTriggerData trigdata;
746 
747  /*
748  * See EventTriggerDDLCommandStart for a discussion about why event
749  * triggers are disabled in single user mode or via a GUC.
750  */
752  return;
753 
754  /*
755  * Use current state to determine whether this event fires at all. If
756  * there are no triggers for the sql_drop event, then we don't have
757  * anything to do here. Note that dropped object collection is disabled
758  * if this is the case, so even if we were to try to run, the list would
759  * be empty.
760  */
763  return;
764 
765  runlist = EventTriggerCommonSetup(parsetree,
766  EVT_SQLDrop, "sql_drop",
767  &trigdata);
768 
769  /*
770  * Nothing to do if run list is empty. Note this typically can't happen,
771  * because if there are no sql_drop events, then objects-to-drop wouldn't
772  * have been collected in the first place and we would have quit above.
773  * But it could occur if event triggers were dropped partway through.
774  */
775  if (runlist == NIL)
776  return;
777 
778  /*
779  * Make sure anything the main command did will be visible to the event
780  * triggers.
781  */
783 
784  /*
785  * Make sure pg_event_trigger_dropped_objects only works when running
786  * these triggers. Use PG_TRY to ensure in_sql_drop is reset even when
787  * one trigger fails. (This is perhaps not necessary, as the currentState
788  * variable will be removed shortly by our caller, but it seems better to
789  * play safe.)
790  */
792 
793  /* Run the triggers. */
794  PG_TRY();
795  {
796  EventTriggerInvoke(runlist, &trigdata);
797  }
798  PG_FINALLY();
799  {
801  }
802  PG_END_TRY();
803 
804  /* Cleanup. */
805  list_free(runlist);
806 }
#define PG_TRY(...)
Definition: elog.h:370
#define PG_END_TRY(...)
Definition: elog.h:395
#define PG_FINALLY(...)
Definition: elog.h:387
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 1179 of file event_trigger.c.

1180 {
1181  SQLDropObject *obj;
1182  MemoryContext oldcxt;
1183 
1185  return;
1186 
1188 
1189  /* don't report temp schemas except my own */
1190  if (object->classId == NamespaceRelationId &&
1191  (isAnyTempNamespace(object->objectId) &&
1192  !isTempNamespace(object->objectId)))
1193  return;
1194 
1196 
1197  obj = palloc0(sizeof(SQLDropObject));
1198  obj->address = *object;
1199  obj->original = original;
1200  obj->normal = normal;
1201 
1202  /*
1203  * Obtain schema names from the object's catalog tuple, if one exists;
1204  * this lets us skip objects in temp schemas. We trust that
1205  * ObjectProperty contains all object classes that can be
1206  * schema-qualified.
1207  */
1208  if (is_objectclass_supported(object->classId))
1209  {
1210  Relation catalog;
1211  HeapTuple tuple;
1212 
1213  catalog = table_open(obj->address.classId, AccessShareLock);
1214  tuple = get_catalog_object_by_oid(catalog,
1215  get_object_attnum_oid(object->classId),
1216  obj->address.objectId);
1217 
1218  if (tuple)
1219  {
1221  Datum datum;
1222  bool isnull;
1223 
1225  if (attnum != InvalidAttrNumber)
1226  {
1227  datum = heap_getattr(tuple, attnum,
1228  RelationGetDescr(catalog), &isnull);
1229  if (!isnull)
1230  {
1231  Oid namespaceId;
1232 
1233  namespaceId = DatumGetObjectId(datum);
1234  /* temp objects are only reported if they are my own */
1235  if (isTempNamespace(namespaceId))
1236  {
1237  obj->schemaname = "pg_temp";
1238  obj->istemp = true;
1239  }
1240  else if (isAnyTempNamespace(namespaceId))
1241  {
1242  pfree(obj);
1243  table_close(catalog, AccessShareLock);
1244  MemoryContextSwitchTo(oldcxt);
1245  return;
1246  }
1247  else
1248  {
1249  obj->schemaname = get_namespace_name(namespaceId);
1250  obj->istemp = false;
1251  }
1252  }
1253  }
1254 
1256  obj->address.objectSubId == 0)
1257  {
1259  if (attnum != InvalidAttrNumber)
1260  {
1261  datum = heap_getattr(tuple, attnum,
1262  RelationGetDescr(catalog), &isnull);
1263  if (!isnull)
1264  obj->objname = pstrdup(NameStr(*DatumGetName(datum)));
1265  }
1266  }
1267  }
1268 
1269  table_close(catalog, AccessShareLock);
1270  }
1271  else
1272  {
1273  if (object->classId == NamespaceRelationId &&
1274  isTempNamespace(object->objectId))
1275  obj->istemp = true;
1276  }
1277 
1278  /* object identity, objname and objargs */
1279  obj->objidentity =
1280  getObjectIdentityParts(&obj->address, &obj->addrnames, &obj->addrargs,
1281  false);
1282 
1283  /* object type */
1284  obj->objecttype = getObjectTypeDescription(&obj->address, false);
1285 
1287 
1288  MemoryContextSwitchTo(oldcxt);
1289 }
int16 AttrNumber
Definition: attnum.h:21
#define InvalidAttrNumber
Definition: attnum.h:23
ObjectClass getObjectClass(const ObjectAddress *object)
Definition: dependency.c:2836
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:3348
char * pstrdup(const char *in)
Definition: mcxt.c:1644
bool isTempNamespace(Oid namespaceId)
Definition: namespace.c:3182
bool isAnyTempNamespace(Oid namespaceId)
Definition: namespace.c:3220
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:530
ObjectAddress address
Definition: event_trigger.c:81
const char * schemaname
Definition: event_trigger.c:82
slist_node next
Definition: event_trigger.c:91
const char * objidentity
Definition: event_trigger.c:84
const char * objecttype
Definition: event_trigger.c:85
List * addrnames
Definition: event_trigger.c:86
const char * objname
Definition: event_trigger.c:83

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

1018 {
1019  switch (objclass)
1020  {
1021  case OCLASS_DATABASE:
1022  case OCLASS_TBLSPACE:
1023  case OCLASS_ROLE:
1025  case OCLASS_PARAMETER_ACL:
1026  /* no support for global objects */
1027  return false;
1028  case OCLASS_EVENT_TRIGGER:
1029  /* no support for event triggers on event triggers */
1030  return false;
1031  case OCLASS_CLASS:
1032  case OCLASS_PROC:
1033  case OCLASS_TYPE:
1034  case OCLASS_CAST:
1035  case OCLASS_COLLATION:
1036  case OCLASS_CONSTRAINT:
1037  case OCLASS_CONVERSION:
1038  case OCLASS_DEFAULT:
1039  case OCLASS_LANGUAGE:
1040  case OCLASS_LARGEOBJECT:
1041  case OCLASS_OPERATOR:
1042  case OCLASS_OPCLASS:
1043  case OCLASS_OPFAMILY:
1044  case OCLASS_AM:
1045  case OCLASS_AMOP:
1046  case OCLASS_AMPROC:
1047  case OCLASS_REWRITE:
1048  case OCLASS_TRIGGER:
1049  case OCLASS_SCHEMA:
1050  case OCLASS_STATISTIC_EXT:
1051  case OCLASS_TSPARSER:
1052  case OCLASS_TSDICT:
1053  case OCLASS_TSTEMPLATE:
1054  case OCLASS_TSCONFIG:
1055  case OCLASS_FDW:
1056  case OCLASS_FOREIGN_SERVER:
1057  case OCLASS_USER_MAPPING:
1058  case OCLASS_DEFACL:
1059  case OCLASS_EXTENSION:
1060  case OCLASS_POLICY:
1061  case OCLASS_PUBLICATION:
1064  case OCLASS_SUBSCRIPTION:
1065  case OCLASS_TRANSFORM:
1066  return true;
1067 
1068  /*
1069  * There's intentionally no default: case here; we want the
1070  * compiler to warn if a new OCLASS hasn't been handled above.
1071  */
1072  }
1073 
1074  /* Shouldn't get here, but if we do, say "no support" */
1075  return false;
1076 }
@ 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 941 of file event_trigger.c.

942 {
943  switch (obtype)
944  {
945  case OBJECT_DATABASE:
946  case OBJECT_TABLESPACE:
947  case OBJECT_ROLE:
949  /* no support for global objects */
950  return false;
952  /* no support for event triggers on event triggers */
953  return false;
955  case OBJECT_AGGREGATE:
956  case OBJECT_AMOP:
957  case OBJECT_AMPROC:
958  case OBJECT_ATTRIBUTE:
959  case OBJECT_CAST:
960  case OBJECT_COLUMN:
961  case OBJECT_COLLATION:
962  case OBJECT_CONVERSION:
963  case OBJECT_DEFACL:
964  case OBJECT_DEFAULT:
965  case OBJECT_DOMAIN:
967  case OBJECT_EXTENSION:
968  case OBJECT_FDW:
971  case OBJECT_FUNCTION:
972  case OBJECT_INDEX:
973  case OBJECT_LANGUAGE:
974  case OBJECT_LARGEOBJECT:
975  case OBJECT_MATVIEW:
976  case OBJECT_OPCLASS:
977  case OBJECT_OPERATOR:
978  case OBJECT_OPFAMILY:
979  case OBJECT_POLICY:
980  case OBJECT_PROCEDURE:
981  case OBJECT_PUBLICATION:
984  case OBJECT_ROUTINE:
985  case OBJECT_RULE:
986  case OBJECT_SCHEMA:
987  case OBJECT_SEQUENCE:
988  case OBJECT_SUBSCRIPTION:
991  case OBJECT_TABLE:
992  case OBJECT_TRANSFORM:
993  case OBJECT_TRIGGER:
995  case OBJECT_TSDICTIONARY:
996  case OBJECT_TSPARSER:
997  case OBJECT_TSTEMPLATE:
998  case OBJECT_TYPE:
999  case OBJECT_USER_MAPPING:
1000  case OBJECT_VIEW:
1001  return true;
1002 
1003  /*
1004  * There's intentionally no default: case here; we want the
1005  * compiler to warn if a new ObjectType hasn't been handled above.
1006  */
1007  }
1008 
1009  /* Shouldn't get here, but if we do, say "no support" */
1010  return false;
1011 }
@ OBJECT_FDW
Definition: parsenodes.h:2136
@ OBJECT_TSPARSER
Definition: parsenodes.h:2167
@ OBJECT_COLLATION
Definition: parsenodes.h:2127
@ OBJECT_USER_MAPPING
Definition: parsenodes.h:2170
@ OBJECT_ACCESS_METHOD
Definition: parsenodes.h:2120
@ OBJECT_OPCLASS
Definition: parsenodes.h:2144
@ OBJECT_DEFACL
Definition: parsenodes.h:2131
@ OBJECT_AGGREGATE
Definition: parsenodes.h:2121
@ OBJECT_MATVIEW
Definition: parsenodes.h:2143
@ OBJECT_SCHEMA
Definition: parsenodes.h:2156
@ OBJECT_POLICY
Definition: parsenodes.h:2148
@ OBJECT_OPERATOR
Definition: parsenodes.h:2145
@ OBJECT_FOREIGN_TABLE
Definition: parsenodes.h:2138
@ OBJECT_TSCONFIGURATION
Definition: parsenodes.h:2165
@ OBJECT_OPFAMILY
Definition: parsenodes.h:2146
@ OBJECT_DOMAIN
Definition: parsenodes.h:2132
@ OBJECT_COLUMN
Definition: parsenodes.h:2126
@ OBJECT_TABLESPACE
Definition: parsenodes.h:2162
@ OBJECT_ROLE
Definition: parsenodes.h:2153
@ OBJECT_ROUTINE
Definition: parsenodes.h:2154
@ OBJECT_LARGEOBJECT
Definition: parsenodes.h:2142
@ OBJECT_PUBLICATION_NAMESPACE
Definition: parsenodes.h:2151
@ OBJECT_PROCEDURE
Definition: parsenodes.h:2149
@ OBJECT_EXTENSION
Definition: parsenodes.h:2135
@ OBJECT_INDEX
Definition: parsenodes.h:2140
@ OBJECT_DEFAULT
Definition: parsenodes.h:2130
@ OBJECT_DATABASE
Definition: parsenodes.h:2129
@ OBJECT_SEQUENCE
Definition: parsenodes.h:2157
@ OBJECT_TSTEMPLATE
Definition: parsenodes.h:2168
@ OBJECT_LANGUAGE
Definition: parsenodes.h:2141
@ OBJECT_AMOP
Definition: parsenodes.h:2122
@ OBJECT_PUBLICATION_REL
Definition: parsenodes.h:2152
@ OBJECT_FOREIGN_SERVER
Definition: parsenodes.h:2137
@ OBJECT_TSDICTIONARY
Definition: parsenodes.h:2166
@ OBJECT_ATTRIBUTE
Definition: parsenodes.h:2124
@ OBJECT_PUBLICATION
Definition: parsenodes.h:2150
@ OBJECT_RULE
Definition: parsenodes.h:2155
@ OBJECT_CONVERSION
Definition: parsenodes.h:2128
@ OBJECT_AMPROC
Definition: parsenodes.h:2123
@ OBJECT_TABLE
Definition: parsenodes.h:2161
@ OBJECT_VIEW
Definition: parsenodes.h:2171
@ OBJECT_PARAMETER_ACL
Definition: parsenodes.h:2147
@ OBJECT_TYPE
Definition: parsenodes.h:2169
@ OBJECT_FUNCTION
Definition: parsenodes.h:2139
@ OBJECT_TABCONSTRAINT
Definition: parsenodes.h:2160
@ OBJECT_DOMCONSTRAINT
Definition: parsenodes.h:2133
@ OBJECT_SUBSCRIPTION
Definition: parsenodes.h:2158
@ OBJECT_STATISTIC_EXT
Definition: parsenodes.h:2159
@ OBJECT_CAST
Definition: parsenodes.h:2125
@ OBJECT_TRIGGER
Definition: parsenodes.h:2164
@ OBJECT_TRANSFORM
Definition: parsenodes.h:2163

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 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  * Also do nothing if our state isn't set up, which it won't be if there
827  * weren't any relevant event triggers at the start of the current DDL
828  * command. This test might therefore seem optional, but it's
829  * *necessary*, because EventTriggerCommonSetup might find triggers that
830  * didn't exist at the time the command started.
831  */
833  return;
834 
835  runlist = EventTriggerCommonSetup(parsetree,
837  "table_rewrite",
838  &trigdata);
839  if (runlist == NIL)
840  return;
841 
842  /*
843  * Make sure pg_event_trigger_table_rewrite_oid only works when running
844  * these triggers. Use PG_TRY to ensure table_rewrite_oid is reset even
845  * when one trigger fails. (This is perhaps not necessary, as the
846  * currentState variable will be removed shortly by our caller, but it
847  * seems better to play safe.)
848  */
851 
852  /* Run the triggers. */
853  PG_TRY();
854  {
855  EventTriggerInvoke(runlist, &trigdata);
856  }
857  PG_FINALLY();
858  {
861  }
862  PG_END_TRY();
863 
864  /* Cleanup. */
865  list_free(runlist);
866 
867  /*
868  * Make sure anything the event triggers did will be visible to the main
869  * command.
870  */
872 }

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

1468 {
1470  return;
1471 
1473 }

References EventTriggerQueryState::commandCollectionInhibited, and currentEventTriggerState.

Referenced by ProcessUtilitySlow().

◆ filter_event_trigger()

static bool filter_event_trigger ( CommandTag  tag,
EventTriggerCacheItem item 
)
static

Definition at line 527 of file event_trigger.c.

528 {
529  /*
530  * Filter by session replication role, knowing that we never see disabled
531  * items down here.
532  */
534  {
535  if (item->enabled == TRIGGER_FIRES_ON_ORIGIN)
536  return false;
537  }
538  else
539  {
540  if (item->enabled == TRIGGER_FIRES_ON_REPLICA)
541  return false;
542  }
543 
544  /* Filter by tags, if any were specified. */
545  if (!bms_is_empty(item->tagset) && !bms_is_member(tag, item->tagset))
546  return false;
547 
548  /* if we reach that point, we're not filtering out this item */
549  return true;
550 }
bool bms_is_member(int x, const Bitmapset *a)
Definition: bitmapset.c:460
#define bms_is_empty(a)
Definition: bitmapset.h:105
Bitmapset * tagset
Definition: evtcache.h:32
int SessionReplicationRole
Definition: trigger.c:70
#define SESSION_REPLICATION_ROLE_REPLICA
Definition: trigger.h:141
#define TRIGGER_FIRES_ON_ORIGIN
Definition: trigger.h:149
#define TRIGGER_FIRES_ON_REPLICA
Definition: trigger.h:151

References bms_is_empty, bms_is_member(), EventTriggerCacheItem::enabled, SESSION_REPLICATION_ROLE_REPLICA, SessionReplicationRole, EventTriggerCacheItem::tagset, TRIGGER_FIRES_ON_ORIGIN, and TRIGGER_FIRES_ON_REPLICA.

Referenced by EventTriggerCommonSetup().

◆ filter_list_to_array()

static Datum filter_list_to_array ( List filterlist)
static

Definition at line 335 of file event_trigger.c.

336 {
337  ListCell *lc;
338  Datum *data;
339  int i = 0,
340  l = list_length(filterlist);
341 
342  data = (Datum *) palloc(l * sizeof(Datum));
343 
344  foreach(lc, filterlist)
345  {
346  const char *value = strVal(lfirst(lc));
347  char *result,
348  *p;
349 
350  result = pstrdup(value);
351  for (p = result; *p; p++)
352  *p = pg_ascii_toupper((unsigned char) *p);
353  data[i++] = PointerGetDatum(cstring_to_text(result));
354  pfree(result);
355  }
356 
357  return PointerGetDatum(construct_array_builtin(data, l, TEXTOID));
358 }
ArrayType * construct_array_builtin(Datum *elems, int nelems, Oid elmtype)
Definition: arrayfuncs.c:3340
static struct @148 value
int i
Definition: isn.c:73
const void * data
static int list_length(const List *l)
Definition: pg_list.h:152
unsigned char pg_ascii_toupper(unsigned char ch)
Definition: pgstrcasecmp.c:135
static Datum PointerGetDatum(const void *X)
Definition: postgres.h:322
#define strVal(v)
Definition: value.h:82
text * cstring_to_text(const char *s)
Definition: varlena.c:182

References construct_array_builtin(), cstring_to_text(), data, i, lfirst, list_length(), palloc(), pfree(), pg_ascii_toupper(), PointerGetDatum(), pstrdup(), strVal, and value.

Referenced by insert_event_trigger_tuple().

◆ get_event_trigger_oid()

Oid get_event_trigger_oid ( const char *  trigname,
bool  missing_ok 
)

Definition at line 508 of file event_trigger.c.

509 {
510  Oid oid;
511 
512  oid = GetSysCacheOid1(EVENTTRIGGERNAME, Anum_pg_event_trigger_oid,
513  CStringGetDatum(trigname));
514  if (!OidIsValid(oid) && !missing_ok)
515  ereport(ERROR,
516  (errcode(ERRCODE_UNDEFINED_OBJECT),
517  errmsg("event trigger \"%s\" does not exist", trigname)));
518  return oid;
519 }
#define GetSysCacheOid1(cacheId, oidcol, key1)
Definition: syscache.h:200

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

Referenced by get_object_address_unqualified().

◆ insert_event_trigger_tuple()

static Oid insert_event_trigger_tuple ( const char *  trigname,
const char *  eventname,
Oid  evtOwner,
Oid  funcoid,
List taglist 
)
static

Definition at line 259 of file event_trigger.c.

261 {
262  Relation tgrel;
263  Oid trigoid;
264  HeapTuple tuple;
265  Datum values[Natts_pg_trigger];
266  bool nulls[Natts_pg_trigger];
267  NameData evtnamedata,
268  evteventdata;
269  ObjectAddress myself,
270  referenced;
271 
272  /* Open pg_event_trigger. */
273  tgrel = table_open(EventTriggerRelationId, RowExclusiveLock);
274 
275  /* Build the new pg_trigger tuple. */
276  trigoid = GetNewOidWithIndex(tgrel, EventTriggerOidIndexId,
277  Anum_pg_event_trigger_oid);
278  values[Anum_pg_event_trigger_oid - 1] = ObjectIdGetDatum(trigoid);
279  memset(nulls, false, sizeof(nulls));
280  namestrcpy(&evtnamedata, trigname);
281  values[Anum_pg_event_trigger_evtname - 1] = NameGetDatum(&evtnamedata);
282  namestrcpy(&evteventdata, eventname);
283  values[Anum_pg_event_trigger_evtevent - 1] = NameGetDatum(&evteventdata);
284  values[Anum_pg_event_trigger_evtowner - 1] = ObjectIdGetDatum(evtOwner);
285  values[Anum_pg_event_trigger_evtfoid - 1] = ObjectIdGetDatum(funcoid);
286  values[Anum_pg_event_trigger_evtenabled - 1] =
288  if (taglist == NIL)
289  nulls[Anum_pg_event_trigger_evttags - 1] = true;
290  else
291  values[Anum_pg_event_trigger_evttags - 1] =
292  filter_list_to_array(taglist);
293 
294  /* Insert heap tuple. */
295  tuple = heap_form_tuple(tgrel->rd_att, values, nulls);
296  CatalogTupleInsert(tgrel, tuple);
297  heap_freetuple(tuple);
298 
299  /* Depend on owner. */
300  recordDependencyOnOwner(EventTriggerRelationId, trigoid, evtOwner);
301 
302  /* Depend on event trigger function. */
303  myself.classId = EventTriggerRelationId;
304  myself.objectId = trigoid;
305  myself.objectSubId = 0;
306  referenced.classId = ProcedureRelationId;
307  referenced.objectId = funcoid;
308  referenced.objectSubId = 0;
309  recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
310 
311  /* Depend on extension, if any. */
312  recordDependencyOnCurrentExtension(&myself, false);
313 
314  /* Post creation hook for new event trigger */
315  InvokeObjectPostCreateHook(EventTriggerRelationId, trigoid, 0);
316 
317  /* Close pg_event_trigger. */
319 
320  return trigoid;
321 }
static Datum values[MAXATTR]
Definition: bootstrap.c:156
Oid GetNewOidWithIndex(Relation relation, Oid indexId, AttrNumber oidcolumn)
Definition: catalog.c:393
@ DEPENDENCY_NORMAL
Definition: dependency.h:33
static Datum filter_list_to_array(List *filterlist)
HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, Datum *values, bool *isnull)
Definition: heaptuple.c:1108
void CatalogTupleInsert(Relation heapRel, HeapTuple tup)
Definition: indexing.c:233
void namestrcpy(Name name, const char *str)
Definition: name.c:233
#define InvokeObjectPostCreateHook(classId, objectId, subId)
Definition: objectaccess.h:173
void recordDependencyOn(const ObjectAddress *depender, const ObjectAddress *referenced, DependencyType behavior)
Definition: pg_depend.c:44
void recordDependencyOnCurrentExtension(const ObjectAddress *object, bool isReplace)
Definition: pg_depend.c:192
void recordDependencyOnOwner(Oid classId, Oid objectId, Oid owner)
Definition: pg_shdepend.c:165
static Datum NameGetDatum(const NameData *X)
Definition: postgres.h:373
static Datum CharGetDatum(char X)
Definition: postgres.h:122
TupleDesc rd_att
Definition: rel.h:112
Definition: c.h:730

References CatalogTupleInsert(), CharGetDatum(), ObjectAddress::classId, DEPENDENCY_NORMAL, filter_list_to_array(), GetNewOidWithIndex(), heap_form_tuple(), heap_freetuple(), InvokeObjectPostCreateHook, NameGetDatum(), namestrcpy(), NIL, ObjectAddress::objectId, ObjectIdGetDatum(), ObjectAddress::objectSubId, RelationData::rd_att, recordDependencyOn(), recordDependencyOnCurrentExtension(), recordDependencyOnOwner(), RowExclusiveLock, table_close(), table_open(), TRIGGER_FIRES_ON_ORIGIN, and values.

Referenced by CreateEventTrigger().

◆ pg_event_trigger_ddl_commands()

Datum pg_event_trigger_ddl_commands ( PG_FUNCTION_ARGS  )

Definition at line 1826 of file event_trigger.c.

1827 {
1828  ReturnSetInfo *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo;
1829  ListCell *lc;
1830 
1831  /*
1832  * Protect this function from being called out of context
1833  */
1835  ereport(ERROR,
1836  (errcode(ERRCODE_E_R_I_E_EVENT_TRIGGER_PROTOCOL_VIOLATED),
1837  errmsg("%s can only be called in an event trigger function",
1838  "pg_event_trigger_ddl_commands()")));
1839 
1840  /* Build tuplestore to hold the result rows */
1841  InitMaterializedSRF(fcinfo, 0);
1842 
1844  {
1845  CollectedCommand *cmd = lfirst(lc);
1846  Datum values[9];
1847  bool nulls[9] = {0};
1848  ObjectAddress addr;
1849  int i = 0;
1850 
1851  /*
1852  * For IF NOT EXISTS commands that attempt to create an existing
1853  * object, the returned OID is Invalid. Don't return anything.
1854  *
1855  * One might think that a viable alternative would be to look up the
1856  * Oid of the existing object and run the deparse with that. But
1857  * since the parse tree might be different from the one that created
1858  * the object in the first place, we might not end up in a consistent
1859  * state anyway.
1860  */
1861  if (cmd->type == SCT_Simple &&
1862  !OidIsValid(cmd->d.simple.address.objectId))
1863  continue;
1864 
1865  switch (cmd->type)
1866  {
1867  case SCT_Simple:
1868  case SCT_AlterTable:
1869  case SCT_AlterOpFamily:
1870  case SCT_CreateOpClass:
1871  case SCT_AlterTSConfig:
1872  {
1873  char *identity;
1874  char *type;
1875  char *schema = NULL;
1876 
1877  if (cmd->type == SCT_Simple)
1878  addr = cmd->d.simple.address;
1879  else if (cmd->type == SCT_AlterTable)
1880  ObjectAddressSet(addr,
1881  cmd->d.alterTable.classId,
1882  cmd->d.alterTable.objectId);
1883  else if (cmd->type == SCT_AlterOpFamily)
1884  addr = cmd->d.opfam.address;
1885  else if (cmd->type == SCT_CreateOpClass)
1886  addr = cmd->d.createopc.address;
1887  else if (cmd->type == SCT_AlterTSConfig)
1888  addr = cmd->d.atscfg.address;
1889 
1890  /*
1891  * If an object was dropped in the same command we may end
1892  * up in a situation where we generated a message but can
1893  * no longer look for the object information, so skip it
1894  * rather than failing. This can happen for example with
1895  * some subcommand combinations of ALTER TABLE.
1896  */
1897  identity = getObjectIdentity(&addr, true);
1898  if (identity == NULL)
1899  continue;
1900 
1901  /* The type can never be NULL. */
1902  type = getObjectTypeDescription(&addr, true);
1903 
1904  /*
1905  * Obtain schema name, if any ("pg_temp" if a temp
1906  * object). If the object class is not in the supported
1907  * list here, we assume it's a schema-less object type,
1908  * and thus "schema" remains set to NULL.
1909  */
1911  {
1912  AttrNumber nspAttnum;
1913 
1914  nspAttnum = get_object_attnum_namespace(addr.classId);
1915  if (nspAttnum != InvalidAttrNumber)
1916  {
1917  Relation catalog;
1918  HeapTuple objtup;
1919  Oid schema_oid;
1920  bool isnull;
1921 
1922  catalog = table_open(addr.classId, AccessShareLock);
1923  objtup = get_catalog_object_by_oid(catalog,
1925  addr.objectId);
1926  if (!HeapTupleIsValid(objtup))
1927  elog(ERROR, "cache lookup failed for object %u/%u",
1928  addr.classId, addr.objectId);
1929  schema_oid =
1930  heap_getattr(objtup, nspAttnum,
1931  RelationGetDescr(catalog), &isnull);
1932  if (isnull)
1933  elog(ERROR,
1934  "invalid null namespace in object %u/%u/%d",
1935  addr.classId, addr.objectId, addr.objectSubId);
1936  schema = get_namespace_name_or_temp(schema_oid);
1937 
1938  table_close(catalog, AccessShareLock);
1939  }
1940  }
1941 
1942  /* classid */
1943  values[i++] = ObjectIdGetDatum(addr.classId);
1944  /* objid */
1945  values[i++] = ObjectIdGetDatum(addr.objectId);
1946  /* objsubid */
1947  values[i++] = Int32GetDatum(addr.objectSubId);
1948  /* command tag */
1950  /* object_type */
1952  /* schema */
1953  if (schema == NULL)
1954  nulls[i++] = true;
1955  else
1956  values[i++] = CStringGetTextDatum(schema);
1957  /* identity */
1958  values[i++] = CStringGetTextDatum(identity);
1959  /* in_extension */
1960  values[i++] = BoolGetDatum(cmd->in_extension);
1961  /* command */
1962  values[i++] = PointerGetDatum(cmd);
1963  }
1964  break;
1965 
1967  /* classid */
1968  nulls[i++] = true;
1969  /* objid */
1970  nulls[i++] = true;
1971  /* objsubid */
1972  nulls[i++] = true;
1973  /* command tag */
1975  /* object_type */
1977  /* schema */
1978  nulls[i++] = true;
1979  /* identity */
1980  nulls[i++] = true;
1981  /* in_extension */
1982  values[i++] = BoolGetDatum(cmd->in_extension);
1983  /* command */
1984  values[i++] = PointerGetDatum(cmd);
1985  break;
1986 
1987  case SCT_Grant:
1988  /* classid */
1989  nulls[i++] = true;
1990  /* objid */
1991  nulls[i++] = true;
1992  /* objsubid */
1993  nulls[i++] = true;
1994  /* command tag */
1995  values[i++] = CStringGetTextDatum(cmd->d.grant.istmt->is_grant ?
1996  "GRANT" : "REVOKE");
1997  /* object_type */
1998  values[i++] = CStringGetTextDatum(stringify_grant_objtype(cmd->d.grant.istmt->objtype));
1999  /* schema */
2000  nulls[i++] = true;
2001  /* identity */
2002  nulls[i++] = true;
2003  /* in_extension */
2004  values[i++] = BoolGetDatum(cmd->in_extension);
2005  /* command */
2006  values[i++] = PointerGetDatum(cmd);
2007  break;
2008  }
2009 
2010  tuplestore_putvalues(rsinfo->setResult, rsinfo->setDesc,
2011  values, nulls);
2012  }
2013 
2014  PG_RETURN_VOID();
2015 }
#define CStringGetTextDatum(s)
Definition: builtins.h:94
static const char * stringify_adefprivs_objtype(ObjectType objtype)
static const char * stringify_grant_objtype(ObjectType objtype)
#define PG_RETURN_VOID()
Definition: fmgr.h:349
void InitMaterializedSRF(FunctionCallInfo fcinfo, bits32 flags)
Definition: funcapi.c:76
if(TABLE==NULL||TABLE_index==NULL)
Definition: isn.c:77
char * get_namespace_name_or_temp(Oid nspid)
Definition: lsyscache.c:3372
char * getObjectIdentity(const ObjectAddress *object, bool missing_ok)
static Datum BoolGetDatum(bool X)
Definition: postgres.h:102
static Datum Int32GetDatum(int32 X)
Definition: postgres.h:212
TupleDesc setDesc
Definition: execnodes.h:334
Tuplestorestate * setResult
Definition: execnodes.h:333
void tuplestore_putvalues(Tuplestorestate *state, TupleDesc tdesc, Datum *values, bool *isnull)
Definition: tuplestore.c:750
static const char * CreateCommandName(Node *parsetree)
Definition: utility.h:103
const char * type

References AccessShareLock, CollectedCommand::alterTable, CollectedCommand::atscfg, BoolGetDatum(), ObjectAddress::classId, EventTriggerQueryState::commandList, CreateCommandName(), CollectedCommand::createopc, CStringGetTextDatum, currentEventTriggerState, CollectedCommand::d, CollectedCommand::defprivs, elog(), ereport, errcode(), errmsg(), ERROR, get_catalog_object_by_oid(), get_namespace_name_or_temp(), get_object_attnum_namespace(), get_object_attnum_oid(), getObjectIdentity(), getObjectTypeDescription(), CollectedCommand::grant, heap_getattr(), HeapTupleIsValid, i, if(), CollectedCommand::in_extension, InitMaterializedSRF(), Int32GetDatum(), InvalidAttrNumber, is_objectclass_supported(), lfirst, ObjectAddressSet, ObjectAddress::objectId, ObjectIdGetDatum(), ObjectAddress::objectSubId, OidIsValid, CollectedCommand::opfam, CollectedCommand::parsetree, PG_RETURN_VOID, PointerGetDatum(), RelationGetDescr, SCT_AlterDefaultPrivileges, SCT_AlterOpFamily, SCT_AlterTable, SCT_AlterTSConfig, SCT_CreateOpClass, SCT_Grant, SCT_Simple, ReturnSetInfo::setDesc, ReturnSetInfo::setResult, CollectedCommand::simple, stringify_adefprivs_objtype(), stringify_grant_objtype(), table_close(), table_open(), tuplestore_putvalues(), type, CollectedCommand::type, and values.

◆ pg_event_trigger_dropped_objects()

Datum pg_event_trigger_dropped_objects ( PG_FUNCTION_ARGS  )

Definition at line 1298 of file event_trigger.c.

1299 {
1300  ReturnSetInfo *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo;
1301  slist_iter iter;
1302 
1303  /*
1304  * Protect this function from being called out of context
1305  */
1308  ereport(ERROR,
1309  (errcode(ERRCODE_E_R_I_E_EVENT_TRIGGER_PROTOCOL_VIOLATED),
1310  errmsg("%s can only be called in a sql_drop event trigger function",
1311  "pg_event_trigger_dropped_objects()")));
1312 
1313  /* Build tuplestore to hold the result rows */
1314  InitMaterializedSRF(fcinfo, 0);
1315 
1317  {
1318  SQLDropObject *obj;
1319  int i = 0;
1320  Datum values[12] = {0};
1321  bool nulls[12] = {0};
1322 
1323  obj = slist_container(SQLDropObject, next, iter.cur);
1324 
1325  /* classid */
1327 
1328  /* objid */
1330 
1331  /* objsubid */
1333 
1334  /* original */
1335  values[i++] = BoolGetDatum(obj->original);
1336 
1337  /* normal */
1338  values[i++] = BoolGetDatum(obj->normal);
1339 
1340  /* is_temporary */
1341  values[i++] = BoolGetDatum(obj->istemp);
1342 
1343  /* object_type */
1345 
1346  /* schema_name */
1347  if (obj->schemaname)
1349  else
1350  nulls[i++] = true;
1351 
1352  /* object_name */
1353  if (obj->objname)
1354  values[i++] = CStringGetTextDatum(obj->objname);
1355  else
1356  nulls[i++] = true;
1357 
1358  /* object_identity */
1359  if (obj->objidentity)
1361  else
1362  nulls[i++] = true;
1363 
1364  /* address_names and address_args */
1365  if (obj->addrnames)
1366  {
1368 
1369  if (obj->addrargs)
1371  else
1373  }
1374  else
1375  {
1376  nulls[i++] = true;
1377  nulls[i++] = true;
1378  }
1379 
1380  tuplestore_putvalues(rsinfo->setResult, rsinfo->setDesc,
1381  values, nulls);
1382  }
1383 
1384  return (Datum) 0;
1385 }
ArrayType * construct_empty_array(Oid elmtype)
Definition: arrayfuncs.c:3527
static int32 next
Definition: blutils.c:219
#define slist_container(type, membername, ptr)
Definition: ilist.h:1106
#define slist_foreach(iter, lhead)
Definition: ilist.h:1132
ArrayType * strlist_to_textarray(List *list)

References SQLDropObject::addrargs, SQLDropObject::address, SQLDropObject::addrnames, BoolGetDatum(), ObjectAddress::classId, construct_empty_array(), CStringGetTextDatum, currentEventTriggerState, ereport, errcode(), errmsg(), ERROR, i, if(), EventTriggerQueryState::in_sql_drop, InitMaterializedSRF(), Int32GetDatum(), SQLDropObject::istemp, next, SQLDropObject::normal, ObjectAddress::objectId, ObjectIdGetDatum(), ObjectAddress::objectSubId, SQLDropObject::objecttype, SQLDropObject::objidentity, SQLDropObject::objname, SQLDropObject::original, PointerGetDatum(), SQLDropObject::schemaname, ReturnSetInfo::setDesc, ReturnSetInfo::setResult, slist_container, slist_foreach, EventTriggerQueryState::SQLDropList, strlist_to_textarray(), tuplestore_putvalues(), and values.

◆ pg_event_trigger_table_rewrite_oid()

Datum pg_event_trigger_table_rewrite_oid ( PG_FUNCTION_ARGS  )

Definition at line 1394 of file event_trigger.c.

1395 {
1396  /*
1397  * Protect this function from being called out of context
1398  */
1399  if (!currentEventTriggerState ||
1401  ereport(ERROR,
1402  (errcode(ERRCODE_E_R_I_E_EVENT_TRIGGER_PROTOCOL_VIOLATED),
1403  errmsg("%s can only be called in a table_rewrite event trigger function",
1404  "pg_event_trigger_table_rewrite_oid()")));
1405 
1407 }
#define PG_RETURN_OID(x)
Definition: fmgr.h:360

References currentEventTriggerState, ereport, errcode(), errmsg(), ERROR, InvalidOid, PG_RETURN_OID, and EventTriggerQueryState::table_rewrite_oid.

◆ pg_event_trigger_table_rewrite_reason()

Datum pg_event_trigger_table_rewrite_reason ( PG_FUNCTION_ARGS  )

Definition at line 1415 of file event_trigger.c.

1416 {
1417  /*
1418  * Protect this function from being called out of context
1419  */
1420  if (!currentEventTriggerState ||
1422  ereport(ERROR,
1423  (errcode(ERRCODE_E_R_I_E_EVENT_TRIGGER_PROTOCOL_VIOLATED),
1424  errmsg("%s can only be called in a table_rewrite event trigger function",
1425  "pg_event_trigger_table_rewrite_reason()")));
1426 
1428 }
#define PG_RETURN_INT32(x)
Definition: fmgr.h:354

References currentEventTriggerState, ereport, errcode(), errmsg(), ERROR, PG_RETURN_INT32, and EventTriggerQueryState::table_rewrite_reason.

◆ stringify_adefprivs_objtype()

static const char * stringify_adefprivs_objtype ( ObjectType  objtype)
static

Definition at line 2107 of file event_trigger.c.

2108 {
2109  switch (objtype)
2110  {
2111  case OBJECT_COLUMN:
2112  return "COLUMNS";
2113  case OBJECT_TABLE:
2114  return "TABLES";
2115  case OBJECT_SEQUENCE:
2116  return "SEQUENCES";
2117  case OBJECT_DATABASE:
2118  return "DATABASES";
2119  case OBJECT_DOMAIN:
2120  return "DOMAINS";
2121  case OBJECT_FDW:
2122  return "FOREIGN DATA WRAPPERS";
2123  case OBJECT_FOREIGN_SERVER:
2124  return "FOREIGN SERVERS";
2125  case OBJECT_FUNCTION:
2126  return "FUNCTIONS";
2127  case OBJECT_LANGUAGE:
2128  return "LANGUAGES";
2129  case OBJECT_LARGEOBJECT:
2130  return "LARGE OBJECTS";
2131  case OBJECT_SCHEMA:
2132  return "SCHEMAS";
2133  case OBJECT_PROCEDURE:
2134  return "PROCEDURES";
2135  case OBJECT_ROUTINE:
2136  return "ROUTINES";
2137  case OBJECT_TABLESPACE:
2138  return "TABLESPACES";
2139  case OBJECT_TYPE:
2140  return "TYPES";
2141  /* these currently aren't used */
2142  case OBJECT_ACCESS_METHOD:
2143  case OBJECT_AGGREGATE:
2144  case OBJECT_AMOP:
2145  case OBJECT_AMPROC:
2146  case OBJECT_ATTRIBUTE:
2147  case OBJECT_CAST:
2148  case OBJECT_COLLATION:
2149  case OBJECT_CONVERSION:
2150  case OBJECT_DEFAULT:
2151  case OBJECT_DEFACL:
2152  case OBJECT_DOMCONSTRAINT:
2153  case OBJECT_EVENT_TRIGGER:
2154  case OBJECT_EXTENSION:
2155  case OBJECT_FOREIGN_TABLE:
2156  case OBJECT_INDEX:
2157  case OBJECT_MATVIEW:
2158  case OBJECT_OPCLASS:
2159  case OBJECT_OPERATOR:
2160  case OBJECT_OPFAMILY:
2161  case OBJECT_PARAMETER_ACL:
2162  case OBJECT_POLICY:
2163  case OBJECT_PUBLICATION:
2166  case OBJECT_ROLE:
2167  case OBJECT_RULE:
2168  case OBJECT_STATISTIC_EXT:
2169  case OBJECT_SUBSCRIPTION:
2170  case OBJECT_TABCONSTRAINT:
2171  case OBJECT_TRANSFORM:
2172  case OBJECT_TRIGGER:
2174  case OBJECT_TSDICTIONARY:
2175  case OBJECT_TSPARSER:
2176  case OBJECT_TSTEMPLATE:
2177  case OBJECT_USER_MAPPING:
2178  case OBJECT_VIEW:
2179  elog(ERROR, "unsupported object type: %d", (int) objtype);
2180  }
2181 
2182  return "???"; /* keep compiler quiet */
2183 }

References elog(), ERROR, 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 pg_event_trigger_ddl_commands().

◆ stringify_grant_objtype()

static const char * stringify_grant_objtype ( ObjectType  objtype)
static

Definition at line 2022 of file event_trigger.c.

2023 {
2024  switch (objtype)
2025  {
2026  case OBJECT_COLUMN:
2027  return "COLUMN";
2028  case OBJECT_TABLE:
2029  return "TABLE";
2030  case OBJECT_SEQUENCE:
2031  return "SEQUENCE";
2032  case OBJECT_DATABASE:
2033  return "DATABASE";
2034  case OBJECT_DOMAIN:
2035  return "DOMAIN";
2036  case OBJECT_FDW:
2037  return "FOREIGN DATA WRAPPER";
2038  case OBJECT_FOREIGN_SERVER:
2039  return "FOREIGN SERVER";
2040  case OBJECT_FUNCTION:
2041  return "FUNCTION";
2042  case OBJECT_LANGUAGE:
2043  return "LANGUAGE";
2044  case OBJECT_LARGEOBJECT:
2045  return "LARGE OBJECT";
2046  case OBJECT_SCHEMA:
2047  return "SCHEMA";
2048  case OBJECT_PARAMETER_ACL:
2049  return "PARAMETER";
2050  case OBJECT_PROCEDURE:
2051  return "PROCEDURE";
2052  case OBJECT_ROUTINE:
2053  return "ROUTINE";
2054  case OBJECT_TABLESPACE:
2055  return "TABLESPACE";
2056  case OBJECT_TYPE:
2057  return "TYPE";
2058  /* these currently aren't used */
2059  case OBJECT_ACCESS_METHOD:
2060  case OBJECT_AGGREGATE:
2061  case OBJECT_AMOP:
2062  case OBJECT_AMPROC:
2063  case OBJECT_ATTRIBUTE:
2064  case OBJECT_CAST:
2065  case OBJECT_COLLATION:
2066  case OBJECT_CONVERSION:
2067  case OBJECT_DEFAULT:
2068  case OBJECT_DEFACL:
2069  case OBJECT_DOMCONSTRAINT:
2070  case OBJECT_EVENT_TRIGGER:
2071  case OBJECT_EXTENSION:
2072  case OBJECT_FOREIGN_TABLE:
2073  case OBJECT_INDEX:
2074  case OBJECT_MATVIEW:
2075  case OBJECT_OPCLASS:
2076  case OBJECT_OPERATOR:
2077  case OBJECT_OPFAMILY:
2078  case OBJECT_POLICY:
2079  case OBJECT_PUBLICATION:
2082  case OBJECT_ROLE:
2083  case OBJECT_RULE:
2084  case OBJECT_STATISTIC_EXT:
2085  case OBJECT_SUBSCRIPTION:
2086  case OBJECT_TABCONSTRAINT:
2087  case OBJECT_TRANSFORM:
2088  case OBJECT_TRIGGER:
2090  case OBJECT_TSDICTIONARY:
2091  case OBJECT_TSPARSER:
2092  case OBJECT_TSTEMPLATE:
2093  case OBJECT_USER_MAPPING:
2094  case OBJECT_VIEW:
2095  elog(ERROR, "unsupported object type: %d", (int) objtype);
2096  }
2097 
2098  return "???"; /* keep compiler quiet */
2099 }

References elog(), ERROR, 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 pg_event_trigger_ddl_commands().

◆ trackDroppedObjectsNeeded()

bool trackDroppedObjectsNeeded ( void  )

Definition at line 1147 of file event_trigger.c.

1148 {
1149  /*
1150  * true if any sql_drop, table_rewrite, ddl_command_end event trigger
1151  * exists
1152  */
1153  return (EventCacheLookup(EVT_SQLDrop) != NIL) ||
1156 }

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

Referenced by deleteObjectsInList(), and EventTriggerBeginCompleteQuery().

◆ validate_ddl_tags()

static void validate_ddl_tags ( const char *  filtervar,
List taglist 
)
static

Definition at line 198 of file event_trigger.c.

199 {
200  ListCell *lc;
201 
202  foreach(lc, taglist)
203  {
204  const char *tagstr = strVal(lfirst(lc));
205  CommandTag commandTag = GetCommandTagEnum(tagstr);
206 
207  if (commandTag == CMDTAG_UNKNOWN)
208  ereport(ERROR,
209  (errcode(ERRCODE_SYNTAX_ERROR),
210  errmsg("filter value \"%s\" not recognized for filter variable \"%s\"",
211  tagstr, filtervar)));
212  if (!command_tag_event_trigger_ok(commandTag))
213  ereport(ERROR,
214  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
215  /* translator: %s represents an SQL statement name */
216  errmsg("event triggers are not supported for %s",
217  tagstr)));
218  }
219 }
CommandTag GetCommandTagEnum(const char *commandname)
Definition: cmdtag.c:84

References command_tag_event_trigger_ok(), ereport, errcode(), errmsg(), ERROR, GetCommandTagEnum(), lfirst, and strVal.

Referenced by CreateEventTrigger().

◆ validate_table_rewrite_tags()

static void validate_table_rewrite_tags ( const char *  filtervar,
List taglist 
)
static

Definition at line 225 of file event_trigger.c.

226 {
227  ListCell *lc;
228 
229  foreach(lc, taglist)
230  {
231  const char *tagstr = strVal(lfirst(lc));
232  CommandTag commandTag = GetCommandTagEnum(tagstr);
233 
234  if (!command_tag_table_rewrite_ok(commandTag))
235  ereport(ERROR,
236  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
237  /* translator: %s represents an SQL statement name */
238  errmsg("event triggers are not supported for %s",
239  tagstr)));
240  }
241 }

References command_tag_table_rewrite_ok(), ereport, errcode(), errmsg(), ERROR, GetCommandTagEnum(), lfirst, and strVal.

Referenced by CreateEventTrigger().

Variable Documentation

◆ currentEventTriggerState

◆ event_triggers