diff --git a/ql/src/java/org/apache/hadoop/hive/ql/optimizer/calcite/cost/HiveVolcanoPlanner.java b/ql/src/java/org/apache/hadoop/hive/ql/optimizer/calcite/cost/HiveVolcanoPlanner.java index fbf2202679..8a462d8292 100644 --- a/ql/src/java/org/apache/hadoop/hive/ql/optimizer/calcite/cost/HiveVolcanoPlanner.java +++ b/ql/src/java/org/apache/hadoop/hive/ql/optimizer/calcite/cost/HiveVolcanoPlanner.java @@ -48,7 +48,7 @@ private static final boolean ENABLE_COLLATION_TRAIT = true; private final boolean isHeuristic; - private static final double FACTOR = 0.2d; + private static final double FACTOR = 0.00001d; /** Creates a HiveVolcanoPlanner. */ @@ -121,15 +121,19 @@ public RelOptCost getCost(RelNode rel, RelMetadataQuery mq) { } } if (isHeuristic && usesMaterializedViews) { - cost = costFactory.makeTinyCost(); + // If a child of this expression uses a materialized view, + // then we decrease its cost by a certain factor. This is + // useful for e.g. partial rewritings, where a part of plan + // does not use the materialization, but we still want to + // decrease its cost so it is chosen instead of the original + // plan + cost = cost.multiplyBy(FACTOR); + if (!costFactory.makeZeroCost().isLt(cost)) { + // cost must be positive, so nudge it + cost = costFactory.makeTinyCost(); + } for (RelNode input : rel.getInputs()) { - // If a child of this expression uses a materialized view, - // then we decrease its cost by a certain factor. This is - // useful for e.g. partial rewritings, where a part of plan - // does not use the materialization, but we still want to - // decrease its cost so it is chosen instead of the original - // plan - cost = cost.plus(getCost(input, mq).multiplyBy(FACTOR)); + cost = cost.plus(getCost(input, mq)); } } else { // No materialized view or not heuristic approach, normal costing