The HDBC documentation states:
fetchAllRows :: Statement -> IO [[SqlValue]]Source
Lazily fetch all rows from an executed Statement.
You can think of this as hGetContents applied to a database result
set.The result of this is a lazy list, and each new row will be read,
lazily, from the database as the list is processed.When you have exhausted the list, the Statement will be finished.
Please note that the careless use of this function can lead to some
unpleasant behavior. In particular, if you have not consumed the
entire list, then attempt to finish or re-execute the statement, and
then attempt to consume more elements from the list, the result will
almost certainly not be what you want.But then, similar caveats apply with hGetContents.
Bottom line: this is a very convenient abstraction; use it wisely.
Use fetchAllRows’ if you need something that is strict, without all
these caveats.
Then, I wonder, to which level does the laziness extend?
Say, I can have
conn <- connectSqlite3 databaseFilePath
rows <- quickQuery conn ("SELECT * FROM foo") []
mapM_ bar $ take n rows
disconnect conn
Will it actually only fetch n
rows? Like, from the database point of view, will it be equivalent of SELECT * FROM foo LIMIT (n)
? Because fetching all rows at the level of database driver and then take
ing n
of them seems to be silly and kind of defeats the purpose.
If it’s lazy up to the database itself, how’s it implemented? Is it using cursors?
I know there’re several drivers for HDBC alone. I’m asking only about principle of implementation.
I suspect (though I can’t verify) that they’re relying on the standard ODBC capability for the data-streaming based on the fact that the documentation says it supports
[…] and have it work with any number of backend SQL databases (MySQL, Oracle, PostgreSQL, ODBC-compliant databases, etc.) […]
(emphasis mine)
If you’ll have a look at MSDNs generic non-DB-specific ODBC API you’ll see it has streaming data reader facilities.
Given this, I assume the ODBC standards dictate lazy data streaming facilities, and the HDBC likely just relies on that (possibly with DB-specific heuristics for some particular DB’s that may be beneficial beyond what ODBC supplies).