SQL-J Language Reference
Page 121 of 121

SQL-J and Java Type Correspondence

This section covers the following topics:

Each built-in type in SQL-J has a Java class associated with it. For example, the corresponding type for an SQL-J INTEGER is java.lang.Integer. Consider the following SQL-J statement:

VALUES (1 INSTANCEOF java.lang.Integer)

It returns the value TRUE, since the SQL-J type INTEGER maps to the Java class java.lang.Integer.

Column Values and Type Correspondence

You can insert a value of a built-in type into a column of its corresponding Java class, and vice versa. Table 1-11, "Java Classes Associated with SQL-J Built-In Types", shows the correspondence between types:

Table 1-11 Java Classes Associated with SQL-J Built-In Types 

Built-In SQL-J Type

Corresponding Java Class

INTEGER

java.lang.Integer

SMALLINT

java.lang.Short

LONGINT

java.lang.Long

TINYINT

java.lang.Byte

REAL

java.lang.Float

DOUBLE PRECISION

java.lang.Double

FLOAT

java.lang.Float OR java.lang.Double, depending on the precision you specify

DECIMAL

java.math.BigDecimal

NUMERIC

java.math.BigDecimal

CHAR

java.lang.String

VARCHAR

java.lang.String

LONG VARCHAR

java.lang.String

BIT

byte[]

BIT VARYING

byte[]

LONG VARBINARY

byte[]

BOOLEAN

java.lang.Boolean

DATE

java.sql.Date

TIME

java.sql.Time

TIMESTAMP

java.sql.Timestamp

SQL-J to Java Type Correspondence

Table 1-12, "Conversion of SQL-J Types to Java Classes During Method Invocation", shows the correspondence between SQL-J types and Java classes. SQL-J expressions that become method receivers, as well as SQL-J expressions used as parameter values passed to the method, are mapped to Java types according to this table during method invocation.

The third column shows what primitive is used during second-chance conversion by Cloudscape if on the first pass it cannot find a method with the matching signature. This conversion is all-or-nothing; see Method Resolution and Type Correspondence.

Table 1-12 Conversion of SQL-J Types to Java Classes
During Method Invocation 

SQL-J Type

Corresponding Java Class

Second-Chance Conversion

INTEGER

java.lang.Integer

int

SMALLINT

java.lang.Short

short

LONGINT

java.lang.Long

long

TINYINT

java.lang.Byte

byte

REAL

java.lang.Float

float

DOUBLE PRECISION

java.lang.Double

double

FLOAT

java.lang.Float OR java.lang.Double, depending on the precision you specify

float/double

DECIMAL

java.math.BigDecimal

double

NUMERIC

java.math.BigDecimal

double

CHAR

java.lang.String


VARCHAR

java.lang.String


LONG VARCHAR

java.lang.String


BIT

byte[]


BIT VARYING

byte[]


LONG VARBINARY

byte[]


BOOLEAN

java.lang.Boolean

boolean

DATE

java.sql.Date


TIME

java.sql.Time


TIMESTAMP

java.sql.Timestamp


Java data type a.b.c

a.b.c


Java to SQL-J Type Correspondence

In SQL-J statements, Cloudscape converts the return values of invoked Java methods and accessed fields of Java objects or classes to SQL-J values, except when the value is used as a receiver or parameter to another method. In that case, the value remains a Java value. This means, for example, that if a method returns a Java int type, that int can be passed directly to a Java method that takes an int; it is not first converted to a SQL-J INTEGER and then back to a Java java.lang.Integer.

Cloudscape converts return values to SQL-J built-in types according to Table 1-13, "Conversion of Java Types to SQL-J Types".

Table 1-13 Conversion of Java Types to SQL-J Types 

Java Type

Corresponding SQL-J Type

java.lang.Integer

INTEGER

int

INTEGER

java.lang.Short

SMALLINT

short

SMALLINT

java.lang.Long

LONGINT

long

LONGINT

java.lang.Byte

TINYINT

byte

TINYINT

java.lang.Float

REAL

float

REAL

java.lang.Double

DOUBLE PRECISION

double

DOUBLE PRECISION

java.lang.String

VARCHAR

byte[]

BIT VARYING

java.lang.Boolean

BOOLEAN

boolean

BOOLEAN

java.math.BigDecimal

DECIMAL

java.sql.Date

DATE

java.sql.Time

TIME

java.sql.Timestamp

TIMESTAMP

a.b.c

Java data type a.b.c

No Java types map to FLOAT, CHAR, BIT, LONG VARBINARY, or LONG VARCHAR by default. The Java primitive types char and byte do not map to any SQL-J types.

Method Resolution and Type Correspondence

General Method Invocation, the NEW command constructor method invocation, and the CALL statement method invocation all require method resolution.

The rules of Java determine that a method's signature which which method is invoked; the signature of a method is its name, the class of the receiver, and the number and types of the parameters. Cloudscape searches the receiving class for a method with a matching signature and can find methods in superclasses of the receiving class. Cloudscape uses the method with the signature that has the best match according to the rules of Java. The return type of the method is determined by the method invoked.

If on the first attempt Cloudscape does not find a match, Cloudscape converts all SQL-J numeric types and BOOLEANs to their corresponding Java primitive types. (This conversion is all-or-nothing.) The conversion from SQL-J to Java primitive types is done according to Table 1-14, "Second-Chance Conversion of SQL-J Types to Java Primitive Types".

Thus:

NEW java.lang.Integer(1)

finds the correct constructor. On the first attempt, Cloudscape looks for a method with a java.lang.Integer parameter (because that is the corresponding type of the SQL-J INTEGER type) and fails. On the second attempt, Cloudscape looks for a method with a primitive int parameter and succeeds.

Table 1-14 Second-Chance Conversion of SQL-J Types to Java Primitive Types

SQL-J Types

Corresponding Java Primitive

TINYINT

byte

BOOLEAN

boolean

SMALLINT

short

INTEGER

int

LONGINT

long

REAL

float

DECIMAL

double

DOUBLE PRECISION

double

Cloudscape uses Java's rules for parameter broadening to determine whether a method matches an invocation. For example, consider the following method invocation:

myColumn.myLongMethod((1).intValue())

The parameter is a java.lang.Integer (which is converted to an int on the second try) so the invocation can match a method that takes a long parameter.

NOTE: Cloudscape is not able to match some signatures, such as those with both an Integer and an int parameter. It will interpret both as Integers on the first pass, and both as ints in the second pass.

Cloudscape treats untyped parameters (dynamic parameters and null) the same as any other parameters. On the first pass, Cloudscape attempts to match the parameters to objects and on the second pass as primitives.

For example, the following statement compiles, because Cloudscape is able to match the ? to a primitive type.

-- will compile
CREATE STATEMENT j4 AS VALUES (CLASS java.lang.Math).abs(?)

Note, however, that since the method named java.lang.Math.abs has four signatures, all of which are primitives, you have no way of guaranteeing that Cloudscape chooses the one you want unless you cast the dynamic parameter to the built-in Cloudscape type that matches the primitive you want. For example:

CREATE STATEMENT j5 AS
VALUES (CLASS java.lang.Math).abs(CAST (? AS LONGINT))