Search in sources :

Example 6 with IgniteDistribution

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);
}
Also used : IgniteSortedIndexSpool(org.apache.ignite.internal.sql.engine.rel.IgniteSortedIndexSpool) IgniteTypeFactory(org.apache.ignite.internal.sql.engine.type.IgniteTypeFactory) IgniteRel(org.apache.ignite.internal.sql.engine.rel.IgniteRel) IgniteDistribution(org.apache.ignite.internal.sql.engine.trait.IgniteDistribution) RelDataTypeFactory(org.apache.calcite.rel.type.RelDataTypeFactory) IgniteSchema(org.apache.ignite.internal.sql.engine.schema.IgniteSchema) RexFieldAccess(org.apache.calcite.rex.RexFieldAccess) RexNode(org.apache.calcite.rex.RexNode) Test(org.junit.jupiter.api.Test)

Example 7 with IgniteDistribution

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;
}
Also used : FilterNode(org.apache.ignite.internal.sql.engine.exec.rel.FilterNode) IgniteDistribution(org.apache.ignite.internal.sql.engine.trait.IgniteDistribution)

Example 8 with IgniteDistribution

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())));
}
Also used : Mappings(org.apache.calcite.util.mapping.Mappings) ImmutableIntList(org.apache.calcite.util.ImmutableIntList) RelTraitSet(org.apache.calcite.plan.RelTraitSet) IgniteDistribution(org.apache.ignite.internal.sql.engine.trait.IgniteDistribution) IntArrayList(it.unimi.dsi.fastutil.ints.IntArrayList)

Example 9 with IgniteDistribution

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);
}
Also used : ArrayList(java.util.ArrayList) RelTraitSet(org.apache.calcite.plan.RelTraitSet) IgniteDistribution(org.apache.ignite.internal.sql.engine.trait.IgniteDistribution) Pair(org.apache.calcite.util.Pair)

Example 10 with IgniteDistribution

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);
}
Also used : ArrayList(java.util.ArrayList) RelTraitSet(org.apache.calcite.plan.RelTraitSet) IgniteDistribution(org.apache.ignite.internal.sql.engine.trait.IgniteDistribution) Pair(org.apache.calcite.util.Pair)

Aggregations

IgniteDistribution (org.apache.ignite.internal.sql.engine.trait.IgniteDistribution)15 IgniteSchema (org.apache.ignite.internal.sql.engine.schema.IgniteSchema)8 IgniteTypeFactory (org.apache.ignite.internal.sql.engine.type.IgniteTypeFactory)8 Test (org.junit.jupiter.api.Test)8 IgniteRel (org.apache.ignite.internal.sql.engine.rel.IgniteRel)7 RelTraitSet (org.apache.calcite.plan.RelTraitSet)5 RelDataTypeFactory (org.apache.calcite.rel.type.RelDataTypeFactory)5 RexNode (org.apache.calcite.rex.RexNode)5 RexFieldAccess (org.apache.calcite.rex.RexFieldAccess)4 ArrayList (java.util.ArrayList)3 ImmutableIntList (org.apache.calcite.util.ImmutableIntList)3 Pair (org.apache.calcite.util.Pair)3 RelCollations (org.apache.calcite.rel.RelCollations)2 RelFieldCollation (org.apache.calcite.rel.RelFieldCollation)2 Mappings (org.apache.calcite.util.mapping.Mappings)2 IgniteHashIndexSpool (org.apache.ignite.internal.sql.engine.rel.IgniteHashIndexSpool)2 IgniteIndexScan (org.apache.ignite.internal.sql.engine.rel.IgniteIndexScan)2 IntArrayList (it.unimi.dsi.fastutil.ints.IntArrayList)1 Arrays (java.util.Arrays)1 HashMap (java.util.HashMap)1