All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.hazelcast.org.apache.calcite.rel.rules.SortJoinTransposeRule Maven / Gradle / Ivy

/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to you under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.hazelcast.org.apache.calcite.rel.rules;

import com.hazelcast.org.apache.calcite.plan.RelOptRule;
import com.hazelcast.org.apache.calcite.plan.RelOptRuleCall;
import com.hazelcast.org.apache.calcite.rel.RelCollation;
import com.hazelcast.org.apache.calcite.rel.RelCollationTraitDef;
import com.hazelcast.org.apache.calcite.rel.RelCollations;
import com.hazelcast.org.apache.calcite.rel.RelFieldCollation;
import com.hazelcast.org.apache.calcite.rel.RelNode;
import com.hazelcast.org.apache.calcite.rel.core.Join;
import com.hazelcast.org.apache.calcite.rel.core.JoinInfo;
import com.hazelcast.org.apache.calcite.rel.core.JoinRelType;
import com.hazelcast.org.apache.calcite.rel.core.RelFactories;
import com.hazelcast.org.apache.calcite.rel.core.Sort;
import com.hazelcast.org.apache.calcite.rel.logical.LogicalJoin;
import com.hazelcast.org.apache.calcite.rel.logical.LogicalSort;
import com.hazelcast.org.apache.calcite.rel.metadata.RelMdUtil;
import com.hazelcast.org.apache.calcite.rel.metadata.RelMetadataQuery;
import com.hazelcast.org.apache.calcite.tools.RelBuilderFactory;

/**
 * Planner rule that pushes a {@link com.hazelcast.org.apache.calcite.rel.core.Sort} past a
 * {@link com.hazelcast.org.apache.calcite.rel.core.Join}.
 *
 * 

At the moment, we only consider left/right outer joins. * However, an extension for full outer joins for this rule could be envisioned. * Special attention should be paid to null values for correctness issues. */ public class SortJoinTransposeRule extends RelOptRule implements TransformationRule { public static final SortJoinTransposeRule INSTANCE = new SortJoinTransposeRule(LogicalSort.class, LogicalJoin.class, RelFactories.LOGICAL_BUILDER); //~ Constructors ----------------------------------------------------------- /** Creates a SortJoinTransposeRule. */ @Deprecated // to be removed before 2.0 public SortJoinTransposeRule(Class sortClass, Class joinClass) { this(sortClass, joinClass, RelFactories.LOGICAL_BUILDER); } /** Creates a SortJoinTransposeRule. */ public SortJoinTransposeRule(Class sortClass, Class joinClass, RelBuilderFactory relBuilderFactory) { super( operand(sortClass, operand(joinClass, any())), relBuilderFactory, null); } //~ Methods ---------------------------------------------------------------- @Override public boolean matches(RelOptRuleCall call) { final Sort sort = call.rel(0); final Join join = call.rel(1); final RelMetadataQuery mq = call.getMetadataQuery(); final JoinInfo joinInfo = JoinInfo.of( join.getLeft(), join.getRight(), join.getCondition()); // 1) If join is not a left or right outer, we bail out // 2) If sort is not a trivial order-by, and if there is // any sort column that is not part of the input where the // sort is pushed, we bail out // 3) If sort has an offset, and if the non-preserved side // of the join is not count-preserving against the join // condition, we bail out if (join.getJoinType() == JoinRelType.LEFT) { if (sort.getCollation() != RelCollations.EMPTY) { for (RelFieldCollation relFieldCollation : sort.getCollation().getFieldCollations()) { if (relFieldCollation.getFieldIndex() >= join.getLeft().getRowType().getFieldCount()) { return false; } } } if (sort.offset != null && !RelMdUtil.areColumnsDefinitelyUnique( mq, join.getRight(), joinInfo.rightSet())) { return false; } } else if (join.getJoinType() == JoinRelType.RIGHT) { if (sort.getCollation() != RelCollations.EMPTY) { for (RelFieldCollation relFieldCollation : sort.getCollation().getFieldCollations()) { if (relFieldCollation.getFieldIndex() < join.getLeft().getRowType().getFieldCount()) { return false; } } } if (sort.offset != null && !RelMdUtil.areColumnsDefinitelyUnique( mq, join.getLeft(), joinInfo.leftSet())) { return false; } } else { return false; } return true; } @Override public void onMatch(RelOptRuleCall call) { final Sort sort = call.rel(0); final Join join = call.rel(1); // We create a new sort operator on the corresponding input final RelNode newLeftInput; final RelNode newRightInput; final RelMetadataQuery mq = call.getMetadataQuery(); if (join.getJoinType() == JoinRelType.LEFT) { // If the input is already sorted and we are not reducing the number of tuples, // we bail out if (RelMdUtil.checkInputForCollationAndLimit(mq, join.getLeft(), sort.getCollation(), sort.offset, sort.fetch)) { return; } newLeftInput = sort.copy(sort.getTraitSet(), join.getLeft(), sort.getCollation(), sort.offset, sort.fetch); newRightInput = join.getRight(); } else { final RelCollation rightCollation = RelCollationTraitDef.INSTANCE.canonize( RelCollations.shift(sort.getCollation(), -join.getLeft().getRowType().getFieldCount())); // If the input is already sorted and we are not reducing the number of tuples, // we bail out if (RelMdUtil.checkInputForCollationAndLimit(mq, join.getRight(), rightCollation, sort.offset, sort.fetch)) { return; } newLeftInput = join.getLeft(); newRightInput = sort.copy(sort.getTraitSet().replace(rightCollation), join.getRight(), rightCollation, sort.offset, sort.fetch); } // We copy the join and the top sort operator final RelNode joinCopy = join.copy(join.getTraitSet(), join.getCondition(), newLeftInput, newRightInput, join.getJoinType(), join.isSemiJoinDone()); final RelNode sortCopy = sort.copy(sort.getTraitSet(), joinCopy, sort.getCollation(), sort.offset, sort.fetch); call.transformTo(sortCopy); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy