private void generateColumnsFromQuery() {
   int columnCount = asQuery.getColumnCount();
   ArrayList<Expression> expressions = asQuery.getExpressions();
   for (int i = 0; i < columnCount; i++) {
     Expression expr = expressions.get(i);
     int type = expr.getType();
     String name = expr.getAlias();
     long precision = expr.getPrecision();
     int displaySize = expr.getDisplaySize();
     DataType dt = DataType.getDataType(type);
     if (precision > 0
         && (dt.defaultPrecision == 0
             || (dt.defaultPrecision > precision && dt.defaultPrecision < Byte.MAX_VALUE))) {
       // dont' set precision to MAX_VALUE if this is the default
       precision = dt.defaultPrecision;
     }
     int scale = expr.getScale();
     if (scale > 0
         && (dt.defaultScale == 0 || (dt.defaultScale > scale && dt.defaultScale < precision))) {
       scale = dt.defaultScale;
     }
     if (scale > precision) {
       precision = scale;
     }
     Column col = new Column(name, type, precision, scale, displaySize);
     addColumn(col);
   }
 }
示例#2
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));
   }
 }
示例#3
0
  private void testResultSetOperations() throws SQLException {
    SimpleResultSet rs = new SimpleResultSet();
    rs.setAutoClose(false);
    rs.addColumn("X", Types.INTEGER, 10, 0);
    rs.addRow(new Object[] {null});
    rs.next();
    for (int type = Value.NULL; type < Value.TYPE_COUNT; type++) {
      Value v = DataType.readValue(null, rs, 1, type);
      assertTrue(v == ValueNull.INSTANCE);
    }
    testResultSetOperation(new byte[0]);
    testResultSetOperation(1);
    testResultSetOperation(Boolean.TRUE);
    testResultSetOperation((byte) 1);
    testResultSetOperation((short) 2);
    testResultSetOperation((long) 3);
    testResultSetOperation(4.0f);
    testResultSetOperation(5.0d);
    testResultSetOperation(new Date(6));
    testResultSetOperation(new Time(7));
    testResultSetOperation(new Timestamp(8));
    testResultSetOperation(new BigDecimal("9"));

    SimpleResultSet rs2 = new SimpleResultSet();
    rs2.setAutoClose(false);
    rs2.addColumn("X", Types.INTEGER, 10, 0);
    rs2.addRow(new Object[] {1});
    rs2.next();
    testResultSetOperation(rs2);
  }
 /**
  * Returns the parameter type. java.sql.Types.VARCHAR is returned if the data type is not known.
  *
  * @param param the column index (1,2,...)
  * @return the data type
  */
 public int getParameterType(int param) throws SQLException {
   try {
     debugCodeCall("getParameterType", param);
     ParameterInterface p = getParameter(param);
     int type = p.getType();
     if (type == Value.UNKNOWN) {
       type = Value.STRING;
     }
     return DataType.getDataType(type).sqlType;
   } catch (Exception e) {
     throw logAndConvert(e);
   }
 }
 /**
  * Returns the Java class name of the parameter. "java.lang.String" is returned if the type is not
  * known.
  *
  * @param param the column index (1,2,...)
  * @return the Java class name
  */
 @Override
 public String getParameterClassName(int param) throws SQLException {
   try {
     debugCodeCall("getParameterClassName", param);
     ParameterInterface p = getParameter(param);
     int type = p.getType();
     if (type == Value.UNKNOWN) {
       type = Value.STRING;
     }
     return DataType.getTypeClassName(type);
   } catch (Exception e) {
     throw logAndConvert(e);
   }
 }
示例#6
0
 @Override
 public Value getValue(Session session) {
   HashMap<Expression, Object> group = select.getCurrentGroup();
   if (group == null) {
     throw DbException.get(ErrorCode.INVALID_USE_OF_AGGREGATE_FUNCTION_1, getSQL());
   }
   try {
     Aggregate agg = (Aggregate) group.get(this);
     if (agg == null) {
       agg = getInstance();
     }
     Object obj = agg.getResult();
     if (obj == null) {
       return ValueNull.INSTANCE;
     }
     return DataType.convertToValue(session, obj, dataType);
   } catch (SQLException e) {
     throw DbException.convert(e);
   }
 }
