PostgreSQL Source Code git master
Loading...
Searching...
No Matches
ts_cache.c File Reference
#include "postgres.h"
#include "access/genam.h"
#include "access/htup_details.h"
#include "access/table.h"
#include "access/xact.h"
#include "catalog/namespace.h"
#include "catalog/pg_ts_config.h"
#include "catalog/pg_ts_config_map.h"
#include "catalog/pg_ts_dict.h"
#include "catalog/pg_ts_parser.h"
#include "catalog/pg_ts_template.h"
#include "commands/defrem.h"
#include "miscadmin.h"
#include "nodes/miscnodes.h"
#include "tsearch/ts_cache.h"
#include "utils/builtins.h"
#include "utils/catcache.h"
#include "utils/fmgroids.h"
#include "utils/guc_hooks.h"
#include "utils/hsearch.h"
#include "utils/inval.h"
#include "utils/lsyscache.h"
#include "utils/memutils.h"
#include "utils/regproc.h"
#include "utils/syscache.h"
Include dependency graph for ts_cache.c:

Go to the source code of this file.

Macros

#define MAXTOKENTYPE   256
 
#define MAXDICTSPERTT   100
 

Functions

static void InvalidateTSCacheCallBack (Datum arg, SysCacheIdentifier cacheid, uint32 hashvalue)
 
TSParserCacheEntrylookup_ts_parser_cache (Oid prsId)
 
TSDictionaryCacheEntrylookup_ts_dictionary_cache (Oid dictId)
 
static void init_ts_config_cache (void)
 
TSConfigCacheEntrylookup_ts_config_cache (Oid cfgId)
 
Oid getTSCurrentConfig (bool emitError)
 
bool check_default_text_search_config (char **newval, void **extra, GucSource source)
 
void assign_default_text_search_config (const char *newval, void *extra)
 

Variables

static HTABTSParserCacheHash = NULL
 
static TSParserCacheEntrylastUsedParser = NULL
 
static HTABTSDictionaryCacheHash = NULL
 
static TSDictionaryCacheEntrylastUsedDictionary = NULL
 
static HTABTSConfigCacheHash = NULL
 
static TSConfigCacheEntrylastUsedConfig = NULL
 
charTSCurrentConfig = NULL
 
static Oid TSCurrentConfigCache = InvalidOid
 

Macro Definition Documentation

◆ MAXDICTSPERTT

#define MAXDICTSPERTT   100

Definition at line 62 of file ts_cache.c.

◆ MAXTOKENTYPE

#define MAXTOKENTYPE   256

Definition at line 61 of file ts_cache.c.

Function Documentation

◆ assign_default_text_search_config()

void assign_default_text_search_config ( const char newval,
void extra 
)

Definition at line 673 of file ts_cache.c.

674{
675 /* Just reset the cache to force a lookup on first use */
677}
#define InvalidOid
static Oid TSCurrentConfigCache
Definition ts_cache.c:79

References InvalidOid, and TSCurrentConfigCache.

◆ check_default_text_search_config()

bool check_default_text_search_config ( char **  newval,
void **  extra,
GucSource  source 
)

Definition at line 605 of file ts_cache.c.

