#include "postgres.h"#include "access/genam.h"#include "access/heapam.h"#include "access/htup_details.h"#include "access/xact.h"#include "catalog/indexing.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 "tsearch/ts_cache.h"#include "utils/builtins.h"#include "utils/catcache.h"#include "utils/fmgroids.h"#include "utils/inval.h"#include "utils/lsyscache.h"#include "utils/memutils.h"#include "utils/syscache.h"#include "utils/tqual.h"
Go to the source code of this file.
Defines | |
| #define | MAXTOKENTYPE 256 |
| #define | MAXDICTSPERTT 100 |
Functions | |
| static void | InvalidateTSCacheCallBack (Datum arg, int cacheid, uint32 hashvalue) |
| TSParserCacheEntry * | lookup_ts_parser_cache (Oid prsId) |
| TSDictionaryCacheEntry * | lookup_ts_dictionary_cache (Oid dictId) |
| static void | init_ts_config_cache (void) |
| TSConfigCacheEntry * | lookup_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 | |
| static HTAB * | TSParserCacheHash = NULL |
| static TSParserCacheEntry * | lastUsedParser = NULL |
| static HTAB * | TSDictionaryCacheHash = NULL |
| static TSDictionaryCacheEntry * | lastUsedDictionary = NULL |
| static HTAB * | TSConfigCacheHash = NULL |
| static TSConfigCacheEntry * | lastUsedConfig = NULL |
| char * | TSCurrentConfig = NULL |
| static Oid | TSCurrentConfigCache = InvalidOid |
| #define MAXDICTSPERTT 100 |
Definition at line 59 of file ts_cache.c.
Referenced by lookup_ts_config_cache().
| #define MAXTOKENTYPE 256 |
Definition at line 58 of file ts_cache.c.
Referenced by lookup_ts_config_cache().
| void assign_TSCurrentConfig | ( | const char * | newval, | |
| void * | extra | |||
| ) |
Definition at line 654 of file ts_cache.c.
References TSCurrentConfigCache.
{
/* Just reset the cache to force a lookup on first use */
TSCurrentConfigCache = InvalidOid;
}
Definition at line 591 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.
{
/*
* If we aren't inside a transaction, we cannot do database access so
* cannot verify the config name. Must accept it on faith.
*/
if (IsTransactionState())
{
Oid cfgId;
HeapTuple tuple;
Form_pg_ts_config cfg;
char *buf;
cfgId = get_ts_config_oid(stringToQualifiedNameList(*newval), true);
/*
* When source == PGC_S_TEST, we are checking the argument of an ALTER
* DATABASE SET or ALTER USER SET command. It could be that the
* intended use of the setting is for some other database, so we
* should not error out if the text search configuration is not
* present in the current database. We issue a NOTICE instead.
*/
if (!OidIsValid(cfgId))
{
if (source == PGC_S_TEST)
{
ereport(NOTICE,
(errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("text search configuration \"%s\" does not exist", *newval)));
return true;
}
else
return false;
}
/*
* Modify the actually stored value to be fully qualified, to ensure
* later changes of search_path don't affect it.
*/
tuple = SearchSysCache1(TSCONFIGOID, ObjectIdGetDatum(cfgId));
if (!HeapTupleIsValid(tuple))
elog(ERROR, "cache lookup failed for text search configuration %u",
cfgId);
cfg = (Form_pg_ts_config) GETSTRUCT(tuple);
buf = quote_qualified_identifier(get_namespace_name(cfg->cfgnamespace),
NameStr(cfg->cfgname));
ReleaseSysCache(tuple);
/* GUC wants it malloc'd not palloc'd */
free(*newval);
*newval = strdup(buf);
pfree(buf);
if (!*newval)
return false;
}
return true;
}
Definition at line 560 of file ts_cache.c.
References elog, ERROR, get_ts_config_oid(), init_ts_config_cache(), NULL, OidIsValid, stringToQualifiedNameList(), TSCurrentConfig, and TSCurrentConfigCache.
Referenced by get_current_ts_config(), plainto_tsquery(), to_tsquery(), to_tsvector(), ts_headline(), and ts_headline_opt().
{
/* if we have a cached value, return it */
if (OidIsValid(TSCurrentConfigCache))
return TSCurrentConfigCache;
/* fail if GUC hasn't been set up yet */
if (TSCurrentConfig == NULL || *TSCurrentConfig == '\0')
{
if (emitError)
elog(ERROR, "text search configuration isn't set");
else
return InvalidOid;
}
if (TSConfigCacheHash == NULL)
{
/* First time through: initialize the tsconfig inval callback */
init_ts_config_cache();
}
/* Look up the config */
TSCurrentConfigCache =
get_ts_config_oid(stringToQualifiedNameList(TSCurrentConfig),
!emitError);
return TSCurrentConfigCache;
}
| static void init_ts_config_cache | ( | void | ) | [static] |
Definition at line 364 of file ts_cache.c.
References CacheMemoryContext, CacheRegisterSyscacheCallback(), CreateCacheMemoryContext(), HASHCTL::entrysize, HASHCTL::hash, hash_create(), HASH_ELEM, HASH_FUNCTION, InvalidateTSCacheCallBack(), HASHCTL::keysize, MemSet, PointerGetDatum, TSCONFIGMAP, and TSCONFIGOID.
Referenced by getTSCurrentConfig(), and lookup_ts_config_cache().
{
HASHCTL ctl;
MemSet(&ctl, 0, sizeof(ctl));
ctl.keysize = sizeof(Oid);
ctl.entrysize = sizeof(TSConfigCacheEntry);
ctl.hash = oid_hash;
TSConfigCacheHash = hash_create("Tsearch configuration cache", 16,
&ctl, HASH_ELEM | HASH_FUNCTION);
/* Flush cache on pg_ts_config and pg_ts_config_map changes */
CacheRegisterSyscacheCallback(TSCONFIGOID, InvalidateTSCacheCallBack,
PointerGetDatum(TSConfigCacheHash));
CacheRegisterSyscacheCallback(TSCONFIGMAP, InvalidateTSCacheCallBack,
PointerGetDatum(TSConfigCacheHash));
/* Also make sure CacheMemoryContext exists */
if (!CacheMemoryContext)
CreateCacheMemoryContext();
}
Definition at line 92 of file ts_cache.c.
References DatumGetPointer, hash(), hash_seq_init(), hash_seq_search(), TSAnyCacheEntry::isvalid, NULL, and TSCurrentConfigCache.
Referenced by init_ts_config_cache(), lookup_ts_dictionary_cache(), and lookup_ts_parser_cache().
{
HTAB *hash = (HTAB *) DatumGetPointer(arg);
HASH_SEQ_STATUS status;
TSAnyCacheEntry *entry;
hash_seq_init(&status, hash);
while ((entry = (TSAnyCacheEntry *) hash_seq_search(&status)) != NULL)
entry->isvalid = false;
/* Also invalidate the current-config cache if it's pg_ts_config */
if (hash == TSConfigCacheHash)
TSCurrentConfigCache = InvalidOid;
}
| TSConfigCacheEntry* lookup_ts_config_cache | ( | Oid | cfgId | ) |
Definition at line 389 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_search(), heap_close, heap_open(), HeapTupleIsValid, i, index_close(), index_open(), init_ts_config_cache(), TSConfigCacheEntry::isvalid, ListDictionary::len, TSConfigCacheEntry::lenmap, TSConfigCacheEntry::map, MAXDICTSPERTT, MAXTOKENTYPE, MemoryContextAlloc(), MemSet, NULL, ObjectIdGetDatum, OidIsValid, pfree(), TSConfigCacheEntry::prsId, ReleaseSysCache(), ScanKeyInit(), SearchSysCache1, SnapshotNow, systable_beginscan_ordered(), systable_endscan_ordered(), systable_getnext_ordered(), TSConfigMapIndexId, TSConfigMapRelationId, and TSCONFIGOID.
Referenced by hlparsetext(), parsetext(), and ts_headline_byid_opt().
{
TSConfigCacheEntry *entry;
if (TSConfigCacheHash == NULL)
{
/* First time through: initialize the hash table */
init_ts_config_cache();
}
/* Check single-entry cache */
if (lastUsedConfig && lastUsedConfig->cfgId == cfgId &&
lastUsedConfig->isvalid)
return lastUsedConfig;
/* Try to look up an existing entry */
entry = (TSConfigCacheEntry *) hash_search(TSConfigCacheHash,
(void *) &cfgId,
HASH_FIND, NULL);
if (entry == NULL || !entry->isvalid)
{
/*
* If we didn't find one, we want to make one. But first look up the
* object to be sure the OID is real.
*/
HeapTuple tp;
Form_pg_ts_config cfg;
Relation maprel;
Relation mapidx;
ScanKeyData mapskey;
SysScanDesc mapscan;
HeapTuple maptup;
ListDictionary maplists[MAXTOKENTYPE + 1];
Oid mapdicts[MAXDICTSPERTT];
int maxtokentype;
int ndicts;
int i;
tp = SearchSysCache1(TSCONFIGOID, ObjectIdGetDatum(cfgId));
if (!HeapTupleIsValid(tp))
elog(ERROR, "cache lookup failed for text search configuration %u",
cfgId);
cfg = (Form_pg_ts_config) GETSTRUCT(tp);
/*
* Sanity checks
*/
if (!OidIsValid(cfg->cfgparser))
elog(ERROR, "text search configuration %u has no parser", cfgId);
if (entry == NULL)
{
bool found;
/* Now make the cache entry */
entry = (TSConfigCacheEntry *)
hash_search(TSConfigCacheHash,
(void *) &cfgId,
HASH_ENTER, &found);
Assert(!found); /* it wasn't there a moment ago */
}
else
{
/* Cleanup old contents */
if (entry->map)
{
for (i = 0; i < entry->lenmap; i++)
if (entry->map[i].dictIds)
pfree(entry->map[i].dictIds);
pfree(entry->map);
}
}
MemSet(entry, 0, sizeof(TSConfigCacheEntry));
entry->cfgId = cfgId;
entry->prsId = cfg->cfgparser;
ReleaseSysCache(tp);
/*
* Scan pg_ts_config_map to gather dictionary list for each token type
*
* Because the index is on (mapcfg, maptokentype, mapseqno), we will
* see the entries in maptokentype order, and in mapseqno order for
* each token type, even though we didn't explicitly ask for that.
*/
MemSet(maplists, 0, sizeof(maplists));
maxtokentype = 0;
ndicts = 0;
ScanKeyInit(&mapskey,
Anum_pg_ts_config_map_mapcfg,
BTEqualStrategyNumber, F_OIDEQ,
ObjectIdGetDatum(cfgId));
maprel = heap_open(TSConfigMapRelationId, AccessShareLock);
mapidx = index_open(TSConfigMapIndexId, AccessShareLock);
mapscan = systable_beginscan_ordered(maprel, mapidx,
SnapshotNow, 1, &mapskey);
while ((maptup = systable_getnext_ordered(mapscan, ForwardScanDirection)) != NULL)
{
Form_pg_ts_config_map cfgmap = (Form_pg_ts_config_map) GETSTRUCT(maptup);
int toktype = cfgmap->maptokentype;
if (toktype <= 0 || toktype > MAXTOKENTYPE)
elog(ERROR, "maptokentype value %d is out of range", toktype);
if (toktype < maxtokentype)
elog(ERROR, "maptokentype entries are out of order");
if (toktype > maxtokentype)
{
/* starting a new token type, but first save the prior data */
if (ndicts > 0)
{
maplists[maxtokentype].len = ndicts;
maplists[maxtokentype].dictIds = (Oid *)
MemoryContextAlloc(CacheMemoryContext,
sizeof(Oid) * ndicts);
memcpy(maplists[maxtokentype].dictIds, mapdicts,
sizeof(Oid) * ndicts);
}
maxtokentype = toktype;
mapdicts[0] = cfgmap->mapdict;
ndicts = 1;
}
else
{
/* continuing data for current token type */
if (ndicts >= MAXDICTSPERTT)
elog(ERROR, "too many pg_ts_config_map entries for one token type");
mapdicts[ndicts++] = cfgmap->mapdict;
}
}
systable_endscan_ordered(mapscan);
index_close(mapidx, AccessShareLock);
heap_close(maprel, AccessShareLock);
if (ndicts > 0)
{
/* save the last token type's dictionaries */
maplists[maxtokentype].len = ndicts;
maplists[maxtokentype].dictIds = (Oid *)
MemoryContextAlloc(CacheMemoryContext,
sizeof(Oid) * ndicts);
memcpy(maplists[maxtokentype].dictIds, mapdicts,
sizeof(Oid) * ndicts);
/* and save the overall map */
entry->lenmap = maxtokentype + 1;
entry->map = (ListDictionary *)
MemoryContextAlloc(CacheMemoryContext,
sizeof(ListDictionary) * entry->lenmap);
memcpy(entry->map, maplists,
sizeof(ListDictionary) * entry->lenmap);
}
entry->isvalid = true;
}
lastUsedConfig = entry;
return entry;
}
| TSDictionaryCacheEntry* lookup_ts_dictionary_cache | ( | Oid | dictId | ) |
Definition at line 210 of file ts_cache.c.
References ALLOCSET_SMALL_INITSIZE, ALLOCSET_SMALL_MAXSIZE, ALLOCSET_SMALL_MINSIZE, 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, HASHCTL::hash, hash_create(), HASH_ELEM, HASH_FUNCTION, hash_search(), HeapTupleIsValid, InvalidateTSCacheCallBack(), TSDictionaryCacheEntry::isvalid, HASHCTL::keysize, TSDictionaryCacheEntry::lexize, TSDictionaryCacheEntry::lexizeOid, MemoryContextResetAndDeleteChildren(), MemoryContextSwitchTo(), MemSet, NameStr, NULL, ObjectIdGetDatum, OidFunctionCall1, OidIsValid, PointerGetDatum, ReleaseSysCache(), SearchSysCache1, SysCacheGetAttr(), TSDICTOID, and TSTEMPLATEOID.
Referenced by LexizeExec(), thesaurus_init(), thesaurus_lexize(), ts_lexize(), and unaccent_dict().
{
TSDictionaryCacheEntry *entry;
if (TSDictionaryCacheHash == NULL)
{
/* First time through: initialize the hash table */
HASHCTL ctl;
MemSet(&ctl, 0, sizeof(ctl));
ctl.keysize = sizeof(Oid);
ctl.entrysize = sizeof(TSDictionaryCacheEntry);
ctl.hash = oid_hash;
TSDictionaryCacheHash = hash_create("Tsearch dictionary cache", 8,
&ctl, HASH_ELEM | HASH_FUNCTION);
/* Flush cache on pg_ts_dict and pg_ts_template changes */
CacheRegisterSyscacheCallback(TSDICTOID, InvalidateTSCacheCallBack,
PointerGetDatum(TSDictionaryCacheHash));
CacheRegisterSyscacheCallback(TSTEMPLATEOID, InvalidateTSCacheCallBack,
PointerGetDatum(TSDictionaryCacheHash));
/* Also make sure CacheMemoryContext exists */
if (!CacheMemoryContext)
CreateCacheMemoryContext();
}
/* Check single-entry cache */
if (lastUsedDictionary && lastUsedDictionary->dictId == dictId &&
lastUsedDictionary->isvalid)
return lastUsedDictionary;
/* Try to look up an existing entry */
entry = (TSDictionaryCacheEntry *) hash_search(TSDictionaryCacheHash,
(void *) &dictId,
HASH_FIND, NULL);
if (entry == NULL || !entry->isvalid)
{
/*
* If we didn't find one, we want to make one. But first look up the
* object to be sure the OID is real.
*/
HeapTuple tpdict,
tptmpl;
Form_pg_ts_dict dict;
Form_pg_ts_template template;
MemoryContext saveCtx;
tpdict = SearchSysCache1(TSDICTOID, ObjectIdGetDatum(dictId));
if (!HeapTupleIsValid(tpdict))
elog(ERROR, "cache lookup failed for text search dictionary %u",
dictId);
dict = (Form_pg_ts_dict) GETSTRUCT(tpdict);
/*
* Sanity checks
*/
if (!OidIsValid(dict->dicttemplate))
elog(ERROR, "text search dictionary %u has no template", dictId);
/*
* Retrieve dictionary's template
*/
tptmpl = SearchSysCache1(TSTEMPLATEOID,
ObjectIdGetDatum(dict->dicttemplate));
if (!HeapTupleIsValid(tptmpl))
elog(ERROR, "cache lookup failed for text search template %u",
dict->dicttemplate);
template = (Form_pg_ts_template) GETSTRUCT(tptmpl);
/*
* Sanity checks
*/
if (!OidIsValid(template->tmpllexize))
elog(ERROR, "text search template %u has no lexize method",
template->tmpllexize);
if (entry == NULL)
{
bool found;
/* Now make the cache entry */
entry = (TSDictionaryCacheEntry *)
hash_search(TSDictionaryCacheHash,
(void *) &dictId,
HASH_ENTER, &found);
Assert(!found); /* it wasn't there a moment ago */
/* Create private memory context the first time through */
saveCtx = AllocSetContextCreate(CacheMemoryContext,
NameStr(dict->dictname),
ALLOCSET_SMALL_MINSIZE,
ALLOCSET_SMALL_INITSIZE,
ALLOCSET_SMALL_MAXSIZE);
}
else
{
/* Clear the existing entry's private context */
saveCtx = entry->dictCtx;
MemoryContextResetAndDeleteChildren(saveCtx);
}
MemSet(entry, 0, sizeof(TSDictionaryCacheEntry));
entry->dictId = dictId;
entry->dictCtx = saveCtx;
entry->lexizeOid = template->tmpllexize;
if (OidIsValid(template->tmplinit))
{
List *dictoptions;
Datum opt;
bool isnull;
MemoryContext oldcontext;
/*
* Init method runs in dictionary's private memory context, and we
* make sure the options are stored there too
*/
oldcontext = MemoryContextSwitchTo(entry->dictCtx);
opt = SysCacheGetAttr(TSDICTOID, tpdict,
Anum_pg_ts_dict_dictinitoption,
&isnull);
if (isnull)
dictoptions = NIL;
else
dictoptions = deserialize_deflist(opt);
entry->dictData =
DatumGetPointer(OidFunctionCall1(template->tmplinit,
PointerGetDatum(dictoptions)));
MemoryContextSwitchTo(oldcontext);
}
ReleaseSysCache(tptmpl);
ReleaseSysCache(tpdict);
fmgr_info_cxt(entry->lexizeOid, &entry->lexize, entry->dictCtx);
entry->isvalid = true;
}
lastUsedDictionary = entry;
return entry;
}
| TSParserCacheEntry* lookup_ts_parser_cache | ( | Oid | prsId | ) |
Definition at line 111 of file ts_cache.c.
References Assert, CacheMemoryContext, CacheRegisterSyscacheCallback(), CreateCacheMemoryContext(), elog, TSParserCacheEntry::endOid, HASHCTL::entrysize, ERROR, fmgr_info_cxt(), GETSTRUCT, HASHCTL::hash, hash_create(), HASH_ELEM, HASH_FUNCTION, hash_search(), TSParserCacheEntry::headlineOid, HeapTupleIsValid, InvalidateTSCacheCallBack(), TSParserCacheEntry::isvalid, HASHCTL::keysize, 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().
{
TSParserCacheEntry *entry;
if (TSParserCacheHash == NULL)
{
/* First time through: initialize the hash table */
HASHCTL ctl;
MemSet(&ctl, 0, sizeof(ctl));
ctl.keysize = sizeof(Oid);
ctl.entrysize = sizeof(TSParserCacheEntry);
ctl.hash = oid_hash;
TSParserCacheHash = hash_create("Tsearch parser cache", 4,
&ctl, HASH_ELEM | HASH_FUNCTION);
/* Flush cache on pg_ts_parser changes */
CacheRegisterSyscacheCallback(TSPARSEROID, InvalidateTSCacheCallBack,
PointerGetDatum(TSParserCacheHash));
/* Also make sure CacheMemoryContext exists */
if (!CacheMemoryContext)
CreateCacheMemoryContext();
}
/* Check single-entry cache */
if (lastUsedParser && lastUsedParser->prsId == prsId &&
lastUsedParser->isvalid)
return lastUsedParser;
/* Try to look up an existing entry */
entry = (TSParserCacheEntry *) hash_search(TSParserCacheHash,
(void *) &prsId,
HASH_FIND, NULL);
if (entry == NULL || !entry->isvalid)
{
/*
* If we didn't find one, we want to make one. But first look up the
* object to be sure the OID is real.
*/
HeapTuple tp;
Form_pg_ts_parser prs;
tp = SearchSysCache1(TSPARSEROID, ObjectIdGetDatum(prsId));
if (!HeapTupleIsValid(tp))
elog(ERROR, "cache lookup failed for text search parser %u",
prsId);
prs = (Form_pg_ts_parser) GETSTRUCT(tp);
/*
* Sanity checks
*/
if (!OidIsValid(prs->prsstart))
elog(ERROR, "text search parser %u has no prsstart method", prsId);
if (!OidIsValid(prs->prstoken))
elog(ERROR, "text search parser %u has no prstoken method", prsId);
if (!OidIsValid(prs->prsend))
elog(ERROR, "text search parser %u has no prsend method", prsId);
if (entry == NULL)
{
bool found;
/* Now make the cache entry */
entry = (TSParserCacheEntry *)
hash_search(TSParserCacheHash,
(void *) &prsId,
HASH_ENTER, &found);
Assert(!found); /* it wasn't there a moment ago */
}
MemSet(entry, 0, sizeof(TSParserCacheEntry));
entry->prsId = prsId;
entry->startOid = prs->prsstart;
entry->tokenOid = prs->prstoken;
entry->endOid = prs->prsend;
entry->headlineOid = prs->prsheadline;
entry->lextypeOid = prs->prslextype;
ReleaseSysCache(tp);
fmgr_info_cxt(entry->startOid, &entry->prsstart, CacheMemoryContext);
fmgr_info_cxt(entry->tokenOid, &entry->prstoken, CacheMemoryContext);
fmgr_info_cxt(entry->endOid, &entry->prsend, CacheMemoryContext);
if (OidIsValid(entry->headlineOid))
fmgr_info_cxt(entry->headlineOid, &entry->prsheadline,
CacheMemoryContext);
entry->isvalid = true;
}
lastUsedParser = entry;
return entry;
}
TSConfigCacheEntry* lastUsedConfig = NULL [static] |
Definition at line 69 of file ts_cache.c.
TSDictionaryCacheEntry* lastUsedDictionary = NULL [static] |
Definition at line 66 of file ts_cache.c.
TSParserCacheEntry* lastUsedParser = NULL [static] |
Definition at line 63 of file ts_cache.c.
HTAB* TSConfigCacheHash = NULL [static] |
Definition at line 68 of file ts_cache.c.
| char* TSCurrentConfig = NULL |
Definition at line 74 of file ts_cache.c.
Referenced by getTSCurrentConfig().
Oid TSCurrentConfigCache = InvalidOid [static] |
Definition at line 76 of file ts_cache.c.
Referenced by assign_TSCurrentConfig(), getTSCurrentConfig(), and InvalidateTSCacheCallBack().
HTAB* TSDictionaryCacheHash = NULL [static] |
Definition at line 65 of file ts_cache.c.
HTAB* TSParserCacheHash = NULL [static] |
Definition at line 62 of file ts_cache.c.
1.7.1