[sqlite] localise statements to where they are used

Summary:
Move Sqlite registered statements inside the functions that use them, since these are only ever used in one place.

Also, reformat some SQL.

Also, make `mark_all_source_files_stale` use an un-prepared statement, as it is used at most once per run, wasting resources if registered.

Reviewed By: skcho

Differential Revision: D23423844

fbshipit-source-id: 07362d19c
master
Nikos Gorogiannis 4 years ago committed by Facebook GitHub Bot
parent 06489dced0
commit 1d908ff327

@ -28,15 +28,7 @@ let proc_kind_of_attr (proc_attributes : ProcAttributes.t) =
if proc_attributes.is_defined then ProcDefined else ProcUndefined
let replace pname pname_blob akind source_file attributes proc_desc callees =
let pname_str = Procname.to_string pname in
let akind_int64 = int64_of_attributes_kind akind in
let proc_desc_blob = Procdesc.SQLite.serialize proc_desc in
let callees_blob = Procname.SQLiteList.serialize callees in
DBWriter.replace_attributes ~pname_str ~pname:pname_blob ~akind:akind_int64 ~source_file
~attributes ~proc_desc:proc_desc_blob ~callees:callees_blob
let should_try_to_update =
let find_more_defined_statement =
ResultsDatabase.register_statement
{|
@ -45,42 +37,50 @@ FROM procedures
WHERE proc_name = :pname
AND attr_kind > :akind
|}
let should_try_to_update pname_blob akind =
in
fun pname_blob akind ->
ResultsDatabase.with_registered_statement find_more_defined_statement ~f:(fun db find_stmt ->
Sqlite3.bind find_stmt 1 (* :pname *) pname_blob
|> SqliteUtils.check_result_code db ~log:"replace bind pname" ;
Sqlite3.bind find_stmt 2 (* :akind *) (Sqlite3.Data.INT (int64_of_attributes_kind akind))
|> SqliteUtils.check_result_code db ~log:"replace bind attribute kind" ;
SqliteUtils.result_single_column_option ~finalize:false ~log:"Attributes.replace" db find_stmt
SqliteUtils.result_single_column_option ~finalize:false ~log:"Attributes.replace" db
find_stmt
|> (* there is no entry with a strictly larger "definedness" for that proc name *)
Option.is_none )
let find =
let select_statement =
ResultsDatabase.register_statement "SELECT proc_attributes FROM procedures WHERE proc_name = :k"
let find pname_blob =
in
fun pname_blob ->
ResultsDatabase.with_registered_statement select_statement ~f:(fun db select_stmt ->
Sqlite3.bind select_stmt 1 pname_blob
|> SqliteUtils.check_result_code db ~log:"find bind proc name" ;
SqliteUtils.result_single_column_option ~finalize:false ~log:"Attributes.find" db select_stmt
SqliteUtils.result_single_column_option ~finalize:false ~log:"Attributes.find" db
select_stmt
|> Option.map ~f:ProcAttributes.SQLite.deserialize )
let load pname = find (Procname.SQLite.serialize pname)
let store ~proc_desc (attr : ProcAttributes.t) =
let pkind = proc_kind_of_attr attr in
let akind = proc_kind_of_attr attr in
let key = Procname.SQLite.serialize attr.proc_name in
if should_try_to_update key pkind then
replace attr.proc_name key pkind
(SourceFile.SQLite.serialize attr.loc.Location.file)
(ProcAttributes.SQLite.serialize attr)
proc_desc
(Option.map proc_desc ~f:Procdesc.get_static_callees |> Option.value ~default:[])
if should_try_to_update key akind then
let source_file_blob = SourceFile.SQLite.serialize attr.loc.Location.file in
let attributes_blob = ProcAttributes.SQLite.serialize attr in
let pname_str = Procname.to_string attr.proc_name in
let akind_int64 = int64_of_attributes_kind akind in
let proc_desc_blob = Procdesc.SQLite.serialize proc_desc in
let callees_blob =
Option.map proc_desc ~f:Procdesc.get_static_callees
|> Option.value ~default:[] |> Procname.SQLiteList.serialize
in
DBWriter.replace_attributes ~pname_str ~pname:key ~akind:akind_int64
~source_file:source_file_blob ~attributes:attributes_blob ~proc_desc:proc_desc_blob
~callees:callees_blob
let find_file_capturing_procedure pname =

