use of org.apache.calcite.util.ImmutableBitSet in project calcite by apache.
the class RelOptUtil method projectMultiJoin.
/**
* Creates a new {@link org.apache.calcite.rel.rules.MultiJoin} to reflect
* projection references from a
* {@link org.apache.calcite.rel.logical.LogicalProject} that is on top of the
* {@link org.apache.calcite.rel.rules.MultiJoin}.
*
* @param multiJoin the original MultiJoin
* @param project the LogicalProject on top of the MultiJoin
* @return the new MultiJoin
*/
public static MultiJoin projectMultiJoin(MultiJoin multiJoin, LogicalProject project) {
// Locate all input references in the projection expressions as well
// the post-join filter. Since the filter effectively sits in
// between the LogicalProject and the MultiJoin, the projection needs
// to include those filter references.
ImmutableBitSet inputRefs = InputFinder.bits(project.getProjects(), multiJoin.getPostJoinFilter());
// create new copies of the bitmaps
List<RelNode> multiJoinInputs = multiJoin.getInputs();
List<BitSet> newProjFields = Lists.newArrayList();
for (RelNode multiJoinInput : multiJoinInputs) {
newProjFields.add(new BitSet(multiJoinInput.getRowType().getFieldCount()));
}
// set the bits found in the expressions
int currInput = -1;
int startField = 0;
int nFields = 0;
for (int bit : inputRefs) {
while (bit >= (startField + nFields)) {
startField += nFields;
currInput++;
assert currInput < multiJoinInputs.size();
nFields = multiJoinInputs.get(currInput).getRowType().getFieldCount();
}
newProjFields.get(currInput).set(bit - startField);
}
// for each input
return new MultiJoin(multiJoin.getCluster(), multiJoin.getInputs(), multiJoin.getJoinFilter(), multiJoin.getRowType(), multiJoin.isFullOuterJoin(), multiJoin.getOuterJoinConditions(), multiJoin.getJoinTypes(), Lists.transform(newProjFields, ImmutableBitSet.FROM_BIT_SET), multiJoin.getJoinFieldRefCountsMap(), multiJoin.getPostJoinFilter());
}
use of org.apache.calcite.util.ImmutableBitSet in project calcite by apache.
the class RelOptUtil method pushDownEqualJoinConditions.
/**
* Pushes down parts of a join condition.
*
* <p>For example, given
* "emp JOIN dept ON emp.deptno + 1 = dept.deptno", adds a project above
* "emp" that computes the expression
* "emp.deptno + 1". The resulting join condition is a simple combination
* of AND, equals, and input fields.
*/
private static RexNode pushDownEqualJoinConditions(RexNode node, int leftCount, int rightCount, List<RexNode> extraLeftExprs, List<RexNode> extraRightExprs) {
switch(node.getKind()) {
case AND:
case EQUALS:
final RexCall call = (RexCall) node;
final List<RexNode> list = new ArrayList<>();
List<RexNode> operands = Lists.newArrayList(call.getOperands());
for (int i = 0; i < operands.size(); i++) {
RexNode operand = operands.get(i);
final int left2 = leftCount + extraLeftExprs.size();
final int right2 = rightCount + extraRightExprs.size();
final RexNode e = pushDownEqualJoinConditions(operand, leftCount, rightCount, extraLeftExprs, extraRightExprs);
final List<RexNode> remainingOperands = Util.skip(operands, i + 1);
final int left3 = leftCount + extraLeftExprs.size();
fix(remainingOperands, left2, left3);
fix(list, left2, left3);
list.add(e);
}
if (!list.equals(call.getOperands())) {
return call.clone(call.getType(), list);
}
return call;
case OR:
case INPUT_REF:
case LITERAL:
return node;
default:
final ImmutableBitSet bits = RelOptUtil.InputFinder.bits(node);
final int mid = leftCount + extraLeftExprs.size();
switch(Side.of(bits, mid)) {
case LEFT:
fix(extraRightExprs, mid, mid + 1);
extraLeftExprs.add(node);
return new RexInputRef(mid, node.getType());
case RIGHT:
final int index2 = mid + rightCount + extraRightExprs.size();
extraRightExprs.add(node);
return new RexInputRef(index2, node.getType());
case BOTH:
case EMPTY:
default:
return node;
}
}
}
use of org.apache.calcite.util.ImmutableBitSet in project calcite by apache.
the class RelMetadataTest method testDistinctRowCountTable.
@Test
public void testDistinctRowCountTable() {
// no unique key information is available so return null
RelNode rel = convertSql("select * from emp where deptno = 10");
final RelMetadataQuery mq = RelMetadataQuery.instance();
ImmutableBitSet groupKey = ImmutableBitSet.of(rel.getRowType().getFieldNames().indexOf("DEPTNO"));
Double result = mq.getDistinctRowCount(rel, groupKey, null);
assertThat(result, nullValue());
}
use of org.apache.calcite.util.ImmutableBitSet in project calcite by apache.
the class RelMetadataTest method testCorrelateUniqueKeys.
@Test
public void testCorrelateUniqueKeys() {
final String sql = "select *\n" + "from (select distinct deptno from emp) as e,\n" + " lateral (\n" + " select * from dept where dept.deptno = e.deptno)";
final RelNode rel = convertSql(sql);
final RelMetadataQuery mq = RelMetadataQuery.instance();
assertThat(rel, isA((Class) Project.class));
final Project project = (Project) rel;
final Set<ImmutableBitSet> result = mq.getUniqueKeys(project);
assertThat(result, sortsAs("[{0}]"));
if (false) {
assertUniqueConsistent(project);
}
assertThat(project.getInput(), isA((Class) Correlate.class));
final Correlate correlate = (Correlate) project.getInput();
final Set<ImmutableBitSet> result2 = mq.getUniqueKeys(correlate);
assertThat(result2, sortsAs("[{0}]"));
if (false) {
assertUniqueConsistent(correlate);
}
}
use of org.apache.calcite.util.ImmutableBitSet in project calcite by apache.
the class RelMetadataTest method testJoinUniqueKeys.
/**
* Test case for
* <a href="https://issues.apache.org/jira/browse/CALCITE-509">[CALCITE-509]
* "RelMdColumnUniqueness uses ImmutableBitSet.Builder twice, gets
* NullPointerException"</a>.
*/
@Test
public void testJoinUniqueKeys() {
RelNode rel = convertSql("select * from emp join bonus using (ename)");
final RelMetadataQuery mq = RelMetadataQuery.instance();
Set<ImmutableBitSet> result = mq.getUniqueKeys(rel);
assertThat(result.isEmpty(), is(true));
assertUniqueConsistent(rel);
}
Aggregations