int16 typlen; /* element type's length */
bool typbyval; /* element type's byval property */
char typalign; /* element type's align property */
+ uint8 typalignby; /* typalign mapped to numeric alignment */
/* information about the requested slice size */
int slice_ndim; /* slice dimension, or 0 if not slicing */
static void array_set_isnull(bits8 *nullbitmap, int offset, bool isNull);
static Datum ArrayCast(char *value, bool byval, int len);
static int ArrayCastAndSet(Datum src,
- int typlen, bool typbyval, char typalign,
+ int typlen, bool typbyval, uint8 typalignby,
char *dest);
static char *array_seek(char *ptr, int offset, bits8 *nullbitmap, int nitems,
int typlen, bool typbyval, char typalign);
int typlen;
bool typbyval;
char typalign;
+ uint8 typalignby;
char typdelim;
Oid typioparam;
char *p;
typlen = my_extra->typlen;
typbyval = my_extra->typbyval;
typalign = my_extra->typalign;
+ typalignby = typalign_to_alignby(typalign);
typdelim = my_extra->typdelim;
typioparam = my_extra->typioparam;
if (typlen == -1)
values[i] = PointerGetDatum(PG_DETOAST_DATUM(values[i]));
nbytes = att_addlength_datum(nbytes, typlen, values[i]);
- nbytes = att_align_nominal(nbytes, typalign);
+ nbytes = att_nominal_alignby(nbytes, typalignby);
/* check for overflow of total request */
if (!AllocSizeIsValid(nbytes))
ereturn(escontext, (Datum) 0,
bits8 *bitmap = ARR_NULLBITMAP(array);
int bitval = 0;
int bitmask = 1;
+ uint8 typalignby = typalign_to_alignby(typalign);
int i;
if (typbyval)
else
{
bitval |= bitmask;
- p += ArrayCastAndSet(values[i], typlen, typbyval, typalign, p);
+ p += ArrayCastAndSet(values[i], typlen, typbyval, typalignby, p);
if (freedata)
pfree(DatumGetPointer(values[i]));
}
needquotes = (bool *) palloc(nitems * sizeof(bool));
overall_length = 0;
- array_iter_setup(&iter, v);
+ array_iter_setup(&iter, v, typlen, typbyval, typalign);
for (i = 0; i < nitems; i++)
{
bool needquote;
/* Get source element, checking for NULL */
- itemvalue = array_iter_next(&iter, &isnull, i,
- typlen, typbyval, typalign);
+ itemvalue = array_iter_next(&iter, &isnull, i);
if (isnull)
{
int i;
bool hasnull;
int32 totbytes;
+ uint8 typalignby = typalign_to_alignby(typalign);
for (i = 0; i < nitems; i++)
{
if (typlen == -1)
values[i] = PointerGetDatum(PG_DETOAST_DATUM(values[i]));
totbytes = att_addlength_datum(totbytes, typlen, values[i]);
- totbytes = att_align_nominal(totbytes, typalign);
+ totbytes = att_nominal_alignby(totbytes, typalignby);
/* check for overflow of total request */
if (!AllocSizeIsValid(totbytes))
ereport(ERROR,
}
/* Send the array elements using the element's own sendproc */
- array_iter_setup(&iter, v);
+ array_iter_setup(&iter, v, typlen, typbyval, typalign);
for (i = 0; i < nitems; i++)
{
bool isnull;
/* Get source element, checking for NULL */
- itemvalue = array_iter_next(&iter, &isnull, i,
- typlen, typbyval, typalign);
+ itemvalue = array_iter_next(&iter, &isnull, i);
if (isnull)
{
addedafter,
lenbefore,
lenafter;
+ uint8 elmalignby = typalign_to_alignby(elmalign);
if (arraytyplen > 0)
{
resultarray = (char *) palloc(arraytyplen);
memcpy(resultarray, DatumGetPointer(arraydatum), arraytyplen);
elt_ptr = resultarray + indx[0] * elmlen;
- ArrayCastAndSet(dataValue, elmlen, elmbyval, elmalign, elt_ptr);
+ ArrayCastAndSet(dataValue, elmlen, elmbyval, elmalignby, elt_ptr);
return PointerGetDatum(resultarray);
}
else
{
olditemlen = att_addlength_pointer(0, elmlen, elt_ptr);
- olditemlen = att_align_nominal(olditemlen, elmalign);
+ olditemlen = att_nominal_alignby(olditemlen, elmalignby);
}
lenafter = olddatasize - lenbefore - olditemlen;
}
else
{
newitemlen = att_addlength_datum(0, elmlen, dataValue);
- newitemlen = att_align_nominal(newitemlen, elmalign);
+ newitemlen = att_nominal_alignby(newitemlen, elmalignby);
}
newsize = overheadlen + lenbefore + newitemlen + lenafter;
(char *) array + oldoverheadlen,
lenbefore);
if (!isNull)
- ArrayCastAndSet(dataValue, elmlen, elmbyval, elmalign,
+ ArrayCastAndSet(dataValue, elmlen, elmbyval, elmalignby,
(char *) newarray + overheadlen + lenbefore);
memcpy((char *) newarray + overheadlen + lenbefore + newitemlen,
(char *) array + oldoverheadlen + lenbefore + olditemlen,
int typlen;
bool typbyval;
char typalign;
+ uint8 typalignby;
array_iter iter;
ArrayMetaState *inp_extra;
ArrayMetaState *ret_extra;
typlen = ret_extra->typlen;
typbyval = ret_extra->typbyval;
typalign = ret_extra->typalign;
+ typalignby = typalign_to_alignby(typalign);
/* Allocate temporary arrays for new values */
values = (Datum *) palloc(nitems * sizeof(Datum));
nulls = (bool *) palloc(nitems * sizeof(bool));
/* Loop over source data */
- array_iter_setup(&iter, v);
+ array_iter_setup(&iter, v, inp_typlen, inp_typbyval, inp_typalign);
hasnulls = false;
for (i = 0; i < nitems; i++)
{
/* Get source element, checking for NULL */
*transform_source =
- array_iter_next(&iter, transform_source_isnull, i,
- inp_typlen, inp_typbyval, inp_typalign);
+ array_iter_next(&iter, transform_source_isnull, i);
/* Apply the given expression to source element */
values[i] = ExecEvalExpr(exprstate, econtext, &nulls[i]);
values[i] = PointerGetDatum(PG_DETOAST_DATUM(values[i]));
/* Update total result size */
nbytes = att_addlength_datum(nbytes, typlen, values[i]);
- nbytes = att_align_nominal(nbytes, typalign);
+ nbytes = att_nominal_alignby(nbytes, typalignby);
/* check for overflow of total request */
if (!AllocSizeIsValid(nbytes))
ereport(ERROR,
int32 dataoffset;
int i;
int nelems;
+ uint8 elmalignby = typalign_to_alignby(elmalign);
if (ndims < 0) /* we do allow zero-dimension arrays */
ereport(ERROR,
if (elmlen == -1)
elems[i] = PointerGetDatum(PG_DETOAST_DATUM(elems[i]));
nbytes = att_addlength_datum(nbytes, elmlen, elems[i]);
- nbytes = att_align_nominal(nbytes, elmalign);
+ nbytes = att_nominal_alignby(nbytes, elmalignby);
/* check for overflow of total request */
if (!AllocSizeIsValid(nbytes))
ereport(ERROR,
bits8 *bitmap;
int bitmask;
int i;
+ uint8 elmalignby = typalign_to_alignby(elmalign);
Assert(ARR_ELEMTYPE(array) == elmtype);
{
elems[i] = fetch_att(p, elmbyval, elmlen);
p = att_addlength_pointer(p, elmlen, p);
- p = (char *) att_align_nominal(p, elmalign);
+ p = (char *) att_nominal_alignby(p, elmalignby);
}
/* advance bitmap pointer if any */
/* Loop over source data */
nitems = ArrayGetNItems(ndims1, dims1);
- array_iter_setup(&it1, array1);
- array_iter_setup(&it2, array2);
+ array_iter_setup(&it1, array1, typlen, typbyval, typalign);
+ array_iter_setup(&it2, array2, typlen, typbyval, typalign);
for (i = 0; i < nitems; i++)
{
bool oprresult;
/* Get elements, checking for NULL */
- elt1 = array_iter_next(&it1, &isnull1, i,
- typlen, typbyval, typalign);
- elt2 = array_iter_next(&it2, &isnull2, i,
- typlen, typbyval, typalign);
+ elt1 = array_iter_next(&it1, &isnull1, i);
+ elt2 = array_iter_next(&it2, &isnull2, i);
/*
* We consider two NULLs equal; NULL and not-NULL are unequal.
/* Loop over source data */
min_nitems = Min(nitems1, nitems2);
- array_iter_setup(&it1, array1);
- array_iter_setup(&it2, array2);
+ array_iter_setup(&it1, array1, typlen, typbyval, typalign);
+ array_iter_setup(&it2, array2, typlen, typbyval, typalign);
for (i = 0; i < min_nitems; i++)
{
int32 cmpresult;
/* Get elements, checking for NULL */
- elt1 = array_iter_next(&it1, &isnull1, i, typlen, typbyval, typalign);
- elt2 = array_iter_next(&it2, &isnull2, i, typlen, typbyval, typalign);
+ elt1 = array_iter_next(&it1, &isnull1, i);
+ elt2 = array_iter_next(&it2, &isnull2, i);
/*
* We consider two NULLs equal; NULL > not-NULL.
/* Loop over source data */
nitems = ArrayGetNItems(ndims, dims);
- array_iter_setup(&iter, array);
+ array_iter_setup(&iter, array, typlen, typbyval, typalign);
for (i = 0; i < nitems; i++)
{
uint32 elthash;
/* Get element, checking for NULL */
- elt = array_iter_next(&iter, &isnull, i, typlen, typbyval, typalign);
+ elt = array_iter_next(&iter, &isnull, i);
if (isnull)
{
/* Loop over source data */
nitems = ArrayGetNItems(ndims, dims);
- array_iter_setup(&iter, array);
+ array_iter_setup(&iter, array, typlen, typbyval, typalign);
for (i = 0; i < nitems; i++)
{
uint64 elthash;
/* Get element, checking for NULL */
- elt = array_iter_next(&iter, &isnull, i, typlen, typbyval, typalign);
+ elt = array_iter_next(&iter, &isnull, i);
if (isnull)
{
/* Loop over source data */
nelems1 = ArrayGetNItems(AARR_NDIM(array1), AARR_DIMS(array1));
- array_iter_setup(&it1, array1);
+ array_iter_setup(&it1, array1, typlen, typbyval, typalign);
for (i = 0; i < nelems1; i++)
{
bool isnull1;
/* Get element, checking for NULL */
- elt1 = array_iter_next(&it1, &isnull1, i, typlen, typbyval, typalign);
+ elt1 = array_iter_next(&it1, &isnull1, i);
/*
* We assume that the comparison operator is strict, so a NULL can't
&iterator->typlen,
&iterator->typbyval,
&iterator->typalign);
+ iterator->typalignby = typalign_to_alignby(iterator->typalign);
/*
* Remember the slicing parameters.
/* Move our data pointer forward to the next element */
p = att_addlength_pointer(p, iterator->typlen, p);
- p = (char *) att_align_nominal(p, iterator->typalign);
+ p = (char *) att_nominal_alignby(p, iterator->typalignby);
iterator->data_ptr = p;
}
}
/* Move our data pointer forward to the next element */
p = att_addlength_pointer(p, iterator->typlen, p);
- p = (char *) att_align_nominal(p, iterator->typalign);
+ p = (char *) att_nominal_alignby(p, iterator->typalignby);
}
}
ArrayCastAndSet(Datum src,
int typlen,
bool typbyval,
- char typalign,
+ uint8 typalignby,
char *dest)
{
int inc;
store_att_byval(dest, src, typlen);
else
memmove(dest, DatumGetPointer(src), typlen);
- inc = att_align_nominal(typlen, typalign);
+ inc = att_nominal_alignby(typlen, typalignby);
}
else
{
Assert(!typbyval);
inc = att_addlength_datum(0, typlen, src);
memmove(dest, DatumGetPointer(src), inc);
- inc = att_align_nominal(inc, typalign);
+ inc = att_nominal_alignby(inc, typalignby);
}
return inc;
array_seek(char *ptr, int offset, bits8 *nullbitmap, int nitems,
int typlen, bool typbyval, char typalign)
{
+ uint8 typalignby = typalign_to_alignby(typalign);
int bitmask;
int i;
/* easy if fixed-size elements and no NULLs */
if (typlen > 0 && !nullbitmap)
- return ptr + nitems * ((Size) att_align_nominal(typlen, typalign));
+ return ptr + nitems * ((Size) att_nominal_alignby(typlen, typalignby));
/* seems worth having separate loops for NULL and no-NULLs cases */
if (nullbitmap)
if (*nullbitmap & bitmask)
{
ptr = att_addlength_pointer(ptr, typlen, ptr);
- ptr = (char *) att_align_nominal(ptr, typalign);
+ ptr = (char *) att_nominal_alignby(ptr, typalignby);
}
bitmask <<= 1;
if (bitmask == 0x100)
for (i = 0; i < nitems; i++)
{
ptr = att_addlength_pointer(ptr, typlen, ptr);
- ptr = (char *) att_align_nominal(ptr, typalign);
+ ptr = (char *) att_nominal_alignby(ptr, typalignby);
}
}
return ptr;
j,
inc;
int count = 0;
+ uint8 typalignby = typalign_to_alignby(typalign);
mda_get_range(ndim, span, st, endp);
/* Pretty easy for fixed element length without nulls ... */
if (typlen > 0 && !arraynullsptr)
- return ArrayGetNItems(ndim, span) * att_align_nominal(typlen, typalign);
+ return ArrayGetNItems(ndim, span) * att_nominal_alignby(typlen, typalignby);
/* Else gotta do it the hard way */
src_offset = ArrayGetOffset(ndim, dim, lb, st);
if (!array_get_isnull(arraynullsptr, src_offset))
{
inc = att_addlength_pointer(0, typlen, ptr);
- inc = att_align_nominal(inc, typalign);
+ inc = att_nominal_alignby(inc, typalignby);
ptr += inc;
count += inc;
}
int16 elmlen;
bool elmbyval;
char elmalign;
+ uint8 elmalignby;
ArrayMetaState *my_extra;
/*
elmlen = my_extra->typlen;
elmbyval = my_extra->typbyval;
elmalign = my_extra->typalign;
+ elmalignby = typalign_to_alignby(elmalign);
/* compute required space */
if (!isnull)
value = PointerGetDatum(PG_DETOAST_DATUM(value));
nbytes = att_addlength_datum(0, elmlen, value);
- nbytes = att_align_nominal(nbytes, elmalign);
+ nbytes = att_nominal_alignby(nbytes, elmalignby);
Assert(nbytes > 0);
totbytes = nbytes * nitems;
p = ARR_DATA_PTR(result);
for (i = 0; i < nitems; i++)
- p += ArrayCastAndSet(value, elmlen, elmbyval, elmalign, p);
+ p += ArrayCastAndSet(value, elmlen, elmbyval, elmalignby, p);
}
else
{
array_iter iter;
int nextelem;
int numelems;
- int16 elmlen;
- bool elmbyval;
- char elmalign;
} array_unnest_fctx;
FuncCallContext *funcctx;
if (SRF_IS_FIRSTCALL())
{
AnyArrayType *arr;
+ int16 elmlen;
+ bool elmbyval;
+ char elmalign;
/* create a function context for cross-call persistence */
funcctx = SRF_FIRSTCALL_INIT();
/* allocate memory for user context */
fctx = palloc_object(array_unnest_fctx);
- /* initialize state */
- array_iter_setup(&fctx->iter, arr);
- fctx->nextelem = 0;
- fctx->numelems = ArrayGetNItems(AARR_NDIM(arr), AARR_DIMS(arr));
-
+ /* get element-type data */
if (VARATT_IS_EXPANDED_HEADER(arr))
{
/* we can just grab the type data from expanded array */
- fctx->elmlen = arr->xpn.typlen;
- fctx->elmbyval = arr->xpn.typbyval;
- fctx->elmalign = arr->xpn.typalign;
+ elmlen = arr->xpn.typlen;
+ elmbyval = arr->xpn.typbyval;
+ elmalign = arr->xpn.typalign;
}
else
get_typlenbyvalalign(AARR_ELEMTYPE(arr),
- &fctx->elmlen,
- &fctx->elmbyval,
- &fctx->elmalign);
+ &elmlen,
+ &elmbyval,
+ &elmalign);
+
+ /* initialize state */
+ array_iter_setup(&fctx->iter, arr, elmlen, elmbyval, elmalign);
+ fctx->nextelem = 0;
+ fctx->numelems = ArrayGetNItems(AARR_NDIM(arr), AARR_DIMS(arr));
funcctx->user_fctx = fctx;
MemoryContextSwitchTo(oldcontext);
int offset = fctx->nextelem++;
Datum elem;
- elem = array_iter_next(&fctx->iter, &fcinfo->isnull, offset,
- fctx->elmlen, fctx->elmbyval, fctx->elmalign);
+ elem = array_iter_next(&fctx->iter, &fcinfo->isnull, offset);
SRF_RETURN_NEXT(funcctx, elem);
}
int typlen;
bool typbyval;
char typalign;
+ uint8 typalignby;
char *arraydataptr;
bits8 *bitmap;
int bitmask;
typlen = typentry->typlen;
typbyval = typentry->typbyval;
typalign = typentry->typalign;
+ typalignby = typalign_to_alignby(typalign);
/*
* Detoast values if they are toasted. The replacement value must be
isNull = false;
elt = fetch_att(arraydataptr, typbyval, typlen);
arraydataptr = att_addlength_datum(arraydataptr, typlen, elt);
- arraydataptr = (char *) att_align_nominal(arraydataptr, typalign);
+ arraydataptr = (char *) att_nominal_alignby(arraydataptr, typalignby);
if (search_isnull)
{
{
/* Update total result size */
nbytes = att_addlength_datum(nbytes, typlen, values[nresult]);
- nbytes = att_align_nominal(nbytes, typalign);
+ nbytes = att_nominal_alignby(nbytes, typalignby);
/* check for overflow of total request */
if (!AllocSizeIsValid(nbytes))
ereport(ERROR,
int typlen = typentry->typlen;
bool typbyval = typentry->typbyval;
char typalign = typentry->typalign;
+ uint8 typalignby = typalign_to_alignby(typalign);
int left;
int right;
for (i = left; i < mid; i++)
{
ptr = att_addlength_pointer(ptr, typlen, ptr);
- ptr = (char *) att_align_nominal(ptr, typalign);
+ ptr = (char *) att_nominal_alignby(ptr, typalignby);
}
locfcinfo->args[0].value = operand;
* ensures we do only O(N) array indexing work, not O(N^2).
*/
ptr = att_addlength_pointer(ptr, typlen, ptr);
- thresholds_data = (char *) att_align_nominal(ptr, typalign);
+ thresholds_data = (char *) att_nominal_alignby(ptr, typalignby);
}
}