Thread: Bug in 7.4_213 driver: returns VARCHAR instead of LONGVARCHAR for text types

Bug in 7.4_213 driver: returns VARCHAR instead of LONGVARCHAR for text types

From
"j.random.programmer"
Date:
The JDBC version 7.4_213 driver has the following bug

For database SQL type:
text    (that is variable unlimited length)

The JDBC driver returns "java.sql.VARCHAR" as
the column type. (via database meta data).

This is wrong. The JDBC driver SHOULD return
java.sql.LONGVARCHAR (since the text type is
of unlimited length).

Please fix this because it is messing up my
relational mapping code.

Best regards,

--j



__________________________________
Do you Yahoo!?
Yahoo! Mail - 50x more storage than other providers!
http://promotions.yahoo.com/new_mail

Re: Bug in 7.4_213 driver: returns VARCHAR instead of

From
Kris Jurka
Date:

On Tue, 27 Jul 2004, j.random.programmer wrote:

> The JDBC version 7.4_213 driver has the following bug
>
> For database SQL type:
> text    (that is variable unlimited length)
>
> The JDBC driver returns "java.sql.VARCHAR" as
> the column type. (via database meta data).
>
> This is wrong. The JDBC driver SHOULD return
> java.sql.LONGVARCHAR (since the text type is
> of unlimited length).
>

I'm not sure this is clearly wrong, but you do make a convincing argument.
My concern is backwards compatibility with existing applications that
expect text as VARCHAR.  When I tried the change in the driver, there were
4 failures and 2 errors in the drivers regression test.  Some code didn't
handle LONGVARCHAR at all and others expected text to be VARCHAR.

For example consider CallableStatements:

CallableStatement call = con.prepareCall ("{ ? = upper(?) }");
call.setString(2, "foo");
call.registerOutParameter(1, Types.VARCHAR);
call.execute();
String result = call.getString(1); // Should be "FOO"

With the proposed change this will fail because the output type of upper
is text and it's no longer mapped to Types.VARCHAR, but LONGVARCHAR, so
you'll get this exception:

 A CallableStatement Function was executed and the return was of type
(java.sql.Types=-1) however type=java.sql.Types=12 was registered.


Kris Jurka


Attachment

Re: Bug in 7.4_213 driver: returns VARCHAR instead of

From
Kris Jurka
Date:

On Thu, 29 Jul 2004, Kris Jurka wrote:

> On Tue, 27 Jul 2004, j.random.programmer wrote:
>
> > The JDBC version 7.4_213 driver has the following bug
> >
> > For database SQL type:
> > text    (that is variable unlimited length)
> >
> > The JDBC driver returns "java.sql.VARCHAR" as
> > the column type. (via database meta data).
> >
> > This is wrong. The JDBC driver SHOULD return
> > java.sql.LONGVARCHAR (since the text type is
> > of unlimited length).
> >
>
> I'm not sure this is clearly wrong, but you do make a convincing argument.

I'm not so sure anymore.  While text can be used for storing large values
it often isn't.  Further returning LONGVARCHAR could be a sign for the
caller to use something like ResultSet.getCharacterStream instead of a
simple getString.

Kris Jurka


Re: Bug in 7.4_213 driver: returns VARCHAR instead of

From
Barry Lind
Date:
Kris Jurka wrote:
 > I'm not so sure anymore.  While text can be used for storing large values
 > it often isn't.  Further returning LONGVARCHAR could be a sign for the
 > caller to use something like ResultSet.getCharacterStream instead of a
 > simple getString.

I would agree.  In our applications we exclusively use text everywhere
we use varchar on other databases.  I am quite sure that a change like
this would break peoples existing apps.  I also agree that LONGVARCHAR
would imply that you should use the getXXXStream methods which I would
say is rarely the correct thing to do.  In my opinion text is just a
better version of varchar (without many of the limitations imposed on
varchar in other database vendor implementations).

