3 ms·
> You can use a CHECK constraint with typeof() to enforce static typing. If your SQL DDL is being generated somehow (as opposed to manually written), you could
by deathanatos 5y ago
> You can use a CHECK constraint with typeof() to enforce static typing. If your SQL DDL is being generated somehow (as opposed to manually written), you could even autogenerate the CHECK constraints.
You can't enforce that text values are actually text:
sqlite> create table foo ( a text, check (typeof(a) == 'text') );
sqlite> insert into foo (a) values ( 'a' || x'ff' );
sqlite> select a, typeof(a) from foo;
a typeof(a)
-- ---------
a� text
(The Unicode replacement character in this comment is the output of sqlite/sane terminals, here.) The value in the column purports to be "text", but it's raw binary data. If you retrieve this in, say, Rust, you'll get,
[b'a', 0xffu8]
(This is with PRAGMA encoding set to "UTF-8". Not that this isn't a blob: for those, typeof() is "blob".)
(I believe this to be a bug with SQLite. It's docs state:
> TEXT. The value is a text string, stored using the database encoding (UTF-8, UTF-16BE or UTF-16LE).
The developers do not see it as a bug.)
Realistically, it's not much of a problem. In Rust, I already have to run-time assert that it is a string and not an integer, so also asserting "it's a string that's actually a string" is just another assertion and doesn't change much. Program goes boom if column unexpectedly has the integer 4 in it, program goes boom if it has b"a\xff" in a text column.
- skissane 5y agoCouldn't your issue be addressed by writing an application-defined function [0] called something like "utf8_is_valid()" and invoking it in the CHECK constraint? (Probably should tag the custom function SQLITE_DETERMINISTIC|SQLITE_INNOCUOUS to make sure you can use it in a CHECK constraint.) [0] https://www.sqlite.org/appfunc.html https://www.sqlite.org/appfunc.html
- CRConrad 5y ago> The value in the column purports to be "text", but it's raw binary data. So what is "text", but raw binary data?