diff options
Diffstat (limited to 'src/backend/utils')
-rw-r--r-- | src/backend/utils/sort/sortsupport.c | 34 | ||||
-rw-r--r-- | src/backend/utils/sort/tuplesort.c | 57 |
2 files changed, 91 insertions, 0 deletions
diff --git a/src/backend/utils/sort/sortsupport.c b/src/backend/utils/sort/sortsupport.c index fcfe6e831a1..c436fbb4ce1 100644 --- a/src/backend/utils/sort/sortsupport.c +++ b/src/backend/utils/sort/sortsupport.c @@ -15,6 +15,7 @@ #include "postgres.h" +#include "access/gist.h" #include "access/nbtree.h" #include "catalog/pg_am.h" #include "fmgr.h" @@ -175,3 +176,36 @@ PrepareSortSupportFromIndexRel(Relation indexRel, int16 strategy, FinishSortSupportFunction(opfamily, opcintype, ssup); } + +/* + * Fill in SortSupport given a GiST index relation + * + * Caller must previously have zeroed the SortSupportData structure and then + * filled in ssup_cxt, ssup_attno, ssup_collation, and ssup_nulls_first. This + * will fill in ssup_reverse (always false for GiST index build), as well as + * the comparator function pointer. + */ +void +PrepareSortSupportFromGistIndexRel(Relation indexRel, SortSupport ssup) +{ + Oid opfamily = indexRel->rd_opfamily[ssup->ssup_attno - 1]; + Oid opcintype = indexRel->rd_opcintype[ssup->ssup_attno - 1]; + Oid sortSupportFunction; + + Assert(ssup->comparator == NULL); + + if (indexRel->rd_rel->relam != GIST_AM_OID) + elog(ERROR, "unexpected non-gist AM: %u", indexRel->rd_rel->relam); + ssup->ssup_reverse = false; + + /* + * Look up the sort support function. This is simpler than for B-tree + * indexes because we don't support the old-style btree comparators. + */ + sortSupportFunction = get_opfamily_proc(opfamily, opcintype, opcintype, + GIST_SORTSUPPORT_PROC); + if (!OidIsValid(sortSupportFunction)) + elog(ERROR, "missing support function %d(%u,%u) in opfamily %u", + GIST_SORTSUPPORT_PROC, opcintype, opcintype, opfamily); + OidFunctionCall1(sortSupportFunction, PointerGetDatum(ssup)); +} diff --git a/src/backend/utils/sort/tuplesort.c b/src/backend/utils/sort/tuplesort.c index cbda911f465..d0cc04a878a 100644 --- a/src/backend/utils/sort/tuplesort.c +++ b/src/backend/utils/sort/tuplesort.c @@ -1168,6 +1168,63 @@ tuplesort_begin_index_hash(Relation heapRel, } Tuplesortstate * +tuplesort_begin_index_gist(Relation heapRel, + Relation indexRel, + int workMem, + SortCoordinate coordinate, + bool randomAccess) +{ + Tuplesortstate *state = tuplesort_begin_common(workMem, coordinate, + randomAccess); + MemoryContext oldcontext; + int i; + + oldcontext = MemoryContextSwitchTo(state->sortcontext); + +#ifdef TRACE_SORT + if (trace_sort) + elog(LOG, + "begin index sort: workMem = %d, randomAccess = %c", + workMem, randomAccess ? 't' : 'f'); +#endif + + state->nKeys = IndexRelationGetNumberOfKeyAttributes(indexRel); + + state->comparetup = comparetup_index_btree; + state->copytup = copytup_index; + state->writetup = writetup_index; + state->readtup = readtup_index; + + state->heapRel = heapRel; + state->indexRel = indexRel; + + /* Prepare SortSupport data for each column */ + state->sortKeys = (SortSupport) palloc0(state->nKeys * + sizeof(SortSupportData)); + + for (i = 0; i < state->nKeys; i++) + { + SortSupport sortKey = state->sortKeys + i; + + sortKey->ssup_cxt = CurrentMemoryContext; + sortKey->ssup_collation = indexRel->rd_indcollation[i]; + sortKey->ssup_nulls_first = false; + sortKey->ssup_attno = i + 1; + /* Convey if abbreviation optimization is applicable in principle */ + sortKey->abbreviate = (i == 0); + + AssertState(sortKey->ssup_attno != 0); + + /* Look for a sort support function */ + PrepareSortSupportFromGistIndexRel(indexRel, sortKey); + } + + MemoryContextSwitchTo(oldcontext); + + return state; +} + +Tuplesortstate * tuplesort_begin_datum(Oid datumType, Oid sortOperator, Oid sortCollation, bool nullsFirstFlag, int workMem, SortCoordinate coordinate, bool randomAccess) |