/** * Generates code to round an expression according to the Farrago convention. The Farrago * convention is to round away from zero. Rounding is performed with the following algorithm. * * <pre> * in = rhs; * if (value < 0) { * in = -in; * out = Math.round(in); * out = -out; * } else { * out = Math.round(in); * } * </pre> * * <p>PRECONDITION: rhsExp must be an unwrapped (not null) Java primitive * * <p>TODO: account for overflow in both unary minus and round. */ private Expression roundAway() { // Get the primitive part of right hand side RelDataType inType = translator.getTypeFactory().createTypeWithNullability(rhsType, false); // TODO: is there any preference between stack and instance var? OJClass inClass = getClass(inType); Variable inTemp = translator.getRelImplementor().newVariable(); translator.addStatement(declareStackVar(inClass, inTemp, rhsExp)); OJClass outClass = getLhsClass(); Variable outTemp = translator.getRelImplementor().newVariable(); translator.addStatement(declareStackVar(outClass, outTemp, null)); boolean isLong = translator.getFarragoTypeFactory().getClassForPrimitive(lhsType) == long.class; addStatement( new IfStatement( new BinaryExpression(inTemp, BinaryExpression.LESS, Literal.constantZero()), new StatementList( assign(inTemp, minus(inClass, inTemp)), assign(outTemp, round(lhsClass, inTemp, isLong)), assign(outTemp, minus(outClass, outTemp))), new StatementList(assign(outTemp, round(lhsClass, inTemp, isLong))))); return outTemp; }
/** Gets an expression for the current date */ private Expression getCurrentDate() { // unfortunately, we hard code the method name here return translator.convertVariable( translator.getTypeFactory().createSqlType(SqlTypeName.DATE), "getContextVariable_CURRENT_DATE", new ExpressionList()); }
/** Creates a field access, as in expr.[value] */ private Expression getValue(RelDataType type, Expression expr) { FarragoTypeFactory factory = (FarragoTypeFactory) translator.getTypeFactory(); return factory.getValueAccessExpression(type, expr); }