mirror of
https://github.com/postgres/postgres.git
synced 2025-07-28 23:42:10 +03:00
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.
This commit is contained in:
@ -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));
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
Reference in New Issue
Block a user