summaryrefslogtreecommitdiff
path: root/src/backend/utils/adt
diff options
context:
space:
mode:
authorRobert Haas <rhaas@postgresql.org>2016-02-17 15:40:00 +0530
committerRobert Haas <rhaas@postgresql.org>2016-02-17 15:40:00 +0530
commitf1f5ec1efafe74ca45e24e0bf3371b1d6985c8ee (patch)
treeeab628891c0c2250d87bc703e27af7ca88fb9c0f /src/backend/utils/adt
parent66f503868b2ac1163aaf48a2f76d8be02af0bc81 (diff)
Reuse abbreviated keys in ordered [set] aggregates.
When processing ordered aggregates following a sort that could make use of the abbreviated key optimization, only call the equality operator to compare successive pairs of tuples when their abbreviated keys were not equal. Peter Geoghegan, reviewd by Andreas Karlsson and by me.
Diffstat (limited to 'src/backend/utils/adt')
-rw-r--r--src/backend/utils/adt/orderedsetaggs.c33
1 files changed, 23 insertions, 10 deletions
diff --git a/src/backend/utils/adt/orderedsetaggs.c b/src/backend/utils/adt/orderedsetaggs.c
index 57201fd03d4..fe44d561295 100644
--- a/src/backend/utils/adt/orderedsetaggs.c
+++ b/src/backend/utils/adt/orderedsetaggs.c
@@ -453,7 +453,7 @@ percentile_disc_final(PG_FUNCTION_ARGS)
elog(ERROR, "missing row in percentile_disc");
}
- if (!tuplesort_getdatum(osastate->sortstate, true, &val, &isnull))
+ if (!tuplesort_getdatum(osastate->sortstate, true, &val, &isnull, NULL))
elog(ERROR, "missing row in percentile_disc");
/*
@@ -553,7 +553,7 @@ percentile_cont_final_common(FunctionCallInfo fcinfo,
if (!tuplesort_skiptuples(osastate->sortstate, first_row, true))
elog(ERROR, "missing row in percentile_cont");
- if (!tuplesort_getdatum(osastate->sortstate, true, &first_val, &isnull))
+ if (!tuplesort_getdatum(osastate->sortstate, true, &first_val, &isnull, NULL))
elog(ERROR, "missing row in percentile_cont");
if (isnull)
PG_RETURN_NULL();
@@ -564,7 +564,7 @@ percentile_cont_final_common(FunctionCallInfo fcinfo,
}
else
{
- if (!tuplesort_getdatum(osastate->sortstate, true, &second_val, &isnull))
+ if (!tuplesort_getdatum(osastate->sortstate, true, &second_val, &isnull, NULL))
elog(ERROR, "missing row in percentile_cont");
if (isnull)
@@ -792,7 +792,7 @@ percentile_disc_multi_final(PG_FUNCTION_ARGS)
if (!tuplesort_skiptuples(osastate->sortstate, target_row - rownum - 1, true))
elog(ERROR, "missing row in percentile_disc");
- if (!tuplesort_getdatum(osastate->sortstate, true, &val, &isnull))
+ if (!tuplesort_getdatum(osastate->sortstate, true, &val, &isnull, NULL))
elog(ERROR, "missing row in percentile_disc");
rownum = target_row;
@@ -921,7 +921,8 @@ percentile_cont_multi_final_common(FunctionCallInfo fcinfo,
if (!tuplesort_skiptuples(osastate->sortstate, first_row - rownum - 1, true))
elog(ERROR, "missing row in percentile_cont");
- if (!tuplesort_getdatum(osastate->sortstate, true, &first_val, &isnull) || isnull)
+ if (!tuplesort_getdatum(osastate->sortstate, true, &first_val,
+ &isnull, NULL) || isnull)
elog(ERROR, "missing row in percentile_cont");
rownum = first_row;
@@ -941,7 +942,8 @@ percentile_cont_multi_final_common(FunctionCallInfo fcinfo,
/* Fetch second_row if needed */
if (second_row > rownum)
{
- if (!tuplesort_getdatum(osastate->sortstate, true, &second_val, &isnull) || isnull)
+ if (!tuplesort_getdatum(osastate->sortstate, true, &second_val,
+ &isnull, NULL) || isnull)
elog(ERROR, "missing row in percentile_cont");
rownum++;
}
@@ -1016,6 +1018,8 @@ mode_final(PG_FUNCTION_ARGS)
int64 last_val_freq = 0;
bool last_val_is_mode = false;
FmgrInfo *equalfn;
+ Datum abbrev_val = (Datum) 0;
+ Datum last_abbrev_val = (Datum) 0;
bool shouldfree;
Assert(AggCheckCallContext(fcinfo, NULL) == AGG_CONTEXT_AGGREGATE);
@@ -1042,7 +1046,7 @@ mode_final(PG_FUNCTION_ARGS)
tuplesort_performsort(osastate->sortstate);
/* Scan tuples and count frequencies */
- while (tuplesort_getdatum(osastate->sortstate, true, &val, &isnull))
+ while (tuplesort_getdatum(osastate->sortstate, true, &val, &isnull, &abbrev_val))
{
/* we don't expect any nulls, but ignore them if found */
if (isnull)
@@ -1054,8 +1058,10 @@ mode_final(PG_FUNCTION_ARGS)
mode_val = last_val = val;
mode_freq = last_val_freq = 1;
last_val_is_mode = true;
+ last_abbrev_val = abbrev_val;
}
- else if (DatumGetBool(FunctionCall2(equalfn, val, last_val)))
+ else if (abbrev_val == last_abbrev_val &&
+ DatumGetBool(FunctionCall2(equalfn, val, last_val)))
{
/* value equal to previous value, count it */
if (last_val_is_mode)
@@ -1078,6 +1084,8 @@ mode_final(PG_FUNCTION_ARGS)
if (shouldfree && !last_val_is_mode)
pfree(DatumGetPointer(last_val));
last_val = val;
+ /* avoid equality function calls by reusing abbreviated keys */
+ last_abbrev_val = abbrev_val;
last_val_freq = 1;
last_val_is_mode = false;
}
@@ -1181,7 +1189,7 @@ hypothetical_rank_common(FunctionCallInfo fcinfo, int flag,
tuplesort_performsort(osastate->sortstate);
/* iterate till we find the hypothetical row */
- while (tuplesort_gettupleslot(osastate->sortstate, true, slot))
+ while (tuplesort_gettupleslot(osastate->sortstate, true, slot, NULL))
{
bool isnull;
Datum d = slot_getattr(slot, nargs + 1, &isnull);
@@ -1266,6 +1274,8 @@ hypothetical_dense_rank_final(PG_FUNCTION_ARGS)
int64 duplicate_count = 0;
OSAPerGroupState *osastate;
int numDistinctCols;
+ Datum abbrevVal = (Datum) 0;
+ Datum abbrevOld = (Datum) 0;
AttrNumber *sortColIdx;
FmgrInfo *equalfns;
TupleTableSlot *slot;
@@ -1342,7 +1352,7 @@ hypothetical_dense_rank_final(PG_FUNCTION_ARGS)
slot2 = extraslot;
/* iterate till we find the hypothetical row */
- while (tuplesort_gettupleslot(osastate->sortstate, true, slot))
+ while (tuplesort_gettupleslot(osastate->sortstate, true, slot, &abbrevVal))
{
bool isnull;
Datum d = slot_getattr(slot, nargs + 1, &isnull);
@@ -1353,6 +1363,7 @@ hypothetical_dense_rank_final(PG_FUNCTION_ARGS)
/* count non-distinct tuples */
if (!TupIsNull(slot2) &&
+ abbrevVal == abbrevOld &&
execTuplesMatch(slot, slot2,
numDistinctCols,
sortColIdx,
@@ -1363,6 +1374,8 @@ hypothetical_dense_rank_final(PG_FUNCTION_ARGS)
tmpslot = slot2;
slot2 = slot;
slot = tmpslot;
+ /* avoid execTuplesMatch() calls by reusing abbreviated keys */
+ abbrevOld = abbrevVal;
rank++;