/** Gets the OJ class for a RelDataType */
    private OJClass getClass(RelDataType type) {
      // TODO: is this code any better?
      // OJUtil.typeToOJClass(
      //     rhsType,
      //     translator.getFarragoTypeFactory());

      FarragoTypeFactory factory = translator.getFarragoTypeFactory();
      return OJClass.forClass(factory.getClassForPrimitive(type));
  * Generates code to round an expression up and cast it. Performs a lenient rounding. Values
  * less than target min or max become the min or max while, rounding (not a number) results in
  * zero.
  * @param clazz type to cast rounded expression as
  * @param expr expression to be rounded
  * @param isLong whether the result should have long precision
 private Expression round(OJClass clazz, Expression expr, boolean isLong) {
   Expression arg = expr;
   if (isLong) {
     arg = new CastExpression(OJClass.forClass(double.class), expr);
   return new CastExpression(
       new MethodCall(
           new Literal(Literal.STRING, "java.lang.Math"), "round", new ExpressionList(arg)));
     * Casts the rhs to a non nullable primitive value. Non nullable primitive values only have a
     * single value field.
    private Expression castToNotNullPrimitive() {
      // If the left and the right types are the same, perform a
      // trivial cast.
      if (lhsType == rhsType) {
        return getDirectAssignment();

      // Retrieve the value of the right side if it is a nullable
      // primitive or a Datetime or an Interval type.
      // TODO: is Decimal a nullable primitive?
      if (translator.isNullablePrimitive(rhsType)
          || SqlTypeUtil.isDatetime(rhsType)
          || SqlTypeUtil.isInterval(rhsType)) {
        rhsExp = getValue(rhsType, rhsExp);

      // Get the name of the numeric class such as Byte, Short, etc.
      String numClassName = SqlTypeUtil.getNumericJavaClassName(lhsType);
      OJClass lhsClass = getLhsClass();

      // When casting from a string (or binary) to a number, trim the
      // value and perform the cast by calling a class-specific parsing
      // function.
      if ((numClassName != null)
          && SqlTypeUtil.inCharOrBinaryFamilies(rhsType)
          && !SqlTypeUtil.isLob(rhsType)) {
        // TODO: toString will cause too much garbage collection.
        rhsExp = new MethodCall(rhsExp, "toString", new ExpressionList());
        rhsExp = new MethodCall(rhsExp, "trim", new ExpressionList());
        String methodName = "parse" + numClassName;
        if (lhsType.getSqlTypeName() == SqlTypeName.INTEGER) {
          methodName = "parseInt";
        rhsExp =
            new MethodCall(
                new Literal(Literal.STRING, numClassName), methodName, new ExpressionList(rhsExp));

        Variable outTemp = translator.getRelImplementor().newVariable();
            new VariableDeclaration(
                TypeName.forOJClass(lhsClass), new VariableDeclarator(outTemp.toString(), rhsExp)));
        rhsExp = outTemp;

        // Note: this check for overflow should only be required
        // when the string conversion does not perform a check.
      } else if ((lhsType.getSqlTypeName() == SqlTypeName.BOOLEAN)
          && SqlTypeUtil.inCharOrBinaryFamilies(rhsType)
          && !SqlTypeUtil.isLob(rhsType)) {
        // Casting from string to boolean relies on the runtime type.
        // Note: string is trimmed by conversion method.

        // TODO: toString will cause too much garbage collection.
        Expression str = new MethodCall(rhsExp, "toString", new ExpressionList());

        rhsExp =
            new MethodCall(
                new ExpressionList(str));
      } else {
        // In general, check for overflow


      rhsExp = new CastExpression(lhsClass, rhsExp);
      return getDirectAssignment();