Java Code Examples for org.apache.calcite.rel.RelNode#getInputs()

The following examples show how to use org.apache.calcite.rel.RelNode#getInputs() . 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: RelOptUtil.java    From Bats with Apache License 2.0 6 votes vote down vote up
/** Helper for {@link #replace}. */
private static RelNode replaceRecurse(RelNode query, RelNode find, RelNode replace) {
    if (query == find) {
        return replace;
    }
    final List<RelNode> inputs = query.getInputs();
    if (!inputs.isEmpty()) {
        final List<RelNode> newInputs = new ArrayList<>();
        for (RelNode input : inputs) {
            newInputs.add(replaceRecurse(input, find, replace));
        }
        if (!newInputs.equals(inputs)) {
            return query.copy(query.getTraitSet(), newInputs);
        }
    }
    return query;
}
 
Example 2
Source File: RelSet.java    From calcite with Apache License 2.0 6 votes vote down vote up
/**
 * Returns the child Relset for current set
 */
public Set<RelSet> getChildSets(VolcanoPlanner planner) {
  Set<RelSet> childSets = new HashSet<>();
  for (RelNode node : this.rels) {
    if (node instanceof Converter) {
      continue;
    }
    for (RelNode child : node.getInputs()) {
      RelSet childSet = planner.equivRoot(((RelSubset) child).getSet());
      if (childSet.id != this.id) {
        childSets.add(childSet);
      }
    }
  }
  return childSets;
}
 
Example 3
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 4
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 5
Source File: StackFinder.java    From dremio-oss with Apache License 2.0 6 votes vote down vote up
public static List<ElasticsearchPrel> getStack(RelNode rel){
  rel = rel.accept(new MoreRelOptUtil.SubsetRemover(false));
  rel = rel.accept(new MoreRelOptUtil.VertexRemover());
  List<ElasticsearchPrel> stack = new ArrayList<>();
  outside: while(rel != null){
    if( !(rel instanceof ElasticsearchPrel) ){
      throw new IllegalStateException("Stack should only include ElasticPrels, but actually included " + rel.getClass().getName());
    }
    stack.add((ElasticsearchPrel) rel);
    List<RelNode> nodes = rel.getInputs();
    switch(nodes.size()){
    case 0:
      break outside;
    case 1:
      rel = nodes.get(0);
      break;
    default:
      throw new IllegalStateException("Elastic rels should be single input or no input.");
    }
  }

  return ImmutableList.copyOf(stack);
}
 
Example 6
Source File: RelOptUtil.java    From calcite with Apache License 2.0 6 votes vote down vote up
/** Helper for {@link #replace}. */
private static RelNode replaceRecurse(
    RelNode query, RelNode find, RelNode replace) {
  if (query == find) {
    return replace;
  }
  final List<RelNode> inputs = query.getInputs();
  if (!inputs.isEmpty()) {
    final List<RelNode> newInputs = new ArrayList<>();
    for (RelNode input : inputs) {
      newInputs.add(replaceRecurse(input, find, replace));
    }
    if (!newInputs.equals(inputs)) {
      return query.copy(query.getTraitSet(), newInputs);
    }
  }
  return query;
}
 
Example 7
Source File: RelXmlWriter.java    From Bats with Apache License 2.0 6 votes vote down vote up
/**
 * Generates specific XML (sometimes called 'attribute-oriented XML'). Like
 * this:
 *
 * <blockquote><pre>
 * &lt;Join condition="EMP.DEPTNO = DEPT.DEPTNO"&gt;
 *   &lt;Project expr1="x + y" expr2="42"&gt;
 *   &lt;TableAccess table="SALES.EMPS"&gt;
 * &lt;/Join&gt;
 * </pre></blockquote>
 *
 * @param rel    Relational expression
 * @param values List of term-value pairs
 */
private void explainSpecific(
    RelNode rel,
    List<Pair<String, Object>> values) {
  String tagName = rel.getRelTypeName();
  xmlOutput.beginBeginTag(tagName);
  xmlOutput.attribute("id", rel.getId() + "");

  for (Pair<String, Object> value : values) {
    if (value.right instanceof RelNode) {
      continue;
    }
    xmlOutput.attribute(
        value.left,
        value.right.toString());
  }
  xmlOutput.endBeginTag(tagName);
  spacer.add(2);
  for (RelNode input : rel.getInputs()) {
    input.explain(this);
  }
  spacer.subtract(2);
}
 
