Search in sources :

Example 1 with RelColumnOrigin

use of org.apache.calcite.rel.metadata.RelColumnOrigin in project calcite by apache.

the class LoptMultiJoin method addRemovableSelfJoinPair.

/**
 * Adds to a map that keeps track of removable self-join pairs.
 *
 * @param factor1 one of the factors in the self-join
 * @param factor2 the second factor in the self-join
 */
public void addRemovableSelfJoinPair(int factor1, int factor2) {
    int leftFactor;
    int rightFactor;
    // preserved after the self-join is removed.
    if (getNumFieldsInJoinFactor(factor1) > getNumFieldsInJoinFactor(factor2)) {
        leftFactor = factor1;
        rightFactor = factor2;
    } else {
        leftFactor = factor2;
        rightFactor = factor1;
    }
    // Compute a column mapping such that if a column from the right
    // factor is also referenced in the left factor, we will map the
    // right reference to the left to avoid redundant references.
    final Map<Integer, Integer> columnMapping = new HashMap<>();
    // First, locate the originating column for all simple column
    // references in the left factor.
    final RelNode left = getJoinFactor(leftFactor);
    final RelMetadataQuery mq = left.getCluster().getMetadataQuery();
    final Map<Integer, Integer> leftFactorColMapping = new HashMap<>();
    for (int i = 0; i < left.getRowType().getFieldCount(); i++) {
        final RelColumnOrigin colOrigin = mq.getColumnOrigin(left, i);
        if (colOrigin != null) {
            leftFactorColMapping.put(colOrigin.getOriginColumnOrdinal(), i);
        }
    }
    // Then, see if the right factor references any of the same columns
    // by locating their originating columns.  If there are matches,
    // then we want to store the corresponding offset into the left
    // factor.
    RelNode right = getJoinFactor(rightFactor);
    for (int i = 0; i < right.getRowType().getFieldCount(); i++) {
        final RelColumnOrigin colOrigin = mq.getColumnOrigin(right, i);
        if (colOrigin == null) {
            continue;
        }
        Integer leftOffset = leftFactorColMapping.get(colOrigin.getOriginColumnOrdinal());
        if (leftOffset == null) {
            continue;
        }
        columnMapping.put(i, leftOffset);
    }
    RemovableSelfJoin selfJoin = new RemovableSelfJoin(leftFactor, rightFactor, columnMapping);
    removableSelfJoinPairs.put(leftFactor, selfJoin);
    removableSelfJoinPairs.put(rightFactor, selfJoin);
}
Also used : RelMetadataQuery(org.apache.calcite.rel.metadata.RelMetadataQuery) RelNode(org.apache.calcite.rel.RelNode) HashMap(java.util.HashMap) RelColumnOrigin(org.apache.calcite.rel.metadata.RelColumnOrigin)

Example 2 with RelColumnOrigin

use of org.apache.calcite.rel.metadata.RelColumnOrigin in project calcite by apache.

the class LoptOptimizeJoinRule method areSelfJoinKeysUnique.

/**
 * Determines if the equality portion of a self-join condition is between
 * identical keys that are unique.
 *
 * @param mq Metadata query
 * @param leftRel left side of the join
 * @param rightRel right side of the join
 * @param joinFilters the join condition
 *
 * @return true if the equality join keys are the same and unique
 */
private static boolean areSelfJoinKeysUnique(RelMetadataQuery mq, RelNode leftRel, RelNode rightRel, RexNode joinFilters) {
    final JoinInfo joinInfo = JoinInfo.of(leftRel, rightRel, joinFilters);
    // corresponding key on the right
    for (IntPair pair : joinInfo.pairs()) {
        final RelColumnOrigin leftOrigin = mq.getColumnOrigin(leftRel, pair.source);
        if (leftOrigin == null) {
            return false;
        }
        final RelColumnOrigin rightOrigin = mq.getColumnOrigin(rightRel, pair.target);
        if (rightOrigin == null) {
            return false;
        }
        if (leftOrigin.getOriginColumnOrdinal() != rightOrigin.getOriginColumnOrdinal()) {
            return false;
        }
    }
    // it's ok if there are nulls in the unique key.
    return RelMdUtil.areColumnsDefinitelyUniqueWhenNullsFiltered(mq, leftRel, joinInfo.leftSet());
}
Also used : JoinInfo(org.apache.calcite.rel.core.JoinInfo) RelColumnOrigin(org.apache.calcite.rel.metadata.RelColumnOrigin) IntPair(org.apache.calcite.util.mapping.IntPair)

