PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
event_trigger.c File Reference
#include "postgres.h"
#include "access/htup_details.h"
#include "access/xact.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 "parser/parse_func.h"
#include "pgstat.h"
#include "lib/ilist.h"
#include "miscadmin.h"
#include "tcop/deparse_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/tqual.h"
#include "utils/syscache.h"
#include "tcop/utility.h"
Include dependency graph for event_trigger.c:

Go to the source code of this file.

Data Structures

struct  EventTriggerQueryState
 
struct  event_trigger_support_data
 
struct  SQLDropObject
 

Typedefs

typedef struct
EventTriggerQueryState 
EventTriggerQueryState
 
typedef struct SQLDropObject SQLDropObject
 

Enumerations

enum  event_trigger_command_tag_check_result { EVENT_TRIGGER_COMMAND_TAG_OK, EVENT_TRIGGER_COMMAND_TAG_NOT_SUPPORTED, EVENT_TRIGGER_COMMAND_TAG_NOT_RECOGNIZED }
 

Functions

static void AlterEventTriggerOwner_internal (Relation rel, HeapTuple tup, Oid newOwnerId)
 
static
event_trigger_command_tag_check_result 
check_ddl_tag (const char *tag)
 
static
event_trigger_command_tag_check_result 
check_table_rewrite_ddl_tag (const char *tag)
 
static void error_duplicate_filter_variable (const char *defname)
 
static Datum filter_list_to_array (List *filterlist)
 
static Oid insert_event_trigger_tuple (char *trigname, 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_grantobjtype (GrantObjectType objtype)
 
static const char * stringify_adefprivs_objtype (GrantObjectType 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 (const char **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 EventTriggerSupportsGrantObjectType (GrantObjectType objtype)
 
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
 
static event_trigger_support_data event_trigger_support []
 

Typedef Documentation

Enumeration Type Documentation

Enumerator
EVENT_TRIGGER_COMMAND_TAG_OK 
EVENT_TRIGGER_COMMAND_TAG_NOT_SUPPORTED 
EVENT_TRIGGER_COMMAND_TAG_NOT_RECOGNIZED 

Definition at line 80 of file event_trigger.c.

Function Documentation

Oid AlterEventTrigger ( AlterEventTrigStmt stmt)

Definition at line 499 of file event_trigger.c.

References ACL_KIND_EVENT_TRIGGER, aclcheck_error(), ACLCHECK_NOT_OWNER, CatalogTupleUpdate(), CStringGetDatum, ereport, errcode(), errmsg(), ERROR, EVENTTRIGGERNAME, EventTriggerRelationId, GETSTRUCT, GetUserId(), heap_close, heap_freetuple(), heap_open(), HeapTupleGetOid, HeapTupleIsValid, InvokeObjectPostAlterHook, pg_event_trigger_ownercheck(), RowExclusiveLock, SearchSysCacheCopy1, HeapTupleData::t_self, AlterEventTrigStmt::tgenabled, and AlterEventTrigStmt::trigname.

Referenced by standard_ProcessUtility().

500 {
501  Relation tgrel;
502  HeapTuple tup;
503  Oid trigoid;
504  Form_pg_event_trigger evtForm;
505  char tgenabled = stmt->tgenabled;
506 
508 
510  CStringGetDatum(stmt->trigname));
511  if (!HeapTupleIsValid(tup))
512  ereport(ERROR,
513  (errcode(ERRCODE_UNDEFINED_OBJECT),
514  errmsg("event trigger \"%s\" does not exist",
515  stmt->trigname)));
516 
517  trigoid = HeapTupleGetOid(tup);
518 
519  if (!pg_event_trigger_ownercheck(trigoid, GetUserId()))
521  stmt->trigname);
522 
523  /* tuple is a copy, so we can modify it below */
524  evtForm = (Form_pg_event_trigger) GETSTRUCT(tup);
525  evtForm->evtenabled = tgenabled;
526 
527  CatalogTupleUpdate(tgrel, &tup->t_self, tup);
528 
530  trigoid, 0);
531 
532  /* clean up */
533  heap_freetuple(tup);
535 
536  return trigoid;
537 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
Oid GetUserId(void)
Definition: miscinit.c:283
int errcode(int sqlerrcode)
Definition: elog.c:575
#define heap_close(r, l)
Definition: heapam.h:97
void heap_freetuple(HeapTuple htup)
Definition: heaptuple.c:1374
unsigned int Oid
Definition: postgres_ext.h:31
#define ERROR
Definition: elog.h:43
bool pg_event_trigger_ownercheck(Oid et_oid, Oid roleid)
Definition: aclchk.c:4920
ItemPointerData t_self
Definition: htup.h:65
void aclcheck_error(AclResult aclerr, AclObjectKind objectkind, const char *objectname)
Definition: aclchk.c:3382
#define RowExclusiveLock
Definition: lockdefs.h:38
#define CStringGetDatum(X)
Definition: postgres.h:584
#define ereport(elevel, rest)
Definition: elog.h:122
#define InvokeObjectPostAlterHook(classId, objectId, subId)
Definition: objectaccess.h:163
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1287
FormData_pg_event_trigger * Form_pg_event_trigger
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
#define EventTriggerRelationId
void CatalogTupleUpdate(Relation heapRel, ItemPointer otid, HeapTuple tup)
Definition: indexing.c:210
#define SearchSysCacheCopy1(cacheId, key1)
Definition: syscache.h:161
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define HeapTupleGetOid(tuple)
Definition: htup_details.h:695
ObjectAddress AlterEventTriggerOwner ( const char *  name,
Oid  newOwnerId 
)

Definition at line 543 of file event_trigger.c.

References AlterEventTriggerOwner_internal(), CStringGetDatum, ereport, errcode(), errmsg(), ERROR, EVENTTRIGGERNAME, EventTriggerRelationId, heap_close, heap_freetuple(), heap_open(), HeapTupleGetOid, HeapTupleIsValid, ObjectAddressSet, RowExclusiveLock, and SearchSysCacheCopy1.

Referenced by ExecAlterOwnerStmt().

544 {
545  Oid evtOid;
546  HeapTuple tup;
547  Relation rel;
548  ObjectAddress address;
549 
551 
553 
554  if (!HeapTupleIsValid(tup))
555  ereport(ERROR,
556  (errcode(ERRCODE_UNDEFINED_OBJECT),
557  errmsg("event trigger \"%s\" does not exist", name)));
558 
559  evtOid = HeapTupleGetOid(tup);
560 
561  AlterEventTriggerOwner_internal(rel, tup, newOwnerId);
562 
563  ObjectAddressSet(address, EventTriggerRelationId, evtOid);
564 
565  heap_freetuple(tup);
566 
568 
569  return address;
570 }
int errcode(int sqlerrcode)
Definition: elog.c:575
#define heap_close(r, l)
Definition: heapam.h:97
void heap_freetuple(HeapTuple htup)
Definition: heaptuple.c:1374
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:584
#define ereport(elevel, rest)
Definition: elog.h:122
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1287
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
#define EventTriggerRelationId
const char * name
Definition: encode.c:521
#define ObjectAddressSet(addr, class_id, object_id)
Definition: objectaddress.h:40
#define SearchSysCacheCopy1(cacheId, key1)
Definition: syscache.h:161
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define HeapTupleGetOid(tuple)
Definition: htup_details.h:695
static void AlterEventTriggerOwner_internal ( Relation  rel,
HeapTuple  tup,
Oid  newOwnerId 
)
static

Definition at line 601 of file event_trigger.c.

References ACL_KIND_EVENT_TRIGGER, aclcheck_error(), ACLCHECK_NOT_OWNER, CatalogTupleUpdate(), changeDependencyOnOwner(), ereport, errcode(), errhint(), errmsg(), ERROR, EventTriggerRelationId, GETSTRUCT, GetUserId(), HeapTupleGetOid, InvokeObjectPostAlterHook, NameStr, pg_event_trigger_ownercheck(), superuser_arg(), and HeapTupleData::t_self.

Referenced by AlterEventTriggerOwner(), and AlterEventTriggerOwner_oid().

602 {
604 
605  form = (Form_pg_event_trigger) GETSTRUCT(tup);
606 
607  if (form->evtowner == newOwnerId)
608  return;
609 
612  NameStr(form->evtname));
613 
614  /* New owner must be a superuser */
615  if (!superuser_arg(newOwnerId))
616  ereport(ERROR,
617  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
618  errmsg("permission denied to change owner of event trigger \"%s\"",
619  NameStr(form->evtname)),
620  errhint("The owner of an event trigger must be a superuser.")));
621 
622  form->evtowner = newOwnerId;
623  CatalogTupleUpdate(rel, &tup->t_self, tup);
624 
625  /* Update owner dependency reference */
627  HeapTupleGetOid(tup),
628  newOwnerId);
629 
631  HeapTupleGetOid(tup), 0);
632 }
int errhint(const char *fmt,...)
Definition: elog.c:987
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
Oid GetUserId(void)
Definition: miscinit.c:283
int errcode(int sqlerrcode)
Definition: elog.c:575
void changeDependencyOnOwner(Oid classId, Oid objectId, Oid newOwnerId)
Definition: pg_shdepend.c:304
#define ERROR
Definition: elog.h:43
bool pg_event_trigger_ownercheck(Oid et_oid, Oid roleid)
Definition: aclchk.c:4920
ItemPointerData t_self
Definition: htup.h:65
void aclcheck_error(AclResult aclerr, AclObjectKind objectkind, const char *objectname)
Definition: aclchk.c:3382
#define ereport(elevel, rest)
Definition: elog.h:122
#define InvokeObjectPostAlterHook(classId, objectId, subId)
Definition: objectaccess.h:163
bool superuser_arg(Oid roleid)
Definition: superuser.c:57
FormData_pg_event_trigger * Form_pg_event_trigger
#define EventTriggerRelationId
void CatalogTupleUpdate(Relation heapRel, ItemPointer otid, HeapTuple tup)
Definition: indexing.c:210
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define NameStr(name)
Definition: c.h:499
#define HeapTupleGetOid(tuple)
Definition: htup_details.h:695
void AlterEventTriggerOwner_oid ( Oid  trigOid,
Oid  newOwnerId 
)

Definition at line 576 of file event_trigger.c.

References AlterEventTriggerOwner_internal(), ereport, errcode(), errmsg(), ERROR, EVENTTRIGGEROID, EventTriggerRelationId, heap_close, heap_freetuple(), heap_open(), HeapTupleIsValid, ObjectIdGetDatum, RowExclusiveLock, and SearchSysCacheCopy1.

Referenced by shdepReassignOwned().

577 {
578  HeapTuple tup;
579  Relation rel;
580 
582 
584 
585  if (!HeapTupleIsValid(tup))
586  ereport(ERROR,
587  (errcode(ERRCODE_UNDEFINED_OBJECT),
588  errmsg("event trigger with OID %u does not exist", trigOid)));
589 
590  AlterEventTriggerOwner_internal(rel, tup, newOwnerId);
591 
592  heap_freetuple(tup);
593 
595 }
int errcode(int sqlerrcode)
Definition: elog.c:575
#define heap_close(r, l)
Definition: heapam.h:97
void heap_freetuple(HeapTuple htup)
Definition: heaptuple.c:1374
static void AlterEventTriggerOwner_internal(Relation rel, HeapTuple tup, Oid newOwnerId)
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define ERROR
Definition: elog.h:43
#define RowExclusiveLock
Definition: lockdefs.h:38
#define ereport(elevel, rest)
Definition: elog.h:122
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1287
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
#define EventTriggerRelationId
#define SearchSysCacheCopy1(cacheId, key1)
Definition: syscache.h:161
int errmsg(const char *fmt,...)
Definition: elog.c:797
static event_trigger_command_tag_check_result check_ddl_tag ( const char *  tag)
static

Definition at line 280 of file event_trigger.c.

References EVENT_TRIGGER_COMMAND_TAG_NOT_RECOGNIZED, EVENT_TRIGGER_COMMAND_TAG_NOT_SUPPORTED, EVENT_TRIGGER_COMMAND_TAG_OK, NULL, event_trigger_support_data::obtypename, pg_strcasecmp(), pg_strncasecmp(), and event_trigger_support_data::supported.

Referenced by EventTriggerCommonSetup(), and validate_ddl_tags().

