#include "catalog/dependency.h"#include "catalog/objectaddress.h"#include "catalog/pg_event_trigger.h"#include "nodes/parsenodes.h"

Go to the source code of this file.
Data Structures | |
| struct | EventTriggerData |
Defines | |
| #define | CALLED_AS_EVENT_TRIGGER(fcinfo) ((fcinfo)->context != NULL && IsA((fcinfo)->context, EventTriggerData)) |
Typedefs | |
| typedef struct EventTriggerData | EventTriggerData |
Functions | |
| Oid | CreateEventTrigger (CreateEventTrigStmt *stmt) |
| void | RemoveEventTriggerById (Oid ctrigOid) |
| Oid | get_event_trigger_oid (const char *trigname, bool missing_ok) |
| Oid | AlterEventTrigger (AlterEventTrigStmt *stmt) |
| Oid | AlterEventTriggerOwner (const char *name, Oid newOwnerId) |
| void | AlterEventTriggerOwner_oid (Oid, Oid newOwnerId) |
| bool | EventTriggerSupportsObjectType (ObjectType obtype) |
| bool | EventTriggerSupportsObjectClass (ObjectClass objclass) |
| void | EventTriggerDDLCommandStart (Node *parsetree) |
| void | EventTriggerDDLCommandEnd (Node *parsetree) |
| void | EventTriggerSQLDrop (Node *parsetree) |
| bool | EventTriggerBeginCompleteQuery (void) |
| void | EventTriggerEndCompleteQuery (void) |
| bool | trackDroppedObjectsNeeded (void) |
| void | EventTriggerSQLDropAddObject (ObjectAddress *object) |
| #define CALLED_AS_EVENT_TRIGGER | ( | fcinfo | ) | ((fcinfo)->context != NULL && IsA((fcinfo)->context, EventTriggerData)) |
Definition at line 33 of file event_trigger.h.
Referenced by do_compile(), and plpgsql_call_handler().
| typedef struct EventTriggerData EventTriggerData |
| Oid AlterEventTrigger | ( | AlterEventTrigStmt * | stmt | ) |
Definition at line 414 of file event_trigger.c.
References ACL_KIND_EVENT_TRIGGER, aclcheck_error(), ACLCHECK_NOT_OWNER, CatalogUpdateIndexes(), CStringGetDatum, ereport, errcode(), errmsg(), ERROR, EVENTTRIGGERNAME, EventTriggerRelationId, GETSTRUCT, GetUserId(), heap_close, heap_freetuple(), heap_open(), HeapTupleGetOid, HeapTupleIsValid, InvokeObjectPostAlterHook, pg_event_trigger_ownercheck(), RowExclusiveLock, SearchSysCacheCopy1, simple_heap_update(), HeapTupleData::t_self, AlterEventTrigStmt::tgenabled, and AlterEventTrigStmt::trigname.
Referenced by standard_ProcessUtility().
{
Relation tgrel;
HeapTuple tup;
Oid trigoid;
Form_pg_event_trigger evtForm;
char tgenabled = stmt->tgenabled;
tgrel = heap_open(EventTriggerRelationId, RowExclusiveLock);
tup = SearchSysCacheCopy1(EVENTTRIGGERNAME,
CStringGetDatum(stmt->trigname));
if (!HeapTupleIsValid(tup))
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("event trigger \"%s\" does not exist",
stmt->trigname)));
trigoid = HeapTupleGetOid(tup);
if (!pg_event_trigger_ownercheck(trigoid, GetUserId()))
aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_EVENT_TRIGGER,
stmt->trigname);
/* tuple is a copy, so we can modify it below */
evtForm = (Form_pg_event_trigger) GETSTRUCT(tup);
evtForm->evtenabled = tgenabled;
simple_heap_update(tgrel, &tup->t_self, tup);
CatalogUpdateIndexes(tgrel, tup);
InvokeObjectPostAlterHook(EventTriggerRelationId,
trigoid, 0);
/* clean up */
heap_freetuple(tup);
heap_close(tgrel, RowExclusiveLock);
return trigoid;
}
Definition at line 459 of file event_trigger.c.
References AlterEventTriggerOwner_internal(), CStringGetDatum, ereport, errcode(), errmsg(), ERROR, EVENTTRIGGERNAME, EventTriggerRelationId, heap_close, heap_freetuple(), heap_open(), HeapTupleGetOid, HeapTupleIsValid, RowExclusiveLock, and SearchSysCacheCopy1.
Referenced by ExecAlterOwnerStmt().
{
Oid evtOid;
HeapTuple tup;
Relation rel;
rel = heap_open(EventTriggerRelationId, RowExclusiveLock);
tup = SearchSysCacheCopy1(EVENTTRIGGERNAME, CStringGetDatum(name));
if (!HeapTupleIsValid(tup))
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("event trigger \"%s\" does not exist", name)));
evtOid = HeapTupleGetOid(tup);
AlterEventTriggerOwner_internal(rel, tup, newOwnerId);
heap_freetuple(tup);
heap_close(rel, RowExclusiveLock);
return evtOid;
}
Definition at line 489 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().
{
HeapTuple tup;
Relation rel;
rel = heap_open(EventTriggerRelationId, RowExclusiveLock);
tup = SearchSysCacheCopy1(EVENTTRIGGEROID, ObjectIdGetDatum(trigOid));
if (!HeapTupleIsValid(tup))
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("event trigger with OID %u does not exist", trigOid)));
AlterEventTriggerOwner_internal(rel, tup, newOwnerId);
heap_freetuple(tup);
heap_close(rel, RowExclusiveLock);
}
| Oid CreateEventTrigger | ( | CreateEventTrigStmt * | stmt | ) |
Definition at line 132 of file event_trigger.c.
References DefElem::arg, CStringGetDatum, DefElem::defname, ereport, errcode(), 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(), and CreateEventTrigStmt::whenclause.
Referenced by standard_ProcessUtility().
{
HeapTuple tuple;
Oid funcoid;
Oid funcrettype;
Oid evtowner = GetUserId();
ListCell *lc;
List *tags = NULL;
/*
* It would be nice to allow database owners or even regular users to do
* this, but there are obvious privilege escalation risks which would have
* to somehow be plugged first.
*/
if (!superuser())
ereport(ERROR,
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
errmsg("permission denied to create event trigger \"%s\"",
stmt->trigname),
errhint("Must be superuser to create an event trigger.")));
/* Validate event name. */
if (strcmp(stmt->eventname, "ddl_command_start") != 0 &&
strcmp(stmt->eventname, "ddl_command_end") != 0 &&
strcmp(stmt->eventname, "sql_drop") != 0)
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("unrecognized event name \"%s\"",
stmt->eventname)));
/* Validate filter conditions. */
foreach (lc, stmt->whenclause)
{
DefElem *def = (DefElem *) lfirst(lc);
if (strcmp(def->defname, "tag") == 0)
{
if (tags != NULL)
error_duplicate_filter_variable(def->defname);
tags = (List *) def->arg;
}
else
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("unrecognized filter variable \"%s\"", def->defname)));
}
/* Validate tag list, if any. */
if ((strcmp(stmt->eventname, "ddl_command_start") == 0 ||
strcmp(stmt->eventname, "ddl_command_end") == 0 ||
strcmp(stmt->eventname, "sql_drop") == 0)
&& tags != NULL)
validate_ddl_tags("tag", tags);
/*
* Give user a nice error message if an event trigger of the same name
* already exists.
*/
tuple = SearchSysCache1(EVENTTRIGGERNAME, CStringGetDatum(stmt->trigname));
if (HeapTupleIsValid(tuple))
ereport(ERROR,
(errcode(ERRCODE_DUPLICATE_OBJECT),
errmsg("event trigger \"%s\" already exists",
stmt->trigname)));
/* Find and validate the trigger function. */
funcoid = LookupFuncName(stmt->funcname, 0, NULL, false);
funcrettype = get_func_rettype(funcoid);
if (funcrettype != EVTTRIGGEROID)
ereport(ERROR,
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
errmsg("function \"%s\" must return type \"event_trigger\"",
NameListToString(stmt->funcname))));
/* Insert catalog entries. */
return insert_event_trigger_tuple(stmt->trigname, stmt->eventname,
evtowner, funcoid, tags);
}
| bool EventTriggerBeginCompleteQuery | ( | void | ) |
Definition at line 1008 of file event_trigger.c.
References ALLOCSET_DEFAULT_INITSIZE, ALLOCSET_DEFAULT_MAXSIZE, ALLOCSET_DEFAULT_MINSIZE, AllocSetContextCreate(), EventTriggerQueryState::cxt, EventTriggerQueryState::in_sql_drop, MemoryContextAlloc(), EventTriggerQueryState::previous, slist_init(), EventTriggerQueryState::SQLDropList, TopMemoryContext, and trackDroppedObjectsNeeded().
Referenced by ProcessUtilitySlow().
{
EventTriggerQueryState *state;
MemoryContext cxt;
/*
* Currently, sql_drop events are the only reason to have event trigger
* state at all; so if there are none, don't install one.
*/
if (!trackDroppedObjectsNeeded())
return false;
cxt = AllocSetContextCreate(TopMemoryContext,
"event trigger state",
ALLOCSET_DEFAULT_MINSIZE,
ALLOCSET_DEFAULT_INITSIZE,
ALLOCSET_DEFAULT_MAXSIZE);
state = MemoryContextAlloc(cxt, sizeof(EventTriggerQueryState));
state->cxt = cxt;
slist_init(&(state->SQLDropList));
state->in_sql_drop = false;
state->previous = currentEventTriggerState;
currentEventTriggerState = state;
return true;
}
| void EventTriggerDDLCommandEnd | ( | Node * | parsetree | ) |
Definition at line 729 of file event_trigger.c.
References CommandCounterIncrement(), EventTriggerCommonSetup(), EventTriggerInvoke(), EVT_DDLCommandEnd, IsUnderPostmaster, list_free(), and NIL.
Referenced by ProcessUtilitySlow().
{
List *runlist;
EventTriggerData trigdata;
/*
* See EventTriggerDDLCommandStart for a discussion about why event
* triggers are disabled in single user mode.
*/
if (!IsUnderPostmaster)
return;
runlist = EventTriggerCommonSetup(parsetree,
EVT_DDLCommandEnd, "ddl_command_end",
&trigdata);
if (runlist == NIL)
return;
/*
* Make sure anything the main command did will be visible to the
* event triggers.
*/
CommandCounterIncrement();
/* Run the triggers. */
EventTriggerInvoke(runlist, &trigdata);
/* Cleanup. */
list_free(runlist);
}
| void EventTriggerDDLCommandStart | ( | Node * | parsetree | ) |
Definition at line 682 of file event_trigger.c.
References CommandCounterIncrement(), EventTriggerCommonSetup(), EventTriggerInvoke(), EVT_DDLCommandStart, IsUnderPostmaster, list_free(), and NIL.
Referenced by ProcessUtilitySlow().
{
List *runlist;
EventTriggerData trigdata;
/*
* Event Triggers are completely disabled in standalone mode. There are
* (at least) two reasons for this:
*
* 1. A sufficiently broken event trigger might not only render the
* database unusable, but prevent disabling itself to fix the situation.
* In this scenario, restarting in standalone mode provides an escape
* hatch.
*
* 2. BuildEventTriggerCache relies on systable_beginscan_ordered, and
* therefore will malfunction if pg_event_trigger's indexes are damaged.
* To allow recovery from a damaged index, we need some operating mode
* wherein event triggers are disabled. (Or we could implement
* heapscan-and-sort logic for that case, but having disaster recovery
* scenarios depend on code that's otherwise untested isn't appetizing.)
*/
if (!IsUnderPostmaster)
return;
runlist = EventTriggerCommonSetup(parsetree,
EVT_DDLCommandStart, "ddl_command_start",
&trigdata);
if (runlist == NIL)
return;
/* Run the triggers. */
EventTriggerInvoke(runlist, &trigdata);
/* Cleanup. */
list_free(runlist);
/*
* Make sure anything the event triggers did will be visible to
* the main command.
*/
CommandCounterIncrement();
}
| void EventTriggerEndCompleteQuery | ( | void | ) |
Definition at line 1048 of file event_trigger.c.
References EventTriggerQueryState::cxt, MemoryContextDelete(), and EventTriggerQueryState::previous.
Referenced by ProcessUtilitySlow().
{
EventTriggerQueryState *prevstate;
prevstate = currentEventTriggerState->previous;
/* this avoids the need for retail pfree of SQLDropList items: */
MemoryContextDelete(currentEventTriggerState->cxt);
currentEventTriggerState = prevstate;
}
| void EventTriggerSQLDrop | ( | Node * | parsetree | ) |
Definition at line 764 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().
{
List *runlist;
EventTriggerData trigdata;
/*
* See EventTriggerDDLCommandStart for a discussion about why event
* triggers are disabled in single user mode.
*/
if (!IsUnderPostmaster)
return;
/*
* Use current state to determine whether this event fires at all. If there
* are no triggers for the sql_drop event, then we don't have anything to do
* here. Note that dropped object collection is disabled if this is the case,
* so even if we were to try to run, the list would be empty.
*/
if (!currentEventTriggerState ||
slist_is_empty(¤tEventTriggerState->SQLDropList))
return;
runlist = EventTriggerCommonSetup(parsetree,
EVT_SQLDrop, "sql_drop",
&trigdata);
/*
* Nothing to do if run list is empty. Note this shouldn't happen, because
* if there are no sql_drop events, then objects-to-drop wouldn't have been
* collected in the first place and we would have quitted above.
*/
if (runlist == NIL)
return;
/*
* Make sure anything the main command did will be visible to the
* event triggers.
*/
CommandCounterIncrement();
/*
* Make sure pg_event_trigger_dropped_objects only works when running these
* triggers. Use PG_TRY to ensure in_sql_drop is reset even when one
* trigger fails. (This is perhaps not necessary, as the currentState
* variable will be removed shortly by our caller, but it seems better to
* play safe.)
*/
currentEventTriggerState->in_sql_drop = true;
/* Run the triggers. */
PG_TRY();
{
EventTriggerInvoke(runlist, &trigdata);
}
PG_CATCH();
{
currentEventTriggerState->in_sql_drop = false;
PG_RE_THROW();
}
PG_END_TRY();
currentEventTriggerState->in_sql_drop = false;
/* Cleanup. */
list_free(runlist);
}
| void EventTriggerSQLDropAddObject | ( | ObjectAddress * | object | ) |
Definition at line 1093 of file event_trigger.c.
References AccessShareLock, SQLDropObject::address, 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(), getObjectIdentity(), getObjectTypeDescription(), heap_close, heap_getattr, heap_open(), InvalidAttrNumber, is_objectclass_supported(), isAnyTempNamespace(), MemoryContextSwitchTo(), NamespaceRelationId, NameStr, SQLDropObject::next, ObjectAddress::objectId, ObjectAddress::objectSubId, SQLDropObject::objecttype, SQLDropObject::objidentity, SQLDropObject::objname, palloc0(), pfree(), pstrdup(), RelationGetDescr, SQLDropObject::schemaname, slist_push_head(), and EventTriggerQueryState::SQLDropList.
Referenced by deleteObjectsInList().
{
SQLDropObject *obj;
MemoryContext oldcxt;
if (!currentEventTriggerState)
return;
Assert(EventTriggerSupportsObjectClass(getObjectClass(object)));
/* don't report temp schemas */
if (object->classId == NamespaceRelationId &&
isAnyTempNamespace(object->objectId))
return;
oldcxt = MemoryContextSwitchTo(currentEventTriggerState->cxt);
obj = palloc0(sizeof(SQLDropObject));
obj->address = *object;
/*
* Obtain schema names from the object's catalog tuple, if one exists;
* this lets us skip objects in temp schemas. We trust that ObjectProperty
* contains all object classes that can be schema-qualified.
*/
if (is_objectclass_supported(object->classId))
{
Relation catalog;
HeapTuple tuple;
catalog = heap_open(obj->address.classId, AccessShareLock);
tuple = get_catalog_object_by_oid(catalog, obj->address.objectId);
if (tuple)
{
AttrNumber attnum;
Datum datum;
bool isnull;
attnum = get_object_attnum_namespace(obj->address.classId);
if (attnum != InvalidAttrNumber)
{
datum = heap_getattr(tuple, attnum,
RelationGetDescr(catalog), &isnull);
if (!isnull)
{
Oid namespaceId;
namespaceId = DatumGetObjectId(datum);
/* Don't report objects in temp namespaces */
if (isAnyTempNamespace(namespaceId))
{
pfree(obj);
heap_close(catalog, AccessShareLock);
MemoryContextSwitchTo(oldcxt);
return;
}
obj->schemaname = get_namespace_name(namespaceId);
}
}
if (get_object_namensp_unique(obj->address.classId) &&
obj->address.objectSubId == 0)
{
attnum = get_object_attnum_name(obj->address.classId);
if (attnum != InvalidAttrNumber)
{
datum = heap_getattr(tuple, attnum,
RelationGetDescr(catalog), &isnull);
if (!isnull)
obj->objname = pstrdup(NameStr(*DatumGetName(datum)));
}
}
}
heap_close(catalog, AccessShareLock);
}
/* object identity */
obj->objidentity = getObjectIdentity(&obj->address);
/* and object type, too */
obj->objecttype = getObjectTypeDescription(&obj->address);
slist_push_head(&(currentEventTriggerState->SQLDropList), &obj->next);
MemoryContextSwitchTo(oldcxt);
}
| bool EventTriggerSupportsObjectClass | ( | ObjectClass | objclass | ) |
Definition at line 948 of file event_trigger.c.
References Assert, MAX_OCLASS, 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_PROC, OCLASS_REWRITE, OCLASS_ROLE, OCLASS_SCHEMA, OCLASS_TBLSPACE, OCLASS_TRIGGER, OCLASS_TSCONFIG, OCLASS_TSDICT, OCLASS_TSPARSER, OCLASS_TSTEMPLATE, OCLASS_TYPE, and OCLASS_USER_MAPPING.
Referenced by deleteObjectsInList(), and EventTriggerSQLDropAddObject().
{
switch (objclass)
{
case OCLASS_DATABASE:
case OCLASS_TBLSPACE:
case OCLASS_ROLE:
/* no support for global objects */
return false;
case OCLASS_EVENT_TRIGGER:
/* no support for event triggers on event triggers */
return false;
case OCLASS_CLASS:
case OCLASS_PROC:
case OCLASS_TYPE:
case OCLASS_CAST:
case OCLASS_COLLATION:
case OCLASS_CONSTRAINT:
case OCLASS_CONVERSION:
case OCLASS_DEFAULT:
case OCLASS_LANGUAGE:
case OCLASS_LARGEOBJECT:
case OCLASS_OPERATOR:
case OCLASS_OPCLASS:
case OCLASS_OPFAMILY:
case OCLASS_AMOP:
case OCLASS_AMPROC:
case OCLASS_REWRITE:
case OCLASS_TRIGGER:
case OCLASS_SCHEMA:
case OCLASS_TSPARSER:
case OCLASS_TSDICT:
case OCLASS_TSTEMPLATE:
case OCLASS_TSCONFIG:
case OCLASS_FDW:
case OCLASS_FOREIGN_SERVER:
case OCLASS_USER_MAPPING:
case OCLASS_DEFACL:
case OCLASS_EXTENSION:
return true;
case MAX_OCLASS:
/*
* This shouldn't ever happen, but we keep the case to avoid a
* compiler warning without a "default" clause in the switch.
*/
Assert(false);
break;
}
return true;
}
| bool EventTriggerSupportsObjectType | ( | ObjectType | obtype | ) |
Definition at line 896 of file event_trigger.c.
References OBJECT_AGGREGATE, OBJECT_ATTRIBUTE, OBJECT_CAST, OBJECT_COLLATION, OBJECT_COLUMN, OBJECT_CONSTRAINT, OBJECT_CONVERSION, OBJECT_DATABASE, OBJECT_DOMAIN, 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_ROLE, OBJECT_RULE, OBJECT_SCHEMA, OBJECT_SEQUENCE, OBJECT_TABLE, OBJECT_TABLESPACE, OBJECT_TRIGGER, OBJECT_TSCONFIGURATION, OBJECT_TSDICTIONARY, OBJECT_TSPARSER, OBJECT_TSTEMPLATE, OBJECT_TYPE, and OBJECT_VIEW.
Referenced by standard_ProcessUtility().
{
switch (obtype)
{
case OBJECT_DATABASE:
case OBJECT_TABLESPACE:
case OBJECT_ROLE:
/* no support for global objects */
return false;
case OBJECT_EVENT_TRIGGER:
/* no support for event triggers on event triggers */
return false;
case OBJECT_AGGREGATE:
case OBJECT_ATTRIBUTE:
case OBJECT_CAST:
case OBJECT_COLUMN:
case OBJECT_CONSTRAINT:
case OBJECT_COLLATION:
case OBJECT_CONVERSION:
case OBJECT_DOMAIN:
case OBJECT_EXTENSION:
case OBJECT_FDW:
case OBJECT_FOREIGN_SERVER:
case OBJECT_FOREIGN_TABLE:
case OBJECT_FUNCTION:
case OBJECT_INDEX:
case OBJECT_LANGUAGE:
case OBJECT_LARGEOBJECT:
case OBJECT_MATVIEW:
case OBJECT_OPCLASS:
case OBJECT_OPERATOR:
case OBJECT_OPFAMILY:
case OBJECT_RULE:
case OBJECT_SCHEMA:
case OBJECT_SEQUENCE:
case OBJECT_TABLE:
case OBJECT_TRIGGER:
case OBJECT_TSCONFIGURATION:
case OBJECT_TSDICTIONARY:
case OBJECT_TSPARSER:
case OBJECT_TSTEMPLATE:
case OBJECT_TYPE:
case OBJECT_VIEW:
return true;
}
return true;
}
Definition at line 555 of file event_trigger.c.
References CStringGetDatum, ereport, errcode(), errmsg(), ERROR, EVENTTRIGGERNAME, GetSysCacheOid1, and OidIsValid.
Referenced by get_object_address_unqualified().
{
Oid oid;
oid = GetSysCacheOid1(EVENTTRIGGERNAME, CStringGetDatum(trigname));
if (!OidIsValid(oid) && !missing_ok)
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("event trigger \"%s\" does not exist", trigname)));
return oid;
}
| void RemoveEventTriggerById | ( | Oid | ctrigOid | ) |
Definition at line 392 of file event_trigger.c.
References elog, ERROR, EVENTTRIGGEROID, EventTriggerRelationId, heap_close, heap_open(), HeapTupleIsValid, ObjectIdGetDatum, ReleaseSysCache(), RowExclusiveLock, SearchSysCache1, simple_heap_delete(), and HeapTupleData::t_self.
Referenced by doDeletion().
{
Relation tgrel;
HeapTuple tup;
tgrel = heap_open(EventTriggerRelationId, RowExclusiveLock);
tup = SearchSysCache1(EVENTTRIGGEROID, ObjectIdGetDatum(trigOid));
if (!HeapTupleIsValid(tup))
elog(ERROR, "cache lookup failed for event trigger %u", trigOid);
simple_heap_delete(tgrel, &tup->t_self);
ReleaseSysCache(tup);
heap_close(tgrel, RowExclusiveLock);
}
| bool trackDroppedObjectsNeeded | ( | void | ) |
Definition at line 1066 of file event_trigger.c.
References EventCacheLookup(), EVT_SQLDrop, and list_length().
Referenced by deleteObjectsInList(), and EventTriggerBeginCompleteQuery().
{
/* true if any sql_drop event trigger exists */
return list_length(EventCacheLookup(EVT_SQLDrop)) > 0;
}
1.7.1