Search in sources :

Example 16 with Join

use of org.apache.calcite.rel.core.Join in project calcite by apache.

the class SqlToRelConverter method translateIn.

private RexNode translateIn(RelOptUtil.Logic logic, RelNode root, final RexNode rex) {
    switch(logic) {
        case TRUE:
            return rexBuilder.makeLiteral(true);
        case TRUE_FALSE:
        case UNKNOWN_AS_FALSE:
            assert rex instanceof RexRangeRef;
            final int fieldCount = rex.getType().getFieldCount();
            RexNode rexNode = rexBuilder.makeFieldAccess(rex, fieldCount - 1);
            rexNode = rexBuilder.makeCall(SqlStdOperatorTable.IS_TRUE, rexNode);
            // Then append the IS NOT NULL(leftKeysForIn).
            // 
            // RexRangeRef contains the following fields:
            // leftKeysForIn,
            // rightKeysForIn (the original sub-query select list),
            // nullIndicator
            // 
            // The first two lists contain the same number of fields.
            final int k = (fieldCount - 1) / 2;
            for (int i = 0; i < k; i++) {
                rexNode = rexBuilder.makeCall(SqlStdOperatorTable.AND, rexNode, rexBuilder.makeCall(SqlStdOperatorTable.IS_NOT_NULL, rexBuilder.makeFieldAccess(rex, i)));
            }
            return rexNode;
        case TRUE_FALSE_UNKNOWN:
        case UNKNOWN_AS_TRUE:
            // select e.deptno,
            // case
            // when ct.c = 0 then false
            // when dt.i is not null then true
            // when e.deptno is null then null
            // when ct.ck < ct.c then null
            // else false
            // end
            // from e
            // cross join (select count(*) as c, count(deptno) as ck from v) as ct
            // left join (select distinct deptno, true as i from v) as dt
            // on e.deptno = dt.deptno
            final Join join = (Join) root;
            final Project left = (Project) join.getLeft();
            final RelNode leftLeft = ((Join) left.getInput()).getLeft();
            final int leftLeftCount = leftLeft.getRowType().getFieldCount();
            final RelDataType longType = typeFactory.createSqlType(SqlTypeName.BIGINT);
            final RexNode cRef = rexBuilder.makeInputRef(root, leftLeftCount);
            final RexNode ckRef = rexBuilder.makeInputRef(root, leftLeftCount + 1);
            final RexNode iRef = rexBuilder.makeInputRef(root, root.getRowType().getFieldCount() - 1);
            final RexLiteral zero = rexBuilder.makeExactLiteral(BigDecimal.ZERO, longType);
            final RexLiteral trueLiteral = rexBuilder.makeLiteral(true);
            final RexLiteral falseLiteral = rexBuilder.makeLiteral(false);
            final RexNode unknownLiteral = rexBuilder.makeNullLiteral(trueLiteral.getType());
            final ImmutableList.Builder<RexNode> args = ImmutableList.builder();
            args.add(rexBuilder.makeCall(SqlStdOperatorTable.EQUALS, cRef, zero), falseLiteral, rexBuilder.makeCall(SqlStdOperatorTable.IS_NOT_NULL, iRef), trueLiteral);
            final JoinInfo joinInfo = join.analyzeCondition();
            for (int leftKey : joinInfo.leftKeys) {
                final RexNode kRef = rexBuilder.makeInputRef(root, leftKey);
                args.add(rexBuilder.makeCall(SqlStdOperatorTable.IS_NULL, kRef), unknownLiteral);
            }
            args.add(rexBuilder.makeCall(SqlStdOperatorTable.LESS_THAN, ckRef, cRef), unknownLiteral, falseLiteral);
            return rexBuilder.makeCall(SqlStdOperatorTable.CASE, args.build());
        default:
            throw new AssertionError(logic);
    }
}
Also used : RexRangeRef(org.apache.calcite.rex.RexRangeRef) JoinInfo(org.apache.calcite.rel.core.JoinInfo) Project(org.apache.calcite.rel.core.Project) LogicalProject(org.apache.calcite.rel.logical.LogicalProject) RexLiteral(org.apache.calcite.rex.RexLiteral) RelNode(org.apache.calcite.rel.RelNode) ImmutableList(com.google.common.collect.ImmutableList) Join(org.apache.calcite.rel.core.Join) LogicalJoin(org.apache.calcite.rel.logical.LogicalJoin) SqlJoin(org.apache.calcite.sql.SqlJoin) RelDataType(org.apache.calcite.rel.type.RelDataType) RexNode(org.apache.calcite.rex.RexNode)

Example 17 with Join

use of org.apache.calcite.rel.core.Join in project calcite by apache.

the class RelOptRulesTest method testPushFilterPastProject.

/**
 * Test case for
 * <a href="https://issues.apache.org/jira/browse/CALCITE-448">[CALCITE-448]
 * FilterIntoJoinRule creates filters containing invalid RexInputRef</a>.
 */
