diff --git a/doc/src/sgml/spgist.sgml b/doc/src/sgml/spgist.sgml
index 56827e520d..0d44d064aa 100644
--- a/doc/src/sgml/spgist.sgml
+++ b/doc/src/sgml/spgist.sgml
@@ -542,6 +542,8 @@ typedef struct spgInnerConsistentIn
     int         nkeys;          /* length of array */
 
     Datum       reconstructedValue;     /* value reconstructed at parent */
+    void       *traversalValue; /* opclass-specific traverse value */
+    MemoryContext traversalMemoryContext;
     int         level;          /* current level (counting from zero) */
     bool        returnData;     /* original data must be returned? */
 
@@ -559,6 +561,8 @@ typedef struct spgInnerConsistentOut
     int        *nodeNumbers;    /* their indexes in the node array */
     int        *levelAdds;      /* increment level by this much for each */
     Datum      *reconstructedValues;    /* associated reconstructed values */
+    void      **traversalValues;        /* opclass-specific traverse values */
+
 } spgInnerConsistentOut;
 </programlisting>
 
@@ -593,6 +597,9 @@ typedef struct spgInnerConsistentOut
        inner tuple, and
        <structfield>nodeLabels</> is an array of their label values, or
        NULL if the nodes do not have labels.
+       <structfield>traversalValue</> is a pointer to data that
+       <function>inner_consistent</> gets when called on child nodes from an
+       outer call of <function>inner_consistent</> on parent nodes.
       </para>
 
       <para>
@@ -612,6 +619,13 @@ typedef struct spgInnerConsistentOut
        responsible for palloc'ing the
        <structfield>nodeNumbers</>, <structfield>levelAdds</> and
        <structfield>reconstructedValues</> arrays.
+       Sometimes accumulating some information is needed, while 
+       descending from parent to child node was happened. In this case
+       <structfield>traversalValues</> array keeps pointers to
+       specific data you need to accumulate for every child node.
+       Memory for <structfield>traversalValues</> should be allocated in
+       the default context, but each element of it should be allocated in
+       <structfield>traversalMemoryContext</>.
       </para>
      </listitem>
     </varlistentry>
@@ -638,6 +652,7 @@ typedef struct spgLeafConsistentIn
     ScanKey     scankeys;       /* array of operators and comparison values */
     int         nkeys;          /* length of array */
 
+    void       *traversalValue; /* opclass-specific traverse value */
     Datum       reconstructedValue;     /* value reconstructed at parent */
     int         level;          /* current level (counting from zero) */
     bool        returnData;     /* original data must be returned? */
diff --git a/src/backend/access/spgist/spgscan.c b/src/backend/access/spgist/spgscan.c
index 620e746199..8aa28ecbc3 100644
--- a/src/backend/access/spgist/spgscan.c
+++ b/src/backend/access/spgist/spgscan.c
@@ -30,6 +30,7 @@ typedef void (*storeRes_func) (SpGistScanOpaque so, ItemPointer heapPtr,
 typedef struct ScanStackEntry
 {
 	Datum		reconstructedValue;		/* value reconstructed from parent */
+	void	   *traversalValue; /* opclass-specific traverse value */
 	int			level;			/* level of items on this page */
 	ItemPointerData ptr;		/* block and offset to scan from */
 } ScanStackEntry;
@@ -42,6 +43,9 @@ freeScanStackEntry(SpGistScanOpaque so, ScanStackEntry *stackEntry)
 	if (!so->state.attType.attbyval &&
 		DatumGetPointer(stackEntry->reconstructedValue) != NULL)
 		pfree(DatumGetPointer(stackEntry->reconstructedValue));
+	if (stackEntry->traversalValue)
+		pfree(stackEntry->traversalValue);
+
 	pfree(stackEntry);
 }
 
@@ -239,6 +243,7 @@ static bool
 spgLeafTest(Relation index, SpGistScanOpaque so,
 			SpGistLeafTuple leafTuple, bool isnull,
 			int level, Datum reconstructedValue,
+			void *traversalValue,
 			Datum *leafValue, bool *recheck)
 {
 	bool		result;
@@ -265,6 +270,7 @@ spgLeafTest(Relation index, SpGistScanOpaque so,
 	in.scankeys = so->keyData;
 	in.nkeys = so->numberOfKeys;
 	in.reconstructedValue = reconstructedValue;
+	in.traversalValue = traversalValue;
 	in.level = level;
 	in.returnData = so->want_itup;
 	in.leafDatum = leafDatum;
@@ -365,6 +371,7 @@ redirect:
 									leafTuple, isnull,
 									stackEntry->level,
 									stackEntry->reconstructedValue,
+									stackEntry->traversalValue,
 									&leafValue,
 									&recheck))
 					{
@@ -411,6 +418,7 @@ redirect:
 									leafTuple, isnull,
 									stackEntry->level,
 									stackEntry->reconstructedValue,
+									stackEntry->traversalValue,
 									&leafValue,
 									&recheck))
 					{
@@ -456,6 +464,8 @@ redirect:
 			in.scankeys = so->keyData;
 			in.nkeys = so->numberOfKeys;
 			in.reconstructedValue = stackEntry->reconstructedValue;
+			in.traversalMemoryContext = oldCtx;
+			in.traversalValue = stackEntry->traversalValue;
 			in.level = stackEntry->level;
 			in.returnData = so->want_itup;
 			in.allTheSame = innerTuple->allTheSame;
@@ -523,6 +533,14 @@ redirect:
 					else
 						newEntry->reconstructedValue = (Datum) 0;
 
+					/*
+					 * Elements of out.traversalValues should be allocated in
+					 * in.traversalMemoryContext, which is actually a long
+					 * lived context of index scan.
+					 */
+					newEntry->traversalValue = (out.traversalValues) ?
+						out.traversalValues[i] : NULL;
+
 					so->scanStack = lcons(newEntry, so->scanStack);
 				}
 			}
diff --git a/src/include/access/spgist.h b/src/include/access/spgist.h
index 1994f718eb..f39a2d6938 100644
--- a/src/include/access/spgist.h
+++ b/src/include/access/spgist.h
@@ -133,6 +133,8 @@ typedef struct spgInnerConsistentIn
 	int			nkeys;			/* length of array */
 
 	Datum		reconstructedValue;		/* value reconstructed at parent */
+	void	   *traversalValue; /* opclass-specific traverse value */
+	MemoryContext traversalMemoryContext;
 	int			level;			/* current level (counting from zero) */
 	bool		returnData;		/* original data must be returned? */
 
@@ -150,6 +152,7 @@ typedef struct spgInnerConsistentOut
 	int		   *nodeNumbers;	/* their indexes in the node array */
 	int		   *levelAdds;		/* increment level by this much for each */
 	Datum	   *reconstructedValues;	/* associated reconstructed values */
+	void	  **traversalValues;	/* opclass-specific traverse values */
 } spgInnerConsistentOut;
 
 /*
@@ -160,6 +163,7 @@ typedef struct spgLeafConsistentIn
 	ScanKey		scankeys;		/* array of operators and comparison values */
 	int			nkeys;			/* length of array */
 
+	void	   *traversalValue; /* opclass-specific traverse value */
 	Datum		reconstructedValue;		/* value reconstructed at parent */
 	int			level;			/* current level (counting from zero) */
 	bool		returnData;		/* original data must be returned? */