提交 e8b34fd4 编写于 作者: H Heikki Linnakangas

Backport patch to reduce alignment of "name" from int to char.

In the previous coding, if a "name" field in a struct, that was used for
direct access to a catalog tuple, i.e. Form_pg_*, was not accidentally
aligned to 4-byte boundary, the struct would not match what's stored on
disk. I was bit by this, when I tried changing the compresstype field
in pg_appendonly from text to name.

This seems like a good idea from an upgrade point of view too. This change
broke pg_upgrade for any tables that use the name datatype. That's not
a big deal, because it shouldn't be used in user tables at all anyway, but
might as well take the hit in 5.0 when the upgrade is expected to be more
painful anyway.

Original commit:

commit 5f6f840e
Author: Tom Lane <tgl@sss.pgh.pa.us>
Date:   Tue Jun 24 17:58:27 2008 +0000

    Reduce the alignment requirement of type "name" from int to char, and arrange
    to suppress zero-padding of "name" entries in indexes.

    The alignment change is unlikely to save any space, but it is really needed
    anyway to make the world safe for our widespread practice of passing plain
    old C strings to functions that are declared as taking Name.  In the previous
    coding, the C compiler was entitled to assume that a Name pointer was
    word-aligned; but we were failing to guarantee that.  I think the reason
    we'd not seen failures is that usually the only thing that gets done with
    such a pointer is strcmp(), which is hard to optimize in a way that exploits
    word-alignment.  Still, some enterprising compiler guy will probably think
    of a way eventually, or we might change our code in a way that exposes
    more-obvious optimization opportunities.

    The padding change is accomplished in one-liner fashion by declaring the
    "name" index opclasses to use storage type "cstring" in pg_opclass.h.
    Normally btree and hash don't allow a nondefault storage type, because they
    don't have any provisions for converting the input datum to another type.
    However, because name and cstring are effectively the same thing except for
    padding, no conversion is needed --- we only need index_form_tuple() to treat
    the datum as being cstring not name, and this is sufficient.  This seems to
    make for about a one-third reduction in the typical sizes of system catalog
    indexes that involve "name" columns, of which we have many.

    These two changes are only weakly related, but the alignment change makes
    me feel safer that the padding change won't introduce problems, so I'm
    committing them together.
