Team Ai
Datasetpublic

codekingpro/portable-devtools

sourceHugging Faceupdated 5mo agoView on Hugging Face
1likes15kdownloads
expandedrecord.h242 linesDownload Raw Back to utils
1/*-------------------------------------------------------------------------2 *3 * expandedrecord.h4 *	  Declarations for composite expanded objects.5 *6 * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group7 * Portions Copyright (c) 1994, Regents of the University of California8 *9 * src/include/utils/expandedrecord.h10 *11 *-------------------------------------------------------------------------12 */13#ifndef EXPANDEDRECORD_H14#define EXPANDEDRECORD_H15 16#include "access/htup.h"17#include "access/tupdesc.h"18#include "fmgr.h"19#include "utils/expandeddatum.h"20 21 22/*23 * An expanded record is contained within a private memory context (as24 * all expanded objects must be) and has a control structure as below.25 *26 * The expanded record might contain a regular "flat" tuple if that was the27 * original input and we've not modified it.  Otherwise, the contents are28 * represented by Datum/isnull arrays plus type information.  We could also29 * have both forms, if we've deconstructed the original tuple for access30 * purposes but not yet changed it.  For pass-by-reference field types, the31 * Datums would point into the flat tuple in this situation.  Once we start32 * modifying tuple fields, new pass-by-ref fields are separately palloc'd33 * within the memory context.34 *35 * It's possible to build an expanded record that references a "flat" tuple36 * stored externally, if the caller can guarantee that that tuple will not37 * change for the lifetime of the expanded record.  (This frammish is mainly38 * meant to avoid unnecessary data copying in trigger functions.)39 */40#define ER_MAGIC 1384727874		/* ID for debugging crosschecks */41 42typedef struct ExpandedRecordHeader43{44	/* Standard header for expanded objects */45	ExpandedObjectHeader hdr;46 47	/* Magic value identifying an expanded record (for debugging only) */48	int			er_magic;49 50	/* Assorted flag bits */51	int			flags;52#define ER_FLAG_FVALUE_VALID	0x0001	/* fvalue is up to date? */53#define ER_FLAG_FVALUE_ALLOCED	0x0002	/* fvalue is local storage? */54#define ER_FLAG_DVALUES_VALID	0x0004	/* dvalues/dnulls are up to date? */55#define ER_FLAG_DVALUES_ALLOCED	0x0008	/* any field values local storage? */56#define ER_FLAG_HAVE_EXTERNAL	0x0010	/* any field values are external? */57#define ER_FLAG_TUPDESC_ALLOCED	0x0020	/* tupdesc is local storage? */58#define ER_FLAG_IS_DOMAIN		0x0040	/* er_decltypeid is domain? */59#define ER_FLAG_IS_DUMMY		0x0080	/* this header is dummy (see below) */60/* flag bits that are not to be cleared when replacing tuple data: */61#define ER_FLAGS_NON_DATA \62	(ER_FLAG_TUPDESC_ALLOCED | ER_FLAG_IS_DOMAIN | ER_FLAG_IS_DUMMY)63 64	/* Declared type of the record variable (could be a domain type) */65	Oid			er_decltypeid;66 67	/*68	 * Actual composite type/typmod; never a domain (if ER_FLAG_IS_DOMAIN,69	 * these identify the composite base type).  These will match70	 * er_tupdesc->tdtypeid/tdtypmod, as well as the header fields of71	 * composite datums made from or stored in this expanded record.72	 */73	Oid			er_typeid;		/* type OID of the composite type */74	int32		er_typmod;		/* typmod of the composite type */75 76	/*77	 * Tuple descriptor, if we have one, else NULL.  This may point to a78	 * reference-counted tupdesc originally belonging to the typcache, in79	 * which case we use a memory context reset callback to release the80	 * refcount.  It can also be locally allocated in this object's private81	 * context (in which case ER_FLAG_TUPDESC_ALLOCED is set).82	 */83	TupleDesc	er_tupdesc;84 85	/*86	 * Unique-within-process identifier for the tupdesc (see typcache.h). This87	 * field will never be equal to INVALID_TUPLEDESC_IDENTIFIER.88	 */89	uint64		er_tupdesc_id;90 91	/*92	 * If we have a Datum-array representation of the record, it's kept here;93	 * else ER_FLAG_DVALUES_VALID is not set, and dvalues/dnulls may be NULL94	 * if they've not yet been allocated.  If allocated, the dvalues and95	 * dnulls arrays are palloc'd within the object private context, and are96	 * of length matching er_tupdesc->natts.  For pass-by-ref field types,97	 * dvalues entries might point either into the fstartptr..fendptr area, or98	 * to separately palloc'd chunks.99	 */100	Datum	   *dvalues;		/* array of Datums */101	bool	   *dnulls;			/* array of is-null flags for Datums */102	int			nfields;		/* length of above arrays */103 104	/*105	 * flat_size is the current space requirement for the flat equivalent of106	 * the expanded record, if known; otherwise it's 0.  We store this to make107	 * consecutive calls of get_flat_size cheap.  If flat_size is not 0, the108	 * component values data_len, hoff, and hasnull must be valid too.109	 */110	Size		flat_size;111 112	Size		data_len;		/* data len within flat_size */113	int			hoff;			/* header offset */114	bool		hasnull;		/* null bitmap needed? */115 116	/*117	 * fvalue points to the flat representation if we have one, else it is118	 * NULL.  If the flat representation is valid (up to date) then119	 * ER_FLAG_FVALUE_VALID is set.  Even if we've outdated the flat120	 * representation due to changes of user fields, it can still be used to121	 * fetch system column values.  If we have a flat representation then122	 * fstartptr/fendptr point to the start and end+1 of its data area; this123	 * is so that we can tell which Datum pointers point into the flat124	 * representation rather than being pointers to separately palloc'd data.125	 */126	HeapTuple	fvalue;			/* might or might not be private storage */127	char	   *fstartptr;		/* start of its data area */128	char	   *fendptr;		/* end+1 of its data area */129 130	/* Some operations on the expanded record need a short-lived context */131	MemoryContext er_short_term_cxt;	/* short-term memory context */132 133	/* Working state for domain checking, used if ER_FLAG_IS_DOMAIN is set */134	struct ExpandedRecordHeader *er_dummy_header;	/* dummy record header */135	void	   *er_domaininfo;	/* cache space for domain_check() */136 137	/* Callback info (it's active if er_mcb.arg is not NULL) */138	MemoryContextCallback er_mcb;139} ExpandedRecordHeader;140 141/* fmgr functions and macros for expanded record objects */142static inline Datum143ExpandedRecordGetDatum(const ExpandedRecordHeader *erh)144{145	return EOHPGetRWDatum(&erh->hdr);146}147 148static inline Datum149ExpandedRecordGetRODatum(const ExpandedRecordHeader *erh)150{151	return EOHPGetRODatum(&erh->hdr);152}153 154#define PG_GETARG_EXPANDED_RECORD(n)  DatumGetExpandedRecord(PG_GETARG_DATUM(n))155#define PG_RETURN_EXPANDED_RECORD(x)  PG_RETURN_DATUM(ExpandedRecordGetDatum(x))156 157/* assorted other macros */158#define ExpandedRecordIsEmpty(erh) \159	(((erh)->flags & (ER_FLAG_DVALUES_VALID | ER_FLAG_FVALUE_VALID)) == 0)160#define ExpandedRecordIsDomain(erh) \161	(((erh)->flags & ER_FLAG_IS_DOMAIN) != 0)162 163/* this can substitute for TransferExpandedObject() when we already have erh */164#define TransferExpandedRecord(erh, cxt) \165	MemoryContextSetParent((erh)->hdr.eoh_context, cxt)166 167/* information returned by expanded_record_lookup_field() */168typedef struct ExpandedRecordFieldInfo169{170	int			fnumber;		/* field's attr number in record */171	Oid			ftypeid;		/* field's type/typmod info */172	int32		ftypmod;173	Oid			fcollation;		/* field's collation if any */174} ExpandedRecordFieldInfo;175 176/*177 * prototypes for functions defined in expandedrecord.c178 */179extern ExpandedRecordHeader *make_expanded_record_from_typeid(Oid type_id, int32 typmod,180															  MemoryContext parentcontext);181extern ExpandedRecordHeader *make_expanded_record_from_tupdesc(TupleDesc tupdesc,182															   MemoryContext parentcontext);183extern ExpandedRecordHeader *make_expanded_record_from_exprecord(ExpandedRecordHeader *olderh,184																 MemoryContext parentcontext);185extern void expanded_record_set_tuple(ExpandedRecordHeader *erh,186									  HeapTuple tuple, bool copy, bool expand_external);187extern Datum make_expanded_record_from_datum(Datum recorddatum,188											 MemoryContext parentcontext);189extern TupleDesc expanded_record_fetch_tupdesc(ExpandedRecordHeader *erh);190extern HeapTuple expanded_record_get_tuple(ExpandedRecordHeader *erh);191extern ExpandedRecordHeader *DatumGetExpandedRecord(Datum d);192extern void deconstruct_expanded_record(ExpandedRecordHeader *erh);193extern bool expanded_record_lookup_field(ExpandedRecordHeader *erh,194										 const char *fieldname,195										 ExpandedRecordFieldInfo *finfo);196extern Datum expanded_record_fetch_field(ExpandedRecordHeader *erh, int fnumber,197										 bool *isnull);198extern void expanded_record_set_field_internal(ExpandedRecordHeader *erh,199											   int fnumber,200											   Datum newValue, bool isnull,201											   bool expand_external,202											   bool check_constraints);203extern void expanded_record_set_fields(ExpandedRecordHeader *erh,204									   const Datum *newValues, const bool *isnulls,205									   bool expand_external);206 207/* outside code should never call expanded_record_set_field_internal as such */208#define expanded_record_set_field(erh, fnumber, newValue, isnull, expand_external) \209	expanded_record_set_field_internal(erh, fnumber, newValue, isnull, expand_external, true)210 211/*212 * Inline-able fast cases.  The expanded_record_fetch_xxx functions above213 * handle the general cases.214 */215 216/* Get the tupdesc for the expanded record's actual type */217static inline TupleDesc218expanded_record_get_tupdesc(ExpandedRecordHeader *erh)219{220	if (likely(erh->er_tupdesc != NULL))221		return erh->er_tupdesc;222	else223		return expanded_record_fetch_tupdesc(erh);224}225 226/* Get value of record field */227static inline Datum228expanded_record_get_field(ExpandedRecordHeader *erh, int fnumber,229						  bool *isnull)230{231	if ((erh->flags & ER_FLAG_DVALUES_VALID) &&232		likely(fnumber > 0 && fnumber <= erh->nfields))233	{234		*isnull = erh->dnulls[fnumber - 1];235		return erh->dvalues[fnumber - 1];236	}237	else238		return expanded_record_fetch_field(erh, fnumber, isnull);239}240 241#endif							/* EXPANDEDRECORD_H */242 
codekingpro/portable-devtools · Team Ai