Issue Details (XML | Word | Printable)

Key: JDBC-632
Type: Bug Bug
Status: Resolved Resolved
Resolution: Fixed
Priority: Major Major
Assignee: Mark Rotteveel
Reporter: Anton Shchyrov
Votes: 0
Watchers: 0
Operations

If you were logged in you would be able to see more operations.
Jaybird JDBC Driver

Case sensitivity first letter in escape clause

Created: 11/Aug/20 12:45 PM   Updated: 12/Aug/20 08:51 AM
Component/s: JDBC driver
Affects Version/s: Jaybird 3.0.7, Jaybird 3.0.8, Jaybird 4.0.0, Jaybird 3.0.9, Jaybird 4.0.1
Fix Version/s: Jaybird 3.0.10, Jaybird 4.0.2, Jaybird 5


 Description  « Hide
When I try to create an object using escape syntax, provided the keyword is in uppercase, I get the exception

org.firebirdsql.jdbc.escape.FBSQLParseException: Unexpected first character inside JDBC escape: C

Code
try (Connection con = DriverManager.getConnection("jdbc:firebirdsql:localhost/3050:c:/db/employee.fdb", "SYSDBA", "masterkey")) {
  CallableStatement stmt = con.prepareCall("{CALL sp_test(?)}");
  stmt.close();
}

Call stack

Exception in thread "main" org.firebirdsql.jdbc.escape.FBSQLParseException: Unexpected first character inside JDBC escape: C
at org.firebirdsql.jdbc.escape.FBEscapedParser$ParserState$4.nextState(FBEscapedParser.java:461)
at org.firebirdsql.jdbc.escape.FBEscapedParser.parse(FBEscapedParser.java:114)
at org.firebirdsql.jdbc.FBConnection.nativeSQL(FBConnection.java:330)
at org.firebirdsql.jdbc.FBStatement.nativeSQL(FBStatement.java:904)
at org.firebirdsql.jdbc.AbstractCallableStatement.<init>(AbstractCallableStatement.java:80)
at org.firebirdsql.jdbc.FBCallableStatement.<init>(FBCallableStatement.java:43)
at org.firebirdsql.jdbc.FBConnection.prepareCall(FBConnection.java:811)
at org.firebirdsql.jdbc.FBConnection.prepareCall(FBConnection.java:777)
at org.firebirdsql.jdbc.FBConnection.prepareCall(FBConnection.java:297)
at test.DBTest.main(DBTest.java:10)


The problem is in method nextState of class ESCAPE_ENTER_STATE

ESCAPE_ENTER_STATE {
  protected FBEscapedParser.ParserState nextState(char inputChar) throws FBSQLParseException {
    switch(inputChar) {
      case '?':
      case 'c':
      case 'd':
      case 'e':
      case 'f':
      case 'l':
      case 'o':
      case 't':
        return NORMAL_STATE;
      default:
        throw new FBSQLParseException("Unexpected first character inside JDBC escape: " + inputChar);
    }
  }
}

This method assumes that the first letter of the keyword should be written in lowercase. Although later, when converting the escape command to native code, there is a forced conversion to lowercase

public final class FBEscapedParser {
    ...............
    private void escapeToNative(StringBuilder target, String escaped) throws SQLException {
        StringBuilder keyword = new StringBuilder();
        StringBuilder payload = new StringBuilder(Math.max(16, escaped.length()));
        this.processEscaped(escaped, keyword, payload);
        String keywordStr = keyword.toString().toLowerCase();

as a consequence, this code works

CallableStatement stmt = con.prepareCall("{сALL sp_test(?)}");
(first letter in lower case)


 All   Comments   Change History   Subversion Commits      Sort Order: Ascending order - Click to sort in descending order
Mark Rotteveel added a comment - 11/Aug/20 03:02 PM
The JDBC specification specifies the escape as {?= call <procedure-name>[(<arg1>,<arg2>, ...)]} and {call <procedure-name>[(<arg1>,<arg2>, ...)]}, so with all lowercase; it doesn't explicitly specify case-sensitivity of escapes, but assuming behaviour similar to SQL keywords, I agree that it should be case-insensitive.

This a regression compared to Jaybird 2.2.x introduced in 3.0.0; I will fix this in Jaybird 4.0.2 and 3.0.10 (and Jaybird 5). Unfortunately, you reported this just while I was releasing 4.0.1, I have no set date for releasing 4.0.2.

As a workaround, I recommend using the syntax as specified by JDBC (that is: lowercase `call`).

Mark Rotteveel added a comment - 11/Aug/20 03:50 PM
Fix committed

Anton Shchyrov added a comment - 12/Aug/20 08:51 AM
Thanks for the quick fix