diff --git a/configure b/configure index e9f6302e7e9dea8bf437b42ff7395e5d164601af..d4d20f0eca8dee2fcea9d3af0c3499564403e103 100755 --- 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 diff --git a/configure.in b/configure.in index 56bdfd9ac5198543cb326caf7d65a4d6678c6a89..dd832477d9863a29aacb210539d1f77ed89ed6b1 100644 --- a/configure.in +++ b/configure.in @@ -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) diff --git a/contrib/btree_gist/btree_cash.c b/contrib/btree_gist/btree_cash.c index eb618754d9aaefccca41377e4f4c763ab798e70e..17edd023091fc9f6f5fff66b31a1a9f6378a770d 100644 --- a/contrib/btree_gist/btree_cash.c +++ b/contrib/btree_gist/btree_cash.c @@ -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); diff --git a/contrib/btree_gist/btree_time.c b/contrib/btree_gist/btree_time.c index 6c1ec80a314264d7ccbbe57f1dd2686478d1f5be..0d2c2cf10ea6715c3ca156d06d4c588bc8a378ea 100644 --- a/contrib/btree_gist/btree_time.c +++ b/contrib/btree_gist/btree_time.c @@ -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)); diff --git a/contrib/btree_gist/btree_ts.c b/contrib/btree_gist/btree_ts.c index 606a986a70db0f2d7600982cb59376aee7ebeaef..32451244b50ada0f3fbdf909235bd77697b21280 100644 --- a/contrib/btree_gist/btree_ts.c +++ b/contrib/btree_gist/btree_ts.c @@ -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) diff --git a/contrib/btree_gist/btree_utils_num.c b/contrib/btree_gist/btree_utils_num.c index c7b41f16c1e2c6a80f9cb06efed72d9c8bf8dac2..5e227196b6577b38eb281c3f33ba3f2dd1013947 100644 --- a/contrib/btree_gist/btree_utils_num.c +++ b/contrib/btree_gist/btree_utils_num.c @@ -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); diff --git a/doc/src/sgml/installation.sgml b/doc/src/sgml/installation.sgml index e0de70e91f1ea9fdcb911bfbac44b41dfa2382c7..0fad43d701c1fa949190fe24b7e598ebc24715d5 100644 --- a/doc/src/sgml/installation.sgml +++ b/doc/src/sgml/installation.sgml @@ -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</>]]> @@ -1032,6 +1032,40 @@ su - postgres </listitem> </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> diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c index bb8f3d4761f37cfb847467dd3b50dc6591cc0f1f..33c912ebaa45a745e9701d626b8fc3ce0987493f 100644 --- a/src/backend/access/transam/xlog.c +++ b/src/backend/access/transam/xlog.c @@ -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"), diff --git a/src/backend/bootstrap/bootstrap.c b/src/backend/bootstrap/bootstrap.c index a5c013bd6c68fd9cdcf29ce2f762ecf05bd7e89a..48eb355a8a9f7fe895c8a25dc628496c64891633 100644 --- a/src/backend/bootstrap/bootstrap.c +++ b/src/backend/bootstrap/bootstrap.c @@ -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}, diff --git a/src/backend/catalog/genbki.sh b/src/backend/catalog/genbki.sh index 045377115fa3150db3db820aeef69f6bb780bce5..a07af451670660872e167d2b5bdb8d021123dede 100644 --- a/src/backend/catalog/genbki.sh +++ b/src/backend/catalog/genbki.sh @@ -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 ' # ---------------- diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index 0363b213a9c805832ad10fb9ab2ef2e08c6945dd..a120463c60e5b5bbaaa671f0b30ab1442875fd31 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -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 diff --git a/src/backend/optimizer/plan/planagg.c b/src/backend/optimizer/plan/planagg.c index 5bb92111f6065035a9758f81014cac061c743c54..ef13f164cd3a8370e85fdcc16939fbf69a40363e 100644 --- a/src/backend/optimizer/plan/planagg.c +++ b/src/backend/optimizer/plan/planagg.c @@ -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 diff --git a/src/backend/parser/parse_node.c b/src/backend/parser/parse_node.c index 8c96813a3f99e9baa6c0368cc03a20f64b294245..c13996711c352e926ffab151d54e80ec74dd746e 100644 --- a/src/backend/parser/parse_node.c +++ b/src/backend/parser/parse_node.c @@ -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 diff --git a/src/backend/utils/adt/cash.c b/src/backend/utils/adt/cash.c index 84e8c742ec5f19354d6b1a4cff748fe8cac394bc..befa27f9bb8b81eddc2bb0765b2a4f44d27f2eab 100644 --- a/src/backend/utils/adt/cash.c +++ b/src/backend/utils/adt/cash.c @@ -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" @@ -34,14 +34,6 @@ #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. diff --git a/src/backend/utils/adt/float.c b/src/backend/utils/adt/float.c index 2f1e262ea7ad315b89cf4b413e73a494c245ba49..2ee2455089e3f2186853f52d564ff706e5af8946 100644 --- a/src/backend/utils/adt/float.c +++ b/src/backend/utils/adt/float.c @@ -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); } diff --git a/src/backend/utils/adt/int8.c b/src/backend/utils/adt/int8.c index 3391769cd433fb1291be86192fc4994a1b8e5e04..6f3f9e2105529c373f3568779e1047f4d71a73df 100644 --- a/src/backend/utils/adt/int8.c +++ b/src/backend/utils/adt/int8.c @@ -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); diff --git a/src/backend/utils/adt/numeric.c b/src/backend/utils/adt/numeric.c index 86765d5d5325f686046f46d152625f181a1df303..c5801ade2a06cc2163c85c24766489ea7cc154a1 100644 --- a/src/backend/utils/adt/numeric.c +++ b/src/backend/utils/adt/numeric.c @@ -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); diff --git a/src/backend/utils/adt/tsquery_gist.c b/src/backend/utils/adt/tsquery_gist.c index 52ba7716ffffdf5c5aac3d4508128708af91c60b..7124fe1529f294e4354497e24afad912675ef5ec 100644 --- a/src/backend/utils/adt/tsquery_gist.c +++ b/src/backend/utils/adt/tsquery_gist.c @@ -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); } diff --git a/src/backend/utils/fmgr/README b/src/backend/utils/fmgr/README index 63990ca1587bcaca47e9ffe116f8f985306c3966..730830a84ce738273e5ff50e29cf5ef5313e28da 100644 --- a/src/backend/utils/fmgr/README +++ b/src/backend/utils/fmgr/README @@ -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 diff --git a/src/backend/utils/fmgr/fmgr.c b/src/backend/utils/fmgr/fmgr.c index 853fb9eda93f4bdc37e78a8fd48a788d1c44d15e..5a0a22ce199b759e91e2ed901fa6ac4089879770 100644 --- a/src/backend/utils/fmgr/fmgr.c +++ b/src/backend/utils/fmgr/fmgr.c @@ -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 *------------------------------------------------------------------------- diff --git a/src/backend/utils/init/flatfiles.c b/src/backend/utils/init/flatfiles.c index 2cc1831dff7a47351199d3a4ae4ef66023dbd6b2..747c34e90b98fe414380999c859d482456725f69 100644 --- a/src/backend/utils/init/flatfiles.c +++ b/src/backend/utils/init/flatfiles.c @@ -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))); } /* diff --git a/src/bin/pg_controldata/pg_controldata.c b/src/bin/pg_controldata/pg_controldata.c index ea712654d8337161395704f412c49531c94343d7..122ef37996a04ab42d5172672a4ef101645a35db 100644 --- a/src/bin/pg_controldata/pg_controldata.c +++ b/src/bin/pg_controldata/pg_controldata.c @@ -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"), diff --git a/src/bin/pg_resetxlog/pg_resetxlog.c b/src/bin/pg_resetxlog/pg_resetxlog.c index 86c4463a2ce7ea5f00f11d89779253100051caf5..109fec7facfb950900dafa2cc9d902c71f9b4ab2 100644 --- a/src/bin/pg_resetxlog/pg_resetxlog.c +++ b/src/bin/pg_resetxlog/pg_resetxlog.c @@ -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"), diff --git a/src/include/c.h b/src/include/c.h index e2697099cbd91262eb6bb0e19d2401db5d13f58a..86b0d9f9997cdaeadb68ce24709023cdb9030270 100644 --- a/src/include/c.h +++ b/src/include/c.h @@ -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 $ * *------------------------------------------------------------------------- */ @@ -248,22 +248,6 @@ typedef uint8 bits8; /* >= 8 bits */ 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 */ diff --git a/src/include/catalog/catversion.h b/src/include/catalog/catversion.h index 83c0dbd36940e16a13bb813265bc1b72afb5932e..041194ff0b955871736ecbc0f4a4b3e8a9d4499e 100644 --- a/src/include/catalog/catversion.h +++ b/src/include/catalog/catversion.h @@ -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 diff --git a/src/include/catalog/pg_attribute.h b/src/include/catalog/pg_attribute.h index 08b18da37d6486b14b7c8e65adfa9507f3b0365e..1378f109f6ef2d3764075331f0de25b2c3e746db 100644 --- a/src/include/catalog/pg_attribute.h +++ b/src/include/catalog/pg_attribute.h @@ -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)); diff --git a/src/include/catalog/pg_control.h b/src/include/catalog/pg_control.h index e61faed987646c6eb9f7cba12bf9d84c26685fee..4f789e9af97a6b58a0b7899547d85aad1b9c1370 100644 --- a/src/include/catalog/pg_control.h +++ b/src/include/catalog/pg_control.h @@ -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; diff --git a/src/include/catalog/pg_type.h b/src/include/catalog/pg_type.h index 2c98f2b5466362d2f64c6a77cd0554089ae44f53..5687332e2a90c5e1d07416bb8a53eaebee089507 100644 --- a/src/include/catalog/pg_type.h +++ b/src/include/catalog/pg_type.h @@ -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_ )); diff --git a/src/include/fmgr.h b/src/include/fmgr.h index 07bce55ee1f066ab80f6acf110db54f04a376273..ec3261b081a7a3e6a592e345fdcf6d641ae4df0c 100644 --- a/src/include/fmgr.h +++ b/src/include/fmgr.h @@ -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 \ } /* diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in index 24b7c0dc86dc0b11e563985b575a271c1688329a..caaf626d747aa3251f6f1f9a04c034faa1ffc3a1 100644 --- a/src/include/pg_config.h.in +++ b/src/include/pg_config.h.in @@ -49,6 +49,13 @@ (--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 @@ -665,6 +672,14 @@ /* 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 diff --git a/src/include/postgres.h b/src/include/postgres.h index 40ecd451a850c3d4cfdc6144aa6764b290ae1232..ae8a4421ed48572a5069c02e45b16288fbcfc7e9 100644 --- a/src/include/postgres.h +++ b/src/include/postgres.h @@ -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 /* ---------------------------------------------------------------- diff --git a/src/include/tsearch/ts_utils.h b/src/include/tsearch/ts_utils.h index bf0e33e58c06c7999b48dcfd2232bc1ff527f3f0..0085b64951a885b346dfea58687606dcbe6b07d8 100644 --- a/src/include/tsearch/ts_utils.h +++ b/src/include/tsearch/ts_utils.h @@ -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); diff --git a/src/include/utils/cash.h b/src/include/utils/cash.h index c58ae72563b9506878ffd49ebe1ba3601b931fbe..808a08643f7e1f4b404c3d2716c3058f81bcdf2d 100644 --- a/src/include/utils/cash.h +++ b/src/include/utils/cash.h @@ -13,6 +13,12 @@ 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); diff --git a/src/test/regress/expected/type_sanity.out b/src/test/regress/expected/type_sanity.out index 932353238d7988305b2672faf0a5e70badcdd6b1..48b51466061ab0b745895c159b113283bf604586 100644 --- a/src/test/regress/expected/type_sanity.out +++ b/src/test/regress/expected/type_sanity.out @@ -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) diff --git a/src/test/regress/sql/type_sanity.sql b/src/test/regress/sql/type_sanity.sql index 44a150a3179dac85e06a8e5592cd0bef80d5590e..e28fccab6c92c86dbf868bc69ade321fa07274b5 100644 --- a/src/test/regress/sql/type_sanity.sql +++ b/src/test/regress/sql/type_sanity.sql @@ -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. diff --git a/src/tools/msvc/Genbki.pm b/src/tools/msvc/Genbki.pm index 69b1371e6f82ae9973d6003b04c1e106a7a4ddd2..d8fe3027961ded55471b506946b782f69327ceed 100644 --- a/src/tools/msvc/Genbki.pm +++ b/src/tools/msvc/Genbki.pm @@ -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;