8
8
*
9
9
*
10
10
* IDENTIFICATION
11
- * $PostgreSQL: pgsql/src/backend/catalog/pg_type.c,v 1.120 2008/07/30 17:05:04 tgl Exp $
11
+ * $PostgreSQL: pgsql/src/backend/catalog/pg_type.c,v 1.121 2008/08/03 15:23:58 tgl Exp $
12
12
*
13
13
*-------------------------------------------------------------------------
14
14
*/
@@ -213,8 +213,7 @@ TypeCreate(Oid newTypeOid,
213
213
* not check for bad combinations.
214
214
*
215
215
* Validate size specifications: either positive (fixed-length) or -1
216
- * (varlena) or -2 (cstring). Pass-by-value types must have a fixed
217
- * length not more than sizeof(Datum).
216
+ * (varlena) or -2 (cstring).
218
217
*/
219
218
if (!(internalSize > 0 ||
220
219
internalSize == -1 ||
@@ -223,12 +222,70 @@ TypeCreate(Oid newTypeOid,
223
222
(errcode (ERRCODE_INVALID_OBJECT_DEFINITION ),
224
223
errmsg ("invalid type internal size %d" ,
225
224
internalSize )));
226
- if (passedByValue &&
227
- (internalSize <= 0 || internalSize > (int16 ) sizeof (Datum )))
228
- ereport (ERROR ,
229
- (errcode (ERRCODE_INVALID_OBJECT_DEFINITION ),
225
+
226
+ if (passedByValue )
227
+ {
228
+ /*
229
+ * Pass-by-value types must have a fixed length that is one of the
230
+ * values supported by fetch_att() and store_att_byval(); and the
231
+ * alignment had better agree, too. All this code must match
232
+ * access/tupmacs.h!
233
+ */
234
+ if (internalSize == (int16 ) sizeof (char ))
235
+ {
236
+ if (alignment != 'c' )
237
+ ereport (ERROR ,
238
+ (errcode (ERRCODE_INVALID_OBJECT_DEFINITION ),
239
+ errmsg ("alignment \"%c\" is invalid for passed-by-value type of size %d" ,
240
+ alignment , internalSize )));
241
+ }
242
+ else if (internalSize == (int16 ) sizeof (int16 ))
243
+ {
244
+ if (alignment != 's' )
245
+ ereport (ERROR ,
246
+ (errcode (ERRCODE_INVALID_OBJECT_DEFINITION ),
247
+ errmsg ("alignment \"%c\" is invalid for passed-by-value type of size %d" ,
248
+ alignment , internalSize )));
249
+ }
250
+ else if (internalSize == (int16 ) sizeof (int32 ))
251
+ {
252
+ if (alignment != 'i' )
253
+ ereport (ERROR ,
254
+ (errcode (ERRCODE_INVALID_OBJECT_DEFINITION ),
255
+ errmsg ("alignment \"%c\" is invalid for passed-by-value type of size %d" ,
256
+ alignment , internalSize )));
257
+ }
258
+ #if SIZEOF_DATUM == 8
259
+ else if (internalSize == (int16 ) sizeof (Datum ))
260
+ {
261
+ if (alignment != 'd' )
262
+ ereport (ERROR ,
263
+ (errcode (ERRCODE_INVALID_OBJECT_DEFINITION ),
264
+ errmsg ("alignment \"%c\" is invalid for passed-by-value type of size %d" ,
265
+ alignment , internalSize )));
266
+ }
267
+ #endif
268
+ else
269
+ ereport (ERROR ,
270
+ (errcode (ERRCODE_INVALID_OBJECT_DEFINITION ),
230
271
errmsg ("internal size %d is invalid for passed-by-value type" ,
231
272
internalSize )));
273
+ }
274
+ else
275
+ {
276
+ /* varlena types must have int align or better */
277
+ if (internalSize == -1 && !(alignment == 'i' || alignment == 'd' ))
278
+ ereport (ERROR ,
279
+ (errcode (ERRCODE_INVALID_OBJECT_DEFINITION ),
280
+ errmsg ("alignment \"%c\" is invalid for variable-length type" ,
281
+ alignment )));
282
+ /* cstring must have char alignment */
283
+ if (internalSize == -2 && !(alignment == 'c' ))
284
+ ereport (ERROR ,
285
+ (errcode (ERRCODE_INVALID_OBJECT_DEFINITION ),
286
+ errmsg ("alignment \"%c\" is invalid for variable-length type" ,
287
+ alignment )));
288
+ }
232
289
233
290
/* Only varlena types can be toasted */
234
291
if (storage != 'p' && internalSize != -1 )
0 commit comments