org.apache.calcite.plan.volcano.RelSubset Java Examples

The following examples show how to use org.apache.calcite.plan.volcano.RelSubset. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: FlinkAggregateJoinTransposeRule.java    From flink with Apache License 2.0 6 votes vote down vote up
private boolean containsSnapshot(RelNode relNode) {
	RelNode original = null;
	if (relNode instanceof RelSubset) {
		original = ((RelSubset) relNode).getOriginal();
	} else if (relNode instanceof HepRelVertex) {
		original = ((HepRelVertex) relNode).getCurrentRel();
	} else {
		original = relNode;
	}
	if (original instanceof LogicalSnapshot) {
		return true;
	} else if (original instanceof SingleRel) {
		return containsSnapshot(((SingleRel) original).getInput());
	} else {
		return false;
	}
}
 
Example #2
Source File: RelMdDistinctRowCount.java    From Bats with Apache License 2.0 6 votes vote down vote up
public Double getDistinctRowCount(RelSubset rel, RelMetadataQuery mq,
    ImmutableBitSet groupKey, RexNode predicate) {
  final RelNode best = rel.getBest();
  if (best != null) {
    return mq.getDistinctRowCount(best, groupKey, predicate);
  }
  if (!Bug.CALCITE_1048_FIXED) {
    return getDistinctRowCount((RelNode) rel, mq, groupKey, predicate);
  }
  Double d = null;
  for (RelNode r2 : rel.getRels()) {
    try {
      Double d2 = mq.getDistinctRowCount(r2, groupKey, predicate);
      d = NumberUtil.min(d, d2);
    } catch (CyclicMetadataException e) {
      // Ignore this relational expression; there will be non-cyclic ones
      // in this set.
    }
  }
  return d;
}
 
Example #3
Source File: StreamExecPythonCorrelateRule.java    From flink with Apache License 2.0 6 votes vote down vote up
private StreamExecPythonCorrelate convertToCorrelate(
	RelNode relNode,
	Option<RexNode> condition) {
	if (relNode instanceof RelSubset) {
		RelSubset rel = (RelSubset) relNode;
		return convertToCorrelate(rel.getRelList().get(0), condition);
	} else if (relNode instanceof FlinkLogicalCalc) {
		FlinkLogicalCalc calc = (FlinkLogicalCalc) relNode;
		RelNode tableScan = StreamExecCorrelateRule.getTableScan(calc);
		FlinkLogicalCalc newCalc = StreamExecCorrelateRule.getMergedCalc(calc);
		return convertToCorrelate(
			tableScan,
			Some.apply(newCalc.getProgram().expandLocalRef(newCalc.getProgram().getCondition())));
	} else {
		FlinkLogicalTableFunctionScan scan = (FlinkLogicalTableFunctionScan) relNode;
		return new StreamExecPythonCorrelate(
			correlate.getCluster(),
			traitSet,
			convInput,
			null,
			scan,
			condition,
			correlate.getRowType(),
			correlate.getJoinType());
	}
}
 
Example #4
Source File: RelMdColumnUniqueness.java    From Bats with Apache License 2.0 6 votes vote down vote up
public Boolean areColumnsUnique(RelSubset rel, RelMetadataQuery mq,
    ImmutableBitSet columns, boolean ignoreNulls) {
  int nullCount = 0;
  for (RelNode rel2 : rel.getRels()) {
    if (rel2 instanceof Aggregate
        || rel2 instanceof Filter
        || rel2 instanceof Values
        || rel2 instanceof TableScan
        || simplyProjects(rel2, columns)) {
      try {
        final Boolean unique = mq.areColumnsUnique(rel2, columns, ignoreNulls);
        if (unique != null) {
          if (unique) {
            return true;
          }
        } else {
          ++nullCount;
        }
      } catch (CyclicMetadataException e) {
        // Ignore this relational expression; there will be non-cyclic ones
        // in this set.
      }
    }
  }
  return nullCount == 0 ? false : null;
}
 
Example #5
Source File: FlinkAggregateJoinTransposeRule.java    From flink with Apache License 2.0 6 votes vote down vote up
private boolean containsSnapshot(RelNode relNode) {
	RelNode original = null;
	if (relNode instanceof RelSubset) {
		original = ((RelSubset) relNode).getOriginal();
	} else if (relNode instanceof HepRelVertex) {
		original = ((HepRelVertex) relNode).getCurrentRel();
	} else {
		original = relNode;
	}
	if (original instanceof LogicalSnapshot) {
		return true;
	} else if (original instanceof SingleRel) {
		return containsSnapshot(((SingleRel) original).getInput());
	} else {
		return false;
	}
}
 
Example #6
Source File: RelMdPredicates.java    From Bats with Apache License 2.0 6 votes vote down vote up
/** @see RelMetadataQuery#getPulledUpPredicates(RelNode) */
public RelOptPredicateList getPredicates(RelSubset r,
    RelMetadataQuery mq) {
  if (!Bug.CALCITE_1048_FIXED) {
    return RelOptPredicateList.EMPTY;
  }
  final RexBuilder rexBuilder = r.getCluster().getRexBuilder();
  RelOptPredicateList list = null;
  for (RelNode r2 : r.getRels()) {
    RelOptPredicateList list2 = mq.getPulledUpPredicates(r2);
    if (list2 != null) {
      list = list == null ? list2 : list.union(rexBuilder, list2);
    }
  }
  return Util.first(list, RelOptPredicateList.EMPTY);
}
 
Example #7
Source File: PruneEmptyRules.java    From calcite with Apache License 2.0 6 votes vote down vote up
private static boolean isEmpty(RelNode node) {
  if (node instanceof Values) {
    return ((Values) node).getTuples().isEmpty();
  }
  if (node instanceof HepRelVertex) {
    return isEmpty(((HepRelVertex) node).getCurrentRel());
  }
  // Note: relation input might be a RelSubset, so we just iterate over the relations
  // in order to check if the subset is equivalent to an empty relation.
  if (!(node instanceof RelSubset)) {
    return false;
  }
  RelSubset subset = (RelSubset) node;
  for (RelNode rel : subset.getRels()) {
    if (isEmpty(rel)) {
      return true;
    }
  }
  return false;
}
 
Example #8
Source File: AbstractPythonCorrelateRuleBase.java    From flink with Apache License 2.0 6 votes vote down vote up
@Override
public boolean matches(RelOptRuleCall call) {
	FlinkLogicalCorrelate join = call.rel(0);
	RelNode right = ((RelSubset) join.getRight()).getOriginal();

	if (right instanceof FlinkLogicalTableFunctionScan) {
		// right node is a python table function
		return PythonUtil.isPythonCall(((FlinkLogicalTableFunctionScan) right).getCall(), null);
	} else if (right instanceof FlinkLogicalCalc) {
		// a filter is pushed above the table function
		FlinkLogicalCalc calc = (FlinkLogicalCalc) right;
		Option<FlinkLogicalTableFunctionScan> scan = CorrelateUtil.getTableFunctionScan(calc);
		return scan.isDefined() && PythonUtil.isPythonCall(scan.get().getCall(), null);
	}
	return false;
}
 
Example #9
Source File: AbstractPythonCorrelateRuleBase.java    From flink with Apache License 2.0 6 votes vote down vote up
private RelNode convertToCorrelate(
	RelNode relNode,
	Option<RexNode> condition) {
	if (relNode instanceof RelSubset) {
		RelSubset rel = (RelSubset) relNode;
		return convertToCorrelate(rel.getRelList().get(0), condition);
	} else if (relNode instanceof FlinkLogicalCalc) {
		FlinkLogicalCalc calc = (FlinkLogicalCalc) relNode;
		FlinkLogicalTableFunctionScan tableScan = CorrelateUtil.getTableFunctionScan(calc).get();
		FlinkLogicalCalc newCalc = CorrelateUtil.getMergedCalc(calc);
		return convertToCorrelate(
			tableScan,
			Some.apply(newCalc.getProgram().expandLocalRef(newCalc.getProgram().getCondition())));
	} else {
		return createPythonCorrelateNode(relNode, condition);
	}
}
 
