Bug #43571 Driver attempts to perform SHOW FULL COLUMNS on a non-existent temporary table.
Submitted: 11 Mar 2009 18:08 Modified: 13 Sep 2012 13:45
Reporter: Chris Lampley Email Updates:
Status: Not a Bug Impact on me:
None 
Category:Connector / J Severity:S2 (Serious)
Version:5.1.7 OS:Any
Assigned to: CPU Architecture:Any

[11 Mar 2009 18:08] Chris Lampley
Description:
In a stored procedure, if a result set is selected from a temporary table and then deleted, a MySQLSyntaxErrorException occurs from the driver trying to perform SHOW FULL COLUMNS on the non-existent temporary table.

com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Table 'tmp_table' doesn't exist
	at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
	at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
	at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
	at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
	at com.mysql.jdbc.Util.handleNewInstance(Util.java:406)
	at com.mysql.jdbc.Util.getInstance(Util.java:381)
	at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1030)
	at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:956)
	at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3491)
	at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3423)
	at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1936)
	at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2060)
	at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2536)
	at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2465)
	at com.mysql.jdbc.StatementImpl.executeQuery(StatementImpl.java:1383)
	at com.mysql.jdbc.Field.getCollation(Field.java:465)
	at com.mysql.jdbc.ResultSetMetaData.isCaseSensitive(ResultSetMetaData.java:558)
	at com.sun.rowset.CachedRowSetImpl.initMetaData(CachedRowSetImpl.java:701)
	at com.sun.rowset.CachedRowSetImpl.populate(CachedRowSetImpl.java:621)
      -- Snip --

How to repeat:
Connection Settings:
-noAccessToProcedureBodies=true
-autoReconnect=true
-connectTimeout=20000
-maxReconnects=5
-initialTimeout=1
-emulateUnsupportedPstmts=true
-useServerPrepStmts=true
-jdbcCompliantTruncation=false
-cacheCallableStmts=false
-elideSetAutoCommits=true
-cachePrepStmts=false
-cacheResultSetMetadata=false
-zeroDateTimeBehavior=convertToNull
-profileSQL=true

In a stored procedure: 
1. Create a temporary table.
2. Insert some values into the temporary table.
3. Select the values back as a result set.
4. Delete the temporary table.

The exception is actually thrown when populating a CachedRowSet using CachedRowSetImpl.populate() and passing the ResultSet from the CallableStatement to it.

If you were to remove the deletion of the temporary table at the end of the procedure, then the resulting SQL Profile looks something like this (notice how it does the SHOW FULL COLUMNS call on a temporary table). Of course this works fine because the temporary table still exists. 

Profiler Event: [QUERY] 	at com.epoch.core.dao.SQLAdapter.exec(SQLAdapter.java:811) duration: 95 ms, connection-id: 1687, statement-id: 1930, resultset-id: 1930, message: CALL mySP()
Profiler Event: [FETCH] 	at com.epoch.core.dao.SQLAdapter.exec(SQLAdapter.java:811) duration: 1 ms, connection-id: 1687, statement-id: 1930, resultset-id: 1930
Profiler Event: [QUERY] 	at com.sun.rowset.CachedRowSetImpl.initMetaData(CachedRowSetImpl.java:701) duration: 96 ms, connection-id: 1687, statement-id: 1932, resultset-id: 1931, message: SHOW FULL COLUMNS FROM `tmp_table`
Profiler Event: [FETCH] 	at com.sun.rowset.CachedRowSetImpl.initMetaData(CachedRowSetImpl.java:701) duration: 1 ms, connection-id: 1687, statement-id: 1932, resultset-id: 1931

Without being able to clean up the temporary table at the end of the procedure, it will stay in memory until the connection is closed (which is very bad in a connection pooling scheme).
[12 Mar 2009 10:39] Tonci Grgin
Hi Chris and thanks for your report.

I would like you to attach compact but complete test case demonstrating this behavior so I can check.
[19 Mar 2009 15:25] Mark Matthews
The issue is that CachedRowSet is calling some result set metadata that requires the driver to go out and execute a query to get this information, which for some reason doesn't exist for temporary tables. The workaround is to add "useDynamicCharsetInfo=false" to your JDBC URL properties, which will cause the driver to use a built-in static table to figure this out, rather than do it dynamically.

See http://dev.mysql.com/doc/refman/5.0/en/connector-j-reference-configuration-properties.html for more information regarding this property.
[12 Apr 2009 23:00] Bugs System
No feedback was provided for this bug for over a month, so it is
being suspended automatically. If you are able to provide the
information that was originally requested, please do so and change
the status of the bug back to "Open".