Super minor, but since sqlite changes are soon to merge, I thought I would ask a little about naming.
Sqlite
vs SQLite
when it shows up in type and module names? From what I can tell, SQLite
is more "official", but I don't think it reads as well.NOMEM
, INTERNAL
, or CANTOPEN
. I feel like I should probably change them to NoMem
, Internal
, and CantOpen
. Maybe even give them a bit color than sqlite does.Nullable a : [NotNull a, Null]
. Is that name reasonable and our perferred way to deal with optional nulls?Result val [NoValue]
even if something like [HasValue val, NoValue]
is more correct because we've optimized so much for Result management. I'd vote for Result val [Null]
for that reasonI agree with Sam here.
Though I'm not sure it's worth changing Nullable. The current impl works well and the naming seems ok to me.
+1 for Nullable, i think Result is a bad semantic there because null
isn't "error-ish" in SQL
Sqlite
. I dislike acronyms being capitalized in title case. And, to us, ”sqlite" is one atomic word, you'd never have a SQSomethingElse
, so there shouldn't be extra word boundaries.NoMem
fits better here.I'd also like to say that... I think it's fine to leave it too. It's not easy to go back through Sqlite.roc
and rename all the tags, and the delta here imo is pretty small.
Here's the docs for the error codes https://www.sqlite.org/rescode.html
SQLITE_ABORT (4)
SQLITE_AUTH (23)
SQLITE_BUSY (5)
SQLITE_CANTOPEN (14)
SQLITE_CONSTRAINT (19)
SQLITE_CORRUPT (11)
SQLITE_DONE (101)
SQLITE_EMPTY (16)
<snipped>
And here's one place we use them in the platform
when code is
ERROR -> "ERROR: Sql error or missing database"
INTERNAL -> "INTERNAL: Internal logic error in Sqlite"
PERM -> "PERM: Access permission denied"
ABORT -> "ABORT: Callback routine requested an abort"
BUSY -> "BUSY: The database file is locked"
LOCKED -> "LOCKED: A table in the database is locked"
NOMEM -> "NOMEM: A malloc() failed"
READONLY -> "READONLY: Attempt to write a readonly database"
<snipped>
I've approved the PR, as this is the only thing that remains... and I figure @Brendan Hansknecht may be happy to merge as is.
Sounds like we should fix the casing here
I'll leave nullable for now
i think Result is a bad semantic there because
null
isn't "error-ish" in SQL
To add a bit of extra color. If you use nullable, you are essentially explicitly saying that you expect null and thus don't want it to be an error (probably eventually will also want to add a version that returns empty string on null). By default, if you request a Str from the roc sqlite api, it will return a result of a Str with an error of: UnexpectedTypeErr : [UnexpectedType [Integer, Real, String, Bytes, Null]]
The big caveat being that in a larger query, only the first error will be returned. Given a column of strings with a few nulls: With Nullable, you will get the list of Nullable Str
; Without nullabe, you would get a single type error UnexpectedType Null
for the entire query.
Also, one thing that still surprises me about sqlite by default (roc api specifically attempts to avoids this), it will autocast data if possible:
The first six interfaces (_blob, _double, _int, _int64, _text, and _text16) each return the value of a result column in a specific data format. If the result column is not initially in the requested format (for example, if the query returns an integer but the sqlite3_column_text() interface is used to extract the value) then an automatic type conversion is performed.
Last updated: Jul 06 2025 at 12:14 UTC