--Barry


Re: Bug in 7.4_213 driver: returns VARCHAR instead of

From
"j.random.programmer"
Date:
Kris:

Firstly, let me say that I, as a end-user, really
appreciate
the time you and others take to reply to posts and
work
on the JDBC driver.

postgresql/jdbc has pretty much become my reference
system
these days and it's no small part due to the sense of
community
one feels in these parts.

> > The JDBC driver returns "java.sql.VARCHAR" as for
"text" but
> > SHOULD return java.sql.LONGVARCHAR (since the text
type is of
> > unlimited length).
>
> My concern is backwards compatibility with existing
> applications that expect text as VARCHAR.  When I
tried the
> change in the driver, there were 4 failures and 2
errors in
> the drivers regression test.  Some code didn't
handle
> LONGVARCHAR at all and others expected text to be
VARCHAR.

But it's always better to do the right thing, isn't it
?

Both the intuitive expectation and the JDBC spec imply
that LONGVARCHAR is the right thing in this case.
Sure, I've
worked around this particular bug in one case (I check
to
see if the max column size = -1 and if so, internally
flip
the type to LONGVARCHAR and return a
reader/inputstream if
the user wants and also ignore setting up size
validation).

> For example consider CallableStatements:
> ...
> A CallableStatement Function was executed and the
return was
> of type (java.sql.Types=-1) however
type=java.sql.Types=12 was
> registered.

I don't understand the full implications of your
CallableStatement (CallableStatement is the one part
of
JDBC I haven't had reason to use).

Is this a unfixable problem though ? Also, isn't it
good that
you are getting some problems in the regression tests,
that means
there are some hidden bugs that just got exposed and
might as
well now get fixed.

> I'm not so sure anymore.  While text can be used for
storing
> large values it often isn't.  Further returning
LONGVARCHAR
> could be a sign for the caller to use something like
> ResultSet.getCharacterStream instead of a simple
getString.

The whole point of using streams is that large strings
may not fit in memory [for multiple users, all those
large strings definitely _won't_ fit in memory]. Of
course
this may be moot in the _current_ driver
implementation
(which for all I know might horking the whole string
from
the database into memory and then returing a
StringReader
or whatever).

But the right thing for large amounts of data again is
streams,
not storing that data in memory.

> In our applications we exclusively use text
everywhere we use
> varchar on other databases.  I am quite sure that a
change
> like this would break peoples existing apps.  I also
agree
> that LONGVARCHAR would imply that you should use the
> getXXXStream methods which I would say is rarely the
correct
> thing to do.

Why are the getXXXStream methods "rarely the correct
thing" ?
Ignoring current implementation artifacts (if any),
they
are almost always the _right_ thing for large amounts
of
data.

Or am I missing something here ?

Best regards,

--j






__________________________________
Do you Yahoo!?
New and Improved Yahoo! Mail - Send 10MB messages!
http://promotions.yahoo.com/new_mail

Re: Bug in 7.4_213 driver: returns VARCHAR instead of

From
Oliver Jowett
Date:
j.random.programmer wrote:

> Why are the getXXXStream methods "rarely the correct
> thing" ?
> Ignoring current implementation artifacts (if any),
> they
> are almost always the _right_ thing for large amounts
> of
> data.

The point is that it *is* all about current implementation artifacts.
There's no way to stream a text value from the server on demand using
the current protocol. So if you use getXXXStream() with the current
driver, you always end up wrapping data that's completely on-heap anyway
with an unnecessary stream interface. Note that this is more of a
client/server protocol issue than a driver issue (and it's not obvious
how to solve it at the protocol level anyway).

As Barry said, returning LONGVARCHAR implies the preferred access method
is via getXXXStream() (see the jdbc type mapping tables), but those
aren't the best methods for accessing text columns in our current
implementation. And the metadata should reflect the characteristics of
the driver implementation actually used, surely..

-O