use of org.apache.ignite.internal.sql.engine.trait.IgniteDistribution in project ignite-3 by apache.
the class AbstractIgniteJoin method passThroughDistribution.
/**
* {@inheritDoc}
*/
@Override
public Pair<RelTraitSet, List<RelTraitSet>> passThroughDistribution(RelTraitSet nodeTraits, List<RelTraitSet> inputTraits) {
// Tere are several rules:
// 1) any join is possible on broadcast or single distribution
// 2) hash distributed join is possible when join keys equal to 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);
IgniteDistribution distribution = TraitUtils.distribution(nodeTraits);
RelDistribution.Type distrType = distribution.getType();
switch(distrType) {
case BROADCAST_DISTRIBUTED:
case SINGLETON:
return Pair.of(nodeTraits, Commons.transform(inputTraits, t -> t.replace(distribution)));
case HASH_DISTRIBUTED:
case RANDOM_DISTRIBUTED:
// It's impossible to get random or hash distribution from a cross join.
if (nullOrEmpty(joinInfo.pairs())) {
break;
}
// We cannot provide random distribution without unique constrain on join keys,
// so, we require hash distribution (wich satisfies random distribution) instead.
DistributionFunction function = distrType == HASH_DISTRIBUTED ? distribution.function() : DistributionFunction.hash();
IgniteDistribution outDistr = hash(joinInfo.leftKeys, function);
if (distrType != HASH_DISTRIBUTED || outDistr.satisfies(distribution)) {
return Pair.of(nodeTraits.replace(outDistr), List.of(left.replace(outDistr), right.replace(hash(joinInfo.rightKeys, function))));
}
break;
default:
}
return Pair.of(nodeTraits.replace(single()), Commons.transform(inputTraits, t -> t.replace(single())));
}
use of org.apache.ignite.internal.sql.engine.trait.IgniteDistribution in project ignite-3 by apache.
the class IgniteProject method deriveDistribution.
/**
* {@inheritDoc}
*/
@Override
public List<Pair<RelTraitSet, List<RelTraitSet>>> deriveDistribution(RelTraitSet nodeTraits, List<RelTraitSet> inputTraits) {
RelTraitSet in = inputTraits.get(0);
IgniteDistribution distribution = TraitUtils.projectDistribution(TraitUtils.distribution(in), getProjects(), getInput().getRowType());
return List.of(Pair.of(nodeTraits.replace(distribution), List.of(in)));
}
use of org.apache.ignite.internal.sql.engine.trait.IgniteDistribution in project ignite-3 by apache.
the class HashIndexSpoolPlannerTest method testMultipleKeys.
@Test
public void testMultipleKeys() 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", "FilterSpoolMergeToSortedIndexSpoolRule");
IgniteHashIndexSpool idxSpool = findFirstNode(phys, byClass(IgniteHashIndexSpool.class));
List<RexNode> searcRow = idxSpool.searchRow();
assertNotNull(searcRow);
assertEquals(4, searcRow.size());
assertTrue(((RexLiteral) searcRow.get(0)).isNull());
assertTrue(searcRow.get(1) instanceof RexFieldAccess);
assertTrue(searcRow.get(2) instanceof RexFieldAccess);
assertTrue(((RexLiteral) searcRow.get(3)).isNull());
}
use of org.apache.ignite.internal.sql.engine.trait.IgniteDistribution in project ignite-3 by apache.
the class HashIndexSpoolPlannerTest method testSourceWithoutCollation.
/**
* Check equi-join on not colocated fields without indexes.
*/
@Test
public void testSourceWithoutCollation() 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("JID", 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("JID", f.createJavaType(Integer.class)).add("VAL", f.createJavaType(String.class)).build()) {
@Override
public IgniteDistribution distribution() {
return IgniteDistributions.affinity(0, "T1", "hash");
}
});
String sql = "select * " + "from t0 " + "join t1 on t0.jid = t1.jid";
IgniteRel phys = physicalPlan(sql, publicSchema, "MergeJoinConverter", "NestedLoopJoinConverter");
IgniteHashIndexSpool idxSpool = findFirstNode(phys, byClass(IgniteHashIndexSpool.class));
List<RexNode> searchRow = idxSpool.searchRow();
assertNotNull(searchRow);
assertEquals(3, searchRow.size());
assertTrue(((RexLiteral) searchRow.get(0)).isNull());
assertTrue(((RexLiteral) searchRow.get(2)).isNull());
assertTrue(searchRow.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(IgniteSender rel) {
IgniteDistribution distribution = rel.distribution();
Destination<RowT> dest = distribution.destination(ctx, affSrvc, ctx.target());
// Outbox fragment ID is used as exchange ID as well.
Outbox<RowT> outbox = new Outbox<>(ctx, rel.getRowType(), exchangeSvc, mailboxRegistry, rel.exchangeId(), rel.targetFragmentId(), dest);
Node<RowT> input = visit(rel.getInput());
outbox.register(input);
mailboxRegistry.register(outbox);
return outbox;
}
Aggregations