diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2008-04-21 00:26:47 +0000 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2008-04-21 00:26:47 +0000 |
commit | 8472bf7a73487b0535c95e299773b882f7523463 (patch) | |
tree | f8cf1ad8529e819aec4d93cdcbf848996f4e3680 /src/backend/utils | |
parent | be939544a68f852107c912da2f35f5d36958deb2 (diff) | |
download | postgresql-8472bf7a73487b0535c95e299773b882f7523463.tar.gz postgresql-8472bf7a73487b0535c95e299773b882f7523463.zip |
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.
Diffstat (limited to 'src/backend/utils')
-rw-r--r-- | src/backend/utils/adt/cash.c | 19 | ||||
-rw-r--r-- | src/backend/utils/adt/float.c | 9 | ||||
-rw-r--r-- | src/backend/utils/adt/int8.c | 20 | ||||
-rw-r--r-- | src/backend/utils/adt/numeric.c | 14 | ||||
-rw-r--r-- | src/backend/utils/adt/tsquery_gist.c | 73 | ||||
-rw-r--r-- | src/backend/utils/fmgr/README | 35 | ||||
-rw-r--r-- | src/backend/utils/fmgr/fmgr.c | 62 | ||||
-rw-r--r-- | src/backend/utils/init/flatfiles.c | 15 |
8 files changed, 140 insertions, 107 deletions
diff --git a/src/backend/utils/adt/cash.c b/src/backend/utils/adt/cash.c index 84e8c742ec5..befa27f9bb8 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 2f1e262ea7a..2ee2455089e 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 3391769cd43..6f3f9e21055 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 86765d5d532..c5801ade2a0 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 52ba7716fff..7124fe1529f 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 63990ca1587..730830a84ce 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 853fb9eda93..5a0a22ce199 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 2cc1831dff7..747c34e90b9 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))); } /* |