Beispiel #1
0
 private boolean sameResultAsLast(Session s, Value[] params, Value[] lastParams, long lastEval) {
   if (!cacheableChecked) {
     long max = getMaxDataModificationId();
     noCache = max == Long.MAX_VALUE;
     cacheableChecked = true;
   }
   if (noCache) {
     return false;
   }
   Database db = s.getDatabase();
   for (int i = 0; i < params.length; i++) {
     Value a = lastParams[i], b = params[i];
     if (a.getType() != b.getType() || !db.areEqual(a, b)) {
       return false;
     }
   }
   if (!isEverything(ExpressionVisitor.DETERMINISTIC_VISITOR)
       || !isEverything(ExpressionVisitor.INDEPENDENT_VISITOR)) {
     return false;
   }
   if (db.getModificationDataId() > lastEval && getMaxDataModificationId() > lastEval) {
     return false;
   }
   return true;
 }
 private int compareTypeSave(Value a, Value b) {
   if (a == b) {
     return 0;
   }
   int dataType = Value.getHigherOrder(a.getType(), b.getType());
   a = a.convertTo(dataType);
   b = b.convertTo(dataType);
   return a.compareTypeSave(b, compareMode);
 }
 private void writeValue(Value v) throws IOException {
   if (v.getType() == Value.CLOB || v.getType() == Value.BLOB) {
     if (v instanceof ValueLobDb) {
       ValueLobDb lob = (ValueLobDb) v;
       if (lob.isStored()) {
         long id = lob.getLobId();
         lobs.put(id, new CachedInputStream(null));
       }
     }
   }
   transfer.writeValue(v);
 }
Beispiel #4
0
 /**
  * Convert an object to the default Java object for the given SQL type. For example, LOB objects
  * are converted to java.sql.Clob / java.sql.Blob.
  *
  * @param v the value
  * @return the object
  */
 Object convertToDefaultObject(Value v) {
   Object o;
   switch (v.getType()) {
     case Value.CLOB:
       {
         if (SysProperties.RETURN_LOB_OBJECTS) {
           int id = getNextId(TraceObject.CLOB);
           o = new JdbcClob(this, v, id);
         } else {
           o = v.getObject();
         }
         break;
       }
     case Value.BLOB:
       {
         if (SysProperties.RETURN_LOB_OBJECTS) {
           int id = getNextId(TraceObject.BLOB);
           o = new JdbcBlob(this, v, id);
         } else {
           o = v.getObject();
         }
         break;
       }
     case Value.JAVA_OBJECT:
       o = Utils.deserialize(v.getBytesNoCopy());
       break;
     default:
       o = v.getObject();
   }
   return o;
 }
Beispiel #5
0
 @Override
 public Value getValue(Session session) {
   Value l = left.getValue(session);
   if (l == ValueNull.INSTANCE) {
     return l;
   }
   boolean result = false;
   boolean hasNull = false;
   for (Expression e : valueList) {
     Value r = e.getValue(session);
     if (r == ValueNull.INSTANCE) {
       hasNull = true;
     } else {
       r = r.convertTo(l.getType());
       result = Comparison.compareNotNull(database, l, r, Comparison.EQUAL);
       if (result) {
         break;
       }
     }
   }
   if (!result && hasNull) {
     return ValueNull.INSTANCE;
   }
   return ValueBoolean.get(result);
 }
Beispiel #6
0
 @Override
 public void addTemporaryLob(Value v) {
   if (v.getType() != Value.CLOB && v.getType() != Value.BLOB) {
     return;
   }
   if (v.getTableId() == LobStorageFrontend.TABLE_RESULT
       || v.getTableId() == LobStorageFrontend.TABLE_TEMP) {
     if (temporaryResultLobs == null) {
       temporaryResultLobs = new LinkedList<TimeoutValue>();
     }
     temporaryResultLobs.add(new TimeoutValue(v));
   } else {
     if (temporaryLobs == null) {
       temporaryLobs = new ArrayList<Value>();
     }
     temporaryLobs.add(v);
   }
 }
Beispiel #7
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 #8
0
 /**
  * Returns the length.
  *
  * @return the length
  */
 public long length() throws SQLException {
   try {
     debugCodeCall("length");
     checkClosed();
     if (value.getType() == Value.CLOB) {
       long precision = value.getPrecision();
       if (precision > 0) {
         return precision;
       }
     }
     return IOUtils.copyAndCloseInput(value.getReader(), null, Long.MAX_VALUE);
   } catch (Exception e) {
     throw logAndConvert(e);
   }
 }
Beispiel #9
0
 private void testResultSetOperation(Object obj) throws SQLException {
   SimpleResultSet rs = new SimpleResultSet();
   rs.setAutoClose(false);
   int valueType = DataType.getTypeFromClass(obj.getClass());
   int sqlType = DataType.convertTypeToSQLType(valueType);
   rs.addColumn("X", sqlType, 10, 0);
   rs.addRow(new Object[] {obj});
   rs.next();
   Value v = DataType.readValue(null, rs, 1, valueType);
   Value v2 = DataType.convertToValue(null, obj, valueType);
   if (v.getType() == Value.RESULT_SET) {
     assertEquals(v.toString(), v2.toString());
   } else {
     assertTrue(v.equals(v2));
   }
 }
Beispiel #10
0
 /**
  * A record is added to a table, or removed from a table.
  *
  * @param session the session
  * @param tableId the table id
  * @param row the row to add
  * @param add true if the row is added, false if it is removed
  */
 void logAddOrRemoveRow(Session session, int tableId, Row row, boolean add) {
   if (trace.isDebugEnabled()) {
     trace.debug(
         "log "
             + (add ? "+" : "-")
             + " s: "
             + session.getId()
             + " table: "
             + tableId
             + " row: "
             + row);
   }
   session.addLogPos(logSectionId, logPos);
   logPos++;
   Data data = dataBuffer;
   data.reset();
   int columns = row.getColumnCount();
   data.writeVarInt(columns);
   data.checkCapacity(row.getByteCount(data));
   if (session.isRedoLogBinaryEnabled()) {
     for (int i = 0; i < columns; i++) {
       data.writeValue(row.getValue(i));
     }
   } else {
     for (int i = 0; i < columns; i++) {
       Value v = row.getValue(i);
       if (v.getType() == Value.BYTES) {
         data.writeValue(ValueNull.INSTANCE);
       } else {
         data.writeValue(v);
       }
     }
   }
   Data buffer = getBuffer();
   buffer.writeByte((byte) (add ? ADD : REMOVE));
   buffer.writeVarInt(session.getId());
   buffer.writeVarInt(tableId);
   buffer.writeVarLong(row.getKey());
   if (add) {
     buffer.writeVarInt(data.length());
     buffer.checkCapacity(data.length());
     buffer.write(data.getBytes(), 0, data.length());
   }
   write(buffer);
 }