Example #10
Source File: JoinUtils.java    From dremio-oss with Apache License 2.0 6 votes vote down vote up
/**
 * Utility method to check if a subquery (represented by its root RelNode) is provably scalar. Currently
 * only aggregates with no group-by are considered scalar. In the future, this method should be generalized
 * to include more cases and reconciled with Calcite's notion of scalar.
 * @param root The root RelNode to be examined
 * @return True if the root rel or its descendant is scalar, False otherwise
 */
public static boolean isScalarSubquery(RelNode root) {
  AggregateRel agg = null;
  RelNode currentrel = root;
  while (agg == null && currentrel != null) {
    if (currentrel instanceof AggregateRel) {
      agg = (AggregateRel)currentrel;
    } else if (currentrel instanceof RelSubset) {
      currentrel = ((RelSubset)currentrel).getBest() ;
    } else if (currentrel.getInputs().size() == 1) {
      // If the rel is not an aggregate or RelSubset, but is a single-input rel (could be Project,
      // Filter, Sort etc.), check its input
      currentrel = currentrel.getInput(0);
    } else {
      break;
    }
  }

  if (agg != null) {
    if (agg.getGroupSet().isEmpty()) {
      return true;
    }
  }
  return false;
}
 
Example #11
Source File: RelMdPredicates.java    From calcite with Apache License 2.0 6 votes vote down vote up
/** @see RelMetadataQuery#getPulledUpPredicates(RelNode) */
public RelOptPredicateList getPredicates(RelSubset r,
    RelMetadataQuery mq) {
  if (!Bug.CALCITE_1048_FIXED) {
    return RelOptPredicateList.EMPTY;
  }
  final RexBuilder rexBuilder = r.getCluster().getRexBuilder();
  RelOptPredicateList list = null;
  for (RelNode r2 : r.getRels()) {
    RelOptPredicateList list2 = mq.getPulledUpPredicates(r2);
    if (list2 != null) {
      list = list == null ? list2 : list.union(rexBuilder, list2);
    }
  }
  return Util.first(list, RelOptPredicateList.EMPTY);
}
 
Example #12
Source File: IndexPlanUtils.java    From Bats with Apache License 2.0 6 votes vote down vote up
static private boolean isFullQuery(IndexCallContext indexContext) {
  RelNode rootInCall = indexContext.getCall().rel(0);
  // check if the tip of the operator stack we have is also the top of the whole query, if yes, return true
  if (indexContext.getCall().getPlanner().getRoot() instanceof RelSubset) {
    final RelSubset rootSet = (RelSubset) indexContext.getCall().getPlanner().getRoot();
    if (rootSet.getRelList().contains(rootInCall)) {
      return true;
    }
  } else {
    if (indexContext.getCall().getPlanner().getRoot().equals(rootInCall)) {
      return true;
    }
  }

  return false;
}
 
Example #13
Source File: DrillPushRowKeyJoinToScanRule.java    From Bats with Apache License 2.0 6 votes vote down vote up
private static boolean canSwapJoinInputsInternal(RelNode rel) {
  if (rel instanceof DrillAggregateRel &&
      ((DrillAggregateRel) rel).getAggCallList().size() > 0) {
    return false;
  } else if (rel instanceof HepRelVertex) {
    return canSwapJoinInputsInternal(((HepRelVertex) rel).getCurrentRel());
  } else if (rel instanceof RelSubset) {
    if (((RelSubset) rel).getBest() != null) {
      return canSwapJoinInputsInternal(((RelSubset) rel).getBest());
    } else {
      return canSwapJoinInputsInternal(((RelSubset) rel).getOriginal());
    }
  } else {
    for (RelNode child : rel.getInputs()) {
      if (!canSwapJoinInputsInternal(child)) {
        return false;
      }
    }
  }
  return true;
}
 
