Skip to content

SQLDroidResultSet#getObject wrong for INT and FLOAT #85

@silvergate

Description

@silvergate

Similar to #81

Reproduction

  1. Store an int value > 2^31-1: e.g. '9007199254740991'
  2. Read that value from column using getObject

Expected
A java long with value '9007199254740991'

Actual result
java.lang.NumberFormatException: For input string: "9007199254740991" (note: Exception comes from Robolectric, might look a bit different depending on the Android-platform)

Location in code
SQLDroidResultSet.java

    @Override
    public Object getObject(int colID) throws SQLException {
        lastColumnRead = colID;
        int newIndex = ci(colID);
        switch(SQLDroidResultSetMetaData.getType(c, newIndex)) {
            case 4: // Cursor.FIELD_TYPE_BLOB:
                //CONVERT TO BYTE[] OBJECT
                return new SQLDroidBlob(c.getBlob(newIndex));
            case 2: // Cursor.FIELD_TYPE_FLOAT:
                return new Float(c.getFloat(newIndex));
            case 1: // Cursor.FIELD_TYPE_INTEGER:
                return new Integer(c.getInt(newIndex));
            case 3: // Cursor.FIELD_TYPE_STRING:
                return c.getString(newIndex);
            case 0: // Cursor.FIELD_TYPE_NULL:
                return null;
            default:
                return c.getString(newIndex);
        }
    }

Problematic are:

  • new Float(c.getFloat(newIndex));
  • new Integer(c.getInt(newIndex));

According to the documentation FIELD_TYPE_INTEGER says that the column is an integer, but it does not say "it's a 32bit signed integer".

So it should look like this:

    @Override
    public Object getObject(int colID) throws SQLException {
        lastColumnRead = colID;
        int newIndex = ci(colID);
        switch (SQLDroidResultSetMetaData.getType(c, newIndex)) {
            case 4: // Cursor.FIELD_TYPE_BLOB:
                //CONVERT TO BYTE[] OBJECT
                return new SQLDroidBlob(c.getBlob(newIndex));
            case 2: // Cursor.FIELD_TYPE_FLOAT:
                return c.getDouble(newIndex);
            case 1: // Cursor.FIELD_TYPE_INTEGER:
                return c.getLong(newIndex);
            case 3: // Cursor.FIELD_TYPE_STRING:
                return c.getString(newIndex);
            case 0: // Cursor.FIELD_TYPE_NULL:
                return null;
            default:
                return c.getString(newIndex);
        }
    }

Or (if you want to return java ints if value is small):

 @Override
    public Object getObject(int colID) throws SQLException {
        lastColumnRead = colID;
        int newIndex = ci(colID);
        switch (SQLDroidResultSetMetaData.getType(c, newIndex)) {
            case 4: // Cursor.FIELD_TYPE_BLOB:
                //CONVERT TO BYTE[] OBJECT
                return new SQLDroidBlob(c.getBlob(newIndex));
            case 2: // Cursor.FIELD_TYPE_FLOAT:
                return c.getDouble(newIndex);
            case 1: // Cursor.FIELD_TYPE_INTEGER:
                long integer = c.getLong(newIndex);
                if (integer >= Integer.MIN_VALUE && integer <= Integer.MAX_VALUE) {
                    return (int) integer;
                } else {
                    return integer;
                }
            case 3: // Cursor.FIELD_TYPE_STRING:
                return c.getString(newIndex);
            case 0: // Cursor.FIELD_TYPE_NULL:
                return null;
            default:
                return c.getString(newIndex);
        }
    }

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions