db-derby-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Dag H. Wanvik (Commented) (JIRA)" <j...@apache.org>
Subject [jira] [Commented] (DERBY-3823) NullPointerException in stress.multi test
Date Thu, 13 Oct 2011 01:25:11 GMT

    [ https://issues.apache.org/jira/browse/DERBY-3823?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13126287#comment-13126287
] 

Dag H. Wanvik commented on DERBY-3823:
--------------------------------------

Fiddling with your program I think the actual result set's getMetaData
is is correct (ResultSet#getMetaData) in the case I was worried about,
it appears it is read early on while processing the rs. (Sorry, I was
a bit mixed up here).

But your concern is *also* correct :) I changed the program to use an
*explicit* prepared statement (since the method for which we made the
patch is PreparedStatement#getMetaData) to retrieve metadata from
there, *as well as* getting the metadata from the actual result set.

The PreparedStatement's getMetaData method is described in this way in
the Javadoc:

   "getMetaData() Retrieves a ResultSetMetaData object
    that contains information about the columns of the ResultSet
    object that *will be* returned when this PreparedStatement object
    is executed." ("will be": my emphasis, not "just was".. ;-)

here is my run result (incl some trace from EmbedPreparedStatement#getMetaData)

Client/server:

$ java -cp .:$CLASSPATH DERBY3823StressTestNPE 2 
execp.getResultDescription: insert into t1 values(?,'aaaaa')
execp.getResultDescription: insert into t1 values(?,'aaaaa')
Done loading data
execp.getResultDescription: select * from t1
execp.getResultDescription: select * from t1
executing alter
2. PS#getMetaData: char column length is 5
Reexecuting ps on changed table...
3. RS#getMetadata: char column length is 5
data:1 12345678

As we can see we are getting a value 8 long, but both ps's metadata
and rs's metadata are both out of date. Note that there is no new call
to execp.getResultDescription *after* we alter the table...

On embedded it is correct:

$ java -cp .:$CLASSPATH DERBY3823StressTestNPE
Done loading data
executing alter
execp.getResultDescription: select * from t1
2. PS#getMetaData: char column length is 8
Reexecuting ps on changed table...
3. RS#getMetadata: char column length is 8
data:1 12345678

As you observed, it should return 8. Maybe because it's cached on the
client side, but should have been invalidated. This looks like a bug
to me.

In any case, I think the patch improves the situation in that we now
will wait if the underlying prepared statement is being re-prepared. I
think we should file a new bug for this and relate it to the two you
mentioned. I can do it if you like. The current patch as least assures we get a consistent
"snapshot" at the time metadata is attempted retrieved.


---------------------------------------------------
import java.sql.*;

public class DERBY3823StressTestNPE extends Thread {
    public static void main(String[] args) throws Exception {

        Connection conn = null;
        if (args.length == 1) {
            int embedded = Integer.parseInt(args[0]);
            if (embedded == 1) {
                Class.forName("org.apache.derby.jdbc.EmbeddedDriver");
                conn = DriverManager.getConnection(
                    "jdbc:derby:DERBY3823DB;create=true");
            } else {
                Class.forName("org.apache.derby.jdbc.ClientDriver");
                String url = "jdbc:derby://localhost:1527/DERBY3823DB;create=true";
                conn = DriverManager.getConnection(url);
            }
        } else {
            Class.forName("org.apache.derby.jdbc.EmbeddedDriver");
            conn = DriverManager.getConnection(
                "jdbc:derby:DERBY3823DB;create=true");
        }
        
        conn.setAutoCommit(false);
        Statement st = conn.createStatement();
        st.executeUpdate("create table t1(c11 int, "+
                         "c12 varchar(5))");
        {
            PreparedStatement ps =
                conn.prepareStatement("insert into t1 values(?,'aaaaa')");
            for (int i = 0; i < 1000; i++) {
                ps.setInt(1, i);
                ps.executeUpdate();
            }
        }
        System.out.println("Done loading data");
        conn.commit();

        PreparedStatement ps = conn.prepareStatement("select * from t1");
        ResultSet rs = ps.executeQuery();

        for (int i = 0; i < 990; i++) {
            rs.next();
        }
        rs.close();

        Statement st2 = conn.createStatement();
        System.err.println("executing " + "alter");
        st2.execute("alter table t1 alter column c12 set data type varchar(8)");
        st2.execute("delete from t1");
        st2.execute("insert into t1 values (1, '12345678')");
        
        {

            // Ps' javadoc: getMetaData() Retrieves a ResultSetMetaData object
            // that contains information about the columns of the ResultSet
            // object that *will be* returned when this PreparedStatement object
            // is executed. (my emphasis)

            ResultSetMetaData rsmd = ps.getMetaData();
            int charLength = rsmd.getColumnDisplaySize(2);
            System.out.println("2. PS#getMetaData: char column length is " + charLength);
            System.out.println("Reexecuting ps on changed table...");
            rs = ps.executeQuery();
            ResultSetMetaData rsmd2 = rs.getMetaData();
            charLength = rsmd2.getColumnDisplaySize(2);
            System.out.println("3. RS#getMetadata: char column length is " + charLength);
            while (rs.next()) {
                System.out.println("data:" + rs.getString(1) + " " + rs.getString(2));
            }
            rs.close();
        }
    }
}

                
> NullPointerException in stress.multi test
> -----------------------------------------
>
>                 Key: DERBY-3823
>                 URL: https://issues.apache.org/jira/browse/DERBY-3823
>             Project: Derby
>          Issue Type: Bug
>          Components: Network Server
>    Affects Versions: 10.3.3.1, 10.7.1.1, 10.8.1.2
>            Reporter: Kathey Marsden
>              Labels: derby_triage10_5_2
>         Attachments: d3823-1.diff, derby.log
>
>
> I saw the following NPE in stress.multi running on 10.3 with derbyclient.
> java.lang.NullPointerException
>         at org.apache.derby.impl.jdbc.EmbedPreparedStatement.getMetaData(Unknown
>  Source)
>         at org.apache.derby.impl.drda.DRDAConnThread.writeSQLDARD(Unknown Source
> )
>         at org.apache.derby.impl.drda.DRDAConnThread.processCommands(Unknown Sou
> rce)
>         at org.apache.derby.impl.drda.DRDAConnThread.run(Unknown Source)
> Cleanup action completed

--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators: https://issues.apache.org/jira/secure/ContactAdministrators!default.jspa
For more information on JIRA, see: http://www.atlassian.com/software/jira

        

Mime
View raw message