Baldur Kristinsson wrote:
> > Interesting. However, the null byte is by definition a string 
> > terminator, so it makes no sense to me to include any data in a string 
> > beyond the null byte. The behavior of quote() to tacitly strip out a 
> > null byte is actually a bug (left over from an earlier implementation) 
> > that should be fixed.
> 
> It may normally be a string terminator in C programs, but in Perl
> strings it is not. People using DBD::Pg are not writing C, they're
> writing Perl - in fact, probably in most cases they know next to no C.

Got it.

> Besides, there is a glaring inconsistency with the way $dbh->quote
> works. In my opinion nothing which "works" using $dbh->quote and direct
> embedding in a SQL statement should fail to work using placeholders and
> bind values. If people learn that embedding works and placeholders
> don't, they adopt programming habits that are even worse than those they
> already have ;-)

Yep, ideally, it should be seamless.

> In DBD::Informix the behaviour differs somewhat: Strings containing
> null bytes are tacitly truncated in the case of char, varchar and
> lvarchar.  However, if you're using custom datatypes such as

Yuck.  Silent truncation seems evil.

> > I think that if you have a string with a null byte in it and you want 
> > to put it into a field other than BYTEA, your code should be 
> > responsible for removing it before it passes it to DBI.
> > 
> > dbi-dev'ers, please correct me if I'm wrong. :-)
> 
> Hmmm... Certainly it's not difficult to add a "s/\0//g" whenever you're
> handling data from a source which could pass the damned thing on to you.
> But isn't it one of Perl's founding principles to Do What I Mean -
> without always being told exactly how it should do it...?


Yep, if they want that NULL, we better either handle it, or throw an
error.

> (As an aside, I don't see why text columns in PostgreSQL should not be
> allowed to contain null bytes. After all, it cannot be a question of
> storage format, as there always are four bytes at the start of a
> PostgreSQL TEXT field telling us how long the string is. In some of my
> attempts I seemed to successfully escape the string as '\\000' so it
> made it to the Pg parser where it was truncated. If it made it that far,
> why not take note of the escape and just bloody well insert the whole
> thing? But of course that has nothing to do with DBD::Pg...)

Ah, been digging in the source, eh.  Yes, you are right.  On-disk data
storage, and in fact backend passing of the varlena types, like text,
char(), varchar(), do all have the length at the beginning.  The problem
is the handling of the data before it is determined to be varlena.  We
actually have all sorts of data type conversion code to try and
determine a passed data type, and our customizable type system doesn't
help simplify this.

You are right our varlena can hold nulls, and in fact our bytea varlena
type actually does this.  The problem is how to pass that null around in
the backend _until_ we determine it is a bytea, and the fact we pass
queries to the backend as simple C strings doesn't help this.  Right
now, we require a NULL to be entered in a bytea field using '\0', which
when quoted becomes '\\0'.  Double-yuck, but we can't figure a better
way.  Add to this the problem that it is very hard to _know_ when you
are binding parameter whether it is a bytea or not, and things get
complicated fast.

I think Dave's solution is to specially flag the bytea values in the
binding, and escape any nulls properly.  I think the current 1.20 driver
does this.

I can't think of an ultimate solution.  If we added a length to the
passed query string, so you could embed nulls, we would still have the
problem of handling the null once we split the query up into data
elements.  The only solution there would be to add a length to all
passed data values, so we could handle nulls in them, but I doubt it is
worth the effort and added code complexity.

-- 
  Bruce Momjian                        |  http://candle.pha.pa.us
  [EMAIL PROTECTED]               |  (610) 359-1001
  +  If your life is a hard drive,     |  13 Roberts Road
  +  Christ can be your backup.        |  Newtown Square, Pennsylvania 19073

Reply via email to