You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by gv...@apache.org on 2020/03/20 19:53:00 UTC
[ignite] branch ignite-12248 updated: IGNITE-12820 Calcite
integration. Do not use AbstarctConverter while planning. This closes #7553
This is an automated email from the ASF dual-hosted git repository.
gvvinblade pushed a commit to branch ignite-12248
in repository https://gitbox.apache.org/repos/asf/ignite.git
The following commit(s) were added to refs/heads/ignite-12248 by this push:
new 4654a3e IGNITE-12820 Calcite integration. Do not use AbstarctConverter while planning. This closes #7553
4654a3e is described below
commit 4654a3e0873972afc27d12b40124b43e532be5dd
Author: Igor Seliverstov <gv...@gmail.com>
AuthorDate: Fri Mar 20 22:52:48 2020 +0300
IGNITE-12820 Calcite integration. Do not use AbstarctConverter while planning. This closes #7553
---
.../apache/calcite/plan/volcano/VolcanoUtils.java | 46 -----
.../query/calcite/exec/LogicalRelImplementor.java | 2 +-
.../metadata/IgniteMdDerivedDistribution.java | 70 +++----
.../calcite/metadata/IgniteMdDistribution.java | 11 +-
.../query/calcite/prepare/IgnitePlanner.java | 23 ++-
.../query/calcite/prepare/PlannerPhase.java | 28 +--
.../query/calcite/rel/IgniteConvention.java | 7 -
.../processors/query/calcite/rel/IgniteJoin.java | 12 ++
.../query/calcite/rel/IgniteReceiver.java | 18 --
.../processors/query/calcite/rel/IgniteRel.java | 19 ++
.../processors/query/calcite/rel/IgniteSender.java | 16 --
.../query/calcite/rule/FilterConverter.java | 70 -------
...luesConverter.java => FilterConverterRule.java} | 40 ++--
...erter.java => FilterTraitsPropagationRule.java} | 40 ++--
.../query/calcite/rule/IgniteConverter.java | 88 ---------
.../query/calcite/rule/JoinConverter.java | 75 --------
...ValuesConverter.java => JoinConverterRule.java} | 41 ++--
.../calcite/rule/JoinTraitsPropagationRule.java | 75 ++++++++
.../query/calcite/rule/ProjectConverter.java | 71 -------
...ifyConverter.java => ProjectConverterRule.java} | 43 ++---
...rter.java => ProjectTraitsPropagationRule.java} | 42 ++---
.../processors/query/calcite/rule/RuleUtils.java | 196 +++++++++++++++++++
...onverter.java => TableModifyConverterRule.java} | 37 ++--
...luesConverter.java => ValuesConverterRule.java} | 32 ++--
.../calcite/serialize/RelToPhysicalConverter.java | 4 +-
.../query/calcite/trait/DistributionTraitDef.java | 38 ++--
.../query/calcite/trait/IgniteDistributions.java | 209 +++++++++++----------
.../processors/query/calcite/PlannerTest.java | 2 +
28 files changed, 623 insertions(+), 732 deletions(-)
diff --git a/modules/calcite/src/main/java/org/apache/calcite/plan/volcano/VolcanoUtils.java b/modules/calcite/src/main/java/org/apache/calcite/plan/volcano/VolcanoUtils.java
deleted file mode 100644
index d66861c..0000000
--- a/modules/calcite/src/main/java/org/apache/calcite/plan/volcano/VolcanoUtils.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * 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 org.apache.calcite.plan.volcano;
-
-import org.apache.calcite.plan.RelTraitSet;
-
-/**
- * Utility methods to exploit package private API.
- */
-public class VolcanoUtils {
- /**
- * Requests an alternative subset with relational nodes, satisfying required traits.
- * @param subset Original subset.
- * @param traits Required traits.
- * @return Result subset, what contains relational nodes, satisfying required traits.
- */
- public static RelSubset subset(RelSubset subset, RelTraitSet traits) {
- return subset.set.getOrCreateSubset(subset.getCluster(), traits.simplify());
- }
-
- /**
- * Utility method, sets {@link VolcanoPlanner#impatient} parameter to {@code true}.
- * @param planner Planer.
- * @return Planer for chaining.
- */
- public static VolcanoPlanner impatient(VolcanoPlanner planner) {
- planner.impatient = true;
-
- return planner;
- }
-}
diff --git a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/LogicalRelImplementor.java b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/LogicalRelImplementor.java
index baea3f2..b6e9b3b 100644
--- a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/LogicalRelImplementor.java
+++ b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/LogicalRelImplementor.java
@@ -97,7 +97,7 @@ public class LogicalRelImplementor implements IgniteRelVisitor<Node<Object[]>> {
/** {@inheritDoc} */
@Override public Node<Object[]> visit(IgniteSender rel) {
RelTarget target = rel.target();
- IgniteDistribution distribution = rel.targetDistribution();
+ IgniteDistribution distribution = rel.distribution();
Destination destination = distribution.function().destination(partitionService, target.mapping(), distribution.getKeys());
// Outbox fragment ID is used as exchange ID as well.
diff --git a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/metadata/IgniteMdDerivedDistribution.java b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/metadata/IgniteMdDerivedDistribution.java
index 23f213c..69e7c90 100644
--- a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/metadata/IgniteMdDerivedDistribution.java
+++ b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/metadata/IgniteMdDerivedDistribution.java
@@ -25,7 +25,7 @@ import org.apache.calcite.plan.Convention;
import org.apache.calcite.plan.hep.HepRelVertex;
import org.apache.calcite.plan.volcano.AbstractConverter;
import org.apache.calcite.plan.volcano.RelSubset;
-import org.apache.calcite.plan.volcano.VolcanoUtils;
+import org.apache.calcite.plan.volcano.VolcanoPlanner;
import org.apache.calcite.rel.RelNode;
import org.apache.calcite.rel.SingleRel;
import org.apache.calcite.rel.core.Project;
@@ -41,6 +41,7 @@ import org.apache.calcite.rel.metadata.RelMetadataProvider;
import org.apache.calcite.rel.metadata.RelMetadataQuery;
import org.apache.calcite.util.mapping.Mappings;
import org.apache.ignite.internal.processors.query.calcite.metadata.IgniteMetadata.DerivedDistribution;
+import org.apache.ignite.internal.processors.query.calcite.rel.IgniteConvention;
import org.apache.ignite.internal.processors.query.calcite.rel.IgniteRel;
import org.apache.ignite.internal.processors.query.calcite.trait.IgniteDistribution;
import org.apache.ignite.internal.processors.query.calcite.trait.IgniteDistributions;
@@ -53,15 +54,6 @@ import org.apache.ignite.internal.util.typedef.F;
*/
public class IgniteMdDerivedDistribution implements MetadataHandler<DerivedDistribution> {
/**
- * Holds initially requested convention. In case there is no physical nodes in interested RelSubset we need to discover
- * another RelSubset, which holds logical ones (to calculate possible distribution types instead of actual).
- * On a deeper layer we need to return to initially requested RelSubset because we primarily interested
- * in physical nodes, but logical ones cannot have them as children, so, we use a value from this holder
- * to request RelSubset of possible physical nodes of a logical parent.
- */
- private static final ThreadLocal<Convention> REQUESTED_CONVENTION = ThreadLocal.withInitial(() -> Convention.NONE);
-
- /**
* Metadata provider, responsible for distribution types derivation. It uses this implementation class under the hood.
*/
public static final RelMetadataProvider SOURCE =
@@ -138,24 +130,25 @@ public class IgniteMdDerivedDistribution implements MetadataHandler<DerivedDistr
* For general information see {@link IgniteMdDerivedDistribution#deriveDistributions(RelNode, RelMetadataQuery)}
*/
public List<IgniteDistribution> deriveDistributions(RelSubset rel, RelMetadataQuery mq) {
- rel = VolcanoUtils.subset(rel, rel.getTraitSet().replace(REQUESTED_CONVENTION.get()));
-
HashSet<IgniteDistribution> res = new HashSet<>();
- for (RelNode rel0 : rel.getRels())
+ RelSubset newSubset = subset(rel, IgniteConvention.INSTANCE);
+
+ for (RelNode rel0 : newSubset.getRels())
res.addAll(_deriveDistributions(rel0, mq));
- if (F.isEmpty(res)) {
- // default traits + NONE convention return a set of all logical rels.
- RelSubset newRel = VolcanoUtils.subset(rel, rel.getCluster().traitSetOf(Convention.NONE));
+ if (!F.isEmpty(res))
+ return new ArrayList<>(res);
- if (newRel != rel) {
- for (RelNode rel0 : newRel.getRels())
- res.addAll(_deriveDistributions(rel0, mq));
- }
- }
+ newSubset = subset(rel, Convention.NONE);
- return new ArrayList<>(res);
+ for (RelNode rel0 : newSubset.getRels())
+ res.addAll(_deriveDistributions(rel0, mq));
+
+ if (!F.isEmpty(res))
+ return new ArrayList<>(res);
+
+ return Collections.emptyList();
}
/**
@@ -176,35 +169,22 @@ public class IgniteMdDerivedDistribution implements MetadataHandler<DerivedDistr
* See {@link IgniteMdDerivedDistribution#deriveDistributions(RelNode, RelMetadataQuery)}
*/
public List<IgniteDistribution> deriveDistributions(LogicalJoin rel, RelMetadataQuery mq) {
- List<IgniteDistribution> left = _deriveDistributions(rel.getLeft(), mq);
- List<IgniteDistribution> right = _deriveDistributions(rel.getRight(), mq);
+ List<IgniteDistributions.BiSuggestion> suggestions = IgniteDistributions.suggestJoin(
+ rel.getLeft(), rel.getRight(), rel.analyzeCondition(), rel.getJoinType());
- return Commons.transform(IgniteDistributions.suggestJoin(left, right, rel.analyzeCondition(), rel.getJoinType()),
- IgniteDistributions.BiSuggestion::out);
- }
-
- /**
- * Derivation entry point. Returns actual (or possible) distribution types of given relational node.
- * @param rel Relational node.
- * @param convention Required convention.
- * @param mq Metadata query instance.
- * @return List of distribution types the given relational node may have.
- */
- public static List<IgniteDistribution> deriveDistributions(RelNode rel, Convention convention, RelMetadataQuery mq) {
- try {
- REQUESTED_CONVENTION.set(convention);
-
- return _deriveDistributions(rel, mq);
- }
- finally {
- REQUESTED_CONVENTION.remove();
- }
+ return Commons.transform(suggestions, IgniteDistributions.BiSuggestion::out);
}
/** */
- private static List<IgniteDistribution> _deriveDistributions(RelNode rel, RelMetadataQuery mq) {
+ public static List<IgniteDistribution> _deriveDistributions(RelNode rel, RelMetadataQuery mq) {
assert mq instanceof RelMetadataQueryEx;
return ((RelMetadataQueryEx) mq).derivedDistributions(rel);
}
+
+ /** */
+ private static RelSubset subset(RelSubset rel, Convention convention) {
+ VolcanoPlanner planner = (VolcanoPlanner) rel.getCluster().getPlanner();
+ return planner.getSubset(rel, rel.getCluster().traitSetOf(convention), true);
+ }
}
diff --git a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/metadata/IgniteMdDistribution.java b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/metadata/IgniteMdDistribution.java
index 2aabb56..e94a31e 100644
--- a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/metadata/IgniteMdDistribution.java
+++ b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/metadata/IgniteMdDistribution.java
@@ -79,7 +79,7 @@ public class IgniteMdDistribution implements MetadataHandler<BuiltInMetadata.Dis
* See {@link IgniteMdDistribution#distribution(RelNode, RelMetadataQuery)}
*/
public IgniteDistribution distribution(IgniteRel rel, RelMetadataQuery mq) {
- return rel.getTraitSet().getTrait(DistributionTraitDef.INSTANCE);
+ return rel.distribution();
}
/**
@@ -177,14 +177,7 @@ public class IgniteMdDistribution implements MetadataHandler<BuiltInMetadata.Dis
* @return Join relational node distribution calculated on the basis of its inputs and join information.
*/
public static IgniteDistribution join(RelMetadataQuery mq, RelNode left, RelNode right, JoinInfo joinInfo, JoinRelType joinType) {
- return join(_distribution(left, mq), _distribution(right, mq), joinInfo, joinType);
- }
-
- /**
- * @return Join relational node distribution calculated on the basis of its inputs distributions and join information.
- */
- public static IgniteDistribution join(IgniteDistribution left, IgniteDistribution right, JoinInfo joinInfo, JoinRelType joinType) {
- return F.first(IgniteDistributions.suggestJoin(left, right, joinInfo, joinType)).out();
+ return F.first(IgniteDistributions.suggestJoin(_distribution(left, mq), _distribution(right, mq), joinInfo, joinType)).out();
}
/**
diff --git a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/prepare/IgnitePlanner.java b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/prepare/IgnitePlanner.java
index aaa4d41..c3ed639 100644
--- a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/prepare/IgnitePlanner.java
+++ b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/prepare/IgnitePlanner.java
@@ -20,7 +20,9 @@ package org.apache.ignite.internal.processors.query.calcite.prepare;
import com.google.common.collect.ImmutableList;
import java.io.Reader;
import java.util.List;
+import org.apache.calcite.plan.Context;
import org.apache.calcite.plan.RelOptCluster;
+import org.apache.calcite.plan.RelOptCostFactory;
import org.apache.calcite.plan.RelOptLattice;
import org.apache.calcite.plan.RelOptMaterialization;
import org.apache.calcite.plan.RelOptPlanner;
@@ -29,7 +31,6 @@ import org.apache.calcite.plan.RelOptTable;
import org.apache.calcite.plan.RelTraitDef;
import org.apache.calcite.plan.RelTraitSet;
import org.apache.calcite.plan.volcano.VolcanoPlanner;
-import org.apache.calcite.plan.volcano.VolcanoUtils;
import org.apache.calcite.prepare.CalciteCatalogReader;
import org.apache.calcite.rel.RelNode;
import org.apache.calcite.rel.RelRoot;
@@ -52,6 +53,7 @@ import org.apache.calcite.tools.Program;
import org.apache.calcite.tools.RelBuilder;
import org.apache.calcite.tools.ValidationException;
import org.apache.calcite.util.Pair;
+import org.apache.ignite.IgniteSystemProperties;
import org.apache.ignite.internal.processors.cache.query.IgniteQueryErrorCode;
import org.apache.ignite.internal.processors.query.IgniteSQLException;
import org.apache.ignite.internal.processors.query.calcite.metadata.IgniteMetadata;
@@ -245,7 +247,7 @@ public class IgnitePlanner implements Planner, RelOptTable.ViewExpander {
/** */
private RelOptPlanner planner() {
if (planner == null) {
- planner = VolcanoUtils.impatient(new VolcanoPlanner(frameworkConfig.getCostFactory(), ctx));
+ planner = new VolcanoPlannerExt(frameworkConfig.getCostFactory(), ctx);
planner.setExecutor(rexExecutor);
for (RelTraitDef<?> def : traitDefs)
@@ -287,4 +289,21 @@ public class IgnitePlanner implements Planner, RelOptTable.ViewExpander {
private List<RelOptMaterialization> materializations() {
return ImmutableList.of(); // TODO
}
+
+ /** */
+ private static class VolcanoPlannerExt extends VolcanoPlanner {
+ /** */
+ private static final Boolean IMPATIENT = IgniteSystemProperties.getBoolean("IGNITE_CALCITE_PLANER_IMPATIENT", true);
+
+ /** */
+ private static final Boolean AMBITIOUS = IgniteSystemProperties.getBoolean("IGNITE_CALCITE_PLANER_AMBITIOUS", true);
+
+ /** */
+ protected VolcanoPlannerExt(RelOptCostFactory costFactory, Context externalContext) {
+ super(costFactory, externalContext);
+
+ impatient = IMPATIENT;
+ ambitious = AMBITIOUS;
+ }
+ }
}
diff --git a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/prepare/PlannerPhase.java b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/prepare/PlannerPhase.java
index e4c3dc0..9192bdc 100644
--- a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/prepare/PlannerPhase.java
+++ b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/prepare/PlannerPhase.java
@@ -17,16 +17,18 @@
package org.apache.ignite.internal.processors.query.calcite.prepare;
-import org.apache.calcite.plan.volcano.AbstractConverter;
import org.apache.calcite.rel.rules.SubQueryRemoveRule;
import org.apache.calcite.tools.Program;
import org.apache.calcite.tools.RuleSet;
import org.apache.calcite.tools.RuleSets;
-import org.apache.ignite.internal.processors.query.calcite.rule.FilterConverter;
-import org.apache.ignite.internal.processors.query.calcite.rule.JoinConverter;
-import org.apache.ignite.internal.processors.query.calcite.rule.ProjectConverter;
-import org.apache.ignite.internal.processors.query.calcite.rule.TableModifyConverter;
-import org.apache.ignite.internal.processors.query.calcite.rule.ValuesConverter;
+import org.apache.ignite.internal.processors.query.calcite.rule.FilterConverterRule;
+import org.apache.ignite.internal.processors.query.calcite.rule.FilterTraitsPropagationRule;
+import org.apache.ignite.internal.processors.query.calcite.rule.JoinConverterRule;
+import org.apache.ignite.internal.processors.query.calcite.rule.JoinTraitsPropagationRule;
+import org.apache.ignite.internal.processors.query.calcite.rule.ProjectConverterRule;
+import org.apache.ignite.internal.processors.query.calcite.rule.ProjectTraitsPropagationRule;
+import org.apache.ignite.internal.processors.query.calcite.rule.TableModifyConverterRule;
+import org.apache.ignite.internal.processors.query.calcite.rule.ValuesConverterRule;
import static org.apache.ignite.internal.processors.query.calcite.prepare.IgnitePrograms.cbo;
import static org.apache.ignite.internal.processors.query.calcite.prepare.IgnitePrograms.decorrelate;
@@ -42,7 +44,7 @@ public enum PlannerPhase {
/** {@inheritDoc} */
@Override public RuleSet getRules(PlanningContext ctx) {
return RuleSets.ofList(
- ValuesConverter.INSTANCE,
+ ValuesConverterRule.INSTANCE,
SubQueryRemoveRule.FILTER,
SubQueryRemoveRule.PROJECT,
SubQueryRemoveRule.JOIN);
@@ -59,11 +61,13 @@ public enum PlannerPhase {
/** {@inheritDoc} */
@Override public RuleSet getRules(PlanningContext ctx) {
return RuleSets.ofList(
- AbstractConverter.ExpandConversionRule.INSTANCE,
- JoinConverter.INSTANCE,
- ProjectConverter.INSTANCE,
- FilterConverter.INSTANCE,
- TableModifyConverter.INSTANCE);
+ JoinConverterRule.INSTANCE,
+ JoinTraitsPropagationRule.INSTANCE,
+ ProjectConverterRule.INSTANCE,
+ ProjectTraitsPropagationRule.INSTANCE,
+ FilterConverterRule.INSTANCE,
+ FilterTraitsPropagationRule.INSTANCE,
+ TableModifyConverterRule.INSTANCE);
}
/** {@inheritDoc} */
diff --git a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rel/IgniteConvention.java b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rel/IgniteConvention.java
index 34c4e5e..3c0cc23 100644
--- a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rel/IgniteConvention.java
+++ b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rel/IgniteConvention.java
@@ -19,7 +19,6 @@ package org.apache.ignite.internal.processors.query.calcite.rel;
import org.apache.calcite.plan.Convention;
import org.apache.calcite.plan.ConventionTraitDef;
-import org.apache.calcite.plan.RelTraitSet;
/**
* Ignite convention trait.
@@ -36,10 +35,4 @@ public class IgniteConvention extends Convention.Impl {
@Override public ConventionTraitDef getTraitDef() {
return ConventionTraitDef.INSTANCE;
}
-
- /** {@inheritDoc} */
- @Override public boolean useAbstractConvertersForConversion(RelTraitSet fromTraits, RelTraitSet toTraits) {
- // use converters for physical nodes only.
- return toTraits.contains(INSTANCE) && fromTraits.contains(INSTANCE);
- }
}
diff --git a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rel/IgniteJoin.java b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rel/IgniteJoin.java
index 9834992..2c0ff3a 100644
--- a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rel/IgniteJoin.java
+++ b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rel/IgniteJoin.java
@@ -19,11 +19,15 @@ package org.apache.ignite.internal.processors.query.calcite.rel;
import java.util.Set;
import org.apache.calcite.plan.RelOptCluster;
+import org.apache.calcite.plan.RelOptCost;
+import org.apache.calcite.plan.RelOptPlanner;
import org.apache.calcite.plan.RelTraitSet;
+import org.apache.calcite.rel.RelDistribution;
import org.apache.calcite.rel.RelNode;
import org.apache.calcite.rel.core.CorrelationId;
import org.apache.calcite.rel.core.Join;
import org.apache.calcite.rel.core.JoinRelType;
+import org.apache.calcite.rel.metadata.RelMetadataQuery;
import org.apache.calcite.rex.RexNode;
/**
@@ -61,4 +65,12 @@ public class IgniteJoin extends Join implements IgniteRel {
@Override public <T> T accept(IgniteRelVisitor<T> visitor) {
return visitor.visit(this);
}
+
+ /** {@inheritDoc} */
+ @Override public RelOptCost computeSelfCost(RelOptPlanner planner, RelMetadataQuery mq) {
+ if (distribution().getType() == RelDistribution.Type.ANY)
+ return planner.getCostFactory().makeInfiniteCost();
+
+ return super.computeSelfCost(planner, mq);
+ }
}
diff --git a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rel/IgniteReceiver.java b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rel/IgniteReceiver.java
index 0e474e3..ae86e74 100644
--- a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rel/IgniteReceiver.java
+++ b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rel/IgniteReceiver.java
@@ -21,13 +21,9 @@ import java.util.List;
import org.apache.calcite.plan.RelOptCluster;
import org.apache.calcite.plan.RelTraitSet;
import org.apache.calcite.rel.AbstractRelNode;
-import org.apache.calcite.rel.RelCollation;
-import org.apache.calcite.rel.RelCollationTraitDef;
import org.apache.calcite.rel.RelNode;
import org.apache.calcite.rel.type.RelDataType;
import org.apache.ignite.internal.processors.query.calcite.prepare.Fragment;
-import org.apache.ignite.internal.processors.query.calcite.trait.DistributionTraitDef;
-import org.apache.ignite.internal.processors.query.calcite.trait.IgniteDistribution;
/**
* Relational expression that receives elements from remote {@link IgniteSender}
@@ -67,18 +63,4 @@ public class IgniteReceiver extends AbstractRelNode implements IgniteRel {
public Fragment source() {
return source;
}
-
- /**
- * @return Node distribution.
- */
- public IgniteDistribution distribution() {
- return getTraitSet().getTrait(DistributionTraitDef.INSTANCE);
- }
-
- /**
- * @return Node collations.
- */
- public List<RelCollation> collations() {
- return getTraitSet().getTraits(RelCollationTraitDef.INSTANCE);
- }
}
diff --git a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rel/IgniteRel.java b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rel/IgniteRel.java
index 9c827f2..7ecfacf 100644
--- a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rel/IgniteRel.java
+++ b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rel/IgniteRel.java
@@ -17,7 +17,12 @@
package org.apache.ignite.internal.processors.query.calcite.rel;
+import java.util.List;
+import org.apache.calcite.rel.RelCollation;
+import org.apache.calcite.rel.RelCollationTraitDef;
import org.apache.calcite.rel.RelNode;
+import org.apache.ignite.internal.processors.query.calcite.trait.DistributionTraitDef;
+import org.apache.ignite.internal.processors.query.calcite.trait.IgniteDistribution;
/**
* A superinterface of all Ignite relational nodes.
@@ -30,4 +35,18 @@ public interface IgniteRel extends RelNode {
* @return Visit result.
*/
<T> T accept(IgniteRelVisitor<T> visitor);
+
+ /**
+ * @return Node distribution.
+ */
+ default IgniteDistribution distribution() {
+ return getTraitSet().getTrait(DistributionTraitDef.INSTANCE);
+ }
+
+ /**
+ * @return Node collations.
+ */
+ default List<RelCollation> collations() {
+ return getTraitSet().getTraits(RelCollationTraitDef.INSTANCE);
+ }
}
diff --git a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rel/IgniteSender.java b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rel/IgniteSender.java
index 403f34b..b95af15 100644
--- a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rel/IgniteSender.java
+++ b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rel/IgniteSender.java
@@ -20,8 +20,6 @@ package org.apache.ignite.internal.processors.query.calcite.rel;
import java.util.List;
import org.apache.calcite.plan.RelOptCluster;
import org.apache.calcite.plan.RelTraitSet;
-import org.apache.calcite.rel.RelCollation;
-import org.apache.calcite.rel.RelCollationTraitDef;
import org.apache.calcite.rel.RelNode;
import org.apache.calcite.rel.SingleRel;
import org.apache.ignite.internal.processors.query.calcite.prepare.RelTarget;
@@ -87,21 +85,7 @@ public class IgniteSender extends SingleRel implements IgniteRel, RelTargetAware
/**
* @return Node distribution.
*/
- public IgniteDistribution targetDistribution() {
- return getTraitSet().getTrait(DistributionTraitDef.INSTANCE);
- }
-
- /**
- * @return Node distribution.
- */
public IgniteDistribution sourceDistribution() {
return input.getTraitSet().getTrait(DistributionTraitDef.INSTANCE);
}
-
- /**
- * @return Node collations.
- */
- public List<RelCollation> collations() {
- return getTraitSet().getTraits(RelCollationTraitDef.INSTANCE);
- }
}
diff --git a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rule/FilterConverter.java b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rule/FilterConverter.java
deleted file mode 100644
index 7760c11..0000000
--- a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rule/FilterConverter.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * 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 org.apache.ignite.internal.processors.query.calcite.rule;
-
-import java.util.List;
-import org.apache.calcite.plan.RelOptCluster;
-import org.apache.calcite.plan.RelTraitSet;
-import org.apache.calcite.rel.RelNode;
-import org.apache.calcite.rel.convert.ConverterRule;
-import org.apache.calcite.rel.logical.LogicalFilter;
-import org.apache.calcite.rel.metadata.RelMetadataQuery;
-import org.apache.ignite.internal.processors.query.calcite.metadata.IgniteMdDerivedDistribution;
-import org.apache.ignite.internal.processors.query.calcite.rel.IgniteConvention;
-import org.apache.ignite.internal.processors.query.calcite.rel.IgniteFilter;
-import org.apache.ignite.internal.processors.query.calcite.trait.IgniteDistribution;
-import org.apache.ignite.internal.processors.query.calcite.util.Commons;
-import org.jetbrains.annotations.NotNull;
-
-/**
- * Ignite Filter converter.
- */
-public class FilterConverter extends IgniteConverter {
- /** */
- public static final ConverterRule INSTANCE = new FilterConverter();
-
- /**
- * Creates a converter.
- */
- public FilterConverter() {
- super(LogicalFilter.class, "FilterConverter");
- }
-
- /** {@inheritDoc} */
- @Override protected List<RelNode> convert0(@NotNull RelNode rel) {
- LogicalFilter filter = (LogicalFilter) rel;
-
- RelNode input = convert(filter.getInput(), IgniteConvention.INSTANCE);
-
- RelOptCluster cluster = rel.getCluster();
- RelMetadataQuery mq = cluster.getMetadataQuery();
-
- List<IgniteDistribution> distrs = IgniteMdDerivedDistribution.deriveDistributions(input, IgniteConvention.INSTANCE, mq);
-
- return Commons.transform(distrs, d -> create(filter, input, d));
- }
-
- /** */
- private static IgniteFilter create(LogicalFilter filter, RelNode input, IgniteDistribution distr) {
- RelTraitSet traits = filter.getTraitSet()
- .replace(distr)
- .replace(IgniteConvention.INSTANCE);
-
- return new IgniteFilter(filter.getCluster(), traits, convert(input, distr), filter.getCondition());
- }
-}
diff --git a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rule/ValuesConverter.java b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rule/FilterConverterRule.java
similarity index 52%
copy from modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rule/ValuesConverter.java
copy to modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rule/FilterConverterRule.java
index 0bfd593..315bf46 100644
--- a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rule/ValuesConverter.java
+++ b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rule/FilterConverterRule.java
@@ -17,41 +17,37 @@
package org.apache.ignite.internal.processors.query.calcite.rule;
-import java.util.Collections;
-import java.util.List;
+import org.apache.calcite.plan.RelOptCluster;
+import org.apache.calcite.plan.RelOptRule;
+import org.apache.calcite.plan.RelOptRuleCall;
import org.apache.calcite.plan.RelTraitSet;
import org.apache.calcite.rel.RelNode;
-import org.apache.calcite.rel.convert.ConverterRule;
-import org.apache.calcite.rel.logical.LogicalValues;
-import org.apache.ignite.internal.processors.query.calcite.metadata.IgniteMdDistribution;
+import org.apache.calcite.rel.logical.LogicalFilter;
import org.apache.ignite.internal.processors.query.calcite.rel.IgniteConvention;
-import org.apache.ignite.internal.processors.query.calcite.rel.IgniteValues;
-import org.jetbrains.annotations.NotNull;
+import org.apache.ignite.internal.processors.query.calcite.rel.IgniteFilter;
/**
*
*/
-public class ValuesConverter extends IgniteConverter {
+public class FilterConverterRule extends RelOptRule {
/** */
- public static final ConverterRule INSTANCE = new ValuesConverter();
+ public static final RelOptRule INSTANCE = new FilterConverterRule();
- /**
- * Creates a ConverterRule.
- */
- protected ValuesConverter() {
- super(LogicalValues.class, "ValuesConverter");
+ /** */
+ public FilterConverterRule() {
+ super(operand(LogicalFilter.class, any()));
}
/** {@inheritDoc} */
- @Override protected List<RelNode> convert0(@NotNull RelNode rel) {
- LogicalValues values = (LogicalValues) rel;
-
- RelTraitSet traits = values.getTraitSet()
- .replace(IgniteConvention.INSTANCE)
- .replace(IgniteMdDistribution.values(values.getRowType(), values.getTuples()));
+ @Override public void onMatch(RelOptRuleCall call) {
+ LogicalFilter rel = call.rel(0);
- final IgniteValues newRel = new IgniteValues(values.getCluster(), values.getRowType(), values.getTuples(), traits);
+ RelOptCluster cluster = rel.getCluster();
+ RelNode input = convert(rel.getInput(), IgniteConvention.INSTANCE);
+ RelTraitSet traits = rel.getTraitSet()
+ .replace(IgniteConvention.INSTANCE);
- return Collections.singletonList(newRel);
+ RuleUtils.transformTo(call,
+ new IgniteFilter(cluster, traits, input, rel.getCondition()));
}
}
diff --git a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rule/ValuesConverter.java b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rule/FilterTraitsPropagationRule.java
similarity index 52%
copy from modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rule/ValuesConverter.java
copy to modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rule/FilterTraitsPropagationRule.java
index 0bfd593..14d5a34 100644
--- a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rule/ValuesConverter.java
+++ b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rule/FilterTraitsPropagationRule.java
@@ -17,41 +17,39 @@
package org.apache.ignite.internal.processors.query.calcite.rule;
-import java.util.Collections;
-import java.util.List;
+import org.apache.calcite.plan.RelOptCluster;
+import org.apache.calcite.plan.RelOptRule;
+import org.apache.calcite.plan.RelOptRuleCall;
import org.apache.calcite.plan.RelTraitSet;
+import org.apache.calcite.plan.volcano.RelSubset;
import org.apache.calcite.rel.RelNode;
-import org.apache.calcite.rel.convert.ConverterRule;
-import org.apache.calcite.rel.logical.LogicalValues;
+import org.apache.calcite.rel.metadata.RelMetadataQuery;
import org.apache.ignite.internal.processors.query.calcite.metadata.IgniteMdDistribution;
-import org.apache.ignite.internal.processors.query.calcite.rel.IgniteConvention;
-import org.apache.ignite.internal.processors.query.calcite.rel.IgniteValues;
-import org.jetbrains.annotations.NotNull;
+import org.apache.ignite.internal.processors.query.calcite.rel.IgniteFilter;
/**
*
*/
-public class ValuesConverter extends IgniteConverter {
+public class FilterTraitsPropagationRule extends RelOptRule {
/** */
- public static final ConverterRule INSTANCE = new ValuesConverter();
+ public static final RelOptRule INSTANCE = new FilterTraitsPropagationRule();
- /**
- * Creates a ConverterRule.
- */
- protected ValuesConverter() {
- super(LogicalValues.class, "ValuesConverter");
+ public FilterTraitsPropagationRule() {
+ super(operand(IgniteFilter.class, operand(RelSubset.class, any())));
}
/** {@inheritDoc} */
- @Override protected List<RelNode> convert0(@NotNull RelNode rel) {
- LogicalValues values = (LogicalValues) rel;
+ @Override public void onMatch(RelOptRuleCall call) {
+ IgniteFilter rel = call.rel(0);
+ RelNode input = call.rel(1);
- RelTraitSet traits = values.getTraitSet()
- .replace(IgniteConvention.INSTANCE)
- .replace(IgniteMdDistribution.values(values.getRowType(), values.getTuples()));
+ RelOptCluster cluster = rel.getCluster();
+ RelMetadataQuery mq = cluster.getMetadataQuery();
- final IgniteValues newRel = new IgniteValues(values.getCluster(), values.getRowType(), values.getTuples(), traits);
+ RelTraitSet traits = rel.getTraitSet()
+ .replace(IgniteMdDistribution.filter(mq, input, rel.getCondition()));
- return Collections.singletonList(newRel);
+ RuleUtils.transformTo(call,
+ new IgniteFilter(cluster, traits, input, rel.getCondition()));
}
}
diff --git a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rule/IgniteConverter.java b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rule/IgniteConverter.java
deleted file mode 100644
index 6c97f65..0000000
--- a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rule/IgniteConverter.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * 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 org.apache.ignite.internal.processors.query.calcite.rule;
-
-import com.google.common.collect.ImmutableMap;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import org.apache.calcite.plan.Convention;
-import org.apache.calcite.plan.RelOptPlanner;
-import org.apache.calcite.plan.RelOptRuleCall;
-import org.apache.calcite.rel.RelNode;
-import org.apache.calcite.rel.convert.ConverterRule;
-import org.apache.ignite.internal.processors.query.calcite.rel.IgniteConvention;
-import org.apache.ignite.internal.util.typedef.F;
-import org.jetbrains.annotations.NotNull;
-
-/**
- * Abstract converter, that converts logical relational expression into one or more physical ones.
- */
-public abstract class IgniteConverter extends ConverterRule {
- /**
- * Creates a ConverterRule.
- *
- * @param clazz Type of relational expression to consider converting
- * @param descriptionPrefix Description prefix of rule
- */
- protected IgniteConverter(Class<? extends RelNode> clazz, String descriptionPrefix) {
- super(clazz, Convention.NONE, IgniteConvention.INSTANCE, descriptionPrefix);
- }
-
- /** {@inheritDoc} */
- @Override public void onMatch(@NotNull RelOptRuleCall call) {
- RelNode rel = call.rel(0);
-
- List<RelNode> rels = convert0(rel);
- if (F.isEmpty(rels))
- return;
-
- Map<RelNode, RelNode> equiv = ImmutableMap.of();
-
- if (rels.size() > 1) {
- equiv = new HashMap<>();
-
- for (int i = 1; i < rels.size(); i++) {
- equiv.put(rels.get(i), rel);
- }
- }
-
- call.transformTo(F.first(rels), equiv);
- }
-
- /** {@inheritDoc} */
- @Override public RelNode convert(@NotNull RelNode rel) {
- List<RelNode> converted = convert0(rel);
-
- if (converted.size() > 1) {
- RelOptPlanner planner = rel.getCluster().getPlanner();
-
- for (int i = 1; i < converted.size(); i++)
- planner.ensureRegistered(converted.get(i), rel);
- }
-
- return F.first(converted);
- }
-
- /**
- * Converts logical relational expression into one or more physical ones.
- * @param rel Logical relational expression.
- * @return A list of physical expressions.
- */
- protected abstract List<RelNode> convert0(@NotNull RelNode rel);
-}
diff --git a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rule/JoinConverter.java b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rule/JoinConverter.java
deleted file mode 100644
index 9a79bbc..0000000
--- a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rule/JoinConverter.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * 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 org.apache.ignite.internal.processors.query.calcite.rule;
-
-import java.util.List;
-import org.apache.calcite.plan.RelOptCluster;
-import org.apache.calcite.plan.RelTraitSet;
-import org.apache.calcite.rel.RelNode;
-import org.apache.calcite.rel.convert.ConverterRule;
-import org.apache.calcite.rel.logical.LogicalJoin;
-import org.apache.calcite.rel.metadata.RelMetadataQuery;
-import org.apache.ignite.internal.processors.query.calcite.metadata.IgniteMdDerivedDistribution;
-import org.apache.ignite.internal.processors.query.calcite.rel.IgniteConvention;
-import org.apache.ignite.internal.processors.query.calcite.rel.IgniteJoin;
-import org.apache.ignite.internal.processors.query.calcite.trait.IgniteDistribution;
-import org.apache.ignite.internal.processors.query.calcite.trait.IgniteDistributions;
-import org.apache.ignite.internal.processors.query.calcite.util.Commons;
-import org.jetbrains.annotations.NotNull;
-
-/**
- * Ignite Join converter.
- */
-public class JoinConverter extends IgniteConverter {
- public static final ConverterRule INSTANCE = new JoinConverter();
-
- /**
- * Creates a converter.
- */
- public JoinConverter() {
- super(LogicalJoin.class, "JoinConverter");
- }
-
- /** {@inheritDoc} */
- @Override protected List<RelNode> convert0(@NotNull RelNode rel) {
- LogicalJoin join = (LogicalJoin) rel;
-
- RelNode left = convert(join.getLeft(), IgniteConvention.INSTANCE);
- RelNode right = convert(join.getRight(), IgniteConvention.INSTANCE);
-
- RelOptCluster cluster = join.getCluster();
- RelMetadataQuery mq = cluster.getMetadataQuery();
-
- List<IgniteDistribution> leftTraits = IgniteMdDerivedDistribution.deriveDistributions(left, IgniteConvention.INSTANCE, mq);
- List<IgniteDistribution> rightTraits = IgniteMdDerivedDistribution.deriveDistributions(right, IgniteConvention.INSTANCE, mq);
-
- List<IgniteDistributions.BiSuggestion> suggestions = IgniteDistributions.suggestJoin(leftTraits, rightTraits, join.analyzeCondition(), join.getJoinType());
-
- return Commons.transform(suggestions, s -> create(join, left, right, s));
- }
-
- /** */
- private static RelNode create(LogicalJoin join, RelNode left, RelNode right, IgniteDistributions.BiSuggestion suggest) {
- left = convert(left, suggest.left());
- right = convert(right, suggest.right());
-
- RelTraitSet traitSet = join.getTraitSet().replace(IgniteConvention.INSTANCE).replace(suggest.out());
-
- return new IgniteJoin(join.getCluster(), traitSet, left, right, join.getCondition(), join.getVariablesSet(), join.getJoinType());
- }
-}
diff --git a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rule/ValuesConverter.java b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rule/JoinConverterRule.java
similarity index 53%
copy from modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rule/ValuesConverter.java
copy to modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rule/JoinConverterRule.java
index 0bfd593..af9a508 100644
--- a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rule/ValuesConverter.java
+++ b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rule/JoinConverterRule.java
@@ -17,41 +17,40 @@
package org.apache.ignite.internal.processors.query.calcite.rule;
-import java.util.Collections;
-import java.util.List;
+import org.apache.calcite.plan.RelOptCluster;
+import org.apache.calcite.plan.RelOptRule;
+import org.apache.calcite.plan.RelOptRuleCall;
import org.apache.calcite.plan.RelTraitSet;
import org.apache.calcite.rel.RelNode;
-import org.apache.calcite.rel.convert.ConverterRule;
-import org.apache.calcite.rel.logical.LogicalValues;
-import org.apache.ignite.internal.processors.query.calcite.metadata.IgniteMdDistribution;
+import org.apache.calcite.rel.logical.LogicalJoin;
import org.apache.ignite.internal.processors.query.calcite.rel.IgniteConvention;
-import org.apache.ignite.internal.processors.query.calcite.rel.IgniteValues;
-import org.jetbrains.annotations.NotNull;
+import org.apache.ignite.internal.processors.query.calcite.rel.IgniteJoin;
/**
- *
+ * Ignite Join converter.
*/
-public class ValuesConverter extends IgniteConverter {
+public class JoinConverterRule extends RelOptRule {
/** */
- public static final ConverterRule INSTANCE = new ValuesConverter();
+ public static final RelOptRule INSTANCE = new JoinConverterRule();
/**
- * Creates a ConverterRule.
+ * Creates a converter.
*/
- protected ValuesConverter() {
- super(LogicalValues.class, "ValuesConverter");
+ public JoinConverterRule() {
+ super(operand(LogicalJoin.class, any()));
}
/** {@inheritDoc} */
- @Override protected List<RelNode> convert0(@NotNull RelNode rel) {
- LogicalValues values = (LogicalValues) rel;
-
- RelTraitSet traits = values.getTraitSet()
- .replace(IgniteConvention.INSTANCE)
- .replace(IgniteMdDistribution.values(values.getRowType(), values.getTuples()));
+ @Override public void onMatch(RelOptRuleCall call) {
+ LogicalJoin rel = call.rel(0);
- final IgniteValues newRel = new IgniteValues(values.getCluster(), values.getRowType(), values.getTuples(), traits);
+ RelOptCluster cluster = rel.getCluster();
+ RelNode left = convert(rel.getLeft(), IgniteConvention.INSTANCE);
+ RelNode right = convert(rel.getRight(), IgniteConvention.INSTANCE);
+ RelTraitSet traits = rel.getTraitSet()
+ .replace(IgniteConvention.INSTANCE);
- return Collections.singletonList(newRel);
+ RuleUtils.transformTo(call,
+ new IgniteJoin(cluster, traits, left, right, rel.getCondition(), rel.getVariablesSet(), rel.getJoinType()));
}
}
diff --git a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rule/JoinTraitsPropagationRule.java b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rule/JoinTraitsPropagationRule.java
new file mode 100644
index 0000000..e6476d5
--- /dev/null
+++ b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rule/JoinTraitsPropagationRule.java
@@ -0,0 +1,75 @@
+/*
+ * 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 org.apache.ignite.internal.processors.query.calcite.rule;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+import org.apache.calcite.plan.RelOptCluster;
+import org.apache.calcite.plan.RelOptRule;
+import org.apache.calcite.plan.RelOptRuleCall;
+import org.apache.calcite.plan.RelTraitSet;
+import org.apache.calcite.plan.volcano.RelSubset;
+import org.apache.calcite.rel.RelNode;
+import org.apache.calcite.rel.core.CorrelationId;
+import org.apache.calcite.rel.core.JoinRelType;
+import org.apache.calcite.rex.RexNode;
+import org.apache.ignite.internal.processors.query.calcite.rel.IgniteJoin;
+import org.apache.ignite.internal.processors.query.calcite.trait.IgniteDistributions;
+
+/**
+ *
+ */
+public class JoinTraitsPropagationRule extends RelOptRule {
+ /** */
+ public static final RelOptRule INSTANCE = new JoinTraitsPropagationRule();
+
+ public JoinTraitsPropagationRule() {
+ super(operand(IgniteJoin.class, operand(RelSubset.class, any())));
+ }
+
+ /** {@inheritDoc} */
+ @Override public void onMatch(RelOptRuleCall call) {
+ IgniteJoin rel = call.rel(0);
+
+ RelNode left = rel.getLeft();
+ RelNode right = rel.getRight();
+
+ RelOptCluster cluster = rel.getCluster();
+ RexNode condition = rel.getCondition();
+ Set<CorrelationId> variablesSet = rel.getVariablesSet();
+ JoinRelType joinType = rel.getJoinType();
+
+ List<IgniteDistributions.BiSuggestion> suggests = IgniteDistributions.suggestJoin(
+ left, right, rel.analyzeCondition(), joinType);
+
+ List<RelNode> newRels = new ArrayList<>(suggests.size());
+
+ for (IgniteDistributions.BiSuggestion suggest : suggests) {
+ RelTraitSet traits = rel.getTraitSet().replace(suggest.out());
+
+ RelNode left0 = RuleUtils.changeTraits(left, suggest.left());
+ RelNode right0 = RuleUtils.changeTraits(right, suggest.right());
+
+ newRels.add(new IgniteJoin(cluster, traits, left0, right0,
+ condition, variablesSet, joinType));
+ }
+
+ RuleUtils.transformTo(call, newRels);
+ }
+}
diff --git a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rule/ProjectConverter.java b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rule/ProjectConverter.java
deleted file mode 100644
index 3879766..0000000
--- a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rule/ProjectConverter.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * 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 org.apache.ignite.internal.processors.query.calcite.rule;
-
-import java.util.List;
-import org.apache.calcite.plan.RelOptCluster;
-import org.apache.calcite.plan.RelTraitSet;
-import org.apache.calcite.rel.RelNode;
-import org.apache.calcite.rel.convert.ConverterRule;
-import org.apache.calcite.rel.logical.LogicalProject;
-import org.apache.calcite.rel.metadata.RelMetadataQuery;
-import org.apache.ignite.internal.processors.query.calcite.metadata.IgniteMdDerivedDistribution;
-import org.apache.ignite.internal.processors.query.calcite.metadata.IgniteMdDistribution;
-import org.apache.ignite.internal.processors.query.calcite.rel.IgniteConvention;
-import org.apache.ignite.internal.processors.query.calcite.rel.IgniteProject;
-import org.apache.ignite.internal.processors.query.calcite.trait.IgniteDistribution;
-import org.apache.ignite.internal.processors.query.calcite.util.Commons;
-import org.jetbrains.annotations.NotNull;
-
-/**
- * Ignite Project converter.
- */
-public class ProjectConverter extends IgniteConverter {
- /** */
- public static final ConverterRule INSTANCE = new ProjectConverter();
-
- /**
- * Creates a converter.
- */
- public ProjectConverter() {
- super(LogicalProject.class, "ProjectConverter");
- }
-
- /** {@inheritDoc} */
- @Override protected List<RelNode> convert0(@NotNull RelNode rel) {
- LogicalProject project = (LogicalProject) rel;
-
- RelNode input = convert(project.getInput(), IgniteConvention.INSTANCE);
-
- RelOptCluster cluster = rel.getCluster();
- RelMetadataQuery mq = cluster.getMetadataQuery();
-
- List<IgniteDistribution> distrs = IgniteMdDerivedDistribution.deriveDistributions(input, IgniteConvention.INSTANCE, mq);
-
- return Commons.transform(distrs, d -> create(project, input, d));
- }
-
- /** */
- private static IgniteProject create(LogicalProject project, RelNode input, IgniteDistribution distr) {
- RelTraitSet traits = project.getTraitSet()
- .replace(IgniteMdDistribution.project(input.getRowType(), distr, project.getProjects()))
- .replace(IgniteConvention.INSTANCE);
-
- return new IgniteProject(project.getCluster(), traits, convert(input, distr), project.getProjects(), project.getRowType());
- }
-}
diff --git a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rule/TableModifyConverter.java b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rule/ProjectConverterRule.java
similarity index 51%
copy from modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rule/TableModifyConverter.java
copy to modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rule/ProjectConverterRule.java
index 0088d64..5c3dcee 100644
--- a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rule/TableModifyConverter.java
+++ b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rule/ProjectConverterRule.java
@@ -17,46 +17,37 @@
package org.apache.ignite.internal.processors.query.calcite.rule;
-import java.util.Collections;
-import java.util.List;
import org.apache.calcite.plan.RelOptCluster;
+import org.apache.calcite.plan.RelOptRule;
+import org.apache.calcite.plan.RelOptRuleCall;
import org.apache.calcite.plan.RelTraitSet;
import org.apache.calcite.rel.RelNode;
-import org.apache.calcite.rel.convert.ConverterRule;
-import org.apache.calcite.rel.logical.LogicalTableModify;
+import org.apache.calcite.rel.logical.LogicalProject;
import org.apache.ignite.internal.processors.query.calcite.rel.IgniteConvention;
-import org.apache.ignite.internal.processors.query.calcite.rel.IgniteTableModify;
-import org.apache.ignite.internal.processors.query.calcite.trait.IgniteDistributions;
-import org.jetbrains.annotations.NotNull;
+import org.apache.ignite.internal.processors.query.calcite.rel.IgniteProject;
/**
*
*/
-public class TableModifyConverter extends IgniteConverter{
+public class ProjectConverterRule extends RelOptRule {
/** */
- public static final ConverterRule INSTANCE = new TableModifyConverter();
+ public static final RelOptRule INSTANCE = new ProjectConverterRule();
- /**
- * Creates a ConverterRule.
- */
- public TableModifyConverter() {
- super(LogicalTableModify.class, "TableModifyConverter");
+ /** */
+ public ProjectConverterRule() {
+ super(operand(LogicalProject.class, any()));
}
- /** {@inheritDoc} */
- @Override protected List<RelNode> convert0(@NotNull RelNode rel) {
- LogicalTableModify modify = (LogicalTableModify) rel;
-
- RelTraitSet traits = rel.getTraitSet()
- .replace(IgniteConvention.INSTANCE)
- .replace(IgniteDistributions.single());
+ /** */
+ @Override public void onMatch(RelOptRuleCall call) {
+ LogicalProject rel = call.rel(0);
RelOptCluster cluster = rel.getCluster();
- RelNode input = convert(modify.getInput(), traits);
-
- IgniteTableModify newRel = new IgniteTableModify(cluster, traits, modify.getTable(), modify.getCatalogReader(), input,
- modify.getOperation(), modify.getUpdateColumnList(), modify.getSourceExpressionList(), modify.isFlattened());
+ RelNode input = convert(rel.getInput(), IgniteConvention.INSTANCE);
+ RelTraitSet traits = rel.getTraitSet()
+ .replace(IgniteConvention.INSTANCE);
- return Collections.singletonList(newRel);
+ RuleUtils.transformTo(call,
+ new IgniteProject(cluster, traits, input, rel.getProjects(), rel.getRowType()));
}
}
diff --git a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rule/ValuesConverter.java b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rule/ProjectTraitsPropagationRule.java
similarity index 51%
copy from modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rule/ValuesConverter.java
copy to modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rule/ProjectTraitsPropagationRule.java
index 0bfd593..2a2b491 100644
--- a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rule/ValuesConverter.java
+++ b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rule/ProjectTraitsPropagationRule.java
@@ -17,41 +17,41 @@
package org.apache.ignite.internal.processors.query.calcite.rule;
-import java.util.Collections;
-import java.util.List;
+import org.apache.calcite.plan.RelOptCluster;
+import org.apache.calcite.plan.RelOptRule;
+import org.apache.calcite.plan.RelOptRuleCall;
import org.apache.calcite.plan.RelTraitSet;
+import org.apache.calcite.plan.volcano.RelSubset;
import org.apache.calcite.rel.RelNode;
-import org.apache.calcite.rel.convert.ConverterRule;
-import org.apache.calcite.rel.logical.LogicalValues;
+import org.apache.calcite.rel.metadata.RelMetadataQuery;
import org.apache.ignite.internal.processors.query.calcite.metadata.IgniteMdDistribution;
-import org.apache.ignite.internal.processors.query.calcite.rel.IgniteConvention;
-import org.apache.ignite.internal.processors.query.calcite.rel.IgniteValues;
-import org.jetbrains.annotations.NotNull;
+import org.apache.ignite.internal.processors.query.calcite.rel.IgniteProject;
/**
- *
+ * Ignite Project converter.
*/
-public class ValuesConverter extends IgniteConverter {
+public class ProjectTraitsPropagationRule extends RelOptRule {
/** */
- public static final ConverterRule INSTANCE = new ValuesConverter();
+ public static final RelOptRule INSTANCE = new ProjectTraitsPropagationRule();
/**
- * Creates a ConverterRule.
+ * Creates a converter.
*/
- protected ValuesConverter() {
- super(LogicalValues.class, "ValuesConverter");
+ public ProjectTraitsPropagationRule() {
+ super(operand(IgniteProject.class, operand(RelSubset.class, any())));
}
- /** {@inheritDoc} */
- @Override protected List<RelNode> convert0(@NotNull RelNode rel) {
- LogicalValues values = (LogicalValues) rel;
+ @Override public void onMatch(RelOptRuleCall call) {
+ IgniteProject rel = call.rel(0);
+ RelNode input = call.rel(1);
- RelTraitSet traits = values.getTraitSet()
- .replace(IgniteConvention.INSTANCE)
- .replace(IgniteMdDistribution.values(values.getRowType(), values.getTuples()));
+ RelOptCluster cluster = rel.getCluster();
+ RelMetadataQuery mq = cluster.getMetadataQuery();
- final IgniteValues newRel = new IgniteValues(values.getCluster(), values.getRowType(), values.getTuples(), traits);
+ RelTraitSet traits = rel.getTraitSet()
+ .replace(IgniteMdDistribution.project(mq, input, rel.getProjects()));
- return Collections.singletonList(newRel);
+ RuleUtils.transformTo(call,
+ new IgniteProject(cluster, traits, input, rel.getProjects(), rel.getRowType()));
}
}
diff --git a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rule/RuleUtils.java b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rule/RuleUtils.java
new file mode 100644
index 0000000..9bba103
--- /dev/null
+++ b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rule/RuleUtils.java
@@ -0,0 +1,196 @@
+/*
+ * 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 org.apache.ignite.internal.processors.query.calcite.rule;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import java.util.List;
+import java.util.Map;
+import org.apache.calcite.plan.RelOptPlanner;
+import org.apache.calcite.plan.RelOptRuleCall;
+import org.apache.calcite.plan.RelTrait;
+import org.apache.calcite.plan.RelTraitDef;
+import org.apache.calcite.plan.RelTraitSet;
+import org.apache.calcite.plan.hep.HepRelVertex;
+import org.apache.calcite.plan.volcano.RelSubset;
+import org.apache.calcite.plan.volcano.VolcanoPlanner;
+import org.apache.calcite.rel.RelNode;
+import org.apache.ignite.internal.processors.query.calcite.util.Commons;
+import org.apache.ignite.internal.util.typedef.F;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ *
+ */
+public class RuleUtils {
+ /** */
+ public static RelNode convert(RelNode rel, @NotNull RelTrait toTrait) {
+ RelTraitSet toTraits = rel.getTraitSet().replace(toTrait);
+
+ if (rel.getTraitSet().matches(toTraits))
+ return rel;
+
+ RelOptPlanner planner = rel.getCluster().getPlanner();
+
+ return planner.changeTraits(rel, toTraits.simplify());
+ }
+
+ /** */
+ public static RelNode convert(RelNode rel, @NotNull RelTraitSet toTraits) {
+ RelTraitSet outTraits = rel.getTraitSet();
+ for (int i = 0; i < toTraits.size(); i++) {
+ RelTrait toTrait = toTraits.getTrait(i);
+
+ if (toTrait != null)
+ outTraits = outTraits.replace(i, toTrait);
+ }
+
+ if (rel.getTraitSet().matches(outTraits))
+ return rel;
+
+ RelOptPlanner planner = rel.getCluster().getPlanner();
+
+ return planner.changeTraits(rel, outTraits);
+ }
+
+ /** */
+ public static void transformTo(RelOptRuleCall call, RelNode newRel) {
+ transformTo(call, ImmutableList.of(newRel));
+ }
+
+ /** */
+ public static void transformTo(RelOptRuleCall call, List<RelNode> newRels) {
+ transformTo(call, newRels, ImmutableMap.of());
+ }
+
+ /** */
+ public static void transformTo(RelOptRuleCall call, List<RelNode> newRels, Map<RelNode, RelNode> additional) {
+ RelNode orig = call.rel(0);
+
+ if (F.isEmpty(newRels)) {
+ if (!F.isEmpty(additional))
+ // small trick to register the additional equivalence map entries only, we pass
+ // the original rel as transformed one, which will be skipped by the planner.
+ call.transformTo(orig, additional);
+
+ return;
+ }
+
+ if (isRoot(orig))
+ newRels = Commons.transform(newRels, RuleUtils::changeToRootTraits);
+
+ RelNode first = F.first(newRels);
+ List<RelNode> remaining = newRels.subList(1, newRels.size());
+ Map<RelNode, RelNode> equivMap = equivMap(orig, remaining, additional);
+
+ call.transformTo(first, equivMap);
+ }
+
+ /** */
+ public static RelNode changeTraits(RelNode rel, RelTrait... diff) {
+ RelTraitSet traits = rel.getTraitSet();
+
+ for (RelTrait trait : diff)
+ traits = traits.replace(trait);
+
+ return changeTraits(rel, traits);
+ }
+
+ /** */
+ @SuppressWarnings({"rawtypes", "unchecked"})
+ public static RelNode changeTraits(RelNode rel, RelTraitSet toTraits) {
+ RelTraitSet fromTraits = rel.getTraitSet();
+
+ if (fromTraits.satisfies(toTraits))
+ return rel;
+
+ assert fromTraits.size() >= toTraits.size();
+
+ RelOptPlanner planner = rel.getCluster().getPlanner();
+
+ RelNode converted = rel;
+
+ for (int i = 0; (converted != null) && (i < toTraits.size()); i++) {
+ RelTrait fromTrait = converted.getTraitSet().getTrait(i);
+ RelTrait toTrait = toTraits.getTrait(i);
+
+ RelTraitDef traitDef = fromTrait.getTraitDef();
+
+ if (toTrait == null)
+ continue;
+
+ assert traitDef == toTrait.getTraitDef();
+
+ if (fromTrait.equals(toTrait))
+ continue;
+
+ rel = traitDef.convert(planner, converted, toTrait, true);
+
+ assert rel == null || rel.getTraitSet().getTrait(traitDef).satisfies(toTrait);
+
+ if (rel != null)
+ planner.register(rel, converted);
+
+ converted = rel;
+ }
+
+ assert converted == null || converted.getTraitSet().satisfies(toTraits);
+
+ return converted;
+ }
+
+ /** */
+ private static boolean isRoot(RelNode rel) {
+ RelOptPlanner planner = rel.getCluster().getPlanner();
+ RelNode root = planner.getRoot();
+
+ if (root instanceof RelSubset)
+ return ((VolcanoPlanner) planner).getSubset(rel, root.getTraitSet()) == root;
+
+ if (root instanceof HepRelVertex)
+ return root == rel || ((HepRelVertex) root).getCurrentRel() == rel;
+
+ return root == rel;
+ }
+
+ /** */
+ private static RelNode changeToRootTraits(RelNode rel) {
+ RelTraitSet rootTraits = rel.getCluster().getPlanner().getRoot().getTraitSet();
+
+ return changeTraits(rel, rootTraits);
+ }
+
+ /** */
+ private static @NotNull Map<RelNode, RelNode> equivMap(RelNode orig, List<RelNode> equivList, Map<RelNode, RelNode> additional) {
+ assert orig != null;
+ assert equivList != null;
+ assert additional != null;
+
+ if(F.isEmpty(equivList))
+ return additional;
+
+ ImmutableMap.Builder<RelNode, RelNode> b = ImmutableMap.builder();
+
+ for (RelNode equiv : equivList)
+ b.put(equiv, orig);
+
+ b.putAll(additional);
+
+ return b.build();
+ }
+}
diff --git a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rule/TableModifyConverter.java b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rule/TableModifyConverterRule.java
similarity index 61%
rename from modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rule/TableModifyConverter.java
rename to modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rule/TableModifyConverterRule.java
index 0088d64..dded683 100644
--- a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rule/TableModifyConverter.java
+++ b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rule/TableModifyConverterRule.java
@@ -17,46 +17,45 @@
package org.apache.ignite.internal.processors.query.calcite.rule;
-import java.util.Collections;
-import java.util.List;
import org.apache.calcite.plan.RelOptCluster;
+import org.apache.calcite.plan.RelOptRule;
+import org.apache.calcite.plan.RelOptRuleCall;
import org.apache.calcite.plan.RelTraitSet;
import org.apache.calcite.rel.RelNode;
-import org.apache.calcite.rel.convert.ConverterRule;
import org.apache.calcite.rel.logical.LogicalTableModify;
import org.apache.ignite.internal.processors.query.calcite.rel.IgniteConvention;
import org.apache.ignite.internal.processors.query.calcite.rel.IgniteTableModify;
import org.apache.ignite.internal.processors.query.calcite.trait.IgniteDistributions;
-import org.jetbrains.annotations.NotNull;
/**
*
*/
-public class TableModifyConverter extends IgniteConverter{
+public class TableModifyConverterRule extends RelOptRule {
/** */
- public static final ConverterRule INSTANCE = new TableModifyConverter();
+ public static final RelOptRule INSTANCE = new TableModifyConverterRule();
/**
* Creates a ConverterRule.
*/
- public TableModifyConverter() {
- super(LogicalTableModify.class, "TableModifyConverter");
+ public TableModifyConverterRule() {
+ super(operand(LogicalTableModify.class, any()));
}
- /** {@inheritDoc} */
- @Override protected List<RelNode> convert0(@NotNull RelNode rel) {
- LogicalTableModify modify = (LogicalTableModify) rel;
-
- RelTraitSet traits = rel.getTraitSet()
- .replace(IgniteConvention.INSTANCE)
- .replace(IgniteDistributions.single());
+ @Override public void onMatch(RelOptRuleCall call) {
+ LogicalTableModify rel = call.rel(0);
RelOptCluster cluster = rel.getCluster();
- RelNode input = convert(modify.getInput(), traits);
- IgniteTableModify newRel = new IgniteTableModify(cluster, traits, modify.getTable(), modify.getCatalogReader(), input,
- modify.getOperation(), modify.getUpdateColumnList(), modify.getSourceExpressionList(), modify.isFlattened());
+ RelNode input = convert(rel.getInput(), IgniteConvention.INSTANCE);
+
+ input = RuleUtils.changeTraits(input, IgniteDistributions.single());
+
+ RelTraitSet traits = rel.getTraitSet()
+ .replace(IgniteConvention.INSTANCE)
+ .replace(IgniteDistributions.single()); // TODO move to IgniteMdDistributions
- return Collections.singletonList(newRel);
+ RuleUtils.transformTo(call,
+ new IgniteTableModify(cluster, traits, rel.getTable(), rel.getCatalogReader(), input,
+ rel.getOperation(), rel.getUpdateColumnList(), rel.getSourceExpressionList(), rel.isFlattened()));
}
}
diff --git a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rule/ValuesConverter.java b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rule/ValuesConverterRule.java
similarity index 60%
rename from modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rule/ValuesConverter.java
rename to modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rule/ValuesConverterRule.java
index 0bfd593..5d59a58 100644
--- a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rule/ValuesConverter.java
+++ b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rule/ValuesConverterRule.java
@@ -17,41 +17,39 @@
package org.apache.ignite.internal.processors.query.calcite.rule;
-import java.util.Collections;
-import java.util.List;
+import org.apache.calcite.plan.RelOptCluster;
+import org.apache.calcite.plan.RelOptRule;
+import org.apache.calcite.plan.RelOptRuleCall;
import org.apache.calcite.plan.RelTraitSet;
-import org.apache.calcite.rel.RelNode;
-import org.apache.calcite.rel.convert.ConverterRule;
import org.apache.calcite.rel.logical.LogicalValues;
import org.apache.ignite.internal.processors.query.calcite.metadata.IgniteMdDistribution;
import org.apache.ignite.internal.processors.query.calcite.rel.IgniteConvention;
import org.apache.ignite.internal.processors.query.calcite.rel.IgniteValues;
-import org.jetbrains.annotations.NotNull;
/**
*
*/
-public class ValuesConverter extends IgniteConverter {
+public class ValuesConverterRule extends RelOptRule {
/** */
- public static final ConverterRule INSTANCE = new ValuesConverter();
+ public static final RelOptRule INSTANCE = new ValuesConverterRule();
/**
* Creates a ConverterRule.
*/
- protected ValuesConverter() {
- super(LogicalValues.class, "ValuesConverter");
+ protected ValuesConverterRule() {
+ super(operand(LogicalValues.class, none()));
}
- /** {@inheritDoc} */
- @Override protected List<RelNode> convert0(@NotNull RelNode rel) {
- LogicalValues values = (LogicalValues) rel;
+ @Override public void onMatch(RelOptRuleCall call) {
+ LogicalValues rel = call.rel(0);
- RelTraitSet traits = values.getTraitSet()
- .replace(IgniteConvention.INSTANCE)
- .replace(IgniteMdDistribution.values(values.getRowType(), values.getTuples()));
+ RelOptCluster cluster = rel.getCluster();
- final IgniteValues newRel = new IgniteValues(values.getCluster(), values.getRowType(), values.getTuples(), traits);
+ RelTraitSet traits = rel.getTraitSet()
+ .replace(IgniteConvention.INSTANCE)
+ .replace(IgniteMdDistribution.values(rel.getRowType(), rel.getTuples()));
- return Collections.singletonList(newRel);
+ RuleUtils.transformTo(call,
+ new IgniteValues(cluster, rel.getRowType(), rel.getTuples(), traits));
}
}
diff --git a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/serialize/RelToPhysicalConverter.java b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/serialize/RelToPhysicalConverter.java
index 04a32af..a5effbf 100644
--- a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/serialize/RelToPhysicalConverter.java
+++ b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/serialize/RelToPhysicalConverter.java
@@ -66,8 +66,8 @@ public class RelToPhysicalConverter implements IgniteRelVisitor<PhysicalRel> {
@Override public PhysicalRel visit(IgniteSender rel) {
long fragmentId = rel.target().fragmentId();
NodesMapping mapping = rel.target().mapping();
- DistributionFunction fun = rel.targetDistribution().function();
- ImmutableIntList keys = rel.targetDistribution().getKeys();
+ DistributionFunction fun = rel.distribution().function();
+ ImmutableIntList keys = rel.distribution().getKeys();
return new SenderPhysicalRel(fragmentId, mapping, fun, keys, visit((IgniteRel) rel.getInput()));
}
diff --git a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/trait/DistributionTraitDef.java b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/trait/DistributionTraitDef.java
index b97794b..f94c0d9 100644
--- a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/trait/DistributionTraitDef.java
+++ b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/trait/DistributionTraitDef.java
@@ -20,9 +20,10 @@ package org.apache.ignite.internal.processors.query.calcite.trait;
import org.apache.calcite.plan.Convention;
import org.apache.calcite.plan.RelOptPlanner;
import org.apache.calcite.plan.RelTraitDef;
-import org.apache.calcite.rel.RelDistribution;
+import org.apache.calcite.plan.RelTraitSet;
import org.apache.calcite.rel.RelNode;
import org.apache.ignite.internal.processors.query.calcite.rel.IgniteExchange;
+import org.apache.ignite.internal.processors.query.calcite.rule.RuleUtils;
/**
*
@@ -42,26 +43,23 @@ public class DistributionTraitDef extends RelTraitDef<IgniteDistribution> {
}
/** {@inheritDoc} */
- @Override public RelNode convert(RelOptPlanner planner, RelNode rel, IgniteDistribution targetDist, boolean allowInfiniteCostConverters) {
+ @Override public RelNode convert(RelOptPlanner planner, RelNode rel, IgniteDistribution toDist, boolean allowInfiniteCostConverters) {
if (rel.getConvention() == Convention.NONE)
return null;
- RelDistribution srcDist = rel.getTraitSet().getTrait(INSTANCE);
+ IgniteDistribution fromDist = rel.getTraitSet().getTrait(INSTANCE);
- if (srcDist == targetDist) // has to be interned
+ if (fromDist.satisfies(toDist))
return rel;
- switch(targetDist.getType()){
- case HASH_DISTRIBUTED:
- case BROADCAST_DISTRIBUTED:
- case SINGLETON:
- return register(planner, rel,
- new IgniteExchange(rel.getCluster(), rel.getTraitSet().replace(targetDist), rel, targetDist));
- case ANY:
- return rel;
- default:
- return null;
- }
+ RelTraitSet newTraits = rel.getTraitSet().replace(toDist);
+ RelNode input = RuleUtils.convert(rel, IgniteDistributions.any()); // erasing source distribution a bit reduces search space
+ RelNode newRel = planner.register(new IgniteExchange(rel.getCluster(), newTraits, input, toDist), rel);
+
+ if (!newRel.getTraitSet().equals(newTraits))
+ newRel = planner.changeTraits(newRel, newTraits);
+
+ return newRel;
}
/** {@inheritDoc} */
@@ -73,14 +71,4 @@ public class DistributionTraitDef extends RelTraitDef<IgniteDistribution> {
@Override public IgniteDistribution getDefault() {
return IgniteDistributions.any();
}
-
- /** */
- private RelNode register(RelOptPlanner planner, RelNode rel, RelNode replace) {
- RelNode registered = planner.register(replace, rel);
-
- if (!registered.getTraitSet().equals(replace.getTraitSet()))
- registered = planner.changeTraits(registered, replace.getTraitSet());
-
- return registered;
- }
}
diff --git a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/trait/IgniteDistributions.java b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/trait/IgniteDistributions.java
index 4fe2777..2385a19 100644
--- a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/trait/IgniteDistributions.java
+++ b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/trait/IgniteDistributions.java
@@ -18,21 +18,28 @@
package org.apache.ignite.internal.processors.query.calcite.trait;
import java.util.ArrayList;
-import java.util.Collections;
import java.util.HashSet;
+import java.util.LinkedHashMap;
import java.util.List;
+import java.util.Map;
import java.util.Objects;
import org.apache.calcite.plan.RelTraitDef;
+import org.apache.calcite.rel.RelDistribution;
+import org.apache.calcite.rel.RelNode;
import org.apache.calcite.rel.core.JoinInfo;
import org.apache.calcite.rel.core.JoinRelType;
+import org.apache.calcite.rel.metadata.RelMetadataQuery;
import org.apache.calcite.util.ImmutableIntList;
import org.apache.calcite.util.mapping.Mappings;
+import org.apache.ignite.IgniteSystemProperties;
+import org.apache.ignite.internal.processors.query.calcite.metadata.IgniteMdDerivedDistribution;
import org.apache.ignite.internal.processors.query.calcite.trait.DistributionFunction.AffinityDistribution;
import org.apache.ignite.internal.processors.query.calcite.trait.DistributionFunction.AnyDistribution;
import org.apache.ignite.internal.processors.query.calcite.trait.DistributionFunction.BroadcastDistribution;
import org.apache.ignite.internal.processors.query.calcite.trait.DistributionFunction.HashDistribution;
import org.apache.ignite.internal.processors.query.calcite.trait.DistributionFunction.RandomDistribution;
import org.apache.ignite.internal.processors.query.calcite.trait.DistributionFunction.SingletonDistribution;
+import org.apache.ignite.internal.processors.query.calcite.util.Commons;
import org.apache.ignite.internal.util.typedef.F;
import org.apache.ignite.internal.util.typedef.internal.CU;
import org.apache.ignite.internal.util.typedef.internal.U;
@@ -47,63 +54,59 @@ import static org.apache.calcite.rel.core.JoinRelType.RIGHT;
*/
public class IgniteDistributions {
/** */
- private static final int BEST_CNT = 3;
+ private static final int BEST_CNT = IgniteSystemProperties.getInteger("IGNITE_CALCITE_JOIN_SUGGESTS_COUNT", 0);
/** */
- private static final IgniteDistribution BROADCAST = new DistributionTrait(BroadcastDistribution.INSTANCE);
+ private static final Integer[] INTS = new Integer[]{0, 1, 2};
/** */
- private static final IgniteDistribution SINGLETON = new DistributionTrait(SingletonDistribution.INSTANCE);
+ private static final IgniteDistribution BROADCAST = canonize(new DistributionTrait(BroadcastDistribution.INSTANCE));
/** */
- private static final IgniteDistribution RANDOM = new DistributionTrait(RandomDistribution.INSTANCE);
+ private static final IgniteDistribution SINGLETON = canonize(new DistributionTrait(SingletonDistribution.INSTANCE));
/** */
- private static final IgniteDistribution ANY = new DistributionTrait(AnyDistribution.INSTANCE);
+ private static final IgniteDistribution RANDOM = canonize(new DistributionTrait(RandomDistribution.INSTANCE));
+
+ /** */
+ private static final IgniteDistribution ANY = canonize(new DistributionTrait(AnyDistribution.INSTANCE));
/**
* @return Any distribution.
*/
public static IgniteDistribution any() {
- return canonize(ANY);
+ return ANY;
}
/**
* @return Random distribution.
*/
public static IgniteDistribution random() {
- return canonize(RANDOM);
+ return RANDOM;
}
/**
* @return Single distribution.
*/
public static IgniteDistribution single() {
- return canonize(SINGLETON);
+ return SINGLETON;
}
/**
* @return Broadcast distribution.
*/
public static IgniteDistribution broadcast() {
- return canonize(BROADCAST);
- }
-
- /**
- * @param keys Distribution keys.
- * @return Hash distribution.
- */
- public static IgniteDistribution hash(List<Integer> keys) {
- return canonize(new DistributionTrait(ImmutableIntList.copyOf(keys), HashDistribution.INSTANCE));
+ return BROADCAST;
}
/**
- * @param keys Distribution keys.
- * @param function Specific hash function.
- * @return Hash distribution.
+ * @param key Affinity key.
+ * @param cacheName Affinity cache name.
+ * @param identity Affinity identity key.
+ * @return Affinity distribution.
*/
- public static IgniteDistribution hash(List<Integer> keys, DistributionFunction function) {
- return canonize(new DistributionTrait(ImmutableIntList.copyOf(keys), function));
+ public static IgniteDistribution affinity(int key, String cacheName, Object identity) {
+ return affinity(key, CU.cacheId(cacheName), identity);
}
/**
@@ -113,65 +116,62 @@ public class IgniteDistributions {
* @return Affinity distribution.
*/
public static IgniteDistribution affinity(int key, int cacheId, Object identity) {
- return canonize(new DistributionTrait(ImmutableIntList.of(key), new AffinityDistribution(cacheId, identity)));
+ return hash(ImmutableIntList.of(key), new AffinityDistribution(cacheId, identity));
}
/**
- * @param key Affinity key.
- * @param cacheName Affinity cache name.
- * @param identity Affinity identity key.
- * @return Affinity distribution.
+ * @param keys Distribution keys.
+ * @return Hash distribution.
*/
- public static IgniteDistribution affinity(int key, String cacheName, Object identity) {
- return affinity(key, CU.cacheId(cacheName), identity);
+ public static IgniteDistribution hash(List<Integer> keys) {
+ return canonize(new DistributionTrait(ImmutableIntList.copyOf(keys), HashDistribution.INSTANCE));
}
/**
- * See {@link RelTraitDef#canonize(org.apache.calcite.plan.RelTrait)}.
+ * @param keys Distribution keys.
+ * @param function Specific hash function.
+ * @return Hash distribution.
*/
- public static IgniteDistribution canonize(IgniteDistribution distr) {
- return DistributionTraitDef.INSTANCE.canonize(distr);
+ public static IgniteDistribution hash(List<Integer> keys, DistributionFunction function) {
+ return canonize(new DistributionTrait(ImmutableIntList.copyOf(keys), function));
}
/**
* Suggests possible join distributions.
*
- * @param leftIn Left distribution.
- * @param rightIn Right distribution.
+ * @param left Left node.
+ * @param right Right node.
* @param joinInfo Join info.
* @param joinType Join type.
* @return Array of possible distributions, sorted by their efficiency (cheaper first).
*/
- public static List<BiSuggestion> suggestJoin(IgniteDistribution leftIn, IgniteDistribution rightIn,
- JoinInfo joinInfo, JoinRelType joinType) {
- return topN(suggestJoin0(leftIn, rightIn, joinInfo, joinType), BEST_CNT);
+ public static List<BiSuggestion> suggestJoin(RelNode left, RelNode right, JoinInfo joinInfo, JoinRelType joinType) {
+ RelMetadataQuery mq = left.getCluster().getMetadataQuery();
+
+ List<IgniteDistribution> leftIn = IgniteMdDerivedDistribution._deriveDistributions(left, mq);
+ List<IgniteDistribution> rightIn = IgniteMdDerivedDistribution._deriveDistributions(right, mq);
+
+ Map<BiSuggestion, Integer> suggestions = new LinkedHashMap<>();
+
+ for (IgniteDistribution leftIn0 : leftIn)
+ for (IgniteDistribution rightIn0 : rightIn)
+ suggestions = suggestJoin0(suggestions, leftIn0, rightIn0, joinInfo, joinType);
+
+ return sorted(suggestions);
}
/**
* Suggests possible join distributions.
*
- * @param leftIn Left distributions.
- * @param rightIn Right distributions.
+ * @param leftIn Left distribution.
+ * @param rightIn Right distribution.
* @param joinInfo Join info.
* @param joinType Join type.
* @return Array of possible distributions, sorted by their efficiency (cheaper first).
*/
- public static List<BiSuggestion> suggestJoin(List<IgniteDistribution> leftIn, List<IgniteDistribution> rightIn,
+ public static List<BiSuggestion> suggestJoin(IgniteDistribution leftIn, IgniteDistribution rightIn,
JoinInfo joinInfo, JoinRelType joinType) {
- HashSet<BiSuggestion> suggestions = new HashSet<>();
-
- int bestCnt = 0;
-
- for (IgniteDistribution leftIn0 : leftIn) {
- for (IgniteDistribution rightIn0 : rightIn) {
- for (BiSuggestion suggest : suggestJoin0(leftIn0, rightIn0, joinInfo, joinType)) {
- if (suggestions.add(suggest) && suggest.needExchange == 0 && (++bestCnt) == BEST_CNT)
- return topN(new ArrayList<>(suggestions), BEST_CNT);
- }
- }
- }
-
- return topN(new ArrayList<>(suggestions), BEST_CNT);
+ return sorted(suggestJoin0(new LinkedHashMap<>(), leftIn, rightIn, joinInfo, joinType));
}
/**
@@ -207,22 +207,20 @@ public class IgniteDistributions {
* @param rightIn Right distribution.
* @param joinInfo Join info.
* @param joinType Join type.
- * @return Array of possible distributions, sorted by their efficiency (cheaper first).
*/
- private static ArrayList<BiSuggestion> suggestJoin0(IgniteDistribution leftIn, IgniteDistribution rightIn,
+ private static Map<BiSuggestion, Integer> suggestJoin0(Map<BiSuggestion, Integer> dst, IgniteDistribution leftIn, IgniteDistribution rightIn,
JoinInfo joinInfo, JoinRelType joinType) {
-
- ArrayList<BiSuggestion> res = new ArrayList<>();
-
IgniteDistribution out, left, right;
if (joinType == LEFT || joinType == RIGHT || (joinType == INNER && !F.isEmpty(joinInfo.pairs()))) {
HashSet<DistributionFunction> factories = U.newHashSet(3);
- if (Objects.equals(joinInfo.leftKeys, leftIn.getKeys()))
+ if (leftIn.getType() == RelDistribution.Type.HASH_DISTRIBUTED
+ && Objects.equals(joinInfo.leftKeys, leftIn.getKeys()))
factories.add(leftIn.function());
- if (Objects.equals(joinInfo.rightKeys, rightIn.getKeys()))
+ if (rightIn.getType() == RelDistribution.Type.HASH_DISTRIBUTED
+ && Objects.equals(joinInfo.rightKeys, rightIn.getKeys()))
factories.add(rightIn.function());
factories.add(HashDistribution.INSTANCE);
@@ -231,56 +229,76 @@ public class IgniteDistributions {
out = hash(joinInfo.leftKeys, factory);
left = hash(joinInfo.leftKeys, factory); right = hash(joinInfo.rightKeys, factory);
- add(res, out, leftIn, rightIn, left, right);
+ dst = add(dst, out, leftIn, rightIn, left, right);
if (joinType == INNER || joinType == LEFT) {
left = hash(joinInfo.leftKeys, factory); right = broadcast();
- add(res, out, leftIn, rightIn, left, right);
+ dst = add(dst, out, leftIn, rightIn, left, right);
}
if (joinType == INNER || joinType == RIGHT) {
left = broadcast(); right = hash(joinInfo.rightKeys, factory);
- add(res, out, leftIn, rightIn, left, right);
+ dst = add(dst, out, leftIn, rightIn, left, right);
}
}
}
out = left = right = broadcast();
- add(res, out, leftIn, rightIn, left, right);
+ dst = add(dst, out, leftIn, rightIn, left, right);
out = left = right = single();
- add(res, out, leftIn, rightIn, left, right);
+ dst = add(dst, out, leftIn, rightIn, left, right);
- return res;
+ return dst;
}
/** */
- private static int add(ArrayList<BiSuggestion> dst, IgniteDistribution out, IgniteDistribution left, IgniteDistribution right,
+ private static Map<BiSuggestion, Integer> add(Map<BiSuggestion, Integer> dst, IgniteDistribution out, IgniteDistribution left, IgniteDistribution right,
IgniteDistribution newLeft, IgniteDistribution newRight) {
- int exch = 0;
+ if (BEST_CNT > 0) {
+ int exch = 0;
- if (needsExchange(left, newLeft))
- exch++;
+ if (!left.satisfies(newLeft))
+ exch++;
- if (needsExchange(right, newRight))
- exch++;
+ if (!right.satisfies(newRight))
+ exch++;
- dst.add(new BiSuggestion(out, newLeft, newRight, exch));
-
- return exch;
+ return add(dst, new BiSuggestion(out, newLeft, newRight), INTS[exch]);
+ }
+ else
+ return add(dst, new BiSuggestion(out, newLeft, newRight), INTS[0]);
}
/** */
- private static boolean needsExchange(IgniteDistribution sourceDist, IgniteDistribution targetDist) {
- return !sourceDist.satisfies(targetDist);
+ private static Map<BiSuggestion, Integer> add(Map<BiSuggestion, Integer> dst, BiSuggestion suggest, Integer exchCnt) {
+ if (dst == null)
+ dst = new LinkedHashMap<>();
+
+ dst.merge(suggest, exchCnt, IgniteDistributions::min);
+
+ return dst;
}
/** */
- @SuppressWarnings("SameParameterValue")
- private static List<BiSuggestion> topN(ArrayList<BiSuggestion> src, int n) {
- Collections.sort(src);
+ private static List<BiSuggestion> sorted(Map<BiSuggestion, Integer> src) {
+ if (BEST_CNT > 0) {
+ List<Map.Entry<BiSuggestion, Integer>> entries = new ArrayList<>(src.entrySet());
+
+ entries.sort(Map.Entry.comparingByValue());
+
+ if (entries.size() >= BEST_CNT)
+ entries = entries.subList(0, BEST_CNT);
+
+ return Commons.transform(entries, Map.Entry::getKey);
+ }
- return src.size() <= n ? src : src.subList(0, n);
+ return new ArrayList<>(src.keySet());
+ }
+
+ /** */
+ private static @NotNull Integer min(@NotNull Integer i1, @NotNull Integer i2) {
+ return i1 < i2 ? i1 : i2;
}
/**
@@ -319,9 +337,16 @@ public class IgniteDistributions {
}
/**
+ * See {@link RelTraitDef#canonize(org.apache.calcite.plan.RelTrait)}.
+ */
+ private static IgniteDistribution canonize(IgniteDistribution distr) {
+ return DistributionTraitDef.INSTANCE.canonize(distr);
+ }
+
+ /**
* Distribution suggestion for BiRel.
*/
- public static class BiSuggestion implements Comparable<BiSuggestion> {
+ public static class BiSuggestion {
/** */
private final IgniteDistribution out;
@@ -331,20 +356,15 @@ public class IgniteDistributions {
/** */
private final IgniteDistribution right;
- /** */
- private final int needExchange;
-
/**
* @param out Result distribution.
* @param left Required left distribution.
* @param right Required right distribution.
- * @param needExchange Exchanges count (for ordering).
*/
- public BiSuggestion(IgniteDistribution out, IgniteDistribution left, IgniteDistribution right, int needExchange) {
+ public BiSuggestion(IgniteDistribution out, IgniteDistribution left, IgniteDistribution right) {
this.out = out;
this.left = left;
this.right = right;
- this.needExchange = needExchange;
}
/**
@@ -369,19 +389,13 @@ public class IgniteDistributions {
}
/** {@inheritDoc} */
- @Override public int compareTo(@NotNull IgniteDistributions.BiSuggestion o) {
- return Integer.compare(needExchange, o.needExchange);
- }
-
- /** {@inheritDoc} */
@Override public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
BiSuggestion that = (BiSuggestion) o;
- return needExchange == that.needExchange
- && out == that.out
+ return out == that.out
&& left == that.left
&& right == that.right;
}
@@ -391,7 +405,6 @@ public class IgniteDistributions {
int result = out.hashCode();
result = 31 * result + left.hashCode();
result = 31 * result + right.hashCode();
- result = 31 * result + needExchange;
return result;
}
}
diff --git a/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/PlannerTest.java b/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/PlannerTest.java
index 62ce15a..25bbe86 100644
--- a/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/PlannerTest.java
+++ b/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/PlannerTest.java
@@ -90,6 +90,7 @@ import org.jetbrains.annotations.Nullable;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
+import org.junit.Ignore;
import org.junit.Test;
import static org.apache.calcite.tools.Frameworks.createRootSchema;
@@ -589,6 +590,7 @@ public class PlannerTest extends GridCommonAbstractTest {
* @throws Exception If failed.
*/
@Test
+ @Ignore("https://issues.apache.org/jira/browse/IGNITE-12819")
public void testSplitterCollocatedPartitionedPartitioned() throws Exception {
IgniteTypeFactory f = new IgniteTypeFactory(IgniteTypeSystem.INSTANCE);