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 "Bryan Pendleton (JIRA)" <ji...@apache.org> on 2015/04/19 19:45:59 UTC

[jira] [Commented] (DERBY-1178) NetworkServer doesn't handle new subclasses of SQLException correctly

    [ https://issues.apache.org/jira/browse/DERBY-1178?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=14502019#comment-14502019 ] 

Bryan Pendleton commented on DERBY-1178:
----------------------------------------

As part of studying DERBY-6773, I've been digging more deeply into how the message handling occurs in the client.

In particular, I'm quite interested in how the message **arguments** are handled.

As Rick noted above:

       "2) The client, on receiving this encoded string, decodes the message ID and args, 
        then asks the server to translate the message into the language preferred by the client."

The heavy lifting for this part of the process occurs in two bits of code which cooperate.

On the client side, we have the method Sqlca.getMessage(), in org.apache.derby.client.am.Sqlca,
which is called by SqlException.getMessage(), in org.apache.derby.client.am.SqlException

And on the server side, we have the SystemProcedure SYSIBM.SQLCAMESSAGE, whose
code lives in org.apache.derby.catalog.SystemProcedures, in the method SQLCAMESSAGE,
and in the lower-level utility routine MessageService.getLocalizedMessage, whose code lives
in org.apache.derby.iapi.services.i18n.MessageService.

So a typical client-side stack trace for getting the correct SQLException to throw on the
client side would look something like this:

        at org.apache.derby.client.am.Sqlca.getMessage(Sqlca.java:285)
        at org.apache.derby.client.am.Sqlca.getJDBCMessage(Sqlca.java:347)
        at org.apache.derby.client.am.SqlException.getMessage(SqlException.java:375)
        at org.apache.derby.client.am.SqlException.getSQLException(SqlException.java:324)
        at org.apache.derby.client.am.ClientPreparedStatement.executeUpdate(ClientPreparedStatement.java:404)
        at DERBY6733Repro.testDerby6733(DERBY6733Repro.java:36)

The reason this is important, is because I think the reality is **slightly** different
that Rick described it. It doesn't appear to me that the client code

        "decodes the message ID and args"

in a complete sense. The client code indeed separates the message ID from the
args, so that when we get to Sqlca.getMessage(), we have, in the case of DERBY-6773:

    SqlCode: -20001
    SqlState: 23505
    errmc:UK_APPLICATION_NAME¶APPLICATION¶23505

This means that, for the purposes of DERBY-6673, which would really like to
get access to the arguments "UK_APPLICATION_NAME" and "APPLICATION",
more work would need to be done on the client side to be able to extract them.


> NetworkServer doesn't handle new subclasses of SQLException correctly
> ---------------------------------------------------------------------
>
>                 Key: DERBY-1178
>                 URL: https://issues.apache.org/jira/browse/DERBY-1178
>             Project: Derby
>          Issue Type: Sub-task
>          Components: JDBC, Localization, Network Server
>    Affects Versions: 10.2.1.6
>            Reporter: Dyre Tjeldvoll
>            Assignee: Rick Hillegas
>            Priority: Critical
>             Fix For: 10.2.1.6
>
>         Attachments: bug1178_rev1.diff
>
>
> I observe a strange diff when running metadata.java under 1.6 and
> NetworkServer.
> Some expected SQLExceptions that are printed in the output have ' : '
> appended to them, and this causes a diff.
> After some debugging and poking around I discovered that this is
> because
> DRDAConnThread::buildSqlerrmc(SQLException se) 
> assumes that if 'se' is NOT an EmbedSQLException it should not build a
> tokenized sqlerrmc:
> 		if (se instanceof EmbedSQLException  && ! severe)
> 			sqlerrmc = buildTokenizedSqlerrmc((EmbedSQLException) se);
> 		else {
> 		    System.out.println("using preformatted..."); 
> 			// If this is not an EmbedSQLException or is a severe excecption where
> 			// we have no hope of succussfully calling the SYSIBM.SQLCAMESSAGE send
> 			// preformatted message using the server locale
> 			sqlerrmc = buildPreformattedSqlerrmc(se);
> 			}
> But in Java 1.6 'se' can indeed be something else, e.g.
> java.sql.SQLSyntaxErrorException
> in this case the NetworkServer will build a preformatted message, and
> SYSIBM.SQLCAMESSAGE will be called on this. Unfortunately  the input
> is not checked very well so it ends up trying to use the preformatted
> message as a real messageId and try to look up a localized version of
> the message. This obviously doesn't work and in the bail-out process we end up
> with the preformatted message with ' : ' appended to it...
> So I think DRDAConnThread::buildSqlerrmc(SQLException se) must be able
> to handle all the new SQLException types.



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)