*** a/src/backend/access/gist/gist.c
--- b/src/backend/access/gist/gist.c
***************
*** 1379,1384 **** initGISTstate(Relation index)
--- 1379,1395 ----
  		else
  			giststate->distanceFn[i].fn_oid = InvalidOid;
  
+ 		/* opclasses are not required to provide a Fetch method */
+ 			//elog(NOTICE, "Debug. gist.c amsupport = %d", index->rd_am->amsupport);
+ 		if (OidIsValid(index_getprocid(index, i + 1, GIST_FETCH_PROC))) {
+ 			//elog(NOTICE, "Debug. gist.c OidIsValid. i=%d fetch. rd_support(%d) = %d", i, GIST_FETCH_PROC, 													//index_getprocid(index, i + 1, GIST_FETCH_PROC));
+ 			fmgr_info_copy(&(giststate->fetchFn[i]),
+ 						 index_getprocinfo(index, i + 1, GIST_FETCH_PROC),
+ 						   scanCxt);
+ 		}
+ 		else
+ 			giststate->fetchFn[i].fn_oid = InvalidOid;
+ 
  		/*
  		 * If the index column has a specified collation, we should honor that
  		 * while doing comparisons.  However, we may have a collatable storage
***************
*** 1401,1406 **** initGISTstate(Relation index)
--- 1412,1433 ----
  	return giststate;
  }
  
+ Datum 
+ gistcanreturn(PG_FUNCTION_ARGS) {
+ 	Relation index = (Relation) PG_GETARG_POINTER(0);
+ 	int i = PG_GETARG_INT32(1);
+ 	
+ 	if (OidIsValid(index_getprocid(index, i+1, GIST_FETCH_PROC))) {
+ 		PG_RETURN_BOOL(true);
+ 	}
+ 	else {
+ 		//elog(NOTICE, " Debug. missing support function %d of index \"%s\"",
+ 		//			GIST_FETCH_PROC,
+ 		//			RelationGetRelationName(index));
+ 		 PG_RETURN_BOOL(false);
+ 	}
+ }
+ 
  void
  freeGISTstate(GISTSTATE *giststate)
  {
*** a/src/backend/access/gist/gistget.c
--- b/src/backend/access/gist/gistget.c
***************
*** 240,245 **** gistScanPage(IndexScanDesc scan, GISTSearchItem *pageItem, double *myDistances,
--- 240,249 ----
  	GISTScanOpaque so = (GISTScanOpaque) scan->opaque;
  	Buffer		buffer;
  	Page		page;
+ 	GISTSTATE *giststate = so->giststate; 
+ 	Relation r = scan->indexRelation;
+ 	bool        isnull[INDEX_MAX_KEYS];
+ 	GISTSearchHeapItem *tmpListItem;
  	GISTPageOpaque opaque;
  	OffsetNumber maxoff;
  	OffsetNumber i;
***************
*** 288,297 **** gistScanPage(IndexScanDesc scan, GISTSearchItem *pageItem, double *myDistances,
  
  		(void) rb_insert(so->queue, (RBNode *) tmpItem, &isNew);
  
  		MemoryContextSwitchTo(oldcxt);
  	}
  
! 	so->nPageData = so->curPageData = 0;
  
  	/*
  	 * check all tuples on page
--- 292,303 ----
  
  		(void) rb_insert(so->queue, (RBNode *) tmpItem, &isNew);
  
+ 		/* Create new GISTSearchHeapItem to insert into pageData*/
+ 
  		MemoryContextSwitchTo(oldcxt);
  	}
  
! 	so->curPageData = NULL;
  
  	/*
  	 * check all tuples on page
***************
*** 329,340 **** gistScanPage(IndexScanDesc scan, GISTSearchItem *pageItem, double *myDistances,
  		}
  		else if (scan->numberOfOrderBys == 0 && GistPageIsLeaf(page))
  		{
! 			/*
! 			 * Non-ordered scan, so report heap tuples in so->pageData[]
! 			 */
! 			so->pageData[so->nPageData].heapPtr = it->t_tid;
! 			so->pageData[so->nPageData].recheck = recheck;
! 			so->nPageData++;
  		}
  		else
  		{
--- 335,356 ----
  		}
  		else if (scan->numberOfOrderBys == 0 && GistPageIsLeaf(page))
  		{
! 			/* Non-oredered scan, so tuples report in so->pageData */
! 			oldcxt = MemoryContextSwitchTo(so->queueCxt);
! 			/* form tmpListItem and fill it with data to add into so->pageData */
! 			tmpListItem = palloc(sizeof(GISTSearchHeapItem));
! 			tmpListItem->heapPtr = it->t_tid;
! 			tmpListItem->recheck = recheck;
! 			if (scan->xs_want_itup)
! 				tmpListItem->ftup = gistFetchTuple(giststate, r, it, isnull);
! 
! 			so->pageData = lappend(so->pageData, tmpListItem);	
! 			
! 			/* If it's first call of lappend() we should set so->curPageData not NULL*/
! 			if(so->curPageData == NULL)
! 				so->curPageData = list_head(so->pageData);
! 			
! 			MemoryContextSwitchTo(oldcxt);
  		}
  		else
  		{
***************
*** 357,362 **** gistScanPage(IndexScanDesc scan, GISTSearchItem *pageItem, double *myDistances,
--- 373,380 ----
  				item->blkno = InvalidBlockNumber;
  				item->data.heap.heapPtr = it->t_tid;
  				item->data.heap.recheck = recheck;
+ 				if (scan->xs_want_itup)
+ 					item->data.heap.ftup = gistFetchTuple(giststate, r, it, isnull); 
  			}
  			else
  			{
***************
*** 451,456 **** getNextNearest(IndexScanDesc scan)
--- 469,476 ----
  			/* found a heap item at currently minimal distance */
  			scan->xs_ctup.t_self = item->data.heap.heapPtr;
  			scan->xs_recheck = item->data.heap.recheck;
+ 			if(scan->xs_want_itup)	
+ 				scan->xs_itup = item->data.heap.ftup;
  			res = true;
  		}
  		else
***************
*** 492,498 **** gistgettuple(PG_FUNCTION_ARGS)
  
  		so->firstCall = false;
  		so->curTreeItem = NULL;
! 		so->curPageData = so->nPageData = 0;
  
  		fakeItem.blkno = GIST_ROOT_BLKNO;
  		memset(&fakeItem.data.parentlsn, 0, sizeof(GistNSN));
--- 512,519 ----
  
  		so->firstCall = false;
  		so->curTreeItem = NULL;
! 
! 		so->curPageData = NULL;
  
  		fakeItem.blkno = GIST_ROOT_BLKNO;
  		memset(&fakeItem.data.parentlsn, 0, sizeof(GistNSN));
***************
*** 509,521 **** gistgettuple(PG_FUNCTION_ARGS)
  		/* Fetch tuples index-page-at-a-time */
  		for (;;)
  		{
! 			if (so->curPageData < so->nPageData)
! 			{
! 				/* continuing to return tuples from a leaf page */
! 				scan->xs_ctup.t_self = so->pageData[so->curPageData].heapPtr;
! 				scan->xs_recheck = so->pageData[so->curPageData].recheck;
! 				so->curPageData++;
! 				PG_RETURN_BOOL(true);
  			}
  
  			/* find and process the next index page */
--- 530,550 ----
  		/* Fetch tuples index-page-at-a-time */
  		for (;;)
  		{
! 			if(so->curPageData!=NULL) {
! 				GISTSearchHeapItem *tmp = (GISTSearchHeapItem *)lfirst(so->curPageData);
! 				scan->xs_ctup.t_self = tmp->heapPtr;
! 				scan->xs_recheck = tmp->recheck;
! 				if(scan->xs_want_itup)
! 					scan->xs_itup = tmp->ftup;
! 
! 				ListCell *tmpPageData = so->curPageData;
! 				/* go to next ListCell */
! 				so->curPageData = lnext(so->curPageData);
! 				/* Delete ListCell that we have already read.
! 				 * It's always head of so->pageData
! 				 */
! 				so->pageData =  list_delete_cell(so->pageData, tmpPageData, NULL);
! 				PG_RETURN_BOOL(TRUE);
  			}
  
  			/* find and process the next index page */
***************
*** 537,543 **** gistgettuple(PG_FUNCTION_ARGS)
  				gistScanPage(scan, item, so->curTreeItem->distances, NULL, NULL);
  
  				pfree(item);
! 			} while (so->nPageData == 0);
  		}
  	}
  }
--- 566,572 ----
  				gistScanPage(scan, item, so->curTreeItem->distances, NULL, NULL);
  
  				pfree(item);
! 			} while (list_length(so->pageData)==0);
  		}
  	}
  }
***************
*** 561,567 **** gistgetbitmap(PG_FUNCTION_ARGS)
  
  	/* Begin the scan by processing the root page */
  	so->curTreeItem = NULL;
! 	so->curPageData = so->nPageData = 0;
  
  	fakeItem.blkno = GIST_ROOT_BLKNO;
  	memset(&fakeItem.data.parentlsn, 0, sizeof(GistNSN));
--- 590,597 ----
  
  	/* Begin the scan by processing the root page */
  	so->curTreeItem = NULL;
! 	so->curPageData = NULL;
! 	//so->curPageData = so->nPageData = 0;
  
  	fakeItem.blkno = GIST_ROOT_BLKNO;
  	memset(&fakeItem.data.parentlsn, 0, sizeof(GistNSN));
*** a/src/backend/access/gist/gistproc.c
--- b/src/backend/access/gist/gistproc.c
***************
*** 152,157 **** gist_box_decompress(PG_FUNCTION_ARGS)
--- 152,168 ----
  }
  
  /*
+  * GiST Fetch method for boxes 
+  * do not do anything --- we just use the stored box as is.
+  */
+ Datum
+ gist_box_fetch(PG_FUNCTION_ARGS)
+ {
+ 	//elog(NOTICE, "Debug. gistproc.c we are in gist_box_fetch");
+ 	PG_RETURN_POINTER(PG_GETARG_POINTER(0));
+ }
+ 
+ /*
   * The GiST Penalty method for boxes (also used for points)
   *
   * As in the R-tree paper, we use change in area as our penalty metric
***************
*** 1142,1147 **** gist_circle_compress(PG_FUNCTION_ARGS)
--- 1153,1192 ----
  }
  
  /*
+  * GiST Fetch method for circle 
+  * get circle coordinates from it's bounding box coordinates
+  */
+ Datum
+ gist_circle_fetch(PG_FUNCTION_ARGS)
+ {
+ 	GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
+ 	GISTENTRY  *retval;
+ 		retval = palloc(sizeof(GISTENTRY));
+ 		if (DatumGetCircleP(entry->key) != NULL)
+ 		{
+ 			BOX	   *in = DatumGetBoxP(entry->key);
+ 			CIRCLE		   *r;
+ 
+ 			r = (CIRCLE *) palloc(sizeof(CIRCLE));
+ 			r->radius = (in->high.x - in->low.x)/2;
+ 			r->center.x = (in->high.x + in->low.x)/2;
+ 			r->center.y = (in->high.y + in->low.y)/2;
+ 			gistentryinit(*retval, PointerGetDatum(r),
+ 						  entry->rel, entry->page,
+ 						  entry->offset, FALSE);
+ 
+ 		}
+ 		else
+ 		{
+ 			gistentryinit(*retval, (Datum) 0,
+ 						  entry->rel, entry->page,
+ 						  entry->offset, FALSE);
+ 		}
+ 	PG_RETURN_POINTER(retval);
+ }
+ 
+ 
+ /*
   * The GiST Consistent method for circles
   */
  Datum
*** a/src/backend/access/gist/gistscan.c
--- b/src/backend/access/gist/gistscan.c
***************
*** 133,138 **** gistbeginscan(PG_FUNCTION_ARGS)
--- 133,146 ----
  
  	scan->opaque = so;
  
+ 	/* All fields required for index-only scans are null until gistrescan. 
+ 	 * However, we set up scan->xs_itupdesc whether we'll need it or not, 
+ 	 * since that's cheap.
+ 	 */
+ 	so->pageData = NULL;
+ 	so->curPageData = NULL;
+ 	scan->xs_itupdesc = RelationGetDescr(r);
+ 
  	MemoryContextSwitchTo(oldCxt);
  
  	PG_RETURN_POINTER(scan);
***************
*** 194,204 **** gistrescan(PG_FUNCTION_ARGS)
  						  GISTSearchTreeItemAllocator,
  						  GISTSearchTreeItemDeleter,
  						  scan);
  	MemoryContextSwitchTo(oldCxt);
  
- 	so->curTreeItem = NULL;
  	so->firstCall = true;
! 
  	/* Update scan key, if a new one is given */
  	if (key && scan->numberOfKeys > 0)
  	{
--- 202,212 ----
  						  GISTSearchTreeItemAllocator,
  						  GISTSearchTreeItemDeleter,
  						  scan);
+ 
  	MemoryContextSwitchTo(oldCxt);
  
  	so->firstCall = true;
! 	
  	/* Update scan key, if a new one is given */
  	if (key && scan->numberOfKeys > 0)
  	{
*** a/src/backend/access/gist/gistutil.c
--- b/src/backend/access/gist/gistutil.c
***************
*** 618,623 **** gistFormTuple(GISTSTATE *giststate, Relation r,
--- 618,682 ----
  	return res;
  }
  
+ 
+ /*
+  * initialize a GiST entry with fetched value in key field
+  */
+ void
+ gistfentryinit(GISTSTATE *giststate, int nkey,
+ 			   GISTENTRY *e, Datum k, Relation r,
+ 			   Page pg, OffsetNumber o, bool l, bool isNull)
+ {
+ 	if (!isNull)
+ 	{
+ 		GISTENTRY  *fep;
+ 
+ 		gistentryinit(*e, k, r, pg, o, l);
+ 		fep = (GISTENTRY *)
+ 			DatumGetPointer(FunctionCall1Coll(&giststate->fetchFn[nkey],
+ 										   giststate->supportCollation[nkey],
+ 											  PointerGetDatum(e)));
+ 		//elog(NOTICE, "Debug. gistfentryinit()");
+ 		/* fecthFn returns the given pointer */
+ 		if (fep != e)
+ 			gistentryinit(*e, fep->key, fep->rel, fep->page, fep->offset,
+ 						  fep->leafkey);
+ 	}
+ 	else
+ 		gistentryinit(*e, (Datum) 0, r, pg, o, l);
+ }
+ 
+ /*
+  * Fetch all keys in tuple.
+  * returns new IndexTuple that contains GISTENTRY with fetched data in key field
+  */
+ IndexTuple
+ gistFetchTuple(GISTSTATE *giststate, Relation r, IndexTuple tuple, bool isnull[])
+ {
+ 	GISTENTRY	fentry[INDEX_MAX_KEYS];
+ 	Datum		fetchatt[INDEX_MAX_KEYS];
+ 	int		i;
+ 	IndexTuple	res;
+ 	
+ 	for (i = 0; i < r->rd_att->natts; i++)  { 
+ 
+ 		Datum datum = index_getattr(tuple, i + 1, giststate->tupdesc, &isnull[i]);
+ 
+ 		gistfentryinit(giststate, i, &fentry[i],
+ 					   datum, r, NULL, (OffsetNumber) 0,
+ 					   FALSE, FALSE);
+ 		fetchatt[i] = fentry[i].key;
+ 	}
+ 	res = index_form_tuple(giststate->tupdesc, fetchatt, isnull);
+ 
+ 	/*
+ 	 * The offset number on tuples on internal pages is unused. For historical
+ 	 * reasons, it is set 0xffff.
+ 	 */
+ 	ItemPointerSetOffsetNumber(&(res->t_tid), 0xffff);
+ 	return res;
+ }
+ 
  float
  gistpenalty(GISTSTATE *giststate, int attno,
  			GISTENTRY *orig, bool isNullOrig,
*** a/src/backend/access/index/indexam.c
--- b/src/backend/access/index/indexam.c
***************
*** 722,732 **** index_vacuum_cleanup(IndexVacuumInfo *info,
  }
  
  /* ----------------
!  *		index_can_return - does index support index-only scans?
   * ----------------
   */
  bool
! index_can_return(Relation indexRelation)
  {
  	FmgrInfo   *procedure;
  
--- 722,732 ----
  }
  
  /* ----------------
!  *		index_can_return - does index column support index-only scans?
   * ----------------
   */
  bool
! index_can_return(Relation indexRelation, int attno)
  {
  	FmgrInfo   *procedure;
  
***************
*** 738,745 **** index_can_return(Relation indexRelation)
  
  	GET_REL_PROCEDURE(amcanreturn);
  
! 	return DatumGetBool(FunctionCall1(procedure,
! 									  PointerGetDatum(indexRelation)));
  }
  
  /* ----------------
--- 738,746 ----
  
  	GET_REL_PROCEDURE(amcanreturn);
  
! 	return DatumGetBool(FunctionCall2(procedure,
! 					  PointerGetDatum(indexRelation),
! 					  Int32GetDatum(attno)));
  }
  
  /* ----------------
*** a/src/backend/optimizer/path/indxpath.c
--- b/src/backend/optimizer/path/indxpath.c
***************
*** 1746,1759 **** check_index_only(RelOptInfo *rel, IndexOptInfo *index)
  	bool		result;
  	Bitmapset  *attrs_used = NULL;
  	Bitmapset  *index_attrs = NULL;
  	ListCell   *lc;
  	int			i;
  
  	/* Index-only scans must be enabled, and index must be capable of them */
  	if (!enable_indexonlyscan)
  		return false;
- 	if (!index->canreturn)
- 		return false;
  
  	/*
  	 * Check that all needed attributes of the relation are available from the
--- 1746,1758 ----
  	bool		result;
  	Bitmapset  *attrs_used = NULL;
  	Bitmapset  *index_attrs = NULL;
+ 	Bitmapset  *index_only_attrs = NULL;
  	ListCell   *lc;
  	int			i;
  
  	/* Index-only scans must be enabled, and index must be capable of them */
  	if (!enable_indexonlyscan)
  		return false;
  
  	/*
  	 * Check that all needed attributes of the relation are available from the
***************
*** 1798,1810 **** check_index_only(RelOptInfo *rel, IndexOptInfo *index)
  		index_attrs =
  			bms_add_member(index_attrs,
  						   attno - FirstLowInvalidHeapAttributeNumber);
  	}
  
  	/* Do we have all the necessary attributes? */
! 	result = bms_is_subset(attrs_used, index_attrs);
  
  	bms_free(attrs_used);
  	bms_free(index_attrs);
  
  	return result;
  }
--- 1797,1815 ----
  		index_attrs =
  			bms_add_member(index_attrs,
  						   attno - FirstLowInvalidHeapAttributeNumber);
+ 
+ 		if (index->canreturn[i])
+ 			index_only_attrs = bms_add_member(index_only_attrs,
+ 						   attno - FirstLowInvalidHeapAttributeNumber);
  	}
  
  	/* Do we have all the necessary attributes? */
! 	result = ((bms_is_subset(attrs_used, index_attrs))&&
! 			(bms_is_subset(attrs_used, index_only_attrs)));
  
  	bms_free(attrs_used);
  	bms_free(index_attrs);
+ 	bms_free(index_only_attrs);
  
  	return result;
  }
*** a/src/backend/optimizer/util/plancat.c
--- b/src/backend/optimizer/util/plancat.c
***************
*** 207,212 **** get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent,
--- 207,213 ----
  			info->indexcollations = (Oid *) palloc(sizeof(Oid) * ncolumns);
  			info->opfamily = (Oid *) palloc(sizeof(Oid) * ncolumns);
  			info->opcintype = (Oid *) palloc(sizeof(Oid) * ncolumns);
+ 			info->canreturn = (bool *) palloc(sizeof(bool) * ncolumns);
  
  			for (i = 0; i < ncolumns; i++)
  			{
***************
*** 214,224 **** get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent,
  				info->indexcollations[i] = indexRelation->rd_indcollation[i];
  				info->opfamily[i] = indexRelation->rd_opfamily[i];
  				info->opcintype[i] = indexRelation->rd_opcintype[i];
  			}
  
  			info->relam = indexRelation->rd_rel->relam;
  			info->amcostestimate = indexRelation->rd_am->amcostestimate;
