org.apache.calcite.rel.core.SetOp Java Examples

The following examples show how to use org.apache.calcite.rel.core.SetOp. 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: UnionMergeRule.java    From calcite with Apache License 2.0 6 votes vote down vote up
@Override public boolean matches(RelOptRuleCall call) {
  // It avoids adding the rule match to the match queue in case the rule is known to be a no-op
  final SetOp topOp = call.rel(0);
  @SuppressWarnings("unchecked") final Class<? extends SetOp> setOpClass =
      (Class<? extends SetOp>) operands.get(0).getMatchedClass();
  final SetOp bottomOp;
  if (setOpClass.isInstance(call.rel(2))
      && !Minus.class.isAssignableFrom(setOpClass)) {
    bottomOp = call.rel(2);
  } else if (setOpClass.isInstance(call.rel(1))) {
    bottomOp = call.rel(1);
  } else {
    return false;
  }

  if (topOp.all && !bottomOp.all) {
    return false;
  }

  return true;
}
 
Example #2
Source File: RelMdUniqueKeys.java    From Bats with Apache License 2.0 5 votes vote down vote up
public Set<ImmutableBitSet> getUniqueKeys(SetOp rel, RelMetadataQuery mq,
    boolean ignoreNulls) {
  if (!rel.all) {
    return ImmutableSet.of(
        ImmutableBitSet.range(rel.getRowType().getFieldCount()));
  }
  return ImmutableSet.of();
}
 
Example #3
Source File: Bindables.java    From calcite with Apache License 2.0 5 votes vote down vote up
public RelNode convert(RelNode rel) {
  final SetOp setOp = (SetOp) rel;
  final BindableConvention out = BindableConvention.INSTANCE;
  final RelTraitSet traitSet = setOp.getTraitSet().replace(out);
  if (setOp instanceof LogicalUnion) {
    return new BindableUnion(rel.getCluster(), traitSet,
        convertList(setOp.getInputs(), out), setOp.all);
  } else if (setOp instanceof LogicalIntersect) {
    return new BindableIntersect(rel.getCluster(), traitSet,
        convertList(setOp.getInputs(), out), setOp.all);
  } else {
    return new BindableMinus(rel.getCluster(), traitSet,
        convertList(setOp.getInputs(), out), setOp.all);
  }
}
 
Example #4
Source File: FilterSetOpTransposeRule.java    From calcite with Apache License 2.0 5 votes vote down vote up
public void onMatch(RelOptRuleCall call) {
  Filter filterRel = call.rel(0);
  SetOp setOp = call.rel(1);

  RexNode condition = filterRel.getCondition();

  // create filters on top of each setop child, modifying the filter
  // condition to reference each setop child
  RexBuilder rexBuilder = filterRel.getCluster().getRexBuilder();
  final RelBuilder relBuilder = call.builder();
  List<RelDataTypeField> origFields =
      setOp.getRowType().getFieldList();
  int[] adjustments = new int[origFields.size()];
  final List<RelNode> newSetOpInputs = new ArrayList<>();
  for (RelNode input : setOp.getInputs()) {
    RexNode newCondition =
        condition.accept(
            new RelOptUtil.RexInputConverter(
                rexBuilder,
                origFields,
                input.getRowType().getFieldList(),
                adjustments));
    newSetOpInputs.add(relBuilder.push(input).filter(newCondition).build());
  }

  // create a new setop whose children are the filters created above
  SetOp newSetOp =
      setOp.copy(setOp.getTraitSet(), newSetOpInputs);

  call.transformTo(newSetOp);
}
 
Example #5
Source File: FilterSetOpTransposeRule.java    From calcite with Apache License 2.0 5 votes vote down vote up
/**
 * Creates a FilterSetOpTransposeRule.
 */
public FilterSetOpTransposeRule(RelBuilderFactory relBuilderFactory) {
  super(
      operand(Filter.class,
          operand(SetOp.class, any())),
      relBuilderFactory, null);
}
 
Example #6
Source File: ProjectSetOpTransposeRule.java    From calcite with Apache License 2.0 5 votes vote down vote up
/**
 * Creates a ProjectSetOpTransposeRule with an explicit condition whether
 * to preserve expressions.
 *
 * @param preserveExprCondition Condition whether to preserve expressions
 */
public ProjectSetOpTransposeRule(
    PushProjector.ExprCondition preserveExprCondition,
    RelBuilderFactory relBuilderFactory) {
  super(
      operand(
          LogicalProject.class,
          operand(SetOp.class, any())),
      relBuilderFactory, null);
  this.preserveExprCondition = preserveExprCondition;
}
 
