Subject | Incorrect handling of Firebird int64 type |
---|---|
Author | sp64_asaon |
Post date | 2004-05-12T11:33:31Z |
I switched from JayBird 1.0 to 1.5. The new driver now handles
java.sql.Types.BIGINT. The mapping from java.sql.Types.BIGINT
to Firebird.BIGINT (int64) is correct, but not the inverse.
int64 has 3 subtypes:
1=NUMERIC
2=DECIMAL
0=BIGINT
But the driver handles only subtypes 1 and 2.
I checked the mapping with the following test table:
CREATE TABLE TYPETEST (
ID BIGINT NOT NULL,
I16 SMALLINT,
I32 INTEGER,
I64 BIGINT,
F32 FLOAT,
F64 DOUBLE PRECISION,
N154 NUMERIC(15,4),
D154 DECIMAL(15,4),
TS TIMESTAMP,
DT DATE,
TM TIME,
CH CHAR(10),
VC VARCHAR(10)
BT BLOB SUB_TYPE 1 SEGMENT SIZE 512,
BB BLOB SUB_TYPE 0 SEGMENT SIZE 512);
ALTER TABLE TYPETEST
ADD CONSTRAINT PK_TYPETEST
PRIMARY KEY (ID);
Firebird type info (from system tables):
------------------------------------
FIELD TYPE SUB_TYPE LENGTH SCALE
------------------------------------
ID 16 8 0
I16 7 2 0
I32 8 4 0
I64 16 8 0
F32 10 4 0
F64 27 8 0
N154 16 1 8 -4
D154 16 2 8 -4
TS 35 8 0
DT 12 4 0
TM 13 4 0
CH 14 10 0
VC 37 10 0
BT 261 1 8 0
BB 261 0 8 0
The driver erroneously reported the fields ID and I64 as type
NUMERIC with size 0.
I patched FBDatabaseMetaData and FBResultSetMetaData to handle
BIGINT correctly (see patches at the end). I don't have write
access to the repository, can someone please apply the patches?
Regards,
Stephan
Index: FBDatabaseMetaData.java
===================================================================
retrieving revision 1.32
diff -u -r1.32 FBDatabaseMetaData.java
--- FBDatabaseMetaData.java 18 Apr 2004 17:00:43 -0000 1.32
+++ FBDatabaseMetaData.java 12 May 2004 10:39:05 -0000
@@ -2721,11 +2721,11 @@
private int getDataType (short fieldType, short fieldSubType,
short fieldScale) {
if (fieldScale < 0) {
switch (fieldType) {
- //This might need some help for long mapping.
case smallint_type:
case integer_type:
case int64_type:
case double_type:
+ // NOTE: can't be BIGINT because of scale
if (fieldSubType == 2)
return Types.DECIMAL;
else
@@ -2756,11 +2756,12 @@
case date_type:
return Types.DATE;
case int64_type:
- //This might need some help for long mapping
- if (fieldSubType == 2)
- return Types.DECIMAL;
- else
- return Types.NUMERIC;
+ if (fieldSubType == 1)
+ return Types.NUMERIC;
+ else if (fieldSubType == 2)
+ return Types.DECIMAL;
+ else
+ return Types.BIGINT;
case blob_type:
if (fieldSubType < 0)
return Types.BLOB;
@@ -2780,11 +2781,11 @@
private String getDataTypeName (short fieldType, short
fieldSubType, short fieldScale) {
if (fieldScale < 0) {
switch (fieldType) {
- //this might need some help for long mapping
case smallint_type:
case integer_type:
case int64_type:
case double_type:
+ // NOTE: can't be BIGINT because of scale
if (fieldSubType == 2)
return "DECIMAL";
else
@@ -2815,11 +2816,12 @@
case date_type:
return "DATE";
case int64_type:
- //this might need some help for long mapping
- if (fieldSubType == 2)
- return "DECIMAL";
- else
- return "NUMERIC";
+ if (fieldSubType == 1)
+ return "NUMERIC";
+ else if (fieldSubType == 2)
+ return "DECIMAL";
+ else
+ return "BIGINT";
case blob_type:
if (fieldSubType < 0)
return "BLOB SUB_TYPE <0";
Index: FBResultSetMetaData.java
===================================================================
retrieving revision 1.20
diff -u -r1.20 FBResultSetMetaData.java
--- FBResultSetMetaData.java 5 May 2004 20:03:48 -0000 1.20
+++ FBResultSetMetaData.java 12 May 2004 10:40:10 -0000
@@ -219,6 +219,8 @@
return 17;
case Types.INTEGER:
return 11;
+ case Types.BIGINT:
+ return 21;
case Types.SMALLINT:
return 6;
case Types.DATE:
@@ -309,6 +311,8 @@
return 7;
case Types.DOUBLE:
return 15;
+ case Types.BIGINT:
+ return 20;
case Types.INTEGER:
return 10;
case Types.SMALLINT:
@@ -382,6 +386,7 @@
case ISCConstants.SQL_LONG:
case ISCConstants.SQL_INT64:
case ISCConstants.SQL_DOUBLE:
+ // NOTE: can't be BIGINT because of scale
if (sqlsubtype == 2)
return Types.DECIMAL;
else
@@ -412,10 +417,12 @@
case ISCConstants.SQL_TYPE_DATE:
return Types.DATE;
case ISCConstants.SQL_INT64:
- if (sqlsubtype == 2)
- return Types.DECIMAL;
- else
- return Types.NUMERIC;
+ if (sqlsubtype == 1)
+ return Types.NUMERIC;
+ else if (sqlsubtype == 2)
+ return Types.DECIMAL;
+ else
+ return Types.BIGINT;
case ISCConstants.SQL_BLOB:
if (sqlsubtype < 0)
return Types.BLOB;
@@ -453,6 +460,7 @@
case ISCConstants.SQL_LONG:
case ISCConstants.SQL_INT64:
case ISCConstants.SQL_DOUBLE:
+ // NOTE: can't be BIGINT because of scale
if (sqlsubtype == 2)
return "DECIMAL";
else
@@ -483,10 +491,12 @@
case ISCConstants.SQL_TYPE_DATE:
return "DATE";
case ISCConstants.SQL_INT64:
- if (sqlsubtype == 2)
- return "DECIMAL";
- else
- return "NUMERIC";
+ if (sqlsubtype == 1)
+ return "NUMERIC";
+ else if (sqlsubtype == 2)
+ return "DECIMAL";
+ else
+ return "BIGINT";
case ISCConstants.SQL_BLOB:
if (sqlsubtype < 0)
return "BLOB SUB_TYPE <0";
java.sql.Types.BIGINT. The mapping from java.sql.Types.BIGINT
to Firebird.BIGINT (int64) is correct, but not the inverse.
int64 has 3 subtypes:
1=NUMERIC
2=DECIMAL
0=BIGINT
But the driver handles only subtypes 1 and 2.
I checked the mapping with the following test table:
CREATE TABLE TYPETEST (
ID BIGINT NOT NULL,
I16 SMALLINT,
I32 INTEGER,
I64 BIGINT,
F32 FLOAT,
F64 DOUBLE PRECISION,
N154 NUMERIC(15,4),
D154 DECIMAL(15,4),
TS TIMESTAMP,
DT DATE,
TM TIME,
CH CHAR(10),
VC VARCHAR(10)
BT BLOB SUB_TYPE 1 SEGMENT SIZE 512,
BB BLOB SUB_TYPE 0 SEGMENT SIZE 512);
ALTER TABLE TYPETEST
ADD CONSTRAINT PK_TYPETEST
PRIMARY KEY (ID);
Firebird type info (from system tables):
------------------------------------
FIELD TYPE SUB_TYPE LENGTH SCALE
------------------------------------
ID 16 8 0
I16 7 2 0
I32 8 4 0
I64 16 8 0
F32 10 4 0
F64 27 8 0
N154 16 1 8 -4
D154 16 2 8 -4
TS 35 8 0
DT 12 4 0
TM 13 4 0
CH 14 10 0
VC 37 10 0
BT 261 1 8 0
BB 261 0 8 0
The driver erroneously reported the fields ID and I64 as type
NUMERIC with size 0.
I patched FBDatabaseMetaData and FBResultSetMetaData to handle
BIGINT correctly (see patches at the end). I don't have write
access to the repository, can someone please apply the patches?
Regards,
Stephan
Index: FBDatabaseMetaData.java
===================================================================
retrieving revision 1.32
diff -u -r1.32 FBDatabaseMetaData.java
--- FBDatabaseMetaData.java 18 Apr 2004 17:00:43 -0000 1.32
+++ FBDatabaseMetaData.java 12 May 2004 10:39:05 -0000
@@ -2721,11 +2721,11 @@
private int getDataType (short fieldType, short fieldSubType,
short fieldScale) {
if (fieldScale < 0) {
switch (fieldType) {
- //This might need some help for long mapping.
case smallint_type:
case integer_type:
case int64_type:
case double_type:
+ // NOTE: can't be BIGINT because of scale
if (fieldSubType == 2)
return Types.DECIMAL;
else
@@ -2756,11 +2756,12 @@
case date_type:
return Types.DATE;
case int64_type:
- //This might need some help for long mapping
- if (fieldSubType == 2)
- return Types.DECIMAL;
- else
- return Types.NUMERIC;
+ if (fieldSubType == 1)
+ return Types.NUMERIC;
+ else if (fieldSubType == 2)
+ return Types.DECIMAL;
+ else
+ return Types.BIGINT;
case blob_type:
if (fieldSubType < 0)
return Types.BLOB;
@@ -2780,11 +2781,11 @@
private String getDataTypeName (short fieldType, short
fieldSubType, short fieldScale) {
if (fieldScale < 0) {
switch (fieldType) {
- //this might need some help for long mapping
case smallint_type:
case integer_type:
case int64_type:
case double_type:
+ // NOTE: can't be BIGINT because of scale
if (fieldSubType == 2)
return "DECIMAL";
else
@@ -2815,11 +2816,12 @@
case date_type:
return "DATE";
case int64_type:
- //this might need some help for long mapping
- if (fieldSubType == 2)
- return "DECIMAL";
- else
- return "NUMERIC";
+ if (fieldSubType == 1)
+ return "NUMERIC";
+ else if (fieldSubType == 2)
+ return "DECIMAL";
+ else
+ return "BIGINT";
case blob_type:
if (fieldSubType < 0)
return "BLOB SUB_TYPE <0";
Index: FBResultSetMetaData.java
===================================================================
retrieving revision 1.20
diff -u -r1.20 FBResultSetMetaData.java
--- FBResultSetMetaData.java 5 May 2004 20:03:48 -0000 1.20
+++ FBResultSetMetaData.java 12 May 2004 10:40:10 -0000
@@ -219,6 +219,8 @@
return 17;
case Types.INTEGER:
return 11;
+ case Types.BIGINT:
+ return 21;
case Types.SMALLINT:
return 6;
case Types.DATE:
@@ -309,6 +311,8 @@
return 7;
case Types.DOUBLE:
return 15;
+ case Types.BIGINT:
+ return 20;
case Types.INTEGER:
return 10;
case Types.SMALLINT:
@@ -382,6 +386,7 @@
case ISCConstants.SQL_LONG:
case ISCConstants.SQL_INT64:
case ISCConstants.SQL_DOUBLE:
+ // NOTE: can't be BIGINT because of scale
if (sqlsubtype == 2)
return Types.DECIMAL;
else
@@ -412,10 +417,12 @@
case ISCConstants.SQL_TYPE_DATE:
return Types.DATE;
case ISCConstants.SQL_INT64:
- if (sqlsubtype == 2)
- return Types.DECIMAL;
- else
- return Types.NUMERIC;
+ if (sqlsubtype == 1)
+ return Types.NUMERIC;
+ else if (sqlsubtype == 2)
+ return Types.DECIMAL;
+ else
+ return Types.BIGINT;
case ISCConstants.SQL_BLOB:
if (sqlsubtype < 0)
return Types.BLOB;
@@ -453,6 +460,7 @@
case ISCConstants.SQL_LONG:
case ISCConstants.SQL_INT64:
case ISCConstants.SQL_DOUBLE:
+ // NOTE: can't be BIGINT because of scale
if (sqlsubtype == 2)
return "DECIMAL";
else
@@ -483,10 +491,12 @@
case ISCConstants.SQL_TYPE_DATE:
return "DATE";
case ISCConstants.SQL_INT64:
- if (sqlsubtype == 2)
- return "DECIMAL";
- else
- return "NUMERIC";
+ if (sqlsubtype == 1)
+ return "NUMERIC";
+ else if (sqlsubtype == 2)
+ return "DECIMAL";
+ else
+ return "BIGINT";
case ISCConstants.SQL_BLOB:
if (sqlsubtype < 0)
return "BLOB SUB_TYPE <0";