Bug #16734 CallableStatement.getMetaData() returns a null ResultSetMetaData
Submitted: 23 Jan 2006 20:07 Modified: 2 Aug 2006 10:02
Reporter: juanma bardavio Email Updates:
Status: Closed Impact on me:
None 
Category:Connector / J Documentation Severity:S3 (Non-critical)
Version:3.1.12 OS:Linux (linux)
Assigned to: MC Brown CPU Architecture:Any

[23 Jan 2006 20:07] juanma bardavio
Description:
First of all, sorry for the expressions. My english isn't very fluently.

I'm using mysql-connector-java-3.1.12, and trying to obtain a ResultSetMetaData
from a CallableStatement. I always get a null ResultSetMetaData.

On bug #9320 you suggested a workaround for a bug that would be fixed in 2005.
The bug was that a call to PreparedStatement.getMetaData() returned
a 'null' ResultSetMetaData when you asked for MetaData returned by an INSERT
sentence. This case is very similar.

Looking at the source code of CallableStatement, I saw that the getMetaData()
method isn't overwritten, so I searched that method in PreparedStatement, and
found that if the variable 'originalSql' does not begin with "SELECT", it
returns 'null':
---------------------------------------------------------------------
 From PreparedStatement.getMetaData():

 if (!StringUtils.startsWithIgnoreCaseAndNonAlphaNumeric(
    this.originalSql, "SELECT")) {
    return null;
 }
----------------------------------------------------------------------------------------

When you are calling a procedure like "{call proc_name()}", the EscapeProcessor
does not return a SQL statement that begins with "SELECT"

Following the trace of the code from Connection.prepareCall(), I think that
'originalSql' gets the value of "CALL procedure_name..." (in the EscapeProcessor
class), and that's the cause of failure on CallableStatement/PreparedStatement.getMetaData().

When you are calling a procedure like "{call proc_name()}", the EscapeProcessor
does not return a SQL statement that begins with "SELECT". It only returns a
"SELECT..." when you are calling a stored function ({?=call proc_name()}).

----------------------------------------------------------------------
from EscapeProcessor:

                        if (StringUtils.startsWithIgnoreCase(collapsedToken,
                                "{?=call")) {
                            callingStoredFunction = true;
                            newSql.append("SELECT ");
                            newSql.append(token.substring(startPos, endPos));
                        } else {
                            callingStoredFunction = false;
                            newSql.append("CALL ");
                            newSql.append(token.substring(startPos, endPos));
                        }
------------------------------------------------------------------------------------------

I'm not sure if this is a real bug, since the PreparedStatement interface
can return a 'null' ResultSetMetaData object when you call its getMetaData()
method.

How to repeat:
Trying to get a ResultSetMetaData from a CallableStatement, when you call a stored procedure with the syntax {call proc_name()}

Suggested fix:
If returning a null ResultSetMetaData is the expected behavior of CallableStatement, it might be useful to describe that behavior on the docs.
 I couldn't find it on 
http://dev.mysql.com/doc/refman/5.0/en/cj-using-callable-statements.html
 neither in the white paper "MySQL 5.0 Stored Procedures: MySQL 5.0 New Features Series - Part1" by Peter Gulutzan
[2 Feb 2006 19:42] Mark Matthews
The server does not currently return enough information to enable the JDBC driver to provide result set metadata for callable statements.

We'll fix the documentation to include this limitation.
[2 Aug 2006 9:52] MC Brown
A note on this limitation has been added to the Connector/J documentation.