Agg fuckwittery.
authorAndres Freund <andres@anarazel.de>
Tue, 14 Mar 2017 03:22:10 +0000 (20:22 -0700)
committerAndres Freund <andres@anarazel.de>
Tue, 14 Mar 2017 06:34:03 +0000 (23:34 -0700)
Author:
Reviewed-By:
Discussion: https://postgr.es/m/
Backpatch:

src/backend/executor/nodeAgg.c

index 730f9c315304817c47d8326f7a6da10eb46562ac..93ba676f590634fa38f37bbc01bcd3c0fda28c43 100644 (file)
@@ -690,22 +690,23 @@ initialize_aggregates(AggState *aggstate,
    int         numGroupingSets = Max(aggstate->phase->numsets, 1);
    int         setno = 0;
    AggStatePerTrans pertrans;
+   AggStatePerGroup pergroupstate;
 
    if (numReset < 1)
        numReset = numGroupingSets;
 
+   pergroupstate = &pergroup[0];
    for (transno = 0, pertrans = &aggstate->pertrans[0];
         transno < aggstate->numtrans; transno++, pertrans++)
    {
-       for (setno = 0; setno < numReset; setno++)
+       for (setno = 0; setno < numGroupingSets; setno++)
        {
-           AggStatePerGroup pergroupstate;
-
-           pergroupstate = &pergroup[transno + (setno * (aggstate->numtrans))];
-
-           aggstate->current_set = setno;
-
-           initialize_aggregate(aggstate, pertrans, pergroupstate);
+           if (setno < numReset)
+           {
+               aggstate->current_set = setno;
+               initialize_aggregate(aggstate, pertrans, pergroupstate);
+           }
+           pergroupstate++;
        }
    }
 }
@@ -721,7 +722,7 @@ initialize_aggregates(AggState *aggstate,
  *
  * It doesn't matter which memory context this is called in.
  */
-static void
+static inline void
 advance_transition_function(AggState *aggstate,
                            AggStatePerTrans pertrans,
                            AggStatePerGroup pergroupstate)
@@ -842,7 +843,7 @@ advance_transition_function(AggState *aggstate,
  *
  * When called, CurrentMemoryContext should be the per-query context.
  */
-static void
+static inline void
 advance_aggregates(AggState *aggstate, AggStatePerGroup pergroup)
 {
    int         transno;
@@ -850,7 +851,10 @@ advance_aggregates(AggState *aggstate, AggStatePerGroup pergroup)
    int         numGroupingSets = Max(aggstate->phase->numsets, 1);
    int         numTrans = aggstate->numtrans;
    TupleTableSlot *slot = aggstate->evalslot;
+   Datum      *values = slot->tts_values;
+   bool       *nulls = slot->tts_isnull;
    AggStatePerTrans pertrans;
+   AggStatePerGroup pergroupstate = &pergroup[0];
 
    /* compute input for all aggregates */
    if (aggstate->evalproj)
@@ -873,7 +877,10 @@ advance_aggregates(AggState *aggstate, AggStatePerGroup pergroup)
            res = ExecEvalExprSwitchContext(filter, aggstate->tmpcontext,
                                            &isnull);
            if (isnull || !DatumGetBool(res))
+           {
+               pergroupstate += numGroupingSets;
                continue;
+           }
        }
 
        if (pertrans->numSortCols > 0)
@@ -896,7 +903,10 @@ advance_aggregates(AggState *aggstate, AggStatePerGroup pergroup)
                        break;
                }
                if (i < numTransInputs)
+               {
+                   pergroupstate += numGroupingSets;
                    continue;
+               }
            }
 
            for (setno = 0; setno < numGroupingSets; setno++)
@@ -904,8 +914,7 @@ advance_aggregates(AggState *aggstate, AggStatePerGroup pergroup)
                /* OK, put the tuple into the tuplesort object */
                if (pertrans->numInputs == 1)
                    tuplesort_putdatum(pertrans->sortstates[setno],
-                                      slot->tts_values[inputoff],
-                                      slot->tts_isnull[inputoff]);
+                                      values[inputoff], nulls[inputoff]);
                else
                {
                    /*
@@ -914,15 +923,17 @@ advance_aggregates(AggState *aggstate, AggStatePerGroup pergroup)
                     */
                    ExecClearTuple(pertrans->sortslot);
                    memcpy(pertrans->sortslot->tts_values,
-                          &slot->tts_values[inputoff],
+                          &values[inputoff],
                           pertrans->numInputs * sizeof(Datum));
                    memcpy(pertrans->sortslot->tts_isnull,
-                          &slot->tts_isnull[inputoff],
+                          &nulls[inputoff],
                           pertrans->numInputs * sizeof(bool));
                    pertrans->sortslot->tts_nvalid = pertrans->numInputs;
                    ExecStoreVirtualTuple(pertrans->sortslot);
                    tuplesort_puttupleslot(pertrans->sortstates[setno], pertrans->sortslot);
                }
+
+               pergroupstate++;
            }
        }
        else
@@ -936,17 +947,17 @@ advance_aggregates(AggState *aggstate, AggStatePerGroup pergroup)
 
            for (i = 0; i < numTransInputs; i++)
            {
-               fcinfo->arg[i + 1] = slot->tts_values[i + inputoff];
-               fcinfo->argnull[i + 1] = slot->tts_isnull[i + inputoff];
+               fcinfo->arg[i + 1] = values[i + inputoff];
+               fcinfo->argnull[i + 1] = nulls[i + inputoff];
            }
 
            for (setno = 0; setno < numGroupingSets; setno++)
            {
-               AggStatePerGroup pergroupstate = &pergroup[transno + (setno * numTrans)];
-
                aggstate->current_set = setno;
 
                advance_transition_function(aggstate, pertrans, pergroupstate);
+
+               pergroupstate++;
            }
        }
    }
@@ -1575,6 +1586,7 @@ finalize_aggregates(AggState *aggstate,
    bool       *aggnulls = econtext->ecxt_aggnulls;
    int         aggno;
    int         transno;
+   int         numGroupingSets = Max(aggstate->phase->numsets, 1);
 
    Assert(currentSet == 0 ||
           ((Agg *) aggstate->ss.ps.plan)->aggstrategy != AGG_HASHED);
@@ -1590,7 +1602,7 @@ finalize_aggregates(AggState *aggstate,
        AggStatePerTrans pertrans = &aggstate->pertrans[transno];
        AggStatePerGroup pergroupstate;
 
-       pergroupstate = &pergroup[transno + (currentSet * (aggstate->numtrans))];
+       pergroupstate = &pergroup[(transno * numGroupingSets) + currentSet];
 
        if (pertrans->numSortCols > 0)
        {
@@ -2279,6 +2291,9 @@ agg_fill_hash_table(AggState *aggstate)
        /* Find or build hashtable entry for this tuple's group */
        entry = lookup_hash_entry(aggstate, outerslot);
 
+       if (aggstate->phase->numsets > 1)
+           __builtin_unreachable();
+
        /* Advance the aggregates */
        if (DO_AGGSPLIT_COMBINE(aggstate->aggsplit))
            combine_aggregates(aggstate, (AggStatePerGroup) entry->additional);