PostgreSQL Source Code git master
Loading...
Searching...
No Matches
evtcache.c File Reference
#include "postgres.h"
#include "access/genam.h"
#include "access/htup_details.h"
#include "access/relation.h"
#include "catalog/pg_event_trigger.h"
#include "catalog/pg_type.h"
#include "commands/trigger.h"
#include "tcop/cmdtag.h"
#include "utils/array.h"
#include "utils/builtins.h"
#include "utils/catcache.h"
#include "utils/evtcache.h"
#include "utils/hsearch.h"
#include "utils/inval.h"
#include "utils/memutils.h"
#include "utils/rel.h"
#include "utils/syscache.h"
Include dependency graph for evtcache.c:

Go to the source code of this file.

Data Structures

struct  EventTriggerCacheEntry
 

Enumerations

enum  EventTriggerCacheStateType { ETCS_NEEDS_REBUILD , ETCS_REBUILD_STARTED , ETCS_VALID }
 

Functions

static void BuildEventTriggerCache (void)
 
static void InvalidateEventCacheCallback (Datum arg, SysCacheIdentifier cacheid, uint32 hashvalue)
 
static BitmapsetDecodeTextArrayToBitmapset (Datum array)
 
ListEventCacheLookup (EventTriggerEvent event)
 

Variables

static HTABEventTriggerCache
 
static MemoryContext EventTriggerCacheContext
 
static EventTriggerCacheStateType EventTriggerCacheState = ETCS_NEEDS_REBUILD
 

Enumeration Type Documentation

◆ EventTriggerCacheStateType

Enumerator
ETCS_NEEDS_REBUILD 
ETCS_REBUILD_STARTED 
ETCS_VALID 

Definition at line 33 of file evtcache.c.

