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