本文整理汇总了C++中HeapTupleIsValid函数的典型用法代码示例。如果您正苦于以下问题:C++ HeapTupleIsValid函数的具体用法?C++ HeapTupleIsValid怎么用?C++ HeapTupleIsValid使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了HeapTupleIsValid函数的20个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于我们的系统推荐出更棒的C++代码示例。
示例1: SearchCatCache
//.........这里部分代码省略.........
* near the front of the hashbucket's list.)
*/
DLMoveToFront(&ct->cache_elem);
/*
* If it's a positive entry, bump its refcount and return it. If it's
* negative, we can report failure to the caller.
*/
if (!ct->negative)
{
ResourceOwnerEnlargeCatCacheRefs(CurrentResourceOwner);
ct->refcount++;
ResourceOwnerRememberCatCacheRef(CurrentResourceOwner, &ct->tuple);
CACHE3_elog(DEBUG2, "SearchCatCache(%s): found in bucket %d",
cache->cc_relname, hashIndex);
#ifdef CATCACHE_STATS
cache->cc_hits++;
#endif
return &ct->tuple;
}
else
{
CACHE3_elog(DEBUG2, "SearchCatCache(%s): found neg entry in bucket %d",
cache->cc_relname, hashIndex);
#ifdef CATCACHE_STATS
cache->cc_neg_hits++;
#endif
return NULL;
}
}
/*
* Tuple was not found in cache, so we have to try to retrieve it directly
* from the relation. If found, we will add it to the cache; if not
* found, we will add a negative cache entry instead.
*
* NOTE: it is possible for recursive cache lookups to occur while reading
* the relation --- for example, due to shared-cache-inval messages being
* processed during heap_open(). This is OK. It's even possible for one
* of those lookups to find and enter the very same tuple we are trying to
* fetch here. If that happens, we will enter a second copy of the tuple
* into the cache. The first copy will never be referenced again, and
* will eventually age out of the cache, so there's no functional problem.
* This case is rare enough that it's not worth expending extra cycles to
* detect.
*/
relation = heap_open(cache->cc_reloid, AccessShareLock);
scandesc = systable_beginscan(relation,
cache->cc_indexoid,
IndexScanOK(cache, cur_skey),
SnapshotNow,
cache->cc_nkeys,
cur_skey);
ct = NULL;
while (HeapTupleIsValid(ntp = systable_getnext(scandesc)))
{
ct = CatalogCacheCreateEntry(cache, ntp,
hashValue, hashIndex,
false);
if (scandesc->inmemonlyscan)
{
/* Make sure tuple is removed during ReleaseCatCache */
ct->dead = true;
}
/* immediately set the refcount to 1 */
ResourceOwnerEnlargeCatCacheRefs(CurrentResourceOwner);
ct->refcount++;
ResourceOwnerRememberCatCacheRef(CurrentResourceOwner, &ct->tuple);
break; /* assume only one match */
}
systable_endscan(scandesc);
heap_close(relation, AccessShareLock);
if (ct == NULL)
{
return NULL;
}
CACHE4_elog(DEBUG2, "SearchCatCache(%s): Contains %d/%d tuples",
cache->cc_relname, cache->cc_ntup, CCacheHdr->ch_ntup);
CACHE3_elog(DEBUG2, "SearchCatCache(%s): put in bucket %d",
cache->cc_relname, hashIndex);
#ifdef CATCACHE_STATS
cache->cc_newloads++;
#endif
return &ct->tuple;
}
开发者ID:BALDELab,项目名称:incubator-hawq,代码行数:101,代码来源:catcache.c
示例2: ltreeparentsel
/*
* ltreeparentsel - Selectivity of parent relationship for ltree data types.
*/
Datum
ltreeparentsel(PG_FUNCTION_ARGS)
{
PlannerInfo *root = (PlannerInfo *) PG_GETARG_POINTER(0);
Oid operator = PG_GETARG_OID(1);
List *args = (List *) PG_GETARG_POINTER(2);
int varRelid = PG_GETARG_INT32(3);
VariableStatData vardata;
Node *other;
bool varonleft;
double selec;
/*
* If expression is not variable <@ something or something <@ variable,
* then punt and return a default estimate.
*/
if (!get_restriction_variable(root, args, varRelid,
&vardata, &other, &varonleft))
PG_RETURN_FLOAT8(DEFAULT_PARENT_SEL);
/*
* If the something is a NULL constant, assume operator is strict and
* return zero, ie, operator will never return TRUE.
*/
if (IsA(other, Const) &&
((Const *) other)->constisnull)
{
ReleaseVariableStats(vardata);
PG_RETURN_FLOAT8(0.0);
}
if (IsA(other, Const))
{
/* Variable is being compared to a known non-null constant */
Datum constval = ((Const *) other)->constvalue;
FmgrInfo contproc;
double mcvsum;
double mcvsel;
double nullfrac;
fmgr_info(get_opcode(operator), &contproc);
/*
* Is the constant "<@" to any of the column's most common values?
*/
mcvsel = mcv_selectivity(&vardata, &contproc, constval, varonleft,
&mcvsum);
/*
* If the histogram is large enough, see what fraction of it the
* constant is "<@" to, and assume that's representative of the
* non-MCV population. Otherwise use the default selectivity for the
* non-MCV population.
*/
selec = histogram_selectivity(&vardata, &contproc,
constval, varonleft,
100, 1);
if (selec < 0)
{
/* Nope, fall back on default */
selec = DEFAULT_PARENT_SEL;
}
else
{
/* Yes, but don't believe extremely small or large estimates. */
if (selec < 0.0001)
selec = 0.0001;
else if (selec > 0.9999)
selec = 0.9999;
}
if (HeapTupleIsValid(vardata.statsTuple))
nullfrac = ((Form_pg_statistic) GETSTRUCT(vardata.statsTuple))->stanullfrac;
else
nullfrac = 0.0;
/*
* Now merge the results from the MCV and histogram calculations,
* realizing that the histogram covers only the non-null values that
* are not listed in MCV.
*/
selec *= 1.0 - nullfrac - mcvsum;
selec += mcvsel;
}
else
selec = DEFAULT_PARENT_SEL;
ReleaseVariableStats(vardata);
/* result should be in range, but make sure... */
CLAMP_PROBABILITY(selec);
PG_RETURN_FLOAT8((float8) selec);
}
开发者ID:KMU-embedded,项目名称:mosbench-ext,代码行数:97,代码来源:ltree_op.c
示例3: BuildEventTriggerCache
/*
* Rebuild the event trigger cache.
*/
static void
BuildEventTriggerCache(void)
{
HASHCTL ctl;
HTAB *cache;
MemoryContext oldcontext;
Relation rel;
Relation irel;
SysScanDesc scan;
if (EventTriggerCacheContext != NULL)
{
/*
* The cache has been previously built, and subsequently invalidated,
* and now we're trying to rebuild it. Normally, there won't be
* anything in the context at this point, because the invalidation
* will have already reset it. But if the previous attempt to rebuild
* the cache failed, then there might be some junk lying around
* that we want to reclaim.
*/
MemoryContextReset(EventTriggerCacheContext);
}
else
{
/*
* This is our first time attempting to build the cache, so we need
* to set up the memory context and register a syscache callback to
* capture future invalidation events.
*/
if (CacheMemoryContext == NULL)
CreateCacheMemoryContext();
EventTriggerCacheContext =
AllocSetContextCreate(CacheMemoryContext,
"EventTriggerCache",
ALLOCSET_DEFAULT_MINSIZE,
ALLOCSET_DEFAULT_INITSIZE,
ALLOCSET_DEFAULT_MAXSIZE);
CacheRegisterSyscacheCallback(EVENTTRIGGEROID,
InvalidateEventCacheCallback,
(Datum) 0);
}
/* Switch to correct memory context. */
oldcontext = MemoryContextSwitchTo(EventTriggerCacheContext);
/*
* Create a new hash table, but don't assign it to the global variable
* until it accurately represents the state of the catalogs, so that
* if we fail midway through this we won't end up with incorrect cache
* contents.
*/
MemSet(&ctl, 0, sizeof(ctl));
ctl.keysize = sizeof(EventTriggerEvent);
ctl.entrysize = sizeof(EventTriggerCacheEntry);
ctl.hash = tag_hash;
cache = hash_create("Event Trigger Cache", 32, &ctl,
HASH_ELEM | HASH_FUNCTION);
/*
* Prepare to scan pg_event_trigger in name order. We use an MVCC
* snapshot to avoid getting inconsistent results if the table is
* being concurrently updated.
*/
rel = relation_open(EventTriggerRelationId, AccessShareLock);
irel = index_open(EventTriggerNameIndexId, AccessShareLock);
scan = systable_beginscan_ordered(rel, irel, GetLatestSnapshot(), 0, NULL);
/*
* Build a cache item for each pg_event_trigger tuple, and append each
* one to the appropriate cache entry.
*/
for (;;)
{
HeapTuple tup;
Form_pg_event_trigger form;
char *evtevent;
EventTriggerEvent event;
EventTriggerCacheItem *item;
Datum evttags;
bool evttags_isnull;
EventTriggerCacheEntry *entry;
bool found;
/* Get next tuple. */
tup = systable_getnext_ordered(scan, ForwardScanDirection);
if (!HeapTupleIsValid(tup))
break;
/* Skip trigger if disabled. */
form = (Form_pg_event_trigger) GETSTRUCT(tup);
if (form->evtenabled == TRIGGER_DISABLED)
continue;
/* Decode event name. */
evtevent = NameStr(form->evtevent);
if (strcmp(evtevent, "ddl_command_start") == 0)
event = EVT_DDLCommandStart;
//.........这里部分代码省略.........
开发者ID:lhcezar,项目名称:postgres,代码行数:101,代码来源:evtcache.c
示例4: sepgsql_relation_setattr
/*
* sepgsql_relation_setattr
*
* It checks privileges to set attribute of the supplied relation
*/
void
sepgsql_relation_setattr(Oid relOid)
{
Relation rel;
ScanKeyData skey;
SysScanDesc sscan;
HeapTuple oldtup;
HeapTuple newtup;
Form_pg_class oldform;
Form_pg_class newform;
ObjectAddress object;
char *audit_name;
uint16_t tclass;
switch (get_rel_relkind(relOid))
{
case RELKIND_RELATION:
tclass = SEPG_CLASS_DB_TABLE;
break;
case RELKIND_SEQUENCE:
tclass = SEPG_CLASS_DB_SEQUENCE;
break;
case RELKIND_VIEW:
tclass = SEPG_CLASS_DB_VIEW;
break;
case RELKIND_INDEX:
/* deal with indexes specially */
sepgsql_index_modify(relOid);
return;
default:
/* other relkinds don't need additional work */
return;
}
/*
* Fetch newer catalog
*/
rel = heap_open(RelationRelationId, AccessShareLock);
ScanKeyInit(&skey,
ObjectIdAttributeNumber,
BTEqualStrategyNumber, F_OIDEQ,
ObjectIdGetDatum(relOid));
sscan = systable_beginscan(rel, ClassOidIndexId, true,
SnapshotSelf, 1, &skey);
newtup = systable_getnext(sscan);
if (!HeapTupleIsValid(newtup))
elog(ERROR, "catalog lookup failed for relation %u", relOid);
newform = (Form_pg_class) GETSTRUCT(newtup);
/*
* Fetch older catalog
*/
oldtup = SearchSysCache1(RELOID, ObjectIdGetDatum(relOid));
if (!HeapTupleIsValid(oldtup))
elog(ERROR, "cache lookup failed for relation %u", relOid);
oldform = (Form_pg_class) GETSTRUCT(oldtup);
/*
* Does this ALTER command takes operation to namespace?
*/
if (newform->relnamespace != oldform->relnamespace)
{
sepgsql_schema_remove_name(oldform->relnamespace);
sepgsql_schema_add_name(newform->relnamespace);
}
if (strcmp(NameStr(newform->relname), NameStr(oldform->relname)) != 0)
sepgsql_schema_rename(oldform->relnamespace);
/*
* XXX - In the future version, db_tuple:{use} of system catalog entry
* shall be checked, if tablespace configuration is changed.
*/
/*
* check db_xxx:{setattr} permission
*/
object.classId = RelationRelationId;
object.objectId = relOid;
object.objectSubId = 0;
audit_name = getObjectIdentity(&object);
sepgsql_avc_check_perms(&object,
tclass,
SEPG_DB_TABLE__SETATTR,
audit_name,
true);
pfree(audit_name);
ReleaseSysCache(oldtup);
systable_endscan(sscan);
heap_close(rel, AccessShareLock);
}
开发者ID:amulsul,项目名称:postgres,代码行数:100,代码来源:relation.c
示例5: swap_heap_or_index_files
/*
* This is a copy of swap_relation_files in cluster.c, but it also swaps
* relfrozenxid.
*/
static void
swap_heap_or_index_files(Oid r1, Oid r2)
{
Relation relRelation;
HeapTuple reltup1,
reltup2;
Form_pg_class relform1,
relform2;
Oid swaptemp;
CatalogIndexState indstate;
/* We need writable copies of both pg_class tuples. */
relRelation = heap_open(RelationRelationId, RowExclusiveLock);
reltup1 = SearchSysCacheCopy(RELOID,
ObjectIdGetDatum(r1),
0, 0, 0);
if (!HeapTupleIsValid(reltup1))
elog(ERROR, "cache lookup failed for relation %u", r1);
relform1 = (Form_pg_class) GETSTRUCT(reltup1);
reltup2 = SearchSysCacheCopy(RELOID,
ObjectIdGetDatum(r2),
0, 0, 0);
if (!HeapTupleIsValid(reltup2))
elog(ERROR, "cache lookup failed for relation %u", r2);
relform2 = (Form_pg_class) GETSTRUCT(reltup2);
Assert(relform1->relkind == relform2->relkind);
/*
* Actually swap the fields in the two tuples
*/
swaptemp = relform1->relfilenode;
relform1->relfilenode = relform2->relfilenode;
relform2->relfilenode = swaptemp;
swaptemp = relform1->reltablespace;
relform1->reltablespace = relform2->reltablespace;
relform2->reltablespace = swaptemp;
swaptemp = relform1->reltoastrelid;
relform1->reltoastrelid = relform2->reltoastrelid;
relform2->reltoastrelid = swaptemp;
/* set rel1's frozen Xid to larger one */
if (TransactionIdIsNormal(relform1->relfrozenxid))
{
if (TransactionIdFollows(relform1->relfrozenxid,
relform2->relfrozenxid))
relform1->relfrozenxid = relform2->relfrozenxid;
else
relform2->relfrozenxid = relform1->relfrozenxid;
}
/* swap size statistics too, since new rel has freshly-updated stats */
{
#if PG_VERSION_NUM >= 90300
int32 swap_pages;
#else
int4 swap_pages;
#endif
float4 swap_tuples;
swap_pages = relform1->relpages;
relform1->relpages = relform2->relpages;
relform2->relpages = swap_pages;
swap_tuples = relform1->reltuples;
relform1->reltuples = relform2->reltuples;
relform2->reltuples = swap_tuples;
}
/* Update the tuples in pg_class */
simple_heap_update(relRelation, &reltup1->t_self, reltup1);
simple_heap_update(relRelation, &reltup2->t_self, reltup2);
/* Keep system catalogs current */
indstate = CatalogOpenIndexes(relRelation);
CatalogIndexInsert(indstate, reltup1);
CatalogIndexInsert(indstate, reltup2);
CatalogCloseIndexes(indstate);
/*
* If we have toast tables associated with the relations being swapped,
* change their dependency links to re-associate them with their new
* owning relations. Otherwise the wrong one will get dropped ...
*
* NOTE: it is possible that only one table has a toast table; this can
* happen in CLUSTER if there were dropped columns in the old table, and
* in ALTER TABLE when adding or changing type of columns.
*
* NOTE: at present, a TOAST table's only dependency is the one on its
* owning table. If more are ever created, we'd need to use something
* more selective than deleteDependencyRecordsFor() to get rid of only the
* link we want.
//.........这里部分代码省略.........
开发者ID:reorg,项目名称:pg_reorg,代码行数:101,代码来源:reorg.c
示例6: find_language_template
/*
* Look to see if we have template information for the given language name.
*/
static PLTemplate *
find_language_template(const char *languageName)
{
PLTemplate *result;
Relation rel;
SysScanDesc scan;
ScanKeyData key;
HeapTuple tup;
rel = heap_open(PLTemplateRelationId, AccessShareLock);
ScanKeyInit(&key,
Anum_pg_pltemplate_tmplname,
BTEqualStrategyNumber, F_NAMEEQ,
CStringGetDatum(languageName));
scan = systable_beginscan(rel, PLTemplateNameIndexId, true,
NULL, 1, &key);
tup = systable_getnext(scan);
if (HeapTupleIsValid(tup))
{
Form_pg_pltemplate tmpl = (Form_pg_pltemplate) GETSTRUCT(tup);
Datum datum;
bool isnull;
result = (PLTemplate *) palloc0(sizeof(PLTemplate));
result->tmpltrusted = tmpl->tmpltrusted;
result->tmpldbacreate = tmpl->tmpldbacreate;
/* Remaining fields are variable-width so we need heap_getattr */
datum = heap_getattr(tup, Anum_pg_pltemplate_tmplhandler,
RelationGetDescr(rel), &isnull);
if (!isnull)
result->tmplhandler = TextDatumGetCString(datum);
datum = heap_getattr(tup, Anum_pg_pltemplate_tmplinline,
RelationGetDescr(rel), &isnull);
if (!isnull)
result->tmplinline = TextDatumGetCString(datum);
datum = heap_getattr(tup, Anum_pg_pltemplate_tmplvalidator,
RelationGetDescr(rel), &isnull);
if (!isnull)
result->tmplvalidator = TextDatumGetCString(datum);
datum = heap_getattr(tup, Anum_pg_pltemplate_tmpllibrary,
RelationGetDescr(rel), &isnull);
if (!isnull)
result->tmpllibrary = TextDatumGetCString(datum);
/* Ignore template if handler or library info is missing */
if (!result->tmplhandler || !result->tmpllibrary)
result = NULL;
}
else
result = NULL;
systable_endscan(scan);
heap_close(rel, AccessShareLock);
return result;
}
开发者ID:Brar,项目名称:postgres,代码行数:66,代码来源:proclang.c
示例7: sepgsql_relation_post_create
/*
* sepgsql_relation_post_create
*
* The post creation hook of relation/attribute
*/
void
sepgsql_relation_post_create(Oid relOid)
{
Relation rel;
ScanKeyData skey;
SysScanDesc sscan;
HeapTuple tuple;
Form_pg_class classForm;
ObjectAddress object;
uint16 tclass;
char *scontext; /* subject */
char *tcontext; /* schema */
char *rcontext; /* relation */
char *ccontext; /* column */
char *nsp_name;
StringInfoData audit_name;
/*
* Fetch catalog record of the new relation. Because pg_class entry is not
* visible right now, we need to scan the catalog using SnapshotSelf.
*/
rel = heap_open(RelationRelationId, AccessShareLock);
ScanKeyInit(&skey,
ObjectIdAttributeNumber,
BTEqualStrategyNumber, F_OIDEQ,
ObjectIdGetDatum(relOid));
sscan = systable_beginscan(rel, ClassOidIndexId, true,
SnapshotSelf, 1, &skey);
tuple = systable_getnext(sscan);
if (!HeapTupleIsValid(tuple))
elog(ERROR, "catalog lookup failed for relation %u", relOid);
classForm = (Form_pg_class) GETSTRUCT(tuple);
/* ignore indexes on toast tables */
if (classForm->relkind == RELKIND_INDEX &&
classForm->relnamespace == PG_TOAST_NAMESPACE)
goto out;
/*
* check db_schema:{add_name} permission of the namespace
*/
object.classId = NamespaceRelationId;
object.objectId = classForm->relnamespace;
object.objectSubId = 0;
sepgsql_avc_check_perms(&object,
SEPG_CLASS_DB_SCHEMA,
SEPG_DB_SCHEMA__ADD_NAME,
getObjectIdentity(&object),
true);
switch (classForm->relkind)
{
case RELKIND_RELATION:
tclass = SEPG_CLASS_DB_TABLE;
break;
case RELKIND_SEQUENCE:
tclass = SEPG_CLASS_DB_SEQUENCE;
break;
case RELKIND_VIEW:
tclass = SEPG_CLASS_DB_VIEW;
break;
case RELKIND_INDEX:
/* deal with indexes specially; no need for tclass */
sepgsql_index_modify(relOid);
goto out;
default:
/* ignore other relkinds */
goto out;
}
/*
* Compute a default security label when we create a new relation object
* under the specified namespace.
*/
scontext = sepgsql_get_client_label();
tcontext = sepgsql_get_label(NamespaceRelationId,
classForm->relnamespace, 0);
rcontext = sepgsql_compute_create(scontext, tcontext, tclass,
NameStr(classForm->relname));
/*
* check db_xxx:{create} permission
*/
nsp_name = get_namespace_name(classForm->relnamespace);
initStringInfo(&audit_name);
appendStringInfo(&audit_name, "%s.%s",
quote_identifier(nsp_name),
quote_identifier(NameStr(classForm->relname)));
sepgsql_avc_check_perms_label(rcontext,
tclass,
SEPG_DB_DATABASE__CREATE,
//.........这里部分代码省略.........
开发者ID:amulsul,项目名称:postgres,代码行数:101,代码来源:relation.c
示例8: get_attstatsslot
/*
* get_attstatsslot
*
* Extract the contents of a "slot" of a pg_statistic tuple.
* Returns TRUE if requested slot type was found, else FALSE.
*
* Unlike other routines in this file, this takes a pointer to an
* already-looked-up tuple in the pg_statistic cache. We do this since
* most callers will want to extract more than one value from the cache
* entry, and we don't want to repeat the cache lookup unnecessarily.
*
* statstuple: pg_statistics tuple to be examined.
* atttype: type OID of attribute (can be InvalidOid if values == NULL).
* atttypmod: typmod of attribute (can be 0 if values == NULL).
* reqkind: STAKIND code for desired statistics slot kind.
* reqop: STAOP value wanted, or InvalidOid if don't care.
* values, nvalues: if not NULL, the slot's stavalues are extracted.
* numbers, nnumbers: if not NULL, the slot's stanumbers are extracted.
*
* If assigned, values and numbers are set to point to palloc'd arrays.
* If the attribute type is pass-by-reference, the values referenced by
* the values array are themselves palloc'd. The palloc'd stuff can be
* freed by calling free_attstatsslot.
*/
bool
get_attstatsslot(HeapTuple statstuple,
Oid atttype, int32 atttypmod,
int reqkind, Oid reqop,
Datum **values, int *nvalues,
float4 **numbers, int *nnumbers)
{
Form_pg_statistic stats = (Form_pg_statistic) GETSTRUCT(statstuple);
int i,
j;
Datum val;
bool isnull;
ArrayType *statarray;
int narrayelem;
HeapTuple typeTuple;
Form_pg_type typeForm;
for (i = 0; i < STATISTIC_NUM_SLOTS; i++)
{
if ((&stats->stakind1)[i] == reqkind &&
(reqop == InvalidOid || (&stats->staop1)[i] == reqop))
break;
}
if (i >= STATISTIC_NUM_SLOTS)
return false; /* not there */
if (values)
{
val = SysCacheGetAttr(STATRELATT, statstuple,
Anum_pg_statistic_stavalues1 + i,
&isnull);
if (isnull)
elog(ERROR, "stavalues is null");
statarray = DatumGetArrayTypeP(val);
/* Need to get info about the array element type */
typeTuple = SearchSysCache(TYPEOID,
ObjectIdGetDatum(atttype),
0, 0, 0);
if (!HeapTupleIsValid(typeTuple))
elog(ERROR, "cache lookup failed for type %u", atttype);
typeForm = (Form_pg_type) GETSTRUCT(typeTuple);
/* Deconstruct array into Datum elements; NULLs not expected */
deconstruct_array(statarray,
atttype,
typeForm->typlen,
typeForm->typbyval,
typeForm->typalign,
values, NULL, nvalues);
/*
* If the element type is pass-by-reference, we now have a bunch of
* Datums that are pointers into the syscache value. Copy them to
* avoid problems if syscache decides to drop the entry.
*/
if (!typeForm->typbyval)
{
for (j = 0; j < *nvalues; j++)
{
(*values)[j] = datumCopy((*values)[j],
typeForm->typbyval,
typeForm->typlen);
}
}
ReleaseSysCache(typeTuple);
/*
* Free statarray if it's a detoasted copy.
*/
if ((Pointer) statarray != DatumGetPointer(val))
pfree(statarray);
}
if (numbers)
//.........这里部分代码省略.........
开发者ID:merlintang,项目名称:sgb,代码行数:101,代码来源:lsyscache.c
示例9: RelidByRelfilenode
/*
* Map a relation's (tablespace, filenode) to a relation's oid and cache the
* result.
*
* Returns InvalidOid if no relation matching the criteria could be found.
*/
Oid
RelidByRelfilenode(Oid reltablespace, Oid relfilenode)
{
RelfilenodeMapKey key;
RelfilenodeMapEntry *entry;
bool found;
SysScanDesc scandesc;
Relation relation;
HeapTuple ntp;
ScanKeyData skey[2];
Oid relid;
if (RelfilenodeMapHash == NULL)
InitializeRelfilenodeMap();
/* pg_class will show 0 when the value is actually MyDatabaseTableSpace */
if (reltablespace == MyDatabaseTableSpace)
reltablespace = 0;
MemSet(&key, 0, sizeof(key));
key.reltablespace = reltablespace;
key.relfilenode = relfilenode;
/*
* Check cache and return entry if one is found. Even if no target
* relation can be found later on we store the negative match and return a
* InvalidOid from cache. That's not really necessary for performance
* since querying invalid values isn't supposed to be a frequent thing,
* but it's basically free.
*/
entry = hash_search(RelfilenodeMapHash, (void *) &key, HASH_FIND, &found);
if (found)
return entry->relid;
/* ok, no previous cache entry, do it the hard way */
/* initialize empty/negative cache entry before doing the actual lookups */
relid = InvalidOid;
if (reltablespace == GLOBALTABLESPACE_OID)
{
/*
* Ok, shared table, check relmapper.
*/
relid = RelationMapFilenodeToOid(relfilenode, true);
}
else
{
/*
* Not a shared table, could either be a plain relation or a
* non-shared, nailed one, like e.g. pg_class.
*/
/* check for plain relations by looking in pg_class */
relation = heap_open(RelationRelationId, AccessShareLock);
/* copy scankey to local copy, it will be modified during the scan */
memcpy(skey, relfilenode_skey, sizeof(skey));
/* set scan arguments */
skey[0].sk_argument = ObjectIdGetDatum(reltablespace);
skey[1].sk_argument = ObjectIdGetDatum(relfilenode);
scandesc = systable_beginscan(relation,
ClassTblspcRelfilenodeIndexId,
true,
NULL,
2,
skey);
found = false;
while (HeapTupleIsValid(ntp = systable_getnext(scandesc)))
{
if (found)
elog(ERROR,
"unexpected duplicate for tablespace %u, relfilenode %u",
reltablespace, relfilenode);
found = true;
#ifdef USE_ASSERT_CHECKING
{
bool isnull;
Oid check;
check = fastgetattr(ntp, Anum_pg_class_reltablespace,
RelationGetDescr(relation),
&isnull);
Assert(!isnull && check == reltablespace);
check = fastgetattr(ntp, Anum_pg_class_relfilenode,
RelationGetDescr(relation),
&isnull);
//.........这里部分代码省略.........
开发者ID:winlibs,项目名称:postgresql,代码行数:101,代码来源:relfilenodemap.c
示例10: get_type_io_data
/*
* get_type_io_data
*
* A six-fer: given the type OID, return typlen, typbyval, typalign,
* typdelim, typioparam, and IO function OID. The IO function
* returned is controlled by IOFuncSelector
*/
void
get_type_io_data(Oid typid,
IOFuncSelector which_func,
int16 *typlen,
bool *typbyval,
char *typalign,
char *typdelim,
Oid *typioparam,
Oid *func)
{
HeapTuple typeTuple;
Form_pg_type typeStruct;
/*
* In bootstrap mode, pass it off to bootstrap.c. This hack allows us to
* use array_in and array_out during bootstrap.
*/
if (IsBootstrapProcessingMode())
{
Oid typinput;
Oid typoutput;
boot_get_type_io_data(typid,
typlen,
typbyval,
typalign,
typdelim,
typioparam,
&typinput,
&typoutput);
switch (which_func)
{
case IOFunc_input:
*func = typinput;
break;
case IOFunc_output:
*func = typoutput;
break;
default:
elog(ERROR, "binary I/O not supported during bootstrap");
break;
}
return;
}
typeTuple = SearchSysCache(TYPEOID,
ObjectIdGetDatum(typid),
0, 0, 0);
if (!HeapTupleIsValid(typeTuple))
elog(ERROR, "cache lookup failed for type %u", typid);
typeStruct = (Form_pg_type) GETSTRUCT(typeTuple);
*typlen = typeStruct->typlen;
*typbyval = typeStruct->typbyval;
*typalign = typeStruct->typalign;
*typdelim = typeStruct->typdelim;
*typioparam = getTypeIOParam(typeTuple);
switch (which_func)
{
case IOFunc_input:
*func = typeStruct->typinput;
break;
case IOFunc_output:
*func = typeStruct->typoutput;
break;
case IOFunc_receive:
*func = typeStruct->typreceive;
break;
case IOFunc_send:
*func = typeStruct->typsend;
break;
}
ReleaseSysCache(typeTuple);
}
开发者ID:merlintang,项目名称:sgb,代码行数:81,代码来源:lsyscache.c
示例11: get_typdefault
/*
* get_typdefault
* Given a type OID, return the type's default value, if any.
*
* The result is a palloc'd expression node tree, or NULL if there
* is no defined default for the datatype.
*
* NB: caller should be prepared to coerce result to correct datatype;
* the returned expression tree might produce something of the wrong type.
*/
Node *
get_typdefault(Oid typid)
{
HeapTuple typeTuple;
Form_pg_type type;
Datum datum;
bool isNull;
Node *expr;
typeTuple = SearchSysCache(TYPEOID,
ObjectIdGetDatum(typid),
0, 0, 0);
if (!HeapTupleIsValid(typeTuple))
elog(ERROR, "cache lookup failed for type %u", typid);
type = (Form_pg_type) GETSTRUCT(typeTuple);
/*
* typdefault and typdefaultbin are potentially null, so don't try to
* access 'em as struct fields. Must do it the hard way with
* SysCacheGetAttr.
*/
datum = SysCacheGetAttr(TYPEOID,
typeTuple,
Anum_pg_type_typdefaultbin,
&isNull);
if (!isNull)
{
/* We have an expression default */
expr = stringToNode(DatumGetCString(DirectFunctionCall1(textout,
datum)));
}
else
{
/* Perhaps we have a plain literal default */
datum = SysCacheGetAttr(TYPEOID,
typeTuple,
Anum_pg_type_typdefault,
&isNull);
if (!isNull)
{
char *strDefaultVal;
/* Convert text datum to C string */
strDefaultVal = DatumGetCString(DirectFunctionCall1(textout,
datum));
/* Convert C string to a value of the given type */
datum = OidInputFunctionCall(type->typinput, strDefaultVal,
getTypeIOParam(typeTuple), -1);
/* Build a Const node containing the value */
expr = (Node *) makeConst(typid,
type->typlen,
datum,
false,
type->typbyval);
pfree(strDefaultVal);
}
else
{
/* No default */
expr = NULL;
}
}
ReleaseSysCache(typeTuple);
return expr;
}
开发者ID:merlintang,项目名称:sgb,代码行数:79,代码来源:lsyscache.c
示例12: pg_newlocale_from_collation
/*
* Create a locale_t from a collation OID. Results are cached for the
* lifetime of the backend. Thus, do not free the result with freelocale().
*
* As a special optimization, the default/database collation returns 0.
* Callers should then revert to the non-locale_t-enabled code path.
* In fact, they shouldn't call this function at all when they are dealing
* with the default locale. That can save quite a bit in hotspots.
* Also, callers should avoid calling this before going down a C/POSIX
* fastpath, because such a fastpath should work even on platforms without
* locale_t support in the C library.
*
* For simplicity, we always generate COLLATE + CTYPE even though we
* might only need one of them. Since this is called only once per session,
* it shouldn't cost much.
*/
pg_locale_t
pg_newlocale_from_collation(Oid collid)
{
collation_cache_entry *cache_entry;
/* Callers must pass a valid OID */
Assert(OidIsValid(collid));
/* Return 0 for "default" collation, just in case caller forgets */
if (collid == DEFAULT_COLLATION_OID)
return (pg_locale_t) 0;
cache_entry = lookup_collation_cache(collid, false);
if (cache_entry->locale == 0)
{
/* We haven't computed this yet in this session, so do it */
#ifdef HAVE_LOCALE_T
HeapTuple tp;
Form_pg_collation collform;
const char *collcollate;
const char *collctype;
locale_t result;
tp = SearchSysCache1(COLLOID, ObjectIdGetDatum(collid));
if (!HeapTupleIsValid(tp))
elog(ERROR, "cache lookup failed for collation %u", collid);
collform = (Form_pg_collation) GETSTRUCT(tp);
collcollate = NameStr(collform->collcollate);
collctype = NameStr(collform->collctype);
if (strcmp(collcollate, collctype) == 0)
{
/* Normal case where they're the same */
#ifndef WIN32
result = newlocale(LC_COLLATE_MASK | LC_CTYPE_MASK, collcollate,
NULL);
#else
result = _create_locale(LC_ALL, collcollate);
#endif
if (!result)
report_newlocale_failure(collcollate);
}
else
{
#ifndef WIN32
/* We need two newlocale() steps */
locale_t loc1;
loc1 = newlocale(LC_COLLATE_MASK, collcollate, NULL);
if (!loc1)
report_newlocale_failure(collcollate);
result = newlocale(LC_CTYPE_MASK, collctype, loc1);
if (!result)
report_newlocale_failure(collctype);
#else
/*
* XXX The _create_locale() API doesn't appear to support this.
* Could perhaps be worked around by changing pg_locale_t to
* contain two separate fields.
*/
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("collations with different collate and ctype values are not supported on this platform")));
#endif
}
cache_entry->locale = result;
ReleaseSysCache(tp);
#else /* not HAVE_LOCALE_T */
/*
* For platforms that don't support locale_t, we can't do anything
* with non-default collations.
*/
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("nondefault collations are not supported on this platform")));
#endif /* not HAVE_LOCALE_T */
}
//.........这里部分代码省略.........
开发者ID:Epictetus,项目名称:postgres,代码行数:101,代码来源:pg_locale.c
示例13: lookup_collation_cache
static collation_cache_entry *
lookup_collation_cache(Oid collation, bool set_flags)
{
collation_cache_entry *cache_entry;
bool found;
Assert(OidIsValid(collation));
Assert(collation != DEFAULT_COLLATION_OID);
if (collation_cache == NULL)
{
/* First time through, initialize the hash table */
HASHCTL ctl;
memset(&ctl, 0, sizeof(ctl));
ctl.keysize = sizeof(Oid);
ctl.entrysize = sizeof(collation_cache_entry);
ctl.hash = oid_hash;
collation_cache = hash_create("Collation cache", 100, &ctl,
HASH_ELEM | HASH_FUNCTION);
}
cache_entry = hash_search(collation_cache, &collation, HASH_ENTER, &found);
if (!found)
{
/*
* Make sure cache entry is marked invalid, in case we fail before
* setting things.
*/
cache_entry->flags_valid = false;
cache_entry->locale = 0;
}
if (set_flags && !cache_entry->flags_valid)
{
/* Attempt to set the flags */
HeapTuple tp;
Form_pg_collation collform;
const char *collcollate;
const char *collctype;
tp = SearchSysCache1(COLLOID, ObjectIdGetDatum(collation));
if (!HeapTupleIsValid(tp))
elog(ERROR, "cache lookup failed for collation %u", collation);
collform = (Form_pg_collation) GETSTRUCT(tp);
collcollate = NameStr(collform->collcollate);
collctype = NameStr(collform->collctype);
cache_entry->collate_is_c = ((strcmp(collcollate, "C") == 0) ||
(strcmp(collcollate, "POSIX") == 0));
cache_entry->ctype_is_c = ((strcmp(collctype, "C") == 0) ||
(strcmp(collctype, "POSIX") == 0));
cache_entry->flags_valid = true;
ReleaseSysCache(tp);
}
return cache_entry;
}
开发者ID:Epictetus,项目名称:postgres,代码行数:61,代码来源:pg_locale.c
示例14: SearchCatCacheList
//.........这里部分代码省略.........
}
/*
* List was not found in cache, so we have to build it by reading the
* relation. For each matching tuple found in the relation, use an
* existing cache entry if possible, else build a new one.
*
* We have to bump the member refcounts temporarily to ensure they won't
* get dropped from the cache while loading other members. We use a PG_TRY
* block to ensure we can undo those refcounts if we get an error before
* we finish constructing the CatCList.
*/
ResourceOwnerEnlargeCatCacheListRefs(CurrentResourceOwner);
ctlist = NIL;
PG_TRY();
{
Relation relation;
SysScanDesc scandesc;
relation = heap_open(cache->cc_reloid, AccessShareLock);
scandesc = systable_beginscan(relation,
cache->cc_indexoid,
IndexScanOK(cache, cur_skey),
SnapshotNow,
nkeys,
cur_skey);
/* The list will be ordered iff we are doing an index scan */
ordered = (scandesc->irel != NULL);
while (HeapTupleIsValid(ntp = systable_getnext(scandesc)))
{
uint32 hashValue;
Index hashIndex;
/*
* See if there's an entry for this tuple already.
*/
ct = NULL;
hashValue = CatalogCacheComputeTupleHashValue(cache, ntp);
hashIndex = HASH_INDEX(hashValue, cache->cc_nbuckets);
for (elt = DLGetHead(&cache->cc_bucket[hashIndex]);
elt;
elt = DLGetSucc(elt))
{
ct = (CatCTup *) DLE_VAL(elt);
if (ct->dead || ct->negative)
continue; /* ignore dead and negative entries */
if (ct->hash_value != hashValue)
continue; /* quickly skip entry if wrong hash val */
if (!ItemPointerEquals(&(ct->tuple.t_self), &(ntp->t_self)))
continue; /* not same tuple */
/*
* Found a match, but can't use it if it belongs to another
* list already
*/
if (ct->c_list)
continue;
开发者ID:BALDELab,项目名称:incubator-hawq,代码行数:67,代码来源:catcache.c
示例15: OperatorUpd
/*
* OperatorUpd
*
* For a given operator, look up its negator and commutator operators.
* If they are defined, but their negator and commutator fields
* (respectively) are empty, then use the new operator for neg or comm.
* This solves a problem for users who need to insert two new operators
* which are the negator or commutator of each other.
*/
static void
OperatorUpd(Oid baseId, Oid commId, Oid negId)
{
int i;
Relation pg_operator_desc;
HeapTuple tup;
bool nulls[Natts_pg_operator];
bool replaces[Natts_pg_operator];
Datum values[Natts_pg_operator];
for (i = 0; i < Natts_pg_operator; ++i)
{
values[i] = (Datum) 0;
replaces[i] = false;
nulls[i] = false;
}
/*
* check and update the commutator & negator, if necessary
*
* We need a CommandCounterIncrement here in case of a self-commutator
* operator: we'll need to update the tuple that we just inserted.
*/
CommandCounterIncrement();
pg_operator_desc = heap_open(OperatorRelationId, RowExclusiveLock);
tup = SearchSysCacheCopy1(OPEROID, ObjectIdGetDatum(commId));
/*
* if the commutator and negator are the same operator, do one update. XXX
* this is probably useless code --- I doubt it ever makes sense for
* commutator and negator to be the same thing...
*/
if (commId == negId)
{
if (HeapTupleIsValid(tup))
{
Form_pg_operator t = (Form_pg_operator) GETSTRUCT(tup);
if (!OidIsValid(t->oprcom) || !OidIsValid(t->oprnegate))
{
if (!OidIsValid(t->oprnegate))
{
values[Anum_pg_operator_oprnegate - 1] = ObjectIdGetDatum(baseId);
replaces[Anum_pg_operator_oprnegate - 1] = true;
}
if (!OidIsValid(t->oprcom))
{
values[Anum_pg_operator_oprcom - 1] = ObjectIdGetDatum(baseId);
replaces[Anum_pg_operator_oprcom - 1] = true;
}
tup = heap_modify_tuple(tup,
RelationGetDescr(pg_operator_desc),
values,
nulls,
replaces);
simple_heap_update(pg_operator_desc, &tup->t_self, tup);
CatalogUpdateIndexes(pg_operator_desc, tup);
}
}
heap_close(pg_operator_desc, RowExclusiveLock);
return;
}
/* if commutator and negator are different, do two updates */
if (HeapTupleIsValid(tup) &&
!(OidIsValid(((Form_pg_operator) GETSTRUCT(tup))->oprcom)))
{
values[Anum_pg_operator_oprcom - 1] = ObjectIdGetDatum(baseId);
replaces[Anum_pg_operator_oprcom - 1] = true;
tup = heap_modify_tuple(tup,
RelationGetDescr(pg_operator_desc),
values,
nulls,
replaces);
simple_heap_update(pg_operator_desc, &tup->t_self, tup);
CatalogUpdateIndexes(pg_operator_desc, tup);
values[Anum_pg_operator_oprcom - 1] = (Datum) NULL;
replaces[Anum_pg_operator_oprcom - 1] = false;
//.........这里部分代码省略.........
开发者ID:aKhadiemik,项目名称:postgres,代码行数:101,代码来源:pg_operator.c
示例16: gp_read_error_log
//.........这里部分代码省略.........
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, ACL_KIND_CLASS, relrv->relname);
ErrorLogFileName(context->filename, MyDatabaseId, relid);
fp = AllocateFile(context->filename, "r");
context->fp = fp;
}
}
MemoryContextSwitchTo(oldcontext);
if (Gp_role != GP_ROLE_DISPATCH && !context->fp)
{
pfree(context);
SRF_RETURN_DONE(funcctx);
}
}
funcctx = SRF_PERCALL_SETUP();
context = (ReadErrorLogContext *) funcctx->user_fctx;
/*
* Read error log, probably on segments. We don't check Gp_role, however,
* in case master also wants to read the file.
*/
if (context->fp)
{
pg_crc32 crc, written_crc;
tuple = ErrorLogRead(context->fp, &written_crc);
/*
* CRC check.
*/
if (HeapTupleIsValid(tuple))
{
INIT_CRC32C(crc);
COMP_CRC32C(crc, tuple->t_data, tuple->t_len);
FIN_CRC32C(crc);
if (!EQ_CRC32C(crc, written_crc))
{
elog(LOG, "incorrect checksum in error log %s",
context->filename);
tuple = NULL;
}
}
/*
* If we found a valid tuple, return it. Otherwise, fall through
* in the DONE routine.
*/
if (HeapTupleIsValid(tuple))
{
/*
* We need to set typmod for the executor to understand
* its type we just blessed.
*/
HeapTupleHeaderSetTypMod(tuple->t_data,
funcctx->tuple_desc->tdtypmod);
result = HeapTupleGetDatum(tuple);
SRF_RETURN_NEXT(funcctx, result);
}
}
/*
开发者ID:qiuyesuifeng,项目名称:gpdb,代码行数:67,代码来源:cdbsreh.c
示例17: changeDependencyFor
/*
* Adjust dependency record(s) to point to a different object of the same type
*
* classId/objectId specify the referencing object.
* refClassId/oldRefObjectId specify the old referenced object.
* newRefObjectId is the new referenced object (must be of class refClassId).
*
* Note the lack of objsubid parameters. If there are subobject references
* they will all be readjusted.
*
* Returns the number of records updated.
*/
long
changeDependencyFor(Oid classId, Oid objectId,
Oid refClassId, Oid oldRefObjectId,
Oid newRefObjectId)
{
long count = 0;
Relation depRel;
ScanKeyData key[2];
SysScanDesc scan;
HeapTuple tup;
ObjectAddress objAddr;
bool newIsPinned;
depRel = heap_open(DependRelationId, RowExclusiveLock);
/*
* If oldRefObjectId is pinned, there won't be any dependen
|
请发表评论