@ -835,11 +835,11 @@ module SQLite = SqliteUtils.MarshalledNullableDataNOTForComparison (struct
type nonrec t = t
end)
let load =
let load_statement =
ResultsDatabase.register_statement "SELECT cfg FROM procedures WHERE proc_name = :k"
let load pname =
in
fun pname ->
ResultsDatabase.with_registered_statement load_statement ~f:(fun db stmt ->
Procname.SQLite.serialize pname |> Sqlite3.bind stmt 1
|> SqliteUtils.check_result_code db ~log:"load bind proc name" ;

@ -10,6 +10,7 @@ module L = Logging
module F = Format
module Implementation = struct
let replace_attributes =
let attribute_replace_statement =
(* The innermost SELECT returns either the current attributes_kind and source_file associated with
the given proc name, or default values of (-1,""). These default values have the property that
@ -41,10 +42,10 @@ module Implementation = struct
WHERE attr_kind < :akind
OR (attr_kind = :akind AND source_file <= :sfile) )
|}
let replace_attributes ~pname_str ~pname ~akind ~source_file ~attributes ~proc_desc ~callees =
ResultsDatabase.with_registered_statement attribute_replace_statement ~f:(fun db replace_stmt ->
in
fun ~pname_str ~pname ~akind ~source_file ~attributes ~proc_desc ~callees ->
ResultsDatabase.with_registered_statement attribute_replace_statement
~f:(fun db replace_stmt ->
Sqlite3.bind replace_stmt 1 (* :pname *) pname
|> SqliteUtils.check_result_code db ~log:"replace bind pname" ;
Sqlite3.bind replace_stmt 2 (* :proc_name_hum *) (Sqlite3.Data.TEXT pname_str)
@ -62,15 +63,15 @@ module Implementation = struct
SqliteUtils.result_unit db ~finalize:false ~log:"Attributes.replace" replace_stmt )
let add_source_file =
let source_file_store_statement =
ResultsDatabase.register_statement
{|
INSERT OR REPLACE INTO source_files
VALUES (:source, :tenv, :integer_type_widths, :proc_names, :freshly_captured)
|}
let add_source_file ~source_file ~tenv ~integer_type_widths ~proc_names =
in
fun ~source_file ~tenv ~integer_type_widths ~proc_names ->
ResultsDatabase.with_registered_statement source_file_store_statement ~f:(fun db store_stmt ->
Sqlite3.bind store_stmt 1 source_file
(* :source *)
@ -90,13 +91,9 @@ module Implementation = struct
SqliteUtils.result_unit ~finalize:false ~log:"Cfg.store" db store_stmt )
let mark_all_source_files_stale_statement =
ResultsDatabase.register_statement "UPDATE source_files SET freshly_captured = 0"
let mark_all_source_files_stale () =
ResultsDatabase.with_registered_statement mark_all_source_files_stale_statement
~f:(fun db stmt -> SqliteUtils.result_unit db ~finalize:false ~log:"mark_all_stale" stmt)
ResultsDatabase.get_database ()
|> SqliteUtils.exec ~stmt:"UPDATE source_files SET freshly_captured = 0" ~log:"mark_all_stale"
let merge_procedures_table ~db_file =

@ -13,26 +13,30 @@ let results_dir_get_path entry = ResultsDirEntryName.get_path ~results_dir:Confi
let procedures_schema prefix =
Printf.sprintf
{|CREATE TABLE IF NOT EXISTS %sprocedures
( proc_name TEXT PRIMARY KEY
{|
CREATE TABLE IF NOT EXISTS %sprocedures
( proc_name BLOB PRIMARY KEY NOT NULL
, proc_name_hum TEXT
, attr_kind INTEGER NOT NULL
, source_file TEXT NOT NULL
, proc_attributes BLOB NOT NULL
, cfg BLOB
, callees BLOB NOT NULL
)|}
)
|}
prefix
let source_files_schema prefix =
Printf.sprintf
{|CREATE TABLE IF NOT EXISTS %ssource_files
{|
CREATE TABLE IF NOT EXISTS %ssource_files
( source_file TEXT PRIMARY KEY
, type_environment BLOB NOT NULL
, integer_type_widths BLOB
, procedure_names BLOB NOT NULL
, freshly_captured INT NOT NULL )|}
, freshly_captured INT NOT NULL )
|}
prefix
@ -40,10 +44,11 @@ let specs_schema prefix =
Printf.sprintf
{|
CREATE TABLE IF NOT EXISTS %sspecs
( proc_name TEXT PRIMARY KEY
( proc_name BLOB PRIMARY KEY NOT NULL
, analysis_summary BLOB NOT NULL
, report_summary BLOB NOT NULL
)|}
)
|}
prefix

Loading…
Cancel
Save