示例#7
0
 JavaMethod(Method method, int id) throws SQLException {
   this.method = method;
   this.id = id;
   Class<?>[] paramClasses = method.getParameterTypes();
   paramCount = paramClasses.length;
   if (paramCount > 0) {
     Class<?> paramClass = paramClasses[0];
     if (Connection.class.isAssignableFrom(paramClass)) {
       hasConnectionParam = true;
       paramCount--;
     }
   }
   if (paramCount > 0) {
     Class<?> lastArg = paramClasses[paramClasses.length - 1];
     if (lastArg.isArray() && ClassUtils.isVarArgs(method)) {
       varArgs = true;
       varArgClass = lastArg.getComponentType();
     }
   }
   Class<?> returnClass = method.getReturnType();
   dataType = DataType.getTypeFromClass(returnClass);
 }
示例#8
0
    /**
     * Call the user-defined function and return the value.
     *
     * @param session the session
     * @param args the argument list
     * @param columnList true if the function should only return the column list
     * @return the value
     */
    public Value getValue(Session session, Expression[] args, boolean columnList)
        throws SQLException {
      Class<?>[] paramClasses = method.getParameterTypes();
      Object[] params = new Object[paramClasses.length];
      int p = 0;
      if (hasConnectionParam && params.length > 0) {
        params[p++] = session.createConnection(columnList);
      }

      // allocate array for varArgs parameters
      Object varArg = null;
      if (varArgs) {
        int len = args.length - params.length + 1 + (hasConnectionParam ? 1 : 0);
        varArg = Array.newInstance(varArgClass, len);
        params[params.length - 1] = varArg;
      }

      for (int a = 0; a < args.length; a++, p++) {
        boolean currentIsVarArg = varArgs && p >= paramClasses.length - 1;
        Class<?> paramClass;
        if (currentIsVarArg) {
          paramClass = varArgClass;
        } else {
          paramClass = paramClasses[p];
        }
        int type = DataType.getTypeFromClass(paramClass);
        Value v = args[a].getValue(session);
        v = v.convertTo(type);
        Object o = v.getObject();
        if (o == null) {
          if (paramClass.isPrimitive()) {
            if (columnList) {
              // if the column list is requested, the parameters may
              // be null
              // need to set to default value otherwise the function
              // can't be called at all
              o = DataType.getDefaultForPrimitiveType(paramClass);
            } else {
              // NULL for a java primitive: return NULL
              return ValueNull.INSTANCE;
            }
          }
        } else {
          if (!paramClass.isAssignableFrom(o.getClass()) && !paramClass.isPrimitive()) {
            o = DataType.convertTo(session, session.createConnection(false), v, paramClass);
          }
        }
        if (currentIsVarArg) {
          Array.set(varArg, p - params.length + 1, o);
        } else {
          params[p] = o;
        }
      }
      boolean old = session.getAutoCommit();
      Value identity = session.getScopeIdentity();
      try {
        session.setAutoCommit(false);
        try {
          Object returnValue;
          returnValue = method.invoke(null, params);
          if (returnValue == null) {
            return ValueNull.INSTANCE;
          }
          Value ret = DataType.convertToValue(session, returnValue, dataType);
          return ret.convertTo(dataType);
        } catch (Exception e) {
          throw Message.convert(e);
        }
      } finally {
        session.setScopeIdentity(identity);
        session.setAutoCommit(old);
      }
    }
示例#9
0
 @Override
 public int getScale() {
   return DataType.getDataType(dataType).defaultScale;
 }
示例#10
0
 public int getScale() {
   return DataType.getDataType(getType()).defaultScale;
 }
示例#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());
   }
 }
示例#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));
     }
   }
 }
示例#13
0
 private void testDataType(int type, Class<?> clazz) {
   assertEquals(type, DataType.getTypeFromClass(clazz));
 }