Обсуждение: some improve JDBC
Hi all!
My name is Victor, I lead the enterprise www.e-evolution.com, we are working
in making a port of software Compiere (www.compiere.org) that now only works
with oracle to PostgreSQL.
Compiere use the RowSet implementation, I made some changes to the source
AbstractJdbc2ResultSetMetaData method:
/*
* What is the column's normal maximum width in characters?
*
* @param column the first column is 1, the second is 2, etc.
* @return the maximum width
* @exception SQLException if a database access error occurs
*/
public int getColumnDisplaySize(int column) throws SQLException
{
Field f = getField(column);
String type_name = getPGType(column);
int typmod = f.getMod();
// I looked at other JDBC implementations and couldn't find a
consistent
// interpretation of the "display size" for numeric values, so this is
our's
// FIXME: currently, only types with a SQL92 or SQL3 pendant are
implemented - jens@jens.de
// fixed length data types
if (type_name.equals( "int2" ))
return 6; // -32768 to +32768 (5 digits and a sign)
if (type_name.equals( "int4" )
|| type_name.equals( "oid" ))
return 11; // -2147483648 to +2147483647
if (type_name.equals( "int8" ))
return 20; // -9223372036854775808 to +9223372036854775807
if (type_name.equals( "money" ))
return 12; // MONEY = DECIMAL(9,2)
if (type_name.equals( "float4" ))
return 11; // i checked it out ans wasn't able to produce more
than 11 digits
if (type_name.equals( "float8" ))
return 20; // dito, 20
if (type_name.equals( "char" ))
return 1;
if (type_name.equals( "bool" ))
return 1;
int secondSize;
switch (typmod)
{
case 0:
secondSize = 0;
break;
case - 1:
// six digits plus the decimal point
secondSize = 7;
break;
default:
// with an odd scale an even number of digits
// are always show so timestamp(1) will print
// two fractional digits.
secondSize = typmod + (typmod % 2) + 1;
break;
}
if (type_name.equals( "date" ))
return 13; // "01/01/4713 BC" - "31/12/32767"
// If we knew the timezone we could avoid having to possibly
// account for fractional hour offsets (which adds three chars).
//
// Also the range of timestamp types is not exactly clear.
// 4 digits is the common case for a year, but there are
// version/compilation dependencies on the exact date ranges,
// (notably --enable-integer-datetimes), but for now we'll
// just ignore them and assume that a year is four digits.
//
if (type_name.equals( "time" ))
return 8 + secondSize; // 00:00:00 + seconds
if (type_name.equals( "timetz" ))
return 8 + secondSize + 6; // 00:00.00 + .000000 + -00:00
if (type_name.equals( "timestamp" ))
return 19 + secondSize; // 0000-00-00 00:00:00 + .000000;
if (type_name.equals( "timestamptz" ))
return 19 + secondSize + 6; // 0000-00-00 00:00:00 + .000000 +
-00:00;
//begin vpj-cd e-evolution
if (type_name.equals( "text") || type_name.equals("bytea"))
{
if (typmod == -1)
return 0;
else
return typmod;
}
if (type_name.equals( "unknown"))
return 0;
//end vpj-cd e-evolution
// variable length fields
typmod -= 4;
if (type_name.equals( "bpchar" )
|| type_name.equals( "varchar" ))
// being vpj-cd e-evolution 07/30/2005
{
if (typmod < 0)
return 0;
else
return typmod; // VARHDRSZ=sizeof(int32)=4
}
// end vpj-cd e-evolution 07/30/2005
if (type_name.equals( "numeric" ))
{
//return ( (typmod >> 16) & 0xffff )
// + 1 + ( typmod & 0xffff ); // DECIMAL(p,s) = (p digits).
(s digits)
if( ((typmod >> 16) & 0xffff ) + 1 + ( typmod & 0xffff ) == -1)
return 0;
else
return ( (typmod >> 16) & 0xffff )
+ 1 + ( typmod & 0xffff );
}
// if we don't know better
return f.getLength();
}
* JDBC driver build number
8.1dev-401 JDBC Source
* Server version
PostgreSQL 8.0.3 in Linux AMD64
Cheers
Victor Pérez
CEO
e-Evolution,SC
www.e-evolution.com
Víctor Pérez Juárez wrote: > Compiere use the RowSet implementation, I made some changes to the source > AbstractJdbc2ResultSetMetaData method: Can you send a diff? I can't see what you've changed from just this. -O
Of cosure!
my changes are commnet with e-evolution
//begin vpj-cd e-evolution
if (type_name.equals( "text") || type_name.equals("bytea"))
{
if (typmod == -1)
return 0;
else
return typmod;
}
if (type_name.equals( "unknown"))
return 0;
//end vpj-cd e-evolution
// being vpj-cd e-evolution 07/30/2005
{
if (typmod < 0)
return 0;
else
return typmod; // VARHDRSZ=sizeof(int32)=4
}
// end vpj-cd e-evolution 07/30/2005
---------------------------------------------------------------------------------------------------------------------------------------
the code complete:
/*
* What is the column's normal maximum width in characters?
*
* @param column the first column is 1, the second is 2, etc.
* @return the maximum width
* @exception SQLException if a database access error occurs
*/
public int getColumnDisplaySize(int column) throws SQLException
{
Field f = getField(column);
String type_name = getPGType(column);
int typmod = f.getMod();
// I looked at other JDBC implementations and couldn't find a
consistent
// interpretation of the "display size" for numeric values, so this is
our's
// FIXME: currently, only types with a SQL92 or SQL3 pendant are
implemented - jens@jens.de
// fixed length data types
if (type_name.equals( "int2" ))
return 6; // -32768 to +32768 (5 digits and a sign)
if (type_name.equals( "int4" )
|| type_name.equals( "oid" ))
return 11; // -2147483648 to +2147483647
if (type_name.equals( "int8" ))
return 20; // -9223372036854775808 to +9223372036854775807
if (type_name.equals( "money" ))
return 12; // MONEY = DECIMAL(9,2)
if (type_name.equals( "float4" ))
return 11; // i checked it out ans wasn't able to produce more
than 11 digits
if (type_name.equals( "float8" ))
return 20; // dito, 20
if (type_name.equals( "char" ))
return 1;
if (type_name.equals( "bool" ))
return 1;
int secondSize;
switch (typmod)
{
case 0:
secondSize = 0;
break;
case - 1:
// six digits plus the decimal point
secondSize = 7;
break;
default:
// with an odd scale an even number of digits
// are always show so timestamp(1) will print
// two fractional digits.
secondSize = typmod + (typmod % 2) + 1;
break;
}
if (type_name.equals( "date" ))
return 13; // "01/01/4713 BC" - "31/12/32767"
// If we knew the timezone we could avoid having to possibly
// account for fractional hour offsets (which adds three chars).
//
// Also the range of timestamp types is not exactly clear.
// 4 digits is the common case for a year, but there are
// version/compilation dependencies on the exact date ranges,
// (notably --enable-integer-datetimes), but for now we'll
// just ignore them and assume that a year is four digits.
//
if (type_name.equals( "time" ))
return 8 + secondSize; // 00:00:00 + seconds
if (type_name.equals( "timetz" ))
return 8 + secondSize + 6; // 00:00.00 + .000000 + -00:00
if (type_name.equals( "timestamp" ))
return 19 + secondSize; // 0000-00-00 00:00:00 + .000000;
if (type_name.equals( "timestamptz" ))
return 19 + secondSize + 6; // 0000-00-00 00:00:00 + .000000 +
-00:00;
//begin vpj-cd e-evolution
if (type_name.equals( "text") || type_name.equals("bytea"))
{
if (typmod == -1)
return 0;
else
return typmod;
}
if (type_name.equals( "unknown"))
return 0;
//end vpj-cd e-evolution
// variable length fields
typmod -= 4;
if (type_name.equals( "bpchar" )
|| type_name.equals( "varchar" ))
// being vpj-cd e-evolution 07/30/2005
{
if (typmod < 0)
return 0;
else
return typmod; // VARHDRSZ=sizeof(int32)=4
}
// end vpj-cd e-evolution 07/30/2005
if (type_name.equals( "numeric" ))
{
//return ( (typmod >> 16) & 0xffff )
// + 1 + ( typmod & 0xffff ); // DECIMAL(p,s) = (p digits).
(s digits)
if( ((typmod >> 16) & 0xffff ) + 1 + ( typmod & 0xffff ) == -1)
return 0;
else
return ( (typmod >> 16) & 0xffff )
+ 1 + ( typmod & 0xffff );
}
// if we don't know better
return f.getLength();
}
* JDBC driver build number
8.1dev-401 JDBC Source
* Server version
PostgreSQL 8.0.3 in Linux AMD64
Cheers
Victor Pérez
CEO
e-Evolution,SC
www.e-evolution.com
El Martes, 2 de Agosto de 2005 18:55, Oliver Jowett escribió:
> Víctor Pérez Juárez wrote:
> > Compiere use the RowSet implementation, I made some changes to the source
> > AbstractJdbc2ResultSetMetaData method:
>
> Can you send a diff? I can't see what you've changed from just this.
>
> -O
>
> ---------------------------(end of broadcast)---------------------------
> TIP 3: Have you checked our extensive FAQ?
>
> http://www.postgresql.org/docs/faq
Victor,
What we need is a cvs diff
cvs diff -c ....
Then we can apply it using
patch
after we read it and approve it
Dave
On 3-Aug-05, at 1:20 PM, Víctor Pérez Juárez wrote:
> Of cosure!
>
> my changes are commnet with e-evolution
>
> //begin vpj-cd e-evolution
> if (type_name.equals( "text") || type_name.equals("bytea"))
> {
> if (typmod == -1)
> return 0;
> else
> return typmod;
> }
> if (type_name.equals( "unknown"))
> return 0;
> //end vpj-cd e-evolution
>
> // being vpj-cd e-evolution 07/30/2005
> {
> if (typmod < 0)
> return 0;
> else
> return typmod; // VARHDRSZ=sizeof(int32)=4
> }
> // end vpj-cd e-evolution 07/30/2005
> ----------------------------------------------------------------------
> -----------------------------------------------------------------
> the code complete:
>
> /*
> * What is the column's normal maximum width in characters?
> *
> * @param column the first column is 1, the second is 2, etc.
> * @return the maximum width
> * @exception SQLException if a database access error occurs
> */
>
> public int getColumnDisplaySize(int column) throws SQLException
> {
> Field f = getField(column);
> String type_name = getPGType(column);
> int typmod = f.getMod();
>
> // I looked at other JDBC implementations and couldn't find a
> consistent
> // interpretation of the "display size" for numeric values,
> so this is
> our's
> // FIXME: currently, only types with a SQL92 or SQL3
> pendant are
> implemented - jens@jens.de
>
> // fixed length data types
> if (type_name.equals( "int2" ))
> return 6; // -32768 to +32768 (5 digits and a sign)
> if (type_name.equals( "int4" )
> || type_name.equals( "oid" ))
> return 11; // -2147483648 to +2147483647
> if (type_name.equals( "int8" ))
> return 20; // -9223372036854775808 to +9223372036854775807
> if (type_name.equals( "money" ))
> return 12; // MONEY = DECIMAL(9,2)
> if (type_name.equals( "float4" ))
> return 11; // i checked it out ans wasn't able to
> produce more
> than 11 digits
> if (type_name.equals( "float8" ))
> return 20; // dito, 20
> if (type_name.equals( "char" ))
> return 1;
> if (type_name.equals( "bool" ))
> return 1;
>
> int secondSize;
> switch (typmod)
> {
> case 0:
> secondSize = 0;
> break;
> case - 1:
> // six digits plus the decimal point
> secondSize = 7;
> break;
> default:
> // with an odd scale an even number of digits
> // are always show so timestamp(1) will print
> // two fractional digits.
> secondSize = typmod + (typmod % 2) + 1;
> break;
> }
>
> if (type_name.equals( "date" ))
> return 13; // "01/01/4713 BC" - "31/12/32767"
>
> // If we knew the timezone we could avoid having to possibly
> // account for fractional hour offsets (which adds three
> chars).
> //
> // Also the range of timestamp types is not exactly clear.
> // 4 digits is the common case for a year, but there are
> // version/compilation dependencies on the exact date ranges,
> // (notably --enable-integer-datetimes), but for now we'll
> // just ignore them and assume that a year is four digits.
> //
> if (type_name.equals( "time" ))
> return 8 + secondSize; // 00:00:00 + seconds
> if (type_name.equals( "timetz" ))
> return 8 + secondSize + 6; // 00:00.00 + .000000 + -00:00
> if (type_name.equals( "timestamp" ))
> return 19 + secondSize; // 0000-00-00 00:00:00 + .000000;
> if (type_name.equals( "timestamptz" ))
> return 19 + secondSize + 6; // 0000-00-00 00:00:00 + .
> 000000 +
> -00:00;
>
> //begin vpj-cd e-evolution
> if (type_name.equals( "text") || type_name.equals("bytea"))
> {
> if (typmod == -1)
> return 0;
> else
> return typmod;
> }
> if (type_name.equals( "unknown"))
> return 0;
> //end vpj-cd e-evolution
>
>
> // variable length fields
> typmod -= 4;
> if (type_name.equals( "bpchar" )
> || type_name.equals( "varchar" ))
> // being vpj-cd e-evolution 07/30/2005
> {
> if (typmod < 0)
> return 0;
> else
> return typmod; // VARHDRSZ=sizeof(int32)=4
> }
> // end vpj-cd e-evolution 07/30/2005
>
> if (type_name.equals( "numeric" ))
> {
> //return ( (typmod >> 16) & 0xffff )
> // + 1 + ( typmod & 0xffff ); // DECIMAL(p,s) =
> (p digits).
> (s digits)
> if( ((typmod >> 16) & 0xffff ) + 1 + ( typmod &
> 0xffff ) == -1)
> return 0;
> else
> return ( (typmod >> 16) & 0xffff )
> + 1 + ( typmod & 0xffff );
> }
> // if we don't know better
> return f.getLength();
> }
>
>
> * JDBC driver build number
> 8.1dev-401 JDBC Source
> * Server version
> PostgreSQL 8.0.3 in Linux AMD64
>
>
> Cheers
> Victor Pérez
> CEO
> e-Evolution,SC
> www.e-evolution.com
>
>
> El Martes, 2 de Agosto de 2005 18:55, Oliver Jowett escribió:
>
>> Víctor Pérez Juárez wrote:
>>
>>> Compiere use the RowSet implementation, I made some changes to
>>> the source
>>> AbstractJdbc2ResultSetMetaData method:
>>>
>>
>> Can you send a diff? I can't see what you've changed from just this.
>>
>> -O
>>
>> ---------------------------(end of
>> broadcast)---------------------------
>> TIP 3: Have you checked our extensive FAQ?
>>
>> http://www.postgresql.org/docs/faq
>>
>
> ---------------------------(end of
> broadcast)---------------------------
> TIP 3: Have you checked our extensive FAQ?
>
> http://www.postgresql.org/docs/faq
>
>
Víctor Pérez Juárez wrote:
> Of cosure!
>
> my changes are commnet with e-evolution
[...]
In the future, please supply a proper diff ('cvs diff -c' will do the
trick if you are working from CVS). It's very hard to see the changes
you've made otherwise.
It appears to boil down to "return 0 instead of -1 for column display
size when we don't know the actual length"?
Why is 0 better than -1 in this case? I don't see anything in the JDBC
spec that covers this..
-O
Hi Oliver!
The problem is that RowSet launchs an exception when JDBC return -1 this cause
my Aplicaction does not work the reasons are down.
The source code in package javax.sql.rowset.RowSetMetaDataImpl.java
/**
* Sets the normal maximum number of chars in the designated column
* to the given number.
*
* @param columnIndex the first column is 1, the second is 2, and so on;
* must be between <code>1</code> and the number of columns,
inclusive
* @param size the maximum size of the column in chars; must be
* <code>0</code> or more
* @throws SQLException if a database access error occurs,
* the given column number is out of bounds, or <i>size</i> is
* less than <code>0</code>
*/
public void setColumnDisplaySize(int columnIndex, int size) throws
SQLException {
if (size < 0) {
throw new SQLException("Invalid column display size. Cannot be
less " +
"than zero");
}
checkColRange(columnIndex);
colInfo[columnIndex].columnDisplaySize = size;
}
the same case is for setPrecision,setScale
Cheers
--
Víctor Pérez Juárez
CEO
e-Evolution,S.C.
www.e-evolution.com
victor.perez@e-evolution.com
teléfono: (52)7711070937
skype: vpj-cd
El Miércoles, 3 de Agosto de 2005 19:17, Oliver Jowett escribió:
> Víctor Pérez Juárez wrote:
> > Of cosure!
> >
> > my changes are commnet with e-evolution
>
> [...]
>
> In the future, please supply a proper diff ('cvs diff -c' will do the
> trick if you are working from CVS). It's very hard to see the changes
> you've made otherwise.
>
> It appears to boil down to "return 0 instead of -1 for column display
> size when we don't know the actual length"?
>
> Why is 0 better than -1 in this case? I don't see anything in the JDBC
> spec that covers this..
>
> -O
>
> ---------------------------(end of broadcast)---------------------------
> TIP 4: Have you searched our list archives?
>
> http://archives.postgresql.org
Víctor Pérez Juárez wrote: > The problem is that RowSet launchs an exception when JDBC return -1 this cause > my Aplicaction does not work the reasons are down. This has been discussed at some length in the past -- see the archives. It's not clear where the fault lies -- according to the JDBC spec, -1 seems like a perfectly valid value to return. As I understand it Sun were going to check their implementation and get back to us, but that hasn't happened yet. Kris was reluctant to change the driver code just for the sake of Sun's implementation. Have you contacted Sun about this to see if they are planning to change their code? -O