Issue Details (XML | Word | Printable)

Key: JDBC-402
Type: Bug Bug
Status: Closed Closed
Resolution: Fixed
Priority: Major Major
Assignee: Mark Rotteveel
Reporter: Attila Molnár
Votes: 0
Watchers: 0
Operations

If you were logged in you would be able to see more operations.
Jaybird JCA/JDBC Driver

prepared CallableStatement.getMetaData() call throws exception when no input parameters provided

Created: 24/Jul/15 09:58 AM   Updated: 19/Oct/15 03:40 PM
Component/s: JDBC driver
Affects Version/s: Jaybird 2.2.8
Fix Version/s: Jaybird 2.2.9, Jaybird 3.0.0

Issue Links:
Relate
 


 Description  « Hide
Hi Mark!

create or alter procedure test(x integer)
returns (y integer)
as
begin
end

BasicDataSource ds = new BasicDataSource();
ds.setUrl("...");
ds.setUsername("SYSDBA");
ds.setPassword("masterkey");
Connection conn = ds.getConnection();
CallableStatement cs = conn.prepareCall("EXECUTE PROCEDURE test(?, ?)");
cs.registerOutParameter(2, java.sql.Types.INTEGER);
System.out.print(cs.getMetaData().getColumnClassName(1));

Exception in thread "main" org.firebirdsql.jdbc.FBSQLException: Value of parameter 1 not set and it was not registered as output parameter.
at org.firebirdsql.jdbc.FBProcedureCall.getSQL(FBProcedureCall.java:370)
at org.firebirdsql.jdbc.AbstractCallableStatement.getMetaData(AbstractCallableStatement.java:244)
at org.apache.commons.dbcp2.DelegatingPreparedStatement.getMetaData(DelegatingPreparedStatement.java:231)
at org.apache.commons.dbcp2.DelegatingPreparedStatement.getMetaData(DelegatingPreparedStatement.java:231)

getMetaData() calls getSQL() (org.firebirdsql.jdbc.FBProcedureCall), but the latter checks wheter input parameters were set. This check is not needed in this case, getMetaData() should work on a prepared statement.

workaround : cs.setObject(1, null); before cs.getMetaData() call.



Thank You!

 All   Comments   Change History   Subversion Commits      Sort Order: Ascending order - Click to sort in descending order
Mark Rotteveel added a comment - 24/Jul/15 10:46 AM - edited
I am not sure why that even works at all. What happens if you use {?=call test(?)} instead?

Attila Molnár added a comment - 24/Jul/15 10:52 AM
Exactly the same.

Mark Rotteveel added a comment - 24/Jul/15 12:36 PM
Looks like you are right, that check in getSQL should be moved out so it is only done on execute. I will see if I can fix this in Jaybird 2.2.9.

As this is a executable stored procedure, technically you should be using getParameterMetaData instead of getMetaData, but out parameters aren't correctly offered in the parameter metadata at the moment... I hope to get it more JDBC compliant with JDBC-297 in Jaybird 3.0.

Mark Rotteveel added a comment - 18/Aug/15 07:26 PM
The code is pretty hairy (and scary). The reason it checks for values set (and registered out parameters) is to determine if all parameters have been "properly" registered before it ask the server to prepare the statement (otherwise it is possible that it tries to prepare a statement with the wrong number of parameters).

Removing the check here in getMetaData (and getParameterMetaData) should fix this problem, but only if all out parameters have been registered, otherwise it will still result in a failure when the statement is prepared server side to obtain the metadata (because of the wrong number of parameters).

Mark Rotteveel added a comment - 18/Oct/15 09:50 AM
Removed the check from getSQL, and created new check that is only done before execute, addBatch and as part normal JDBC escape parsing.

The check in the normal JDBC escape parsing is slightly dubious, as it might break unintentionally. I will look at this as part of JDBC-296 and JDBC-297.

Attila Molnár added a comment - 19/Oct/15 12:09 PM
Great!

When we can expect 2.2.9 to be released?

Mark Rotteveel added a comment - 19/Oct/15 01:39 PM
I am running the last tests now, and I am trying to get it out the door today.