Search in sources :

Example 1 with IgniteExchange

use of org.apache.ignite.internal.sql.engine.rel.IgniteExchange in project ignite-3 by apache.

the class JoinColocationPlannerTest method joinComplexToComplexAffWithDifferentOrder.

/**
 * Re-hashing for complex affinity is not supported.
 */
@Test
public void joinComplexToComplexAffWithDifferentOrder() throws Exception {
    TestTable complexTblDirect = createTable("COMPLEX_TBL_DIRECT", IgniteDistributions.affinity(ImmutableIntList.of(0, 1), ThreadLocalRandom.current().nextInt(), "hash"), "ID1", Integer.class, "ID2", Integer.class, "VAL", String.class);
    complexTblDirect.addIndex(new IgniteIndex(RelCollations.of(ImmutableIntList.of(0, 1)), "PK", complexTblDirect));
    TestTable complexTblIndirect = createTable("COMPLEX_TBL_INDIRECT", IgniteDistributions.affinity(ImmutableIntList.of(1, 0), ThreadLocalRandom.current().nextInt(), "hash"), "ID1", Integer.class, "ID2", Integer.class, "VAL", String.class);
    complexTblIndirect.addIndex(new IgniteIndex(RelCollations.of(ImmutableIntList.of(0, 1)), "PK", complexTblIndirect));
    IgniteSchema schema = createSchema(complexTblDirect, complexTblIndirect);
    String sql = "select count(*) " + "from COMPLEX_TBL_DIRECT t1 " + "join COMPLEX_TBL_INDIRECT t2 on t1.id1 = t2.id1 and t1.id2 = t2.id2";
    RelNode phys = physicalPlan(sql, schema, "NestedLoopJoinConverter", "CorrelatedNestedLoopJoin");
    IgniteMergeJoin exchange = findFirstNode(phys, node -> node instanceof IgniteExchange && ((IgniteRel) node).distribution().function().affinity());
    String invalidPlanMsg = "Invalid plan:\n" + RelOptUtil.toString(phys);
    assertThat(invalidPlanMsg, exchange, nullValue());
}
Also used : IgniteMergeJoin(org.apache.ignite.internal.sql.engine.rel.IgniteMergeJoin) IgniteIndex(org.apache.ignite.internal.sql.engine.schema.IgniteIndex) RelNode(org.apache.calcite.rel.RelNode) IgniteRel(org.apache.ignite.internal.sql.engine.rel.IgniteRel) IgniteSchema(org.apache.ignite.internal.sql.engine.schema.IgniteSchema) IgniteExchange(org.apache.ignite.internal.sql.engine.rel.IgniteExchange) Test(org.junit.jupiter.api.Test)

Example 2 with IgniteExchange

use of org.apache.ignite.internal.sql.engine.rel.IgniteExchange in project ignite-3 by apache.

the class TraitUtils method convertDistribution.

/**
 * Convert distribution. TODO Documentation https://issues.apache.org/jira/browse/IGNITE-15859
 */
@Nullable
public static RelNode convertDistribution(RelOptPlanner planner, IgniteDistribution toTrait, RelNode rel) {
    IgniteDistribution fromTrait = distribution(rel);
    if (fromTrait.satisfies(toTrait)) {
        return rel;
    }
    // key object, thus this conversion is impossible
    if (toTrait.function().affinity() && toTrait.getKeys().size() > 1) {
        return null;
    }
    RelTraitSet traits = rel.getTraitSet().replace(toTrait);
    if (fromTrait.getType() == BROADCAST_DISTRIBUTED && toTrait.getType() == HASH_DISTRIBUTED) {
        return new IgniteTrimExchange(rel.getCluster(), traits, rel, toTrait);
    } else {
        return new IgniteExchange(rel.getCluster(), traits.replace(RewindabilityTrait.ONE_WAY).replace(CorrelationTrait.UNCORRELATED), RelOptRule.convert(rel, rel.getTraitSet().replace(CorrelationTrait.UNCORRELATED)), toTrait);
    }
}
Also used : IgniteTrimExchange(org.apache.ignite.internal.sql.engine.rel.IgniteTrimExchange) RelTraitSet(org.apache.calcite.plan.RelTraitSet) IgniteExchange(org.apache.ignite.internal.sql.engine.rel.IgniteExchange) Nullable(org.jetbrains.annotations.Nullable)

Example 3 with IgniteExchange

use of org.apache.ignite.internal.sql.engine.rel.IgniteExchange in project ignite-3 by apache.

the class JoinColocationPlannerTest method joinComplexToSimpleAff.

/**
 * Re-hashing based on simple affinity is possible, so bigger table with complex affinity should be sended to the smaller one.
 */