606{
607 /*
608 * If we aren't inside a transaction, or connected to a database, we
609 * cannot do the catalog accesses necessary to verify the config name.
610 * Must accept it on faith.
611 */
613 {
615 List *namelist;
616 Oid cfgId;
617 HeapTuple tuple;
619 char *buf;
620
622 (Node *) &escontext);
623 if (namelist != NIL)
624 cfgId = get_ts_config_oid(namelist, true);
625 else
626 cfgId = InvalidOid; /* bad name list syntax */
627
628 /*
629 * When source == PGC_S_TEST, don't throw a hard error for a
630 * nonexistent configuration, only a NOTICE. See comments in guc.h.
631 */
632 if (!OidIsValid(cfgId))
633 {
634 if (source == PGC_S_TEST)
635 {
638 errmsg("text search configuration \"%s\" does not exist", *newval)));
639 return true;
640 }
641 else
642 return false;
643 }
644
645 /*
646 * Modify the actually stored value to be fully qualified, to ensure
647 * later changes of search_path don't affect it.
648 */
650 if (!HeapTupleIsValid(tuple))
651 elog(ERROR, "cache lookup failed for text search configuration %u",
652 cfgId);
653 cfg = (Form_pg_ts_config) GETSTRUCT(tuple);
654
656 NameStr(cfg->cfgname));
657
658 ReleaseSysCache(tuple);
659
660 /* GUC wants it guc_malloc'd not palloc'd */
663 pfree(buf);
664 if (!*newval)
665 return false;
666 }
667
668 return true;
669}
#define NameStr(name)
Definition c.h:835
#define OidIsValid(objectId)
Definition c.h:858
int errcode(int sqlerrcode)
Definition elog.c:874
#define LOG
Definition elog.h:32
#define ERROR
Definition elog.h:40
#define elog(elevel,...)
Definition elog.h:228
#define NOTICE
Definition elog.h:36
#define ereport(elevel,...)
Definition elog.h:152
Oid MyDatabaseId
Definition globals.c:96
void guc_free(void *ptr)
Definition guc.c:688
#define newval
char * guc_strdup(int elevel, const char *src)
Definition guc.c:676
@ PGC_S_TEST
Definition guc.h:125
#define HeapTupleIsValid(tuple)
Definition htup.h:78
static void * GETSTRUCT(const HeapTupleData *tuple)
char * get_namespace_name(Oid nspid)
Definition lsyscache.c:3588
void pfree(void *pointer)
Definition mcxt.c:1616
Oid get_ts_config_oid(List *names, bool missing_ok)
Definition namespace.c:3224
static char * errmsg
#define NIL
Definition pg_list.h:68
static rewind_source * source
Definition pg_rewind.c:89
static char buf[DEFAULT_XLOG_SEG_SIZE]
END_CATALOG_STRUCT typedef FormData_pg_ts_config * Form_pg_ts_config
static Datum ObjectIdGetDatum(Oid X)
Definition postgres.h:252
unsigned int Oid
static int fb(int x)
List * stringToQualifiedNameList(const char *string, Node *escontext)
Definition regproc.c:1922
char * quote_qualified_identifier(const char *qualifier, const char *ident)
Definition pg_list.h:54
Definition nodes.h:135
void ReleaseSysCache(HeapTuple tuple)
Definition syscache.c:265
HeapTuple SearchSysCache1(SysCacheIdentifier cacheId, Datum key1)
Definition syscache.c:221
bool IsTransactionState(void)
Definition xact.c:389

References buf, elog, ereport, errcode(), errmsg, ERROR, fb(), Form_pg_ts_config, get_namespace_name(), get_ts_config_oid(), GETSTRUCT(), guc_free(), guc_strdup(), HeapTupleIsValid, InvalidOid, IsTransactionState(), LOG, MyDatabaseId, NameStr, newval, NIL, NOTICE, ObjectIdGetDatum(), OidIsValid, pfree(), PGC_S_TEST, quote_qualified_identifier(), ReleaseSysCache(), SearchSysCache1(), source, and stringToQualifiedNameList().

◆ getTSCurrentConfig()

Oid getTSCurrentConfig ( bool  emitError)

Definition at line 559 of file ts_cache.c.

560{
561 List *namelist;
562
563 /* if we have a cached value, return it */
566
567 /* fail if GUC hasn't been set up yet */
568 if (TSCurrentConfig == NULL || *TSCurrentConfig == '\0')
569 {
570 if (emitError)
571 elog(ERROR, "text search configuration isn't set");
572 else
573 return InvalidOid;
574 }
575
576 if (TSConfigCacheHash == NULL)
577 {
578 /* First time through: initialize the tsconfig inval callback */
580 }
581
582 /* Look up the config */
583 if (emitError)
584 {
587 }
588 else
589 {
591
593 (Node *) &escontext);
594 if (namelist != NIL)
596 else
597 TSCurrentConfigCache = InvalidOid; /* bad name list syntax */
598 }
599
601}
static void init_ts_config_cache(void)
Definition ts_cache.c:365
static HTAB * TSConfigCacheHash
Definition ts_cache.c:71
char * TSCurrentConfig
Definition ts_cache.c:77

References elog, ERROR, fb(), get_ts_config_oid(), init_ts_config_cache(), InvalidOid, NIL, OidIsValid, stringToQualifiedNameList(), TSConfigCacheHash, TSCurrentConfig, and TSCurrentConfigCache.

