-
Notifications
You must be signed in to change notification settings - Fork 56
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix memory leaks in custom executor #251
Conversation
784bd6d
to
867f174
Compare
src/pgduckdb_node.cpp
Outdated
} | ||
} | ||
|
||
auto pending = prepared.PendingQuery(duckdb_params, true); | ||
if (pending->HasError()) { | ||
elog(ERROR, "DuckDB execute returned an error: %s", pending->GetError().c_str()); | ||
throw std::runtime_error(pending->GetError()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can use pending->ThrowError()
instead
That would also preserve the duckdb exception type and the information the exception holds, rather than stringifying it
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's what I did initially but sadly it throws an ugly JSON then... Maybe I missed something, I'll try again.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tried again and I got something like this:
ERROR: (PGDuckDB/ExecuteQuery) {"exception_type":"Conversion","exception_message":"Could not convert string 'not an integer' to INT32\nLINE 1: SELECT (t)::integer AS t198 FROM public.foo\n ^","position":"10"}
Is there something specific to do so it doesn't output JSON?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Tishj I've pushed that commit to support the pending->ThrowError()
.
Maybe I missed something from DuckDB API, but I'm a bit surprised that:
- I have to specially handle
duckdb::Exception
ThrowError
(in some cases at least) throws astd::exception
, not aduckdb::Exception
one
Happy to improve if there's a better way?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, if I'm reading this correctly, we add DuckDBFunctionGuard to catch a c++ exception so we can perform cleanup on the postgres side before propagating this error upward?
src/pgduckdb_node.cpp
Outdated
if (execution_result == duckdb::PendingExecutionResult::EXECUTION_ERROR) { | ||
CleanupDuckdbScanState(state); | ||
elog(ERROR, "(PGDuckDB/ExecuteQuery) %s", pending->GetError().c_str()); | ||
throw std::runtime_error(pending->GetError()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same comment as above
Yep, that's correct! |
This reverts commit 59ada4b. Seems that the previous PR is causing issues like: ``` 2024-10-07 15:55:16.797 CEST client backend[159884] pg_regress/execution_error STATEMENT: select a::INTEGER from int_as_varchar; TRAP: failed Assert("rel->rd_refcnt > 0"), File: "relcache.c", Line: 2176, PID: 159884 postgres: jelte regression [local] idle(ExceptionalCondition+0x6e)[0x5ff6eb3300a4] postgres: jelte regression [local] idle(RelationDecrementReferenceCount+0x38)[0x5ff6eb323998] postgres: jelte regression [local] idle(RelationClose+0x15)[0x5ff6eb3239c5] /home/jelte/.pgenv/pgsql-17beta9/lib/pg_duckdb.so(+0x2b836)[0x7c5b33ae6836] /home/jelte/.pgenv/pgsql-17beta9/lib/pg_duckdb.so(+0x2bc7e)[0x7c5b33ae6c7e] /home/jelte/.pgenv/pgsql-17beta9/lib/pg_duckdb.so(+0x2bdbd)[0x7c5b33ae6dbd] /home/jelte/.pgenv/pgsql-17beta9/lib/pg_duckdb.so(+0x2e015)[0x7c5b33ae9015] /home/jelte/.pgenv/pgsql-17beta9/lib/libduckdb.so(_ZN6duckdb16AttachedDatabaseD1Ev+0x2d)[0x7c5b2f707edd] /home/jelte/.pgenv/pgsql-17beta9/lib/libduckdb.so(_ZN6duckdb16AttachedDatabaseD0Ev+0xd)[0x7c5b2f707f1d] /home/jelte/.pgenv/pgsql-17beta9/lib/libduckdb.so(+0x1409628)[0x7c5b2f009628] /home/jelte/.pgenv/pgsql-17beta9/lib/libduckdb.so(_ZN6duckdb10CatalogSetD1Ev+0x2e)[0x7c5b2f00c66e] /home/jelte/.pgenv/pgsql-17beta9/lib/libduckdb.so(_ZN6duckdb15DatabaseManager14ResetDatabasesERNS_10unique_ptrINS_13TaskSchedulerESt14default_deleteIS2_ELb1EEE+0xfd)[0x7c5b2f70830d] /home/jelte/.pgenv/pgsql-17beta9/lib/libduckdb.so(_ZN6duckdb16DatabaseInstanceD1Ev+0x25)[0x7c5b2f70b5c5] /home/jelte/.pgenv/pgsql-17beta9/lib/libduckdb.so(_ZNSt16_Sp_counted_baseILN9__gnu_cxx12_Lock_policyE2EE24_M_release_last_use_coldEv+0xe)[0x7c5b2e5d9a6e] /home/jelte/.pgenv/pgsql-17beta9/lib/pg_duckdb.so(+0x1a6f5)[0x7c5b33ad56f5] /lib/x86_64-linux-gnu/libc.so.6(+0x47a66)[0x7c5b32e47a66] /lib/x86_64-linux-gnu/libc.so.6(+0x47bae)[0x7c5b32e47bae] postgres: jelte regression [local] idle(proc_exit+0x3d)[0x5ff6eb1b013a] postgres: jelte regression [local] idle(PostgresMain+0x37e)[0x5ff6eb1e0ffe] postgres: jelte regression [local] idle(BackendMain+0x51)[0x5ff6eb1da61b] postgres: jelte regression [local] idle(postmaster_child_launch+0xc7)[0x5ff6eb131860] postgres: jelte regression [local] idle(+0x444029)[0x5ff6eb136029] postgres: jelte regression [local] idle(+0x4442ac)[0x5ff6eb1362ac] postgres: jelte regression [local] idle(BackgroundWorkerInitializeConnection+0x0)[0x5ff6eb137920] postgres: jelte regression [local] idle(main+0x20e)[0x5ff6eb053282] /lib/x86_64-linux-gnu/libc.so.6(+0x2a1ca)[0x7c5b32e2a1ca] /lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0x8b)[0x7c5b32e2a28b] postgres: jelte regression [local] idle(_start+0x25)[0x5ff6eadcfef5] ``` Reverting to investigate
When one calls
elog(ERROR,...
itlongjmp
out of the current stack leaving no chance for the C++ to be executed.This PR is a first iteration toward what we want to rationalize (cf. #93 ):
This fixes #120, even though there still seem to be a small leak with DuckDB's
PrepareQuery
leftover (to be followed-up separately)