diff options
author | Robert Haas <rhaas@postgresql.org> | 2016-02-17 15:40:00 +0530 |
---|---|---|
committer | Robert Haas <rhaas@postgresql.org> | 2016-02-17 15:40:00 +0530 |
commit | f1f5ec1efafe74ca45e24e0bf3371b1d6985c8ee (patch) | |
tree | eab628891c0c2250d87bc703e27af7ca88fb9c0f /src/backend/utils/adt | |
parent | 66f503868b2ac1163aaf48a2f76d8be02af0bc81 (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.c | 33 |
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++; |