Skip to content

Commit af3d278

Browse files
authored
Move CPP functions wrapper to dedicated file (#452)
Move CPP function wrapper to dedicated file. Next, will do the same for the PG wrapper.
1 parent 3cb6110 commit af3d278

19 files changed

+114
-53
lines changed

Diff for: include/pgduckdb/logger.hpp

+2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
#include "pgduckdb/pgduckdb_process_lock.hpp"
44

5+
#include "pgduckdb/utility/cpp_only_file.hpp" // Must be last include.
6+
57
extern "C" {
68
bool errstart(int elevel, const char *domain);
79
void errfinish(const char *filename, int lineno, const char *funcname);

Diff for: include/pgduckdb/pg/error_data.hpp

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#pragma once
2+
3+
extern "C" {
4+
struct ErrorData;
5+
}
6+
7+
namespace pgduckdb::pg {
8+
const char* GetErrorDataMessage(ErrorData* error_data);
9+
}

Diff for: include/pgduckdb/pgduckdb_types.hpp

+2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
#include "pgduckdb/pg/declarations.hpp"
44

5+
#include "pgduckdb/utility/cpp_only_file.hpp" // Must be last include.
6+
57
namespace pgduckdb {
68

79
class PostgresScanGlobalState;

Diff for: include/pgduckdb/pgduckdb_utils.hpp

+20-36
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,26 @@
33
#include "duckdb/common/exception.hpp"
44
#include "duckdb/common/error_data.hpp"
55
#include "pgduckdb/pgduckdb_duckdb.hpp"
6+
#include "pgduckdb/pg/error_data.hpp"
7+
#include "pgduckdb/logger.hpp"
8+
9+
#include <setjmp.h>
10+
11+
#include "pgduckdb/utility/cpp_only_file.hpp" // Must be last include.
612

713
extern "C" {
8-
#include "postgres.h"
14+
// Note: these forward-declarations could live in a header under the `pg/` folder.
15+
// But since they are (hopefully) only used in this file, we keep them here.
16+
struct ErrorContextCallback;
17+
struct MemoryContextData;
18+
19+
typedef struct MemoryContextData *MemoryContext;
20+
21+
extern sigjmp_buf *PG_exception_stack;
22+
extern MemoryContext CurrentMemoryContext;
23+
extern ErrorContextCallback *error_context_stack;
24+
extern ErrorData * CopyErrorData();
25+
extern void FlushErrorState();
926
}
1027

1128
namespace pgduckdb {
@@ -44,52 +61,19 @@ __PostgresFunctionGuard__(const char *func_name, FuncArgs... args) {
4461
return func(std::forward<FuncArgs>(args)...);
4562
} else {
4663
g.RestoreStacks();
47-
MemoryContextSwitchTo(ctx);
64+
CurrentMemoryContext = ctx;
4865
edata = CopyErrorData();
4966
FlushErrorState();
5067
}
5168
} // PG_END_TRY();
5269

53-
auto message = duckdb::StringUtil::Format("(PGDuckDB/%s) %s", func_name, edata->message);
70+
auto message = duckdb::StringUtil::Format("(PGDuckDB/%s) %s", func_name, pg::GetErrorDataMessage(edata));
5471
throw duckdb::Exception(duckdb::ExceptionType::EXECUTOR, message);
5572
}
5673

5774
#define PostgresFunctionGuard(FUNC, ...) \
5875
pgduckdb::__PostgresFunctionGuard__<decltype(&FUNC), &FUNC>(__func__, __VA_ARGS__)
5976

60-
template <typename Func, Func func, typename... FuncArgs>
61-
typename std::invoke_result<Func, FuncArgs...>::type
62-
__CPPFunctionGuard__(const char *func_name, FuncArgs... args) {
63-
const char *error_message = nullptr;
64-
try {
65-
return func(args...);
66-
} catch (duckdb::Exception &ex) {
67-
duckdb::ErrorData edata(ex.what());
68-
error_message = pstrdup(edata.Message().c_str());
69-
} catch (std::exception &ex) {
70-
const auto msg = ex.what();
71-
if (msg[0] == '{') {
72-
duckdb::ErrorData edata(ex.what());
73-
error_message = pstrdup(edata.Message().c_str());
74-
} else {
75-
error_message = pstrdup(ex.what());
76-
}
77-
}
78-
79-
elog(ERROR, "(PGDuckDB/%s) %s", func_name, error_message);
80-
}
81-
82-
#define InvokeCPPFunc(FUNC, ...) pgduckdb::__CPPFunctionGuard__<decltype(&FUNC), &FUNC>(__FUNCTION__, __VA_ARGS__)
83-
84-
// Wrappers
85-
86-
#define DECLARE_PG_FUNCTION(func_name) \
87-
PG_FUNCTION_INFO_V1(func_name); \
88-
Datum func_name##_cpp(PG_FUNCTION_ARGS); \
89-
Datum func_name(PG_FUNCTION_ARGS) { \
90-
return InvokeCPPFunc(func_name##_cpp, fcinfo); \
91-
} \
92-
Datum func_name##_cpp(PG_FUNCTION_ARGS __attribute__((unused)))
9377

9478
duckdb::unique_ptr<duckdb::QueryResult> DuckDBQueryOrThrow(duckdb::ClientContext &context, const std::string &query);
9579

Diff for: include/pgduckdb/utility/cpp_wrapper.hpp

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
#pragma once
2+
3+
extern "C" {
4+
#include "postgres.h"
5+
}
6+
7+
namespace pgduckdb {
8+
9+
template <typename Func, Func func, typename... FuncArgs>
10+
typename std::invoke_result<Func, FuncArgs...>::type
11+
__CPPFunctionGuard__(const char *func_name, FuncArgs... args) {
12+
const char *error_message = nullptr;
13+
try {
14+
return func(args...);
15+
} catch (duckdb::Exception &ex) {
16+
duckdb::ErrorData edata(ex.what());
17+
error_message = pstrdup(edata.Message().c_str());
18+
} catch (std::exception &ex) {
19+
const auto msg = ex.what();
20+
if (msg[0] == '{') {
21+
duckdb::ErrorData edata(ex.what());
22+
error_message = pstrdup(edata.Message().c_str());
23+
} else {
24+
error_message = pstrdup(ex.what());
25+
}
26+
}
27+
28+
elog(ERROR, "(PGDuckDB/%s) %s", func_name, error_message);
29+
}
30+
31+
}
32+
33+
#define InvokeCPPFunc(FUNC, ...) pgduckdb::__CPPFunctionGuard__<decltype(&FUNC), &FUNC>(__FUNCTION__, __VA_ARGS__)
34+
35+
// Wrappers
36+
37+
#define DECLARE_PG_FUNCTION(func_name) \
38+
PG_FUNCTION_INFO_V1(func_name); \
39+
Datum func_name##_cpp(PG_FUNCTION_ARGS); \
40+
Datum func_name(PG_FUNCTION_ARGS) { \
41+
return InvokeCPPFunc(func_name##_cpp, fcinfo); \
42+
} \
43+
Datum func_name##_cpp(PG_FUNCTION_ARGS __attribute__((unused)))

Diff for: src/pg/error_data.cpp

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#include "pgduckdb/pg/error_data.hpp"
2+
3+
extern "C" {
4+
#include "postgres.h"
5+
}
6+
7+
namespace pgduckdb::pg {
8+
const char* GetErrorDataMessage(ErrorData* error_data) {
9+
return error_data->message;
10+
}
11+
} // namespace pgduckdb

Diff for: src/pgduckdb_background_worker.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
#include "duckdb/storage/table_storage_info.hpp"
1414
#include "duckdb/main/attached_database.hpp"
1515
#include "pgduckdb/pgduckdb_types.hpp"
16+
#include "pgduckdb/pgduckdb_utils.hpp"
17+
#include "pgduckdb/utility/cpp_wrapper.hpp"
1618
#include <string>
1719
#include <unordered_map>
1820

@@ -50,7 +52,6 @@ extern "C" {
5052
#include "pgduckdb/pgduckdb_duckdb.hpp"
5153
#include "pgduckdb/pgduckdb_background_worker.hpp"
5254
#include "pgduckdb/pgduckdb_metadata_cache.hpp"
53-
#include "pgduckdb/pgduckdb_utils.hpp"
5455

5556
static bool is_background_worker = false;
5657
static std::unordered_map<std::string, std::string> last_known_motherduck_catalog_versions;

Diff for: src/pgduckdb_ddl.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#include <regex>
33

44
#include "pgduckdb/pgduckdb_planner.hpp"
5+
#include "pgduckdb/pgduckdb_utils.hpp"
56

67
extern "C" {
78
#include "postgres.h"
@@ -27,10 +28,10 @@ extern "C" {
2728
#include "pgduckdb/pgduckdb_ruleutils.h"
2829
}
2930

31+
#include "pgduckdb/utility/cpp_wrapper.hpp"
3032
#include "pgduckdb/pgduckdb_duckdb.hpp"
3133
#include "pgduckdb/pgduckdb_background_worker.hpp"
3234
#include "pgduckdb/pgduckdb_metadata_cache.hpp"
33-
#include "pgduckdb/pgduckdb_utils.hpp"
3435
#include "pgduckdb/utility/copy.hpp"
3536
#include "pgduckdb/vendor/pg_list.hpp"
3637
#include <inttypes.h>

Diff for: src/pgduckdb_detoast.cpp

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
#include "duckdb.hpp"
22

3+
#include "pgduckdb/pgduckdb_types.hpp"
4+
#include "pgduckdb/pgduckdb_utils.hpp"
5+
36
extern "C" {
47
#include "postgres.h"
58
#include "pg_config.h"
@@ -20,9 +23,7 @@ extern "C" {
2023
}
2124

2225
#include "pgduckdb/pgduckdb_process_lock.hpp"
23-
#include "pgduckdb/pgduckdb_types.hpp"
2426
#include "pgduckdb/pgduckdb_detoast.hpp"
25-
#include "pgduckdb/pgduckdb_utils.hpp"
2627

2728
/*
2829
* Following functions are direct logic found in postgres code but for duckdb execution they are needed to be thread

Diff for: src/pgduckdb_duckdb.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include "pgduckdb/scan/postgres_scan.hpp"
1111
#include "pgduckdb/scan/postgres_seq_scan.hpp"
1212
#include "pgduckdb/pg/transactions.hpp"
13+
#include "pgduckdb/pgduckdb_utils.hpp"
1314

1415
extern "C" {
1516
#include "postgres.h"
@@ -23,7 +24,6 @@ extern "C" {
2324
#include "pgduckdb/pgduckdb_options.hpp"
2425
#include "pgduckdb/pgduckdb_xact.hpp"
2526
#include "pgduckdb/pgduckdb_metadata_cache.hpp"
26-
#include "pgduckdb/pgduckdb_utils.hpp"
2727

2828
#include <sys/stat.h>
2929
#include <unistd.h>

Diff for: src/pgduckdb_filter.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#include "duckdb.hpp"
22
#include "duckdb/planner/filter/constant_filter.hpp"
3+
#include "pgduckdb/pgduckdb_types.hpp"
34

45
extern "C" {
56
#include "postgres.h"
@@ -14,7 +15,6 @@ extern "C" {
1415

1516
#include "pgduckdb/pgduckdb_filter.hpp"
1617
#include "pgduckdb/pgduckdb_detoast.hpp"
17-
#include "pgduckdb/pgduckdb_types.hpp"
1818

1919
namespace pgduckdb {
2020

Diff for: src/pgduckdb_hooks.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include "pgduckdb/pgduckdb_planner.hpp"
44
#include "pgduckdb/pg/transactions.hpp"
55
#include "pgduckdb/pgduckdb_xact.hpp"
6+
#include "pgduckdb/pgduckdb_utils.hpp"
67

78
extern "C" {
89
#include "postgres.h"
@@ -29,8 +30,8 @@ extern "C" {
2930
#include "pgduckdb/utility/copy.hpp"
3031
#include "pgduckdb/vendor/pg_explain.hpp"
3132
#include "pgduckdb/vendor/pg_list.hpp"
32-
#include "pgduckdb/pgduckdb_utils.hpp"
3333
#include "pgduckdb/pgduckdb_node.hpp"
34+
#include "pgduckdb/utility/cpp_wrapper.hpp"
3435

3536
static planner_hook_type prev_planner_hook = NULL;
3637
static ExecutorStart_hook_type prev_executor_start_hook = NULL;

Diff for: src/pgduckdb_node.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include "duckdb/common/exception.hpp"
55

66
#include "pgduckdb/pgduckdb_planner.hpp"
7+
#include "pgduckdb/pgduckdb_types.hpp"
78

89
extern "C" {
910
#include "postgres.h"
@@ -14,9 +15,8 @@ extern "C" {
1415
}
1516

1617
#include "pgduckdb/pgduckdb_node.hpp"
17-
#include "pgduckdb/pgduckdb_types.hpp"
1818
#include "pgduckdb/pgduckdb_duckdb.hpp"
19-
#include "pgduckdb/pgduckdb_utils.hpp"
19+
#include "pgduckdb/utility/cpp_wrapper.hpp"
2020

2121
/* global variables */
2222
CustomScanMethods duckdb_scan_scan_methods;

Diff for: src/pgduckdb_options.cpp

+4-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44
#include <filesystem>
55
#include <fstream>
66

7+
#include "pgduckdb/pgduckdb_types.hpp"
8+
#include "pgduckdb/pgduckdb_utils.hpp"
9+
710
extern "C" {
811
#include "postgres.h"
912
#include "miscadmin.h"
@@ -24,8 +27,8 @@ extern "C" {
2427
#include "pgduckdb/pgduckdb_options.hpp"
2528
#include "pgduckdb/pgduckdb_duckdb.hpp"
2629
#include "pgduckdb/pgduckdb_utils.hpp"
27-
#include "pgduckdb/pgduckdb_types.hpp"
2830
#include "pgduckdb/pgduckdb_xact.hpp"
31+
#include "pgduckdb/utility/cpp_wrapper.hpp"
2932

3033
namespace pgduckdb {
3134

Diff for: src/pgduckdb_planner.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
#include "pgduckdb/catalog/pgduckdb_transaction.hpp"
66
#include "pgduckdb/scan/postgres_scan.hpp"
7+
#include "pgduckdb/pgduckdb_types.hpp"
78

89
extern "C" {
910
#include "postgres.h"
@@ -24,8 +25,7 @@ extern "C" {
2425

2526
#include "pgduckdb/pgduckdb_duckdb.hpp"
2627
#include "pgduckdb/pgduckdb_node.hpp"
27-
#include "pgduckdb/pgduckdb_types.hpp"
28-
#include "pgduckdb/pgduckdb_utils.hpp"
28+
#include "pgduckdb/utility/cpp_wrapper.hpp"
2929

3030
bool duckdb_explain_analyze = false;
3131

Diff for: src/pgduckdb_types.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@
33
#include "duckdb/common/extra_type_info.hpp"
44
#include "duckdb/common/types/uuid.hpp"
55

6+
#include "pgduckdb/pgduckdb_types.hpp"
67
#include "pgduckdb/scan/postgres_scan.hpp"
8+
#include "pgduckdb/types/decimal.hpp"
79

810
extern "C" {
911
#include "postgres.h"
@@ -26,7 +28,6 @@ extern "C" {
2628
#include "pgduckdb/types/decimal.hpp"
2729
#include "pgduckdb/pgduckdb_filter.hpp"
2830
#include "pgduckdb/pgduckdb_detoast.hpp"
29-
#include "pgduckdb/pgduckdb_types.hpp"
3031

3132
namespace pgduckdb {
3233

Diff for: src/pgduckdb_xact.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
#include "duckdb/common/exception.hpp"
22
#include "pgduckdb/pgduckdb_duckdb.hpp"
33
#include "pgduckdb/pgduckdb_utils.hpp"
4+
45
#include "pgduckdb/pg/transactions.hpp"
6+
#include "pgduckdb/utility/cpp_wrapper.hpp"
57

68
namespace pgduckdb {
79

Diff for: src/scan/heap_reader.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
#include "duckdb.hpp"
22

33
#include "pgduckdb/scan/heap_reader.hpp"
4+
#include "pgduckdb/pgduckdb_types.hpp"
5+
#include "pgduckdb/pgduckdb_utils.hpp"
46

57
extern "C" {
68
#include "postgres.h"
@@ -12,8 +14,6 @@ extern "C" {
1214
}
1315

1416
#include "pgduckdb/pgduckdb_process_lock.hpp"
15-
#include "pgduckdb/pgduckdb_types.hpp"
16-
#include "pgduckdb/pgduckdb_utils.hpp"
1717

1818
#include <optional>
1919

Diff for: src/scan/postgres_scan.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
#include "duckdb/common/enums/expression_type.hpp"
1414

1515
#include "pgduckdb/scan/postgres_scan.hpp"
16+
#include "pgduckdb/pgduckdb_types.hpp"
17+
#include "pgduckdb/pgduckdb_utils.hpp"
1618

1719
extern "C" {
1820
#include "postgres.h"
@@ -28,8 +30,6 @@ extern "C" {
2830
}
2931

3032
#include "pgduckdb/pgduckdb_process_lock.hpp"
31-
#include "pgduckdb/pgduckdb_types.hpp"
32-
#include "pgduckdb/pgduckdb_utils.hpp"
3333

3434
namespace pgduckdb {
3535

0 commit comments

Comments
 (0)