Skip to content

Commit 6febecc

Browse files
committed
Clean up att_align calculations so that XXXALIGN macros
need not be bogus.
1 parent d471f80 commit 6febecc

File tree

5 files changed

+117
-136
lines changed

5 files changed

+117
-136
lines changed

src/backend/bootstrap/bootstrap.c

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Copyright (c) 1994, Regents of the University of California
88
*
99
* IDENTIFICATION
10-
* $Header: /cvsroot/pgsql/src/backend/bootstrap/bootstrap.c,v 1.56 1999/03/17 22:52:45 momjian Exp $
10+
* $Header: /cvsroot/pgsql/src/backend/bootstrap/bootstrap.c,v 1.57 1999/03/25 03:49:25 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -605,8 +605,28 @@ DefineAttr(char *name, char *type, int attnum)
605605
printf("<%s %s> ", attrtypes[attnum]->attname.data, type);
606606
attrtypes[attnum]->attnum = 1 + attnum; /* fillatt */
607607
attlen = attrtypes[attnum]->attlen = Procid[typeoid].len;
608-
attrtypes[attnum]->attbyval = (attlen == 1) || (attlen == 2) || (attlen == 4);
609-
attrtypes[attnum]->attalign = 'i';
608+
/* Cheat like mad to fill in these items from the length only.
609+
* This only has to work for types used in the system catalogs...
610+
*/
611+
switch (attlen)
612+
{
613+
case 1:
614+
attrtypes[attnum]->attbyval = true;
615+
attrtypes[attnum]->attalign = 'c';
616+
break;
617+
case 2:
618+
attrtypes[attnum]->attbyval = true;
619+
attrtypes[attnum]->attalign = 's';
620+
break;
621+
case 4:
622+
attrtypes[attnum]->attbyval = true;
623+
attrtypes[attnum]->attalign = 'i';
624+
break;
625+
default:
626+
attrtypes[attnum]->attbyval = false;
627+
attrtypes[attnum]->attalign = 'i';
628+
break;
629+
}
610630
}
611631
attrtypes[attnum]->attcacheoff = -1;
612632
attrtypes[attnum]->atttypmod = -1;

src/include/access/tupmacs.h

Lines changed: 13 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
*
77
* Copyright (c) 1994, Regents of the University of California
88
*
9-
* $Id: tupmacs.h,v 1.8 1999/02/13 23:20:59 momjian Exp $
9+
* $Id: tupmacs.h,v 1.9 1999/03/25 03:49:26 tgl Exp $
1010
*
1111
*-------------------------------------------------------------------------
1212
*/
@@ -62,43 +62,22 @@
6262
(char *) (T) \
6363
)
6464

