Skip to content

Commit 5e773a4

Browse files
committed
Here's a patch for Versions 1 and 2 that fixes the following bug:
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
1 parent 93ad36f commit 5e773a4

File tree

4 files changed

+96
-46
lines changed

4 files changed

+96
-46
lines changed

src/backend/access/tupmacs.h

Lines changed: 14 additions & 2 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.1.1.1 1996/07/09 06:21:09 scrappy Exp $
9+
* $Id: tupmacs.h,v 1.2 1996/08/21 04:25:37 scrappy Exp $
1010
*
1111
*-------------------------------------------------------------------------
1212
*/
@@ -22,6 +22,12 @@
2222
* given a AttributeTupleForm and a pointer into a tuple's data
2323
* area, return the correct value or pointer.
2424
*
25+
* We return a 4 byte (char *) value in all cases. If the attribute has
26+
* "byval" false or has variable length, we return the same pointer
27+
* into the tuple data area that we're passed. Otherwise, we return
28+
* the 1, 2, or 4 bytes pointed to by it, properly extended to 4
29+
* bytes, depending on the length of the attribute.
30+
*
2531
* note that T must already be properly LONGALIGN/SHORTALIGN'd for
2632
* this to work correctly.
2733
*
@@ -30,9 +36,15 @@
3036
* sign-extension may get weird if you use an integer type that
3137
* isn't the same size as (char *) for the first cast. (on the other
3238
* hand, it's safe to use another type for the (foo *)(T).)
39+
*
40+
* attbyval seems to be fairly redundant. We have to return a pointer if
41+
* the value is longer than 4 bytes or has variable length; returning the
42+
* value would be useless. In fact, for at least the variable length case,
43+
* the caller assumes we return a pointer regardless of attbyval.
44+
* I would eliminate attbyval altogether, but I don't know how. -BRYANH.
3345
*/
3446
#define fetchatt(A, T) \
35-
((*(A))->attbyval \
47+
((*(A))->attbyval && (*(A))->attlen != -1 \
3648
? ((*(A))->attlen > sizeof(int16) \
3749
? (char *) (long) *((int32 *)(T)) \
3850
: ((*(A))->attlen < sizeof(int16) \

src/backend/catalog/genbki.sh

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
#
1111
#
1212
# IDENTIFICATION
13-
# $Header: /cvsroot/pgsql/src/backend/catalog/Attic/genbki.sh,v 1.2 1996/08/19 13:52:02 scrappy Exp $
13+
# $Header: /cvsroot/pgsql/src/backend/catalog/Attic/genbki.sh,v 1.3 1996/08/21 04:25:44 scrappy Exp $
1414
#
1515
# NOTES
1616
# non-essential whitespace is removed from the generated file.
@@ -58,8 +58,11 @@ done
5858
cat $SYSFILES | \
5959
sed -e 's/\/\*.*\*\///g' \
6060
-e 's/;[ ]*$//g' \
61+
-e 's/^[ ]*//g' \
6162
-e 's/\ Oid/\ oid/g' \
6263
-e 's/\ NameData/\ name/g' \
64+
-e 's/^Oid/oid/g' \
65+
-e 's/^NameData/\name/g' \
6366
-e 's/(NameData/(name/g' \
6467
-e 's/(Oid/(oid/g' | \
6568
gawk '
@@ -78,8 +81,21 @@ BEGIN {
7881
bootstrap = 0;
7982
nc = 0;
8083
reln_open = 0;
84+
comment_level = 0;
8185
}
8286
87+
# ----------------
88+
# Anything in a /* .. */ block should be ignored.
89+
# Blank lines also go.
90+
# Note that any /* */ comment on a line by itself was removed from the line
91+
# by the sed above.
92+
# ----------------
93+
/^\/\*/ { comment_level += 1; next; }
94+
/^*\// { comment_level -= 1; next; }
95+
comment_level > 0 { next; }
96+
97+
/^[ ]*$/ { next; }
98+
8399
# ----------------
84100
# anything in a BKI_BEGIN .. BKI_END block should be passed
85101
# along without interpretation.

src/backend/catalog/pg_attribute.h

Lines changed: 60 additions & 42 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_attribute.h,v 1.1.1.1 1996/07/09 06:21:16 scrappy Exp $
10+
* $Id: pg_attribute.h,v 1.2 1996/08/21 04:25:47 scrappy Exp $
1111
*
1212
* NOTES
1313
* the genbki.sh script reads this file and generates .bki
@@ -18,12 +18,6 @@
1818
* these changes, be sure and change the appropriate Schema_xxx
1919
* macros! -cim 2/5/91
2020
*
21-
* fastgetattr() now uses attcacheoff to cache byte offsets of
22-
* attributes in heap tuples. The data actually stored in
23-
* pg_attribute (-1) indicates no cached value. But when we copy
24-
* these tuples into a tuple descriptor, we may then update attcacheoff
25-
* in the copies. This speeds up the attribute walking process.
26-
*
2721
*-------------------------------------------------------------------------
2822
*/
2923
#ifndef PG_ATTRIBUTE_H
@@ -54,15 +48,39 @@ CATALOG(pg_attribute) BOOTSTRAP {
5448
int4 attnvals;
5549
Oid atttyparg; /* type arg for arrays/spquel/procs */
5650
int2 attlen;
51+
/* attlen is the number of bytes we use to represent the value
52+
of this attribute, e.g. 4 for an int4. But for a variable length
53+
attribute, attlen is -1.
54+
*/
5755
int2 attnum;
56+
/* attnum is the "attribute number" for the attribute: A
57+
value that uniquely identifies this attribute within its class.
58+
For user attributes, Attribute numbers are greater than 0 and
59+
not greater than the number of attributes in the class.
60+
I.e. if the Class pg_class says that Class XYZ has 10
61+
attributes, then the user attribute numbers in Class
62+
pg_attribute must be 1-10.
63+
64+
System attributes have attribute numbers less than 0 that are
65+
unique within the class, but not constrained to any particular range.
66+
67+
Note that (attnum - 1) is often used as the index to an array.
68+
*/
5869
int2 attbound;
5970
bool attbyval;
6071
bool attcanindex;
6172
Oid attproc; /* spquel? */
6273
int4 attnelems;
6374
int4 attcacheoff;
75+
/* fastgetattr() uses attcacheoff to cache byte offsets of
76+
attributes in heap tuples. The data actually stored in
77+
pg_attribute (-1) indicates no cached value. But when we
78+
copy these tuples into a tuple descriptor, we may then update
79+
attcacheoff in the copies. This speeds up the attribute
80+
walking process.
81+
*/
6482
bool attisset;
65-
char attalign; /* alignment (c=char, s=short, i=int, d=double) */
83+
char attalign; /* alignment (c=char, s=short, i=int, d=double) */
6684
} FormData_pg_attribute;
6785

6886
/*
@@ -380,43 +398,43 @@ DATA(insert OID = 0 ( 75 vtype 18 0 0 0 1 -11 0 t t 0 0 -1 f c));
380398
* ----------------
381399
*/
382400
#define Schema_pg_class \
383-
{ 83l, {"relname"}, 19l, 83l, 0l, 0l, NAMEDATALEN, 1, 0, '\0', '\001', 0l, 0l, -1l, '\0', 'i' }, \
384-
{ 83l, {"reltype"}, 26l, 83l, 0l, 0l, 4, 2, 0, '\001', '\001', 0l, 0l, -1l, '\0', 'i' }, \
385-
{ 83l, {"relowner"}, 26l, 83l, 0l, 0l, 4, 2, 0, '\001', '\001', 0l, 0l, -1l, '\0', 'i' }, \
386-
{ 83l, {"relam"}, 26l, 83l, 0l, 0l, 4, 3, 0, '\001', '\001', 0l, 0l, -1l, '\0', 'i' }, \
387-
{ 83l, {"relpages"}, 23, 83l, 0l, 0l, 4, 4, 0, '\001', '\001', 0l, 0l, -1l, '\0', 'i' }, \
388-
{ 83l, {"reltuples"}, 23, 83l, 0l, 0l, 4, 5, 0, '\001', '\001', 0l, 0l, -1l, '\0', 'i' }, \
389-
{ 83l, {"relexpires"}, 702, 83l, 0l, 0l, 4, 6, 0, '\001', '\001', 0l, 0l, -1l, '\0', 'i' }, \
390-
{ 83l, {"relpreserved"}, 703, 83l, 0l, 0l, 4, 7, 0, '\001', '\001', 0l, 0l, -1l, '\0', 'i' }, \
391-
{ 83l, {"relhasindex"}, 16, 83l, 0l, 0l, 1, 8, 0, '\001', '\001', 0l, 0l, -1l, '\0', 'c' }, \
392-
{ 83l, {"relisshared"}, 16, 83l, 0l, 0l, 1, 9, 0, '\001', '\001', 0l, 0l, -1l, '\0', 'c' }, \
393-
{ 83l, {"relkind"}, 18, 83l, 0l, 0l, 1, 10, 0, '\001', '\001', 0l, 0l, -1l, '\0', 'c' }, \
394-
{ 83l, {"relarch"}, 18, 83l, 0l, 0l, 1, 11, 0, '\001', '\001', 0l, 0l, -1l, '\0', 'c' }, \
395-
{ 83l, {"relnatts"}, 21, 83l, 0l, 0l, 2, 12, 0, '\001', '\001', 0l, 0l, -1l, '\0', 's' }, \
396-
{ 83l, {"relsmgr"}, 210l, 83l, 0l, 0l, 2, 13, 0, '\001', '\001', 0l, 0l, -1l, '\0', 's' }, \
397-
{ 83l, {"relkey"}, 22, 83l, 0l, 0l, 16, 14, 0, '\0', '\001', 0l, 0l, -1l, '\0', 'i' }, \
398-
{ 83l, {"relkeyop"}, 30, 83l, 0l, 0l, 32, 15, 0, '\0', '\001', 0l, 0l, -1l, '\0', 'i' }, \
399-
{ 83l, {"relhasrules"}, 16, 83l, 0l, 0l, 1, 16, 0, '\001', '\001', 0l, 0l, -1l, '\0', 'c' }, \
400-
{ 83l, {"relacl"}, 1034l, 83l, 0l, 0l, -1, 17, 0, '\0', '\001', 0l, 0l, -1l, '\0', 'i' }
401+
{ 83l, {"relname"}, 19l, 83l, 0l, 0l, NAMEDATALEN, 1, 0, '\000', '\001', 0l, 0l, -1l, '\0', 'i' }, \
402+
{ 83l, {"reltype"}, 26l, 83l, 0l, 0l, 4, 2, 0, '\001', '\001', 0l, 0l, -1l, '\0', 'i' }, \
403+
{ 83l, {"relowner"}, 26l, 83l, 0l, 0l, 4, 3, 0, '\001', '\001', 0l, 0l, -1l, '\0', 'i' }, \
404+
{ 83l, {"relam"}, 26l, 83l, 0l, 0l, 4, 4, 0, '\001', '\001', 0l, 0l, -1l, '\0', 'i' }, \
405+
{ 83l, {"relpages"}, 23, 83l, 0l, 0l, 4, 5, 0, '\001', '\001', 0l, 0l, -1l, '\0', 'i' }, \
406+
{ 83l, {"reltuples"}, 23, 83l, 0l, 0l, 4, 6, 0, '\001', '\001', 0l, 0l, -1l, '\0', 'i' }, \
407+
{ 83l, {"relexpires"}, 702, 83l, 0l, 0l, 4, 7, 0, '\001', '\001', 0l, 0l, -1l, '\0', 'i' }, \
408+
{ 83l, {"relpreserved"}, 703, 83l, 0l, 0l, 4, 8, 0, '\001', '\001', 0l, 0l, -1l, '\0', 'i' }, \
409+
{ 83l, {"relhasindex"}, 16, 83l, 0l, 0l, 1, 9, 0, '\001', '\001', 0l, 0l, -1l, '\0', 'c' }, \
410+
{ 83l, {"relisshared"}, 16, 83l, 0l, 0l, 1, 10, 0, '\001', '\001', 0l, 0l, -1l, '\0', 'c' }, \
411+
{ 83l, {"relkind"}, 18, 83l, 0l, 0l, 1, 11, 0, '\001', '\001', 0l, 0l, -1l, '\0', 'c' }, \
412+
{ 83l, {"relarch"}, 18, 83l, 0l, 0l, 1, 12, 0, '\001', '\001', 0l, 0l, -1l, '\0', 'c' }, \
413+
{ 83l, {"relnatts"}, 21, 83l, 0l, 0l, 2, 13, 0, '\001', '\001', 0l, 0l, -1l, '\0', 's' }, \
414+
{ 83l, {"relsmgr"}, 210l, 83l, 0l, 0l, 2, 14, 0, '\001', '\001', 0l, 0l, -1l, '\0', 's' }, \
415+
{ 83l, {"relkey"}, 22, 83l, 0l, 0l, 16, 15, 0, '\000', '\001', 0l, 0l, -1l, '\0', 'i' }, \
416+
{ 83l, {"relkeyop"}, 30, 83l, 0l, 0l, 32, 16, 0, '\000', '\001', 0l, 0l, -1l, '\0', 'i' }, \
417+
{ 83l, {"relhasrules"}, 16, 83l, 0l, 0l, 1, 17, 0, '\001', '\001', 0l, 0l, -1l, '\0', 'c' }, \
418+
{ 83l, {"relacl"}, 1034l, 83l, 0l, 0l, -1, 18, 0, '\000', '\001', 0l, 0l, -1l, '\0', 'i' }
401419

402420
DATA(insert OID = 0 ( 83 relname 19 0 0 0 NAMEDATALEN 1 0 f t 0 0 -1 f i));
403421
DATA(insert OID = 0 ( 83 reltype 26 0 0 0 4 2 0 t t 0 0 -1 f i));
404-
DATA(insert OID = 0 ( 83 relowner 26 0 0 0 4 2 0 t t 0 0 -1 f i));
405-
DATA(insert OID = 0 ( 83 relam 26 0 0 0 4 3 0 t t 0 0 -1 f i));
406-
DATA(insert OID = 0 ( 83 relpages 23 0 0 0 4 4 0 t t 0 0 -1 f i));
407-
DATA(insert OID = 0 ( 83 reltuples 23 0 0 0 4 5 0 t t 0 0 -1 f i));
408-
DATA(insert OID = 0 ( 83 relexpires 702 0 0 0 4 6 0 t t 0 0 -1 f i));
409-
DATA(insert OID = 0 ( 83 relpreserved 702 0 0 0 4 7 0 t t 0 0 -1 f i));
410-
DATA(insert OID = 0 ( 83 relhasindex 16 0 0 0 1 8 0 t t 0 0 -1 f c));
411-
DATA(insert OID = 0 ( 83 relisshared 16 0 0 0 1 9 0 t t 0 0 -1 f c));
412-
DATA(insert OID = 0 ( 83 relkind 18 0 0 0 1 10 0 t t 0 0 -1 f c));
413-
DATA(insert OID = 0 ( 83 relarch 18 0 0 0 1 11 0 t t 0 0 -1 f c));
414-
DATA(insert OID = 0 ( 83 relnatts 21 0 0 0 2 12 0 t t 0 0 -1 f s));
415-
DATA(insert OID = 0 ( 83 relsmgr 210 0 0 0 2 13 0 t t 0 0 -1 f s));
416-
DATA(insert OID = 0 ( 83 relkey 22 0 0 0 16 14 0 f t 0 0 -1 f i));
417-
DATA(insert OID = 0 ( 83 relkeyop 30 0 0 0 32 15 0 f t 0 0 -1 f i));
418-
DATA(insert OID = 0 ( 83 relhasrules 16 0 0 0 1 16 0 t t 0 0 -1 f c));
419-
DATA(insert OID = 0 ( 83 relacl 1034 0 0 0 -1 17 0 f t 0 0 -1 f i));
422+
DATA(insert OID = 0 ( 83 relowner 26 0 0 0 4 3 0 t t 0 0 -1 f i));
423+
DATA(insert OID = 0 ( 83 relam 26 0 0 0 4 4 0 t t 0 0 -1 f i));
424+
DATA(insert OID = 0 ( 83 relpages 23 0 0 0 4 5 0 t t 0 0 -1 f i));
425+
DATA(insert OID = 0 ( 83 reltuples 23 0 0 0 4 6 0 t t 0 0 -1 f i));
426+
DATA(insert OID = 0 ( 83 relexpires 702 0 0 0 4 7 0 t t 0 0 -1 f i));
427+
DATA(insert OID = 0 ( 83 relpreserved 703 0 0 0 4 8 0 t t 0 0 -1 f i));
428+
DATA(insert OID = 0 ( 83 relhasindex 16 0 0 0 1 9 0 t t 0 0 -1 f c));
429+
DATA(insert OID = 0 ( 83 relisshared 16 0 0 0 1 10 0 t t 0 0 -1 f c));
430+
DATA(insert OID = 0 ( 83 relkind 18 0 0 0 1 11 0 t t 0 0 -1 f c));
431+
DATA(insert OID = 0 ( 83 relarch 18 0 0 0 1 12 0 t t 0 0 -1 f c));
432+
DATA(insert OID = 0 ( 83 relnatts 21 0 0 0 2 13 0 t t 0 0 -1 f s));
433+
DATA(insert OID = 0 ( 83 relsmgr 210 0 0 0 2 14 0 t t 0 0 -1 f s));
434+
DATA(insert OID = 0 ( 83 relkey 22 0 0 0 16 15 0 f t 0 0 -1 f i));
435+
DATA(insert OID = 0 ( 83 relkeyop 30 0 0 0 32 16 0 f t 0 0 -1 f i));
436+
DATA(insert OID = 0 ( 83 relhasrules 16 0 0 0 1 17 0 t t 0 0 -1 f c));
437+
DATA(insert OID = 0 ( 83 relacl 1034 0 0 0 -1 18 0 f t 0 0 -1 f i));
420438
DATA(insert OID = 0 ( 83 ctid 27 0 0 0 6 -1 0 f t 0 0 -1 f i));
421439
DATA(insert OID = 0 ( 83 oid 26 0 0 0 4 -2 0 t t 0 0 -1 f i));
422440
DATA(insert OID = 0 ( 83 xmin 28 0 0 0 4 -3 0 f t 0 0 -1 f i));

src/backend/catalog/pg_class.h

Lines changed: 5 additions & 1 deletion
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_class.h,v 1.2 1996/08/04 22:00:13 scrappy Exp $
10+
* $Id: pg_class.h,v 1.3 1996/08/21 04:25:49 scrappy Exp $
1111
*
1212
* NOTES
1313
* ``pg_relation'' is being replaced by ``pg_class''. currently
@@ -66,6 +66,10 @@ CATALOG(pg_class) BOOTSTRAP {
6666
char relkind;
6767
char relarch; /* 'h' = heavy, 'l' = light, 'n' = no archival*/
6868
int2 relnatts;
69+
/* relnatts is the number of user attributes this class has. There
70+
must be exactly this many instances in Class pg_attribute for this
71+
class which have attnum > 0 (= user attribute).
72+
*/
6973
int2 relsmgr;
7074
int28 relkey; /* not used */
7175
oid8 relkeyop; /* not used */

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy