Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 3e23b68

Browse files
committed
Support varlena fields with single-byte headers and unaligned storage.
This commit breaks any code that assumes that the mere act of forming a tuple (without writing it to disk) does not "toast" any fields. While all available regression tests pass, I'm not totally sure that we've fixed every nook and cranny, especially in contrib. Greg Stark with some help from Tom Lane
1 parent d441639 commit 3e23b68

38 files changed

+1806
-809
lines changed

configure

+231-1
Original file line numberDiff line numberDiff line change
@@ -11143,7 +11143,237 @@ fi
1114311143
## Types, structures, compiler characteristics
1114411144
##
1114511145

11146-
echo "$as_me:$LINENO: checking for an ANSI C-conforming const" >&5
11146+
echo "$as_me:$LINENO: checking whether byte ordering is bigendian" >&5
11147+
echo $ECHO_N "checking whether byte ordering is bigendian... $ECHO_C" >&6
11148+
if test "${ac_cv_c_bigendian+set}" = set; then
11149+
echo $ECHO_N "(cached) $ECHO_C" >&6
11150+
else
11151+
# See if sys/param.h defines the BYTE_ORDER macro.
11152+
cat >conftest.$ac_ext <<_ACEOF
11153+
/* confdefs.h. */
11154+
_ACEOF
11155+
cat confdefs.h >>conftest.$ac_ext
11156+
cat >>conftest.$ac_ext <<_ACEOF
11157+
/* end confdefs.h. */
11158+
#include <sys/types.h>
11159+
#include <sys/param.h>
11160+
11161+
int
11162+
main ()
11163+
{
11164+
#if !BYTE_ORDER || !BIG_ENDIAN || !LITTLE_ENDIAN
11165+
bogus endian macros
11166+
#endif
11167+
11168+
;
11169+
return 0;
11170+
}
11171+
_ACEOF
11172+
rm -f conftest.$ac_objext
11173+
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
11174+
(eval $ac_compile) 2>conftest.er1
11175+
ac_status=$?
11176+
grep -v '^ *+' conftest.er1 >conftest.err
11177+
rm -f conftest.er1
11178+
cat conftest.err >&5
11179+
echo "$as_me:$LINENO: \$? = $ac_status" >&5
11180+
(exit $ac_status); } &&
11181+
{ ac_try='test -z "$ac_c_werror_flag"
11182+
|| test ! -s conftest.err'
11183+
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
11184+
(eval $ac_try) 2>&5
11185+
ac_status=$?
11186+
echo "$as_me:$LINENO: \$? = $ac_status" >&5
11187+
(exit $ac_status); }; } &&
11188+
{ ac_try='test -s conftest.$ac_objext'
11189+
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
11190+
(eval $ac_try) 2>&5
11191+
ac_status=$?
11192+
echo "$as_me:$LINENO: \$? = $ac_status" >&5
11193+
(exit $ac_status); }; }; then
11194+
# It does; now see whether it defined to BIG_ENDIAN or not.
11195+
cat >conftest.$ac_ext <<_ACEOF
11196+
/* confdefs.h. */
11197+
_ACEOF
11198+
cat confdefs.h >>conftest.$ac_ext
11199+
cat >>conftest.$ac_ext <<_ACEOF
11200+
/* end confdefs.h. */
11201+
#include <sys/types.h>
11202+
#include <sys/param.h>
11203+
11204+
int
11205+
main ()
11206+
{
11207+
#if BYTE_ORDER != BIG_ENDIAN
11208+
not big endian
11209+
#endif
11210+
11211+
;
11212+
return 0;
11213+
}
11214+
_ACEOF
11215+
rm -f conftest.$ac_objext
11216+
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
11217+
(eval $ac_compile) 2>conftest.er1
11218+
ac_status=$?
11219+
grep -v '^ *+' conftest.er1 >conftest.err
11220+
rm -f conftest.er1
11221+
cat conftest.err >&5
11222+
echo "$as_me:$LINENO: \$? = $ac_status" >&5
11223+
(exit $ac_status); } &&
11224+
{ ac_try='test -z "$ac_c_werror_flag"
11225+
|| test ! -s conftest.err'
11226+
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
11227+
(eval $ac_try) 2>&5
11228+
ac_status=$?
11229+
echo "$as_me:$LINENO: \$? = $ac_status" >&5
11230+
(exit $ac_status); }; } &&
11231+
{ ac_try='test -s conftest.$ac_objext'
11232+
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
11233+
(eval $ac_try) 2>&5
11234+
ac_status=$?
11235+
echo "$as_me:$LINENO: \$? = $ac_status" >&5
11236+
(exit $ac_status); }; }; then
11237+
ac_cv_c_bigendian=yes
11238+
else
11239+
echo "$as_me: failed program was:" >&5
11240+
sed 's/^/| /' conftest.$ac_ext >&5
11241+
11242+
ac_cv_c_bigendian=no
11243+
fi
11244+
rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
11245+
else
11246+
echo "$as_me: failed program was:" >&5
11247+
sed 's/^/| /' conftest.$ac_ext >&5
11248+
11249+
# It does not; compile a test program.
11250+
if test "$cross_compiling" = yes; then
11251+
# try to guess the endianness by grepping values into an object file
11252+
ac_cv_c_bigendian=unknown
11253+
cat >conftest.$ac_ext <<_ACEOF
11254+
/* confdefs.h. */
11255+
_ACEOF
11256+
cat confdefs.h >>conftest.$ac_ext
11257+
cat >>conftest.$ac_ext <<_ACEOF
11258+
/* end confdefs.h. */
11259+
short ascii_mm[] = { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 };
11260+
short ascii_ii[] = { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 };
11261+
void _ascii () { char *s = (char *) ascii_mm; s = (char *) ascii_ii; }
11262+
short ebcdic_ii[] = { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 };
11263+
short ebcdic_mm[] = { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 };
11264+
void _ebcdic () { char *s = (char *) ebcdic_mm; s = (char *) ebcdic_ii; }
11265+
int
11266+
main ()
11267+
{
11268+
_ascii (); _ebcdic ();
11269+
;
11270+
return 0;
11271+
}
11272+
_ACEOF
11273+
rm -f conftest.$ac_objext
11274+
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
11275+
(eval $ac_compile) 2>conftest.er1
11276+
ac_status=$?
11277+
grep -v '^ *+' conftest.er1 >conftest.err
11278+
rm -f conftest.er1
11279+
cat conftest.err >&5
11280+
echo "$as_me:$LINENO: \$? = $ac_status" >&5
11281+
(exit $ac_status); } &&
11282+
{ ac_try='test -z "$ac_c_werror_flag"
11283+
|| test ! -s conftest.err'
11284+
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
11285+
(eval $ac_try) 2>&5
11286+
ac_status=$?
11287+
echo "$as_me:$LINENO: \$? = $ac_status" >&5
11288+
(exit $ac_status); }; } &&
11289+
{ ac_try='test -s conftest.$ac_objext'
11290+
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
11291+
(eval $ac_try) 2>&5
11292+
ac_status=$?
11293+
echo "$as_me:$LINENO: \$? = $ac_status" >&5
11294+
(exit $ac_status); }; }; then
11295+
if grep BIGenDianSyS conftest.$ac_objext >/dev/null ; then
11296+
ac_cv_c_bigendian=yes
11297+
fi
11298+
if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then
11299+
if test "$ac_cv_c_bigendian" = unknown; then
11300+
ac_cv_c_bigendian=no
11301+
else
11302+
# finding both strings is unlikely to happen, but who knows?
11303+
ac_cv_c_bigendian=unknown
11304+
fi
11305+
fi
11306+
else
11307+
echo "$as_me: failed program was:" >&5
11308+
sed 's/^/| /' conftest.$ac_ext >&5
11309+
11310+
fi
11311+
rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
11312+
else
11313+
cat >conftest.$ac_ext <<_ACEOF
11314+
/* confdefs.h. */
11315+
_ACEOF
11316+
cat confdefs.h >>conftest.$ac_ext
11317+
cat >>conftest.$ac_ext <<_ACEOF
11318+
/* end confdefs.h. */
11319+
int
11320+
main ()
11321+
{
11322+
/* Are we little or big endian? From Harbison&Steele. */
11323+
union
11324+
{
11325+
long l;
11326+
char c[sizeof (long)];
11327+
} u;
11328+
u.l = 1;
11329+
exit (u.c[sizeof (long) - 1] == 1);
11330+
}
11331+
_ACEOF
11332+
rm -f conftest$ac_exeext
11333+
if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
11334+
(eval $ac_link) 2>&5
11335+
ac_status=$?
11336+
echo "$as_me:$LINENO: \$? = $ac_status" >&5
11337+
(exit $ac_status); } && { ac_try='./conftest$ac_exeext'
11338+
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
11339+
(eval $ac_try) 2>&5
11340+
ac_status=$?
11341+
echo "$as_me:$LINENO: \$? = $ac_status" >&5
11342+
(exit $ac_status); }; }; then
11343+
ac_cv_c_bigendian=no
11344+
else
11345+
echo "$as_me: program exited with status $ac_status" >&5
11346+
echo "$as_me: failed program was:" >&5
11347+
sed 's/^/| /' conftest.$ac_ext >&5
11348+
11349+
( exit $ac_status )
11350+
ac_cv_c_bigendian=yes
11351+
fi
11352+
rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
11353+
fi
11354+
fi
11355+
rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
11356+
fi
11357+
echo "$as_me:$LINENO: result: $ac_cv_c_bigendian" >&5
11358+
echo "${ECHO_T}$ac_cv_c_bigendian" >&6
11359+
case $ac_cv_c_bigendian in
11360+
yes)
11361+
11362+
cat >>confdefs.h <<\_ACEOF
11363+
#define WORDS_BIGENDIAN 1
11364+
_ACEOF
11365+
;;
11366+
no)
11367+
;;
11368+
*)
11369+
{ { echo "$as_me:$LINENO: error: unknown endianness
11370+
presetting ac_cv_c_bigendian=no (or yes) will help" >&5
11371+
echo "$as_me: error: unknown endianness
11372+
presetting ac_cv_c_bigendian=no (or yes) will help" >&2;}
11373+
{ (exit 1); exit 1; }; } ;;
11374+
esac
11375+
11376+
echo "$as_me:$LINENO: checking for an ANSI C-conforming const" >&5
1114711377
echo $ECHO_N "checking for an ANSI C-conforming const... $ECHO_C" >&6
1114811378
if test "${ac_cv_c_const+set}" = set; then
1114911379
echo $ECHO_N "(cached) $ECHO_C" >&6

configure.in

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
dnl Process this file with autoconf to produce a configure script.
2-
dnl $PostgreSQL: pgsql/configure.in,v 1.507 2007/03/29 15:30:51 mha Exp $
2+
dnl $PostgreSQL: pgsql/configure.in,v 1.508 2007/04/06 04:21:41 tgl Exp $
33
dnl
44
dnl Developers, please strive to achieve this order:
55
dnl
@@ -869,6 +869,7 @@ fi
869869
##
870870

871871
m4_defun([AC_PROG_CC_STDC], []) dnl We don't want that.
872+
AC_C_BIGENDIAN
872873
AC_C_CONST
873874
AC_C_INLINE
874875
AC_C_STRINGIZE

contrib/dblink/dblink.c

+3-3
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
* Darko Prenosil <Darko.Prenosil@finteh.hr>
99
* Shridhar Daithankar <shridhar_daithankar@persistent.co.in>
1010
*
11-
* $PostgreSQL: pgsql/contrib/dblink/dblink.c,v 1.62 2007/02/07 00:52:35 petere Exp $
11+
* $PostgreSQL: pgsql/contrib/dblink/dblink.c,v 1.63 2007/04/06 04:21:41 tgl Exp $
1212
* Copyright (c) 2001-2007, PostgreSQL Global Development Group
1313
* ALL RIGHTS RESERVED;
1414
*
@@ -1752,8 +1752,8 @@ get_text_array_contents(ArrayType *array, int *numitems)
17521752
{
17531753
values[i] = DatumGetCString(DirectFunctionCall1(textout,
17541754
PointerGetDatum(ptr)));
1755-
ptr = att_addlength(ptr, typlen, PointerGetDatum(ptr));
1756-
ptr = (char *) att_align(ptr, typalign);
1755+
ptr = att_addlength_pointer(ptr, typlen, ptr);
1756+
ptr = (char *) att_align_nominal(ptr, typalign);
17571757
}
17581758

17591759
/* advance bitmap pointer if any */

contrib/hstore/hstore_gist.c

+19-1
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,25 @@ ghstore_compress(PG_FUNCTION_ARGS)
170170
Datum
171171
ghstore_decompress(PG_FUNCTION_ARGS)
172172
{
173-
PG_RETURN_DATUM(PG_GETARG_DATUM(0));
173+
GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
174+
GISTENTRY *retval;
175+
HStore *key;
176+
177+
key = (HStore *) PG_DETOAST_DATUM(entry->key);
178+
179+
if (key != (HStore *) DatumGetPointer(entry->key))
180+
{
181+
/* need to pass back the decompressed item */
182+
retval = palloc(sizeof(GISTENTRY));
183+
gistentryinit(*retval, PointerGetDatum(key),
184+
entry->rel, entry->page, entry->offset, entry->leafkey);
185+
PG_RETURN_POINTER(retval);
186+
}
187+
else
188+
{
189+
/* we can return the entry as-is */
190+
PG_RETURN_POINTER(entry);
191+
}
174192
}
175193

176194
Datum

contrib/intarray/_int_gist.c

+9
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,16 @@ g_int_decompress(PG_FUNCTION_ARGS)
232232

233233
CHECKARRVALID(in);
234234
if (ARRISVOID(in))
235+
{
236+
if (in != (ArrayType *) DatumGetPointer(entry->key)) {
237+
retval = palloc(sizeof(GISTENTRY));
238+
gistentryinit(*retval, PointerGetDatum(in),
239+
entry->rel, entry->page, entry->offset, FALSE);
240+
PG_RETURN_POINTER(retval);
241+
}
242+
235243
PG_RETURN_POINTER(entry);
244+
}
236245

237246
lenin = ARRNELEMS(in);
238247

contrib/pg_trgm/trgm_gist.c

+20-2
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ gtrgm_compress(PG_FUNCTION_ARGS)
9797
if (entry->leafkey)
9898
{ /* trgm */
9999
TRGM *res;
100-
text *val = (text *) DatumGetPointer(PG_DETOAST_DATUM(entry->key));
100+
text *val = DatumGetTextP(entry->key);
101101

102102
res = generate_trgm(VARDATA(val), VARSIZE(val) - VARHDRSZ);
103103
retval = (GISTENTRY *) palloc(sizeof(GISTENTRY));
@@ -134,7 +134,25 @@ gtrgm_compress(PG_FUNCTION_ARGS)
134134
Datum
135135
gtrgm_decompress(PG_FUNCTION_ARGS)
136136
{
137-
PG_RETURN_DATUM(PG_GETARG_DATUM(0));
137+
GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
138+
GISTENTRY *retval;
139+
text *key;
140+
141+
key = DatumGetTextP(entry->key);
142+
143+
if (key != (text *) DatumGetPointer(entry->key))
144+
{
145+
/* need to pass back the decompressed item */
146+
retval = palloc(sizeof(GISTENTRY));
147+
gistentryinit(*retval, PointerGetDatum(key),
148+
entry->rel, entry->page, entry->offset, entry->leafkey);
149+
PG_RETURN_POINTER(retval);
150+
}
151+
else
152+
{
153+
/* we can return the entry as-is */
154+
PG_RETURN_POINTER(entry);
155+
}
138156
}
139157

140158
Datum

contrib/tsearch2/ts_cfg.c

+1-3
Original file line numberDiff line numberDiff line change
@@ -62,9 +62,7 @@ init_cfg(Oid id, TSCfgInfo * cfg)
6262
ts_error(ERROR, "SPI_execp return %d", stat);
6363
if (SPI_processed > 0)
6464
{
65-
prsname = (text *) DatumGetPointer(
66-
SPI_getbinval(SPI_tuptable->vals[0], SPI_tuptable->tupdesc, 1, &isnull)
67-
);
65+
prsname = DatumGetTextP(SPI_getbinval(SPI_tuptable->vals[0], SPI_tuptable->tupdesc, 1, &isnull));
6866
oldcontext = MemoryContextSwitchTo(TopMemoryContext);
6967
prsname = ptextdup(prsname);
7068
MemoryContextSwitchTo(oldcontext);

0 commit comments

Comments
 (0)