Example 8
Source File: RelMdMemory.java    From calcite with Apache License 2.0 6 votes vote down vote up
/** Catch-all implementation for
 * {@link BuiltInMetadata.Memory#cumulativeMemoryWithinPhase()},
 * invoked using reflection.
 *
 * @see org.apache.calcite.rel.metadata.RelMetadataQuery#memory
 */
public Double cumulativeMemoryWithinPhase(RelNode rel, RelMetadataQuery mq) {
  Double nullable = mq.memory(rel);
  if (nullable == null) {
    return null;
  }
  Boolean isPhaseTransition = mq.isPhaseTransition(rel);
  if (isPhaseTransition == null) {
    return null;
  }
  double d = nullable;
  if (!isPhaseTransition) {
    for (RelNode input : rel.getInputs()) {
      nullable = mq.cumulativeMemoryWithinPhase(input);
      if (nullable == null) {
        return null;
      }
      d += nullable;
    }
  }
  return d;
}
 
Example 9
Source File: RexSubQueryUtils.java    From dremio-oss with Apache License 2.0 6 votes vote down vote up
public boolean visit(final RelNode node) {
  if (node instanceof JdbcCrel) {
    return false;
  }

  for (RelNode input : node.getInputs()) {
    if (visit(input)) {
      return true;
    }
  }

  final RexSubQueryFinder subQueryFinder = new RexSubQueryFinder();
  node.accept(subQueryFinder);
  if (subQueryFinder.getFoundSubQuery()) {
    return true;
  }

  return false;
}
 
Example 10
Source File: RelOptUtil.java    From Bats with Apache License 2.0 5 votes vote down vote up
/**
 * Returns a shallow copy of a relational expression with a particular
 * input replaced.
 */
public static RelNode replaceInput(RelNode parent, int ordinal, RelNode newInput) {
    final List<RelNode> inputs = new ArrayList<>(parent.getInputs());
    if (inputs.get(ordinal) == newInput) {
        return parent;
    }
    inputs.set(ordinal, newInput);
    return parent.copy(parent.getTraitSet(), inputs);
}
 
Example 11
Source File: RelWalker.java    From sql-gremlin with Apache License 2.0 5 votes vote down vote up
private void walk(RelNode node) {
    if (node == null) return;

    for (RelNode child : node.getInputs()) {
        walk(child);
    }

    visitor.visit(node);
}
 
Example 12
Source File: RelStructuredTypeFlattener.java    From calcite with Apache License 2.0 5 votes vote down vote up
public void rewriteGeneric(RelNode rel) {
  RelNode newRel = rel.copy(rel.getTraitSet(), rel.getInputs());
  List<RelNode> oldInputs = rel.getInputs();
  for (int i = 0; i < oldInputs.size(); ++i) {
    newRel.replaceInput(
        i,
        getNewForOldRel(oldInputs.get(i)));
  }
  setNewForOldRel(rel, newRel);
}
 
Example 13
Source File: RelOptUtil.java    From calcite with Apache License 2.0 5 votes vote down vote up
/**
 * Visits a particular child of a parent.
 */
protected RelNode visitChild(RelNode parent, int i, RelNode child) {
  inheritPaths.forEach(inheritPath -> inheritPath.right.push(i));
  try {
    RelNode child2 = child.accept(this);
    if (child2 != child) {
      final List<RelNode> newInputs = new ArrayList<>(parent.getInputs());
      newInputs.set(i, child2);
      return parent.copy(parent.getTraitSet(), newInputs);
    }
    return parent;
  } finally {
    inheritPaths.forEach(inheritPath -> inheritPath.right.pop());
  }
}
 
Example 14
Source File: RelOptUtil.java    From calcite with Apache License 2.0 5 votes vote down vote up
/**
 * Returns a shallow copy of a relational expression with a particular
 * input replaced.
 */
public static RelNode replaceInput(
    RelNode parent, int ordinal, RelNode newInput) {
  final List<RelNode> inputs = new ArrayList<>(parent.getInputs());
  if (inputs.get(ordinal) == newInput) {
    return parent;
  }
  inputs.set(ordinal, newInput);
  return parent.copy(parent.getTraitSet(), inputs);
}
 