65+
/* att_align aligns the given offset as needed for a datum of length attlen
66+
* and alignment requirement attalign. In practice we don't need the length.
67+
* The attalign cases are tested in what is hopefully something like their
68+
* frequency of occurrence.
69+
*/
6570
#define att_align(cur_offset, attlen, attalign) \
6671
( \
67-
((attlen) < sizeof(int32)) ? \
68-
( \
69-
((attlen) == -1) ? \
70-
( \
71-
((attalign) == 'd') ? DOUBLEALIGN(cur_offset) : \
72-
INTALIGN(cur_offset) \
73-
) \
74-
: \
75-
( \
76-
((attlen) == sizeof(char)) ? \
77-
( \
78-
(long)(cur_offset) \
79-
) \
80-
: \
81-
( \
82-
AssertMacro((attlen) == sizeof(short)), \
83-
SHORTALIGN(cur_offset) \
84-
) \
85-
) \
86-
) \
87-
: \
88-
( \
89-
((attlen) == sizeof(int32)) ? \
90-
( \
91-
INTALIGN(cur_offset) \
92-
) \
93-
: \
72+
((attalign) == 'i') ? INTALIGN(cur_offset) : \
73+
(((attalign) == 'c') ? ((long)(cur_offset)) : \
74+
(((attalign) == 'd') ? DOUBLEALIGN(cur_offset) : \
9475
( \
95-
AssertMacro((attlen) > sizeof(int32)), \
96-
((attalign) == 'd') ? DOUBLEALIGN(cur_offset) : \
97-
LONGALIGN(cur_offset) \
98-
) \
99-
) \
76+
AssertMacro((attalign) == 's'), \
77+
SHORTALIGN(cur_offset) \
78+
))) \
10079
)
101-
80+
10281
#define att_addlength(cur_offset, attlen, attval) \
10382
( \
10483
((attlen) != -1) ? \

src/include/catalog/pg_type.h

Lines changed: 41 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*
88
* Copyright (c) 1994, Regents of the University of California
99
*
10-
* $Id: pg_type.h,v 1.55 1999/03/10 05:02:34 tgl Exp $
10+
* $Id: pg_type.h,v 1.56 1999/03/25 03:49:25 tgl Exp $
1111
*
1212
* NOTES
1313
* the genbki.sh script reads this file and generates .bki
@@ -21,7 +21,7 @@
2121
#include <utils/rel.h>
2222

2323
/* ----------------
24-
* postgres.h contains the system type definintions and the
24+
* postgres.h contains the system type definitions and the
2525
* CATALOG(), BOOTSTRAP and DATA() sugar words so this file
2626
* can be read by both genbki.sh and the C compiler.
2727
* ----------------
@@ -53,44 +53,38 @@ CATALOG(pg_type) BOOTSTRAP
5353

5454
/*
5555
* typbyval determines whether internal Postgres routines pass a value
56-
* of this type by value or by reference. Postgres uses a 4 byte area
57-
* for passing a field value info, so if the value is not 1, 2, or 4
58-
* bytes long, Postgres does not have the option of passing by value
59-
* and ignores typbyval.
60-
*
61-
* (I don't understand why this column exists. The above description may
62-
* be an oversimplification. Also, there appear to be bugs in which
63-
* Postgres doesn't ignore typbyval when it should, but I'm afraid to
64-
* change them until I see proof of damage. -BRYANH 96.08).
65-
*
66-
* (Postgres crashes if typbyval is true, the declared length is 8, and
67-
* the I/O routines are written to expect pass by reference. Note that
68-
* float4 is written for pass by reference and has a declared length
69-
* of 4 bytes, so it looks like pass by reference must be consistant
70-
* with the declared length, and typbyval is used somewhere. - tgl
71-
* 1997-03-20).
56+
* of this type by value or by reference. Only char, short, and int-
57+
* equivalent items can be passed by value, so if the type is not
58+
* 1, 2, or 4 bytes long, Postgres does not have the option of passing
59+
* by value and so typbyval had better be FALSE. Variable-length types
60+
* are always passed by reference.
61+
* Note that typbyval can be false even if the length would allow
62+
* pass-by-value; this is currently true for type float4, for example.
7263
*/
7364
char typtype;
65+
66+
/*
67+
* typtype is 'b' for a basic type and 'c' for a catalog type (ie a class).
68+
* If typtype is 'c', typrelid is the OID of the class' entry in pg_class.
69+
* (Why do we need an entry in pg_type for classes, anyway?)
70+
*/
7471
bool typisdefined;
7572
char typdelim;
76-
Oid typrelid;
73+
Oid typrelid; /* 0 if not a class type */
7774
Oid typelem;
7875

7976
/*
80-
* typelem is NULL if this is not an array type. If this is an array
77+
* typelem is 0 if this is not an array type. If this is an array
8178
* type, typelem is the OID of the type of the elements of the array
8279
* (it identifies another row in Table pg_type).
83-
*
84-
* (Note that zero ("0") rather than _null_ is used in the declarations.
85-
* - tgl 97/03/20)
8680
*/
8781
regproc typinput;
8882
regproc typoutput;
8983
regproc typreceive;
9084
regproc typsend;
9185
char typalign;
9286

93-
/*
87+
/* ----------------
9488
* typalign is the alignment required when storing a value of this
9589
* type. It applies to storage on disk as well as most
9690
* representations of the value inside Postgres. When multiple values
@@ -99,11 +93,18 @@ CATALOG(pg_type) BOOTSTRAP
9993
* type so that it begins on the specified boundary. The alignment
10094
* reference is the beginning of the first datum in the sequence.
10195
*
102-
* 'c' = 1 byte alignment. 's' = 2 byte alignment. 'i' = 4 byte
103-
* alignment. 'd' = 8 byte alignment.
96+
* 'c' = CHAR alignment, ie no alignment needed.
97+
* 's' = SHORT alignment (2 bytes on most machines).
98+
* 'i' = INT alignment (4 bytes on most machines).
99+
* 'd' = DOUBLE alignment (8 bytes on many machines, but by no means all).
100+
*
101+
* See include/utils/memutils.h for the macros that compute these
102+
* alignment requirements.
104103
*
105-
* (This might actually be flexible depending on machine architecture,
106-
* but I doubt it - BRYANH 96.08).
104+
* NOTE: for types used in system tables, it is critical that the
105+
* size and alignment defined in pg_type agree with the way that the
106+
* compiler will lay out the field in a struct representing a table row.
107+
* ----------------
107108
*/
108109
text typdefault; /* VARIABLE LENGTH FIELD */
109110
} FormData_pg_type;
@@ -218,21 +219,21 @@ DESCR("array of 8 oid, used in system tables");
218219
DATA(insert OID = 32 ( SET PGUID -1 -1 f r t \054 0 -1 textin textout textin textout i _null_ ));
219220
DESCR("set of tuples");
220221

