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

📄 htup.h

📁 PostgreSQL 8.1.4的源码 适用于Linux下的开源数据库系统
💻 H
📖 第 1 页 / 共 2 页
字号:
/*------------------------------------------------------------------------- * * htup.h *	  POSTGRES heap tuple definitions. * * * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * $PostgreSQL: pgsql/src/include/access/htup.h,v 1.78 2005/10/15 02:49:42 momjian Exp $ * *------------------------------------------------------------------------- */#ifndef HTUP_H#define HTUP_H#include "storage/bufpage.h"#include "storage/relfilenode.h"#include "access/transam.h"/* * MaxTupleAttributeNumber limits the number of (user) columns in a tuple. * The key limit on this value is that the size of the fixed overhead for * a tuple, plus the size of the null-values bitmap (at 1 bit per column), * plus MAXALIGN alignment, must fit into t_hoff which is uint8.  On most * machines the upper limit without making t_hoff wider would be a little * over 1700.  We use round numbers here and for MaxHeapAttributeNumber * so that alterations in HeapTupleHeaderData layout won't change the * supported max number of columns. */#define MaxTupleAttributeNumber 1664	/* 8 * 208 *//*---------- * MaxHeapAttributeNumber limits the number of (user) columns in a table. * This should be somewhat less than MaxTupleAttributeNumber.  It must be * at least one less, else we will fail to do UPDATEs on a maximal-width * table (because UPDATE has to form working tuples that include CTID). * In practice we want some additional daylight so that we can gracefully * support operations that add hidden "resjunk" columns, for example * SELECT * FROM wide_table ORDER BY foo, bar, baz. * In any case, depending on column data types you will likely be running * into the disk-block-based limit on overall tuple size if you have more * than a thousand or so columns.  TOAST won't help. *---------- */#define MaxHeapAttributeNumber	1600	/* 8 * 200 *//*---------- * Heap tuple header.  To avoid wasting space, the fields should be * layed out in such a way to avoid structure padding. * * Datums of composite types (row types) share the same general structure * as on-disk tuples, so that the same routines can be used to build and * examine them.  However the requirements are slightly different: a Datum * does not need any transaction visibility information, and it does need * a length word and some embedded type information.  We can achieve this * by overlaying the xmin/cmin/xmax/cmax/xvac fields of a heap tuple * with the fields needed in the Datum case.  Typically, all tuples built * in-memory will be initialized with the Datum fields; but when a tuple is * about to be inserted in a table, the transaction fields will be filled, * overwriting the datum fields. * * The overall structure of a heap tuple looks like: *			fixed fields (HeapTupleHeaderData struct) *			nulls bitmap (if HEAP_HASNULL is set in t_infomask) *			alignment padding (as needed to make user data MAXALIGN'd) *			object ID (if HEAP_HASOID is set in t_infomask) *			user data fields * * We store five "virtual" fields Xmin, Cmin, Xmax, Cmax, and Xvac in four * physical fields.  Xmin, Cmin and Xmax are always really stored, but * Cmax and Xvac share a field.  This works because we know that there are * only a limited number of states that a tuple can be in, and that Cmax * is only interesting for the lifetime of the deleting transaction. * This assumes that VACUUM FULL never tries to move a tuple whose Cmax * is still interesting (ie, delete-in-progress). * * Note that in 7.3 and 7.4 a similar idea was applied to Xmax and Cmin. * However, with the advent of subtransactions, a tuple may need both Xmax * and Cmin simultaneously, so this is no longer possible. * * A word about t_ctid: whenever a new tuple is stored on disk, its t_ctid * is initialized with its own TID (location).	If the tuple is ever updated, * its t_ctid is changed to point to the replacement version of the tuple. * Thus, a tuple is the latest version of its row iff XMAX is invalid or * t_ctid points to itself (in which case, if XMAX is valid, the tuple is * either locked or deleted).  One can follow the chain of t_ctid links * to find the newest version of the row.  Beware however that VACUUM might * erase the pointed-to (newer) tuple before erasing the pointing (older) * tuple.  Hence, when following a t_ctid link, it is necessary to check * to see if the referenced slot is empty or contains an unrelated tuple. * Check that the referenced tuple has XMIN equal to the referencing tuple's * XMAX to verify that it is actually the descendant version and not an * unrelated tuple stored into a slot recently freed by VACUUM.  If either * check fails, one may assume that there is no live descendant version. * * Following the fixed header fields, the nulls bitmap is stored (beginning * at t_bits).	The bitmap is *not* stored if t_infomask shows that there * are no nulls in the tuple.  If an OID field is present (as indicated by * t_infomask), then it is stored just before the user data, which begins at * the offset shown by t_hoff.	Note that t_hoff must be a multiple of * MAXALIGN. *---------- */typedef struct HeapTupleFields{	TransactionId t_xmin;		/* inserting xact ID */	CommandId	t_cmin;			/* inserting command ID */	TransactionId t_xmax;		/* deleting or locking xact ID */	union	{		CommandId	t_cmax;		/* deleting or locking command ID */		TransactionId t_xvac;	/* VACUUM FULL xact ID */	}			t_field4;} HeapTupleFields;typedef struct DatumTupleFields{	int32		datum_len;		/* required to be a varlena type */	int32		datum_typmod;	/* -1, or identifier of a record type */	Oid			datum_typeid;	/* composite type OID, or RECORDOID */	/*	 * Note: field ordering is chosen with thought that Oid might someday	 * widen to 64 bits.	 */} DatumTupleFields;typedef struct HeapTupleHeaderData{	union	{		HeapTupleFields t_heap;		DatumTupleFields t_datum;	}			t_choice;	ItemPointerData t_ctid;		/* current TID of this or newer tuple */	int16		t_natts;		/* number of attributes */	uint16		t_infomask;		/* various flag bits, see below */	uint8		t_hoff;			/* sizeof header incl. bitmap, padding */	/* ^ - 27 bytes - ^ */	bits8		t_bits[1];		/* bitmap of NULLs -- VARIABLE LENGTH */	/* MORE DATA FOLLOWS AT END OF STRUCT */} HeapTupleHeaderData;typedef HeapTupleHeaderData *HeapTupleHeader;/* * information stored in t_infomask: */#define HEAP_HASNULL			0x0001	/* has null attribute(s) */#define HEAP_HASVARWIDTH		0x0002	/* has variable-width attribute(s) */#define HEAP_HASEXTERNAL		0x0004	/* has external stored attribute(s) */#define HEAP_HASCOMPRESSED		0x0008	/* has compressed stored attribute(s) */#define HEAP_HASEXTENDED		0x000C	/* the two above combined */#define HEAP_HASOID				0x0010	/* has an object-id field *//* 0x0020 is presently unused */#define HEAP_XMAX_EXCL_LOCK		0x0040	/* xmax is exclusive locker */#define HEAP_XMAX_SHARED_LOCK	0x0080	/* xmax is shared locker *//* if either LOCK bit is set, xmax hasn't deleted the tuple, only locked it */#define HEAP_IS_LOCKED	(HEAP_XMAX_EXCL_LOCK | HEAP_XMAX_SHARED_LOCK)#define HEAP_XMIN_COMMITTED		0x0100	/* t_xmin committed */#define HEAP_XMIN_INVALID		0x0200	/* t_xmin invalid/aborted */#define HEAP_XMAX_COMMITTED		0x0400	/* t_xmax committed */#define HEAP_XMAX_INVALID		0x0800	/* t_xmax invalid/aborted */#define HEAP_XMAX_IS_MULTI		0x1000	/* t_xmax is a MultiXactId */#define HEAP_UPDATED			0x2000	/* this is UPDATEd version of row */#define HEAP_MOVED_OFF			0x4000	/* moved to another place by VACUUM										 * FULL */#define HEAP_MOVED_IN			0x8000	/* moved from another place by VACUUM										 * FULL */#define HEAP_MOVED (HEAP_MOVED_OFF | HEAP_MOVED_IN)#define HEAP_XACT_MASK			0xFFC0	/* visibility-related bits *//* * HeapTupleHeader accessor macros * * Note: beware of multiple evaluations of "tup" argument.	But the Set * macros evaluate their other argument only once. */#define HeapTupleHeaderGetXmin(tup) \( \	(tup)->t_choice.t_heap.t_xmin \)#define HeapTupleHeaderSetXmin(tup, xid) \( \	TransactionIdStore((xid), &(tup)->t_choice.t_heap.t_xmin) \)#define HeapTupleHeaderGetXmax(tup) \( \	(tup)->t_choice.t_heap.t_xmax \)#define HeapTupleHeaderSetXmax(tup, xid) \( \	TransactionIdStore((xid), &(tup)->t_choice.t_heap.t_xmax) \)#define HeapTupleHeaderGetCmin(tup) \( \	(tup)->t_choice.t_heap.t_cmin \)#define HeapTupleHeaderSetCmin(tup, cid) \( \	(tup)->t_choice.t_heap.t_cmin = (cid) \)/* * Note: GetCmax will produce wrong answers after SetXvac has been executed * by a transaction other than the inserting one.  We could check * HEAP_XMAX_INVALID and return FirstCommandId if it's clear, but since that * bit will be set again if the deleting transaction aborts, there'd be no * real gain in safety from the extra test.  So, just rely on the caller not * to trust the value unless it's meaningful. */#define HeapTupleHeaderGetCmax(tup) \( \	(tup)->t_choice.t_heap.t_field4.t_cmax \)#define HeapTupleHeaderSetCmax(tup, cid) \do { \	Assert(!((tup)->t_infomask & HEAP_MOVED)); \	(tup)->t_choice.t_heap.t_field4.t_cmax = (cid); \} while (0)#define HeapTupleHeaderGetXvac(tup) \( \	((tup)->t_infomask & HEAP_MOVED) ? \		(tup)->t_choice.t_heap.t_field4.t_xvac \	: \		InvalidTransactionId \)#define HeapTupleHeaderSetXvac(tup, xid) \do { \	Assert((tup)->t_infomask & HEAP_MOVED); \	TransactionIdStore((xid), &(tup)->t_choice.t_heap.t_field4.t_xvac); \} while (0)#define HeapTupleHeaderGetDatumLength(tup) \( \	(tup)->t_choice.t_datum.datum_len \)#define HeapTupleHeaderSetDatumLength(tup, len) \( \	(tup)->t_choice.t_datum.datum_len = (len) \)#define HeapTupleHeaderGetTypeId(tup) \( \	(tup)->t_choice.t_datum.datum_typeid \)#define HeapTupleHeaderSetTypeId(tup, typeid) \( \	(tup)->t_choice.t_datum.datum_typeid = (typeid) \

⌨️ 快捷键说明

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