use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rel.core.Join in project calcite by apache.
the class JoinPushExpressionsRule method onMatch.
@Override
public void onMatch(RelOptRuleCall call) {
Join join = call.rel(0);
// Push expression in join condition into Project below Join.
RelNode newJoin = RelOptUtil.pushDownJoinConditions(join, call.builder());
// If the join is the same, we bail out
if (newJoin instanceof Join) {
final RexNode newCondition = ((Join) newJoin).getCondition();
if (join.getCondition().toString().equals(newCondition.toString())) {
return;
}
}
call.transformTo(newJoin);
}
use of org.apache.beam.vendor.calcite.v1_28_0.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);
}
}
use of org.apache.beam.vendor.calcite.v1_28_0.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);
}
use of org.apache.beam.vendor.calcite.v1_28_0.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;
}
});
}
use of org.apache.beam.vendor.calcite.v1_28_0.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);
}
Aggregations