@Test
public void joinComplexToSimpleAff() throws Exception {
    TestTable complexTbl = createTable("COMPLEX_TBL", 2 * DEFAULT_TBL_SIZE, IgniteDistributions.affinity(ImmutableIntList.of(0, 1), ThreadLocalRandom.current().nextInt(), "hash"), "ID1", Integer.class, "ID2", Integer.class, "VAL", String.class);
    complexTbl.addIndex(new IgniteIndex(RelCollations.of(ImmutableIntList.of(0, 1)), "PK", complexTbl));
    TestTable simpleTbl = createTable("SIMPLE_TBL", DEFAULT_TBL_SIZE, IgniteDistributions.affinity(0, "default", "hash"), "ID", Integer.class, "VAL", String.class);
    simpleTbl.addIndex(new IgniteIndex(RelCollations.of(0), "PK", simpleTbl));
    IgniteSchema schema = createSchema(complexTbl, simpleTbl);
    String sql = "select count(*) " + "from COMPLEX_TBL t1 " + "join SIMPLE_TBL t2 on t1.id1 = t2.id";
    RelNode phys = physicalPlan(sql, schema, "NestedLoopJoinConverter", "CorrelatedNestedLoopJoin");
    IgniteMergeJoin join = findFirstNode(phys, byClass(IgniteMergeJoin.class));
    String invalidPlanMsg = "Invalid plan:\n" + RelOptUtil.toString(phys);
    assertThat(invalidPlanMsg, join, notNullValue());
    assertThat(invalidPlanMsg, join.distribution().function().affinity(), is(true));
    List<IgniteExchange> exchanges = findNodes(phys, node -> node instanceof IgniteExchange && ((IgniteRel) node).distribution().function().affinity());
    assertThat(invalidPlanMsg, exchanges, hasSize(1));
    assertThat(invalidPlanMsg, exchanges.get(0).getInput(0), instanceOf(IgniteIndexScan.class));
    assertThat(invalidPlanMsg, exchanges.get(0).getInput(0).getTable().unwrap(TestTable.class), equalTo(complexTbl));
}
Also used : IgniteMergeJoin(org.apache.ignite.internal.sql.engine.rel.IgniteMergeJoin) IgniteIndex(org.apache.ignite.internal.sql.engine.schema.IgniteIndex) RelNode(org.apache.calcite.rel.RelNode) IgniteIndexScan(org.apache.ignite.internal.sql.engine.rel.IgniteIndexScan) IgniteRel(org.apache.ignite.internal.sql.engine.rel.IgniteRel) IgniteSchema(org.apache.ignite.internal.sql.engine.schema.IgniteSchema) IgniteExchange(org.apache.ignite.internal.sql.engine.rel.IgniteExchange) Test(org.junit.jupiter.api.Test)

Example 4 with IgniteExchange

use of org.apache.ignite.internal.sql.engine.rel.IgniteExchange in project ignite-3 by apache.

the class IgniteMdFragmentMapping method fragmentMapping.

/**
 * See {@link IgniteMdFragmentMapping#fragmentMapping(RelNode, RelMetadataQuery, MappingQueryContext)}.
 *
 * <p>{@link ColocationMappingException} may be thrown on two children nodes locations merge. This means that the fragment
 * (which part the parent node is) cannot be executed on any node and additional exchange is needed. This case we throw {@link
 * NodeMappingException} with an edge, where we need the additional exchange. After the exchange is put into the fragment and the
 * fragment is split into two ones, fragment meta information will be recalculated for all fragments.
 */
public FragmentMapping fragmentMapping(BiRel rel, RelMetadataQuery mq, MappingQueryContext ctx) {
    RelNode left = rel.getLeft();
    RelNode right = rel.getRight();
    FragmentMapping frgLeft = fragmentMappingForMetadataQuery(left, mq, ctx);
    FragmentMapping frgRight = fragmentMappingForMetadataQuery(right, mq, ctx);
    try {
        return frgLeft.colocate(frgRight);
    } catch (ColocationMappingException e) {
        IgniteExchange leftExch = new IgniteExchange(rel.getCluster(), left.getTraitSet(), left, TraitUtils.distribution(left));
        IgniteExchange rightExch = new IgniteExchange(rel.getCluster(), right.getTraitSet(), right, TraitUtils.distribution(right));
        RelNode leftVar = rel.copy(rel.getTraitSet(), List.of(leftExch, right));
        RelNode rightVar = rel.copy(rel.getTraitSet(), List.of(left, rightExch));
        RelOptCost leftVarCost = mq.getCumulativeCost(leftVar);
        RelOptCost rightVarCost = mq.getCumulativeCost(rightVar);
        if (leftVarCost.isLt(rightVarCost)) {
            throw new NodeMappingException("Failed to calculate physical distribution", left, e);
        } else {
            throw new NodeMappingException("Failed to calculate physical distribution", right, e);
        }
    }
}
Also used : RelNode(org.apache.calcite.rel.RelNode) RelOptCost(org.apache.calcite.plan.RelOptCost) IgniteExchange(org.apache.ignite.internal.sql.engine.rel.IgniteExchange)

Aggregations

IgniteExchange (org.apache.ignite.internal.sql.engine.rel.IgniteExchange)4 RelNode (org.apache.calcite.rel.RelNode)3 IgniteMergeJoin (org.apache.ignite.internal.sql.engine.rel.IgniteMergeJoin)2 IgniteRel (org.apache.ignite.internal.sql.engine.rel.IgniteRel)2 IgniteIndex (org.apache.ignite.internal.sql.engine.schema.IgniteIndex)2 IgniteSchema (org.apache.ignite.internal.sql.engine.schema.IgniteSchema)2 Test (org.junit.jupiter.api.Test)2 RelOptCost (org.apache.calcite.plan.RelOptCost)1 RelTraitSet (org.apache.calcite.plan.RelTraitSet)1 IgniteIndexScan (org.apache.ignite.internal.sql.engine.rel.IgniteIndexScan)1 IgniteTrimExchange (org.apache.ignite.internal.sql.engine.rel.IgniteTrimExchange)1 Nullable (org.jetbrains.annotations.Nullable)1