*** 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);