use of org.apache.calcite.rex.RexBuilder in project hive by apache.
the class HiveReduceExpressionsWithStatsRule method onMatch.
@Override
public void onMatch(RelOptRuleCall call) {
final Filter filter = call.rel(0);
final RexBuilder rexBuilder = filter.getCluster().getRexBuilder();
final RelMetadataQuery metadataProvider = RelMetadataQuery.instance();
// 1. Recompose filter possibly by pulling out common elements from DNF
// expressions
RexNode newFilterCondition = RexUtil.pullFactors(rexBuilder, filter.getCondition());
// 2. Reduce filter with stats information
RexReplacer replacer = new RexReplacer(filter, rexBuilder, metadataProvider);
newFilterCondition = replacer.apply(newFilterCondition);
// 3. Transform if we have created a new filter operator
if (!filter.getCondition().toString().equals(newFilterCondition.toString())) {
Filter newFilter = filter.copy(filter.getTraitSet(), filter.getInput(), newFilterCondition);
call.transformTo(newFilter);
}
}
use of org.apache.calcite.rex.RexBuilder in project drill by apache.
the class DrillReduceAggregatesRule method reduceAvg.
private RexNode reduceAvg(Aggregate oldAggRel, AggregateCall oldCall, List<AggregateCall> newCalls, Map<AggregateCall, RexNode> aggCallMapping) {
final PlannerSettings plannerSettings = (PlannerSettings) oldAggRel.getCluster().getPlanner().getContext();
final boolean isInferenceEnabled = plannerSettings.isTypeInferenceEnabled();
final int nGroups = oldAggRel.getGroupCount();
RelDataTypeFactory typeFactory = oldAggRel.getCluster().getTypeFactory();
RexBuilder rexBuilder = oldAggRel.getCluster().getRexBuilder();
int iAvgInput = oldCall.getArgList().get(0);
RelDataType avgInputType = getFieldType(oldAggRel.getInput(), iAvgInput);
RelDataType sumType = typeFactory.createTypeWithNullability(avgInputType, avgInputType.isNullable() || nGroups == 0);
SqlAggFunction sumAgg = new SqlSumEmptyIsZeroAggFunction();
AggregateCall sumCall = AggregateCall.create(sumAgg, oldCall.isDistinct(), oldCall.getArgList(), -1, sumType, null);
final SqlCountAggFunction countAgg = (SqlCountAggFunction) SqlStdOperatorTable.COUNT;
final RelDataType countType = countAgg.getReturnType(typeFactory);
AggregateCall countCall = AggregateCall.create(countAgg, oldCall.isDistinct(), oldCall.getArgList(), -1, countType, null);
RexNode tmpsumRef = rexBuilder.addAggCall(sumCall, nGroups, oldAggRel.indicator, newCalls, aggCallMapping, ImmutableList.of(avgInputType));
RexNode tmpcountRef = rexBuilder.addAggCall(countCall, nGroups, oldAggRel.indicator, newCalls, aggCallMapping, ImmutableList.of(avgInputType));
RexNode n = rexBuilder.makeCall(SqlStdOperatorTable.CASE, rexBuilder.makeCall(SqlStdOperatorTable.EQUALS, tmpcountRef, rexBuilder.makeExactLiteral(BigDecimal.ZERO)), rexBuilder.constantNull(), tmpsumRef);
// NOTE: these references are with respect to the output
// of newAggRel
/*
RexNode numeratorRef =
rexBuilder.makeCall(CastHighOp,
rexBuilder.addAggCall(
sumCall,
nGroups,
newCalls,
aggCallMapping,
ImmutableList.of(avgInputType))
);
*/
RexNode numeratorRef = rexBuilder.makeCall(CastHighOp, n);
RexNode denominatorRef = rexBuilder.addAggCall(countCall, nGroups, oldAggRel.indicator, newCalls, aggCallMapping, ImmutableList.of(avgInputType));
if (isInferenceEnabled) {
return rexBuilder.makeCall(new DrillSqlOperator("divide", 2, true, oldCall.getType(), false), numeratorRef, denominatorRef);
} else {
final RexNode divideRef = rexBuilder.makeCall(SqlStdOperatorTable.DIVIDE, numeratorRef, denominatorRef);
return rexBuilder.makeCast(typeFactory.createSqlType(SqlTypeName.ANY), divideRef);
}
}
use of org.apache.calcite.rex.RexBuilder in project drill by apache.
the class DrillReduceAggregatesRule method reduceAggs.
/*
private boolean isMatch(AggregateCall call) {
if (call.getAggregation() instanceof SqlAvgAggFunction) {
final SqlAvgAggFunction.Subtype subtype =
((SqlAvgAggFunction) call.getAggregation()).getSubtype();
return (subtype == SqlAvgAggFunction.Subtype.AVG);
}
return false;
}
*/
/**
* Reduces all calls to AVG, STDDEV_POP, STDDEV_SAMP, VAR_POP, VAR_SAMP in
* the aggregates list to.
*
* <p>It handles newly generated common subexpressions since this was done
* at the sql2rel stage.
*/
private void reduceAggs(RelOptRuleCall ruleCall, Aggregate oldAggRel) {
RexBuilder rexBuilder = oldAggRel.getCluster().getRexBuilder();
List<AggregateCall> oldCalls = oldAggRel.getAggCallList();
final int nGroups = oldAggRel.getGroupCount();
List<AggregateCall> newCalls = new ArrayList<>();
Map<AggregateCall, RexNode> aggCallMapping = new HashMap<>();
List<RexNode> projList = new ArrayList<>();
// pass through group key
for (int i = 0; i < nGroups; ++i) {
projList.add(rexBuilder.makeInputRef(getFieldType(oldAggRel, i), i));
}
// List of input expressions. If a particular aggregate needs more, it
// will add an expression to the end, and we will create an extra
// project.
RelNode input = oldAggRel.getInput();
List<RexNode> inputExprs = new ArrayList<>();
for (RelDataTypeField field : input.getRowType().getFieldList()) {
inputExprs.add(rexBuilder.makeInputRef(field.getType(), inputExprs.size()));
}
// create new agg function calls and rest of project list together
for (AggregateCall oldCall : oldCalls) {
projList.add(reduceAgg(oldAggRel, oldCall, newCalls, aggCallMapping, inputExprs));
}
final int extraArgCount = inputExprs.size() - input.getRowType().getFieldCount();
if (extraArgCount > 0) {
input = RelOptUtil.createProject(input, inputExprs, CompositeList.of(input.getRowType().getFieldNames(), Collections.<String>nCopies(extraArgCount, null)));
}
Aggregate newAggRel = newAggregateRel(oldAggRel, input, newCalls);
RelNode projectRel = RelOptUtil.createProject(newAggRel, projList, oldAggRel.getRowType().getFieldNames());
ruleCall.transformTo(projectRel);
}
use of org.apache.calcite.rex.RexBuilder in project drill by apache.
the class DrillMergeFilterRule method onMatch.
//~ Methods ----------------------------------------------------------------
// implement RelOptRule
public void onMatch(RelOptRuleCall call) {
Filter topFilter = call.rel(0);
Filter bottomFilter = call.rel(1);
// use RexPrograms to merge the two FilterRels into a single program
// so we can convert the two FilterRel conditions to directly
// reference the bottom FilterRel's child
RexBuilder rexBuilder = topFilter.getCluster().getRexBuilder();
RexProgram bottomProgram = createProgram(bottomFilter);
RexProgram topProgram = createProgram(topFilter);
RexProgram mergedProgram = RexProgramBuilder.mergePrograms(topProgram, bottomProgram, rexBuilder);
RexNode newCondition = mergedProgram.expandLocalRef(mergedProgram.getCondition());
// if(!RexUtil.isFlat(newCondition)){
// RexCall newCall = (RexCall) newCondition;
// newCondition = rexBuilder.makeFlatCall( newCall.getOperator(), newCall.getOperands());
// }
Filter newFilterRel = (Filter) filterFactory.createFilter(bottomFilter.getInput(), RexUtil.flatten(rexBuilder, newCondition));
call.transformTo(newFilterRel);
}
use of org.apache.calcite.rex.RexBuilder in project drill by apache.
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