aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>1999-03-25 03:49:34 +0000
committerTom Lane <tgl@sss.pgh.pa.us>1999-03-25 03:49:34 +0000
commit6febecc569f42817b7b86a167a38e682317a6c2c (patch)
tree7dddca9d4e5e9ddde660f11042738a007b591eee /src
parentd471f8073a51a7769efad581e017e7c0fd5e9e84 (diff)
downloadpostgresql-6febecc569f42817b7b86a167a38e682317a6c2c.tar.gz
postgresql-6febecc569f42817b7b86a167a38e682317a6c2c.zip
Clean up att_align calculations so that XXXALIGN macros
need not be bogus.
Diffstat (limited to 'src')
-rw-r--r--src/backend/bootstrap/bootstrap.c26
-rw-r--r--src/include/access/tupmacs.h47
-rw-r--r--src/include/catalog/pg_type.h81
-rw-r--r--src/include/postgres.h9
-rw-r--r--src/include/utils/memutils.h90
5 files changed, 117 insertions, 136 deletions
diff --git a/src/backend/bootstrap/bootstrap.c b/src/backend/bootstrap/bootstrap.c
index eacb0129f6b..c4cb0df1c56 100644
--- a/src/backend/bootstrap/bootstrap.c
+++ b/src/backend/bootstrap/bootstrap.c
@@ -7,7 +7,7 @@
* Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/bootstrap/bootstrap.c,v 1.56 1999/03/17 22:52:45 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/bootstrap/bootstrap.c,v 1.57 1999/03/25 03:49:25 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -605,8 +605,28 @@ DefineAttr(char *name, char *type, int attnum)
printf("<%s %s> ", attrtypes[attnum]->attname.data, type);
attrtypes[attnum]->attnum = 1 + attnum; /* fillatt */
attlen = attrtypes[attnum]->attlen = Procid[typeoid].len;
- attrtypes[attnum]->attbyval = (attlen == 1) || (attlen == 2) || (attlen == 4);
- attrtypes[attnum]->attalign = 'i';
+ /* Cheat like mad to fill in these items from the length only.
+ * This only has to work for types used in the system catalogs...
+ */
+ switch (attlen)
+ {
+ case 1:
+ attrtypes[attnum]->attbyval = true;
+ attrtypes[attnum]->attalign = 'c';
+ break;
+ case 2:
+ attrtypes[attnum]->attbyval = true;
+ attrtypes[attnum]->attalign = 's';
+ break;
+ case 4:
+ attrtypes[attnum]->attbyval = true;
+ attrtypes[attnum]->attalign = 'i';
+ break;
+ default:
+ attrtypes[attnum]->attbyval = false;
+ attrtypes[attnum]->attalign = 'i';
+ break;
+ }
}
attrtypes[attnum]->attcacheoff = -1;
attrtypes[attnum]->atttypmod = -1;
diff --git a/src/include/access/tupmacs.h b/src/include/access/tupmacs.h
index c9cb759221b..6dd499c60b9 100644
--- a/src/include/access/tupmacs.h
+++ b/src/include/access/tupmacs.h
@@ -6,7 +6,7 @@
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: tupmacs.h,v 1.8 1999/02/13 23:20:59 momjian Exp $
+ * $Id: tupmacs.h,v 1.9 1999/03/25 03:49:26 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -62,43 +62,22 @@
(char *) (T) \
)
+/* att_align aligns the given offset as needed for a datum of length attlen
+ * and alignment requirement attalign. In practice we don't need the length.
+ * The attalign cases are tested in what is hopefully something like their
+ * frequency of occurrence.
+ */
#define att_align(cur_offset, attlen, attalign) \
( \
- ((attlen) < sizeof(int32)) ? \
- ( \
- ((attlen) == -1) ? \
- ( \
- ((attalign) == 'd') ? DOUBLEALIGN(cur_offset) : \
- INTALIGN(cur_offset) \
- ) \
- : \
- ( \
- ((attlen) == sizeof(char)) ? \
- ( \
- (long)(cur_offset) \
- ) \
- : \
- ( \
- AssertMacro((attlen) == sizeof(short)), \
- SHORTALIGN(cur_offset) \
- ) \
- ) \
- ) \
- : \
- ( \
- ((attlen) == sizeof(int32)) ? \
- ( \
- INTALIGN(cur_offset) \
- ) \
- : \
+ ((attalign) == 'i') ? INTALIGN(cur_offset) : \
+ (((attalign) == 'c') ? ((long)(cur_offset)) : \
+ (((attalign) == 'd') ? DOUBLEALIGN(cur_offset) : \
( \
- AssertMacro((attlen) > sizeof(int32)), \
- ((attalign) == 'd') ? DOUBLEALIGN(cur_offset) : \
- LONGALIGN(cur_offset) \
- ) \
- ) \
+ AssertMacro((attalign) == 's'), \
+ SHORTALIGN(cur_offset) \
+ ))) \
)
-
+
#define att_addlength(cur_offset, attlen, attval) \
( \
((attlen) != -1) ? \
diff --git a/src/include/catalog/pg_type.h b/src/include/catalog/pg_type.h
index a185a1912d4..2abfa643032 100644
--- a/src/include/catalog/pg_type.h
+++ b/src/include/catalog/pg_type.h
@@ -7,7 +7,7 @@
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: pg_type.h,v 1.55 1999/03/10 05:02:34 tgl Exp $
+ * $Id: pg_type.h,v 1.56 1999/03/25 03:49:25 tgl Exp $
*
* NOTES
* the genbki.sh script reads this file and generates .bki
@@ -21,7 +21,7 @@
#include <utils/rel.h>
/* ----------------
- * postgres.h contains the system type definintions and the
+ * postgres.h contains the system type definitions and the
* CATALOG(), BOOTSTRAP and DATA() sugar words so this file
* can be read by both genbki.sh and the C compiler.
* ----------------
@@ -53,36 +53,30 @@ CATALOG(pg_type) BOOTSTRAP
/*
* typbyval determines whether internal Postgres routines pass a value
- * of this type by value or by reference. Postgres uses a 4 byte area
- * for passing a field value info, so if the value is not 1, 2, or 4
- * bytes long, Postgres does not have the option of passing by value
- * and ignores typbyval.
- *
- * (I don't understand why this column exists. The above description may
- * be an oversimplification. Also, there appear to be bugs in which
- * Postgres doesn't ignore typbyval when it should, but I'm afraid to
- * change them until I see proof of damage. -BRYANH 96.08).
- *
- * (Postgres crashes if typbyval is true, the declared length is 8, and
- * the I/O routines are written to expect pass by reference. Note that
- * float4 is written for pass by reference and has a declared length
- * of 4 bytes, so it looks like pass by reference must be consistant
- * with the declared length, and typbyval is used somewhere. - tgl
- * 1997-03-20).
+ * of this type by value or by reference. Only char, short, and int-
+ * equivalent items can be passed by value, so if the type is not
+ * 1, 2, or 4 bytes long, Postgres does not have the option of passing
+ * by value and so typbyval had better be FALSE. Variable-length types
+ * are always passed by reference.
+ * Note that typbyval can be false even if the length would allow
+ * pass-by-value; this is currently true for type float4, for example.
*/
char typtype;
+
+ /*
+ * typtype is 'b' for a basic type and 'c' for a catalog type (ie a class).
+ * If typtype is 'c', typrelid is the OID of the class' entry in pg_class.
+ * (Why do we need an entry in pg_type for classes, anyway?)
+ */
bool typisdefined;
char typdelim;
- Oid typrelid;
+ Oid typrelid; /* 0 if not a class type */
Oid typelem;
/*
- * typelem is NULL if this is not an array type. If this is an array
+ * typelem is 0 if this is not an array type. If this is an array
* type, typelem is the OID of the type of the elements of the array
* (it identifies another row in Table pg_type).
- *
- * (Note that zero ("0") rather than _null_ is used in the declarations.
- * - tgl 97/03/20)
*/
regproc typinput;
regproc typoutput;
@@ -90,7 +84,7 @@ CATALOG(pg_type) BOOTSTRAP
regproc typsend;
char typalign;
- /*
+ /* ----------------
* typalign is the alignment required when storing a value of this
* type. It applies to storage on disk as well as most
* representations of the value inside Postgres. When multiple values
@@ -99,11 +93,18 @@ CATALOG(pg_type) BOOTSTRAP
* type so that it begins on the specified boundary. The alignment
* reference is the beginning of the first datum in the sequence.
*
- * 'c' = 1 byte alignment. 's' = 2 byte alignment. 'i' = 4 byte
- * alignment. 'd' = 8 byte alignment.
+ * 'c' = CHAR alignment, ie no alignment needed.
+ * 's' = SHORT alignment (2 bytes on most machines).
+ * 'i' = INT alignment (4 bytes on most machines).
+ * 'd' = DOUBLE alignment (8 bytes on many machines, but by no means all).
+ *
+ * See include/utils/memutils.h for the macros that compute these
+ * alignment requirements.
*
- * (This might actually be flexible depending on machine architecture,
- * but I doubt it - BRYANH 96.08).
+ * NOTE: for types used in system tables, it is critical that the
+ * size and alignment defined in pg_type agree with the way that the
+ * compiler will lay out the field in a struct representing a table row.
+ * ----------------
*/
text typdefault; /* VARIABLE LENGTH FIELD */
} FormData_pg_type;
@@ -218,21 +219,21 @@ DESCR("array of 8 oid, used in system tables");
DATA(insert OID = 32 ( SET PGUID -1 -1 f r t \054 0 -1 textin textout textin textout i _null_ ));
DESCR("set of tuples");
-DATA(insert OID = 71 ( pg_type PGUID -1 -1 t b t \054 1247 0 foo bar foo bar c _null_));
-DATA(insert OID = 75 ( pg_attribute PGUID -1 -1 t b t \054 1249 0 foo bar foo bar c _null_));
-DATA(insert OID = 81 ( pg_proc PGUID -1 -1 t b t \054 1255 0 foo bar foo bar c _null_));
-DATA(insert OID = 83 ( pg_class PGUID -1 -1 t b t \054 1259 0 foo bar foo bar c _null_));
-DATA(insert OID = 86 ( pg_shadow PGUID -1 -1 t b t \054 1260 0 foo bar foo bar c _null_));
-DATA(insert OID = 87 ( pg_group PGUID -1 -1 t b t \054 1261 0 foo bar foo bar c _null_));
-DATA(insert OID = 88 ( pg_database PGUID -1 -1 t b t \054 1262 0 foo bar foo bar c _null_));
-DATA(insert OID = 90 ( pg_variable PGUID -1 -1 t b t \054 1264 0 foo bar foo bar c _null_));
-DATA(insert OID = 99 ( pg_log PGUID -1 -1 t b t \054 1269 0 foo bar foo bar c _null_));
+DATA(insert OID = 71 ( pg_type PGUID 4 4 t c t \054 1247 0 foo bar foo bar i _null_));
+DATA(insert OID = 75 ( pg_attribute PGUID 4 4 t c t \054 1249 0 foo bar foo bar i _null_));
+DATA(insert OID = 81 ( pg_proc PGUID 4 4 t c t \054 1255 0 foo bar foo bar i _null_));
+DATA(insert OID = 83 ( pg_class PGUID 4 4 t c t \054 1259 0 foo bar foo bar i _null_));
+DATA(insert OID = 86 ( pg_shadow PGUID 4 4 t c t \054 1260 0 foo bar foo bar i _null_));
+DATA(insert OID = 87 ( pg_group PGUID 4 4 t c t \054 1261 0 foo bar foo bar i _null_));
+DATA(insert OID = 88 ( pg_database PGUID 4 4 t c t \054 1262 0 foo bar foo bar i _null_));
+DATA(insert OID = 90 ( pg_variable PGUID 4 4 t c t \054 1264 0 foo bar foo bar i _null_));
+DATA(insert OID = 99 ( pg_log PGUID 4 4 t c t \054 1269 0 foo bar foo bar i _null_));
/* OIDS 100 - 199 */
-DATA(insert OID = 109 ( pg_attrdef PGUID -1 -1 t b t \054 1215 0 foo bar foo bar c _null_));
-DATA(insert OID = 110 ( pg_relcheck PGUID -1 -1 t b t \054 1216 0 foo bar foo bar c _null_));
-DATA(insert OID = 111 ( pg_trigger PGUID -1 -1 t b t \054 1219 0 foo bar foo bar c _null_));
+DATA(insert OID = 109 ( pg_attrdef PGUID 4 4 t c t \054 1215 0 foo bar foo bar i _null_));
+DATA(insert OID = 110 ( pg_relcheck PGUID 4 4 t c t \054 1216 0 foo bar foo bar i _null_));
+DATA(insert OID = 111 ( pg_trigger PGUID 4 4 t c t \054 1219 0 foo bar foo bar i _null_));
/* OIDS 200 - 299 */
diff --git a/src/include/postgres.h b/src/include/postgres.h
index ed625cd07d0..ab57059295f 100644
--- a/src/include/postgres.h
+++ b/src/include/postgres.h
@@ -6,7 +6,7 @@
*
* Copyright (c) 1995, Regents of the University of California
*
- * $Id: postgres.h,v 1.20 1999/02/13 23:20:46 momjian Exp $
+ * $Id: postgres.h,v 1.21 1999/03/25 03:49:28 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -92,9 +92,14 @@ typedef struct varlena text;
typedef int2 int28[8];
typedef Oid oid8[8];
-typedef struct nameData
+/* We want NameData to have length NAMEDATALEN and int alignment,
+ * because that's how the data type 'name' is defined in pg_type.
+ * Use a union to make sure the compiler agrees.
+ */
+typedef union nameData
{
char data[NAMEDATALEN];
+ int alignmentDummy;
} NameData;
typedef NameData *Name;
diff --git a/src/include/utils/memutils.h b/src/include/utils/memutils.h
index 2d25f2ebdc9..58db49693ee 100644
--- a/src/include/utils/memutils.h
+++ b/src/include/utils/memutils.h
@@ -15,7 +15,7 @@
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: memutils.h,v 1.21 1999/02/13 23:22:25 momjian Exp $
+ * $Id: memutils.h,v 1.22 1999/03/25 03:49:34 tgl Exp $
*
* NOTES
* some of the information in this file will be moved to
@@ -27,76 +27,52 @@
#define MEMUTILS_H
-#ifdef NOT_USED
-/*****************************************************************************
- * align.h - alignment macros *
- ****************************************************************************
- [TRH] Let the compiler decide what alignment it uses instead of
-tending
- we know better.
- GCC (at least v2.5.8 and up) has an __alignof__ keyword.
- However, we cannot use it here since on some architectures it reports
- just a _recommended_ alignment instead of the actual alignment used in
- padding structures (or at least, this is how I understand gcc).
- So define a macro that gives us the _actual_ alignment inside a struct.
- {{note: assumes that alignment size is always a power of 2.}}
+/* ----------------
+ * Alignment macros: align a length or address appropriately for a given type.
+ *
+ * It'd be best to use offsetof to check how the compiler aligns stuff,
+ * but not all compilers support that (still true)? So we make the
+ * conservative assumption that a type must be aligned on a boundary equal
+ * to its own size, except on a few architectures where we know better.
+ *
+ * CAUTION: for the system tables, the struct declarations found in
+ * src/include/pg_*.h had better be interpreted by the compiler in a way
+ * that agrees with the workings of these macros. In practice that means
+ * being careful to lay out the columns of a system table in a way that avoids
+ * wasted pad space.
+ *
+ * CAUTION: _ALIGN will not work if sizeof(TYPE) is not a power of 2.
+ * There are machines where sizeof(double) is not, for example.
+ * But such a size is almost certainly not an alignment boundary anyway.
+ * ----------------
*/
-#define _ALIGNSIZE(TYPE) offsetof(struct { char __c; TYPE __t;}, __t)
-#define _ALIGN(TYPE, LEN) \
- (((long)(LEN) + (_ALIGNSIZE(TYPE) - 1)) & ~(_ALIGNSIZE(TYPE) - 1))
-#define SHORTALIGN(LEN) _ALIGN(short, (LEN))
-#define INTALIGN(LEN) _ALIGN(int, (LEN))
-#define LONGALIGN(LEN) _ALIGN(long, (LEN))
-#define DOUBLEALIGN(LEN) _ALIGN(double, (LEN))
-#define MAXALIGN(LEN) _ALIGN(double, (LEN))
-#endif /* 0 */
+#define _ALIGN(TYPE,LEN) \
+ (((long)(LEN) + (sizeof(TYPE) - 1)) & ~(sizeof(TYPE) - 1))
-/*
- * SHORTALIGN(LEN) - length (or address) aligned for shorts
- */
-#define SHORTALIGN(LEN)\
- (((long)(LEN) + (sizeof (short) - 1)) & ~(sizeof (short) - 1))
+#define SHORTALIGN(LEN) _ALIGN(short, (LEN))
#if defined(m68k)
-#define INTALIGN(LEN) SHORTALIGN(LEN)
+#define INTALIGN(LEN) _ALIGN(short, (LEN))
#else
-#define INTALIGN(LEN)\
- (((long)(LEN) + (sizeof (int) - 1)) & ~(sizeof (int) -1))
+#define INTALIGN(LEN) _ALIGN(int, (LEN))
#endif
-/*
- * LONGALIGN(LEN) - length (or address) aligned for longs
- */
#if (defined(sun) && ! defined(sparc)) || defined(m68k)
-#define LONGALIGN(LEN) SHORTALIGN(LEN)
-#elif defined (__alpha)
-
- /*
- * even though "long alignment" should really be on 8-byte boundaries for
- * linuxalpha, we want the strictest alignment to be on 4-byte (int)
- * boundaries, because otherwise things break when they try to use the
- * FormData_pg_* structures. --djm 12/12/96
- */
-#define LONGALIGN(LEN)\
- (((long)(LEN) + (sizeof (int) - 1)) & ~(sizeof (int) -1))
+#define LONGALIGN(LEN) _ALIGN(short, (LEN))
#else
-#define LONGALIGN(LEN)\
- (((long)(LEN) + (sizeof (long) - 1)) & ~(sizeof (long) -1))
+#define LONGALIGN(LEN) _ALIGN(long, (LEN))
#endif
#if defined(m68k)
-#define DOUBLEALIGN(LEN) SHORTALIGN(LEN)
-#define MAXALIGN(LEN) SHORTALIGN(LEN)
-#elif ! defined(sco)
-#define DOUBLEALIGN(LEN)\
- (((long)(LEN) + (sizeof (double) - 1)) & ~(sizeof (double) -1))
-
-#define MAXALIGN(LEN)\
- (((long)(LEN) + (sizeof (double) - 1)) & ~(sizeof (double) -1))
+#define DOUBLEALIGN(LEN) _ALIGN(short, (LEN))
+#define MAXALIGN(LEN) _ALIGN(short, (LEN))
+#elif defined(sco)
+#define DOUBLEALIGN(LEN) _ALIGN(int, (LEN))
+#define MAXALIGN(LEN) _ALIGN(int, (LEN))
#else
-#define DOUBLEALIGN(LEN) INTALIGN(LEN)
-#define MAXALIGN(LEN) INTALIGN(LEN)
+#define DOUBLEALIGN(LEN) _ALIGN(double, (LEN))
+#define MAXALIGN(LEN) _ALIGN(double, (LEN))
#endif
/*****************************************************************************