Skip to content

Commit e07be25

Browse files
authored
Fix memory management for postgres in edge cases (#89)
1 parent 5131953 commit e07be25

2 files changed

Lines changed: 15 additions & 3 deletions

File tree

src/sqlgen/postgres/Connection.cpp

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,11 @@ Result<Nothing> Connection::end_write() {
3333
}
3434
const auto res = PQgetResult(conn_.get());
3535
if (PQresultStatus(res) != PGRES_COMMAND_OK) {
36-
return error(PQerrorMessage(conn_.get()));
36+
const auto err = error(PQerrorMessage(conn_.get()));
37+
PQclear(res);
38+
return err;
3739
}
40+
PQclear(res);
3841
return Nothing{};
3942
}
4043

@@ -68,6 +71,7 @@ Result<Nothing> Connection::insert_impl(
6871
const auto& d = _data[i];
6972

7073
if (d.size() != current_row.size()) {
74+
execute("ROLLBACK;");
7175
execute("DEALLOCATE " + name + ";");
7276
return error("Error in entry " + std::to_string(i) + ": Expected " +
7377
std::to_string(current_row.size()) + " entries, got " +
@@ -88,13 +92,15 @@ Result<Nothing> Connection::insert_impl(
8892
);
8993

9094
const auto status = PQresultStatus(res);
91-
9295
if (status != PGRES_COMMAND_OK) {
96+
PQclear(res);
9397
const auto err = error(std::string("Executing INSERT failed: ") +
9498
PQresultErrorMessage(res));
99+
execute("ROLLBACK;");
95100
execute("DEALLOCATE " + name + ";");
96101
return err;
97102
}
103+
PQclear(res);
98104
}
99105

100106
return execute("DEALLOCATE " + name + ";");
@@ -170,6 +176,9 @@ Result<Nothing> Connection::write_impl(
170176
static_cast<int>(buffer.size()));
171177
if (success != 1) {
172178
PQputCopyEnd(conn_.get(), NULL);
179+
while (auto res = PQgetResult(conn_.get()))
180+
PQclear(res);
181+
173182
return error("Error occurred while writing data to postgres.");
174183
}
175184
}

src/sqlgen/postgres/exec.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ namespace sqlgen::postgres {
99

1010
Result<Ref<PGresult>> exec(const Ref<PGconn>& _conn,
1111
const std::string& _sql) noexcept {
12-
const auto res = PQexec(_conn.get(), _sql.c_str());
12+
auto res = PQexec(_conn.get(), _sql.c_str());
1313

1414
const auto status = PQresultStatus(res);
1515

@@ -18,6 +18,9 @@ Result<Ref<PGresult>> exec(const Ref<PGconn>& _conn,
1818
const auto err =
1919
error("Executing '" + _sql + "' failed: " + PQresultErrorMessage(res));
2020
PQclear(res);
21+
while ((res = PQgetResult(_conn.get())) != nullptr)
22+
PQclear(res);
23+
2124
return err;
2225
}
2326

0 commit comments

Comments
 (0)