From 837680c2195a04bf1f1ecf567fadc3a3d69087fa Mon Sep 17 00:00:00 2001 From: Peter Eisentraut Date: Tue, 12 Oct 2021 14:08:10 +0200 Subject: [PATCH v1] Add ABI extra field to fmgr magic block This allows derived products to intentionally make their fmgr ABI incompatible, with a clean error message. Discussion: https://www.postgresql.org/message-id/flat/55215fda-db31-a045-d6b7-d6f2d2dc9920%40enterprisedb.com --- src/backend/utils/fmgr/dfmgr.c | 15 +++++++++++++++ src/include/fmgr.h | 7 ++++++- src/include/pg_config_manual.h | 17 +++++++++++++++++ 3 files changed, 38 insertions(+), 1 deletion(-) diff --git a/src/backend/utils/fmgr/dfmgr.c b/src/backend/utils/fmgr/dfmgr.c index 96fd9d2268..cc1a520070 100644 --- a/src/backend/utils/fmgr/dfmgr.c +++ b/src/backend/utils/fmgr/dfmgr.c @@ -330,6 +330,21 @@ incompatible_module_error(const char *libname, magic_data.version / 100, library_version))); } + /* + * Similarly, if the ABI extra field doesn't match, error out. Other + * fields below might also mismatch, but that isn't useful information if + * you're using the wrong product altogether. + */ + if (strcmp(module_magic_data->abi_extra, magic_data.abi_extra) != 0) + { + ereport(ERROR, + (errmsg("incompatible library \"%s\": ABI mismatch", + libname), + errdetail("Server has ABI \"%s\", library has \"%s\".", + magic_data.abi_extra, + module_magic_data->abi_extra))); + } + /* * Otherwise, spell out which fields don't agree. * diff --git a/src/include/fmgr.h b/src/include/fmgr.h index ab7b85c86e..cec663bdff 100644 --- a/src/include/fmgr.h +++ b/src/include/fmgr.h @@ -458,6 +458,7 @@ typedef struct int indexmaxkeys; /* INDEX_MAX_KEYS */ int namedatalen; /* NAMEDATALEN */ int float8byval; /* FLOAT8PASSBYVAL */ + char abi_extra[32]; /* see pg_config_manual.h */ } Pg_magic_struct; /* The actual data block contents */ @@ -468,9 +469,13 @@ typedef struct FUNC_MAX_ARGS, \ INDEX_MAX_KEYS, \ NAMEDATALEN, \ - FLOAT8PASSBYVAL \ + FLOAT8PASSBYVAL, \ + FMGR_ABI_EXTRA, \ } +StaticAssertDecl(sizeof(FMGR_ABI_EXTRA) <= sizeof(((Pg_magic_struct*)0)->abi_extra), + "FMGR_ABI_EXTRA too long"); + /* * Declare the module magic function. It needs to be a function as the dlsym * in the backend is only guaranteed to work on functions, not data diff --git a/src/include/pg_config_manual.h b/src/include/pg_config_manual.h index 614035e215..225c5b87cc 100644 --- a/src/include/pg_config_manual.h +++ b/src/include/pg_config_manual.h @@ -42,6 +42,23 @@ */ #define FUNC_MAX_ARGS 100 +/* + * When creating a product derived from PostgreSQL with changes that cause + * incompatibilities for loadable modules, it is recommended to change this + * string so that dfmgr.c can refuse to load incompatible modules with a clean + * error message. Typical examples that cause incompatibilities are any + * changes to node tags or node structures. (Note that dfmgr.c already + * detects common sources of incompatibilities due to major version + * differences and due to some changed compile-time constants. This setting + * is for catching anything that cannot be detected in a straightforward way.) + * + * There is no prescribed format for the string. The suggestion is to include + * product or company name, and optionally any internally-relevant ABI + * version. Example: "ACME Postgres/1.2". Note that the string will appear + * in a user-facing error message if an ABI mismatch is detected. + */ +#define FMGR_ABI_EXTRA "PostgreSQL" + /* * Maximum number of columns in an index. There is little point in making * this anything but a multiple of 32, because the main cost is associated -- 2.33.0