Referenced by get_current_ts_config(), json_string_to_tsvector(), json_to_tsvector(), jsonb_string_to_tsvector(), jsonb_to_tsvector(), phraseto_tsquery(), plainto_tsquery(), to_tsquery(), to_tsvector(), ts_headline(), ts_headline_json(), ts_headline_json_opt(), ts_headline_jsonb(), ts_headline_jsonb_opt(), ts_headline_opt(), and websearch_to_tsquery().

◆ init_ts_config_cache()

static void init_ts_config_cache ( void  )
static

Definition at line 365 of file ts_cache.c.

366{
367 HASHCTL ctl;
368
369 ctl.keysize = sizeof(Oid);
370 ctl.entrysize = sizeof(TSConfigCacheEntry);
371 TSConfigCacheHash = hash_create("Tsearch configuration cache", 16,
373 /* Flush cache on pg_ts_config and pg_ts_config_map changes */
378
379 /* Also make sure CacheMemoryContext exists */
382}
void CreateCacheMemoryContext(void)
Definition catcache.c:715
HTAB * hash_create(const char *tabname, int64 nelem, const HASHCTL *info, int flags)
Definition dynahash.c:360
#define HASH_ELEM
Definition hsearch.h:90
#define HASH_BLOBS
Definition hsearch.h:92
void CacheRegisterSyscacheCallback(SysCacheIdentifier cacheid, SyscacheCallbackFunction func, Datum arg)
Definition inval.c:1816
MemoryContext CacheMemoryContext
Definition mcxt.c:169
static Datum PointerGetDatum(const void *X)
Definition postgres.h:342
tree ctl
Definition radixtree.h:1838
Size keysize
Definition hsearch.h:69
static void InvalidateTSCacheCallBack(Datum arg, SysCacheIdentifier cacheid, uint32 hashvalue)
Definition ts_cache.c:95

References CacheMemoryContext, CacheRegisterSyscacheCallback(), CreateCacheMemoryContext(), ctl, fb(), HASH_BLOBS, hash_create(), HASH_ELEM, InvalidateTSCacheCallBack(), HASHCTL::keysize, PointerGetDatum(), and TSConfigCacheHash.

Referenced by getTSCurrentConfig(), and lookup_ts_config_cache().

◆ InvalidateTSCacheCallBack()

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

Definition at line 95 of file ts_cache.c.

96{
98 HASH_SEQ_STATUS status;
99 TSAnyCacheEntry *entry;
100
101 hash_seq_init(&status, hash);
102 while ((entry = (TSAnyCacheEntry *) hash_seq_search(&status)) != NULL)
103 entry->isvalid = false;
104
105 /* Also invalidate the current-config cache if it's pg_ts_config */
106 if (hash == TSConfigCacheHash)
108}
void * hash_seq_search(HASH_SEQ_STATUS *status)
Definition dynahash.c:1352
void hash_seq_init(HASH_SEQ_STATUS *status, HTAB *hashp)
Definition dynahash.c:1317
Datum arg
Definition elog.c:1322
static Pointer DatumGetPointer(Datum X)
Definition postgres.h:332
static unsigned hash(unsigned *uv, int n)
Definition rege_dfa.c:715

References arg, DatumGetPointer(), fb(), hash(), hash_seq_init(), hash_seq_search(), InvalidOid, TSAnyCacheEntry::isvalid, TSConfigCacheHash, and TSCurrentConfigCache.

Referenced by init_ts_config_cache(), lookup_ts_dictionary_cache(), and lookup_ts_parser_cache().

◆ lookup_ts_config_cache()

TSConfigCacheEntry * lookup_ts_config_cache ( Oid  cfgId)

Definition at line 388 of file ts_cache.c.

389{
390 TSConfigCacheEntry *entry;
391
392 if (TSConfigCacheHash == NULL)
393 {
394 /* First time through: initialize the hash table */
396 }
397
398 /* Check single-entry cache */
399 if (lastUsedConfig && lastUsedConfig->cfgId == cfgId &&
401 return lastUsedConfig;
402
403 /* Try to look up an existing entry */
405 &cfgId,
406 HASH_FIND, NULL);
407 if (entry == NULL || !entry->isvalid)
408 {
409 /*
410 * If we didn't find one, we want to make one. But first look up the
411 * object to be sure the OID is real.
412 */
413 HeapTuple tp;
422 int maxtokentype;
423 int ndicts;
424 int i;
425
427 if (!HeapTupleIsValid(tp))
428 elog(ERROR, "cache lookup failed for text search configuration %u",
429 cfgId);
430 cfg = (Form_pg_ts_config) GETSTRUCT(tp);
431
432 /*
433 * Sanity checks
434 */
435 if (!OidIsValid(cfg->cfgparser))
436 elog(ERROR, "text search configuration %u has no parser", cfgId);
437
438 if (entry == NULL)
439 {
440 bool found;
441
442 /* Now make the cache entry */
443 entry = (TSConfigCacheEntry *)
445 &cfgId,
446 HASH_ENTER, &found);
447 Assert(!found); /* it wasn't there a moment ago */
448 }
449 else
450 {
451 /* Cleanup old contents */
452 if (entry->map)
453 {
454 for (i = 0; i < entry->lenmap; i++)
455 if (entry->map[i].dictIds)
456 pfree(entry->map[i].dictIds);
457 pfree(entry->map);
458 }
459 }
460
461 MemSet(entry, 0, sizeof(TSConfigCacheEntry));
462 entry->cfgId = cfgId;
463 entry->prsId = cfg->cfgparser;
464
465 ReleaseSysCache(tp);
466
467 /*
468 * Scan pg_ts_config_map to gather dictionary list for each token type
469 *
470 * Because the index is on (mapcfg, maptokentype, mapseqno), we will
471 * see the entries in maptokentype order, and in mapseqno order for
472 * each token type, even though we didn't explicitly ask for that.
473 */
474 MemSet(maplists, 0, sizeof(maplists));
475 maxtokentype = 0;
476 ndicts = 0;
477
481 ObjectIdGetDatum(cfgId));
482
486 NULL, 1, &mapskey);
487
489 {
491 int toktype = cfgmap->maptokentype;
492
494 elog(ERROR, "maptokentype value %d is out of range", toktype);
495 if (toktype < maxtokentype)
496 elog(ERROR, "maptokentype entries are out of order");
497 if (toktype > maxtokentype)
498 {
499 /* starting a new token type, but first save the prior data */
500 if (ndicts > 0)
501 {
502 maplists[maxtokentype].len = ndicts;
503 maplists[maxtokentype].dictIds = (Oid *)
505 sizeof(Oid) * ndicts);
507 sizeof(Oid) * ndicts);
508 }
510 mapdicts[0] = cfgmap->mapdict;
511 ndicts = 1;
512 }
513 else
514 {
515 /* continuing data for current token type */
516 if (ndicts >= MAXDICTSPERTT)
517 elog(ERROR, "too many pg_ts_config_map entries for one token type");
518 mapdicts[ndicts++] = cfgmap->mapdict;
519 }
520 }
521
525
526 if (ndicts > 0)
527 {
528 /* save the last token type's dictionaries */
529 maplists[maxtokentype].len = ndicts;
530 maplists[maxtokentype].dictIds = (Oid *)
532 sizeof(Oid) * ndicts);
534 sizeof(Oid) * ndicts);
535 /* and save the overall map */
536 entry->lenmap = maxtokentype + 1;
537 entry->map = (ListDictionary *)
539 sizeof(ListDictionary) * entry->lenmap);
540 memcpy(entry->map, maplists,
541 sizeof(ListDictionary) * entry->lenmap);
542 }
543
544 entry->isvalid = true;
545 }
546
547 lastUsedConfig = entry;
548
549 return entry;
550}
#define Assert(condition)
Definition c.h:943
#define MemSet(start, val, len)
Definition c.h:1107
memcpy(sums, checksumBaseOffsets, sizeof(checksumBaseOffsets))
void * hash_search(HTAB *hashp, const void *keyPtr, HASHACTION action, bool *foundPtr)
Definition dynahash.c:889
SysScanDesc systable_beginscan_ordered(Relation heapRelation, Relation indexRelation, Snapshot snapshot, int nkeys, ScanKey key)
Definition genam.c:659
void systable_endscan_ordered(SysScanDesc sysscan)
Definition genam.c:767
HeapTuple systable_getnext_ordered(SysScanDesc sysscan, ScanDirection direction)
Definition genam.c:742
@ HASH_FIND
Definition hsearch.h:108
@ HASH_ENTER
Definition hsearch.h:109
void index_close(Relation relation, LOCKMODE lockmode)
Definition indexam.c:178
Relation index_open(Oid relationId, LOCKMODE lockmode)
Definition indexam.c:134
int i
Definition isn.c:77
#define AccessShareLock
Definition lockdefs.h:36
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition mcxt.c:1232
END_CATALOG_STRUCT typedef FormData_pg_ts_config_map * Form_pg_ts_config_map
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition scankey.c:76
@ ForwardScanDirection
Definition sdir.h:28
#define BTEqualStrategyNumber
Definition stratnum.h:31
Oid * dictIds
Definition ts_cache.h:68
ListDictionary * map
Definition ts_cache.h:80
void table_close(Relation relation, LOCKMODE lockmode)
Definition table.c:126
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition table.c:40
#define MAXTOKENTYPE
Definition ts_cache.c:61
#define MAXDICTSPERTT
Definition ts_cache.c:62
static TSConfigCacheEntry * lastUsedConfig
Definition ts_cache.c:72

References AccessShareLock, Assert, BTEqualStrategyNumber, CacheMemoryContext, TSConfigCacheEntry::cfgId, ListDictionary::dictIds, elog, ERROR, fb(), Form_pg_ts_config, Form_pg_ts_config_map, ForwardScanDirection, GETSTRUCT(), HASH_ENTER, HASH_FIND, hash_search(), HeapTupleIsValid, i, index_close(), index_open(), init_ts_config_cache(), TSConfigCacheEntry::isvalid, lastUsedConfig, TSConfigCacheEntry::lenmap, TSConfigCacheEntry::map, MAXDICTSPERTT, MAXTOKENTYPE, memcpy(), MemoryContextAlloc(), MemSet, ObjectIdGetDatum(), OidIsValid, pfree(), TSConfigCacheEntry::prsId, ReleaseSysCache(), ScanKeyInit(), SearchSysCache1(), systable_beginscan_ordered(), systable_endscan_ordered(), systable_getnext_ordered(), table_close(), table_open(), and TSConfigCacheHash.

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

◆ lookup_ts_dictionary_cache()

TSDictionaryCacheEntry * lookup_ts_dictionary_cache ( Oid  dictId)

Definition at line 209 of file ts_cache.c.

210{
212
214 {
215 /* First time through: initialize the hash table */
216 HASHCTL ctl;
217
218 ctl.keysize = sizeof(Oid);
219 ctl.entrysize = sizeof(TSDictionaryCacheEntry);
220 TSDictionaryCacheHash = hash_create("Tsearch dictionary cache", 8,
222 /* Flush cache on pg_ts_dict and pg_ts_template changes */
227
228 /* Also make sure CacheMemoryContext exists */
231 }
232
233 /* Check single-entry cache */
234 if (lastUsedDictionary && lastUsedDictionary->dictId == dictId &&
236 return lastUsedDictionary;
237
238 /* Try to look up an existing entry */
240 &dictId,
241 HASH_FIND, NULL);
242 if (entry == NULL || !entry->isvalid)
243 {
244 /*
245 * If we didn't find one, we want to make one. But first look up the
246 * object to be sure the OID is real.
247 */
249 tptmpl;
251 Form_pg_ts_template template;
253
256 elog(ERROR, "cache lookup failed for text search dictionary %u",
257 dictId);
259
260 /*
261 * Sanity checks
262 */
263 if (!OidIsValid(dict->dicttemplate))
264 elog(ERROR, "text search dictionary %u has no template", dictId);
265
266 /*
267 * Retrieve dictionary's template
268 */
270 ObjectIdGetDatum(dict->dicttemplate));
272 elog(ERROR, "cache lookup failed for text search template %u",
273 dict->dicttemplate);
275
276 /*
277 * Sanity checks
278 */
279 if (!OidIsValid(template->tmpllexize))
280 elog(ERROR, "text search template %u has no lexize method",
281 template->tmpllexize);
282
283 if (entry == NULL)
284 {
285 bool found;
286
287 /* Now make the cache entry */
288 entry = (TSDictionaryCacheEntry *)
290 &dictId,
291 HASH_ENTER, &found);
292 Assert(!found); /* it wasn't there a moment ago */
293
294 /* Create private memory context the first time through */
296 "TS dictionary",
299 }
300 else
301 {
302 /* Clear the existing entry's private context */
303 saveCtx = entry->dictCtx;
304 /* Don't let context's ident pointer dangle while we reset it */
308 }
309
310 MemSet(entry, 0, sizeof(TSDictionaryCacheEntry));
311 entry->dictId = dictId;
312 entry->dictCtx = saveCtx;
313
314 entry->lexizeOid = template->tmpllexize;
315
316 if (OidIsValid(template->tmplinit))
317 {
319 Datum opt;
320 bool isnull;
321 MemoryContext oldcontext;
322
323 /*
324 * Init method runs in dictionary's private memory context, and we
325 * make sure the options are stored there too. This typically
326 * results in a small amount of memory leakage, but it's not worth
327 * complicating the API for tmplinit functions to avoid it.
328 */
329 oldcontext = MemoryContextSwitchTo(entry->dictCtx);
330
333 &isnull);
334 if (isnull)
336 else
338
339 entry->dictData =
342
343 MemoryContextSwitchTo(oldcontext);
344 }
345
348
349 fmgr_info_cxt(entry->lexizeOid, &entry->lexize, entry->dictCtx);
350
351 entry->isvalid = true;
352 }
353
354 lastUsedDictionary = entry;
355
356 return entry;
357}
void fmgr_info_cxt(Oid functionId, FmgrInfo *finfo, MemoryContext mcxt)
Definition fmgr.c:139
#define OidFunctionCall1(functionId, arg1)
Definition fmgr.h:722
void MemoryContextReset(MemoryContext context)
Definition mcxt.c:403
void MemoryContextSetIdentifier(MemoryContext context, const char *id)
Definition mcxt.c:661
#define AllocSetContextCreate
Definition memutils.h:129
#define ALLOCSET_SMALL_SIZES
Definition memutils.h:170
#define MemoryContextCopyAndSetIdentifier(cxt, id)
Definition memutils.h:101
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition palloc.h:124
END_CATALOG_STRUCT typedef FormData_pg_ts_dict * Form_pg_ts_dict
Definition pg_ts_dict.h:56
END_CATALOG_STRUCT typedef FormData_pg_ts_template * Form_pg_ts_template
uint64_t Datum
Definition postgres.h:70
MemoryContext dictCtx
Definition ts_cache.h:61
Datum SysCacheGetAttr(SysCacheIdentifier cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)
Definition syscache.c:596
static TSDictionaryCacheEntry * lastUsedDictionary
Definition ts_cache.c:69
static HTAB * TSDictionaryCacheHash
Definition ts_cache.c:68
List * deserialize_deflist(Datum txt)

