Bug #907 OutOfMemoryError
Submitted: 24 Jul 2003 5:11 Modified: 28 Mar 2014 11:44
Reporter: Gene Vayngrib Email Updates:
Status: Can't repeat Impact on me:
None 
Category:Connector / J Severity:S1 (Critical)
Version:Connector/J 3.0.8, MySQL 4.0.13 OS:Windows (Windows 2000)
Assigned to: Alexander Soklakov CPU Architecture:Any

[24 Jul 2003 5:11] Gene Vayngrib
Description:
      com.mysql.jdbc.MysqlIO.sqlQueryDirect(com.mysql.jdbc.Buffer, int, com.mysql.jdbc.Connection, int, boolean, java.lang.String) line: 1001 
      com.mysql.jdbc.MysqlIO.sqlQuery(java.lang.String, int, java.lang.String, com.mysql.jdbc.Connection, int, boolean, java.lang.String) line: 928 
      com.mysql.jdbc.Connection.execSQL(java.lang.String, int, com.mysql.jdbc.Buffer, int, boolean, boolean, java.lang.String) line: 1871 
      com.mysql.jdbc.Connection.execSQL(java.lang.String, int, com.mysql.jdbc.Buffer, int, java.lang.String) line: 1817 
      com.mysql.jdbc.Connection.execSQL(java.lang.String, int, java.lang.String) line: 1798 
      com.mysql.jdbc.Connection.unsetMaxRows(com.mysql.jdbc.Statement) line: 1936 
      com.mysql.jdbc.Statement.close() line: 795 

the problem is caused by the fact that MySQL returns -2 (last packet)
in fact code in MysqlIO.java line 1682 detects it 
(resultPacket.isLastDataPacket() returns true and creates an SQlWarning "Command=3")), 
but the code on line 1001 fails to notice this and as a result 
columnCount becomes huge (-2) which causes OutOfMemory

How to repeat:
happens when application is using stm.setMaxRows(limit);
upon statement close Connector/J attempts to
reset the default: SET OPTION SQL_SELECT_LIMIT=DEFAULT
which cause the above problem.
In debugger you can catch OutOfMemoryError, reexecute
the method sqlQueryDirect and the second time MySQL returns normal
packet which causes no problems.
[24 Jul 2003 5:52] Mark Matthews
I've tried this with the latest snapshot of the 3.0 tree, and can't repeat this bug with the following code:

    /**
     * Tests fix for BUG#907
     * 
     * @throws Exception if an error occurs
     */
    public void testSetMaxRows() throws Exception {
    	Statement maxRowsStmt = null;
    	
    	try {
    		maxRowsStmt = this.conn.createStatement();
    		maxRowsStmt.setMaxRows(1);
    		maxRowsStmt.executeQuery("SELECT 1");
    	}
    	finally {
    		if (maxRowsStmt != null) {
    			maxRowsStmt.close();
    		}
    	}
    }

Can you try the latest snapshot from http://mmmysql.sourceforge.net/snapshots/stable/ ? If this bug is still present in the latest code, can you provide a fully repeatable, standalone testcase?
[24 Jul 2003 6:27] Gene Vayngrib
The clue I think lies in the fact that for some reason
in return for SET OPTION SQL_SELECT_LIMIT=DEFAULT
MySQL sent a packet that was marked "last data packet".
When does MySQL normally return such packet?
Could Connector/J check for such condition before treating
this packet as a normal one?

We have rather big application and I lack the 
understanding of MySQL protocol to see what sequence 
of its actions had caused the problem.

If you want to suggest something I can try it - 
I have a stable reproduction. May be there is a way 
to trace all calls to Connector/J - I could turn the trace on.
[24 Jul 2003 6:47] Mark Matthews
Would it be possible to get a tcpdump of the session between JDBC and MySQL?
[7 Aug 2003 15:19] Mark Matthews
No feedback was provided. The bug is being suspended because
we assume that you are no longer experiencing the problem.
If this is not the case and you are able to provide the
information that was requested earlier, please do so and
change the status of the bug back to "Open". Thank you.
[28 Mar 2014 11:44] Alexander Soklakov
I close this report as "Can't repeat" because there is no feedback for a long time and codebase is too old. Please, feel free to reopen it if the problem still exists in current driver.