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