[
https://issues.apache.org/jira/browse/DERBY-6488?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Knut Anders Hatlen updated DERBY-6488:
--------------------------------------
Attachment: d6488-1a.diff
The attached patch (d6488-1a.diff) removes the EmbedSQLException class and the
associated DerbySQLException interface. The network server now uses the message
id and message arguments from the StandardException class instead of the
EmbedSQLException class when encoding an error message for transport over DRDA.
This change makes the typical SQLException stack trace slightly simpler. The
simplest SQLExceptions produced by Derby used to be a chain of three exceptions:
# the top-level SQLException (possibly a specialized class, such as
SQLSyntaxErrorException)
# an EmbedSQLException
# a StandardException
After the patch, the chain only contains 1 and 3.
For example, the stack trace of a syntax error used to look like this:
{noformat}
Exception in thread "main" java.sql.SQLSyntaxErrorException: Table/View 'T'
does not exist.
at
org.apache.derby.impl.jdbc.SQLExceptionFactory.getSQLException(SQLExceptionFactory.java:93)
at org.apache.derby.impl.jdbc.Util.generateCsSQLException(Util.java:288)
at
org.apache.derby.impl.jdbc.TransactionResourceImpl.wrapInSQLException(TransactionResourceImpl.java:424)
at
org.apache.derby.impl.jdbc.TransactionResourceImpl.handleException(TransactionResourceImpl.java:353)
at
org.apache.derby.impl.jdbc.EmbedConnection.handleException(EmbedConnection.java:2396)
at
org.apache.derby.impl.jdbc.ConnectionChild.handleException(ConnectionChild.java:82)
at
org.apache.derby.impl.jdbc.EmbedStatement.execute(EmbedStatement.java:691)
at
org.apache.derby.impl.jdbc.EmbedStatement.executeQuery(EmbedStatement.java:147)
at Kladd.main(Kladd.java:20)
Caused by: java.sql.SQLException: Table/View 'T' does not exist.
at
org.apache.derby.impl.jdbc.SQLExceptionFactory.wrapArgsForTransportAcrossDRDA(SQLExceptionFactory.java:141)
at
org.apache.derby.impl.jdbc.SQLExceptionFactory.getSQLException(SQLExceptionFactory.java:73)
... 8 more
Caused by: ERROR 42X05: Table/View 'T' does not exist.
at
org.apache.derby.iapi.error.StandardException.newException(StandardException.java:265)
at
org.apache.derby.iapi.error.StandardException.newException(StandardException.java:260)
at
org.apache.derby.impl.sql.compile.FromBaseTable.bindTableDescriptor(FromBaseTable.java:2687)
at
org.apache.derby.impl.sql.compile.FromBaseTable.bindNonVTITables(FromBaseTable.java:2309)
at
org.apache.derby.impl.sql.compile.FromList.bindTables(FromList.java:343)
at
org.apache.derby.impl.sql.compile.SelectNode.bindNonVTITables(SelectNode.java:490)
at
org.apache.derby.impl.sql.compile.DMLStatementNode.bindTables(DMLStatementNode.java:190)
at
org.apache.derby.impl.sql.compile.DMLStatementNode.bind(DMLStatementNode.java:127)
at
org.apache.derby.impl.sql.compile.CursorNode.bindStatement(CursorNode.java:272)
at
org.apache.derby.impl.sql.GenericStatement.prepMinion(GenericStatement.java:401)
at
org.apache.derby.impl.sql.GenericStatement.prepare(GenericStatement.java:99)
at
org.apache.derby.impl.sql.conn.GenericLanguageConnectionContext.prepareInternalStatement(GenericLanguageConnectionContext.java:1116)
at
org.apache.derby.impl.jdbc.EmbedStatement.execute(EmbedStatement.java:683)
{noformat}
Now the same error has a stack trace that looks like this:
{noformat}
Exception in thread "main" java.sql.SQLSyntaxErrorException: Table/View 'T'
does not exist.
at
org.apache.derby.impl.jdbc.SQLExceptionFactory.getSQLException(SQLExceptionFactory.java:95)
at org.apache.derby.impl.jdbc.Util.generateCsSQLException(Util.java:265)
at
org.apache.derby.impl.jdbc.TransactionResourceImpl.wrapInSQLException(TransactionResourceImpl.java:424)
at
org.apache.derby.impl.jdbc.TransactionResourceImpl.handleException(TransactionResourceImpl.java:353)
at
org.apache.derby.impl.jdbc.EmbedConnection.handleException(EmbedConnection.java:2396)
at
org.apache.derby.impl.jdbc.ConnectionChild.handleException(ConnectionChild.java:82)
at
org.apache.derby.impl.jdbc.EmbedStatement.execute(EmbedStatement.java:691)
at
org.apache.derby.impl.jdbc.EmbedStatement.executeQuery(EmbedStatement.java:147)
at Kladd.main(Kladd.java:20)
Caused by: ERROR 42X05: Table/View 'T' does not exist.
at
org.apache.derby.iapi.error.StandardException.newException(StandardException.java:288)
at
org.apache.derby.iapi.error.StandardException.newException(StandardException.java:283)
at
org.apache.derby.impl.sql.compile.FromBaseTable.bindTableDescriptor(FromBaseTable.java:2687)
at
org.apache.derby.impl.sql.compile.FromBaseTable.bindNonVTITables(FromBaseTable.java:2309)
at
org.apache.derby.impl.sql.compile.FromList.bindTables(FromList.java:343)
at
org.apache.derby.impl.sql.compile.SelectNode.bindNonVTITables(SelectNode.java:490)
at
org.apache.derby.impl.sql.compile.DMLStatementNode.bindTables(DMLStatementNode.java:190)
at
org.apache.derby.impl.sql.compile.DMLStatementNode.bind(DMLStatementNode.java:127)
at
org.apache.derby.impl.sql.compile.CursorNode.bindStatement(CursorNode.java:272)
at
org.apache.derby.impl.sql.GenericStatement.prepMinion(GenericStatement.java:401)
at
org.apache.derby.impl.sql.GenericStatement.prepare(GenericStatement.java:99)
at
org.apache.derby.impl.sql.conn.GenericLanguageConnectionContext.prepareInternalStatement(GenericLanguageConnectionContext.java:1116)
at
org.apache.derby.impl.jdbc.EmbedStatement.execute(EmbedStatement.java:683)
... 2 more
{noformat}
The changes made by the patch are as follows:
*java/engine/org/apache/derby/impl/jdbc/EmbedSQLException.java*
*java/engine/org/apache/derby/iapi/error/DerbySQLException.java*
Deleted.
*java/engine/org/apache/derby/iapi/error/PublicAPI.java*
Produce an SQLException instead of an EmbedSQLException.
Flag the exception as one created by PublicAPI, since the EmbedSQLException
instances created here used to have some special handling in
StandardException.unexpectedUserException().
*java/engine/org/apache/derby/iapi/error/StandardException.java*
Make unexpectedUserException() look for ferried arguments in StandardException
instead of EmbedSQLException.
Add methods that replace the "simple wrapper" functionality in the removed
EmbedSQLException class, needed by PublicAPI.wrapStandardException().
*java/engine/org/apache/derby/impl/jdbc/Util.java*
Remove an unneeded cast to EmbedSQLException in debug code (which definitely
won't work now, and probably didn't work earlier either if the code had ever
been exercised on Java 6 or later).
Remove an unused method (which also had an unneeded and possibly broken cast to
EmbedSQLException).
*java/engine/org/apache/derby/impl/jdbc/SQLExceptionFactory.java*
Get the arguments from the StandardException instead of EmbedSQLException.
Produce a dummy StandardException (instead of EmbedSQLException) to hold the
message arguments if one isn't already provided.
*java/drda/org/apache/derby/impl/drda/DRDAConnThread.java*
*java/drda/org/apache/derby/impl/drda/NetworkServerControlImpl.java*
Fetch the message arguments from StandardException instead of EmbedSQLException.
*java/testing/org/apache/derbyTesting/functionTests/master/importExportIJ.out*
Update canon. After PublicAPI.wrapStandardException() started using the
exception factory, a syntax error wrapped by that method comes out with a
proper SQLSyntaxErrorException instead of a plain SQLException.
*java/testing/org/apache/derbyTesting/functionTests/tests/jdbc4/PreparedStatementTest.java*
Update an assert. It checked that one of the exceptions in the chain (a
StandardException) was not an EmbedSQLException. While this is still true, it
makes little sense to check for a removed class. The assert now checks that the
exception is a StandardException.
All the regression tests ran cleanly with the patch.
> Get rid of the EmbedSQLException class
> --------------------------------------
>
> Key: DERBY-6488
> URL: https://issues.apache.org/jira/browse/DERBY-6488
> Project: Derby
> Issue Type: Improvement
> Components: JDBC
> Affects Versions: 10.11.0.0
> Reporter: Knut Anders Hatlen
> Assignee: Knut Anders Hatlen
> Attachments: d6488-1a.diff
>
>
> EmbedSQLException used to be the top-level exception raised on error in the
> JDBC 3 version of the embedded driver. The primary purpose of the
> EmbedSQLException class is gone now that JDBC 4.0 is the minimum JDBC level,
> and all top-level exceptions are vanilla java.sql.SQLExceptions or one of its
> specialized subtypes.
> The top-level SQLException still links to an EmbedSQLException in order to
> provide some extra information (such as the message id) that the network
> server needs when encoding the exception for transport over the wire. I think
> it should be possible for the network server to get this information from the
> StandardException which is typically also in the exception chain.
> When embedded Derby raises an exception currently, it is typically a
> java.sql.SQLException (or subclass) that's linked to an EmbedSQLException
> that's linked to a StandardException. If we could find a way to eliminate the
> EmbedSQLException from the exception chain, the stack traces would be easier
> to read, and the structure of the exception chains would be more consistent
> with the client exceptions.
--
This message was sent by Atlassian JIRA
(v6.1.5#6160)