You are viewing a plain text version of this content. The canonical link for it is here.
Posted to derby-dev@db.apache.org by "Knut Anders Hatlen (JIRA)" <ji...@apache.org> on 2014/02/25 15:36:19 UTC

[jira] [Updated] (DERBY-6488) Get rid of the EmbedSQLException class

     [ 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)