The PostgreSQL C Dialect
When I was writing my first PostgreSQL extension, I was at sea on a lot of the conventions that make up the "PostgreSQL C Dialect." I've taken my notes, added some additional things that confused me, and put it up on the wiki for review:
https://wiki.postgresql.org/wiki/The_PostgreSQL_C_Dialect
Feedback welcome, of course!
Christophe Pettus <xof@thebuild.com> writes:
When I was writing my first PostgreSQL extension, I was at sea on a lot of the conventions that make up the "PostgreSQL C Dialect." I've taken my notes, added some additional things that confused me, and put it up on the wiki for review:
https://wiki.postgresql.org/wiki/The_PostgreSQL_C_Dialect
Feedback welcome, of course!
Very nice! Thanks for writing that up.
regards, tom lane
On Mon, Jun 22, 2026 at 04:15:57PM -0400, Tom Lane wrote:
Christophe Pettus <xof@thebuild.com> writes:
When I was writing my first PostgreSQL extension, I was at sea on a lot of the conventions that make up the "PostgreSQL C Dialect." I've taken my notes, added some additional things that confused me, and put it up on the wiki for review:
https://wiki.postgresql.org/wiki/The_PostgreSQL_C_DialectFeedback welcome, of course!
Very nice! Thanks for writing that up.
I have added a link from the Developer's FAQ:
--
Bruce Momjian <bruce@momjian.us> https://momjian.us
EDB https://enterprisedb.com
Do not let urgent matters crowd out time for investment in the future.
Very nice.
Given the many emdashes in the text, can I ask if you used an LLM to write
it? If so, which one?
And importantly, if an LLM was used (no issues there) did you ask a
different model to double-check every statement it makes, just to be sure?
Thanks,
Roberto
On Mon, Jun 22, 2026 at 1:39 PM Christophe Pettus <xof@thebuild.com> wrote:
Show quoted text
When I was writing my first PostgreSQL extension, I was at sea on a lot of
the conventions that make up the "PostgreSQL C Dialect." I've taken my
notes, added some additional things that confused me, and put it up on the
wiki for review:https://wiki.postgresql.org/wiki/The_PostgreSQL_C_Dialect
Feedback welcome, of course!
I did use Claude Opus 4.8 to expand on my rather cryptic and uninteresting notes into something more readable.
I did use a different model to check everything, which was me. :-)
Show quoted text
On Jun 22, 2026, at 15:10, Roberto Mello <roberto.mello@gmail.com> wrote:
Very nice.
Given the many emdashes in the text, can I ask if you used an LLM to write it? If so, which one?
And importantly, if an LLM was used (no issues there) did you ask a different model to double-check every statement it makes, just to be sure?
Thanks,
Roberto
On Mon, Jun 22, 2026 at 1:39 PM Christophe Pettus <xof@thebuild.com <mailto:xof@thebuild.com>> wrote:
When I was writing my first PostgreSQL extension, I was at sea on a lot of the conventions that make up the "PostgreSQL C Dialect." I've taken my notes, added some additional things that confused me, and put it up on the wiki for review:
https://wiki.postgresql.org/wiki/The_PostgreSQL_C_Dialect
Feedback welcome, of course!
On Tue, Jun 23, 2026 at 2:39 AM Christophe Pettus <xof@thebuild.com> wrote:
When I was writing my first PostgreSQL extension, I was at sea on a lot of the conventions that make up the "PostgreSQL C Dialect." I've taken my notes, added some additional things that confused me, and put it up on the wiki for review:
https://wiki.postgresql.org/wiki/The_PostgreSQL_C_Dialect
Feedback welcome, of course!
Cool work! Minor comments:
Size, Index - These are not common, and I think they are actually
discouraged now, in favor of the more common size_t and uint32. I'm
not sure if there's a consensus on that, though.
C99 -> we started requiring C11 during the dev cycle of the PG19, and
it doesn't seem to early to mention that. The part about C99 features
we don't allow are still accurate, I believe.
--
John Naylor
Amazon Web Services
Hi,
On Mon, Jun 22, 2026 at 12:39:36PM -0700, Christophe Pettus wrote:
When I was writing my first PostgreSQL extension, I was at sea on a lot of the conventions that make up the "PostgreSQL C Dialect." I've taken my notes, added some additional things that confused me, and put it up on the wiki for review:
https://wiki.postgresql.org/wiki/The_PostgreSQL_C_Dialect
Feedback welcome, of course!
Thanks for doing this, that's cool work!
One comment about "The frontend/backend split and portability", what about adding
that (see 49bff412)
"
Headers never include postgres.h, postgres_fe.h, or c.h themselves.
"
say, before the "The FRONTEND macro" bullet?
Regards,
--
Bertrand Drouvot
PostgreSQL Contributors Team
RDS Open Source Databases
Amazon Web Services: https://aws.amazon.com
On Jun 22, 2026, at 20:53, Bertrand Drouvot <bertranddrouvot.pg@gmail.com> wrote:
One comment about "The frontend/backend split and portability", what about adding
that (see 49bff412)"
Headers never include postgres.h, postgres_fe.h, or c.h themselves.
"say, before the "The FRONTEND macro" bullet?
Good catch! Added.
On Jun 22, 2026, at 20:32, John Naylor <johncnaylorls@gmail.com> wrote:
Size, Index - These are not common, and I think they are actually
discouraged now, in favor of the more common size_t and uint32. I'm
not sure if there's a consensus on that, though.
Thanks! I'll be happy to edit if appropriate.
C99 -> we started requiring C11 during the dev cycle of the PG19, and
it doesn't seem to early to mention that. The part about C99 features
we don't allow are still accurate, I believe.
Good catch. I've updated the mentions, as well as moving the C-language baseline up (it was in kind of a weird and offhand place before). I did add an admonition to not be too innovative in the use of new features in C11 without making sure there is consensus here as to their use.
Christophe Pettus <xof@thebuild.com> writes:
On Jun 22, 2026, at 20:32, John Naylor <johncnaylorls@gmail.com> wrote:
Size, Index - These are not common, and I think they are actually
discouraged now, in favor of the more common size_t and uint32. I'm
not sure if there's a consensus on that, though.
Thanks! I'll be happy to edit if appropriate.
I think the consensus is to prefer "size_t" over "Size" in all-new
code. But when modifying or adding to existing code, match what's
around you, which in many places favors "Size".
"Index" is in a grayer area because there was never a solid consensus
on what to use it for to begin with. Again, there are places where
the match-nearby-code rule tells you to use Index, but if that doesn't
apply I'd avoid it.
BTW, you might want to mention match-nearby-code in the para about
naming too. It's not like we have just one preferred naming style
--- depending on where you look, there's camelCase, CapitalizeEachWord,
use_underscores_instead, etc etc. I have no appetite for trying to
force tree-wide uniformity on that score; but I do get annoyed when
adjacent routines don't look anything alike.
regards, tom lane
On Jun 23, 2026, at 06:53, Tom Lane <tgl@sss.pgh.pa.us> wrote:
I think the consensus is to prefer "size_t" over "Size" in all-new
code. But when modifying or adding to existing code, match what's
around you, which in many places favors "Size"."Index" is in a grayer area because there was never a solid consensus
on what to use it for to begin with. Again, there are places where
the match-nearby-code rule tells you to use Index, but if that doesn't
apply I'd avoid it.BTW, you might want to mention match-nearby-code in the para about naming too. It's not like we have just one preferred naming style --- depending on where you look, there's camelCase, CapitalizeEachWord, use_underscores_instead, etc etc. I have no appetite for trying to force tree-wide uniformity on that score; but I do get annoyed when adjacent routines don't look anything alike.
Thank you! I've updated the page to include statements around this. I took the liberty of borrowing your "camelCase" etc. wording.
Thanks. This is really helpful.
I saw it says "Everything here is written against the PostgreSQL 18
source tree.", but my understanding is that since PostgreSQL 19, the
preferred approach is to use the macros palloc0_object(),
palloc0_array(), and related macros instead of palloc directly.
======
Kind Regards,
Peter Smith.
Fujitsu Australia
On Jun 22, 2026, at 12:39, Christophe Pettus <xof@thebuild.com> wrote:
https://wiki.postgresql.org/wiki/The_PostgreSQL_C_Dialect
I've removed the admonition that the page is not to be trusted. If anyone spots anything wrong or unclear, of course, please let me know and I'll fix it ASAP.
Really nice wiki page!
I'm biased since I added the foreach_node/foreach_ptr/etc macros, but
I think it'd be good to say that using them is usually preferred over
the foreach+lfirst macro.
Show quoted text
On Mon, 22 Jun 2026 at 21:39, Christophe Pettus <xof@thebuild.com> wrote:
When I was writing my first PostgreSQL extension, I was at sea on a lot of the conventions that make up the "PostgreSQL C Dialect." I've taken my notes, added some additional things that confused me, and put it up on the wiki for review:
https://wiki.postgresql.org/wiki/The_PostgreSQL_C_Dialect
Feedback welcome, of course!
On Jun 24, 2026, at 13:16, Jelte Fennema-Nio <postgres@jeltef.nl> wrote:
I'm biased since I added the foreach_node/foreach_ptr/etc macros, but
I think it'd be good to say that using them is usually preferred over
the foreach+lfirst macro.
Thanks! Updated.
On Tue, Jun 23, 2026 at 3:39 AM Christophe Pettus <xof@thebuild.com> wrote:
When I was writing my first PostgreSQL extension, I was at sea on a lot of the conventions that make up the "PostgreSQL C Dialect." I've taken my notes, added some additional things that confused me, and put it up on the wiki for review:
In many cases, we may need to add trailing commas to enum definitions.
See https://git.postgresql.org/cgit/postgresql.git/commit/?id=611806cd726fc92989ac918eac48fd8d684869c7
https://www.postgresql.org/docs/current/error-message-reporting.html
already mentioned that
```The extra parentheses were required before PostgreSQL version 12,
but are now optional.```.
Fewer parentheses are generally more readable, IMHO.
So https://wiki.postgresql.org/wiki/The_PostgreSQL_C_Dialect
ereport(ERROR,
(errcode(ERRCODE_DIVISION_BY_ZERO),
errmsg("division by zero")));
can be replaced by
ereport(ERROR,
errcode(ERRCODE_DIVISION_BY_ZERO),
errmsg("division by zero"));
````
The compiler‑attribute wrappers: pg_attribute_noreturn(),
pg_attribute_printf(), pg_attribute_unused(), pg_noinline,
pg_nodiscard, and pg_unreachable() — portable spellings with fallbacks
where a compiler lacks the underlying feature.
````
pg_attribute_noreturn is replaced by something else, probabaly by
pg_noreturn (i am not so sure).
```
Validity helpers such as PointerIsValid() and OidIsValid().
```
PointerIsValid() is removed.
Per
/messages/by-id/3482022.1728839631@sss.pgh.pa.us
It's encouraged to include parser_errposition while adding
``ereport(ERROR,`` in src/backend/parser/gram.y.
Fewer parentheses are generally more readable, IMHO.
So https://wiki.postgresql.org/wiki/The_PostgreSQL_C_Dialectereport(ERROR,
(errcode(ERRCODE_DIVISION_BY_ZERO),
errmsg("division by zero")));can be replaced by
ereport(ERROR,
errcode(ERRCODE_DIVISION_BY_ZERO),
errmsg("division by zero"));````
I just saw this, and I had already a change a while back. Per
e3a87b4991cc2d00, fewer parens is the standard for new code, but existing
code is not altered to avoid code churn and messy backports.