Search in sources :

Example 1 with IgniteProject

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

the class JoinCommutePlannerTest method testInnerCommute.

@Test
public void testInnerCommute() throws Exception {
    String sql = "SELECT COUNT(*) FROM SMALL s JOIN HUGE h on h.id = s.id";
    IgniteRel phys = physicalPlan(sql, publicSchema, "MergeJoinConverter", "CorrelatedNestedLoopJoin");
    assertNotNull(phys);
    IgniteNestedLoopJoin join = findFirstNode(phys, byClass(IgniteNestedLoopJoin.class));
    assertNotNull(join);
    IgniteProject proj = findFirstNode(phys, byClass(IgniteProject.class));
    assertNotNull(proj);
    IgniteTableScan rightScan = findFirstNode(join.getRight(), byClass(IgniteTableScan.class));
    assertNotNull(rightScan);
    IgniteTableScan leftScan = findFirstNode(join.getLeft(), byClass(IgniteTableScan.class));
    assertNotNull(leftScan);
    List<String> rightSchemaWithName = rightScan.getTable().getQualifiedName();
    assertEquals(2, rightSchemaWithName.size());
    assertEquals(rightSchemaWithName.get(1), "SMALL");
    List<String> leftSchemaWithName = leftScan.getTable().getQualifiedName();
    assertEquals(leftSchemaWithName.get(1), "HUGE");
    assertEquals(JoinRelType.INNER, join.getJoinType());
    PlanningContext ctx = plannerCtx(sql, publicSchema, "MergeJoinConverter", "CorrelatedNestedLoopJoin");
    RelOptPlanner pl = ctx.cluster().getPlanner();
    RelOptCost costWithCommute = pl.getCost(phys, phys.getCluster().getMetadataQuery());
    assertNotNull(costWithCommute);
    System.out.println("plan: " + RelOptUtil.toString(phys));
    assertNotNull(phys);
    phys = physicalPlan(sql, publicSchema, "MergeJoinConverter", "CorrelatedNestedLoopJoin", "JoinCommuteRule");
    join = findFirstNode(phys, byClass(IgniteNestedLoopJoin.class));
    proj = findFirstNode(phys, byClass(IgniteProject.class));
    rightScan = findFirstNode(join.getRight(), byClass(IgniteTableScan.class));
    leftScan = findFirstNode(join.getLeft(), byClass(IgniteTableScan.class));
    assertNotNull(join);
    assertNull(proj);
    assertNotNull(rightScan);
    assertNotNull(leftScan);
    rightSchemaWithName = rightScan.getTable().getQualifiedName();
    assertEquals(2, rightSchemaWithName.size());
    // no commute
    assertEquals(rightSchemaWithName.get(1), "HUGE");
    leftSchemaWithName = leftScan.getTable().getQualifiedName();
    assertEquals(leftSchemaWithName.get(1), "SMALL");
    // no commute
    assertEquals(JoinRelType.INNER, join.getJoinType());
    ctx = plannerCtx(sql, publicSchema, "MergeJoinConverter", "CorrelatedNestedLoopJoin", "JoinCommuteRule");
    pl = ctx.cluster().getPlanner();
    RelOptCost costWithoutCommute = pl.getCost(phys, phys.getCluster().getMetadataQuery());
    System.out.println("plan: " + RelOptUtil.toString(phys));
    assertTrue(costWithCommute.isLt(costWithoutCommute));
}
Also used : IgniteProject(org.apache.ignite.internal.sql.engine.rel.IgniteProject) PlanningContext(org.apache.ignite.internal.sql.engine.prepare.PlanningContext) RelOptCost(org.apache.calcite.plan.RelOptCost) IgniteRel(org.apache.ignite.internal.sql.engine.rel.IgniteRel) IgniteNestedLoopJoin(org.apache.ignite.internal.sql.engine.rel.IgniteNestedLoopJoin) IgniteTableScan(org.apache.ignite.internal.sql.engine.rel.IgniteTableScan) RelOptPlanner(org.apache.calcite.plan.RelOptPlanner) Test(org.junit.jupiter.api.Test)

