Thread: \0 and IllegalArgumentException

\0 and IllegalArgumentException

From
Sebastiaan van Erk
Date:
Hi,

I'm using postgres 7.4 with the latest JDBC driver, and had an insert
statement to insert data as follows

try
{
    ...
    ps.setCharacterStream(1, myStream, myStreamLength);
    ps.executeUpdate();
}
catch (SQLException e)
{
...
}

With this I was hoping to catch invalid inserts (with an SQLException),
however I'm getting:

java.lang.IllegalArgumentException: \0 not allowed

which is an UNCHECKED runtime exception, that in no way indicates
(programatically) that the insert failed.

I think very few people would expect a runtime exception on what
essentially amounts to a failed insert. Futhermore, it is very hard to
discover the SOURCE of the runtime exception (lots of things might throw
an IllegalArgumentException) and to programatically do something
sensible with this.

Thus in my opinion, an SQLException would be better here for at least
three reasons:
1) It's a checked exception (I'm counting on it happening)...
2) I will know where it came from (postgres)...
3) Now I'm totally unsure of what other kind of runtime exceptions the
postgres driver may throw for some reason or other, nor do I know how to
handle a runtime exception properly if one does occur... I want runtime
exceptions basically only on PROGRAMMATIC errors, errors that I as the
developer made and can fix. User data CAN in fact contain \0, and the
fact that postgres cannot handle this is an issue of the backend, which
(in the case of postgres, but certainly not in the case of all
databases) does not consider these kind of strings as valid. As the
developer (oblivious to what kind of backend database is used) I cannot
take any programmatic steps to avoid this problem (other than string
scanning caught IllegalArgumentExceptions for this specific problem).

In conclusion, I REALLY think that this is the wrong exception to be
thrown.

Greetings,
Sebastiaan van Erk



Re: \0 and IllegalArgumentException

From
Oliver Jowett
Date:
Sebastiaan van Erk wrote:

> I'm using postgres 7.4 with the latest JDBC driver, [...]

> java.lang.IllegalArgumentException: \0 not allowed

Please check your driver version. The latest development driver throws
SQLException in this case:

>> throw new PSQLException(GT.tr("Zero bytes may not occur in string parameters."), PSQLState.INVALID_PARAMETER_VALUE);

-O

Re: \0 and IllegalArgumentException

From
Vadim Nasardinov
Date:
On Friday 29 October 2004 05:55, Sebastiaan van Erk wrote:
[...]
> however I'm getting:
>
> java.lang.IllegalArgumentException: \0 not allowed
[...]
> 2) I will know where it came from (postgres)...
[...]
> User data CAN in fact contain \0, and the fact that postgres cannot
> handle this is an issue of the backend


Funny you should mention this.  Just yesterday a coworker of mine was
bitching about the PostgreSQL JDBC driver's refusal to allow \0 in
strings.  As he pointed out, it's not totally clear if the blame rests
entirely with the backend.  Consider these examples:

 | test=> create table dropme (str varchar(100));
 | CREATE TABLE
 | test=> insert into dropme values ('Hello' || chr(0) || 'world');
 | INSERT 160829 1
 | test=> select str, length(str) as length from dropme;
 |   str  | length
 | -------+--------
 |  Hello |      5
 | (1 row)
 |
 | test=> select str, length(str) as length from dropme where str like '%world';
 |   str  | length
 | -------+--------
 |  Hello |      5
 | (1 row)
 |
 | test=> select str, length(str) as length from dropme where str like '%Welt';
 |  str | length
 | -----+--------
 | (0 rows)


This is with a fairly old version of PosgreSQL:

 | test=> select substring(version(), 1, 20) as version;
 |        version
 | ----------------------
 |  PostgreSQL 7.3.4-RH
 | (1 row)

Not sure how the latest version behaves.

I think you do have a point though when you say that \0 should be
allowed (and handled properly).



Vadim


Re: \0 and IllegalArgumentException

From
Tom Lane
Date:
Vadim Nasardinov <vadimn@redhat.com> writes:
> I think you do have a point though when you say that \0 should be
> allowed (and handled properly).

Don't hold your breath.

Moving away from the zero-terminated-string approach would require
protocol changes (IIRC, the v3 protocol still depends on that in places),
a massive rewrite effort to change every datatype's I/O functions, plus
writing our own locale library because we couldn't use strcoll()
anymore.  And that's just the impacts I can think of before having
had any coffee ;-)

While the private locale library might eventually happen anyway, the
other two things are still daunting, mainly because they break a ton of
user code not only the backend.

Basically, the bang for the buck doesn't seem to be there...

            regards, tom lane

Re: \0 and IllegalArgumentException

From
Sebastiaan van Erk
Date:
I just tested pg74.215.jdbc3.jar which I just downloaded from
the jdbc.postgresql.org site, and it still gives me the
IllegalArgumentException. Happy to know it has been fixed in the
latest development version.

Greetings,
Sebastiaan van Erk

Oliver Jowett wrote:

> Sebastiaan van Erk wrote:
>
> >I'm using postgres 7.4 with the latest JDBC driver, [...]
>
> >java.lang.IllegalArgumentException: \0 not allowed
>
> Please check your driver version. The latest development driver throws
> SQLException in this case:
>
> >>throw new PSQLException(GT.tr("Zero bytes may not occur in string
> >>parameters."), PSQLState.INVALID_PARAMETER_VALUE);
>
> -O
>
> ---------------------------(end of broadcast)---------------------------
> TIP 2: you can get off all lists at once with the unregister command
>    (send "unregister YourEmailAddressHere" to majordomo@postgresql.org)

Re: \0 and IllegalArgumentException

From
Jon Orris
Date:
On Fri, 2004-10-29 at 10:24 -0400, Vadim Nasardinov wrote:
>  | test=> select str, length(str) as length from dropme;
>  |   str  | length
>  | -------+--------
>  |  Hello |      5
>  | (1 row)
>  |
>  | test=> select str, length(str) as length from dropme where str like '%world';
>  |   str  | length
>  | -------+--------
>  |  Hello |      5
>  | (1 row)
>  |
>  | test=> select str, length(str) as length from dropme where str like '%Welt';
>  |  str | length
>  | -----+--------
>  | (0 rows)

> Not sure how the latest version behaves.

I get slightly different results from 7.4.5. The string is still
truncated, but the length is correct:

jorris=# select str, length(str) as length from dropme;
  str  | length
-------+--------
 Hello |     11
(1 row)

jorris=# select str, length(str) as length from dropme where str like '%
world';
  str  | length
-------+--------
 Hello |     11
(1 row)

jorris=#  select substring(version(), 1, 20) as version;
       version
----------------------
 PostgreSQL 7.4.5 on
(1 row)