Skip to content

Commit

Permalink
Improve performance of insertMany with prepared statement
Browse files Browse the repository at this point in the history
  • Loading branch information
HeinrichApfelmus committed Jul 25, 2024
1 parent dbc8a44 commit 5206b45
Showing 1 changed file with 15 additions and 1 deletion.
16 changes: 15 additions & 1 deletion lib/delta-table/src/Database/Table/SQLite/Simple/Exec.hs
Original file line number Diff line number Diff line change
Expand Up @@ -134,8 +134,22 @@ selectWhere expr = queryNamed . Stmt.selectWhere expr
insertOne :: IsTableSql t => Row t -> proxy t -> SqlM ()
insertOne row proxy = executeOne (Stmt.insertOne proxy) row

-- | Insert many rows into a database table.
--
-- As an optimization, we use a single prepared SQL statement.
insertMany :: IsTableSql t => [Row t] -> proxy t -> SqlM ()
insertMany rows proxy = for_ rows (`insertOne` proxy)
insertMany rows proxy =
ReaderT $ \conn -> do
-- The 'query' string contains '?' which will be substituted
-- for the values in the row, but no named params.
let (query, _noBindings) = renderStmt $ Stmt.insertOne proxy
Sqlite.withStatement conn query $ \stmt ->
for_ rows $ \row ->
-- From <https://www.sqlite.org/cintro.html>:
-- Each call to sqlite3_bind() overrides
-- prior bindings on the same parameter.
Sqlite.withBind stmt row (Sqlite.nextRow stmt)
:: IO (Maybe [Bool]) -- dummy type, we expect 'Nothing'

updateWhere
:: IsTableSql t
Expand Down

0 comments on commit 5206b45

Please sign in to comment.