Example 2 with IgniteProject

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

the class JoinCommutePlannerTest method testOuterCommute.

@Test
public void testOuterCommute() throws Exception {
    String sql = "SELECT COUNT(*) FROM SMALL s RIGHT JOIN HUGE h on h.id = s.id";
    IgniteRel phys = physicalPlan(sql, publicSchema, "MergeJoinConverter", "CorrelatedNestedLoopJoin");
    assertNotNull(phys);
    IgniteNestedLoopJoin join = findFirstNode(phys, byClass(IgniteNestedLoopJoin.class));
    IgniteProject proj = findFirstNode(phys, byClass(IgniteProject.class));
    assertNotNull(proj);
    assertEquals(JoinRelType.LEFT, join.getJoinType());
    PlanningContext ctx = plannerCtx(sql, publicSchema, "MergeJoinConverter", "CorrelatedNestedLoopJoin");
    RelOptPlanner pl = ctx.cluster().getPlanner();
    RelOptCost costWithCommute = pl.getCost(phys, phys.getCluster().getMetadataQuery());
    assertNotNull(costWithCommute);
    System.out.println("plan: " + RelOptUtil.toString(phys));
    assertNotNull(phys);
    phys = physicalPlan(sql, publicSchema, "MergeJoinConverter", "CorrelatedNestedLoopJoin", "JoinCommuteRule");
    join = findFirstNode(phys, byClass(IgniteNestedLoopJoin.class));
    proj = findFirstNode(phys, byClass(IgniteProject.class));
    assertNull(proj);
    // no commute
    assertEquals(JoinRelType.RIGHT, join.getJoinType());
    ctx = plannerCtx(sql, publicSchema, "MergeJoinConverter", "CorrelatedNestedLoopJoin", "JoinCommuteRule");
    pl = ctx.cluster().getPlanner();
    RelOptCost costWithoutCommute = pl.getCost(phys, phys.getCluster().getMetadataQuery());
    System.out.println("plan: " + RelOptUtil.toString(phys));
    assertTrue(costWithCommute.isLt(costWithoutCommute));
}
Also used : IgniteProject(org.apache.ignite.internal.sql.engine.rel.IgniteProject) PlanningContext(org.apache.ignite.internal.sql.engine.prepare.PlanningContext) RelOptCost(org.apache.calcite.plan.RelOptCost) IgniteRel(org.apache.ignite.internal.sql.engine.rel.IgniteRel) IgniteNestedLoopJoin(org.apache.ignite.internal.sql.engine.rel.IgniteNestedLoopJoin) RelOptPlanner(org.apache.calcite.plan.RelOptPlanner) Test(org.junit.jupiter.api.Test)

Example 3 with IgniteProject

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

the class PlannerHelper method optimize.

/**
 * Optimize.
 * TODO Documentation https://issues.apache.org/jira/browse/IGNITE-15859
 *
 * @param sqlNode Sql node.
 * @param planner Planner.
 */