Example 15
Source File: Foreman.java    From dremio-oss with Apache License 2.0 5 votes vote down vote up
private static boolean containsHashAggregate(final RelNode relNode) {
  if (relNode instanceof HashAggPrel) {
    return true;
  }
  else {
    for (final RelNode child : relNode.getInputs()) {
      if (containsHashAggregate(child)) {
        return true;
      } // else, continue
    }
  }
  return false;
}
 
Example 16
Source File: HepPlanner.java    From Bats with Apache License 2.0 4 votes vote down vote up
private HepRelVertex addRelToGraph(
    RelNode rel) {
  // Check if a transformation already produced a reference
  // to an existing vertex.
  if (graph.vertexSet().contains(rel)) {
    return (HepRelVertex) rel;
  }

  // Recursively add children, replacing this rel's inputs
  // with corresponding child vertices.
  final List<RelNode> inputs = rel.getInputs();
  final List<RelNode> newInputs = new ArrayList<>();
  for (RelNode input1 : inputs) {
    HepRelVertex childVertex = addRelToGraph(input1);
    newInputs.add(childVertex);
  }

  if (!Util.equalShallow(inputs, newInputs)) {
    RelNode oldRel = rel;
    rel = rel.copy(rel.getTraitSet(), newInputs);
    onCopy(oldRel, rel);
  }
  // Compute digest first time we add to DAG,
  // otherwise can't get equivVertex for common sub-expression
  rel.recomputeDigest();

  // try to find equivalent rel only if DAG is allowed
  if (!noDag) {
    // Now, check if an equivalent vertex already exists in graph.
    String digest = rel.getDigest();
    HepRelVertex equivVertex = mapDigestToVertex.get(digest);
    if (equivVertex != null) {
      // Use existing vertex.
      return equivVertex;
    }
  }

  // No equivalence:  create a new vertex to represent this rel.
  HepRelVertex newVertex = new HepRelVertex(rel);
  graph.addVertex(newVertex);
  updateVertex(newVertex, rel);

  for (RelNode input : rel.getInputs()) {
    graph.addEdge(newVertex, (HepRelVertex) input);
  }

  nTransformations++;
  return newVertex;
}
 
Example 17
Source File: MycatCalcitePlanner.java    From Mycat2 with GNU General Public License v3.0 4 votes vote down vote up
/**
 * 测试单库分表与不同分片两个情况
 *
 * @param relBuilder
 * @param cache
 * @param margeList
 * @param bestExp2
 * @return
 */
private RelNode simplyAggreate(MycatRelBuilder relBuilder, IdentityHashMap<RelNode, Boolean> cache, IdentityHashMap<RelNode, List<String>> margeList, RelNode bestExp2) {
    RelNode parent = bestExp2;
    RelNode child = bestExp2 instanceof Aggregate ? bestExp2.getInput(0) : null;
    RelNode bestExp3 = parent;
    if (parent instanceof Aggregate && child instanceof Union) {
        Aggregate aggregate = (Aggregate) parent;
        if (aggregate.getAggCallList() != null && !aggregate.getAggCallList().isEmpty()) {//distinct会没有参数
            List<AggregateCall> aggCallList = aggregate.getAggCallList();
            boolean allMatch = aggregate.getRowType().getFieldCount() == 1 && aggCallList.stream().allMatch(new Predicate<AggregateCall>() {
                @Override
                public boolean test(AggregateCall aggregateCall) {
                    return SUPPORTED_AGGREGATES.getOrDefault(aggregateCall.getAggregation().getKind(), false)
                            &&
                            aggregate.getRowType().getFieldList().stream().allMatch(i -> i.getType().getSqlTypeName().getFamily() == SqlTypeFamily.NUMERIC);
                }
            });
            if (allMatch) {
                List<RelNode> inputs = child.getInputs();
                List<RelNode> resList = new ArrayList<>(inputs.size());
                boolean allCanPush = true;//是否聚合节点涉及不同分片
                String target = null;
                for (RelNode input : inputs) {
                    RelNode res;
                    if (cache.get(input)) {
                        res = LogicalAggregate.create(input, aggregate.getGroupSet(), aggregate.getGroupSets(), aggregate.getAggCallList());
                        cache.put(res, Boolean.TRUE);
                        List<String> strings = margeList.getOrDefault(input, Collections.emptyList());
                        Objects.requireNonNull(strings);
                        if (target == null && strings.size() > 0) {
                            target = strings.get(0);
                        } else if (target != null && strings.size() > 0) {
                            if (!target.equals(strings.get(0))) {
                                allCanPush = false;
                            }
                        }
                        margeList.put(res, strings);
                    } else {
                        res = input;
                        allCanPush = false;
                    }
                    resList.add(res);
                }

                LogicalUnion logicalUnion = LogicalUnion.create(resList, ((Union) child).all);

                //构造sum
                relBuilder.clear();
                relBuilder.push(logicalUnion);
                List<RexNode> fields = relBuilder.fields();
                if (fields == null) {
                    fields = Collections.emptyList();
                }

                RelBuilder.GroupKey groupKey = relBuilder.groupKey();
                List<RelBuilder.AggCall> aggCalls = fields.stream().map(i -> relBuilder.sum(i)).collect(Collectors.toList());
                relBuilder.aggregate(groupKey, aggCalls);
                bestExp3 = relBuilder.build();

                cache.put(logicalUnion, allCanPush);
                cache.put(bestExp3, allCanPush);
                if (target != null) {//是否聚合节点涉及不同分片
                    List<String> targetSingelList = Collections.singletonList(target);
                    margeList.put(logicalUnion, targetSingelList);
                    margeList.put(bestExp3, targetSingelList);
                }
            }
        }
    }
    return bestExp3;
}
 
