Hi,
On 2019-05-30 16:31:39 +0530, Ashutosh Sharma wrote:
> > *Analysis:*
> > I did some quick investigation on this and found that when the aggregate
> > is performed on the first group i.e. group by 'a', all the input tuples are
> > fetched from the outer plan and stored into the tuplesort object and for
> > the subsequent groups i.e. from the second group onwards, the tuples stored
> > in tuplessort object during 1st phase is used. But, then, the tuples stored
> > in the tuplesort object are actually the minimal tuples whereas it is
> > expected to be a heap tuple which actually results into the assertion
> > failure.
> >
> > I might be wrong, but it seems to me like the slot fetched from tuplesort
> > object needs to be converted to the heap tuple. Actually the following
> > lines of code in agg_retrieve_direct() gets executed only when we have
> > crossed a group boundary. I think, at least the function call to
> > ExecCopySlotHeapTuple(outerslot); followed by ExecForceStoreHeapTuple();
> > should always happen irrespective of the group boundary limit is crossed or
> > not... Sorry if I'm saying something ...
I think that's mostly the right diagnosis, but I think it's not the
right fix. We can just flag here that the slot type isn't fixed - we're
not using any slot type specific functions, we just are promising that
the slot type doesn't change (mostly for the benefit of JIT compiled
deforming, which needs to generate different code for different slot
types).
I've pushed a fix for that. As the commit explains:
https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=af3deff3f2ac79585481181cb198b04c67486c09
we probably could quite easily optimize this case further by setting the
slot type separately for each "phase" of grouping set processing. As we
already generate separate expressions for each phase, that should be
quite doable. But that's something for another day, and not for v12.
Greetings,
Andres Freund