References ALLOCSET_SMALL_SIZES, AllocSetContextCreate, Assert, CacheMemoryContext, CacheRegisterSyscacheCallback(), CreateCacheMemoryContext(), ctl, DatumGetPointer(), deserialize_deflist(), TSDictionaryCacheEntry::dictCtx, TSDictionaryCacheEntry::dictData, TSDictionaryCacheEntry::dictId, elog, ERROR, fb(), fmgr_info_cxt(), Form_pg_ts_dict, Form_pg_ts_template, GETSTRUCT(), HASH_BLOBS, hash_create(), HASH_ELEM, HASH_ENTER, HASH_FIND, hash_search(), HeapTupleIsValid, InvalidateTSCacheCallBack(), TSDictionaryCacheEntry::isvalid, HASHCTL::keysize, lastUsedDictionary, TSDictionaryCacheEntry::lexize, TSDictionaryCacheEntry::lexizeOid, MemoryContextCopyAndSetIdentifier, MemoryContextReset(), MemoryContextSetIdentifier(), MemoryContextSwitchTo(), MemSet, NameStr, NIL, ObjectIdGetDatum(), OidFunctionCall1, OidIsValid, PointerGetDatum(), ReleaseSysCache(), SearchSysCache1(), SysCacheGetAttr(), and TSDictionaryCacheHash.

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

