summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane2008-06-24 17:58:27 +0000
committerTom Lane2008-06-24 17:58:27 +0000
commit386b37bbd8850a446f5bda6d99bffbb8eb4b1e8f (patch)
tree2c651227aea0636dd6a6343b51f523300cb7b639
parent483572b5f9fdf51b5de2e534921e881279d2affe (diff)
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.
-rw-r--r--src/backend/bootstrap/bootstrap.c2
-rw-r--r--src/backend/utils/adt/name.c2
-rw-r--r--src/include/c.h10
-rw-r--r--src/include/catalog/catversion.h2
-rw-r--r--src/include/catalog/pg_attribute.h16
-rw-r--r--src/include/catalog/pg_opclass.h11
-rw-r--r--src/include/catalog/pg_type.h2
-rw-r--r--src/include/pg_config_manual.h4
8 files changed, 26 insertions, 23 deletions
diff --git a/src/backend/bootstrap/bootstrap.c b/src/backend/bootstrap/bootstrap.c
index 14cb38558d..5ff9d52491 100644
--- a/src/backend/bootstrap/bootstrap.c
+++ b/src/backend/bootstrap/bootstrap.c
@@ -125,7 +125,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},
diff --git a/src/backend/utils/adt/name.c b/src/backend/utils/adt/name.c
index 684d9147a6..ea268e3961 100644
--- a/src/backend/utils/adt/name.c
+++ b/src/backend/utils/adt/name.c
@@ -315,7 +315,7 @@ current_schemas(PG_FUNCTION_ARGS)
NAMEOID,
NAMEDATALEN, /* sizeof(Name) */
false, /* Name is not by-val */
- 'i'); /* alignment of Name */
+ 'c'); /* alignment of Name */
PG_RETURN_POINTER(array);
}
diff --git a/src/include/c.h b/src/include/c.h
index 1a00309281..6fb48c6979 100644
--- a/src/include/c.h
+++ b/src/include/c.h
@@ -442,16 +442,12 @@ typedef struct
} oidvector; /* VARIABLE LENGTH STRUCT */
/*
- * 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. Note that NAMEDATALEN
- * must be a multiple of sizeof(int), else sizeof(NameData) will probably
- * not come out equal to NAMEDATALEN.
+ * Representation of a Name: effectively just a C string, but null-padded to
+ * exactly NAMEDATALEN bytes. The use of a struct is historical.
*/
-typedef union nameData
+typedef struct nameData
{
char data[NAMEDATALEN];
- int alignmentDummy;
} NameData;
typedef NameData *Name;
diff --git a/src/include/catalog/catversion.h b/src/include/catalog/catversion.h
index 673f050009..3d99517ba5 100644
--- a/src/include/catalog/catversion.h
+++ b/src/include/catalog/catversion.h
@@ -53,6 +53,6 @@
*/
/* yyyymmddN */
-#define CATALOG_VERSION_NO 200806171
+#define CATALOG_VERSION_NO 200806241
#endif
diff --git a/src/include/catalog/pg_attribute.h b/src/include/catalog/pg_attribute.h
index 7fe8f855cf..8fef548674 100644
--- a/src/include/catalog/pg_attribute.h
+++ b/src/include/catalog/pg_attribute.h
@@ -217,7 +217,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 }, \
@@ -244,7 +244,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));
@@ -283,7 +283,7 @@ DATA(insert ( 1247 tableoid 26 0 4 -7 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 }, \
@@ -305,7 +305,7 @@ DATA(insert ( 1247 tableoid 26 0 4 -7 0 -1 -1 t p i t f f t 0));
{ 1255, {"proconfig"}, 1009, -1, -1, 20, 1, -1, -1, false, 'x', 'i', false, false, false, true, 0 }, \
{ 1255, {"proacl"}, 1034, -1, -1, 21, 1, -1, -1, false, 'x', 'i', false, 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));
@@ -340,7 +340,7 @@ DATA(insert ( 1255 tableoid 26 0 4 -7 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 }, \
@@ -358,7 +358,7 @@ DATA(insert ( 1255 tableoid 26 0 4 -7 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));
@@ -387,7 +387,7 @@ DATA(insert ( 1249 tableoid 26 0 4 -7 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 }, \
@@ -415,7 +415,7 @@ DATA(insert ( 1249 tableoid 26 0 4 -7 0 -1 -1 t p i t f f t 0));
{ 1259, {"relacl"}, 1034, -1, -1, 26, 1, -1, -1, false, 'x', 'i', false, false, false, true, 0 }, \
{ 1259, {"reloptions"}, 1009, -1, -1, 27, 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));
diff --git a/src/include/catalog/pg_opclass.h b/src/include/catalog/pg_opclass.h
index 543d0a1ae1..115069b432 100644
--- a/src/include/catalog/pg_opclass.h
+++ b/src/include/catalog/pg_opclass.h
@@ -121,8 +121,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 OID = 1981 ( 403 oid_ops PGNSP PGUID 1989 26 t 0 ));
diff --git a/src/include/catalog/pg_type.h b/src/include/catalog/pg_type.h
index 16ea859a99..9b18ea3b14 100644
--- a/src/include/catalog/pg_type.h
+++ b/src/include/catalog/pg_type.h
@@ -267,7 +267,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
diff --git a/src/include/pg_config_manual.h b/src/include/pg_config_manual.h
index ff543992d3..a3ced75a43 100644
--- a/src/include/pg_config_manual.h
+++ b/src/include/pg_config_manual.h
@@ -12,8 +12,8 @@
/*
* Maximum length for identifiers (e.g. table names, column names,
- * function names). It must be a multiple of sizeof(int) (typically
- * 4).
+ * function names). Names actually are limited to one less byte than this,
+ * because the length must include a trailing zero byte.
*
* Changing this requires an initdb.
*/