Example #7
Source File: UnionMergeRule.java    From calcite with Apache License 2.0 5 votes vote down vote up
/** Creates a UnionMergeRule. */
public UnionMergeRule(Class<? extends SetOp> unionClazz, String description,
    RelBuilderFactory relBuilderFactory) {
  super(
      operand(unionClazz,
          operand(RelNode.class, any()),
          operand(RelNode.class, any())),
      relBuilderFactory, description);
}
 
Example #8
Source File: RelMdColumnUniqueness.java    From calcite with Apache License 2.0 5 votes vote down vote up
public Boolean areColumnsUnique(Minus rel, RelMetadataQuery mq,
    ImmutableBitSet columns, boolean ignoreNulls) {
  columns = decorateWithConstantColumnsFromPredicates(columns, rel, mq);
  if (areColumnsUnique((SetOp) rel, mq, columns, ignoreNulls)) {
    return true;
  }
  return mq.areColumnsUnique(rel.getInput(0), columns, ignoreNulls);
}
 
Example #9
Source File: RelMdColumnUniqueness.java    From calcite with Apache License 2.0 5 votes vote down vote up
public Boolean areColumnsUnique(Intersect rel, RelMetadataQuery mq,
    ImmutableBitSet columns, boolean ignoreNulls) {
  columns = decorateWithConstantColumnsFromPredicates(columns, rel, mq);
  if (areColumnsUnique((SetOp) rel, mq, columns, ignoreNulls)) {
    return true;
  }
  for (RelNode input : rel.getInputs()) {
    Boolean b = mq.areColumnsUnique(input, columns, ignoreNulls);
    if (b != null && b) {
      return true;
    }
  }
  return false;
}
 
Example #10
Source File: RelMdColumnUniqueness.java    From calcite with Apache License 2.0 5 votes vote down vote up
public Boolean areColumnsUnique(SetOp rel, RelMetadataQuery mq,
    ImmutableBitSet columns, boolean ignoreNulls) {
  columns = decorateWithConstantColumnsFromPredicates(columns, rel, mq);
  // If not ALL then the rows are distinct.
  // Therefore the set of all columns is a key.
  return !rel.all
      && columns.nextClearBit(0) >= rel.getRowType().getFieldCount();
}
 
Example #11
Source File: RelMdUniqueKeys.java    From calcite with Apache License 2.0 5 votes vote down vote up
public Set<ImmutableBitSet> getUniqueKeys(SetOp rel, RelMetadataQuery mq,
    boolean ignoreNulls) {
  if (!rel.all) {
    return ImmutableSet.of(
        ImmutableBitSet.range(rel.getRowType().getFieldCount()));
  }
  return ImmutableSet.of();
}
 
Example #12
Source File: RelMdTableReferences.java    From calcite with Apache License 2.0 5 votes vote down vote up
/**
 * Table references from Union, Intersect, Minus.
 *
 * <p>For Union operator, we might be able to extract multiple table
 * references.
 */
public Set<RelTableRef> getTableReferences(SetOp rel, RelMetadataQuery mq) {
  final Set<RelTableRef> result = new HashSet<>();

  // Infer column origin expressions for given references
  final Multimap<List<String>, RelTableRef> qualifiedNamesToRefs = HashMultimap.create();
  for (RelNode input : rel.getInputs()) {
    final Map<RelTableRef, RelTableRef> currentTablesMapping = new HashMap<>();
    final Set<RelTableRef> inputTableRefs = mq.getTableReferences(input);
    if (inputTableRefs == null) {
      // We could not infer the table refs from input
      return null;
    }
    for (RelTableRef tableRef : inputTableRefs) {
      int shift = 0;
      Collection<RelTableRef> lRefs = qualifiedNamesToRefs.get(
          tableRef.getQualifiedName());
      if (lRefs != null) {
        shift = lRefs.size();
      }
      RelTableRef shiftTableRef = RelTableRef.of(
          tableRef.getTable(), shift + tableRef.getEntityNumber());
      assert !result.contains(shiftTableRef);
      result.add(shiftTableRef);
      currentTablesMapping.put(tableRef, shiftTableRef);
    }
    // Add to existing qualified names
    for (RelTableRef newRef : currentTablesMapping.values()) {
      qualifiedNamesToRefs.put(newRef.getQualifiedName(), newRef);
    }
  }

  // Return result
  return result;
}
 
