Java Code Examples for org.apache.calcite.plan.RelOptUtil

The following examples show how to use org.apache.calcite.plan.RelOptUtil. These examples are extracted from open source projects. 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 Project: Bats   Source File: BatsOptimizerTest.java    License: Apache License 2.0 6 votes vote down vote up
static void testVolcanoPlanner() throws Exception {
    VolcanoPlanner volcanoPlanner = createVolcanoPlanner();
    volcanoPlanner.addRelTraitDef(ConventionTraitDef.INSTANCE);
    // volcanoPlanner.addRelTraitDef(RelCollationTraitDef.INSTANCE);
    // addRules(volcanoPlanner);
    volcanoPlanner.addRule(ReduceExpressionsRule.PROJECT_INSTANCE);
    // volcanoPlanner.addRule(EnumerableRules.ENUMERABLE_PROJECT_RULE);

    RelNode relNode = testSqlToRelConverter(volcanoPlanner);
    volcanoPlanner.setRoot(relNode);
    relNode = volcanoPlanner.findBestExp(); // 在这一步出错

    String plan = RelOptUtil.toString(relNode);
    System.out.println("Volcano Plan:");
    System.out.println("------------------------------------------------------------------");
    System.out.println(plan);
}
 
Example 2
Source Project: calcite   Source File: RelFieldTrimmer.java    License: Apache License 2.0 6 votes vote down vote up
/** Creates a project with a dummy column, to protect the parts of the system
 * that cannot handle a relational expression with no columns.
 *
 * @param fieldCount Number of fields in the original relational expression
 * @param input Trimmed input
 * @param originalRelNode Source RelNode for hint propagation (or null if no propagation needed)
 * @return Dummy project
 */
protected TrimResult dummyProject(int fieldCount, RelNode input, RelNode originalRelNode) {
  final RelOptCluster cluster = input.getCluster();
  final Mapping mapping =
      Mappings.create(MappingType.INVERSE_SURJECTION, fieldCount, 1);
  if (input.getRowType().getFieldCount() == 1) {
    // Input already has one field (and may in fact be a dummy project we
    // created for the child). We can't do better.
    return result(input, mapping);
  }
  final RexLiteral expr =
      cluster.getRexBuilder().makeExactLiteral(BigDecimal.ZERO);
  relBuilder.push(input);
  relBuilder.project(ImmutableList.of(expr), ImmutableList.of("DUMMY"));
  RelNode newProject = relBuilder.build();
  if (originalRelNode != null) {
    newProject = RelOptUtil.propagateRelHints(originalRelNode, newProject);
  }
  return result(newProject, mapping);
}
 
Example 3
Source Project: calcite   Source File: Lattice.java    License: Apache License 2.0 6 votes vote down vote up
private static boolean populate(List<RelNode> nodes, List<int[][]> tempLinks,
    RelNode rel) {
  if (nodes.isEmpty() && rel instanceof LogicalProject) {
    return populate(nodes, tempLinks, ((LogicalProject) rel).getInput());
  }
  if (rel instanceof TableScan) {
    nodes.add(rel);
    return true;
  }
  if (rel instanceof LogicalJoin) {
    LogicalJoin join = (LogicalJoin) rel;
    if (join.getJoinType().isOuterJoin()) {
      throw new RuntimeException("only non nulls-generating join allowed, but got "
          + join.getJoinType());
    }
    populate(nodes, tempLinks, join.getLeft());
    populate(nodes, tempLinks, join.getRight());
    for (RexNode rex : RelOptUtil.conjunctions(join.getCondition())) {
      tempLinks.add(grab(nodes, rex));
    }
    return true;
  }
  throw new RuntimeException("Invalid node type "
      + rel.getClass().getSimpleName() + " in lattice query");
}
 
Example 4
Source Project: Bats   Source File: RelMdPredicates.java    License: Apache License 2.0 6 votes vote down vote up
private void infer(RexNode predicates, Set<RexNode> allExprs,
    List<RexNode> inferredPredicates, boolean includeEqualityInference,
    ImmutableBitSet inferringFields) {
  for (RexNode r : RelOptUtil.conjunctions(predicates)) {
    if (!includeEqualityInference
        && equalityPredicates.contains(r)) {
      continue;
    }
    for (Mapping m : mappings(r)) {
      RexNode tr = r.accept(
          new RexPermuteInputsShuttle(m, joinRel.getInput(0),
              joinRel.getInput(1)));
      // Filter predicates can be already simplified, so we should work with
      // simplified RexNode versions as well. It also allows prevent of having
      // some duplicates in in result pulledUpPredicates
      RexNode simplifiedTarget =
          simplify.simplifyFilterPredicates(RelOptUtil.conjunctions(tr));
      if (checkTarget(inferringFields, allExprs, tr)
          && checkTarget(inferringFields, allExprs, simplifiedTarget)) {
        inferredPredicates.add(simplifiedTarget);
        allExprs.add(simplifiedTarget);
      }
    }
  }
}
 
Example 5
Source Project: flink   Source File: FlinkJoinToMultiJoinRule.java    License: Apache License 2.0 6 votes vote down vote up
/**
 * Shifts a filter originating from the right child of the LogicalJoin to the
 * right, to reflect the filter now being applied on the resulting
 * MultiJoin.
 *
 * @param joinRel     the original LogicalJoin
 * @param left        the left child of the LogicalJoin
 * @param right       the right child of the LogicalJoin
 * @param rightFilter the filter originating from the right child
 * @return the adjusted right filter
 */
private RexNode shiftRightFilter(
		Join joinRel,
		RelNode left,
		MultiJoin right,
		RexNode rightFilter) {
	if (rightFilter == null) {
		return null;
	}

	int nFieldsOnLeft = left.getRowType().getFieldList().size();
	int nFieldsOnRight = right.getRowType().getFieldList().size();
	int[] adjustments = new int[nFieldsOnRight];
	for (int i = 0; i < nFieldsOnRight; i++) {
		adjustments[i] = nFieldsOnLeft;
	}
	rightFilter =
			rightFilter.accept(
					new RelOptUtil.RexInputConverter(
							joinRel.getCluster().getRexBuilder(),
							right.getRowType().getFieldList(),
							joinRel.getRowType().getFieldList(),
							adjustments));
	return rightFilter;
}
 
Example 6
Source Project: Bats   Source File: JoinCommuteRule.java    License: Apache License 2.0 6 votes vote down vote up
/**
 * Returns a relational expression with the inputs switched round. Does not
 * modify <code>join</code>. Returns null if the join cannot be swapped (for
 * example, because it is an outer join).
 *
 * @param join              join to be swapped
 * @param swapOuterJoins    whether outer joins should be swapped
 * @param relBuilder        Builder for relational expressions
 * @return swapped join if swapping possible; else null
 */
public static RelNode swap(Join join, boolean swapOuterJoins, RelBuilder relBuilder) {
    final JoinRelType joinType = join.getJoinType();
    if (!swapOuterJoins && joinType != JoinRelType.INNER) {
        return null;
    }
    final RexBuilder rexBuilder = join.getCluster().getRexBuilder();
    final RelDataType leftRowType = join.getLeft().getRowType();
    final RelDataType rightRowType = join.getRight().getRowType();
    final VariableReplacer variableReplacer = new VariableReplacer(rexBuilder, leftRowType, rightRowType);
    final RexNode oldCondition = join.getCondition();
    RexNode condition = variableReplacer.go(oldCondition);

    // NOTE jvs 14-Mar-2006: We preserve attribute semiJoinDone after the
    // swap. This way, we will generate one semijoin for the original
    // join, and one for the swapped join, and no more. This
    // doesn't prevent us from seeing any new combinations assuming
    // that the planner tries the desired order (semijoins after swaps).
    Join newJoin = join.copy(join.getTraitSet(), condition, join.getRight(), join.getLeft(), joinType.swap(),
            join.isSemiJoinDone());
    final List<RexNode> exps = RelOptUtil.createSwappedJoinExprs(newJoin, join, true);
    return relBuilder.push(newJoin).project(exps, join.getRowType().getFieldNames()).build();
}
 
Example 7
Source Project: Bats   Source File: MaterializedViewFilterScanRule.java    License: Apache License 2.0 6 votes vote down vote up
protected void apply(RelOptRuleCall call, Filter filter, TableScan scan) {
  final RelOptPlanner planner = call.getPlanner();
  final List<RelOptMaterialization> materializations =
      planner.getMaterializations();
  if (!materializations.isEmpty()) {
    RelNode root = filter.copy(filter.getTraitSet(),
        Collections.singletonList((RelNode) scan));
    List<RelOptMaterialization> applicableMaterializations =
        RelOptMaterializations.getApplicableMaterializations(root, materializations);
    for (RelOptMaterialization materialization : applicableMaterializations) {
      if (RelOptUtil.areRowTypesEqual(scan.getRowType(),
          materialization.queryRel.getRowType(), false)) {
        RelNode target = materialization.queryRel;
        final HepPlanner hepPlanner =
            new HepPlanner(program, planner.getContext());
        hepPlanner.setRoot(target);
        target = hepPlanner.findBestExp();
        List<RelNode> subs = new MaterializedViewSubstitutionVisitor(target, root)
            .go(materialization.tableRel);
        for (RelNode s : subs) {
          call.transformTo(s);
        }
      }
    }
  }
}
 
Example 8
Source Project: Bats   Source File: LoptOptimizeJoinRule.java    License: Apache License 2.0 6 votes vote down vote up
/**
 * Determines whether any additional filters are applicable to a join tree.
 * If there are any, creates a filter node on top of the join tree with the
 * additional filters.
 *
 * @param relBuilder Builder holding current join tree
 * @param multiJoin join factors being optimized
 * @param left left side of join tree
 * @param right right side of join tree
 * @param filtersToAdd remaining filters
 */
private void addAdditionalFilters(
    RelBuilder relBuilder,
    LoptMultiJoin multiJoin,
    LoptJoinTree left,
    LoptJoinTree right,
    List<RexNode> filtersToAdd) {
  RexNode filterCond =
      addFilters(multiJoin, left, -1, right, filtersToAdd, false);
  if (!filterCond.isAlwaysTrue()) {
    // adjust the filter to reflect the outer join output
    int [] adjustments = new int[multiJoin.getNumTotalFields()];
    if (needsAdjustment(multiJoin, adjustments, left, right, false)) {
      RexBuilder rexBuilder =
          multiJoin.getMultiJoinRel().getCluster().getRexBuilder();
      filterCond =
          filterCond.accept(
              new RelOptUtil.RexInputConverter(
                  rexBuilder,
                  multiJoin.getMultiJoinFields(),
                  relBuilder.peek().getRowType().getFieldList(),
                  adjustments));
      relBuilder.filter(filterCond);
    }
  }
}
 
Example 9
Source Project: Bats   Source File: MultiJoinProjectTransposeRule.java    License: Apache License 2.0 6 votes vote down vote up
protected RelNode getProjectChild(
    RelOptRuleCall call,
    LogicalProject project,
    boolean leftChild) {
  // locate the appropriate MultiJoin based on which rule was fired
  // and which projection we're dealing with
  MultiJoin multiJoin;
  if (leftChild) {
    multiJoin = call.rel(2);
  } else if (call.rels.length == 4) {
    multiJoin = call.rel(3);
  } else {
    multiJoin = call.rel(4);
  }

  // create a new MultiJoin that reflects the columns in the projection
  // above the MultiJoin
  return RelOptUtil.projectMultiJoin(multiJoin, project);
}
 
Example 10
Source Project: calcite   Source File: DruidRules.java    License: Apache License 2.0 6 votes vote down vote up
private static Pair<List<RexNode>, List<RexNode>> splitProjects(
    final RexBuilder rexBuilder, final RelNode input, List<RexNode> nodes) {
  final RelOptUtil.InputReferencedVisitor visitor =
      new RelOptUtil.InputReferencedVisitor();
  visitor.visitEach(nodes);
  if (visitor.inputPosReferenced.size() == input.getRowType().getFieldCount()) {
    // All inputs are referenced
    return null;
  }
  final List<RexNode> belowNodes = new ArrayList<>();
  final List<RelDataType> belowTypes = new ArrayList<>();
  final List<Integer> positions = Lists.newArrayList(visitor.inputPosReferenced);
  for (int i : positions) {
    final RexNode node = rexBuilder.makeInputRef(input, i);
    belowNodes.add(node);
    belowTypes.add(node.getType());
  }
  final List<RexNode> aboveNodes = new RexShuttle() {
    @Override public RexNode visitInputRef(RexInputRef ref) {
      final int index = positions.indexOf(ref.getIndex());
      return rexBuilder.makeInputRef(belowTypes.get(index), index);
    }
  }.visitList(nodes);
  return Pair.of(aboveNodes, belowNodes);
}
 
Example 11
Source Project: calcite   Source File: RexProgramTest.java    License: Apache License 2.0 6 votes vote down vote up
@Test void testIsDeterministic() {
  SqlOperator ndc = new SqlSpecialOperator(
          "NDC",
          SqlKind.OTHER_FUNCTION,
          0,
          false,
          ReturnTypes.BOOLEAN,
          null, null) {
    @Override public boolean isDeterministic() {
      return false;
    }
  };
  RexNode n = rexBuilder.makeCall(ndc);
  assertFalse(RexUtil.isDeterministic(n));
  assertEquals(0,
          RexUtil.retainDeterministic(RelOptUtil.conjunctions(n)).size());
}
 
Example 12
Source Project: Bats   Source File: JoinPrel.java    License: Apache License 2.0 6 votes vote down vote up
/**
 * Build the list of join conditions for this join.
 * A join condition is built only for equality and IS NOT DISTINCT FROM comparisons. The difference is:
 * null == null is FALSE whereas null IS NOT DISTINCT FROM null is TRUE
 * For a use case of the IS NOT DISTINCT FROM comparison, see
 * {@link org.apache.calcite.rel.rules.AggregateRemoveRule}
 * @param conditions populated list of join conditions
 * @param leftFields join fields from the left input
 * @param rightFields join fields from the right input
 */
protected void buildJoinConditions(List<JoinCondition> conditions,
    List<String> leftFields,
    List<String> rightFields,
    List<Integer> leftKeys,
    List<Integer> rightKeys) {
  List<RexNode> conjuncts = RelOptUtil.conjunctions(this.getCondition());
  short i=0;

  for (Pair<Integer, Integer> pair : Pair.zip(leftKeys, rightKeys)) {
    final RexNode conditionExpr = conjuncts.get(i++);
    final SqlKind kind  = conditionExpr.getKind();
    if (kind != SqlKind.EQUALS && kind != SqlKind.IS_NOT_DISTINCT_FROM) {
      throw UserException.unsupportedError()
          .message("Unsupported comparator in join condition %s", conditionExpr)
          .build(logger);
    }

    conditions.add(new JoinCondition(kind.toString(),
        FieldReference.getWithQuotedRef(leftFields.get(pair.left)),
        FieldReference.getWithQuotedRef(rightFields.get(pair.right))));
  }
}
 
Example 13
Source Project: Bats   Source File: RexSimplify.java    License: Apache License 2.0 6 votes vote down vote up
RexNode simplifyAnd(RexCall e, RexUnknownAs unknownAs) {
    List<RexNode> operands = RelOptUtil.conjunctions(e);

    if (unknownAs == FALSE && predicateElimination) {
        simplifyAndTerms(operands, FALSE);
    } else {
        simplifyList(operands, unknownAs);
    }

    final List<RexNode> terms = new ArrayList<>();
    final List<RexNode> notTerms = new ArrayList<>();

    for (RexNode o : operands) {
        RelOptUtil.decomposeConjunction(o, terms, notTerms);
    }

    switch (unknownAs) {
    case FALSE:
        return simplifyAnd2ForUnknownAsFalse(terms, notTerms, Comparable.class);
    }
    return simplifyAnd2(terms, notTerms);
}
 
Example 14
Source Project: calcite   Source File: Prepare.java    License: Apache License 2.0 6 votes vote down vote up
public final RelOptTable extend(List<RelDataTypeField> extendedFields) {
  final Table table = unwrap(Table.class);

  // Get the set of extended columns that do not have the same name as a column
  // in the base table.
  final List<RelDataTypeField> baseColumns = getRowType().getFieldList();
  final List<RelDataTypeField> dedupedFields =
      RelOptUtil.deduplicateColumns(baseColumns, extendedFields);
  final List<RelDataTypeField> dedupedExtendedFields =
      dedupedFields.subList(baseColumns.size(), dedupedFields.size());

  if (table instanceof ExtensibleTable) {
    final Table extendedTable =
            ((ExtensibleTable) table).extend(dedupedExtendedFields);
    return extend(extendedTable);
  } else if (table instanceof ModifiableViewTable) {
    final ModifiableViewTable modifiableViewTable =
            (ModifiableViewTable) table;
    final ModifiableViewTable extendedView =
        modifiableViewTable.extend(dedupedExtendedFields,
            getRelOptSchema().getTypeFactory());
    return extend(extendedView);
  }
  throw new RuntimeException("Cannot extend " + table);
}
 
Example 15
Source Project: dk-fitting   Source File: ElasticsearchJoin.java    License: Apache License 2.0 6 votes vote down vote up
public void implement(Implementor implementor) {
    implementor.visitChild(0, getLeft());
    implementor.visitChild(0, getRight());
    if (!getCondition().isA(SqlKind.EQUALS)) {
        throw new IllegalArgumentException("Only equi-join are supported");
    }
    List<RexNode> operands = ((RexCall) getCondition()).getOperands();
    if (operands.size() != 2) {
        throw new IllegalArgumentException("Only equi-join are supported");
    }
    List<Integer> leftKeys = new ArrayList<Integer>(1);
    List<Integer> rightKeys = new ArrayList<Integer>(1);
    List<Boolean> filterNulls = new ArrayList<Boolean>(1);
    RexNode rexNode = RelOptUtil.splitJoinCondition(getLeft(), getRight(), getCondition(), leftKeys, rightKeys,
            filterNulls);
    String leftRelAlias = implementor.getElasticsearchRelationAlias((ElasticsearchRelNode) getLeft());
    String rightRelAlias = implementor.getElasticsearchRelationAlias((ElasticsearchRelNode) getRight());
    String leftJoinFieldName = implementor.getFieldName((ElasticsearchRelNode) getLeft(), leftKeys.get(0));
    String rightJoinFieldName = implementor.getFieldName((ElasticsearchRelNode) getRight(), rightKeys.get(0));
    String result = implementor.getElasticsearchRelationAlias((ElasticsearchRelNode) getLeft())
            + " = JOIN " + leftRelAlias + " BY "+ leftJoinFieldName + ' ' + getElasticsearchJoinType() + ", " +
            rightRelAlias + " BY "+ rightJoinFieldName + ';';
    System.out.println("implementor = " + result);
}
 
Example 16
Source Project: calcite   Source File: EnumerableCalcRule.java    License: Apache License 2.0 5 votes vote down vote up
EnumerableCalcRule() {
  // The predicate ensures that if there's a multiset, FarragoMultisetSplitter
  // will work on it first.
  super(LogicalCalc.class,
      (Predicate<Calc>) RelOptUtil::notContainsWindowedAgg,
      Convention.NONE, EnumerableConvention.INSTANCE,
      RelFactories.LOGICAL_BUILDER, "EnumerableCalcRule");
}
 
Example 17
Source Project: Bats   Source File: BatsOptimizerTest.java    License: Apache License 2.0 5 votes vote down vote up
static void testHepPlanner() throws Exception {
    RelOptPlanner hepPlanner = createHepPlanner();
    RelNode relNode = testSqlToRelConverter(hepPlanner);
    hepPlanner = relNode.getCluster().getPlanner();
    // relNode.getCluster().getPlanner().setExecutor(RexUtil.EXECUTOR);
    hepPlanner.setRoot(relNode);
    relNode = hepPlanner.findBestExp();

    String plan = RelOptUtil.toString(relNode);
    System.out.println("Hep Plan:");
    System.out.println("------------------------------------------------------------------");
    System.out.println(plan);
}
 
Example 18
Source Project: streamline   Source File: TestCompilerUtils.java    License: Apache License 2.0 5 votes vote down vote up
public static CalciteState sqlOverDummyTable(String sql)
        throws RelConversionException, ValidationException, SqlParseException {
    SchemaPlus schema = Frameworks.createRootSchema(true);
    JavaTypeFactory typeFactory = new JavaTypeFactoryImpl
            (RelDataTypeSystem.DEFAULT);
    StreamableTable streamableTable = new CompilerUtil.TableBuilderInfo(typeFactory)
            .field("ID", SqlTypeName.INTEGER)
            .field("NAME", typeFactory.createType(String.class))
            .field("ADDR", typeFactory.createType(String.class))
            .build();
    Table table = streamableTable.stream();
    schema.add("FOO", table);
    schema.add("BAR", table);
    schema.add("MYPLUS", ScalarFunctionImpl.create(MyPlus.class, "eval"));

    List<SqlOperatorTable> sqlOperatorTables = new ArrayList<>();
    sqlOperatorTables.add(SqlStdOperatorTable.instance());
    sqlOperatorTables.add(new CalciteCatalogReader(CalciteSchema.from(schema),
            false,
            Collections.<String>emptyList(), typeFactory));
    SqlOperatorTable chainedSqlOperatorTable = new ChainedSqlOperatorTable(sqlOperatorTables);
    FrameworkConfig config = Frameworks.newConfigBuilder().defaultSchema(
            schema).operatorTable(chainedSqlOperatorTable).build();
    Planner planner = Frameworks.getPlanner(config);
    SqlNode parse = planner.parse(sql);
    SqlNode validate = planner.validate(parse);
    RelNode tree = planner.convert(validate);
    System.out.println(RelOptUtil.toString(tree, SqlExplainLevel.ALL_ATTRIBUTES));
    return new CalciteState(schema, tree);
}
 
