/*-------------------------------------------------------------------------
 *
 * array_expanded.c
 *	  Basic functions for manipulating expanded arrays.
 *
 * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group
 * Portions Copyright (c) 1994, Regents of the University of California
 *
 *
 * IDENTIFICATION
 *	  src/backend/utils/adt/array_expanded.c
 *
 *-------------------------------------------------------------------------
 */
#include "postgres.h"

#include "access/tupmacs.h"
#include "utils/array.h"
#include "utils/lsyscache.h"
#include "utils/memutils.h"


/* "Methods" required for an expanded object */
static Size EA_get_flat_size(ExpandedObjectHeader *eohptr);
static void EA_flatten_into(ExpandedObjectHeader *eohptr,
							void *result, Size allocated_size);

static const ExpandedObjectMethods EA_methods =
{
	EA_get_flat_size,
	EA_flatten_into
};

/* Other local functions */
static void copy_byval_expanded_array(ExpandedArrayHeader *eah,
									  ExpandedArrayHeader *oldeah);


/*
 * expand_array: convert an array Datum into an expanded array
 *
 * The expanded object will be a child of parentcontext.
 *
 * Some callers can provide cache space to avoid repeated lookups of element
 * type data across calls; if so, pass a metacache pointer, making sure that
 * metacache->element_type is initialized to InvalidOid before first call.
 * If no cross-call caching is required, pass NULL for metacache.
 */
Datum
expand_array(Datum arraydatum, MemoryContext parentcontext,
			 ArrayMetaState *metacache)
{
	ArrayType  *array;
	ExpandedArrayHeader *eah;
	MemoryContext objcxt;
	MemoryContext oldcxt;
	ArrayMetaState fakecache;

	/*
	 * Allocate private context for expanded object.  We start by assuming
	 * that the array won't be very large; but if it does grow a lot, don't
	 * constrain aset.c's large-context behavior.
	 */
	objcxt = AllocSetContextCreate(parentcontext,
								   "expanded array",
								   ALLOCSET_START_SMALL_SIZES);

	/* Set up expanded array header */
	eah = (ExpandedArrayHeader *)
		MemoryContextAlloc(objcxt, sizeof(ExpandedArrayHeader));

	EOH_init_header(&eah->hdr, &EA_methods, objcxt);
	eah->ea_magic = EA_MAGIC;

	/* If the source is an expanded array, we may be able to optimize */
	if (VARATT_IS_EXTERNAL_EXPANDED(DatumGetPointer(arraydatum)))
	{
		ExpandedArrayHeader *oldeah = (ExpandedArrayHeader *) DatumGetEOHP(arraydatum);

		Assert(oldeah->ea_magic == EA_MAGIC);

		/*
		 * Update caller's cache if provided; we don't need it this time, but
		 * next call might be for a non-expanded source array.  Furthermore,
		 * if the caller didn't provide a cache area, use some local storage
		 * to cache anyway, thereby avoiding a catalog lookup in the case
		 * where we fall through to the flat-copy code path.
		 */
		if (metacache == NULL)
			metacache = &fakecache;
		metacache->element_type = oldeah->element_type;
		metacache->typlen = oldeah->typlen;
		metacache->typbyval = oldeah->typbyval;
		metacache->typalign = oldeah->typalign;

		/*
		 * If element type is pass-by-value and we have a Datum-array
		 * representation, just copy the source's metadata and Datum/isnull
		 * arrays.  The original flat array, if present at all, adds no
		 * additional information so we need not copy it.
		 */
		if (oldeah->typbyval && oldeah->dvalues != NULL)
		{
			copy_byval_expanded_array(eah, oldeah);
			/* return a R/W pointer to the expanded array */
			return EOHPGetRWDatum(&eah->hdr);
		}

		/*
		 * Otherwise, either we have only a flat representation or the
		 * elements are pass-by-reference.  In either case, the best thing
		 * seems to be to copy the source as a flat representation and then
		 * deconstruct that later if necessary.  For the pass-by-ref case, we
		 * could perhaps save some cycles with custom code that generates the
		 * deconstructed representation in parallel with copying the values,
		 * but it would be a lot of extra code for fairly marginal gain.  So,
		 * fall through into the flat-source code path.
		 */
	}

	/*
	 * Detoast and copy source array into private context, as a flat array.
	 *
	 * Note that this coding risks leaking some memory in the private context
	 * if we have to fetch data from a TOAST table; however, experimentation
	 * says that the leak is minimal.  Doing it this way saves a copy step,
	 * which seems worthwhile, especially if the array is large enough to need
	 * external storage.
	 */
	oldcxt = MemoryContextSwitchTo(objcxt);
	array = DatumGetArrayTypePCopy(arraydatum);
	MemoryContextSwitchTo(oldcxt);

	eah->ndims = ARR_NDIM(array);
	/* note these pointers point into the fvalue header! */
	eah->dims = ARR_DIMS(array);
	eah->lbound = ARR_LBOUND(array);

	/* Save array's element-type data for possible use later */
	eah->element_type = ARR_ELEMTYPE(array);
	if (metacache && metacache->element_type == eah->element_type)
	{
		/* We have a valid cache of representational data */
		eah->typlen = metacache->typlen;
		eah->typbyval = metacache->typbyval;
		eah->typalign = metacache->typalign;
	}
	else
	{
		/* No, so look it up */
		get_typlenbyvalalign(eah->element_type,
							 &eah->typlen,
							 &eah->typbyval,
							 &eah->typalign);
		/* Update cache if provided */
		if (metacache)
		{
			metacache->element_type = eah->element_type;
			metacache->typlen = eah->typlen;
			metacache->typbyval = eah->typbyval;
			metacache->typalign = eah->typalign;
		}
	}

	/* we don't make a deconstructed representation now */
	eah->dvalues = NULL;
	eah->dnulls = NULL;
	eah->dvalueslen = 0;
	eah->nelems = 0;
	eah->flat_size = 0;

	/* remember we have a flat representation */
	eah->fvalue = array;
	eah->fstartptr = ARR_DATA_PTR(array);
	eah->fendptr = ((char *) array) + ARR_SIZE(array);

	/* return a R/W pointer to the expanded array */
	return EOHPGetRWDatum(&eah->hdr);
}

