📄 executils.c
字号:
* ---------------- */ if (VARSIZE(&indexStruct->indpred) != 0) { predString = fmgr(F_TEXTOUT, &indexStruct->indpred); predicate = (PredInfo *) stringToNode(predString); pfree(predString); } else predicate = NULL; /* ---------------- * save the index information into lists * ---------------- */ oidList = lconsi(indexOid, oidList); nkeyList = lconsi(numKeyAtts, nkeyList); keyList = lcons(indexKeyAtts, keyList); fiList = lcons(fInfoP, fiList); predList = lcons(predicate, predList); } /* ---------------- * we have the info we need so close the pg_index relation.. * ---------------- */ heap_endscan(indexSd); heap_close(indexRd); /* ---------------- * Now that we've collected the index information into three * lists, we open the index relations and store the descriptors * and the key information into arrays. * ---------------- */ len = length(oidList); if (len > 0) { /* ---------------- * allocate space for relation descs * ---------------- */ CXT1_printf("ExecOpenIndices: context is %d\n", CurrentMemoryContext); relationDescs = (RelationPtr) palloc(len * sizeof(Relation)); /* ---------------- * initialize index info array * ---------------- */ CXT1_printf("ExecOpenIndices: context is %d\n", CurrentMemoryContext); indexInfoArray = (IndexInfo **) palloc(len * sizeof(IndexInfo *)); for (i = 0; i < len; i++) { IndexInfo *ii = makeNode(IndexInfo); ii->ii_NumKeyAttributes = 0; ii->ii_KeyAttributeNumbers = (AttrNumber *) NULL; ii->ii_FuncIndexInfo = (FuncIndexInfoPtr) NULL; ii->ii_Predicate = NULL; indexInfoArray[i] = ii; } /* ---------------- * attempt to open each of the indices. If we succeed, * then store the index relation descriptor into the * relation descriptor array. * ---------------- */ i = 0; foreach(indexoid, oidList) { Relation indexDesc; indexOid = lfirsti(indexoid); indexDesc = index_open(indexOid); if (indexDesc != NULL) { relationDescs[i++] = indexDesc; /* * Hack for not btree and hash indices: they use relation * level exclusive locking on updation (i.e. - they are * not ready for MVCC) and so we have to exclusively lock * indices here to prevent deadlocks if we will scan them * - index_beginscan places AccessShareLock, indices * update methods don't use locks at all. We release this * lock in ExecCloseIndices. Note, that hashes use page * level locking - i.e. are not deadlock-free, - let's * them be on their way -:)) vadim 03-12-1998 */ if (indexDesc->rd_rel->relam != BTREE_AM_OID && indexDesc->rd_rel->relam != HASH_AM_OID) LockRelation(indexDesc, AccessExclusiveLock); } } /* ---------------- * store the relation descriptor array and number of * descs into the result relation info. * ---------------- */ resultRelationInfo->ri_NumIndices = i; resultRelationInfo->ri_IndexRelationDescs = relationDescs; /* ---------------- * store the index key information collected in our * lists into the index info array * ---------------- */ i = 0; foreach(numkeys, nkeyList) { numKeyAtts = lfirsti(numkeys); indexInfoArray[i++]->ii_NumKeyAttributes = numKeyAtts; } i = 0; foreach(indexkeys, keyList) { indexKeyAtts = (AttrNumber *) lfirst(indexkeys); indexInfoArray[i++]->ii_KeyAttributeNumbers = indexKeyAtts; } i = 0; foreach(indexfuncs, fiList) { FuncIndexInfoPtr fiP = (FuncIndexInfoPtr) lfirst(indexfuncs); indexInfoArray[i++]->ii_FuncIndexInfo = fiP; } i = 0; foreach(indexpreds, predList) indexInfoArray[i++]->ii_Predicate = lfirst(indexpreds); /* ---------------- * store the index info array into relation info * ---------------- */ resultRelationInfo->ri_IndexRelationInfo = indexInfoArray; } /* ---------------- * All done, resultRelationInfo now contains complete information * on the indices associated with the result relation. * ---------------- */ /* should free oidList, nkeyList and keyList here */ /* OK - let's do it -jolly */ freeList(oidList); freeList(nkeyList); freeList(keyList); freeList(fiList); freeList(predList);}/* ---------------------------------------------------------------- * ExecCloseIndices * * Close the index relations stored in resultRelationInfo * ---------------------------------------------------------------- */voidExecCloseIndices(RelationInfo *resultRelationInfo){ int i; int numIndices; RelationPtr relationDescs; numIndices = resultRelationInfo->ri_NumIndices; relationDescs = resultRelationInfo->ri_IndexRelationDescs; for (i = 0; i < numIndices; i++) { if (relationDescs[i] == NULL) continue; /* * Notes in ExecOpenIndices. */ if (relationDescs[i]->rd_rel->relam != BTREE_AM_OID && relationDescs[i]->rd_rel->relam != HASH_AM_OID) UnlockRelation(relationDescs[i], AccessExclusiveLock); index_close(relationDescs[i]); } /* * XXX should free indexInfo array here too. */}/* ---------------------------------------------------------------- * ExecFormIndexTuple * * Most of this code is cannabilized from DefaultBuild(). * As said in the comments for ExecOpenIndices, most of * this functionality should be rearranged into a proper * set of routines.. * ---------------------------------------------------------------- */#ifdef NOT_USEDIndexTupleExecFormIndexTuple(HeapTuple heapTuple, Relation heapRelation, Relation indexRelation, IndexInfo *indexInfo){ IndexTuple indexTuple; TupleDesc heapDescriptor; TupleDesc indexDescriptor; Datum *datum; char *nulls; int numberOfAttributes; AttrNumber *keyAttributeNumbers; FuncIndexInfoPtr fInfoP; /* ---------------- * get information from index info structure * ---------------- */ numberOfAttributes = indexInfo->ii_NumKeyAttributes; keyAttributeNumbers = indexInfo->ii_KeyAttributeNumbers; fInfoP = indexInfo->ii_FuncIndexInfo; /* ---------------- * datum and null are arrays in which we collect the index attributes * when forming a new index tuple. * ---------------- */ CXT1_printf("ExecFormIndexTuple: context is %d\n", CurrentMemoryContext); datum = (Datum *) palloc(numberOfAttributes * sizeof *datum); nulls = (char *) palloc(numberOfAttributes * sizeof *nulls); /* ---------------- * get the tuple descriptors from the relations so we know * how to form the index tuples.. * ---------------- */ heapDescriptor = RelationGetDescr(heapRelation); indexDescriptor = RelationGetDescr(indexRelation); /* ---------------- * FormIndexDatum fills in its datum and null parameters * with attribute information taken from the given heap tuple. * ---------------- */ FormIndexDatum(numberOfAttributes, /* num attributes */ keyAttributeNumbers, /* array of att nums to extract */ heapTuple, /* tuple from base relation */ heapDescriptor, /* heap tuple's descriptor */ datum, /* return: array of attributes */ nulls, /* return: array of char's */ fInfoP); /* functional index information */ indexTuple = index_formtuple(indexDescriptor, datum, nulls); /* ---------------- * free temporary arrays * * XXX should store these in the IndexInfo instead of allocating * and freeing on every insertion, but efficency here is not * that important and FormIndexTuple is wasteful anyways.. * -cim 9/27/89 * ---------------- */ pfree(nulls); pfree(datum); return indexTuple;}#endif/* ---------------------------------------------------------------- * ExecInsertIndexTuples * * This routine takes care of inserting index tuples * into all the relations indexing the result relation * when a heap tuple is inserted into the result relation. * Much of this code should be moved into the genam * stuff as it only exists here because the genam stuff * doesn't provide the functionality needed by the * executor.. -cim 9/27/89 * ---------------------------------------------------------------- */voidExecInsertIndexTuples(TupleTableSlot *slot, ItemPointer tupleid, EState *estate, bool is_update){ HeapTuple heapTuple; RelationInfo *resultRelationInfo; int i; int numIndices; RelationPtr relationDescs; Relation heapRelation; IndexInfo **indexInfoArray; IndexInfo *indexInfo; Node *predicate; bool satisfied; ExprContext *econtext; InsertIndexResult result; int numberOfAttributes; AttrNumber *keyAttributeNumbers; FuncIndexInfoPtr fInfoP; TupleDesc heapDescriptor; Datum *datum; char *nulls; heapTuple = slot->val; /* ---------------- * get information from the result relation info structure. * ---------------- */ resultRelationInfo = estate->es_result_relation_info; numIndices = resultRelationInfo->ri_NumIndices; relationDescs = resultRelationInfo->ri_IndexRelationDescs; indexInfoArray = resultRelationInfo->ri_IndexRelationInfo; heapRelation = resultRelationInfo->ri_RelationDesc; /* ---------------- * for each index, form and insert the index tuple * ---------------- */ econtext = NULL; for (i = 0; i < numIndices; i++) { if (relationDescs[i] == NULL) continue; indexInfo = indexInfoArray[i]; predicate = indexInfo->ii_Predicate; if (predicate != NULL) { if (econtext == NULL) econtext = makeNode(ExprContext); econtext->ecxt_scantuple = slot; /* Skip this index-update if the predicate isn't satisfied */ satisfied = ExecQual((List *) predicate, econtext); if (satisfied == false) continue; } /* ---------------- * get information from index info structure * ---------------- */ numberOfAttributes = indexInfo->ii_NumKeyAttributes; keyAttributeNumbers = indexInfo->ii_KeyAttributeNumbers; fInfoP = indexInfo->ii_FuncIndexInfo; datum = (Datum *) palloc(numberOfAttributes * sizeof *datum); nulls = (char *) palloc(numberOfAttributes * sizeof *nulls); heapDescriptor = (TupleDesc) RelationGetDescr(heapRelation); FormIndexDatum(numberOfAttributes, /* num attributes */ keyAttributeNumbers, /* array of att nums to * extract */ heapTuple, /* tuple from base relation */ heapDescriptor, /* heap tuple's descriptor */ datum, /* return: array of attributes */ nulls, /* return: array of char's */ fInfoP); /* functional index information */ result = index_insert(relationDescs[i], /* index relation */ datum, /* array of heaptuple Datums */ nulls, /* info on nulls */ &(heapTuple->t_self), /* tid of heap tuple */ heapRelation); /* ---------------- * keep track of index inserts for debugging * ---------------- */ IncrIndexInserted(); /* ---------------- * free index tuple after insertion * ---------------- */ if (result) pfree(result); } if (econtext != NULL) pfree(econtext);}voidSetChangedParamList(Plan *node, List *newchg){ List *nl; foreach(nl, newchg) { int paramId = lfirsti(nl); /* if this node doesn't depend on a param ... */ if (!intMember(paramId, node->extParam) && !intMember(paramId, node->locParam)) continue; /* if this param is already in list of changed ones ... */ if (intMember(paramId, node->chgParam)) continue; /* else - add this param to the list */ node->chgParam = lappendi(node->chgParam, paramId); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -