OSDN Git Service

Allow float8, int8, and related datatypes to be passed by value on machines
authorTom Lane <tgl@sss.pgh.pa.us>
Mon, 21 Apr 2008 00:26:47 +0000 (00:26 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Mon, 21 Apr 2008 00:26:47 +0000 (00:26 +0000)
where Datum is 8 bytes wide.  Since this will break old-style C functions
(those still using version 0 calling convention) that have arguments or
results of these types, provide a configure option to disable it and retain
the old pass-by-reference behavior.  Likewise, provide a configure option
to disable the recently-committed float4 pass-by-value change.

Zoltan Boszormenyi, plus configurability stuff by me.

36 files changed:
configure
configure.in
contrib/btree_gist/btree_cash.c
contrib/btree_gist/btree_time.c
contrib/btree_gist/btree_ts.c
contrib/btree_gist/btree_utils_num.c
doc/src/sgml/installation.sgml
src/backend/access/transam/xlog.c
src/backend/bootstrap/bootstrap.c
src/backend/catalog/genbki.sh
src/backend/commands/analyze.c
src/backend/optimizer/plan/planagg.c
src/backend/parser/parse_node.c
src/backend/utils/adt/cash.c
src/backend/utils/adt/float.c
src/backend/utils/adt/int8.c
src/backend/utils/adt/numeric.c
src/backend/utils/adt/tsquery_gist.c
src/backend/utils/fmgr/README
src/backend/utils/fmgr/fmgr.c
src/backend/utils/init/flatfiles.c
src/bin/pg_controldata/pg_controldata.c
src/bin/pg_resetxlog/pg_resetxlog.c
src/include/c.h
src/include/catalog/catversion.h
src/include/catalog/pg_attribute.h
src/include/catalog/pg_control.h
src/include/catalog/pg_type.h
src/include/fmgr.h
src/include/pg_config.h.in
src/include/postgres.h
src/include/tsearch/ts_utils.h
src/include/utils/cash.h
src/test/regress/expected/type_sanity.out
src/test/regress/sql/type_sanity.sql
src/tools/msvc/Genbki.pm

index e9f6302..d4d20f0 100755 (executable)
--- a/configure
+++ b/configure
@@ -1362,6 +1362,8 @@ Optional Features:
   --enable-cassert        enable assertion checks (for debugging)
   --enable-thread-safety  make client libraries thread-safe
   --enable-thread-safety-force  force thread-safety despite thread test failure
+  --disable-float4-byval  disable float4 passed by value
+  --disable-float8-byval  disable float8 passed by value
   --disable-largefile     omit support for large files
 
 Optional Packages:
@@ -20838,6 +20840,137 @@ _ACEOF
 
 
 
+# Decide whether float4 is passed by value: user-selectable, enabled by default
+{ echo "$as_me:$LINENO: checking whether to build with float4 passed by value" >&5
+echo $ECHO_N "checking whether to build with float4 passed by value... $ECHO_C" >&6; }
+
+pgac_args="$pgac_args enable_float4_byval"
+
+# Check whether --enable-float4-byval was given.
+if test "${enable_float4_byval+set}" = set; then
+  enableval=$enable_float4_byval;
+  case $enableval in
+    yes)
+
+cat >>confdefs.h <<\_ACEOF
+#define USE_FLOAT4_BYVAL 1
+_ACEOF
+
+               float4passbyval=true
+      ;;
+    no)
+      float4passbyval=false
+      ;;
+    *)
+      { { echo "$as_me:$LINENO: error: no argument expected for --enable-float4-byval option" >&5
+echo "$as_me: error: no argument expected for --enable-float4-byval option" >&2;}
+   { (exit 1); exit 1; }; }
+      ;;
+  esac
+
+else
+  enable_float4_byval=yes
+
+cat >>confdefs.h <<\_ACEOF
+#define USE_FLOAT4_BYVAL 1
+_ACEOF
+
+               float4passbyval=true
+fi
+
+
+{ echo "$as_me:$LINENO: result: $enable_float4_byval" >&5
+echo "${ECHO_T}$enable_float4_byval" >&6; }
+
+cat >>confdefs.h <<_ACEOF
+#define FLOAT4PASSBYVAL $float4passbyval
+_ACEOF
+
+
+# Decide whether float8 is passed by value.
+# Note: this setting also controls int8 and related types such as timestamp.
+# If sizeof(Datum) >= 8, this is user-selectable, enabled by default.
+# If not, trying to select it is an error.
+{ echo "$as_me:$LINENO: checking whether to build with float8 passed by value" >&5
+echo $ECHO_N "checking whether to build with float8 passed by value... $ECHO_C" >&6; }
+if test $ac_cv_sizeof_unsigned_long -ge 8 ; then
+
+pgac_args="$pgac_args enable_float8_byval"
+
+# Check whether --enable-float8-byval was given.
+if test "${enable_float8_byval+set}" = set; then
+  enableval=$enable_float8_byval;
+  case $enableval in
+    yes)
+      :
+      ;;
+    no)
+      :
+      ;;
+    *)
+      { { echo "$as_me:$LINENO: error: no argument expected for --enable-float8-byval option" >&5
+echo "$as_me: error: no argument expected for --enable-float8-byval option" >&2;}
+   { (exit 1); exit 1; }; }
+      ;;
+  esac
+
+else
+  enable_float8_byval=yes
+
+fi
+
+
+else
+
+pgac_args="$pgac_args enable_float8_byval"
+
+# Check whether --enable-float8-byval was given.
+if test "${enable_float8_byval+set}" = set; then
+  enableval=$enable_float8_byval;
+  case $enableval in
+    yes)
+      :
+      ;;
+    no)
+      :
+      ;;
+    *)
+      { { echo "$as_me:$LINENO: error: no argument expected for --enable-float8-byval option" >&5
+echo "$as_me: error: no argument expected for --enable-float8-byval option" >&2;}
+   { (exit 1); exit 1; }; }
+      ;;
+  esac
+
+else
+  enable_float8_byval=no
+
+fi
+
+
+  if test "$enable_float8_byval" = yes ; then
+    { { echo "$as_me:$LINENO: error: --enable-float8-byval is not supported on 32-bit platforms." >&5
+echo "$as_me: error: --enable-float8-byval is not supported on 32-bit platforms." >&2;}
+   { (exit 1); exit 1; }; }
+  fi
+fi
+if test "$enable_float8_byval" = yes ; then
+
+cat >>confdefs.h <<\_ACEOF
+#define USE_FLOAT8_BYVAL 1
+_ACEOF
+
+  float8passbyval=true
+else
+  float8passbyval=false
+fi
+{ echo "$as_me:$LINENO: result: $enable_float8_byval" >&5
+echo "${ECHO_T}$enable_float8_byval" >&6; }
+
+cat >>confdefs.h <<_ACEOF
+#define FLOAT8PASSBYVAL $float8passbyval
+_ACEOF
+
+
 # Determine memory alignment requirements for the basic C data types.
 
 { echo "$as_me:$LINENO: checking for short" >&5
index 56bdfd9..dd83247 100644 (file)
@@ -1,5 +1,5 @@
 dnl Process this file with autoconf to produce a configure script.
-dnl $PostgreSQL: pgsql/configure.in,v 1.555 2008/03/30 04:08:14 neilc Exp $
+dnl $PostgreSQL: pgsql/configure.in,v 1.556 2008/04/21 00:26:44 tgl Exp $
 dnl
 dnl Developers, please strive to achieve this order:
 dnl
@@ -1368,6 +1368,39 @@ AC_CHECK_SIZEOF([unsigned long])
 # And one for the size of size_t (enables tweaks for > 32bit address space)
 AC_CHECK_SIZEOF([size_t])
 
+# Decide whether float4 is passed by value: user-selectable, enabled by default
+AC_MSG_CHECKING([whether to build with float4 passed by value])   
+PGAC_ARG_BOOL(enable, float4-byval, yes, [  --disable-float4-byval  disable float4 passed by value],
+              [AC_DEFINE([USE_FLOAT4_BYVAL], 1,
+                         [Define to 1 if you want float4 values to be passed by value. (--enable-float4-byval)])
+               float4passbyval=true],
+              [float4passbyval=false])
+AC_MSG_RESULT([$enable_float4_byval])
+AC_DEFINE_UNQUOTED([FLOAT4PASSBYVAL], [$float4passbyval], [float4 values are passed by value if 'true', by reference if 'false'])
+
+# Decide whether float8 is passed by value.
+# Note: this setting also controls int8 and related types such as timestamp.
+# If sizeof(Datum) >= 8, this is user-selectable, enabled by default.
+# If not, trying to select it is an error.
+AC_MSG_CHECKING([whether to build with float8 passed by value])   
+if test $ac_cv_sizeof_unsigned_long -ge 8 ; then
+  PGAC_ARG_BOOL(enable, float8-byval, yes, [  --disable-float8-byval  disable float8 passed by value])
+else
+  PGAC_ARG_BOOL(enable, float8-byval, no, [  --disable-float8-byval  disable float8 passed by value])
+  if test "$enable_float8_byval" = yes ; then
+    AC_MSG_ERROR([--enable-float8-byval is not supported on 32-bit platforms.])
+  fi
+fi
+if test "$enable_float8_byval" = yes ; then
+  AC_DEFINE([USE_FLOAT8_BYVAL], 1,
+            [Define to 1 if you want float8, int8, etc values to be passed by value. (--enable-float8-byval)])
+  float8passbyval=true
+else
+  float8passbyval=false
+fi
+AC_MSG_RESULT([$enable_float8_byval])
+AC_DEFINE_UNQUOTED([FLOAT8PASSBYVAL], [$float8passbyval], [float8, int8, and related values are passed by value if 'true', by reference if 'false'])
+
 # Determine memory alignment requirements for the basic C data types.
 
 AC_CHECK_ALIGNOF(short)
index eb61875..17edd02 100644 (file)
@@ -96,7 +96,7 @@ Datum
 gbt_cash_consistent(PG_FUNCTION_ARGS)
 {
        GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
-       Cash            query = (*((Cash *) PG_GETARG_POINTER(1)));
+       Cash            query = PG_GETARG_CASH(1);
        StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
        /* Oid          subtype = PG_GETARG_OID(3); */
        bool       *recheck = (bool *) PG_GETARG_POINTER(4);
index 6c1ec80..0d2c2cf 100644 (file)
@@ -31,46 +31,66 @@ Datum               gbt_time_penalty(PG_FUNCTION_ARGS);
 Datum          gbt_time_same(PG_FUNCTION_ARGS);
 
 
-#define P_TimeADTGetDatum(x)   PointerGetDatum( &(x) )
+#ifdef USE_FLOAT8_BYVAL
+#define TimeADTGetDatumFast(X) TimeADTGetDatum(X)
+#else
+#define TimeADTGetDatumFast(X) PointerGetDatum(&(X))
+#endif
+
 
 static bool
 gbt_timegt(const void *a, const void *b)
 {
-       return DatumGetBool(
-                DirectFunctionCall2(time_gt, PointerGetDatum(a), PointerGetDatum(b))
-               );
+       const TimeADT *aa = (const TimeADT *) a;
+       const TimeADT *bb = (const TimeADT *) b;
+
+       return DatumGetBool(DirectFunctionCall2(time_gt,
+                                                                                       TimeADTGetDatumFast(*aa),
+                                                                                       TimeADTGetDatumFast(*bb)));
 }
 
 static bool
 gbt_timege(const void *a, const void *b)
 {
-       return DatumGetBool(
-                DirectFunctionCall2(time_ge, PointerGetDatum(a), PointerGetDatum(b))
-               );
+       const TimeADT *aa = (const TimeADT *) a;
+       const TimeADT *bb = (const TimeADT *) b;
+
+       return DatumGetBool(DirectFunctionCall2(time_ge,
+                                                                                       TimeADTGetDatumFast(*aa),
+                                                                                       TimeADTGetDatumFast(*bb)));
 }
 
 static bool
 gbt_timeeq(const void *a, const void *b)
 {
-       return DatumGetBool(
-                DirectFunctionCall2(time_eq, PointerGetDatum(a), PointerGetDatum(b))
-               );
+       const TimeADT *aa = (const TimeADT *) a;
+       const TimeADT *bb = (const TimeADT *) b;
+
+       return DatumGetBool(DirectFunctionCall2(time_eq,
+                                                                                       TimeADTGetDatumFast(*aa),
+                                                                                       TimeADTGetDatumFast(*bb)));
 }
 
 static bool
 gbt_timele(const void *a, const void *b)
 {
-       return DatumGetBool(
-                DirectFunctionCall2(time_le, PointerGetDatum(a), PointerGetDatum(b))
-               );
+       const TimeADT *aa = (const TimeADT *) a;
+       const TimeADT *bb = (const TimeADT *) b;
+
+       return DatumGetBool(DirectFunctionCall2(time_le,
+                                                                                       TimeADTGetDatumFast(*aa),
+                                                                                       TimeADTGetDatumFast(*bb)));
 }
 
 static bool
 gbt_timelt(const void *a, const void *b)
 {
-       return DatumGetBool(
-                DirectFunctionCall2(time_lt, PointerGetDatum(a), PointerGetDatum(b))
-               );
+       const TimeADT *aa = (const TimeADT *) a;
+       const TimeADT *bb = (const TimeADT *) b;
+
+       return DatumGetBool(DirectFunctionCall2(time_lt,
+                                                                                       TimeADTGetDatumFast(*aa),
+                                                                                       TimeADTGetDatumFast(*bb)));
 }
 
 
@@ -221,15 +241,15 @@ gbt_time_penalty(PG_FUNCTION_ARGS)
 
        intr = DatumGetIntervalP(DirectFunctionCall2(
                                                                                                 time_mi_time,
-                                                                                 P_TimeADTGetDatum(newentry->upper),
-                                                                          P_TimeADTGetDatum(origentry->upper)));
+                                                                                 TimeADTGetDatumFast(newentry->upper),
+                                                                          TimeADTGetDatumFast(origentry->upper)));
        res = INTERVAL_TO_SEC(intr);
        res = Max(res, 0);
 
        intr = DatumGetIntervalP(DirectFunctionCall2(
                                                                                                 time_mi_time,
-                                                                                P_TimeADTGetDatum(origentry->lower),
-                                                                               P_TimeADTGetDatum(newentry->lower)));
+                                                                                TimeADTGetDatumFast(origentry->lower),
+                                                                               TimeADTGetDatumFast(newentry->lower)));
        res2 = INTERVAL_TO_SEC(intr);
        res2 = Max(res2, 0);
 