Example #13
Source File: RelMdColumnOrigins.java    From calcite with Apache License 2.0 5 votes vote down vote up
public Set<RelColumnOrigin> getColumnOrigins(SetOp rel,
    RelMetadataQuery mq, int iOutputColumn) {
  final Set<RelColumnOrigin> set = new HashSet<>();
  for (RelNode input : rel.getInputs()) {
    Set<RelColumnOrigin> inputSet = mq.getColumnOrigins(input, iOutputColumn);
    if (inputSet == null) {
      return null;
    }
    set.addAll(inputSet);
  }
  return set;
}
 
Example #14
Source File: DremioFieldTrimmer.java    From dremio-oss with Apache License 2.0 5 votes vote down vote up
@Override
public TrimResult trimFields(
    SetOp setOp,
    ImmutableBitSet fieldsUsed,
    Set<RelDataTypeField> extraFields) {
  if(!setOp.all) {
    return result(setOp, Mappings.createIdentity(setOp.getRowType().getFieldCount()));
  }
  return super.trimFields(setOp, fieldsUsed, extraFields);
}
 
Example #15
Source File: RelMdColumnOrigins.java    From Bats with Apache License 2.0 5 votes vote down vote up
public Set<RelColumnOrigin> getColumnOrigins(SetOp rel,
    RelMetadataQuery mq, int iOutputColumn) {
  final Set<RelColumnOrigin> set = new HashSet<>();
  for (RelNode input : rel.getInputs()) {
    Set<RelColumnOrigin> inputSet = mq.getColumnOrigins(input, iOutputColumn);
    if (inputSet == null) {
      return null;
    }
    set.addAll(inputSet);
  }
  return set;
}
 
Example #16
Source File: FilterSetOpTransposeRule.java    From Bats with Apache License 2.0 5 votes vote down vote up
public void onMatch(RelOptRuleCall call) {
  Filter filterRel = call.rel(0);
  SetOp setOp = call.rel(1);

  RexNode condition = filterRel.getCondition();

  // create filters on top of each setop child, modifying the filter
  // condition to reference each setop child
  RexBuilder rexBuilder = filterRel.getCluster().getRexBuilder();
  final RelBuilder relBuilder = call.builder();
  List<RelDataTypeField> origFields =
      setOp.getRowType().getFieldList();
  int[] adjustments = new int[origFields.size()];
  final List<RelNode> newSetOpInputs = new ArrayList<>();
  for (RelNode input : setOp.getInputs()) {
    RexNode newCondition =
        condition.accept(
            new RelOptUtil.RexInputConverter(
                rexBuilder,
                origFields,
                input.getRowType().getFieldList(),
                adjustments));
    newSetOpInputs.add(relBuilder.push(input).filter(newCondition).build());
  }

  // create a new setop whose children are the filters created above
  SetOp newSetOp =
      setOp.copy(setOp.getTraitSet(), newSetOpInputs);

  call.transformTo(newSetOp);
}
 
Example #17
Source File: FilterSetOpTransposeRule.java    From Bats with Apache License 2.0 5 votes vote down vote up
/**
 * Creates a FilterSetOpTransposeRule.
 */
public FilterSetOpTransposeRule(RelBuilderFactory relBuilderFactory) {
  super(
      operand(Filter.class,
          operand(SetOp.class, any())),
      relBuilderFactory, null);
}
 
Example #18
Source File: ProjectSetOpTransposeRule.java    From Bats with Apache License 2.0 5 votes vote down vote up
public void onMatch(RelOptRuleCall call) {
  LogicalProject origProj = call.rel(0);
  SetOp setOp = call.rel(1);

  // cannot push project past a distinct
  if (!setOp.all) {
    return;
  }

  // locate all fields referenced in the projection
  PushProjector pushProject =
      new PushProjector(
          origProj, null, setOp, preserveExprCondition, call.builder());
  pushProject.locateAllRefs();

  List<RelNode> newSetOpInputs = new ArrayList<>();
  int[] adjustments = pushProject.getAdjustments();

  // push the projects completely below the setop; this
  // is different from pushing below a join, where we decompose
  // to try to keep expensive expressions above the join,
  // because UNION ALL does not have any filtering effect,
  // and it is the only operator this rule currently acts on
  for (RelNode input : setOp.getInputs()) {
    // be lazy:  produce two ProjectRels, and let another rule
    // merge them (could probably just clone origProj instead?)
    Project p = pushProject.createProjectRefsAndExprs(input, true, false);
    newSetOpInputs.add(pushProject.createNewProject(p, adjustments));
  }

  // create a new setop whose children are the ProjectRels created above
  SetOp newSetOp =
      setOp.copy(setOp.getTraitSet(), newSetOpInputs);

  call.transformTo(newSetOp);
}
 
