*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/utils/fmgr/dfmgr.c,v 1.96 2008/01/01 19:45:53 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/fmgr/dfmgr.c,v 1.97 2008/09/03 22:34:50 tgl Exp $
*
*-------------------------------------------------------------------------
*/
#else
#include "port/dynloader/win32.h"
#endif
+#include "lib/stringinfo.h"
#include "miscadmin.h"
#include "utils/dynamic_loader.h"
#include "utils/hsearch.h"
char *Dynamic_library_path;
static void *internal_load_library(const char *libname);
+static void incompatible_module_error(const char *libname,
+ const Pg_magic_struct *module_magic_data);
static void internal_unload_library(const char *libname);
static bool file_exists(const char *name);
static char *expand_dynamic_library_name(const char *name);
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)));
+ /* issue suitable complaint */
+ incompatible_module_error(libname, &module_magic_data);
}
}
else
return file_scanner->handle;
}
+/*
+ * Report a suitable error for an incompatible magic block.
+ */
+static void
+incompatible_module_error(const char *libname,
+ const Pg_magic_struct *module_magic_data)
+{
+ StringInfoData details;
+
+ /*
+ * If the version doesn't match, just report that, because the rest of the
+ * block might not even have the fields we expect.
+ */
+ if (magic_data.version != module_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)));
+
+ /*
+ * Otherwise, spell out which fields don't agree.
+ *
+ * XXX this code has to be adjusted any time the set of fields in a magic
+ * block change!
+ */
+ initStringInfo(&details);
+
+ if (module_magic_data->funcmaxargs != magic_data.funcmaxargs)
+ {
+ if (details.len)
+ appendStringInfoChar(&details, '\n');
+ appendStringInfo(&details,
+ _("Server has FUNC_MAX_ARGS = %d, library has %d."),
+ magic_data.funcmaxargs,
+ module_magic_data->funcmaxargs);
+ }
+ if (module_magic_data->indexmaxkeys != magic_data.indexmaxkeys)
+ {
+ if (details.len)
+ appendStringInfoChar(&details, '\n');
+ appendStringInfo(&details,
+ _("Server has INDEX_MAX_KEYS = %d, library has %d."),
+ magic_data.indexmaxkeys,
+ module_magic_data->indexmaxkeys);
+ }
+ if (module_magic_data->namedatalen != magic_data.namedatalen)
+ {
+ if (details.len)
+ appendStringInfoChar(&details, '\n');
+ appendStringInfo(&details,
+ _("Server has NAMEDATALEN = %d, library has %d."),
+ magic_data.namedatalen,
+ module_magic_data->namedatalen);
+ }
+ if (module_magic_data->float4byval != magic_data.float4byval)
+ {
+ if (details.len)
+ appendStringInfoChar(&details, '\n');
+ appendStringInfo(&details,
+ _("Server has FLOAT4PASSBYVAL = %s, library has %s."),
+ magic_data.float4byval ? "true" : "false",
+ module_magic_data->float4byval ? "true" : "false");
+ }
+ if (module_magic_data->float8byval != magic_data.float8byval)
+ {
+ if (details.len)
+ appendStringInfoChar(&details, '\n');
+ appendStringInfo(&details,
+ _("Server has FLOAT8PASSBYVAL = %s, library has %s."),
+ magic_data.float8byval ? "true" : "false",
+ module_magic_data->float8byval ? "true" : "false");
+ }
+
+ if (details.len == 0)
+ appendStringInfo(&details,
+ _("Magic block has unexpected length or padding difference."));
+
+ ereport(ERROR,
+ (errmsg("incompatible library \"%s\": magic block mismatch",
+ libname),
+ errdetail("%s", details.data)));
+}
+
/*
* Unload the specified dynamic-link library file, if it is loaded.
*