Skip to content

Commit 38ae2a5

Browse files
committed
fix: guard libpg_query cleanup lifecycle
1 parent 1c819c7 commit 38ae2a5

1 file changed

Lines changed: 30 additions & 7 deletions

File tree

tools/pg_compat/pg_compat.cpp

Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,27 @@ struct Candidate {
4343
std::string sql;
4444
};
4545

46+
class PgQueryLifecycle {
47+
public:
48+
PgQueryLifecycle() = default;
49+
50+
~PgQueryLifecycle() {
51+
if (initialized_) {
52+
pg_query_exit();
53+
}
54+
}
55+
56+
PgQueryLifecycle(const PgQueryLifecycle&) = delete;
57+
PgQueryLifecycle& operator=(const PgQueryLifecycle&) = delete;
58+
59+
void mark_initialized() {
60+
initialized_ = true;
61+
}
62+
63+
private:
64+
bool initialized_ = false;
65+
};
66+
4667
class SplitResultOwner {
4768
public:
4869
explicit SplitResultOwner(PgQuerySplitResult result)
@@ -352,8 +373,11 @@ std::vector<Candidate> extract_candidates(
352373
return candidates;
353374
}
354375

355-
std::vector<Candidate> split_candidates(std::string_view input) {
376+
std::vector<Candidate> split_candidates(
377+
std::string_view input,
378+
PgQueryLifecycle& lifecycle) {
356379
std::string owned_input(input);
380+
lifecycle.mark_initialized();
357381
SplitResultOwner parser_split(
358382
pg_query_split_with_parser(owned_input.c_str()));
359383
if (parser_split.get().error == nullptr) {
@@ -597,9 +621,10 @@ void emit_accepted(const Options& options,
597621
std::cout << "}\n";
598622
}
599623

600-
void run(const Options& options) {
624+
void run(const Options& options, PgQueryLifecycle& lifecycle) {
601625
const std::string input = read_input(options.input);
602-
const std::vector<Candidate> candidates = split_candidates(input);
626+
const std::vector<Candidate> candidates =
627+
split_candidates(input, lifecycle);
603628
sql_parser::Parser<sql_parser::Dialect::PostgreSQL> parser;
604629

605630
for (const Candidate& candidate : candidates) {
@@ -660,18 +685,16 @@ void run(const Options& options) {
660685
} // namespace
661686

662687
int main(int argc, char** argv) {
688+
PgQueryLifecycle lifecycle;
663689
try {
664690
const Options options = parse_options(argc, argv);
665-
run(options);
666-
pg_query_exit();
691+
run(options, lifecycle);
667692
return 0;
668693
} catch (const UsageError&) {
669694
std::cerr << USAGE;
670-
pg_query_exit();
671695
return 2;
672696
} catch (const std::exception& error) {
673697
std::cerr << "infrastructure error: " << error.what() << '\n';
674-
pg_query_exit();
675698
return 1;
676699
}
677700
}

0 commit comments

Comments
 (0)