FirebirdSQL / jaybird

JDBC driver for Firebird
https://firebirdsql.org/en/jdbc-driver/
GNU Lesser General Public License v2.1
94 stars 23 forks source link

Setting null value on PreparedStatement::setClob produces NullPointerException #712

Closed lukaseder closed 2 years ago

lukaseder commented 2 years ago

Try this code:

try (PreparedStatement s = connection.prepareStatement(
    """
    SELECT cast(? as blob sub_type text) FROM rdb$database
    """
)) {
    s.setClob(1, (Clob) null);
    try (ResultSet rs = s.executeQuery()) {
        while (rs.next())
            System.out.println(rs.getString(1));
    }
}

It produces:

Exception in thread "main" java.lang.NullPointerException: Cannot invoke "java.sql.Clob.getCharacterStream()" because "clob" is null
    at org.firebirdsql.jdbc.AbstractPreparedStatement.setClob(AbstractPreparedStatement.java:723)
    at org.jooq.testscripts.JDBC.main(JDBC.java:71)

This works:

try (PreparedStatement s = connection.prepareStatement(
    """
    SELECT cast(? as blob sub_type text) FROM rdb$database
    """
)) {
    s.setNull(1, Types.CLOB);
    try (ResultSet rs = s.executeQuery()) {
        while (rs.next())
            System.out.println(rs.getString(1));
    }
}

And so does this:

try (PreparedStatement s = connection.prepareStatement(
    """
    SELECT cast(? as blob sub_type text) FROM rdb$database
    """
)) {
    s.setString(1, null);
    try (ResultSet rs = s.executeQuery()) {
        while (rs.next())
            System.out.println(rs.getString(1));
    }
}

Other drivers support null values on the setClob() (or setBlob()) methods. I don't think the behaviour is ambiguous. In fact, I think it's inconsistent with ResultSet behaviour:

try (PreparedStatement s = connection.prepareStatement(
    """
    SELECT cast(? as blob sub_type text) FROM rdb$database
    """
)) {
    s.setString(1, null);
    try (ResultSet rs = s.executeQuery()) {
        while (rs.next())
            System.out.println(rs.getClob(1));
    }
}

When fetching the CLOB value, the ResultSet returns a null value, so it should be possible to bind it as well.

mrotteveel commented 2 years ago

Yes, this is indeed a bug (violates section 13.2.2.4 of JDBC 4.3).

mrotteveel commented 2 years ago

Fixed for Jaybird 4.0.7 and Jaybird 5. Thanks for reporting!

Jaybird 4.0.7 will probably be released around the end of October.