@Test
public void testPushFilterPastProject() {
    final HepProgram preProgram = HepProgram.builder().addRuleInstance(ProjectMergeRule.INSTANCE).build();
    final FilterJoinRule.Predicate predicate = new FilterJoinRule.Predicate() {

        public boolean apply(Join join, JoinRelType joinType, RexNode exp) {
            return joinType != JoinRelType.INNER;
        }
    };
    final FilterJoinRule join = new FilterJoinRule.JoinConditionPushRule(RelBuilder.proto(), predicate);
    final FilterJoinRule filterOnJoin = new FilterJoinRule.FilterIntoJoinRule(true, RelBuilder.proto(), predicate);
    final HepProgram program = HepProgram.builder().addGroupBegin().addRuleInstance(FilterProjectTransposeRule.INSTANCE).addRuleInstance(join).addRuleInstance(filterOnJoin).addGroupEnd().build();
    final String sql = "select a.name\n" + "from dept a\n" + "left join dept b on b.deptno > 10\n" + "right join dept c on b.deptno > 10\n";
    checkPlanning(tester, preProgram, new HepPlanner(program), sql);
}
Also used : JoinRelType(org.apache.calcite.rel.core.JoinRelType) HepProgram(org.apache.calcite.plan.hep.HepProgram) Join(org.apache.calcite.rel.core.Join) FilterJoinRule(org.apache.calcite.rel.rules.FilterJoinRule) HepPlanner(org.apache.calcite.plan.hep.HepPlanner) RexNode(org.apache.calcite.rex.RexNode) Test(org.junit.Test)

Example 18 with Join

use of org.apache.calcite.rel.core.Join in project calcite by apache.

the class RelMetadataTest method testAllPredicates.

@Test
public void testAllPredicates() {
    final Project rel = (Project) convertSql("select * from emp, dept");
    final Join join = (Join) rel.getInput();
    final RelOptTable empTable = join.getInput(0).getTable();
    final RelOptTable deptTable = join.getInput(1).getTable();
    Frameworks.withPlanner(new Frameworks.PlannerAction<Void>() {

        public Void apply(RelOptCluster cluster, RelOptSchema relOptSchema, SchemaPlus rootSchema) {
            checkAllPredicates(cluster, empTable, deptTable);
            return null;
        }
    });
}
Also used : RelOptCluster(org.apache.calcite.plan.RelOptCluster) Project(org.apache.calcite.rel.core.Project) LogicalProject(org.apache.calcite.rel.logical.LogicalProject) RelOptSchema(org.apache.calcite.plan.RelOptSchema) Frameworks(org.apache.calcite.tools.Frameworks) SchemaPlus(org.apache.calcite.schema.SchemaPlus) SemiJoin(org.apache.calcite.rel.core.SemiJoin) Join(org.apache.calcite.rel.core.Join) LogicalJoin(org.apache.calcite.rel.logical.LogicalJoin) EnumerableMergeJoin(org.apache.calcite.adapter.enumerable.EnumerableMergeJoin) RelOptTable(org.apache.calcite.plan.RelOptTable) Test(org.junit.Test)

Example 19 with Join

use of org.apache.calcite.rel.core.Join in project calcite by apache.

the class SemiJoinJoinTransposeRule method onMatch.