Example 19
Source Project: calcite   Source File: MaterializedViewRelOptRulesTest.java    License: Apache License 2.0 5 votes vote down vote up
protected List<RelNode> optimize(TestConfig testConfig) {
  RelNode queryRel = testConfig.queryRel;
  RelOptPlanner planner = queryRel.getCluster().getPlanner();
  RelTraitSet traitSet = queryRel.getCluster().traitSet()
      .replace(EnumerableConvention.INSTANCE);
  RelOptUtil.registerDefaultRules(planner, true, false);
  return ImmutableList.of(
      Programs.standard().run(
          planner, queryRel, traitSet, testConfig.materializations, ImmutableList.of()));
}
 
Example 20
Source Project: Bats   Source File: LogicalCalc.java    License: Apache License 2.0 5 votes vote down vote up
@Override public void collectVariablesUsed(Set<CorrelationId> variableSet) {
  final RelOptUtil.VariableUsedVisitor vuv =
      new RelOptUtil.VariableUsedVisitor(null);
  for (RexNode expr : program.getExprList()) {
    expr.accept(vuv);
  }
  variableSet.addAll(vuv.variables);
}
 
Example 21
Source Project: dremio-oss   Source File: FilterProjectNLJRule.java    License: Apache License 2.0 5 votes vote down vote up
@Override
public void onMatch(RelOptRuleCall call) {
  FilterPrel filter = call.rel(0);
  ProjectPrel project = call.rel(1);
  NestedLoopJoinPrel join = call.rel(2);
  RexNode newCondition = RelOptUtil.pushPastProject(filter.getCondition(), project);

  final RelBuilder relBuilder = call.builder();
  RelNode newFilterRel = filter.copy(filter.getTraitSet(),
    NestedLoopJoinPrel.create(join.getCluster(), join.getTraitSet(), join.getLeft(), join.getRight(), join.getJoinType(), join.getCondition(), join.getProjectedFields()),
  RexUtil.removeNullabilityCast(relBuilder.getTypeFactory(), newCondition));

  RelNode newProjRel = project.copy(project.getTraitSet(), newFilterRel, project.getProjects(), project.getRowType());
  call.transformTo(newProjRel);
}
 
Example 22
Source Project: quark   Source File: FilterAggStarRule.java    License: Apache License 2.0 5 votes vote down vote up
/**
 * Pushes a {@link org.apache.calcite.rel.core.Filter}
 * past a {@link org.apache.calcite.rel.core.Aggregate}.
 */
RelNode filterAggregateTranspose(RelOptRuleCall call,
                                 Filter filterRel,
                                 Aggregate aggRel) {
  final List<RexNode> conditions =
      RelOptUtil.conjunctions(filterRel.getCondition());
  final RexBuilder rexBuilder = filterRel.getCluster().getRexBuilder();
  final List<RelDataTypeField> origFields =
      aggRel.getRowType().getFieldList();
  final int[] adjustments = new int[origFields.size()];
  int i = 0;
  for (int key : aggRel.getGroupSet()) {
    adjustments[i] = key - i;
    i++;
  }
  final List<RexNode> pushedConditions = Lists.newArrayList();

  for (RexNode condition : conditions) {
    ImmutableBitSet rCols = RelOptUtil.InputFinder.bits(condition);
    if (canPush(aggRel, rCols)) {
      pushedConditions.add(
          condition.accept(
              new RelOptUtil.RexInputConverter(rexBuilder, origFields,
                  aggRel.getInput(0).getRowType().getFieldList(),
                  adjustments)));
    } else {
      return null;
    }
  }

  final RelBuilder builder = call.builder();
  RelNode rel =
      builder.push(aggRel.getInput()).filter(pushedConditions).build();
  if (rel == aggRel.getInput(0)) {
    return null;
  }
  rel = aggRel.copy(aggRel.getTraitSet(), ImmutableList.of(rel));
  return rel;
}
 
