mirror of
https://github.com/postgres/postgres.git
synced 2025-09-02 04:21:28 +03:00
Use the sortsupport infrastructure in more cases.
This removes some fmgr overhead from cases such as btree index builds. Peter Geoghegan, reviewed by Andreas Karlsson and me.
This commit is contained in:
@@ -686,6 +686,7 @@ _bt_load(BTWriteState *wstate, BTSpool *btspool, BTSpool *btspool2)
|
||||
int i,
|
||||
keysz = RelationGetNumberOfAttributes(wstate->index);
|
||||
ScanKey indexScanKey = NULL;
|
||||
SortSupport sortKeys;
|
||||
|
||||
if (merge)
|
||||
{
|
||||
@@ -701,6 +702,31 @@ _bt_load(BTWriteState *wstate, BTSpool *btspool, BTSpool *btspool2)
|
||||
true, &should_free2);
|
||||
indexScanKey = _bt_mkscankey_nodata(wstate->index);
|
||||
|
||||
/* Prepare SortSupport data for each column */
|
||||
sortKeys = (SortSupport) palloc0(keysz * sizeof(SortSupportData));
|
||||
|
||||
for (i = 0; i < keysz; i++)
|
||||
{
|
||||
SortSupport sortKey = sortKeys + i;
|
||||
ScanKey scanKey = indexScanKey + i;
|
||||
int16 strategy;
|
||||
|
||||
sortKey->ssup_cxt = CurrentMemoryContext;
|
||||
sortKey->ssup_collation = scanKey->sk_collation;
|
||||
sortKey->ssup_nulls_first =
|
||||
(scanKey->sk_flags & SK_BT_NULLS_FIRST) != 0;
|
||||
sortKey->ssup_attno = scanKey->sk_attno;
|
||||
|
||||
AssertState(sortKey->ssup_attno != 0);
|
||||
|
||||
strategy = (scanKey->sk_flags & SK_BT_DESC) != 0 ?
|
||||
BTGreaterStrategyNumber : BTLessStrategyNumber;
|
||||
|
||||
PrepareSortSupportFromIndexRel(wstate->index, strategy, sortKey);
|
||||
}
|
||||
|
||||
_bt_freeskey(indexScanKey);
|
||||
|
||||
for (;;)
|
||||
{
|
||||
load1 = true; /* load BTSpool next ? */
|
||||
@@ -713,43 +739,20 @@ _bt_load(BTWriteState *wstate, BTSpool *btspool, BTSpool *btspool2)
|
||||
{
|
||||
for (i = 1; i <= keysz; i++)
|
||||
{
|
||||
ScanKey entry;
|
||||
SortSupport entry;
|
||||
Datum attrDatum1,
|
||||
attrDatum2;
|
||||
bool isNull1,
|
||||
isNull2;
|
||||
int32 compare;
|
||||
|
||||
entry = indexScanKey + i - 1;
|
||||
entry = sortKeys + i - 1;
|
||||
attrDatum1 = index_getattr(itup, i, tupdes, &isNull1);
|
||||
attrDatum2 = index_getattr(itup2, i, tupdes, &isNull2);
|
||||
if (isNull1)
|
||||
{
|
||||
if (isNull2)
|
||||
compare = 0; /* NULL "=" NULL */
|
||||
else if (entry->sk_flags & SK_BT_NULLS_FIRST)
|
||||
compare = -1; /* NULL "<" NOT_NULL */
|
||||
else
|
||||
compare = 1; /* NULL ">" NOT_NULL */
|
||||
}
|
||||
else if (isNull2)
|
||||
{
|
||||
if (entry->sk_flags & SK_BT_NULLS_FIRST)
|
||||
compare = 1; /* NOT_NULL ">" NULL */
|
||||
else
|
||||
compare = -1; /* NOT_NULL "<" NULL */
|
||||
}
|
||||
else
|
||||
{
|
||||
compare =
|
||||
DatumGetInt32(FunctionCall2Coll(&entry->sk_func,
|
||||
entry->sk_collation,
|
||||
attrDatum1,
|
||||
attrDatum2));
|
||||
|
||||
if (entry->sk_flags & SK_BT_DESC)
|
||||
compare = -compare;
|
||||
}
|
||||
compare = ApplySortComparator(attrDatum1, isNull1,
|
||||
attrDatum2, isNull2,
|
||||
entry);
|
||||
if (compare > 0)
|
||||
{
|
||||
load1 = false;
|
||||
@@ -783,7 +786,7 @@ _bt_load(BTWriteState *wstate, BTSpool *btspool, BTSpool *btspool2)
|
||||
true, &should_free2);
|
||||
}
|
||||
}
|
||||
_bt_freeskey(indexScanKey);
|
||||
pfree(sortKeys);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
Reference in New Issue
Block a user