1/*-------------------------------------------------------------------------
4 * Routines to handle unique'ing of queries where appropriate
6 * Unique is a very simple node type that just filters out duplicate
7 * tuples from a stream of sorted tuples from its subplan. It's essentially
8 * a dumbed-down form of Group: the duplicate-removal functionality is
9 * identical. However, Unique doesn't do projection nor qual checking,
10 * so it's marginally more efficient for cases where neither is needed.
11 * (It's debatable whether the savings justifies carrying two plan node
14 * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group
15 * Portions Copyright (c) 1994, Regents of the University of California
19 * src/backend/executor/nodeUnique.c
21 *-------------------------------------------------------------------------
25 * ExecUnique - generate a unique'd temporary relation
26 * ExecInitUnique - initialize node and subnodes
27 * ExecEndUnique - shutdown node and subnodes
30 * Assumes tuples returned from subplan arrive in
41/* ----------------------------------------------------------------
43 * ----------------------------------------------------------------
57 * get information from the node
63 * now loop, returning only non-duplicate tuples. We assume that the
64 * tuples arrive in sorted order so we can detect duplicates easily. The
65 * first tuple of each group is returned.
70 * fetch a tuple from the outer subplan
75 /* end of subplan, so we're done */
81 * Always return the first tuple from the subplan.
87 * Else test if the new tuple and the previously returned tuple match.
88 * If so then we loop back and fetch another new tuple from the
98 * We have a new tuple different from the previous saved tuple (if any).
99 * Save it and return it. We must copy it because the source subplan
100 * won't guarantee that this source tuple is still accessible after
101 * fetching the next source tuple.
106/* ----------------------------------------------------------------
109 * This initializes the unique node state structures and
110 * the node's subplan.
111 * ----------------------------------------------------------------
118 /* check for unsupported flags */
122 * create state structure
126 uniquestate->
ps.
state = estate;
130 * create expression context
135 * then initialize outer plan
140 * Initialize result slot and type. Unique nodes do no projections, so
141 * initialize projection info for this node appropriately.
147 * Precompute fmgr lookup data for inner loop
154 node->uniqCollations,
160/* ----------------------------------------------------------------
163 * This shuts down the subplan and frees resources allocated
165 * ----------------------------------------------------------------
179 /* must clear result tuple so first input tuple is returned */
183 * if chgParam of subnode is not null then plan will be re-scanned by
184 * first ExecProcNode.
void ExecReScan(PlanState *node)
ExprState * execTuplesMatchPrepare(TupleDesc desc, int numCols, const AttrNumber *keyColIdx, const Oid *eqOperators, const Oid *collations, PlanState *parent)
void ExecEndNode(PlanState *node)
PlanState * ExecInitNode(Plan *node, EState *estate, int eflags)
void ExecInitResultTupleSlotTL(PlanState *planstate, const TupleTableSlotOps *tts_ops)
const TupleTableSlotOps TTSOpsMinimalTuple
TupleDesc ExecGetResultType(PlanState *planstate)
void ExecAssignExprContext(EState *estate, PlanState *planstate)
#define outerPlanState(node)
#define EXEC_FLAG_BACKWARD
static bool ExecQualAndReset(ExprState *state, ExprContext *econtext)
static TupleTableSlot * ExecProcNode(PlanState *node)
Assert(PointerIsAligned(start, uint64))
#define CHECK_FOR_INTERRUPTS()
void ExecEndUnique(UniqueState *node)
static TupleTableSlot * ExecUnique(PlanState *pstate)
void ExecReScanUnique(UniqueState *node)
UniqueState * ExecInitUnique(Unique *node, EState *estate, int eflags)
#define castNode(_type_, nodeptr)
TupleTableSlot * ecxt_innertuple
TupleTableSlot * ecxt_outertuple
ExprContext * ps_ExprContext
TupleTableSlot * ps_ResultTupleSlot
ProjectionInfo * ps_ProjInfo
ExecProcNodeMtd ExecProcNode
static TupleTableSlot * ExecClearTuple(TupleTableSlot *slot)
static TupleTableSlot * ExecCopySlot(TupleTableSlot *dstslot, TupleTableSlot *srcslot)