上级 b03bce78
......@@ -132,7 +132,7 @@ static const struct typinfo TypInfo[] = {
F_INT4IN, F_INT4OUT},
{"float4", FLOAT4OID, 0, 4, FLOAT4PASSBYVAL, 'i', 'p',
F_FLOAT4IN, F_FLOAT4OUT},
{"name", NAMEOID, CHAROID, NAMEDATALEN, false, 'i', 'p',
{"name", NAMEOID, CHAROID, NAMEDATALEN, false, 'c', 'p',
F_NAMEIN, F_NAMEOUT},
{"regclass", REGCLASSOID, 0, 4, true, 'i', 'p',
F_REGCLASSIN, F_REGCLASSOUT},
......
......@@ -264,7 +264,7 @@ typedef FormData_pg_attribute *Form_pg_attribute;
* ----------------
*/
#define Schema_pg_type \
{ 1247, {"typname"}, 19, -1, NAMEDATALEN, 1, 0, -1, -1, false, 'p', 'i', true, false, false, true, 0 }, \
{ 1247, {"typname"}, 19, -1, NAMEDATALEN, 1, 0, -1, -1, false, 'p', 'c', true, false, false, true, 0 }, \
{ 1247, {"typnamespace"}, 26, -1, 4, 2, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \
{ 1247, {"typowner"}, 26, -1, 4, 3, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \
{ 1247, {"typlen"}, 21, -1, 2, 4, 0, -1, -1, true, 'p', 's', true, false, false, true, 0 }, \
......@@ -291,7 +291,7 @@ typedef FormData_pg_attribute *Form_pg_attribute;
{ 1247, {"typdefaultbin"}, 25, -1, -1, 25, 0, -1, -1, false, 'x', 'i', false, false, false, true, 0 }, \
{ 1247, {"typdefault"}, 25, -1, -1, 26, 0, -1, -1, false, 'x', 'i', false, false, false, true, 0 }
DATA(insert ( 1247 typname 19 -1 NAMEDATALEN 1 0 -1 -1 f p i t f f t 0));
DATA(insert ( 1247 typname 19 -1 NAMEDATALEN 1 0 -1 -1 f p c t f f t 0));
DATA(insert ( 1247 typnamespace 26 -1 4 2 0 -1 -1 t p i t f f t 0));
DATA(insert ( 1247 typowner 26 -1 4 3 0 -1 -1 t p i t f f t 0));
DATA(insert ( 1247 typlen 21 -1 2 4 0 -1 -1 t p s t f f t 0));
......@@ -331,7 +331,7 @@ DATA(insert ( 1247 gp_segment_id 23 0 4 -8 0 -1 -1 t p i t f f t 0));
* ----------------
*/
#define Schema_pg_proc \
{ 1255, {"proname"}, 19, -1, NAMEDATALEN, 1, 0, -1, -1, false, 'p', 'i', true, false, false, true, 0 }, \
{ 1255, {"proname"}, 19, -1, NAMEDATALEN, 1, 0, -1, -1, false, 'p', 'c', true, false, false, true, 0 }, \
{ 1255, {"pronamespace"}, 26, -1, 4, 2, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \
{ 1255, {"proowner"}, 26, -1, 4, 3, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \
{ 1255, {"prolang"}, 26, -1, 4, 4, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \
......@@ -358,7 +358,7 @@ DATA(insert ( 1247 gp_segment_id 23 0 4 -8 0 -1 -1 t p i t f f t 0));
{ 1255, {"proacl"}, 1034, -1, -1, 25, 1, -1, -1, false, 'x', 'i', false, false, false, true, 0 }, \
{ 1255, {"prodataaccess"}, 18, -1, 1, 26, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0 }
DATA(insert ( 1255 proname 19 -1 NAMEDATALEN 1 0 -1 -1 f p i t f f t 0));
DATA(insert ( 1255 proname 19 -1 NAMEDATALEN 1 0 -1 -1 f p c t f f t 0));
DATA(insert ( 1255 pronamespace 26 -1 4 2 0 -1 -1 t p i t f f t 0));
DATA(insert ( 1255 proowner 26 -1 4 3 0 -1 -1 t p i t f f t 0));
DATA(insert ( 1255 prolang 26 -1 4 4 0 -1 -1 t p i t f f t 0));
......@@ -399,7 +399,7 @@ DATA(insert ( 1255 gp_segment_id 23 0 4 -8 0 -1 -1 t p i t f f t 0));
*/
#define Schema_pg_attribute \
{ 1249, {"attrelid"}, 26, -1, 4, 1, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \
{ 1249, {"attname"}, 19, -1, NAMEDATALEN, 2, 0, -1, -1, false, 'p', 'i', true, false, false, true, 0 }, \
{ 1249, {"attname"}, 19, -1, NAMEDATALEN, 2, 0, -1, -1, false, 'p', 'c', true, false, false, true, 0 }, \
{ 1249, {"atttypid"}, 26, -1, 4, 3, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \
{ 1249, {"attstattarget"}, 23, -1, 4, 4, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \
{ 1249, {"attlen"}, 21, -1, 2, 5, 0, -1, -1, true, 'p', 's', true, false, false, true, 0 }, \
......@@ -417,7 +417,7 @@ DATA(insert ( 1255 gp_segment_id 23 0 4 -8 0 -1 -1 t p i t f f t 0));
{ 1249, {"attinhcount"}, 23, -1, 4, 17, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }
DATA(insert ( 1249 attrelid 26 -1 4 1 0 -1 -1 t p i t f f t 0));
DATA(insert ( 1249 attname 19 -1 NAMEDATALEN 2 0 -1 -1 f p i t f f t 0));
DATA(insert ( 1249 attname 19 -1 NAMEDATALEN 2 0 -1 -1 f p c t f f t 0));
DATA(insert ( 1249 atttypid 26 -1 4 3 0 -1 -1 t p i t f f t 0));
DATA(insert ( 1249 attstattarget 23 -1 4 4 0 -1 -1 t p i t f f t 0));
DATA(insert ( 1249 attlen 21 -1 2 5 0 -1 -1 t p s t f f t 0));
......@@ -447,7 +447,7 @@ DATA(insert ( 1249 gp_segment_id 23 0 4 -8 0 -1 -1 t p i t f f t 0));
* ----------------
*/
#define Schema_pg_class \
{ 1259, {"relname"}, 19, -1, NAMEDATALEN, 1, 0, -1, -1, false, 'p', 'i', true, false, false, true, 0 }, \
{ 1259, {"relname"}, 19, -1, NAMEDATALEN, 1, 0, -1, -1, false, 'p', 'c', true, false, false, true, 0 }, \
{ 1259, {"relnamespace"}, 26, -1, 4, 2, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \
{ 1259, {"reltype"}, 26, -1, 4, 3, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \
{ 1259, {"relowner"}, 26, -1, 4, 4, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \
......@@ -476,7 +476,7 @@ DATA(insert ( 1249 gp_segment_id 23 0 4 -8 0 -1 -1 t p i t f f t 0));
{ 1259, {"relacl"}, 1034, -1, -1, 27, 1, -1, -1, false, 'x', 'i', false, false, false, true, 0 }, \
{ 1259, {"reloptions"}, 1009, -1, -1, 28, 1, -1, -1, false, 'x', 'i', false, false, false, true, 0 }
DATA(insert ( 1259 relname 19 -1 NAMEDATALEN 1 0 -1 -1 f p i t f f t 0));
DATA(insert ( 1259 relname 19 -1 NAMEDATALEN 1 0 -1 -1 f p c t f f t 0));
DATA(insert ( 1259 relnamespace 26 -1 4 2 0 -1 -1 t p i t f f t 0));
DATA(insert ( 1259 reltype 26 -1 4 3 0 -1 -1 t p i t f f t 0));
DATA(insert ( 1259 relowner 26 -1 4 4 0 -1 -1 t p i t f f t 0));
......
......@@ -146,8 +146,15 @@ DATA(insert ( 403 interval_ops PGNSP PGUID 1982 1186 t 0 ));
DATA(insert ( 405 interval_ops PGNSP PGUID 1983 1186 t 0 ));
DATA(insert ( 403 macaddr_ops PGNSP PGUID 1984 829 t 0 ));
DATA(insert ( 405 macaddr_ops PGNSP PGUID 1985 829 t 0 ));
DATA(insert ( 403 name_ops PGNSP PGUID 1986 19 t 0 ));
DATA(insert ( 405 name_ops PGNSP PGUID 1987 19 t 0 ));
/*
* Here's an ugly little hack to save space in the system catalog indexes.
* btree and hash don't ordinarily allow a storage type different from input
* type; but cstring and name are the same thing except for trailing padding,
* and we can safely omit that within an index entry. So we declare the
* opclasses for name as using cstring storage type.
*/
DATA(insert ( 403 name_ops PGNSP PGUID 1986 19 t 2275 ));
DATA(insert ( 405 name_ops PGNSP PGUID 1987 19 t 2275 ));
DATA(insert ( 403 numeric_ops PGNSP PGUID 1988 1700 t 0 ));
DATA(insert ( 405 numeric_ops PGNSP PGUID 1998 1700 t 0 ));
DATA(insert ( 403 complex_ops PGNSP PGUID 3221 195 t 0 ));
......
......@@ -333,7 +333,7 @@ DATA(insert OID = 18 ( char PGNSP PGUID 1 t b t \054 0 0 1002 charin charout
DESCR("single character");
#define CHAROID 18
DATA(insert OID = 19 ( name PGNSP PGUID NAMEDATALEN f b t \054 0 18 1003 namein nameout namerecv namesend - - - i p f 0 -1 0 _null_ _null_ ));
DATA(insert OID = 19 ( name PGNSP PGUID NAMEDATALEN f b t \054 0 18 1003 namein nameout namerecv namesend - - - c p f 0 -1 0 _null_ _null_ ));
DESCR("63-character type for storing system identifiers");
#define NAMEOID 19
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册