@@ -241,8 +261,8 @@ gbt_time_penalty(PG_FUNCTION_ARGS)
        {
                intr = DatumGetIntervalP(DirectFunctionCall2(
                                                                                                         time_mi_time,
-                                                                                P_TimeADTGetDatum(origentry->upper),
-                                                                          P_TimeADTGetDatum(origentry->lower)));
+                                                                                TimeADTGetDatumFast(origentry->upper),
+                                                                          TimeADTGetDatumFast(origentry->lower)));
                *result += FLT_MIN;
                *result += (float) (res / (res + INTERVAL_TO_SEC(intr)));
                *result *= (FLT_MAX / (((GISTENTRY *) PG_GETARG_POINTER(0))->rel->rd_att->natts + 1));
index 606a986..3245124 100644 (file)
@@ -1,9 +1,7 @@
 #include "btree_gist.h"
 #include "btree_utils_num.h"
-
 #include "utils/datetime.h"
 
-
 typedef struct
 {
        Timestamp       lower;
@@ -32,46 +30,66 @@ Datum               gbt_ts_penalty(PG_FUNCTION_ARGS);
 Datum          gbt_ts_same(PG_FUNCTION_ARGS);
 
 
-#define P_TimestampGetDatum(x) PointerGetDatum( &(x) )
+#ifdef USE_FLOAT8_BYVAL
+#define TimestampGetDatumFast(X) TimestampGetDatum(X)
+#else
+#define TimestampGetDatumFast(X) PointerGetDatum(&(X))
+#endif
+
 
 static bool
 gbt_tsgt(const void *a, const void *b)
 {
-       return DatumGetBool(
-       DirectFunctionCall2(timestamp_gt, PointerGetDatum(a), PointerGetDatum(b))
-               );
+       const Timestamp *aa = (const Timestamp *) a;
+       const Timestamp *bb = (const Timestamp *) b;
+
+       return DatumGetBool(DirectFunctionCall2(timestamp_gt,
+                                                                                       TimestampGetDatumFast(*aa),
+                                                                                       TimestampGetDatumFast(*bb)));
 }
 
 static bool
 gbt_tsge(const void *a, const void *b)
 {
-       return DatumGetBool(
-       DirectFunctionCall2(timestamp_ge, PointerGetDatum(a), PointerGetDatum(b))
-               );
+       const Timestamp *aa = (const Timestamp *) a;
+       const Timestamp *bb = (const Timestamp *) b;
+
+       return DatumGetBool(DirectFunctionCall2(timestamp_ge,
+                                                                                       TimestampGetDatumFast(*aa),
+                                                                                       TimestampGetDatumFast(*bb)));
 }
 
 static bool
 gbt_tseq(const void *a, const void *b)
 {
-       return DatumGetBool(
-       DirectFunctionCall2(timestamp_eq, PointerGetDatum(a), PointerGetDatum(b))
-               );
+       const Timestamp *aa = (const Timestamp *) a;
+       const Timestamp *bb = (const Timestamp *) b;
+
+       return DatumGetBool(DirectFunctionCall2(timestamp_eq,
+                                                                                       TimestampGetDatumFast(*aa),
+                                                                                       TimestampGetDatumFast(*bb)));
 }
 
 static bool
 gbt_tsle(const void *a, const void *b)
 {
-       return DatumGetBool(
-       DirectFunctionCall2(timestamp_le, PointerGetDatum(a), PointerGetDatum(b))
-               );
+       const Timestamp *aa = (const Timestamp *) a;
+       const Timestamp *bb = (const Timestamp *) b;
+
+       return DatumGetBool(DirectFunctionCall2(timestamp_le,
+                                                                                       TimestampGetDatumFast(*aa),
+                                                                                       TimestampGetDatumFast(*bb)));
 }
 
 static bool
 gbt_tslt(const void *a, const void *b)
 {
-       return DatumGetBool(
-       DirectFunctionCall2(timestamp_lt, PointerGetDatum(a), PointerGetDatum(b))
-               );
+       const Timestamp *aa = (const Timestamp *) a;
+       const Timestamp *bb = (const Timestamp *) b;
+
+       return DatumGetBool(DirectFunctionCall2(timestamp_lt,
+                                                                                       TimestampGetDatumFast(*aa),
+                                                                                       TimestampGetDatumFast(*bb)));
 }
 
 
@@ -104,32 +122,30 @@ static const gbtree_ninfo tinfo =
  **************************************************/
 
 
-
-static Timestamp *
-tstz_to_ts_gmt(Timestamp *gmt, TimestampTz *ts)
+static Timestamp
+tstz_to_ts_gmt(TimestampTz ts)
 {
+       Timestamp       gmt;
        int                     val,
                                tz;
 
-       *gmt = *ts;
+       gmt = ts;
        DecodeSpecial(0, "gmt", &val);
 
-       if (*ts < DT_NOEND && *ts > DT_NOBEGIN)
+       if (ts < DT_NOEND && ts > DT_NOBEGIN)
        {
                tz = val * 60;
 
 #ifdef HAVE_INT64_TIMESTAMP
-               *gmt -= (tz * INT64CONST(1000000));
+               gmt -= (tz * INT64CONST(1000000));
 #else
-               *gmt -= tz;
+               gmt -= tz;
 #endif
        }
        return gmt;
 }
 
 
-
-
 Datum
 gbt_ts_compress(PG_FUNCTION_ARGS)
 {
@@ -149,11 +165,10 @@ gbt_tstz_compress(PG_FUNCTION_ARGS)
        if (entry->leafkey)
        {
                tsKEY      *r = (tsKEY *) palloc(sizeof(tsKEY));
-
-               TimestampTz ts = *(TimestampTz *) DatumGetPointer(entry->key);
+               TimestampTz ts = DatumGetTimestampTz(entry->key);
                Timestamp       gmt;
 
-               tstz_to_ts_gmt(&gmt, &ts);
+               gmt = tstz_to_ts_gmt(ts);
 
                retval = palloc(sizeof(GISTENTRY));
                r->lower = r->upper = gmt;
@@ -172,7 +187,7 @@ Datum
 gbt_ts_consistent(PG_FUNCTION_ARGS)
 {
        GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
-       Timestamp  *query = (Timestamp *) PG_GETARG_POINTER(1);
+       Timestamp       query = PG_GETARG_TIMESTAMP(1);
        StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
        /* Oid          subtype = PG_GETARG_OID(3); */
        bool       *recheck = (bool *) PG_GETARG_POINTER(4);
@@ -186,7 +201,7 @@ gbt_ts_consistent(PG_FUNCTION_ARGS)
        key.upper = (GBT_NUMKEY *) & kkk->upper;
 
        PG_RETURN_BOOL(
-                                  gbt_num_consistent(&key, (void *) query, &strategy, GIST_LEAF(entry), &tinfo)
+                                  gbt_num_consistent(&key, (void *) &query, &strategy, GIST_LEAF(entry), &tinfo)
                );
 }
 
@@ -194,7 +209,7 @@ Datum
 gbt_tstz_consistent(PG_FUNCTION_ARGS)
 {
        GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
-       TimestampTz *query = (Timestamp *) PG_GETARG_POINTER(1);
+       TimestampTz     query = PG_GETARG_TIMESTAMPTZ(1);
        StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
        /* Oid          subtype = PG_GETARG_OID(3); */
        bool       *recheck = (bool *) PG_GETARG_POINTER(4);
@@ -207,7 +222,7 @@ gbt_tstz_consistent(PG_FUNCTION_ARGS)
 
        key.lower = (GBT_NUMKEY *) & kkk[0];
        key.upper = (GBT_NUMKEY *) & kkk[MAXALIGN(tinfo.size)];
-       tstz_to_ts_gmt(&qqq, query);
+       qqq = tstz_to_ts_gmt(query);
 
        PG_RETURN_BOOL(
                                   gbt_num_consistent(&key, (void *) &qqq, &strategy, GIST_LEAF(entry), &tinfo)
index c7b41f1..5e22719 100644 (file)
@@ -1,20 +1,25 @@
 #include "btree_gist.h"
 #include "btree_utils_num.h"
+#include "utils/cash.h"
 #include "utils/date.h"
 
+
 GISTENTRY *
 gbt_num_compress(GISTENTRY *retval, GISTENTRY *entry, const gbtree_ninfo * tinfo)
 {
-
        if (entry->leafkey)
        {
-
                union
                {
                        int16           i2;
                        int32           i4;
+                       int64           i8;
                        float4          f4;
+                       float8          f8;
                        DateADT         dt;
+                       TimeADT         tm;
+                       Timestamp       ts;
+                       Cash            ch;
                }                       v;
 
                GBT_NUMKEY *r = (GBT_NUMKEY *) palloc0(2 * tinfo->size);
@@ -30,17 +35,37 @@ gbt_num_compress(GISTENTRY *retval, GISTENTRY *entry, const gbtree_ninfo * tinfo
                                v.i4 = DatumGetInt32(entry->key);
                                leaf = &v.i4;
                                break;
+                       case gbt_t_int8:
+                               v.i8 = DatumGetInt64(entry->key);
+                               leaf = &v.i8;
+                               break;
                        case gbt_t_oid:
                                v.i4 = DatumGetObjectId(entry->key);
                                leaf = &v.i4;
                                break;
+                       case gbt_t_float4:
+                               v.f4 = DatumGetFloat4(entry->key);
+                               leaf = &v.f4;
+                               break;
+                       case gbt_t_float8:
+                               v.f8 = DatumGetFloat8(entry->key);
+                               leaf = &v.f8;
+                               break;
                        case gbt_t_date:
                                v.dt = DatumGetDateADT(entry->key);
                                leaf = &v.dt;
                                break;
-                       case gbt_t_float4:
-                               v.f4 = DatumGetFloat4(entry->key);
-                               leaf = &v.f4;
+                       case gbt_t_time:
+                               v.tm = DatumGetTimeADT(entry->key);
+                               leaf = &v.tm;
+                               break;
+                       case gbt_t_ts:
+                               v.ts = DatumGetTimestamp(entry->key);
+                               leaf = &v.ts;
+                               break;
+                       case gbt_t_cash:
+                               v.ch = DatumGetCash(entry->key);
+                               leaf = &v.ch;
                                break;
                        default:
                                leaf = DatumGetPointer(entry->key);
index e0de70e..0fad43d 100644 (file)
@@ -1,4 +1,4 @@
-<!-- $PostgreSQL: pgsql/doc/src/sgml/installation.sgml,v 1.306 2008/03/30 04:08:15 neilc Exp $ -->
+<!-- $PostgreSQL: pgsql/doc/src/sgml/installation.sgml,v 1.307 2008/04/21 00:26:44 tgl Exp $ -->
 
 <chapter id="installation">
  <title><![%standalone-include[<productname>PostgreSQL</>]]>
@@ -1033,6 +1033,40 @@ su - postgres
       </varlistentry>
 
       <varlistentry>
+       <term><option>--disable-float4-byval</option></term>
+       <listitem>
+        <para>
+         Disable passing float4 values <quote>by value</>, causing them
+         to be passed <quote>by reference</> instead.  This option costs
+         performance, but may be needed for compatibility with old
+         user-defined functions that are written in C and use the
+         <quote>version 0</> calling convention.  A better long-term
+         solution is to update any such functions to use the
+         <quote>version 1</> calling convention.
+        </para>
+       </listitem>
+      </varlistentry>
+
+      <varlistentry>
+       <term><option>--disable-float8-byval</option></term>
+       <listitem>
+        <para>
+         Disable passing float8 values <quote>by value</>, causing them
+         to be passed <quote>by reference</> instead.  This option costs
+         performance, but may be needed for compatibility with old
+         user-defined functions that are written in C and use the
+         <quote>version 0</> calling convention.  A better long-term
+         solution is to update any such functions to use the
+         <quote>version 1</> calling convention.
+         Note that this option affects not only float8, but also int8 and some
+         related types such as timestamp.
+         On 32-bit platforms, <option>--disable-float8-byval</> is the default
+         and it is not allowed to select <option>--enable-float8-byval</>.
+        </para>
+       </listitem>
+      </varlistentry>
+
+      <varlistentry>
        <term><option>--disable-segmented-files</option></term>
        <listitem>
         <para>
index bb8f3d4..33c912e 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/backend/access/transam/xlog.c,v 1.297 2008/04/16 23:59:40 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/access/transam/xlog.c,v 1.298 2008/04/21 00:26:44 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -3791,10 +3791,12 @@ WriteControlFile(void)
        ControlFile->toast_max_chunk_size = TOAST_MAX_CHUNK_SIZE;
 
 #ifdef HAVE_INT64_TIMESTAMP
-       ControlFile->enableIntTimes = TRUE;
+       ControlFile->enableIntTimes = true;
 #else
-       ControlFile->enableIntTimes = FALSE;
+       ControlFile->enableIntTimes = false;
 #endif
+       ControlFile->float4ByVal = FLOAT4PASSBYVAL;
+       ControlFile->float8ByVal = FLOAT8PASSBYVAL;
 
        ControlFile->localeBuflen = LOCALE_NAME_BUFLEN;
        localeptr = setlocale(LC_COLLATE, NULL);
@@ -4000,14 +4002,14 @@ ReadControlFile(void)
                                 errhint("It looks like you need to recompile or initdb.")));
 
 #ifdef HAVE_INT64_TIMESTAMP
-       if (ControlFile->enableIntTimes != TRUE)
+       if (ControlFile->enableIntTimes != true)
                ereport(FATAL,
                                (errmsg("database files are incompatible with server"),
                                 errdetail("The database cluster was initialized without HAVE_INT64_TIMESTAMP"
                                  " but the server was compiled with HAVE_INT64_TIMESTAMP."),
                                 errhint("It looks like you need to recompile or initdb.")));
 #else
-       if (ControlFile->enableIntTimes != FALSE)
+       if (ControlFile->enableIntTimes != false)
                ereport(FATAL,
                                (errmsg("database files are incompatible with server"),
                                 errdetail("The database cluster was initialized with HAVE_INT64_TIMESTAMP"
@@ -4015,6 +4017,38 @@ ReadControlFile(void)
                                 errhint("It looks like you need to recompile or initdb.")));
 #endif
 
+#ifdef USE_FLOAT4_BYVAL
+       if (ControlFile->float4ByVal != true)
+               ereport(FATAL,
+                               (errmsg("database files are incompatible with server"),
+                                errdetail("The database cluster was initialized without USE_FLOAT4_BYVAL"
+                                                  " but the server was compiled with USE_FLOAT4_BYVAL."),
+                                errhint("It looks like you need to recompile or initdb.")));
+#else
+       if (ControlFile->float4ByVal != false)
+               ereport(FATAL,
+                               (errmsg("database files are incompatible with server"),
+                                errdetail("The database cluster was initialized with USE_FLOAT4_BYVAL"
+                                                  " but the server was compiled without USE_FLOAT4_BYVAL."),
+                                errhint("It looks like you need to recompile or initdb.")));
+#endif
+
+#ifdef USE_FLOAT8_BYVAL
+       if (ControlFile->float8ByVal != true)
+               ereport(FATAL,
+                               (errmsg("database files are incompatible with server"),
+                                errdetail("The database cluster was initialized without USE_FLOAT8_BYVAL"
+                                                  " but the server was compiled with USE_FLOAT8_BYVAL."),
+                                errhint("It looks like you need to recompile or initdb.")));
+#else
+       if (ControlFile->float8ByVal != false)
+               ereport(FATAL,
+                               (errmsg("database files are incompatible with server"),
+                                errdetail("The database cluster was initialized with USE_FLOAT8_BYVAL"
+                                                  " but the server was compiled without USE_FLOAT8_BYVAL."),
+                                errhint("It looks like you need to recompile or initdb.")));
+#endif
+
        if (ControlFile->localeBuflen != LOCALE_NAME_BUFLEN)
                ereport(FATAL,
                                (errmsg("database files are incompatible with server"),
index a5c013b..48eb355 100644 (file)
@@ -8,7 +8,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/bootstrap/bootstrap.c,v 1.241 2008/04/18 18:43:09 alvherre Exp $
+ *       $PostgreSQL: pgsql/src/backend/bootstrap/bootstrap.c,v 1.242 2008/04/21 00:26:45 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -122,7 +122,7 @@ static const struct typinfo TypInfo[] = {
        F_INT2IN, F_INT2OUT},
        {"int4", INT4OID, 0, 4, true, 'i', 'p',
        F_INT4IN, F_INT4OUT},
-       {"float4", FLOAT4OID, 0, 4, true, 'i', 'p',
+       {"float4", FLOAT4OID, 0, 4, FLOAT4PASSBYVAL, 'i', 'p',
        F_FLOAT4IN, F_FLOAT4OUT},
        {"name", NAMEOID, CHAROID, NAMEDATALEN, false, 'i', 'p',
        F_NAMEIN, F_NAMEOUT},
index 0453771..a07af45 100644 (file)
@@ -11,7 +11,7 @@
 #
 #
 # IDENTIFICATION
-#    $PostgreSQL: pgsql/src/backend/catalog/genbki.sh,v 1.43 2008/01/01 19:45:48 momjian Exp $
+#    $PostgreSQL: pgsql/src/backend/catalog/genbki.sh,v 1.44 2008/04/21 00:26:45 tgl Exp $
 #
 # NOTES
 #    non-essential whitespace is removed from the generated file.
@@ -114,6 +114,15 @@ for dir in $INCLUDE_DIRS; do
     fi
 done
 
+# Get FLOAT4PASSBYVAL and FLOAT8PASSBYVAL from pg_config.h
+for dir in $INCLUDE_DIRS; do
+    if [ -f "$dir/pg_config.h" ]; then
+        FLOAT4PASSBYVAL=`grep '^#define[       ]*FLOAT4PASSBYVAL' $dir/pg_config.h | $AWK '{ print $3 }'`
+        FLOAT8PASSBYVAL=`grep '^#define[       ]*FLOAT8PASSBYVAL' $dir/pg_config.h | $AWK '{ print $3 }'`
+        break
+    fi
+done
+
 # Get BOOTSTRAP_SUPERUSERID from catalog/pg_authid.h
 for dir in $INCLUDE_DIRS; do
     if [ -f "$dir/catalog/pg_authid.h" ]; then
@@ -164,6 +173,8 @@ sed -e "s/;[        ]*$//g" \
     -e "s/(TransactionId/(xid/g" \
     -e "s/PGUID/$BOOTSTRAP_SUPERUSERID/g" \
     -e "s/NAMEDATALEN/$NAMEDATALEN/g" \
+    -e "s/FLOAT4PASSBYVAL/$FLOAT4PASSBYVAL/g" \
+    -e "s/FLOAT8PASSBYVAL/$FLOAT8PASSBYVAL/g" \
     -e "s/PGNSP/$PG_CATALOG_NAMESPACE/g" \
 | $AWK '
 # ----------------
index 0363b21..a120463 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/commands/analyze.c,v 1.118 2008/04/18 18:43:09 alvherre Exp $
+ *       $PostgreSQL: pgsql/src/backend/commands/analyze.c,v 1.119 2008/04/21 00:26:45 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1304,7 +1304,7 @@ update_attstats(Oid relid, int natts, VacAttrStats **vacattrstats)
                                /* XXX knows more than it should about type float4: */
                                arry = construct_array(numdatums, nnum,
                                                                           FLOAT4OID,
-                                                                          sizeof(float4), true, 'i');
+                                                                          sizeof(float4), FLOAT4PASSBYVAL, 'i');
                                values[i++] = PointerGetDatum(arry);    /* stanumbersN */
                        }
                        else
index 5bb9211..ef13f16 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/optimizer/plan/planagg.c,v 1.37 2008/03/31 16:59:26 tgl Exp $
+ *       $PostgreSQL: pgsql/src/backend/optimizer/plan/planagg.c,v 1.38 2008/04/21 00:26:45 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -514,8 +514,8 @@ make_agg_subplan(PlannerInfo *root, MinMaxAggInfo *info)
        /* set up LIMIT 1 */
        subparse->limitOffset = NULL;
        subparse->limitCount = (Node *) makeConst(INT8OID, -1, sizeof(int64),
-                                                                                         Int64GetDatum(1),
-                                                                                         false, false /* not by val */ );
+                                                                                         Int64GetDatum(1), false,
+                                                                                         FLOAT8PASSBYVAL);
 
        /*
         * Generate the plan for the subquery.  We already have a Path for the
index 8c96813..c139967 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/parser/parse_node.c,v 1.99 2008/01/01 19:45:51 momjian Exp $
+ *       $PostgreSQL: pgsql/src/backend/parser/parse_node.c,v 1.100 2008/04/21 00:26:45 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -375,7 +375,7 @@ make_const(Value *value)
 
                                        typeid = INT8OID;
                                        typelen = sizeof(int64);
-                                       typebyval = false;      /* XXX might change someday */
+                                       typebyval = FLOAT8PASSBYVAL;    /* int8 and float8 alike */
                                }
                        }
                        else
index 84e8c74..befa27f 100644 (file)
@@ -13,7 +13,7 @@
  * this version handles 64 bit numbers and so can hold values up to
  * $92,233,720,368,547,758.07.
  *
- * $PostgreSQL: pgsql/src/backend/utils/adt/cash.c,v 1.78 2008/03/25 22:42:43 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/adt/cash.c,v 1.79 2008/04/21 00:26:45 tgl Exp $
  */
 
 #include "postgres.h"
 #define LAST_PAREN             (TERMINATOR - 1)
 #define LAST_DIGIT             (LAST_PAREN - 1)
 
-/*
- * Cash is a pass-by-ref SQL type, so we must pass and return pointers.
- * These macros and support routine hide the pass-by-refness.
- */
-#define PG_GETARG_CASH(n)  (* ((Cash *) PG_GETARG_POINTER(n)))
-#define PG_RETURN_CASH(x)  return CashGetDatum(x)
-
-
 
 /*************************************************************************
  * Private routines
@@ -99,15 +91,6 @@ num_word(Cash value)
        return buf;
 }      /* num_word() */
 
-static Datum
-CashGetDatum(Cash value)
-{
-       Cash       *result = (Cash *) palloc(sizeof(Cash));
-
-       *result = value;
-       return PointerGetDatum(result);
-}
-
 
 /* cash_in()
  * Convert a string to a cash data type.
index 2f1e262..2ee2455 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/utils/adt/float.c,v 1.154 2008/03/10 12:39:22 tgl Exp $
+ *       $PostgreSQL: pgsql/src/backend/utils/adt/float.c,v 1.155 2008/04/21 00:26:45 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1780,7 +1780,7 @@ float8_accum(PG_FUNCTION_ARGS)
 
                result = construct_array(transdatums, 3,
                                                                 FLOAT8OID,
-                                                        sizeof(float8), false /* float8 byval */ , 'd');
+                                                                sizeof(float8), FLOAT8PASSBYVAL, 'd');
 
                PG_RETURN_ARRAYTYPE_P(result);
        }
@@ -1833,7 +1833,7 @@ float4_accum(PG_FUNCTION_ARGS)
 
                result = construct_array(transdatums, 3,
                                                                 FLOAT8OID,
-                                                        sizeof(float8), false /* float8 byval */ , 'd');
+                                                                sizeof(float8), FLOAT8PASSBYVAL, 'd');
 
                PG_RETURN_ARRAYTYPE_P(result);
        }
