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 *tags)
 
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
 

Typedef Documentation

◆ EventTriggerQueryState

◆ SQLDropObject

typedef struct SQLDropObject SQLDropObject

Function Documentation

◆ AlterEventTrigger()

Oid AlterEventTrigger ( AlterEventTrigStmt stmt)

Definition at line 362 of file event_trigger.c.

363 {
364  Relation tgrel;
365  HeapTuple tup;
366  Oid trigoid;
367  Form_pg_event_trigger evtForm;
368  char tgenabled = stmt->tgenabled;
369 
370  tgrel = table_open(EventTriggerRelationId, RowExclusiveLock);
371 
373  CStringGetDatum(stmt->trigname));
374  if (!HeapTupleIsValid(tup))
375  ereport(ERROR,
376  (errcode(ERRCODE_UNDEFINED_OBJECT),
377  errmsg("event trigger \"%s\" does not exist",
378  stmt->trigname)));
379 
380  evtForm = (Form_pg_event_trigger) GETSTRUCT(tup);
381  trigoid = evtForm->oid;
382 
383  if (!pg_event_trigger_ownercheck(trigoid, GetUserId()))
385  stmt->trigname);
386 
387  /* tuple is a copy, so we can modify it below */
388  evtForm->evtenabled = tgenabled;
389 
390  CatalogTupleUpdate(tgrel, &tup->t_self, tup);
391 
392  InvokeObjectPostAlterHook(EventTriggerRelationId,
393  trigoid, 0);
394 
395  /* clean up */
396  heap_freetuple(tup);
398 
399  return trigoid;
400 }
@ ACLCHECK_NOT_OWNER
Definition: acl.h:184
bool pg_event_trigger_ownercheck(Oid et_oid, Oid roleid)
Definition: aclchk.c:5562
void aclcheck_error(AclResult aclerr, ObjectType objtype, const char *objectname)
Definition: aclchk.c:3512
int errcode(int sqlerrcode)
Definition: elog.c:693
int errmsg(const char *fmt,...)
Definition: elog.c:904
#define ERROR
Definition: elog.h:33
#define ereport(elevel,...)
Definition: elog.h:143
void heap_freetuple(HeapTuple htup)
Definition: heaptuple.c:1338
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
#define GETSTRUCT(TUP)
Definition: htup_details.h:649
void CatalogTupleUpdate(Relation heapRel, ItemPointer otid, HeapTuple tup)
Definition: indexing.c:301
#define RowExclusiveLock
Definition: lockdefs.h:38
Oid GetUserId(void)
Definition: miscinit.c:492
#define InvokeObjectPostAlterHook(classId, objectId, subId)
Definition: objectaccess.h:195
@ OBJECT_EVENT_TRIGGER
Definition: parsenodes.h:2148
FormData_pg_event_trigger * Form_pg_event_trigger
#define CStringGetDatum(X)
Definition: postgres.h:622
unsigned int Oid
Definition: postgres_ext.h:31
ItemPointerData t_self
Definition: htup.h:65
#define SearchSysCacheCopy1(cacheId, key1)
Definition: syscache.h:179
@ EVENTTRIGGERNAME
Definition: syscache.h:59
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:167
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:39

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

Referenced by standard_ProcessUtility().

◆ AlterEventTriggerOwner()

ObjectAddress AlterEventTriggerOwner ( const char *  name,
Oid  newOwnerId 
)

Definition at line 406 of file event_trigger.c.

407 {
408  Oid evtOid;
409  HeapTuple tup;
410  Form_pg_event_trigger evtForm;
411  Relation rel;
412  ObjectAddress address;
413 
414  rel = table_open(EventTriggerRelationId, RowExclusiveLock);
415 
417 
418  if (!HeapTupleIsValid(tup))
419  ereport(ERROR,
420  (errcode(ERRCODE_UNDEFINED_OBJECT),
421  errmsg("event trigger \"%s\" does not exist", name)));
422 
423  evtForm = (Form_pg_event_trigger) GETSTRUCT(tup);
424  evtOid = evtForm->oid;
425 
426  AlterEventTriggerOwner_internal(rel, tup, newOwnerId);
427 
428  ObjectAddressSet(address, EventTriggerRelationId, evtOid);
429 
430  heap_freetuple(tup);
431 
433 
434  return address;
435 }
const char * name
Definition: encode.c:561
static void AlterEventTriggerOwner_internal(Relation rel, HeapTuple tup, Oid newOwnerId)
#define ObjectAddressSet(addr, class_id, object_id)
Definition: objectaddress.h:40

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

467 {
469 
470  form = (Form_pg_event_trigger) GETSTRUCT(tup);
471 
472  if (form->evtowner == newOwnerId)
473  return;
474 
475  if (!pg_event_trigger_ownercheck(form->oid, GetUserId()))
477  NameStr(form->evtname));
478 
479  /* New owner must be a superuser */
480  if (!superuser_arg(newOwnerId))
481  ereport(ERROR,
482  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
483  errmsg("permission denied to change owner of event trigger \"%s\"",
484  NameStr(form->evtname)),
485  errhint("The owner of an event trigger must be a superuser.")));
486 
487  form->evtowner = newOwnerId;
488  CatalogTupleUpdate(rel, &tup->t_self, tup);
489 
490  /* Update owner dependency reference */
491  changeDependencyOnOwner(EventTriggerRelationId,
492  form->oid,
493  newOwnerId);
494 
495  InvokeObjectPostAlterHook(EventTriggerRelationId,
496  form->oid, 0);
497 }
#define NameStr(name)
Definition: c.h:681
int errhint(const char *fmt,...)
Definition: elog.c:1151
void changeDependencyOnOwner(Oid classId, Oid objectId, Oid newOwnerId)
Definition: pg_shdepend.c:312
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, pg_event_trigger_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 441 of file event_trigger.c.

442 {
443  HeapTuple tup;
444  Relation rel;
445 
446  rel = table_open(EventTriggerRelationId, RowExclusiveLock);
447 
449 
450  if (!HeapTupleIsValid(tup))
451  ereport(ERROR,
452  (errcode(ERRCODE_UNDEFINED_OBJECT),
453  errmsg("event trigger with OID %u does not exist", trigOid)));
454 
455  AlterEventTriggerOwner_internal(rel, tup, newOwnerId);
456 
457  heap_freetuple(tup);
458 
460 }
#define ObjectIdGetDatum(X)
Definition: postgres.h:551
@ 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 108 of file event_trigger.c.

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

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