Example 18
Source File: NumberingRelWriter.java    From dremio-oss with Apache License 2.0 4 votes vote down vote up
protected void explain_(
    RelNode rel,
    List<Pair<String, Object>> values) {
  List<RelNode> inputs = rel.getInputs();
  RelMetadataQuery mq = rel.getCluster().getMetadataQuery();
  if (rel instanceof HashJoinPrel && ((HashJoinPrel) rel).isSwapped()) {
    HashJoinPrel joinPrel = (HashJoinPrel) rel;
    inputs = FlatLists.of(joinPrel.getRight(), joinPrel.getLeft());
  }

  if (!mq.isVisibleInExplain(rel, detailLevel)) {
    // render children in place of this, at same level
    explainInputs(inputs);
    return;
  }

  StringBuilder s = new StringBuilder();
  OpId id = ids.get(rel);
  if (id != null) {
    s.append(String.format("%02d-%02d", id.fragmentId, id.opId));
  }else{
    s.append("     ");
  }
  s.append("  ");

  if (id != null && id.opId == 0) {
    for(int i =0; i < spacer.get(); i++){ s.append('-');}
  }else{
    spacer.spaces(s);
  }

  s.append("  ");

  s.append(rel.getRelTypeName().replace("Prel", ""));
  if (detailLevel != SqlExplainLevel.NO_ATTRIBUTES) {
    int j = 0;
    for (Pair<String, Object> value : values) {
      if (value.right instanceof RelNode) {
        continue;
      }
      if (j++ == 0) {
        s.append("(");
      } else {
        s.append(", ");
      }
      s.append(value.left)
          .append("=[")
          .append(value.right)
          .append("]");
    }
    if (j > 0) {
      s.append(")");
    }
  }
  if (detailLevel == SqlExplainLevel.ALL_ATTRIBUTES) {
    s.append(" : rowType = " + rel.getRowType().toString());
    s.append(": rowcount = ")
        .append(mq.getRowCount(rel))
        .append(", cumulative cost = ")
        .append(mq.getCumulativeCost(rel));
     s.append(", id = ").append(rel.getId());
  }
  pw.println(s);
  spacer.add(2);
  explainInputs(inputs);
  spacer.subtract(2);
}
 
