use of org.apache.ignite.internal.sql.engine.trait.IgniteDistribution in project ignite-3 by apache.
the class SortedIndexSpoolPlannerTest method testPartialIndexForCondition.
/**
* Check case when exists index (collation) isn't applied not for whole join condition but may be used by part of
* condition.
*/
@Test
public void testPartialIndexForCondition() throws Exception {
IgniteSchema publicSchema = new IgniteSchema("PUBLIC");
IgniteTypeFactory f = new IgniteTypeFactory(IgniteTypeSystem.INSTANCE);
publicSchema.addTable("T0", new TestTable(new RelDataTypeFactory.Builder(f).add("ID", f.createJavaType(Integer.class)).add("JID0", f.createJavaType(Integer.class)).add("JID1", f.createJavaType(Integer.class)).add("VAL", f.createJavaType(String.class)).build()) {
@Override
public IgniteDistribution distribution() {
return IgniteDistributions.affinity(0, "T0", "hash");
}
});
publicSchema.addTable("T1", new TestTable(new RelDataTypeFactory.Builder(f).add("ID", f.createJavaType(Integer.class)).add("JID0", f.createJavaType(Integer.class)).add("JID1", f.createJavaType(Integer.class)).add("VAL", f.createJavaType(String.class)).build()) {
@Override
public IgniteDistribution distribution() {
return IgniteDistributions.affinity(0, "T1", "hash");
}
}.addIndex(RelCollations.of(ImmutableIntList.of(1, 0)), "t1_jid0_idx"));
String sql = "select * " + "from t0 " + "join t1 on t0.jid0 = t1.jid0 and t0.jid1 = t1.jid1";
IgniteRel phys = physicalPlan(sql, publicSchema, "MergeJoinConverter", "NestedLoopJoinConverter", "FilterSpoolMergeToHashIndexSpoolRule");
System.out.println("+++ \n" + RelOptUtil.toString(phys));
IgniteSortedIndexSpool idxSpool = findFirstNode(phys, byClass(IgniteSortedIndexSpool.class));
List<RexNode> lowerBound = idxSpool.indexCondition().lowerBound();
assertNotNull(lowerBound);
assertEquals(4, lowerBound.size());
assertTrue(((RexLiteral) lowerBound.get(0)).isNull());
assertTrue(((RexLiteral) lowerBound.get(2)).isNull());
assertTrue(((RexLiteral) lowerBound.get(3)).isNull());
assertTrue(lowerBound.get(1) instanceof RexFieldAccess);
List<RexNode> upperBound = idxSpool.indexCondition().upperBound();
assertNotNull(upperBound);
assertEquals(4, upperBound.size());
assertTrue(((RexLiteral) upperBound.get(0)).isNull());
assertTrue(((RexLiteral) lowerBound.get(2)).isNull());
assertTrue(((RexLiteral) lowerBound.get(3)).isNull());
assertTrue(upperBound.get(1) instanceof RexFieldAccess);
}
use of org.apache.ignite.internal.sql.engine.trait.IgniteDistribution in project ignite-3 by apache.
the class LogicalRelImplementor method visit.
/**
* {@inheritDoc}
*/
@Override
public Node<RowT> visit(IgniteTrimExchange rel) {
assert TraitUtils.distribution(rel).getType() == HASH_DISTRIBUTED;
IgniteDistribution distr = rel.distribution();
Destination<RowT> dest = distr.destination(ctx, affSrvc, ctx.group(rel.sourceId()));
String localNodeId = ctx.localNodeId();
FilterNode<RowT> node = new FilterNode<>(ctx, rel.getRowType(), r -> Objects.equals(localNodeId, first(dest.targets(r))));
Node<RowT> input = visit(rel.getInput());
node.register(input);
return node;
}
use of org.apache.ignite.internal.sql.engine.trait.IgniteDistribution in project ignite-3 by apache.
the class IgniteProject method passThroughDistribution.
/**
* {@inheritDoc}
*/
@Override
public Pair<RelTraitSet, List<RelTraitSet>> passThroughDistribution(RelTraitSet nodeTraits, List<RelTraitSet> inputTraits) {
// All distribution types except hash distribution are propagated as is.
// In case of hash distribution we need to project distribution keys.
// In case one of distribution keys is erased by projection result distribution
// becomes default single since we cannot calculate required input distribution.
RelTraitSet in = inputTraits.get(0);
IgniteDistribution distribution = TraitUtils.distribution(nodeTraits);
if (distribution.getType() != HASH_DISTRIBUTED) {
return Pair.of(nodeTraits, List.of(in.replace(distribution)));
}
Mappings.TargetMapping mapping = getPartialMapping(input.getRowType().getFieldCount(), getProjects());
ImmutableIntList keys = distribution.getKeys();
IntArrayList srcKeys = new IntArrayList(keys.size());
int key;
for (int i = 0; i < keys.size(); i++) {
key = keys.getInt(i);
int src = mapping.getSourceOpt(key);
if (src == -1) {
break;
}
srcKeys.add(src);
}
if (srcKeys.size() == keys.size()) {
return Pair.of(nodeTraits, List.of(in.replace(hash(ImmutableIntList.of(srcKeys.elements()), distribution.function()))));
}
return Pair.of(nodeTraits.replace(single()), List.of(in.replace(single())));
}
use of org.apache.ignite.internal.sql.engine.trait.IgniteDistribution in project ignite-3 by apache.
the class IgniteUnionAll method deriveDistribution.
/**
* {@inheritDoc}
*/
@Override
public List<Pair<RelTraitSet, List<RelTraitSet>>> deriveDistribution(RelTraitSet nodeTraits, List<RelTraitSet> inputTraits) {
// Union node requires the same traits from all its inputs.
Set<IgniteDistribution> distributions = inputTraits.stream().map(TraitUtils::distribution).collect(Collectors.toSet());
List<Pair<RelTraitSet, List<RelTraitSet>>> deriveTraits = new ArrayList<>();
for (IgniteDistribution distribution : distributions) {
deriveTraits.add(Pair.of(nodeTraits.replace(distribution), Commons.transform(inputTraits, t -> t.replace(distribution))));
}
return List.copyOf(deriveTraits);
}
use of org.apache.ignite.internal.sql.engine.trait.IgniteDistribution in project ignite-3 by apache.
the class AbstractIgniteJoin method deriveDistribution.
/**
* {@inheritDoc}
*/
@Override
public List<Pair<RelTraitSet, List<RelTraitSet>>> deriveDistribution(RelTraitSet nodeTraits, List<RelTraitSet> inputTraits) {
// There are several rules:
// 1) any join is possible on broadcast or single distribution
// 2) hash distributed join is possible when join keys are superset of source distribution keys
// 3) hash and broadcast distributed tables can be joined when join keys equal to hash
// distributed table distribution keys and:
// 3.1) it's a left join and a hash distributed table is at left
// 3.2) it's a right join and a hash distributed table is at right
// 3.3) it's an inner join, this case a hash distributed table may be at any side
RelTraitSet left = inputTraits.get(0);
RelTraitSet right = inputTraits.get(1);
List<Pair<RelTraitSet, List<RelTraitSet>>> res = new ArrayList<>();
final IgniteDistribution leftDistr = TraitUtils.distribution(left);
final IgniteDistribution rightDistr = TraitUtils.distribution(right);
final IgniteDistribution left2rightProjectedDistr = leftDistr.apply(buildTransposeMapping(true));
final IgniteDistribution right2leftProjectedDistr = rightDistr.apply(buildTransposeMapping(false));
RelTraitSet outTraits;
RelTraitSet leftTraits;
RelTraitSet rightTraits;
if (leftDistr == broadcast() && rightDistr == broadcast()) {
outTraits = nodeTraits.replace(broadcast());
leftTraits = left.replace(broadcast());
rightTraits = right.replace(broadcast());
} else {
outTraits = nodeTraits.replace(single());
leftTraits = left.replace(single());
rightTraits = right.replace(single());
}
res.add(Pair.of(outTraits, List.of(leftTraits, rightTraits)));
if (nullOrEmpty(joinInfo.pairs())) {
return List.copyOf(res);
}
if (leftDistr.getType() == HASH_DISTRIBUTED && left2rightProjectedDistr != random()) {
outTraits = nodeTraits.replace(leftDistr);
leftTraits = left.replace(leftDistr);
rightTraits = right.replace(left2rightProjectedDistr);
res.add(Pair.of(outTraits, List.of(leftTraits, rightTraits)));
}
if (rightDistr.getType() == HASH_DISTRIBUTED && right2leftProjectedDistr != random()) {
outTraits = nodeTraits.replace(rightDistr);
leftTraits = left.replace(right2leftProjectedDistr);
rightTraits = right.replace(rightDistr);
res.add(Pair.of(outTraits, List.of(leftTraits, rightTraits)));
}
leftTraits = left.replace(hash(joinInfo.leftKeys, DistributionFunction.hash()));
rightTraits = right.replace(hash(joinInfo.rightKeys, DistributionFunction.hash()));
outTraits = nodeTraits.replace(hash(joinInfo.leftKeys, DistributionFunction.hash()));
res.add(Pair.of(outTraits, List.of(leftTraits, rightTraits)));
outTraits = nodeTraits.replace(hash(joinInfo.rightKeys, DistributionFunction.hash()));
res.add(Pair.of(outTraits, List.of(leftTraits, rightTraits)));
return List.copyOf(res);
}
Aggregations