v7-0002-Support-using-copyObject-in-C.patch
text/x-patch
Filename: v7-0002-Support-using-copyObject-in-C.patch
Type: text/x-patch
Part: 1
Message:
Re: Make copyObject work in C++
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: format-patch
Series: patch v7-0002
Subject: Support using copyObject in C++
| File | + | − |
|---|---|---|
| src/include/c.h | 13 | 0 |
| src/include/nodes/nodes.h | 2 | 2 |
| src/test/modules/test_cplusplusext/test_cplusplusext.cpp | 6 | 0 |
From 2d7130aab09383c88ca8c98d666144df70d0f2da Mon Sep 17 00:00:00 2001
From: Jelte Fennema-Nio <postgres@jeltef.nl>
Date: Fri, 5 Dec 2025 15:37:59 +0100
Subject: [PATCH v7 2/5] Support using copyObject in C++
Calling copyObject in C++ without GNU extensions fails with an error
like this:
error: use of undeclared identifier 'typeof'; did you mean 'typeid'
This is due to the C compiler supporting used to compile postgres
supporting typeof, but that function actually not being present in the
C++ compiler. This fixes that by defining pg_exprtype which maps to
typeof or decltype depending on the compiler. While pg_typeof would have
been a more natural name, that name is already taken in our codebase as
the implementation of the pg_typeof UDF.
---
src/include/c.h | 13 +++++++++++++
src/include/nodes/nodes.h | 4 ++--
.../modules/test_cplusplusext/test_cplusplusext.cpp | 6 ++++++
3 files changed, 21 insertions(+), 2 deletions(-)
diff --git a/src/include/c.h b/src/include/c.h
index c0be07a4566..08490641906 100644
--- a/src/include/c.h
+++ b/src/include/c.h
@@ -412,6 +412,19 @@
#define unlikely(x) ((x) != 0)
#endif
+/*
+ * pg_exprtype
+ * Get the type of an expression at compile time.
+ *
+ * In C++ we use decltype since typeof is not standard C++, while in C we use
+ * typeof when available.
+ */
+#if defined(__cplusplus)
+#define pg_exprtype(x) decltype(x)
+#elif defined(HAVE_TYPEOF)
+#define pg_exprtype(x) typeof(x)
+#endif
+
/*
* CppAsString
* Convert the argument to a string, using the C preprocessor.
diff --git a/src/include/nodes/nodes.h b/src/include/nodes/nodes.h
index b6ad28618ab..f5e17e670b7 100644
--- a/src/include/nodes/nodes.h
+++ b/src/include/nodes/nodes.h
@@ -226,8 +226,8 @@ extern int16 *readAttrNumberCols(int numCols);
extern void *copyObjectImpl(const void *from);
/* cast result back to argument type, if supported by compiler */
-#ifdef HAVE_TYPEOF
-#define copyObject(obj) ((typeof(obj)) copyObjectImpl(obj))
+#ifdef pg_exprtype
+#define copyObject(obj) ((pg_exprtype(obj)) copyObjectImpl(obj))
#else
#define copyObject(obj) copyObjectImpl(obj)
#endif
diff --git a/src/test/modules/test_cplusplusext/test_cplusplusext.cpp b/src/test/modules/test_cplusplusext/test_cplusplusext.cpp
index 7108e5b1cc5..48741f27949 100644
--- a/src/test/modules/test_cplusplusext/test_cplusplusext.cpp
+++ b/src/test/modules/test_cplusplusext/test_cplusplusext.cpp
@@ -17,6 +17,7 @@
extern "C" {
#include "postgres.h"
#include "fmgr.h"
+#include "nodes/parsenodes.h"
PG_MODULE_MAGIC_EXT("test_cplusplusext", "1.2");
@@ -32,6 +33,11 @@ test_cplusplus_add(PG_FUNCTION_ARGS)
{
int32 a = PG_GETARG_INT32(0);
int32 b = PG_GETARG_INT32(1);
+ RangeTblRef *node = makeNode(RangeTblRef);
+ RangeTblRef *copy = copyObject(node);
+
+ pfree(copy);
+ pfree(node);
PG_RETURN_INT32(a + b);
}
--
2.52.0