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

📄 heaptuple.c

📁 PostgreSQL7.4.6 for Linux
💻 C
📖 第 1 页 / 共 2 页
字号:
/*------------------------------------------------------------------------- * * heaptuple.c *	  This file contains heap tuple accessor and mutator routines, as well *	  as various tuple utilities. * * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * * IDENTIFICATION *	  $Header: /cvsroot/pgsql/src/backend/access/common/heaptuple.c,v 1.87 2003/09/25 06:57:56 petere Exp $ * * NOTES *	  The old interface functions have been converted to macros *	  and moved to heapam.h * *------------------------------------------------------------------------- */#include "postgres.h"#include "access/heapam.h"#include "catalog/pg_type.h"/* ---------------------------------------------------------------- *						misc support routines * ---------------------------------------------------------------- *//* ---------------- *		ComputeDataSize * ---------------- */SizeComputeDataSize(TupleDesc tupleDesc,				Datum *value,				char *nulls){	uint32		data_length = 0;	int			i;	int			numberOfAttributes = tupleDesc->natts;	Form_pg_attribute *att = tupleDesc->attrs;	for (i = 0; i < numberOfAttributes; i++)	{		if (nulls[i] != ' ')			continue;		data_length = att_align(data_length, att[i]->attalign);		data_length = att_addlength(data_length, att[i]->attlen, value[i]);	}	return data_length;}/* ---------------- *		DataFill * ---------------- */voidDataFill(char *data,		 TupleDesc tupleDesc,		 Datum *value,		 char *nulls,		 uint16 *infomask,		 bits8 *bit){	bits8	   *bitP = 0;	int			bitmask = 0;	Size		data_length;	int			i;	int			numberOfAttributes = tupleDesc->natts;	Form_pg_attribute *att = tupleDesc->attrs;	if (bit != NULL)	{		bitP = &bit[-1];		bitmask = CSIGNBIT;	}	*infomask &= ~(HEAP_HASNULL | HEAP_HASVARWIDTH | HEAP_HASEXTENDED);	for (i = 0; i < numberOfAttributes; i++)	{		if (bit != NULL)		{			if (bitmask != CSIGNBIT)				bitmask <<= 1;			else			{				bitP += 1;				*bitP = 0x0;				bitmask = 1;			}			if (nulls[i] == 'n')			{				*infomask |= HEAP_HASNULL;				continue;			}			*bitP |= bitmask;		}		/* XXX we are aligning the pointer itself, not the offset */		data = (char *) att_align((long) data, att[i]->attalign);		if (att[i]->attbyval)		{			/* pass-by-value */			store_att_byval(data, value[i], att[i]->attlen);			data_length = att[i]->attlen;		}		else if (att[i]->attlen == -1)		{			/* varlena */			*infomask |= HEAP_HASVARWIDTH;			if (VARATT_IS_EXTERNAL(value[i]))				*infomask |= HEAP_HASEXTERNAL;			if (VARATT_IS_COMPRESSED(value[i]))				*infomask |= HEAP_HASCOMPRESSED;			data_length = VARATT_SIZE(DatumGetPointer(value[i]));			memcpy(data, DatumGetPointer(value[i]), data_length);		}		else if (att[i]->attlen == -2)		{			/* cstring */			*infomask |= HEAP_HASVARWIDTH;			data_length = strlen(DatumGetCString(value[i])) + 1;			memcpy(data, DatumGetPointer(value[i]), data_length);		}		else		{			/* fixed-length pass-by-reference */			Assert(att[i]->attlen > 0);			data_length = att[i]->attlen;			memcpy(data, DatumGetPointer(value[i]), data_length);		}		data += data_length;	}}/* ---------------------------------------------------------------- *						heap tuple interface * ---------------------------------------------------------------- *//* ---------------- *		heap_attisnull	- returns 1 iff tuple attribute is not present * ---------------- */intheap_attisnull(HeapTuple tup, int attnum){	if (attnum > (int) tup->t_data->t_natts)		return 1;	if (HeapTupleNoNulls(tup))		return 0;	if (attnum > 0)		return att_isnull(attnum - 1, tup->t_data->t_bits);	else		switch (attnum)		{			case TableOidAttributeNumber:			case SelfItemPointerAttributeNumber:			case ObjectIdAttributeNumber:			case MinTransactionIdAttributeNumber:			case MinCommandIdAttributeNumber:			case MaxTransactionIdAttributeNumber:			case MaxCommandIdAttributeNumber:				/* these are never null */				break;			default:				elog(ERROR, "invalid attnum: %d", attnum);		}	return 0;}/* ---------------- *		nocachegetattr * *		This only gets called from fastgetattr() macro, in cases where *		we can't use a cacheoffset and the value is not null. * *		This caches attribute offsets in the attribute descriptor. * *		An alternate way to speed things up would be to cache offsets *		with the tuple, but that seems more difficult unless you take *		the storage hit of actually putting those offsets into the *		tuple you send to disk.  Yuck. * *		This scheme will be slightly slower than that, but should *		perform well for queries which hit large #'s of tuples.  After *		you cache the offsets once, examining all the other tuples using *		the same attribute descriptor will go much quicker. -cim 5/4/91 * ---------------- */Datumnocachegetattr(HeapTuple tuple,			   int attnum,			   TupleDesc tupleDesc,			   bool *isnull){	HeapTupleHeader tup = tuple->t_data;	Form_pg_attribute *att = tupleDesc->attrs;	char	   *tp;				/* ptr to att in tuple */	bits8	   *bp = tup->t_bits;		/* ptr to null bitmask in tuple */	bool		slow = false;	/* do we have to walk nulls? */	(void) isnull;				/* not used */#ifdef IN_MACRO/* This is handled in the macro */	Assert(attnum > 0);	if (isnull)		*isnull = false;#endif	attnum--;	/* ----------------	 *	 Three cases:	 *	 *	 1: No nulls and no variable-width attributes.	 *	 2: Has a null or a var-width AFTER att.	 *	 3: Has nulls or var-widths BEFORE att.	 * ----------------	 */	if (HeapTupleNoNulls(tuple))	{#ifdef IN_MACRO/* This is handled in the macro */		if (att[attnum]->attcacheoff != -1)		{			return fetchatt(att[attnum],							(char *) tup + tup->t_hoff +							att[attnum]->attcacheoff);		}#endif	}	else	{		/*		 * there's a null somewhere in the tuple		 *		 * check to see if desired att is null		 */#ifdef IN_MACRO/* This is handled in the macro */		if (att_isnull(attnum, bp))		{			if (isnull)				*isnull = true;			return (Datum) NULL;		}#endif		/*		 * Now check to see if any preceding bits are null...		 */		{			int			byte = attnum >> 3;			int			finalbit = attnum & 0x07;			/* check for nulls "before" final bit of last byte */			if ((~bp[byte]) & ((1 << finalbit) - 1))				slow = true;			else			{				/* check for nulls in any "earlier" bytes */				int			i;				for (i = 0; i < byte; i++)				{					if (bp[i] != 0xFF)					{						slow = true;						break;					}				}			}		}	}	tp = (char *) tup + tup->t_hoff;	/*	 * now check for any non-fixed length attrs before our attribute	 */	if (!slow)	{		if (att[attnum]->attcacheoff != -1)		{			return fetchatt(att[attnum],							tp + att[attnum]->attcacheoff);		}		else if (!HeapTupleAllFixed(tuple))		{			int			j;			/*			 * In for(), we test <= and not < because we want to see if we			 * can go past it in initializing offsets.			 */			for (j = 0; j <= attnum; j++)			{				if (att[j]->attlen <= 0)				{					slow = true;					break;				}			}		}	}	/*	 * If slow is false, and we got here, we know that we have a tuple	 * with no nulls or var-widths before the target attribute. If	 * possible, we also want to initialize the remainder of the attribute	 * cached offset values.	 */	if (!slow)	{		int			j = 1;		long		off;		/*		 * need to set cache for some atts		 */		att[0]->attcacheoff = 0;		while (j < attnum && att[j]->attcacheoff > 0)			j++;		off = att[j - 1]->attcacheoff + att[j - 1]->attlen;		for (; j <= attnum ||		/* Can we compute more?  We will probably need them */			 (j < tup->t_natts &&			  att[j]->attcacheoff == -1 &&			  (HeapTupleNoNulls(tuple) || !att_isnull(j, bp)) &&			  (HeapTupleAllFixed(tuple) || att[j]->attlen > 0)); j++)		{			off = att_align(off, att[j]->attalign);			att[j]->attcacheoff = off;			off = att_addlength(off, att[j]->attlen, tp + off);		}		return fetchatt(att[attnum], tp + att[attnum]->attcacheoff);	}	else	{		bool		usecache = true;		int			off = 0;		int			i;		/*		 * Now we know that we have to walk the tuple CAREFULLY.		 *		 * Note - This loop is a little tricky.  On iteration i we first set		 * the offset for attribute i and figure out how much the offset		 * should be incremented.  Finally, we need to align the offset		 * based on the size of attribute i+1 (for which the offset has		 * been computed). -mer 12 Dec 1991		 */		for (i = 0; i < attnum; i++)		{			if (!HeapTupleNoNulls(tuple))			{				if (att_isnull(i, bp))				{					usecache = false;					continue;				}			}			/* If we know the next offset, we can skip the rest */			if (usecache && att[i]->attcacheoff != -1)				off = att[i]->attcacheoff;			else

⌨️ 快捷键说明

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