📄 exectuples.c
字号:
/* -------------------------------- * ExecSetSlotDescriptor * * This function is used to set the tuple descriptor associated * with the slot's tuple. * -------------------------------- */voidExecSetSlotDescriptor(TupleTableSlot *slot, /* slot to change */ TupleDesc tupdesc, /* new tuple descriptor */ bool shouldFree) /* is desc owned by slot? */{ if (slot->ttc_shouldFreeDesc && slot->ttc_tupleDescriptor != NULL) FreeTupleDesc(slot->ttc_tupleDescriptor); slot->ttc_tupleDescriptor = tupdesc; slot->ttc_shouldFreeDesc = shouldFree;}/* -------------------------------- * ExecSetSlotDescriptorIsNew * * This function is used to change the setting of the "isNew" flag * -------------------------------- */voidExecSetSlotDescriptorIsNew(TupleTableSlot *slot, /* slot to change */ bool isNew) /* "isNew" setting */{ slot->ttc_descIsNew = isNew;}/* ---------------------------------------------------------------- * tuple table slot status predicates * ---------------------------------------------------------------- *//* ---------------------------------------------------------------- * convenience initialization routines * ---------------------------------------------------------------- *//* -------------------------------- * ExecInit{Result,Scan,Extra}TupleSlot * * These are convenience routines to initialize the specified slot * in nodes inheriting the appropriate state. ExecInitExtraTupleSlot * is used for initializing special-purpose slots. * -------------------------------- */#define INIT_SLOT_DEFS \ TupleTable tupleTable; \ TupleTableSlot* slot#define INIT_SLOT_ALLOC \ tupleTable = (TupleTable) estate->es_tupleTable; \ slot = ExecAllocTableSlot(tupleTable);/* ---------------- * ExecInitResultTupleSlot * ---------------- */voidExecInitResultTupleSlot(EState *estate, PlanState *planstate){ INIT_SLOT_DEFS; INIT_SLOT_ALLOC; planstate->ps_ResultTupleSlot = slot;}/* ---------------- * ExecInitScanTupleSlot * ---------------- */voidExecInitScanTupleSlot(EState *estate, ScanState *scanstate){ INIT_SLOT_DEFS; INIT_SLOT_ALLOC; scanstate->ss_ScanTupleSlot = slot;}/* ---------------- * ExecInitExtraTupleSlot * ---------------- */TupleTableSlot *ExecInitExtraTupleSlot(EState *estate){ INIT_SLOT_DEFS; INIT_SLOT_ALLOC; return slot;}/* ---------------- * ExecInitNullTupleSlot * * Build a slot containing an all-nulls tuple of the given type. * This is used as a substitute for an input tuple when performing an * outer join. * ---------------- */TupleTableSlot *ExecInitNullTupleSlot(EState *estate, TupleDesc tupType){ TupleTableSlot *slot = ExecInitExtraTupleSlot(estate); /* * Since heap_getattr() will treat attributes beyond a tuple's t_natts * as being NULL, we can make an all-nulls tuple just by making it be * of zero length. However, the slot descriptor must match the real * tupType. */ HeapTuple nullTuple; Datum values[1]; char nulls[1]; static struct tupleDesc NullTupleDesc; /* we assume this inits to * zeroes */ ExecSetSlotDescriptor(slot, tupType, false); nullTuple = heap_formtuple(&NullTupleDesc, values, nulls); return ExecStoreTuple(nullTuple, slot, InvalidBuffer, true);}/* ---------------------------------------------------------------- * ExecTypeFromTL * * Generate a tuple descriptor for the result tuple of a targetlist. * (A parse/plan tlist must be passed, not an ExprState tlist.) * Note that resjunk columns, if any, are included in the result. * * Currently there are about 4 different places where we create * TupleDescriptors. They should all be merged, or perhaps * be rewritten to call BuildDesc(). * ---------------------------------------------------------------- */TupleDescExecTypeFromTL(List *targetList, bool hasoid){ TupleDesc typeInfo; List *tlitem; int len; /* * allocate a new typeInfo */ len = ExecTargetListLength(targetList); typeInfo = CreateTemplateTupleDesc(len, hasoid); /* * scan list, generate type info for each entry */ foreach(tlitem, targetList) { TargetEntry *tle = lfirst(tlitem); Resdom *resdom = tle->resdom; TupleDescInitEntry(typeInfo, resdom->resno, resdom->resname, resdom->restype, resdom->restypmod, 0, false); } return typeInfo;}/* ---------------------------------------------------------------- * ExecCleanTypeFromTL * * Same as above, but resjunk columns are omitted from the result. * ---------------------------------------------------------------- */TupleDescExecCleanTypeFromTL(List *targetList, bool hasoid){ TupleDesc typeInfo; List *tlitem; int len; int cleanresno; /* * allocate a new typeInfo */ len = ExecCleanTargetListLength(targetList); typeInfo = CreateTemplateTupleDesc(len, hasoid); /* * scan list, generate type info for each entry */ cleanresno = 1; foreach(tlitem, targetList) { TargetEntry *tle = lfirst(tlitem); Resdom *resdom = tle->resdom; if (resdom->resjunk) continue; TupleDescInitEntry(typeInfo, cleanresno++, resdom->resname, resdom->restype, resdom->restypmod, 0, false); } return typeInfo;}/* * TupleDescGetSlot - Initialize a slot based on the supplied tupledesc */TupleTableSlot *TupleDescGetSlot(TupleDesc tupdesc){ TupleTableSlot *slot; /* Make a standalone slot */ slot = MakeTupleTableSlot(); /* Bind the tuple description to the slot */ ExecSetSlotDescriptor(slot, tupdesc, true); /* Return the slot */ return slot;}/* * TupleDescGetAttInMetadata - Build an AttInMetadata structure based on the * supplied TupleDesc. AttInMetadata can be used in conjunction with C strings * to produce a properly formed tuple. */AttInMetadata *TupleDescGetAttInMetadata(TupleDesc tupdesc){ int natts = tupdesc->natts; int i; Oid atttypeid; Oid attinfuncid; FmgrInfo *attinfuncinfo; Oid *attelems; int32 *atttypmods; AttInMetadata *attinmeta; attinmeta = (AttInMetadata *) palloc(sizeof(AttInMetadata)); /* * Gather info needed later to call the "in" function for each * attribute */ attinfuncinfo = (FmgrInfo *) palloc0(natts * sizeof(FmgrInfo)); attelems = (Oid *) palloc0(natts * sizeof(Oid)); atttypmods = (int32 *) palloc0(natts * sizeof(int32)); for (i = 0; i < natts; i++) { /* Ignore dropped attributes */ if (!tupdesc->attrs[i]->attisdropped) { atttypeid = tupdesc->attrs[i]->atttypid; getTypeInputInfo(atttypeid, &attinfuncid, &attelems[i]); fmgr_info(attinfuncid, &attinfuncinfo[i]); atttypmods[i] = tupdesc->attrs[i]->atttypmod; } } attinmeta->tupdesc = tupdesc; attinmeta->attinfuncs = attinfuncinfo; attinmeta->attelems = attelems; attinmeta->atttypmods = atttypmods; return attinmeta;}/* * BuildTupleFromCStrings - build a HeapTuple given user data in C string form. * values is an array of C strings, one for each attribute of the return tuple. */HeapTupleBuildTupleFromCStrings(AttInMetadata *attinmeta, char **values){ TupleDesc tupdesc = attinmeta->tupdesc; int natts = tupdesc->natts; Datum *dvalues; char *nulls; int i; Oid attelem; int32 atttypmod; HeapTuple tuple; dvalues = (Datum *) palloc(natts * sizeof(Datum)); nulls = (char *) palloc(natts * sizeof(char)); /* Call the "in" function for each non-null, non-dropped attribute */ for (i = 0; i < natts; i++) { if (!tupdesc->attrs[i]->attisdropped) { /* Non-dropped attributes */ if (values[i] != NULL) { attelem = attinmeta->attelems[i]; atttypmod = attinmeta->atttypmods[i]; dvalues[i] = FunctionCall3(&attinmeta->attinfuncs[i], CStringGetDatum(values[i]), ObjectIdGetDatum(attelem), Int32GetDatum(atttypmod)); nulls[i] = ' '; } else { dvalues[i] = (Datum) 0; nulls[i] = 'n'; } } else { /* Handle dropped attributes by setting to NULL */ dvalues[i] = (Datum) 0; nulls[i] = 'n'; } } /* * Form a tuple */ tuple = heap_formtuple(tupdesc, dvalues, nulls); /* * Release locally palloc'd space. XXX would probably be good to * pfree values of pass-by-reference datums, as well. */ pfree(dvalues); pfree(nulls); return tuple;}/* * Functions for sending tuples to the frontend (or other specified destination) * as though it is a SELECT result. These are used by utility commands that * need to project directly to the destination and don't need or want full * Table Function capability. Currently used by EXPLAIN and SHOW ALL */TupOutputState *begin_tup_output_tupdesc(DestReceiver *dest, TupleDesc tupdesc){ TupOutputState *tstate; tstate = (TupOutputState *) palloc(sizeof(TupOutputState)); tstate->metadata = TupleDescGetAttInMetadata(tupdesc); tstate->dest = dest; (*tstate->dest->rStartup) (tstate->dest, (int) CMD_SELECT, tupdesc); return tstate;}/* * write a single tuple * * values is a list of the external C string representations of the values * to be projected. */voiddo_tup_output(TupOutputState *tstate, char **values){ /* build a tuple from the input strings using the tupdesc */ HeapTuple tuple = BuildTupleFromCStrings(tstate->metadata, values); /* send the tuple to the receiver */ (*tstate->dest->receiveTuple) (tuple, tstate->metadata->tupdesc, tstate->dest); /* clean up */ heap_freetuple(tuple);}/* * write a chunk of text, breaking at newline characters * * NB: scribbles on its input! * * Should only be used with a single-TEXT-attribute tupdesc. */voiddo_text_output_multiline(TupOutputState *tstate, char *text){ while (*text) { char *eol; eol = strchr(text, '\n'); if (eol) *eol++ = '\0'; else eol = text +strlen(text); do_tup_output(tstate, &text); text = eol; }}voidend_tup_output(TupOutputState *tstate){ (*tstate->dest->rShutdown) (tstate->dest); /* note that destroying the dest is not ours to do */ /* XXX worth cleaning up the attinmetadata? */ pfree(tstate);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -