diff --git a/doc/src/sgml/spgist.sgml b/doc/src/sgml/spgist.sgml
new file mode 100644
index 139c8ed..bae5714
*** a/doc/src/sgml/spgist.sgml
--- b/doc/src/sgml/spgist.sgml
***************
*** 240,259 ****
  
   <para>
    There are five user-defined methods that an index operator class for
!   <acronym>SP-GiST</acronym> must provide.  All five follow the convention
!   of accepting two <type>internal</type> arguments, the first of which is a
!   pointer to a C struct containing input values for the support method,
!   while the second argument is a pointer to a C struct where output values
!   must be placed.  Four of the methods just return <type>void</type>, since
!   all their results appear in the output struct; but
    <function>leaf_consistent</function> additionally returns a <type>boolean</type> result.
    The methods must not modify any fields of their input structs.  In all
    cases, the output struct is initialized to zeroes before calling the
!   user-defined method.
   </para>
  
   <para>
!   The five user-defined methods are:
   </para>
  
   <variablelist>
--- 240,261 ----
  
   <para>
    There are five user-defined methods that an index operator class for
!   <acronym>SP-GiST</acronym> must provide, and one is optional.  All five
!   mandatory methods follow the convention of accepting two <type>internal</type>
!   arguments, the first of which is a pointer to a C struct containing input
!   values for the support method, while the second argument is a pointer to a
!   C struct where output values must be placed.  Four of the mandatory methods just
!   return <type>void</type>, since all their results appear in the output struct; but
    <function>leaf_consistent</function> additionally returns a <type>boolean</type> result.
    The methods must not modify any fields of their input structs.  In all
    cases, the output struct is initialized to zeroes before calling the
!   user-defined method.  Optional sixth method <function>compress</function>
!   accepts datum to be indexed as the only argument and returns value suitable
!   for physical storage in leaf tuple.
   </para>
  
   <para>
!   The five mandatory user-defined methods are:
   </para>
  
   <variablelist>
*************** typedef struct spgConfigOut
*** 283,288 ****
--- 285,291 ----
  {
      Oid         prefixType;     /* Data type of inner-tuple prefixes */
      Oid         labelType;      /* Data type of inner-tuple node labels */
+     Oid         leafType;       /* Data type of leaf-tuple values */
      bool        canReturnData;  /* Opclass can reconstruct original data */
      bool        longValuesOK;   /* Opclass can cope with values &gt; 1 page */
  } spgConfigOut;
*************** typedef struct spgConfigOut
*** 305,310 ****
--- 308,329 ----
        class is capable of segmenting long values by repeated suffixing
        (see <xref linkend="spgist-limits"/>).
       </para>
+ 
+      <para>
+       <structfield>leafType</structfield> is typically the same as
+       <structfield>attType</structfield>.  For the reasons of backward
+       compatibility, method <function>config</function> can
+       leave <structfield>leafType</structfield> uninitialized; that would
+       give the same effect as setting <structfield>leafType</structfield> equal
+       to <structfield>attType</structfield>.  When <structfield>attType</structfield>
+       and <structfield>leafType</structfield> are different, then optional
+       method <function>compress</function> must be provided.
+       Method <function>compress</function> is responsible
+       for transformation of datums to be indexed from <structfield>attType</structfield>
+       to <structfield>leafType</structfield>.
+       Note: both consistent functions will get <structfield>scankeys</structfield>
+       unchanged, without transformation using <function>compress</function>.
+      </para>
       </listitem>
      </varlistentry>
  
*************** typedef struct spgChooseOut
*** 380,389 ****
  } spgChooseOut;
  </programlisting>
  
!        <structfield>datum</structfield> is the original datum that was to be inserted
!        into the index.
!        <structfield>leafDatum</structfield> is initially the same as
!        <structfield>datum</structfield>, but can change at lower levels of the tree
         if the <function>choose</function> or <function>picksplit</function>
         methods change it.  When the insertion search reaches a leaf page,
         the current value of <structfield>leafDatum</structfield> is what will be stored
--- 399,414 ----
  } spgChooseOut;
  </programlisting>
  
!        <structfield>datum</structfield> is the original datum of
!        <structname>spgConfigIn</structname>.<structfield>attType</structfield>
!        type that was to be inserted into the index.
!        <structfield>leafDatum</structfield> is a value of
!        <structname>spgConfigOut</structname>.<structfield>leafType</structfield>
!        type which is initially an result of method
!        <function>compress</function> applied to <structfield>datum</structfield>
!        when method <function>compress</function> is provided, or same value as
!        <structfield>datum</structfield> otherwise.
!        <structfield>leafDatum</structfield> can change at lower levels of the tree
         if the <function>choose</function> or <function>picksplit</function>
         methods change it.  When the insertion search reaches a leaf page,
         the current value of <structfield>leafDatum</structfield> is what will be stored
*************** typedef struct spgChooseOut
*** 418,424 ****
         Set <structfield>levelAdd</structfield> to the increment in
         <structfield>level</structfield> caused by descending through that node,
         or leave it as zero if the operator class does not use levels.
!        Set <structfield>restDatum</structfield> to equal <structfield>datum</structfield>
         if the operator class does not modify datums from one level to the
         next, or otherwise set it to the modified value to be used as
         <structfield>leafDatum</structfield> at the next level.
--- 443,449 ----
         Set <structfield>levelAdd</structfield> to the increment in
         <structfield>level</structfield> caused by descending through that node,
         or leave it as zero if the operator class does not use levels.
!        Set <structfield>restDatum</structfield> to equal <structfield>leafDatum</structfield>
         if the operator class does not modify datums from one level to the
         next, or otherwise set it to the modified value to be used as
         <structfield>leafDatum</structfield> at the next level.
*************** typedef struct spgPickSplitOut
*** 509,515 ****
  </programlisting>
  
         <structfield>nTuples</structfield> is the number of leaf tuples provided.
!        <structfield>datums</structfield> is an array of their datum values.
         <structfield>level</structfield> is the current level that all the leaf tuples
         share, which will become the level of the new inner tuple.
        </para>
--- 534,542 ----
  </programlisting>
  
         <structfield>nTuples</structfield> is the number of leaf tuples provided.
!        <structfield>datums</structfield> is an array of their datum values of
!        <structname>spgConfigOut</structname>.<structfield>leafType</structfield>
!        type.
         <structfield>level</structfield> is the current level that all the leaf tuples
         share, which will become the level of the new inner tuple.
        </para>
*************** typedef struct spgInnerConsistentOut
*** 624,630 ****
         <structfield>reconstructedValue</structfield> is the value reconstructed for the
         parent tuple; it is <literal>(Datum) 0</literal> at the root level or if the
         <function>inner_consistent</function> function did not provide a value at the
!        parent level.
         <structfield>traversalValue</structfield> is a pointer to any traverse data
         passed down from the previous call of <function>inner_consistent</function>
         on the parent index tuple, or NULL at the root level.
--- 651,658 ----
         <structfield>reconstructedValue</structfield> is the value reconstructed for the
         parent tuple; it is <literal>(Datum) 0</literal> at the root level or if the
         <function>inner_consistent</function> function did not provide a value at the
!        parent level. <structfield>reconstructedValue</structfield> is always of
!        <structname>spgConfigIn</structname>.<structfield>attType</structfield> type.
         <structfield>traversalValue</structfield> is a pointer to any traverse data
         passed down from the previous call of <function>inner_consistent</function>
         on the parent index tuple, or NULL at the root level.
*************** typedef struct spgInnerConsistentOut
*** 659,664 ****
--- 687,693 ----
         necessarily so, so an array is used.)
         If value reconstruction is needed, set
         <structfield>reconstructedValues</structfield> to an array of the values
+        of <structname>spgConfigIn</structname>.<structfield>attType</structfield> type
         reconstructed for each child node to be visited; otherwise, leave
         <structfield>reconstructedValues</structfield> as NULL.
         If it is desired to pass down additional out-of-band information
*************** typedef struct spgLeafConsistentOut
*** 730,736 ****
         <structfield>reconstructedValue</structfield> is the value reconstructed for the
         parent tuple; it is <literal>(Datum) 0</literal> at the root level or if the
         <function>inner_consistent</function> function did not provide a value at the
!        parent level.
         <structfield>traversalValue</structfield> is a pointer to any traverse data
         passed down from the previous call of <function>inner_consistent</function>
         on the parent index tuple, or NULL at the root level.
--- 759,766 ----
         <structfield>reconstructedValue</structfield> is the value reconstructed for the
         parent tuple; it is <literal>(Datum) 0</literal> at the root level or if the
         <function>inner_consistent</function> function did not provide a value at the