@@ -2056,8 +2056,7 @@ float8_regr_accum(PG_FUNCTION_ARGS)
 
                result = construct_array(transdatums, 6,
                                                                 FLOAT8OID,
-                                                                sizeof(float8),
-                                                                false /* float8 byval */ , 'd');
+                                                                sizeof(float8), FLOAT8PASSBYVAL, 'd');
 
                PG_RETURN_ARRAYTYPE_P(result);
        }
index 3391769..6f3f9e2 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/utils/adt/int8.c,v 1.68 2008/01/01 19:45:52 momjian Exp $
+ *       $PostgreSQL: pgsql/src/backend/utils/adt/int8.c,v 1.69 2008/04/21 00:26:45 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -657,17 +657,16 @@ int8mod(PG_FUNCTION_ARGS)
 Datum
 int8inc(PG_FUNCTION_ARGS)
 {
+       /*
+        * When int8 is pass-by-reference, we provide this special case to avoid
+        * palloc overhead for COUNT(): when called from nodeAgg, we know that the
+        * argument is modifiable local storage, so just update it in-place.
+        * (If int8 is pass-by-value, then of course this is useless as well
+        * as incorrect, so just ifdef it out.)
+        */
+#ifndef USE_FLOAT8_BYVAL               /* controls int8 too */
        if (fcinfo->context && IsA(fcinfo->context, AggState))
        {
-               /*
-                * Special case to avoid palloc overhead for COUNT(): when called from
-                * nodeAgg, we know that the argument is modifiable local storage, so
-                * just update it in-place.
-                *
-                * Note: this assumes int8 is a pass-by-ref type; if we ever support
-                * pass-by-val int8, this should be ifdef'd out when int8 is
-                * pass-by-val.
-                */
                int64      *arg = (int64 *) PG_GETARG_POINTER(0);
                int64           result;
 
@@ -682,6 +681,7 @@ int8inc(PG_FUNCTION_ARGS)
                PG_RETURN_POINTER(arg);
        }
        else
+#endif
        {
                /* Not called by nodeAgg, so just do it the dumb way */
                int64           arg = PG_GETARG_INT64(0);
index 86765d5..c5801ad 100644 (file)
@@ -14,7 +14,7 @@
  * Copyright (c) 1998-2008, PostgreSQL Global Development Group
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/utils/adt/numeric.c,v 1.109 2008/04/04 18:45:36 tgl Exp $
+ *       $PostgreSQL: pgsql/src/backend/utils/adt/numeric.c,v 1.110 2008/04/21 00:26:45 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -2599,10 +2599,13 @@ int2_sum(PG_FUNCTION_ARGS)
        }
 
        /*
-        * If we're invoked by nodeAgg, we can cheat and modify out first
+        * If we're invoked by nodeAgg, we can cheat and modify our first
         * parameter in-place to avoid palloc overhead. If not, we need to return
         * the new value of the transition variable.
+        * (If int8 is pass-by-value, then of course this is useless as well
+        * as incorrect, so just ifdef it out.)
         */
+#ifndef USE_FLOAT8_BYVAL               /* controls int8 too */
        if (fcinfo->context && IsA(fcinfo->context, AggState))
        {
                int64      *oldsum = (int64 *) PG_GETARG_POINTER(0);
@@ -2614,6 +2617,7 @@ int2_sum(PG_FUNCTION_ARGS)
                PG_RETURN_POINTER(oldsum);
        }
        else
+#endif
        {
                int64           oldsum = PG_GETARG_INT64(0);
 
@@ -2644,10 +2648,13 @@ int4_sum(PG_FUNCTION_ARGS)
        }
 
        /*
-        * If we're invoked by nodeAgg, we can cheat and modify out first
+        * If we're invoked by nodeAgg, we can cheat and modify our first
         * parameter in-place to avoid palloc overhead. If not, we need to return
         * the new value of the transition variable.
+        * (If int8 is pass-by-value, then of course this is useless as well
+        * as incorrect, so just ifdef it out.)
         */
+#ifndef USE_FLOAT8_BYVAL               /* controls int8 too */
        if (fcinfo->context && IsA(fcinfo->context, AggState))
        {
                int64      *oldsum = (int64 *) PG_GETARG_POINTER(0);
@@ -2659,6 +2666,7 @@ int4_sum(PG_FUNCTION_ARGS)
                PG_RETURN_POINTER(oldsum);
        }
        else
+#endif
        {
                int64           oldsum = PG_GETARG_INT64(0);
 
index 52ba771..7124fe1 100644 (file)
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/utils/adt/tsquery_gist.c,v 1.6 2008/04/20 09:17:57 teodor Exp $
+ *       $PostgreSQL: pgsql/src/backend/utils/adt/tsquery_gist.c,v 1.7 2008/04/21 00:26:45 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -19,7 +19,8 @@
 #include "tsearch/ts_type.h"
 #include "tsearch/ts_utils.h"
 
-#define GETENTRY(vec,pos) ((TSQuerySign *) DatumGetPointer((vec)->vector[(pos)].key))
+#define GETENTRY(vec,pos) DatumGetTSQuerySign((vec)->vector[pos].key)
+
 
 Datum
 gtsquery_compress(PG_FUNCTION_ARGS)
@@ -29,12 +30,12 @@ gtsquery_compress(PG_FUNCTION_ARGS)
 
        if (entry->leafkey)
        {
-               TSQuerySign *sign = (TSQuerySign *) palloc(sizeof(TSQuerySign));
+               TSQuerySign sign;
 
                retval = (GISTENTRY *) palloc(sizeof(GISTENTRY));
-               *sign = makeTSQuerySign(DatumGetTSQuery(entry->key));
+               sign = makeTSQuerySign(DatumGetTSQuery(entry->key));
 
-               gistentryinit(*retval, PointerGetDatum(sign),
+               gistentryinit(*retval, TSQuerySignGetDatum(sign),
                                          entry->rel, entry->page,
                                          entry->offset, FALSE);
        }
@@ -56,7 +57,7 @@ gtsquery_consistent(PG_FUNCTION_ARGS)
        StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
        /* Oid          subtype = PG_GETARG_OID(3); */
        bool       *recheck = (bool *) PG_GETARG_POINTER(4);
-       TSQuerySign *key = (TSQuerySign *) DatumGetPointer(entry->key);
+       TSQuerySign     key = DatumGetTSQuerySign(entry->key);
        TSQuerySign sq = makeTSQuerySign(query);
        bool            retval;
 
@@ -67,15 +68,15 @@ gtsquery_consistent(PG_FUNCTION_ARGS)
        {
                case RTContainsStrategyNumber:
                        if (GIST_LEAF(entry))
-                               retval = (*key & sq) == sq;
+                               retval = (key & sq) == sq;
                        else
-                               retval = (*key & sq) != 0;
+                               retval = (key & sq) != 0;
                        break;
                case RTContainedByStrategyNumber:
                        if (GIST_LEAF(entry))
-                               retval = (*key & sq) == *key;
+                               retval = (key & sq) == key;
                        else
-                               retval = (*key & sq) != 0;
+                               retval = (key & sq) != 0;
                        break;
                default:
                        retval = FALSE;
@@ -88,27 +89,27 @@ gtsquery_union(PG_FUNCTION_ARGS)
 {
        GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
        int                *size = (int *) PG_GETARG_POINTER(1);
-       TSQuerySign *sign = (TSQuerySign *) palloc(sizeof(TSQuerySign));
+       TSQuerySign sign;
        int                     i;
 
-       memset(sign, 0, sizeof(TSQuerySign));
+       sign = 0;
 
        for (i = 0; i < entryvec->n; i++)
-               *sign |= *GETENTRY(entryvec, i);
+               sign |= GETENTRY(entryvec, i);
 
        *size = sizeof(TSQuerySign);
 
-       PG_RETURN_POINTER(sign);
+       PG_RETURN_TSQUERYSIGN(sign);
 }
 
 Datum
 gtsquery_same(PG_FUNCTION_ARGS)
 {
-       TSQuerySign *a = (TSQuerySign *) PG_GETARG_POINTER(0);
-       TSQuerySign *b = (TSQuerySign *) PG_GETARG_POINTER(1);
-       bool            *result = (bool *) PG_GETARG_POINTER(2);
+       TSQuerySign a = PG_GETARG_TSQUERYSIGN(0);
+       TSQuerySign b = PG_GETARG_TSQUERYSIGN(1);
+       bool       *result = (bool *) PG_GETARG_POINTER(2);
 
-       *result = (*a == *b) ? true : false;
+       *result = (a == b) ? true : false;
 
        PG_RETURN_POINTER(result);
 }
@@ -136,11 +137,11 @@ hemdist(TSQuerySign a, TSQuerySign b)
 Datum
 gtsquery_penalty(PG_FUNCTION_ARGS)
 {
-       TSQuerySign *origval = (TSQuerySign *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(0))->key);
-       TSQuerySign *newval = (TSQuerySign *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(1))->key);
+       TSQuerySign origval = DatumGetTSQuerySign(((GISTENTRY *) PG_GETARG_POINTER(0))->key);
+       TSQuerySign newval = DatumGetTSQuerySign(((GISTENTRY *) PG_GETARG_POINTER(1))->key);
        float      *penalty = (float *) PG_GETARG_POINTER(2);
 
-       *penalty = hemdist(*origval, *newval);
+       *penalty = hemdist(origval, newval);
 
        PG_RETURN_POINTER(penalty);
 }
@@ -171,9 +172,8 @@ gtsquery_picksplit(PG_FUNCTION_ARGS)
        OffsetNumber maxoff = entryvec->n - 2;
        OffsetNumber k,
                                j;
-
-       TSQuerySign *datum_l,
-                          *datum_r;
+       TSQuerySign datum_l,
+                               datum_r;
        int4            size_alpha,
                                size_beta;
        int4            size_waste,
@@ -194,7 +194,7 @@ gtsquery_picksplit(PG_FUNCTION_ARGS)
        for (k = FirstOffsetNumber; k < maxoff; k = OffsetNumberNext(k))
                for (j = OffsetNumberNext(k); j <= maxoff; j = OffsetNumberNext(j))
                {
-                       size_waste = hemdist(*GETENTRY(entryvec, j), *GETENTRY(entryvec, k));
+                       size_waste = hemdist(GETENTRY(entryvec, j), GETENTRY(entryvec, k));
                        if (size_waste > waste)
                        {
                                waste = size_waste;
@@ -210,19 +210,16 @@ gtsquery_picksplit(PG_FUNCTION_ARGS)
                seed_2 = 2;
        }
 
-       datum_l = (TSQuerySign *) palloc(sizeof(TSQuerySign));
-       *datum_l = *GETENTRY(entryvec, seed_1);
-       datum_r = (TSQuerySign *) palloc(sizeof(TSQuerySign));
-       *datum_r = *GETENTRY(entryvec, seed_2);
-
+       datum_l = GETENTRY(entryvec, seed_1);
+       datum_r = GETENTRY(entryvec, seed_2);
 
        maxoff = OffsetNumberNext(maxoff);
        costvector = (SPLITCOST *) palloc(sizeof(SPLITCOST) * maxoff);
        for (j = FirstOffsetNumber; j <= maxoff; j = OffsetNumberNext(j))
        {
                costvector[j - 1].pos = j;
-               size_alpha = hemdist(*GETENTRY(entryvec, seed_1), *GETENTRY(entryvec, j));
-               size_beta = hemdist(*GETENTRY(entryvec, seed_2), *GETENTRY(entryvec, j));
+               size_alpha = hemdist(GETENTRY(entryvec, seed_1), GETENTRY(entryvec, j));
+               size_beta = hemdist(GETENTRY(entryvec, seed_2), GETENTRY(entryvec, j));
                costvector[j - 1].cost = abs(size_alpha - size_beta);
        }
        qsort((void *) costvector, maxoff, sizeof(SPLITCOST), comparecost);
@@ -242,26 +239,26 @@ gtsquery_picksplit(PG_FUNCTION_ARGS)
                        v->spl_nright++;
                        continue;
                }
-               size_alpha = hemdist(*datum_l, *GETENTRY(entryvec, j));
-               size_beta = hemdist(*datum_r, *GETENTRY(entryvec, j));
+               size_alpha = hemdist(datum_l, GETENTRY(entryvec, j));
+               size_beta = hemdist(datum_r, GETENTRY(entryvec, j));
 
                if (size_alpha < size_beta + WISH_F(v->spl_nleft, v->spl_nright, 0.05))
                {
-                       *datum_l |= *GETENTRY(entryvec, j);
+                       datum_l |= GETENTRY(entryvec, j);
                        *left++ = j;
                        v->spl_nleft++;
                }
                else
                {
-                       *datum_r |= *GETENTRY(entryvec, j);
+                       datum_r |= GETENTRY(entryvec, j);
                        *right++ = j;
                        v->spl_nright++;
                }
        }
 
        *right = *left = FirstOffsetNumber;
-       v->spl_ldatum = PointerGetDatum(datum_l);
-       v->spl_rdatum = PointerGetDatum(datum_r);
+       v->spl_ldatum = TSQuerySignGetDatum(datum_l);
+       v->spl_rdatum = TSQuerySignGetDatum(datum_r);
 
        PG_RETURN_POINTER(v);
 }
