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)
 
void RemoveEventTriggerById (Oid trigOid)
 
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 384 of file event_trigger.c.

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().

385 {
386  Relation tgrel;
387  HeapTuple tup;
388  Oid trigoid;
389  Form_pg_event_trigger evtForm;
390  char tgenabled = stmt->tgenabled;
391 
392  tgrel = table_open(EventTriggerRelationId, RowExclusiveLock);
393 
395  CStringGetDatum(stmt->trigname));
396  if (!HeapTupleIsValid(tup))
397  ereport(ERROR,
398  (errcode(ERRCODE_UNDEFINED_OBJECT),
399  errmsg("event trigger \"%s\" does not exist",
400  stmt->trigname)));
401 
402  evtForm = (Form_pg_event_trigger) GETSTRUCT(tup);
403  trigoid = evtForm->oid;
404 
405  if (!pg_event_trigger_ownercheck(trigoid, GetUserId()))
407  stmt->trigname);
408 
409  /* tuple is a copy, so we can modify it below */
410  evtForm->evtenabled = tgenabled;
411 
412  CatalogTupleUpdate(tgrel, &tup->t_self, tup);
413 
414  InvokeObjectPostAlterHook(EventTriggerRelationId,
415  trigoid, 0);
416 
417  /* clean up */
418  heap_freetuple(tup);
420 
421  return trigoid;
422 }
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:133
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
Oid GetUserId(void)
Definition: miscinit.c:448
int errcode(int sqlerrcode)
Definition: elog.c:610
void heap_freetuple(HeapTuple htup)
Definition: heaptuple.c:1338
unsigned int Oid
Definition: postgres_ext.h:31
void aclcheck_error(AclResult aclerr, ObjectType objtype, const char *objectname)
Definition: aclchk.c:3327
#define ERROR
Definition: elog.h:43
bool pg_event_trigger_ownercheck(Oid et_oid, Oid roleid)
Definition: aclchk.c:5111
ItemPointerData t_self
Definition: htup.h:65
#define RowExclusiveLock
Definition: lockdefs.h:38
#define CStringGetDatum(X)
Definition: postgres.h:578
#define InvokeObjectPostAlterHook(classId, objectId, subId)
Definition: objectaccess.h:175
#define ereport(elevel,...)
Definition: elog.h:144
FormData_pg_event_trigger * Form_pg_event_trigger
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
void CatalogTupleUpdate(Relation heapRel, ItemPointer otid, HeapTuple tup)
Definition: indexing.c:224
#define SearchSysCacheCopy1(cacheId, key1)
Definition: syscache.h:174
int errmsg(const char *fmt,...)
Definition: elog.c:824
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:39

◆ AlterEventTriggerOwner()

ObjectAddress AlterEventTriggerOwner ( const char *  name,
Oid  newOwnerId 
)

Definition at line 428 of file event_trigger.c.

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

Referenced by ExecAlterOwnerStmt().

429 {
430  Oid evtOid;
431  HeapTuple tup;
432  Form_pg_event_trigger evtForm;
433  Relation rel;
434  ObjectAddress address;
435 
436  rel = table_open(EventTriggerRelationId, RowExclusiveLock);
437 
439 
440  if (!HeapTupleIsValid(tup))
441  ereport(ERROR,
442  (errcode(ERRCODE_UNDEFINED_OBJECT),
443  errmsg("event trigger \"%s\" does not exist", name)));
444 
445  evtForm = (Form_pg_event_trigger) GETSTRUCT(tup);
446  evtOid = evtForm->oid;
447 
448  AlterEventTriggerOwner_internal(rel, tup, newOwnerId);
449 
450  ObjectAddressSet(address, EventTriggerRelationId, evtOid);
451 
452  heap_freetuple(tup);
453 
455 
456  return address;
457 }
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:133
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
int errcode(int sqlerrcode)
Definition: elog.c:610
void heap_freetuple(HeapTuple htup)
Definition: heaptuple.c:1338
unsigned int Oid
Definition: postgres_ext.h:31
static void AlterEventTriggerOwner_internal(Relation rel, HeapTuple tup, Oid newOwnerId)
#define ERROR
Definition: elog.h:43
#define RowExclusiveLock
Definition: lockdefs.h:38
#define CStringGetDatum(X)
Definition: postgres.h:578
#define ereport(elevel,...)
Definition: elog.h:144
FormData_pg_event_trigger * Form_pg_event_trigger
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
const char * name
Definition: encode.c:555
#define ObjectAddressSet(addr, class_id, object_id)
Definition: objectaddress.h:40
#define SearchSysCacheCopy1(cacheId, key1)
Definition: syscache.h:174
int errmsg(const char *fmt,...)
Definition: elog.c:824
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:39

◆ AlterEventTriggerOwner_internal()

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

Definition at line 488 of file event_trigger.c.

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().

489 {
491 
492  form = (Form_pg_event_trigger) GETSTRUCT(tup);
493 
494  if (form->evtowner == newOwnerId)
495  return;
496 
497  if (!pg_event_trigger_ownercheck(form->oid, GetUserId()))
499  NameStr(form->evtname));
500 
501  /* New owner must be a superuser */
502  if (!superuser_arg(newOwnerId))
503  ereport(ERROR,
504  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
505  errmsg("permission denied to change owner of event trigger \"%s\"",
506  NameStr(form->evtname)),
507  errhint("The owner of an event trigger must be a superuser.")));
508 
509  form->evtowner = newOwnerId;
510  CatalogTupleUpdate(rel, &tup->t_self, tup);
511 
512  /* Update owner dependency reference */
513  changeDependencyOnOwner(EventTriggerRelationId,
514  form->oid,
515  newOwnerId);
516 
517  InvokeObjectPostAlterHook(EventTriggerRelationId,
518  form->oid, 0);
519 }
int errhint(const char *fmt,...)
Definition: elog.c:1071
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
Oid GetUserId(void)
Definition: miscinit.c:448
int errcode(int sqlerrcode)
Definition: elog.c:610
void changeDependencyOnOwner(Oid classId, Oid objectId, Oid newOwnerId)
Definition: pg_shdepend.c:309
void aclcheck_error(AclResult aclerr, ObjectType objtype, const char *objectname)
Definition: aclchk.c:3327
#define ERROR
Definition: elog.h:43
bool pg_event_trigger_ownercheck(Oid et_oid, Oid roleid)
Definition: aclchk.c:5111
ItemPointerData t_self
Definition: htup.h:65
#define InvokeObjectPostAlterHook(classId, objectId, subId)
Definition: objectaccess.h:175
bool superuser_arg(Oid roleid)
Definition: superuser.c:56
#define ereport(elevel,...)
Definition: elog.h:144
FormData_pg_event_trigger * Form_pg_event_trigger
void CatalogTupleUpdate(Relation heapRel, ItemPointer otid, HeapTuple tup)
Definition: indexing.c:224
int errmsg(const char *fmt,...)
Definition: elog.c:824
#define NameStr(name)
Definition: c.h:615

◆ AlterEventTriggerOwner_oid()

void AlterEventTriggerOwner_oid ( Oid  trigOid,
Oid  newOwnerId 
)

Definition at line 463 of file event_trigger.c.

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

Referenced by shdepReassignOwned().

464 {
465  HeapTuple tup;
466  Relation rel;
467 
468  rel = table_open(EventTriggerRelationId, RowExclusiveLock);
469 
471 
472  if (!HeapTupleIsValid(tup))
473  ereport(ERROR,
474  (errcode(ERRCODE_UNDEFINED_OBJECT),
475  errmsg("event trigger with OID %u does not exist", trigOid)));
476 
477  AlterEventTriggerOwner_internal(rel, tup, newOwnerId);
478 
479  heap_freetuple(tup);
480 
482 }
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:133
int errcode(int sqlerrcode)
Definition: elog.c:610
void heap_freetuple(HeapTuple htup)
Definition: heaptuple.c:1338
static void AlterEventTriggerOwner_internal(Relation rel, HeapTuple tup, Oid newOwnerId)
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
#define RowExclusiveLock
Definition: lockdefs.h:38
#define ereport(elevel,...)
Definition: elog.h:144
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
#define SearchSysCacheCopy1(cacheId, key1)
Definition: syscache.h:174
int errmsg(const char *fmt,...)
Definition: elog.c:824
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:39

◆ CreateEventTrigger()

Oid CreateEventTrigger ( CreateEventTrigStmt stmt)

Definition at line 108 of file event_trigger.c.

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().

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 != EVTTRIGGEROID)
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_ddl_tags(const char *filtervar, List *taglist)
int errhint(const char *fmt,...)
Definition: elog.c:1071
Oid GetUserId(void)
Definition: miscinit.c:448
int errcode(int sqlerrcode)
Definition: elog.c:610
bool superuser(void)
Definition: superuser.c:46
unsigned int Oid
Definition: postgres_ext.h:31
Oid get_func_rettype(Oid funcid)
Definition: lsyscache.c:1518
#define ERROR
Definition: elog.h:43
static void validate_table_rewrite_tags(const char *filtervar, List *taglist)
Oid LookupFuncName(List *funcname, int nargs, const Oid *argtypes, bool missing_ok)
Definition: parse_func.c:2103
static void error_duplicate_filter_variable(const char *defname)
#define CStringGetDatum(X)
Definition: postgres.h:578
Node * arg
Definition: parsenodes.h:733
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1116
char * NameListToString(List *names)
Definition: namespace.c:3102
static Oid insert_event_trigger_tuple(const char *trigname, const char *eventname, Oid evtOwner, Oid funcoid, List *tags)
#define ereport(elevel,...)
Definition: elog.h:144
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
#define lfirst(lc)
Definition: pg_list.h:190
int errmsg(const char *fmt,...)
Definition: elog.c:824
char * defname
Definition: parsenodes.h:732
#define ERRCODE_DUPLICATE_OBJECT
Definition: streamutil.c:31
Definition: pg_list.h:50

◆ error_duplicate_filter_variable()

static void error_duplicate_filter_variable ( const char *  defname)
static

Definition at line 244 of file event_trigger.c.

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

Referenced by CreateEventTrigger().

245 {
246  ereport(ERROR,
247  (errcode(ERRCODE_SYNTAX_ERROR),
248  errmsg("filter variable \"%s\" specified more than once",
249  defname)));
250 }
int errcode(int sqlerrcode)
Definition: elog.c:610
#define ERROR
Definition: elog.h:43
#define ereport(elevel,...)
Definition: elog.h:144
int errmsg(const char *fmt,...)
Definition: elog.c:824

◆ EventTriggerAlterTableEnd()

void EventTriggerAlterTableEnd ( void  )

Definition at line 1656 of file event_trigger.c.

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

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

1657 {
1658  CollectedCommand *parent;
1659 
1660  /* ignore if event trigger context not set, or collection disabled */
1661  if (!currentEventTriggerState ||
1663  return;
1664 
1666 
1667  /* If no subcommands, don't collect */
1669  {
1673  }
1674  else
1676 
1678 }
struct CollectedCommand::@109::@111 alterTable
static EventTriggerQueryState * currentEventTriggerState
Definition: event_trigger.c:73
void pfree(void *pointer)
Definition: mcxt.c:1056
CollectedCommand * currentCommand
Definition: event_trigger.c:67
struct CollectedCommand * parent
union CollectedCommand::@109 d
List * lappend(List *list, void *datum)
Definition: list.c:321
static int list_length(const List *l)
Definition: pg_list.h:169

◆ EventTriggerAlterTableRelid()

void EventTriggerAlterTableRelid ( Oid  objectId)

Definition at line 1603 of file event_trigger.c.

References CollectedCommand::alterTable, EventTriggerQueryState::commandCollectionInhibited, EventTriggerQueryState::currentCommand, and CollectedCommand::d.

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

1604 {
1605  if (!currentEventTriggerState ||
1607  return;
1608 
1609  currentEventTriggerState->currentCommand->d.alterTable.objectId = objectId;
1610 }
struct CollectedCommand::@109::@111 alterTable
static EventTriggerQueryState * currentEventTriggerState
Definition: event_trigger.c:73
CollectedCommand * currentCommand
Definition: event_trigger.c:67
union CollectedCommand::@109 d

◆ EventTriggerAlterTableStart()

void EventTriggerAlterTableStart ( Node parsetree)

Definition at line 1569 of file event_trigger.c.

References CollectedCommand::alterTable, EventTriggerQueryState::commandCollectionInhibited, copyObject, creating_extension, EventTriggerQueryState::currentCommand, 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().

1570 {
1571  MemoryContext oldcxt;
1572  CollectedCommand *command;
1573 
1574  /* ignore if event trigger context not set, or collection disabled */
1575  if (!currentEventTriggerState ||
1577  return;
1578 
1580 
1581  command = palloc(sizeof(CollectedCommand));
1582 
1583  command->type = SCT_AlterTable;
1584  command->in_extension = creating_extension;
1585 
1586  command->d.alterTable.classId = RelationRelationId;
1587  command->d.alterTable.objectId = InvalidOid;
1588  command->d.alterTable.subcmds = NIL;
1589  command->parsetree = copyObject(parsetree);
1590 
1593 
1594  MemoryContextSwitchTo(oldcxt);
1595 }
#define NIL
Definition: pg_list.h:65
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
struct CollectedCommand::@109::@111 alterTable
CollectedCommandType type
static EventTriggerQueryState * currentEventTriggerState
Definition: event_trigger.c:73
CollectedCommand * currentCommand
Definition: event_trigger.c:67
struct CollectedCommand * parent
union CollectedCommand::@109 d
#define InvalidOid
Definition: postgres_ext.h:36
bool creating_extension
Definition: extension.c:71
void * palloc(Size size)
Definition: mcxt.c:949
#define copyObject(obj)
Definition: nodes.h:645

◆ EventTriggerBeginCompleteQuery()

bool EventTriggerBeginCompleteQuery ( void  )

Definition at line 1097 of file event_trigger.c.

References ALLOCSET_DEFAULT_SIZES, AllocSetContextCreate, EventTriggerQueryState::commandCollectionInhibited, EventTriggerQueryState::commandList, EventTriggerQueryState::currentCommand, currentEventTriggerState, EventTriggerQueryState::cxt, EventTriggerQueryState::in_sql_drop, InvalidOid, MemoryContextAlloc(), NIL, EventTriggerQueryState::previous, slist_init(), EventTriggerQueryState::SQLDropList, EventTriggerQueryState::table_rewrite_oid, TopMemoryContext, and trackDroppedObjectsNeeded().

Referenced by ProcessUtilitySlow().

1098 {
1100  MemoryContext cxt;
1101 
1102  /*
1103  * Currently, sql_drop, table_rewrite, ddl_command_end events are the only
1104  * reason to have event trigger state at all; so if there are none, don't
1105  * install one.
1106  */
1108  return false;
1109 
1111  "event trigger state",
1113  state = MemoryContextAlloc(cxt, sizeof(EventTriggerQueryState));
1114  state->cxt = cxt;
1115  slist_init(&(state->SQLDropList));
1116  state->in_sql_drop = false;
1117  state->table_rewrite_oid = InvalidOid;
1118 
1121  state->currentCommand = NULL;
1122  state->commandList = NIL;
1124  currentEventTriggerState = state;
1125 
1126  return true;
1127 }
#define NIL
Definition: pg_list.h:65
#define AllocSetContextCreate
Definition: memutils.h:170
bool trackDroppedObjectsNeeded(void)
static EventTriggerQueryState * currentEventTriggerState
Definition: event_trigger.c:73
static void slist_init(slist_head *head)
Definition: ilist.h:554
#define ALLOCSET_DEFAULT_SIZES
Definition: memutils.h:192
CollectedCommand * currentCommand
Definition: event_trigger.c:67
struct EventTriggerQueryState * previous
Definition: event_trigger.c:70
MemoryContext TopMemoryContext
Definition: mcxt.c:44
#define InvalidOid
Definition: postgres_ext.h:36
Definition: regguts.h:298
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition: mcxt.c:796

◆ EventTriggerCollectAlterDefPrivs()

void EventTriggerCollectAlterDefPrivs ( AlterDefaultPrivilegesStmt stmt)

Definition at line 1834 of file event_trigger.c.

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

Referenced by ProcessUtilitySlow().

1835 {
1836  MemoryContext oldcxt;
1837  CollectedCommand *command;
1838 
1839  /* ignore if event trigger context not set, or collection disabled */
1840  if (!currentEventTriggerState ||
1842  return;
1843 
1845 
1846  command = palloc0(sizeof(CollectedCommand));
1847  command->type = SCT_AlterDefaultPrivileges;
1848  command->d.defprivs.objtype = stmt->action->objtype;
1849  command->in_extension = creating_extension;
1850  command->parsetree = (Node *) copyObject(stmt);
1851 
1854  MemoryContextSwitchTo(oldcxt);
1855 }
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
Definition: nodes.h:529
CollectedCommandType type
static EventTriggerQueryState * currentEventTriggerState
Definition: event_trigger.c:73
union CollectedCommand::@109 d
List * lappend(List *list, void *datum)
Definition: list.c:321
void * palloc0(Size size)
Definition: mcxt.c:980
bool creating_extension
Definition: extension.c:71
struct CollectedCommand::@109::@116 defprivs
ObjectType objtype
Definition: parsenodes.h:1929
#define copyObject(obj)
Definition: nodes.h:645

◆ EventTriggerCollectAlterOpFam()

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

Definition at line 1732 of file event_trigger.c.

References EventTriggerQueryState::commandCollectionInhibited, EventTriggerQueryState::commandList, copyObject, creating_extension, 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().

1734 {
1735  MemoryContext oldcxt;
1736  CollectedCommand *command;
1737 
1738  /* ignore if event trigger context not set, or collection disabled */
1739  if (!currentEventTriggerState ||
1741  return;
1742 
1744 
1745  command = palloc(sizeof(CollectedCommand));
1746  command->type = SCT_AlterOpFamily;
1747  command->in_extension = creating_extension;
1748  ObjectAddressSet(command->d.opfam.address,
1749  OperatorFamilyRelationId, opfamoid);
1750  command->d.opfam.operators = operators;
1751  command->d.opfam.procedures = procedures;
1752  command->parsetree = (Node *) copyObject(stmt);
1753 
1756 
1757  MemoryContextSwitchTo(oldcxt);
1758 }
struct CollectedCommand::@109::@113 opfam
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
Definition: nodes.h:529
CollectedCommandType type
static EventTriggerQueryState * currentEventTriggerState
Definition: event_trigger.c:73
union CollectedCommand::@109 d
List * lappend(List *list, void *datum)
Definition: list.c:321
bool creating_extension
Definition: extension.c:71
#define ObjectAddressSet(addr, class_id, object_id)
Definition: objectaddress.h:40
void * palloc(Size size)
Definition: mcxt.c:949
#define copyObject(obj)
Definition: nodes.h:645

◆ EventTriggerCollectAlterTableSubcmd()

void EventTriggerCollectAlterTableSubcmd ( Node subcmd,
ObjectAddress  address 
)

Definition at line 1621 of file event_trigger.c.

References CollectedATSubcmd::address, CollectedCommand::alterTable, Assert, EventTriggerQueryState::commandCollectionInhibited, copyObject, EventTriggerQueryState::currentCommand, EventTriggerQueryState::cxt, CollectedCommand::d, IsA, lappend(), MemoryContextSwitchTo(), newsub(), OidIsValid, palloc(), and CollectedATSubcmd::parsetree.

Referenced by ATExecCmd().

1622 {
1623  MemoryContext oldcxt;
1625 
1626  /* ignore if event trigger context not set, or collection disabled */
1627  if (!currentEventTriggerState ||
1629  return;
1630 
1631  Assert(IsA(subcmd, AlterTableCmd));
1634 
1636 
1637  newsub = palloc(sizeof(CollectedATSubcmd));
1638  newsub->address = address;
1639  newsub->parsetree = copyObject(subcmd);
1640 
1643 
1644  MemoryContextSwitchTo(oldcxt);
1645 }
#define IsA(nodeptr, _type_)
Definition: nodes.h:580
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
struct CollectedCommand::@109::@111 alterTable
#define OidIsValid(objectId)
Definition: c.h:644
static EventTriggerQueryState * currentEventTriggerState
Definition: event_trigger.c:73
CollectedCommand * currentCommand
Definition: event_trigger.c:67
union CollectedCommand::@109 d
List * lappend(List *list, void *datum)
Definition: list.c:321
#define Assert(condition)
Definition: c.h:738
void * palloc(Size size)
Definition: mcxt.c:949
#define copyObject(obj)
Definition: nodes.h:645
static color newsub(struct colormap *cm, color co)
Definition: regc_color.c:389
ObjectAddress address

◆ EventTriggerCollectAlterTSConfig()

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

Definition at line 1799 of file event_trigger.c.

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

Referenced by DropConfigurationMapping(), and MakeConfigurationMapping().

1801 {
1802  MemoryContext oldcxt;
1803  CollectedCommand *command;
1804 
1805  /* ignore if event trigger context not set, or collection disabled */
1806  if (!currentEventTriggerState ||
1808  return;
1809 
1811 
1812  command = palloc0(sizeof(CollectedCommand));
1813  command->type = SCT_AlterTSConfig;
1814  command->in_extension = creating_extension;
1815  ObjectAddressSet(command->d.atscfg.address,
1816  TSConfigRelationId, cfgId);
1817  command->d.atscfg.dictIds = palloc(sizeof(Oid) * ndicts);
1818  memcpy(command->d.atscfg.dictIds, dictIds, sizeof(Oid) * ndicts);
1819  command->d.atscfg.ndicts = ndicts;
1820  command->parsetree = (Node *) copyObject(stmt);
1821 
1824 
1825  MemoryContextSwitchTo(oldcxt);
1826 }
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
Definition: nodes.h:529
CollectedCommandType type
unsigned int Oid
Definition: postgres_ext.h:31
static EventTriggerQueryState * currentEventTriggerState
Definition: event_trigger.c:73
union CollectedCommand::@109 d
List * lappend(List *list, void *datum)
Definition: list.c:321
void * palloc0(Size size)
Definition: mcxt.c:980
bool creating_extension
Definition: extension.c:71
struct CollectedCommand::@109::@115 atscfg
#define ObjectAddressSet(addr, class_id, object_id)
Definition: objectaddress.h:40
void * palloc(Size size)
Definition: mcxt.c:949
#define copyObject(obj)
Definition: nodes.h:645

◆ EventTriggerCollectCreateOpClass()

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

Definition at line 1765 of file event_trigger.c.

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

Referenced by DefineOpClass().

1767 {
1768  MemoryContext oldcxt;
1769  CollectedCommand *command;
1770 
1771  /* ignore if event trigger context not set, or collection disabled */
1772  if (!currentEventTriggerState ||
1774  return;
1775 
1777 
1778  command = palloc0(sizeof(CollectedCommand));
1779  command->type = SCT_CreateOpClass;
1780  command->in_extension = creating_extension;
1781  ObjectAddressSet(command->d.createopc.address,
1782  OperatorClassRelationId, opcoid);
1783  command->d.createopc.operators = operators;
1784  command->d.createopc.procedures = procedures;
1785  command->parsetree = (Node *) copyObject(stmt);
1786 
1789 
1790  MemoryContextSwitchTo(oldcxt);
1791 }
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
Definition: nodes.h:529
CollectedCommandType type
static EventTriggerQueryState * currentEventTriggerState
Definition: event_trigger.c:73
union CollectedCommand::@109 d
List * lappend(List *list, void *datum)
Definition: list.c:321
void * palloc0(Size size)
Definition: mcxt.c:980
bool creating_extension
Definition: extension.c:71
struct CollectedCommand::@109::@114 createopc
#define ObjectAddressSet(addr, class_id, object_id)
Definition: objectaddress.h:40
#define copyObject(obj)
Definition: nodes.h:645

◆ EventTriggerCollectGrant()

void EventTriggerCollectGrant ( InternalGrant istmt)

Definition at line 1688 of file event_trigger.c.

References InternalGrant::col_privs, EventTriggerQueryState::commandCollectionInhibited, EventTriggerQueryState::commandList, copyObject, creating_extension, 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().

1689 {
1690  MemoryContext oldcxt;
1691  CollectedCommand *command;
1692  InternalGrant *icopy;
1693  ListCell *cell;
1694 
1695  /* ignore if event trigger context not set, or collection disabled */
1696  if (!currentEventTriggerState ||
1698  return;
1699 
1701 
1702  /*
1703  * This is tedious, but necessary.
1704  */
1705  icopy = palloc(sizeof(InternalGrant));
1706  memcpy(icopy, istmt, sizeof(InternalGrant));
1707  icopy->objects = list_copy(istmt->objects);
1708  icopy->grantees = list_copy(istmt->grantees);
1709  icopy->col_privs = NIL;
1710  foreach(cell, istmt->col_privs)
1711  icopy->col_privs = lappend(icopy->col_privs, copyObject(lfirst(cell)));
1712 
1713  /* Now collect it, using the copied InternalGrant */
1714  command = palloc(sizeof(CollectedCommand));
1715  command->type = SCT_Grant;
1716  command->in_extension = creating_extension;
1717  command->d.grant.istmt = icopy;
1718  command->parsetree = NULL;
1719 
1722 
1723  MemoryContextSwitchTo(oldcxt);
1724 }
#define NIL
Definition: pg_list.h:65
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
List * list_copy(const List *oldlist)
Definition: list.c:1403
CollectedCommandType type
static EventTriggerQueryState * currentEventTriggerState
Definition: event_trigger.c:73
struct CollectedCommand::@109::@112 grant
union CollectedCommand::@109 d
List * lappend(List *list, void *datum)
Definition: list.c:321
bool creating_extension
Definition: extension.c:71
#define lfirst(lc)
Definition: pg_list.h:190
void * palloc(Size size)
Definition: mcxt.c:949
#define copyObject(obj)
Definition: nodes.h:645

◆ EventTriggerCollectSimpleCommand()

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

Definition at line 1531 of file event_trigger.c.

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

Referenced by AlterPublicationOptions(), CreateSchemaCommand(), ProcessUtilitySlow(), and PublicationAddTables().

1534 {
1535  MemoryContext oldcxt;
1536  CollectedCommand *command;
1537 
1538  /* ignore if event trigger context not set, or collection disabled */
1539  if (!currentEventTriggerState ||
1541  return;
1542 
1544 
1545  command = palloc(sizeof(CollectedCommand));
1546 
1547  command->type = SCT_Simple;
1548  command->in_extension = creating_extension;
1549 
1550  command->d.simple.address = address;
1551  command->d.simple.secondaryObject = secondaryObject;
1552  command->parsetree = copyObject(parsetree);
1553 
1555  command);
1556 
1557  MemoryContextSwitchTo(oldcxt);
1558 }
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
CollectedCommandType type
static EventTriggerQueryState * currentEventTriggerState
Definition: event_trigger.c:73
union CollectedCommand::@109 d
struct CollectedCommand::@109::@110 simple
List * lappend(List *list, void *datum)
Definition: list.c:321
bool creating_extension
Definition: extension.c:71
void * palloc(Size size)
Definition: mcxt.c:949
#define copyObject(obj)
Definition: nodes.h:645

◆ EventTriggerCommonSetup()

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

Definition at line 578 of file event_trigger.c.

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().

581 {
582  CommandTag tag;
583  List *cachelist;
584  ListCell *lc;
585  List *runlist = NIL;
586 
587  /*
588  * We want the list of command tags for which this procedure is actually
589  * invoked to match up exactly with the list that CREATE EVENT TRIGGER
590  * accepts. This debugging cross-check will throw an error if this
591  * function is invoked for a command tag that CREATE EVENT TRIGGER won't
592  * accept. (Unfortunately, there doesn't seem to be any simple, automated
593  * way to verify that CREATE EVENT TRIGGER doesn't accept extra stuff that
594  * never reaches this control point.)
595  *
596  * If this cross-check fails for you, you probably need to either adjust
597  * standard_ProcessUtility() not to invoke event triggers for the command
598  * type in question, or you need to adjust event_trigger_ok to accept the
599  * relevant command tag.
600  */
601 #ifdef USE_ASSERT_CHECKING
602  {
603  CommandTag dbgtag;
604 
605  dbgtag = CreateCommandTag(parsetree);
606  if (event == EVT_DDLCommandStart ||
607  event == EVT_DDLCommandEnd ||
608  event == EVT_SQLDrop)
609  {
610  if (!command_tag_event_trigger_ok(dbgtag))
611  elog(ERROR, "unexpected command tag \"%s\"", GetCommandTagName(dbgtag));
612  }
613  else if (event == EVT_TableRewrite)
614  {
615  if (!command_tag_table_rewrite_ok(dbgtag))
616  elog(ERROR, "unexpected command tag \"%s\"", GetCommandTagName(dbgtag));
617  }
618  }
619 #endif
620 
621  /* Use cache to find triggers for this event; fast exit if none. */
622  cachelist = EventCacheLookup(event);
623  if (cachelist == NIL)
624  return NIL;
625 
626  /* Get the command tag. */
627  tag = CreateCommandTag(parsetree);
628 
629  /*
630  * Filter list of event triggers by command tag, and copy them into our
631  * memory context. Once we start running the command triggers, or indeed
632  * once we do anything at all that touches the catalogs, an invalidation
633  * might leave cachelist pointing at garbage, so we must do this before we
634  * can do much else.
635  */
636  foreach(lc, cachelist)
637  {
638  EventTriggerCacheItem *item = lfirst(lc);
639 
640  if (filter_event_trigger(tag, item))
641  {
642  /* We must plan to fire this trigger. */
643  runlist = lappend_oid(runlist, item->fnoid);
644  }
645  }
646 
647  /* don't spend any more time on this if no functions to run */
648  if (runlist == NIL)
649  return NIL;
650 
651  trigdata->type = T_EventTriggerData;
652  trigdata->event = eventstr;
653  trigdata->parsetree = parsetree;
654  trigdata->tag = tag;
655 
656  return runlist;
657 }
#define NIL
Definition: pg_list.h:65
CommandTag
Definition: cmdtag.h:20
CommandTag tag
Definition: event_trigger.h:29
bool command_tag_table_rewrite_ok(CommandTag commandTag)
Definition: cmdtag.c:63
List * lappend_oid(List *list, Oid datum)
Definition: list.c:357
#define ERROR
Definition: elog.h:43
const char * event
Definition: event_trigger.h:27
#define lfirst(lc)
Definition: pg_list.h:190
CommandTag CreateCommandTag(Node *parsetree)
Definition: utility.c:2246
const char * GetCommandTagName(CommandTag commandTag)
Definition: cmdtag.c:45
#define elog(elevel,...)
Definition: elog.h:214
List * EventCacheLookup(EventTriggerEvent event)
Definition: evtcache.c:65
bool command_tag_event_trigger_ok(CommandTag commandTag)
Definition: cmdtag.c:57
Definition: pg_list.h:50
static bool filter_event_trigger(CommandTag tag, EventTriggerCacheItem *item)

◆ EventTriggerDDLCommandEnd()

void EventTriggerDDLCommandEnd ( Node parsetree)

Definition at line 711 of file event_trigger.c.

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

Referenced by ProcessUtilitySlow().

712 {
713  List *runlist;
714  EventTriggerData trigdata;
715 
716  /*
717  * See EventTriggerDDLCommandStart for a discussion about why event
718  * triggers are disabled in single user mode.
719  */
720  if (!IsUnderPostmaster)
721  return;
722 
723  /*
724  * Also do nothing if our state isn't set up, which it won't be if there
725  * weren't any relevant event triggers at the start of the current DDL
726  * command. This test might therefore seem optional, but it's important
727  * because EventTriggerCommonSetup might find triggers that didn't exist
728  * at the time the command started. Although this function itself
729  * wouldn't crash, the event trigger functions would presumably call
730  * pg_event_trigger_ddl_commands which would fail. Better to do nothing
731  * until the next command.
732  */
734  return;
735 
736  runlist = EventTriggerCommonSetup(parsetree,
737  EVT_DDLCommandEnd, "ddl_command_end",
738  &trigdata);
739  if (runlist == NIL)
740  return;
741 
742  /*
743  * Make sure anything the main command did will be visible to the event
744  * triggers.
745  */
747 
748  /* Run the triggers. */
749  EventTriggerInvoke(runlist, &trigdata);
750 
751  /* Cleanup. */
752  list_free(runlist);
753 }
#define NIL
Definition: pg_list.h:65
static void EventTriggerInvoke(List *fn_oid_list, EventTriggerData *trigdata)
static EventTriggerQueryState * currentEventTriggerState
Definition: event_trigger.c:73
static List * EventTriggerCommonSetup(Node *parsetree, EventTriggerEvent event, const char *eventstr, EventTriggerData *trigdata)
bool IsUnderPostmaster
Definition: globals.c:109
void CommandCounterIncrement(void)
Definition: xact.c:1006
void list_free(List *list)
Definition: list.c:1376
Definition: pg_list.h:50

◆ EventTriggerDDLCommandStart()

void EventTriggerDDLCommandStart ( Node parsetree)

Definition at line 663 of file event_trigger.c.

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

Referenced by ProcessUtilitySlow().

664 {
665  List *runlist;
666  EventTriggerData trigdata;
667 
668  /*
669  * Event Triggers are completely disabled in standalone mode. There are
670  * (at least) two reasons for this:
671  *
672  * 1. A sufficiently broken event trigger might not only render the
673  * database unusable, but prevent disabling itself to fix the situation.
674  * In this scenario, restarting in standalone mode provides an escape
675  * hatch.
676  *
677  * 2. BuildEventTriggerCache relies on systable_beginscan_ordered, and
678  * therefore will malfunction if pg_event_trigger's indexes are damaged.
679  * To allow recovery from a damaged index, we need some operating mode
680  * wherein event triggers are disabled. (Or we could implement
681  * heapscan-and-sort logic for that case, but having disaster recovery
682  * scenarios depend on code that's otherwise untested isn't appetizing.)
683  */
684  if (!IsUnderPostmaster)
685  return;
686 
687  runlist = EventTriggerCommonSetup(parsetree,
689  "ddl_command_start",
690  &trigdata);
691  if (runlist == NIL)
692  return;
693 
694  /* Run the triggers. */
695  EventTriggerInvoke(runlist, &trigdata);
696 
697  /* Cleanup. */
698  list_free(runlist);
699 
700  /*
701  * Make sure anything the event triggers did will be visible to the main
702  * command.
703  */
705 }
#define NIL
Definition: pg_list.h:65
static void EventTriggerInvoke(List *fn_oid_list, EventTriggerData *trigdata)
static List * EventTriggerCommonSetup(Node *parsetree, EventTriggerEvent event, const char *eventstr, EventTriggerData *trigdata)
bool IsUnderPostmaster
Definition: globals.c:109
void CommandCounterIncrement(void)
Definition: xact.c:1006
void list_free(List *list)
Definition: list.c:1376
Definition: pg_list.h:50

◆ EventTriggerEndCompleteQuery()

void EventTriggerEndCompleteQuery ( void  )

Definition at line 1141 of file event_trigger.c.

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

Referenced by ProcessUtilitySlow().

1142 {
1143  EventTriggerQueryState *prevstate;
1144 
1145  prevstate = currentEventTriggerState->previous;
1146 
1147  /* this avoids the need for retail pfree of SQLDropList items: */
1149 
1150  currentEventTriggerState = prevstate;
1151 }
void MemoryContextDelete(MemoryContext context)
Definition: mcxt.c:211
static EventTriggerQueryState * currentEventTriggerState
Definition: event_trigger.c:73
struct EventTriggerQueryState * previous
Definition: event_trigger.c:70

◆ EventTriggerInhibitCommandCollection()

void EventTriggerInhibitCommandCollection ( void  )

Definition at line 1497 of file event_trigger.c.

References EventTriggerQueryState::commandCollectionInhibited.

Referenced by ProcessUtilitySlow().

1498 {
1500  return;
1501 
1503 }
static EventTriggerQueryState * currentEventTriggerState
Definition: event_trigger.c:73

◆ EventTriggerInvoke()

static void EventTriggerInvoke ( List fn_oid_list,
EventTriggerData trigdata 
)
static

Definition at line 895 of file event_trigger.c.

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().

896 {
897  MemoryContext context;
898  MemoryContext oldcontext;
899  ListCell *lc;
900  bool first = true;
901 
902  /* Guard against stack overflow due to recursive event trigger */
904 
905  /*
906  * Let's evaluate event triggers in their own memory context, so that any
907  * leaks get cleaned up promptly.
908  */
910  "event trigger context",
912  oldcontext = MemoryContextSwitchTo(context);
913 
914  /* Call each event trigger. */
915  foreach(lc, fn_oid_list)
916  {
917  LOCAL_FCINFO(fcinfo, 0);
918  Oid fnoid = lfirst_oid(lc);
919  FmgrInfo flinfo;
920  PgStat_FunctionCallUsage fcusage;
921 
922  elog(DEBUG1, "EventTriggerInvoke %u", fnoid);
923 
924  /*
925  * We want each event trigger to be able to see the results of the
926  * previous event trigger's action. Caller is responsible for any
927  * command-counter increment that is needed between the event trigger
928  * and anything else in the transaction.
929  */
930  if (first)
931  first = false;
932  else
934 
935  /* Look up the function */
936  fmgr_info(fnoid, &flinfo);
937 
938  /* Call the function, passing no arguments but setting a context. */
939  InitFunctionCallInfoData(*fcinfo, &flinfo, 0,
940  InvalidOid, (Node *) trigdata, NULL);
941  pgstat_init_function_usage(fcinfo, &fcusage);
942  FunctionCallInvoke(fcinfo);
943  pgstat_end_function_usage(&fcusage, true);
944 
945  /* Reclaim memory. */
946  MemoryContextReset(context);
947  }
948 
949  /* Restore old memory context and delete the temporary one. */
950  MemoryContextSwitchTo(oldcontext);
951  MemoryContextDelete(context);
952 }
Definition: fmgr.h:56
void MemoryContextDelete(MemoryContext context)
Definition: mcxt.c:211
#define AllocSetContextCreate
Definition: memutils.h:170
#define DEBUG1
Definition: elog.h:25
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
Definition: nodes.h:529
void MemoryContextReset(MemoryContext context)
Definition: mcxt.c:136
unsigned int Oid
Definition: postgres_ext.h:31
void pgstat_init_function_usage(FunctionCallInfo fcinfo, PgStat_FunctionCallUsage *fcu)
Definition: pgstat.c:1675
void fmgr_info(Oid functionId, FmgrInfo *finfo)
Definition: fmgr.c:126
#define ALLOCSET_DEFAULT_SIZES
Definition: memutils.h:192
#define FunctionCallInvoke(fcinfo)
Definition: fmgr.h:172
void check_stack_depth(void)
Definition: postgres.c:3312
MemoryContext CurrentMemoryContext
Definition: mcxt.c:38
void CommandCounterIncrement(void)
Definition: xact.c:1006
#define InvalidOid
Definition: postgres_ext.h:36
#define LOCAL_FCINFO(name, nargs)
Definition: fmgr.h:110
#define InitFunctionCallInfoData(Fcinfo, Flinfo, Nargs, Collation, Context, Resultinfo)
Definition: fmgr.h:150
void pgstat_end_function_usage(PgStat_FunctionCallUsage *fcu, bool finalize)
Definition: pgstat.c:1747
#define elog(elevel,...)
Definition: elog.h:214
#define lfirst_oid(lc)
Definition: pg_list.h:192

◆ EventTriggerSQLDrop()

void EventTriggerSQLDrop ( Node parsetree)

Definition at line 759 of file event_trigger.c.

References CommandCounterIncrement(), 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().

760 {
761  List *runlist;
762  EventTriggerData trigdata;
763 
764  /*
765  * See EventTriggerDDLCommandStart for a discussion about why event
766  * triggers are disabled in single user mode.
767  */
768  if (!IsUnderPostmaster)
769  return;
770 
771  /*
772  * Use current state to determine whether this event fires at all. If
773  * there are no triggers for the sql_drop event, then we don't have
774  * anything to do here. Note that dropped object collection is disabled
775  * if this is the case, so even if we were to try to run, the list would
776  * be empty.
777  */
780  return;
781 
782  runlist = EventTriggerCommonSetup(parsetree,
783  EVT_SQLDrop, "sql_drop",
784  &trigdata);
785 
786  /*
787  * Nothing to do if run list is empty. Note this typically can't happen,
788  * because if there are no sql_drop events, then objects-to-drop wouldn't
789  * have been collected in the first place and we would have quit above.
790  * But it could occur if event triggers were dropped partway through.
791  */
792  if (runlist == NIL)
793  return;
794 
795  /*
796  * Make sure anything the main command did will be visible to the event
797  * triggers.
798  */
800 
801  /*
802  * Make sure pg_event_trigger_dropped_objects only works when running
803  * these triggers. Use PG_TRY to ensure in_sql_drop is reset even when
804  * one trigger fails. (This is perhaps not necessary, as the currentState
805  * variable will be removed shortly by our caller, but it seems better to
806  * play safe.)
807  */
809 
810  /* Run the triggers. */
811  PG_TRY();
812  {
813  EventTriggerInvoke(runlist, &trigdata);
814  }
815  PG_FINALLY();
816  {
818  }
819  PG_END_TRY();
820 
821  /* Cleanup. */
822  list_free(runlist);
823 }
#define NIL
Definition: pg_list.h:65
static void EventTriggerInvoke(List *fn_oid_list, EventTriggerData *trigdata)
static EventTriggerQueryState * currentEventTriggerState
Definition: event_trigger.c:73
static List * EventTriggerCommonSetup(Node *parsetree, EventTriggerEvent event, const char *eventstr, EventTriggerData *trigdata)
bool IsUnderPostmaster
Definition: globals.c:109
static bool slist_is_empty(slist_head *head)
Definition: ilist.h:563
#define PG_FINALLY()
Definition: elog.h:312
void CommandCounterIncrement(void)
Definition: xact.c:1006
void list_free(List *list)
Definition: list.c:1376
#define PG_TRY()
Definition: elog.h:295
Definition: pg_list.h:50
#define PG_END_TRY()
Definition: elog.h:320

◆ EventTriggerSQLDropAddObject()

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

Definition at line 1191 of file event_trigger.c.

References AccessShareLock, SQLDropObject::addrargs, SQLDropObject::address, SQLDropObject::addrnames, Assert, attnum, ObjectAddress::classId, 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().

1192 {
1193  SQLDropObject *obj;
1194  MemoryContext oldcxt;
1195 
1197  return;
1198 
1200 
1201  /* don't report temp schemas except my own */
1202  if (object->classId == NamespaceRelationId &&
1203  (isAnyTempNamespace(object->objectId) &&
1204  !isTempNamespace(object->objectId)))
1205  return;
1206 
1208 
1209  obj = palloc0(sizeof(SQLDropObject));
1210  obj->address = *object;
1211  obj->original = original;
1212  obj->normal = normal;
1213 
1214  /*
1215  * Obtain schema names from the object's catalog tuple, if one exists;
1216  * this lets us skip objects in temp schemas. We trust that
1217  * ObjectProperty contains all object classes that can be
1218  * schema-qualified.
1219  */
1220  if (is_objectclass_supported(object->classId))
1221  {
1222  Relation catalog;
1223  HeapTuple tuple;
1224 
1225  catalog = table_open(obj->address.classId, AccessShareLock);
1226  tuple = get_catalog_object_by_oid(catalog,
1227  get_object_attnum_oid(object->classId),
1228  obj->address.objectId);
1229 
1230  if (tuple)
1231  {
1233  Datum datum;
1234  bool isnull;
1235 
1237  if (attnum != InvalidAttrNumber)
1238  {
1239  datum = heap_getattr(tuple, attnum,
1240  RelationGetDescr(catalog), &isnull);
1241  if (!isnull)
1242  {
1243  Oid namespaceId;
1244 
1245  namespaceId = DatumGetObjectId(datum);
1246  /* temp objects are only reported if they are my own */
1247  if (isTempNamespace(namespaceId))
1248  {
1249  obj->schemaname = "pg_temp";
1250  obj->istemp = true;
1251  }
1252  else if (isAnyTempNamespace(namespaceId))
1253  {
1254  pfree(obj);
1255  table_close(catalog, AccessShareLock);
1256  MemoryContextSwitchTo(oldcxt);
1257  return;
1258  }
1259  else
1260  {
1261  obj->schemaname = get_namespace_name(namespaceId);
1262  obj->istemp = false;
1263  }
1264  }
1265  }
1266 
1268  obj->address.objectSubId == 0)
1269  {
1270  attnum = get_object_attnum_name(obj->address.classId);
1271  if (attnum != InvalidAttrNumber)
1272  {
1273  datum = heap_getattr(tuple, attnum,
1274  RelationGetDescr(catalog), &isnull);
1275  if (!isnull)
1276  obj->objname = pstrdup(NameStr(*DatumGetName(datum)));
1277  }
1278  }
1279  }
1280 
1281  table_close(catalog, AccessShareLock);
1282  }
1283  else
1284  {
1285  if (object->classId == NamespaceRelationId &&
1286  isTempNamespace(object->objectId))
1287  obj->istemp = true;
1288  }
1289 
1290  /* object identity, objname and objargs */
1291  obj->objidentity =
1292  getObjectIdentityParts(&obj->address, &obj->addrnames, &obj->addrargs);
1293 
1294  /* object type */
1296 
1298 
1299  MemoryContextSwitchTo(oldcxt);
1300 }
bool get_object_namensp_unique(Oid class_id)
slist_node next
Definition: event_trigger.c:88
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:133
ObjectAddress address
Definition: event_trigger.c:78
char * getObjectTypeDescription(const ObjectAddress *object)
AttrNumber get_object_attnum_oid(Oid class_id)
#define RelationGetDescr(relation)
Definition: rel.h:482
const char * objname
Definition: event_trigger.c:80
#define DatumGetObjectId(X)
Definition: postgres.h:500
char * pstrdup(const char *in)
Definition: mcxt.c:1186
char * getObjectIdentityParts(const ObjectAddress *object, List **objname, List **objargs)
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
#define AccessShareLock
Definition: lockdefs.h:36
static void slist_push_head(slist_head *head, slist_node *node)
Definition: ilist.h:574
List * addrnames
Definition: event_trigger.c:83
AttrNumber get_object_attnum_namespace(Oid class_id)
const char * objidentity
Definition: event_trigger.c:81
unsigned int Oid
Definition: postgres_ext.h:31
ObjectClass getObjectClass(const ObjectAddress *object)
Definition: dependency.c:2728
const char * objecttype
Definition: event_trigger.c:82
static EventTriggerQueryState * currentEventTriggerState
Definition: event_trigger.c:73
#define DatumGetName(X)
Definition: postgres.h:585
void pfree(void *pointer)
Definition: mcxt.c:1056
char * get_namespace_name(Oid nspid)
Definition: lsyscache.c:3155
bool isTempNamespace(Oid namespaceId)
Definition: namespace.c:3157
bool EventTriggerSupportsObjectClass(ObjectClass objclass)
const char * schemaname
Definition: event_trigger.c:79
#define heap_getattr(tup, attnum, tupleDesc, isnull)
Definition: htup_details.h:762
AttrNumber get_object_attnum_name(Oid class_id)
void * palloc0(Size size)
Definition: mcxt.c:980
HeapTuple get_catalog_object_by_oid(Relation catalog, AttrNumber oidcol, Oid objectId)
uintptr_t Datum
Definition: postgres.h:367
int16 attnum
Definition: pg_attribute.h:79
#define Assert(condition)
Definition: c.h:738
#define InvalidAttrNumber
Definition: attnum.h:23
#define NameStr(name)
Definition: c.h:615
bool isAnyTempNamespace(Oid namespaceId)
Definition: namespace.c:3195
bool is_objectclass_supported(Oid class_id)
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:39
int16 AttrNumber
Definition: attnum.h:21

◆ EventTriggerSupportsObjectClass()

bool EventTriggerSupportsObjectClass ( ObjectClass  objclass)

Definition at line 1032 of file event_trigger.c.

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_POLICY, OCLASS_PROC, OCLASS_PUBLICATION, 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().

1033 {
1034  switch (objclass)
1035  {
1036  case OCLASS_DATABASE:
1037  case OCLASS_TBLSPACE:
1038  case OCLASS_ROLE:
1039  /* no support for global objects */
1040  return false;
1041  case OCLASS_EVENT_TRIGGER:
1042  /* no support for event triggers on event triggers */
1043  return false;
1044  case OCLASS_CLASS:
1045  case OCLASS_PROC:
1046  case OCLASS_TYPE:
1047  case OCLASS_CAST:
1048  case OCLASS_COLLATION:
1049  case OCLASS_CONSTRAINT:
1050  case OCLASS_CONVERSION:
1051  case OCLASS_DEFAULT:
1052  case OCLASS_LANGUAGE:
1053  case OCLASS_LARGEOBJECT:
1054  case OCLASS_OPERATOR:
1055  case OCLASS_OPCLASS:
1056  case OCLASS_OPFAMILY:
1057  case OCLASS_AM:
1058  case OCLASS_AMOP:
1059  case OCLASS_AMPROC:
1060  case OCLASS_REWRITE:
1061  case OCLASS_TRIGGER:
1062  case OCLASS_SCHEMA:
1063  case OCLASS_STATISTIC_EXT:
1064  case OCLASS_TSPARSER:
1065  case OCLASS_TSDICT:
1066  case OCLASS_TSTEMPLATE:
1067  case OCLASS_TSCONFIG:
1068  case OCLASS_FDW:
1069  case OCLASS_FOREIGN_SERVER:
1070  case OCLASS_USER_MAPPING:
1071  case OCLASS_DEFACL:
1072  case OCLASS_EXTENSION:
1073  case OCLASS_POLICY:
1074  case OCLASS_PUBLICATION:
1076  case OCLASS_SUBSCRIPTION:
1077  case OCLASS_TRANSFORM:
1078  return true;
1079 
1080  /*
1081  * There's intentionally no default: case here; we want the
1082  * compiler to warn if a new OCLASS hasn't been handled above.
1083  */
1084  }
1085 
1086  /* Shouldn't get here, but if we do, say "no support" */
1087  return false;
1088 }

◆ EventTriggerSupportsObjectType()

bool EventTriggerSupportsObjectType ( ObjectType  obtype)

Definition at line 958 of file event_trigger.c.

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_POLICY, OBJECT_PROCEDURE, OBJECT_PUBLICATION, 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().

959 {
960  switch (obtype)
961  {
962  case OBJECT_DATABASE:
963  case OBJECT_TABLESPACE:
964  case OBJECT_ROLE:
965  /* no support for global objects */
966  return false;
968  /* no support for event triggers on event triggers */
969  return false;
971  case OBJECT_AGGREGATE:
972  case OBJECT_AMOP:
973  case OBJECT_AMPROC:
974  case OBJECT_ATTRIBUTE:
975  case OBJECT_CAST:
976  case OBJECT_COLUMN:
977  case OBJECT_COLLATION:
978  case OBJECT_CONVERSION:
979  case OBJECT_DEFACL:
980  case OBJECT_DEFAULT:
981  case OBJECT_DOMAIN:
983  case OBJECT_EXTENSION:
984  case OBJECT_FDW:
987  case OBJECT_FUNCTION:
988  case OBJECT_INDEX:
989  case OBJECT_LANGUAGE:
990  case OBJECT_LARGEOBJECT:
991  case OBJECT_MATVIEW:
992  case OBJECT_OPCLASS:
993  case OBJECT_OPERATOR:
994  case OBJECT_OPFAMILY:
995  case OBJECT_POLICY:
996  case OBJECT_PROCEDURE:
997  case OBJECT_PUBLICATION:
999  case OBJECT_ROUTINE:
1000  case OBJECT_RULE:
1001  case OBJECT_SCHEMA:
1002  case OBJECT_SEQUENCE:
1003  case OBJECT_SUBSCRIPTION:
1004  case OBJECT_STATISTIC_EXT:
1005  case OBJECT_TABCONSTRAINT:
1006  case OBJECT_TABLE:
1007  case OBJECT_TRANSFORM:
1008  case OBJECT_TRIGGER:
1010  case OBJECT_TSDICTIONARY:
1011  case OBJECT_TSPARSER:
1012  case OBJECT_TSTEMPLATE:
1013  case OBJECT_TYPE:
1014  case OBJECT_USER_MAPPING:
1015  case OBJECT_VIEW:
1016  return true;
1017 
1018  /*
1019  * There's intentionally no default: case here; we want the
1020  * compiler to warn if a new ObjectType hasn't been handled above.
1021  */
1022  }
1023 
1024  /* Shouldn't get here, but if we do, say "no support" */
1025  return false;
1026 }

◆ EventTriggerTableRewrite()

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

Definition at line 830 of file event_trigger.c.

References CommandCounterIncrement(), 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().

831 {
832  List *runlist;
833  EventTriggerData trigdata;
834 
835  /*
836  * See EventTriggerDDLCommandStart for a discussion about why event
837  * triggers are disabled in single user mode.
838  */
839  if (!IsUnderPostmaster)
840  return;
841 
842  /*
843  * Also do nothing if our state isn't set up, which it won't be if there
844  * weren't any relevant event triggers at the start of the current DDL
845  * command. This test might therefore seem optional, but it's
846  * *necessary*, because EventTriggerCommonSetup might find triggers that
847  * didn't exist at the time the command started.
848  */
850  return;
851 
852  runlist = EventTriggerCommonSetup(parsetree,
854  "table_rewrite",
855  &trigdata);
856  if (runlist == NIL)
857  return;
858 
859  /*
860  * Make sure pg_event_trigger_table_rewrite_oid only works when running
861  * these triggers. Use PG_TRY to ensure table_rewrite_oid is reset even
862  * when one trigger fails. (This is perhaps not necessary, as the
863  * currentState variable will be removed shortly by our caller, but it
864  * seems better to play safe.)
865  */
868 
869  /* Run the triggers. */
870  PG_TRY();
871  {
872  EventTriggerInvoke(runlist, &trigdata);
873  }
874  PG_FINALLY();
875  {
878  }
879  PG_END_TRY();
880 
881  /* Cleanup. */
882  list_free(runlist);
883 
884  /*
885  * Make sure anything the event triggers did will be visible to the main
886  * command.
887  */
889 }
#define NIL
Definition: pg_list.h:65
static void EventTriggerInvoke(List *fn_oid_list, EventTriggerData *trigdata)
static EventTriggerQueryState * currentEventTriggerState
Definition: event_trigger.c:73
static List * EventTriggerCommonSetup(Node *parsetree, EventTriggerEvent event, const char *eventstr, EventTriggerData *trigdata)
bool IsUnderPostmaster
Definition: globals.c:109
#define PG_FINALLY()
Definition: elog.h:312
void CommandCounterIncrement(void)
Definition: xact.c:1006
#define InvalidOid
Definition: postgres_ext.h:36
void list_free(List *list)
Definition: list.c:1376
#define PG_TRY()
Definition: elog.h:295
Definition: pg_list.h:50
#define PG_END_TRY()
Definition: elog.h:320

◆ EventTriggerUndoInhibitCommandCollection()

void EventTriggerUndoInhibitCommandCollection ( void  )

Definition at line 1509 of file event_trigger.c.

References EventTriggerQueryState::commandCollectionInhibited.

Referenced by ProcessUtilitySlow().

1510 {
1512  return;
1513 
1515 }
static EventTriggerQueryState * currentEventTriggerState
Definition: event_trigger.c:73

◆ filter_event_trigger()

static bool filter_event_trigger ( CommandTag  tag,
EventTriggerCacheItem item 
)
static

Definition at line 547 of file event_trigger.c.

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().

548 {
549  /*
550  * Filter by session replication role, knowing that we never see disabled
551  * items down here.
552  */
554  {
555  if (item->enabled == TRIGGER_FIRES_ON_ORIGIN)
556  return false;
557  }
558  else
559  {
560  if (item->enabled == TRIGGER_FIRES_ON_REPLICA)
561  return false;
562  }
563 
564  /* Filter by tags, if any were specified. */
565  if (!bms_is_empty(item->tagset) && !bms_is_member(tag, item->tagset))
566  return false;
567 
568  /* if we reach that point, we're not filtering out this item */
569  return true;
570 }
#define TRIGGER_FIRES_ON_ORIGIN
Definition: trigger.h:156
int SessionReplicationRole
Definition: trigger.c:67
bool bms_is_empty(const Bitmapset *a)
Definition: bitmapset.c:701
#define SESSION_REPLICATION_ROLE_REPLICA
Definition: trigger.h:148
#define TRIGGER_FIRES_ON_REPLICA
Definition: trigger.h:158
Bitmapset * tagset
Definition: evtcache.h:32
bool bms_is_member(int x, const Bitmapset *a)
Definition: bitmapset.c:427

◆ filter_list_to_array()

static Datum filter_list_to_array ( List filterlist)
static

Definition at line 332 of file event_trigger.c.

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

Referenced by insert_event_trigger_tuple().

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 }
#define PointerGetDatum(X)
Definition: postgres.h:556
char * pstrdup(const char *in)
Definition: mcxt.c:1186
ArrayType * construct_array(Datum *elems, int nelems, Oid elmtype, int elmlen, bool elmbyval, char elmalign)
Definition: arrayfuncs.c:3292
#define strVal(v)
Definition: value.h:54
unsigned char pg_ascii_toupper(unsigned char ch)
Definition: pgstrcasecmp.c:135
void pfree(void *pointer)
Definition: mcxt.c:1056
uintptr_t Datum
Definition: postgres.h:367
static struct @143 value
text * cstring_to_text(const char *s)
Definition: varlena.c:172
#define lfirst(lc)
Definition: pg_list.h:190
static int list_length(const List *l)
Definition: pg_list.h:169
void * palloc(Size size)
Definition: mcxt.c:949
int i

◆ get_event_trigger_oid()

Oid get_event_trigger_oid ( const char *  trigname,
bool  missing_ok 
)

Definition at line 528 of file event_trigger.c.

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

Referenced by get_object_address_unqualified().

529 {
530  Oid oid;
531 
532  oid = GetSysCacheOid1(EVENTTRIGGERNAME, Anum_pg_event_trigger_oid,
533  CStringGetDatum(trigname));
534  if (!OidIsValid(oid) && !missing_ok)
535  ereport(ERROR,
536  (errcode(ERRCODE_UNDEFINED_OBJECT),
537  errmsg("event trigger \"%s\" does not exist", trigname)));
538  return oid;
539 }
#define GetSysCacheOid1(cacheId, oidcol, key1)
Definition: syscache.h:192
int errcode(int sqlerrcode)
Definition: elog.c:610
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:644
#define ERROR
Definition: elog.h:43
#define CStringGetDatum(X)
Definition: postgres.h:578
#define ereport(elevel,...)
Definition: elog.h:144
int errmsg(const char *fmt,...)
Definition: elog.c:824

◆ 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.

References CatalogTupleInsert(), CharGetDatum, ObjectAddress::classId, DEPENDENCY_NORMAL, EventTriggerOidIndexId, 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().

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. */
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 }
#define NIL
Definition: pg_list.h:65
Oid GetNewOidWithIndex(Relation relation, Oid indexId, AttrNumber oidcolumn)
Definition: catalog.c:317
#define NameGetDatum(X)
Definition: postgres.h:595
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:133
#define InvokeObjectPostCreateHook(classId, objectId, subId)
Definition: objectaccess.h:151
void recordDependencyOn(const ObjectAddress *depender, const ObjectAddress *referenced, DependencyType behavior)
Definition: pg_depend.c:43
HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, Datum *values, bool *isnull)
Definition: heaptuple.c:1020
void recordDependencyOnOwner(Oid classId, Oid objectId, Oid owner)
Definition: pg_shdepend.c:164
void heap_freetuple(HeapTuple htup)
Definition: heaptuple.c:1338
unsigned int Oid
Definition: postgres_ext.h:31
int namestrcpy(Name name, const char *str)
Definition: name.c:250
#define TRIGGER_FIRES_ON_ORIGIN
Definition: trigger.h:156
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
static Datum filter_list_to_array(List *filterlist)
Definition: c.h:609
#define RowExclusiveLock
Definition: lockdefs.h:38
uintptr_t Datum
Definition: postgres.h:367
TupleDesc rd_att
Definition: rel.h:110
void recordDependencyOnCurrentExtension(const ObjectAddress *object, bool isReplace)
Definition: pg_depend.c:138
#define EventTriggerOidIndexId
Definition: indexing.h:260
#define CharGetDatum(X)
Definition: postgres.h:416
static Datum values[MAXATTR]
Definition: bootstrap.c:167
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:39
void CatalogTupleInsert(Relation heapRel, HeapTuple tup)
Definition: indexing.c:183

◆ pg_event_trigger_ddl_commands()

Datum pg_event_trigger_ddl_commands ( PG_FUNCTION_ARGS  )

Definition at line 1862 of file event_trigger.c.

References AccessShareLock, ReturnSetInfo::allowedModes, CollectedCommand::alterTable, CollectedCommand::atscfg, BoolGetDatum, ObjectAddress::classId, EventTriggerQueryState::commandList, CreateCommandName(), CollectedCommand::createopc, CStringGetTextDatum, CollectedCommand::d, CollectedCommand::defprivs, ReturnSetInfo::econtext, ExprContext::ecxt_per_query_memory, elog, ereport, errcode(), errmsg(), ERROR, get_call_result_type(), get_catalog_object_by_oid(), get_namespace_name(), get_object_attnum_namespace(), get_object_attnum_oid(), getObjectIdentity(), getObjectTypeDescription(), CollectedCommand::grant, heap_getattr, HeapTupleIsValid, i, CollectedCommand::in_extension, Int32GetDatum, InvalidAttrNumber, is_objectclass_supported(), IsA, isAnyTempNamespace(), lfirst, MemoryContextSwitchTo(), MemSet, ObjectAddressSet, ObjectAddress::objectId, ObjectIdGetDatum, ObjectAddress::objectSubId, OidIsValid, CollectedCommand::opfam, CollectedCommand::parsetree, PG_RETURN_VOID, PointerGetDatum, pstrdup(), RelationGetDescr, ReturnSetInfo::returnMode, SCT_AlterDefaultPrivileges, SCT_AlterOpFamily, SCT_AlterTable, SCT_AlterTSConfig, SCT_CreateOpClass, SCT_Grant, SCT_Simple, ReturnSetInfo::setDesc, ReturnSetInfo::setResult, SFRM_Materialize, CollectedCommand::simple, stringify_adefprivs_objtype(), stringify_grant_objtype(), table_close(), table_open(), tuplestore_begin_heap(), tuplestore_donestoring, tuplestore_putvalues(), CollectedCommand::type, generate_unaccent_rules::type, TYPEFUNC_COMPOSITE, values, and work_mem.

1863 {
1864  ReturnSetInfo *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo;
1865  TupleDesc tupdesc;
1866  Tuplestorestate *tupstore;
1867  MemoryContext per_query_ctx;
1868  MemoryContext oldcontext;
1869  ListCell *lc;
1870 
1871  /*
1872  * Protect this function from being called out of context
1873  */
1875  ereport(ERROR,
1876  (errcode(ERRCODE_E_R_I_E_EVENT_TRIGGER_PROTOCOL_VIOLATED),
1877  errmsg("%s can only be called in an event trigger function",
1878  "pg_event_trigger_ddl_commands()")));
1879 
1880  /* check to see if caller supports us returning a tuplestore */
1881  if (rsinfo == NULL || !IsA(rsinfo, ReturnSetInfo))
1882  ereport(ERROR,
1883  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1884  errmsg("set-valued function called in context that cannot accept a set")));
1885  if (!(rsinfo->allowedModes & SFRM_Materialize))
1886  ereport(ERROR,
1887  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1888  errmsg("materialize mode required, but it is not allowed in this context")));
1889 
1890  /* Build a tuple descriptor for our result type */
1891  if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
1892  elog(ERROR, "return type must be a row type");
1893 
1894  /* Build tuplestore to hold the result rows */
1895  per_query_ctx = rsinfo->econtext->ecxt_per_query_memory;
1896  oldcontext = MemoryContextSwitchTo(per_query_ctx);
1897 
1898  tupstore = tuplestore_begin_heap(true, false, work_mem);
1899  rsinfo->returnMode = SFRM_Materialize;
1900  rsinfo->setResult = tupstore;
1901  rsinfo->setDesc = tupdesc;
1902 
1903  MemoryContextSwitchTo(oldcontext);
1904 
1906  {
1907  CollectedCommand *cmd = lfirst(lc);
1908  Datum values[9];
1909  bool nulls[9];
1910  ObjectAddress addr;
1911  int i = 0;
1912 
1913  /*
1914  * For IF NOT EXISTS commands that attempt to create an existing
1915  * object, the returned OID is Invalid. Don't return anything.
1916  *
1917  * One might think that a viable alternative would be to look up the
1918  * Oid of the existing object and run the deparse with that. But
1919  * since the parse tree might be different from the one that created
1920  * the object in the first place, we might not end up in a consistent
1921  * state anyway.
1922  */
1923  if (cmd->type == SCT_Simple &&
1924  !OidIsValid(cmd->d.simple.address.objectId))
1925  continue;
1926 
1927  MemSet(nulls, 0, sizeof(nulls));
1928 
1929  switch (cmd->type)
1930  {
1931  case SCT_Simple:
1932  case SCT_AlterTable:
1933  case SCT_AlterOpFamily:
1934  case SCT_CreateOpClass:
1935  case SCT_AlterTSConfig:
1936  {
1937  char *identity;
1938  char *type;
1939  char *schema = NULL;
1940 
1941  if (cmd->type == SCT_Simple)
1942  addr = cmd->d.simple.address;
1943  else if (cmd->type == SCT_AlterTable)
1944  ObjectAddressSet(addr,
1945  cmd->d.alterTable.classId,
1946  cmd->d.alterTable.objectId);
1947  else if (cmd->type == SCT_AlterOpFamily)
1948  addr = cmd->d.opfam.address;
1949  else if (cmd->type == SCT_CreateOpClass)
1950  addr = cmd->d.createopc.address;
1951  else if (cmd->type == SCT_AlterTSConfig)
1952  addr = cmd->d.atscfg.address;
1953 
1954  type = getObjectTypeDescription(&addr);
1955  identity = getObjectIdentity(&addr);
1956 
1957  /*
1958  * Obtain schema name, if any ("pg_temp" if a temp
1959  * object). If the object class is not in the supported
1960  * list here, we assume it's a schema-less object type,
1961  * and thus "schema" remains set to NULL.
1962  */
1964  {
1965  AttrNumber nspAttnum;
1966 
1967  nspAttnum = get_object_attnum_namespace(addr.classId);
1968  if (nspAttnum != InvalidAttrNumber)
1969  {
1970  Relation catalog;
1971  HeapTuple objtup;
1972  Oid schema_oid;
1973  bool isnull;
1974 
1975  catalog = table_open(addr.classId, AccessShareLock);
1976  objtup = get_catalog_object_by_oid(catalog,
1978  addr.objectId);
1979  if (!HeapTupleIsValid(objtup))
1980  elog(ERROR, "cache lookup failed for object %u/%u",
1981  addr.classId, addr.objectId);
1982  schema_oid =
1983  heap_getattr(objtup, nspAttnum,
1984  RelationGetDescr(catalog), &isnull);
1985  if (isnull)
1986  elog(ERROR,
1987  "invalid null namespace in object %u/%u/%d",
1988  addr.classId, addr.objectId, addr.objectSubId);
1989  /* XXX not quite get_namespace_name_or_temp */
1990  if (isAnyTempNamespace(schema_oid))
1991  schema = pstrdup("pg_temp");
1992  else
1993  schema = get_namespace_name(schema_oid);
1994 
1995  table_close(catalog, AccessShareLock);
1996  }
1997  }
1998 
1999  /* classid */
2000  values[i++] = ObjectIdGetDatum(addr.classId);
2001  /* objid */
2002  values[i++] = ObjectIdGetDatum(addr.objectId);
2003  /* objsubid */
2004  values[i++] = Int32GetDatum(addr.objectSubId);
2005  /* command tag */
2006  values[i++] = CStringGetTextDatum(CreateCommandName(cmd->parsetree));
2007  /* object_type */
2008  values[i++] = CStringGetTextDatum(type);
2009  /* schema */
2010  if (schema == NULL)
2011  nulls[i++] = true;
2012  else
2013  values[i++] = CStringGetTextDatum(schema);
2014  /* identity */
2015  values[i++] = CStringGetTextDatum(identity);
2016  /* in_extension */
2017  values[i++] = BoolGetDatum(cmd->in_extension);
2018  /* command */
2019  values[i++] = PointerGetDatum(cmd);
2020  }
2021  break;
2022 
2024  /* classid */
2025  nulls[i++] = true;
2026  /* objid */
2027  nulls[i++] = true;
2028  /* objsubid */
2029  nulls[i++] = true;
2030  /* command tag */
2031  values[i++] = CStringGetTextDatum(CreateCommandName(cmd->parsetree));
2032  /* object_type */
2033  values[i++] = CStringGetTextDatum(stringify_adefprivs_objtype(cmd->d.defprivs.objtype));
2034  /* schema */
2035  nulls[i++] = true;
2036  /* identity */
2037  nulls[i++] = true;
2038  /* in_extension */
2039  values[i++] = BoolGetDatum(cmd->in_extension);
2040  /* command */
2041  values[i++] = PointerGetDatum(cmd);
2042  break;
2043 
2044  case SCT_Grant:
2045  /* classid */
2046  nulls[i++] = true;
2047  /* objid */
2048  nulls[i++] = true;
2049  /* objsubid */
2050  nulls[i++] = true;
2051  /* command tag */
2052  values[i++] = CStringGetTextDatum(cmd->d.grant.istmt->is_grant ?
2053  "GRANT" : "REVOKE");
2054  /* object_type */
2055  values[i++] = CStringGetTextDatum(stringify_grant_objtype(cmd->d.grant.istmt->objtype));
2056  /* schema */
2057  nulls[i++] = true;
2058  /* identity */
2059  nulls[i++] = true;
2060  /* in_extension */
2061  values[i++] = BoolGetDatum(cmd->in_extension);
2062  /* command */
2063  values[i++] = PointerGetDatum(cmd);
2064  break;
2065  }
2066 
2067  tuplestore_putvalues(tupstore, tupdesc, values, nulls);
2068  }
2069 
2070  /* clean up and return the tuplestore */
2071  tuplestore_donestoring(tupstore);
2072 
2073  PG_RETURN_VOID();
2074 }
void tuplestore_putvalues(Tuplestorestate *state, TupleDesc tdesc, Datum *values, bool *isnull)
Definition: tuplestore.c:750
#define IsA(nodeptr, _type_)
Definition: nodes.h:580
TypeFuncClass get_call_result_type(FunctionCallInfo fcinfo, Oid *resultTypeId, TupleDesc *resultTupleDesc)
Definition: funcapi.c:205
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:133
struct CollectedCommand::@109::@113 opfam
char * getObjectTypeDescription(const ObjectAddress *object)
AttrNumber get_object_attnum_oid(Oid class_id)
#define RelationGetDescr(relation)
Definition: rel.h:482
#define PointerGetDatum(X)
Definition: postgres.h:556
static const char * CreateCommandName(Node *parsetree)
Definition: utility.h:99
char * pstrdup(const char *in)
Definition: mcxt.c:1186
#define tuplestore_donestoring(state)
Definition: tuplestore.h:60
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
#define AccessShareLock
Definition: lockdefs.h:36
int errcode(int sqlerrcode)
Definition: elog.c:610
#define MemSet(start, val, len)
Definition: c.h:971
struct CollectedCommand::@109::@111 alterTable
AttrNumber get_object_attnum_namespace(Oid class_id)
CollectedCommandType type
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:644
static EventTriggerQueryState * currentEventTriggerState
Definition: event_trigger.c:73
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
char * getObjectIdentity(const ObjectAddress *object)
char * get_namespace_name(Oid nspid)
Definition: lsyscache.c:3155
struct CollectedCommand::@109::@112 grant
union CollectedCommand::@109 d
struct CollectedCommand::@109::@110 simple
#define heap_getattr(tup, attnum, tupleDesc, isnull)
Definition: htup_details.h:762
Tuplestorestate * tuplestore_begin_heap(bool randomAccess, bool interXact, int maxKBytes)
Definition: tuplestore.c:318
HeapTuple get_catalog_object_by_oid(Relation catalog, AttrNumber oidcol, Oid objectId)
uintptr_t Datum
Definition: postgres.h:367
int work_mem
Definition: globals.c:121
static const char * stringify_adefprivs_objtype(ObjectType objtype)
#define BoolGetDatum(X)
Definition: postgres.h:402
#define ereport(elevel,...)
Definition: elog.h:144
int allowedModes
Definition: execnodes.h:305
#define PG_RETURN_VOID()
Definition: fmgr.h:348
SetFunctionReturnMode returnMode
Definition: execnodes.h:307
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
struct CollectedCommand::@109::@116 defprivs
#define lfirst(lc)
Definition: pg_list.h:190
struct CollectedCommand::@109::@114 createopc
struct CollectedCommand::@109::@115 atscfg
MemoryContext ecxt_per_query_memory
Definition: execnodes.h:233
#define InvalidAttrNumber
Definition: attnum.h:23
#define ObjectAddressSet(addr, class_id, object_id)
Definition: objectaddress.h:40
Tuplestorestate * setResult
Definition: execnodes.h:310
static Datum values[MAXATTR]
Definition: bootstrap.c:167
ExprContext * econtext
Definition: execnodes.h:303
#define Int32GetDatum(X)
Definition: postgres.h:479
TupleDesc setDesc
Definition: execnodes.h:311
int errmsg(const char *fmt,...)
Definition: elog.c:824
#define elog(elevel,...)
Definition: elog.h:214
int i
#define CStringGetTextDatum(s)
Definition: builtins.h:87
bool isAnyTempNamespace(Oid namespaceId)
Definition: namespace.c:3195
bool is_objectclass_supported(Oid class_id)
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:39
static const char * stringify_grant_objtype(ObjectType objtype)
int16 AttrNumber
Definition: attnum.h:21

◆ pg_event_trigger_dropped_objects()

Datum pg_event_trigger_dropped_objects ( PG_FUNCTION_ARGS  )

Definition at line 1309 of file event_trigger.c.

References SQLDropObject::addrargs, SQLDropObject::address, SQLDropObject::addrnames, ReturnSetInfo::allowedModes, BoolGetDatum, ObjectAddress::classId, construct_empty_array(), CStringGetTextDatum, ReturnSetInfo::econtext, ExprContext::ecxt_per_query_memory, elog, ereport, errcode(), errmsg(), ERROR, get_call_result_type(), i, EventTriggerQueryState::in_sql_drop, Int32GetDatum, IsA, SQLDropObject::istemp, MemoryContextSwitchTo(), MemSet, next, SQLDropObject::normal, ObjectAddress::objectId, ObjectIdGetDatum, ObjectAddress::objectSubId, SQLDropObject::objecttype, SQLDropObject::objidentity, SQLDropObject::objname, SQLDropObject::original, PointerGetDatum, ReturnSetInfo::returnMode, SQLDropObject::schemaname, ReturnSetInfo::setDesc, ReturnSetInfo::setResult, SFRM_Materialize, slist_container, slist_foreach, EventTriggerQueryState::SQLDropList, strlist_to_textarray(), tuplestore_begin_heap(), tuplestore_donestoring, tuplestore_putvalues(), TYPEFUNC_COMPOSITE, values, and work_mem.

1310 {
1311  ReturnSetInfo *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo;
1312  TupleDesc tupdesc;
1313  Tuplestorestate *tupstore;
1314  MemoryContext per_query_ctx;
1315  MemoryContext oldcontext;
1316  slist_iter iter;
1317 
1318  /*
1319  * Protect this function from being called out of context
1320  */
1321  if (!currentEventTriggerState ||
1323  ereport(ERROR,
1324  (errcode(ERRCODE_E_R_I_E_EVENT_TRIGGER_PROTOCOL_VIOLATED),
1325  errmsg("%s can only be called in a sql_drop event trigger function",
1326  "pg_event_trigger_dropped_objects()")));
1327 
1328  /* check to see if caller supports us returning a tuplestore */
1329  if (rsinfo == NULL || !IsA(rsinfo, ReturnSetInfo))
1330  ereport(ERROR,
1331  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1332  errmsg("set-valued function called in context that cannot accept a set")));
1333  if (!(rsinfo->allowedModes & SFRM_Materialize))
1334  ereport(ERROR,
1335  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1336  errmsg("materialize mode required, but it is not allowed in this context")));
1337 
1338  /* Build a tuple descriptor for our result type */
1339  if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
1340  elog(ERROR, "return type must be a row type");
1341 
1342  /* Build tuplestore to hold the result rows */
1343  per_query_ctx = rsinfo->econtext->ecxt_per_query_memory;
1344  oldcontext = MemoryContextSwitchTo(per_query_ctx);
1345 
1346  tupstore = tuplestore_begin_heap(true, false, work_mem);
1347  rsinfo->returnMode = SFRM_Materialize;
1348  rsinfo->setResult = tupstore;
1349  rsinfo->setDesc = tupdesc;
1350 
1351  MemoryContextSwitchTo(oldcontext);
1352 
1354  {
1355  SQLDropObject *obj;
1356  int i = 0;
1357  Datum values[12];
1358  bool nulls[12];
1359 
1360  obj = slist_container(SQLDropObject, next, iter.cur);
1361 
1362  MemSet(values, 0, sizeof(values));
1363  MemSet(nulls, 0, sizeof(nulls));
1364 
1365  /* classid */
1366  values[i++] = ObjectIdGetDatum(obj->address.classId);
1367 
1368  /* objid */
1369  values[i++] = ObjectIdGetDatum(obj->address.objectId);
1370 
1371  /* objsubid */
1372  values[i++] = Int32GetDatum(obj->address.objectSubId);
1373 
1374  /* original */
1375  values[i++] = BoolGetDatum(obj->original);
1376 
1377  /* normal */
1378  values[i++] = BoolGetDatum(obj->normal);
1379 
1380  /* is_temporary */
1381  values[i++] = BoolGetDatum(obj->istemp);
1382 
1383  /* object_type */
1384  values[i++] = CStringGetTextDatum(obj->objecttype);
1385 
1386  /* schema_name */
1387  if (obj->schemaname)
1388  values[i++] = CStringGetTextDatum(obj->schemaname);
1389  else
1390  nulls[i++] = true;
1391 
1392  /* object_name */
1393  if (obj->objname)
1394  values[i++] = CStringGetTextDatum(obj->objname);
1395  else
1396  nulls[i++] = true;
1397 
1398  /* object_identity */
1399  if (obj->objidentity)
1400  values[i++] = CStringGetTextDatum(obj->objidentity);
1401  else
1402  nulls[i++] = true;
1403 
1404  /* address_names and address_args */
1405  if (obj->addrnames)
1406  {
1407  values[i++] = PointerGetDatum(strlist_to_textarray(obj->addrnames));
1408 
1409  if (obj->addrargs)
1410  values[i++] = PointerGetDatum(strlist_to_textarray(obj->addrargs));
1411  else
1412  values[i++] = PointerGetDatum(construct_empty_array(TEXTOID));
1413  }
1414  else
1415  {
1416  nulls[i++] = true;
1417  nulls[i++] = true;
1418  }
1419 
1420  tuplestore_putvalues(tupstore, tupdesc, values, nulls);
1421  }
1422 
1423  /* clean up and return the tuplestore */
1424  tuplestore_donestoring(tupstore);
1425 
1426  return (Datum) 0;
1427 }
void tuplestore_putvalues(Tuplestorestate *state, TupleDesc tdesc, Datum *values, bool *isnull)
Definition: tuplestore.c:750
#define IsA(nodeptr, _type_)
Definition: nodes.h:580
TypeFuncClass get_call_result_type(FunctionCallInfo fcinfo, Oid *resultTypeId, TupleDesc *resultTupleDesc)
Definition: funcapi.c:205
static int32 next
Definition: blutils.c:218
ObjectAddress address
Definition: event_trigger.c:78
#define PointerGetDatum(X)
Definition: postgres.h:556
const char * objname
Definition: event_trigger.c:80
#define tuplestore_donestoring(state)
Definition: tuplestore.h:60
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
List * addrnames
Definition: event_trigger.c:83
int errcode(int sqlerrcode)
Definition: elog.c:610
#define MemSet(start, val, len)
Definition: c.h:971
const char * objidentity
Definition: event_trigger.c:81
ArrayType * construct_empty_array(Oid elmtype)
Definition: arrayfuncs.c:3411
const char * objecttype
Definition: event_trigger.c:82
static EventTriggerQueryState * currentEventTriggerState
Definition: event_trigger.c:73
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
const char * schemaname
Definition: event_trigger.c:79
Tuplestorestate * tuplestore_begin_heap(bool randomAccess, bool interXact, int maxKBytes)
Definition: tuplestore.c:318
#define slist_container(type, membername, ptr)
Definition: ilist.h:674
uintptr_t Datum
Definition: postgres.h:367
int work_mem
Definition: globals.c:121
#define BoolGetDatum(X)
Definition: postgres.h:402
#define ereport(elevel,...)
Definition: elog.h:144
int allowedModes
Definition: execnodes.h:305
SetFunctionReturnMode returnMode
Definition: execnodes.h:307
MemoryContext ecxt_per_query_memory
Definition: execnodes.h:233
Tuplestorestate * setResult
Definition: execnodes.h:310
static Datum values[MAXATTR]
Definition: bootstrap.c:167
ExprContext * econtext
Definition: execnodes.h:303
#define slist_foreach(iter, lhead)
Definition: ilist.h:700
#define Int32GetDatum(X)
Definition: postgres.h:479
TupleDesc setDesc
Definition: execnodes.h:311
int errmsg(const char *fmt,...)
Definition: elog.c:824
#define elog(elevel,...)
Definition: elog.h:214
int i
#define CStringGetTextDatum(s)
Definition: builtins.h:87
ArrayType * strlist_to_textarray(List *list)

◆ pg_event_trigger_table_rewrite_oid()

Datum pg_event_trigger_table_rewrite_oid ( PG_FUNCTION_ARGS  )

Definition at line 1436 of file event_trigger.c.

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

1437 {
1438  /*
1439  * Protect this function from being called out of context
1440  */
1441  if (!currentEventTriggerState ||
1443  ereport(ERROR,
1444  (errcode(ERRCODE_E_R_I_E_EVENT_TRIGGER_PROTOCOL_VIOLATED),
1445  errmsg("%s can only be called in a table_rewrite event trigger function",
1446  "pg_event_trigger_table_rewrite_oid()")));
1447 
1449 }
int errcode(int sqlerrcode)
Definition: elog.c:610
static EventTriggerQueryState * currentEventTriggerState
Definition: event_trigger.c:73
#define ERROR
Definition: elog.h:43
#define InvalidOid
Definition: postgres_ext.h:36
#define ereport(elevel,...)
Definition: elog.h:144
int errmsg(const char *fmt,...)
Definition: elog.c:824
#define PG_RETURN_OID(x)
Definition: fmgr.h:359

◆ pg_event_trigger_table_rewrite_reason()

Datum pg_event_trigger_table_rewrite_reason ( PG_FUNCTION_ARGS  )

Definition at line 1457 of file event_trigger.c.

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

1458 {
1459  /*
1460  * Protect this function from being called out of context
1461  */
1462  if (!currentEventTriggerState ||
1464  ereport(ERROR,
1465  (errcode(ERRCODE_E_R_I_E_EVENT_TRIGGER_PROTOCOL_VIOLATED),
1466  errmsg("%s can only be called in a table_rewrite event trigger function",
1467  "pg_event_trigger_table_rewrite_reason()")));
1468 
1470 }
#define PG_RETURN_INT32(x)
Definition: fmgr.h:353
int errcode(int sqlerrcode)
Definition: elog.c:610
static EventTriggerQueryState * currentEventTriggerState
Definition: event_trigger.c:73
#define ERROR
Definition: elog.h:43
#define ereport(elevel,...)
Definition: elog.h:144
int errmsg(const char *fmt,...)
Definition: elog.c:824

◆ RemoveEventTriggerById()

void RemoveEventTriggerById ( Oid  trigOid)

Definition at line 362 of file event_trigger.c.

References CatalogTupleDelete(), elog, ERROR, EVENTTRIGGEROID, HeapTupleIsValid, ObjectIdGetDatum, ReleaseSysCache(), RowExclusiveLock, SearchSysCache1(), HeapTupleData::t_self, table_close(), and table_open().

Referenced by doDeletion().

363 {
364  Relation tgrel;
365  HeapTuple tup;
366 
367  tgrel = table_open(EventTriggerRelationId, RowExclusiveLock);
368 
370  if (!HeapTupleIsValid(tup))
371  elog(ERROR, "cache lookup failed for event trigger %u", trigOid);
372 
373  CatalogTupleDelete(tgrel, &tup->t_self);
374 
375  ReleaseSysCache(tup);
376 
378 }
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:133
void CatalogTupleDelete(Relation heapRel, ItemPointer tid)
Definition: indexing.c:269
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
ItemPointerData t_self
Definition: htup.h:65
#define RowExclusiveLock
Definition: lockdefs.h:38
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1116
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1164
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
#define elog(elevel,...)
Definition: elog.h:214
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:39

◆ stringify_adefprivs_objtype()

static const char * stringify_adefprivs_objtype ( ObjectType  objtype)
static

Definition at line 2163 of file event_trigger.c.

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_POLICY, OBJECT_PROCEDURE, OBJECT_PUBLICATION, 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().

2164 {
2165  switch (objtype)
2166  {
2167  case OBJECT_COLUMN:
2168  return "COLUMNS";
2169  case OBJECT_TABLE:
2170  return "TABLES";
2171  case OBJECT_SEQUENCE:
2172  return "SEQUENCES";
2173  case OBJECT_DATABASE:
2174  return "DATABASES";
2175  case OBJECT_DOMAIN:
2176  return "DOMAINS";
2177  case OBJECT_FDW:
2178  return "FOREIGN DATA WRAPPERS";
2179  case OBJECT_FOREIGN_SERVER:
2180  return "FOREIGN SERVERS";
2181  case OBJECT_FUNCTION:
2182  return "FUNCTIONS";
2183  case OBJECT_LANGUAGE:
2184  return "LANGUAGES";
2185  case OBJECT_LARGEOBJECT:
2186  return "LARGE OBJECTS";
2187  case OBJECT_SCHEMA:
2188  return "SCHEMAS";
2189  case OBJECT_PROCEDURE:
2190  return "PROCEDURES";
2191  case OBJECT_ROUTINE:
2192  return "ROUTINES";
2193  case OBJECT_TABLESPACE:
2194  return "TABLESPACES";
2195  case OBJECT_TYPE:
2196  return "TYPES";
2197  /* these currently aren't used */
2198  case OBJECT_ACCESS_METHOD:
2199  case OBJECT_AGGREGATE:
2200  case OBJECT_AMOP:
2201  case OBJECT_AMPROC:
2202  case OBJECT_ATTRIBUTE:
2203  case OBJECT_CAST:
2204  case OBJECT_COLLATION:
2205  case OBJECT_CONVERSION:
2206  case OBJECT_DEFAULT:
2207  case OBJECT_DEFACL:
2208  case OBJECT_DOMCONSTRAINT:
2209  case OBJECT_EVENT_TRIGGER:
2210  case OBJECT_EXTENSION:
2211  case OBJECT_FOREIGN_TABLE:
2212  case OBJECT_INDEX:
2213  case OBJECT_MATVIEW:
2214  case OBJECT_OPCLASS:
2215  case OBJECT_OPERATOR:
2216  case OBJECT_OPFAMILY:
2217  case OBJECT_POLICY:
2218  case OBJECT_PUBLICATION:
2220  case OBJECT_ROLE:
2221  case OBJECT_RULE:
2222  case OBJECT_STATISTIC_EXT:
2223  case OBJECT_SUBSCRIPTION:
2224  case OBJECT_TABCONSTRAINT:
2225  case OBJECT_TRANSFORM:
2226  case OBJECT_TRIGGER:
2228  case OBJECT_TSDICTIONARY:
2229  case OBJECT_TSPARSER:
2230  case OBJECT_TSTEMPLATE:
2231  case OBJECT_USER_MAPPING:
2232  case OBJECT_VIEW:
2233  elog(ERROR, "unsupported object type: %d", (int) objtype);
2234  }
2235 
2236  return "???"; /* keep compiler quiet */
2237 }
#define ERROR
Definition: elog.h:43
#define elog(elevel,...)
Definition: elog.h:214

◆ stringify_grant_objtype()

static const char * stringify_grant_objtype ( ObjectType  objtype)
static

Definition at line 2081 of file event_trigger.c.

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_POLICY, OBJECT_PROCEDURE, OBJECT_PUBLICATION, 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().

2082 {
2083  switch (objtype)
2084  {
2085  case OBJECT_COLUMN:
2086  return "COLUMN";
2087  case OBJECT_TABLE:
2088  return "TABLE";
2089  case OBJECT_SEQUENCE:
2090  return "SEQUENCE";
2091  case OBJECT_DATABASE:
2092  return "DATABASE";
2093  case OBJECT_DOMAIN:
2094  return "DOMAIN";
2095  case OBJECT_FDW:
2096  return "FOREIGN DATA WRAPPER";
2097  case OBJECT_FOREIGN_SERVER:
2098  return "FOREIGN SERVER";
2099  case OBJECT_FUNCTION:
2100  return "FUNCTION";
2101  case OBJECT_LANGUAGE:
2102  return "LANGUAGE";
2103  case OBJECT_LARGEOBJECT:
2104  return "LARGE OBJECT";
2105  case OBJECT_SCHEMA:
2106  return "SCHEMA";
2107  case OBJECT_PROCEDURE:
2108  return "PROCEDURE";
2109  case OBJECT_ROUTINE:
2110  return "ROUTINE";
2111  case OBJECT_TABLESPACE:
2112  return "TABLESPACE";
2113  case OBJECT_TYPE:
2114  return "TYPE";
2115  /* these currently aren't used */
2116  case OBJECT_ACCESS_METHOD:
2117  case OBJECT_AGGREGATE:
2118  case OBJECT_AMOP:
2119  case OBJECT_AMPROC:
2120  case OBJECT_ATTRIBUTE:
2121  case OBJECT_CAST:
2122  case OBJECT_COLLATION:
2123  case OBJECT_CONVERSION:
2124  case OBJECT_DEFAULT:
2125  case OBJECT_DEFACL:
2126  case OBJECT_DOMCONSTRAINT:
2127  case OBJECT_EVENT_TRIGGER:
2128  case OBJECT_EXTENSION:
2129  case OBJECT_FOREIGN_TABLE:
2130  case OBJECT_INDEX:
2131  case OBJECT_MATVIEW:
2132  case OBJECT_OPCLASS:
2133  case OBJECT_OPERATOR:
2134  case OBJECT_OPFAMILY:
2135  case OBJECT_POLICY:
2136  case OBJECT_PUBLICATION:
2138  case OBJECT_ROLE:
2139  case OBJECT_RULE:
2140  case OBJECT_STATISTIC_EXT:
2141  case OBJECT_SUBSCRIPTION:
2142  case OBJECT_TABCONSTRAINT:
2143  case OBJECT_TRANSFORM:
2144  case OBJECT_TRIGGER:
2146  case OBJECT_TSDICTIONARY:
2147  case OBJECT_TSPARSER:
2148  case OBJECT_TSTEMPLATE:
2149  case OBJECT_USER_MAPPING:
2150  case OBJECT_VIEW:
2151  elog(ERROR, "unsupported object type: %d", (int) objtype);
2152  }
2153 
2154  return "???"; /* keep compiler quiet */
2155 }
#define ERROR
Definition: elog.h:43
#define elog(elevel,...)
Definition: elog.h:214

◆ trackDroppedObjectsNeeded()

bool trackDroppedObjectsNeeded ( void  )

Definition at line 1159 of file event_trigger.c.

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

Referenced by deleteObjectsInList(), and EventTriggerBeginCompleteQuery().

1160 {
1161  /*
1162  * true if any sql_drop, table_rewrite, ddl_command_end event trigger
1163  * exists
1164  */
1165  return list_length(EventCacheLookup(EVT_SQLDrop)) > 0 ||
1168 }
static int list_length(const List *l)
Definition: pg_list.h:169
List * EventCacheLookup(EventTriggerEvent event)
Definition: evtcache.c:65

◆ validate_ddl_tags()

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

Definition at line 195 of file event_trigger.c.

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

Referenced by CreateEventTrigger().

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
Definition: cmdtag.h:20
#define strVal(v)
Definition: value.h:54
int errcode(int sqlerrcode)
Definition: elog.c:610
#define ERROR
Definition: elog.h:43
#define ereport(elevel,...)
Definition: elog.h:144
#define lfirst(lc)
Definition: pg_list.h:190
CommandTag GetCommandTagEnum(const char *commandname)
Definition: cmdtag.c:74
int errmsg(const char *fmt,...)
Definition: elog.c:824
bool command_tag_event_trigger_ok(CommandTag commandTag)
Definition: cmdtag.c:57

◆ 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.

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

Referenced by CreateEventTrigger().

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 }
CommandTag
Definition: cmdtag.h:20
#define strVal(v)
Definition: value.h:54
int errcode(int sqlerrcode)
Definition: elog.c:610
bool command_tag_table_rewrite_ok(CommandTag commandTag)
Definition: cmdtag.c:63
#define ERROR
Definition: elog.h:43
#define ereport(elevel,...)
Definition: elog.h:144
#define lfirst(lc)
Definition: pg_list.h:190
CommandTag GetCommandTagEnum(const char *commandname)
Definition: cmdtag.c:74
int errmsg(const char *fmt,...)
Definition: elog.c:824

Variable Documentation

◆ currentEventTriggerState

EventTriggerQueryState* currentEventTriggerState = NULL
static

Definition at line 73 of file event_trigger.c.

Referenced by EventTriggerBeginCompleteQuery().