use of org.apache.calcite.rel.core.Project in project calcite by apache.
the class SortProjectTransposeRule method onMatch.
// ~ Methods ----------------------------------------------------------------
public void onMatch(RelOptRuleCall call) {
final Sort sort = call.rel(0);
final Project project = call.rel(1);
final RelOptCluster cluster = project.getCluster();
if (sort.getConvention() != project.getConvention()) {
return;
}
// Determine mapping between project input and output fields. If sort
// relies on non-trivial expressions, we can't push.
final Mappings.TargetMapping map = RelOptUtil.permutationIgnoreCast(project.getProjects(), project.getInput().getRowType());
for (RelFieldCollation fc : sort.getCollation().getFieldCollations()) {
if (map.getTargetOpt(fc.getFieldIndex()) < 0) {
return;
}
final RexNode node = project.getProjects().get(fc.getFieldIndex());
if (node.isA(SqlKind.CAST)) {
// Check whether it is a monotonic preserving cast, otherwise we cannot push
final RexCall cast = (RexCall) node;
final RexCallBinding binding = RexCallBinding.create(cluster.getTypeFactory(), cast, ImmutableList.of(RelCollations.of(RexUtil.apply(map, fc))));
if (cast.getOperator().getMonotonicity(binding) == SqlMonotonicity.NOT_MONOTONIC) {
return;
}
}
}
final RelCollation newCollation = cluster.traitSet().canonize(RexUtil.apply(map, sort.getCollation()));
final Sort newSort = sort.copy(sort.getTraitSet().replace(newCollation), project.getInput(), newCollation, sort.offset, sort.fetch);
RelNode newProject = project.copy(sort.getTraitSet(), ImmutableList.<RelNode>of(newSort));
// Not only is newProject equivalent to sort;
// newSort is equivalent to project's input
// (but only if the sort is not also applying an offset/limit).
Map<RelNode, RelNode> equiv;
if (sort.offset == null && sort.fetch == null && cluster.getPlanner().getRelTraitDefs().contains(RelCollationTraitDef.INSTANCE)) {
equiv = ImmutableMap.of((RelNode) newSort, project.getInput());
} else {
equiv = ImmutableMap.of();
}
call.transformTo(newProject, equiv);
}
use of org.apache.calcite.rel.core.Project in project calcite by apache.
the class DruidQuery method deriveQuerySpec.
protected QuerySpec deriveQuerySpec() {
final RelDataType rowType = table.getRowType();
int i = 1;
Filter filterRel = null;
if (i < rels.size() && rels.get(i) instanceof Filter) {
filterRel = (Filter) rels.get(i++);
}
Project project = null;
if (i < rels.size() && rels.get(i) instanceof Project) {
project = (Project) rels.get(i++);
}
ImmutableBitSet groupSet = null;
List<AggregateCall> aggCalls = null;
List<String> aggNames = null;
if (i < rels.size() && rels.get(i) instanceof Aggregate) {
final Aggregate aggregate = (Aggregate) rels.get(i++);
groupSet = aggregate.getGroupSet();
aggCalls = aggregate.getAggCallList();
aggNames = Util.skip(aggregate.getRowType().getFieldNames(), groupSet.cardinality());
}
Filter havingFilter = null;
if (i < rels.size() && rels.get(i) instanceof Filter) {
havingFilter = (Filter) rels.get(i++);
}
Project postProject = null;
if (i < rels.size() && rels.get(i) instanceof Project) {
postProject = (Project) rels.get(i++);
}
List<Integer> collationIndexes = null;
List<Direction> collationDirections = null;
ImmutableBitSet.Builder numericCollationBitSetBuilder = ImmutableBitSet.builder();
Integer fetch = null;
if (i < rels.size() && rels.get(i) instanceof Sort) {
final Sort sort = (Sort) rels.get(i++);
collationIndexes = new ArrayList<>();
collationDirections = new ArrayList<>();
for (RelFieldCollation fCol : sort.collation.getFieldCollations()) {
collationIndexes.add(fCol.getFieldIndex());
collationDirections.add(fCol.getDirection());
if (sort.getRowType().getFieldList().get(fCol.getFieldIndex()).getType().getFamily() == SqlTypeFamily.NUMERIC) {
numericCollationBitSetBuilder.set(fCol.getFieldIndex());
}
}
fetch = sort.fetch != null ? RexLiteral.intValue(sort.fetch) : null;
}
if (i != rels.size()) {
throw new AssertionError("could not implement all rels");
}
return getQuery(rowType, filterRel, project, groupSet, aggCalls, aggNames, collationIndexes, collationDirections, numericCollationBitSetBuilder.build(), fetch, postProject, havingFilter);
}
use of org.apache.calcite.rel.core.Project in project drill by axbaretto.
the class DrillPushProjectIntoScanRule method onMatch.
@Override
public void onMatch(RelOptRuleCall call) {
final Project project = call.rel(0);
final TableScan scan = call.rel(1);
try {
if (scan.getRowType().getFieldList().isEmpty()) {
return;
}
ProjectPushInfo projectPushInfo = getFieldsInformation(scan.getRowType(), project.getProjects());
if (!canPushProjectIntoScan(scan.getTable(), projectPushInfo)) {
return;
}
final DrillScanRel newScan = new DrillScanRel(scan.getCluster(), scan.getTraitSet().plus(DrillRel.DRILL_LOGICAL), scan.getTable(), projectPushInfo.createNewRowType(project.getInput().getCluster().getTypeFactory()), projectPushInfo.getFields());
List<RexNode> newProjects = new ArrayList<>();
for (RexNode n : project.getChildExps()) {
newProjects.add(n.accept(projectPushInfo.getInputReWriter()));
}
final DrillProjectRel newProject = new DrillProjectRel(project.getCluster(), project.getTraitSet().plus(DrillRel.DRILL_LOGICAL), newScan, newProjects, project.getRowType());
if (ProjectRemoveRule.isTrivial(newProject)) {
call.transformTo(newScan);
} else {
call.transformTo(newProject);
}
} catch (IOException e) {
throw new DrillRuntimeException(e);
}
}
use of org.apache.calcite.rel.core.Project in project drill by axbaretto.
the class DrillMergeProjectRule method matches.
@Override
public boolean matches(RelOptRuleCall call) {
Project topProject = call.rel(0);
Project bottomProject = call.rel(1);
// Make sure both projects be LogicalProject.
if (topProject.getTraitSet().getTrait(ConventionTraitDef.INSTANCE) != Convention.NONE || bottomProject.getTraitSet().getTrait(ConventionTraitDef.INSTANCE) != Convention.NONE) {
return false;
}
// We have a complex output type do not fire the merge project rule
if (checkComplexOutput(topProject) || checkComplexOutput(bottomProject)) {
return false;
}
return true;
}
use of org.apache.calcite.rel.core.Project in project drill by axbaretto.
the class DefaultSqlHandler method addRenamedProject.
protected DrillRel addRenamedProject(DrillRel rel, RelDataType validatedRowType) {
RelDataType t = rel.getRowType();
RexBuilder b = rel.getCluster().getRexBuilder();
List<RexNode> projections = Lists.newArrayList();
int projectCount = t.getFieldList().size();
for (int i = 0; i < projectCount; i++) {
projections.add(b.makeInputRef(rel, i));
}
final List<String> fieldNames2 = SqlValidatorUtil.uniquify(validatedRowType.getFieldNames(), SqlValidatorUtil.EXPR_SUGGESTER, rel.getCluster().getTypeFactory().getTypeSystem().isSchemaCaseSensitive());
RelDataType newRowType = RexUtil.createStructType(rel.getCluster().getTypeFactory(), projections, fieldNames2);
DrillProjectRel topProj = DrillProjectRel.create(rel.getCluster(), rel.getTraitSet(), rel, projections, newRowType);
// Add a final non-trivial Project to get the validatedRowType, if child is not project.
if (rel instanceof Project && DrillRelOptUtil.isTrivialProject(topProj, true)) {
return rel;
} else {
return topProj;
}
}
Aggregations