use of org.apache.calcite.rel.logical.LogicalProject in project flink by apache.
the class ProjectWatermarkAssignerTransposeRule method matches.
@Override
public boolean matches(RelOptRuleCall call) {
LogicalProject project = call.rel(0);
LogicalWatermarkAssigner watermarkAssigner = call.rel(1);
NestedSchema usedFieldInProjectIncludingRowTimeFields = getUsedFieldsInTopLevelProjectAndWatermarkAssigner(project, watermarkAssigner);
return usedFieldInProjectIncludingRowTimeFields.columns().size() != watermarkAssigner.getRowType().getFieldCount();
}
use of org.apache.calcite.rel.logical.LogicalProject in project beam by apache.
the class AggregateScanConverter method convert.
@Override
public RelNode convert(ResolvedAggregateScan zetaNode, List<RelNode> inputs) {
LogicalProject input = convertAggregateScanInputScanToLogicalProject(zetaNode, inputs.get(0));
// Calcite LogicalAggregate's GroupSet is indexes of group fields starting from 0.
int groupFieldsListSize = zetaNode.getGroupByList().size();
ImmutableBitSet groupSet;
if (groupFieldsListSize != 0) {
groupSet = ImmutableBitSet.of(IntStream.rangeClosed(0, groupFieldsListSize - 1).boxed().collect(Collectors.toList()));
} else {
groupSet = ImmutableBitSet.of();
}
// TODO: add support for indicator
List<AggregateCall> aggregateCalls;
if (zetaNode.getAggregateList().isEmpty()) {
aggregateCalls = ImmutableList.of();
} else {
aggregateCalls = new ArrayList<>();
// For aggregate calls, their input ref follow after GROUP BY input ref.
int columnRefoff = groupFieldsListSize;
for (ResolvedComputedColumn computedColumn : zetaNode.getAggregateList()) {
AggregateCall aggCall = convertAggCall(computedColumn, columnRefoff, groupSet.size(), input);
aggregateCalls.add(aggCall);
if (!aggCall.getArgList().isEmpty()) {
// Only increment column reference offset when aggregates use them (BEAM-8042).
// Ex: COUNT(*) does not have arguments, while COUNT(`field`) does.
columnRefoff++;
}
}
}
LogicalAggregate logicalAggregate = new LogicalAggregate(getCluster(), input.getTraitSet(), input, groupSet, ImmutableList.of(groupSet), aggregateCalls);
return logicalAggregate;
}
use of org.apache.calcite.rel.logical.LogicalProject in project beam by apache.
the class BeamZetaSqlUnnestRule method onMatch.
@Override
public void onMatch(RelOptRuleCall call) {
LogicalCorrelate correlate = call.rel(0);
RelNode outer = call.rel(1);
RelNode uncollect = call.rel(2);
if (correlate.getRequiredColumns().cardinality() != 1) {
// can only unnest a single column
return;
}
if (correlate.getJoinType() != JoinRelType.INNER) {
return;
}
if (!(uncollect instanceof ZetaSqlUnnest)) {
// Drop projection
uncollect = ((SingleRel) uncollect).getInput();
if (uncollect instanceof RelSubset) {
uncollect = ((RelSubset) uncollect).getOriginal();
}
if (!(uncollect instanceof ZetaSqlUnnest)) {
return;
}
}
RelNode project = ((ZetaSqlUnnest) uncollect).getInput();
if (project instanceof RelSubset) {
project = ((RelSubset) project).getOriginal();
}
if (!(project instanceof LogicalProject)) {
return;
}
if (((LogicalProject) project).getProjects().size() != 1) {
// can only unnest a single column
return;
}
RexNode exp = ((LogicalProject) project).getProjects().get(0);
if (!(exp instanceof RexFieldAccess)) {
return;
}
RexFieldAccess fieldAccess = (RexFieldAccess) exp;
// Innermost field index comes first (e.g. struct.field1.field2 => [2, 1])
ImmutableList.Builder<Integer> fieldAccessIndices = ImmutableList.builder();
while (true) {
fieldAccessIndices.add(fieldAccess.getField().getIndex());
if (!(fieldAccess.getReferenceExpr() instanceof RexFieldAccess)) {
break;
}
fieldAccess = (RexFieldAccess) fieldAccess.getReferenceExpr();
}
call.transformTo(new BeamZetaSqlUnnestRel(correlate.getCluster(), correlate.getTraitSet().replace(BeamLogicalConvention.INSTANCE), convert(outer, outer.getTraitSet().replace(BeamLogicalConvention.INSTANCE)), call.rel(2).getRowType(), fieldAccessIndices.build()));
}
use of org.apache.calcite.rel.logical.LogicalProject in project nifi by apache.
the class FlowFileProjectTableScanRule method onMatch.
@Override
public void onMatch(RelOptRuleCall call) {
final LogicalProject project = call.rel(0);
final FlowFileTableScan scan = call.rel(1);
final int[] fields = getProjectFields(project.getProjects());
if (fields == null) {
// Project contains expressions more complex than just field references.
return;
}
call.transformTo(new FlowFileTableScan(scan.getCluster(), scan.getTable(), scan.flowFileTable, fields));
}
use of org.apache.calcite.rel.logical.LogicalProject in project drill by axbaretto.
the class PreProcessLogicalRel method visit.
@Override
public RelNode visit(LogicalProject project) {
final List<RexNode> projExpr = Lists.newArrayList();
for (RexNode rexNode : project.getChildExps()) {
projExpr.add(rexNode.accept(unwrappingExpressionVisitor));
}
project = project.copy(project.getTraitSet(), project.getInput(), projExpr, project.getRowType());
List<RexNode> exprList = new ArrayList<>();
boolean rewrite = false;
for (RexNode rex : project.getChildExps()) {
RexNode newExpr = rex;
if (rex instanceof RexCall) {
RexCall function = (RexCall) rex;
String functionName = function.getOperator().getName();
int nArgs = function.getOperands().size();
// check if its a convert_from or convert_to function
if (functionName.equalsIgnoreCase("convert_from") || functionName.equalsIgnoreCase("convert_to")) {
String literal;
if (nArgs == 2) {
if (function.getOperands().get(1) instanceof RexLiteral) {
try {
literal = ((NlsString) (((RexLiteral) function.getOperands().get(1)).getValue())).getValue();
} catch (final ClassCastException e) {
// Caused by user entering a value with a non-string literal
throw getConvertFunctionInvalidTypeException(function);
}
} else {
// caused by user entering a non-literal
throw getConvertFunctionInvalidTypeException(function);
}
} else {
// Second operand is missing
throw UserException.parseError().message("'%s' expects a string literal as a second argument.", functionName).build(logger);
}
RexBuilder builder = new RexBuilder(factory);
// construct the new function name based on the input argument
String newFunctionName = functionName + literal;
// Look up the new function name in the drill operator table
List<SqlOperator> operatorList = table.getSqlOperator(newFunctionName);
if (operatorList.size() == 0) {
// User typed in an invalid type name
throw getConvertFunctionException(functionName, literal);
}
SqlFunction newFunction = null;
// Find the SqlFunction with the correct args
for (SqlOperator op : operatorList) {
if (op.getOperandTypeChecker().getOperandCountRange().isValidCount(nArgs - 1)) {
newFunction = (SqlFunction) op;
break;
}
}
if (newFunction == null) {
// we are here because we found some dummy convert function. (See DummyConvertFrom and DummyConvertTo)
throw getConvertFunctionException(functionName, literal);
}
// create the new expression to be used in the rewritten project
newExpr = builder.makeCall(newFunction, function.getOperands().subList(0, 1));
rewrite = true;
}
}
exprList.add(newExpr);
}
if (rewrite == true) {
LogicalProject newProject = project.copy(project.getTraitSet(), project.getInput(0), exprList, project.getRowType());
return visitChild(newProject, 0, project.getInput());
}
return visitChild(project, 0, project.getInput());
}
Aggregations