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

com.hazelcast.org.apache.calcite.rel.rules.SortJoinCopyRule 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.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;

import java.util.ArrayList;
import java.util.List;

/**
 * Planner rule that copies a {@link com.hazelcast.org.apache.calcite.rel.core.Sort} past a
 * {@link com.hazelcast.org.apache.calcite.rel.core.Join} without its limit and offset. The
 * original {@link com.hazelcast.org.apache.calcite.rel.core.Sort} is preserved but can be
 * potentially removed by {@link com.hazelcast.org.apache.calcite.rel.rules.SortRemoveRule} if
 * redundant.
 *
 * 

Some examples where {@link com.hazelcast.org.apache.calcite.rel.rules.SortJoinCopyRule} * can be useful: allowing a {@link com.hazelcast.org.apache.calcite.rel.core.Sort} to be * incorporated in an index scan; facilitating the use of operators requiring * sorted inputs; and allowing the sort to be performed on a possibly smaller * result. */ public class SortJoinCopyRule extends RelOptRule implements TransformationRule { public static final SortJoinCopyRule INSTANCE = new SortJoinCopyRule(LogicalSort.class, LogicalJoin.class, RelFactories.LOGICAL_BUILDER); //~ Constructors ----------------------------------------------------------- /** Creates a SortJoinCopyRule. */ public SortJoinCopyRule(Class sortClass, Class joinClass, RelBuilderFactory relBuilderFactory) { super( operand(sortClass, operand(joinClass, any())), relBuilderFactory, null); } //~ Methods ----------------------------------------------------------------- @Override public void onMatch(RelOptRuleCall call) { final Sort sort = call.rel(0); final Join join = call.rel(1); final RelMetadataQuery metadataQuery = call.getMetadataQuery(); final RelNode newLeftInput; final RelNode newRightInput; final List leftFieldCollation = new ArrayList<>(); final List rightFieldCollation = new ArrayList<>(); // Decompose sort collations into left and right collations for (RelFieldCollation relFieldCollation : sort.getCollation().getFieldCollations()) { if (relFieldCollation.getFieldIndex() >= join.getLeft().getRowType().getFieldCount()) { rightFieldCollation.add(relFieldCollation); } else { leftFieldCollation.add(relFieldCollation); } } // Add sort to new left node only if sort collations // contained fields from left table if (leftFieldCollation.isEmpty()) { newLeftInput = join.getLeft(); } else { final RelCollation leftCollation = RelCollationTraitDef.INSTANCE.canonize( RelCollations.of(leftFieldCollation)); // If left table already sorted don't add a sort if (RelMdUtil.checkInputForCollationAndLimit( metadataQuery, join.getLeft(), leftCollation, null, null)) { newLeftInput = join.getLeft(); } else { newLeftInput = sort.copy( sort.getTraitSet().replaceIf( RelCollationTraitDef.INSTANCE, () -> leftCollation), join.getLeft(), leftCollation, null, null); } } // Add sort to new right node only if sort collations // contained fields from right table if (rightFieldCollation.isEmpty()) { newRightInput = join.getRight(); } else { final RelCollation rightCollation = RelCollationTraitDef.INSTANCE.canonize( RelCollations.shift( RelCollations.of(rightFieldCollation), -join.getLeft().getRowType().getFieldCount())); // If right table already sorted don't add a sort if (RelMdUtil.checkInputForCollationAndLimit( metadataQuery, join.getRight(), rightCollation, null, null)) { newRightInput = join.getRight(); } else { newRightInput = sort.copy( sort.getTraitSet().replaceIf( RelCollationTraitDef.INSTANCE, () -> rightCollation), join.getRight(), rightCollation, null, null); } } // If no change was made no need to apply the rule if (newLeftInput == join.getLeft() && newRightInput == join.getRight()) { return; } 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