In case module and server magic blocks do not match
report exact parameters that differ.
It is quite cumbersome problem to track down unless
user already knows the cause.
As we want to encourage module use, such situations
can happen more often.
*** a/src/backend/utils/fmgr/dfmgr.c
--- b/src/backend/utils/fmgr/dfmgr.c
***************
*** 19,28 ****
--- 19,29 ----
#ifndef WIN32_ONLY_COMPILER
#include "dynloader.h"
#else
#include "port/dynloader/win32.h"
#endif
+ #include "lib/stringinfo.h"
#include "miscadmin.h"
#include "utils/dynamic_loader.h"
#include "utils/hsearch.h"
*************** PGFunction
*** 163,172 ****
--- 164,213 ----
lookup_external_function(void *filehandle, char *funcname)
{
return (PGFunction) pg_dlsym(filehandle, funcname);
}
+ /*
+ * Detailed error report when module incompatibility is detected.
+ */
+
+ #define MAGIC_FIELD_TEST(field) do { \
+ if (srv->field != mod->field) { \
+ if (det->len) \
+ appendStringInfo(det, ", "); \
+ appendStringInfo(det, "%s: %d != %d", #field, mod->field,
srv->field); \
+ } \
+ } while (0)
+
+ static void
+ module_incompat_error(const Pg_magic_struct *mod, const Pg_magic_struct *srv,
const char *libname)
+ {
+ StringInfo det;
+
+ if (mod->version != srv->version)
+ ereport(ERROR,
+ (errmsg("incompatible library \"%s\": version mismatch",
+ libname),
+ errdetail("Server is version %d.%d, library is version
%d.%d.",
+ srv->version / 100,
+ srv->version % 100,
+ mod->version / 100,
+ mod->version % 100)));
+
+ det = makeStringInfo();
+
+ MAGIC_FIELD_TEST(funcmaxargs);
+ MAGIC_FIELD_TEST(indexmaxkeys);
+ MAGIC_FIELD_TEST(namedatalen);
+ MAGIC_FIELD_TEST(float4byval);
+ MAGIC_FIELD_TEST(float8byval);
+
+ ereport(ERROR,
+ (errmsg("incompatible library \"%s\": magic block mismatch: %s",
+ libname, det->data)));
+ }
+ #undef MAGIC_FIELD_TEST
/*
* Load the specified dynamic-link library file, unless it already is
* loaded. Return the pg_dl* handle for the file.
*
*************** internal_load_library(const char *libnam
*** 255,281 ****
/* try to unlink library */
pg_dlclose(file_scanner->handle);
free((char *) file_scanner);
! /*
! * Report suitable error. It's probably not
worth writing a
! * separate error message for each field; only
the most common
! * case of wrong major version gets its own
message.
! */
! if (module_magic_data.version !=
magic_data.version)
! ereport(ERROR,
! (errmsg("incompatible library \"%s\":
version mismatch",
! libname),
! errdetail("Server is version %d.%d,
library is version %d.%d.",
!
magic_data.version / 100,
!
magic_data.version % 100,
!
module_magic_data.version / 100,
!
module_magic_data.version % 100)));
! ereport(ERROR,
! (errmsg("incompatible library \"%s\": magic
block mismatch",
! libname)));
}
}
else
{
/* try to unlink library */
--- 296,306 ----
/* try to unlink library */
pg_dlclose(file_scanner->handle);
free((char *) file_scanner);
! module_incompat_error(&module_magic_data,
&magic_data, libname);
}
}
else
{
/* try to unlink library */
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers