1

I'm looking for a way to introduce a formal public API into a program (PostgreSQL) that presently lacks any formal boundary between extension-accessible interfaces and those for internal use only.

It has a few headers that say they're for internal use only, and it uses a lot of statics, but there's still a great deal that extensions can just reach into ... but shouldn't. This makes it impractical to offer binary compatibility guarantees across even patch releases. The current approach boils down to "it should work but we don't promise anything," which is not ideal.

It's a large piece of software and it's not going to be practical to introduce a hard boundary all at once since there's such a lively extension community outside the core codebase. But we'd need a way to tell people "this interface is private, don't use it or speak up and ask for it to be declared public if you need it and can justify it".

Portably.

All I've been able to come up with so far is to add macros around gcc's __attribute__ ((deprecated)) and MSVC's __declspec(deprecated) that are empty when building the core server, but defined normally when building extensions. That'll work, but "deprecated" isn't quite right, it's more a case of "use of non-public internal API".

Is there any better way than using deprecated annotations? I'd quite like to actually be able to use them for deprecating use of functionality in-core too, as the server grows and it becomes impractical to always change everything all in one sweep.

Community
  • 1
  • 1
Craig Ringer
  • 307,061
  • 76
  • 688
  • 778
  • The classic scenario is: initially bad design + code rot over time = complete mess. If the design was bad from the start, the only way to save the program long-term is unfortunately to rewrite it. – Lundin Jul 01 '16 at 06:52
  • What about writing a separate set of headers containing only the public API? – MikeMB Jul 01 '16 at 09:22
  • @Lundin Rewrite? Er, no. Really no. That'd be a Mozilla in the making, and totally pointless. Nor is it a bad design in general, it's pretty civilized. It just has issues with extensions, where it doesn't define a clear extension API. That can't be "rewritten" - it's the server's API for queries, node management, etc, and just a matter of which parts are blessed as stable and acceptable for extensions to access. – Craig Ringer Jul 01 '16 at 13:18
  • @MikeMB Yeah, that's one option. It'll involve a lot of code churn that'll be painful for maintainers of existing extensions and for backporting fixes to older server versions, but it's a possibility. On GCC we could have a `#warning` block in internal headers that's `#ifdef`'d out for internal compiles, too, so you see an indication if you include headers you aren't supposed to. And/or put in them in a separate include-dir. – Craig Ringer Jul 01 '16 at 13:19
  • @CraigRinger Well this is all very fuzzy. I don't think anyone can give you concrete advise without having a look at the whole code base. – Lundin Jul 01 '16 at 13:23
  • @CraigRinger: Of course, without knowing your codebase, I can't speculate on the necessary amount of work and whether it would be worth it. However, I'd guess that for the most part it would mean a mechanical moving of function and data-type declarations that you deem part of the stable API to new Headers, which you then include in the internal ones. Extension Maintainers wouldn't have to change anything if they use the correct functions and can live with the warnings and "only" have to rename their headers to silence the warnings. – MikeMB Jul 01 '16 at 15:37
  • It would certainly be a non-trivial change to the code base, but it might be worth it, if it simplifies your future life. – MikeMB Jul 01 '16 at 15:37

0 Answers0