Example 19
Source File: DrillPushRowKeyJoinToScanRule.java    From Bats with Apache License 2.0 4 votes vote down vote up
private static boolean isRowKeyColumn(int index, RelNode rel) {
  RelNode curRel = rel;
  int curIndex = index;
  while (curRel != null && !(curRel instanceof DrillScanRel)) {
    logger.debug("IsRowKeyColumn: Rel={}, RowTypePos={}, RowType={}", curRel.toString(), curIndex,
        curRel.getRowType().toString());
    if (curRel instanceof HepRelVertex) {
      curRel = ((HepRelVertex) curRel).getCurrentRel();
    } else if (curRel instanceof RelSubset) {
      if (((RelSubset) curRel).getBest() != null) {
        curRel = ((RelSubset) curRel).getBest();
      } else {
        curRel = ((RelSubset) curRel).getOriginal();
      }
    } else {
      RelNode child = null;
      // For multi-input parent rels, found out the 0-based index in the child rel,
      // before recursing down that child rel.
      for (RelNode input : curRel.getInputs()) {
        if (input.getRowType().getFieldList().size() <= curIndex) {
          curIndex -= input.getRowType().getFieldList().size();
        } else {
          child = input;
          break;
        }
      }
      curRel = child;
    }
    // If no exprs present in projection the column index remains the same in the child.
    // Otherwise, the column index is the `RexInputRef` index.
    if (curRel != null && curRel instanceof DrillProjectRel) {
      List<RexNode> childExprs = curRel.getChildExps();
      if (childExprs != null && childExprs.size() > 0) {
        if (childExprs.get(curIndex) instanceof RexInputRef) {
          curIndex = ((RexInputRef) childExprs.get(curIndex)).getIndex();
        } else {
          // Currently do not support expressions on rowkey col. So if an expr is present,
          // return false
          logger.debug("IsRowKeyColumn: ABORT: Primary-key EXPR$={}", childExprs.get(curIndex).toString());
          return false;
        }
      }
    }
  }
  logger.debug("IsRowKeyColumn:Primary-key Col={} ",
      curRel != null ? curRel.getRowType().getFieldNames().get(curIndex) : "??");
  // Get the primary-key col name from the scan and match with the column being referenced.
  if (curRel != null && curRel instanceof DrillScanRel) {
    if (((DrillScanRel) curRel).getGroupScan() instanceof DbGroupScan) {
      DbGroupScan dbGroupScan = (DbGroupScan) ((DrillScanRel) curRel).getGroupScan();
      String rowKeyName = dbGroupScan.getRowKeyName();
      DbGroupScan restrictedGroupScan = dbGroupScan.getRestrictedScan(((DrillScanRel)curRel).getColumns());
      // Also verify this scan supports restricted groupscans(random seeks)
      if (restrictedGroupScan != null &&
          curRel.getRowType().getFieldNames().get(curIndex).equalsIgnoreCase(rowKeyName)) {
        logger.debug("IsRowKeyColumn: FOUND: Rel={}, RowTypePos={}, RowType={}",
            curRel.toString(), curIndex, curRel.getRowType().toString());
        return true;
      }
    }
  }
  logger.debug("IsRowKeyColumn: NOT FOUND");
  return false;
}
 
Example 20
Source File: RelNodeConvertor.java    From Mycat2 with GNU General Public License v3.0 4 votes vote down vote up
public static Schema convertRelNode(RelNode relNode) {

        List<RelNode> inputs = relNode.getInputs();
        String relTypeName = relNode.getRelTypeName();
        String correlVariable = relNode.getCorrelVariable();
        RelOptTable table = relNode.getTable();
        Set<CorrelationId> variablesSet = relNode.getVariablesSet();
        switch (relTypeName) {
            case "LogicalValues": {
                return logicValues(relNode);
            }
            case "LogicalProject": {
                return logicProject(relNode);
            }
            case "LogicalAggregate": {
                return logicalAggregate(relNode);
            }
            case "LogicalTableScan": {
                return logicalTableScan(relNode);
            }
            case "LogicalIntersect":
            case "LogicalMinus":
            case "LogicalUnion": {
                return logicalSetOp(relNode);
            }
            case "LogicalSort": {
                return logicalSort(relNode);
            }
            case "LogicalFilter": {
                return logicalFilter(relNode);
            }
            case "LogicalJoin": {
                return logicalJoin(relNode);
            }
            case "LogicalCorrelate": {
                return logicalCorrelate(relNode);
            }
        }
        if (relNode instanceof TableScan) {
            List<FieldType> fields = getFields(relNode);
            TableScan relNode1 = (TableScan) relNode;
            MycatSQLTableScan unwrap = relNode1.getTable().unwrap(MycatSQLTableScan.class);
            if (unwrap != null) {
                return new FromSqlSchema(fields, unwrap.getTargetName(), unwrap.getSql());
            }
        }
        throw new UnsupportedOperationException();
    }