class RexBuilder {

  protected RexLiteral makeLiteral(
      Comparable o,
      RelDataType type,
      SqlTypeName typeName) {
    // All literals except NULL have NOT NULL types.
    type = typeFactory.createTypeWithNullability(type, o == null);
    int p;
    switch (typeName) {
      case CHAR:
        // Character literals must have a charset and collation. Populate
        // from the type if necessary.
        assert o instanceof NlsString;
        NlsString nlsString = (NlsString) o;
        if ((nlsString.getCollation() == null)
            || (nlsString.getCharset() == null)) {
          assert type.getSqlTypeName() == SqlTypeName.CHAR;
          assert type.getCharset().name() != null;
          assert type.getCollation() != null;
          o = new NlsString(
              nlsString.getValue(),
              type.getCharset().name(),
              type.getCollation());
        }
        break;
      case TIME:
        assert o instanceof TimeString;
        p = type.getPrecision();
        if (p == RelDataType.PRECISION_NOT_SPECIFIED) {
          p = 0;
        }
        o = ((TimeString) o).round(p);
        break;
      case TIME_WITH_LOCAL_TIME_ZONE:
        assert o instanceof TimeString;
        p = type.getPrecision();
        if (p == RelDataType.PRECISION_NOT_SPECIFIED) {
          p = 0;
        }
        o = ((TimeString) o).round(p);
        break;
      case TIMESTAMP:
        assert o instanceof TimestampString;
        p = type.getPrecision();
        if (p == RelDataType.PRECISION_NOT_SPECIFIED) {
          p = 0;
        }
        o = ((TimestampString) o).round(p);
        break;
      case TIMESTAMP_WITH_LOCAL_TIME_ZONE:
        assert o instanceof TimestampString;
        p = type.getPrecision();
        if (p == RelDataType.PRECISION_NOT_SPECIFIED) {
          p = 0;
        }
        o = ((TimestampString) o).round(p);
    }
    return new RexLiteral(o, type, typeName);
  }

  public  RexBuilder(RelDataTypeFactory typeFactory);

}