Hey Craig,
At the end of this message, I have attached a program which demonstrates
the behavior of Statement.cancel() in both the Derby embedded and
network drivers. As you can see from the following output, both drivers
raise a java.sql.SQLFeatureNotSupportedException exception. I ran the
test on Open JDK 22 using the latest Derby release (10.17.1.0):
mainline (22) > runjavaExperimental
/Users/rhillegas/derby/upgradeReleases/10.17.1.0 CancelTest embedded
[/Users/rhillegas/derby/upgradeReleases/10.17.1.0/derby.jar] 10.17.1.0 -
(1913217)
java CancelTest embedded
java.sql.SQLFeatureNotSupportedException: Feature not implemented: cancel.
at
org.apache.derby.impl.jdbc.SQLExceptionFactory.getSQLException(SQLExceptionFactory.java:106)
at
org.apache.derby.impl.jdbc.SQLExceptionFactory.getSQLException(SQLExceptionFactory.java:141)
at org.apache.derby.impl.jdbc.Util.generateCsSQLException(Util.java:225)
at org.apache.derby.impl.jdbc.Util.generateCsSQLException(Util.java:220)
at org.apache.derby.impl.jdbc.Util.notImplemented(Util.java:289)
at org.apache.derby.impl.jdbc.EmbedStatement.cancel(EmbedStatement.java:556)
at CancelTest.main(CancelTest.java:43)
Caused by: ERROR 0A000: Feature not implemented: cancel.
at
org.apache.derby.shared.common.error.StandardException.newException(StandardException.java:299)
at
org.apache.derby.impl.jdbc.SQLExceptionFactory.wrapArgsForTransportAcrossDRDA(SQLExceptionFactory.java:170)
at
org.apache.derby.impl.jdbc.SQLExceptionFactory.getSQLException(SQLExceptionFactory.java:75)
... 6 more
mainline (22) > runjavaExperimental
/Users/rhillegas/derby/upgradeReleases/10.17.1.0 CancelTest network
[/Users/rhillegas/derby/upgradeReleases/10.17.1.0/derby.jar] 10.17.1.0 -
(1913217)
java CancelTest network
java.sql.SQLFeatureNotSupportedException: cancel() not supported by the server.
at
org.apache.derby.client.am.SQLExceptionFactory.getSQLException(SQLExceptionFactory.java:103)
at
org.apache.derby.client.am.SqlException.getSQLException(SqlException.java:325)
at
org.apache.derby.client.am.ClientStatement.cancel(ClientStatement.java:902)
at CancelTest.main(CancelTest.java:43)
Caused by: ERROR 0A000: cancel() not supported by the server.
at
org.apache.derby.client.am.ClientStatement.cancel(ClientStatement.java:897)
... 1 more
Derby code is managed by subversion at
https://svn.apache.org/repos/asf/db/derby/code/trunk/
The code for EmbedStatement is at
https://svn.apache.org/repos/asf/db/derby/code/trunk/java/org.apache.derby.engine/org/apache/derby/impl/jdbc/EmbedStatement.java
The code for ClientStatement is at
https://svn.apache.org/repos/asf/db/derby/code/trunk/java/org.apache.derby.client/org/apache/derby/client/am/ClientStatement.java
Here is the CancelTest program:
import java.sql.*;
public class CancelTest
{
private static final int MILLIS_PER_MINUTE = 1000 * 60;
public static void main(String... args) throws Exception {
String connectionURL = null;
if ((args == null) || (args.length != 1)) { usage(); System.exit(1); }
switch(args[0])
{
case "embedded" : connectionURL =
"jdbc:derby:memory:db;create=true"; break;
case "network" : connectionURL =
"jdbc:derby://localhost:8246/memory:db;create=true"; break;
default: usage(); System.exit(1);
}
Connection conn = DriverManager.getConnection(connectionURL);
conn.prepareStatement
(
"CREATE PROCEDURE waitProc(IN minutesToWait INT)\n" +
"LANGUAGE JAVA\n" +
"PARAMETER STYLE JAVA\n" +
"NO SQL\n" +
"EXTERNAL NAME 'CancelTest.waitProc'\n"
)
.execute();
PreparedStatement waitProcStatement = conn.prepareStatement
(
"CALL waitProc(1)"
);
StatementRunner statementRunner = new
StatementRunner(waitProcStatement);
Thread statementThread = new Thread(statementRunner);
statementThread.start();
Thread.currentThread().sleep(5000);
try
{
waitProcStatement.cancel();
}
catch (Throwable t) { t.printStackTrace(); }
System.exit(1);
}
private static void usage() {
println
(
"Usage:\n" +
"\n" +
" java CancelTest driverType\n" +
"\n" +
" driverType embedded or network\n"
);
}
public static void waitProc(int minutesToWait) throws Exception {
Thread.currentThread().sleep(minutesToWait * MILLIS_PER_MINUTE);
}
private static void println(String text) { System.out.println(text); }
public static class StatementRunner implements Runnable
{
private PreparedStatement _ps;
public StatementRunner(PreparedStatement ps) { _ps = ps; }
public void run() {
try
{
_ps.execute();
}
catch (Throwable t) { t.printStackTrace(); }
}
}
}
On 3/25/24 5:29 PM, Craig Russell wrote:
Hi,
You may notice that JDO is having a bit of a hard time trying to get our test
for canceling a query to work. Our specification calls for throwing an
exception if the JDBC driver does not support it. Our reference implementation
is DataNucleus.
I'd like to verify that since you do not support Statement.cancel() that you
throw an exception when you receive it. Hopefully, it's
SQLFeatureNotSupportedException but for some reason we are not seeing it when
we run DataNucleus and look for exceptions in the log.
I also tried to find the Derby implementation of cancel but could not (I got
lost in the github repo). Could you give us a pointer to the code in the repo?
Many thanks,
Craig
Craig L Russell
c...@apache.org