Beispiel #11
0
 /**
  * Calculate the number of bytes required to encode the given value.
  *
  * @param v the value
  * @param handler the data handler for lobs
  * @return the number of bytes required to store this value
  */
 public static int getValueLen(Value v, DataHandler handler) {
   if (v == ValueNull.INSTANCE) {
     return 1;
   }
   switch (v.getType()) {
     case Value.BOOLEAN:
       return 1;
     case Value.BYTE:
       return 2;
     case Value.SHORT:
       return 3;
     case Value.INT:
       {
         int x = v.getInt();
         if (x < 0) {
           return 1 + getVarIntLen(-x);
         } else if (x < 16) {
           return 1;
         } else {
           return 1 + getVarIntLen(x);
         }
       }
     case Value.LONG:
       {
         long x = v.getLong();
         if (x < 0) {
           return 1 + getVarLongLen(-x);
         } else if (x < 8) {
           return 1;
         } else {
           return 1 + getVarLongLen(x);
         }
       }
     case Value.DOUBLE:
       {
         double x = v.getDouble();
         if (x == 1.0d) {
           return 1;
         }
         long d = Double.doubleToLongBits(x);
         if (d == ValueDouble.ZERO_BITS) {
           return 1;
         }
         return 1 + getVarLongLen(Long.reverse(d));
       }
     case Value.FLOAT:
       {
         float x = v.getFloat();
         if (x == 1.0f) {
           return 1;
         }
         int f = Float.floatToIntBits(x);
         if (f == ValueFloat.ZERO_BITS) {
           return 1;
         }
         return 1 + getVarIntLen(Integer.reverse(f));
       }
     case Value.STRING:
       {
         String s = v.getString();
         int len = s.length();
         if (len < 32) {
           return 1 + getStringWithoutLengthLen(s, len);
         }
         return 1 + getStringLen(s);
       }
     case Value.STRING_IGNORECASE:
     case Value.STRING_FIXED:
       return 1 + getStringLen(v.getString());
     case Value.DECIMAL:
       {
         BigDecimal x = v.getBigDecimal();
         if (BigDecimal.ZERO.equals(x)) {
           return 1;
         } else if (BigDecimal.ONE.equals(x)) {
           return 1;
         }
         int scale = x.scale();
         BigInteger b = x.unscaledValue();
         int bits = b.bitLength();
         if (bits <= 63) {
           if (scale == 0) {
             return 1 + getVarLongLen(b.longValue());
           }
           return 1 + getVarIntLen(scale) + getVarLongLen(b.longValue());
         }
         byte[] bytes = b.toByteArray();
         return 1 + getVarIntLen(scale) + getVarIntLen(bytes.length) + bytes.length;
       }
     case Value.TIME:
       if (SysProperties.STORE_LOCAL_TIME) {
         long nanos = ((ValueTime) v).getNanos();
         long millis = nanos / 1000000;
         nanos -= millis * 1000000;
         return 1 + getVarLongLen(millis) + getVarLongLen(nanos);
       }
       return 1 + getVarLongLen(DateTimeUtils.getTimeLocalWithoutDst(v.getTime()));
     case Value.DATE:
       {
         if (SysProperties.STORE_LOCAL_TIME) {
           long dateValue = ((ValueDate) v).getDateValue();
           return 1 + getVarLongLen(dateValue);
         }
         long x = DateTimeUtils.getTimeLocalWithoutDst(v.getDate());
         return 1 + getVarLongLen(x / MILLIS_PER_MINUTE);
       }
     case Value.TIMESTAMP:
       {
         if (SysProperties.STORE_LOCAL_TIME) {
           ValueTimestamp ts = (ValueTimestamp) v;
           long dateValue = ts.getDateValue();
           long nanos = ts.getNanos();
           long millis = nanos / 1000000;
           nanos -= millis * 1000000;
           return 1 + getVarLongLen(dateValue) + getVarLongLen(millis) + getVarLongLen(nanos);
         }
         Timestamp ts = v.getTimestamp();
         return 1
             + getVarLongLen(DateTimeUtils.getTimeLocalWithoutDst(ts))
             + getVarIntLen(ts.getNanos());
       }
     case Value.GEOMETRY:
     case Value.JAVA_OBJECT:
       {
         byte[] b = v.getBytesNoCopy();
         return 1 + getVarIntLen(b.length) + b.length;
       }
     case Value.BYTES:
       {
         byte[] b = v.getBytesNoCopy();
         int len = b.length;
         if (len < 32) {
           return 1 + b.length;
         }
         return 1 + getVarIntLen(b.length) + b.length;
       }
     case Value.UUID:
       return 1 + LENGTH_LONG + LENGTH_LONG;
     case Value.BLOB:
     case Value.CLOB:
       {
         int len = 1;
         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;
             }
             len += getVarIntLen(t);
             len += getVarIntLen(lob.getTableId());
             len += getVarIntLen(lob.getObjectId());
             len += getVarLongLen(lob.getPrecision());
             len += 1;
             if (t == -2) {
               len += getStringLen(lob.getFileName());
             }
           } else {
             len += getVarIntLen(small.length);
             len += small.length;
           }
         } else {
           ValueLobDb lob = (ValueLobDb) v;
           byte[] small = lob.getSmall();
           if (small == null) {
             len += getVarIntLen(-3);
             len += getVarIntLen(lob.getTableId());
             len += getVarLongLen(lob.getLobId());
             len += getVarLongLen(lob.getPrecision());
           } else {
             len += getVarIntLen(small.length);
             len += small.length;
           }
         }
         return len;
       }
     case Value.ARRAY:
       {
         Value[] list = ((ValueArray) v).getList();
         int len = 1 + getVarIntLen(list.length);
         for (Value x : list) {
           len += getValueLen(x, handler);
         }
         return len;
       }
     case Value.RESULT_SET:
       {
         int len = 1;
         try {
           ResultSet rs = ((ValueResultSet) v).getResultSet();
           rs.beforeFirst();
           ResultSetMetaData meta = rs.getMetaData();
           int columnCount = meta.getColumnCount();
           len += getVarIntLen(columnCount);
           for (int i = 0; i < columnCount; i++) {
             len += getStringLen(meta.getColumnName(i + 1));
             len += getVarIntLen(meta.getColumnType(i + 1));
             len += getVarIntLen(meta.getPrecision(i + 1));
             len += getVarIntLen(meta.getScale(i + 1));
           }
           while (rs.next()) {
             len++;
             for (int i = 0; i < columnCount; i++) {
               int t = DataType.getValueTypeFromResultSet(meta, i + 1);
               Value val = DataType.readValue(null, rs, i + 1, t);
               len += getValueLen(val, handler);
             }
           }
           len++;
           rs.beforeFirst();
         } catch (SQLException e) {
           throw DbException.convert(e);
         }
         return len;
       }
     default:
       throw DbException.throwInternalError("type=" + v.getType());
   }
 }
Beispiel #12
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));
     }
   }
 }