/** 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(
       clazz,
       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();
        translator.addStatement(
            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.
        checkOverflow();
      } 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(
                OJClass.forClass(NullablePrimitive.NullableBoolean.class),
                "convertString",
                new ExpressionList(str));
      } else {
        // In general, check for overflow
        checkOverflow();
      }

      roundAsNeeded();

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