Example 23
Source Project: Bats   Source File: RelMdSelectivity.java    License: Apache License 2.0 5 votes vote down vote up
public Double getSelectivity(Union rel, RelMetadataQuery mq,
    RexNode predicate) {
  if ((rel.getInputs().size() == 0) || (predicate == null)) {
    return 1.0;
  }

  double sumRows = 0.0;
  double sumSelectedRows = 0.0;
  int[] adjustments = new int[rel.getRowType().getFieldCount()];
  RexBuilder rexBuilder = rel.getCluster().getRexBuilder();
  for (RelNode input : rel.getInputs()) {
    Double nRows = mq.getRowCount(input);
    if (nRows == null) {
      return null;
    }

    // convert the predicate to reference the types of the union child
    RexNode modifiedPred =
        predicate.accept(
            new RelOptUtil.RexInputConverter(
                rexBuilder,
                null,
                input.getRowType().getFieldList(),
                adjustments));
    double sel = mq.getSelectivity(input, modifiedPred);

    sumRows += nRows;
    sumSelectedRows += nRows * sel;
  }

  if (sumRows < 1.0) {
    sumRows = 1.0;
  }
  return sumSelectedRows / sumRows;
}
 
Example 24
Source Project: calcite   Source File: RelBuilder.java    License: Apache License 2.0 5 votes vote down vote up
/**
 * Creates a projection that converts the current relational expression's
 * output to a desired row type.
 *
 * @param castRowType row type after cast
 * @param rename      if true, use field names from castRowType; if false,
 *                    preserve field names from rel
 */
public RelBuilder convert(RelDataType castRowType, boolean rename) {
  final RelNode r = build();
  final RelNode r2 =
      RelOptUtil.createCastRel(r, castRowType, rename,
          struct.projectFactory);
  push(r2);
  return this;
}
 
Example 25
Source Project: Bats   Source File: RexUtil.java    License: Apache License 2.0 5 votes vote down vote up
public RexNode toDnf(RexNode rex) {
    final List<RexNode> operands;
    switch (rex.getKind()) {
    case AND:
        operands = flattenAnd(((RexCall) rex).getOperands());
        final RexNode head = operands.get(0);
        final RexNode headDnf = toDnf(head);
        final List<RexNode> headDnfs = RelOptUtil.disjunctions(headDnf);
        final RexNode tail = and(Util.skip(operands));
        final RexNode tailDnf = toDnf(tail);
        final List<RexNode> tailDnfs = RelOptUtil.disjunctions(tailDnf);
        final List<RexNode> list = new ArrayList<>();
        for (RexNode h : headDnfs) {
            for (RexNode t : tailDnfs) {
                list.add(and(ImmutableList.of(h, t)));
            }
        }
        return or(list);
    case OR:
        operands = flattenOr(((RexCall) rex).getOperands());
        return or(toDnfs(operands));
    case NOT:
        final RexNode arg = ((RexCall) rex).getOperands().get(0);
        switch (arg.getKind()) {
        case NOT:
            return toDnf(((RexCall) arg).getOperands().get(0));
        case OR:
            operands = ((RexCall) arg).getOperands();
            return toDnf(and(Lists.transform(flattenOr(operands), RexUtil::addNot)));
        case AND:
            operands = ((RexCall) arg).getOperands();
            return toDnf(or(Lists.transform(flattenAnd(operands), RexUtil::addNot)));
        default:
            return rex;
        }
    default:
        return rex;
    }
}
 
Example 26
Source Project: dremio-oss   Source File: LogicalPlanCaptureListener.java    License: Apache License 2.0 5 votes vote down vote up
@Override
public void onPhaseCompletion(final PlannerPhase phase, final RelNode before, final RelNode after, final long millisTaken) {
  if (!Strings.isNullOrEmpty(plan)) {
    return;
  }

  if (phase == PlannerPhase.LOGICAL) {
    plan = RelOptUtil.dumpPlan("", after, SqlExplainFormat.TEXT, SqlExplainLevel.ALL_ATTRIBUTES);
  }
}
 
Example 27
Source Project: Mycat2   Source File: HBTBaseTest.java    License: GNU General Public License v3.0 5 votes vote down vote up
private void testRel(RelNode relNode, String expect) {
    Assert.assertEquals(
            expect.replace("\n", "").replace("\r", "").trim()
            ,
            RelOptUtil.toString(relNode, SqlExplainLevel.EXPPLAN_ATTRIBUTES)
                    .replace("\n", "").replace("\r", "").trim()
    );
}
 