public static IgniteRel optimize(SqlNode sqlNode, IgnitePlanner planner) {
    try {
        // Convert to Relational operators graph
        RelRoot root = planner.rel(sqlNode);
        RelNode rel = root.rel;
        if (HintUtils.containsDisabledRules(root.hints)) {
            planner.setDisabledRules(HintUtils.disabledRules(root.hints));
        }
        // Transformation chain
        rel = planner.transform(PlannerPhase.HEP_DECORRELATE, rel.getTraitSet(), rel);
        rel = planner.trimUnusedFields(root.withRel(rel)).rel;
        rel = planner.transform(PlannerPhase.HEP_FILTER_PUSH_DOWN, rel.getTraitSet(), rel);
        rel = planner.transform(PlannerPhase.HEP_PROJECT_PUSH_DOWN, rel.getTraitSet(), rel);
        RelTraitSet desired = rel.getCluster().traitSet().replace(IgniteConvention.INSTANCE).replace(IgniteDistributions.single()).replace(root.collation == null ? RelCollations.EMPTY : root.collation).simplify();
        IgniteRel igniteRel = planner.transform(PlannerPhase.OPTIMIZATION, desired, rel);
        if (!root.isRefTrivial()) {
            final List<RexNode> projects = new ArrayList<>();
            final RexBuilder rexBuilder = igniteRel.getCluster().getRexBuilder();
            for (int field : Pair.left(root.fields)) {
                projects.add(rexBuilder.makeInputRef(igniteRel, field));
            }
            igniteRel = new IgniteProject(igniteRel.getCluster(), desired, igniteRel, projects, root.validatedRowType);
        }
        if (sqlNode.isA(Set.of(SqlKind.INSERT, SqlKind.UPDATE, SqlKind.MERGE))) {
            igniteRel = new FixDependentModifyNodeShuttle().visit(igniteRel);
        }
        return igniteRel;
    } catch (Throwable ex) {
        LOG.error("Unexpected error at query optimizer.", ex);
        if (LOG.isDebugEnabled()) {
            LOG.error(planner.dump());
        }
        throw ex;
    }
}
Also used : IgniteProject(org.apache.ignite.internal.sql.engine.rel.IgniteProject) RelNode(org.apache.calcite.rel.RelNode) IgniteRel(org.apache.ignite.internal.sql.engine.rel.IgniteRel) ArrayList(java.util.ArrayList) RexBuilder(org.apache.calcite.rex.RexBuilder) RelRoot(org.apache.calcite.rel.RelRoot) RelTraitSet(org.apache.calcite.plan.RelTraitSet) RexNode(org.apache.calcite.rex.RexNode)

Example 4 with IgniteProject

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

the class ProjectConverterRule method convert.

/**
 * {@inheritDoc}
 */
@Override
protected PhysicalNode convert(RelOptPlanner planner, RelMetadataQuery mq, LogicalProject rel) {
    RelOptCluster cluster = rel.getCluster();
    RelTraitSet traits = cluster.traitSetOf(IgniteConvention.INSTANCE).replace(IgniteDistributions.single());
    Collection<CorrelationId> corrIds = RexUtils.extractCorrelationIds(rel.getProjects());
    if (!corrIds.isEmpty()) {
        traits = traits.replace(CorrelationTrait.correlations(corrIds)).replace(RewindabilityTrait.REWINDABLE);
    }
    RelNode input = convert(rel.getInput(), traits);
    return new IgniteProject(cluster, traits, input, rel.getProjects(), rel.getRowType());
}
Also used : RelOptCluster(org.apache.calcite.plan.RelOptCluster) IgniteProject(org.apache.ignite.internal.sql.engine.rel.IgniteProject) RelNode(org.apache.calcite.rel.RelNode) RelTraitSet(org.apache.calcite.plan.RelTraitSet) CorrelationId(org.apache.calcite.rel.core.CorrelationId)

Aggregations

IgniteProject (org.apache.ignite.internal.sql.engine.rel.IgniteProject)4 IgniteRel (org.apache.ignite.internal.sql.engine.rel.IgniteRel)3 RelOptCost (org.apache.calcite.plan.RelOptCost)2 RelOptPlanner (org.apache.calcite.plan.RelOptPlanner)2 RelTraitSet (org.apache.calcite.plan.RelTraitSet)2 RelNode (org.apache.calcite.rel.RelNode)2 PlanningContext (org.apache.ignite.internal.sql.engine.prepare.PlanningContext)2 IgniteNestedLoopJoin (org.apache.ignite.internal.sql.engine.rel.IgniteNestedLoopJoin)2 Test (org.junit.jupiter.api.Test)2 ArrayList (java.util.ArrayList)1 RelOptCluster (org.apache.calcite.plan.RelOptCluster)1 RelRoot (org.apache.calcite.rel.RelRoot)1 CorrelationId (org.apache.calcite.rel.core.CorrelationId)1 RexBuilder (org.apache.calcite.rex.RexBuilder)1 RexNode (org.apache.calcite.rex.RexNode)1 IgniteTableScan (org.apache.ignite.internal.sql.engine.rel.IgniteTableScan)1