]> granicus.if.org Git - postgresql/commitdiff
Here's a patch for Versions 1 and 2 that fixes the following bug:
authorMarc G. Fournier <scrappy@hub.org>
Wed, 21 Aug 1996 04:25:49 +0000 (04:25 +0000)
committerMarc G. Fournier <scrappy@hub.org>
Wed, 21 Aug 1996 04:25:49 +0000 (04:25 +0000)
When you try to do any UPDATE of the catalog class pg_class, such as
to change ownership of a class, the backend crashes.

This is really two serial bugs: 1) there is a hardcoded copy of the
schema of pg_class in the postgres program, and it doesn't match the
actual class that initdb creates in the database; 2) Parts of postgres
determine whether to pass an attribute value by value or by reference
based on the attbyval attribute of the attribute in class
pg_attribute.  Other parts of postgres have it hardcoded.  For the
relacl[] attribute in class pg_class, attbyval does not match the
hardcoded expectation.

The fix is to correct the hardcoded schema for pg_attribute and to
change the fetchatt macro so it ignores attbyval for all variable
length attributes.  The fix also adds a bunch of logic documentation and
extends genbki.sh so it allows source files to contain such documentation.

--
Bryan Henderson                                    Phone 408-227-6803
San Jose, California

src/backend/access/tupmacs.h
src/backend/catalog/genbki.sh
src/backend/catalog/pg_attribute.h
src/backend/catalog/pg_class.h

index 9a9bcce3b418351ffa3ffe22e52f163dbc13e79d..168a4669c3b6c9b0f33878ec581401cf5ad8c950 100644 (file)
@@ -6,7 +6,7 @@
  *
  * Copyright (c) 1994, Regents of the University of California
  *
- * $Id: tupmacs.h,v 1.1.1.1 1996/07/09 06:21:09 scrappy Exp $
+ * $Id: tupmacs.h,v 1.2 1996/08/21 04:25:37 scrappy Exp $
  *
  *-------------------------------------------------------------------------
  */
  * given a AttributeTupleForm and a pointer into a tuple's data
  * area, return the correct value or pointer.
  *
+ * We return a 4 byte (char *) value in all cases.  If the attribute has
+ * "byval" false or has variable length, we return the same pointer
+ * into the tuple data area that we're passed.  Otherwise, we return
+ * the 1, 2, or 4 bytes pointed to by it, properly extended to 4
+ * bytes, depending on the length of the attribute.
+ *
  * note that T must already be properly LONGALIGN/SHORTALIGN'd for
  * this to work correctly.
  *
  * sign-extension may get weird if you use an integer type that
  * isn't the same size as (char *) for the first cast.  (on the other
  * hand, it's safe to use another type for the (foo *)(T).)
+ *
+ * attbyval seems to be fairly redundant.  We have to return a pointer if
+ * the value is longer than 4 bytes or has variable length; returning the
+ * value would be useless.  In fact, for at least the variable length case,
+ * the caller assumes we return a pointer regardless of attbyval.
+ * I would eliminate attbyval altogether, but I don't know how.  -BRYANH.
  */
 #define fetchatt(A, T) \
