Planner.buildSide and the merge-versus-hash choice,
kept so :explain can show them.
Why beside the plan and not on it
PhysicalNode is a sealed hierarchy of records. Carrying the
estimate as a component would touch every arm and every construction site, and —
the deciding argument — it would make the estimate part of node
identity: two structurally identical plans costed under different
statistics would stop being equals, which is a property the plan itself
has no business having. A side table keeps the nodes clean and matches what
SchemaAnnotations already does for logical nodes.
Identity, not equality
The map is an IdentityHashMap, because two sibling nodes of a plan can
easily be equals — A ⨝ A is a legal self-join, and its two
Scans are equal records — while being estimated in different contexts.
Keying on equality would let one overwrite the other.
Unknown is not zero
rows returns OptionalLong.empty() both for a node the planner
never estimated and for one whose estimate the cost model declined to make.
That is deliberately not collapsed to 0: the estimator is
documented as honest, returning empty rather than fabricating a number when a
contributing leaf has no row count, and a plan step that will produce nothing is a
materially different claim from one nobody costed. Renderers must keep the two
apart — rows=? versus rows=0, null versus 0 in
JSON.
Instances are mutable during planning and effectively immutable afterwards;
they are not thread-safe, and a Planner plans one root.
-
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionbooleanisEmpty()Returns whether any estimate at all was recorded — the cheap test a renderer uses to decide whether to add a numeric column.static PlanEstimatesnone()Returns a shared empty instance — every lookup is unknown.voidrecord(PhysicalNode node, OptionalLong estimate) Recordsestimatefornode, if it is present.rows(PhysicalNode node) Returns the estimated row count fornode.
-
Constructor Details
-
PlanEstimates
public PlanEstimates()Creates an empty set of estimates.
-
-
Method Details
-
none
Returns a shared empty instance — every lookup is unknown. Use it where a plan is rendered outside a planning run (a hand-built plan in a test, or a printer call that has no estimates to hand).- Returns:
- the empty estimates; never null
-
record
Recordsestimatefornode, if it is present. An absent estimate is not stored, so "unknown" has exactly one representation.- Parameters:
node- the plan node; must not be nullestimate- the estimated row count, or empty if the cost model declined
-
rows
Returns the estimated row count fornode.- Parameters:
node- the plan node; must not be null- Returns:
- the estimate, or empty when unknown — which is not zero
-
isEmpty
public boolean isEmpty()Returns whether any estimate at all was recorded — the cheap test a renderer uses to decide whether to add a numeric column.- Returns:
trueif at least one node has a known estimate
-