From 1b304e8491771bcb2d0c2b05c931d82c32045a92 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Tue, 25 Mar 2008 19:31:40 +0000 Subject: [PATCH] Adjust DatumGetBool macro so that it isn't fooled by garbage in the Datum to the left of the actual bool value. While in most cases there won't be any, our support for old-style user-defined functions violates the C spec to the extent of calling functions that might return char or short through a function pointer declared to return "char *", which we then coerce to Datum. It is not surprising that the result might contain garbage high-order bits ... what is surprising is that we didn't see such cases long ago. Per report from Magnus. This is a back-patch of a change that was made in HEAD almost exactly a year ago. I had refrained from back-patching at the time, but now we find that this is *necessary* for contrib to work with gcc 4.3. --- src/include/postgres.h | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/src/include/postgres.h b/src/include/postgres.h index b82cd2fa8b..45b70f7367 100644 --- a/src/include/postgres.h +++ b/src/include/postgres.h @@ -10,7 +10,7 @@ * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1995, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/postgres.h,v 1.71 2005/04/14 01:38:21 tgl Exp $ + * $PostgreSQL: pgsql/src/include/postgres.h,v 1.71.2.1 2008/03/25 19:31:40 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -123,13 +123,18 @@ typedef struct varattrib * * sizeof(short) == 2 * - * If your machine meets these requirements, Datums should also be checked - * to see if the positioning is correct. + * When a type narrower than Datum is stored in a Datum, we place it in the + * low-order bits and are careful that the DatumGetXXX macro for it discards + * the unused high-order bits (as opposed to, say, assuming they are zero). + * This is needed to support old-style user-defined functions, since depending + * on architecture and compiler, the return value of a function returning char + * or short may contain garbage when called as if it returned Datum. */ typedef unsigned long Datum; /* XXX sizeof(long) >= sizeof(void *) */ #define SIZEOF_DATUM SIZEOF_UNSIGNED_LONG + typedef Datum *DatumPtr; #define GET_1_BYTE(datum) (((Datum) (datum)) & 0x000000ff) @@ -143,10 +148,11 @@ typedef Datum *DatumPtr; * DatumGetBool * Returns boolean value of a datum. * - * Note: any nonzero value will be considered TRUE. + * Note: any nonzero value will be considered TRUE, but we ignore bits to + * the left of the width of bool, per comment above. */ -#define DatumGetBool(X) ((bool) (((Datum) (X)) != 0)) +#define DatumGetBool(X) ((bool) (((bool) (X)) != 0)) /* * BoolGetDatum -- 2.40.0