@@ -35,11 +35,6 @@ struct PgExceptionGuard {
35
35
}
36
36
37
37
~PgExceptionGuard () noexcept {
38
- RestoreStacks ();
39
- }
40
-
41
- void
42
- RestoreStacks () const noexcept {
43
38
PG_exception_stack = _save_exception_stack;
44
39
error_context_stack = _save_context_stack;
45
40
}
@@ -83,20 +78,33 @@ typename std::invoke_result<Func, FuncArgs...>::type
83
78
__PostgresFunctionGuard__ (const char *func_name, FuncArgs... args) {
84
79
std::lock_guard<std::recursive_mutex> lock (pgduckdb::GlobalProcessLock::GetLock ());
85
80
MemoryContext ctx = CurrentMemoryContext;
86
- ErrorData *edata = nullptr ;
87
- { // Scope for PG_END_TRY
81
+
82
+ { // PG_TRY
88
83
PgExceptionGuard g;
89
84
sigjmp_buf _local_sigjmp_buf;
90
85
if (sigsetjmp (_local_sigjmp_buf, 0 ) == 0 ) {
91
86
PG_exception_stack = &_local_sigjmp_buf;
92
87
return func (std::forward<FuncArgs>(args)...);
93
- } else {
94
- g.RestoreStacks ();
95
- CurrentMemoryContext = ctx;
88
+ }
89
+ }
90
+
91
+ CurrentMemoryContext = ctx;
92
+
93
+ ErrorData *edata = nullptr ;
94
+ { // PG_CATCH
95
+ // Extract the error message (edata) within a PG_TRY block.
96
+ PgExceptionGuard g;
97
+ sigjmp_buf _local_sigjmp_buf;
98
+ if (sigsetjmp (_local_sigjmp_buf, 0 ) == 0 ) {
99
+ PG_exception_stack = &_local_sigjmp_buf;
100
+
96
101
edata = CopyErrorData ();
97
102
FlushErrorState ();
103
+ } else {
104
+ // This is a pretty bad situation - we failed to extract the error message.
105
+ throw duckdb::Exception (duckdb::ExceptionType::EXECUTOR, " Failed to extract Postgres error message" );
98
106
}
99
- } // PG_END_TRY();
107
+ } // PG_END_TRY
100
108
101
109
auto message = duckdb::StringUtil::Format (" (PGDuckDB/%s) %s" , func_name, pg::GetErrorDataMessage (edata));
102
110
throw duckdb::Exception (duckdb::ExceptionType::EXECUTOR, message);
0 commit comments