Commit 8472bf7a authored by Tom Lane's avatar Tom Lane

Allow float8, int8, and related datatypes to be passed by value on machines

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.
parent be939544
......@@ -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
......
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)
......
......@@ -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);
......
......@@ -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));
......
#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)
......
#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);
......
<!-- $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>
......
......@@ -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"),
......
......@@ -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},
......
......@@ -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 '
# ----------------
......
......@@ -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
......
......@@ -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
......
......@@ -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
......
......@@ -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.
......
......@@ -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);
}
......
......@@ -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);
......
......@@ -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);
......
......@@ -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);
}
$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
......
......@@ -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
*-------------------------------------------------------------------------
......
......@@ -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)));
}
/*
......
......@@ -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"),
......
......@@ -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"),
......
......@@ -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
*/
......
......@@ -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
......@@ -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));
......
......@@ -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;
......
......@@ -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_ ));
......
......@@ -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 \
}
/*
......
......@@ -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
......
......@@ -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
/* ----------------------------------------------------------------
......
......@@ -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);
......
......@@ -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);
......
......@@ -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)
......
......@@ -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.
......
......@@ -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;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment