/* ---------- * toast_compress_datum - * * Create a compressed version of a varlena datum * * If we fail (ie, compressed result is actually bigger than original) * then return NULL. We must not use compressed data if it'd expand * the tuple! * * We use VAR{SIZE,DATA}_ANY so we can handle short varlenas here without * copying them. But we can't handle external or compressed datums. * ---------- */ Datum toast_compress_datum(Datum value) { varattrib *tmp; int32 valsize = VARSIZE_ANY_EXHDR_D(value); Assert(!VARATT_IS_EXTERNAL(DatumGetPointer(value))); Assert(!VARATT_IS_COMPRESSED(DatumGetPointer(value))); /* * No point in wasting a palloc cycle if value size is out of the allowed * range for compression */ if (valsize < PGLZ_strategy_default->min_input_size || valsize > PGLZ_strategy_default->max_input_size) return PointerGetDatum(NULL); tmp = (varattrib *) palloc(PGLZ_MAX_OUTPUT(valsize)); if (pglz_compress(VARDATA_ANY_D(value), valsize, (PGLZ_Header *) tmp, PGLZ_strategy_default) && VARSIZE(tmp) < VARSIZE_ANY_D(value)) { /* successful compression */ VARATT_SET_COMPRESSED(tmp); return PointerGetDatum(tmp); } else { /* incompressible data */ pfree(tmp); return PointerGetDatum(NULL); } }
/* * heap_compute_data_size * Determine size of the data area of a tuple to be constructed */ Size heap_compute_data_size(TupleDesc tupleDesc, Datum *values, bool *isnull) { Size data_length = 0; int i; int numberOfAttributes = tupleDesc->natts; Form_pg_attribute *att = tupleDesc->attrs; for (i = 0; i < numberOfAttributes; i++) { if (isnull[i]) continue; /* we're anticipating converting to a short varlena header even if it's * not currently */ if (att[i]->attlen == -1 && value_type_could_short(values[i], att[i]->atttypid)) { /* no alignment and we will convert to 1-byte header */; data_length += VARSIZE_ANY_EXHDR_D(values[i]) + VARHDRSZ_SHORT; } else { data_length = att_align(data_length, att[i]->attalign); data_length = att_addlength(data_length, att[i]->attlen, values[i]); } } return data_length; }