# JDBC 2.0 implementation

Last updated. December 17 2002

## 1.- Introduction

This document is focused on feature coverage of the JDBC 2.0 specification and performance.

For more information about the driver and how to use it, please read the release notes and FAQ.

## 2.- Connection URL

The driver URL syntax has two forms:

Standard format= jdbc:firebirdsql:[//host[:port]/]<database>
FB old format= jdbc:firebirdsql:[host[/port]:]<database>

## 3.- JDBC Features

The driver complies with the JDBC 2.0 core with some features and methods not implemented. Some of the unimplemented features are required by the specification and some are optional.

The following optional features and the methods that support it are not implemented:

- ResultSet.TYPE_SCROLL_SENSITIVE

  Server does not support scrollable cursors, so we are not able to implement this feature correctly. When you create a statement with result set type TYPE_SCROLL_SENSITIVE, it is replaced with TYPE_SCROLL_INSENSITIVE and corresponding warning is added to connection warnings.

- ResultSet.CONCUR_UPDATABLE

  - java.sql.ResultSet

    - rowUpdated()

    - rowInserted()

    - rowDeleted()

    - updateXXX(....)

    - insertRow()

    - updateRow()

    - deleteRow()

    - refreshRow()

    - cancelRowUpdates()

    - moveToInsertRow()

    - moveToCurrentRow()

- Ref, Clob and Array types.

  - java.sql.PreparedStatement

    - setRef(int i, Ref x)

    - setClob (int i, Clob x)

    - setArray(int i, Array x)

  - java.sql.ResultSet

    - getArray(int i)

    - getArray(String columnName)

    - getRef(int i)

    - getRef(String columnName)

    - getClob(int i)

    - getClob(String columnName)

- User Defined Types/Type Maps.

  - java.sql.ResultSet

    - getObject(int i, java.util.Map map)

    - getObject(String columnName, java.util.Map map)

  - java.sql.Connection

    - getTypeMap()

    - setTypeMap(java.util.Map map)

Excluding the unsupported features, the following methods are not yet implemented:

- java.sql.Statement

  - cancel()

- java.sql.Blob

  - position(byte pattern[], long start)

  - position(Blob pattern, long start)

The following methods are implemented, but do not work as expected:

- java.sql.Statement

  - get/setMaxFieldSize does nothing

  - get/setQueryTimeout does nothing

- java.sql.PreparedStatement

  - setObject(index,object,type) This method is implemented but behaves as setObject(index,object)

  - setObject(index,object,type,scale) This method is implemented but behaves as setObject(index,object)

- java.sql.ResultSetMetaData

  - isReadOnly(i) always returns false

  - isWritable(i) always returns true

  - isDefinitivelyWritable(i) always returns true

- java.sql.DatabaseMetaData

  - getBestRowIdentifier(i) always returns empty resultSet

## 4.- Compliance Tests

JDBC 2.0 compliance was checked with Sun JDBC CTS 1.3.1 test suite. Driver passed all relevant tests (totally 1216 tests), excluded tests can be checked in the CVS in client-java/src/jdbccts/excludes.properties. This file also contains explanations why the test was exluded. There are two main groups of test cases that were excluded: BIT data type tests and tests that fail due to rounding problems in floating-point numbers within the Firebird itself. BIT data type is not yet supported by Firebird and rounding problems will be checked with server team. Some tests were excluded due to errors within the tests themselves, this will be checked with Sun Microsystems later.

## 5.- Performance recommendations

Updates, deletes etc

Don't use executeUpdate when you don't need the affected record count. Because the database doesn't send this information to the result, the driver must request it after the execution finishes, and it needs some time to do it . Use execute() instead of executeUpdate() when count is not needed.

Character encoding

In FB the client notifies the server which character set it will use in the communication. The server then converts all the incoming character information from this character set to the one of the field or database. In the output the server also does the conversion from the database/field character set to the one needed by the client.

This driver sets as the default the NONE character set, the same that Interclient uses. It seems there are some performance problems in the engine and when the NONE character set is received it takes some time to convert it to the character set of the field/database. When using NONE, the theory is that the server only verifies that the characters received are valid characters.

When using a character set other than NONE in the database, set the lc_ctype parameter equal to the database default charset. If you can, select the database default character set to be equivalent to the default character set of your JVM.

Also you can set the default character set of the database to NONE, but this is not recommended since other tools that can be used with the database can't know which character set is in use.

Apparently, there can be some problems if the database uses character set NONE and the lc_ctype parameter is set to WIN1252.

| A) RC2 | B) RC2 | C) RC2 | time B/A(%) | time C/A(%)
Client lc_ctype | NONE | WIN1252 | NONE |  |
DB default charset | WIN1252 | WIN1252 | NONE |  |
IMPLICIT TRANSACTION CONTROL
Insert short record of Char | 14719 | 13547 | 12844 | 92 | 87
Insert long record of Char | 10218 | 8656 | 8453 | 85 | 83
Insert short record of Varchar | 14016 | 13484 | 12828 | 96 | 92
Insert long record of Varchar | 9172 | 8406 | 8031 | 92 | 88
EXPLICIT TRANSACTION CONTROL
Insert short record of Char | 4594 | 3579 | 3469 | 78 | 76
Insert long record of Char | 4500 | 3110 | 3063 | 69 | 68
Insert short record of Varchar | 4109 | 3672 | 3578 | 89 | 87
Insert long record of Varchar | 3609 | 2985 | 2922 | 83 | 81