|
8 | 8 | *
|
9 | 9 | *
|
10 | 10 | * 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 $ |
12 | 12 | *
|
13 | 13 | *-------------------------------------------------------------------------
|
14 | 14 | */
|
|
21 | 21 | #else
|
22 | 22 | #include "port/dynloader/win32.h"
|
23 | 23 | #endif
|
| 24 | +#include "lib/stringinfo.h" |
24 | 25 | #include "miscadmin.h"
|
25 | 26 | #include "utils/dynamic_loader.h"
|
26 | 27 | #include "utils/hsearch.h"
|
@@ -71,6 +72,8 @@ static DynamicFileList *file_tail = NULL;
|
71 | 72 | char *Dynamic_library_path;
|
72 | 73 |
|
73 | 74 | 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); |
74 | 77 | static void internal_unload_library(const char *libname);
|
75 | 78 | static bool file_exists(const char *name);
|
76 | 79 | static char *expand_dynamic_library_name(const char *name);
|
@@ -257,23 +260,8 @@ internal_load_library(const char *libname)
|
257 | 260 | pg_dlclose(file_scanner->handle);
|
258 | 261 | free((char *) file_scanner);
|
259 | 262 |
|
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); |
277 | 265 | }
|
278 | 266 | }
|
279 | 267 | else
|
@@ -306,6 +294,93 @@ internal_load_library(const char *libname)
|
306 | 294 | return file_scanner->handle;
|
307 | 295 | }
|
308 | 296 |
|
| 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 | + |
309 | 384 | /*
|
310 | 385 | * Unload the specified dynamic-link library file, if it is loaded.
|
311 | 386 | *
|
|
0 commit comments