!        parent level. <structfield>reconstructedValue</structfield> is always of
!        <structname>spgConfigIn</structname>.<structfield>attType</structfield> type. 
         <structfield>traversalValue</structfield> is a pointer to any traverse data
         passed down from the previous call of <function>inner_consistent</function>
         on the parent index tuple, or NULL at the root level.
*************** typedef struct spgLeafConsistentOut
*** 739,754 ****
         <structfield>returnData</structfield> is <literal>true</literal> if reconstructed data is
         required for this query; this will only be so if the
         <function>config</function> function asserted <structfield>canReturnData</structfield>.
!        <structfield>leafDatum</structfield> is the key value stored in the current
!        leaf tuple.
        </para>
  
        <para>
         The function must return <literal>true</literal> if the leaf tuple matches the
         query, or <literal>false</literal> if not.  In the <literal>true</literal> case,
         if <structfield>returnData</structfield> is <literal>true</literal> then
!        <structfield>leafValue</structfield> must be set to the value originally supplied
!        to be indexed for this leaf tuple.  Also,
         <structfield>recheck</structfield> may be set to <literal>true</literal> if the match
         is uncertain and so the operator(s) must be re-applied to the actual
         heap tuple to verify the match.
--- 769,786 ----
         <structfield>returnData</structfield> is <literal>true</literal> if reconstructed data is
         required for this query; this will only be so if the
         <function>config</function> function asserted <structfield>canReturnData</structfield>.
!        <structfield>leafDatum</structfield> is the key value of
!        <structname>spgConfigOut</structname>.<structfield>leafType</structfield>
!        stored in the current leaf tuple.
        </para>
  
        <para>
         The function must return <literal>true</literal> if the leaf tuple matches the
         query, or <literal>false</literal> if not.  In the <literal>true</literal> case,
         if <structfield>returnData</structfield> is <literal>true</literal> then
!        <structfield>leafValue</structfield> must be set to the value of
!        <structname>spgConfigIn</structname>.<structfield>attType</structfield> type
!        originally supplied to be indexed for this leaf tuple.  Also,
         <structfield>recheck</structfield> may be set to <literal>true</literal> if the match
         is uncertain and so the operator(s) must be re-applied to the actual
         heap tuple to verify the match.
*************** typedef struct spgLeafConsistentOut
*** 757,762 ****
--- 789,814 ----
      </varlistentry>
     </variablelist>
  
+  <para>
+   The optional user-defined method is:
+  </para>
+ 
+  <variablelist>
+     <varlistentry>
+      <term><function>Datum compress(Datum in)</function></term>
+      <listitem>
+       <para>
+        Converts the data item into a format suitable for physical storage in 
+        a leaf tuple of index page.  It accepts
+        <structname>spgConfigIn</structname>.<structfield>attType</structfield>
+        value and return
+        <structname>spgConfigOut</structname>.<structfield>leafType</structfield>
+        value.  Output value should not be toasted.
+       </para>
+      </listitem>
+     </varlistentry>
+   </variablelist>
+ 
    <para>
     All the SP-GiST support methods are normally called in a short-lived
     memory context; that is, <varname>CurrentMemoryContext</varname> will be reset
