It is incredible.
GENERATED ALWAYS AS IDENTITY and GENERATED BY DEFAULT AS is IBM DB2 syntax that became part of the SQL standard. It is meant to be the unifying syntax for all the various flavors of AUTOINCREMENT that exist (GENERATED ALWAYS AS IDENTITY is now the standard way). It also makes a distinction between ALWAYS generated and BY DEFAULT which can be bypassed with a user supplied value.
SQLITE's GENERATED ALWAYS doesn't apply to keys/indexes so it doesn't work in the main use case in the SQL standard; primary key generation. Hopefully the AS IDENTITY syntax will eventually be added to SQLite to fix the goofy INT PRIMARY KEY vs. INTEGER PRIMARY KEY (long-form INTEGER is a synonym for IDENTITY/AUTOINCREMENT) syntax.
The JSON Document use case is useful but nowhere near as useful as supporting a clean and standard GENERATED ALWAYS AS IDENTITY for primary keys, in my opinion. Maybe I'm missing something.
A decade or so ago, I might have installed MySQL or Postgres to do some log processing or something. I never bother any more. SQLite is just the perfect data tool. You can load it up with gigs of data and it flies.
I still discover little tweaks and features I didn't realize it had as well. It's just a really well done project.
I've always been a bit confused by the design decision for SQLite to allow you to store any value in any column despite the column's type, but I've never had that been a problem since my applications don't try to store strings in integer columns.
It's a similar situation for storing date types as strings. Seems like an odd choice, but I've never had a problem because I keep my date types consistent.
It just goes to show that seemingly odd design choices might never end up being a problem.
I'd be fascinated to hear from those who may have had problems with SQLite's "flexible" type system.
However, on the OTHER hand... if we think about SQLite as a general purpose data storage tool, it's actually a really handy feature, letting the in datatypes almost every case be more of an additional type of label.
For example, if I required a high-precision timestamp, I could declare the column type something like 'UTCEpochNanos', providing a reminder to myself and other consumers of the data how it should be interpreted.
In the past I tested importing dumps of the full HTML and CSS documentation docset from MDN and: - Importing files in a directory is relatively fast: I import batches and it can import hundreds of pages in a few seconds - sadly there's no bulk operation yet to insert arbitrary json documents (unless they are stored as files in a folder), so that's quite slow. - full text search and querying indexed (JSON) properties is fast (double-digit milliseconds for searching several hundred of relatively large documents with paged results)
I do need to do some compared benchmarks with similar data stores though.
How did you get sqlite3 to index JSON? I don't see anything in the product that does that. I'm searching through your source code now but I don't see anything specific.
Regarding indexing json... here's how I do it:
proc createIndex*(store: Datastore, indexId, field: string) =
let query = sql("CREATE INDEX json_index_$1 ON documents(json_extract(data, ?) COLLATE NOCASE) WHERE json_valid(data)" % [indexId])
store.begin()
store.db.exec(query, field)
store.commit()
Basically, SQLite supports indexes in arbitrary expressions and so you can use it in conjunction with json_extract. In this case, field is an arbitrary json path.I then added a REST API in LiteStore to create (JSON) indexes... in that way you can make your queries more performant based on the specific json documents that you store in the data store.
[1]: https://simonwillison.net/2019/Jan/7/exploring-search-releva...
Only thing per page I see in the docs is
https://www.sqlite.org/fileformat2.html
"SQLite has the ability to set aside a small number of extra bytes at the end of every page for use by extensions. These extra bytes are used, for example, by the SQLite Encryption Extension to store a nonce and/or cryptographic checksum associated with each page."
Postgres (and other databases that actually care about data integrity) have per page checksums:
https://www.postgresql.org/docs/13/storage-page-layout.html#...
I feel like the obvious answer is to just get the stable, released source from the SQLite web site and build it yourself.
I'm somewhat tempted to use it at work. The idea of having wiki and targeted job/improvement tickets in the same repo as the code is very tempting.
I use gitea to host code which has tickets/wiki/bug-tracking but no forum, no blogging.
I used to use redmine + git which has more than what I wanted.
I wish gitea adds forum and blogging someday.
Now, a dedicated JSONB datatype (and indexes!) like Postgres would be awesome, but sqlite3's "poor man's JSON" seems appropriate for many use cases.
As a result, I like to statically link it into the binary, when possible. Life is too short to write a bunch of feature discovery and graceful degradation code.