⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 heaptuple.c

📁 postgresql8.3.4源码,开源数据库
💻 C
📖 第 1 页 / 共 4 页
字号:
				 att[i]->attndims == 0 &&				 !VARATT_IS_EXTENDED(values[i]))		{			values[i] = toast_flatten_tuple_attribute(values[i],													  att[i]->atttypid,													  att[i]->atttypmod);		}	}	/*	 * Determine total space needed	 */	len = offsetof(HeapTupleHeaderData, t_bits);	if (hasnull)		len += BITMAPLEN(numberOfAttributes);	if (tupleDescriptor->tdhasoid)		len += sizeof(Oid);	hoff = len = MAXALIGN(len); /* align user data safely */	data_len = ComputeDataSize(tupleDescriptor, values, nulls);	len += data_len;	/*	 * Allocate and zero the space needed.	Note that the tuple body and	 * HeapTupleData management structure are allocated in one chunk.	 */	tuple = (HeapTuple) palloc0(HEAPTUPLESIZE + len);	tuple->t_data = td = (HeapTupleHeader) ((char *) tuple + HEAPTUPLESIZE);	/*	 * And fill in the information.  Note we fill the Datum fields even though	 * this tuple may never become a Datum.	 */	tuple->t_len = len;	ItemPointerSetInvalid(&(tuple->t_self));	tuple->t_tableOid = InvalidOid;	HeapTupleHeaderSetDatumLength(td, len);	HeapTupleHeaderSetTypeId(td, tupleDescriptor->tdtypeid);	HeapTupleHeaderSetTypMod(td, tupleDescriptor->tdtypmod);	HeapTupleHeaderSetNatts(td, numberOfAttributes);	td->t_hoff = hoff;	if (tupleDescriptor->tdhasoid)		/* else leave infomask = 0 */		td->t_infomask = HEAP_HASOID;	DataFill(tupleDescriptor,			 values,			 nulls,			 (char *) td + hoff,			 data_len,			 &td->t_infomask,			 (hasnull ? td->t_bits : NULL));	return tuple;}/* * heap_modify_tuple *		form a new tuple from an old tuple and a set of replacement values. * * The replValues, replIsnull, and doReplace arrays must be of the length * indicated by tupleDesc->natts.  The new tuple is constructed using the data * from replValues/replIsnull at columns where doReplace is true, and using * the data from the old tuple at columns where doReplace is false. * * The result is allocated in the current memory context. */HeapTupleheap_modify_tuple(HeapTuple tuple,				  TupleDesc tupleDesc,				  Datum *replValues,				  bool *replIsnull,				  bool *doReplace){	int			numberOfAttributes = tupleDesc->natts;	int			attoff;	Datum	   *values;	bool	   *isnull;	HeapTuple	newTuple;	/*	 * allocate and fill values and isnull arrays from either the tuple or the	 * repl information, as appropriate.	 *	 * NOTE: it's debatable whether to use heap_deform_tuple() here or just	 * heap_getattr() only the non-replaced colums.  The latter could win if	 * there are many replaced columns and few non-replaced ones. However,	 * heap_deform_tuple costs only O(N) while the heap_getattr way would cost	 * O(N^2) if there are many non-replaced columns, so it seems better to	 * err on the side of linear cost.	 */	values = (Datum *) palloc(numberOfAttributes * sizeof(Datum));	isnull = (bool *) palloc(numberOfAttributes * sizeof(bool));	heap_deform_tuple(tuple, tupleDesc, values, isnull);	for (attoff = 0; attoff < numberOfAttributes; attoff++)	{		if (doReplace[attoff])		{			values[attoff] = replValues[attoff];			isnull[attoff] = replIsnull[attoff];		}	}	/*	 * create a new tuple from the values and isnull arrays	 */	newTuple = heap_form_tuple(tupleDesc, values, isnull);	pfree(values);	pfree(isnull);	/*	 * copy the identification info of the old tuple: t_ctid, t_self, and OID	 * (if any)	 */	newTuple->t_data->t_ctid = tuple->t_data->t_ctid;	newTuple->t_self = tuple->t_self;	newTuple->t_tableOid = tuple->t_tableOid;	if (tupleDesc->tdhasoid)		HeapTupleSetOid(newTuple, HeapTupleGetOid(tuple));	return newTuple;}/* ---------------- *		heap_modifytuple * *		forms a new tuple from an old tuple and a set of replacement values. *		returns a new palloc'ed tuple. * * OLD API with char 'n'/' ' convention for indicating nulls, and * char 'r'/' ' convention for indicating whether to replace columns. * ---------------- */HeapTupleheap_modifytuple(HeapTuple tuple,				 TupleDesc tupleDesc,				 Datum *replValues,				 char *replNulls,				 char *replActions){	int			numberOfAttributes = tupleDesc->natts;	int			attoff;	Datum	   *values;	char	   *nulls;	HeapTuple	newTuple;	/*	 * allocate and fill values and nulls arrays from either the tuple or the	 * repl information, as appropriate.	 *	 * NOTE: it's debatable whether to use heap_deformtuple() here or just	 * heap_getattr() only the non-replaced colums.  The latter could win if	 * there are many replaced columns and few non-replaced ones. However,	 * heap_deformtuple costs only O(N) while the heap_getattr way would cost	 * O(N^2) if there are many non-replaced columns, so it seems better to	 * err on the side of linear cost.	 */	values = (Datum *) palloc(numberOfAttributes * sizeof(Datum));	nulls = (char *) palloc(numberOfAttributes * sizeof(char));	heap_deformtuple(tuple, tupleDesc, values, nulls);	for (attoff = 0; attoff < numberOfAttributes; attoff++)	{		if (replActions[attoff] == 'r')		{			values[attoff] = replValues[attoff];			nulls[attoff] = replNulls[attoff];		}		else if (replActions[attoff] != ' ')			elog(ERROR, "unrecognized replace flag: %d",				 (int) replActions[attoff]);	}	/*	 * create a new tuple from the values and nulls arrays	 */	newTuple = heap_formtuple(tupleDesc, values, nulls);	pfree(values);	pfree(nulls);	/*	 * copy the identification info of the old tuple: t_ctid, t_self, and OID	 * (if any)	 */	newTuple->t_data->t_ctid = tuple->t_data->t_ctid;	newTuple->t_self = tuple->t_self;	newTuple->t_tableOid = tuple->t_tableOid;	if (tupleDesc->tdhasoid)		HeapTupleSetOid(newTuple, HeapTupleGetOid(tuple));	return newTuple;}/* * heap_deform_tuple *		Given a tuple, extract data into values/isnull arrays; this is *		the inverse of heap_form_tuple. * *		Storage for the values/isnull arrays is provided by the caller; *		it should be sized according to tupleDesc->natts not tuple->t_natts. * *		Note that for pass-by-reference datatypes, the pointer placed *		in the Datum will point into the given tuple. * *		When all or most of a tuple's fields need to be extracted, *		this routine will be significantly quicker than a loop around *		heap_getattr; the loop will become O(N^2) as soon as any *		noncacheable attribute offsets are involved. */voidheap_deform_tuple(HeapTuple tuple, TupleDesc tupleDesc,				  Datum *values, bool *isnull){	HeapTupleHeader tup = tuple->t_data;	bool		hasnulls = HeapTupleHasNulls(tuple);	Form_pg_attribute *att = tupleDesc->attrs;	int			tdesc_natts = tupleDesc->natts;	int			natts;			/* number of atts to extract */	int			attnum;	char	   *tp;				/* ptr to tuple data */	long		off;			/* offset in tuple data */	bits8	   *bp = tup->t_bits;		/* ptr to null bitmap in tuple */	bool		slow = false;	/* can we use/set attcacheoff? */	natts = HeapTupleHeaderGetNatts(tup);	/*	 * In inheritance situations, it is possible that the given tuple actually	 * has more fields than the caller is expecting.  Don't run off the end of	 * the caller's arrays.	 */	natts = Min(natts, tdesc_natts);	tp = (char *) tup + tup->t_hoff;	off = 0;	for (attnum = 0; attnum < natts; attnum++)	{		Form_pg_attribute thisatt = att[attnum];		if (hasnulls && att_isnull(attnum, bp))		{			values[attnum] = (Datum) 0;			isnull[attnum] = true;			slow = true;		/* can't use attcacheoff anymore */			continue;		}		isnull[attnum] = false;		if (!slow && thisatt->attcacheoff >= 0)			off = thisatt->attcacheoff;		else if (thisatt->attlen == -1)		{			/*			 * We can only cache the offset for a varlena attribute if the			 * offset is already suitably aligned, so that there would be no			 * pad bytes in any case: then the offset will be valid for either			 * an aligned or unaligned value.			 */			if (!slow &&				off == att_align_nominal(off, thisatt->attalign))				thisatt->attcacheoff = off;			else			{				off = att_align_pointer(off, thisatt->attalign, -1,										tp + off);				slow = true;			}		}		else		{			/* not varlena, so safe to use att_align_nominal */			off = att_align_nominal(off, thisatt->attalign);			if (!slow)				thisatt->attcacheoff = off;		}		values[attnum] = fetchatt(thisatt, tp + off);		off = att_addlength_pointer(off, thisatt->attlen, tp + off);		if (thisatt->attlen <= 0)			slow = true;		/* can't use attcacheoff anymore */	}	/*	 * If tuple doesn't have all the atts indicated by tupleDesc, read the	 * rest as null	 */	for (; attnum < tdesc_natts; attnum++)	{		values[attnum] = (Datum) 0;		isnull[attnum] = true;	}}/* ---------------- *		heap_deformtuple * *		Given a tuple, extract data into values/nulls arrays; this is *		the inverse of heap_formtuple. * *		Storage for the values/nulls arrays is provided by the caller; *		it should be sized according to tupleDesc->natts not tuple->t_natts. * *		Note that for pass-by-reference datatypes, the pointer placed *		in the Datum will point into the given tuple. * *		When all or most of a tuple's fields need to be extracted, *		this routine will be significantly quicker than a loop around *		heap_getattr; the loop will become O(N^2) as soon as any *		noncacheable attribute offsets are involved. * * OLD API with char 'n'/' ' convention for indicating nulls * ---------------- */voidheap_deformtuple(HeapTuple tuple,				 TupleDesc tupleDesc,				 Datum *values,				 char *nulls){	HeapTupleHeader tup = tuple->t_data;	bool		hasnulls = HeapTupleHasNulls(tuple);	Form_pg_attribute *att = tupleDesc->attrs;	int			tdesc_natts = tupleDesc->natts;	int			natts;			/* number of atts to extract */	int			attnum;	char	   *tp;				/* ptr to tuple data */	long		off;			/* offset in tuple data */	bits8	   *bp = tup->t_bits;		/* ptr to null bitmap in tuple */	bool		slow = false;	/* can we use/set attcacheoff? */	natts = HeapTupleHeaderGetNatts(tup);	/*	 * In inheritance situations, it is possible that the given tuple actually	 * has more fields than the caller is expecting.  Don't run off the end of	 * the caller's arrays.	 */	natts = Min(natts, tdesc_natts);	tp = (char *) tup + tup->t_hoff;	off = 0;	for (attnum = 0; attnum < natts; attnum++)	{		Form_pg_attribute thisatt = att[attnum];		if (hasnulls && att_isnull(attnum, bp))		{			values[attnum] = (Datum) 0;			nulls[attnum] = 'n';			slow = true;		/* can't use attcacheoff anymore */			continue;		}		nulls[attnum] = ' ';		if (!slow && thisatt->attcacheoff >= 0)			off = thisatt->attcacheoff;		else if (thisatt->attlen == -1)		{			/*			 * We can only cache the offset for a varlena attribute if the			 * offset is already suitably aligned, so that there would be no			 * pad bytes in any case: then the offset will be valid for either			 * an aligned or unaligned value.			 */			if (!slow &&				off == att_align_nominal(off, thisatt->attalign))				thisatt->attcacheoff = off;			else			{				off = att_align_pointer(off, thisatt->attalign, -1,										tp + off);				slow = true;			}		}		else		{			/* not varlena, so safe to use att_align_nominal */			off = att_align_nominal(off, thisatt->attalign);			if (!slow)				thisatt->attcacheoff = off;		}		values[attnum] = fetchatt(thisatt, tp + off);		off = att_addlength_pointer(off, thisatt->attlen, tp + off);		if (thisatt->attlen <= 0)			slow = true;		/* can't use attcacheoff anymore */	}	/*	 * If tuple doesn't have all the atts indicated by tupleDesc, read the	 * rest as null	 */	for (; attnum < tdesc_natts; attnum++)	{		values[attnum] = (Datum) 0;		nulls[attnum] = 'n';	}}/* * slot_deform_tuple *		Given a TupleTableSlot, extract data from the slot's physical tuple *		into its Datum/isnull arrays.  Data is extracted up through the *		natts'th column (caller must ensure this is a legal column number). * *		This is essentially an incremental version of heap_deform_tuple: *		on each call we extract attributes up to the one needed, without *		re-computing information about previously extracted attributes. *		slot->tts_nvalid is the number of attributes already extracted. */static voidslot_deform_tuple(TupleTableSlot *slot, int natts){	HeapTuple	tuple = slot->tts_tuple;	TupleDesc	tupleDesc = slot->tts_tupleDescriptor;	Datum	   *values = slot->tts_values;	bool	   *isnull = slot->tts_isnull;	HeapTupleHeader tup = tuple->t_data;	bool		hasnulls = HeapTupleHasNulls(tuple);	Form_pg_attribute *att = tupleDesc->attrs;	int			attnum;	char	   *tp;				/* ptr to tuple data */	long		off;			/* offset in tuple data */	bits8	   *bp = tup->t_bits;		/* ptr to null bitmap in tuple */	bool		slow;			/* can we use/set attcacheoff? */	/*	 * Check whether the first call for this tuple, and initialize or restore	 * loop state.	 */	attnum = slot->tts_nvalid;	if (attnum == 0)	{		/* Start from the first attribute */		off = 0;		slow = false;	}	else	{		/* Restore state from previous execution */		off = slot->tts_off;		slow = slot->tts_slow;	}	tp = (char *) tup + tup->t_hoff;	for (; attnum < natts; attnum++)	{		Form_pg_attribute thisatt = att[attnum];		if (hasnulls && att_isnull(attnum, bp))		{			values[attnum] = (Datum) 0;			isnull[attnum] = true;			slow = true;		/* can't use attcacheoff anymore */			continue;		}		isnull[attnum] = false;		if (!slow && thisatt->attcacheoff >= 0)			off = thisatt->attcacheoff;		else if (thisatt->attlen == -1)		{			/*			 * We can only cache the offset for a varlena attribute if the			 * offset is already suitably aligned, so that there would be no			 * pad bytes in any case: then the offset will be valid for either			 * an aligned or unaligned value.			 */			if (!slow &&				off == att_align_nominal(off, thisatt->attalign))				thisatt->attcacheoff = off;			else			{				off = att_align_pointer(off, thisatt->attalign, -1,										tp + off);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -