private void testCastTrim() {
    Value v;
    String spaces = new String(new char[100]).replace((char) 0, ' ');

    v = ValueArray.get(new Value[] {ValueString.get("hello"), ValueString.get("world")});
    assertEquals(10, v.getPrecision());
    assertEquals(5, v.convertPrecision(5, true).getPrecision());
    v = ValueArray.get(new Value[] {ValueString.get(""), ValueString.get("")});
    assertEquals(0, v.getPrecision());
    assertEquals("('')", v.convertPrecision(1, true).toString());

    v = ValueBytes.get(spaces.getBytes());
    assertEquals(100, v.getPrecision());
    assertEquals(10, v.convertPrecision(10, false).getPrecision());
    assertEquals(10, v.convertPrecision(10, false).getBytes().length);
    assertEquals(32, v.convertPrecision(10, false).getBytes()[9]);
    assertEquals(10, v.convertPrecision(10, true).getPrecision());

    final Value vd = ValueDecimal.get(new BigDecimal("1234567890.123456789"));
    assertEquals(19, vd.getPrecision());
    assertEquals("1234567890.1234567", vd.convertPrecision(10, true).getString());
    new AssertThrows(ErrorCode.NUMERIC_VALUE_OUT_OF_RANGE_1) {
      @Override
      public void test() {
        vd.convertPrecision(10, false);
      }
    };

    v = ValueLobDb.createSmallLob(Value.CLOB, spaces.getBytes(), 100);
    assertEquals(100, v.getPrecision());
    assertEquals(10, v.convertPrecision(10, false).getPrecision());
    assertEquals(10, v.convertPrecision(10, false).getString().length());
    assertEquals("          ", v.convertPrecision(10, false).getString());
    assertEquals(10, v.convertPrecision(10, true).getPrecision());

    v = ValueLobDb.createSmallLob(Value.BLOB, spaces.getBytes(), 100);
    assertEquals(100, v.getPrecision());
    assertEquals(10, v.convertPrecision(10, false).getPrecision());
    assertEquals(10, v.convertPrecision(10, false).getBytes().length);
    assertEquals(32, v.convertPrecision(10, false).getBytes()[9]);
    assertEquals(10, v.convertPrecision(10, true).getPrecision());

    ResultSet rs = new SimpleResultSet();
    v = ValueResultSet.get(rs);
    assertEquals(Integer.MAX_VALUE, v.getPrecision());
    assertEquals(Integer.MAX_VALUE, v.convertPrecision(10, false).getPrecision());
    assertTrue(rs == v.convertPrecision(10, false).getObject());
    assertFalse(rs == v.convertPrecision(10, true).getObject());
    assertEquals(Integer.MAX_VALUE, v.convertPrecision(10, true).getPrecision());

    v = ValueString.get(spaces);
    assertEquals(100, v.getPrecision());
    assertEquals(10, v.convertPrecision(10, false).getPrecision());
    assertEquals("          ", v.convertPrecision(10, false).getString());
    assertEquals("          ", v.convertPrecision(10, true).getString());
  }
Exemple #2
0
 /**
  * Read a value.
  *
  * @return the value
  */
 public Value readValue() {
   int type = data[pos++] & 255;
   switch (type) {
     case Value.NULL:
       return ValueNull.INSTANCE;
     case BOOLEAN_TRUE:
       return ValueBoolean.get(true);
     case BOOLEAN_FALSE:
       return ValueBoolean.get(false);
     case INT_NEG:
       return ValueInt.get(-readVarInt());
     case Value.INT:
       return ValueInt.get(readVarInt());
     case LONG_NEG:
       return ValueLong.get(-readVarLong());
     case Value.LONG:
       return ValueLong.get(readVarLong());
     case Value.BYTE:
       return ValueByte.get(readByte());
     case Value.SHORT:
       return ValueShort.get(readShortInt());
     case DECIMAL_0_1:
       return (ValueDecimal) ValueDecimal.ZERO;
     case DECIMAL_0_1 + 1:
       return (ValueDecimal) ValueDecimal.ONE;
     case DECIMAL_SMALL_0:
       return ValueDecimal.get(BigDecimal.valueOf(readVarLong()));
     case DECIMAL_SMALL:
       {
         int scale = readVarInt();
         return ValueDecimal.get(BigDecimal.valueOf(readVarLong(), scale));
       }
     case Value.DECIMAL:
       {
         int scale = readVarInt();
         int len = readVarInt();
         byte[] buff = DataUtils.newBytes(len);
         read(buff, 0, len);
         BigInteger b = new BigInteger(buff);
         return ValueDecimal.get(new BigDecimal(b, scale));
       }
     case LOCAL_DATE:
       {
         return ValueDate.fromDateValue(readVarLong());
       }
     case Value.DATE:
       {
         long x = readVarLong() * MILLIS_PER_MINUTE;
         return ValueDate.get(new Date(DateTimeUtils.getTimeUTCWithoutDst(x)));
       }
     case LOCAL_TIME:
       {
         long nanos = readVarLong() * 1000000 + readVarLong();
         return ValueTime.fromNanos(nanos);
       }
     case Value.TIME:
       // need to normalize the year, month and day
       return ValueTime.get(new Time(DateTimeUtils.getTimeUTCWithoutDst(readVarLong())));
     case LOCAL_TIMESTAMP:
       {
         long dateValue = readVarLong();
         long nanos = readVarLong() * 1000000 + readVarLong();
         return ValueTimestamp.fromDateValueAndNanos(dateValue, nanos);
       }
     case Value.TIMESTAMP:
       {
         Timestamp ts = new Timestamp(DateTimeUtils.getTimeUTCWithoutDst(readVarLong()));
         ts.setNanos(readVarInt());
         return ValueTimestamp.get(ts);
       }
     case Value.BYTES:
       {
         int len = readVarInt();
         byte[] b = DataUtils.newBytes(len);
         read(b, 0, len);
         return ValueBytes.getNoCopy(b);
       }
     case Value.GEOMETRY:
       {
         int len = readVarInt();
         byte[] b = DataUtils.newBytes(len);
         read(b, 0, len);
         return ValueGeometry.get(b);
       }
     case Value.JAVA_OBJECT:
       {
         int len = readVarInt();
         byte[] b = DataUtils.newBytes(len);
         read(b, 0, len);
         return ValueJavaObject.getNoCopy(null, b, handler);
       }
     case Value.UUID:
       return ValueUuid.get(readLong(), readLong());
     case Value.STRING:
       return ValueString.get(readString());
     case Value.STRING_IGNORECASE:
       return ValueStringIgnoreCase.get(readString());
     case Value.STRING_FIXED:
       return ValueStringFixed.get(readString());
     case FLOAT_0_1:
       return ValueFloat.get(0);
     case FLOAT_0_1 + 1:
       return ValueFloat.get(1);
     case DOUBLE_0_1:
       return ValueDouble.get(0);
     case DOUBLE_0_1 + 1:
       return ValueDouble.get(1);
     case Value.DOUBLE:
       return ValueDouble.get(Double.longBitsToDouble(Long.reverse(readVarLong())));
     case Value.FLOAT:
       return ValueFloat.get(Float.intBitsToFloat(Integer.reverse(readVarInt())));
     case Value.BLOB:
     case Value.CLOB:
       {
         int smallLen = readVarInt();
         if (smallLen >= 0) {
           byte[] small = DataUtils.newBytes(smallLen);
           read(small, 0, smallLen);
           return ValueLobDb.createSmallLob(type, small);
         } else if (smallLen == -3) {
           int tableId = readVarInt();
           long lobId = readVarLong();
           long precision = readVarLong();
           ValueLobDb lob = ValueLobDb.create(type, handler, tableId, lobId, null, precision);
           return lob;
         } else {
           int tableId = readVarInt();
           int objectId = readVarInt();
           long precision = 0;
           boolean compression = false;
           // -1: regular; -2: regular, but not linked (in this case:
           // including file name)
           if (smallLen == -1 || smallLen == -2) {
             precision = readVarLong();
             compression = readByte() == 1;
           }
           if (smallLen == -2) {
             String filename = readString();
             return ValueLob.openUnlinked(
                 type, handler, tableId, objectId, precision, compression, filename);
           }
           return ValueLob.openLinked(type, handler, tableId, objectId, precision, compression);
         }
       }
     case Value.ARRAY:
       {
         int len = readVarInt();
         Value[] list = new Value[len];
         for (int i = 0; i < len; i++) {
           list[i] = readValue();
         }
         return ValueArray.get(list);
       }
     case Value.RESULT_SET:
       {
         SimpleResultSet rs = new SimpleResultSet();
         rs.setAutoClose(false);
         int columns = readVarInt();
         for (int i = 0; i < columns; i++) {
           rs.addColumn(readString(), readVarInt(), readVarInt(), readVarInt());
         }
         while (true) {
           if (readByte() == 0) {
             break;
           }
           Object[] o = new Object[columns];
           for (int i = 0; i < columns; i++) {
             o[i] = readValue().getObject();
           }
           rs.addRow(o);
         }
         return ValueResultSet.get(rs);
       }
     default:
       if (type >= INT_0_15 && type < INT_0_15 + 16) {
         return ValueInt.get(type - INT_0_15);
       } else if (type >= LONG_0_7 && type < LONG_0_7 + 8) {
         return ValueLong.get(type - LONG_0_7);
       } else if (type >= BYTES_0_31 && type < BYTES_0_31 + 32) {
         int len = type - BYTES_0_31;
         byte[] b = DataUtils.newBytes(len);
         read(b, 0, len);
         return ValueBytes.getNoCopy(b);
       } else if (type >= STRING_0_31 && type < STRING_0_31 + 32) {
         return ValueString.get(readString(type - STRING_0_31));
       }
       throw DbException.get(ErrorCode.FILE_CORRUPTED_1, "type: " + type);
   }
 }