aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPeter Eisentraut <peter@eisentraut.org>2021-11-22 07:40:17 +0100
committerPeter Eisentraut <peter@eisentraut.org>2021-11-22 08:00:14 +0100
commitd6d1dfcc99e3dd6e70e2a7024924e491bb7a9670 (patch)
tree6fef3affc3f8e081be88963d4ccb677f8909486b /src
parent1b06d7bac901e5fd20bba597188bae2882bf954b (diff)
downloadpostgresql-d6d1dfcc99e3dd6e70e2a7024924e491bb7a9670.tar.gz
postgresql-d6d1dfcc99e3dd6e70e2a7024924e491bb7a9670.zip
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
Diffstat (limited to 'src')
-rw-r--r--src/backend/utils/fmgr/dfmgr.c15
-rw-r--r--src/include/fmgr.h7
-rw-r--r--src/include/pg_config_manual.h17
3 files changed, 38 insertions, 1 deletions
diff --git a/src/backend/utils/fmgr/dfmgr.c b/src/backend/utils/fmgr/dfmgr.c
index 96fd9d22685..cc1a5200705 100644
--- a/src/backend/utils/fmgr/dfmgr.c
+++ b/src/backend/utils/fmgr/dfmgr.c
@@ -331,6 +331,21 @@ incompatible_module_error(const char *libname,
}
/*
+ * 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.
*
* XXX this code has to be adjusted any time the set of fields in a magic
diff --git a/src/include/fmgr.h b/src/include/fmgr.h
index ab7b85c86e1..cec663bdff0 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 614035e2159..225c5b87cc7 100644
--- a/src/include/pg_config_manual.h
+++ b/src/include/pg_config_manual.h
@@ -43,6 +43,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
* with index tuple header size (see access/itup.h).