45 #include "utils/fmgroids.h"
124 (
errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
125 errmsg(
"permission denied to create event trigger \"%s\"",
127 errhint(
"Must be superuser to create an event trigger.")));
130 if (strcmp(
stmt->eventname,
"ddl_command_start") != 0 &&
131 strcmp(
stmt->eventname,
"ddl_command_end") != 0 &&
132 strcmp(
stmt->eventname,
"sql_drop") != 0 &&
133 strcmp(
stmt->eventname,
"table_rewrite") != 0)
135 (
errcode(ERRCODE_SYNTAX_ERROR),
136 errmsg(
"unrecognized event name \"%s\"",
140 foreach(lc,
stmt->whenclause)
144 if (strcmp(def->
defname,
"tag") == 0)
152 (
errcode(ERRCODE_SYNTAX_ERROR),
153 errmsg(
"unrecognized filter variable \"%s\"", def->
defname)));
157 if ((strcmp(
stmt->eventname,
"ddl_command_start") == 0 ||
158 strcmp(
stmt->eventname,
"ddl_command_end") == 0 ||
159 strcmp(
stmt->eventname,
"sql_drop") == 0)
162 else if (strcmp(
stmt->eventname,
"table_rewrite") == 0
174 errmsg(
"event trigger \"%s\" already exists",
180 if (funcrettype != EVENT_TRIGGEROID)
182 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
183 errmsg(
"function %s must return type %s",
188 evtowner, funcoid, tags);
204 if (commandTag == CMDTAG_UNKNOWN)
206 (
errcode(ERRCODE_SYNTAX_ERROR),
207 errmsg(
"filter value \"%s\" not recognized for filter variable \"%s\"",
208 tagstr, filtervar)));
211 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
213 errmsg(
"event triggers are not supported for %s",
233 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
235 errmsg(
"event triggers are not supported for %s",
247 (
errcode(ERRCODE_SYNTAX_ERROR),
248 errmsg(
"filter variable \"%s\" specified more than once",
263 bool nulls[Natts_pg_trigger];
274 Anum_pg_event_trigger_oid);
276 memset(nulls,
false,
sizeof(nulls));
283 values[Anum_pg_event_trigger_evtenabled - 1] =
286 nulls[Anum_pg_event_trigger_evttags - 1] =
true;
288 values[Anum_pg_event_trigger_evttags - 1] =
300 myself.
classId = EventTriggerRelationId;
303 referenced.
classId = ProcedureRelationId;
341 foreach(lc, filterlist)
348 for (p = result; *p; p++)
367 char tgenabled =
stmt->tgenabled;
375 (
errcode(ERRCODE_UNDEFINED_OBJECT),
376 errmsg(
"event trigger \"%s\" does not exist",
380 trigoid = evtForm->oid;
387 evtForm->evtenabled = tgenabled;
419 (
errcode(ERRCODE_UNDEFINED_OBJECT),
420 errmsg(
"event trigger \"%s\" does not exist",
name)));
423 evtOid = evtForm->oid;
451 (
errcode(ERRCODE_UNDEFINED_OBJECT),
452 errmsg(
"event trigger with OID %u does not exist", trigOid)));
471 if (form->evtowner == newOwnerId)
481 (
errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
482 errmsg(
"permission denied to change owner of event trigger \"%s\"",
484 errhint(
"The owner of an event trigger must be a superuser.")));
486 form->evtowner = newOwnerId;
513 (
errcode(ERRCODE_UNDEFINED_OBJECT),
514 errmsg(
"event trigger \"%s\" does not exist", trigname)));
578 #ifdef USE_ASSERT_CHECKING
600 if (cachelist ==
NIL)
613 foreach(lc, cachelist)
628 trigdata->
type = T_EventTriggerData;
629 trigdata->
event = eventstr;
887 "event trigger context",
892 foreach(lc, fn_oid_list)
1093 "event trigger state",
1098 state->in_sql_drop =
false;
1103 state->currentCommand = NULL;
1184 if (object->
classId == NamespaceRelationId &&
1267 if (object->
classId == NamespaceRelationId &&
1303 (
errcode(ERRCODE_E_R_I_E_EVENT_TRIGGER_PROTOCOL_VIOLATED),
1304 errmsg(
"%s can only be called in a sql_drop event trigger function",
1305 "pg_event_trigger_dropped_objects()")));
1315 bool nulls[12] = {0};
1396 (
errcode(ERRCODE_E_R_I_E_EVENT_TRIGGER_PROTOCOL_VIOLATED),
1397 errmsg(
"%s can only be called in a table_rewrite event trigger function",
1398 "pg_event_trigger_table_rewrite_oid()")));
1417 (
errcode(ERRCODE_E_R_I_E_EVENT_TRIGGER_PROTOCOL_VIOLATED),
1418 errmsg(
"%s can only be called in a table_rewrite event trigger function",
1419 "pg_event_trigger_table_rewrite_reason()")));
1502 command->
d.
simple.address = address;
1503 command->
d.
simple.secondaryObject = secondaryObject;
1538 command->
d.
alterTable.classId = RelationRelationId;
1590 newsub->address = address;
1675 command->
d.
grant.istmt = icopy;
1707 OperatorFamilyRelationId, opfamoid);
1708 command->
d.
opfam.operators = operators;
1709 command->
d.
opfam.procedures = procedures;
1740 OperatorClassRelationId, opcoid);
1742 command->
d.
createopc.procedures = procedures;
1758 Oid *dictIds,
int ndicts)
1774 TSConfigRelationId, cfgId);
1776 memcpy(command->
d.
atscfg.dictIds, dictIds,
sizeof(
Oid) * ndicts);
1777 command->
d.
atscfg.ndicts = ndicts;
1830 (
errcode(ERRCODE_E_R_I_E_EVENT_TRIGGER_PROTOCOL_VIOLATED),
1831 errmsg(
"%s can only be called in an event trigger function",
1832 "pg_event_trigger_ddl_commands()")));
1841 bool nulls[9] = {0};
1869 char *schema = NULL;
1878 addr = cmd->
d.
opfam.address;
1892 if (identity == NULL)
1921 elog(
ERROR,
"cache lookup failed for object %u/%u",
1928 "invalid null namespace in object %u/%u/%d",
1990 "GRANT" :
"REVOKE");
2031 return "FOREIGN DATA WRAPPER";
2033 return "FOREIGN SERVER";
2039 return "LARGE OBJECT";
2049 return "TABLESPACE";
2089 elog(
ERROR,
"unsupported object type: %d", (
int) objtype);
2116 return "FOREIGN DATA WRAPPERS";
2118 return "FOREIGN SERVERS";
2124 return "LARGE OBJECTS";
2128 return "PROCEDURES";
2132 return "TABLESPACES";
2173 elog(
ERROR,
"unsupported object type: %d", (
int) objtype);
void aclcheck_error(AclResult aclerr, ObjectType objtype, const char *objectname)
bool object_ownercheck(Oid classid, Oid objectid, Oid roleid)
ArrayType * construct_array_builtin(Datum *elems, int nelems, Oid elmtype)
ArrayType * construct_empty_array(Oid elmtype)
#define InvalidAttrNumber
bool bms_is_member(int x, const Bitmapset *a)
static Datum values[MAXATTR]
#define CStringGetTextDatum(s)
#define OidIsValid(objectId)
Oid GetNewOidWithIndex(Relation relation, Oid indexId, AttrNumber oidcolumn)
CommandTag GetCommandTagEnum(const char *commandname)
bool command_tag_event_trigger_ok(CommandTag commandTag)
bool command_tag_table_rewrite_ok(CommandTag commandTag)
const char * GetCommandTagName(CommandTag commandTag)
elog(ERROR, "%s: %s", p2, msg)
@ SCT_AlterDefaultPrivileges
ObjectClass getObjectClass(const ObjectAddress *object)
@ OCLASS_PUBLICATION_NAMESPACE
int errhint(const char *fmt,...)
int errcode(int sqlerrcode)
int errmsg(const char *fmt,...)
#define ereport(elevel,...)
void EventTriggerUndoInhibitCommandCollection(void)
void EventTriggerSQLDropAddObject(const ObjectAddress *object, bool original, bool normal)
static void AlterEventTriggerOwner_internal(Relation rel, HeapTuple tup, Oid newOwnerId)
void EventTriggerAlterTableStart(Node *parsetree)
void EventTriggerCollectAlterDefPrivs(AlterDefaultPrivilegesStmt *stmt)
bool trackDroppedObjectsNeeded(void)
Datum pg_event_trigger_ddl_commands(PG_FUNCTION_ARGS)
void EventTriggerDDLCommandStart(Node *parsetree)
void EventTriggerInhibitCommandCollection(void)
bool EventTriggerBeginCompleteQuery(void)
static bool filter_event_trigger(CommandTag tag, EventTriggerCacheItem *item)
void EventTriggerTableRewrite(Node *parsetree, Oid tableOid, int reason)
bool EventTriggerSupportsObjectType(ObjectType obtype)
Oid CreateEventTrigger(CreateEventTrigStmt *stmt)
static void validate_table_rewrite_tags(const char *filtervar, List *taglist)
Oid AlterEventTrigger(AlterEventTrigStmt *stmt)
static const char * stringify_adefprivs_objtype(ObjectType objtype)
void EventTriggerCollectGrant(InternalGrant *istmt)
struct EventTriggerQueryState EventTriggerQueryState
Datum pg_event_trigger_table_rewrite_reason(PG_FUNCTION_ARGS)
void EventTriggerSQLDrop(Node *parsetree)
Datum pg_event_trigger_dropped_objects(PG_FUNCTION_ARGS)
void EventTriggerEndCompleteQuery(void)
Datum pg_event_trigger_table_rewrite_oid(PG_FUNCTION_ARGS)
static void validate_ddl_tags(const char *filtervar, List *taglist)
void AlterEventTriggerOwner_oid(Oid trigOid, Oid newOwnerId)
void EventTriggerAlterTableRelid(Oid objectId)
void EventTriggerCollectAlterTSConfig(AlterTSConfigurationStmt *stmt, Oid cfgId, Oid *dictIds, int ndicts)
static EventTriggerQueryState * currentEventTriggerState
struct SQLDropObject SQLDropObject
void EventTriggerAlterTableEnd(void)
void EventTriggerCollectAlterOpFam(AlterOpFamilyStmt *stmt, Oid opfamoid, List *operators, List *procedures)
static List * EventTriggerCommonSetup(Node *parsetree, EventTriggerEvent event, const char *eventstr, EventTriggerData *trigdata)
void EventTriggerCollectCreateOpClass(CreateOpClassStmt *stmt, Oid opcoid, List *operators, List *procedures)
static void error_duplicate_filter_variable(const char *defname)
bool EventTriggerSupportsObjectClass(ObjectClass objclass)
void EventTriggerCollectSimpleCommand(ObjectAddress address, ObjectAddress secondaryObject, Node *parsetree)
static const char * stringify_grant_objtype(ObjectType objtype)
void EventTriggerDDLCommandEnd(Node *parsetree)
static Oid insert_event_trigger_tuple(const char *trigname, const char *eventname, Oid evtOwner, Oid funcoid, List *taglist)
void EventTriggerCollectAlterTableSubcmd(Node *subcmd, ObjectAddress address)
Oid get_event_trigger_oid(const char *trigname, bool missing_ok)
ObjectAddress AlterEventTriggerOwner(const char *name, Oid newOwnerId)
static void EventTriggerInvoke(List *fn_oid_list, EventTriggerData *trigdata)
static Datum filter_list_to_array(List *filterlist)
List * EventCacheLookup(EventTriggerEvent event)
void fmgr_info(Oid functionId, FmgrInfo *finfo)
#define InitFunctionCallInfoData(Fcinfo, Flinfo, Nargs, Collation, Context, Resultinfo)
#define LOCAL_FCINFO(name, nargs)
#define FunctionCallInvoke(fcinfo)
#define PG_RETURN_INT32(x)
void InitMaterializedSRF(FunctionCallInfo fcinfo, bits32 flags)
HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, Datum *values, bool *isnull)
void heap_freetuple(HeapTuple htup)
#define HeapTupleIsValid(tuple)
static Datum heap_getattr(HeapTuple tup, int attnum, TupleDesc tupleDesc, bool *isnull)
static void slist_init(slist_head *head)
static bool slist_is_empty(const slist_head *head)
static void slist_push_head(slist_head *head, slist_node *node)
#define slist_container(type, membername, ptr)
#define slist_foreach(iter, lhead)
void CatalogTupleUpdate(Relation heapRel, ItemPointer otid, HeapTuple tup)
void CatalogTupleInsert(Relation heapRel, HeapTuple tup)
if(TABLE==NULL||TABLE_index==NULL)
Assert(fmt[strlen(fmt) - 1] !='\n')
List * lappend(List *list, void *datum)
List * lappend_oid(List *list, Oid datum)
List * list_copy(const List *oldlist)
void list_free(List *list)
char * get_namespace_name_or_temp(Oid nspid)
char * get_namespace_name(Oid nspid)
Oid get_func_rettype(Oid funcid)
void MemoryContextReset(MemoryContext context)
char * pstrdup(const char *in)
void pfree(void *pointer)
MemoryContext TopMemoryContext
void * palloc0(Size size)
MemoryContext CurrentMemoryContext
void * MemoryContextAlloc(MemoryContext context, Size size)
void MemoryContextDelete(MemoryContext context)
#define AllocSetContextCreate
#define ALLOCSET_DEFAULT_SIZES
void namestrcpy(Name name, const char *str)
bool isTempNamespace(Oid namespaceId)
bool isAnyTempNamespace(Oid namespaceId)
char * NameListToString(const List *names)
#define IsA(nodeptr, _type_)
#define InvokeObjectPostCreateHook(classId, objectId, subId)
#define InvokeObjectPostAlterHook(classId, objectId, subId)
bool get_object_namensp_unique(Oid class_id)
ArrayType * strlist_to_textarray(List *list)
HeapTuple get_catalog_object_by_oid(Relation catalog, AttrNumber oidcol, Oid objectId)
AttrNumber get_object_attnum_oid(Oid class_id)
AttrNumber get_object_attnum_namespace(Oid class_id)
AttrNumber get_object_attnum_name(Oid class_id)
char * getObjectIdentity(const ObjectAddress *object, bool missing_ok)
char * getObjectTypeDescription(const ObjectAddress *object, bool missing_ok)
char * getObjectIdentityParts(const ObjectAddress *object, List **objname, List **objargs, bool missing_ok)
bool is_objectclass_supported(Oid class_id)
#define ObjectAddressSet(addr, class_id, object_id)
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Oid LookupFuncName(List *funcname, int nargs, const Oid *argtypes, bool missing_ok)
@ OBJECT_PUBLICATION_NAMESPACE
void recordDependencyOn(const ObjectAddress *depender, const ObjectAddress *referenced, DependencyType behavior)
void recordDependencyOnCurrentExtension(const ObjectAddress *object, bool isReplace)
FormData_pg_event_trigger * Form_pg_event_trigger
static int list_length(const List *l)
void changeDependencyOnOwner(Oid classId, Oid objectId, Oid newOwnerId)
void recordDependencyOnOwner(Oid classId, Oid objectId, Oid owner)
void pgstat_init_function_usage(FunctionCallInfo fcinfo, PgStat_FunctionCallUsage *fcu)
void pgstat_end_function_usage(PgStat_FunctionCallUsage *fcu, bool finalize)
unsigned char pg_ascii_toupper(unsigned char ch)
void check_stack_depth(void)
static Datum PointerGetDatum(const void *X)
static Name DatumGetName(Datum X)
static Oid DatumGetObjectId(Datum X)
static Datum BoolGetDatum(bool X)
static Datum ObjectIdGetDatum(Oid X)
static Datum NameGetDatum(const NameData *X)
static Datum CStringGetDatum(const char *X)
static Datum Int32GetDatum(int32 X)
static Datum CharGetDatum(char X)
static color newsub(struct colormap *cm, color co)
#define RelationGetDescr(relation)
#define ERRCODE_DUPLICATE_OBJECT
struct CollectedCommand::@112::@113 simple
struct CollectedCommand::@112::@116 opfam
CollectedCommandType type
union CollectedCommand::@112 d
struct CollectedCommand::@112::@115 grant
struct CollectedCommand * parent
struct CollectedCommand::@112::@119 defprivs
struct CollectedCommand::@112::@118 atscfg
struct CollectedCommand::@112::@117 createopc
struct CollectedCommand::@112::@114 alterTable
struct EventTriggerQueryState * previous
CollectedCommand * currentCommand
bool commandCollectionInhibited
Tuplestorestate * setResult
bool superuser_arg(Oid roleid)
HeapTuple SearchSysCache1(int cacheId, Datum key1)
#define SearchSysCacheCopy1(cacheId, key1)
#define GetSysCacheOid1(cacheId, oidcol, key1)
void table_close(Relation relation, LOCKMODE lockmode)
Relation table_open(Oid relationId, LOCKMODE lockmode)
int SessionReplicationRole
#define SESSION_REPLICATION_ROLE_REPLICA
#define TRIGGER_FIRES_ON_ORIGIN
#define TRIGGER_FIRES_ON_REPLICA
void tuplestore_putvalues(Tuplestorestate *state, TupleDesc tdesc, Datum *values, bool *isnull)
CommandTag CreateCommandTag(Node *parsetree)
static const char * CreateCommandName(Node *parsetree)
text * cstring_to_text(const char *s)
void CommandCounterIncrement(void)