Referenced by standard_ProcessUtility().

◆ error_duplicate_filter_variable()

static void error_duplicate_filter_variable ( const char *  defname)
static

Definition at line 244 of file event_trigger.c.

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

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

Referenced by CreateEventTrigger().

◆ EventTriggerAlterTableEnd()

void EventTriggerAlterTableEnd ( void  )

Definition at line 1611 of file event_trigger.c.

1612 {
1613  CollectedCommand *parent;
1614 
1615  /* ignore if event trigger context not set, or collection disabled */
1616  if (!currentEventTriggerState ||
1618  return;
1619 
1621 
1622  /* If no subcommands, don't collect */
1624  {
1625  MemoryContext oldcxt;
1626 
1628 
1632 
1633  MemoryContextSwitchTo(oldcxt);
1634  }
1635  else
1637 
1639 }
static EventTriggerQueryState * currentEventTriggerState
Definition: event_trigger.c:73
List * lappend(List *list, void *datum)
Definition: list.c:336
void pfree(void *pointer)
Definition: mcxt.c:1175
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
static int list_length(const List *l)
Definition: pg_list.h:149
struct CollectedCommand * parent
union CollectedCommand::@117 d
struct CollectedCommand::@117::@119 alterTable
CollectedCommand * currentCommand
Definition: event_trigger.c:67

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

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

◆ EventTriggerAlterTableRelid()

◆ EventTriggerAlterTableStart()

void EventTriggerAlterTableStart ( Node parsetree)

Definition at line 1524 of file event_trigger.c.

1525 {
1526  MemoryContext oldcxt;
1527  CollectedCommand *command;
1528 
1529  /* ignore if event trigger context not set, or collection disabled */
1530  if (!currentEventTriggerState ||
1532  return;
1533 
1535 
1536  command = palloc(sizeof(CollectedCommand));
1537 
1538  command->type = SCT_AlterTable;
1539  command->in_extension = creating_extension;
1540 
1541  command->d.alterTable.classId = RelationRelationId;
1542  command->d.alterTable.objectId = InvalidOid;
1543  command->d.alterTable.subcmds = NIL;
1544  command->parsetree = copyObject(parsetree);
1545 
1548 
1549  MemoryContextSwitchTo(oldcxt);
1550 }
@ SCT_AlterTable
bool creating_extension
Definition: extension.c:71
void * palloc(Size size)
Definition: mcxt.c:1068
#define copyObject(obj)
Definition: nodes.h:689
#define NIL
Definition: pg_list.h:65
#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 1079 of file event_trigger.c.

1080 {
1082  MemoryContext cxt;
1083 
1084  /*
1085  * Currently, sql_drop, table_rewrite, ddl_command_end events are the only
1086  * reason to have event trigger state at all; so if there are none, don't
1087  * install one.
1088  */
1090  return false;
1091 
1093  "event trigger state",
1096  state->cxt = cxt;
1097  slist_init(&(state->SQLDropList));
1098  state->in_sql_drop = false;
1099  state->table_rewrite_oid = InvalidOid;
1100 
1101  state->commandCollectionInhibited = currentEventTriggerState ?
1103  state->currentCommand = NULL;
1104  state->commandList = NIL;
1105  state->previous = currentEventTriggerState;
1107 
1108  return true;
1109 }
bool trackDroppedObjectsNeeded(void)
static void slist_init(slist_head *head)
Definition: ilist.h:573
MemoryContext TopMemoryContext
Definition: mcxt.c:48
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition: mcxt.c:863
#define AllocSetContextCreate
Definition: memutils.h:173
#define ALLOCSET_DEFAULT_SIZES
Definition: memutils.h:197
Definition: regguts.h:318

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

1796 {
1797  MemoryContext oldcxt;
1798  CollectedCommand *command;
1799 
1800  /* ignore if event trigger context not set, or collection disabled */
1801  if (!currentEventTriggerState ||
1803  return;
1804 
1806 
1807  command = palloc0(sizeof(CollectedCommand));
1808  command->type = SCT_AlterDefaultPrivileges;
1809  command->d.defprivs.objtype = stmt->action->objtype;
1810  command->in_extension = creating_extension;
1811  command->parsetree = (Node *) copyObject(stmt);
1812 
1815  MemoryContextSwitchTo(oldcxt);
1816 }
@ SCT_AlterDefaultPrivileges
void * palloc0(Size size)
Definition: mcxt.c:1099
struct CollectedCommand::@117::@124 defprivs
ObjectType objtype
Definition: parsenodes.h:2375
Definition: nodes.h:574

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

Referenced by ProcessUtilitySlow().

◆ EventTriggerCollectAlterOpFam()

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

Definition at line 1693 of file event_trigger.c.

1695 {
1696  MemoryContext oldcxt;
1697  CollectedCommand *command;
1698 
1699  /* ignore if event trigger context not set, or collection disabled */
1700  if (!currentEventTriggerState ||
1702  return;
1703 
1705 
1706  command = palloc(sizeof(CollectedCommand));
1707  command->type = SCT_AlterOpFamily;
1708  command->in_extension = creating_extension;
1709  ObjectAddressSet(command->d.opfam.address,
1710  OperatorFamilyRelationId, opfamoid);
1711  command->d.opfam.operators = operators;
1712  command->d.opfam.procedures = procedures;
1713  command->parsetree = (Node *) copyObject(stmt);
1714 
1717 
1718  MemoryContextSwitchTo(oldcxt);
1719 }
@ SCT_AlterOpFamily
struct CollectedCommand::@117::@121 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, and CollectedCommand::type.

Referenced by AlterOpFamilyAdd(), and AlterOpFamilyDrop().

◆ EventTriggerCollectAlterTableSubcmd()

void EventTriggerCollectAlterTableSubcmd ( Node subcmd,
ObjectAddress  address 
)

Definition at line 1576 of file event_trigger.c.

1577 {
1578  MemoryContext oldcxt;
1580 
1581  /* ignore if event trigger context not set, or collection disabled */
1582  if (!currentEventTriggerState ||
1584  return;
1585 
1586  Assert(IsA(subcmd, AlterTableCmd));
1589 
1591 
1592  newsub = palloc(sizeof(CollectedATSubcmd));
1593  newsub->address = address;
1594  newsub->parsetree = copyObject(subcmd);
1595 
1598 
1599  MemoryContextSwitchTo(oldcxt);
1600 }
#define OidIsValid(objectId)
Definition: c.h:710
Assert(fmt[strlen(fmt) - 1] !='\n')
#define IsA(nodeptr, _type_)
Definition: nodes.h:624
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 1760 of file event_trigger.c.

1762 {
1763  MemoryContext oldcxt;
1764  CollectedCommand *command;
1765 
1766  /* ignore if event trigger context not set, or collection disabled */
1767  if (!currentEventTriggerState ||
1769  return;
1770 
1772 
1773  command = palloc0(sizeof(CollectedCommand));
1774  command->type = SCT_AlterTSConfig;
1775  command->in_extension = creating_extension;
1776  ObjectAddressSet(command->d.atscfg.address,
1777  TSConfigRelationId, cfgId);
1778  command->d.atscfg.dictIds = palloc(sizeof(Oid) * ndicts);
1779  memcpy(command->d.atscfg.dictIds, dictIds, sizeof(Oid) * ndicts);
1780  command->d.atscfg.ndicts = ndicts;
1781  command->parsetree = (Node *) copyObject(stmt);
1782 
1785 
1786  MemoryContextSwitchTo(oldcxt);
1787 }
@ SCT_AlterTSConfig
struct CollectedCommand::@117::@123 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, and CollectedCommand::type.

Referenced by DropConfigurationMapping(), and MakeConfigurationMapping().

◆ EventTriggerCollectCreateOpClass()

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

Definition at line 1726 of file event_trigger.c.

1728 {
1729  MemoryContext oldcxt;
1730  CollectedCommand *command;
1731 
1732  /* ignore if event trigger context not set, or collection disabled */
1733  if (!currentEventTriggerState ||
1735  return;
1736 
1738 
1739  command = palloc0(sizeof(CollectedCommand));
1740  command->type = SCT_CreateOpClass;
1741  command->in_extension = creating_extension;
1742  ObjectAddressSet(command->d.createopc.address,
1743  OperatorClassRelationId, opcoid);
1744  command->d.createopc.operators = operators;
1745  command->d.createopc.procedures = procedures;
1746  command->parsetree = (Node *) copyObject(stmt);
1747 
1750 
1751  MemoryContextSwitchTo(oldcxt);
1752 }
@ SCT_CreateOpClass
struct CollectedCommand::@117::@122 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, and CollectedCommand::type.

Referenced by DefineOpClass().

◆ EventTriggerCollectGrant()

void EventTriggerCollectGrant ( InternalGrant istmt)

Definition at line 1649 of file event_trigger.c.

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

1489 {
1490  MemoryContext oldcxt;
1491  CollectedCommand *command;
1492 
1493  /* ignore if event trigger context not set, or collection disabled */
1494  if (!currentEventTriggerState ||
1496  return;
1497 
1499 
1500  command = palloc(sizeof(CollectedCommand));
1501 
1502  command->type = SCT_Simple;
1503  command->in_extension = creating_extension;
1504 
1505  command->d.simple.address = address;
1506  command->d.simple.secondaryObject = secondaryObject;
1507  command->parsetree = copyObject(parsetree);
1508 
1510  command);
1511 
1512  MemoryContextSwitchTo(oldcxt);
1513 }
@ SCT_Simple
struct CollectedCommand::@117::@118 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 556 of file event_trigger.c.

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

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, T_EventTriggerData, EventTriggerData::tag, and EventTriggerData::type.

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

◆ EventTriggerDDLCommandEnd()

void EventTriggerDDLCommandEnd ( Node parsetree)

Definition at line 689 of file event_trigger.c.

690 {
691  List *runlist;
692  EventTriggerData trigdata;
693 
694  /*
695  * See EventTriggerDDLCommandStart for a discussion about why event
696  * triggers are disabled in single user mode.
697  */
698  if (!IsUnderPostmaster)
699  return;
700 
701  /*
702  * Also do nothing if our state isn't set up, which it won't be if there
703  * weren't any relevant event triggers at the start of the current DDL
704  * command. This test might therefore seem optional, but it's important
705  * because EventTriggerCommonSetup might find triggers that didn't exist
706  * at the time the command started. Although this function itself
707  * wouldn't crash, the event trigger functions would presumably call
708  * pg_event_trigger_ddl_commands which would fail. Better to do nothing
709  * until the next command.
710  */
712  return;
713 
714  runlist = EventTriggerCommonSetup(parsetree,
715  EVT_DDLCommandEnd, "ddl_command_end",
716  &trigdata);
717  if (runlist == NIL)
718  return;
719 
720  /*
721  * Make sure anything the main command did will be visible to the event
722  * triggers.
723  */
725 
726  /* Run the triggers. */
727  EventTriggerInvoke(runlist, &trigdata);
728 
729  /* Cleanup. */
730  list_free(runlist);
731 }
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:1505
void CommandCounterIncrement(void)
Definition: xact.c:1074

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

Referenced by ProcessUtilitySlow().

◆ EventTriggerDDLCommandStart()

void EventTriggerDDLCommandStart ( Node parsetree)

Definition at line 641 of file event_trigger.c.

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

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

Referenced by ProcessUtilitySlow().

◆ EventTriggerEndCompleteQuery()

void EventTriggerEndCompleteQuery ( void  )

Definition at line 1123 of file event_trigger.c.

1124 {
1125  EventTriggerQueryState *prevstate;
1126 
1127  prevstate = currentEventTriggerState->previous;
1128 
1129  /* this avoids the need for retail pfree of SQLDropList items: */
1131 
1132  currentEventTriggerState = prevstate;
1133 }
void MemoryContextDelete(MemoryContext context)
Definition: mcxt.c:218
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 1452 of file event_trigger.c.

1453 {
1455  return;
1456 
1458 }

References EventTriggerQueryState::commandCollectionInhibited, and currentEventTriggerState.

Referenced by ProcessUtilitySlow().

◆ EventTriggerInvoke()

static void EventTriggerInvoke ( List fn_oid_list,
EventTriggerData trigdata 
)
static

Definition at line 873 of file event_trigger.c.

874 {
875  MemoryContext context;
876  MemoryContext oldcontext;
877  ListCell *lc;
878  bool first = true;
879 
880  /* Guard against stack overflow due to recursive event trigger */
882 
883  /*
884  * Let's evaluate event triggers in their own memory context, so that any
885  * leaks get cleaned up promptly.
886  */
888  "event trigger context",
890  oldcontext = MemoryContextSwitchTo(context);
891 
892  /* Call each event trigger. */
893  foreach(lc, fn_oid_list)
894  {
895  LOCAL_FCINFO(fcinfo, 0);
896  Oid fnoid = lfirst_oid(lc);
897  FmgrInfo flinfo;
898  PgStat_FunctionCallUsage fcusage;
899 
900  elog(DEBUG1, "EventTriggerInvoke %u", fnoid);
901 
902  /*
903  * We want each event trigger to be able to see the results of the
904  * previous event trigger's action. Caller is responsible for any
905  * command-counter increment that is needed between the event trigger
906  * and anything else in the transaction.
907  */
908  if (first)
909  first = false;
910  else
912 
913  /* Look up the function */
914  fmgr_info(fnoid, &flinfo);
915 
916  /* Call the function, passing no arguments but setting a context. */
917  InitFunctionCallInfoData(*fcinfo, &flinfo, 0,
918  InvalidOid, (Node *) trigdata, NULL);
919  pgstat_init_function_usage(fcinfo, &fcusage);
920  FunctionCallInvoke(fcinfo);
921  pgstat_end_function_usage(&fcusage, true);
922 
923  /* Reclaim memory. */
924  MemoryContextReset(context);
925  }
926 
927  /* Restore old memory context and delete the temporary one. */
928  MemoryContextSwitchTo(oldcontext);
929  MemoryContextDelete(context);
930 }
#define DEBUG1
Definition: elog.h:24
void fmgr_info(Oid functionId, FmgrInfo *finfo)
Definition: fmgr.c:126
#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:143
MemoryContext CurrentMemoryContext
Definition: mcxt.c:42
#define lfirst_oid(lc)
Definition: pg_list.h:171
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:3500
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 737 of file event_trigger.c.

738 {
739  List *runlist;
740  EventTriggerData trigdata;
741 
742  /*
743  * See EventTriggerDDLCommandStart for a discussion about why event
744  * triggers are disabled in single user mode.
745  */
746  if (!IsUnderPostmaster)
747  return;
748 
749  /*
750  * Use current state to determine whether this event fires at all. If
751  * there are no triggers for the sql_drop event, then we don't have
752  * anything to do here. Note that dropped object collection is disabled
753  * if this is the case, so even if we were to try to run, the list would
754  * be empty.
755  */
758  return;
759 
760  runlist = EventTriggerCommonSetup(parsetree,
761  EVT_SQLDrop, "sql_drop",
762  &trigdata);
763 
764  /*
765  * Nothing to do if run list is empty. Note this typically can't happen,
766  * because if there are no sql_drop events, then objects-to-drop wouldn't
767  * have been collected in the first place and we would have quit above.
768  * But it could occur if event triggers were dropped partway through.
769  */
770  if (runlist == NIL)
771  return;
772 
773  /*
774  * Make sure anything the main command did will be visible to the event
775  * triggers.
776  */
778 
779  /*
780  * Make sure pg_event_trigger_dropped_objects only works when running
781  * these triggers. Use PG_TRY to ensure in_sql_drop is reset even when
782  * one trigger fails. (This is perhaps not necessary, as the currentState
783  * variable will be removed shortly by our caller, but it seems better to
784  * play safe.)
785  */
787 
788  /* Run the triggers. */
789  PG_TRY();
790  {
791  EventTriggerInvoke(runlist, &trigdata);
792  }
793  PG_FINALLY();
794  {
796  }
797  PG_END_TRY();
798 
799  /* Cleanup. */
800  list_free(runlist);
801 }
#define PG_END_TRY()
Definition: elog.h:324
#define PG_TRY()
Definition: elog.h:299
#define PG_FINALLY()
Definition: elog.h:316
static bool slist_is_empty(slist_head *head)
Definition: ilist.h:582

References CommandCounterIncrement(), currentEventTriggerState, 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 1173 of file event_trigger.c.

1174 {
1175  SQLDropObject *obj;
1176  MemoryContext oldcxt;
1177 
1179  return;
1180 
1182 
1183  /* don't report temp schemas except my own */
1184  if (object->classId == NamespaceRelationId &&
1185  (isAnyTempNamespace(object->objectId) &&
1186  !isTempNamespace(object->objectId)))
1187  return;
1188 
1190 
1191  obj = palloc0(sizeof(SQLDropObject));
1192  obj->address = *object;
1193  obj->original = original;
1194  obj->normal = normal;
1195 
1196  /*
1197  * Obtain schema names from the object's catalog tuple, if one exists;
1198  * this lets us skip objects in temp schemas. We trust that
1199  * ObjectProperty contains all object classes that can be
1200  * schema-qualified.
1201  */
1202  if (is_objectclass_supported(object->classId))
1203  {
1204  Relation catalog;
1205  HeapTuple tuple;
1206 
1207  catalog = table_open(obj->address.classId, AccessShareLock);
1208  tuple = get_catalog_object_by_oid(catalog,
1209  get_object_attnum_oid(object->classId),
1210  obj->address.objectId);
1211 
1212  if (tuple)
1213  {
1215  Datum datum;
1216  bool isnull;
1217 
1219  if (attnum != InvalidAttrNumber)
1220  {
1221  datum = heap_getattr(tuple, attnum,
1222  RelationGetDescr(catalog), &isnull);
1223  if (!isnull)
1224  {
1225  Oid namespaceId;
1226 
1227  namespaceId = DatumGetObjectId(datum);
1228  /* temp objects are only reported if they are my own */
1229  if (isTempNamespace(namespaceId))
1230  {
1231  obj->schemaname = "pg_temp";
1232  obj->istemp = true;
1233  }
1234  else if (isAnyTempNamespace(namespaceId))
1235  {
1236  pfree(obj);
1237  table_close(catalog, AccessShareLock);
1238  MemoryContextSwitchTo(oldcxt);
1239  return;
1240  }
1241  else
1242  {
1243  obj->schemaname = get_namespace_name(namespaceId);
1244  obj->istemp = false;
1245  }
1246  }
1247  }
1248 
1250  obj->address.objectSubId == 0)
1251  {
1253  if (attnum != InvalidAttrNumber)
1254  {
1255  datum = heap_getattr(tuple, attnum,
1256  RelationGetDescr(catalog), &isnull);
1257  if (!isnull)
1258  obj->objname = pstrdup(NameStr(*DatumGetName(datum)));
1259  }
1260  }
1261  }
1262 
1263  table_close(catalog, AccessShareLock);
1264  }
1265  else
1266  {
1267  if (object->classId == NamespaceRelationId &&
1268  isTempNamespace(object->objectId))
1269  obj->istemp = true;
1270  }
1271 
1272  /* object identity, objname and objargs */
1273  obj->objidentity =
1274  getObjectIdentityParts(&obj->address, &obj->addrnames, &obj->addrargs,
1275  false);
1276 
1277  /* object type */
1278  obj->objecttype = getObjectTypeDescription(&obj->address, false);
1279 
1281 
1282  MemoryContextSwitchTo(oldcxt);
1283 }
int16 AttrNumber
Definition: attnum.h:21
#define InvalidAttrNumber
Definition: attnum.h:23
ObjectClass getObjectClass(const ObjectAddress *object)
Definition: dependency.c:2757
bool EventTriggerSupportsObjectClass(ObjectClass objclass)
static Datum heap_getattr(HeapTuple tup, int attnum, TupleDesc tupleDesc, bool *isnull)
Definition: htup_details.h:788
static void slist_push_head(slist_head *head, slist_node *node)
Definition: ilist.h:593
#define AccessShareLock
Definition: lockdefs.h:36
char * get_namespace_name(Oid nspid)
Definition: lsyscache.c:3326
char * pstrdup(const char *in)
Definition: mcxt.c:1305
bool isTempNamespace(Oid namespaceId)
Definition: namespace.c:3203
bool isAnyTempNamespace(Oid namespaceId)
Definition: namespace.c:3241
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:83
#define DatumGetObjectId(X)
Definition: postgres.h:544
uintptr_t Datum
Definition: postgres.h:411
#define DatumGetName(X)
Definition: postgres.h:629
#define RelationGetDescr(relation)
Definition: rel.h:515
ObjectAddress address
Definition: event_trigger.c:78
const char * schemaname
Definition: event_trigger.c:79
slist_node next
Definition: event_trigger.c:88
const char * objidentity
Definition: event_trigger.c:81
const char * objecttype
Definition: event_trigger.c:82
List * addrnames
Definition: event_trigger.c:83
const char * objname
Definition: event_trigger.c:80

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

1013 {
1014  switch (objclass)
1015  {
1016  case OCLASS_DATABASE:
1017  case OCLASS_TBLSPACE:
1018  case OCLASS_ROLE:
1019  case OCLASS_PARAMETER_ACL:
1020  /* no support for global objects */
1021  return false;
1022  case OCLASS_EVENT_TRIGGER:
1023  /* no support for event triggers on event triggers */
1024  return false;
1025  case OCLASS_CLASS:
1026  case OCLASS_PROC:
1027  case OCLASS_TYPE:
1028  case OCLASS_CAST:
1029  case OCLASS_COLLATION:
1030  case OCLASS_CONSTRAINT:
1031  case OCLASS_CONVERSION:
1032  case OCLASS_DEFAULT:
1033  case OCLASS_LANGUAGE:
1034  case OCLASS_LARGEOBJECT:
1035  case OCLASS_OPERATOR:
1036  case OCLASS_OPCLASS:
1037  case OCLASS_OPFAMILY:
1038  case OCLASS_AM:
1039  case OCLASS_AMOP:
1040  case OCLASS_AMPROC:
1041  case OCLASS_REWRITE:
1042  case OCLASS_TRIGGER:
1043  case OCLASS_SCHEMA:
1044  case OCLASS_STATISTIC_EXT:
1045  case OCLASS_TSPARSER:
1046  case OCLASS_TSDICT:
1047  case OCLASS_TSTEMPLATE:
1048  case OCLASS_TSCONFIG:
1049  case OCLASS_FDW:
1050  case OCLASS_FOREIGN_SERVER:
1051  case OCLASS_USER_MAPPING:
1052  case OCLASS_DEFACL:
1053  case OCLASS_EXTENSION:
1054  case OCLASS_POLICY:
1055  case OCLASS_PUBLICATION:
1058  case OCLASS_SUBSCRIPTION:
1059  case OCLASS_TRANSFORM:
1060  return true;
1061 
1062  /*
1063  * There's intentionally no default: case here; we want the
1064  * compiler to warn if a new OCLASS hasn't been handled above.
1065  */
1066  }
1067 
1068  /* Shouldn't get here, but if we do, say "no support" */
1069  return false;
1070 }
@ OCLASS_OPERATOR
Definition: dependency.h:100
@ OCLASS_PARAMETER_ACL
Definition: dependency.h:123
@ OCLASS_LARGEOBJECT
Definition: dependency.h:99
@ OCLASS_FDW
Definition: dependency.h:117
@ OCLASS_OPFAMILY
Definition: dependency.h:102
@ OCLASS_DEFACL
Definition: dependency.h:120
@ 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:116
@ 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:128
@ OCLASS_PUBLICATION_NAMESPACE
Definition: dependency.h:126
@ OCLASS_EXTENSION
Definition: dependency.h:121
@ OCLASS_COLLATION
Definition: dependency.h:94
@ OCLASS_FOREIGN_SERVER
Definition: dependency.h:118
@ 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:115
@ OCLASS_SCHEMA
Definition: dependency.h:108
@ OCLASS_EVENT_TRIGGER
Definition: dependency.h:122
@ OCLASS_CLASS
Definition: dependency.h:90
@ OCLASS_TRANSFORM
Definition: dependency.h:129
@ OCLASS_ROLE
Definition: dependency.h:114
@ OCLASS_CONSTRAINT
Definition: dependency.h:95
@ OCLASS_POLICY
Definition: dependency.h:124
@ OCLASS_USER_MAPPING
Definition: dependency.h:119
@ OCLASS_PUBLICATION_REL
Definition: dependency.h:127
@ OCLASS_AM
Definition: dependency.h:103
@ OCLASS_TSDICT
Definition: dependency.h:111
@ OCLASS_PUBLICATION
Definition: dependency.h:125
@ 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_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 936 of file event_trigger.c.

937 {
938  switch (obtype)
939  {
940  case OBJECT_DATABASE:
941  case OBJECT_TABLESPACE:
942  case OBJECT_ROLE:
944  /* no support for global objects */
945  return false;
947  /* no support for event triggers on event triggers */
948  return false;
950  case OBJECT_AGGREGATE:
951  case OBJECT_AMOP:
952  case OBJECT_AMPROC:
953  case OBJECT_ATTRIBUTE:
954  case OBJECT_CAST:
955  case OBJECT_COLUMN:
956  case OBJECT_COLLATION:
957  case OBJECT_CONVERSION:
958  case OBJECT_DEFACL:
959  case OBJECT_DEFAULT:
960  case OBJECT_DOMAIN:
962  case OBJECT_EXTENSION:
963  case OBJECT_FDW:
966  case OBJECT_FUNCTION:
967  case OBJECT_INDEX:
968  case OBJECT_LANGUAGE:
969  case OBJECT_LARGEOBJECT:
970  case OBJECT_MATVIEW:
971  case OBJECT_OPCLASS:
972  case OBJECT_OPERATOR:
973  case OBJECT_OPFAMILY:
974  case OBJECT_POLICY:
975  case OBJECT_PROCEDURE:
976  case OBJECT_PUBLICATION:
979  case OBJECT_ROUTINE:
980  case OBJECT_RULE:
981  case OBJECT_SCHEMA:
982  case OBJECT_SEQUENCE:
983  case OBJECT_SUBSCRIPTION:
986  case OBJECT_TABLE:
987  case OBJECT_TRANSFORM:
988  case OBJECT_TRIGGER:
990  case OBJECT_TSDICTIONARY:
991  case OBJECT_TSPARSER:
992  case OBJECT_TSTEMPLATE:
993  case OBJECT_TYPE:
994  case OBJECT_USER_MAPPING:
995  case OBJECT_VIEW:
996  return true;
997 
998  /*
999  * There's intentionally no default: case here; we want the
1000  * compiler to warn if a new ObjectType hasn't been handled above.
1001  */
1002  }
1003 
1004  /* Shouldn't get here, but if we do, say "no support" */
1005  return false;
1006 }
@ OBJECT_FDW
Definition: parsenodes.h:2150
@ OBJECT_TSPARSER
Definition: parsenodes.h:2181
@ OBJECT_COLLATION
Definition: parsenodes.h:2141
@ OBJECT_USER_MAPPING
Definition: parsenodes.h:2184
@ OBJECT_ACCESS_METHOD
Definition: parsenodes.h:2134
@ OBJECT_OPCLASS
Definition: parsenodes.h:2158
@ OBJECT_DEFACL
Definition: parsenodes.h:2145
@ OBJECT_AGGREGATE
Definition: parsenodes.h:2135
@ OBJECT_MATVIEW
Definition: parsenodes.h:2157
@ OBJECT_SCHEMA
Definition: parsenodes.h:2170
@ OBJECT_POLICY
Definition: parsenodes.h:2162
@ OBJECT_OPERATOR
Definition: parsenodes.h:2159
@ OBJECT_FOREIGN_TABLE
Definition: parsenodes.h:2152
@ OBJECT_TSCONFIGURATION
Definition: parsenodes.h:2179
@ OBJECT_OPFAMILY
Definition: parsenodes.h:2160
@ OBJECT_DOMAIN
Definition: parsenodes.h:2146
@ OBJECT_COLUMN
Definition: parsenodes.h:2140
@ OBJECT_TABLESPACE
Definition: parsenodes.h:2176
@ OBJECT_ROLE
Definition: parsenodes.h:2167
@ OBJECT_ROUTINE
Definition: parsenodes.h:2168
@ OBJECT_LARGEOBJECT
Definition: parsenodes.h:2156
@ OBJECT_PUBLICATION_NAMESPACE
Definition: parsenodes.h:2165
@ OBJECT_PROCEDURE
Definition: parsenodes.h:2163
@ OBJECT_EXTENSION
Definition: parsenodes.h:2149
@ OBJECT_INDEX
Definition: parsenodes.h:2154
@ OBJECT_DEFAULT
Definition: parsenodes.h:2144
@ OBJECT_DATABASE
Definition: parsenodes.h:2143
@ OBJECT_SEQUENCE
Definition: parsenodes.h:2171
@ OBJECT_TSTEMPLATE
Definition: parsenodes.h:2182
@ OBJECT_LANGUAGE
Definition: parsenodes.h:2155
@ OBJECT_AMOP
Definition: parsenodes.h:2136
@ OBJECT_PUBLICATION_REL
Definition: parsenodes.h:2166
@ OBJECT_FOREIGN_SERVER
Definition: parsenodes.h:2151
@ OBJECT_TSDICTIONARY
Definition: parsenodes.h:2180
@ OBJECT_ATTRIBUTE
Definition: parsenodes.h:2138
@ OBJECT_PUBLICATION
Definition: parsenodes.h:2164
@ OBJECT_RULE
Definition: parsenodes.h:2169
@ OBJECT_CONVERSION
Definition: parsenodes.h:2142
@ OBJECT_AMPROC
Definition: parsenodes.h:2137
@ OBJECT_TABLE
Definition: parsenodes.h:2175
@ OBJECT_VIEW
Definition: parsenodes.h:2185
@ OBJECT_PARAMETER_ACL
Definition: parsenodes.h:2161
@ OBJECT_TYPE
Definition: parsenodes.h:2183
@ OBJECT_FUNCTION
Definition: parsenodes.h:2153
@ OBJECT_TABCONSTRAINT
Definition: parsenodes.h:2174
@ OBJECT_DOMCONSTRAINT
Definition: parsenodes.h:2147
@ OBJECT_SUBSCRIPTION
Definition: parsenodes.h:2172
@ OBJECT_STATISTIC_EXT
Definition: parsenodes.h:2173
@ OBJECT_CAST
Definition: parsenodes.h:2139
@ OBJECT_TRIGGER
Definition: parsenodes.h:2178
@ OBJECT_TRANSFORM
Definition: parsenodes.h:2177

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

809 {
810  List *runlist;
811  EventTriggerData trigdata;
812 
813  /*
814  * See EventTriggerDDLCommandStart for a discussion about why event
815  * triggers are disabled in single user mode.
816  */
817  if (!IsUnderPostmaster)
818  return;
819 
820  /*
821  * Also do nothing if our state isn't set up, which it won't be if there
822  * weren't any relevant event triggers at the start of the current DDL
823  * command. This test might therefore seem optional, but it's
824  * *necessary*, because EventTriggerCommonSetup might find triggers that
825  * didn't exist at the time the command started.
826  */
828  return;
829 
830  runlist = EventTriggerCommonSetup(parsetree,
832  "table_rewrite",
833  &trigdata);
834  if (runlist == NIL)
835  return;
836 
837  /*
838  * Make sure pg_event_trigger_table_rewrite_oid only works when running
839  * these triggers. Use PG_TRY to ensure table_rewrite_oid is reset even
840  * when one trigger fails. (This is perhaps not necessary, as the
841  * currentState variable will be removed shortly by our caller, but it
842  * seems better to play safe.)
843  */
846 
847  /* Run the triggers. */
848  PG_TRY();
849  {
850  EventTriggerInvoke(runlist, &trigdata);
851  }
852  PG_FINALLY();
853  {
856  }
857  PG_END_TRY();
858 
859  /* Cleanup. */
860  list_free(runlist);
861 
862  /*
863  * Make sure anything the event triggers did will be visible to the main
864  * command.
865  */
867 }

References CommandCounterIncrement(), currentEventTriggerState, 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 1464 of file event_trigger.c.

1465 {
1467  return;
1468 
1470 }

References EventTriggerQueryState::commandCollectionInhibited, and currentEventTriggerState.

Referenced by ProcessUtilitySlow().

◆ filter_event_trigger()

static bool filter_event_trigger ( CommandTag  tag,
EventTriggerCacheItem item 
)
static

Definition at line 525 of file event_trigger.c.

526 {
527  /*
528  * Filter by session replication role, knowing that we never see disabled
529  * items down here.
530  */
532  {
533  if (item->enabled == TRIGGER_FIRES_ON_ORIGIN)
534  return false;
535  }
536  else
537  {
538  if (item->enabled == TRIGGER_FIRES_ON_REPLICA)
539  return false;
540  }
541 
542  /* Filter by tags, if any were specified. */
543  if (!bms_is_empty(item->tagset) && !bms_is_member(tag, item->tagset))
544  return false;
545 
546  /* if we reach that point, we're not filtering out this item */
547  return true;
548 }
bool bms_is_member(int x, const Bitmapset *a)
Definition: bitmapset.c:427
bool bms_is_empty(const Bitmapset *a)
Definition: bitmapset.c:703
Bitmapset * tagset
Definition: evtcache.h:32
int SessionReplicationRole
Definition: trigger.c:68
#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 332 of file event_trigger.c.

333 {
334  ListCell *lc;
335  Datum *data;
336  int i = 0,
337  l = list_length(filterlist);
338 
339  data = (Datum *) palloc(l * sizeof(Datum));
340 
341  foreach(lc, filterlist)
342  {
343  const char *value = strVal(lfirst(lc));
344  char *result,
345  *p;
346 
347  result = pstrdup(value);
348  for (p = result; *p; p++)
349  *p = pg_ascii_toupper((unsigned char) *p);
350  data[i++] = PointerGetDatum(cstring_to_text(result));
351  pfree(result);
352  }
353 
354  return PointerGetDatum(construct_array(data, l, TEXTOID,
355  -1, false, TYPALIGN_INT));
356 }
ArrayType * construct_array(Datum *elems, int nelems, Oid elmtype, int elmlen, bool elmbyval, char elmalign)
Definition: arrayfuncs.c:3319
static struct @151 value
int i
Definition: isn.c:73
const void * data
unsigned char pg_ascii_toupper(unsigned char ch)
Definition: pgstrcasecmp.c:135
#define PointerGetDatum(X)
Definition: postgres.h:600
#define strVal(v)
Definition: value.h:72
text * cstring_to_text(const char *s)
Definition: varlena.c:188

References construct_array(), 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 506 of file event_trigger.c.

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

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 tags 
)
static

Definition at line 256 of file event_trigger.c.

258 {
259  Relation tgrel;
260  Oid trigoid;
261  HeapTuple tuple;
262  Datum values[Natts_pg_trigger];
263  bool nulls[Natts_pg_trigger];
264  NameData evtnamedata,
265  evteventdata;
266  ObjectAddress myself,
267  referenced;
268 
269  /* Open pg_event_trigger. */
270  tgrel = table_open(EventTriggerRelationId, RowExclusiveLock);
271 
272  /* Build the new pg_trigger tuple. */
273  trigoid = GetNewOidWithIndex(tgrel, EventTriggerOidIndexId,
274  Anum_pg_event_trigger_oid);
275  values[Anum_pg_event_trigger_oid - 1] = ObjectIdGetDatum(trigoid);
276  memset(nulls, false, sizeof(nulls));
277  namestrcpy(&evtnamedata, trigname);
278  values[Anum_pg_event_trigger_evtname - 1] = NameGetDatum(&evtnamedata);
279  namestrcpy(&evteventdata, eventname);
280  values[Anum_pg_event_trigger_evtevent - 1] = NameGetDatum(&evteventdata);
281  values[Anum_pg_event_trigger_evtowner - 1] = ObjectIdGetDatum(evtOwner);
282  values[Anum_pg_event_trigger_evtfoid - 1] = ObjectIdGetDatum(funcoid);
283  values[Anum_pg_event_trigger_evtenabled - 1] =
285  if (taglist == NIL)
286  nulls[Anum_pg_event_trigger_evttags - 1] = true;
287  else
288  values[Anum_pg_event_trigger_evttags - 1] =
289  filter_list_to_array(taglist);
290 
291  /* Insert heap tuple. */
292  tuple = heap_form_tuple(tgrel->rd_att, values, nulls);
293  CatalogTupleInsert(tgrel, tuple);
294  heap_freetuple(tuple);
295 
296  /* Depend on owner. */
297  recordDependencyOnOwner(EventTriggerRelationId, trigoid, evtOwner);
298 
299  /* Depend on event trigger function. */
300  myself.classId = EventTriggerRelationId;
301  myself.objectId = trigoid;
302  myself.objectSubId = 0;
303  referenced.classId = ProcedureRelationId;
304  referenced.objectId = funcoid;
305  referenced.objectSubId = 0;
306  recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
307 
308  /* Depend on extension, if any. */
309  recordDependencyOnCurrentExtension(&myself, false);
310 
311  /* Post creation hook for new event trigger */
312  InvokeObjectPostCreateHook(EventTriggerRelationId, trigoid, 0);
313 
314  /* Close pg_event_trigger. */
316 
317  return trigoid;
318 }
static Datum values[MAXATTR]
Definition: bootstrap.c:156
Oid GetNewOidWithIndex(Relation relation, Oid indexId, AttrNumber oidcolumn)
Definition: catalog.c:391
@ 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:1020
void CatalogTupleInsert(Relation heapRel, HeapTuple tup)
Definition: indexing.c:221
void namestrcpy(Name name, const char *str)
Definition: name.c:233
#define InvokeObjectPostCreateHook(classId, objectId, subId)
Definition: objectaccess.h:171
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:191
void recordDependencyOnOwner(Oid classId, Oid objectId, Oid owner)
Definition: pg_shdepend.c:164
#define NameGetDatum(X)
Definition: postgres.h:639
#define CharGetDatum(X)
Definition: postgres.h:460
TupleDesc rd_att
Definition: rel.h:110
Definition: c.h:676

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

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

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, Int32GetDatum, InvalidAttrNumber, is_objectclass_supported(), lfirst, MemSet, 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, SetSingleFuncCall(), CollectedCommand::simple, stringify_adefprivs_objtype(), stringify_grant_objtype(), table_close(), table_open(), tuplestore_putvalues(), generate_unaccent_rules::type, CollectedCommand::type, and values.

◆ pg_event_trigger_dropped_objects()

Datum pg_event_trigger_dropped_objects ( PG_FUNCTION_ARGS  )

Definition at line 1292 of file event_trigger.c.

1293 {
1294  ReturnSetInfo *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo;
1295  slist_iter iter;
1296 
1297  /*
1298  * Protect this function from being called out of context
1299  */
1302  ereport(ERROR,
1303  (errcode(ERRCODE_E_R_I_E_EVENT_TRIGGER_PROTOCOL_VIOLATED),
1304  errmsg("%s can only be called in a sql_drop event trigger function",
1305  "pg_event_trigger_dropped_objects()")));
1306 
1307  /* Build tuplestore to hold the result rows */
1308  SetSingleFuncCall(fcinfo, 0);
1309 
1311  {
1312  SQLDropObject *obj;
1313  int i = 0;
1314  Datum values[12];
1315  bool nulls[12];
1316 
1317  obj = slist_container(SQLDropObject, next, iter.cur);
1318 
1319  MemSet(values, 0, sizeof(values));
1320  MemSet(nulls, 0, sizeof(nulls));
1321 
1322  /* classid */
1324 
1325  /* objid */
1327 
1328  /* objsubid */
1330 
1331  /* original */
1332  values[i++] = BoolGetDatum(obj->original);
1333 
1334  /* normal */
1335  values[i++] = BoolGetDatum(obj->normal);
1336 
1337  /* is_temporary */
1338  values[i++] = BoolGetDatum(obj->istemp);
1339 
1340  /* object_type */
1342 
1343  /* schema_name */
1344  if (obj->schemaname)
1346  else
1347  nulls[i++] = true;
1348 
1349  /* object_name */
1350  if (obj->objname)
1351  values[i++] = CStringGetTextDatum(obj->objname);
1352  else
1353  nulls[i++] = true;
1354 
1355  /* object_identity */
1356  if (obj->objidentity)
1358  else
1359  nulls[i++] = true;
1360 
1361  /* address_names and address_args */
1362  if (obj->addrnames)
1363  {
1365 
1366  if (obj->addrargs)
1368  else
1370  }
1371  else
1372  {
1373  nulls[i++] = true;
1374  nulls[i++] = true;
1375  }
1376 
1377  tuplestore_putvalues(rsinfo->setResult, rsinfo->setDesc,
1378  values, nulls);
1379  }
1380 
1381  return (Datum) 0;
1382 }
ArrayType * construct_empty_array(Oid elmtype)
Definition: arrayfuncs.c:3440
static int32 next
Definition: blutils.c:219
#define slist_container(type, membername, ptr)
Definition: ilist.h:693
#define slist_foreach(iter, lhead)
Definition: ilist.h:719
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, Int32GetDatum, SQLDropObject::istemp, MemSet, next, SQLDropObject::normal, ObjectAddress::objectId, ObjectIdGetDatum, ObjectAddress::objectSubId, SQLDropObject::objecttype, SQLDropObject::objidentity, SQLDropObject::objname, SQLDropObject::original, PointerGetDatum, SQLDropObject::schemaname, ReturnSetInfo::setDesc, ReturnSetInfo::setResult, SetSingleFuncCall(), 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 1391 of file event_trigger.c.

1392 {
1393  /*
1394  * Protect this function from being called out of context
1395  */
1396  if (!currentEventTriggerState ||
1398  ereport(ERROR,
1399  (errcode(ERRCODE_E_R_I_E_EVENT_TRIGGER_PROTOCOL_VIOLATED),
1400  errmsg("%s can only be called in a table_rewrite event trigger function",
1401  "pg_event_trigger_table_rewrite_oid()")));
1402 
1404 }
#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 1412 of file event_trigger.c.

1413 {
1414  /*
1415  * Protect this function from being called out of context
1416  */
1417  if (!currentEventTriggerState ||
1419  ereport(ERROR,
1420  (errcode(ERRCODE_E_R_I_E_EVENT_TRIGGER_PROTOCOL_VIOLATED),
1421  errmsg("%s can only be called in a table_rewrite event trigger function",
1422  "pg_event_trigger_table_rewrite_reason()")));
1423 
1425 }
#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 2106 of file event_trigger.c.

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

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

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

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

1142 {
1143  /*
1144  * true if any sql_drop, table_rewrite, ddl_command_end event trigger
1145  * exists
1146  */
1147  return list_length(EventCacheLookup(EVT_SQLDrop)) > 0 ||
1150 }

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

Referenced by deleteObjectsInList(), and EventTriggerBeginCompleteQuery().

◆ validate_ddl_tags()

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

Definition at line 195 of file event_trigger.c.

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

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

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

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

Referenced by CreateEventTrigger().

Variable Documentation

◆ currentEventTriggerState