Change copyObject() to use typeof_unqual
Peter Eisentraut <peter@eisentraut.org>
From: Peter Eisentraut <peter@eisentraut.org>
To: pgsql-hackers <pgsql-hackers@postgresql.org>
Date: 2026-01-20T09:37:35Z
Lists: pgsql-hackers
Attachments
- 0001-Change-copyObject-to-use-typeof_unqual.patch (text/plain) patch 0001
- 0002-Add-some-const-qualifiers-enabled-by-typeof_unqual-c.patch (text/plain) patch 0002
Currently, when the argument of copyObject() is const-qualified, the return type is also, because the use of typeof carries over all the qualifiers. This is incorrect, since the point of copyObject() is to make a copy to mutate. But apparently no code ran into it. The new implementation uses typeof_unqual, which drops the qualifiers, making this work correctly. typeof_unqual is standardized in C23, but all recent versions of all the usual compilers support it even in non-C23 mode, at least as __typeof_unqual__. We add a configure/meson test for typeof_unqual and __typeof_unqual__ and use it if it's available, else we use the existing fallback of just returning void *. (Even MSVC supports it, if we use a slightly newer version than is on CI. For example, the new buildfarm member unicorn would support it.) The second patch make some changes to take advantage of this improved qualifier handling. EventTriggerCollectSimpleCommand() is a good example: It takes a node tree and makes a copy that it keeps around for its internal purposes, but it can't communicate via its function signature that it promises not scribble on the passed node tree. That is now fixed. The obvious drawback is that if you use an older compiler that supports typeof but not typeof_unqual, this change will make you lose that check. Currently, on the Cirrus CI system, only the NetBSD and OpenBSD tasks are affected by this. Anyway, the reason I'm posting this now instead of, say, waiting another year, is that over in the thread "Make copyObject work in C++"[0], we're discussing, well, making copyObject() work in (standard) C++ (typeof and typeof_unqual are not in C++). Assuming we want to make the typeof_unqual change in principle, I figured it would be worth considering doing that change first and then developing a C++ equivalent of that, instead of making a C++ equivalent of the current logic and then having to find another C++ solution when changing to typeof_unqual. [0]: https://www.postgresql.org/message-id/flat/CAGECzQR21OnnKiZO_1rLWO0-16kg1JBxnVq-wymYW0-_1cUNtg@mail.gmail.com
Commits
Same data as JSON:
GET /api/v1/messages/:b64id/commits
the thread's linked commits as JSON, with link sources.
API reference →
-
Add some const qualifiers enabled by typeof_unqual change on copyObject
- 7724cb9935a9 19 (unreleased) landed
-
Hardcode typeof_unqual to __typeof_unqual__ for clang
- 2eb6cd327cae 19 (unreleased) landed
-
Clean up postgres_fdw/t/010_subscription.pl.
- f4af7849b3db 19 (unreleased) cited
-
Hardcode override of typeof_unqual for clang-for-bitcode
- 63275ce84d2f 19 (unreleased) landed
-
Make typeof and typeof_unqual fallback definitions work on C++11
- cd083b54bd67 19 (unreleased) landed
-
Change copyObject() to use typeof_unqual
- 59292f7aac72 19 (unreleased) landed
- 4cfce4e62c8f 19 (unreleased) landed
-
Fixes for C++ typeof implementation
- 9c05f152b5dd 19 (unreleased) landed
-
Support using copyObject in standard C++
- 1887d822f142 19 (unreleased) cited