PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
ts_cache.h File Reference
#include "utils/guc.h"
Include dependency graph for ts_cache.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  TSAnyCacheEntry
 
struct  TSParserCacheEntry
 
struct  TSDictionaryCacheEntry
 
struct  ListDictionary
 
struct  TSConfigCacheEntry
 

Typedefs

typedef struct TSAnyCacheEntry TSAnyCacheEntry
 
typedef struct TSParserCacheEntry TSParserCacheEntry
 
typedef struct
TSDictionaryCacheEntry 
TSDictionaryCacheEntry
 

Functions

TSParserCacheEntrylookup_ts_parser_cache (Oid prsId)
 
TSDictionaryCacheEntrylookup_ts_dictionary_cache (Oid dictId)
 
TSConfigCacheEntrylookup_ts_config_cache (Oid cfgId)
 
Oid getTSCurrentConfig (bool emitError)
 
bool check_TSCurrentConfig (char **newval, void **extra, GucSource source)
 
void assign_TSCurrentConfig (const char *newval, void *extra)
 

Variables

char * TSCurrentConfig
 

Typedef Documentation

Function Documentation

void assign_TSCurrentConfig ( const char *  newval,
void *  extra 
)

Definition at line 647 of file ts_cache.c.

References InvalidOid, and TSCurrentConfigCache.

648 {
649  /* Just reset the cache to force a lookup on first use */
651 }
static Oid TSCurrentConfigCache
Definition: ts_cache.c:77
#define InvalidOid
Definition: postgres_ext.h:36
bool check_TSCurrentConfig ( char **  newval,
void **  extra,
GucSource  source 
)

Definition at line 587 of file ts_cache.c.

References buf, elog, ereport, errcode(), errmsg(), ERROR, free, get_namespace_name(), get_ts_config_oid(), GETSTRUCT, HeapTupleIsValid, IsTransactionState(), NameStr, NOTICE, ObjectIdGetDatum, OidIsValid, pfree(), PGC_S_TEST, quote_qualified_identifier(), ReleaseSysCache(), SearchSysCache1, stringToQualifiedNameList(), TSCONFIGOID, and catclist::tuple.

