void initSpGistState(SpGistState *state, Relation index) { RegProcedure propOid; Assert(index->rd_att->natts == 1); propOid = index_getprocid(index, 1, SPGIST_PROP_PROC); state->prop = *(SpGistOpClassProp*)DatumGetPointer(OidFunctionCall0Coll(propOid, InvalidOid)); fillTypeDesc(&state->attType, state->prop.leafType); fillTypeDesc(&state->attNodeType, state->prop.nodeType); fillTypeDesc(&state->attPrefixType, state->prop.prefixType); fmgr_info_copy(&(state->chooseFn), index_getprocinfo(index, 1, SPGIST_CHOOSE_PROC), CurrentMemoryContext); fmgr_info_copy(&(state->picksplitFn), index_getprocinfo(index, 1, SPGIST_PICKSPLIT_PROC), CurrentMemoryContext); fmgr_info_copy(&(state->leafConsistentFn), index_getprocinfo(index, 1, SPGIST_LEAFCONS_PROC), CurrentMemoryContext); fmgr_info_copy(&(state->innerConsistentFn), index_getprocinfo(index, 1, SPGIST_INNERCONS_PROC), CurrentMemoryContext); state->nodeTupDesc = CreateTemplateTupleDesc(1, false); TupleDescInitEntry(state->nodeTupDesc, (AttrNumber) 1, NULL, state->attNodeType.type, -1, 0); }
/* * Fetch local cache of AM-specific info about the index, initializing it * if necessary */ SpGistCache * spgGetCache(Relation index) { SpGistCache *cache; if (index->rd_amcache == NULL) { Oid atttype; spgConfigIn in; FmgrInfo *procinfo; Buffer metabuffer; SpGistMetaPageData *metadata; cache = MemoryContextAllocZero(index->rd_indexcxt, sizeof(SpGistCache)); /* SPGiST doesn't support multi-column indexes */ Assert(index->rd_att->natts == 1); /* * Get the actual data type of the indexed column from the index * tupdesc. We pass this to the opclass config function so that * polymorphic opclasses are possible. */ atttype = index->rd_att->attrs[0]->atttypid; /* Call the config function to get config info for the opclass */ in.attType = atttype; procinfo = index_getprocinfo(index, 1, SPGIST_CONFIG_PROC); FunctionCall2Coll(procinfo, index->rd_indcollation[0], PointerGetDatum(&in), PointerGetDatum(&cache->config)); /* Get the information we need about each relevant datatype */ fillTypeDesc(&cache->attType, atttype); fillTypeDesc(&cache->attPrefixType, cache->config.prefixType); fillTypeDesc(&cache->attLabelType, cache->config.labelType); /* Last, get the lastUsedPages data from the metapage */ metabuffer = ReadBuffer(index, SPGIST_METAPAGE_BLKNO); LockBuffer(metabuffer, BUFFER_LOCK_SHARE); metadata = SpGistPageGetMeta(BufferGetPage(metabuffer)); if (metadata->magicNumber != SPGIST_MAGIC_NUMBER) elog(ERROR, "index \"%s\" is not an SP-GiST index", RelationGetRelationName(index)); cache->lastUsedPages = metadata->lastUsedPages; UnlockReleaseBuffer(metabuffer); index->rd_amcache = (void *) cache; } else { /* assume it's up to date */ cache = (SpGistCache *) index->rd_amcache; } return cache; }