88 *
99 *
1010 * IDENTIFICATION
11- * $Header: /cvsroot/pgsql/src/backend/access/common/tupdesc.c,v 1.90 2002/09/22 19:42:50 tgl Exp $
11+ * $Header: /cvsroot/pgsql/src/backend/access/common/tupdesc.c,v 1.91 2002/09/28 20:00:18 tgl Exp $
1212 *
1313 * NOTES
1414 * some of the executor utility code such as "ExecTypeFromTL" should be
3939TupleDesc
4040CreateTemplateTupleDesc (int natts ,bool hasoid )
4141{
42- uint32 size ;
4342TupleDesc desc ;
4443
4544/*
4645 * sanity checks
4746 */
48- AssertArg (natts >=1 );
47+ AssertArg (natts >=0 );
4948
5049/*
5150 * allocate enough memory for the tuple descriptor and zero it as
5251 * TupleDescInitEntry assumes that the descriptor is filled with NULL
5352 * pointers.
5453 */
55- size = natts * sizeof (Form_pg_attribute );
5654desc = (TupleDesc )palloc (sizeof (struct tupleDesc ));
57- desc -> attrs = (Form_pg_attribute * )palloc (size );
58- desc -> constr = NULL ;
59- MemSet (desc -> attrs ,0 ,size );
6055
6156desc -> natts = natts ;
6257desc -> tdhasoid = hasoid ;
6358
59+ if (natts > 0 )
60+ {
61+ uint32 size = natts * sizeof (Form_pg_attribute );
62+
63+ desc -> attrs = (Form_pg_attribute * )palloc (size );
64+ MemSet (desc -> attrs ,0 ,size );
65+ }
66+ else
67+ desc -> attrs = NULL ;
68+ desc -> constr = NULL ;
69+
6470return desc ;
6571}
6672
@@ -79,7 +85,7 @@ CreateTupleDesc(int natts, bool hasoid, Form_pg_attribute *attrs)
7985/*
8086 * sanity checks
8187 */
82- AssertArg (natts >=1 );
88+ AssertArg (natts >=0 );
8389
8490desc = (TupleDesc )palloc (sizeof (struct tupleDesc ));
8591desc -> attrs = attrs ;
@@ -108,17 +114,20 @@ CreateTupleDescCopy(TupleDesc tupdesc)
108114
109115desc = (TupleDesc )palloc (sizeof (struct tupleDesc ));
110116desc -> natts = tupdesc -> natts ;
111- size = desc -> natts * sizeof (Form_pg_attribute );
112- desc -> attrs = (Form_pg_attribute * )palloc (size );
113- for (i = 0 ;i < desc -> natts ;i ++ )
117+ if (desc -> natts > 0 )
114118{
115- desc -> attrs [i ]= (Form_pg_attribute )palloc (ATTRIBUTE_TUPLE_SIZE );
116- memcpy (desc -> attrs [i ],
117- tupdesc -> attrs [i ],
118- ATTRIBUTE_TUPLE_SIZE );
119- desc -> attrs [i ]-> attnotnull = false;
120- desc -> attrs [i ]-> atthasdef = false;
119+ size = desc -> natts * sizeof (Form_pg_attribute );
120+ desc -> attrs = (Form_pg_attribute * )palloc (size );
121+ for (i = 0 ;i < desc -> natts ;i ++ )
122+ {
123+ desc -> attrs [i ]= (Form_pg_attribute )palloc (ATTRIBUTE_TUPLE_SIZE );
124+ memcpy (desc -> attrs [i ],tupdesc -> attrs [i ],ATTRIBUTE_TUPLE_SIZE );
125+ desc -> attrs [i ]-> attnotnull = false;
126+ desc -> attrs [i ]-> atthasdef = false;
127+ }
121128}
129+ else
130+ desc -> attrs = NULL ;
122131desc -> constr = NULL ;
123132desc -> tdhasoid = tupdesc -> tdhasoid ;
124133
@@ -142,15 +151,18 @@ CreateTupleDescCopyConstr(TupleDesc tupdesc)
142151
143152desc = (TupleDesc )palloc (sizeof (struct tupleDesc ));
144153desc -> natts = tupdesc -> natts ;
145- size = desc -> natts * sizeof (Form_pg_attribute );
146- desc -> attrs = (Form_pg_attribute * )palloc (size );
147- for (i = 0 ;i < desc -> natts ;i ++ )
154+ if (desc -> natts > 0 )
148155{
149- desc -> attrs [i ]= (Form_pg_attribute )palloc (ATTRIBUTE_TUPLE_SIZE );
150- memcpy (desc -> attrs [i ],
151- tupdesc -> attrs [i ],
152- ATTRIBUTE_TUPLE_SIZE );
156+ size = desc -> natts * sizeof (Form_pg_attribute );
157+ desc -> attrs = (Form_pg_attribute * )palloc (size );
158+ for (i = 0 ;i < desc -> natts ;i ++ )
159+ {
160+ desc -> attrs [i ]= (Form_pg_attribute )palloc (ATTRIBUTE_TUPLE_SIZE );
161+ memcpy (desc -> attrs [i ],tupdesc -> attrs [i ],ATTRIBUTE_TUPLE_SIZE );
162+ }
153163}
164+ else
165+ desc -> attrs = NULL ;
154166if (constr )
155167{
156168TupleConstr * cpy = (TupleConstr * )palloc (sizeof (TupleConstr ));
@@ -197,7 +209,8 @@ FreeTupleDesc(TupleDesc tupdesc)
197209
198210for (i = 0 ;i < tupdesc -> natts ;i ++ )
199211pfree (tupdesc -> attrs [i ]);
200- pfree (tupdesc -> attrs );
212+ if (tupdesc -> attrs )
213+ pfree (tupdesc -> attrs );
201214if (tupdesc -> constr )
202215{
203216if (tupdesc -> constr -> num_defval > 0 )
@@ -228,7 +241,6 @@ FreeTupleDesc(TupleDesc tupdesc)
228241}
229242
230243pfree (tupdesc );
231-
232244}
233245
234246/*
@@ -361,6 +373,7 @@ TupleDescInitEntry(TupleDesc desc,
361373 */
362374AssertArg (PointerIsValid (desc ));
363375AssertArg (attributeNumber >=1 );
376+ AssertArg (attributeNumber <=desc -> natts );
364377
365378/*
366379 * attributeName's are sometimes NULL, from resdom's. I don't know