dynamobi/dynamobi — Issue #803: [FRG-67] RelSubset.getRows() always returns 1
Author: dynamobi-build
Created: 2011-12-30 03:49:47+00:00
State: open
Labels: FRG, Volcano Planner

[reporter="jvs", created="Thu, 9 Mar 2006 16:48:42 -0500 (GMT-05:00)"]
The pattern in most non-leaf rels for implementing RelNode.getRows() is to compute some function of the child's row-count, e.g. for FilterRel:

public double getRows()

{

return getChild().getRows() * RexUtil.getSelectivity(condition);

}

Most rels also use getRows() in implementing computeSelfCost(). Unfortunately, throughout all of planning except the very final phase (buildCheapestPlan), the child is always a RelSubset equivalence class, not any particular rel. And RelSubset inherits its getRows implementation from AbstractRelNode, which always returns 1. So most of the costs used for plan selection come out highly bogus. It's easy to overlook this without tracing because EXPLAIN PLAN INCLUDING ALL ATTRIBUTES shows the final (correctly propagated) rowcounts.

FennelWindowRel is the one exception I have found; it does this:

RelOptCost childCost = planner.getCost(getChild());

final double rowsIn = childCost.getRows();

This isn't really correct either, because VolcanoPlanner.getCost sums the total number of rows from all descendants, not just the immediate child. But at least the author seems to have realized that SOMETHING better was needed. :)

Anyway, perhaps the implementation of RelSubset.getRows should be changed to use the logic from VolcanoPlanner.getCost:

if (rel instanceof RelSubset) {

return ((RelSubset) rel).bestCost;

}

so return bestCost.getRows().

Or am I totally misunderstanding things?