/*
 * helper for expand_array(): copy pass-by-value Datum-array representation
 */
static void
copy_byval_expanded_array(ExpandedArrayHeader *eah,
						  ExpandedArrayHeader *oldeah)
{
	MemoryContext objcxt = eah->hdr.eoh_context;
	int			ndims = oldeah->ndims;
	int			dvalueslen = oldeah->dvalueslen;

	/* Copy array dimensionality information */
	eah->ndims = ndims;
	/* We can alloc both dimensionality arrays with one palloc */
	eah->dims = (int *) MemoryContextAlloc(objcxt, ndims * 2 * sizeof(int));
	eah->lbound = eah->dims + ndims;
	/* .. but don't assume the source's arrays are contiguous */
	memcpy(eah->dims, oldeah->dims, ndims * sizeof(int));
	memcpy(eah->lbound, oldeah->lbound, ndims * sizeof(int));

	/* Copy element-type data */
	eah->element_type = oldeah->element_type;
	eah->typlen = oldeah->typlen;
	eah->typbyval = oldeah->typbyval;
	eah->typalign = oldeah->typalign;

	/* Copy the deconstructed representation */
	eah->dvalues = (Datum *) MemoryContextAlloc(objcxt,
												dvalueslen * sizeof(Datum));
	memcpy(eah->dvalues, oldeah->dvalues, dvalueslen * sizeof(Datum));
	if (oldeah->dnulls)
	{
		eah->dnulls = (bool *) MemoryContextAlloc(objcxt,
												  dvalueslen * sizeof(bool));
		memcpy(eah->dnulls, oldeah->dnulls, dvalueslen * sizeof(bool));
	}
	else
		eah->dnulls = NULL;
	eah->dvalueslen = dvalueslen;
	eah->nelems = oldeah->nelems;
	eah->flat_size = oldeah->flat_size;

	/* we don't make a flat representation */
	eah->fvalue = NULL;
	eah->fstartptr = NULL;
	eah->fendptr = NULL;
}

