Beispiel #1
0
 private void writeRow(Data buff, Row r) {
   buff.checkCapacity(1 + Data.LENGTH_INT * 8);
   buff.writeByte((byte) 1);
   buff.writeInt(r.getMemory());
   int columnCount = r.getColumnCount();
   buff.writeInt(columnCount);
   buff.writeLong(r.getKey());
   buff.writeInt(r.getVersion());
   buff.writeInt(r.isDeleted() ? 1 : 0);
   buff.writeInt(r.getSessionId());
   for (int i = 0; i < columnCount; i++) {
     Value v = r.getValue(i);
     buff.checkCapacity(1);
     if (v == null) {
       buff.writeByte((byte) 0);
     } else {
       buff.writeByte((byte) 1);
       if (v.getType() == Value.CLOB || v.getType() == Value.BLOB) {
         // need to keep a reference to temporary lobs,
         // otherwise the temp file is deleted
         if (v.getSmall() == null && v.getTableId() == 0) {
           if (lobs == null) {
             lobs = New.arrayList();
           }
           // need to create a copy, otherwise,
           // if stored multiple times, it may be renamed
           // and then not found
           v = v.copyToTemp();
           lobs.add(v);
         }
       }
       buff.checkCapacity(buff.getValueLen(v));
       buff.writeValue(v);
     }
   }
 }
