📄 exectuples.c
字号:
slot->ttc_descIsNew = isNew;}/* -------------------------------- * ExecSetNewSlotDescriptor * * This function is used to set the tuple descriptor associated * with the slot's tuple, and set the "isNew" flag at the same time. * -------------------------------- */#ifdef NOT_USEDTupleDesc /* return: old slot tuple descriptor */ExecSetNewSlotDescriptor(TupleTableSlot *slot, /* slot to change */ TupleDesc tupdesc) /* tuple descriptor */{ TupleDesc old_tupdesc = slot->ttc_tupleDescriptor; slot->ttc_tupleDescriptor = tupdesc; slot->ttc_descIsNew = true; return old_tupdesc;}#endif/* -------------------------------- * ExecSlotBuffer * * This function is used to get the tuple descriptor associated * with the slot's tuple. Be very careful with this as it does not * balance the reference counts. If the buffer returned is stored * someplace else, then also use ExecIncrSlotBufferRefcnt(). * * Now a macro in tuptable.h * -------------------------------- *//* -------------------------------- * ExecSetSlotBuffer * * This function is used to set the tuple descriptor associated * with the slot's tuple. Be very careful with this as it does not * balance the reference counts. If we're using this then we should * also use ExecIncrSlotBufferRefcnt(). * -------------------------------- */#ifdef NOT_USEDBuffer /* return: old slot buffer */ExecSetSlotBuffer(TupleTableSlot *slot, /* slot to change */ Buffer b) /* tuple descriptor */{ Buffer oldb = slot->ttc_buffer; slot->ttc_buffer = b; return oldb;}#endif/* ---------------------------------------------------------------- * tuple table slot status predicates * ---------------------------------------------------------------- *//* -------------------------------- * ExecSlotDescriptorIsNew * * This function is used to check if the tuple descriptor * associated with this slot has just changed. ie: we are * now storing a new type of tuple in this slot * -------------------------------- */#ifdef NOT_USEDbool /* return: descriptor "is new" */ExecSlotDescriptorIsNew(TupleTableSlot *slot) /* slot to inspect */{/* bool isNew = SlotTupleDescriptorIsNew((TupleTableSlot*) slot); return isNew; */ return slot->ttc_descIsNew;}#endif/* ---------------------------------------------------------------- * convenience initialization routines * ---------------------------------------------------------------- *//* -------------------------------- * ExecInit{Result,Scan,Raw,Marked,Outer,Hash}TupleSlot * * These are convenience routines to initialize the specfied slot * in nodes inheriting the appropriate state. * -------------------------------- */#define INIT_SLOT_DEFS \ TupleTable tupleTable; \ TupleTableSlot* slot#define INIT_SLOT_ALLOC \ tupleTable = (TupleTable) estate->es_tupleTable; \ slot = ExecAllocTableSlot(tupleTable); \ slot->val = (HeapTuple)NULL; \ slot->ttc_shouldFree = true; \ slot->ttc_tupleDescriptor = (TupleDesc)NULL; \ slot->ttc_whichplan = -1;\ slot->ttc_descIsNew = true;/* ---------------- * ExecInitResultTupleSlot * ---------------- */voidExecInitResultTupleSlot(EState *estate, CommonState *commonstate){ INIT_SLOT_DEFS; INIT_SLOT_ALLOC; commonstate->cs_ResultTupleSlot = (TupleTableSlot *) slot;}/* ---------------- * ExecInitScanTupleSlot * ---------------- */voidExecInitScanTupleSlot(EState *estate, CommonScanState *commonscanstate){ INIT_SLOT_DEFS; INIT_SLOT_ALLOC; commonscanstate->css_ScanTupleSlot = (TupleTableSlot *) slot;}#ifdef NOT_USED/* ---------------- * ExecInitMarkedTupleSlot * ---------------- */voidExecInitMarkedTupleSlot(EState *estate, MergeJoinState *mergestate){ INIT_SLOT_DEFS; INIT_SLOT_ALLOC; mergestate->mj_MarkedTupleSlot = (TupleTableSlot *) slot;}#endif/* ---------------- * ExecInitOuterTupleSlot * ---------------- */voidExecInitOuterTupleSlot(EState *estate, HashJoinState *hashstate){ INIT_SLOT_DEFS; INIT_SLOT_ALLOC; hashstate->hj_OuterTupleSlot = slot;}/* ---------------- * ExecInitHashTupleSlot * ---------------- */#ifdef NOT_USEDvoidExecInitHashTupleSlot(EState *estate, HashJoinState *hashstate){ INIT_SLOT_DEFS; INIT_SLOT_ALLOC; hashstate->hj_HashTupleSlot = slot;}#endifstatic TupleTableSlot *NodeGetResultTupleSlot(Plan *node){ TupleTableSlot *slot; switch (nodeTag(node)) { case T_Result: { ResultState *resstate = ((Result *) node)->resstate; slot = resstate->cstate.cs_ResultTupleSlot; } break; case T_SeqScan: { CommonScanState *scanstate = ((SeqScan *) node)->scanstate; slot = scanstate->cstate.cs_ResultTupleSlot; } break; case T_NestLoop: { NestLoopState *nlstate = ((NestLoop *) node)->nlstate; slot = nlstate->jstate.cs_ResultTupleSlot; } break; case T_Append: { Append *n = (Append *) node; AppendState *appendstate; List *appendplans; int whichplan; Plan *subplan; appendstate = n->appendstate; appendplans = n->appendplans; whichplan = appendstate->as_whichplan; subplan = (Plan *) nth(whichplan, appendplans); slot = NodeGetResultTupleSlot(subplan); break; } case T_IndexScan: { CommonScanState *scanstate = ((IndexScan *) node)->scan.scanstate; slot = scanstate->cstate.cs_ResultTupleSlot; } break; case T_Material: { MaterialState *matstate = ((Material *) node)->matstate; slot = matstate->csstate.css_ScanTupleSlot; } break; case T_Sort: { SortState *sortstate = ((Sort *) node)->sortstate; slot = sortstate->csstate.css_ScanTupleSlot; } break; case T_Agg: { AggState *aggstate = ((Agg *) node)->aggstate; slot = aggstate->csstate.cstate.cs_ResultTupleSlot; } break; case T_Group: { GroupState *grpstate = ((Group *) node)->grpstate; slot = grpstate->csstate.cstate.cs_ResultTupleSlot; } break; case T_Hash: { HashState *hashstate = ((Hash *) node)->hashstate; slot = hashstate->cstate.cs_ResultTupleSlot; } break; case T_Unique: { UniqueState *uniquestate = ((Unique *) node)->uniquestate; slot = uniquestate->cs_ResultTupleSlot; } break; case T_MergeJoin: { MergeJoinState *mergestate = ((MergeJoin *) node)->mergestate; slot = mergestate->jstate.cs_ResultTupleSlot; } break; case T_HashJoin: { HashJoinState *hashjoinstate = ((HashJoin *) node)->hashjoinstate; slot = hashjoinstate->jstate.cs_ResultTupleSlot; } break; default: /* ---------------- * should never get here * ---------------- */ elog(ERROR, "NodeGetResultTupleSlot: node not yet supported: %d ", nodeTag(node)); return NULL; } return slot;}/* ---------------------------------------------------------------- * ExecGetTupType * * this gives you the tuple descriptor for tuples returned * by this node. I really wish I could ditch this routine, * but since not all nodes store their type info in the same * place, we have to do something special for each node type. * * Soon, the system will have to adapt to deal with changing * tuple descriptors as we deal with dynamic tuple types * being returned from procedure nodes. Perhaps then this * routine can be retired. -cim 6/3/91 * * old comments * This routine just gets the type information out of the * node's state. If you already have a node's state, you * can get this information directly, but this is a useful * routine if you want to get the type information from * the node's inner or outer subplan easily without having * to inspect the subplan.. -cim 10/16/89 * * ---------------------------------------------------------------- */TupleDescExecGetTupType(Plan *node){ TupleTableSlot *slot; TupleDesc tupType; if (node == NULL) return NULL; slot = NodeGetResultTupleSlot(node); tupType = slot->ttc_tupleDescriptor; return tupType;}/*TupleDescExecCopyTupType(TupleDesc td, int natts){ TupleDesc newTd; int i; newTd = CreateTemplateTupleDesc(natts); i = 0; while (i < natts) { newTd[i] = (Form_pg_attribute)palloc(sizeof(FormData_pg_attribute)); memmove(newTd[i], td[i], sizeof(FormData_pg_attribute)); i++; } return newTd;}*//* ---------------------------------------------------------------- * ExecTypeFromTL * * Currently there are about 4 different places where we create * TupleDescriptors. They should all be merged, or perhaps * be rewritten to call BuildDesc(). * * old comments * Forms attribute type info from the target list in the node. * It assumes all domains are individually specified in the target list. * It fails if the target list contains something like Emp.all * which represents all the attributes from EMP relation. * * Conditions: * The inner and outer subtrees should be initialized because it * might be necessary to know the type infos of the subtrees. * ---------------------------------------------------------------- */TupleDescExecTypeFromTL(List *targetList){ List *tlcdr; TupleDesc typeInfo; Resdom *resdom; Oid restype; int len; /* ---------------- * examine targetlist - if empty then return NULL * ---------------- */ len = ExecTargetListLength(targetList); if (len == 0) return NULL; /* ---------------- * allocate a new typeInfo * ---------------- */ typeInfo = CreateTemplateTupleDesc(len); /* ---------------- * notes: get resdom from (resdom expr) * get_typbyval comes from src/lib/l-lisp/lsyscache.c * ---------------- */ tlcdr = targetList; while (tlcdr != NIL) { TargetEntry *tle = lfirst(tlcdr); if (tle->resdom != NULL) { resdom = tle->resdom; restype = resdom->restype; TupleDescInitEntry(typeInfo, resdom->resno, resdom->resname, /* fix for SELECT NULL ... */ (restype ? restype : UNKNOWNOID), resdom->restypmod, 0, false);/* ExecSetTypeInfo(resdom->resno - 1, typeInfo, (Oid) restype, resdom->resno, resdom->reslen, resdom->resname->data, get_typbyval(restype), get_typalign(restype));*/ } else { Resdom *fjRes; List *fjTlistP; List *fjList = lfirst(tlcdr);#ifdef SETS_FIXED TargetEntry *tle; Fjoin *fjNode = ((TargetEntry *) lfirst(fjList))->fjoin; tle = fjNode->fj_innerNode; /* ??? */#endif fjRes = tle->resdom; restype = fjRes->restype; TupleDescInitEntry(typeInfo, fjRes->resno, fjRes->resname, restype, fjRes->restypmod, 0, false);/* ExecSetTypeInfo(fjRes->resno - 1, typeInfo, (Oid) restype, fjRes->resno, fjRes->reslen, (char *) fjRes->resname, get_typbyval(restype), get_typalign(restype));*/ foreach(fjTlistP, lnext(fjList)) { TargetEntry *fjTle = lfirst(fjTlistP); fjRes = fjTle->resdom; TupleDescInitEntry(typeInfo, fjRes->resno, fjRes->resname, restype, fjRes->restypmod, 0, false);/* ExecSetTypeInfo(fjRes->resno - 1, typeInfo, (Oid) fjRes->restype, fjRes->resno, fjRes->reslen, (char *) fjRes->resname, get_typbyval(fjRes->restype), get_typalign(fjRes->restype));*/ } } tlcdr = lnext(tlcdr); } return typeInfo;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -