On Wed, 27 Sept 2023 at 20:01, David Rowley <dgrowle...@gmail.com> wrote: > > On Sat, 23 Sept 2023 at 03:15, Heikki Linnakangas <hlinn...@iki.fi> wrote: > > So not a win in this case. Could you peek at the outer slot type, and > > use the same kind of slot for the Unique's result? Or some more > > complicated logic, like use a virtual slot if all the values are > > pass-by-val? I'd also like to keep this simple, though... > > > > Would this kind of optimization make sense elsewhere? > > There are a few usages of ExecGetResultSlotOps(). e.g ExecInitHashJoin(). > > If I adjust the patch to: > > - ExecInitResultTupleSlotTL(&uniquestate->ps, &TTSOpsMinimalTuple); > + ExecInitResultTupleSlotTL(&uniquestate->ps, > + > ExecGetResultSlotOps(outerPlanState(uniquestate), > + > NULL));
Just to keep this from going cold, here's that in patch form for anyone who wants to test. I spent a bit more time running some more benchmarks and I don't see any workload where it slows things down. I'd be happy if someone else had a go at finding a regression. David
diff --git a/src/backend/executor/nodeUnique.c b/src/backend/executor/nodeUnique.c index 01f951197c..be585e284b 100644 --- a/src/backend/executor/nodeUnique.c +++ b/src/backend/executor/nodeUnique.c @@ -115,6 +115,7 @@ UniqueState * ExecInitUnique(Unique *node, EState *estate, int eflags) { UniqueState *uniquestate; + const TupleTableSlotOps *ops; /* check for unsupported flags */ Assert(!(eflags & (EXEC_FLAG_BACKWARD | EXEC_FLAG_MARK))); @@ -137,11 +138,14 @@ ExecInitUnique(Unique *node, EState *estate, int eflags) */ outerPlanState(uniquestate) = ExecInitNode(outerPlan(node), estate, eflags); + /* initialize result slot and type */ + ops = ExecGetResultSlotOps(outerPlanState(uniquestate), NULL); + ExecInitResultTupleSlotTL(&uniquestate->ps, ops); + /* - * Initialize result slot and type. Unique nodes do no projections, so - * initialize projection info for this node appropriately. + * Unique nodes do no projections, so initialize projection info for this + * node appropriately. */ - ExecInitResultTupleSlotTL(&uniquestate->ps, &TTSOpsMinimalTuple); uniquestate->ps.ps_ProjInfo = NULL; /*