momo - 2014-01-07

According to these JavaDoc comments it seems that driver should close underlying resources immediately and reading all rows from ResultSet is not immediate!

Here "immediately" specifies the time when a resource should be closed in contrast to "waiting for this to happen when it is automatically closed" - closing itself will of course take some time anyway and in this certain case unfortunately also involves reading all remaining rows.

I fully understand that running through the whole result may cause immense problems and is anything but a perfect solution. But in almost any problematic case I've seen so far, the application logic was poorly designed and issuing an appropriate query solved the problem of huge amounts of waste rows. Needless to say this wouldn't help if you are stuck to a third party software product.

It seems that one would need to use Statement#getResultSet() and Statement#getMoreResults(int) methods to obtain current and next ResultSets. Since Statement#getMoreResults(int) allows passing constant Statement#KEEP_CURRENT_RESULT I would expect that one can actually obtain different ResultSet objects in this case, because one moves to another ResultSet without closing or discarding previous ResultSet. Hence ResultSets should be independent of one another and therefore invoking ResultSet#close() on one of them should not depend or impact other ResultSets!

That's what this discussion is all about - jTDS has to provide a client-side implementation of the describes behavior (e.g. by buffering results to disk) because SQL Server simply sends a single data stream containing all results, one after another, without previously announcing what it will return in response to the last command. So we have to read through the complete first ResultSet just to know whether there is any further result, fetch errors reported by the server and so on. There simply is no server-side function for skipping anything - we could just cancel the whole operation, discarding any remaining results.

What if when Statement#executeQuery(java.lang.String) is called it will create JtdsResultSet object with a flag that says that method close() should terminate immediately...

Sounds quite reasonable. I'll see if that can be implemented without causing too much hassle.

Current workaround for this bug that we use is to call Statement#cancel() prior closing ResultSet and Statement objects.

This is exactly what I would recommend if you know you are dealing with a lot of unused data. This may not be the most elegant solution but the driver simply cannot distinguish between "close this result and continue with whatever comes next" and "close the result, I'm done".