aboutsummaryrefslogtreecommitdiff
path: root/src/backend/executor/nodeMergeAppend.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2011-12-07 00:18:38 -0500
committerTom Lane <tgl@sss.pgh.pa.us>2011-12-07 00:19:39 -0500
commitc6e3ac11b60ac4a8942ab964252d51c1c0bd8845 (patch)
treefa9ffffed5b31d01a007f447368fd9479bba3aef /src/backend/executor/nodeMergeAppend.c
parentd2a662182eac1069ff3874a1db499508a13c6bca (diff)
downloadpostgresql-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.c77
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;
}