From 1d5855a372fd35cabcc848f8a8c93b6d613359d6 Mon Sep 17 00:00:00 2001 From: Nikos Gorogiannis Date: Thu, 12 Oct 2023 05:49:38 -0700 Subject: [PATCH] [sqlite] clear bindings after execution Summary: The OCaml bindings to SQLite ensure that when a value is bound to a query parameter it is copied to a value that is memory-managed by SQLite. This means that any value bound occupies memory until the bindings are cleared, and this memory lies outside of the OCaml heap. When writing out summaries, this memory can potentially amount to a lot. This diff clears bindings and resets the prepared statement right after query execution, meaning that memory for parameter values is released immediately. Reviewed By: dulmarod Differential Revision: D50126133 Privacy Context Container: L1208441 fbshipit-source-id: ea7e9dfb2272ca78a4db935ef9a277571663d112 --- infer/src/base/Database.ml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/infer/src/base/Database.ml b/infer/src/base/Database.ml index d060ac0c04e..750d6a667e2 100644 --- a/infer/src/base/Database.ml +++ b/infer/src/base/Database.ml @@ -226,9 +226,6 @@ let register_statement id = | None -> L.(die InternalError) "database not initialized" | Some (stmt, db) -> - Sqlite3.reset stmt |> SqliteUtils.check_result_code db ~log:"reset prepared statement" ; - Sqlite3.clear_bindings stmt - |> SqliteUtils.check_result_code db ~log:"clear bindings of prepared statement" ; (stmt, db) in fun stmt_fmt -> Printf.ksprintf k stmt_fmt @@ -238,6 +235,9 @@ let with_registered_statement get_stmt ~f = PerfEvent.(log (fun logger -> log_begin_event logger ~name:"sql op" ())) ; let stmt, db = get_stmt () in let result = f db stmt in + Sqlite3.reset stmt |> SqliteUtils.check_result_code db ~log:"reset prepared statement" ; + Sqlite3.clear_bindings stmt + |> SqliteUtils.check_result_code db ~log:"clear bindings of prepared statement" ; PerfEvent.(log (fun logger -> log_end_event logger ())) ; result