index 63990ca..730830a 100644 (file)
@@ -1,4 +1,4 @@
-$PostgreSQL: pgsql/src/backend/utils/fmgr/README,v 1.11 2008/04/18 18:43:09 alvherre Exp $
+$PostgreSQL: pgsql/src/backend/utils/fmgr/README,v 1.12 2008/04/21 00:26:45 tgl Exp $
 
 Function Manager
 ================
@@ -211,13 +211,11 @@ also amenable to machine processing --- for example, we could probably
 write a script that scans code like this and extracts argument and result
 type info for comparison to the pg_proc table.
 
-For the standard data types float8 and int8, these macros should
-hide the indirection and space allocation involved, so that the function's
-code is not explicitly aware that these types are pass-by-reference.  This
-will offer a considerable gain in readability, and it also opens up the
-opportunity to make these types be pass-by-value on machines where it's
-feasible to do so.  (For example, on an Alpha it's pretty silly to make int8
-be pass-by-ref, since Datum is going to be 64 bits anyway.)
+For the standard data types float4, float8, and int8, these macros should hide
+whether the types are pass-by-value or pass-by reference, by incorporating
+indirection and space allocation if needed.  This will offer a considerable
+gain in readability, and it also opens up the opportunity to make these types
+be pass-by-value on machines where it's feasible to do so.
 
 Here are the proposed macros and coding conventions:
 