Example #19
Source File: ProjectSetOpTransposeRule.java    From Bats with Apache License 2.0 5 votes vote down vote up
/**
 * Creates a ProjectSetOpTransposeRule with an explicit condition whether
 * to preserve expressions.
 *
 * @param preserveExprCondition Condition whether to preserve expressions
 */
public ProjectSetOpTransposeRule(
    PushProjector.ExprCondition preserveExprCondition,
    RelBuilderFactory relBuilderFactory) {
  super(
      operand(
          LogicalProject.class,
          operand(SetOp.class, any())),
      relBuilderFactory, null);
  this.preserveExprCondition = preserveExprCondition;
}
 
Example #20
Source File: UnionMergeRule.java    From Bats with Apache License 2.0 5 votes vote down vote up
/** Creates a UnionMergeRule. */
public UnionMergeRule(Class<? extends SetOp> unionClazz, String description,
    RelBuilderFactory relBuilderFactory) {
  super(
      operand(unionClazz,
          operand(RelNode.class, any()),
          operand(RelNode.class, any())),
      relBuilderFactory, description);
}
 
Example #21
Source File: RelMdColumnUniqueness.java    From Bats with Apache License 2.0 5 votes vote down vote up
public Boolean areColumnsUnique(Minus rel, RelMetadataQuery mq,
    ImmutableBitSet columns, boolean ignoreNulls) {
  if (areColumnsUnique((SetOp) rel, mq, columns, ignoreNulls)) {
    return true;
  }
  return mq.areColumnsUnique(rel.getInput(0), columns, ignoreNulls);
}
 
Example #22
Source File: RelMdColumnUniqueness.java    From Bats with Apache License 2.0 5 votes vote down vote up
public Boolean areColumnsUnique(SetOp rel, RelMetadataQuery mq,
    ImmutableBitSet columns, boolean ignoreNulls) {
  // If not ALL then the rows are distinct.
  // Therefore the set of all columns is a key.
  return !rel.all
      && columns.nextClearBit(0) >= rel.getRowType().getFieldCount();
}
 
Example #23
Source File: RelMdColumnUniqueness.java    From Bats with Apache License 2.0 5 votes vote down vote up
public Boolean areColumnsUnique(Intersect rel, RelMetadataQuery mq,
    ImmutableBitSet columns, boolean ignoreNulls) {
  if (areColumnsUnique((SetOp) rel, mq, columns, ignoreNulls)) {
    return true;
  }
  for (RelNode input : rel.getInputs()) {
    Boolean b = mq.areColumnsUnique(input, columns, ignoreNulls);
    if (b != null && b) {
      return true;
    }
  }
  return false;
}
 
Example #24
Source File: SetOpNode.java    From calcite with Apache License 2.0 4 votes vote down vote up
public SetOpNode(Compiler compiler, SetOp setOp) {
  leftSource = compiler.source(setOp, 0);
  rightSource = compiler.source(setOp, 1);
  sink = compiler.sink(setOp);
  this.setOp = setOp;
}
 
Example #25
Source File: SubQueryDecorrelator.java    From flink with Apache License 2.0 4 votes vote down vote up
/**
 * check whether a SetOp has some children node which have correlation condition.
 * e.g. SELECT a FROM l WHERE b IN (SELECT r1.e FROM r1 WHERE l.a = r1.d UNION SELECT r2.i FROM r2)
 */
private void checkCorConditionOfSetOpInputs(SetOp setOp) {
	for (RelNode child : setOp.getInputs()) {
		checkCorConditionOfInput(child);
	}
}
 
Example #26
Source File: Nodes.java    From calcite with Apache License 2.0 4 votes vote down vote up
public void visit(SetOp setOp) {
  node = new SetOpNode(this, setOp);
}
 
Example #27
Source File: Bindables.java    From calcite with Apache License 2.0 4 votes vote down vote up
/**
 * Creates a BindableSetOpRule.
 *
 * @param relBuilderFactory Builder for relational expressions
 */
public BindableSetOpRule(RelBuilderFactory relBuilderFactory) {
  super(SetOp.class, (Predicate<RelNode>) r -> true,
      Convention.NONE, BindableConvention.INSTANCE, relBuilderFactory,
      "BindableSetOpRule");
}
 
Example #28
Source File: RelFieldTrimmer.java    From calcite with Apache License 2.0 4 votes vote down vote up
/**
 * Variant of {@link #trimFields(RelNode, ImmutableBitSet, Set)} for
 * {@link org.apache.calcite.rel.core.SetOp} (including UNION and UNION ALL).
 */
public TrimResult trimFields(
    SetOp setOp,
    ImmutableBitSet fieldsUsed,
    Set<RelDataTypeField> extraFields) {
  final RelDataType rowType = setOp.getRowType();
  final int fieldCount = rowType.getFieldCount();
  int changeCount = 0;

  // Fennel abhors an empty row type, so pretend that the parent rel
  // wants the last field. (The last field is the least likely to be a
  // system field.)
  if (fieldsUsed.isEmpty()) {
    fieldsUsed = ImmutableBitSet.of(rowType.getFieldCount() - 1);
  }

  // Compute the desired field mapping. Give the consumer the fields they
  // want, in the order that they appear in the bitset.
  final Mapping mapping = createMapping(fieldsUsed, fieldCount);

  // Create input with trimmed columns.
  for (RelNode input : setOp.getInputs()) {
    TrimResult trimResult =
        trimChild(setOp, input, fieldsUsed, extraFields);

    // We want "mapping", the input gave us "inputMapping", compute
    // "remaining" mapping.
    //    |                   |                |
    //    |---------------- mapping ---------->|
    //    |-- inputMapping -->|                |
    //    |                   |-- remaining -->|
    //
    // For instance, suppose we have columns [a, b, c, d],
    // the consumer asked for mapping = [b, d],
    // and the transformed input has columns inputMapping = [d, a, b].
    // remaining will permute [b, d] to [d, a, b].
    Mapping remaining = Mappings.divide(mapping, trimResult.right);

    // Create a projection; does nothing if remaining is identity.
    relBuilder.push(trimResult.left);
    relBuilder.permute(remaining);

    if (input != relBuilder.peek()) {
      ++changeCount;
    }
  }

  // If the input is unchanged, and we need to project all columns,
  // there's to do.
  if (changeCount == 0
      && mapping.isIdentity()) {
    for (RelNode input : setOp.getInputs()) {
      relBuilder.build();
    }
    return result(setOp, mapping);
  }

  switch (setOp.kind) {
  case UNION:
    relBuilder.union(setOp.all, setOp.getInputs().size());
    break;
  case INTERSECT:
    relBuilder.intersect(setOp.all, setOp.getInputs().size());
    break;
  case EXCEPT:
    assert setOp.getInputs().size() == 2;
    relBuilder.minus(setOp.all);
    break;
  default:
    throw new AssertionError("unknown setOp " + setOp);
  }
  return result(relBuilder.build(), mapping);
}
 
Example #29
Source File: JoinUnionTransposeRule.java    From calcite with Apache License 2.0 4 votes vote down vote up
public void onMatch(RelOptRuleCall call) {
  final Join join = call.rel(0);
  final Union unionRel;
  RelNode otherInput;
  boolean unionOnLeft;
  if (call.rel(1) instanceof Union) {
    unionRel = call.rel(1);
    otherInput = call.rel(2);
    unionOnLeft = true;
  } else {
    otherInput = call.rel(1);
    unionRel = call.rel(2);
    unionOnLeft = false;
  }
  if (!unionRel.all) {
    return;
  }
  if (!join.getVariablesSet().isEmpty()) {
    return;
  }
  // The UNION ALL cannot be on the null generating side
  // of an outer join (otherwise we might generate incorrect
  // rows for the other side for join keys which lack a match
  // in one or both branches of the union)
  if (unionOnLeft) {
    if (join.getJoinType().generatesNullsOnLeft()) {
      return;
    }
  } else {
    if (join.getJoinType().generatesNullsOnRight()
        || !join.getJoinType().projectsRight()) {
      return;
    }
  }
  List<RelNode> newUnionInputs = new ArrayList<>();
  for (RelNode input : unionRel.getInputs()) {
    RelNode joinLeft;
    RelNode joinRight;
    if (unionOnLeft) {
      joinLeft = input;
      joinRight = otherInput;
    } else {
      joinLeft = otherInput;
      joinRight = input;
    }
    newUnionInputs.add(
        join.copy(
            join.getTraitSet(),
            join.getCondition(),
            joinLeft,
            joinRight,
            join.getJoinType(),
            join.isSemiJoinDone()));
  }
  final SetOp newUnionRel =
      unionRel.copy(unionRel.getTraitSet(), newUnionInputs, true);
  call.transformTo(newUnionRel);
}
 
Example #30
Source File: RelMdDistribution.java    From Bats with Apache License 2.0 4 votes vote down vote up
public RelDistribution distribution(SetOp rel, RelMetadataQuery mq) {
  return mq.distribution(rel.getInputs().get(0));
}