Skip to content

Commit ba9f37f

Browse files
committed
If a loadable module has wrong values in its magic block, spell out
exactly what they are in the complaint message. Marko Kreen, some editorialization by me.
1 parent fbb2b69 commit ba9f37f

File tree

2 files changed

+97
-19
lines changed

2 files changed

+97
-19
lines changed

src/backend/utils/fmgr/dfmgr.c

Lines changed: 93 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/utils/fmgr/dfmgr.c,v 1.96 2008/01/01 19:45:53 momjian Exp $
11+
* $PostgreSQL: pgsql/src/backend/utils/fmgr/dfmgr.c,v 1.97 2008/09/03 22:34:50 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -21,6 +21,7 @@
2121
#else
2222
#include "port/dynloader/win32.h"
2323
#endif
24+
#include "lib/stringinfo.h"
2425
#include "miscadmin.h"
2526
#include "utils/dynamic_loader.h"
2627
#include "utils/hsearch.h"
@@ -71,6 +72,8 @@ static DynamicFileList *file_tail = NULL;
7172
char *Dynamic_library_path;
7273

7374
static void *internal_load_library(const char *libname);
75+
static void incompatible_module_error(const char *libname,
76+
const Pg_magic_struct *module_magic_data);
7477
static void internal_unload_library(const char *libname);
7578
static bool file_exists(const char *name);
7679
static char *expand_dynamic_library_name(const char *name);
@@ -257,23 +260,8 @@ internal_load_library(const char *libname)
257260
pg_dlclose(file_scanner->handle);
258261
free((char *) file_scanner);
259262

260-
/*
261-
* Report suitable error. It's probably not worth writing a
262-
* separate error message for each field; only the most common
263-
* case of wrong major version gets its own message.
264-
*/
265-
if (module_magic_data.version != magic_data.version)
266-
ereport(ERROR,
267-
(errmsg("incompatible library \"%s\": version mismatch",
268-
libname),
269-
errdetail("Server is version %d.%d, library is version %d.%d.",
270-
magic_data.version / 100,
271-
magic_data.version % 100,
272-
module_magic_data.version / 100,
273-
module_magic_data.version % 100)));
274-
ereport(ERROR,
275-
(errmsg("incompatible library \"%s\": magic block mismatch",
276-
libname)));
263+
/* issue suitable complaint */
264+
incompatible_module_error(libname, &module_magic_data);
277265
}
278266
}
279267
else
@@ -306,6 +294,93 @@ internal_load_library(const char *libname)
306294
return file_scanner->handle;
307295
}
308296

297+
/*
298+
* Report a suitable error for an incompatible magic block.
299+
*/
300+
static void
301+
incompatible_module_error(const char *libname,
302+
const Pg_magic_struct *module_magic_data)
303+
{
304+
StringInfoData details;
305+
306+
/*
307+
* If the version doesn't match, just report that, because the rest of the
308+
* block might not even have the fields we expect.
309+
*/
310+
if (magic_data.version != module_magic_data->version)
311+
ereport(ERROR,
312+
(errmsg("incompatible library \"%s\": version mismatch",
313+
libname),
314+
errdetail("Server is version %d.%d, library is version %d.%d.",
315+
magic_data.version / 100,
316+
magic_data.version % 100,
317+
module_magic_data->version / 100,
318+
module_magic_data->version % 100)));
319+
320+
/*
321+
* Otherwise, spell out which fields don't agree.
322+
*
323+
* XXX this code has to be adjusted any time the set of fields in a magic
324+
* block change!
325+
*/
326+
initStringInfo(&details);
327+
328+
if (module_magic_data->funcmaxargs != magic_data.funcmaxargs)
329+
{
330+
if (details.len)
331+
appendStringInfoChar(&details, '\n');
332+
appendStringInfo(&details,
333+
_("Server has FUNC_MAX_ARGS = %d, library has %d."),
334+
magic_data.funcmaxargs,
335+
module_magic_data->funcmaxargs);
336+
}
337+
if (module_magic_data->indexmaxkeys != magic_data.indexmaxkeys)
338+
{
339+
if (details.len)
340+
appendStringInfoChar(&details, '\n');
341+
appendStringInfo(&details,
342+
_("Server has INDEX_MAX_KEYS = %d, library has %d."),
343+
magic_data.indexmaxkeys,
344+
module_magic_data->indexmaxkeys);
345+
}
346+
if (module_magic_data->namedatalen != magic_data.namedatalen)
347+
{
348+
if (details.len)
349+
appendStringInfoChar(&details, '\n');
350+
appendStringInfo(&details,
351+
_("Server has NAMEDATALEN = %d, library has %d."),
352+
magic_data.namedatalen,
353+
module_magic_data->namedatalen);
354+
}
355+
if (module_magic_data->float4byval != magic_data.float4byval)
356+
{
357+
if (details.len)
358+
appendStringInfoChar(&details, '\n');
359+
appendStringInfo(&details,
360+
_("Server has FLOAT4PASSBYVAL = %s, library has %s."),
361+
magic_data.float4byval ? "true" : "false",
362+
module_magic_data->float4byval ? "true" : "false");
363+
}
364+
if (module_magic_data->float8byval != magic_data.float8byval)
365+
{
366+
if (details.len)
367+
appendStringInfoChar(&details, '\n');
368+
appendStringInfo(&details,
369+
_("Server has FLOAT8PASSBYVAL = %s, library has %s."),
370+
magic_data.float8byval ? "true" : "false",
371+
module_magic_data->float8byval ? "true" : "false");
372+
}
373+
374+
if (details.len == 0)
375+
appendStringInfo(&details,
376+
_("Magic block has unexpected length or padding difference."));
377+
378+
ereport(ERROR,
379+
(errmsg("incompatible library \"%s\": magic block mismatch",
380+
libname),
381+
errdetail("%s", details.data)));
382+
}
383+
309384
/*
310385
* Unload the specified dynamic-link library file, if it is loaded.
311386
*

src/include/fmgr.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
1212
* Portions Copyright (c) 1994, Regents of the University of California
1313
*
14-
* $PostgreSQL: pgsql/src/include/fmgr.h,v 1.59 2008/05/15 00:17:41 tgl Exp $
14+
* $PostgreSQL: pgsql/src/include/fmgr.h,v 1.60 2008/09/03 22:34:50 tgl Exp $
1515
*
1616
*-------------------------------------------------------------------------
1717
*/
@@ -357,6 +357,9 @@ extern int no_such_variable
357357
*
358358
* Note: we compare magic blocks with memcmp(), so there had better not be
359359
* any alignment pad bytes in them.
360+
*
361+
* Note: when changing the contents of magic blocks, be sure to adjust the
362+
* incompatible_module_error() function in dfmgr.c.
360363
*-------------------------------------------------------------------------
361364
*/
362365

0 commit comments

Comments
 (0)