588 {
589  /*
590  * If we aren't inside a transaction, we cannot do database access so
591  * cannot verify the config name. Must accept it on faith.
592  */
593  if (IsTransactionState())
594  {
595  Oid cfgId;
596  HeapTuple tuple;
597  Form_pg_ts_config cfg;
598  char *buf;
599 
601 
602  /*
603  * When source == PGC_S_TEST, don't throw a hard error for a
604  * nonexistent configuration, only a NOTICE. See comments in guc.h.
605  */
606  if (!OidIsValid(cfgId))
607  {
608  if (source == PGC_S_TEST)
609  {
610  ereport(NOTICE,
611  (errcode(ERRCODE_UNDEFINED_OBJECT),
612  errmsg("text search configuration \"%s\" does not exist", *newval)));
613  return true;
614  }
615  else
616  return false;
617  }
618 
619  /*
620  * Modify the actually stored value to be fully qualified, to ensure
621  * later changes of search_path don't affect it.
622  */
624  if (!HeapTupleIsValid(tuple))
625  elog(ERROR, "cache lookup failed for text search configuration %u",
626  cfgId);
627  cfg = (Form_pg_ts_config) GETSTRUCT(tuple);
628 
629  buf = quote_qualified_identifier(get_namespace_name(cfg->cfgnamespace),
630  NameStr(cfg->cfgname));
631 
632  ReleaseSysCache(tuple);
633 
634  /* GUC wants it malloc'd not palloc'd */
635  free(*newval);
636  *newval = strdup(buf);
637  pfree(buf);
638  if (!*newval)
639  return false;
640  }
641 
642  return true;
643 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
FormData_pg_ts_config * Form_pg_ts_config
Definition: pg_ts_config.h:41
int errcode(int sqlerrcode)
Definition: elog.c:575
Oid get_ts_config_oid(List *names, bool missing_ok)
Definition: namespace.c:2473
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:534
#define SearchSysCache1(cacheId, key1)
Definition: syscache.h:149
void pfree(void *pointer)
Definition: mcxt.c:992
#define ObjectIdGetDatum(X)
Definition: postgres.h:515
#define ERROR
Definition: elog.h:43
char * get_namespace_name(Oid nspid)
Definition: lsyscache.c:3006
static char * buf
Definition: pg_test_fsync.c:65
#define ereport(elevel, rest)
Definition: elog.h:122
char * quote_qualified_identifier(const char *qualifier, const char *ident)
Definition: ruleutils.c:10054
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1083
#define NOTICE
Definition: elog.h:37
#define free(a)
Definition: header.h:60
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
#define newval
bool IsTransactionState(void)
Definition: xact.c:349
List * stringToQualifiedNameList(const char *string)
Definition: regproc.c:1830
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define NameStr(name)
Definition: c.h:495
#define elog
Definition: elog.h:219
Oid getTSCurrentConfig ( bool  emitError)

Definition at line 556 of file ts_cache.c.

References elog, ERROR, get_ts_config_oid(), init_ts_config_cache(), InvalidOid, NULL, OidIsValid, stringToQualifiedNameList(), TSCurrentConfig, and TSCurrentConfigCache.

Referenced by get_current_ts_config(), phraseto_tsquery(), plainto_tsquery(), to_tsquery(), to_tsvector(), ts_headline(), and ts_headline_opt().

557 {
558  /* if we have a cached value, return it */
560  return TSCurrentConfigCache;
561 
562  /* fail if GUC hasn't been set up yet */
563  if (TSCurrentConfig == NULL || *TSCurrentConfig == '\0')
564  {
565  if (emitError)
566  elog(ERROR, "text search configuration isn't set");
567  else
568  return InvalidOid;
569  }
570 
571  if (TSConfigCacheHash == NULL)
572  {
573  /* First time through: initialize the tsconfig inval callback */
575  }
576 
577  /* Look up the config */
580  !emitError);
581 
582  return TSCurrentConfigCache;
583 }
Oid get_ts_config_oid(List *names, bool missing_ok)
Definition: namespace.c:2473
#define OidIsValid(objectId)
Definition: c.h:534
char * TSCurrentConfig
Definition: ts_cache.c:75
static Oid TSCurrentConfigCache
Definition: ts_cache.c:77
#define ERROR
Definition: elog.h:43
#define InvalidOid
Definition: postgres_ext.h:36
static void init_ts_config_cache(void)
Definition: ts_cache.c:361
static HTAB * TSConfigCacheHash
Definition: ts_cache.c:69
#define NULL
Definition: c.h:226
List * stringToQualifiedNameList(const char *string)
Definition: regproc.c:1830
#define elog
Definition: elog.h:219
TSConfigCacheEntry* lookup_ts_config_cache ( Oid  cfgId)

Definition at line 385 of file ts_cache.c.

References AccessShareLock, Anum_pg_ts_config_map_mapcfg, Assert, BTEqualStrategyNumber, CacheMemoryContext, TSConfigCacheEntry::cfgId, ListDictionary::dictIds, elog, ERROR, ForwardScanDirection, GETSTRUCT, HASH_ENTER, HASH_FIND, hash_search(), heap_close, heap_open(), HeapTupleIsValid, i, index_close(), index_open(), init_ts_config_cache(), TSConfigCacheEntry::isvalid, lastUsedConfig, ListDictionary::len, TSConfigCacheEntry::lenmap, TSConfigCacheEntry::map, MAXDICTSPERTT, MAXTOKENTYPE, MemoryContextAlloc(), MemSet, NULL, ObjectIdGetDatum, OidIsValid, pfree(), TSConfigCacheEntry::prsId, ReleaseSysCache(), ScanKeyInit(), SearchSysCache1, systable_beginscan_ordered(), systable_endscan_ordered(), systable_getnext_ordered(), TSConfigMapIndexId, TSConfigMapRelationId, and TSCONFIGOID.

