Thread: Help extending pg_class

Help extending pg_class

From
overbored
Date:
Hi all, I added a new variable-length field to the pg_class catalog, but 
I did something wrong, and I can't tell what else I'd need to change. (I 
know about how extending pg_class is bad and all, but it seems to be the 
simplest solution to my problem right now, and I'd just like to get it 
working.) The code I'm working with is based on Postgres 7.3.2 (avail. 
at http://telegraph.cs.berkeley.edu). I've added a char field to it 
before, but now I'm trying to add a text field, which pg_type also has. 
I modified pg_class.h and pg_attribute.h (which I've pasted to 
http://rafb.net/paste/results/c1CiIo27.html), but when I run initdb, I'm 
getting a seg fault in the first postgres being run under the section 
'CREATE VIEWS and other things'. gdb tells me that it's happening for 
the line:

backend> REVOKE ALL on pg_shadow FROM public;
QUERY: REVOKE ALL on pg_shadow FROM public;

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 1076389696 (LWP 7710)]
0x0807a6e8 in DataFill (data=0x83d4710 '\177' <repeats 200 times>...,    tupleDesc=0x83971e4, value=0x83d4400,
nulls=0x83d45d8' ' <repeats 24 times>, 
 
"n~\177\177\177\177\177\177$F=\b ", infomask=0x83d4688, bit=0x83d468b 
"ÿÿÿ\002") at heaptuple.c:120
120                             if (VARATT_IS_EXTERNAL(value[i]))
(gdb) l
115                     }
116                     else if (att[i]->attlen == -1)
117                     {
118                             /* varlena */
119                             *infomask |= HEAP_HASVARWIDTH;
120                             if (VARATT_IS_EXTERNAL(value[i]))
121                                     *infomask |= HEAP_HASEXTERNAL;
122                             if (VARATT_IS_COMPRESSED(value[i]))
123                                     *infomask |= HEAP_HASCOMPRESSED;
124                             data_length = 
VARATT_SIZE(DatumGetPointer(value[i]));
(gdb) p i
$1 = 25
(gdb) bt
#0  0x0807a6e8 in DataFill (data=0x83d4710 '\177' <repeats 200 times>...,    tupleDesc=0x83971e4, value=0x83d4400,
nulls=0x83d45d8' ' <repeats 24 times>, 
 
"n~\177\177\177\177\177\177$F=\b ", infomask=0x83d4688, bit=0x83d468b 
"ÿÿÿ\002") at heaptuple.c:120
#1  0x0807bbc7 in heap_formtuple (tupleDescriptor=0x83971e4, 
value=0x83d4400,    nulls=0x83d45d8 ' ' <repeats 24 times>, 
"n~\177\177\177\177\177\177$F=\b ")    at heaptuple.c:622
#2  0x0807c0fe in heap_modifytuple (tuple=0x403b6a60, relation=0x83970cc,    replValue=0xbffff5b0,
replNull=0xbffff590' ' <repeats 26 times>, "ÿ¿1\t&\b",    repl=0xbffff570 ' ' <repeats 25 times>, "rÿ¿1\t&\b", ' '
<repeats
 
26 times>, "ÿ¿1\t&\b") at heaptuple.c:697
#3  0x080ce977 in ExecuteGrantStmt_Relation (stmt=0x83c1954) at aclchk.c:236
#4  0x080ce4e8 in ExecuteGrantStmt (stmt=0x83c1954) at aclchk.c:138
#5  0x081ec38d in ProcessUtility (parsetree=0x83c1954, dest=Debug,    completionTag=0xbffff790 "") at utility.c:690
#6  0x081e7fdc in pg_exec_query_string (query_string=0x83c1664, dest=Debug,    parse_context=0x83954ec) at
postgres.c:1035
#7  0x081ea453 in PostgresMain (argc=7, argv=0x837e5c8,    username=0x837f988 "z") at postgres.c:2774
#8  0x08177692 in main (argc=7, argv=0xbffff9f4) at main.c:236

The REVOKE command invokes ExecuteGrantStmt_Relation() to modify the 
relacl attribute of pg_class, which is the last attribute and also 
var-length. My new field is interfering with this operation somehow. For 
some reason, in frame 2, the new 'value' array is allocated with length 
numberOfAttributes = RelationGetForm(relation)->relnatts = 25, instead 
of 26. This looks like a problem (not sure if it's *the* problem), but I 
have no idea where/how this was set. I've tried setting the 
Natts_pg_class_fixed to both 24 and 25, to no avail.

Please let me know if more details are needed; thanks very much in 
advance for any help!


Re: Help extending pg_class

From
Alvaro Herrera
Date:
On Sun, Dec 19, 2004 at 01:56:02AM -0800, overbored wrote:
> Hi all, I added a new variable-length field to the pg_class catalog, but 
> I did something wrong, and I can't tell what else I'd need to change. (I 
> know about how extending pg_class is bad and all, but it seems to be the 
> simplest solution to my problem right now, and I'd just like to get it 
> working.) The code I'm working with is based on Postgres 7.3.2 (avail. 
> at http://telegraph.cs.berkeley.edu). I've added a char field to it 
> before, but now I'm trying to add a text field, which pg_type also has. 
> I modified pg_class.h and pg_attribute.h (which I've pasted to 
> http://rafb.net/paste/results/c1CiIo27.html),

You need to fix CLASS_TUPLE_SIZE.  Not sure how far that would take you,
because adding a varlena field to pg_class does not strike me as a
trivial exercise.  For a modification that's gonna stay academic, I
would have opted for a different catalog.

-- 
Alvaro Herrera (<alvherre[@]dcc.uchile.cl>)
"Ellos andaban todos desnudos como su madre los parió, y también las mujeres,
aunque no vi más que una, harto moza, y todos los que yo vi eran todos
mancebos, que ninguno vi de edad de más de XXX años" (Cristóbal Colón)


Re: Help extending pg_class

From
Tom Lane
Date:
overbored <overbored@overbored.net> writes:
> Hi all, I added a new variable-length field to the pg_class catalog, but 
> I did something wrong, and I can't tell what else I'd need to change.
> ...
> The REVOKE command invokes ExecuteGrantStmt_Relation() to modify the 
> relacl attribute of pg_class, which is the last attribute and also 
> var-length. My new field is interfering with this operation somehow. For 
> some reason, in frame 2, the new 'value' array is allocated with length 
> numberOfAttributes = RelationGetForm(relation)->relnatts = 25, instead 
> of 26.

I think that would come from Natts_pg_class (via formrdesc()).  Are you
sure you updated pg_class completely, did a full rebuild, and an initdb?
        regards, tom lane