/*
 * get_flat_size method for expanded arrays
 */
static Size
EA_get_flat_size(ExpandedObjectHeader *eohptr)
{
	ExpandedArrayHeader *eah = (ExpandedArrayHeader *) eohptr;
	int			nelems;
	int			ndims;
	Datum	   *dvalues;
	bool	   *dnulls;
	Size		nbytes;
	int			i;

	Assert(eah->ea_magic == EA_MAGIC);

	/* Easy if we have a valid flattened value */
	if (eah->fvalue)
		return ARR_SIZE(eah->fvalue);

	/* If we have a cached size value, believe that */
	if (eah->flat_size)
		return eah->flat_size;

	/*
	 * Compute space needed by examining dvalues/dnulls.  Note that the result
	 * array will have a nulls bitmap if dnulls isn't NULL, even if the array
	 * doesn't actually contain any nulls now.
	 */
	nelems = eah->nelems;
	ndims = eah->ndims;
	Assert(nelems == ArrayGetNItems(ndims, eah->dims));
	dvalues = eah->dvalues;
	dnulls = eah->dnulls;
	nbytes = 0;
	for (i = 0; i < nelems; i++)
	{
		if (dnulls && dnulls[i])
			continue;
		nbytes = att_addlength_datum(nbytes, eah->typlen, dvalues[i]);
		nbytes = att_align_nominal(nbytes, eah->typalign);
		/* check for overflow of total request */
		if (!AllocSizeIsValid(nbytes))
			ereport(ERROR,
					(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
					 errmsg("array size exceeds the maximum allowed (%d)",
							(int) MaxAllocSize)));
	}

	if (dnulls)
		nbytes += ARR_OVERHEAD_WITHNULLS(ndims, nelems);
	else
		nbytes += ARR_OVERHEAD_NONULLS(ndims);

	/* cache for next time */
	eah->flat_size = nbytes;

	return nbytes;
}

/*
 * flatten_into method for expanded arrays
 */
static void
EA_flatten_into(ExpandedObjectHeader *eohptr,
				void *result, Size allocated_size)
{
	ExpandedArrayHeader *eah = (ExpandedArrayHeader *) eohptr;
	ArrayType  *aresult = (ArrayType *) result;
	int			nelems;
	int			ndims;
	int32		dataoffset;

	Assert(eah->ea_magic == EA_MAGIC);

	/* Easy if we have a valid flattened value */
	if (eah->fvalue)
	{
		Assert(allocated_size == ARR_SIZE(eah->fvalue));
		memcpy(result, eah->fvalue, allocated_size);
		return;
	}

	/* Else allocation should match previous get_flat_size result */
	Assert(allocated_size == eah->flat_size);

	/* Fill result array from dvalues/dnulls */
	nelems = eah->nelems;
	ndims = eah->ndims;

	if (eah->dnulls)
		dataoffset = ARR_OVERHEAD_WITHNULLS(ndims, nelems);
	else
		dataoffset = 0;			/* marker for no null bitmap */

	/* We must ensure that any pad space is zero-filled */
	memset(aresult, 0, allocated_size);

	SET_VARSIZE(aresult, allocated_size);
	aresult->ndim = ndims;
	aresult->dataoffset = dataoffset;
	aresult->elemtype = eah->element_type;
	memcpy(ARR_DIMS(aresult), eah->dims, ndims * sizeof(int));
	memcpy(ARR_LBOUND(aresult), eah->lbound, ndims * sizeof(int));

	CopyArrayEls(aresult,
				 eah->dvalues, eah->dnulls, nelems,
				 eah->typlen, eah->typbyval, eah->typalign,
				 false);
}