Example 3 with RelColumnOrigin

use of org.apache.calcite.rel.metadata.RelColumnOrigin in project calcite by apache.

the class LoptSemiJoinOptimizer method validateKeys.

/**
 * Validates the candidate semijoin keys corresponding to the fact table.
 * Ensure the keys all originate from the same underlying table, and they
 * all correspond to simple column references. If unsuitable keys are found,
 * they're removed from the key list and a new list corresponding to the
 * remaining valid keys is returned.
 *
 * @param factRel fact table RelNode
 * @param leftKeys fact table semijoin keys
 * @param rightKeys dimension table semijoin keys
 * @param actualLeftKeys the remaining valid fact table semijoin keys
 *
 * @return the underlying fact table if the semijoin keys are valid;
 * otherwise null
 */
private LcsTable validateKeys(RelNode factRel, List<Integer> leftKeys, List<Integer> rightKeys, List<Integer> actualLeftKeys) {
    int keyIdx = 0;
    RelOptTable theTable = null;
    ListIterator<Integer> keyIter = leftKeys.listIterator();
    while (keyIter.hasNext()) {
        boolean removeKey = false;
        final RelColumnOrigin colOrigin = mq.getColumnOrigin(factRel, keyIter.next());
        // can't use the rid column as a semijoin key
        if ((colOrigin == null) || LucidDbSpecialOperators.isLcsRidColumnId(colOrigin.getOriginColumnOrdinal())) {
            removeKey = true;
        } else {
            RelOptTable table = colOrigin.getOriginTable();
            if (theTable == null) {
                if (!(table instanceof LcsTable)) {
                    // not a column store table
                    removeKey = true;
                } else {
                    theTable = table;
                }
            } else {
                // a simple origin
                assert table == theTable;
            }
        }
        if (!removeKey) {
            actualLeftKeys.add(colOrigin.getOriginColumnOrdinal());
            keyIdx++;
        } else {
            keyIter.remove();
            rightKeys.remove(keyIdx);
        }
    }
    // keys
    if (actualLeftKeys.isEmpty()) {
        return null;
    } else {
        return (LcsTable) theTable;
    }
}
Also used : RelColumnOrigin(org.apache.calcite.rel.metadata.RelColumnOrigin) RelOptTable(org.apache.calcite.plan.RelOptTable)

Example 4 with RelColumnOrigin

use of org.apache.calcite.rel.metadata.RelColumnOrigin in project calcite by apache.

the class RelMetadataTest method checkSingleColumnOrigin.

private void checkSingleColumnOrigin(String sql, String expectedTableName, String expectedColumnName, boolean expectedDerived) {
    Set<RelColumnOrigin> result = checkColumnOrigin(sql);
    assertTrue(result != null);
    assertEquals(1, result.size());
    RelColumnOrigin rco = result.iterator().next();
    checkColumnOrigin(rco, expectedTableName, expectedColumnName, expectedDerived);
}
Also used : RelColumnOrigin(org.apache.calcite.rel.metadata.RelColumnOrigin)

Example 5 with RelColumnOrigin

use of org.apache.calcite.rel.metadata.RelColumnOrigin in project hive by apache.

the class HiveExpandDistinctAggregatesRule method onMatch.