221-
DATA(insert OID = 71 ( pg_type PGUID -1 -1 t b t \054 1247 0 foo bar foo bar c _null_));
222-
DATA(insert OID = 75 ( pg_attribute PGUID -1 -1 t b t \054 1249 0 foo bar foo bar c _null_));
223-
DATA(insert OID = 81 ( pg_proc PGUID -1 -1 t b t \054 1255 0 foo bar foo bar c _null_));
224-
DATA(insert OID = 83 ( pg_class PGUID -1 -1 t b t \054 1259 0 foo bar foo bar c _null_));
225-
DATA(insert OID = 86 ( pg_shadow PGUID -1 -1 t b t \054 1260 0 foo bar foo bar c _null_));
226-
DATA(insert OID = 87 ( pg_group PGUID -1 -1 t b t \054 1261 0 foo bar foo bar c _null_));
227-
DATA(insert OID = 88 ( pg_database PGUID -1 -1 t b t \054 1262 0 foo bar foo bar c _null_));
228-
DATA(insert OID = 90 ( pg_variable PGUID -1 -1 t b t \054 1264 0 foo bar foo bar c _null_));
229-
DATA(insert OID = 99 ( pg_log PGUID -1 -1 t b t \054 1269 0 foo bar foo bar c _null_));
222+
DATA(insert OID = 71 ( pg_type PGUID 4 4 t c t \054 1247 0 foo bar foo bar i _null_));
223+
DATA(insert OID = 75 ( pg_attribute PGUID 4 4 t c t \054 1249 0 foo bar foo bar i _null_));
224+
DATA(insert OID = 81 ( pg_proc PGUID 4 4 t c t \054 1255 0 foo bar foo bar i _null_));
225+
DATA(insert OID = 83 ( pg_class PGUID 4 4 t c t \054 1259 0 foo bar foo bar i _null_));
226+
DATA(insert OID = 86 ( pg_shadow PGUID 4 4 t c t \054 1260 0 foo bar foo bar i _null_));
227+
DATA(insert OID = 87 ( pg_group PGUID 4 4 t c t \054 1261 0 foo bar foo bar i _null_));
228+
DATA(insert OID = 88 ( pg_database PGUID 4 4 t c t \054 1262 0 foo bar foo bar i _null_));
229+
DATA(insert OID = 90 ( pg_variable PGUID 4 4 t c t \054 1264 0 foo bar foo bar i _null_));
230+
DATA(insert OID = 99 ( pg_log PGUID 4 4 t c t \054 1269 0 foo bar foo bar i _null_));
230231

231232
/* OIDS 100 - 199 */
232233

