Tighten up sanity checks for parallel aggregate in execQual.c.
authorRobert Haas
Wed, 27 Apr 2016 16:05:35 +0000 (12:05 -0400)
committerRobert Haas
Wed, 27 Apr 2016 16:05:35 +0000 (12:05 -0400)
David Rowley

src/backend/executor/execQual.c

index 4df4a9b0f7d4587c0679ad1a6c06210332530e23..c0ca58bbb4d348258195c7ebf05cda15877b6ab6 100644 (file)
@@ -4510,28 +4510,35 @@ ExecInitExpr(Expr *node, PlanState *parent)
        case T_Aggref:
            {
                AggrefExprState *astate = makeNode(AggrefExprState);
+               AggState   *aggstate = (AggState *) parent;
+               Aggref     *aggref = (Aggref *) node;
 
                astate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalAggref;
-               if (parent && IsA(parent, AggState))
+               if (!aggstate || !IsA(aggstate, AggState))
                {
-                   AggState   *aggstate = (AggState *) parent;
-                   Aggref     *aggref = (Aggref *) node;
-
-                   if (aggstate->finalizeAggs &&
-                       aggref->aggoutputtype != aggref->aggtype)
-                   {
-                       /* planner messed up */
-                       elog(ERROR, "Aggref aggoutputtype must match aggtype");
-                   }
-
-                   aggstate->aggs = lcons(astate, aggstate->aggs);
-                   aggstate->numaggs++;
+                   /* planner messed up */
+                   elog(ERROR, "Aggref found in non-Agg plan node");
                }
-               else
+               if (aggref->aggpartial == aggstate->finalizeAggs)
                {
                    /* planner messed up */
-                   elog(ERROR, "Aggref found in non-Agg plan node");
+                   if (aggref->aggpartial)
+                       elog(ERROR, "partial Aggref found in finalize agg plan node");
+                   else
+                       elog(ERROR, "non-partial Aggref found in non-finalize agg plan node");
                }
+
+               if (aggref->aggcombine != aggstate->combineStates)
+               {
+                   /* planner messed up */
+                   if (aggref->aggcombine)
+                       elog(ERROR, "combine Aggref found in non-combine agg plan node");
+                   else
+                       elog(ERROR, "non-combine Aggref found in combine agg plan node");
+               }
+
+               aggstate->aggs = lcons(astate, aggstate->aggs);
+               aggstate->numaggs++;
                state = (ExprState *) astate;
            }
            break;