- 			info->canreturn = index_can_return(indexRelation);
  			info->amcanorderbyop = indexRelation->rd_am->amcanorderbyop;
  			info->amoptionalkey = indexRelation->rd_am->amoptionalkey;
  			info->amsearcharray = indexRelation->rd_am->amsearcharray;
--- 215,225 ----
  				info->indexcollations[i] = indexRelation->rd_indcollation[i];
  				info->opfamily[i] = indexRelation->rd_opfamily[i];
  				info->opcintype[i] = indexRelation->rd_opcintype[i];
+ 				info->canreturn[i] = index_can_return(indexRelation, i);
  			}
  
  			info->relam = indexRelation->rd_rel->relam;
  			info->amcostestimate = indexRelation->rd_am->amcostestimate;
  			info->amcanorderbyop = indexRelation->rd_am->amcanorderbyop;
  			info->amoptionalkey = indexRelation->rd_am->amoptionalkey;
  			info->amsearcharray = indexRelation->rd_am->amsearcharray;
*** a/src/include/access/genam.h
--- b/src/include/access/genam.h
***************
*** 156,162 **** extern IndexBulkDeleteResult *index_bulk_delete(IndexVacuumInfo *info,
  				  void *callback_state);
  extern IndexBulkDeleteResult *index_vacuum_cleanup(IndexVacuumInfo *info,
  					 IndexBulkDeleteResult *stats);
! extern bool index_can_return(Relation indexRelation);
  extern RegProcedure index_getprocid(Relation irel, AttrNumber attnum,
  				uint16 procnum);
  extern FmgrInfo *index_getprocinfo(Relation irel, AttrNumber attnum,
--- 156,162 ----
  				  void *callback_state);
  extern IndexBulkDeleteResult *index_vacuum_cleanup(IndexVacuumInfo *info,
  					 IndexBulkDeleteResult *stats);
! extern bool index_can_return(Relation indexRelation, int attno);
  extern RegProcedure index_getprocid(Relation irel, AttrNumber attnum,
  				uint16 procnum);
  extern FmgrInfo *index_getprocinfo(Relation irel, AttrNumber attnum,
*** a/src/include/access/gist.h
--- b/src/include/access/gist.h
***************
*** 33,39 ****
  #define GIST_PICKSPLIT_PROC				6
  #define GIST_EQUAL_PROC					7
  #define GIST_DISTANCE_PROC				8
! #define GISTNProcs						8
  
  /*
   * strategy numbers for GiST opclasses that want to implement the old
--- 33,40 ----
  #define GIST_PICKSPLIT_PROC				6
  #define GIST_EQUAL_PROC					7
  #define GIST_DISTANCE_PROC				8
! #define GIST_FETCH_PROC					9
! #define GISTNProcs					9
  
  /*
   * strategy numbers for GiST opclasses that want to implement the old
*** a/src/include/access/gist_private.h
--- b/src/include/access/gist_private.h
***************
*** 86,91 **** typedef struct GISTSTATE
--- 86,92 ----
  	FmgrInfo	picksplitFn[INDEX_MAX_KEYS];
  	FmgrInfo	equalFn[INDEX_MAX_KEYS];
  	FmgrInfo	distanceFn[INDEX_MAX_KEYS];
+ 	FmgrInfo	fetchFn[INDEX_MAX_KEYS];
  
  	/* Collations to pass to the support functions */
  	Oid			supportCollation[INDEX_MAX_KEYS];
***************
*** 117,122 **** typedef struct GISTSearchHeapItem
--- 118,124 ----
  {
  	ItemPointerData heapPtr;
  	bool		recheck;		/* T if quals must be rechecked */
+ 	IndexTuple ftup;		/* Tuple contains datum fetched from key for index-only scans. ftup = fetched tuple*/
  } GISTSearchHeapItem;
  
  /* Unvisited item, either index page or heap tuple */
***************
*** 167,175 **** typedef struct GISTScanOpaqueData
  	double	   *distances;		/* output area for gistindex_keytest */
  
  	/* In a non-ordered search, returnable heap items are stored here: */
! 	GISTSearchHeapItem pageData[BLCKSZ / sizeof(IndexTupleData)];
! 	OffsetNumber nPageData;		/* number of valid items in array */
! 	OffsetNumber curPageData;	/* next item to return */
  } GISTScanOpaqueData;
  
  typedef GISTScanOpaqueData *GISTScanOpaque;
--- 169,177 ----
  	double	   *distances;		/* output area for gistindex_keytest */
  
  	/* In a non-ordered search, returnable heap items are stored here: */
! 	List *pageData;
! 	ListCell *curPageData;
! 
  } GISTScanOpaqueData;
  
  typedef GISTScanOpaqueData *GISTScanOpaque;
***************
*** 423,428 **** typedef struct GiSTOptions
--- 425,431 ----
  /* gist.c */
  extern Datum gistbuildempty(PG_FUNCTION_ARGS);
  extern Datum gistinsert(PG_FUNCTION_ARGS);