233-
DATA(insert OID = 109 ( pg_attrdef PGUID -1 -1 t b t \054 1215 0 foo bar foo bar c _null_));
234-
DATA(insert OID = 110 ( pg_relcheck PGUID -1 -1 t b t \054 1216 0 foo bar foo bar c _null_));
235-
DATA(insert OID = 111 ( pg_trigger PGUID -1 -1 t b t \054 1219 0 foo bar foo bar c _null_));
234+
DATA(insert OID = 109 ( pg_attrdef PGUID 4 4 t c t \054 1215 0 foo bar foo bar i _null_));
235+
DATA(insert OID = 110 ( pg_relcheck PGUID 4 4 t c t \054 1216 0 foo bar foo bar i _null_));
236+
DATA(insert OID = 111 ( pg_trigger PGUID 4 4 t c t \054 1219 0 foo bar foo bar i _null_));
236237

237238
/* OIDS 200 - 299 */
238239

src/include/postgres.h

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
*
77
* Copyright (c) 1995, Regents of the University of California
88
*
9-
* $Id: postgres.h,v 1.20 1999/02/13 23:20:46 momjian Exp $
9+
* $Id: postgres.h,v 1.21 1999/03/25 03:49:28 tgl Exp $
1010
*
1111
*-------------------------------------------------------------------------
1212
*/
@@ -92,9 +92,14 @@ typedef struct varlena text;
9292
typedef int2 int28[8];
9393
typedef Oid oid8[8];
9494

95-
typedef struct nameData
95+
/* We want NameData to have length NAMEDATALEN and int alignment,
96+
* because that's how the data type 'name' is defined in pg_type.
97+
* Use a union to make sure the compiler agrees.
98+
*/
99+
typedef union nameData
96100
{
97101
char data[NAMEDATALEN];
102+
int alignmentDummy;
98103
} NameData;
99104
typedef NameData *Name;
100105

src/include/utils/memutils.h

Lines changed: 33 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
*
1616
* Copyright (c) 1994, Regents of the University of California
1717
*
18-
* $Id: memutils.h,v 1.21 1999/02/13 23:22:25 momjian Exp $
18+
* $Id: memutils.h,v 1.22 1999/03/25 03:49:34 tgl Exp $
1919
*
2020
* NOTES
2121
* some of the information in this file will be moved to
@@ -27,76 +27,52 @@
2727
#define MEMUTILS_H
2828

2929

30-
#ifdef NOT_USED
31-
/*****************************************************************************
32-
* align.h - alignment macros *
33-
****************************************************************************
34-
[TRH] Let the compiler decide what alignment it uses instead of
35-
tending
36-
we know better.
37-
GCC (at least v2.5.8 and up) has an __alignof__ keyword.
38-
However, we cannot use it here since on some architectures it reports
39-
just a _recommended_ alignment instead of the actual alignment used in
40-
padding structures (or at least, this is how I understand gcc).
41-
So define a macro that gives us the _actual_ alignment inside a struct.
42-
{{note: assumes that alignment size is always a power of 2.}}
30+
/* ----------------
31+
* Alignment macros: align a length or address appropriately for a given type.
32+
*
33+
* It'd be best to use offsetof to check how the compiler aligns stuff,
34+
* but not all compilers support that (still true)? So we make the
35+
* conservative assumption that a type must be aligned on a boundary equal
36+
* to its own size, except on a few architectures where we know better.
37+
*
38+
* CAUTION: for the system tables, the struct declarations found in
39+
* src/include/pg_*.h had better be interpreted by the compiler in a way
40+
* that agrees with the workings of these macros. In practice that means
41+
* being careful to lay out the columns of a system table in a way that avoids
42+
* wasted pad space.
43+
*
44+
* CAUTION: _ALIGN will not work if sizeof(TYPE) is not a power of 2.
45+
* There are machines where sizeof(double) is not, for example.
46+
* But such a size is almost certainly not an alignment boundary anyway.
47+
* ----------------
4348
*/
44-
#define _ALIGNSIZE(TYPE) offsetof(struct { char __c; TYPE __t;}, __t)
45-
#define _ALIGN(TYPE, LEN) \
46-
(((long)(LEN) + (_ALIGNSIZE(TYPE) - 1)) & ~(_ALIGNSIZE(TYPE) - 1))
47-
#define SHORTALIGN(LEN) _ALIGN(short, (LEN))
48-
#define INTALIGN(LEN) _ALIGN(int, (LEN))
49-
#define LONGALIGN(LEN) _ALIGN(long, (LEN))
50-
#define DOUBLEALIGN(LEN) _ALIGN(double, (LEN))
51-
#define MAXALIGN(LEN) _ALIGN(double, (LEN))
5249