@@ -247,20 +245,22 @@ which expands to
 Argument values are ordinarily fetched using code like
        int32   name = PG_GETARG_INT32(number);
 
-For float8 and int8, the PG_GETARG macros will hide the pass-by-reference
-nature of the data types; for example PG_GETARG_FLOAT8 expands to
+For float4, float8, and int8, the PG_GETARG macros will hide whether the
+types are pass-by-value or pass-by-reference.  For example, if float8 is
+pass-by-reference then PG_GETARG_FLOAT8 expands to
        (* (float8 *) DatumGetPointer(fcinfo->arg[number]))
 and would typically be called like this:
        float8  arg = PG_GETARG_FLOAT8(0);
-Note that "float8" is the recommended typedef to use, not "float64data", and
-the macros are named accordingly.  But 64-bit ints should be declared as
-"int64".
+For what are now historical reasons, the float-related typedefs and macros
+express the type width in bytes (4 or 8), whereas we prefer to label the
+widths of integer types in bits.
 
 Non-null values are returned with a PG_RETURN_XXX macro of the appropriate
 type.  For example, PG_RETURN_INT32 expands to
        return Int32GetDatum(x)
-PG_RETURN_FLOAT8 and PG_RETURN_INT64 hide the pass-by-reference nature of
-their datatypes.
+PG_RETURN_FLOAT4, PG_RETURN_FLOAT8, and PG_RETURN_INT64 hide whether their
+data types are pass-by-value or pass-by-reference, by doing a palloc if
+needed.
 
 fmgr.h will provide PG_GETARG and PG_RETURN macros for all the basic data
 types.  Modules or header files that define specialized SQL datatypes
@@ -333,9 +333,8 @@ Again, this style of coding does not allow for expressing NULL inputs
 or receiving a NULL result.
 
 As with the callee-side situation, I propose adding argument conversion
-macros that hide the pass-by-reference nature of int8, and
-float8, with an eye to making those types relatively painless to convert
-to pass-by-value.
+macros that hide whether int8, float4, and float8 are pass-by-value or
+pass-by-reference.
 
 The existing helper functions fmgr(), fmgr_c(), etc will be left in
 place until all uses of them are gone.  Of course their internals will
index 853fb9e..5a0a22c 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/utils/fmgr/fmgr.c,v 1.116 2008/04/18 18:43:09 alvherre Exp $
+ *       $PostgreSQL: pgsql/src/backend/utils/fmgr/fmgr.c,v 1.117 2008/04/21 00:26:46 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -2023,17 +2023,23 @@ fmgr(Oid procedureId,...)
 
 
 /*-------------------------------------------------------------------------
- *             Support routines for standard pass-by-reference datatypes
+ *             Support routines for standard maybe-pass-by-reference datatypes
  *
- * Note: at some point, at least on some platforms, these might become
- * pass-by-value types.  Obviously Datum must be >= 8 bytes to allow
- * int64 or float8 to be pass-by-value.  I think that Float4GetDatum
- * and Float8GetDatum will need to be out-of-line routines anyway,
- * since just casting from float to Datum will not do the right thing;
- * some kind of trick with pointer-casting or a union will be needed.
+ * int8, float4, and float8 can be passed by value if Datum is wide enough.
+ * (For backwards-compatibility reasons, we allow pass-by-ref to be chosen
+ * at compile time even if pass-by-val is possible.)  For the float types,
+ * we need a support routine even if we are passing by value, because many
+ * machines pass int and float function parameters/results differently;
+ * so we need to play weird games with unions.
+ *
+ * Note: there is only one switch controlling the pass-by-value option for
+ * both int8 and float8; this is to avoid making things unduly complicated
+ * for the timestamp types, which might have either representation.
  *-------------------------------------------------------------------------
  */
 
