Team Ai
Datasetpublic

codekingpro/portable-devtools

sourceHugging Faceupdated 5mo agoView on Hugging Face
1likes14kdownloads
tupmacs.h208 linesDownload Raw Back to access
1/*-------------------------------------------------------------------------2 *3 * tupmacs.h4 *	  Tuple macros used by both index tuples and heap tuples.5 *6 *7 * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group8 * Portions Copyright (c) 1994, Regents of the University of California9 *10 * src/include/access/tupmacs.h11 *12 *-------------------------------------------------------------------------13 */14#ifndef TUPMACS_H15#define TUPMACS_H16 17#include "catalog/pg_type_d.h"	/* for TYPALIGN macros */18 19 20/*21 * Check a tuple's null bitmap to determine whether the attribute is null.22 * Note that a 0 in the null bitmap indicates a null, while 1 indicates23 * non-null.24 */25static inline bool26att_isnull(int ATT, const bits8 *BITS)27{28	return !(BITS[ATT >> 3] & (1 << (ATT & 0x07)));29}30 31#ifndef FRONTEND32/*33 * Given a Form_pg_attribute and a pointer into a tuple's data area,34 * return the correct value or pointer.35 *36 * We return a Datum value in all cases.  If the attribute has "byval" false,37 * we return the same pointer into the tuple data area that we're passed.38 * Otherwise, we return the correct number of bytes fetched from the data39 * area and extended to Datum form.40 *41 * On machines where Datum is 8 bytes, we support fetching 8-byte byval42 * attributes; otherwise, only 1, 2, and 4-byte values are supported.43 *44 * Note that T must already be properly aligned for this to work correctly.45 */46#define fetchatt(A,T) fetch_att(T, (A)->attbyval, (A)->attlen)47 48/*49 * Same, but work from byval/len parameters rather than Form_pg_attribute.50 */51static inline Datum52fetch_att(const void *T, bool attbyval, int attlen)53{54	if (attbyval)55	{56		switch (attlen)57		{58			case sizeof(char):59				return CharGetDatum(*((const char *) T));60			case sizeof(int16):61				return Int16GetDatum(*((const int16 *) T));62			case sizeof(int32):63				return Int32GetDatum(*((const int32 *) T));64#if SIZEOF_DATUM == 865			case sizeof(Datum):66				return *((const Datum *) T);67#endif68			default:69				elog(ERROR, "unsupported byval length: %d", attlen);70				return 0;71		}72	}73	else74		return PointerGetDatum(T);75}76#endif							/* FRONTEND */77 78/*79 * att_align_datum aligns the given offset as needed for a datum of alignment80 * requirement attalign and typlen attlen.  attdatum is the Datum variable81 * we intend to pack into a tuple (it's only accessed if we are dealing with82 * a varlena type).  Note that this assumes the Datum will be stored as-is;83 * callers that are intending to convert non-short varlena datums to short84 * format have to account for that themselves.85 */86#define att_align_datum(cur_offset, attalign, attlen, attdatum) \87( \88	((attlen) == -1 && VARATT_IS_SHORT(DatumGetPointer(attdatum))) ? \89	(uintptr_t) (cur_offset) : \90	att_align_nominal(cur_offset, attalign) \91)92 93/*94 * att_align_pointer performs the same calculation as att_align_datum,95 * but is used when walking a tuple.  attptr is the current actual data96 * pointer; when accessing a varlena field we have to "peek" to see if we97 * are looking at a pad byte or the first byte of a 1-byte-header datum.98 * (A zero byte must be either a pad byte, or the first byte of a correctly99 * aligned 4-byte length word; in either case we can align safely.  A non-zero100 * byte must be either a 1-byte length word, or the first byte of a correctly101 * aligned 4-byte length word; in either case we need not align.)102 *103 * Note: some callers pass a "char *" pointer for cur_offset.  This is104 * a bit of a hack but should work all right as long as uintptr_t is the105 * correct width.106 */107#define att_align_pointer(cur_offset, attalign, attlen, attptr) \108( \109	((attlen) == -1 && VARATT_NOT_PAD_BYTE(attptr)) ? \110	(uintptr_t) (cur_offset) : \111	att_align_nominal(cur_offset, attalign) \112)113 114/*115 * att_align_nominal aligns the given offset as needed for a datum of alignment116 * requirement attalign, ignoring any consideration of packed varlena datums.117 * There are three main use cases for using this macro directly:118 *	* we know that the att in question is not varlena (attlen != -1);119 *	  in this case it is cheaper than the above macros and just as good.120 *	* we need to estimate alignment padding cost abstractly, ie without121 *	  reference to a real tuple.  We must assume the worst case that122 *	  all varlenas are aligned.123 *	* within arrays and multiranges, we unconditionally align varlenas (XXX this124 *	  should be revisited, probably).125 *126 * The attalign cases are tested in what is hopefully something like their127 * frequency of occurrence.128 */129#define att_align_nominal(cur_offset, attalign) \130( \131	((attalign) == TYPALIGN_INT) ? INTALIGN(cur_offset) : \132	 (((attalign) == TYPALIGN_CHAR) ? (uintptr_t) (cur_offset) : \133	  (((attalign) == TYPALIGN_DOUBLE) ? DOUBLEALIGN(cur_offset) : \134	   ( \135			AssertMacro((attalign) == TYPALIGN_SHORT), \136			SHORTALIGN(cur_offset) \137	   ))) \138)139 140/*141 * att_addlength_datum increments the given offset by the space needed for142 * the given Datum variable.  attdatum is only accessed if we are dealing143 * with a variable-length attribute.144 */145#define att_addlength_datum(cur_offset, attlen, attdatum) \146	att_addlength_pointer(cur_offset, attlen, DatumGetPointer(attdatum))147 148/*149 * att_addlength_pointer performs the same calculation as att_addlength_datum,150 * but is used when walking a tuple --- attptr is the pointer to the field151 * within the tuple.152 *153 * Note: some callers pass a "char *" pointer for cur_offset.  This is154 * actually perfectly OK, but probably should be cleaned up along with155 * the same practice for att_align_pointer.156 */157#define att_addlength_pointer(cur_offset, attlen, attptr) \158( \159	((attlen) > 0) ? \160	( \161		(cur_offset) + (attlen) \162	) \163	: (((attlen) == -1) ? \164	( \165		(cur_offset) + VARSIZE_ANY(attptr) \166	) \167	: \168	( \169		AssertMacro((attlen) == -2), \170		(cur_offset) + (strlen((char *) (attptr)) + 1) \171	)) \172)173 174#ifndef FRONTEND175/*176 * store_att_byval is a partial inverse of fetch_att: store a given Datum177 * value into a tuple data area at the specified address.  However, it only178 * handles the byval case, because in typical usage the caller needs to179 * distinguish by-val and by-ref cases anyway, and so a do-it-all function180 * wouldn't be convenient.181 */182static inline void183store_att_byval(void *T, Datum newdatum, int attlen)184{185	switch (attlen)186	{187		case sizeof(char):188			*(char *) T = DatumGetChar(newdatum);189			break;190		case sizeof(int16):191			*(int16 *) T = DatumGetInt16(newdatum);192			break;193		case sizeof(int32):194			*(int32 *) T = DatumGetInt32(newdatum);195			break;196#if SIZEOF_DATUM == 8197		case sizeof(Datum):198			*(Datum *) T = newdatum;199			break;200#endif201		default:202			elog(ERROR, "unsupported byval length: %d", attlen);203	}204}205#endif							/* FRONTEND */206 207#endif							/* TUPMACS_H */208 
codekingpro/portable-devtools · Team Ai