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

📄 heaptuple.c

📁 postgresql8.3.4源码,开源数据库
💻 C
📖 第 1 页 / 共 4 页
字号:
				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 */	}	/*	 * Save state for next execution	 */	slot->tts_nvalid = attnum;	slot->tts_off = off;	slot->tts_slow = slow;}/* * slot_getattr *		This function fetches an attribute of the slot's current tuple. *		It is functionally equivalent to heap_getattr, but fetches of *		multiple attributes of the same tuple will be optimized better, *		because we avoid O(N^2) behavior from multiple calls of *		nocachegetattr(), even when attcacheoff isn't usable. * *		A difference from raw heap_getattr is that attnums beyond the *		slot's tupdesc's last attribute will be considered NULL even *		when the physical tuple is longer than the tupdesc. */Datumslot_getattr(TupleTableSlot *slot, int attnum, bool *isnull){	HeapTuple	tuple = slot->tts_tuple;	TupleDesc	tupleDesc = slot->tts_tupleDescriptor;	HeapTupleHeader tup;	/*	 * system attributes are handled by heap_getsysattr	 */	if (attnum <= 0)	{		if (tuple == NULL)		/* internal error */			elog(ERROR, "cannot extract system attribute from virtual tuple");		if (slot->tts_mintuple) /* internal error */			elog(ERROR, "cannot extract system attribute from minimal tuple");		return heap_getsysattr(tuple, attnum, tupleDesc, isnull);	}	/*	 * fast path if desired attribute already cached	 */	if (attnum <= slot->tts_nvalid)	{		*isnull = slot->tts_isnull[attnum - 1];		return slot->tts_values[attnum - 1];	}	/*	 * return NULL if attnum is out of range according to the tupdesc	 */	if (attnum > tupleDesc->natts)	{		*isnull = true;		return (Datum) 0;	}	/*	 * otherwise we had better have a physical tuple (tts_nvalid should equal	 * natts in all virtual-tuple cases)	 */	if (tuple == NULL)			/* internal error */		elog(ERROR, "cannot extract attribute from empty tuple slot");	/*	 * return NULL if attnum is out of range according to the tuple	 *	 * (We have to check this separately because of various inheritance and	 * table-alteration scenarios: the tuple could be either longer or shorter	 * than the tupdesc.)	 */	tup = tuple->t_data;	if (attnum > HeapTupleHeaderGetNatts(tup))	{		*isnull = true;		return (Datum) 0;	}	/*	 * check if target attribute is null: no point in groveling through tuple	 */	if (HeapTupleHasNulls(tuple) && att_isnull(attnum - 1, tup->t_bits))	{		*isnull = true;		return (Datum) 0;	}	/*	 * If the attribute's column has been dropped, we force a NULL result.	 * This case should not happen in normal use, but it could happen if we	 * are executing a plan cached before the column was dropped.	 */	if (tupleDesc->attrs[attnum - 1]->attisdropped)	{		*isnull = true;		return (Datum) 0;	}	/*	 * Extract the attribute, along with any preceding attributes.	 */	slot_deform_tuple(slot, attnum);	/*	 * The result is acquired from tts_values array.	 */	*isnull = slot->tts_isnull[attnum - 1];	return slot->tts_values[attnum - 1];}/* * slot_getallattrs *		This function forces all the entries of the slot's Datum/isnull *		arrays to be valid.  The caller may then extract data directly *		from those arrays instead of using slot_getattr. */voidslot_getallattrs(TupleTableSlot *slot){	int			tdesc_natts = slot->tts_tupleDescriptor->natts;	int			attnum;	HeapTuple	tuple;	/* Quick out if we have 'em all already */	if (slot->tts_nvalid == tdesc_natts)		return;	/*	 * otherwise we had better have a physical tuple (tts_nvalid should equal	 * natts in all virtual-tuple cases)	 */	tuple = slot->tts_tuple;	if (tuple == NULL)			/* internal error */		elog(ERROR, "cannot extract attribute from empty tuple slot");	/*	 * load up any slots available from physical tuple	 */	attnum = HeapTupleHeaderGetNatts(tuple->t_data);	attnum = Min(attnum, tdesc_natts);	slot_deform_tuple(slot, attnum);	/*	 * If tuple doesn't have all the atts indicated by tupleDesc, read the	 * rest as null	 */	for (; attnum < tdesc_natts; attnum++)	{		slot->tts_values[attnum] = (Datum) 0;		slot->tts_isnull[attnum] = true;	}	slot->tts_nvalid = tdesc_natts;}/* * slot_getsomeattrs *		This function forces the entries of the slot's Datum/isnull *		arrays to be valid at least up through the attnum'th entry. */voidslot_getsomeattrs(TupleTableSlot *slot, int attnum){	HeapTuple	tuple;	int			attno;	/* Quick out if we have 'em all already */	if (slot->tts_nvalid >= attnum)		return;	/* Check for caller error */	if (attnum <= 0 || attnum > slot->tts_tupleDescriptor->natts)		elog(ERROR, "invalid attribute number %d", attnum);	/*	 * otherwise we had better have a physical tuple (tts_nvalid should equal	 * natts in all virtual-tuple cases)	 */	tuple = slot->tts_tuple;	if (tuple == NULL)			/* internal error */		elog(ERROR, "cannot extract attribute from empty tuple slot");	/*	 * load up any slots available from physical tuple	 */	attno = HeapTupleHeaderGetNatts(tuple->t_data);	attno = Min(attno, attnum);	slot_deform_tuple(slot, attno);	/*	 * If tuple doesn't have all the atts indicated by tupleDesc, read the	 * rest as null	 */	for (; attno < attnum; attno++)	{		slot->tts_values[attno] = (Datum) 0;		slot->tts_isnull[attno] = true;	}	slot->tts_nvalid = attnum;}/* * slot_attisnull *		Detect whether an attribute of the slot is null, without *		actually fetching it. */boolslot_attisnull(TupleTableSlot *slot, int attnum){	HeapTuple	tuple = slot->tts_tuple;	TupleDesc	tupleDesc = slot->tts_tupleDescriptor;	/*	 * system attributes are handled by heap_attisnull	 */	if (attnum <= 0)	{		if (tuple == NULL)		/* internal error */			elog(ERROR, "cannot extract system attribute from virtual tuple");		if (slot->tts_mintuple) /* internal error */			elog(ERROR, "cannot extract system attribute from minimal tuple");		return heap_attisnull(tuple, attnum);	}	/*	 * fast path if desired attribute already cached	 */	if (attnum <= slot->tts_nvalid)		return slot->tts_isnull[attnum - 1];	/*	 * return NULL if attnum is out of range according to the tupdesc	 */	if (attnum > tupleDesc->natts)		return true;	/*	 * otherwise we had better have a physical tuple (tts_nvalid should equal	 * natts in all virtual-tuple cases)	 */	if (tuple == NULL)			/* internal error */		elog(ERROR, "cannot extract attribute from empty tuple slot");	/* and let the tuple tell it */	return heap_attisnull(tuple, attnum);}/* * heap_freetuple */voidheap_freetuple(HeapTuple htup){	pfree(htup);}/* * heap_form_minimal_tuple *		construct a MinimalTuple from the given values[] and isnull[] arrays, *		which are of the length indicated by tupleDescriptor->natts * * This is exactly like heap_form_tuple() except that the result is a * "minimal" tuple lacking a HeapTupleData header as well as room for system * columns. * * The result is allocated in the current memory context. */MinimalTupleheap_form_minimal_tuple(TupleDesc tupleDescriptor,						Datum *values,						bool *isnull){	MinimalTuple tuple;			/* return tuple */	Size		len,				data_len;	int			hoff;	bool		hasnull = false;	Form_pg_attribute *att = tupleDescriptor->attrs;	int			numberOfAttributes = tupleDescriptor->natts;	int			i;	if (numberOfAttributes > MaxTupleAttributeNumber)		ereport(ERROR,				(errcode(ERRCODE_TOO_MANY_COLUMNS),				 errmsg("number of columns (%d) exceeds limit (%d)",						numberOfAttributes, MaxTupleAttributeNumber)));	/*	 * Check for nulls and embedded tuples; expand any toasted attributes in	 * embedded tuples.  This preserves the invariant that toasting can only	 * go one level deep.	 *	 * We can skip calling toast_flatten_tuple_attribute() if the attribute	 * couldn't possibly be of composite type.  All composite datums are	 * varlena and have alignment 'd'; furthermore they aren't arrays. Also,	 * if an attribute is already toasted, it must have been sent to disk	 * already and so cannot contain toasted attributes.	 */	for (i = 0; i < numberOfAttributes; i++)	{		if (isnull[i])			hasnull = true;		else if (att[i]->attlen == -1 &&				 att[i]->attalign == 'd' &&				 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(MinimalTupleData, t_bits);	if (hasnull)		len += BITMAPLEN(numberOfAttributes);	if (tupleDescriptor->tdhasoid)		len += sizeof(Oid);	hoff = len = MAXALIGN(len); /* align user data safely */	data_len = heap_compute_data_size(tupleDescriptor, values, isnull);	len += data_len;	/*	 * Allocate and zero the space needed.	 */	tuple = (MinimalTuple) palloc0(len);	/*	 * And fill in the information.	 */	tuple->t_len = len;	HeapTupleHeaderSetNatts(tuple, numberOfAttributes);	tuple->t_hoff = hoff + MINIMAL_TUPLE_OFFSET;	if (tupleDescriptor->tdhasoid)		/* else leave infomask = 0 */		tuple->t_infomask = HEAP_HASOID;	heap_fill_tuple(tupleDescriptor,					values,					isnull,					(char *) tuple + hoff,					data_len,					&tuple->t_infomask,					(hasnull ? tuple->t_bits : NULL));	return tuple;}/* * heap_free_minimal_tuple */voidheap_free_minimal_tuple(MinimalTuple mtup){	pfree(mtup);}/* * heap_copy_minimal_tuple *		copy a MinimalTuple * * The result is allocated in the current memory context. */MinimalTupleheap_copy_minimal_tuple(MinimalTuple mtup){	MinimalTuple result;	result = (MinimalTuple) palloc(mtup->t_len);	memcpy(result, mtup, mtup->t_len);	return result;}/* * heap_tuple_from_minimal_tuple *		create a HeapTuple by copying from a MinimalTuple; *		system columns are filled with zeroes * * The result is allocated in the current memory context. * The HeapTuple struct, tuple header, and tuple data are all allocated * as a single palloc() block. */HeapTupleheap_tuple_from_minimal_tuple(MinimalTuple mtup){	HeapTuple	result;	uint32		len = mtup->t_len + MINIMAL_TUPLE_OFFSET;	result = (HeapTuple) palloc(HEAPTUPLESIZE + len);	result->t_len = len;	ItemPointerSetInvalid(&(result->t_self));	result->t_tableOid = InvalidOid;	result->t_data = (HeapTupleHeader) ((char *) result + HEAPTUPLESIZE);	memcpy((char *) result->t_data + MINIMAL_TUPLE_OFFSET, mtup, mtup->t_len);	memset(result->t_data, 0, offsetof(HeapTupleHeaderData, t_infomask2));	return result;}/* * minimal_tuple_from_heap_tuple *		create a MinimalTuple by copying from a HeapTuple * * The result is allocated in the current memory context. */MinimalTupleminimal_tuple_from_heap_tuple(HeapTuple htup){	MinimalTuple result;	uint32		len;	Assert(htup->t_len > MINIMAL_TUPLE_OFFSET);	len = htup->t_len - MINIMAL_TUPLE_OFFSET;	result = (MinimalTuple) palloc(len);	memcpy(result, (char *) htup->t_data + MINIMAL_TUPLE_OFFSET, len);	result->t_len = len;	return result;}/* ---------------- *		heap_addheader * * This routine forms a HeapTuple by copying the given structure (tuple * data) and adding a generic header.  Note that the tuple data is * presumed to contain no null fields and no varlena fields. * * This routine is really only useful for certain system tables that are * known to be fixed-width and null-free.  Currently it is only used for * pg_attribute tuples. * ---------------- */HeapTupleheap_addheader(int natts,		/* max domain index */			   bool withoid,	/* reserve space for oid */			   Size structlen,	/* its length */			   void *structure) /* pointer to the struct */{	HeapTuple	tuple;	HeapTupleHeader td;	Size		len;	int			hoff;	AssertArg(natts > 0);	/* header needs no null bitmap */	hoff = offsetof(HeapTupleHeaderData, t_bits);	if (withoid)		hoff += sizeof(Oid);	hoff = MAXALIGN(hoff);	len = hoff + structlen;	tuple = (HeapTuple) palloc0(HEAPTUPLESIZE + len);	tuple->t_data = td = (HeapTupleHeader) ((char *) tuple + HEAPTUPLESIZE);	tuple->t_len = len;	ItemPointerSetInvalid(&(tuple->t_self));	tuple->t_tableOid = InvalidOid;	/* we don't bother to fill the Datum fields */	HeapTupleHeaderSetNatts(td, natts);	td->t_hoff = hoff;	if (withoid)				/* else leave infomask = 0 */		td->t_infomask = HEAP_HASOID;	memcpy((char *) td + hoff, structure, structlen);	return tuple;}

⌨️ 快捷键说明

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