281 {
282  const char *obtypename;
284 
285  /*
286  * Handle some idiosyncratic special cases.
287  */
288  if (pg_strcasecmp(tag, "CREATE TABLE AS") == 0 ||
289  pg_strcasecmp(tag, "SELECT INTO") == 0 ||
290  pg_strcasecmp(tag, "REFRESH MATERIALIZED VIEW") == 0 ||
291  pg_strcasecmp(tag, "ALTER DEFAULT PRIVILEGES") == 0 ||
292  pg_strcasecmp(tag, "ALTER LARGE OBJECT") == 0 ||
293  pg_strcasecmp(tag, "COMMENT") == 0 ||
294  pg_strcasecmp(tag, "GRANT") == 0 ||
295  pg_strcasecmp(tag, "REVOKE") == 0 ||
296  pg_strcasecmp(tag, "DROP OWNED") == 0 ||
297  pg_strcasecmp(tag, "IMPORT FOREIGN SCHEMA") == 0 ||
298  pg_strcasecmp(tag, "SECURITY LABEL") == 0)
300 
301  /*
302  * Otherwise, command should be CREATE, ALTER, or DROP.
303  */
304  if (pg_strncasecmp(tag, "CREATE ", 7) == 0)
305  obtypename = tag + 7;
306  else if (pg_strncasecmp(tag, "ALTER ", 6) == 0)
307  obtypename = tag + 6;
308  else if (pg_strncasecmp(tag, "DROP ", 5) == 0)
309  obtypename = tag + 5;
310  else
312 
313  /*
314  * ...and the object type should be something recognizable.
315  */
316  for (etsd = event_trigger_support; etsd->obtypename != NULL; etsd++)
317  if (pg_strcasecmp(etsd->obtypename, obtypename) == 0)
318  break;
319  if (etsd->obtypename == NULL)
321  if (!etsd->supported)
324 }
int pg_strcasecmp(const char *s1, const char *s2)
Definition: pgstrcasecmp.c:36
int pg_strncasecmp(const char *s1, const char *s2, size_t n)
Definition: pgstrcasecmp.c:69
static event_trigger_support_data event_trigger_support[]
Definition: event_trigger.c:88
#define NULL
Definition: c.h:229
static event_trigger_command_tag_check_result check_table_rewrite_ddl_tag ( const char *  tag)
static

Definition at line 350 of file event_trigger.c.

References EVENT_TRIGGER_COMMAND_TAG_NOT_SUPPORTED, EVENT_TRIGGER_COMMAND_TAG_OK, and pg_strcasecmp().

Referenced by EventTriggerCommonSetup(), and validate_table_rewrite_tags().

351 {
352  if (pg_strcasecmp(tag, "ALTER TABLE") == 0 ||
353  pg_strcasecmp(tag, "ALTER TYPE") == 0)
355 
357 }
int pg_strcasecmp(const char *s1, const char *s2)
Definition: pgstrcasecmp.c:36
Oid CreateEventTrigger ( CreateEventTrigStmt stmt)

Definition at line 167 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, EVTTRIGGEROID, CreateEventTrigStmt::funcname, get_func_rettype(), GetUserId(), HeapTupleIsValid, insert_event_trigger_tuple(), lfirst, LookupFuncName(), NameListToString(), NULL, SearchSysCache1, superuser(), CreateEventTrigStmt::trigname, validate_ddl_tags(), validate_table_rewrite_tags(), and CreateEventTrigStmt::whenclause.

Referenced by standard_ProcessUtility().

168 {
169  HeapTuple tuple;
170  Oid funcoid;
171  Oid funcrettype;
172  Oid fargtypes[1]; /* dummy */
173  Oid evtowner = GetUserId();
174  ListCell *lc;
175  List *tags = NULL;
176 
177  /*
178  * It would be nice to allow database owners or even regular users to do
179  * this, but there are obvious privilege escalation risks which would have
180  * to somehow be plugged first.
181  */
182  if (!superuser())
183  ereport(ERROR,
184  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
185  errmsg("permission denied to create event trigger \"%s\"",
186  stmt->trigname),
187  errhint("Must be superuser to create an event trigger.")));
188 
189  /* Validate event name. */
190  if (strcmp(stmt->eventname, "ddl_command_start") != 0 &&
191  strcmp(stmt->eventname, "ddl_command_end") != 0 &&
192  strcmp(stmt->eventname, "sql_drop") != 0 &&
193  strcmp(stmt->eventname, "table_rewrite") != 0)
194  ereport(ERROR,
195  (errcode(ERRCODE_SYNTAX_ERROR),
196  errmsg("unrecognized event name \"%s\"",
197  stmt->eventname)));
198 
199  /* Validate filter conditions. */
200  foreach(lc, stmt->whenclause)
201  {
202  DefElem *def = (DefElem *) lfirst(lc);
203 
204  if (strcmp(def->defname, "tag") == 0)
205  {
206  if (tags != NULL)
208  tags = (List *) def->arg;
209  }
210  else
211  ereport(ERROR,
212  (errcode(ERRCODE_SYNTAX_ERROR),
213  errmsg("unrecognized filter variable \"%s\"", def->defname)));
214  }
215 
216  /* Validate tag list, if any. */
217  if ((strcmp(stmt->eventname, "ddl_command_start") == 0 ||
218  strcmp(stmt->eventname, "ddl_command_end") == 0 ||
219  strcmp(stmt->eventname, "sql_drop") == 0)
220  && tags != NULL)
221  validate_ddl_tags("tag", tags);
222  else if (strcmp(stmt->eventname, "table_rewrite") == 0
223  && tags != NULL)
224  validate_table_rewrite_tags("tag", tags);
225 
226  /*
227  * Give user a nice error message if an event trigger of the same name
228  * already exists.
229  */
231  if (HeapTupleIsValid(tuple))
232  ereport(ERROR,
234  errmsg("event trigger \"%s\" already exists",
235  stmt->trigname)));
236 
237  /* Find and validate the trigger function. */
238  funcoid = LookupFuncName(stmt->funcname, 0, fargtypes, false);
239  funcrettype = get_func_rettype(funcoid);
240  if (funcrettype != EVTTRIGGEROID)
241  ereport(ERROR,
242  (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
243  errmsg("function %s must return type %s",
244  NameListToString(stmt->funcname), "event_trigger")));
245 
246  /* Insert catalog entries. */
247  return insert_event_trigger_tuple(stmt->trigname, stmt->eventname,
248  evtowner, funcoid, tags);
249 }
static void validate_ddl_tags(const char *filtervar, List *taglist)
int errhint(const char *fmt,...)
Definition: elog.c:987
Oid GetUserId(void)
Definition: miscinit.c:283
static Oid insert_event_trigger_tuple(char *trigname, char *eventname, Oid evtOwner, Oid funcoid, List *tags)
int errcode(int sqlerrcode)
Definition: elog.c:575
bool superuser(void)
Definition: superuser.c:47
unsigned int Oid
Definition: postgres_ext.h:31
#define SearchSysCache1(cacheId, key1)
Definition: syscache.h:152
Oid get_func_rettype(Oid funcid)
Definition: lsyscache.c:1427
#define ERROR
Definition: elog.h:43
static void validate_table_rewrite_tags(const char *filtervar, List *taglist)
static void error_duplicate_filter_variable(const char *defname)
#define CStringGetDatum(X)
Definition: postgres.h:584
#define ereport(elevel, rest)
Definition: elog.h:122
Node * arg
Definition: parsenodes.h:709
char * NameListToString(List *names)
Definition: namespace.c:2953
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
#define EVTTRIGGEROID
Definition: pg_type.h:690
#define NULL
Definition: c.h:229
#define lfirst(lc)
Definition: pg_list.h:106
Oid LookupFuncName(List *funcname, int nargs, const Oid *argtypes, bool noError)
Definition: parse_func.c:1910
int errmsg(const char *fmt,...)
Definition: elog.c:797
char * defname
Definition: parsenodes.h:708
#define ERRCODE_DUPLICATE_OBJECT
Definition: streamutil.c:31
Definition: pg_list.h:45
static void error_duplicate_filter_variable ( const char *  defname)
static

Definition at line 363 of file event_trigger.c.

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

Referenced by CreateEventTrigger().

364 {
365  ereport(ERROR,
366  (errcode(ERRCODE_SYNTAX_ERROR),
367  errmsg("filter variable \"%s\" specified more than once",
368  defname)));
369 }
int errcode(int sqlerrcode)
Definition: elog.c:575
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
int errmsg(const char *fmt,...)
Definition: elog.c:797
void EventTriggerAlterTableEnd ( void  )

Definition at line 1780 of file event_trigger.c.

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

Referenced by AlterTableMoveAll(), and ProcessUtilitySlow().

1781 {
1782  /* ignore if event trigger context not set, or collection disabled */
1783  if (!currentEventTriggerState ||
1785  return;
1786 
1787  /* If no subcommands, don't collect */
1789  {
1793  }
1794  else
1796 
1798 }
union CollectedCommand::@95 d
static EventTriggerQueryState * currentEventTriggerState
Definition: event_trigger.c:72
void pfree(void *pointer)
Definition: mcxt.c:950
CollectedCommand * currentCommand
Definition: event_trigger.c:66
struct CollectedCommand::@95::@97 alterTable
List * lappend(List *list, void *datum)
Definition: list.c:128
#define NULL
Definition: c.h:229
static int list_length(const List *l)
Definition: pg_list.h:89
void EventTriggerAlterTableRelid ( Oid  objectId)

Definition at line 1728 of file event_trigger.c.

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

Referenced by AlterTableInternal(), and ProcessUtilitySlow().

1729 {
1730  if (!currentEventTriggerState ||
1732  return;
1733 
1734  currentEventTriggerState->currentCommand->d.alterTable.objectId = objectId;
1735 }
union CollectedCommand::@95 d
static EventTriggerQueryState * currentEventTriggerState
Definition: event_trigger.c:72
CollectedCommand * currentCommand
Definition: event_trigger.c:66
struct CollectedCommand::@95::@97 alterTable
void EventTriggerAlterTableStart ( Node parsetree)

Definition at line 1695 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::parsetree, RelationRelationId, SCT_AlterTable, and CollectedCommand::type.

Referenced by AlterTableMoveAll(), and ProcessUtilitySlow().

1696 {
1697  MemoryContext oldcxt;
1698  CollectedCommand *command;
1699 
1700  /* ignore if event trigger context not set, or collection disabled */
1701  if (!currentEventTriggerState ||
1703  return;
1704 
1706 
1707  command = palloc(sizeof(CollectedCommand));
1708 
1709  command->type = SCT_AlterTable;
1710  command->in_extension = creating_extension;
1711 
1712  command->d.alterTable.classId = RelationRelationId;
1713  command->d.alterTable.objectId = InvalidOid;
1714  command->d.alterTable.subcmds = NIL;
1715  command->parsetree = copyObject(parsetree);
1716 
1718 
1719  MemoryContextSwitchTo(oldcxt);
1720 }
#define NIL
Definition: pg_list.h:69
#define RelationRelationId
Definition: pg_class.h:29
union CollectedCommand::@95 d
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
CollectedCommandType type
static EventTriggerQueryState * currentEventTriggerState
Definition: event_trigger.c:72
void * copyObject(const void *from)
Definition: copyfuncs.c:4619
CollectedCommand * currentCommand
Definition: event_trigger.c:66
struct CollectedCommand::@95::@97 alterTable
#define InvalidOid
Definition: postgres_ext.h:36
bool creating_extension
Definition: extension.c:67
void * palloc(Size size)
Definition: mcxt.c:849
bool EventTriggerBeginCompleteQuery ( void  )

Definition at line 1220 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, NULL, EventTriggerQueryState::previous, slist_init(), EventTriggerQueryState::SQLDropList, EventTriggerQueryState::table_rewrite_oid, TopMemoryContext, and trackDroppedObjectsNeeded().

Referenced by ProcessUtilitySlow().

1221 {
1223  MemoryContext cxt;
1224 
1225  /*
1226  * Currently, sql_drop, table_rewrite, ddl_command_end events are the only
1227  * reason to have event trigger state at all; so if there are none, don't
1228  * install one.
1229  */
1231  return false;
1232 
1234  "event trigger state",
1236  state = MemoryContextAlloc(cxt, sizeof(EventTriggerQueryState));
1237  state->cxt = cxt;
1238  slist_init(&(state->SQLDropList));
1239  state->in_sql_drop = false;
1240  state->table_rewrite_oid = InvalidOid;
1241 
1244  state->currentCommand = NULL;
1245  state->commandList = NIL;
1247  currentEventTriggerState = state;
1248 
1249  return true;
1250 }
#define NIL
Definition: pg_list.h:69
bool trackDroppedObjectsNeeded(void)
static EventTriggerQueryState * currentEventTriggerState
Definition: event_trigger.c:72
static void slist_init(slist_head *head)
Definition: ilist.h:554
#define ALLOCSET_DEFAULT_SIZES
Definition: memutils.h:165
CollectedCommand * currentCommand
Definition: event_trigger.c:66
struct EventTriggerQueryState * previous
Definition: event_trigger.c:69
MemoryContext TopMemoryContext
Definition: mcxt.c:43
MemoryContext AllocSetContextCreate(MemoryContext parent, const char *name, Size minContextSize, Size initBlockSize, Size maxBlockSize)
Definition: aset.c:322
#define InvalidOid
Definition: postgres_ext.h:36
#define NULL
Definition: c.h:229
Definition: regguts.h:298
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition: mcxt.c:707
void EventTriggerCollectAlterDefPrivs ( AlterDefaultPrivilegesStmt stmt)

Definition at line 1954 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().

1955 {
1956  MemoryContext oldcxt;
1957  CollectedCommand *command;
1958 
1959  /* ignore if event trigger context not set, or collection disabled */
1960  if (!currentEventTriggerState ||
1962  return;
1963 
1965 
1966  command = palloc0(sizeof(CollectedCommand));
1967  command->type = SCT_AlterDefaultPrivileges;
1968  command->d.defprivs.objtype = stmt->action->objtype;
1969  command->in_extension = creating_extension;
1970  command->parsetree = copyObject(stmt);
1971 
1974  MemoryContextSwitchTo(oldcxt);
1975 }
struct CollectedCommand::@95::@102 defprivs
union CollectedCommand::@95 d
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
CollectedCommandType type
static EventTriggerQueryState * currentEventTriggerState
Definition: event_trigger.c:72
void * copyObject(const void *from)
Definition: copyfuncs.c:4619
List * lappend(List *list, void *datum)
Definition: list.c:128
void * palloc0(Size size)
Definition: mcxt.c:878
bool creating_extension
Definition: extension.c:67
GrantObjectType objtype
Definition: parsenodes.h:1806
void EventTriggerCollectAlterOpFam ( AlterOpFamilyStmt stmt,
Oid  opfamoid,
List operators,
List procedures 
)

Definition at line 1852 of file event_trigger.c.

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

Referenced by AlterOpFamilyAdd(), and AlterOpFamilyDrop().

1854 {
1855  MemoryContext oldcxt;
1856  CollectedCommand *command;
1857 
1858  /* ignore if event trigger context not set, or collection disabled */
1859  if (!currentEventTriggerState ||
1861  return;
1862 
1864 
1865  command = palloc(sizeof(CollectedCommand));
1866  command->type = SCT_AlterOpFamily;
1867  command->in_extension = creating_extension;
1868  ObjectAddressSet(command->d.opfam.address,
1869  OperatorFamilyRelationId, opfamoid);
1870  command->d.opfam.operators = operators;
1871  command->d.opfam.procedures = procedures;
1872  command->parsetree = copyObject(stmt);
1873 
1876 
1877  MemoryContextSwitchTo(oldcxt);
1878 }
union CollectedCommand::@95 d
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
#define OperatorFamilyRelationId
Definition: pg_opfamily.h:29
CollectedCommandType type
static EventTriggerQueryState * currentEventTriggerState
Definition: event_trigger.c:72
void * copyObject(const void *from)
Definition: copyfuncs.c:4619
List * lappend(List *list, void *datum)
Definition: list.c:128
bool creating_extension
Definition: extension.c:67
#define ObjectAddressSet(addr, class_id, object_id)
Definition: objectaddress.h:40
void * palloc(Size size)
Definition: mcxt.c:849
struct CollectedCommand::@95::@99 opfam
void EventTriggerCollectAlterTableSubcmd ( Node subcmd,
ObjectAddress  address 
)

Definition at line 1746 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().

1747 {
1748  MemoryContext oldcxt;
1750 
1751  /* ignore if event trigger context not set, or collection disabled */
1752  if (!currentEventTriggerState ||
1754  return;
1755 
1756  Assert(IsA(subcmd, AlterTableCmd));
1758 
1760 
1761  newsub = palloc(sizeof(CollectedATSubcmd));
1762  newsub->address = address;
1763  newsub->parsetree = copyObject(subcmd);
1764 
1767 
1768  MemoryContextSwitchTo(oldcxt);
1769 }
#define IsA(nodeptr, _type_)
Definition: nodes.h:555
union CollectedCommand::@95 d
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
#define OidIsValid(objectId)
Definition: c.h:538
static EventTriggerQueryState * currentEventTriggerState
Definition: event_trigger.c:72
void * copyObject(const void *from)
Definition: copyfuncs.c:4619
CollectedCommand * currentCommand
Definition: event_trigger.c:66
struct CollectedCommand::@95::@97 alterTable
List * lappend(List *list, void *datum)
Definition: list.c:128
#define Assert(condition)
Definition: c.h:675
void * palloc(Size size)
Definition: mcxt.c:849
static color newsub(struct colormap *cm, color co)
Definition: regc_color.c:389
ObjectAddress address
void EventTriggerCollectAlterTSConfig ( AlterTSConfigurationStmt stmt,
Oid  cfgId,
Oid dictIds,
int  ndicts 
)

Definition at line 1919 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, TSConfigRelationId, and CollectedCommand::type.

Referenced by DropConfigurationMapping(), and MakeConfigurationMapping().

1921 {
1922  MemoryContext oldcxt;
1923  CollectedCommand *command;
1924 
1925  /* ignore if event trigger context not set, or collection disabled */
1926  if (!currentEventTriggerState ||
1928  return;
1929 
1931 
1932  command = palloc0(sizeof(CollectedCommand));
1933  command->type = SCT_AlterTSConfig;
1934  command->in_extension = creating_extension;
1935  ObjectAddressSet(command->d.atscfg.address,
1936  TSConfigRelationId, cfgId);
1937  command->d.atscfg.dictIds = palloc(sizeof(Oid) * ndicts);
1938  memcpy(command->d.atscfg.dictIds, dictIds, sizeof(Oid) * ndicts);
1939  command->d.atscfg.ndicts = ndicts;
1940  command->parsetree = copyObject(stmt);
1941 
1944 
1945  MemoryContextSwitchTo(oldcxt);
1946 }
union CollectedCommand::@95 d
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
CollectedCommandType type
unsigned int Oid
Definition: postgres_ext.h:31
static EventTriggerQueryState * currentEventTriggerState
Definition: event_trigger.c:72
void * copyObject(const void *from)
Definition: copyfuncs.c:4619
#define TSConfigRelationId
Definition: pg_ts_config.h:31
List * lappend(List *list, void *datum)
Definition: list.c:128
void * palloc0(Size size)
Definition: mcxt.c:878
bool creating_extension
Definition: extension.c:67
#define ObjectAddressSet(addr, class_id, object_id)
Definition: objectaddress.h:40
struct CollectedCommand::@95::@101 atscfg
void * palloc(Size size)
Definition: mcxt.c:849
void EventTriggerCollectCreateOpClass ( CreateOpClassStmt stmt,
Oid  opcoid,
List operators,
List procedures 
)

Definition at line 1885 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, OperatorClassRelationId, palloc0(), CollectedCommand::parsetree, SCT_CreateOpClass, and CollectedCommand::type.

Referenced by DefineOpClass().

1887 {
1888  MemoryContext oldcxt;
1889  CollectedCommand *command;
1890 
1891  /* ignore if event trigger context not set, or collection disabled */
1892  if (!currentEventTriggerState ||
1894  return;
1895 
1897 
1898  command = palloc0(sizeof(CollectedCommand));
1899  command->type = SCT_CreateOpClass;
1900  command->in_extension = creating_extension;
1901  ObjectAddressSet(command->d.createopc.address,
1902  OperatorClassRelationId, opcoid);
1903  command->d.createopc.operators = operators;
1904  command->d.createopc.procedures = procedures;
1905  command->parsetree = copyObject(stmt);
1906 
1909 
1910  MemoryContextSwitchTo(oldcxt);
1911 }
union CollectedCommand::@95 d
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
#define OperatorClassRelationId
Definition: pg_opclass.h:49
CollectedCommandType type
struct CollectedCommand::@95::@100 createopc
static EventTriggerQueryState * currentEventTriggerState
Definition: event_trigger.c:72
void * copyObject(const void *from)
Definition: copyfuncs.c:4619
List * lappend(List *list, void *datum)
Definition: list.c:128
void * palloc0(Size size)
Definition: mcxt.c:878
bool creating_extension
Definition: extension.c:67
#define ObjectAddressSet(addr, class_id, object_id)
Definition: objectaddress.h:40
void EventTriggerCollectGrant ( InternalGrant istmt)

Definition at line 1808 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, NULL, InternalGrant::objects, palloc(), CollectedCommand::parsetree, SCT_Grant, and CollectedCommand::type.

Referenced by ExecGrantStmt_oids().

1809 {
1810  MemoryContext oldcxt;
1811  CollectedCommand *command;
1812  InternalGrant *icopy;
1813  ListCell *cell;
1814 
1815  /* ignore if event trigger context not set, or collection disabled */
1816  if (!currentEventTriggerState ||
1818  return;
1819 
1821 
1822  /*
1823  * This is tedious, but necessary.
1824  */
1825  icopy = palloc(sizeof(InternalGrant));
1826  memcpy(icopy, istmt, sizeof(InternalGrant));
1827  icopy->objects = list_copy(istmt->objects);
1828  icopy->grantees = list_copy(istmt->grantees);
1829  icopy->col_privs = NIL;
1830  foreach(cell, istmt->col_privs)
1831  icopy->col_privs = lappend(icopy->col_privs, copyObject(lfirst(cell)));
1832 
1833  /* Now collect it, using the copied InternalGrant */
1834  command = palloc(sizeof(CollectedCommand));
1835  command->type = SCT_Grant;
1836  command->in_extension = creating_extension;
1837  command->d.grant.istmt = icopy;
1838  command->parsetree = NULL;
1839 
1842 
1843  MemoryContextSwitchTo(oldcxt);
1844 }
#define NIL
Definition: pg_list.h:69
union CollectedCommand::@95 d
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
List * list_copy(const List *oldlist)
Definition: list.c:1160
CollectedCommandType type
static EventTriggerQueryState * currentEventTriggerState
Definition: event_trigger.c:72
void * copyObject(const void *from)
Definition: copyfuncs.c:4619
List * lappend(List *list, void *datum)
Definition: list.c:128
bool creating_extension
Definition: extension.c:67
#define NULL
Definition: c.h:229
#define lfirst(lc)
Definition: pg_list.h:106
struct CollectedCommand::@95::@98 grant
void * palloc(Size size)
Definition: mcxt.c:849
void EventTriggerCollectSimpleCommand ( ObjectAddress  address,
ObjectAddress  secondaryObject,
Node parsetree 
)

Definition at line 1652 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().

1655 {
1656  MemoryContext oldcxt;
1657  CollectedCommand *command;
1658 
1659  /* ignore if event trigger context not set, or collection disabled */
1660  if (!currentEventTriggerState ||
1662  return;
1663 
1665 
1666  command = palloc(sizeof(CollectedCommand));
1667 
1668  command->type = SCT_Simple;
1669  command->in_extension = creating_extension;
1670 
1671  command->d.simple.address = address;
1672  command->d.simple.secondaryObject = secondaryObject;
1673  command->parsetree = copyObject(parsetree);
1674 
1676  command);
1677 
1678  MemoryContextSwitchTo(oldcxt);
1679 }
struct CollectedCommand::@95::@96 simple
union CollectedCommand::@95 d
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
CollectedCommandType type
static EventTriggerQueryState * currentEventTriggerState
Definition: event_trigger.c:72
void * copyObject(const void *from)
Definition: copyfuncs.c:4619
List * lappend(List *list, void *datum)
Definition: list.c:128
bool creating_extension
Definition: extension.c:67
void * palloc(Size size)
Definition: mcxt.c:849
static List* EventTriggerCommonSetup ( Node parsetree,
EventTriggerEvent  event,
const char *  eventstr,
EventTriggerData trigdata 
)
static

Definition at line 692 of file event_trigger.c.

References check_ddl_tag(), check_table_rewrite_ddl_tag(), CreateCommandTag(), elog, ERROR, EventTriggerData::event, EVENT_TRIGGER_COMMAND_TAG_OK, EventCacheLookup(), EVT_DDLCommandEnd, EVT_DDLCommandStart, EVT_SQLDrop, EVT_TableRewrite, filter_event_trigger(), EventTriggerCacheItem::fnoid, lappend_oid(), lfirst, NIL, EventTriggerData::parsetree, T_EventTriggerData, EventTriggerData::tag, and EventTriggerData::type.

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

695 {
696  const char *tag;
697  List *cachelist;
698  ListCell *lc;
699  List *runlist = NIL;
700 
701  /*
702  * We want the list of command tags for which this procedure is actually
703  * invoked to match up exactly with the list that CREATE EVENT TRIGGER
704  * accepts. This debugging cross-check will throw an error if this
705  * function is invoked for a command tag that CREATE EVENT TRIGGER won't
706  * accept. (Unfortunately, there doesn't seem to be any simple, automated
707  * way to verify that CREATE EVENT TRIGGER doesn't accept extra stuff that
708  * never reaches this control point.)
709  *
710  * If this cross-check fails for you, you probably need to either adjust
711  * standard_ProcessUtility() not to invoke event triggers for the command
712  * type in question, or you need to adjust check_ddl_tag to accept the
713  * relevant command tag.
714  */
715 #ifdef USE_ASSERT_CHECKING
716  {
717  const char *dbgtag;
718 
719  dbgtag = CreateCommandTag(parsetree);
720  if (event == EVT_DDLCommandStart ||
721  event == EVT_DDLCommandEnd ||
722  event == EVT_SQLDrop)
723  {
725  elog(ERROR, "unexpected command tag \"%s\"", dbgtag);
726  }
727  else if (event == EVT_TableRewrite)
728  {
730  elog(ERROR, "unexpected command tag \"%s\"", dbgtag);
731  }
732  }
733 #endif
734 
735  /* Use cache to find triggers for this event; fast exit if none. */
736  cachelist = EventCacheLookup(event);
737  if (cachelist == NIL)
738  return NIL;
739 
740  /* Get the command tag. */
741  tag = CreateCommandTag(parsetree);
742 
743  /*
744  * Filter list of event triggers by command tag, and copy them into our
745  * memory context. Once we start running the command triggers, or indeed
746  * once we do anything at all that touches the catalogs, an invalidation
747  * might leave cachelist pointing at garbage, so we must do this before we
748  * can do much else.
749  */
750  foreach(lc, cachelist)
751  {
752  EventTriggerCacheItem *item = lfirst(lc);
753 
754  if (filter_event_trigger(&tag, item))
755  {
756  /* We must plan to fire this trigger. */
757  runlist = lappend_oid(runlist, item->fnoid);
758  }
759  }
760 
761  /* don't spend any more time on this if no functions to run */
762  if (runlist == NIL)
763  return NIL;
764 
765  trigdata->type = T_EventTriggerData;
766  trigdata->event = eventstr;
767  trigdata->parsetree = parsetree;
768  trigdata->tag = tag;
769 
770  return runlist;
771 }
#define NIL
Definition: pg_list.h:69
const char * tag
Definition: event_trigger.h:28
List * lappend_oid(List *list, Oid datum)
Definition: list.c:164
static event_trigger_command_tag_check_result check_ddl_tag(const char *tag)
static bool filter_event_trigger(const char **tag, EventTriggerCacheItem *item)
#define ERROR
Definition: elog.h:43
static event_trigger_command_tag_check_result check_table_rewrite_ddl_tag(const char *tag)
const char * event
Definition: event_trigger.h:26
const char * CreateCommandTag(Node *parsetree)
Definition: utility.c:2024
#define lfirst(lc)
Definition: pg_list.h:106
List * EventCacheLookup(EventTriggerEvent event)
Definition: evtcache.c:64
#define elog
Definition: elog.h:219
Definition: pg_list.h:45
void EventTriggerDDLCommandEnd ( Node parsetree)

Definition at line 825 of file event_trigger.c.

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

Referenced by ProcessUtilitySlow().

826 {
827  List *runlist;
828  EventTriggerData trigdata;
829 
830  /*
831  * See EventTriggerDDLCommandStart for a discussion about why event
832  * triggers are disabled in single user mode.
833  */
834  if (!IsUnderPostmaster)
835  return;
836 
837  runlist = EventTriggerCommonSetup(parsetree,
838  EVT_DDLCommandEnd, "ddl_command_end",
839  &trigdata);
840  if (runlist == NIL)
841  return;
842 
843  /*
844  * Make sure anything the main command did will be visible to the event
845  * triggers.
846  */
848 
849  /* Run the triggers. */
850  EventTriggerInvoke(runlist, &trigdata);
851 
852  /* Cleanup. */
853  list_free(runlist);
854 }
#define NIL
Definition: pg_list.h:69
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:100
void CommandCounterIncrement(void)
Definition: xact.c:922
void list_free(List *list)
Definition: list.c:1133
Definition: pg_list.h:45
void EventTriggerDDLCommandStart ( Node parsetree)

Definition at line 777 of file event_trigger.c.

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

Referenced by ProcessUtilitySlow().

778 {
779  List *runlist;
780  EventTriggerData trigdata;
781 
782  /*
783  * Event Triggers are completely disabled in standalone mode. There are
784  * (at least) two reasons for this:
785  *
786  * 1. A sufficiently broken event trigger might not only render the
787  * database unusable, but prevent disabling itself to fix the situation.
788  * In this scenario, restarting in standalone mode provides an escape
789  * hatch.
790  *
791  * 2. BuildEventTriggerCache relies on systable_beginscan_ordered, and
792  * therefore will malfunction if pg_event_trigger's indexes are damaged.
793  * To allow recovery from a damaged index, we need some operating mode
794  * wherein event triggers are disabled. (Or we could implement
795  * heapscan-and-sort logic for that case, but having disaster recovery
796  * scenarios depend on code that's otherwise untested isn't appetizing.)
797  */
798  if (!IsUnderPostmaster)
799  return;
800 
801  runlist = EventTriggerCommonSetup(parsetree,
803  "ddl_command_start",
804  &trigdata);
805  if (runlist == NIL)
806  return;
807 
808  /* Run the triggers. */
809  EventTriggerInvoke(runlist, &trigdata);
810 
811  /* Cleanup. */
812  list_free(runlist);
813 
814  /*
815  * Make sure anything the event triggers did will be visible to the main
816  * command.
817  */
819 }
#define NIL
Definition: pg_list.h:69
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:100
void CommandCounterIncrement(void)
Definition: xact.c:922
void list_free(List *list)
Definition: list.c:1133
Definition: pg_list.h:45
void EventTriggerEndCompleteQuery ( void  )

Definition at line 1264 of file event_trigger.c.

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

Referenced by ProcessUtilitySlow().

1265 {
1266  EventTriggerQueryState *prevstate;
1267 
1268  prevstate = currentEventTriggerState->previous;
1269 
1270  /* this avoids the need for retail pfree of SQLDropList items: */
1272 
1273  currentEventTriggerState = prevstate;
1274 }
void MemoryContextDelete(MemoryContext context)
Definition: mcxt.c:200
static EventTriggerQueryState * currentEventTriggerState
Definition: event_trigger.c:72
struct EventTriggerQueryState * previous
Definition: event_trigger.c:69
void EventTriggerInhibitCommandCollection ( void  )

Definition at line 1618 of file event_trigger.c.

References EventTriggerQueryState::commandCollectionInhibited.

Referenced by ProcessUtilitySlow().

1619 {
1621  return;
1622 
1624 }
static EventTriggerQueryState * currentEventTriggerState
Definition: event_trigger.c:72
static void EventTriggerInvoke ( List fn_oid_list,
EventTriggerData trigdata 
)
static

Definition at line 1005 of file event_trigger.c.

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

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

1006 {
1007  MemoryContext context;
1008  MemoryContext oldcontext;
1009  ListCell *lc;
1010  bool first = true;
1011 
1012  /* Guard against stack overflow due to recursive event trigger */
1014 
1015  /*
1016  * Let's evaluate event triggers in their own memory context, so that any
1017  * leaks get cleaned up promptly.
1018  */
1020  "event trigger context",
1022  oldcontext = MemoryContextSwitchTo(context);
1023 
1024  /* Call each event trigger. */
1025  foreach(lc, fn_oid_list)
1026  {
1027  Oid fnoid = lfirst_oid(lc);
1028  FmgrInfo flinfo;
1029  FunctionCallInfoData fcinfo;
1030  PgStat_FunctionCallUsage fcusage;
1031 
1032  elog(DEBUG1, "EventTriggerInvoke %u", fnoid);
1033 
1034  /*
1035  * We want each event trigger to be able to see the results of the
1036  * previous event trigger's action. Caller is responsible for any
1037  * command-counter increment that is needed between the event trigger
1038  * and anything else in the transaction.
1039  */
1040  if (first)
1041  first = false;
1042  else
1044 
1045  /* Look up the function */
1046  fmgr_info(fnoid, &flinfo);
1047 
1048  /* Call the function, passing no arguments but setting a context. */
1049  InitFunctionCallInfoData(fcinfo, &flinfo, 0,
1050  InvalidOid, (Node *) trigdata, NULL);
1051  pgstat_init_function_usage(&fcinfo, &fcusage);
1052  FunctionCallInvoke(&fcinfo);
1053  pgstat_end_function_usage(&fcusage, true);
1054 
1055  /* Reclaim memory. */
1056  MemoryContextReset(context);
1057  }
1058 
1059  /* Restore old memory context and delete the temporary one. */
1060  MemoryContextSwitchTo(oldcontext);
1061  MemoryContextDelete(context);
1062 }
Definition: fmgr.h:56
void MemoryContextDelete(MemoryContext context)
Definition: mcxt.c:200
#define DEBUG1
Definition: elog.h:25
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
Definition: nodes.h:504
void MemoryContextReset(MemoryContext context)
Definition: mcxt.c:135
unsigned int Oid
Definition: postgres_ext.h:31
void fmgr_info(Oid functionId, FmgrInfo *finfo)
Definition: fmgr.c:159
#define ALLOCSET_DEFAULT_SIZES
Definition: memutils.h:165
#define FunctionCallInvoke(fcinfo)
Definition: fmgr.h:137
void check_stack_depth(void)
Definition: postgres.c:3098
MemoryContext CurrentMemoryContext
Definition: mcxt.c:37
MemoryContext AllocSetContextCreate(MemoryContext parent, const char *name, Size minContextSize, Size initBlockSize, Size maxBlockSize)
Definition: aset.c:322
void CommandCounterIncrement(void)
Definition: xact.c:922
#define InvalidOid
Definition: postgres_ext.h:36
#define NULL
Definition: c.h:229
#define InitFunctionCallInfoData(Fcinfo, Flinfo, Nargs, Collation, Context, Resultinfo)
Definition: fmgr.h:120
void pgstat_end_function_usage(PgStat_FunctionCallUsage *fcu, bool finalize)
Definition: pgstat.c:1578
void pgstat_init_function_usage(FunctionCallInfoData *fcinfo, PgStat_FunctionCallUsage *fcu)
Definition: pgstat.c:1506
#define elog
Definition: elog.h:219
#define lfirst_oid(lc)
Definition: pg_list.h:108
void EventTriggerSQLDrop ( Node parsetree)

Definition at line 860 of file event_trigger.c.

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

Referenced by ProcessUtilitySlow().

861 {
862  List *runlist;
863  EventTriggerData trigdata;
864 
865  /*
866  * See EventTriggerDDLCommandStart for a discussion about why event
867  * triggers are disabled in single user mode.
868  */
869  if (!IsUnderPostmaster)
870  return;
871 
872  /*
873  * Use current state to determine whether this event fires at all. If
874  * there are no triggers for the sql_drop event, then we don't have
875  * anything to do here. Note that dropped object collection is disabled
876  * if this is the case, so even if we were to try to run, the list would
877  * be empty.
878  */
881  return;
882 
883  runlist = EventTriggerCommonSetup(parsetree,
884  EVT_SQLDrop, "sql_drop",
885  &trigdata);
886 
887  /*
888  * Nothing to do if run list is empty. Note this shouldn't happen,
889  * because if there are no sql_drop events, then objects-to-drop wouldn't
890  * have been collected in the first place and we would have quit above.
891  */
892  if (runlist == NIL)
893  return;
894 
895  /*
896  * Make sure anything the main command did will be visible to the event
897  * triggers.
898  */
900 
901  /*
902  * Make sure pg_event_trigger_dropped_objects only works when running
903  * these triggers. Use PG_TRY to ensure in_sql_drop is reset even when
904  * one trigger fails. (This is perhaps not necessary, as the currentState
905  * variable will be removed shortly by our caller, but it seems better to
906  * play safe.)
907  */
909 
910  /* Run the triggers. */
911  PG_TRY();
912  {
913  EventTriggerInvoke(runlist, &trigdata);
914  }
915  PG_CATCH();
916  {
918  PG_RE_THROW();
919  }
920  PG_END_TRY();
922 
923  /* Cleanup. */
924  list_free(runlist);
925 }
#define NIL
Definition: pg_list.h:69
static void EventTriggerInvoke(List *fn_oid_list, EventTriggerData *trigdata)
static EventTriggerQueryState * currentEventTriggerState
Definition: event_trigger.c:72
static List * EventTriggerCommonSetup(Node *parsetree, EventTriggerEvent event, const char *eventstr, EventTriggerData *trigdata)
bool IsUnderPostmaster
Definition: globals.c:100
static bool slist_is_empty(slist_head *head)
Definition: ilist.h:563
void CommandCounterIncrement(void)
Definition: xact.c:922
#define PG_CATCH()
Definition: elog.h:293
#define PG_RE_THROW()
Definition: elog.h:314
void list_free(List *list)
Definition: list.c:1133
#define PG_TRY()
Definition: elog.h:284
Definition: pg_list.h:45
#define PG_END_TRY()
Definition: elog.h:300
void EventTriggerSQLDropAddObject ( const ObjectAddress object,
bool  original,
bool  normal 
)

Definition at line 1314 of file event_trigger.c.

References AccessShareLock, SQLDropObject::addrargs, SQLDropObject::address, SQLDropObject::addrnames, Assert, 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_namensp_unique(), getObjectClass(), getObjectIdentityParts(), getObjectTypeDescription(), heap_close, heap_getattr, heap_open(), InvalidAttrNumber, is_objectclass_supported(), isAnyTempNamespace(), SQLDropObject::istemp, isTempNamespace(), MemoryContextSwitchTo(), NamespaceRelationId, 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(), and EventTriggerQueryState::SQLDropList.

Referenced by deleteObjectsInList(), and DropSubscription().

1315 {
1316  SQLDropObject *obj;
1317  MemoryContext oldcxt;
1318 
1320  return;
1321 
1323 
1324  /* don't report temp schemas except my own */
1325  if (object->classId == NamespaceRelationId &&
1326  (isAnyTempNamespace(object->objectId) &&
1327  !isTempNamespace(object->objectId)))
1328  return;
1329 
1331 
1332  obj = palloc0(sizeof(SQLDropObject));
1333  obj->address = *object;
1334  obj->original = original;
1335  obj->normal = normal;
1336 
1337  /*
1338  * Obtain schema names from the object's catalog tuple, if one exists;
1339  * this lets us skip objects in temp schemas. We trust that
1340  * ObjectProperty contains all object classes that can be
1341  * schema-qualified.
1342  */
1343  if (is_objectclass_supported(object->classId))
1344  {
1345  Relation catalog;
1346  HeapTuple tuple;
1347 
1348  catalog = heap_open(obj->address.classId, AccessShareLock);
1349  tuple = get_catalog_object_by_oid(catalog, obj->address.objectId);
1350 
1351  if (tuple)
1352  {
1353  AttrNumber attnum;
1354  Datum datum;
1355  bool isnull;
1356 
1358  if (attnum != InvalidAttrNumber)
1359  {
1360  datum = heap_getattr(tuple, attnum,
1361  RelationGetDescr(catalog), &isnull);
1362  if (!isnull)
1363  {
1364  Oid namespaceId;
1365 
1366  namespaceId = DatumGetObjectId(datum);
1367  /* temp objects are only reported if they are my own */
1368  if (isTempNamespace(namespaceId))
1369  {
1370  obj->schemaname = "pg_temp";
1371  obj->istemp = true;
1372  }
1373  else if (isAnyTempNamespace(namespaceId))
1374  {
1375  pfree(obj);
1376  heap_close(catalog, AccessShareLock);
1377  MemoryContextSwitchTo(oldcxt);
1378  return;
1379  }
1380  else
1381  {
1382  obj->schemaname = get_namespace_name(namespaceId);
1383  obj->istemp = false;
1384  }
1385  }
1386  }
1387 
1389  obj->address.objectSubId == 0)
1390  {
1391  attnum = get_object_attnum_name(obj->address.classId);
1392  if (attnum != InvalidAttrNumber)
1393  {
1394  datum = heap_getattr(tuple, attnum,
1395  RelationGetDescr(catalog), &isnull);
1396  if (!isnull)
1397  obj->objname = pstrdup(NameStr(*DatumGetName(datum)));
1398  }
1399  }
1400  }
1401 
1402  heap_close(catalog, AccessShareLock);
1403  }
1404  else
1405  {
1406  if (object->classId == NamespaceRelationId &&
1407  isTempNamespace(object->objectId))
1408  obj->istemp = true;
1409  }
1410 
1411  /* object identity, objname and objargs */
1412  obj->objidentity =
1413  getObjectIdentityParts(&obj->address, &obj->addrnames, &obj->addrargs);
1414 
1415  /* object type */
1417 
1419 
1420  MemoryContextSwitchTo(oldcxt);
1421 }
bool get_object_namensp_unique(Oid class_id)
slist_node next
#define NamespaceRelationId
Definition: pg_namespace.h:34
ObjectAddress address
char * getObjectTypeDescription(const ObjectAddress *object)
#define RelationGetDescr(relation)
Definition: rel.h:429
const char * objname
#define DatumGetObjectId(X)
Definition: postgres.h:506
char * pstrdup(const char *in)
Definition: mcxt.c:1077
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
AttrNumber get_object_attnum_namespace(Oid class_id)
#define heap_close(r, l)
Definition: heapam.h:97
const char * objidentity
unsigned int Oid
Definition: postgres_ext.h:31
ObjectClass getObjectClass(const ObjectAddress *object)
Definition: dependency.c:2318
const char * objecttype
static EventTriggerQueryState * currentEventTriggerState
Definition: event_trigger.c:72
#define DatumGetName(X)
Definition: postgres.h:591
void pfree(void *pointer)
Definition: mcxt.c:950
char * get_namespace_name(Oid nspid)
Definition: lsyscache.c:3006
bool isTempNamespace(Oid namespaceId)
Definition: namespace.c:3008
bool EventTriggerSupportsObjectClass(ObjectClass objclass)
const char * schemaname
#define heap_getattr(tup, attnum, tupleDesc, isnull)
Definition: htup_details.h:769
AttrNumber get_object_attnum_name(Oid class_id)
void * palloc0(Size size)
Definition: mcxt.c:878
uintptr_t Datum
Definition: postgres.h:372
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1287
#define Assert(condition)
Definition: c.h:675
HeapTuple get_catalog_object_by_oid(Relation catalog, Oid objectId)
#define InvalidAttrNumber
Definition: attnum.h:23
#define NameStr(name)
Definition: c.h:499
bool isAnyTempNamespace(Oid namespaceId)
Definition: namespace.c:3046
bool is_objectclass_supported(Oid class_id)
int16 AttrNumber
Definition: attnum.h:21
bool EventTriggerSupportsGrantObjectType ( GrantObjectType  objtype)

Definition at line 1186 of file event_trigger.c.

References ACL_OBJECT_COLUMN, ACL_OBJECT_DATABASE, ACL_OBJECT_DOMAIN, ACL_OBJECT_FDW, ACL_OBJECT_FOREIGN_SERVER, ACL_OBJECT_FUNCTION, ACL_OBJECT_LANGUAGE, ACL_OBJECT_LARGEOBJECT, ACL_OBJECT_NAMESPACE, ACL_OBJECT_RELATION, ACL_OBJECT_SEQUENCE, ACL_OBJECT_TABLESPACE, ACL_OBJECT_TYPE, and Assert.

Referenced by ExecGrantStmt_oids(), and standard_ProcessUtility().

1187 {
1188  switch (objtype)
1189  {
1190  case ACL_OBJECT_DATABASE:
1191  case ACL_OBJECT_TABLESPACE:
1192  /* no support for global objects */
1193  return false;
1194 
1195  case ACL_OBJECT_COLUMN:
1196  case ACL_OBJECT_RELATION:
1197  case ACL_OBJECT_SEQUENCE:
1198  case ACL_OBJECT_DOMAIN:
1199  case ACL_OBJECT_FDW:
1201  case ACL_OBJECT_FUNCTION:
1202  case ACL_OBJECT_LANGUAGE:
1204  case ACL_OBJECT_NAMESPACE:
1205  case ACL_OBJECT_TYPE:
1206  return true;
1207  default:
1208  Assert(false);
1209  return true;
1210  }
1211 }
#define Assert(condition)
Definition: c.h:675
bool EventTriggerSupportsObjectClass ( ObjectClass  objclass)

Definition at line 1133 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().

1134 {
1135  switch (objclass)
1136  {
1137  case OCLASS_DATABASE:
1138  case OCLASS_TBLSPACE:
1139  case OCLASS_ROLE:
1140  /* no support for global objects */
1141  return false;
1142  case OCLASS_EVENT_TRIGGER:
1143  /* no support for event triggers on event triggers */
1144  return false;
1145  case OCLASS_CLASS:
1146  case OCLASS_PROC:
1147  case OCLASS_TYPE:
1148  case OCLASS_CAST:
1149  case OCLASS_COLLATION:
1150  case OCLASS_CONSTRAINT:
1151  case OCLASS_CONVERSION:
1152  case OCLASS_DEFAULT:
1153  case OCLASS_LANGUAGE:
1154  case OCLASS_LARGEOBJECT:
1155  case OCLASS_OPERATOR:
1156  case OCLASS_OPCLASS:
1157  case OCLASS_OPFAMILY:
1158  case OCLASS_AMOP:
1159  case OCLASS_AMPROC:
1160  case OCLASS_REWRITE:
1161  case OCLASS_TRIGGER:
1162  case OCLASS_SCHEMA:
1163  case OCLASS_TRANSFORM:
1164  case OCLASS_TSPARSER:
1165  case OCLASS_TSDICT:
1166  case OCLASS_TSTEMPLATE:
1167  case OCLASS_TSCONFIG:
1168  case OCLASS_FDW:
1169  case OCLASS_FOREIGN_SERVER:
1170  case OCLASS_USER_MAPPING:
1171  case OCLASS_DEFACL:
1172  case OCLASS_EXTENSION:
1173  case OCLASS_POLICY:
1174  case OCLASS_AM:
1175  case OCLASS_PUBLICATION:
1177  case OCLASS_SUBSCRIPTION:
1178  case OCLASS_STATISTIC_EXT:
1179  return true;
1180  }
1181 
1182  return true;
1183 }
bool EventTriggerSupportsObjectType ( ObjectType  obtype)

Definition at line 1068 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_PUBLICATION, OBJECT_PUBLICATION_REL, OBJECT_ROLE, 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 standard_ProcessUtility().

1069 {
1070  switch (obtype)
1071  {
1072  case OBJECT_DATABASE:
1073  case OBJECT_TABLESPACE:
1074  case OBJECT_ROLE:
1075  /* no support for global objects */
1076  return false;
1077  case OBJECT_EVENT_TRIGGER:
1078  /* no support for event triggers on event triggers */
1079  return false;
1080  case OBJECT_ACCESS_METHOD:
1081  case OBJECT_AGGREGATE:
1082  case OBJECT_AMOP:
1083  case OBJECT_AMPROC:
1084  case OBJECT_ATTRIBUTE:
1085  case OBJECT_CAST:
1086  case OBJECT_COLUMN:
1087  case OBJECT_COLLATION:
1088  case OBJECT_CONVERSION:
1089  case OBJECT_DEFACL:
1090  case OBJECT_DEFAULT:
1091  case OBJECT_DOMAIN:
1092  case OBJECT_DOMCONSTRAINT:
1093  case OBJECT_EXTENSION:
1094  case OBJECT_FDW:
1095  case OBJECT_FOREIGN_SERVER:
1096  case OBJECT_FOREIGN_TABLE:
1097  case OBJECT_FUNCTION:
1098  case OBJECT_INDEX:
1099  case OBJECT_LANGUAGE:
1100  case OBJECT_LARGEOBJECT:
1101  case OBJECT_MATVIEW:
1102  case OBJECT_OPCLASS:
1103  case OBJECT_OPERATOR:
1104  case OBJECT_OPFAMILY:
1105  case OBJECT_POLICY:
1106  case OBJECT_PUBLICATION:
1108  case OBJECT_RULE:
1109  case OBJECT_SCHEMA:
1110  case OBJECT_SEQUENCE:
1111  case OBJECT_SUBSCRIPTION:
1112  case OBJECT_STATISTIC_EXT:
1113  case OBJECT_TABCONSTRAINT:
1114  case OBJECT_TABLE:
1115  case OBJECT_TRANSFORM:
1116  case OBJECT_TRIGGER:
1118  case OBJECT_TSDICTIONARY:
1119  case OBJECT_TSPARSER:
1120  case OBJECT_TSTEMPLATE:
1121  case OBJECT_TYPE:
1122  case OBJECT_USER_MAPPING:
1123  case OBJECT_VIEW:
1124  return true;
1125  }
1126  return true;
1127 }
void EventTriggerTableRewrite ( Node parsetree,
Oid  tableOid,
int  reason 
)

Definition at line 932 of file event_trigger.c.

References CommandCounterIncrement(), DEBUG1, elog, EventTriggerCommonSetup(), EventTriggerInvoke(), EVT_TableRewrite, InvalidOid, IsUnderPostmaster, list_free(), NIL, PG_CATCH, PG_END_TRY, PG_RE_THROW, PG_TRY, EventTriggerQueryState::table_rewrite_oid, and EventTriggerQueryState::table_rewrite_reason.

Referenced by ATRewriteTables().

933 {
934  List *runlist;
935  EventTriggerData trigdata;
936 
937  elog(DEBUG1, "EventTriggerTableRewrite(%u)", tableOid);
938 
939  /*
940  * Event Triggers are completely disabled in standalone mode. There are
941  * (at least) two reasons for this:
942  *
943  * 1. A sufficiently broken event trigger might not only render the
944  * database unusable, but prevent disabling itself to fix the situation.
945  * In this scenario, restarting in standalone mode provides an escape
946  * hatch.
947  *
948  * 2. BuildEventTriggerCache relies on systable_beginscan_ordered, and
949  * therefore will malfunction if pg_event_trigger's indexes are damaged.
950  * To allow recovery from a damaged index, we need some operating mode
951  * wherein event triggers are disabled. (Or we could implement
952  * heapscan-and-sort logic for that case, but having disaster recovery
953  * scenarios depend on code that's otherwise untested isn't appetizing.)
954  */
955  if (!IsUnderPostmaster)
956  return;
957 
958  runlist = EventTriggerCommonSetup(parsetree,
960  "table_rewrite",
961  &trigdata);
962  if (runlist == NIL)
963  return;
964 
965  /*
966  * Make sure pg_event_trigger_table_rewrite_oid only works when running
967  * these triggers. Use PG_TRY to ensure table_rewrite_oid is reset even
968  * when one trigger fails. (This is perhaps not necessary, as the
969  * currentState variable will be removed shortly by our caller, but it
970  * seems better to play safe.)
971  */
974 
975  /* Run the triggers. */
976  PG_TRY();
977  {
978  EventTriggerInvoke(runlist, &trigdata);
979  }
980  PG_CATCH();
981  {
984  PG_RE_THROW();
985  }
986  PG_END_TRY();
987 
990 
991  /* Cleanup. */
992  list_free(runlist);
993 
994  /*
995  * Make sure anything the event triggers did will be visible to the main
996  * command.
997  */
999 }
#define NIL
Definition: pg_list.h:69
#define DEBUG1
Definition: elog.h:25
static void EventTriggerInvoke(List *fn_oid_list, EventTriggerData *trigdata)
static EventTriggerQueryState * currentEventTriggerState
Definition: event_trigger.c:72
static List * EventTriggerCommonSetup(Node *parsetree, EventTriggerEvent event, const char *eventstr, EventTriggerData *trigdata)
bool IsUnderPostmaster
Definition: globals.c:100
void CommandCounterIncrement(void)
Definition: xact.c:922
#define InvalidOid
Definition: postgres_ext.h:36
#define PG_CATCH()
Definition: elog.h:293
#define PG_RE_THROW()
Definition: elog.h:314
void list_free(List *list)
Definition: list.c:1133
#define elog
Definition: elog.h:219
#define PG_TRY()
Definition: elog.h:284
Definition: pg_list.h:45
#define PG_END_TRY()
Definition: elog.h:300
void EventTriggerUndoInhibitCommandCollection ( void  )

Definition at line 1630 of file event_trigger.c.

References EventTriggerQueryState::commandCollectionInhibited.

Referenced by ProcessUtilitySlow().

1631 {
1633  return;
1634 
1636 }
static EventTriggerQueryState * currentEventTriggerState
Definition: event_trigger.c:72
static bool filter_event_trigger ( const char **  tag,
EventTriggerCacheItem item 
)
static

Definition at line 659 of file event_trigger.c.

References EventTriggerCacheItem::enabled, EventTriggerCacheItem::ntags, NULL, pg_qsort_strcmp(), SESSION_REPLICATION_ROLE_REPLICA, SessionReplicationRole, EventTriggerCacheItem::tag, TRIGGER_FIRES_ON_ORIGIN, and TRIGGER_FIRES_ON_REPLICA.

Referenced by EventTriggerCommonSetup().

660 {
661  /*
662  * Filter by session replication role, knowing that we never see disabled
663  * items down here.
664  */
666  {
667  if (item->enabled == TRIGGER_FIRES_ON_ORIGIN)
668  return false;
669  }
670  else
671  {
672  if (item->enabled == TRIGGER_FIRES_ON_REPLICA)
673  return false;
674  }
675 
676  /* Filter by tags, if any were specified. */
677  if (item->ntags != 0 && bsearch(tag, item->tag,
678  item->ntags, sizeof(char *),
679  pg_qsort_strcmp) == NULL)
680  return false;
681 
682  /* if we reach that point, we're not filtering out this item */
683  return true;
684 }
#define TRIGGER_FIRES_ON_ORIGIN
Definition: trigger.h:109
int SessionReplicationRole
Definition: trigger.c:64
#define SESSION_REPLICATION_ROLE_REPLICA
Definition: trigger.h:101
#define NULL
Definition: c.h:229
int pg_qsort_strcmp(const void *a, const void *b)
Definition: qsort.c:232
#define TRIGGER_FIRES_ON_REPLICA
Definition: trigger.h:111
static Datum filter_list_to_array ( List filterlist)
static

Definition at line 448 of file event_trigger.c.

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

Referenced by insert_event_trigger_tuple().

449 {
450  ListCell *lc;
451  Datum *data;
452  int i = 0,
453  l = list_length(filterlist);
454 
455  data = (Datum *) palloc(l * sizeof(Datum));
456 
457  foreach(lc, filterlist)
458  {
459  const char *value = strVal(lfirst(lc));
460  char *result,
461  *p;
462 
463  result = pstrdup(value);
464  for (p = result; *p; p++)
465  *p = pg_ascii_toupper((unsigned char) *p);
466  data[i++] = PointerGetDatum(cstring_to_text(result));
467  pfree(result);
468  }
469 
470  return PointerGetDatum(construct_array(data, l, TEXTOID, -1, false, 'i'));
471 }
#define TEXTOID
Definition: pg_type.h:324
#define PointerGetDatum(X)
Definition: postgres.h:562
char * pstrdup(const char *in)
Definition: mcxt.c:1077
ArrayType * construct_array(Datum *elems, int nelems, Oid elmtype, int elmlen, bool elmbyval, char elmalign)
Definition: arrayfuncs.c:3306
#define strVal(v)
Definition: value.h:54
unsigned char pg_ascii_toupper(unsigned char ch)
Definition: pgstrcasecmp.c:135
return result
Definition: formatting.c:1618
static struct @114 value
void pfree(void *pointer)
Definition: mcxt.c:950
uintptr_t Datum
Definition: postgres.h:372
text * cstring_to_text(const char *s)
Definition: varlena.c:149
#define lfirst(lc)
Definition: pg_list.h:106
static int list_length(const List *l)
Definition: pg_list.h:89
void * palloc(Size size)
Definition: mcxt.c:849
int i
Oid get_event_trigger_oid ( const char *  trigname,
bool  missing_ok 
)

Definition at line 641 of file event_trigger.c.

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

Referenced by get_object_address_unqualified().

642 {
643  Oid oid;
644 
646  if (!OidIsValid(oid) && !missing_ok)
647  ereport(ERROR,
648  (errcode(ERRCODE_UNDEFINED_OBJECT),
649  errmsg("event trigger \"%s\" does not exist", trigname)));
650  return oid;
651 }
int errcode(int sqlerrcode)
Definition: elog.c:575
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:538
#define GetSysCacheOid1(cacheId, key1)
Definition: syscache.h:179
#define ERROR
Definition: elog.h:43
#define CStringGetDatum(X)
Definition: postgres.h:584
#define ereport(elevel, rest)
Definition: elog.h:122
int errmsg(const char *fmt,...)
Definition: elog.c:797
static Oid insert_event_trigger_tuple ( char *  trigname,
char *  eventname,
Oid  evtOwner,
Oid  funcoid,
List tags 
)
static

Definition at line 375 of file event_trigger.c.

References Anum_pg_event_trigger_evtenabled, Anum_pg_event_trigger_evtevent, Anum_pg_event_trigger_evtfoid, Anum_pg_event_trigger_evtname, Anum_pg_event_trigger_evtowner, Anum_pg_event_trigger_evttags, CatalogTupleInsert(), CharGetDatum, ObjectAddress::classId, DEPENDENCY_NORMAL, EventTriggerRelationId, filter_list_to_array(), heap_close, heap_form_tuple(), heap_freetuple(), heap_open(), InvokeObjectPostCreateHook, NameGetDatum, namestrcpy(), Natts_pg_trigger, NIL, ObjectAddress::objectId, ObjectIdGetDatum, ObjectAddress::objectSubId, ProcedureRelationId, RelationData::rd_att, recordDependencyOn(), recordDependencyOnCurrentExtension(), recordDependencyOnOwner(), RowExclusiveLock, TRIGGER_FIRES_ON_ORIGIN, and values.

Referenced by CreateEventTrigger().

377 {
378  Relation tgrel;
379  Oid trigoid;
380  HeapTuple tuple;
382  bool nulls[Natts_pg_trigger];
383  NameData evtnamedata,
384  evteventdata;
385  ObjectAddress myself,
386  referenced;
387 
388  /* Open pg_event_trigger. */
390 
391  /* Build the new pg_trigger tuple. */
392  memset(nulls, false, sizeof(nulls));
393  namestrcpy(&evtnamedata, trigname);
394  values[Anum_pg_event_trigger_evtname - 1] = NameGetDatum(&evtnamedata);
395  namestrcpy(&evteventdata, eventname);
396  values[Anum_pg_event_trigger_evtevent - 1] = NameGetDatum(&evteventdata);
397  values[Anum_pg_event_trigger_evtowner - 1] = ObjectIdGetDatum(evtOwner);
398  values[Anum_pg_event_trigger_evtfoid - 1] = ObjectIdGetDatum(funcoid);
401  if (taglist == NIL)
402  nulls[Anum_pg_event_trigger_evttags - 1] = true;
403  else
404  values[Anum_pg_event_trigger_evttags - 1] =
405  filter_list_to_array(taglist);
406 
407  /* Insert heap tuple. */
408  tuple = heap_form_tuple(tgrel->rd_att, values, nulls);
409  trigoid = CatalogTupleInsert(tgrel, tuple);
410  heap_freetuple(tuple);
411 
412  /* Depend on owner. */
414 
415  /* Depend on event trigger function. */
417  myself.objectId = trigoid;
418  myself.objectSubId = 0;
419  referenced.classId = ProcedureRelationId;
420  referenced.objectId = funcoid;
421  referenced.objectSubId = 0;
422  recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
423 
424  /* Depend on extension, if any. */
425  recordDependencyOnCurrentExtension(&myself, false);
426 
427  /* Post creation hook for new event trigger */
429 
430  /* Close pg_event_trigger. */
432 
433  return trigoid;
434 }
#define Anum_pg_event_trigger_evtname
#define NIL
Definition: pg_list.h:69
#define Anum_pg_event_trigger_evtevent
#define NameGetDatum(X)
Definition: postgres.h:601
#define InvokeObjectPostCreateHook(classId, objectId, subId)
Definition: objectaccess.h:145
#define ProcedureRelationId
Definition: pg_proc.h:33
void recordDependencyOn(const ObjectAddress *depender, const ObjectAddress *referenced, DependencyType behavior)
Definition: pg_depend.c:44
HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, Datum *values, bool *isnull)
Definition: heaptuple.c:692
#define heap_close(r, l)
Definition: heapam.h:97
void recordDependencyOnOwner(Oid classId, Oid objectId, Oid owner)
Definition: pg_shdepend.c:159
#define Anum_pg_event_trigger_evtfoid
void heap_freetuple(HeapTuple htup)
Definition: heaptuple.c:1374
unsigned int Oid
Definition: postgres_ext.h:31
int namestrcpy(Name name, const char *str)
Definition: name.c:217
#define TRIGGER_FIRES_ON_ORIGIN
Definition: trigger.h:109
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
Oid CatalogTupleInsert(Relation heapRel, HeapTuple tup)
Definition: indexing.c:162
static Datum filter_list_to_array(List *filterlist)
Definition: c.h:493
#define RowExclusiveLock
Definition: lockdefs.h:38
uintptr_t Datum
Definition: postgres.h:372
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1287
TupleDesc rd_att
Definition: rel.h:115
#define EventTriggerRelationId
void recordDependencyOnCurrentExtension(const ObjectAddress *object, bool isReplace)
Definition: pg_depend.c:139
#define Anum_pg_event_trigger_evttags
#define Anum_pg_event_trigger_evtenabled
#define CharGetDatum(X)
Definition: postgres.h:422
static Datum values[MAXATTR]
Definition: bootstrap.c:162
#define Anum_pg_event_trigger_evtowner
#define Natts_pg_trigger
Definition: pg_trigger.h:78
Datum pg_event_trigger_ddl_commands ( PG_FUNCTION_ARGS  )

Definition at line 1982 of file event_trigger.c.

References AccessShareLock, ReturnSetInfo::allowedModes, CollectedCommand::alterTable, CollectedCommand::atscfg, BoolGetDatum, ObjectAddress::classId, EventTriggerQueryState::commandList, CreateCommandTag(), 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(), getObjectIdentity(), getObjectTypeDescription(), CollectedCommand::grant, heap_close, heap_getattr, heap_open(), HeapTupleIsValid, i, CollectedCommand::in_extension, Int32GetDatum, InvalidAttrNumber, is_objectclass_supported(), IsA, isAnyTempNamespace(), lfirst, MemoryContextSwitchTo(), MemSet, NULL, 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_grantobjtype(), tuplestore_begin_heap(), tuplestore_donestoring, tuplestore_putvalues(), CollectedCommand::type, TYPEFUNC_COMPOSITE, values, and work_mem.

1983 {
1984  ReturnSetInfo *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo;
1985  TupleDesc tupdesc;
1986  Tuplestorestate *tupstore;
1987  MemoryContext per_query_ctx;
1988  MemoryContext oldcontext;
1989  ListCell *lc;
1990 
1991  /*
1992  * Protect this function from being called out of context
1993  */
1995  ereport(ERROR,
1996  (errcode(ERRCODE_E_R_I_E_EVENT_TRIGGER_PROTOCOL_VIOLATED),
1997  errmsg("%s can only be called in an event trigger function",
1998  "pg_event_trigger_ddl_commands()")));
1999 
2000  /* check to see if caller supports us returning a tuplestore */
2001  if (rsinfo == NULL || !IsA(rsinfo, ReturnSetInfo))
2002  ereport(ERROR,
2003  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2004  errmsg("set-valued function called in context that cannot accept a set")));
2005  if (!(rsinfo->allowedModes & SFRM_Materialize))
2006  ereport(ERROR,
2007  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2008  errmsg("materialize mode required, but it is not allowed in this context")));
2009 
2010  /* Build a tuple descriptor for our result type */
2011  if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
2012  elog(ERROR, "return type must be a row type");
2013 
2014  /* Build tuplestore to hold the result rows */
2015  per_query_ctx = rsinfo->econtext->ecxt_per_query_memory;
2016  oldcontext = MemoryContextSwitchTo(per_query_ctx);
2017 
2018  tupstore = tuplestore_begin_heap(true, false, work_mem);
2019  rsinfo->returnMode = SFRM_Materialize;
2020  rsinfo->setResult = tupstore;
2021  rsinfo->setDesc = tupdesc;
2022 
2023  MemoryContextSwitchTo(oldcontext);
2024 
2026  {
2027  CollectedCommand *cmd = lfirst(lc);
2028  Datum values[9];
2029  bool nulls[9];
2030  ObjectAddress addr;
2031  int i = 0;
2032 
2033  /*
2034  * For IF NOT EXISTS commands that attempt to create an existing
2035  * object, the returned OID is Invalid. Don't return anything.
2036  *
2037  * One might think that a viable alternative would be to look up the
2038  * Oid of the existing object and run the deparse with that. But
2039  * since the parse tree might be different from the one that created
2040  * the object in the first place, we might not end up in a consistent
2041  * state anyway.
2042  */
2043  if (cmd->type == SCT_Simple &&
2044  !OidIsValid(cmd->d.simple.address.objectId))
2045  continue;
2046 
2047  MemSet(nulls, 0, sizeof(nulls));
2048 
2049  switch (cmd->type)
2050  {
2051  case SCT_Simple:
2052  case SCT_AlterTable:
2053  case SCT_AlterOpFamily:
2054  case SCT_CreateOpClass:
2055  case SCT_AlterTSConfig:
2056  {
2057  char *identity;
2058  char *type;
2059  char *schema = NULL;
2060 
2061  if (cmd->type == SCT_Simple)
2062  addr = cmd->d.simple.address;
2063  else if (cmd->type == SCT_AlterTable)
2064  ObjectAddressSet(addr,
2065  cmd->d.alterTable.classId,
2066  cmd->d.alterTable.objectId);
2067  else if (cmd->type == SCT_AlterOpFamily)
2068  addr = cmd->d.opfam.address;
2069  else if (cmd->type == SCT_CreateOpClass)
2070  addr = cmd->d.createopc.address;
2071  else if (cmd->type == SCT_AlterTSConfig)
2072  addr = cmd->d.atscfg.address;
2073 
2074  type = getObjectTypeDescription(&addr);
2075  identity = getObjectIdentity(&addr);
2076 
2077  /*
2078  * Obtain schema name, if any ("pg_temp" if a temp
2079  * object). If the object class is not in the supported
2080  * list here, we assume it's a schema-less object type,
2081  * and thus "schema" remains set to NULL.
2082  */
2084  {
2085  AttrNumber nspAttnum;
2086 
2087  nspAttnum = get_object_attnum_namespace(addr.classId);
2088  if (nspAttnum != InvalidAttrNumber)
2089  {
2090  Relation catalog;
2091  HeapTuple objtup;
2092  Oid schema_oid;
2093  bool isnull;
2094 
2095  catalog = heap_open(addr.classId, AccessShareLock);
2096  objtup = get_catalog_object_by_oid(catalog,
2097  addr.objectId);
2098  if (!HeapTupleIsValid(objtup))
2099  elog(ERROR, "cache lookup failed for object %u/%u",
2100  addr.classId, addr.objectId);
2101  schema_oid =
2102  heap_getattr(objtup, nspAttnum,
2103  RelationGetDescr(catalog), &isnull);
2104  if (isnull)
2105  elog(ERROR,
2106  "invalid null namespace in object %u/%u/%d",
2107  addr.classId, addr.objectId, addr.objectSubId);
2108  /* XXX not quite get_namespace_name_or_temp */
2109  if (isAnyTempNamespace(schema_oid))
2110  schema = pstrdup("pg_temp");
2111  else
2112  schema = get_namespace_name(schema_oid);
2113 
2114  heap_close(catalog, AccessShareLock);
2115  }
2116  }
2117 
2118  /* classid */
2119  values[i++] = ObjectIdGetDatum(addr.classId);
2120  /* objid */
2121  values[i++] = ObjectIdGetDatum(addr.objectId);
2122  /* objsubid */
2123  values[i++] = Int32GetDatum(addr.objectSubId);
2124  /* command tag */
2125  values[i++] = CStringGetTextDatum(CreateCommandTag(cmd->parsetree));
2126  /* object_type */
2127  values[i++] = CStringGetTextDatum(type);
2128  /* schema */
2129  if (schema == NULL)
2130  nulls[i++] = true;
2131  else
2132  values[i++] = CStringGetTextDatum(schema);
2133  /* identity */
2134  values[i++] = CStringGetTextDatum(identity);
2135  /* in_extension */
2136  values[i++] = BoolGetDatum(cmd->in_extension);
2137  /* command */
2138  values[i++] = PointerGetDatum(cmd);
2139  }
2140  break;
2141 
2143  /* classid */
2144  nulls[i++] = true;
2145  /* objid */
2146  nulls[i++] = true;
2147  /* objsubid */
2148  nulls[i++] = true;
2149  /* command tag */
2150  values[i++] = CStringGetTextDatum(CreateCommandTag(cmd->parsetree));
2151  /* object_type */
2153  cmd->d.defprivs.objtype));
2154  /* schema */
2155  nulls[i++] = true;
2156  /* identity */
2157  nulls[i++] = true;
2158  /* in_extension */
2159  values[i++] = BoolGetDatum(cmd->in_extension);
2160  /* command */
2161  values[i++] = PointerGetDatum(cmd);
2162  break;
2163 
2164  case SCT_Grant:
2165  /* classid */
2166  nulls[i++] = true;
2167  /* objid */
2168  nulls[i++] = true;
2169  /* objsubid */
2170  nulls[i++] = true;
2171  /* command tag */
2172  values[i++] = CStringGetTextDatum(cmd->d.grant.istmt->is_grant ?
2173  "GRANT" : "REVOKE");
2174  /* object_type */
2176  cmd->d.grant.istmt->objtype));
2177  /* schema */
2178  nulls[i++] = true;
2179  /* identity */
2180  nulls[i++] = true;
2181  /* in_extension */
2182  values[i++] = BoolGetDatum(cmd->in_extension);
2183  /* command */
2184  values[i++] = PointerGetDatum(cmd);
2185  break;
2186  }
2187 
2188  tuplestore_putvalues(tupstore, tupdesc, values, nulls);
2189  }
2190 
2191  /* clean up and return the tuplestore */
2192  tuplestore_donestoring(tupstore);
2193 
2194  PG_RETURN_VOID();
2195 }
void tuplestore_putvalues(Tuplestorestate *state, TupleDesc tdesc, Datum *values, bool *isnull)
Definition: tuplestore.c:735
#define IsA(nodeptr, _type_)
Definition: nodes.h:555
TypeFuncClass get_call_result_type(FunctionCallInfo fcinfo, Oid *resultTypeId, TupleDesc *resultTupleDesc)
Definition: funcapi.c:211
struct CollectedCommand::@95::@96 simple
struct CollectedCommand::@95::@102 defprivs
char * getObjectTypeDescription(const ObjectAddress *object)
#define RelationGetDescr(relation)
Definition: rel.h:429
#define PointerGetDatum(X)
Definition: postgres.h:562
char * pstrdup(const char *in)
Definition: mcxt.c:1077
union CollectedCommand::@95 d
#define tuplestore_donestoring(state)
Definition: tuplestore.h:60
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
#define AccessShareLock
Definition: lockdefs.h:36
static const char * stringify_adefprivs_objtype(GrantObjectType objtype)
int errcode(int sqlerrcode)
Definition: elog.c:575
#define MemSet(start, val, len)
Definition: c.h:857
AttrNumber get_object_attnum_namespace(Oid class_id)
#define heap_close(r, l)
Definition: heapam.h:97
CollectedCommandType type
unsigned int Oid
Definition: postgres_ext.h:31
struct CollectedCommand::@95::@100 createopc
#define OidIsValid(objectId)
Definition: c.h:538
static EventTriggerQueryState * currentEventTriggerState
Definition: event_trigger.c:72
static const char * stringify_grantobjtype(GrantObjectType objtype)
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define ERROR
Definition: elog.h:43
char * getObjectIdentity(const ObjectAddress *object)
char * get_namespace_name(Oid nspid)
Definition: lsyscache.c:3006
struct CollectedCommand::@95::@97 alterTable
#define ereport(elevel, rest)
Definition: elog.h:122
const char * CreateCommandTag(Node *parsetree)
Definition: utility.c:2024
#define heap_getattr(tup, attnum, tupleDesc, isnull)
Definition: htup_details.h:769
Tuplestorestate * tuplestore_begin_heap(bool randomAccess, bool interXact, int maxKBytes)
Definition: tuplestore.c:316
uintptr_t Datum
Definition: postgres.h:372
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1287
int work_mem
Definition: globals.c:112
#define BoolGetDatum(X)
Definition: postgres.h:408
int allowedModes
Definition: execnodes.h:267
#define PG_RETURN_VOID()
Definition: fmgr.h:309
SetFunctionReturnMode returnMode
Definition: execnodes.h:269
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
#define NULL
Definition: c.h:229
#define lfirst(lc)
Definition: pg_list.h:106
MemoryContext ecxt_per_query_memory
Definition: execnodes.h:201
HeapTuple get_catalog_object_by_oid(Relation catalog, Oid objectId)
#define InvalidAttrNumber
Definition: attnum.h:23
#define ObjectAddressSet(addr, class_id, object_id)
Definition: objectaddress.h:40
Tuplestorestate * setResult
Definition: execnodes.h:272
struct CollectedCommand::@95::@98 grant
static Datum values[MAXATTR]
Definition: bootstrap.c:162
ExprContext * econtext
Definition: execnodes.h:265
#define Int32GetDatum(X)
Definition: postgres.h:485
TupleDesc setDesc
Definition: execnodes.h:273
struct CollectedCommand::@95::@101 atscfg
int errmsg(const char *fmt,...)
Definition: elog.c:797
int i
#define CStringGetTextDatum(s)
Definition: builtins.h:91
bool isAnyTempNamespace(Oid namespaceId)
Definition: namespace.c:3046
#define elog
Definition: elog.h:219
bool is_objectclass_supported(Oid class_id)
struct CollectedCommand::@95::@99 opfam
int16 AttrNumber
Definition: attnum.h:21
Datum pg_event_trigger_dropped_objects ( PG_FUNCTION_ARGS  )

Definition at line 1430 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, NULL, 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(), TEXTOID, tuplestore_begin_heap(), tuplestore_donestoring, tuplestore_putvalues(), TYPEFUNC_COMPOSITE, values, and work_mem.

1431 {
1432  ReturnSetInfo *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo;
1433  TupleDesc tupdesc;
1434  Tuplestorestate *tupstore;
1435  MemoryContext per_query_ctx;
1436  MemoryContext oldcontext;
1437  slist_iter iter;
1438 
1439  /*
1440  * Protect this function from being called out of context
1441  */
1442  if (!currentEventTriggerState ||
1444  ereport(ERROR,
1445  (errcode(ERRCODE_E_R_I_E_EVENT_TRIGGER_PROTOCOL_VIOLATED),
1446  errmsg("%s can only be called in a sql_drop event trigger function",
1447  "pg_event_trigger_dropped_objects()")));
1448 
1449  /* check to see if caller supports us returning a tuplestore */
1450  if (rsinfo == NULL || !IsA(rsinfo, ReturnSetInfo))
1451  ereport(ERROR,
1452  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1453  errmsg("set-valued function called in context that cannot accept a set")));
1454  if (!(rsinfo->allowedModes & SFRM_Materialize))
1455  ereport(ERROR,
1456  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1457  errmsg("materialize mode required, but it is not allowed in this context")));
1458 
1459  /* Build a tuple descriptor for our result type */
1460  if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
1461  elog(ERROR, "return type must be a row type");
1462 
1463  /* Build tuplestore to hold the result rows */
1464  per_query_ctx = rsinfo->econtext->ecxt_per_query_memory;
1465  oldcontext = MemoryContextSwitchTo(per_query_ctx);
1466 
1467  tupstore = tuplestore_begin_heap(true, false, work_mem);
1468  rsinfo->returnMode = SFRM_Materialize;
1469  rsinfo->setResult = tupstore;
1470  rsinfo->setDesc = tupdesc;
1471 
1472  MemoryContextSwitchTo(oldcontext);
1473 
1475  {
1476  SQLDropObject *obj;
1477  int i = 0;
1478  Datum values[12];
1479  bool nulls[12];
1480 
1481  obj = slist_container(SQLDropObject, next, iter.cur);
1482 
1483  MemSet(values, 0, sizeof(values));
1484  MemSet(nulls, 0, sizeof(nulls));
1485 
1486  /* classid */
1487  values[i++] = ObjectIdGetDatum(obj->address.classId);
1488 
1489  /* objid */
1490  values[i++] = ObjectIdGetDatum(obj->address.objectId);
1491 
1492  /* objsubid */
1493  values[i++] = Int32GetDatum(obj->address.objectSubId);
1494 
1495  /* original */
1496  values[i++] = BoolGetDatum(obj->original);
1497 
1498  /* normal */
1499  values[i++] = BoolGetDatum(obj->normal);
1500 
1501  /* is_temporary */
1502  values[i++] = BoolGetDatum(obj->istemp);
1503 
1504  /* object_type */
1505  values[i++] = CStringGetTextDatum(obj->objecttype);
1506 
1507  /* schema_name */
1508  if (obj->schemaname)
1509  values[i++] = CStringGetTextDatum(obj->schemaname);
1510  else
1511  nulls[i++] = true;
1512 
1513  /* object_name */
1514  if (obj->objname)
1515  values[i++] = CStringGetTextDatum(obj->objname);
1516  else
1517  nulls[i++] = true;
1518 
1519  /* object_identity */
1520  if (obj->objidentity)
1521  values[i++] = CStringGetTextDatum(obj->objidentity);
1522  else
1523  nulls[i++] = true;
1524 
1525  /* address_names and address_args */
1526  if (obj->addrnames)
1527  {
1528  values[i++] = PointerGetDatum(strlist_to_textarray(obj->addrnames));
1529 
1530  if (obj->addrargs)
1531  values[i++] = PointerGetDatum(strlist_to_textarray(obj->addrargs));
1532  else
1534  }
1535  else
1536  {
1537  nulls[i++] = true;
1538  nulls[i++] = true;
1539  }
1540 
1541  tuplestore_putvalues(tupstore, tupdesc, values, nulls);
1542  }
1543 
1544  /* clean up and return the tuplestore */
1545  tuplestore_donestoring(tupstore);
1546 
1547  return (Datum) 0;
1548 }
void tuplestore_putvalues(Tuplestorestate *state, TupleDesc tdesc, Datum *values, bool *isnull)
Definition: tuplestore.c:735
#define IsA(nodeptr, _type_)
Definition: nodes.h:555
TypeFuncClass get_call_result_type(FunctionCallInfo fcinfo, Oid *resultTypeId, TupleDesc *resultTupleDesc)
Definition: funcapi.c:211
static int32 next
Definition: blutils.c:210
ObjectAddress address
#define TEXTOID
Definition: pg_type.h:324
#define PointerGetDatum(X)
Definition: postgres.h:562
const char * objname
#define tuplestore_donestoring(state)
Definition: tuplestore.h:60
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
int errcode(int sqlerrcode)
Definition: elog.c:575
#define MemSet(start, val, len)
Definition: c.h:857
const char * objidentity
ArrayType * construct_empty_array(Oid elmtype)
Definition: arrayfuncs.c:3424
const char * objecttype
static EventTriggerQueryState * currentEventTriggerState
Definition: event_trigger.c:72
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
const char * schemaname
Tuplestorestate * tuplestore_begin_heap(bool randomAccess, bool interXact, int maxKBytes)
Definition: tuplestore.c:316
#define slist_container(type, membername, ptr)
Definition: ilist.h:674
uintptr_t Datum
Definition: postgres.h:372
int work_mem
Definition: globals.c:112
#define BoolGetDatum(X)
Definition: postgres.h:408
int allowedModes
Definition: execnodes.h:267
SetFunctionReturnMode returnMode
Definition: execnodes.h:269
#define NULL
Definition: c.h:229
MemoryContext ecxt_per_query_memory
Definition: execnodes.h:201
Tuplestorestate * setResult
Definition: execnodes.h:272
static Datum values[MAXATTR]
Definition: bootstrap.c:162
ExprContext * econtext
Definition: execnodes.h:265
#define slist_foreach(iter, lhead)
Definition: ilist.h:700
#define Int32GetDatum(X)
Definition: postgres.h:485
TupleDesc setDesc
Definition: execnodes.h:273
int errmsg(const char *fmt,...)
Definition: elog.c:797
int i
#define CStringGetTextDatum(s)
Definition: builtins.h:91
ArrayType * strlist_to_textarray(List *list)
#define elog
Definition: elog.h:219
Datum pg_event_trigger_table_rewrite_oid ( PG_FUNCTION_ARGS  )

