use of org.apache.calcite.rel.core.Project in project flink by apache.
the class FlinkRelDecorrelator method projectedLiteral.
/**
* Returns a literal output field, or null if it is not literal.
*/
private static RexLiteral projectedLiteral(RelNode rel, int i) {
if (rel instanceof Project) {
final Project project = (Project) rel;
final RexNode node = project.getProjects().get(i);
if (node instanceof RexLiteral) {
return (RexLiteral) node;
}
}
return null;
}
use of org.apache.calcite.rel.core.Project in project storm by apache.
the class TridentProjectRule method convert.
@Override
public RelNode convert(RelNode rel) {
final Project project = (Project) rel;
final RelNode input = project.getInput();
return new TridentProjectRel(project.getCluster(), project.getTraitSet().replace(TridentLogicalConvention.INSTANCE), convert(input, input.getTraitSet().replace(TridentLogicalConvention.INSTANCE)), project.getProjects(), project.getRowType());
}
use of org.apache.calcite.rel.core.Project in project druid by druid-io.
the class GroupByRules method applyAggregate.
/**
* Applies a filter -> project -> aggregate chain to a druidRel. Do not call this method unless
* {@link #canApplyAggregate(DruidRel, Filter, Project, Aggregate)} returns true.
*
* @return new rel, or null if the chain cannot be applied
*/
private static DruidRel applyAggregate(final DruidRel druidRel, final Filter filter0, final Project project0, final Aggregate aggregate, final DruidOperatorTable operatorTable, final boolean approximateCountDistinct) {
Preconditions.checkState(canApplyAggregate(druidRel, filter0, project0, aggregate), "Cannot applyAggregate.");
final RowSignature sourceRowSignature;
final boolean isNestedQuery = druidRel.getQueryBuilder().getGrouping() != null;
if (isNestedQuery) {
// Nested groupBy; source row signature is the output signature of druidRel.
sourceRowSignature = druidRel.getOutputRowSignature();
} else {
sourceRowSignature = druidRel.getSourceRowSignature();
}
// Filter that should be applied before aggregating.
final DimFilter filter;
if (filter0 != null) {
filter = Expressions.toFilter(operatorTable, druidRel.getPlannerContext(), sourceRowSignature, filter0.getCondition());
if (filter == null) {
// Can't plan this filter.
return null;
}
} else if (druidRel.getQueryBuilder().getFilter() != null && !isNestedQuery) {
// We're going to replace the existing druidRel, so inherit its filter.
filter = druidRel.getQueryBuilder().getFilter();
} else {
filter = null;
}
// Projection that should be applied before aggregating.
final Project project;
if (project0 != null) {
project = project0;
} else if (druidRel.getQueryBuilder().getSelectProjection() != null && !isNestedQuery) {
// We're going to replace the existing druidRel, so inherit its projection.
project = druidRel.getQueryBuilder().getSelectProjection().getProject();
} else {
project = null;
}
final List<DimensionSpec> dimensions = Lists.newArrayList();
final List<Aggregation> aggregations = Lists.newArrayList();
final List<String> rowOrder = Lists.newArrayList();
// Translate groupSet.
final ImmutableBitSet groupSet = aggregate.getGroupSet();
int dimOutputNameCounter = 0;
for (int i : groupSet) {
if (project != null && project.getChildExps().get(i) instanceof RexLiteral) {
// Ignore literals in GROUP BY, so a user can write e.g. "GROUP BY 'dummy'" to group everything into a single
// row. Add dummy rowOrder entry so NULLs come out. This is not strictly correct but it works as long as
// nobody actually expects to see the literal.
rowOrder.add(dimOutputName(dimOutputNameCounter++));
} else {
final RexNode rexNode = Expressions.fromFieldAccess(sourceRowSignature, project, i);
final RowExtraction rex = Expressions.toRowExtraction(operatorTable, druidRel.getPlannerContext(), sourceRowSignature.getRowOrder(), rexNode);
if (rex == null) {
return null;
}
final SqlTypeName sqlTypeName = rexNode.getType().getSqlTypeName();
final ValueType outputType = Calcites.getValueTypeForSqlTypeName(sqlTypeName);
if (outputType == null) {
throw new ISE("Cannot translate sqlTypeName[%s] to Druid type for field[%s]", sqlTypeName, rowOrder.get(i));
}
final DimensionSpec dimensionSpec = rex.toDimensionSpec(sourceRowSignature, dimOutputName(dimOutputNameCounter++), outputType);
if (dimensionSpec == null) {
return null;
}
dimensions.add(dimensionSpec);
rowOrder.add(dimensionSpec.getOutputName());
}
}
// Translate aggregates.
for (int i = 0; i < aggregate.getAggCallList().size(); i++) {
final AggregateCall aggCall = aggregate.getAggCallList().get(i);
final Aggregation aggregation = translateAggregateCall(druidRel.getPlannerContext(), sourceRowSignature, project, aggCall, operatorTable, aggregations, i, approximateCountDistinct);
if (aggregation == null) {
return null;
}
aggregations.add(aggregation);
rowOrder.add(aggregation.getOutputName());
}
if (isNestedQuery) {
// Nested groupBy.
return DruidNestedGroupBy.from(druidRel, filter, Grouping.create(dimensions, aggregations), aggregate.getRowType(), rowOrder);
} else {
// groupBy on a base dataSource.
return druidRel.withQueryBuilder(druidRel.getQueryBuilder().withFilter(filter).withGrouping(Grouping.create(dimensions, aggregations), aggregate.getRowType(), rowOrder));
}
}
use of org.apache.calcite.rel.core.Project in project hive by apache.
the class HiveSubQRemoveRelBuilder method sortLimit.
/**
* Creates a {@link Sort} by a list of expressions, with limit and offset.
*
* @param offset Number of rows to skip; non-positive means don't skip any
* @param fetch Maximum number of rows to fetch; negative means no limit
* @param nodes Sort expressions
*/
public HiveSubQRemoveRelBuilder sortLimit(int offset, int fetch, Iterable<? extends RexNode> nodes) {
final List<RelFieldCollation> fieldCollations = new ArrayList<>();
final RelDataType inputRowType = peek().getRowType();
final List<RexNode> extraNodes = projects(inputRowType);
final List<RexNode> originalExtraNodes = ImmutableList.copyOf(extraNodes);
for (RexNode node : nodes) {
fieldCollations.add(collation(node, RelFieldCollation.Direction.ASCENDING, null, extraNodes));
}
final RexNode offsetNode = offset <= 0 ? null : literal(offset);
final RexNode fetchNode = fetch < 0 ? null : literal(fetch);
if (offsetNode == null && fetch == 0) {
return empty();
}
if (offsetNode == null && fetchNode == null && fieldCollations.isEmpty()) {
// sort is trivial
return this;
}
final boolean addedFields = extraNodes.size() > originalExtraNodes.size();
if (fieldCollations.isEmpty()) {
assert !addedFields;
RelNode top = peek();
if (top instanceof Sort) {
final Sort sort2 = (Sort) top;
if (sort2.offset == null && sort2.fetch == null) {
stack.pop();
push(sort2.getInput());
final RelNode sort = sortFactory.createSort(build(), sort2.collation, offsetNode, fetchNode);
push(sort);
return this;
}
}
if (top instanceof Project) {
final Project project = (Project) top;
if (project.getInput() instanceof Sort) {
final Sort sort2 = (Sort) project.getInput();
if (sort2.offset == null && sort2.fetch == null) {
stack.pop();
push(sort2.getInput());
final RelNode sort = sortFactory.createSort(build(), sort2.collation, offsetNode, fetchNode);
push(sort);
project(project.getProjects());
return this;
}
}
}
}
if (addedFields) {
project(extraNodes);
}
final RelNode sort = sortFactory.createSort(build(), RelCollations.of(fieldCollations), offsetNode, fetchNode);
push(sort);
if (addedFields) {
project(originalExtraNodes);
}
return this;
}
use of org.apache.calcite.rel.core.Project in project drill by axbaretto.
the class DrillPushFilterPastProjectRule method onMatch.
// ~ Methods ----------------------------------------------------------------
// implement RelOptRule
public void onMatch(RelOptRuleCall call) {
Filter filterRel = call.rel(0);
Project projRel = call.rel(1);
// get a conjunctions of the filter condition. For each conjunction, if it refers to ITEM or FLATTEN expression
// then we could not pushed down. Otherwise, it's qualified to be pushed down.
final List<RexNode> predList = RelOptUtil.conjunctions(filterRel.getCondition());
final List<RexNode> qualifiedPredList = Lists.newArrayList();
final List<RexNode> unqualifiedPredList = Lists.newArrayList();
for (final RexNode pred : predList) {
if (DrillRelOptUtil.findOperators(pred, projRel.getProjects(), BANNED_OPERATORS) == null) {
qualifiedPredList.add(pred);
} else {
unqualifiedPredList.add(pred);
}
}
final RexNode qualifedPred = RexUtil.composeConjunction(filterRel.getCluster().getRexBuilder(), qualifiedPredList, true);
if (qualifedPred == null) {
return;
}
// convert the filter to one that references the child of the project
RexNode newCondition = RelOptUtil.pushPastProject(qualifedPred, projRel);
Filter newFilterRel = LogicalFilter.create(projRel.getInput(), newCondition);
Project newProjRel = (Project) RelOptUtil.createProject(newFilterRel, Pair.left(projRel.getNamedProjects()), Pair.right(projRel.getNamedProjects()), false, relBuilderFactory.create(projRel.getCluster(), null));
final RexNode unqualifiedPred = RexUtil.composeConjunction(filterRel.getCluster().getRexBuilder(), unqualifiedPredList, true);
if (unqualifiedPred == null) {
call.transformTo(newProjRel);
} else {
// if there are filters not qualified to be pushed down, then we have to put those filters on top of
// the new Project operator.
// Filter -- unqualified filters
// \
// Project
// \
// Filter -- qualified filters
Filter filterNotPushed = LogicalFilter.create(newProjRel, unqualifiedPred);
call.transformTo(filterNotPushed);
}
}
Aggregations