◆ lookup_ts_parser_cache()

TSParserCacheEntry * lookup_ts_parser_cache ( Oid  prsId)

Definition at line 114 of file ts_cache.c.

115{
116 TSParserCacheEntry *entry;
117
118 if (TSParserCacheHash == NULL)
119 {
120 /* First time through: initialize the hash table */
121 HASHCTL ctl;
122
123 ctl.keysize = sizeof(Oid);
124 ctl.entrysize = sizeof(TSParserCacheEntry);
125 TSParserCacheHash = hash_create("Tsearch parser cache", 4,
127 /* Flush cache on pg_ts_parser changes */
130
131 /* Also make sure CacheMemoryContext exists */
134 }
135
136 /* Check single-entry cache */
137 if (lastUsedParser && lastUsedParser->prsId == prsId &&
139 return lastUsedParser;
140
141 /* Try to look up an existing entry */
143 &prsId,
144 HASH_FIND, NULL);
145 if (entry == NULL || !entry->isvalid)
146 {
147 /*
148 * If we didn't find one, we want to make one. But first look up the
149 * object to be sure the OID is real.
150 */
151 HeapTuple tp;
153
155 if (!HeapTupleIsValid(tp))
156 elog(ERROR, "cache lookup failed for text search parser %u",
157 prsId);
158 prs = (Form_pg_ts_parser) GETSTRUCT(tp);
159
160 /*
161 * Sanity checks
162 */
163 if (!OidIsValid(prs->prsstart))
164 elog(ERROR, "text search parser %u has no prsstart method", prsId);
165 if (!OidIsValid(prs->prstoken))
166 elog(ERROR, "text search parser %u has no prstoken method", prsId);
167 if (!OidIsValid(prs->prsend))
168 elog(ERROR, "text search parser %u has no prsend method", prsId);
169
170 if (entry == NULL)
171 {
172 bool found;
173
174 /* Now make the cache entry */
175 entry = (TSParserCacheEntry *)
176 hash_search(TSParserCacheHash, &prsId, HASH_ENTER, &found);
177 Assert(!found); /* it wasn't there a moment ago */
178 }
179
180 MemSet(entry, 0, sizeof(TSParserCacheEntry));
181 entry->prsId = prsId;
182 entry->startOid = prs->prsstart;
183 entry->tokenOid = prs->prstoken;
184 entry->endOid = prs->prsend;
185 entry->headlineOid = prs->prsheadline;
186 entry->lextypeOid = prs->prslextype;
187
188 ReleaseSysCache(tp);
189
193 if (OidIsValid(entry->headlineOid))
194 fmgr_info_cxt(entry->headlineOid, &entry->prsheadline,
196
197 entry->isvalid = true;
198 }
199
200 lastUsedParser = entry;
201
202 return entry;
203}
END_CATALOG_STRUCT typedef FormData_pg_ts_parser * Form_pg_ts_parser
FmgrInfo prstoken
Definition ts_cache.h:46
FmgrInfo prsstart
Definition ts_cache.h:45
FmgrInfo prsheadline
Definition ts_cache.h:48
FmgrInfo prsend
Definition ts_cache.h:47
static TSParserCacheEntry * lastUsedParser
Definition ts_cache.c:66
static HTAB * TSParserCacheHash
Definition ts_cache.c:65

References Assert, CacheMemoryContext, CacheRegisterSyscacheCallback(), CreateCacheMemoryContext(), ctl, elog, TSParserCacheEntry::endOid, ERROR, fb(), fmgr_info_cxt(), Form_pg_ts_parser, 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, ObjectIdGetDatum(), OidIsValid, PointerGetDatum(), TSParserCacheEntry::prsend, TSParserCacheEntry::prsheadline, TSParserCacheEntry::prsId, TSParserCacheEntry::prsstart, TSParserCacheEntry::prstoken, ReleaseSysCache(), SearchSysCache1(), TSParserCacheEntry::startOid, TSParserCacheEntry::tokenOid, and TSParserCacheHash.

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

Variable Documentation

◆ lastUsedConfig

TSConfigCacheEntry* lastUsedConfig = NULL
static

Definition at line 72 of file ts_cache.c.

Referenced by lookup_ts_config_cache().

◆ lastUsedDictionary

TSDictionaryCacheEntry* lastUsedDictionary = NULL
static

Definition at line 69 of file ts_cache.c.

Referenced by lookup_ts_dictionary_cache().

◆ lastUsedParser

TSParserCacheEntry* lastUsedParser = NULL
static

Definition at line 66 of file ts_cache.c.

Referenced by lookup_ts_parser_cache().

◆ TSConfigCacheHash

HTAB* TSConfigCacheHash = NULL
static

◆ TSCurrentConfig

char* TSCurrentConfig = NULL

Definition at line 77 of file ts_cache.c.

Referenced by getTSCurrentConfig().

◆ TSCurrentConfigCache

Oid TSCurrentConfigCache = InvalidOid
static

◆ TSDictionaryCacheHash

HTAB* TSDictionaryCacheHash = NULL
static

Definition at line 68 of file ts_cache.c.

Referenced by lookup_ts_dictionary_cache().

◆ TSParserCacheHash

HTAB* TSParserCacheHash = NULL
static

Definition at line 65 of file ts_cache.c.

Referenced by lookup_ts_parser_cache().