Definition at line 1557 of file event_trigger.c.

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

1558 {
1559  /*
1560  * Protect this function from being called out of context
1561  */
1562  if (!currentEventTriggerState ||
1564  ereport(ERROR,
1565  (errcode(ERRCODE_E_R_I_E_EVENT_TRIGGER_PROTOCOL_VIOLATED),
1566  errmsg("%s can only be called in a table_rewrite event trigger function",
1567  "pg_event_trigger_table_rewrite_oid()")));
1568 
1570 }
int errcode(int sqlerrcode)
Definition: elog.c:575
static EventTriggerQueryState * currentEventTriggerState
Definition: event_trigger.c:72
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
#define InvalidOid
Definition: postgres_ext.h:36
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define PG_RETURN_OID(x)
Definition: fmgr.h:320
Datum pg_event_trigger_table_rewrite_reason ( PG_FUNCTION_ARGS  )

Definition at line 1578 of file event_trigger.c.

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

1579 {
1580  /*
1581  * Protect this function from being called out of context
1582  */
1583  if (!currentEventTriggerState ||
1585  ereport(ERROR,
1586  (errcode(ERRCODE_E_R_I_E_EVENT_TRIGGER_PROTOCOL_VIOLATED),
1587  errmsg("%s can only be called in a table_rewrite event trigger function",
1588  "pg_event_trigger_table_rewrite_reason()")));
1589 
1591 }
#define PG_RETURN_INT32(x)
Definition: fmgr.h:314
int errcode(int sqlerrcode)
Definition: elog.c:575
static EventTriggerQueryState * currentEventTriggerState
Definition: event_trigger.c:72
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
int errmsg(const char *fmt,...)
Definition: elog.c:797
void RemoveEventTriggerById ( Oid  trigOid)

Definition at line 477 of file event_trigger.c.

References CatalogTupleDelete(), elog, ERROR, EVENTTRIGGEROID, EventTriggerRelationId, heap_close, heap_open(), HeapTupleIsValid, ObjectIdGetDatum, ReleaseSysCache(), RowExclusiveLock, SearchSysCache1, and HeapTupleData::t_self.

Referenced by doDeletion().

478 {
479  Relation tgrel;
480  HeapTuple tup;
481 
483 
485  if (!HeapTupleIsValid(tup))
486  elog(ERROR, "cache lookup failed for event trigger %u", trigOid);
487 
488  CatalogTupleDelete(tgrel, &tup->t_self);
489 
490  ReleaseSysCache(tup);
491 
493 }
void CatalogTupleDelete(Relation heapRel, ItemPointer tid)
Definition: indexing.c:255
#define heap_close(r, l)
Definition: heapam.h:97
#define SearchSysCache1(cacheId, key1)
Definition: syscache.h:152
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define ERROR
Definition: elog.h:43
ItemPointerData t_self
Definition: htup.h:65
#define RowExclusiveLock
Definition: lockdefs.h:38
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1116
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1287
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
#define EventTriggerRelationId
#define elog
Definition: elog.h:219
static const char * stringify_adefprivs_objtype ( GrantObjectType  objtype)
static

Definition at line 2243 of file event_trigger.c.

References ACL_OBJECT_FUNCTION, ACL_OBJECT_RELATION, ACL_OBJECT_SEQUENCE, ACL_OBJECT_TYPE, elog, and ERROR.

Referenced by pg_event_trigger_ddl_commands().

2244 {
2245  switch (objtype)
2246  {
2247  case ACL_OBJECT_RELATION:
2248  return "TABLES";
2249  break;
2250  case ACL_OBJECT_FUNCTION:
2251  return "FUNCTIONS";
2252  break;
2253  case ACL_OBJECT_SEQUENCE:
2254  return "SEQUENCES";
2255  break;
2256  case ACL_OBJECT_TYPE:
2257  return "TYPES";
2258  break;
2259  default:
2260  elog(ERROR, "unrecognized type %d", objtype);
2261  return "???"; /* keep compiler quiet */
2262  }
2263 }
#define ERROR
Definition: elog.h:43
#define elog
Definition: elog.h:219
static const char * stringify_grantobjtype ( GrantObjectType  objtype)
static

Definition at line 2202 of file event_trigger.c.

References ACL_OBJECT_COLUMN, ACL_OBJECT_DATABASE, ACL_OBJECT_DOMAIN, ACL_OBJECT_FDW, ACL_OBJECT_FOREIGN_SERVER, ACL_OBJECT_FUNCTION, ACL_OBJECT_LANGUAGE, ACL_OBJECT_LARGEOBJECT, ACL_OBJECT_NAMESPACE, ACL_OBJECT_RELATION, ACL_OBJECT_SEQUENCE, ACL_OBJECT_TABLESPACE, ACL_OBJECT_TYPE, elog, and ERROR.

Referenced by pg_event_trigger_ddl_commands().

2203 {
2204  switch (objtype)
2205  {
2206  case ACL_OBJECT_COLUMN:
2207  return "COLUMN";
2208  case ACL_OBJECT_RELATION:
2209  return "TABLE";
2210  case ACL_OBJECT_SEQUENCE:
2211  return "SEQUENCE";
2212  case ACL_OBJECT_DATABASE:
2213  return "DATABASE";
2214  case ACL_OBJECT_DOMAIN:
2215  return "DOMAIN";
2216  case ACL_OBJECT_FDW:
2217  return "FOREIGN DATA WRAPPER";
2219  return "FOREIGN SERVER";
2220  case ACL_OBJECT_FUNCTION:
2221  return "FUNCTION";
2222  case ACL_OBJECT_LANGUAGE:
2223  return "LANGUAGE";
2225  return "LARGE OBJECT";
2226  case ACL_OBJECT_NAMESPACE:
2227  return "SCHEMA";
2228  case ACL_OBJECT_TABLESPACE:
2229  return "TABLESPACE";
2230  case ACL_OBJECT_TYPE:
2231  return "TYPE";
2232  default:
2233  elog(ERROR, "unrecognized type %d", objtype);
2234  return "???"; /* keep compiler quiet */
2235  }
2236 }
#define ERROR
Definition: elog.h:43
#define elog
Definition: elog.h:219
bool trackDroppedObjectsNeeded ( void  )

Definition at line 1282 of file event_trigger.c.

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

Referenced by deleteObjectsInList(), and EventTriggerBeginCompleteQuery().

1283 {
1284  /*
1285  * true if any sql_drop, table_rewrite, ddl_command_end event trigger
1286  * exists
1287  */
1288  return list_length(EventCacheLookup(EVT_SQLDrop)) > 0 ||
1291 }
static int list_length(const List *l)
Definition: pg_list.h:89
List * EventCacheLookup(EventTriggerEvent event)
Definition: evtcache.c:64
static void validate_ddl_tags ( const char *  filtervar,
List taglist 
)
static

Definition at line 255 of file event_trigger.c.

References check_ddl_tag(), ereport, errcode(), errmsg(), ERROR, EVENT_TRIGGER_COMMAND_TAG_NOT_RECOGNIZED, EVENT_TRIGGER_COMMAND_TAG_NOT_SUPPORTED, lfirst, result, and strVal.

Referenced by CreateEventTrigger().

256 {
257  ListCell *lc;
258 
259  foreach(lc, taglist)
260  {
261  const char *tag = strVal(lfirst(lc));
263 
264  result = check_ddl_tag(tag);
266  ereport(ERROR,
267  (errcode(ERRCODE_SYNTAX_ERROR),
268  errmsg("filter value \"%s\" not recognized for filter variable \"%s\"",
269  tag, filtervar)));
271  ereport(ERROR,
272  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
273  /* translator: %s represents an SQL statement name */
274  errmsg("event triggers are not supported for %s",
275  tag)));
276  }
277 }
#define strVal(v)
Definition: value.h:54
int errcode(int sqlerrcode)
Definition: elog.c:575
return result
Definition: formatting.c:1618
static event_trigger_command_tag_check_result check_ddl_tag(const char *tag)
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
event_trigger_command_tag_check_result
Definition: event_trigger.c:80
#define lfirst(lc)
Definition: pg_list.h:106
int errmsg(const char *fmt,...)
Definition: elog.c:797
static void validate_table_rewrite_tags ( const char *  filtervar,
List taglist 
)
static

Definition at line 330 of file event_trigger.c.

References check_table_rewrite_ddl_tag(), ereport, errcode(), errmsg(), ERROR, EVENT_TRIGGER_COMMAND_TAG_NOT_SUPPORTED, lfirst, result, and strVal.

Referenced by CreateEventTrigger().

331 {
332  ListCell *lc;
333 
334  foreach(lc, taglist)
335  {
336  const char *tag = strVal(lfirst(lc));
338 
339  result = check_table_rewrite_ddl_tag(tag);
341  ereport(ERROR,
342  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
343  /* translator: %s represents an SQL statement name */
344  errmsg("event triggers are not supported for %s",
345  tag)));
346  }
347 }
#define strVal(v)
Definition: value.h:54
int errcode(int sqlerrcode)
Definition: elog.c:575
return result
Definition: formatting.c:1618
#define ERROR
Definition: elog.h:43
static event_trigger_command_tag_check_result check_table_rewrite_ddl_tag(const char *tag)
#define ereport(elevel, rest)
Definition: elog.h:122
event_trigger_command_tag_check_result
Definition: event_trigger.c:80
#define lfirst(lc)
Definition: pg_list.h:106
int errmsg(const char *fmt,...)
Definition: elog.c:797

Variable Documentation

EventTriggerQueryState* currentEventTriggerState = NULL
static

Definition at line 72 of file event_trigger.c.

Referenced by EventTriggerBeginCompleteQuery().

event_trigger_support_data event_trigger_support[]
static

Definition at line 88 of file event_trigger.c.