Java Code Examples for org.apache.calcite.util.ImmutableBitSet#isEmpty()
The following examples show how to use
org.apache.calcite.util.ImmutableBitSet#isEmpty() .
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: RelMdDistinctRowCount.java From Bats with Apache License 2.0 | 6 votes |
public Double getDistinctRowCount(Filter rel, RelMetadataQuery mq, ImmutableBitSet groupKey, RexNode predicate) { if (predicate == null || predicate.isAlwaysTrue()) { if (groupKey.isEmpty()) { return 1D; } } // REVIEW zfong 4/18/06 - In the Broadbase code, duplicates are not // removed from the two filter lists. However, the code below is // doing so. RexNode unionPreds = RelMdUtil.unionPreds( rel.getCluster().getRexBuilder(), predicate, rel.getCondition()); return mq.getDistinctRowCount(rel.getInput(), groupKey, unionPreds); }
Example 2
Source File: RelMdExpressionLineage.java From Bats with Apache License 2.0 | 6 votes |
/** * Given an expression, it will create all equivalent expressions resulting * from replacing all possible combinations of references in the mapping by * the corresponding expressions. * * @param rexBuilder rexBuilder * @param expr expression * @param mapping mapping * @return set of resulting expressions equivalent to the input expression */ protected static Set<RexNode> createAllPossibleExpressions(RexBuilder rexBuilder, RexNode expr, Map<RexInputRef, Set<RexNode>> mapping) { // Extract input fields referenced by expression final ImmutableBitSet predFieldsUsed = extractInputRefs(expr); if (predFieldsUsed.isEmpty()) { // The unique expression is the input expression return ImmutableSet.of(expr); } try { return createAllPossibleExpressions(rexBuilder, expr, predFieldsUsed, mapping, new HashMap<>()); } catch (UnsupportedOperationException e) { // There may be a RexNode unsupported by RexCopier, just return null return null; } }
Example 3
Source File: RelMdExpressionLineage.java From calcite with Apache License 2.0 | 6 votes |
/** * Given an expression, it will create all equivalent expressions resulting * from replacing all possible combinations of references in the mapping by * the corresponding expressions. * * @param rexBuilder rexBuilder * @param expr expression * @param mapping mapping * @return set of resulting expressions equivalent to the input expression */ @Nullable protected static Set<RexNode> createAllPossibleExpressions(RexBuilder rexBuilder, RexNode expr, Map<RexInputRef, Set<RexNode>> mapping) { // Extract input fields referenced by expression final ImmutableBitSet predFieldsUsed = extractInputRefs(expr); if (predFieldsUsed.isEmpty()) { // The unique expression is the input expression return ImmutableSet.of(expr); } try { return createAllPossibleExpressions(rexBuilder, expr, predFieldsUsed, mapping, new HashMap<>()); } catch (UnsupportedOperationException e) { // There may be a RexNode unsupported by RexCopier, just return null return null; } }
Example 4
Source File: RelMdUtil.java From calcite with Apache License 2.0 | 6 votes |
/** * Computes the number of distinct rows for a set of keys returned from a * semi-join * * @param semiJoinRel RelNode representing the semi-join * @param mq metadata query * @param groupKey keys that the distinct row count will be computed for * @param predicate join predicate * @return number of distinct rows */ public static Double getSemiJoinDistinctRowCount(Join semiJoinRel, RelMetadataQuery mq, ImmutableBitSet groupKey, RexNode predicate) { if (predicate == null || predicate.isAlwaysTrue()) { if (groupKey.isEmpty()) { return 1D; } } // create a RexNode representing the selectivity of the // semijoin filter and pass it to getDistinctRowCount RexNode newPred = RelMdUtil.makeSemiJoinSelectivityRexNode(mq, semiJoinRel); if (predicate != null) { RexBuilder rexBuilder = semiJoinRel.getCluster().getRexBuilder(); newPred = rexBuilder.makeCall( SqlStdOperatorTable.AND, newPred, predicate); } return mq.getDistinctRowCount(semiJoinRel.getLeft(), groupKey, newPred); }
Example 5
Source File: FlinkRelMetadataQuery.java From flink with Apache License 2.0 | 6 votes |
/** * Returns the (minimum) unique groups of the given columns. * * @param rel the relational expression * @param columns the given columns in a specified relational expression. * The given columns should not be null. * @return the (minimum) unique columns which should be a sub-collection of the given columns, * and should not be null or empty. If none unique columns can be found, return the * given columns. */ public ImmutableBitSet getUniqueGroups(RelNode rel, ImmutableBitSet columns) { for (; ; ) { try { Preconditions.checkArgument(columns != null); if (columns.isEmpty()) { return columns; } ImmutableBitSet uniqueGroups = uniqueGroupsHandler.getUniqueGroups(rel, this, columns); Preconditions.checkArgument(uniqueGroups != null && !uniqueGroups.isEmpty()); Preconditions.checkArgument(columns.contains(uniqueGroups)); return uniqueGroups; } catch (JaninoRelMetadataProvider.NoHandler e) { uniqueGroupsHandler = revise(e.relClass, FlinkMetadata.UniqueGroups.DEF); } } }
Example 6
Source File: FlinkRelMetadataQuery.java From flink with Apache License 2.0 | 6 votes |
/** * Returns the (minimum) unique groups of the given columns. * * @param rel the relational expression * @param columns the given columns in a specified relational expression. * The given columns should not be null. * @return the (minimum) unique columns which should be a sub-collection of the given columns, * and should not be null or empty. If none unique columns can be found, return the * given columns. */ public ImmutableBitSet getUniqueGroups(RelNode rel, ImmutableBitSet columns) { for (; ; ) { try { Preconditions.checkArgument(columns != null); if (columns.isEmpty()) { return columns; } ImmutableBitSet uniqueGroups = uniqueGroupsHandler.getUniqueGroups(rel, this, columns); Preconditions.checkArgument(uniqueGroups != null && !uniqueGroups.isEmpty()); Preconditions.checkArgument(columns.contains(uniqueGroups)); return uniqueGroups; } catch (JaninoRelMetadataProvider.NoHandler e) { uniqueGroupsHandler = revise(e.relClass, FlinkMetadata.UniqueGroups.DEF); } } }
Example 7
Source File: RelMdDistinctRowCount.java From calcite with Apache License 2.0 | 5 votes |
public Double getDistinctRowCount(Aggregate rel, RelMetadataQuery mq, ImmutableBitSet groupKey, RexNode predicate) { if (predicate == null || predicate.isAlwaysTrue()) { if (groupKey.isEmpty()) { return 1D; } } // determine which predicates can be applied on the child of the // aggregate final List<RexNode> notPushable = new ArrayList<>(); final List<RexNode> pushable = new ArrayList<>(); RelOptUtil.splitFilters( rel.getGroupSet(), predicate, pushable, notPushable); final RexBuilder rexBuilder = rel.getCluster().getRexBuilder(); RexNode childPreds = RexUtil.composeConjunction(rexBuilder, pushable, true); // set the bits as they correspond to the child input ImmutableBitSet.Builder childKey = ImmutableBitSet.builder(); RelMdUtil.setAggChildKeys(groupKey, rel, childKey); Double distinctRowCount = mq.getDistinctRowCount(rel.getInput(), childKey.build(), childPreds); if (distinctRowCount == null) { return null; } else if (notPushable.isEmpty()) { return distinctRowCount; } else { RexNode preds = RexUtil.composeConjunction(rexBuilder, notPushable, true); return distinctRowCount * RelMdUtil.guessSelectivity(preds); } }
Example 8
Source File: RelMdPredicates.java From calcite with Apache License 2.0 | 5 votes |
/** * 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 > 7, b + c < 10, a + e = 9} * groupSet : { a, b} * pulledUpExprs : { a > 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 9
Source File: RelMdRowCount.java From dremio-oss with Apache License 2.0 | 5 votes |
@Override public Double getRowCount(Aggregate rel, RelMetadataQuery mq) { ImmutableBitSet groupKey = ImmutableBitSet.range(rel.getGroupCount()); if (groupKey.isEmpty()) { return 1.0; } return rel.estimateRowCount(mq); }
Example 10
Source File: RelMdDistinctRowCount.java From dremio-oss with Apache License 2.0 | 5 votes |
public Double getDistinctRowCount(Join rel, RelMetadataQuery mq, ImmutableBitSet groupKey, RexNode predicate) { if (predicate == null || predicate.isAlwaysTrue()) { if (groupKey.isEmpty()) { return 1D; } } return getDistinctRowCountFromEstimateRowCount(rel, mq, groupKey, predicate); }
Example 11
Source File: DrillRelMdRowCount.java From Bats with Apache License 2.0 | 5 votes |
@Override public Double getRowCount(Aggregate rel, RelMetadataQuery mq) { ImmutableBitSet groupKey = ImmutableBitSet.range(rel.getGroupCount()); if (groupKey.isEmpty()) { return 1.0; } else { return super.getRowCount(rel, mq); } }
Example 12
Source File: SqlValidatorUtil.java From Bats with Apache License 2.0 | 5 votes |
/** Computes the rollup of bit sets. * * <p>For example, <code>rollup({0}, {1})</code> * returns <code>({0, 1}, {0}, {})</code>. * * <p>Bit sets are not necessarily singletons: * <code>rollup({0, 2}, {3, 5})</code> * returns <code>({0, 2, 3, 5}, {0, 2}, {})</code>. */ @VisibleForTesting public static ImmutableList<ImmutableBitSet> rollup( List<ImmutableBitSet> bitSets) { Set<ImmutableBitSet> builder = new LinkedHashSet<>(); for (;;) { final ImmutableBitSet union = ImmutableBitSet.union(bitSets); builder.add(union); if (union.isEmpty()) { break; } bitSets = bitSets.subList(0, bitSets.size() - 1); } return ImmutableList.copyOf(builder); }
Example 13
Source File: RelMdPredicates.java From Bats with Apache License 2.0 | 5 votes |
/** * 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 > 7, b + c < 10, a + e = 9} * groupSet : { a, b} * pulledUpExprs : { a > 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 14
Source File: SqlValidatorUtil.java From calcite with Apache License 2.0 | 5 votes |
/** Computes the rollup of bit sets. * * <p>For example, <code>rollup({0}, {1})</code> * returns <code>({0, 1}, {0}, {})</code>. * * <p>Bit sets are not necessarily singletons: * <code>rollup({0, 2}, {3, 5})</code> * returns <code>({0, 2, 3, 5}, {0, 2}, {})</code>. */ @VisibleForTesting public static ImmutableList<ImmutableBitSet> rollup( List<ImmutableBitSet> bitSets) { Set<ImmutableBitSet> builder = new LinkedHashSet<>(); for (;;) { final ImmutableBitSet union = ImmutableBitSet.union(bitSets); builder.add(union); if (union.isEmpty()) { break; } bitSets = bitSets.subList(0, bitSets.size() - 1); } return ImmutableList.copyOf(builder); }
Example 15
Source File: RelMdDistinctRowCount.java From Bats with Apache License 2.0 | 5 votes |
public Double getDistinctRowCount(Join rel, RelMetadataQuery mq, ImmutableBitSet groupKey, RexNode predicate) { if (predicate == null || predicate.isAlwaysTrue()) { if (groupKey.isEmpty()) { return 1D; } } return RelMdUtil.getJoinDistinctRowCount(mq, rel, rel.getJoinType(), groupKey, predicate, false); }
Example 16
Source File: RelMdDistinctRowCount.java From calcite with Apache License 2.0 | 4 votes |
public Double getDistinctRowCount(Project rel, RelMetadataQuery mq, ImmutableBitSet groupKey, RexNode predicate) { if (predicate == null || predicate.isAlwaysTrue()) { if (groupKey.isEmpty()) { return 1D; } } ImmutableBitSet.Builder baseCols = ImmutableBitSet.builder(); ImmutableBitSet.Builder projCols = ImmutableBitSet.builder(); List<RexNode> projExprs = rel.getProjects(); RelMdUtil.splitCols(projExprs, groupKey, baseCols, projCols); final List<RexNode> notPushable = new ArrayList<>(); final List<RexNode> pushable = new ArrayList<>(); RelOptUtil.splitFilters( ImmutableBitSet.range(rel.getRowType().getFieldCount()), predicate, pushable, notPushable); final RexBuilder rexBuilder = rel.getCluster().getRexBuilder(); // get the distinct row count of the child input, passing in the // columns and filters that only reference the child; convert the // filter to reference the children projection expressions RexNode childPred = RexUtil.composeConjunction(rexBuilder, pushable, true); RexNode modifiedPred; if (childPred == null) { modifiedPred = null; } else { modifiedPred = RelOptUtil.pushPastProject(childPred, rel); } Double distinctRowCount = mq.getDistinctRowCount(rel.getInput(), baseCols.build(), modifiedPred); if (distinctRowCount == null) { return null; } else if (!notPushable.isEmpty()) { RexNode preds = RexUtil.composeConjunction(rexBuilder, notPushable, true); distinctRowCount *= RelMdUtil.guessSelectivity(preds); } // No further computation required if the projection expressions // are all column references if (projCols.cardinality() == 0) { return distinctRowCount; } // multiply by the cardinality of the non-child projection expressions for (int bit : projCols.build()) { Double subRowCount = RelMdUtil.cardOfProjExpr(mq, rel, projExprs.get(bit)); if (subRowCount == null) { return null; } distinctRowCount *= subRowCount; } return RelMdUtil.numDistinctVals(distinctRowCount, mq.getRowCount(rel)); }
Example 17
Source File: ReduceExpressionsRule.java From Bats with Apache License 2.0 | 4 votes |
/** Pushes predicates into a CASE. * * <p>We have a loose definition of 'predicate': any boolean expression will * do, except CASE. For example '(CASE ...) = 5' or '(CASE ...) IS NULL'. */ public static RexCall pushPredicateIntoCase(RexCall call) { if (call.getType().getSqlTypeName() != SqlTypeName.BOOLEAN) { return call; } switch (call.getKind()) { case CASE: case AND: case OR: return call; // don't push CASE into CASE! case EQUALS: { // checks that the EQUALS operands may be splitted and // doesn't push EQUALS into CASE List<RexNode> equalsOperands = call.getOperands(); ImmutableBitSet left = RelOptUtil.InputFinder.bits(equalsOperands.get(0)); ImmutableBitSet right = RelOptUtil.InputFinder.bits(equalsOperands.get(1)); if (!left.isEmpty() && !right.isEmpty() && left.intersect(right).isEmpty()) { return call; } } } int caseOrdinal = -1; final List<RexNode> operands = call.getOperands(); for (int i = 0; i < operands.size(); i++) { RexNode operand = operands.get(i); switch (operand.getKind()) { case CASE: caseOrdinal = i; } } if (caseOrdinal < 0) { return call; } // Convert // f(CASE WHEN p1 THEN v1 ... END, arg) // to // CASE WHEN p1 THEN f(v1, arg) ... END final RexCall case_ = (RexCall) operands.get(caseOrdinal); final List<RexNode> nodes = new ArrayList<>(); for (int i = 0; i < case_.getOperands().size(); i++) { RexNode node = case_.getOperands().get(i); if (!RexUtil.isCasePredicate(case_, i)) { node = substitute(call, caseOrdinal, node); } nodes.add(node); } return case_.clone(call.getType(), nodes); }
Example 18
Source File: RelMdDistinctRowCount.java From Bats with Apache License 2.0 | 4 votes |
public Double getDistinctRowCount(Project rel, RelMetadataQuery mq, ImmutableBitSet groupKey, RexNode predicate) { if (predicate == null || predicate.isAlwaysTrue()) { if (groupKey.isEmpty()) { return 1D; } } ImmutableBitSet.Builder baseCols = ImmutableBitSet.builder(); ImmutableBitSet.Builder projCols = ImmutableBitSet.builder(); List<RexNode> projExprs = rel.getProjects(); RelMdUtil.splitCols(projExprs, groupKey, baseCols, projCols); final List<RexNode> notPushable = new ArrayList<>(); final List<RexNode> pushable = new ArrayList<>(); RelOptUtil.splitFilters( ImmutableBitSet.range(rel.getRowType().getFieldCount()), predicate, pushable, notPushable); final RexBuilder rexBuilder = rel.getCluster().getRexBuilder(); // get the distinct row count of the child input, passing in the // columns and filters that only reference the child; convert the // filter to reference the children projection expressions RexNode childPred = RexUtil.composeConjunction(rexBuilder, pushable, true); RexNode modifiedPred; if (childPred == null) { modifiedPred = null; } else { modifiedPred = RelOptUtil.pushPastProject(childPred, rel); } Double distinctRowCount = mq.getDistinctRowCount(rel.getInput(), baseCols.build(), modifiedPred); if (distinctRowCount == null) { return null; } else if (!notPushable.isEmpty()) { RexNode preds = RexUtil.composeConjunction(rexBuilder, notPushable, true); distinctRowCount *= RelMdUtil.guessSelectivity(preds); } // No further computation required if the projection expressions // are all column references if (projCols.cardinality() == 0) { return distinctRowCount; } // multiply by the cardinality of the non-child projection expressions for (int bit : projCols.build()) { Double subRowCount = RelMdUtil.cardOfProjExpr(mq, rel, projExprs.get(bit)); if (subRowCount == null) { return null; } distinctRowCount *= subRowCount; } return RelMdUtil.numDistinctVals(distinctRowCount, mq.getRowCount(rel)); }
Example 19
Source File: RelMdUtil.java From calcite with Apache License 2.0 | 4 votes |
/** * Computes the number of distinct rows for a set of keys returned from a * join. Also known as NDV (number of distinct values). * * @param joinRel RelNode representing the join * @param joinType type of join * @param groupKey keys that the distinct row count will be computed for * @param predicate join predicate * @param useMaxNdv If true use formula <code>max(left NDV, right NDV)</code>, * otherwise use <code>left NDV * right NDV</code>. * @return number of distinct rows */ public static Double getJoinDistinctRowCount(RelMetadataQuery mq, RelNode joinRel, JoinRelType joinType, ImmutableBitSet groupKey, RexNode predicate, boolean useMaxNdv) { if (predicate == null || predicate.isAlwaysTrue()) { if (groupKey.isEmpty()) { return 1D; } } Join join = (Join) joinRel; if (join.isSemiJoin()) { return getSemiJoinDistinctRowCount(join, mq, groupKey, predicate); } Double distRowCount; ImmutableBitSet.Builder leftMask = ImmutableBitSet.builder(); ImmutableBitSet.Builder rightMask = ImmutableBitSet.builder(); RelNode left = joinRel.getInputs().get(0); RelNode right = joinRel.getInputs().get(1); RelMdUtil.setLeftRightBitmaps( groupKey, leftMask, rightMask, left.getRowType().getFieldCount()); // determine which filters apply to the left vs right RexNode leftPred = null; RexNode rightPred = null; if (predicate != null) { final List<RexNode> leftFilters = new ArrayList<>(); final List<RexNode> rightFilters = new ArrayList<>(); final List<RexNode> joinFilters = new ArrayList<>(); final List<RexNode> predList = RelOptUtil.conjunctions(predicate); RelOptUtil.classifyFilters( joinRel, predList, joinType, !joinType.isOuterJoin(), !joinType.generatesNullsOnLeft(), !joinType.generatesNullsOnRight(), joinFilters, leftFilters, rightFilters); RexBuilder rexBuilder = joinRel.getCluster().getRexBuilder(); leftPred = RexUtil.composeConjunction(rexBuilder, leftFilters, true); rightPred = RexUtil.composeConjunction(rexBuilder, rightFilters, true); } if (useMaxNdv) { distRowCount = Math.max( mq.getDistinctRowCount(left, leftMask.build(), leftPred), mq.getDistinctRowCount(right, rightMask.build(), rightPred)); } else { distRowCount = NumberUtil.multiply( mq.getDistinctRowCount(left, leftMask.build(), leftPred), mq.getDistinctRowCount(right, rightMask.build(), rightPred)); } return RelMdUtil.numDistinctVals(distRowCount, mq.getRowCount(joinRel)); }
Example 20
Source File: RelMdUniqueKeys.java From calcite with Apache License 2.0 | 4 votes |
private Set<ImmutableBitSet> getProjectUniqueKeys(SingleRel rel, RelMetadataQuery mq, boolean ignoreNulls, List<RexNode> projExprs) { // LogicalProject maps a set of rows to a different set; // Without knowledge of the mapping function(whether it // preserves uniqueness), it is only safe to derive uniqueness // info from the child of a project when the mapping is f(a) => a. // // Further more, the unique bitset coming from the child needs // to be mapped to match the output of the project. // Single input can be mapped to multiple outputs ImmutableMultimap.Builder<Integer, Integer> inToOutPosBuilder = ImmutableMultimap.builder(); ImmutableBitSet.Builder mappedInColumnsBuilder = ImmutableBitSet.builder(); // Build an input to output position map. for (int i = 0; i < projExprs.size(); i++) { RexNode projExpr = projExprs.get(i); if (projExpr instanceof RexInputRef) { int inputIndex = ((RexInputRef) projExpr).getIndex(); inToOutPosBuilder.put(inputIndex, i); mappedInColumnsBuilder.set(inputIndex); } } ImmutableBitSet inColumnsUsed = mappedInColumnsBuilder.build(); if (inColumnsUsed.isEmpty()) { // if there's no RexInputRef in the projected expressions // return empty set. return ImmutableSet.of(); } Set<ImmutableBitSet> childUniqueKeySet = mq.getUniqueKeys(rel.getInput(), ignoreNulls); if (childUniqueKeySet == null) { return ImmutableSet.of(); } Map<Integer, ImmutableBitSet> mapInToOutPos = Maps.transformValues(inToOutPosBuilder.build().asMap(), ImmutableBitSet::of); ImmutableSet.Builder<ImmutableBitSet> resultBuilder = ImmutableSet.builder(); // Now add to the projUniqueKeySet the child keys that are fully // projected. for (ImmutableBitSet colMask : childUniqueKeySet) { ImmutableBitSet.Builder tmpMask = ImmutableBitSet.builder(); if (!inColumnsUsed.contains(colMask)) { // colMask contains a column that is not projected as RexInput => the key is not unique continue; } // colMask is mapped to output project, however, the column can be mapped more than once: // select id, id, id, unique2, unique2 // the resulting unique keys would be {{0},{3}}, {{0},{4}}, {{0},{1},{4}}, ... Iterable<List<ImmutableBitSet>> product = Linq4j.product( Iterables.transform(colMask, in -> Iterables.filter(mapInToOutPos.get(in).powerSet(), bs -> !bs.isEmpty()))); resultBuilder.addAll(Iterables.transform(product, ImmutableBitSet::union)); } return resultBuilder.build(); }