Skip to content

Commit 845d7e6

Browse files
committed
Return :invalid_statement in statement NIFs; free buffer on deserialize failure
All 12 statement NIFs returned {:error, :connection_closed} when statement->statement was NULL, which is confusing (the connection is not closed; the statement was released) and changed the return type of NIFs that normally return an integer. Switch to {:error, :invalid_statement}. Also: sqlite3_deserialize() failure path was not calling sqlite3_free() on the malloc'd buffer. SQLITE_DESERIALIZE_FREEONCLOSE only takes ownership on success; the previous code leaked the buffer on any error rc. Update @SPEC for reset/1 and bind_parameter_count/1 to include {:error, atom()} in the return type.
1 parent 983b051 commit 845d7e6

2 files changed

Lines changed: 14 additions & 13 deletions

File tree

c_src/sqlite3_nif.c

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -545,7 +545,7 @@ exqlite_reset(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
545545
statement_acquire_lock(statement);
546546
if (statement->statement == NULL) {
547547
statement_release_lock(statement);
548-
return make_error_tuple(env, am_connection_closed);
548+
return make_error_tuple(env, am_invalid_statement);
549549
}
550550
sqlite3_reset(statement->statement);
551551
statement_release_lock(statement);
@@ -566,7 +566,7 @@ exqlite_bind_parameter_count(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]
566566
statement_acquire_lock(statement);
567567
if (statement->statement == NULL) {
568568
statement_release_lock(statement);
569-
return make_error_tuple(env, am_connection_closed);
569+
return make_error_tuple(env, am_invalid_statement);
570570
}
571571
int bind_parameter_count = sqlite3_bind_parameter_count(statement->statement);
572572
statement_release_lock(statement);
@@ -594,7 +594,7 @@ exqlite_bind_parameter_index(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]
594594
statement_acquire_lock(statement);
595595
if (statement->statement == NULL) {
596596
statement_release_lock(statement);
597-
return make_error_tuple(env, am_connection_closed);
597+
return make_error_tuple(env, am_invalid_statement);
598598
}
599599
int index = sqlite3_bind_parameter_index(statement->statement, (const char*)name.data);
600600
statement_release_lock(statement);
@@ -625,7 +625,7 @@ exqlite_bind_text(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
625625
statement_acquire_lock(statement);
626626
if (statement->statement == NULL) {
627627
statement_release_lock(statement);
628-
return make_error_tuple(env, am_connection_closed);
628+
return make_error_tuple(env, am_invalid_statement);
629629
}
630630
int rc = sqlite3_bind_text(statement->statement, idx, (char*)text.data, text.size, SQLITE_TRANSIENT);
631631
statement_release_lock(statement);
@@ -656,7 +656,7 @@ exqlite_bind_blob(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
656656
statement_acquire_lock(statement);
657657
if (statement->statement == NULL) {
658658
statement_release_lock(statement);
659-
return make_error_tuple(env, am_connection_closed);
659+
return make_error_tuple(env, am_invalid_statement);
660660
}
661661
int rc = sqlite3_bind_blob(statement->statement, idx, (char*)blob.data, blob.size, SQLITE_TRANSIENT);
662662
statement_release_lock(statement);
@@ -687,7 +687,7 @@ exqlite_bind_integer(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
687687
statement_acquire_lock(statement);
688688
if (statement->statement == NULL) {
689689
statement_release_lock(statement);
690-
return make_error_tuple(env, am_connection_closed);
690+
return make_error_tuple(env, am_invalid_statement);
691691
}
692692
int rc = sqlite3_bind_int64(statement->statement, idx, i);
693693
statement_release_lock(statement);
@@ -718,7 +718,7 @@ exqlite_bind_float(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
718718
statement_acquire_lock(statement);
719719
if (statement->statement == NULL) {
720720
statement_release_lock(statement);
721-
return make_error_tuple(env, am_connection_closed);
721+
return make_error_tuple(env, am_invalid_statement);
722722
}
723723
int rc = sqlite3_bind_double(statement->statement, idx, f);
724724
statement_release_lock(statement);
@@ -744,7 +744,7 @@ exqlite_bind_null(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
744744
statement_acquire_lock(statement);
745745
if (statement->statement == NULL) {
746746
statement_release_lock(statement);
747-
return make_error_tuple(env, am_connection_closed);
747+
return make_error_tuple(env, am_invalid_statement);
748748
}
749749
int rc = sqlite3_bind_null(statement->statement, idx);
750750
statement_release_lock(statement);
@@ -799,7 +799,7 @@ exqlite_multi_step(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
799799

800800
if (statement->statement == NULL) {
801801
connection_release_lock(conn);
802-
return make_error_tuple(env, am_connection_closed);
802+
return make_error_tuple(env, am_invalid_statement);
803803
}
804804

805805

@@ -866,7 +866,7 @@ exqlite_step(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
866866

867867
if (statement->statement == NULL) {
868868
connection_release_lock(conn);
869-
return make_error_tuple(env, am_connection_closed);
869+
return make_error_tuple(env, am_invalid_statement);
870870
}
871871

872872
int rc = sqlite3_step(statement->statement);
@@ -920,7 +920,7 @@ exqlite_columns(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
920920
statement_acquire_lock(statement);
921921
if (statement->statement == NULL) {
922922
statement_release_lock(statement);
923-
return make_error_tuple(env, am_connection_closed);
923+
return make_error_tuple(env, am_invalid_statement);
924924
}
925925
size = sqlite3_column_count(statement->statement);
926926

@@ -1114,6 +1114,7 @@ exqlite_deserialize(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
11141114
memcpy(buffer, serialized.data, size);
11151115
rc = sqlite3_deserialize(conn->db, "main", buffer, size, size, flags);
11161116
if (rc != SQLITE_OK) {
1117+
sqlite3_free(buffer);
11171118
connection_release_lock(conn);
11181119
return make_sqlite3_error_tuple(env, rc, conn->db);
11191120
}

lib/exqlite/sqlite3.ex

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ defmodule Exqlite.Sqlite3 do
124124
125125
See: https://sqlite.org/c3ref/reset.html
126126
"""
127-
@spec reset(statement) :: :ok
127+
@spec reset(statement) :: :ok | {:error, atom()}
128128
def reset(stmt), do: Sqlite3NIF.reset(stmt)
129129

130130
@doc """
@@ -136,7 +136,7 @@ defmodule Exqlite.Sqlite3 do
136136
2
137137
138138
"""
139-
@spec bind_parameter_count(statement) :: integer
139+
@spec bind_parameter_count(statement) :: non_neg_integer | {:error, atom()}
140140
def bind_parameter_count(stmt), do: Sqlite3NIF.bind_parameter_count(stmt)
141141

142142
@type bind_value ::

0 commit comments

Comments
 (0)