use of org.apache.calcite.rel.core.Project in project hive by apache.
the class HiveSemiJoinRule method onMatch.
@Override
public void onMatch(RelOptRuleCall call) {
LOG.debug("Matched HiveSemiJoinRule");
final Project project = call.rel(0);
final Join join = call.rel(1);
final RelNode left = call.rel(2);
final Aggregate aggregate = call.rel(3);
final RelOptCluster cluster = join.getCluster();
final RexBuilder rexBuilder = cluster.getRexBuilder();
final ImmutableBitSet bits = RelOptUtil.InputFinder.bits(project.getProjects(), null);
final ImmutableBitSet rightBits = ImmutableBitSet.range(left.getRowType().getFieldCount(), join.getRowType().getFieldCount());
if (bits.intersects(rightBits)) {
return;
}
final JoinInfo joinInfo = join.analyzeCondition();
if (!joinInfo.rightSet().equals(ImmutableBitSet.range(aggregate.getGroupCount()))) {
// By the way, neither a super-set nor a sub-set would work.
return;
}
if (join.getJoinType() == JoinRelType.LEFT) {
// since for LEFT join we are only interested in rows from LEFT we can get rid of right side
call.transformTo(call.builder().push(left).project(project.getProjects(), project.getRowType().getFieldNames()).build());
return;
}
if (join.getJoinType() != JoinRelType.INNER) {
return;
}
if (!joinInfo.isEqui()) {
return;
}
LOG.debug("All conditions matched for HiveSemiJoinRule. Going to apply transformation.");
final List<Integer> newRightKeyBuilder = Lists.newArrayList();
final List<Integer> aggregateKeys = aggregate.getGroupSet().asList();
for (int key : joinInfo.rightKeys) {
newRightKeyBuilder.add(aggregateKeys.get(key));
}
final ImmutableIntList newRightKeys = ImmutableIntList.copyOf(newRightKeyBuilder);
final RelNode newRight = aggregate.getInput();
final RexNode newCondition = RelOptUtil.createEquiJoinCondition(left, joinInfo.leftKeys, newRight, newRightKeys, rexBuilder);
RelNode semi = null;
// is not expected further down the pipeline. see jira for more details
if (aggregate.getInput() instanceof HepRelVertex && ((HepRelVertex) aggregate.getInput()).getCurrentRel() instanceof Join) {
Join rightJoin = (Join) (((HepRelVertex) aggregate.getInput()).getCurrentRel());
List<RexNode> projects = new ArrayList<>();
for (int i = 0; i < rightJoin.getRowType().getFieldCount(); i++) {
projects.add(rexBuilder.makeInputRef(rightJoin, i));
}
RelNode topProject = call.builder().push(rightJoin).project(projects, rightJoin.getRowType().getFieldNames(), true).build();
semi = call.builder().push(left).push(topProject).semiJoin(newCondition).build();
} else {
semi = call.builder().push(left).push(aggregate.getInput()).semiJoin(newCondition).build();
}
call.transformTo(call.builder().push(semi).project(project.getProjects(), project.getRowType().getFieldNames()).build());
}
use of org.apache.calcite.rel.core.Project in project druid by druid-io.
the class DruidSemiJoinRule method onMatch.
@Override
public void onMatch(RelOptRuleCall call) {
final Project project = call.rel(0);
final Join join = call.rel(1);
final DruidRel left = call.rel(2);
final DruidRel right = call.rel(3);
final ImmutableBitSet bits = RelOptUtil.InputFinder.bits(project.getProjects(), null);
final ImmutableBitSet rightBits = ImmutableBitSet.range(left.getRowType().getFieldCount(), join.getRowType().getFieldCount());
if (bits.intersects(rightBits)) {
return;
}
final JoinInfo joinInfo = join.analyzeCondition();
final List<Integer> rightDimsOut = new ArrayList<>();
for (DimensionSpec dimensionSpec : right.getQueryBuilder().getGrouping().getDimensions()) {
rightDimsOut.add(right.getOutputRowSignature().getRowOrder().indexOf(dimensionSpec.getOutputName()));
}
if (!joinInfo.isEqui() || !joinInfo.rightSet().equals(ImmutableBitSet.of(rightDimsOut))) {
// By the way, neither a super-set nor a sub-set would work.
return;
}
final RelBuilder relBuilder = call.builder();
final PlannerConfig plannerConfig = left.getPlannerContext().getPlannerConfig();
if (join.getJoinType() == JoinRelType.LEFT) {
// Join can be eliminated since the right-hand side cannot have any effect (nothing is being selected,
// and LEFT means even if there is no match, a left-hand row will still be included).
relBuilder.push(left);
} else {
final DruidSemiJoin druidSemiJoin = DruidSemiJoin.from(left, right, joinInfo.leftKeys, joinInfo.rightKeys, plannerConfig);
if (druidSemiJoin == null) {
return;
}
// Check maxQueryCount.
if (plannerConfig.getMaxQueryCount() > 0 && druidSemiJoin.getQueryCount() > plannerConfig.getMaxQueryCount()) {
return;
}
relBuilder.push(druidSemiJoin);
}
call.transformTo(relBuilder.project(project.getProjects(), project.getRowType().getFieldNames()).build());
}
use of org.apache.calcite.rel.core.Project in project drill by apache.
the class DrillPushProjIntoScan method onMatch.
@Override
public void onMatch(RelOptRuleCall call) {
final Project proj = (Project) call.rel(0);
final TableScan scan = (TableScan) call.rel(1);
try {
ProjectPushInfo columnInfo = PrelUtil.getColumns(scan.getRowType(), proj.getProjects());
// get DrillTable, either wrapped in RelOptTable, or DrillTranslatableTable.
DrillTable table = scan.getTable().unwrap(DrillTable.class);
if (table == null) {
table = scan.getTable().unwrap(DrillTranslatableTable.class).getDrillTable();
}
if (//
columnInfo == null || columnInfo.isStarQuery() || !//
table.getGroupScan().canPushdownProjects(columnInfo.columns)) {
return;
}
final DrillScanRel newScan = new DrillScanRel(scan.getCluster(), scan.getTraitSet().plus(DrillRel.DRILL_LOGICAL), scan.getTable(), columnInfo.createNewRowType(proj.getInput().getCluster().getTypeFactory()), columnInfo.columns);
List<RexNode> newProjects = Lists.newArrayList();
for (RexNode n : proj.getChildExps()) {
newProjects.add(n.accept(columnInfo.getInputRewriter()));
}
final DrillProjectRel newProj = new DrillProjectRel(proj.getCluster(), proj.getTraitSet().plus(DrillRel.DRILL_LOGICAL), newScan, newProjects, proj.getRowType());
if (ProjectRemoveRule.isTrivial(newProj)) {
call.transformTo(newScan);
} else {
call.transformTo(newProj);
}
} catch (IOException e) {
throw new DrillRuntimeException(e);
}
}
use of org.apache.calcite.rel.core.Project in project calcite by apache.
the class ElasticsearchFilter method implement.
@Override
public void implement(Implementor implementor) {
implementor.visitChild(0, getInput());
List<String> fieldNames;
if (input instanceof Project) {
final List<RexNode> projects = ((Project) input).getProjects();
fieldNames = new ArrayList<>(projects.size());
for (RexNode project : projects) {
String name = project.accept(MapProjectionFieldVisitor.INSTANCE);
fieldNames.add(name);
}
} else {
fieldNames = ElasticsearchRules.elasticsearchFieldNames(getRowType());
}
Translator translator = new Translator(fieldNames);
String match = translator.translateMatch(condition);
implementor.add(match);
}
use of org.apache.calcite.rel.core.Project in project calcite by apache.
the class ElasticsearchSort method implement.
@Override
public void implement(Implementor implementor) {
implementor.visitChild(0, getInput());
if (!collation.getFieldCollations().isEmpty()) {
final List<String> keys = new ArrayList<>();
if (input instanceof Project) {
final List<RexNode> projects = ((Project) input).getProjects();
for (RelFieldCollation fieldCollation : collation.getFieldCollations()) {
RexNode project = projects.get(fieldCollation.getFieldIndex());
String name = project.accept(MapProjectionFieldVisitor.INSTANCE);
keys.add(ElasticsearchRules.quote(name) + ": " + direction(fieldCollation));
}
} else {
final List<RelDataTypeField> fields = getRowType().getFieldList();
for (RelFieldCollation fieldCollation : collation.getFieldCollations()) {
final String name = fields.get(fieldCollation.getFieldIndex()).getName();
keys.add(ElasticsearchRules.quote(name) + ": " + direction(fieldCollation));
}
}
implementor.add("\"sort\": [ " + Util.toString(keys, "{", "}, {", "}") + "]");
}
if (offset != null) {
implementor.add("\"from\": " + ((RexLiteral) offset).getValue());
}
if (fetch != null) {
implementor.add("\"size\": " + ((RexLiteral) fetch).getValue());
}
}
Aggregations