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

📄 heaptuple.c

📁 PostgreSQL 8.1.4的源码 适用于Linux下的开源数据库系统
💻 C
📖 第 1 页 / 共 3 页
字号:
		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		{			off = att_align(off, thisatt->attalign);			if (!slow)				thisatt->attcacheoff = off;		}		values[attnum] = fetchatt(thisatt, tp + off);		off = att_addlength(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 = tup->t_natts;	/*	 * 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		{			off = att_align(off, thisatt->attalign);			if (!slow)				thisatt->attcacheoff = off;		}		values[attnum] = fetchatt(thisatt, tp + off);		off = att_addlength(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		{			off = att_align(off, thisatt->attalign);			if (!slow)				thisatt->attcacheoff = off;		}		values[attnum] = fetchatt(thisatt, tp + off);		off = att_addlength(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");		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 > tup->t_natts)	{		*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 = tuple->t_data->t_natts;	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 = tuple->t_data->t_natts;	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");		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){	if (htup->t_data != NULL)		if (htup->t_datamcxt != NULL && (char *) (htup->t_data) !=			((char *) htup + HEAPTUPLESIZE))			pfree(htup->t_data);	pfree(htup);}/* ---------------- *		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.  It is used in some places for * pg_class, but that is a gross hack (it only works because relacl can * be omitted from the tuple entirely in those places). * ---------------- */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_datamcxt = CurrentMemoryContext;	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 */	td->t_natts = 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 + -