Hacker News new | ask | show | jobs
by Groxx 16 days ago
>* The length() SQL function only counts characters up to and excluding the first NUL.*

>The quote() SQL function only shows characters up to and excluding the first NUL.

>The .dump command in the CLI omits the first NUL character and all subsequent text in the SQL output that it generates. In fact, the CLI omits everything past the first NUL character in all contexts.

That's just all kinds of "oh no", wow.

I mean, I can't come up with a better strategy, but... oof. C-style strings being a thing at all really hurts.

3 comments

The better strategy is that it should just work, isn't it?
> C-style strings being a thing at all really hurts.

Well, C strings exist and are probably here to stay.

I believe Pascal strings, where the length is stored in the 0th character, were much worse (also, obligatory reference to Joel Spolsky's “Back to Basics” and “fucked strings” [1]).

Looks like we only got enough memory to spare to allow arbitrary length strings with arbitrary characters – that is, being able to use 2 or 4 bytes for the length of every string – in 1990s or so, when C++ strings and similar types became popular.

[1]: https://www.joelonsoftware.com/2001/12/11/back-to-basics/

> Pascal strings, where the length is stored in the 0th character, were much worse

Until unicode became widely supported, many databases used to reserve 1 byte for the length of a VARCHAR, typically at the 0th position of the column. The content was understandably limited to 255 characters.

Because of that extra byte per row, it is considered a waste of memory to use VARCHAR for data that is expected to be fixed-length. Well, it's an even larger waste in some cases. A certain popular ORM continues to insist on mapping UUID to VARCHAR(36), wasting a whopping 21 bytes per row! Certainly something to keep in mind at a time when both RAM and disks are expensive.

SQLite of course doesn't care, and stores all string as TEXT.

It's not really a big problem. You should be storing arbitrary binary strings as blobs (and length() works properly with them), but the underlying encoding is nearly identical: https://www.sqlite.org/fileformat.html#record_format
Then DBMS should not allow to save a string that would make some function return wrong results. Either truncate with a warning on INSERT (MySQL approach) or better throw an error.
Note that this breaks a lot of core functionality unless you CAST(s as TEXT) before you use it, eg iirc LIKE won’t work. Then you’re back to the same problem.