- ((*(A))->attbyval \
+ ((*(A))->attbyval && (*(A))->attlen != -1 \
   ? ((*(A))->attlen > sizeof(int16) \
      ? (char *) (long) *((int32 *)(T)) \
      : ((*(A))->attlen < sizeof(int16) \
index d8f5d29025411f47dd82bf85a0a4a2add3c06798..c42beff980d68f4fa05e8f43d01a07e6dc6ddad2 100644 (file)
@@ -10,7 +10,7 @@
 #
 #
 # IDENTIFICATION
-#    $Header: /cvsroot/pgsql/src/backend/catalog/Attic/genbki.sh,v 1.2 1996/08/19 13:52:02 scrappy Exp $
+#    $Header: /cvsroot/pgsql/src/backend/catalog/Attic/genbki.sh,v 1.3 1996/08/21 04:25:44 scrappy Exp $
 #
 # NOTES
 #    non-essential whitespace is removed from the generated file.
@@ -58,8 +58,11 @@ done
 cat $SYSFILES | \
 sed -e 's/\/\*.*\*\///g' \
     -e 's/;[   ]*$//g'  \
+    -e 's/^[   ]*//g' \
     -e 's/\ Oid/\ oid/g' \
     -e 's/\ NameData/\ name/g' \
+    -e 's/^Oid/oid/g' \
+    -e 's/^NameData/\name/g' \
     -e 's/(NameData/(name/g' \
     -e 's/(Oid/(oid/g' | \
 gawk '
@@ -78,8 +81,21 @@ BEGIN {
        bootstrap = 0;
        nc = 0;
        reln_open = 0;
+        comment_level = 0;
 }
 
+# ----------------
+# Anything in a /* .. */ block should be ignored.
+# Blank lines also go.
+# Note that any /* */ comment on a line by itself was removed from the line
+# by the sed above.
+# ----------------
+/^\/\*/           { comment_level += 1; next; }
+/^*\//            { comment_level -= 1; next; }
+comment_level > 0 { next; }
+
+/^[    ]*$/      { next; }
+
 # ----------------
 #      anything in a BKI_BEGIN .. BKI_END block should be passed
 #      along without interpretation.
index d8133177d5274fc870437b1e43c0a692c3432014..4de5884005299f06833d36aca8d48b62fd4ff71d 100644 (file)
@@ -7,7 +7,7 @@
  *
  * Copyright (c) 1994, Regents of the University of California
  *
- * $Id: pg_attribute.h,v 1.1.1.1 1996/07/09 06:21:16 scrappy Exp $
+ * $Id: pg_attribute.h,v 1.2 1996/08/21 04:25:47 scrappy Exp $
  *
  * NOTES
  *    the genbki.sh script reads this file and generates .bki
  *    these changes, be sure and change the appropriate Schema_xxx
  *    macros!  -cim 2/5/91
  *
- *    fastgetattr() now uses attcacheoff to cache byte offsets of
- *    attributes in heap tuples.  The data actually stored in 
- *    pg_attribute (-1) indicates no cached value.  But when we copy
- *    these tuples into a tuple descriptor, we may then update attcacheoff
- *    in the copies.  This speeds up the attribute walking process.
- *
  *-------------------------------------------------------------------------
  */
 #ifndef PG_ATTRIBUTE_H
@@ -54,15 +48,39 @@ CATALOG(pg_attribute) BOOTSTRAP {
     int4       attnvals;
     Oid        atttyparg;      /* type arg for arrays/spquel/procs */
     int2       attlen;
+      /* attlen is the number of bytes we use to represent the value 
+         of this attribute, e.g. 4 for an int4.  But for a variable length 
+         attribute, attlen is -1.
+         */
     int2       attnum;
+      /* attnum is the "attribute number" for the attribute:  A 
+         value that uniquely identifies this attribute within its class.
+         For user attributes, Attribute numbers are greater than 0 and
+         not greater than the number of attributes in the class.
+         I.e. if the Class pg_class says that Class XYZ has 10
+         attributes, then the user attribute numbers in Class
+         pg_attribute must be 1-10.
+        
+         System attributes have attribute numbers less than 0 that are
+         unique within the class, but not constrained to any particular range.
+         
+         Note that (attnum - 1) is often used as the index to an array.  
+         */
     int2       attbound;
     bool       attbyval;
     bool       attcanindex;
     Oid        attproc;        /* spquel? */
     int4       attnelems;
     int4       attcacheoff;
+      /* fastgetattr() uses attcacheoff to cache byte offsets of
+         attributes in heap tuples.  The data actually stored in
+         pg_attribute (-1) indicates no cached value.  But when we
+         copy these tuples into a tuple descriptor, we may then update
+         attcacheoff in the copies.  This speeds up the attribute
+         walking process.  
+         */
     bool        attisset;
-    char       attalign;       /* alignment (c=char, s=short, i=int, d=double) */
+    char       attalign;  /* alignment (c=char, s=short, i=int, d=double) */
 } FormData_pg_attribute;
 
 /*
@@ -380,43 +398,43 @@ DATA(insert OID = 0 (  75 vtype            18 0 0 0  1 -11 0 t t 0 0 -1 f c));
  * ----------------
  */
 #define Schema_pg_class \
-{ 83l, {"relname"},      19l, 83l, 0l, 0l, NAMEDATALEN,  1, 0,   '\0', '\001', 0l, 0l, -1l, '\0', 'i' }, \
-{ 83l, {"reltype"},     26l, 83l, 0l, 0l,  4,  2, 0, '\001', '\001', 0l, 0l, -1l, '\0', 'i' }, \
-{ 83l, {"relowner"},     26l, 83l, 0l, 0l,  4,  2, 0, '\001', '\001', 0l, 0l, -1l, '\0', 'i' }, \
-{ 83l, {"relam"},        26l, 83l, 0l, 0l,  4,  3, 0, '\001', '\001', 0l, 0l, -1l, '\0', 'i' }, \
-{ 83l, {"relpages"},     23,  83l, 0l, 0l,  4,  4, 0, '\001', '\001', 0l, 0l, -1l, '\0', 'i' }, \
-{ 83l, {"reltuples"},    23,  83l, 0l, 0l,  4,  5, 0, '\001', '\001', 0l, 0l, -1l, '\0', 'i' }, \
-{ 83l, {"relexpires"},   702,  83l, 0l, 0l,  4,  6, 0, '\001', '\001', 0l, 0l, -1l, '\0', 'i' }, \
-{ 83l, {"relpreserved"}, 703,  83l, 0l, 0l,  4,  7, 0, '\001', '\001', 0l, 0l, -1l, '\0', 'i' }, \
-{ 83l, {"relhasindex"},  16,  83l, 0l, 0l,  1,  8, 0, '\001', '\001', 0l, 0l, -1l, '\0', 'c' }, \
-{ 83l, {"relisshared"},  16,  83l, 0l, 0l,  1,  9, 0, '\001', '\001', 0l, 0l, -1l, '\0', 'c' }, \
-{ 83l, {"relkind"},      18,  83l, 0l, 0l,  1, 10, 0, '\001', '\001', 0l, 0l, -1l, '\0', 'c' }, \
-{ 83l, {"relarch"},      18,  83l, 0l, 0l,  1, 11, 0, '\001', '\001', 0l, 0l, -1l, '\0', 'c' }, \
-{ 83l, {"relnatts"},     21,  83l, 0l, 0l,  2, 12, 0, '\001', '\001', 0l, 0l, -1l, '\0', 's' }, \
-{ 83l, {"relsmgr"},      210l,  83l, 0l, 0l,  2, 13, 0, '\001', '\001', 0l, 0l, -1l, '\0', 's' }, \
-{ 83l, {"relkey"},       22,  83l, 0l, 0l, 16, 14, 0,   '\0', '\001', 0l, 0l, -1l, '\0', 'i' }, \
-{ 83l, {"relkeyop"},     30,  83l, 0l, 0l, 32, 15, 0,   '\0', '\001', 0l, 0l, -1l, '\0', 'i' }, \
-{ 83l, {"relhasrules"},  16,  83l, 0l, 0l,  1, 16, 0, '\001', '\001', 0l, 0l, -1l, '\0', 'c' }, \
-{ 83l, {"relacl"},     1034l, 83l, 0l, 0l, -1, 17, 0,   '\0', '\001', 0l, 0l, -1l, '\0', 'i' }
+{ 83l, {"relname"},      19l,  83l, 0l, 0l, NAMEDATALEN,  1, 0,   '\000', '\001', 0l, 0l, -1l, '\0', 'i' }, \
+{ 83l, {"reltype"},      26l,  83l, 0l, 0l,  4,  2, 0, '\001', '\001', 0l, 0l, -1l, '\0', 'i' }, \
+{ 83l, {"relowner"},     26l,  83l, 0l, 0l,  4,  3, 0, '\001', '\001', 0l, 0l, -1l, '\0', 'i' }, \
+{ 83l, {"relam"},        26l,  83l, 0l, 0l,  4,  4, 0, '\001', '\001', 0l, 0l, -1l, '\0', 'i' }, \
+{ 83l, {"relpages"},     23,   83l, 0l, 0l,  4,  5, 0, '\001', '\001', 0l, 0l, -1l, '\0', 'i' }, \
+{ 83l, {"reltuples"},    23,   83l, 0l, 0l,  4,  6, 0, '\001', '\001', 0l, 0l, -1l, '\0', 'i' }, \
+{ 83l, {"relexpires"},   702,  83l, 0l, 0l,  4,  7, 0, '\001', '\001', 0l, 0l, -1l, '\0', 'i' }, \
+{ 83l, {"relpreserved"}, 703,  83l, 0l, 0l,  4,  8, 0, '\001', '\001', 0l, 0l, -1l, '\0', 'i' }, \
+{ 83l, {"relhasindex"},  16,   83l, 0l, 0l,  1,  9, 0, '\001', '\001', 0l, 0l, -1l, '\0', 'c' }, \
+{ 83l, {"relisshared"},  16,   83l, 0l, 0l,  1, 10, 0, '\001', '\001', 0l, 0l, -1l, '\0', 'c' }, \
+{ 83l, {"relkind"},      18,   83l, 0l, 0l,  1, 11, 0, '\001', '\001', 0l, 0l, -1l, '\0', 'c' }, \
+{ 83l, {"relarch"},      18,   83l, 0l, 0l,  1, 12, 0, '\001', '\001', 0l, 0l, -1l, '\0', 'c' }, \
+{ 83l, {"relnatts"},     21,   83l, 0l, 0l,  2, 13, 0, '\001', '\001', 0l, 0l, -1l, '\0', 's' }, \
+{ 83l, {"relsmgr"},      210l, 83l, 0l, 0l,  2, 14, 0, '\001', '\001', 0l, 0l, -1l, '\0', 's' }, \
+{ 83l, {"relkey"},       22,   83l, 0l, 0l, 16, 15, 0, '\000', '\001', 0l, 0l, -1l, '\0', 'i' }, \
+{ 83l, {"relkeyop"},     30,   83l, 0l, 0l, 32, 16, 0, '\000', '\001', 0l, 0l, -1l, '\0', 'i' }, \
+{ 83l, {"relhasrules"},  16,   83l, 0l, 0l,  1, 17, 0, '\001', '\001', 0l, 0l, -1l, '\0', 'c' }, \
+{ 83l, {"relacl"},     1034l,  83l, 0l, 0l, -1, 18, 0, '\000', '\001', 0l, 0l, -1l, '\0', 'i' }
 
 DATA(insert OID = 0 (  83 relname          19 0 0 0 NAMEDATALEN   1 0 f t 0 0 -1 f i));
 DATA(insert OID = 0 (  83 reltype          26 0 0 0  4   2 0 t t 0 0 -1 f i));
-DATA(insert OID = 0 (  83 relowner         26 0 0 0  4   2 0 t t 0 0 -1 f i));
-DATA(insert OID = 0 (  83 relam            26 0 0 0  4   3 0 t t 0 0 -1 f i));
-DATA(insert OID = 0 (  83 relpages         23 0 0 0  4   4 0 t t 0 0 -1 f i));
-DATA(insert OID = 0 (  83 reltuples        23 0 0 0  4   5 0 t t 0 0 -1 f i));
-DATA(insert OID = 0 (  83 relexpires      702 0 0 0  4   6 0 t t 0 0 -1 f i));
-DATA(insert OID = 0 (  83 relpreserved    702 0 0 0  4   7 0 t t 0 0 -1 f i));
-DATA(insert OID = 0 (  83 relhasindex      16 0 0 0  1   8 0 t t 0 0 -1 f c));
-DATA(insert OID = 0 (  83 relisshared      16 0 0 0  1   9 0 t t 0 0 -1 f c));
-DATA(insert OID = 0 (  83 relkind          18 0 0 0  1  10 0 t t 0 0 -1 f c));
-DATA(insert OID = 0 (  83 relarch          18 0 0 0  1  11 0 t t 0 0 -1 f c));
-DATA(insert OID = 0 (  83 relnatts         21 0 0 0  2  12 0 t t 0 0 -1 f s));
-DATA(insert OID = 0 (  83 relsmgr         210 0 0 0  2  13 0 t t 0 0 -1 f s));
-DATA(insert OID = 0 (  83 relkey           22 0 0 0 16  14 0 f t 0 0 -1 f i));
-DATA(insert OID = 0 (  83 relkeyop         30 0 0 0 32  15 0 f t 0 0 -1 f i));
-DATA(insert OID = 0 (  83 relhasrules      16 0 0 0  1  16 0 t t 0 0 -1 f c));
-DATA(insert OID = 0 (  83 relacl         1034 0 0 0 -1  17 0 f t 0 0 -1 f i));
+DATA(insert OID = 0 (  83 relowner         26 0 0 0  4   3 0 t t 0 0 -1 f i));
+DATA(insert OID = 0 (  83 relam            26 0 0 0  4   4 0 t t 0 0 -1 f i));
+DATA(insert OID = 0 (  83 relpages         23 0 0 0  4   5 0 t t 0 0 -1 f i));
+DATA(insert OID = 0 (  83 reltuples        23 0 0 0  4   6 0 t t 0 0 -1 f i));
+DATA(insert OID = 0 (  83 relexpires      702 0 0 0  4   7 0 t t 0 0 -1 f i));
+DATA(insert OID = 0 (  83 relpreserved    703 0 0 0  4   8 0 t t 0 0 -1 f i));
+DATA(insert OID = 0 (  83 relhasindex      16 0 0 0  1   9 0 t t 0 0 -1 f c));
+DATA(insert OID = 0 (  83 relisshared      16 0 0 0  1  10 0 t t 0 0 -1 f c));
+DATA(insert OID = 0 (  83 relkind          18 0 0 0  1  11 0 t t 0 0 -1 f c));
+DATA(insert OID = 0 (  83 relarch          18 0 0 0  1  12 0 t t 0 0 -1 f c));
+DATA(insert OID = 0 (  83 relnatts         21 0 0 0  2  13 0 t t 0 0 -1 f s));
+DATA(insert OID = 0 (  83 relsmgr         210 0 0 0  2  14 0 t t 0 0 -1 f s));
+DATA(insert OID = 0 (  83 relkey           22 0 0 0 16  15 0 f t 0 0 -1 f i));
+DATA(insert OID = 0 (  83 relkeyop         30 0 0 0 32  16 0 f t 0 0 -1 f i));
+DATA(insert OID = 0 (  83 relhasrules      16 0 0 0  1  17 0 t t 0 0 -1 f c));
+DATA(insert OID = 0 (  83 relacl         1034 0 0 0 -1  18 0 f t 0 0 -1 f i));
 DATA(insert OID = 0 (  83 ctid             27 0 0 0  6  -1 0 f t 0 0 -1 f i));
 DATA(insert OID = 0 (  83 oid              26 0 0 0  4  -2 0 t t 0 0 -1 f i));
 DATA(insert OID = 0 (  83 xmin             28 0 0 0  4  -3 0 f t 0 0 -1 f i));
index f9fdbfb1c3e3910d64b42dc45411e5c4d3483354..d60e694a44ccf80e719671902ebae9845436c7ae 100644 (file)
@@ -7,7 +7,7 @@
  *
  * Copyright (c) 1994, Regents of the University of California
  *
- * $Id: pg_class.h,v 1.2 1996/08/04 22:00:13 scrappy Exp $
+ * $Id: pg_class.h,v 1.3 1996/08/21 04:25:49 scrappy Exp $
  *
  * NOTES
  *    ``pg_relation'' is being replaced by ``pg_class''.  currently
@@ -66,6 +66,10 @@ CATALOG(pg_class) BOOTSTRAP {
      char      relkind;
      char      relarch; /* 'h' = heavy, 'l' = light, 'n' = no archival*/
      int2      relnatts;
+       /* relnatts is the number of user attributes this class has.  There 
+          must be exactly this many instances in Class pg_attribute for this 
+          class which have attnum > 0 (= user attribute).
+          */
      int2      relsmgr;
      int28     relkey;                 /* not used */
      oid8      relkeyop;               /* not used */