Example 28
Source Project: streamline   Source File: RelNodeCompiler.java    License: Apache License 2.0 5 votes vote down vote up
private void beginJoinStage(Join join) {
  int[] ordinals = new int[2];
  if (!RelOptUtil.analyzeSimpleEquiJoin((LogicalJoin) join, ordinals)) {
    throw new UnsupportedOperationException("Only simple equi joins are supported");
  }

  pw.print(String.format(JOIN_STAGE_PROLOGUE, getStageName(join),
                         getStageName(join.getLeft()),
                         getStageName(join.getRight()),
                         ordinals[0],
                         ordinals[1]));
}
 
Example 29
Source Project: Bats   Source File: RelMdPredicates.java    License: Apache License 2.0 5 votes vote down vote up
/**
 * Infers predicates for an Aggregate.
 *
 * <p>Pulls up predicates that only contains references to columns in the
 * GroupSet. For e.g.
 *
 * <blockquote><pre>
 * inputPullUpExprs : { a &gt; 7, b + c &lt; 10, a + e = 9}
 * groupSet         : { a, b}
 * pulledUpExprs    : { a &gt; 7}
 * </pre></blockquote>
 */
public RelOptPredicateList getPredicates(Aggregate agg, RelMetadataQuery mq) {
  final RelNode input = agg.getInput();
  final RexBuilder rexBuilder = agg.getCluster().getRexBuilder();
  final RelOptPredicateList inputInfo = mq.getPulledUpPredicates(input);
  final List<RexNode> aggPullUpPredicates = new ArrayList<>();

  ImmutableBitSet groupKeys = agg.getGroupSet();
  if (groupKeys.isEmpty()) {
    // "GROUP BY ()" can convert an empty relation to a non-empty relation, so
    // it is not valid to pull up predicates. In particular, consider the
    // predicate "false": it is valid on all input rows (trivially - there are
    // no rows!) but not on the output (there is one row).
    return RelOptPredicateList.EMPTY;
  }
  Mapping m = Mappings.create(MappingType.PARTIAL_FUNCTION,
      input.getRowType().getFieldCount(), agg.getRowType().getFieldCount());

  int i = 0;
  for (int j : groupKeys) {
    m.set(j, i++);
  }

  for (RexNode r : inputInfo.pulledUpPredicates) {
    ImmutableBitSet rCols = RelOptUtil.InputFinder.bits(r);
    if (groupKeys.contains(rCols)) {
      r = r.accept(new RexPermuteInputsShuttle(m, input));
      aggPullUpPredicates.add(r);
    }
  }
  return RelOptPredicateList.of(rexBuilder, aggPullUpPredicates);
}
 
Example 30
Source Project: dremio-oss   Source File: JoinUtils.java    License: Apache License 2.0 5 votes vote down vote up
/**
   * Check if the given RelNode contains any Cartesian join.
   * Return true if find one. Otherwise, return false.
   *
   * @param relNode   the RelNode to be inspected.
   * @param leftKeys  a list used for the left input into the join which has
   *                  equi-join keys. It can be empty or not (but not null),
   *                  this method will clear this list before using it.
   * @param rightKeys a list used for the right input into the join which has
   *                  equi-join keys. It can be empty or not (but not null),
   *                  this method will clear this list before using it.
   * @param filterNulls   The join key positions for which null values will not
   *                      match. null values only match for the "is not distinct
   *                      from" condition.
   * @return          Return true if the given relNode contains Cartesian join.
   *                  Otherwise, return false
   */
public static boolean checkCartesianJoin(RelNode relNode, List<Integer> leftKeys, List<Integer> rightKeys, List<Boolean> filterNulls) {
  if (relNode instanceof Join) {
    leftKeys.clear();
    rightKeys.clear();

    Join joinRel = (Join) relNode;
    RelNode left = joinRel.getLeft();
    RelNode right = joinRel.getRight();

    RexNode remaining = RelOptUtil.splitJoinCondition(left, right, joinRel.getCondition(), leftKeys, rightKeys, filterNulls);
    if(joinRel.getJoinType() == JoinRelType.INNER) {
      if(leftKeys.isEmpty() || rightKeys.isEmpty()) {
        return true;
      }
    } else {
      if(!remaining.isAlwaysTrue() || leftKeys.isEmpty() || rightKeys.isEmpty()) {
        return true;
      }
    }
  }

  for (RelNode child : relNode.getInputs()) {
    if(checkCartesianJoin(child, leftKeys, rightKeys, filterNulls)) {
      return true;
    }
  }

  return false;
}