#ifndef EXPANDEDRECORD_H
#define EXPANDEDRECORD_H
#include "access/htup.h"
#include "access/tupdesc.h"
#include "fmgr.h"
#include "utils/expandeddatum.h"
#define ER_MAGIC 1384727874
typedef struct ExpandedRecordHeader
{
ExpandedObjectHeader hdr;
int er_magic;
int flags;
#define ER_FLAG_FVALUE_VALID 0x0001
#define ER_FLAG_FVALUE_ALLOCED 0x0002
#define ER_FLAG_DVALUES_VALID 0x0004
#define ER_FLAG_DVALUES_ALLOCED 0x0008
#define ER_FLAG_HAVE_EXTERNAL 0x0010
#define ER_FLAG_TUPDESC_ALLOCED 0x0020
#define ER_FLAG_IS_DOMAIN 0x0040
#define ER_FLAG_IS_DUMMY 0x0080
#define ER_FLAGS_NON_DATA \
(ER_FLAG_TUPDESC_ALLOCED | ER_FLAG_IS_DOMAIN | ER_FLAG_IS_DUMMY)
Oid er_decltypeid;
Oid er_typeid;
int32 er_typmod;
TupleDesc er_tupdesc;
uint64 er_tupdesc_id;
Datum *dvalues;
bool *dnulls;
int nfields;
Size flat_size;
Size data_len;
int hoff;
bool hasnull;
HeapTuple fvalue;
char *fstartptr;
char *fendptr;
MemoryContext er_short_term_cxt;
struct ExpandedRecordHeader *er_dummy_header;
void *er_domaininfo;
MemoryContextCallback er_mcb;
} ExpandedRecordHeader;
static inline Datum
ExpandedRecordGetDatum(const ExpandedRecordHeader *erh)
{
return EOHPGetRWDatum(&erh->hdr);
}
static inline Datum
ExpandedRecordGetRODatum(const ExpandedRecordHeader *erh)
{
return EOHPGetRODatum(&erh->hdr);
}
#define PG_GETARG_EXPANDED_RECORD(n) DatumGetExpandedRecord(PG_GETARG_DATUM(n))
#define PG_RETURN_EXPANDED_RECORD(x) PG_RETURN_DATUM(ExpandedRecordGetDatum(x))
#define ExpandedRecordIsEmpty(erh) \
(((erh)->flags & (ER_FLAG_DVALUES_VALID | ER_FLAG_FVALUE_VALID)) == 0)
#define ExpandedRecordIsDomain(erh) \
(((erh)->flags & ER_FLAG_IS_DOMAIN) != 0)
#define TransferExpandedRecord(erh, cxt) \
MemoryContextSetParent((erh)->hdr.eoh_context, cxt)
typedef struct ExpandedRecordFieldInfo
{
int fnumber;
Oid ftypeid;
int32 ftypmod;
Oid fcollation;
} ExpandedRecordFieldInfo;
extern ExpandedRecordHeader *make_expanded_record_from_typeid(Oid type_id, int32 typmod,
MemoryContext parentcontext);
extern ExpandedRecordHeader *make_expanded_record_from_tupdesc(TupleDesc tupdesc,
MemoryContext parentcontext);
extern ExpandedRecordHeader *make_expanded_record_from_exprecord(ExpandedRecordHeader *olderh,
MemoryContext parentcontext);
extern void expanded_record_set_tuple(ExpandedRecordHeader *erh,
HeapTuple tuple, bool copy, bool expand_external);
extern Datum make_expanded_record_from_datum(Datum recorddatum,
MemoryContext parentcontext);
extern TupleDesc expanded_record_fetch_tupdesc(ExpandedRecordHeader *erh);
extern HeapTuple expanded_record_get_tuple(ExpandedRecordHeader *erh);
extern ExpandedRecordHeader *DatumGetExpandedRecord(Datum d);
extern void deconstruct_expanded_record(ExpandedRecordHeader *erh);
extern bool expanded_record_lookup_field(ExpandedRecordHeader *erh,
const char *fieldname,
ExpandedRecordFieldInfo *finfo);
extern Datum expanded_record_fetch_field(ExpandedRecordHeader *erh, int fnumber,
bool *isnull);
extern void expanded_record_set_field_internal(ExpandedRecordHeader *erh,
int fnumber,
Datum newValue, bool isnull,
bool expand_external,
bool check_constraints);
extern void expanded_record_set_fields(ExpandedRecordHeader *erh,
const Datum *newValues, const bool *isnulls,
bool expand_external);
#define expanded_record_set_field(erh, fnumber, newValue, isnull, expand_external) \
expanded_record_set_field_internal(erh, fnumber, newValue, isnull, expand_external, true)
static inline TupleDesc
expanded_record_get_tupdesc(ExpandedRecordHeader *erh)
{
if (likely(erh->er_tupdesc != NULL))
return erh->er_tupdesc;
else
return expanded_record_fetch_tupdesc(erh);
}
static inline Datum
expanded_record_get_field(ExpandedRecordHeader *erh, int fnumber,
bool *isnull)
{
if ((erh->flags & ER_FLAG_DVALUES_VALID) &&
likely(fnumber > 0 && fnumber <= erh->nfields))
{
*isnull = erh->dnulls[fnumber - 1];
return erh->dvalues[fnumber - 1];
}
else
return expanded_record_fetch_field(erh, fnumber, isnull);
}
#endif