Example #14
Source File: DrillPushRowKeyJoinToScanRule.java    From Bats with Apache License 2.0 6 votes vote down vote up
public static RelNode getValidJoinInput(RelNode rel) {
  if (rel instanceof DrillScanRel) {
    return rel;
  } else if (rel instanceof DrillProjectRel
      || rel instanceof DrillFilterRel
      || rel instanceof DrillLimitRel) {
    for (RelNode child : rel.getInputs()) {
      RelNode tgt = getValidJoinInput(child);
      if (tgt != null) {
        return tgt;
      }
    }
  } else if (rel instanceof HepRelVertex) {
    return getValidJoinInput(((HepRelVertex) rel).getCurrentRel());
  } else if (rel instanceof RelSubset) {
    if (((RelSubset) rel).getBest() != null) {
      return getValidJoinInput(((RelSubset) rel).getBest());
    } else {
      return getValidJoinInput(((RelSubset) rel).getOriginal());
    }
  }
  return null;
}
 
Example #15
Source File: SubsetTransformer.java    From dremio-oss with Apache License 2.0 6 votes vote down vote up
boolean go(T n, RelNode candidateSet) throws E {
  if ( !(candidateSet instanceof RelSubset) ) {
    return false;
  }

  boolean transform = false;
  for (RelNode rel : ((RelSubset)candidateSet).getRelList()) {
    if (isPhysical(rel)) {
      RelNode newRel = RelOptRule.convert(candidateSet, rel.getTraitSet().plus(Prel.PHYSICAL).simplify());
      RelNode out = convertChild(n, newRel);
      if (out != null) {
        call.transformTo(out);
        transform = true;
      }
    }
  }


  return transform;
}
 
Example #16
Source File: DistributionTraitDef.java    From dremio-oss with Apache License 2.0 6 votes vote down vote up
@Override
public boolean canConvert(
    RelOptPlanner planner, DistributionTrait fromTrait, DistributionTrait toTrait, RelNode fromRel) {
  if (fromTrait.equals(toTrait)) {
    return true;
  }

  // Source trait is "ANY", which is abstract type of distribution.
  // We do not want to convert from "ANY", since it's abstract.
  // Source trait should be concrete type: SINGLETON, HASH_DISTRIBUTED, etc.
  if (fromTrait.equals(DistributionTrait.DEFAULT) && !(fromRel instanceof RelSubset) ) {
    return false;
  }

  // It is only possible to apply a distribution trait to a PHYSICAL convention.
  if (fromRel.getConvention() != Prel.PHYSICAL) {
    return false;
  }
  if (fromTrait.getType() == DistributionType.BROADCAST_DISTRIBUTED && toTrait.getType() == DistributionType.HASH_DISTRIBUTED) {
    return false;
  }
  return true;
}
 
Example #17
Source File: RuntimeFilterVisitor.java    From Bats with Apache License 2.0 6 votes vote down vote up
/**
 * Find a join condition's left input source scan Prel. If we can't find a target scan Prel then this
 * RuntimeFilter can not pushed down to a probe side scan Prel.
 *
 * @param fieldName   left join condition field Name
 * @param leftRelNode left RelNode of a BiRel or the SingleRel
 * @return a left scan Prel which contains the left join condition name or null
 */
private ScanPrel findLeftScanPrel(String fieldName, RelNode leftRelNode) {
  if (leftRelNode instanceof ScanPrel) {
    RelDataType scanRowType = leftRelNode.getRowType();
    RelDataTypeField field = scanRowType.getField(fieldName, true, true);
    if (field != null) {
      //found
      return (ScanPrel) leftRelNode;
    } else {
      return null;
    }
  } else if (leftRelNode instanceof RelSubset) {
    RelNode bestNode = ((RelSubset) leftRelNode).getBest();
    if (bestNode != null) {
      return findLeftScanPrel(fieldName, bestNode);
    } else {
      return null;
    }
  } else {
    List<RelNode> relNodes = leftRelNode.getInputs();
    RelNode leftNode = relNodes.get(0);
    return findLeftScanPrel(fieldName, leftNode);
  }
}
 
Example #18
Source File: RuntimeFilterVisitor.java    From Bats with Apache License 2.0 6 votes vote down vote up
private ExchangePrel findRightExchangePrel(RelNode rightRelNode) {
  if (rightRelNode instanceof ExchangePrel) {
    return (ExchangePrel) rightRelNode;
  }
  if (rightRelNode instanceof ScanPrel) {
    return null;
  } else if (rightRelNode instanceof RelSubset) {
    RelNode bestNode = ((RelSubset) rightRelNode).getBest();
    if (bestNode != null) {
      return findRightExchangePrel(bestNode);
    } else {
      return null;
    }
  } else {
    List<RelNode> relNodes = rightRelNode.getInputs();
    if (relNodes.size() == 1) {
      RelNode leftNode = relNodes.get(0);
      return findRightExchangePrel(leftNode);
    } else {
      return null;
    }
  }
}
 