34{
EventTriggerCacheStateType
Definition evtcache.c:34
@ ETCS_REBUILD_STARTED
Definition evtcache.c:36
@ ETCS_NEEDS_REBUILD
Definition evtcache.c:35
@ ETCS_VALID
Definition evtcache.c:37

Function Documentation

◆ BuildEventTriggerCache()

static void BuildEventTriggerCache ( void  )
static

Definition at line 78 of file evtcache.c.

79{
81 HTAB *cache;
82 Relation rel;
83 Relation irel;
84 SysScanDesc scan;
85
87 {
88 /*
89 * Free up any memory already allocated in EventTriggerCacheContext.
90 * This can happen either because a previous rebuild failed, or
91 * because an invalidation happened before the rebuild was complete.
92 */
94 }
95 else
96 {
97 /*
98 * This is our first time attempting to build the cache, so we need to
99 * set up the memory context and register a syscache callback to
100 * capture future invalidation events.
101 */
106 "EventTriggerCache",
110 (Datum) 0);
111 }
112
113 /* Prevent the memory context from being nuked while we're rebuilding. */
115
116 /* Create new hash table. */
117 ctl.keysize = sizeof(EventTriggerEvent);
118 ctl.entrysize = sizeof(EventTriggerCacheEntry);
120 cache = hash_create("EventTriggerCacheHash", 32, &ctl,
122
123 /*
124 * Prepare to scan pg_event_trigger in name order.
125 */
128 scan = systable_beginscan_ordered(rel, irel, NULL, 0, NULL);
129
130 /*
131 * Build a cache item for each pg_event_trigger tuple, and append each one
132 * to the appropriate cache entry.
133 */
134 for (;;)
135 {
138 char *evtevent;
139 EventTriggerEvent event;
141 Datum evttags;
142 bool evttags_isnull;
144 bool found;
145 MemoryContext oldcontext;
146
147 /* Get next tuple. */
149 if (!HeapTupleIsValid(tup))
150 break;
151
152 /* Skip trigger if disabled. */
154 if (form->evtenabled == TRIGGER_DISABLED)
155 continue;
156
157 /* Decode event name. */
158 evtevent = NameStr(form->evtevent);
159 if (strcmp(evtevent, "ddl_command_start") == 0)
160 event = EVT_DDLCommandStart;
161 else if (strcmp(evtevent, "ddl_command_end") == 0)
162 event = EVT_DDLCommandEnd;
163 else if (strcmp(evtevent, "sql_drop") == 0)
164 event = EVT_SQLDrop;
165 else if (strcmp(evtevent, "table_rewrite") == 0)
166 event = EVT_TableRewrite;
167 else if (strcmp(evtevent, "login") == 0)
168 event = EVT_Login;
169 else
170 continue;
171
172 /* Switch to correct memory context. */
174
175 /* Allocate new cache item. */
177 item->fnoid = form->evtfoid;
178 item->enabled = form->evtenabled;
179
180 /* Decode and sort tags array. */
183 if (!evttags_isnull)
184 item->tagset = DecodeTextArrayToBitmapset(evttags);
185
186 /* Add to cache entry. */
187 entry = hash_search(cache, &event, HASH_ENTER, &found);
188 if (found)
189 entry->triggerlist = lappend(entry->triggerlist, item);
190 else
191 entry->triggerlist = list_make1(item);
192
193 /* Restore previous memory context. */
194 MemoryContextSwitchTo(oldcontext);
195 }
196
197 /* Done with pg_event_trigger scan. */
201
202 /* Install new cache. */
203 EventTriggerCache = cache;
204
205 /*
206 * If the cache has been invalidated since we entered this routine, we
207 * still use and return the cache we just finished constructing, to avoid
208 * infinite loops, but we leave the cache marked stale so that we'll
209 * rebuild it again on next access. Otherwise, we mark the cache valid.
210 */
213}
#define NameStr(name)
Definition c.h:777
void CreateCacheMemoryContext(void)
Definition catcache.c:715
void * hash_search(HTAB *hashp, const void *keyPtr, HASHACTION action, bool *foundPtr)
Definition dynahash.c:952
HTAB * hash_create(const char *tabname, int64 nelem, const HASHCTL *info, int flags)
Definition dynahash.c:358
static void InvalidateEventCacheCallback(Datum arg, SysCacheIdentifier cacheid, uint32 hashvalue)
Definition evtcache.c:258
static MemoryContext EventTriggerCacheContext
Definition evtcache.c:47
static Bitmapset * DecodeTextArrayToBitmapset(Datum array)
Definition evtcache.c:223
static HTAB * EventTriggerCache
Definition evtcache.c:46
static EventTriggerCacheStateType EventTriggerCacheState
Definition evtcache.c:48
EventTriggerEvent
Definition evtcache.h:21
@ EVT_SQLDrop
Definition evtcache.h:24
@ EVT_Login
Definition evtcache.h:26
@ EVT_DDLCommandEnd
Definition evtcache.h:23
@ EVT_DDLCommandStart
Definition evtcache.h:22
@ EVT_TableRewrite
Definition evtcache.h:25
#define palloc0_object(type)
Definition fe_memutils.h:75
SysScanDesc systable_beginscan_ordered(Relation heapRelation, Relation indexRelation, Snapshot snapshot, int nkeys, ScanKey key)
Definition genam.c:650
void systable_endscan_ordered(SysScanDesc sysscan)
Definition genam.c:757
HeapTuple systable_getnext_ordered(SysScanDesc sysscan, ScanDirection direction)
Definition genam.c:732
@ HASH_ENTER
Definition hsearch.h:114
#define HASH_CONTEXT
Definition hsearch.h:102
#define HASH_ELEM
Definition hsearch.h:95
#define HASH_BLOBS
Definition hsearch.h:97
#define HeapTupleIsValid(tuple)
Definition htup.h:78
static Datum heap_getattr(HeapTuple tup, int attnum, TupleDesc tupleDesc, bool *isnull)
static void * GETSTRUCT(const HeapTupleData *tuple)
void index_close(Relation relation, LOCKMODE lockmode)
Definition indexam.c:177
Relation index_open(Oid relationId, LOCKMODE lockmode)
Definition indexam.c:133
void CacheRegisterSyscacheCallback(SysCacheIdentifier cacheid, SyscacheCallbackFunction func, Datum arg)
Definition inval.c:1816
List * lappend(List *list, void *datum)
Definition list.c:339
#define AccessShareLock
Definition lockdefs.h:36
void MemoryContextReset(MemoryContext context)
Definition mcxt.c:403
MemoryContext CacheMemoryContext
Definition mcxt.c:169
#define AllocSetContextCreate
Definition memutils.h:129
#define ALLOCSET_DEFAULT_SIZES
Definition memutils.h:160
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition palloc.h:124
END_CATALOG_STRUCT typedef FormData_pg_event_trigger * Form_pg_event_trigger
#define list_make1(x1)
Definition pg_list.h:212
uint64_t Datum
Definition postgres.h:70
static int fb(int x)
tree ctl
Definition radixtree.h:1838
#define RelationGetDescr(relation)
Definition rel.h:540
@ ForwardScanDirection
Definition sdir.h:28
void relation_close(Relation relation, LOCKMODE lockmode)
Definition relation.c:205
Relation relation_open(Oid relationId, LOCKMODE lockmode)
Definition relation.c:47
Bitmapset * tagset
Definition evtcache.h:33
#define TRIGGER_DISABLED
Definition trigger.h:154

References AccessShareLock, ALLOCSET_DEFAULT_SIZES, AllocSetContextCreate, CacheMemoryContext, CacheRegisterSyscacheCallback(), CreateCacheMemoryContext(), ctl, DecodeTextArrayToBitmapset(), EventTriggerCacheItem::enabled, ETCS_REBUILD_STARTED, ETCS_VALID, EventTriggerCache, EventTriggerCacheContext, EventTriggerCacheState, EVT_DDLCommandEnd, EVT_DDLCommandStart, EVT_Login, EVT_SQLDrop, EVT_TableRewrite, fb(), EventTriggerCacheItem::fnoid, Form_pg_event_trigger, ForwardScanDirection, GETSTRUCT(), HASH_BLOBS, HASH_CONTEXT, hash_create(), HASH_ELEM, HASH_ENTER, hash_search(), heap_getattr(), HeapTupleIsValid, index_close(), index_open(), InvalidateEventCacheCallback(), lappend(), list_make1, MemoryContextReset(), MemoryContextSwitchTo(), NameStr, palloc0_object, relation_close(), relation_open(), RelationGetDescr, systable_beginscan_ordered(), systable_endscan_ordered(), systable_getnext_ordered(), EventTriggerCacheItem::tagset, TRIGGER_DISABLED, and EventTriggerCacheEntry::triggerlist.

Referenced by EventCacheLookup().

◆ DecodeTextArrayToBitmapset()

static Bitmapset * DecodeTextArrayToBitmapset ( Datum  array)
static

Definition at line 223 of file evtcache.c.

224{
225 ArrayType *arr = DatumGetArrayTypeP(array);
226 Datum *elems;
227 Bitmapset *bms;
228 int i;
229 int nelems;
230
231 if (ARR_NDIM(arr) != 1 || ARR_HASNULL(arr) || ARR_ELEMTYPE(arr) != TEXTOID)
232 elog(ERROR, "expected 1-D text array");
233 deconstruct_array_builtin(arr, TEXTOID, &elems, NULL, &nelems);
234
235 for (bms = NULL, i = 0; i < nelems; ++i)
236 {
237 char *str = TextDatumGetCString(elems[i]);
238
240 pfree(str);
241 }
242
243 pfree(elems);
244 if (arr != DatumGetPointer(array))
245 pfree(arr);
246
247 return bms;
248}
#define ARR_NDIM(a)
Definition array.h:290
#define DatumGetArrayTypeP(X)
Definition array.h:261
#define ARR_ELEMTYPE(a)
Definition array.h:292
#define ARR_HASNULL(a)
Definition array.h:291
void deconstruct_array_builtin(const ArrayType *array, Oid elmtype, Datum **elemsp, bool **nullsp, int *nelemsp)
Bitmapset * bms_add_member(Bitmapset *a, int x)
Definition bitmapset.c:799
#define TextDatumGetCString(d)
Definition builtins.h:99
CommandTag GetCommandTagEnum(const char *commandname)
Definition cmdtag.c:83
#define ERROR
Definition elog.h:39
#define elog(elevel,...)
Definition elog.h:226
const char * str
int i
Definition isn.c:77
void pfree(void *pointer)
Definition mcxt.c:1616
static Pointer DatumGetPointer(Datum X)
Definition postgres.h:342

References ARR_ELEMTYPE, ARR_HASNULL, ARR_NDIM, bms_add_member(), DatumGetArrayTypeP, DatumGetPointer(), deconstruct_array_builtin(), elog, ERROR, fb(), GetCommandTagEnum(), i, pfree(), str, and TextDatumGetCString.

Referenced by BuildEventTriggerCache().

◆ EventCacheLookup()

List * EventCacheLookup ( EventTriggerEvent  event)

Definition at line 64 of file evtcache.c.

65{
67
71 return entry != NULL ? entry->triggerlist : NIL;
72}
static void BuildEventTriggerCache(void)
Definition evtcache.c:78
@ HASH_FIND
Definition hsearch.h:113
#define NIL
Definition pg_list.h:68

References BuildEventTriggerCache(), ETCS_VALID, EventTriggerCache, EventTriggerCacheState, fb(), HASH_FIND, hash_search(), NIL, and EventTriggerCacheEntry::triggerlist.

Referenced by EventTriggerCommonSetup(), and trackDroppedObjectsNeeded().

◆ InvalidateEventCacheCallback()

static void InvalidateEventCacheCallback ( Datum  arg,
SysCacheIdentifier  cacheid,
uint32  hashvalue 
)
static

Definition at line 258 of file evtcache.c.

260{
261 /*
262 * If the cache isn't valid, then there might be a rebuild in progress, so
263 * we can't immediately blow it away. But it's advantageous to do this
264 * when possible, so as to immediately free memory.
265 */
267 {
270 }
271
272 /* Mark cache for rebuild. */
274}

References ETCS_NEEDS_REBUILD, ETCS_VALID, EventTriggerCache, EventTriggerCacheContext, EventTriggerCacheState, fb(), and MemoryContextReset().

Referenced by BuildEventTriggerCache().

Variable Documentation

◆ EventTriggerCache

HTAB* EventTriggerCache
static

◆ EventTriggerCacheContext

MemoryContext EventTriggerCacheContext
static

Definition at line 47 of file evtcache.c.

Referenced by BuildEventTriggerCache(), and InvalidateEventCacheCallback().

◆ EventTriggerCacheState

EventTriggerCacheStateType EventTriggerCacheState = ETCS_NEEDS_REBUILD
static