@Override public Statistics visitFunctionHolderExpression(FunctionHolderExpression holderExpr, Void value) throws RuntimeException { FuncHolder funcHolder = holderExpr.getHolder(); if (!(funcHolder instanceof DrillSimpleFuncHolder)) { // Only Drill function is allowed. return null; } final String funcName = ((DrillSimpleFuncHolder) funcHolder).getRegisteredNames()[0]; if (CastFunctions.isCastFunction(funcName)) { Statistics stat = holderExpr.args.get(0).accept(this, null); if (stat != null && !stat.isEmpty()) { return evalCastFunc(holderExpr, stat); } } return null; }
private Statistics evalCastFunc(FunctionHolderExpression holderExpr, Statistics input) { try { DrillSimpleFuncHolder funcHolder = (DrillSimpleFuncHolder) holderExpr.getHolder(); DrillSimpleFunc interpreter = funcHolder.createInterpreter(); final ValueHolder minHolder, maxHolder; TypeProtos.MinorType srcType = holderExpr.args.get(0).getMajorType().getMinorType(); TypeProtos.MinorType destType = holderExpr.getMajorType().getMinorType(); if (srcType.equals(destType)) { // same type cast ==> NoOp. return input; } else if (!CAST_FUNC.containsKey(srcType) || !CAST_FUNC.get(srcType).contains(destType)) { return null; // cast func between srcType and destType is NOT allowed. } switch (srcType) { case INT: minHolder = ValueHolderHelper.getIntHolder(((IntStatistics) input).getMin()); maxHolder = ValueHolderHelper.getIntHolder(((IntStatistics) input).getMax()); break; case BIGINT: minHolder = ValueHolderHelper.getBigIntHolder(((LongStatistics) input).getMin()); maxHolder = ValueHolderHelper.getBigIntHolder(((LongStatistics) input).getMax()); break; case FLOAT4: minHolder = ValueHolderHelper.getFloat4Holder(((FloatStatistics) input).getMin()); maxHolder = ValueHolderHelper.getFloat4Holder(((FloatStatistics) input).getMax()); break; case FLOAT8: minHolder = ValueHolderHelper.getFloat8Holder(((DoubleStatistics) input).getMin()); maxHolder = ValueHolderHelper.getFloat8Holder(((DoubleStatistics) input).getMax()); break; default: return null; } final ValueHolder[] args1 = {minHolder}; final ValueHolder[] args2 = {maxHolder}; final ValueHolder minFuncHolder = InterpreterEvaluator.evaluateFunction(interpreter, args1, holderExpr.getName()); final ValueHolder maxFuncHolder = InterpreterEvaluator.evaluateFunction(interpreter, args2, holderExpr.getName()); switch (destType) { // TODO : need handle # of nulls. case INT: return getStatistics( ((IntHolder) minFuncHolder).value, ((IntHolder) maxFuncHolder).value); case BIGINT: return getStatistics( ((BigIntHolder) minFuncHolder).value, ((BigIntHolder) maxFuncHolder).value); case FLOAT4: return getStatistics( ((Float4Holder) minFuncHolder).value, ((Float4Holder) maxFuncHolder).value); case FLOAT8: return getStatistics( ((Float8Holder) minFuncHolder).value, ((Float8Holder) maxFuncHolder).value); default: return null; } } catch (Exception e) { throw new DrillRuntimeException("Error in evaluating function of " + holderExpr.getName()); } }