1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-07 00:36:50 +03:00

Although we can't support out-of-line TOAST storage in indexes (yet),

compressed storage works perfectly well.  Might as well have a coherent
strategy for applying it, rather than the haphazard store-what-you-get
approach that was in the code before.  The strategy I've set up here is
to attempt compression of any compressible index value exceeding
BLCKSZ/16, or about 500 bytes by default.
This commit is contained in:
Tom Lane
2001-02-15 20:57:01 +00:00
parent 5341cddba8
commit 059e361481
3 changed files with 54 additions and 22 deletions

View File

@ -2,14 +2,14 @@
*
* indextuple.c
* This file contains index tuple accessor and mutator routines,
* as well as a few various tuple utilities.
* as well as various tuple utilities.
*
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/common/indextuple.c,v 1.50 2001/01/24 19:42:47 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/access/common/indextuple.c,v 1.51 2001/02/15 20:57:01 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -57,25 +57,45 @@ index_formtuple(TupleDesc tupleDescriptor,
#ifdef TOAST_INDEX_HACK
for (i = 0; i < numberOfAttributes; i++)
{
if (null[i] != ' ' || tupleDescriptor->attrs[i]->attlen >= 0)
Form_pg_attribute att = tupleDescriptor->attrs[i];
untoasted_value[i] = value[i];
untoasted_free[i] = false;
/* Do nothing if value is NULL or not of varlena type */
if (null[i] != ' ' || att->attlen >= 0)
continue;
/*
* If value is stored EXTERNAL, must fetch it so we are not
* depending on outside storage. This should be improved someday.
*/
if (VARATT_IS_EXTERNAL(value[i]))
{
untoasted_value[i] = value[i];
untoasted_free[i] = false;
untoasted_value[i] = PointerGetDatum(
heap_tuple_fetch_attr(
(varattrib *) DatumGetPointer(value[i])));
untoasted_free[i] = true;
}
else
/*
* If value is above size target, and is of a compressible datatype,
* try to compress it in-line.
*/
if (VARATT_SIZE(untoasted_value[i]) > TOAST_INDEX_TARGET &&
!VARATT_IS_EXTENDED(untoasted_value[i]) &&
(att->attstorage == 'x' || att->attstorage == 'm'))
{
if (VARATT_IS_EXTERNAL(value[i]))
Datum cvalue = toast_compress_datum(untoasted_value[i]);
if (DatumGetPointer(cvalue) != NULL)
{
untoasted_value[i] = PointerGetDatum(
heap_tuple_fetch_attr(
(varattrib *)DatumGetPointer(value[i])));
/* successful compression */
if (untoasted_free[i])
pfree(DatumGetPointer(untoasted_value[i]));
untoasted_value[i] = cvalue;
untoasted_free[i] = true;
}
else
{
untoasted_value[i] = value[i];
untoasted_free[i] = false;
}
}
}
#endif
@ -137,10 +157,9 @@ index_formtuple(TupleDesc tupleDescriptor,
* Here we make sure that the size will fit in the field reserved for
* it in t_info.
*/
if ((size & INDEX_SIZE_MASK) != size)
elog(ERROR, "index_formtuple: data takes %lu bytes: too big",
(unsigned long)size);
elog(ERROR, "index_formtuple: data takes %lu bytes, max is %d",
(unsigned long) size, INDEX_SIZE_MASK);
infomask |= size;