Обсуждение: some improve JDBC

Поиск
Список
Период
Сортировка

some improve JDBC

От
Víctor Pérez Juárez
Дата:
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

Re: some improve JDBC

От
Oliver Jowett
Дата:
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

Re: some improve JDBC

От
Víctor Pérez Juárez
Дата:
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

Re: some improve JDBC

От
Dave Cramer
Дата:
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
>
>


Re: some improve JDBC

От
Oliver Jowett
Дата:
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

Re: some improve JDBC

От
Víctor Pérez Juárez
Дата:
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




Re: some improve JDBC

От
Oliver Jowett
Дата:
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