+#ifndef USE_FLOAT8_BYVAL               /* controls int8 too */
+
 Datum
 Int64GetDatum(int64 X)
 {
@@ -2057,9 +2063,12 @@ Int64GetDatum(int64 X)
 #endif   /* INT64_IS_BUSTED */
 }
 
+#endif /* USE_FLOAT8_BYVAL */
+
 Datum
 Float4GetDatum(float4 X)
 {
+#ifdef USE_FLOAT4_BYVAL
        union {
                float4  value;
                int32   retval;
@@ -2067,8 +2076,16 @@ Float4GetDatum(float4 X)
 
        myunion.value = X;
        return SET_4_BYTES(myunion.retval);
+#else
+       float4     *retval = (float4 *) palloc(sizeof(float4));
+
+       *retval = X;
+       return PointerGetDatum(retval);
+#endif
 }
 
+#ifdef USE_FLOAT4_BYVAL
+
 float4
 DatumGetFloat4(Datum X)
 {
@@ -2081,15 +2098,44 @@ DatumGetFloat4(Datum X)
        return myunion.retval;
 }
 
+#endif /* USE_FLOAT4_BYVAL */
+
 Datum
 Float8GetDatum(float8 X)
 {
+#ifdef USE_FLOAT8_BYVAL
+       union {
+               float8  value;
+               int64   retval;
+       } myunion;
+
+       myunion.value = X;
+       return SET_8_BYTES(myunion.retval);
+#else
        float8     *retval = (float8 *) palloc(sizeof(float8));
 
        *retval = X;
        return PointerGetDatum(retval);
+#endif
 }
 
+#ifdef USE_FLOAT8_BYVAL
+
+float8
+DatumGetFloat8(Datum X)
+{
+       union {
+               int64   value;
+               float8  retval;
+       } myunion;
+
+       myunion.value = GET_8_BYTES(X);
+       return myunion.retval;
+}
+
+#endif /* USE_FLOAT8_BYVAL */
+
+
 /*-------------------------------------------------------------------------
  *             Support routines for toastable datatypes
  *-------------------------------------------------------------------------
index 2cc1831..747c34e 100644 (file)
@@ -23,7 +23,7 @@
  * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/backend/utils/init/flatfiles.c,v 1.32 2008/03/26 21:10:39 alvherre Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/init/flatfiles.c,v 1.33 2008/04/21 00:26:46 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -483,13 +483,14 @@ write_auth_file(Relation rel_authid, Relation rel_authmem)
                }
                else
                {
-                       /*
-                        * rolvaliduntil is timestamptz, which we assume is double
-                        * alignment and pass-by-reference.
-                        */
+                       TimestampTz *rvup;
+
+                       /* Assume timestamptz has double alignment */
                        off = att_align_nominal(off, 'd');
-                       datum = PointerGetDatum(tp + off);
-                       auth_info[curr_role].rolvaliduntil = DatumGetCString(DirectFunctionCall1(timestamptz_out, datum));
+                       rvup = (TimestampTz *) (tp + off);
+                       auth_info[curr_role].rolvaliduntil =
+                               DatumGetCString(DirectFunctionCall1(timestamptz_out,
+                                                                                               TimestampTzGetDatum(*rvup)));
                }
 
                /*
index ea71265..122ef37 100644 (file)
@@ -6,7 +6,7 @@
  * copyright (c) Oliver Elphick <olly@lfix.co.uk>, 2001;
  * licence: BSD
  *
- * $PostgreSQL: pgsql/src/bin/pg_controldata/pg_controldata.c,v 1.38 2008/03/27 03:57:33 tgl Exp $
+ * $PostgreSQL: pgsql/src/bin/pg_controldata/pg_controldata.c,v 1.39 2008/04/21 00:26:46 tgl Exp $
  */
 #include "postgres_fe.h"
 
@@ -216,6 +216,10 @@ main(int argc, char *argv[])
                   ControlFile.toast_max_chunk_size);
        printf(_("Date/time type storage:               %s\n"),
                   (ControlFile.enableIntTimes ? _("64-bit integers") : _("floating-point numbers")));
+       printf(_("Float4 argument passing:              %s\n"),
+                  (ControlFile.float4ByVal ? _("by value") : _("by reference")));
+       printf(_("Float8 argument passing:              %s\n"),
+                  (ControlFile.float8ByVal ? _("by value") : _("by reference")));
        printf(_("Maximum length of locale name:        %u\n"),
                   ControlFile.localeBuflen);
        printf(_("LC_COLLATE:                           %s\n"),
index 86c4463..109fec7 100644 (file)
@@ -23,7 +23,7 @@
  * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/bin/pg_resetxlog/pg_resetxlog.c,v 1.64 2008/02/17 02:09:30 tgl Exp $
+ * $PostgreSQL: pgsql/src/bin/pg_resetxlog/pg_resetxlog.c,v 1.65 2008/04/21 00:26:46 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -487,10 +487,12 @@ GuessControlValues(void)
        ControlFile.indexMaxKeys = INDEX_MAX_KEYS;
        ControlFile.toast_max_chunk_size = TOAST_MAX_CHUNK_SIZE;
 #ifdef HAVE_INT64_TIMESTAMP
-       ControlFile.enableIntTimes = TRUE;
+       ControlFile.enableIntTimes = true;
 #else
-       ControlFile.enableIntTimes = FALSE;
+       ControlFile.enableIntTimes = false;
 #endif
+       ControlFile.float4ByVal = FLOAT4PASSBYVAL;
+       ControlFile.float8ByVal = FLOAT8PASSBYVAL;
        ControlFile.localeBuflen = LOCALE_NAME_BUFLEN;
 
        localeptr = setlocale(LC_COLLATE, "");
@@ -578,6 +580,10 @@ PrintControlValues(bool guessed)
                   ControlFile.toast_max_chunk_size);
        printf(_("Date/time type storage:               %s\n"),
                   (ControlFile.enableIntTimes ? _("64-bit integers") : _("floating-point numbers")));