53-
#endif /* 0 */
50+
#define _ALIGN(TYPE,LEN) \
51+
(((long)(LEN) + (sizeof(TYPE) - 1)) & ~(sizeof(TYPE) - 1))
5452

55-
/*
56-
* SHORTALIGN(LEN) - length (or address) aligned for shorts
57-
*/
58-
#define SHORTALIGN(LEN)\
59-
(((long)(LEN) + (sizeof (short) - 1)) & ~(sizeof (short) - 1))
53+
#define SHORTALIGN(LEN) _ALIGN(short, (LEN))
6054

6155
#if defined(m68k)
62-
#define INTALIGN(LEN) SHORTALIGN(LEN)
56+
#define INTALIGN(LEN) _ALIGN(short, (LEN))
6357
#else
64-
#define INTALIGN(LEN)\
65-
(((long)(LEN) + (sizeof (int) - 1)) & ~(sizeof (int) -1))
58+
#define INTALIGN(LEN) _ALIGN(int, (LEN))
6659
#endif
6760

68-
/*
69-
* LONGALIGN(LEN) - length (or address) aligned for longs
70-
*/
7161
#if (defined(sun) && ! defined(sparc)) || defined(m68k)
72-
#define LONGALIGN(LEN) SHORTALIGN(LEN)
73-
#elif defined (__alpha)
74-
75-
/*
76-
* even though "long alignment" should really be on 8-byte boundaries for
77-
* linuxalpha, we want the strictest alignment to be on 4-byte (int)
78-
* boundaries, because otherwise things break when they try to use the
79-
* FormData_pg_* structures. --djm 12/12/96
80-
*/
81-
#define LONGALIGN(LEN)\
82-
(((long)(LEN) + (sizeof (int) - 1)) & ~(sizeof (int) -1))
62+
#define LONGALIGN(LEN) _ALIGN(short, (LEN))
8363
#else
84-
#define LONGALIGN(LEN)\
85-
(((long)(LEN) + (sizeof (long) - 1)) & ~(sizeof (long) -1))
64+
#define LONGALIGN(LEN) _ALIGN(long, (LEN))
8665
#endif
8766

8867
#if defined(m68k)
89-
#define DOUBLEALIGN(LEN) SHORTALIGN(LEN)
90-
#define MAXALIGN(LEN) SHORTALIGN(LEN)
91-
#elif ! defined(sco)
92-
#define DOUBLEALIGN(LEN)\
93-
(((long)(LEN) + (sizeof (double) - 1)) & ~(sizeof (double) -1))
94-
95-
#define MAXALIGN(LEN)\
96-
(((long)(LEN) + (sizeof (double) - 1)) & ~(sizeof (double) -1))
68+
#define DOUBLEALIGN(LEN) _ALIGN(short, (LEN))
69+
#define MAXALIGN(LEN) _ALIGN(short, (LEN))
70+
#elif defined(sco)
71+
#define DOUBLEALIGN(LEN) _ALIGN(int, (LEN))
72+
#define MAXALIGN(LEN) _ALIGN(int, (LEN))
9773
#else
98-
#define DOUBLEALIGN(LEN) INTALIGN(LEN)
99-
#define MAXALIGN(LEN) INTALIGN(LEN)
74+
#define DOUBLEALIGN(LEN) _ALIGN(double, (LEN))
75+
#define MAXALIGN(LEN) _ALIGN(double, (LEN))
10076
#endif
10177

10278
/*****************************************************************************

0 commit comments

Comments
 (0)