/*
 * Argument fetching support code
 */

/*
 * DatumGetExpandedArray: get a writable expanded array from an input argument
 *
 * Caution: if the input is a read/write pointer, this returns the input
 * argument; so callers must be sure that their changes are "safe", that is
 * they cannot leave the array in a corrupt state.
 */
ExpandedArrayHeader *
DatumGetExpandedArray(Datum d)
{
	/* If it's a writable expanded array already, just return it */
	if (VARATT_IS_EXTERNAL_EXPANDED_RW(DatumGetPointer(d)))
	{
		ExpandedArrayHeader *eah = (ExpandedArrayHeader *) DatumGetEOHP(d);

		Assert(eah->ea_magic == EA_MAGIC);
		return eah;
	}

	/* Else expand the hard way */
	d = expand_array(d, CurrentMemoryContext, NULL);
	return (ExpandedArrayHeader *) DatumGetEOHP(d);
}

/*
 * As above, when caller has the ability to cache element type info
 */
ExpandedArrayHeader *
DatumGetExpandedArrayX(Datum d, ArrayMetaState *metacache)
{
	/* If it's a writable expanded array already, just return it */
	if (VARATT_IS_EXTERNAL_EXPANDED_RW(DatumGetPointer(d)))
	{
		ExpandedArrayHeader *eah = (ExpandedArrayHeader *) DatumGetEOHP(d);

		Assert(eah->ea_magic == EA_MAGIC);
		/* Update cache if provided */
		if (metacache)
		{
			metacache->element_type = eah->element_type;
			metacache->typlen = eah->typlen;
			metacache->typbyval = eah->typbyval;
			metacache->typalign = eah->typalign;
		}
		return eah;
	}

	/* Else expand using caller's cache if any */
	d = expand_array(d, CurrentMemoryContext, metacache);
	return (ExpandedArrayHeader *) DatumGetEOHP(d);
}

/*
 * DatumGetAnyArrayP: return either an expanded array or a detoasted varlena
 * array.  The result must not be modified in-place.
 */
AnyArrayType *
DatumGetAnyArrayP(Datum d)
{
	ExpandedArrayHeader *eah;

	/*
	 * If it's an expanded array (RW or RO), return the header pointer.
	 */
	if (VARATT_IS_EXTERNAL_EXPANDED(DatumGetPointer(d)))
	{
		eah = (ExpandedArrayHeader *) DatumGetEOHP(d);
		Assert(eah->ea_magic == EA_MAGIC);
		return (AnyArrayType *) eah;
	}

	/* Else do regular detoasting as needed */
	return (AnyArrayType *) PG_DETOAST_DATUM(d);
}

/*
 * Create the Datum/isnull representation of an expanded array object
 * if we didn't do so previously
 */
void
deconstruct_expanded_array(ExpandedArrayHeader *eah)
{
	if (eah->dvalues == NULL)
	{
		MemoryContext oldcxt = MemoryContextSwitchTo(eah->hdr.eoh_context);
		Datum	   *dvalues;
		bool	   *dnulls;
		int			nelems;

		dnulls = NULL;
		deconstruct_array(eah->fvalue,
						  eah->element_type,
						  eah->typlen, eah->typbyval, eah->typalign,
						  &dvalues,
						  ARR_HASNULL(eah->fvalue) ? &dnulls : NULL,
						  &nelems);

		/*
		 * Update header only after successful completion of this step.  If
		 * deconstruct_array fails partway through, worst consequence is some
		 * leaked memory in the object's context.  If the caller fails at a
		 * later point, that's fine, since the deconstructed representation is
		 * valid anyhow.
		 */
		eah->dvalues = dvalues;
		eah->dnulls = dnulls;
		eah->dvalueslen = eah->nelems = nelems;
		MemoryContextSwitchTo(oldcxt);
	}
}
