On Wed, 27 Sept 2023 at 20:01, David Rowley <[email protected]> wrote:
>
> On Sat, 23 Sept 2023 at 03:15, Heikki Linnakangas <[email protected]> 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;
/*