Example #19
Source File: RelMdDistinctRowCount.java    From calcite with Apache License 2.0 6 votes vote down vote up
public Double getDistinctRowCount(RelSubset rel, RelMetadataQuery mq,
    ImmutableBitSet groupKey, RexNode predicate) {
  final RelNode best = rel.getBest();
  if (best != null) {
    return mq.getDistinctRowCount(best, groupKey, predicate);
  }
  if (!Bug.CALCITE_1048_FIXED) {
    return getDistinctRowCount((RelNode) rel, mq, groupKey, predicate);
  }
  Double d = null;
  for (RelNode r2 : rel.getRels()) {
    try {
      Double d2 = mq.getDistinctRowCount(r2, groupKey, predicate);
      d = NumberUtil.min(d, d2);
    } catch (CyclicMetadataException e) {
      // Ignore this relational expression; there will be non-cyclic ones
      // in this set.
    }
  }
  return d;
}
 
Example #20
Source File: BatchExecPythonCorrelateRule.java    From flink with Apache License 2.0 6 votes vote down vote up
private BatchExecPythonCorrelate convertToCorrelate(
	RelNode relNode,
	Option<RexNode> condition) {
	if (relNode instanceof RelSubset) {
		RelSubset rel = (RelSubset) relNode;
		return convertToCorrelate(rel.getRelList().get(0), condition);
	} else if (relNode instanceof FlinkLogicalCalc) {
		FlinkLogicalCalc calc = (FlinkLogicalCalc) relNode;
		return convertToCorrelate(
			((RelSubset) calc.getInput()).getOriginal(),
			Some.apply(calc.getProgram().expandLocalRef(calc.getProgram().getCondition())));
	} else {
		FlinkLogicalTableFunctionScan scan = (FlinkLogicalTableFunctionScan) relNode;
		return new BatchExecPythonCorrelate(
			correlate.getCluster(),
			traitSet,
			convInput,
			scan,
			condition,
			null,
			correlate.getRowType(),
			correlate.getJoinType());
	}
}
 
Example #21
Source File: StreamExecPythonCorrelateRule.java    From flink with Apache License 2.0 5 votes vote down vote up
@Override
public boolean matches(RelOptRuleCall call) {
	FlinkLogicalCorrelate correlate = call.rel(0);
	RelNode right = ((RelSubset) correlate.getRight()).getOriginal();
	if (right instanceof FlinkLogicalTableFunctionScan) {
		// right node is a table function
		FlinkLogicalTableFunctionScan scan = (FlinkLogicalTableFunctionScan) right;
		// return true if the table function is python table function
		return PythonUtil.isPythonCall(scan.getCall(), null);
	} else if (right instanceof FlinkLogicalCalc) {
		// a filter is pushed above the table function
		return findTableFunction((FlinkLogicalCalc) right);
	}
	return false;
}
 
Example #22
Source File: StreamExecPythonCorrelateRule.java    From flink with Apache License 2.0 5 votes vote down vote up
private boolean findTableFunction(FlinkLogicalCalc calc) {
	RelNode child = ((RelSubset) calc.getInput()).getOriginal();
	if (child instanceof FlinkLogicalTableFunctionScan) {
		FlinkLogicalTableFunctionScan scan = (FlinkLogicalTableFunctionScan) child;
		return PythonUtil.isPythonCall(scan.getCall(), null);
	} else if (child instanceof FlinkLogicalCalc) {
		FlinkLogicalCalc childCalc = (FlinkLogicalCalc) child;
		return findTableFunction(childCalc);
	}
	return false;
}
 
Example #23
Source File: CheapestPlanWithReflectionVisitor.java    From dremio-oss with Apache License 2.0 5 votes vote down vote up
private RelNode convertRelSubsets(RelNode root) {
  return root.accept(new RoutingShuttle() {
    @Override
    public RelNode visit(RelNode other) {
      if (other instanceof RelSubset) {
        return visit(((RelSubset) other).getBest());
      }
      return super.visit(other);
    }
  });
}
 
