8
8
*
9
9
*
10
10
* 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 $
12
12
*
13
13
* NOTES
14
14
* some of the executor utility code such as "ExecTypeFromTL" should be
39
39
TupleDesc
40
40
CreateTemplateTupleDesc (int natts ,bool hasoid )
41
41
{
42
- uint32 size ;
43
42
TupleDesc desc ;
44
43
45
44
/*
46
45
* sanity checks
47
46
*/
48
- AssertArg (natts >=1 );
47
+ AssertArg (natts >=0 );
49
48
50
49
/*
51
50
* allocate enough memory for the tuple descriptor and zero it as
52
51
* TupleDescInitEntry assumes that the descriptor is filled with NULL
53
52
* pointers.
54
53
*/
55
- size = natts * sizeof (Form_pg_attribute );
56
54
desc = (TupleDesc )palloc (sizeof (struct tupleDesc ));
57
- desc -> attrs = (Form_pg_attribute * )palloc (size );
58
- desc -> constr = NULL ;
59
- MemSet (desc -> attrs ,0 ,size );
60
55
61
56
desc -> natts = natts ;
62
57
desc -> tdhasoid = hasoid ;
63
58
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
+
64
70
return desc ;
65
71
}
66
72
@@ -79,7 +85,7 @@ CreateTupleDesc(int natts, bool hasoid, Form_pg_attribute *attrs)
79
85
/*
80
86
* sanity checks
81
87
*/
82
- AssertArg (natts >=1 );
88
+ AssertArg (natts >=0 );
83
89
84
90
desc = (TupleDesc )palloc (sizeof (struct tupleDesc ));
85
91
desc -> attrs = attrs ;
@@ -108,17 +114,20 @@ CreateTupleDescCopy(TupleDesc tupdesc)
108
114
109
115
desc = (TupleDesc )palloc (sizeof (struct tupleDesc ));
110
116
desc -> 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 )
114
118
{
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
+ }
121
128
}
129
+ else
130
+ desc -> attrs = NULL ;
122
131
desc -> constr = NULL ;
123
132
desc -> tdhasoid = tupdesc -> tdhasoid ;
124
133
@@ -142,15 +151,18 @@ CreateTupleDescCopyConstr(TupleDesc tupdesc)
142
151
143
152
desc = (TupleDesc )palloc (sizeof (struct tupleDesc ));
144
153
desc -> 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 )
148
155
{
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
+ }
153
163
}
164
+ else
165
+ desc -> attrs = NULL ;
154
166
if (constr )
155
167
{
156
168
TupleConstr * cpy = (TupleConstr * )palloc (sizeof (TupleConstr ));
@@ -197,7 +209,8 @@ FreeTupleDesc(TupleDesc tupdesc)
197
209
198
210
for (i = 0 ;i < tupdesc -> natts ;i ++ )
199
211
pfree (tupdesc -> attrs [i ]);
200
- pfree (tupdesc -> attrs );
212
+ if (tupdesc -> attrs )
213
+ pfree (tupdesc -> attrs );
201
214
if (tupdesc -> constr )
202
215
{
203
216
if (tupdesc -> constr -> num_defval > 0 )
@@ -228,7 +241,6 @@ FreeTupleDesc(TupleDesc tupdesc)
228
241
}
229
242
230
243
pfree (tupdesc );
231
-
232
244
}
233
245
234
246
/*
@@ -361,6 +373,7 @@ TupleDescInitEntry(TupleDesc desc,
361
373
*/
362
374
AssertArg (PointerIsValid (desc ));
363
375
AssertArg (attributeNumber >=1 );
376
+ AssertArg (attributeNumber <=desc -> natts );
364
377
365
378
/*
366
379
* attributeName's are sometimes NULL, from resdom's. I don't know