// ~ Methods ----------------------------------------------------------------
// implement RelOptRule
public void onMatch(RelOptRuleCall call) {
    SemiJoin semiJoin = call.rel(0);
    final Join join = call.rel(1);
    if (join instanceof SemiJoin) {
        return;
    }
    final ImmutableIntList leftKeys = semiJoin.getLeftKeys();
    final ImmutableIntList rightKeys = semiJoin.getRightKeys();
    // X is the left child of the join below the semi-join
    // Y is the right child of the join below the semi-join
    // Z is the right child of the semi-join
    int nFieldsX = join.getLeft().getRowType().getFieldList().size();
    int nFieldsY = join.getRight().getRowType().getFieldList().size();
    int nFieldsZ = semiJoin.getRight().getRowType().getFieldList().size();
    int nTotalFields = nFieldsX + nFieldsY + nFieldsZ;
    List<RelDataTypeField> fields = new ArrayList<RelDataTypeField>();
    // create a list of fields for the full join result; note that
    // we can't simply use the fields from the semi-join because the
    // row-type of a semi-join only includes the left hand side fields
    List<RelDataTypeField> joinFields = semiJoin.getRowType().getFieldList();
    for (int i = 0; i < (nFieldsX + nFieldsY); i++) {
        fields.add(joinFields.get(i));
    }
    joinFields = semiJoin.getRight().getRowType().getFieldList();
    for (int i = 0; i < nFieldsZ; i++) {
        fields.add(joinFields.get(i));
    }
    // determine which operands below the semi-join are the actual
    // Rels that participate in the semi-join
    int nKeysFromX = 0;
    for (int leftKey : leftKeys) {
        if (leftKey < nFieldsX) {
            nKeysFromX++;
        }
    }
    // otherwise, a semi-join wouldn't have been created
    assert (nKeysFromX == 0) || (nKeysFromX == leftKeys.size());
    // need to convert the semi-join condition and possibly the keys
    RexNode newSemiJoinFilter;
    List<Integer> newLeftKeys;
    int[] adjustments = new int[nTotalFields];
    if (nKeysFromX > 0) {
        // (X, Y, Z) --> (X, Z, Y)
        // semiJoin(X, Z)
        // pass 0 as Y's adjustment because there shouldn't be any
        // references to Y in the semi-join filter
        setJoinAdjustments(adjustments, nFieldsX, nFieldsY, nFieldsZ, 0, -nFieldsY);
        newSemiJoinFilter = semiJoin.getCondition().accept(new RelOptUtil.RexInputConverter(semiJoin.getCluster().getRexBuilder(), fields, adjustments));
        newLeftKeys = leftKeys;
    } else {
        // (X, Y, Z) --> (X, Y, Z)
        // semiJoin(Y, Z)
        setJoinAdjustments(adjustments, nFieldsX, nFieldsY, nFieldsZ, -nFieldsX, -nFieldsX);
        newSemiJoinFilter = semiJoin.getCondition().accept(new RelOptUtil.RexInputConverter(semiJoin.getCluster().getRexBuilder(), fields, adjustments));
        newLeftKeys = RelOptUtil.adjustKeys(leftKeys, -nFieldsX);
    }
    // create the new join
    RelNode leftSemiJoinOp;
    if (nKeysFromX > 0) {
        leftSemiJoinOp = join.getLeft();
    } else {
        leftSemiJoinOp = join.getRight();
    }
    SemiJoin newSemiJoin = SemiJoin.create(leftSemiJoinOp, semiJoin.getRight(), newSemiJoinFilter, ImmutableIntList.copyOf(newLeftKeys), rightKeys);
    RelNode leftJoinRel;
    RelNode rightJoinRel;
    if (nKeysFromX > 0) {
        leftJoinRel = newSemiJoin;
        rightJoinRel = join.getRight();
    } else {
        leftJoinRel = join.getLeft();
        rightJoinRel = newSemiJoin;
    }
    RelNode newJoinRel = join.copy(join.getTraitSet(), join.getCondition(), leftJoinRel, rightJoinRel, join.getJoinType(), join.isSemiJoinDone());
    call.transformTo(newJoinRel);
}
Also used : ArrayList(java.util.ArrayList) SemiJoin(org.apache.calcite.rel.core.SemiJoin) Join(org.apache.calcite.rel.core.Join) RelDataTypeField(org.apache.calcite.rel.type.RelDataTypeField) RelNode(org.apache.calcite.rel.RelNode) SemiJoin(org.apache.calcite.rel.core.SemiJoin) ImmutableIntList(org.apache.calcite.util.ImmutableIntList) RexNode(org.apache.calcite.rex.RexNode)

Example 20 with Join

use of org.apache.calcite.rel.core.Join in project calcite by apache.

the class SemiJoinRule method onMatch.

@Override
public void onMatch(RelOptRuleCall call) {
    final Join join = call.rel(0);
    final RelNode left = call.rel(1);
    final Aggregate aggregate = call.rel(2);
    perform(call, null, join, left, aggregate);
}
Also used : RelNode(org.apache.calcite.rel.RelNode) Join(org.apache.calcite.rel.core.Join) Aggregate(org.apache.calcite.rel.core.Aggregate)

Aggregations

Join (org.apache.calcite.rel.core.Join)57 RelNode (org.apache.calcite.rel.RelNode)38 RexNode (org.apache.calcite.rex.RexNode)32 LogicalJoin (org.apache.calcite.rel.logical.LogicalJoin)25 ArrayList (java.util.ArrayList)23 RexBuilder (org.apache.calcite.rex.RexBuilder)20 Project (org.apache.calcite.rel.core.Project)16 RelBuilder (org.apache.calcite.tools.RelBuilder)15 ImmutableBitSet (org.apache.calcite.util.ImmutableBitSet)15 SemiJoin (org.apache.calcite.rel.core.SemiJoin)12 RelOptCluster (org.apache.calcite.plan.RelOptCluster)11 Aggregate (org.apache.calcite.rel.core.Aggregate)11 RelMetadataQuery (org.apache.calcite.rel.metadata.RelMetadataQuery)9 LogicalProject (org.apache.calcite.rel.logical.LogicalProject)8 RelDataType (org.apache.calcite.rel.type.RelDataType)8 Mappings (org.apache.calcite.util.mapping.Mappings)8 JoinRelType (org.apache.calcite.rel.core.JoinRelType)7 HiveJoin (org.apache.hadoop.hive.ql.optimizer.calcite.reloperators.HiveJoin)7 HashMap (java.util.HashMap)6 Sort (org.apache.calcite.rel.core.Sort)6