use of org.apache.calcite.sql.SqlAggFunction in project drill by apache.
the class DrillOperatorTable method populateWrappedCalciteOperators.
private void populateWrappedCalciteOperators() {
for (SqlOperator calciteOperator : inner.getOperatorList()) {
final SqlOperator wrapper;
if (calciteOperator instanceof SqlAggFunction) {
wrapper = new DrillCalciteSqlAggFunctionWrapper((SqlAggFunction) calciteOperator, getFunctionListWithInference(calciteOperator.getName()));
} else if (calciteOperator instanceof SqlFunction) {
wrapper = new DrillCalciteSqlFunctionWrapper((SqlFunction) calciteOperator, getFunctionListWithInference(calciteOperator.getName()));
} else if (calciteOperator instanceof SqlBetweenOperator) {
// During the procedure of converting to RexNode,
// StandardConvertletTable.convertBetween expects the SqlOperator to be a subclass of SqlBetweenOperator
final SqlBetweenOperator sqlBetweenOperator = (SqlBetweenOperator) calciteOperator;
wrapper = new DrillCalciteSqlBetweenOperatorWrapper(sqlBetweenOperator);
} else {
final String drillOpName;
// Otherwise, Calcite will mix them up with binary operator subtract (-) or add (+)
if (calciteOperator == SqlStdOperatorTable.UNARY_MINUS || calciteOperator == SqlStdOperatorTable.UNARY_PLUS) {
drillOpName = calciteOperator.getName();
} else {
drillOpName = FunctionCallFactory.convertToDrillFunctionName(calciteOperator.getName());
}
final List<DrillFuncHolder> drillFuncHolders = getFunctionListWithInference(drillOpName);
if (drillFuncHolders.isEmpty()) {
continue;
}
wrapper = new DrillCalciteSqlOperatorWrapper(calciteOperator, drillOpName, drillFuncHolders);
}
calciteToWrapper.put(calciteOperator, wrapper);
}
}
use of org.apache.calcite.sql.SqlAggFunction in project flink by apache.
the class HiveParserUtils method toAggCall.
public static AggregateCall toAggCall(HiveParserBaseSemanticAnalyzer.AggInfo aggInfo, HiveParserRexNodeConverter converter, Map<String, Integer> rexNodeToPos, int groupCount, RelNode input, RelOptCluster cluster, SqlFunctionConverter funcConverter) throws SemanticException {
// 1. Get agg fn ret type in Calcite
RelDataType aggFnRetType = HiveParserUtils.toRelDataType(aggInfo.getReturnType(), cluster.getTypeFactory());
// 2. Convert Agg Fn args and type of args to Calcite
// TODO: Does HQL allows expressions as aggregate args or can it only be projections from
// child?
List<Integer> argIndices = new ArrayList<>();
RelDataTypeFactory typeFactory = cluster.getTypeFactory();
List<RelDataType> calciteArgTypes = new ArrayList<>();
for (ExprNodeDesc expr : aggInfo.getAggParams()) {
RexNode paramRex = converter.convert(expr).accept(funcConverter);
Integer argIndex = Preconditions.checkNotNull(rexNodeToPos.get(paramRex.toString()));
argIndices.add(argIndex);
// TODO: does arg need type cast?
calciteArgTypes.add(HiveParserUtils.toRelDataType(expr.getTypeInfo(), typeFactory));
}
// 3. Get Aggregation FN from Calcite given name, ret type and input arg type
final SqlAggFunction aggFunc = HiveParserSqlFunctionConverter.getCalciteAggFn(aggInfo.getUdfName(), aggInfo.isDistinct(), calciteArgTypes, aggFnRetType);
// If we have input arguments, set type to null (instead of aggFnRetType) to let
// AggregateCall
// infer the type, so as to avoid nullability mismatch
RelDataType type = null;
if (aggInfo.isAllColumns() && argIndices.isEmpty()) {
type = aggFnRetType;
}
return AggregateCall.create((SqlAggFunction) funcConverter.convertOperator(aggFunc), aggInfo.isDistinct(), false, false, argIndices, -1, RelCollations.EMPTY, groupCount, input, type, aggInfo.getAlias());
}
use of org.apache.calcite.sql.SqlAggFunction in project flink by apache.
the class SqlFunctionConverter method visitOver.
@Override
public RexNode visitOver(RexOver over) {
SqlOperator operator = convertOperator(over.getAggOperator());
Preconditions.checkArgument(operator instanceof SqlAggFunction, "Expect converted operator to be an agg function, but got " + operator.toString());
SqlAggFunction convertedAgg = (SqlAggFunction) operator;
RexWindow window = over.getWindow();
// let's not rely on the type of the RexOver created by Hive since it can be different from
// what Flink expects
RelDataType inferredType = builder.makeCall(convertedAgg, over.getOperands()).getType();
// Hive may add literals to partition keys, remove them
List<RexNode> partitionKeys = new ArrayList<>();
for (RexNode hivePartitionKey : getPartKeys(window)) {
if (!(hivePartitionKey instanceof RexLiteral)) {
partitionKeys.add(hivePartitionKey);
}
}
List<RexFieldCollation> convertedOrderKeys = new ArrayList<>(getOrderKeys(window).size());
for (RexFieldCollation orderKey : getOrderKeys(window)) {
convertedOrderKeys.add(new RexFieldCollation(orderKey.getKey().accept(this), orderKey.getValue()));
}
final boolean[] update = null;
return HiveParserUtils.makeOver(builder, inferredType, convertedAgg, visitList(over.getOperands(), update), visitList(partitionKeys, update), convertedOrderKeys, window.getLowerBound(), window.getUpperBound(), window.isRows(), true, false, false, false);
}
use of org.apache.calcite.sql.SqlAggFunction in project flink by apache.
the class HiveParserCalcitePlanner method getWindowRexAndType.
private Pair<RexNode, TypeInfo> getWindowRexAndType(HiveParserWindowingSpec.WindowExpressionSpec winExprSpec, RelNode srcRel) throws SemanticException {
RexNode window;
if (winExprSpec instanceof HiveParserWindowingSpec.WindowFunctionSpec) {
HiveParserWindowingSpec.WindowFunctionSpec wFnSpec = (HiveParserWindowingSpec.WindowFunctionSpec) winExprSpec;
HiveParserASTNode windowProjAst = wFnSpec.getExpression();
// TODO: do we need to get to child?
int wndSpecASTIndx = getWindowSpecIndx(windowProjAst);
// 2. Get Hive Aggregate Info
AggInfo hiveAggInfo = getHiveAggInfo(windowProjAst, wndSpecASTIndx - 1, relToRowResolver.get(srcRel), (HiveParserWindowingSpec.WindowFunctionSpec) winExprSpec, semanticAnalyzer, frameworkConfig, cluster);
// 3. Get Calcite Return type for Agg Fn
RelDataType calciteAggFnRetType = HiveParserUtils.toRelDataType(hiveAggInfo.getReturnType(), cluster.getTypeFactory());
// 4. Convert Agg Fn args to Calcite
Map<String, Integer> posMap = relToHiveColNameCalcitePosMap.get(srcRel);
HiveParserRexNodeConverter converter = new HiveParserRexNodeConverter(cluster, srcRel.getRowType(), posMap, 0, false, funcConverter);
List<RexNode> calciteAggFnArgs = new ArrayList<>();
List<RelDataType> calciteAggFnArgTypes = new ArrayList<>();
for (int i = 0; i < hiveAggInfo.getAggParams().size(); i++) {
calciteAggFnArgs.add(converter.convert(hiveAggInfo.getAggParams().get(i)));
calciteAggFnArgTypes.add(HiveParserUtils.toRelDataType(hiveAggInfo.getAggParams().get(i).getTypeInfo(), cluster.getTypeFactory()));
}
// 5. Get Calcite Agg Fn
final SqlAggFunction calciteAggFn = HiveParserSqlFunctionConverter.getCalciteAggFn(hiveAggInfo.getUdfName(), hiveAggInfo.isDistinct(), calciteAggFnArgTypes, calciteAggFnRetType);
// 6. Translate Window spec
HiveParserRowResolver inputRR = relToRowResolver.get(srcRel);
HiveParserWindowingSpec.WindowSpec wndSpec = ((HiveParserWindowingSpec.WindowFunctionSpec) winExprSpec).getWindowSpec();
List<RexNode> partitionKeys = getPartitionKeys(wndSpec.getPartition(), converter, inputRR, new HiveParserTypeCheckCtx(inputRR, frameworkConfig, cluster), semanticAnalyzer);
List<RexFieldCollation> orderKeys = getOrderKeys(wndSpec.getOrder(), converter, inputRR, new HiveParserTypeCheckCtx(inputRR, frameworkConfig, cluster), semanticAnalyzer);
RexWindowBound lowerBound = getBound(wndSpec.getWindowFrame().getStart(), cluster);
RexWindowBound upperBound = getBound(wndSpec.getWindowFrame().getEnd(), cluster);
boolean isRows = wndSpec.getWindowFrame().getWindowType() == HiveParserWindowingSpec.WindowType.ROWS;
window = HiveParserUtils.makeOver(cluster.getRexBuilder(), calciteAggFnRetType, calciteAggFn, calciteAggFnArgs, partitionKeys, orderKeys, lowerBound, upperBound, isRows, true, false, false, false);
window = window.accept(funcConverter);
} else {
throw new SemanticException("Unsupported window Spec");
}
return new Pair<>(window, HiveParserTypeConverter.convert(window.getType()));
}
use of org.apache.calcite.sql.SqlAggFunction in project flink by apache.
the class OverConvertRule method convert.
@Override
public Optional<RexNode> convert(CallExpression call, ConvertContext context) {
List<Expression> children = call.getChildren();
if (call.getFunctionDefinition() == BuiltInFunctionDefinitions.OVER) {
FlinkTypeFactory typeFactory = context.getTypeFactory();
Expression agg = children.get(0);
FunctionDefinition def = ((CallExpression) agg).getFunctionDefinition();
boolean isDistinct = BuiltInFunctionDefinitions.DISTINCT == def;
SqlAggFunction aggFunc = agg.accept(new SqlAggFunctionVisitor(context.getRelBuilder()));
RelDataType aggResultType = typeFactory.createFieldTypeFromLogicalType(fromDataTypeToLogicalType(((ResolvedExpression) agg).getOutputDataType()));
// assemble exprs by agg children
List<RexNode> aggExprs = agg.getChildren().stream().map(child -> {
if (isDistinct) {
return context.toRexNode(child.getChildren().get(0));
} else {
return context.toRexNode(child);
}
}).collect(Collectors.toList());
// assemble order by key
Expression orderKeyExpr = children.get(1);
Set<SqlKind> kinds = new HashSet<>();
RexNode collationRexNode = createCollation(context.toRexNode(orderKeyExpr), RelFieldCollation.Direction.ASCENDING, null, kinds);
ImmutableList<RexFieldCollation> orderKey = ImmutableList.of(new RexFieldCollation(collationRexNode, kinds));
// assemble partition by keys
List<RexNode> partitionKeys = children.subList(4, children.size()).stream().map(context::toRexNode).collect(Collectors.toList());
// assemble bounds
Expression preceding = children.get(2);
boolean isPhysical = fromDataTypeToLogicalType(((ResolvedExpression) preceding).getOutputDataType()).is(LogicalTypeRoot.BIGINT);
Expression following = children.get(3);
RexWindowBound lowerBound = createBound(context, preceding, SqlKind.PRECEDING);
RexWindowBound upperBound = createBound(context, following, SqlKind.FOLLOWING);
// build RexOver
return Optional.of(context.getRelBuilder().getRexBuilder().makeOver(aggResultType, aggFunc, aggExprs, partitionKeys, orderKey, lowerBound, upperBound, isPhysical, true, false, isDistinct));
}
return Optional.empty();
}
Aggregations