Example #24
Source File: MoreRelOptUtil.java    From dremio-oss with Apache License 2.0 5 votes vote down vote up
/**
 * Computes the height of the rel tree under the input rel node.
 * @param rel RelNode to compute the minimum height of the tree underneath it
 * @return minimum height of the tree under the input rel node
 */
public static int getDepth(RelNode rel) {
  if (rel == null) {
    return 0;
  }
  if (rel instanceof RelSubset) {
    RelSubset subset = (RelSubset) rel;
    return getDepth(subset.getBest());
  }

  if (rel.getInputs() == null || rel.getInputs().size() == 0) {
    return 1;
  }

  int minDepth = Integer.MAX_VALUE;
  for (RelNode node : rel.getInputs()) {
    int nodeDepth = getDepth(node);
    if (nodeDepth > 0) {
      minDepth = Math.min(nodeDepth, minDepth);
    }
  }

  if (minDepth == Integer.MAX_VALUE) {
    return 0;
  }

  return minDepth + 1;
}
 
Example #25
Source File: MoreRelOptUtil.java    From dremio-oss with Apache License 2.0 5 votes vote down vote up
@Override
public RelNode visit(RelNode other) {
  if (other instanceof RelSubset) {
    if (((RelSubset) other).getBest() != null) {
      return ((RelSubset) other).getBest().accept(this);
    }
    if (!needBest && ((RelSubset) other).getRelList().size() == 1) {
      return ((RelSubset) other).getRelList().get(0).accept(this);
    }
    throw UserException.unsupportedError().message("SubsetRemover: found null best, parent " + other).build(logger);
  } else {
    return super.visit(other);
  }
}
 
Example #26
Source File: FlinkRelMdCollation.java    From flink with Apache License 2.0 5 votes vote down vote up
public com.google.common.collect.ImmutableList<RelCollation> collations(RelSubset subset, RelMetadataQuery mq) {
	if (!Bug.CALCITE_1048_FIXED) {
		//if the best node is null, so we can get the collation based original node, due to
		//the original node is logically equivalent as the rel.
		RelNode rel = Util.first(subset.getBest(), subset.getOriginal());
		return mq.collations(rel);
	} else {
		throw new RuntimeException("CALCITE_1048 is fixed, so check this method again!");
	}
}
 
Example #27
Source File: RelMdPredicates.java    From dremio-oss with Apache License 2.0 5 votes vote down vote up
public RelOptPredicateList getPredicates(RelSubset subset,
    RelMetadataQuery mq) {
  // Currently disabled in Calcite upstream
  // Only go over the best node if it exists, and try the original node otherwise
  RelOptPredicateList predicates = mq.getPulledUpPredicates(Util.first(subset.getBest(), subset.getOriginal()));
  return predicates;
}
 
Example #28
Source File: RelMdCost.java    From dremio-oss with Apache License 2.0 5 votes vote down vote up
public RelOptCost getNonCumulativeCost(RelSubset subset, RelMetadataQuery mq) {
  final RelNode best = subset.getBest();
  if (best != null) {
    return mq.getNonCumulativeCost(best);
  }

  return null;
}
 
Example #29
Source File: RelMdCost.java    From dremio-oss with Apache License 2.0 5 votes vote down vote up
public RelOptCost getCumulativeCost(RelSubset subset, RelMetadataQuery mq) {
  final RelNode best = subset.getBest();
  if (best != null) {
    return mq.getCumulativeCost(best);
  }

  return null;
}
 
Example #30
Source File: AbstractRelOptPlanner.java    From calcite with Apache License 2.0 5 votes vote down vote up
/** Returns sub-classes of relational expression. */
public Iterable<Class<? extends RelNode>> subClasses(
    final Class<? extends RelNode> clazz) {
  return Util.filter(classes, c -> {
    // RelSubset must be exact type, not subclass
    if (c == RelSubset.class) {
      return c == clazz;
    }
    return clazz.isAssignableFrom(c);
  });
}