Referenced by hlparsetext(), parsetext(), and ts_headline_byid_opt().

386 {
387  TSConfigCacheEntry *entry;
388 
389  if (TSConfigCacheHash == NULL)
390  {
391  /* First time through: initialize the hash table */
393  }
394 
395  /* Check single-entry cache */
396  if (lastUsedConfig && lastUsedConfig->cfgId == cfgId &&
398  return lastUsedConfig;
399 
400  /* Try to look up an existing entry */
402  (void *) &cfgId,
403  HASH_FIND, NULL);
404  if (entry == NULL || !entry->isvalid)
405  {
406  /*
407  * If we didn't find one, we want to make one. But first look up the
408  * object to be sure the OID is real.
409  */
410  HeapTuple tp;
411  Form_pg_ts_config cfg;
412  Relation maprel;
413  Relation mapidx;
414  ScanKeyData mapskey;
415  SysScanDesc mapscan;
416  HeapTuple maptup;
417  ListDictionary maplists[MAXTOKENTYPE + 1];
418  Oid mapdicts[MAXDICTSPERTT];
419  int maxtokentype;
420  int ndicts;
421  int i;
422 
424  if (!HeapTupleIsValid(tp))
425  elog(ERROR, "cache lookup failed for text search configuration %u",
426  cfgId);
427  cfg = (Form_pg_ts_config) GETSTRUCT(tp);
428 
429  /*
430  * Sanity checks
431  */
432  if (!OidIsValid(cfg->cfgparser))
433  elog(ERROR, "text search configuration %u has no parser", cfgId);
434 
435  if (entry == NULL)
436  {
437  bool found;
438 
439  /* Now make the cache entry */
440  entry = (TSConfigCacheEntry *)
442  (void *) &cfgId,
443  HASH_ENTER, &found);
444  Assert(!found); /* it wasn't there a moment ago */
445  }
446  else
447  {
448  /* Cleanup old contents */
449  if (entry->map)
450  {
451  for (i = 0; i < entry->lenmap; i++)
452  if (entry->map[i].dictIds)
453  pfree(entry->map[i].dictIds);
454  pfree(entry->map);
455  }
456  }
457 
458  MemSet(entry, 0, sizeof(TSConfigCacheEntry));
459  entry->cfgId = cfgId;
460  entry->prsId = cfg->cfgparser;
461 
462  ReleaseSysCache(tp);
463 
464  /*
465  * Scan pg_ts_config_map to gather dictionary list for each token type
466  *
467  * Because the index is on (mapcfg, maptokentype, mapseqno), we will
468  * see the entries in maptokentype order, and in mapseqno order for
469  * each token type, even though we didn't explicitly ask for that.
470  */
471  MemSet(maplists, 0, sizeof(maplists));
472  maxtokentype = 0;
473  ndicts = 0;
474 
475  ScanKeyInit(&mapskey,
477  BTEqualStrategyNumber, F_OIDEQ,
478  ObjectIdGetDatum(cfgId));
479 
482  mapscan = systable_beginscan_ordered(maprel, mapidx,
483  NULL, 1, &mapskey);
484 
485  while ((maptup = systable_getnext_ordered(mapscan, ForwardScanDirection)) != NULL)
486  {
488  int toktype = cfgmap->maptokentype;
489 
490  if (toktype <= 0 || toktype > MAXTOKENTYPE)
491  elog(ERROR, "maptokentype value %d is out of range", toktype);
492  if (toktype < maxtokentype)
493  elog(ERROR, "maptokentype entries are out of order");
494  if (toktype > maxtokentype)
495  {
496  /* starting a new token type, but first save the prior data */
497  if (ndicts > 0)
498  {
499  maplists[maxtokentype].len = ndicts;
500  maplists[maxtokentype].dictIds = (Oid *)
502  sizeof(Oid) * ndicts);
503  memcpy(maplists[maxtokentype].dictIds, mapdicts,
504  sizeof(Oid) * ndicts);
505  }
506  maxtokentype = toktype;
507  mapdicts[0] = cfgmap->mapdict;
508  ndicts = 1;
509  }
510  else
511  {
512  /* continuing data for current token type */
513  if (ndicts >= MAXDICTSPERTT)
514  elog(ERROR, "too many pg_ts_config_map entries for one token type");
515  mapdicts[ndicts++] = cfgmap->mapdict;
516  }
517  }
518 
519  systable_endscan_ordered(mapscan);
520  index_close(mapidx, AccessShareLock);
521  heap_close(maprel, AccessShareLock);
522 
523  if (ndicts > 0)
524  {
525  /* save the last token type's dictionaries */
526  maplists[maxtokentype].len = ndicts;
527  maplists[maxtokentype].dictIds = (Oid *)
529  sizeof(Oid) * ndicts);
530  memcpy(maplists[maxtokentype].dictIds, mapdicts,
531  sizeof(Oid) * ndicts);
532  /* and save the overall map */
533  entry->lenmap = maxtokentype + 1;
534  entry->map = (ListDictionary *)
536  sizeof(ListDictionary) * entry->lenmap);
537  memcpy(entry->map, maplists,
538  sizeof(ListDictionary) * entry->lenmap);
539  }
540 
541  entry->isvalid = true;
542  }
543 
544  lastUsedConfig = entry;
545 
546  return entry;
547 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
#define MAXDICTSPERTT
Definition: ts_cache.c:60
FormData_pg_ts_config * Form_pg_ts_config
Definition: pg_ts_config.h:41
FormData_pg_ts_config_map * Form_pg_ts_config_map
#define AccessShareLock
Definition: lockdefs.h:36
#define MemSet(start, val, len)
Definition: c.h:853
#define heap_close(r, l)
Definition: heapam.h:97
void * hash_search(HTAB *hashp, const void *keyPtr, HASHACTION action, bool *foundPtr)
Definition: dynahash.c:885
HeapTuple systable_getnext_ordered(SysScanDesc sysscan, ScanDirection direction)
Definition: genam.c:591
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:534
#define SearchSysCache1(cacheId, key1)
Definition: syscache.h:149
void pfree(void *pointer)
Definition: mcxt.c:992
#define TSConfigMapRelationId
#define ObjectIdGetDatum(X)
Definition: postgres.h:515
#define ERROR
Definition: elog.h:43
#define Anum_pg_ts_config_map_mapcfg
#define MAXTOKENTYPE
Definition: ts_cache.c:59
Oid * dictIds
Definition: ts_cache.h:68
ListDictionary * map
Definition: ts_cache.h:80
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1083
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1287
void systable_endscan_ordered(SysScanDesc sysscan)
Definition: genam.c:608
static void init_ts_config_cache(void)
Definition: ts_cache.c:361
static HTAB * TSConfigCacheHash
Definition: ts_cache.c:69
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
#define NULL
Definition: c.h:226
#define Assert(condition)
Definition: c.h:671
static TSConfigCacheEntry * lastUsedConfig
Definition: ts_cache.c:70
void index_close(Relation relation, LOCKMODE lockmode)
Definition: indexam.c:176
SysScanDesc systable_beginscan_ordered(Relation heapRelation, Relation indexRelation, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:527
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition: mcxt.c:749
int i
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
#define TSConfigMapIndexId
Definition: indexing.h:257
#define elog
Definition: elog.h:219
Relation index_open(Oid relationId, LOCKMODE lockmode)
Definition: indexam.c:151
#define BTEqualStrategyNumber
Definition: stratnum.h:31
MemoryContext CacheMemoryContext
Definition: mcxt.c:46
TSDictionaryCacheEntry* lookup_ts_dictionary_cache ( Oid  dictId)

Definition at line 210 of file ts_cache.c.

References ALLOCSET_SMALL_SIZES, AllocSetContextCreate(), Anum_pg_ts_dict_dictinitoption, Assert, CacheMemoryContext, CacheRegisterSyscacheCallback(), CreateCacheMemoryContext(), DatumGetPointer, deserialize_deflist(), TSDictionaryCacheEntry::dictCtx, TSDictionaryCacheEntry::dictData, TSDictionaryCacheEntry::dictId, elog, HASHCTL::entrysize, ERROR, fmgr_info_cxt(), GETSTRUCT, HASH_BLOBS, hash_create(), HASH_ELEM, HASH_ENTER, HASH_FIND, hash_search(), HeapTupleIsValid, InvalidateTSCacheCallBack(), TSDictionaryCacheEntry::isvalid, HASHCTL::keysize, lastUsedDictionary, TSDictionaryCacheEntry::lexize, TSDictionaryCacheEntry::lexizeOid, MemoryContextResetAndDeleteChildren, MemoryContextSwitchTo(), MemSet, NameStr, NIL, NULL, ObjectIdGetDatum, OidFunctionCall1, OidIsValid, PointerGetDatum, ReleaseSysCache(), SearchSysCache1, SysCacheGetAttr(), TSDICTOID, and TSTEMPLATEOID.

Referenced by LexizeExec(), thesaurus_init(), thesaurus_lexize(), ts_lexize(), and unaccent_dict().

211 {
212  TSDictionaryCacheEntry *entry;
213 
215  {
216  /* First time through: initialize the hash table */
217  HASHCTL ctl;
218 
219  MemSet(&ctl, 0, sizeof(ctl));
220  ctl.keysize = sizeof(Oid);
221  ctl.entrysize = sizeof(TSDictionaryCacheEntry);
222  TSDictionaryCacheHash = hash_create("Tsearch dictionary cache", 8,
223  &ctl, HASH_ELEM | HASH_BLOBS);
224  /* Flush cache on pg_ts_dict and pg_ts_template changes */
229 
230  /* Also make sure CacheMemoryContext exists */
231  if (!CacheMemoryContext)
233  }
234 
235  /* Check single-entry cache */
236  if (lastUsedDictionary && lastUsedDictionary->dictId == dictId &&
238  return lastUsedDictionary;
239 
240  /* Try to look up an existing entry */
242  (void *) &dictId,
243  HASH_FIND, NULL);
244  if (entry == NULL || !entry->isvalid)
245  {
246  /*
247  * If we didn't find one, we want to make one. But first look up the
248  * object to be sure the OID is real.
249  */
250  HeapTuple tpdict,
251  tptmpl;
252  Form_pg_ts_dict dict;
253  Form_pg_ts_template template;
254  MemoryContext saveCtx;
255 
256  tpdict = SearchSysCache1(TSDICTOID, ObjectIdGetDatum(dictId));
257  if (!HeapTupleIsValid(tpdict))
258  elog(ERROR, "cache lookup failed for text search dictionary %u",
259  dictId);
260  dict = (Form_pg_ts_dict) GETSTRUCT(tpdict);
261 
262  /*
263  * Sanity checks
264  */
265  if (!OidIsValid(dict->dicttemplate))
266  elog(ERROR, "text search dictionary %u has no template", dictId);
267 
268  /*
269  * Retrieve dictionary's template
270  */
272  ObjectIdGetDatum(dict->dicttemplate));
273  if (!HeapTupleIsValid(tptmpl))
274  elog(ERROR, "cache lookup failed for text search template %u",
275  dict->dicttemplate);
276  template = (Form_pg_ts_template) GETSTRUCT(tptmpl);
277 
278  /*
279  * Sanity checks
280  */
281  if (!OidIsValid(template->tmpllexize))
282  elog(ERROR, "text search template %u has no lexize method",
283  template->tmpllexize);
284 
285  if (entry == NULL)
286  {
287  bool found;
288 
289  /* Now make the cache entry */
290  entry = (TSDictionaryCacheEntry *)
292  (void *) &dictId,
293  HASH_ENTER, &found);
294  Assert(!found); /* it wasn't there a moment ago */
295 
296  /* Create private memory context the first time through */
298  NameStr(dict->dictname),
300  }
301  else
302  {
303  /* Clear the existing entry's private context */
304  saveCtx = entry->dictCtx;
306  }
307 
308  MemSet(entry, 0, sizeof(TSDictionaryCacheEntry));
309  entry->dictId = dictId;
310  entry->dictCtx = saveCtx;
311 
312  entry->lexizeOid = template->tmpllexize;
313 
314  if (OidIsValid(template->tmplinit))
315  {
316  List *dictoptions;
317  Datum opt;
318  bool isnull;
319  MemoryContext oldcontext;
320 
321  /*
322  * Init method runs in dictionary's private memory context, and we
323  * make sure the options are stored there too
324  */
325  oldcontext = MemoryContextSwitchTo(entry->dictCtx);
326 
327  opt = SysCacheGetAttr(TSDICTOID, tpdict,
329  &isnull);
330  if (isnull)
331  dictoptions = NIL;
332  else
333  dictoptions = deserialize_deflist(opt);
334 
335  entry->dictData =
336  DatumGetPointer(OidFunctionCall1(template->tmplinit,
337  PointerGetDatum(dictoptions)));
338 
339  MemoryContextSwitchTo(oldcontext);
340  }
341 
342  ReleaseSysCache(tptmpl);
343  ReleaseSysCache(tpdict);
344 
345  fmgr_info_cxt(entry->lexizeOid, &entry->lexize, entry->dictCtx);
346 
347  entry->isvalid = true;
348  }
349 
350  lastUsedDictionary = entry;
351 
352  return entry;
353 }
#define NIL
Definition: pg_list.h:69
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
#define HASH_ELEM
Definition: hsearch.h:87
#define PointerGetDatum(X)
Definition: postgres.h:564
static TSDictionaryCacheEntry * lastUsedDictionary
Definition: ts_cache.c:67
List * deserialize_deflist(Datum txt)
Definition: tsearchcmds.c:1562
#define ALLOCSET_SMALL_SIZES
Definition: memutils.h:161
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
Size entrysize
Definition: hsearch.h:73
#define MemSet(start, val, len)
Definition: c.h:853
void * hash_search(HTAB *hashp, const void *keyPtr, HASHACTION action, bool *foundPtr)
Definition: dynahash.c:885
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:534
#define SearchSysCache1(cacheId, key1)
Definition: syscache.h:149
#define ObjectIdGetDatum(X)
Definition: postgres.h:515
#define ERROR
Definition: elog.h:43
#define OidFunctionCall1(functionId, arg1)
Definition: fmgr.h:593
FormData_pg_ts_dict * Form_pg_ts_dict
Definition: pg_ts_dict.h:45
void fmgr_info_cxt(Oid functionId, FmgrInfo *finfo, MemoryContext mcxt)
Definition: fmgr.c:169
static void InvalidateTSCacheCallBack(Datum arg, int cacheid, uint32 hashvalue)
Definition: ts_cache.c:93
#define MemoryContextResetAndDeleteChildren(ctx)
Definition: memutils.h:88
#define HASH_BLOBS
Definition: hsearch.h:88
MemoryContext AllocSetContextCreate(MemoryContext parent, const char *name, Size minContextSize, Size initBlockSize, Size maxBlockSize)
Definition: aset.c:329
void CacheRegisterSyscacheCallback(int cacheid, SyscacheCallbackFunction func, Datum arg)
Definition: inval.c:1381
uintptr_t Datum
Definition: postgres.h:374
HTAB * hash_create(const char *tabname, long nelem, HASHCTL *info, int flags)
Definition: dynahash.c:301
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1083
Datum SysCacheGetAttr(int cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)
Definition: syscache.c:1245
Size keysize
Definition: hsearch.h:72
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
#define NULL
Definition: c.h:226
#define Assert(condition)
Definition: c.h:671
#define Anum_pg_ts_dict_dictinitoption
Definition: pg_ts_dict.h:56
void CreateCacheMemoryContext(void)
Definition: catcache.c:525
#define DatumGetPointer(X)
Definition: postgres.h:557
FormData_pg_ts_template * Form_pg_ts_template
#define NameStr(name)
Definition: c.h:495
static HTAB * TSDictionaryCacheHash
Definition: ts_cache.c:66
#define elog
Definition: elog.h:219
struct TSDictionaryCacheEntry TSDictionaryCacheEntry
Definition: pg_list.h:45
MemoryContext dictCtx
Definition: ts_cache.h:61
MemoryContext CacheMemoryContext
Definition: mcxt.c:46
TSParserCacheEntry* lookup_ts_parser_cache ( Oid  prsId)