diff --git a/src/backend/access/spgist/spgdoinsert.c b/src/backend/access/spgist/spgdoinsert.c
new file mode 100644
index a5f4c40..a8cb8c7
*** a/src/backend/access/spgist/spgdoinsert.c
--- b/src/backend/access/spgist/spgdoinsert.c
*************** spgdoinsert(Relation index, SpGistState 
*** 1906,1919 ****
  		procinfo = index_getprocinfo(index, 1, SPGIST_CHOOSE_PROC);
  
  	/*
! 	 * Since we don't use index_form_tuple in this AM, we have to make sure
  	 * value to be inserted is not toasted; FormIndexDatum doesn't guarantee
! 	 * that.
  	 */
! 	if (!isnull && state->attType.attlen == -1)
! 		datum = PointerGetDatum(PG_DETOAST_DATUM(datum));
  
! 	leafDatum = datum;
  
  	/*
  	 * Compute space needed for a leaf tuple containing the given datum.
--- 1906,1942 ----
  		procinfo = index_getprocinfo(index, 1, SPGIST_CHOOSE_PROC);
  
  	/*
! 	 * Prepare the leaf datum to insert.
! 	 *
! 	 * If an optional "compress" method is provided, then call it to form
! 	 * the leaf datum from the input datum.  Otherwise store the input datum as
! 	 * is.  Since we don't use index_form_tuple in this AM, we have to make sure
  	 * value to be inserted is not toasted; FormIndexDatum doesn't guarantee
! 	 * that.  But we assume the "compress" method to return an untoasted value.
  	 */
! 	if (!isnull)
! 	{
! 		if (OidIsValid(index_getprocid(index, 1, SPGIST_COMPRESS_PROC)))
! 		{
! 			FmgrInfo   *compressProcinfo = NULL;
  
! 			compressProcinfo = index_getprocinfo(index, 1, SPGIST_COMPRESS_PROC);
! 			leafDatum = FunctionCall1Coll(compressProcinfo,
! 										  index->rd_indcollation[0],
! 										  datum);
! 		}
! 		else
! 		{
! 			Assert(state->attLeafType.type == state->attType.type);
! 
! 			if (state->attType.attlen == -1)
! 				leafDatum = PointerGetDatum(PG_DETOAST_DATUM(datum));
! 			else
! 				leafDatum = datum;
! 		}
! 	}
! 	else
! 		leafDatum = (Datum) 0;
  
  	/*
  	 * Compute space needed for a leaf tuple containing the given datum.
*************** spgdoinsert(Relation index, SpGistState 
*** 1923,1929 ****
  	 */
  	if (!isnull)
  		leafSize = SGLTHDRSZ + sizeof(ItemIdData) +
! 			SpGistGetTypeSize(&state->attType, leafDatum);
  	else
  		leafSize = SGDTSIZE + sizeof(ItemIdData);
  
--- 1946,1952 ----
  	 */
  	if (!isnull)
  		leafSize = SGLTHDRSZ + sizeof(ItemIdData) +
! 			SpGistGetTypeSize(&state->attLeafType, leafDatum);
  	else
  		leafSize = SGDTSIZE + sizeof(ItemIdData);
  
*************** spgdoinsert(Relation index, SpGistState 
*** 2138,2144 ****
  					{
  						leafDatum = out.result.matchNode.restDatum;
  						leafSize = SGLTHDRSZ + sizeof(ItemIdData) +
! 							SpGistGetTypeSize(&state->attType, leafDatum);
  					}
  
  					/*
--- 2161,2167 ----
  					{
  						leafDatum = out.result.matchNode.restDatum;
  						leafSize = SGLTHDRSZ + sizeof(ItemIdData) +
! 							SpGistGetTypeSize(&state->attLeafType, leafDatum);
  					}
  
  					/*
diff --git a/src/backend/access/spgist/spgutils.c b/src/backend/access/spgist/spgutils.c
new file mode 100644
index bd5301f..668e3c4
*** a/src/backend/access/spgist/spgutils.c
--- b/src/backend/access/spgist/spgutils.c
*************** spgGetCache(Relation index)
*** 124,130 ****
  						  PointerGetDatum(&cache->config));
  
  		/* Get the information we need about each relevant datatype */
! 		fillTypeDesc(&cache->attType, atttype);
  		fillTypeDesc(&cache->attPrefixType, cache->config.prefixType);
  		fillTypeDesc(&cache->attLabelType, cache->config.labelType);
  
--- 124,146 ----
  						  PointerGetDatum(&cache->config));
  
  		/* Get the information we need about each relevant datatype */
! 		if (OidIsValid(cache->config.leafType) &&
! 			cache->config.leafType != atttype)
! 		{
! 			if (!OidIsValid(index_getprocid(index, 1, SPGIST_COMPRESS_PROC)))
! 				ereport(ERROR,
! 						(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
! 						 errmsg("compress method must not defined when leaf type is different from input type")));
! 
! 			fillTypeDesc(&cache->attType, atttype);
! 			fillTypeDesc(&cache->attLeafType, cache->config.leafType);
! 		}
! 		else
! 		{
! 			fillTypeDesc(&cache->attType, atttype);
! 			cache->attLeafType = cache->attType;
! 		}
! 
  		fillTypeDesc(&cache->attPrefixType, cache->config.prefixType);
  		fillTypeDesc(&cache->attLabelType, cache->config.labelType);
  
*************** initSpGistState(SpGistState *state, Rela
*** 164,169 ****
--- 180,186 ----
  
  	state->config = cache->config;
  	state->attType = cache->attType;
+ 	state->attLeafType = cache->attLeafType;
  	state->attPrefixType = cache->attPrefixType;
  	state->attLabelType = cache->attLabelType;
  
*************** spgFormLeafTuple(SpGistState *state, Ite
*** 618,624 ****
  	/* compute space needed (note result is already maxaligned) */
  	size = SGLTHDRSZ;
  	if (!isnull)
! 		size += SpGistGetTypeSize(&state->attType, datum);
  
  	/*
  	 * Ensure that we can replace the tuple with a dead tuple later.  This
--- 635,641 ----
  	/* compute space needed (note result is already maxaligned) */
  	size = SGLTHDRSZ;
  	if (!isnull)
! 		size += SpGistGetTypeSize(&state->attLeafType, datum);
  
  	/*
  	 * Ensure that we can replace the tuple with a dead tuple later.  This
*************** spgFormLeafTuple(SpGistState *state, Ite
*** 634,640 ****
  	tup->nextOffset = InvalidOffsetNumber;
  	tup->heapPtr = *heapPtr;
  	if (!isnull)
! 		memcpyDatum(SGLTDATAPTR(tup), &state->attType, datum);
  
  	return tup;
  }
--- 651,657 ----
  	tup->nextOffset = InvalidOffsetNumber;
  	tup->heapPtr = *heapPtr;
  	if (!isnull)
! 		memcpyDatum(SGLTDATAPTR(tup), &state->attLeafType, datum);
  
  	return tup;
  }
diff --git a/src/backend/access/spgist/spgvalidate.c b/src/backend/access/spgist/spgvalidate.c
new file mode 100644
index 157cf2a..514da47
*** a/src/backend/access/spgist/spgvalidate.c
--- b/src/backend/access/spgist/spgvalidate.c
*************** spgvalidate(Oid opclassoid)
*** 52,57 ****
--- 52,61 ----
  	OpFamilyOpFuncGroup *opclassgroup;
  	int			i;
  	ListCell   *lc;
+ 	spgConfigIn	configIn;
+ 	spgConfigOut configOut;
+ 	Oid			configOutLefttype = InvalidOid;
+ 	Oid			configOutRighttype = InvalidOid;
  
  	/* Fetch opclass information */
  	classtup = SearchSysCache1(CLAOID, ObjectIdGetDatum(opclassoid));
*************** spgvalidate(Oid opclassoid)
*** 100,105 ****
--- 104,118 ----
  		switch (procform->amprocnum)
  		{
  			case SPGIST_CONFIG_PROC:
+ 				ok = check_amproc_signature(procform->amproc, VOIDOID, true,
+ 											2, 2, INTERNALOID, INTERNALOID);
+ 				configIn.attType = procform->amproclefttype;
+ 				OidFunctionCall2(procform->amproc,
+ 								 PointerGetDatum(&configIn),
+ 								 PointerGetDatum(&configOut));
+ 				configOutLefttype = procform->amproclefttype;
+ 				configOutRighttype = procform->amprocrighttype;
+ 				break;
  			case SPGIST_CHOOSE_PROC:
  			case SPGIST_PICKSPLIT_PROC:
  			case SPGIST_INNER_CONSISTENT_PROC:
*************** spgvalidate(Oid opclassoid)
*** 110,115 ****
--- 123,137 ----
  				ok = check_amproc_signature(procform->amproc, BOOLOID, true,
  											2, 2, INTERNALOID, INTERNALOID);
  				break;
+ 			case SPGIST_COMPRESS_PROC:
+ 				if (configOutLefttype != procform->amproclefttype ||
+ 					configOutRighttype != procform->amprocrighttype)
+ 					ok = false;
+ 				else
+ 					ok = check_amproc_signature(procform->amproc,
+ 												configOut.leafType, true,
+ 												1, 1, procform->amproclefttype);
+ 				break;
  			default:
  				ereport(INFO,
  						(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
*************** spgvalidate(Oid opclassoid)
*** 212,218 ****
  		if (thisgroup->lefttype != thisgroup->righttype)
  			continue;
  
! 		for (i = 1; i <= SPGISTNProc; i++)
  		{
  			if ((thisgroup->functionset & (((uint64) 1) << i)) != 0)
  				continue;		/* got it */
--- 234,240 ----
  		if (thisgroup->lefttype != thisgroup->righttype)
  			continue;
  
! 		for (i = 1; i <= SPGISTNRequiredProc; i++)
  		{
  			if ((thisgroup->functionset & (((uint64) 1) << i)) != 0)
  				continue;		/* got it */
diff --git a/src/include/access/spgist.h b/src/include/access/spgist.h
new file mode 100644
index d1bc396..06b1d88
*** a/src/include/access/spgist.h
--- b/src/include/access/spgist.h
***************
*** 30,36 ****
  #define SPGIST_PICKSPLIT_PROC			3
  #define SPGIST_INNER_CONSISTENT_PROC	4
  #define SPGIST_LEAF_CONSISTENT_PROC		5
! #define SPGISTNProc						5
  
  /*
   * Argument structs for spg_config method
--- 30,38 ----
  #define SPGIST_PICKSPLIT_PROC			3
  #define SPGIST_INNER_CONSISTENT_PROC	4
  #define SPGIST_LEAF_CONSISTENT_PROC		5
! #define SPGIST_COMPRESS_PROC			6
! #define SPGISTNRequiredProc				5
! #define SPGISTNProc						6
  
  /*
   * Argument structs for spg_config method
*************** typedef struct spgConfigOut
*** 44,49 ****
--- 46,52 ----
  {
  	Oid			prefixType;		/* Data type of inner-tuple prefixes */
  	Oid			labelType;		/* Data type of inner-tuple node labels */
+ 	Oid			leafType;		/* Data type of leaf-tuple values */
  	bool		canReturnData;	/* Opclass can reconstruct original data */
  	bool		longValuesOK;	/* Opclass can cope with values > 1 page */
  } spgConfigOut;
diff --git a/src/include/access/spgist_private.h b/src/include/access/spgist_private.h
new file mode 100644
index 1c4b321..e55de9d
*** a/src/include/access/spgist_private.h
--- b/src/include/access/spgist_private.h
*************** typedef struct SpGistState
*** 119,125 ****
  {
  	spgConfigOut config;		/* filled in by opclass config method */
  
! 	SpGistTypeDesc attType;		/* type of input data and leaf values */
  	SpGistTypeDesc attPrefixType;	/* type of inner-tuple prefix values */
  	SpGistTypeDesc attLabelType;	/* type of node label values */
  
--- 119,126 ----
  {
  	spgConfigOut config;		/* filled in by opclass config method */
  
! 	SpGistTypeDesc attType;		/* type of values to be indexed/restored */
! 	SpGistTypeDesc attLeafType;		/* type of leaf-tuple values */
  	SpGistTypeDesc attPrefixType;	/* type of inner-tuple prefix values */
  	SpGistTypeDesc attLabelType;	/* type of node label values */
  
*************** typedef struct SpGistCache
*** 178,184 ****
  {
  	spgConfigOut config;		/* filled in by opclass config method */
  
! 	SpGistTypeDesc attType;		/* type of input data and leaf values */
  	SpGistTypeDesc attPrefixType;	/* type of inner-tuple prefix values */
  	SpGistTypeDesc attLabelType;	/* type of node label values */
  
--- 179,186 ----
  {
  	spgConfigOut config;		/* filled in by opclass config method */
  
! 	SpGistTypeDesc attType;		/* type of values to be indexed/restored */
! 	SpGistTypeDesc attLeafType;		/* type of leaf-tuple values */
  	SpGistTypeDesc attPrefixType;	/* type of inner-tuple prefix values */
  	SpGistTypeDesc attLabelType;	/* type of node label values */
  
*************** typedef SpGistLeafTupleData *SpGistLeafT
*** 300,306 ****
  
  #define SGLTHDRSZ			MAXALIGN(sizeof(SpGistLeafTupleData))
  #define SGLTDATAPTR(x)		(((char *) (x)) + SGLTHDRSZ)
! #define SGLTDATUM(x, s)		((s)->attType.attbyval ? \
  							 *(Datum *) SGLTDATAPTR(x) : \
  							 PointerGetDatum(SGLTDATAPTR(x)))
  
--- 302,308 ----
  
  #define SGLTHDRSZ			MAXALIGN(sizeof(SpGistLeafTupleData))
  #define SGLTDATAPTR(x)		(((char *) (x)) + SGLTHDRSZ)
! #define SGLTDATUM(x, s)		((s)->attLeafType.attbyval ? \
  							 *(Datum *) SGLTDATAPTR(x) : \
  							 PointerGetDatum(SGLTDATAPTR(x)))
  