+       printf(_("Float4 argument passing:              %s\n"),
+                  (ControlFile.float4ByVal ? _("by value") : _("by reference")));
+       printf(_("Float8 argument passing:              %s\n"),
+                  (ControlFile.float8ByVal ? _("by value") : _("by reference")));
        printf(_("Maximum length of locale name:        %u\n"),
                   ControlFile.localeBuflen);
        printf(_("LC_COLLATE:                           %s\n"),
index e269709..86b0d9f 100644 (file)
@@ -12,7 +12,7 @@
  * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/c.h,v 1.225 2008/04/18 18:43:09 alvherre Exp $
+ * $PostgreSQL: pgsql/src/include/c.h,v 1.226 2008/04/21 00:26:46 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -249,22 +249,6 @@ typedef uint16 bits16;                     /* >= 16 bits */
 typedef uint32 bits32;                 /* >= 32 bits */
 
 /*
- * floatN
- *             Floating point number, AT LEAST N BITS IN SIZE,
- *             used for numerical computations.
- *
- *             Since sizeof(float8) may be > sizeof(char *), always pass
- *             float8 by reference.  float4 is passed by value.
- *
- * XXX: these typedefs are now deprecated in favor of float4 and float8.
- * They will eventually go away.
- */
-typedef float float32data;
-typedef double float64data;
-typedef float *float32;
-typedef double *float64;
-
-/*
  * 64-bit integers
  */
 #ifdef HAVE_LONG_INT_64
index 83c0dbd..041194f 100644 (file)
@@ -37,7 +37,7 @@
  * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.449 2008/04/18 18:43:09 alvherre Exp $
+ * $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.450 2008/04/21 00:26:46 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -53,6 +53,6 @@
  */
 
 /*                                                     yyyymmddN */
-#define CATALOG_VERSION_NO     200804181
+#define CATALOG_VERSION_NO     200804201
 
 #endif
index 08b18da..1378f10 100644 (file)
@@ -8,7 +8,7 @@
  * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/catalog/pg_attribute.h,v 1.136 2008/04/18 18:43:09 alvherre Exp $
+ * $PostgreSQL: pgsql/src/include/catalog/pg_attribute.h,v 1.137 2008/04/21 00:26:46 tgl Exp $
  *
  * NOTES
  *       the genbki.sh script reads this file and generates .bki
@@ -287,8 +287,8 @@ DATA(insert ( 1247 tableoid                 26 0  4  -7 0 -1 -1 t p i t f f t 0));
 { 1255, {"pronamespace"},              26, -1, 4,      2, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \
 { 1255, {"proowner"},                  26, -1, 4,      3, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \
 { 1255, {"prolang"},                   26, -1, 4,      4, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \
-{ 1255, {"procost"},              700, -1, 4,  5, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \
-{ 1255, {"prorows"},              700, -1, 4,  6, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \
+{ 1255, {"procost"},              700, -1, 4,  5, 0, -1, -1, FLOAT4PASSBYVAL, 'p', 'i', true, false, false, true, 0 }, \
+{ 1255, {"prorows"},              700, -1, 4,  6, 0, -1, -1, FLOAT4PASSBYVAL, 'p', 'i', true, false, false, true, 0 }, \
 { 1255, {"proisagg"},                  16, -1, 1,      7, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0 }, \
 { 1255, {"prosecdef"},                 16, -1, 1,      8, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0 }, \
 { 1255, {"proisstrict"},               16, -1, 1,      9, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0 }, \
@@ -309,8 +309,8 @@ DATA(insert ( 1255 proname                  19 -1 NAMEDATALEN       1 0 -1 -1 f p i t f f t 0));
 DATA(insert ( 1255 pronamespace                26 -1 4   2 0 -1 -1 t p i t f f t 0));
 DATA(insert ( 1255 proowner                    26 -1 4   3 0 -1 -1 t p i t f f t 0));
 DATA(insert ( 1255 prolang                     26 -1 4   4 0 -1 -1 t p i t f f t 0));
-DATA(insert ( 1255 procost                700 -1 4   5 0 -1 -1 t p i t f f t 0));
-DATA(insert ( 1255 prorows                700 -1 4   6 0 -1 -1 t p i t f f t 0));
+DATA(insert ( 1255 procost                700 -1 4   5 0 -1 -1 FLOAT4PASSBYVAL p i t f f t 0));
+DATA(insert ( 1255 prorows                700 -1 4   6 0 -1 -1 FLOAT4PASSBYVAL p i t f f t 0));
 DATA(insert ( 1255 proisagg                    16 -1 1   7 0 -1 -1 t p c t f f t 0));
 DATA(insert ( 1255 prosecdef           16 -1 1   8 0 -1 -1 t p c t f f t 0));
 DATA(insert ( 1255 proisstrict         16 -1 1   9 0 -1 -1 t p c t f f t 0));
@@ -395,7 +395,7 @@ DATA(insert ( 1249 tableoid                 26 0  4  -7 0 -1 -1 t p i t f f t 0));
 { 1259, {"relfilenode"},   26, -1,     4,      6, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \
 { 1259, {"reltablespace"}, 26, -1,     4,      7, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \
 { 1259, {"relpages"},     23, -1,      4,      8, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \
-{ 1259, {"reltuples"},    700, -1, 4,  9, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \
+{ 1259, {"reltuples"},    700, -1, 4,  9, 0, -1, -1, FLOAT4PASSBYVAL, 'p', 'i', true, false, false, true, 0 }, \
 { 1259, {"reltoastrelid"}, 26, -1,     4, 10, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \
 { 1259, {"reltoastidxid"}, 26, -1,     4, 11, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \
 { 1259, {"relhasindex"},   16, -1,     1, 12, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0 }, \
@@ -423,7 +423,7 @@ DATA(insert ( 1259 relam                    26 -1 4   5 0 -1 -1 t p i t f f t 0));
 DATA(insert ( 1259 relfilenode         26 -1 4   6 0 -1 -1 t p i t f f t 0));
 DATA(insert ( 1259 reltablespace       26 -1 4   7 0 -1 -1 t p i t f f t 0));
 DATA(insert ( 1259 relpages                    23 -1 4   8 0 -1 -1 t p i t f f t 0));
-DATA(insert ( 1259 reltuples      700 -1 4   9 0 -1 -1 t p i t f f t 0));
+DATA(insert ( 1259 reltuples      700 -1 4   9 0 -1 -1 FLOAT4PASSBYVAL p i t f f t 0));
 DATA(insert ( 1259 reltoastrelid       26 -1 4  10 0 -1 -1 t p i t f f t 0));
 DATA(insert ( 1259 reltoastidxid       26 -1 4  11 0 -1 -1 t p i t f f t 0));
 DATA(insert ( 1259 relhasindex         16 -1 1  12 0 -1 -1 t p c t f f t 0));
index e61faed..4f789e9 100644 (file)
@@ -8,7 +8,7 @@
  * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/catalog/pg_control.h,v 1.40 2008/02/17 02:09:30 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/catalog/pg_control.h,v 1.41 2008/04/21 00:26:47 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -21,7 +21,7 @@
 
 
 /* Version identifier for this pg_control format */
-#define PG_CONTROL_VERSION     841
+#define PG_CONTROL_VERSION     842
 
 /*
  * Body of CheckPoint XLOG records.  This is declared here because we keep
@@ -138,7 +138,11 @@ typedef struct ControlFileData
        uint32          toast_max_chunk_size;   /* chunk size in TOAST tables */
 
        /* flag indicating internal format of timestamp, interval, time */
-       uint32          enableIntTimes; /* int64 storage enabled? */
+       bool            enableIntTimes; /* int64 storage enabled? */
+
+       /* flags indicating pass-by-value status of various types */
+       bool            float4ByVal;    /* float4 pass-by-value? */
+       bool            float8ByVal;    /* float8, int8, etc pass-by-value? */
 
        /* active locales */
        uint32          localeBuflen;
index 2c98f2b..5687332 100644 (file)
@@ -8,7 +8,7 @@
  * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/catalog/pg_type.h,v 1.194 2008/04/18 18:43:09 alvherre Exp $
+ * $PostgreSQL: pgsql/src/include/catalog/pg_type.h,v 1.195 2008/04/21 00:26:47 tgl Exp $
  *
  * NOTES
  *       the genbki.sh script reads this file and generates .bki
@@ -271,7 +271,7 @@ DATA(insert OID = 19 (      name       PGNSP PGUID NAMEDATALEN f b t \054 0 18 1003 name
 DESCR("63-character type for storing system identifiers");
 #define NAMEOID                        19
 
-DATA(insert OID = 20 ( int8       PGNSP PGUID  8 f b t \054 0   0 1016 int8in int8out int8recv int8send - - - d p f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 20 ( int8       PGNSP PGUID  8 FLOAT8PASSBYVAL b t \054 0     0 1016 int8in int8out int8recv int8send - - - d p f 0 -1 0 _null_ _null_ ));
 DESCR("~18 digit integer, 8-byte storage");
 #define INT8OID                        20
 
@@ -368,10 +368,10 @@ DESCR("");
 
 /* OIDS 700 - 799 */
 
-DATA(insert OID = 700 (  float4    PGNSP PGUID 4 t b t \054 0   0 1021 float4in float4out float4recv float4send - - - i p f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 700 (  float4    PGNSP PGUID 4 FLOAT4PASSBYVAL b t \054 0     0 1021 float4in float4out float4recv float4send - - - i p f 0 -1 0 _null_ _null_ ));
 DESCR("single-precision floating point number, 4-byte storage");
 #define FLOAT4OID 700
-DATA(insert OID = 701 (  float8    PGNSP PGUID 8 f b t \054 0   0 1022 float8in float8out float8recv float8send - - - d p f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 701 (  float8    PGNSP PGUID 8 FLOAT8PASSBYVAL b t \054 0     0 1022 float8in float8out float8recv float8send - - - d p f 0 -1 0 _null_ _null_ ));
 DESCR("double-precision floating point number, 8-byte storage");
 #define FLOAT8OID 701
 DATA(insert OID = 702 (  abstime   PGNSP PGUID 4 t b t \054 0   0 1023 abstimein abstimeout abstimerecv abstimesend - - - i p f 0 -1 0 _null_ _null_ ));
@@ -391,7 +391,7 @@ DATA(insert OID = 718 (  circle    PGNSP PGUID      24 f b t \054 0 0 719 circle_in c
 DESCR("geometric circle '(center,radius)'");
 #define CIRCLEOID              718
 DATA(insert OID = 719 (  _circle   PGNSP PGUID -1 f b t \054 0  718 0 array_in array_out array_recv array_send - - - d x f 0 -1 0 _null_ _null_ ));
-DATA(insert OID = 790 (  money    PGNSP PGUID   8 f b t \054 0 0 791 cash_in cash_out cash_recv cash_send - - - d p f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 790 (  money    PGNSP PGUID   8 FLOAT8PASSBYVAL b t \054 0 0 791 cash_in cash_out cash_recv cash_send - - - d p f 0 -1 0 _null_ _null_ ));
 DESCR("monetary amounts, $d,ddd.cc");
 #define CASHOID 790
 DATA(insert OID = 791 (  _money    PGNSP PGUID -1 f b t \054 0  790 0 array_in array_out array_recv array_send - - - d x f 0 -1 0 _null_ _null_ ));
@@ -459,18 +459,18 @@ DESCR("varchar(length), non-blank-padded string, variable storage length");
 DATA(insert OID = 1082 ( date           PGNSP PGUID    4 t b t \054 0  0 1182 date_in date_out date_recv date_send - - - i p f 0 -1 0 _null_ _null_ ));
 DESCR("ANSI SQL date");
 #define DATEOID                        1082
-DATA(insert OID = 1083 ( time           PGNSP PGUID    8 f b t \054 0  0 1183 time_in time_out time_recv time_send timetypmodin timetypmodout - d p f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 1083 ( time           PGNSP PGUID    8 FLOAT8PASSBYVAL b t \054 0    0 1183 time_in time_out time_recv time_send timetypmodin timetypmodout - d p f 0 -1 0 _null_ _null_ ));
 DESCR("hh:mm:ss, ANSI SQL time");
 #define TIMEOID                        1083
 
 /* OIDS 1100 - 1199 */
-DATA(insert OID = 1114 ( timestamp      PGNSP PGUID    8 f b t \054 0  0 1115 timestamp_in timestamp_out timestamp_recv timestamp_send timestamptypmodin timestamptypmodout - d p f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 1114 ( timestamp      PGNSP PGUID    8 FLOAT8PASSBYVAL b t \054 0    0 1115 timestamp_in timestamp_out timestamp_recv timestamp_send timestamptypmodin timestamptypmodout - d p f 0 -1 0 _null_ _null_ ));
 DESCR("date and time");
 #define TIMESTAMPOID   1114
 DATA(insert OID = 1115 ( _timestamp  PGNSP PGUID       -1 f b t \054 0 1114 0 array_in array_out array_recv array_send timestamptypmodin timestamptypmodout - d x f 0 -1 0 _null_ _null_ ));
 DATA(insert OID = 1182 ( _date          PGNSP PGUID    -1 f b t \054 0 1082 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
 DATA(insert OID = 1183 ( _time          PGNSP PGUID    -1 f b t \054 0 1083 0 array_in array_out array_recv array_send timetypmodin timetypmodout - d x f 0 -1 0 _null_ _null_ ));
-DATA(insert OID = 1184 ( timestamptz PGNSP PGUID       8 f b t \054 0  0 1185 timestamptz_in timestamptz_out timestamptz_recv timestamptz_send timestamptztypmodin timestamptztypmodout - d p f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 1184 ( timestamptz PGNSP PGUID       8 FLOAT8PASSBYVAL b t \054 0    0 1185 timestamptz_in timestamptz_out timestamptz_recv timestamptz_send timestamptztypmodin timestamptztypmodout - d p f 0 -1 0 _null_ _null_ ));
 DESCR("date and time with time zone");
 #define TIMESTAMPTZOID 1184
 DATA(insert OID = 1185 ( _timestamptz PGNSP PGUID -1 f b t \054 0      1184 0 array_in array_out array_recv array_send timestamptztypmodin timestamptztypmodout - d x f 0 -1 0 _null_ _null_ ));
index 07bce55..ec3261b 100644 (file)
@@ -11,7 +11,7 @@
  * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/fmgr.h,v 1.57 2008/01/01 19:45:56 momjian Exp $
+ * $PostgreSQL: pgsql/src/include/fmgr.h,v 1.58 2008/04/21 00:26:46 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -353,6 +353,9 @@ extern int no_such_variable
  * are custom-configurable and especially likely to break dynamically loaded
  * modules if they were compiled with other values.  Also, the length field
  * can be used to detect definition changes.
+ *
+ * Note: we compare magic blocks with memcmp(), so there had better not be
+ * any alignment pad bytes in them.
  *-------------------------------------------------------------------------
  */
 
@@ -364,6 +367,8 @@ typedef struct
        int                     funcmaxargs;    /* FUNC_MAX_ARGS */
        int                     indexmaxkeys;   /* INDEX_MAX_KEYS */
        int                     namedatalen;    /* NAMEDATALEN */
+       int                     float4byval;    /* FLOAT4PASSBYVAL */
+       int                     float8byval;    /* FLOAT8PASSBYVAL */
 } Pg_magic_struct;
 
 /* The actual data block contents */
@@ -373,7 +378,9 @@ typedef struct
        PG_VERSION_NUM / 100, \
        FUNC_MAX_ARGS, \
        INDEX_MAX_KEYS, \
-       NAMEDATALEN \
+       NAMEDATALEN, \
+       FLOAT4PASSBYVAL, \
+       FLOAT8PASSBYVAL \
 }
 
 /*
index 24b7c0d..caaf626 100644 (file)
    (--enable-thread-safety) */
 #undef ENABLE_THREAD_SAFETY
 
+/* float4 values are passed by value if 'true', by reference if 'false' */
+#undef FLOAT4PASSBYVAL
+
+/* float8, int8, and related values are passed by value if 'true', by
+   reference if 'false' */
+#undef FLOAT8PASSBYVAL
+
 /* Define to 1 if getpwuid_r() takes a 5th argument. */
 #undef GETPWUID_R_5ARG
 
 /* Define to 1 to build with Bonjour support. (--with-bonjour) */
 #undef USE_BONJOUR
 
+/* Define to 1 if you want float4 values to be passed by value.
+   (--enable-float4-byval) */
+#undef USE_FLOAT4_BYVAL
+
+/* Define to 1 if you want float8, int8, etc values to be passed by value.
+   (--enable-float8-byval) */
+#undef USE_FLOAT8_BYVAL
+
 /* Define to 1 if you want 64-bit integer timestamp and interval support.
    (--enable-integer-datetimes) */
 #undef USE_INTEGER_DATETIMES
index 40ecd45..ae8a442 100644 (file)
@@ -10,7 +10,7 @@
  * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
  * Portions Copyright (c) 1995, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/postgres.h,v 1.90 2008/04/18 18:43:09 alvherre Exp $
+ * $PostgreSQL: pgsql/src/include/postgres.h,v 1.91 2008/04/21 00:26:46 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -314,9 +314,15 @@ typedef Datum *DatumPtr;
 #define GET_1_BYTE(datum)      (((Datum) (datum)) & 0x000000ff)
 #define GET_2_BYTES(datum)     (((Datum) (datum)) & 0x0000ffff)
 #define GET_4_BYTES(datum)     (((Datum) (datum)) & 0xffffffff)
+#if SIZEOF_DATUM == 8
+#define GET_8_BYTES(datum)     ((Datum) (datum))
+#endif
 #define SET_1_BYTE(value)      (((Datum) (value)) & 0x000000ff)
 #define SET_2_BYTES(value)     (((Datum) (value)) & 0x0000ffff)
 #define SET_4_BYTES(value)     (((Datum) (value)) & 0xffffffff)
+#if SIZEOF_DATUM == 8
+#define SET_8_BYTES(value)     ((Datum) (value))
+#endif
 
 /*
  * DatumGetBool
@@ -527,32 +533,48 @@ typedef Datum *DatumPtr;
  * DatumGetInt64
  *             Returns 64-bit integer value of a datum.
  *
- * Note: this macro hides the fact that int64 is currently a
- * pass-by-reference type.     Someday it may be pass-by-value,
- * at least on some platforms.
+ * Note: this macro hides whether int64 is pass by value or by reference.
  */
 
+#ifdef USE_FLOAT8_BYVAL
+#define DatumGetInt64(X) ((int64) GET_8_BYTES(X))
+#else
 #define DatumGetInt64(X) (* ((int64 *) DatumGetPointer(X)))
+#endif
 
 /*
  * Int64GetDatum
  *             Returns datum representation for a 64-bit integer.
  *
- * Note: this routine returns a reference to palloc'd space.
+ * Note: if int64 is pass by reference, this function returns a reference
+ * to palloc'd space.
  */
 
+#ifdef USE_FLOAT8_BYVAL
+#define Int64GetDatum(X) ((Datum) SET_8_BYTES(X))
+#else
 extern Datum Int64GetDatum(int64 X);
+#endif
 
 /*
  * DatumGetFloat4
  *             Returns 4-byte floating point value of a datum.
+ *
+ * Note: this macro hides whether float4 is pass by value or by reference.
  */
 
+#ifdef USE_FLOAT4_BYVAL
 extern float4 DatumGetFloat4(Datum X);
+#else
+#define DatumGetFloat4(X) (* ((float4 *) DatumGetPointer(X)))
+#endif
 
 /*
  * Float4GetDatum
  *             Returns datum representation for a 4-byte floating point number.
+ *
+ * Note: if float4 is pass by reference, this function returns a reference
+ * to palloc'd space.
  */
 
 extern Datum Float4GetDatum(float4 X);
@@ -561,18 +583,21 @@ extern Datum Float4GetDatum(float4 X);
  * DatumGetFloat8
  *             Returns 8-byte floating point value of a datum.
  *
- * Note: this macro hides the fact that float8 is currently a
- * pass-by-reference type.     Someday it may be pass-by-value,
- * at least on some platforms.
+ * Note: this macro hides whether float8 is pass by value or by reference.
  */
 
+#ifdef USE_FLOAT8_BYVAL
+extern float8 DatumGetFloat8(Datum X);
+#else
 #define DatumGetFloat8(X) (* ((float8 *) DatumGetPointer(X)))
+#endif
 
 /*
  * Float8GetDatum
  *             Returns datum representation for an 8-byte floating point number.
  *
- * Note: this routine returns a reference to palloc'd space.
+ * Note: if float8 is pass by reference, this function returns a reference
+ * to palloc'd space.
  */
 
 extern Datum Float8GetDatum(float8 X);
@@ -581,9 +606,10 @@ extern Datum Float8GetDatum(float8 X);
 /*
  * Int64GetDatumFast
  * Float8GetDatumFast
+ * Float4GetDatumFast
  *
  * These macros are intended to allow writing code that does not depend on
- * whether int64, float8 are pass-by-reference types, while not
+ * whether int64, float8, float4 are pass-by-reference types, while not
  * sacrificing performance when they are.  The argument must be a variable
  * that will exist and have the same value for as long as the Datum is needed.
  * In the pass-by-ref case, the address of the variable is taken to use as
@@ -591,8 +617,19 @@ extern Datum Float8GetDatum(float8 X);
  * macros.
  */
 
+#ifdef USE_FLOAT8_BYVAL
+#define Int64GetDatumFast(X)  Int64GetDatum(X)
+#define Float8GetDatumFast(X) Float8GetDatum(X)
+#else
 #define Int64GetDatumFast(X)  PointerGetDatum(&(X))
 #define Float8GetDatumFast(X) PointerGetDatum(&(X))
+#endif
+
+#ifdef USE_FLOAT4_BYVAL
+#define Float4GetDatumFast(X) Float4GetDatum(X)
+#else
+#define Float4GetDatumFast(X) PointerGetDatum(&(X))
+#endif
 
 
 /* ----------------------------------------------------------------
index bf0e33e..0085b64 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Copyright (c) 1998-2008, PostgreSQL Global Development Group
  *
- * $PostgreSQL: pgsql/src/include/tsearch/ts_utils.h,v 1.13 2008/03/25 22:42:45 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/tsearch/ts_utils.h,v 1.14 2008/04/21 00:26:47 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -178,6 +178,11 @@ typedef uint64 TSQuerySign;
 
 #define TSQS_SIGLEN  (sizeof(TSQuerySign)*BITS_PER_BYTE)
 
+#define TSQuerySignGetDatum(X)         Int64GetDatum((int64) (X))
+#define DatumGetTSQuerySign(X)         ((TSQuerySign) DatumGetInt64(X))
+#define PG_RETURN_TSQUERYSIGN(X)       return TSQuerySignGetDatum(X)
+#define PG_GETARG_TSQUERYSIGN(n)       DatumGetTSQuerySign(PG_GETARG_DATUM(n))
+
 
 extern QTNode *QT2QTN(QueryItem *in, char *operand);
 extern TSQuery QTN2QT(QTNode *in);
index c58ae72..808a086 100644 (file)
 
 typedef int64 Cash;
 
+/* Cash is pass-by-reference if and only if int64 is */
+#define DatumGetCash(X)                ((Cash) DatumGetInt64(X))
+#define CashGetDatum(X)                Int64GetDatum(X)
+#define PG_GETARG_CASH(n)      DatumGetCash(PG_GETARG_DATUM(n))
+#define PG_RETURN_CASH(x)      return CashGetDatum(x)
+
 extern Datum cash_in(PG_FUNCTION_ARGS);
 extern Datum cash_out(PG_FUNCTION_ARGS);
 extern Datum cash_recv(PG_FUNCTION_ARGS);
index 9323532..48b5146 100644 (file)
@@ -31,7 +31,8 @@ FROM pg_type as p1
 WHERE p1.typbyval AND
     (p1.typlen != 1 OR p1.typalign != 'c') AND
     (p1.typlen != 2 OR p1.typalign != 's') AND
-    (p1.typlen != 4 OR p1.typalign != 'i');
+    (p1.typlen != 4 OR p1.typalign != 'i') AND
+    (p1.typlen != 8 OR p1.typalign != 'd');
  oid | typname 
 -----+---------
 (0 rows)
index 44a150a..e28fcca 100644 (file)
@@ -32,7 +32,8 @@ FROM pg_type as p1
 WHERE p1.typbyval AND
     (p1.typlen != 1 OR p1.typalign != 'c') AND
     (p1.typlen != 2 OR p1.typalign != 's') AND
-    (p1.typlen != 4 OR p1.typalign != 'i');
+    (p1.typlen != 4 OR p1.typalign != 'i') AND
+    (p1.typlen != 8 OR p1.typalign != 'd');
 
 -- Look for "toastable" types that aren't varlena.
 
index 69b1371..d8fe302 100644 (file)
@@ -11,7 +11,7 @@
 #
 #
 # IDENTIFICATION
-#    $PostgreSQL: pgsql/src/tools/msvc/Genbki.pm,v 1.3 2008/01/01 19:46:01 momjian Exp $
+#    $PostgreSQL: pgsql/src/tools/msvc/Genbki.pm,v 1.4 2008/04/21 00:26:47 tgl Exp $
 #
 #-------------------------------------------------------------------------
 
@@ -38,6 +38,14 @@ sub genbki
       || die "Could not read NAMEDATALEN from pg_config_manual.h\n";
     my $namedatalen = $1;
 
+    my $pgconf = read_file("src/include/pg_config.h");
+    $pgconf =~ /^#define\s+FLOAT4PASSBYVAL\s+(\w+)$/mg
+      || die "Could not read FLOAT4PASSBYVAL from pg_config.h\n";
+    my $float4passbyval = $1;
+    $pgconf =~ /^#define\s+FLOAT8PASSBYVAL\s+(\w+)$/mg
+      || die "Could not read FLOAT8PASSBYVAL from pg_config.h\n";
+    my $float8passbyval = $1;
+
     my $pgauthid = read_file("src/include/catalog/pg_authid.h");
     $pgauthid =~ /^#define\s+BOOTSTRAP_SUPERUSERID\s+(\d+)$/mg
       || die "Could not read BOOTSTRAUP_SUPERUSERID from pg_authid.h\n";
@@ -71,6 +79,8 @@ sub genbki
     $indata =~ s{\(TransactionId}{(xid}g;
     $indata =~ s{PGUID}{$bootstrapsuperuserid}g;
     $indata =~ s{NAMEDATALEN}{$namedatalen}g;
+    $indata =~ s{FLOAT4PASSBYVAL}{$float4passbyval}g;
+    $indata =~ s{FLOAT8PASSBYVAL}{$float8passbyval}g;
     $indata =~ s{PGNSP}{$pgcatalognamespace}g;
 
     #print $indata;