// ~ Methods ----------------------------------------------------------------
@Override
public void onMatch(RelOptRuleCall call) {
    final Aggregate aggregate = call.rel(0);
    int numCountDistinct = getNumCountDistinctCall(aggregate);
    if (numCountDistinct == 0 || numCountDistinct + aggregate.getGroupCount() >= Long.SIZE || aggregate.getGroupType() != Group.SIMPLE) {
        return;
    }
    // Find all of the agg expressions. We use a List (for all count(distinct))
    // as well as a Set (for all others) to ensure determinism.
    int nonDistinctCount = 0;
    List<List<Integer>> argListList = new ArrayList<List<Integer>>();
    Set<List<Integer>> argListSets = new LinkedHashSet<List<Integer>>();
    ImmutableBitSet.Builder newGroupSet = ImmutableBitSet.builder();
    newGroupSet.addAll(aggregate.getGroupSet());
    for (AggregateCall aggCall : aggregate.getAggCallList()) {
        if (!aggCall.isDistinct()) {
            ++nonDistinctCount;
            continue;
        }
        ArrayList<Integer> argList = new ArrayList<Integer>();
        for (Integer arg : aggCall.getArgList()) {
            argList.add(arg);
            newGroupSet.set(arg);
        }
        // Aggr checks for sorted argList.
        argListList.add(argList);
        argListSets.add(argList);
    }
    Preconditions.checkArgument(argListSets.size() > 0, "containsDistinctCall lied");
    if (numCountDistinct > 1 && numCountDistinct == aggregate.getAggCallList().size()) {
        LOG.debug("Trigger countDistinct rewrite. numCountDistinct is " + numCountDistinct);
        // now positions contains all the distinct positions, i.e., $5, $4, $6
        // we need to first sort them as group by set
        // and then get their position later, i.e., $4->1, $5->2, $6->3
        cluster = aggregate.getCluster();
        rexBuilder = cluster.getRexBuilder();
        try {
            call.transformTo(convert(aggregate, argListList, newGroupSet.build()));
        } catch (CalciteSemanticException e) {
            LOG.debug(e.toString());
            throw new RuntimeException(e);
        }
        return;
    }
    // If all of the agg expressions are distinct and have the same
    // arguments then we can use a more efficient form.
    final RelMetadataQuery mq = call.getMetadataQuery();
    if ((nonDistinctCount == 0) && (argListSets.size() == 1)) {
        for (Integer arg : argListSets.iterator().next()) {
            Set<RelColumnOrigin> colOrigs = mq.getColumnOrigins(aggregate.getInput(), arg);
            if (null != colOrigs) {
                for (RelColumnOrigin colOrig : colOrigs) {
                    RelOptHiveTable hiveTbl = (RelOptHiveTable) colOrig.getOriginTable();
                    if (hiveTbl.getPartColInfoMap().containsKey(colOrig.getOriginColumnOrdinal())) {
                        // Encountered partitioning column, this will be better handled by MetadataOnly optimizer.
                        return;
                    }
                }
            }
        }
        RelNode converted = convertMonopole(aggregate, argListSets.iterator().next());
        call.transformTo(converted);
        return;
    }
}
Also used : LinkedHashSet(java.util.LinkedHashSet) RelMetadataQuery(org.apache.calcite.rel.metadata.RelMetadataQuery) ImmutableBitSet(org.apache.calcite.util.ImmutableBitSet) ArrayList(java.util.ArrayList) AggregateCall(org.apache.calcite.rel.core.AggregateCall) RelOptHiveTable(org.apache.hadoop.hive.ql.optimizer.calcite.RelOptHiveTable) HiveRelNode(org.apache.hadoop.hive.ql.optimizer.calcite.reloperators.HiveRelNode) RelNode(org.apache.calcite.rel.RelNode) RelColumnOrigin(org.apache.calcite.rel.metadata.RelColumnOrigin) ArrayList(java.util.ArrayList) ImmutableList(com.google.common.collect.ImmutableList) List(java.util.List) CalciteSemanticException(org.apache.hadoop.hive.ql.optimizer.calcite.CalciteSemanticException) HiveAggregate(org.apache.hadoop.hive.ql.optimizer.calcite.reloperators.HiveAggregate) Aggregate(org.apache.calcite.rel.core.Aggregate)

Aggregations

RelColumnOrigin (org.apache.calcite.rel.metadata.RelColumnOrigin)6 RelOptTable (org.apache.calcite.plan.RelOptTable)2 RelNode (org.apache.calcite.rel.RelNode)2 RelMetadataQuery (org.apache.calcite.rel.metadata.RelMetadataQuery)2 ImmutableList (com.google.common.collect.ImmutableList)1 ArrayList (java.util.ArrayList)1 HashMap (java.util.HashMap)1 LinkedHashSet (java.util.LinkedHashSet)1 List (java.util.List)1 Aggregate (org.apache.calcite.rel.core.Aggregate)1 AggregateCall (org.apache.calcite.rel.core.AggregateCall)1 JoinInfo (org.apache.calcite.rel.core.JoinInfo)1 ImmutableBitSet (org.apache.calcite.util.ImmutableBitSet)1 IntPair (org.apache.calcite.util.mapping.IntPair)1 CalciteSemanticException (org.apache.hadoop.hive.ql.optimizer.calcite.CalciteSemanticException)1 RelOptHiveTable (org.apache.hadoop.hive.ql.optimizer.calcite.RelOptHiveTable)1 HiveAggregate (org.apache.hadoop.hive.ql.optimizer.calcite.reloperators.HiveAggregate)1 HiveRelNode (org.apache.hadoop.hive.ql.optimizer.calcite.reloperators.HiveRelNode)1