Beispiel #2
0
 /**
  * Append a value.
  *
  * @param v the value
  */
 public void writeValue(Value v) {
   int start = pos;
   if (v == ValueNull.INSTANCE) {
     data[pos++] = 0;
     return;
   }
   int type = v.getType();
   switch (type) {
     case Value.BOOLEAN:
       writeByte((byte) (v.getBoolean().booleanValue() ? BOOLEAN_TRUE : BOOLEAN_FALSE));
       break;
     case Value.BYTE:
       writeByte((byte) type);
       writeByte(v.getByte());
       break;
     case Value.SHORT:
       writeByte((byte) type);
       writeShortInt(v.getShort());
       break;
     case Value.INT:
       {
         int x = v.getInt();
         if (x < 0) {
           writeByte((byte) INT_NEG);
           writeVarInt(-x);
         } else if (x < 16) {
           writeByte((byte) (INT_0_15 + x));
         } else {
           writeByte((byte) type);
           writeVarInt(x);
         }
         break;
       }
     case Value.LONG:
       {
         long x = v.getLong();
         if (x < 0) {
           writeByte((byte) LONG_NEG);
           writeVarLong(-x);
         } else if (x < 8) {
           writeByte((byte) (LONG_0_7 + x));
         } else {
           writeByte((byte) type);
           writeVarLong(x);
         }
         break;
       }
     case Value.DECIMAL:
       {
         BigDecimal x = v.getBigDecimal();
         if (BigDecimal.ZERO.equals(x)) {
           writeByte((byte) DECIMAL_0_1);
         } else if (BigDecimal.ONE.equals(x)) {
           writeByte((byte) (DECIMAL_0_1 + 1));
         } else {
           int scale = x.scale();
           BigInteger b = x.unscaledValue();
           int bits = b.bitLength();
           if (bits <= 63) {
             if (scale == 0) {
               writeByte((byte) DECIMAL_SMALL_0);
               writeVarLong(b.longValue());
             } else {
               writeByte((byte) DECIMAL_SMALL);
               writeVarInt(scale);
               writeVarLong(b.longValue());
             }
           } else {
             writeByte((byte) type);
             writeVarInt(scale);
             byte[] bytes = b.toByteArray();
             writeVarInt(bytes.length);
             write(bytes, 0, bytes.length);
           }
         }
         break;
       }
     case Value.TIME:
       if (SysProperties.STORE_LOCAL_TIME) {
         writeByte((byte) LOCAL_TIME);
         ValueTime t = (ValueTime) v;
         long nanos = t.getNanos();
         long millis = nanos / 1000000;
         nanos -= millis * 1000000;
         writeVarLong(millis);
         writeVarLong(nanos);
       } else {
         writeByte((byte) type);
         writeVarLong(DateTimeUtils.getTimeLocalWithoutDst(v.getTime()));
       }
       break;
     case Value.DATE:
       {
         if (SysProperties.STORE_LOCAL_TIME) {
           writeByte((byte) LOCAL_DATE);
           long x = ((ValueDate) v).getDateValue();
           writeVarLong(x);
         } else {
           writeByte((byte) type);
           long x = DateTimeUtils.getTimeLocalWithoutDst(v.getDate());
           writeVarLong(x / MILLIS_PER_MINUTE);
         }
         break;
       }
     case Value.TIMESTAMP:
       {
         if (SysProperties.STORE_LOCAL_TIME) {
           writeByte((byte) LOCAL_TIMESTAMP);
           ValueTimestamp ts = (ValueTimestamp) v;
           long dateValue = ts.getDateValue();
           writeVarLong(dateValue);
           long nanos = ts.getNanos();
           long millis = nanos / 1000000;
           nanos -= millis * 1000000;
           writeVarLong(millis);
           writeVarLong(nanos);
         } else {
           Timestamp ts = v.getTimestamp();
           writeByte((byte) type);
           writeVarLong(DateTimeUtils.getTimeLocalWithoutDst(ts));
           writeVarInt(ts.getNanos());
         }
         break;
       }
     case Value.GEOMETRY:
     case Value.JAVA_OBJECT:
       {
         writeByte((byte) type);
         byte[] b = v.getBytesNoCopy();
         int len = b.length;
         writeVarInt(len);
         write(b, 0, len);
         break;
       }
     case Value.BYTES:
       {
         byte[] b = v.getBytesNoCopy();
         int len = b.length;
         if (len < 32) {
           writeByte((byte) (BYTES_0_31 + len));
           write(b, 0, len);
         } else {
           writeByte((byte) type);
           writeVarInt(len);
           write(b, 0, len);
         }
         break;
       }
     case Value.UUID:
       {
         writeByte((byte) type);
         ValueUuid uuid = (ValueUuid) v;
         writeLong(uuid.getHigh());
         writeLong(uuid.getLow());
         break;
       }
     case Value.STRING:
       {
         String s = v.getString();
         int len = s.length();
         if (len < 32) {
           writeByte((byte) (STRING_0_31 + len));
           writeStringWithoutLength(s, len);
         } else {
           writeByte((byte) type);
           writeString(s);
         }
         break;
       }
     case Value.STRING_IGNORECASE:
     case Value.STRING_FIXED:
       writeByte((byte) type);
       writeString(v.getString());
       break;
     case Value.DOUBLE:
       {
         double x = v.getDouble();
         if (x == 1.0d) {
           writeByte((byte) (DOUBLE_0_1 + 1));
         } else {
           long d = Double.doubleToLongBits(x);
           if (d == ValueDouble.ZERO_BITS) {
             writeByte((byte) DOUBLE_0_1);
           } else {
             writeByte((byte) type);
             writeVarLong(Long.reverse(d));
           }
         }
         break;
       }
     case Value.FLOAT:
       {
         float x = v.getFloat();
         if (x == 1.0f) {
           writeByte((byte) (FLOAT_0_1 + 1));
         } else {
           int f = Float.floatToIntBits(x);
           if (f == ValueFloat.ZERO_BITS) {
             writeByte((byte) FLOAT_0_1);
           } else {
             writeByte((byte) type);
             writeVarInt(Integer.reverse(f));
           }
         }
         break;
       }
     case Value.BLOB:
     case Value.CLOB:
       {
         writeByte((byte) type);
         if (v instanceof ValueLob) {
           ValueLob lob = (ValueLob) v;
           lob.convertToFileIfRequired(handler);
           byte[] small = lob.getSmall();
           if (small == null) {
             int t = -1;
             if (!lob.isLinked()) {
               t = -2;
             }
             writeVarInt(t);
             writeVarInt(lob.getTableId());
             writeVarInt(lob.getObjectId());
             writeVarLong(lob.getPrecision());
             writeByte((byte) (lob.isCompressed() ? 1 : 0));
             if (t == -2) {
               writeString(lob.getFileName());
             }
           } else {
             writeVarInt(small.length);
             write(small, 0, small.length);
           }
         } else {
           ValueLobDb lob = (ValueLobDb) v;
           byte[] small = lob.getSmall();
           if (small == null) {
             writeVarInt(-3);
             writeVarInt(lob.getTableId());
             writeVarLong(lob.getLobId());
             writeVarLong(lob.getPrecision());
           } else {
             writeVarInt(small.length);
             write(small, 0, small.length);
           }
         }
         break;
       }
     case Value.ARRAY:
       {
         writeByte((byte) type);
         Value[] list = ((ValueArray) v).getList();
         writeVarInt(list.length);
         for (Value x : list) {
           writeValue(x);
         }
         break;
       }
     case Value.RESULT_SET:
       {
         writeByte((byte) type);
         try {
           ResultSet rs = ((ValueResultSet) v).getResultSet();
           rs.beforeFirst();
           ResultSetMetaData meta = rs.getMetaData();
           int columnCount = meta.getColumnCount();
           writeVarInt(columnCount);
           for (int i = 0; i < columnCount; i++) {
             writeString(meta.getColumnName(i + 1));
             writeVarInt(meta.getColumnType(i + 1));
             writeVarInt(meta.getPrecision(i + 1));
             writeVarInt(meta.getScale(i + 1));
           }
           while (rs.next()) {
             writeByte((byte) 1);
             for (int i = 0; i < columnCount; i++) {
               int t = DataType.getValueTypeFromResultSet(meta, i + 1);
               Value val = DataType.readValue(null, rs, i + 1, t);
               writeValue(val);
             }
           }
           writeByte((byte) 0);
           rs.beforeFirst();
         } catch (SQLException e) {
           throw DbException.convert(e);
         }
         break;
       }
     default:
       DbException.throwInternalError("type=" + v.getType());
   }
   if (SysProperties.CHECK2) {
     if (pos - start != getValueLen(v, handler)) {
       throw DbException.throwInternalError(
           "value size error: got " + (pos - start) + " expected " + getValueLen(v, handler));
     }
   }
 }