Definition at line 112 of file ts_cache.c.

References Assert, CacheMemoryContext, CacheRegisterSyscacheCallback(), CreateCacheMemoryContext(), elog, TSParserCacheEntry::endOid, HASHCTL::entrysize, ERROR, fmgr_info_cxt(), GETSTRUCT, HASH_BLOBS, hash_create(), HASH_ELEM, HASH_ENTER, HASH_FIND, hash_search(), TSParserCacheEntry::headlineOid, HeapTupleIsValid, InvalidateTSCacheCallBack(), TSParserCacheEntry::isvalid, HASHCTL::keysize, lastUsedParser, TSParserCacheEntry::lextypeOid, MemSet, NULL, ObjectIdGetDatum, OidIsValid, PointerGetDatum, TSParserCacheEntry::prsend, TSParserCacheEntry::prsheadline, TSParserCacheEntry::prsId, TSParserCacheEntry::prsstart, TSParserCacheEntry::prstoken, ReleaseSysCache(), SearchSysCache1, TSParserCacheEntry::startOid, TSParserCacheEntry::tokenOid, and TSPARSEROID.

Referenced by getTokenTypes(), hlparsetext(), parsetext(), prs_setup_firstcall(), ts_headline_byid_opt(), and tt_setup_firstcall().

113 {
114  TSParserCacheEntry *entry;
115 
116  if (TSParserCacheHash == NULL)
117  {
118  /* First time through: initialize the hash table */
119  HASHCTL ctl;
120 
121  MemSet(&ctl, 0, sizeof(ctl));
122  ctl.keysize = sizeof(Oid);
123  ctl.entrysize = sizeof(TSParserCacheEntry);
124  TSParserCacheHash = hash_create("Tsearch parser cache", 4,
125  &ctl, HASH_ELEM | HASH_BLOBS);
126  /* Flush cache on pg_ts_parser changes */
129 
130  /* Also make sure CacheMemoryContext exists */
131  if (!CacheMemoryContext)
133  }
134 
135  /* Check single-entry cache */
136  if (lastUsedParser && lastUsedParser->prsId == prsId &&
138  return lastUsedParser;
139 
140  /* Try to look up an existing entry */
142  (void *) &prsId,
143  HASH_FIND, NULL);
144  if (entry == NULL || !entry->isvalid)
145  {
146  /*
147  * If we didn't find one, we want to make one. But first look up the
148  * object to be sure the OID is real.
149  */
150  HeapTuple tp;
151  Form_pg_ts_parser prs;
152 
154  if (!HeapTupleIsValid(tp))
155  elog(ERROR, "cache lookup failed for text search parser %u",
156  prsId);
157  prs = (Form_pg_ts_parser) GETSTRUCT(tp);
158 
159  /*
160  * Sanity checks
161  */
162  if (!OidIsValid(prs->prsstart))
163  elog(ERROR, "text search parser %u has no prsstart method", prsId);
164  if (!OidIsValid(prs->prstoken))
165  elog(ERROR, "text search parser %u has no prstoken method", prsId);
166  if (!OidIsValid(prs->prsend))
167  elog(ERROR, "text search parser %u has no prsend method", prsId);
168 
169  if (entry == NULL)
170  {
171  bool found;
172 
173  /* Now make the cache entry */
174  entry = (TSParserCacheEntry *)
176  (void *) &prsId,
177  HASH_ENTER, &found);
178  Assert(!found); /* it wasn't there a moment ago */
179  }
180 
181  MemSet(entry, 0, sizeof(TSParserCacheEntry));
182  entry->prsId = prsId;
183  entry->startOid = prs->prsstart;
184  entry->tokenOid = prs->prstoken;
185  entry->endOid = prs->prsend;
186  entry->headlineOid = prs->prsheadline;
187  entry->lextypeOid = prs->prslextype;
188 
189  ReleaseSysCache(tp);
190 
193  fmgr_info_cxt(entry->endOid, &entry->prsend, CacheMemoryContext);
194  if (OidIsValid(entry->headlineOid))
195  fmgr_info_cxt(entry->headlineOid, &entry->prsheadline,
197 
198  entry->isvalid = true;
199  }
200 
201  lastUsedParser = entry;
202 
203  return entry;
204 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
#define HASH_ELEM
Definition: hsearch.h:87
#define PointerGetDatum(X)
Definition: postgres.h:564
Size entrysize
Definition: hsearch.h:73
#define MemSet(start, val, len)
Definition: c.h:853
void * hash_search(HTAB *hashp, const void *keyPtr, HASHACTION action, bool *foundPtr)
Definition: dynahash.c:885
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:534
#define SearchSysCache1(cacheId, key1)
Definition: syscache.h:149
#define ObjectIdGetDatum(X)
Definition: postgres.h:515
#define ERROR
Definition: elog.h:43
FmgrInfo prsend
Definition: ts_cache.h:47
static HTAB * TSParserCacheHash
Definition: ts_cache.c:63
void fmgr_info_cxt(Oid functionId, FmgrInfo *finfo, MemoryContext mcxt)
Definition: fmgr.c:169
static void InvalidateTSCacheCallBack(Datum arg, int cacheid, uint32 hashvalue)
Definition: ts_cache.c:93
#define HASH_BLOBS
Definition: hsearch.h:88
void CacheRegisterSyscacheCallback(int cacheid, SyscacheCallbackFunction func, Datum arg)
Definition: inval.c:1381
HTAB * hash_create(const char *tabname, long nelem, HASHCTL *info, int flags)
Definition: dynahash.c:301
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1083
FormData_pg_ts_parser * Form_pg_ts_parser
Definition: pg_ts_parser.h:44
Size keysize
Definition: hsearch.h:72
static TSParserCacheEntry * lastUsedParser
Definition: ts_cache.c:64
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
#define NULL
Definition: c.h:226
#define Assert(condition)
Definition: c.h:671
FmgrInfo prstoken
Definition: ts_cache.h:46
void CreateCacheMemoryContext(void)
Definition: catcache.c:525
FmgrInfo prsstart
Definition: ts_cache.h:45
struct TSParserCacheEntry TSParserCacheEntry
#define elog
Definition: elog.h:219
MemoryContext CacheMemoryContext
Definition: mcxt.c:46
FmgrInfo prsheadline
Definition: ts_cache.h:48

Variable Documentation

char* TSCurrentConfig

Definition at line 75 of file ts_cache.c.

Referenced by getTSCurrentConfig().