diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2011-12-07 00:18:38 -0500 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2011-12-07 00:19:39 -0500 |
commit | c6e3ac11b60ac4a8942ab964252d51c1c0bd8845 (patch) | |
tree | fa9ffffed5b31d01a007f447368fd9479bba3aef /src/backend/executor/nodeMergeAppend.c | |
parent | d2a662182eac1069ff3874a1db499508a13c6bca (diff) | |
download | postgresql-c6e3ac11b60ac4a8942ab964252d51c1c0bd8845.tar.gz postgresql-c6e3ac11b60ac4a8942ab964252d51c1c0bd8845.zip |
Create a "sort support" interface API for faster sorting.
This patch creates an API whereby a btree index opclass can optionally
provide non-SQL-callable support functions for sorting. In the initial
patch, we only use this to provide a directly-callable comparator function,
which can be invoked with a bit less overhead than the traditional
SQL-callable comparator. While that should be of value in itself, the real
reason for doing this is to provide a datatype-extensible framework for
more aggressive optimizations, as in Peter Geoghegan's recent work.
Robert Haas and Tom Lane
Diffstat (limited to 'src/backend/executor/nodeMergeAppend.c')
-rw-r--r-- | src/backend/executor/nodeMergeAppend.c | 77 |
1 files changed, 16 insertions, 61 deletions
diff --git a/src/backend/executor/nodeMergeAppend.c b/src/backend/executor/nodeMergeAppend.c index 43059664b93..6065e2176ac 100644 --- a/src/backend/executor/nodeMergeAppend.c +++ b/src/backend/executor/nodeMergeAppend.c @@ -38,10 +38,8 @@ #include "postgres.h" -#include "access/nbtree.h" #include "executor/execdebug.h" #include "executor/nodeMergeAppend.h" -#include "utils/lsyscache.h" /* * It gets quite confusing having a heap array (indexed by integers) which @@ -128,38 +126,18 @@ ExecInitMergeAppend(MergeAppend *node, EState *estate, int eflags) * initialize sort-key information */ mergestate->ms_nkeys = node->numCols; - mergestate->ms_scankeys = palloc0(sizeof(ScanKeyData) * node->numCols); + mergestate->ms_sortkeys = palloc0(sizeof(SortSupportData) * node->numCols); for (i = 0; i < node->numCols; i++) { - Oid sortFunction; - bool reverse; - int flags; - - if (!get_compare_function_for_ordering_op(node->sortOperators[i], - &sortFunction, &reverse)) - elog(ERROR, "operator %u is not a valid ordering operator", - node->sortOperators[i]); - - /* We use btree's conventions for encoding directionality */ - flags = 0; - if (reverse) - flags |= SK_BT_DESC; - if (node->nullsFirst[i]) - flags |= SK_BT_NULLS_FIRST; + SortSupport sortKey = mergestate->ms_sortkeys + i; - /* - * We needn't fill in sk_strategy or sk_subtype since these scankeys - * will never be passed to an index. - */ - ScanKeyEntryInitialize(&mergestate->ms_scankeys[i], - flags, - node->sortColIdx[i], - InvalidStrategy, - InvalidOid, - node->collations[i], - sortFunction, - (Datum) 0); + sortKey->ssup_cxt = CurrentMemoryContext; + sortKey->ssup_collation = node->collations[i]; + sortKey->ssup_nulls_first = node->nullsFirst[i]; + sortKey->ssup_attno = node->sortColIdx[i]; + + PrepareSortSupportFromOrderingOp(node->sortOperators[i], sortKey); } /* @@ -298,45 +276,22 @@ heap_compare_slots(MergeAppendState *node, SlotNumber slot1, SlotNumber slot2) for (nkey = 0; nkey < node->ms_nkeys; nkey++) { - ScanKey scankey = node->ms_scankeys + nkey; - AttrNumber attno = scankey->sk_attno; + SortSupport sortKey = node->ms_sortkeys + nkey; + AttrNumber attno = sortKey->ssup_attno; Datum datum1, datum2; bool isNull1, isNull2; - int32 compare; + int compare; datum1 = slot_getattr(s1, attno, &isNull1); datum2 = slot_getattr(s2, attno, &isNull2); - if (isNull1) - { - if (isNull2) - continue; /* NULL "=" NULL */ - else if (scankey->sk_flags & SK_BT_NULLS_FIRST) - return -1; /* NULL "<" NOT_NULL */ - else - return 1; /* NULL ">" NOT_NULL */ - } - else if (isNull2) - { - if (scankey->sk_flags & SK_BT_NULLS_FIRST) - return 1; /* NOT_NULL ">" NULL */ - else - return -1; /* NOT_NULL "<" NULL */ - } - else - { - compare = DatumGetInt32(FunctionCall2Coll(&scankey->sk_func, - scankey->sk_collation, - datum1, datum2)); - if (compare != 0) - { - if (scankey->sk_flags & SK_BT_DESC) - compare = -compare; - return compare; - } - } + compare = ApplySortComparator(datum1, isNull1, + datum2, isNull2, + sortKey); + if (compare != 0) + return compare; } return 0; } |