@Test
public void shouldOptimizePlanForQueryJoiningMultipleTypeViewsUsingNonIdentityEquiJoin() {

    node = optimize("SELECT type1.a1 AS a, type1.a2 AS b, type2.a3 as c, type2.a4 as d "
                    + "FROM type1 JOIN type2 ON type1.a2 = type2.a3 WHERE CONTAINS(type1.a1,'something')");
    // Create the expected plan ...
    PlanNode project = new PlanNode(Type.PROJECT, selector("type1"), selector("type2"));
    project.setProperty(Property.PROJECT_COLUMNS,
                        columns(column("type1", "a1", "a"), column("type1", "a2", "b"), column("type2", "a3", "c"),
                                column("type2", "a4", "d")));
    PlanNode join = new PlanNode(Type.JOIN, project, selector("type1"), selector("type2"));
    join.setProperty(Property.JOIN_ALGORITHM, JoinAlgorithm.NESTED_LOOP);
    join.setProperty(Property.JOIN_TYPE, JoinType.INNER);
    join.setProperty(Property.JOIN_CONDITION, new EquiJoinCondition(selector("type1"), "a2", selector("type2"), "a3"));
    PlanNode leftAccess = new PlanNode(Type.ACCESS, join, selector("type1"));
    PlanNode leftProject = new PlanNode(Type.PROJECT, leftAccess, selector("type1"));
    leftProject.setProperty(Property.PROJECT_COLUMNS, columns(column("type1", "a1"), column("type1", "a2")));
    PlanNode leftSelect1 = new PlanNode(Type.SELECT, leftProject, selector("type1"));
    leftSelect1.setProperty(Property.SELECT_CRITERIA, new FullTextSearch(selector("type1"), "a1", "something"));
    PlanNode leftSelect2 = new PlanNode(Type.SELECT, leftSelect1, selector("type1"));
    leftSelect2.setProperty(Property.SELECT_CRITERIA, new SetCriteria(new PropertyValue(selector("type1"), "primaryType"),
                                                                      new Literal("t1"), new Literal("t0")));
    PlanNode leftSelect3 = new PlanNode(Type.SELECT, leftSelect2, selector("type1"));
    leftSelect3.setProperty(Property.SELECT_CRITERIA, new SetCriteria(new PropertyValue(selector("type1"), "mixins"),
                                                                      new Literal("t3"), new Literal("t4")));
    PlanNode leftSource = new PlanNode(Type.SOURCE, leftSelect3, selector("type1"));
    leftSource.setProperty(Property.SOURCE_NAME, selector("all"));
    leftSource.setProperty(Property.SOURCE_ALIAS, selector("type1"));
    leftSource.setProperty(Property.SOURCE_COLUMNS, context.getSchemata().getTable(selector("all")).getColumns());
    PlanNode rightAccess = new PlanNode(Type.ACCESS, join, selector("type2"));
    PlanNode rightProject = new PlanNode(Type.PROJECT, rightAccess, selector("type2"));
    rightProject.setProperty(Property.PROJECT_COLUMNS, columns(column("type2", "a3"), column("type2", "a4")));
    PlanNode rightSelect1 = new PlanNode(Type.SELECT, rightProject, selector("type2"));
    rightSelect1.setProperty(Property.SELECT_CRITERIA, new SetCriteria(new PropertyValue(selector("type2"), "primaryType"),
                                                                       new Literal("t2"), new Literal("t0")));
    PlanNode rightSelect2 = new PlanNode(Type.SELECT, rightSelect1, selector("type2"));
    rightSelect2.setProperty(Property.SELECT_CRITERIA, new SetCriteria(new PropertyValue(selector("type2"), "mixins"),
                                                                       new Literal("t4"), new Literal("t5")));
    PlanNode rightSource = new PlanNode(Type.SOURCE, rightSelect2, selector("type2"));
    rightSource.setProperty(Property.SOURCE_NAME, selector("all"));
    rightSource.setProperty(Property.SOURCE_ALIAS, selector("type2"));
    rightSource.setProperty(Property.SOURCE_COLUMNS, context.getSchemata().getTable(selector("all")).getColumns());
    // Compare the expected and actual plan ...
    assertPlanMatches(project);
}