+ extern Datum gistcanreturn(PG_FUNCTION_ARGS);
  extern MemoryContext createTempGistContext(void);
  extern GISTSTATE *initGISTstate(Relation index);
  extern void freeGISTstate(GISTSTATE *giststate);
***************
*** 522,527 **** extern bool gistKeyIsEQ(GISTSTATE *giststate, int attno, Datum a, Datum b);
--- 525,536 ----
  extern void gistDeCompressAtt(GISTSTATE *giststate, Relation r, IndexTuple tuple, Page p,
  				  OffsetNumber o, GISTENTRY *attdata, bool *isnull);
  
+ extern void gistfentryinit(GISTSTATE *giststate, int nkey,
+ 			   GISTENTRY *e, Datum k, Relation r,
+ 			   Page pg, OffsetNumber o, bool l, bool isNull);
+ 			   
+ extern IndexTuple gistFetchTuple(GISTSTATE *giststate, Relation r, IndexTuple tuple, bool *isnull);
+ 
  extern void gistMakeUnionKey(GISTSTATE *giststate, int attno,
  				 GISTENTRY *entry1, bool isnull1,
  				 GISTENTRY *entry2, bool isnull2,
*** a/src/include/catalog/pg_am.h
--- b/src/include/catalog/pg_am.h
***************
*** 123,129 **** DESCR("b-tree index access method");
  DATA(insert OID = 405 (  hash		1 1 f f t f f f f f f f f 23 hashinsert hashbeginscan hashgettuple hashgetbitmap hashrescan hashendscan hashmarkpos hashrestrpos hashbuild hashbuildempty hashbulkdelete hashvacuumcleanup - hashcostestimate hashoptions ));
  DESCR("hash index access method");
  #define HASH_AM_OID 405
! DATA(insert OID = 783 (  gist		0 8 f t f f t t f t t t f 0 gistinsert gistbeginscan gistgettuple gistgetbitmap gistrescan gistendscan gistmarkpos gistrestrpos gistbuild gistbuildempty gistbulkdelete gistvacuumcleanup - gistcostestimate gistoptions ));
  DESCR("GiST index access method");
  #define GIST_AM_OID 783
  DATA(insert OID = 2742 (  gin		0 6 f f f f t t f f t f f 0 gininsert ginbeginscan - gingetbitmap ginrescan ginendscan ginmarkpos ginrestrpos ginbuild ginbuildempty ginbulkdelete ginvacuumcleanup - gincostestimate ginoptions ));
--- 123,129 ----
  DATA(insert OID = 405 (  hash		1 1 f f t f f f f f f f f 23 hashinsert hashbeginscan hashgettuple hashgetbitmap hashrescan hashendscan hashmarkpos hashrestrpos hashbuild hashbuildempty hashbulkdelete hashvacuumcleanup - hashcostestimate hashoptions ));
  DESCR("hash index access method");
  #define HASH_AM_OID 405
! DATA(insert OID = 783 (  gist		0 9 f t f f t t f t t t f 0 gistinsert gistbeginscan gistgettuple gistgetbitmap gistrescan gistendscan gistmarkpos gistrestrpos gistbuild gistbuildempty gistbulkdelete gistvacuumcleanup gistcanreturn gistcostestimate gistoptions ));
  DESCR("GiST index access method");
  #define GIST_AM_OID 783
  DATA(insert OID = 2742 (  gin		0 6 f f f f t t f f t f f 0 gininsert ginbeginscan - gingetbitmap ginrescan ginendscan ginmarkpos ginrestrpos ginbuild ginbuildempty ginbulkdelete ginvacuumcleanup - gincostestimate ginoptions ));
*** a/src/include/catalog/pg_amproc.h
--- b/src/include/catalog/pg_amproc.h
***************
*** 195,200 **** DATA(insert (	2593   603 603 4 2580 ));
--- 195,201 ----
  DATA(insert (	2593   603 603 5 2581 ));
  DATA(insert (	2593   603 603 6 2582 ));
  DATA(insert (	2593   603 603 7 2584 ));
+ DATA(insert (	2593   603 603 9 3252 ));
  DATA(insert (	2594   604 604 1 2585 ));
  DATA(insert (	2594   604 604 2 2583 ));
  DATA(insert (	2594   604 604 3 2586 ));
***************
*** 209,214 **** DATA(insert (	2595   718 718 4 2580 ));
--- 210,216 ----
  DATA(insert (	2595   718 718 5 2581 ));
  DATA(insert (	2595   718 718 6 2582 ));
  DATA(insert (	2595   718 718 7 2584 ));
+ DATA(insert (	2595   718 718 9 3253 ));
  DATA(insert (	3655   3614 3614 1 3654 ));
  DATA(insert (	3655   3614 3614 2 3651 ));
  DATA(insert (	3655   3614 3614 3 3648 ));
*** a/src/include/catalog/pg_proc.h
--- b/src/include/catalog/pg_proc.h
***************
*** 558,564 **** DATA(insert OID = 332 (  btbulkdelete	   PGNSP PGUID 12 1 0 0 0 f f f f t f v 4
  DESCR("btree(internal)");
  DATA(insert OID = 972 (  btvacuumcleanup   PGNSP PGUID 12 1 0 0 0 f f f f t f v 2 0 2281 "2281 2281" _null_ _null_ _null_ _null_ btvacuumcleanup _null_ _null_ _null_ ));
  DESCR("btree(internal)");
! DATA(insert OID = 276 (  btcanreturn	   PGNSP PGUID 12 1 0 0 0 f f f f t f s 1 0 16 "2281" _null_ _null_ _null_ _null_ btcanreturn _null_ _null_ _null_ ));
  DESCR("btree(internal)");
  DATA(insert OID = 1268 (  btcostestimate   PGNSP PGUID 12 1 0 0 0 f f f f t f v 7 0 2278 "2281 2281 2281 2281 2281 2281 2281" _null_ _null_ _null_ _null_ btcostestimate _null_ _null_ _null_ ));
  DESCR("btree(internal)");
--- 558,564 ----
  DESCR("btree(internal)");
  DATA(insert OID = 972 (  btvacuumcleanup   PGNSP PGUID 12 1 0 0 0 f f f f t f v 2 0 2281 "2281 2281" _null_ _null_ _null_ _null_ btvacuumcleanup _null_ _null_ _null_ ));
  DESCR("btree(internal)");
! DATA(insert OID = 276 (  btcanreturn	   PGNSP PGUID 12 1 0 0 0 f f f f t f s 1 0 16 "2281 2281" _null_ _null_ _null_ _null_ btcanreturn _null_ _null_ _null_ ));
  DESCR("btree(internal)");
  DATA(insert OID = 1268 (  btcostestimate   PGNSP PGUID 12 1 0 0 0 f f f f t f v 7 0 2278 "2281 2281 2281 2281 2281 2281 2281" _null_ _null_ _null_ _null_ btcostestimate _null_ _null_ _null_ ));
  DESCR("btree(internal)");
***************
*** 941,946 **** DATA(insert OID = 776 (  gistbulkdelete    PGNSP PGUID 12 1 0 0 0 f f f f t f v
--- 941,949 ----
  DESCR("gist(internal)");
  DATA(insert OID = 2561 (  gistvacuumcleanup   PGNSP PGUID 12 1 0 0 0 f f f f t f v 2 0 2281 "2281 2281" _null_ _null_ _null_ _null_ gistvacuumcleanup _null_ _null_ _null_ ));
  DESCR("gist(internal)");
+ //Debug
+ DATA(insert OID = 3251 (  gistcanreturn	   PGNSP PGUID 12 1 0 0 0 f f f f t f s 1 0 16 "2281 2281" _null_ _null_ _null_ _null_ gistcanreturn _null_ _null_ _null_ ));
+ DESCR("gist(internal)");
  DATA(insert OID = 772 (  gistcostestimate  PGNSP PGUID 12 1 0 0 0 f f f f t f v 7 0 2278 "2281 2281 2281 2281 2281 2281 2281" _null_ _null_ _null_ _null_ gistcostestimate _null_ _null_ _null_ ));
  DESCR("gist(internal)");
  DATA(insert OID = 2787 (  gistoptions	   PGNSP PGUID 12 1 0 0 0 f f f f t f s 2 0 17 "1009 16" _null_ _null_ _null_ _null_  gistoptions _null_ _null_ _null_ ));
***************
*** 3996,4001 **** DATA(insert OID = 2579 (  gist_box_compress		PGNSP PGUID 12 1 0 0 0 f f f f t f
--- 3999,4007 ----
  DESCR("GiST support");
  DATA(insert OID = 2580 (  gist_box_decompress	PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 2281 "2281" _null_ _null_ _null_ _null_ gist_box_decompress _null_ _null_ _null_ ));
  DESCR("GiST support");
+ //Debug. gist_box_fetch
+ DATA(insert OID = 3252 (  gist_box_fetch	PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 2281 "2281" _null_ _null_ _null_ _null_ gist_box_fetch _null_ _null_ _null_ ));
+ DESCR("GiST support");
  DATA(insert OID = 2581 (  gist_box_penalty		PGNSP PGUID 12 1 0 0 0 f f f f t f i 3 0 2281 "2281 2281 2281" _null_ _null_ _null_ _null_	gist_box_penalty _null_ _null_ _null_ ));
  DESCR("GiST support");
  DATA(insert OID = 2582 (  gist_box_picksplit	PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 2281 "2281 2281" _null_ _null_ _null_ _null_	gist_box_picksplit _null_ _null_ _null_ ));
***************
*** 4012,4017 **** DATA(insert OID = 2591 (  gist_circle_consistent PGNSP PGUID 12 1 0 0 0 f f f f
--- 4018,4025 ----
  DESCR("GiST support");
  DATA(insert OID = 2592 (  gist_circle_compress	PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 2281 "2281" _null_ _null_ _null_ _null_ gist_circle_compress _null_ _null_ _null_ ));
  DESCR("GiST support");
+ DATA(insert OID = 3253 (  gist_circle_fetch	PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 2281 "2281" _null_ _null_ _null_ _null_ gist_circle_fetch _null_ _null_ _null_ ));
+ DESCR("GiST support");
  DATA(insert OID = 1030 (  gist_point_compress	PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 2281 "2281" _null_ _null_ _null_ _null_ gist_point_compress _null_ _null_ _null_ ));
  DESCR("GiST support");
  DATA(insert OID = 2179 (  gist_point_consistent PGNSP PGUID 12 1 0 0 0 f f f f t f i 5 0 16 "2281 600 23 26 2281" _null_ _null_ _null_ _null_	gist_point_consistent _null_ _null_ _null_ ));
***************
*** 4905,4911 **** DATA(insert OID = 4011 (  spgbulkdelete    PGNSP PGUID 12 1 0 0 0 f f f f t f v
  DESCR("spgist(internal)");
  DATA(insert OID = 4012 (  spgvacuumcleanup	 PGNSP PGUID 12 1 0 0 0 f f f f t f v 2 0 2281 "2281 2281" _null_ _null_ _null_ _null_ spgvacuumcleanup _null_ _null_ _null_ ));
  DESCR("spgist(internal)");
! DATA(insert OID = 4032 (  spgcanreturn	   PGNSP PGUID 12 1 0 0 0 f f f f t f s 1 0 16 "2281" _null_ _null_ _null_ _null_ spgcanreturn _null_ _null_ _null_ ));
  DESCR("spgist(internal)");
  DATA(insert OID = 4013 (  spgcostestimate  PGNSP PGUID 12 1 0 0 0 f f f f t f v 7 0 2278 "2281 2281 2281 2281 2281 2281 2281" _null_ _null_ _null_ _null_ spgcostestimate _null_ _null_ _null_ ));
  DESCR("spgist(internal)");
--- 4913,4919 ----
  DESCR("spgist(internal)");
  DATA(insert OID = 4012 (  spgvacuumcleanup	 PGNSP PGUID 12 1 0 0 0 f f f f t f v 2 0 2281 "2281 2281" _null_ _null_ _null_ _null_ spgvacuumcleanup _null_ _null_ _null_ ));
  DESCR("spgist(internal)");
! DATA(insert OID = 4032 (  spgcanreturn	   PGNSP PGUID 12 1 0 0 0 f f f f t f s 1 0 16 "2281 2281" _null_ _null_ _null_ _null_ spgcanreturn _null_ _null_ _null_ ));
  DESCR("spgist(internal)");
  DATA(insert OID = 4013 (  spgcostestimate  PGNSP PGUID 12 1 0 0 0 f f f f t f v 7 0 2278 "2281 2281 2281 2281 2281 2281 2281" _null_ _null_ _null_ _null_ spgcostestimate _null_ _null_ _null_ ));
  DESCR("spgist(internal)");
*** a/src/include/nodes/relation.h
--- b/src/include/nodes/relation.h
***************
*** 526,532 **** typedef struct IndexOptInfo
  	bool		unique;			/* true if a unique index */
  	bool		immediate;		/* is uniqueness enforced immediately? */
  	bool		hypothetical;	/* true if index doesn't really exist */
! 	bool		canreturn;		/* can index return IndexTuples? */
  	bool		amcanorderbyop; /* does AM support order by operator result? */
  	bool		amoptionalkey;	/* can query omit key for the first column? */
  	bool		amsearcharray;	/* can AM handle ScalarArrayOpExpr quals? */
--- 526,532 ----
  	bool		unique;			/* true if a unique index */
  	bool		immediate;		/* is uniqueness enforced immediately? */
  	bool		hypothetical;	/* true if index doesn't really exist */
! 	bool		*canreturn;		/* can index return IndexTuples? */
  	bool		amcanorderbyop; /* does AM support order by operator result? */
  	bool		amoptionalkey;	/* can query omit key for the first column? */
  	bool		amsearcharray;	/* can AM handle ScalarArrayOpExpr quals? */
*** a/src/include/utils/geo_decls.h
--- b/src/include/utils/geo_decls.h
***************
*** 273,278 **** extern Datum box_out(PG_FUNCTION_ARGS);
--- 273,279 ----
  extern Datum box_recv(PG_FUNCTION_ARGS);
  extern Datum box_send(PG_FUNCTION_ARGS);
  extern Datum box_same(PG_FUNCTION_ARGS);
+ extern Datum gist_box_fetch(PG_FUNCTION_ARGS); //Debug. gist_box_fetch
  extern Datum box_overlap(PG_FUNCTION_ARGS);
  extern Datum box_left(PG_FUNCTION_ARGS);
  extern Datum box_overleft(PG_FUNCTION_ARGS);
***************
*** 367,372 **** extern Datum circle_out(PG_FUNCTION_ARGS);
--- 368,374 ----
  extern Datum circle_recv(PG_FUNCTION_ARGS);
  extern Datum circle_send(PG_FUNCTION_ARGS);
  extern Datum circle_same(PG_FUNCTION_ARGS);
+ extern Datum gist_circle_fetch(PG_FUNCTION_ARGS);
  extern Datum circle_overlap(PG_FUNCTION_ARGS);
  extern Datum circle_overleft(PG_FUNCTION_ARGS);
  extern Datum circle_left(PG_FUNCTION_ARGS);