88 *
99 *
1010 * 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 $
1212 *
1313 *-------------------------------------------------------------------------
1414 */
@@ -213,8 +213,7 @@ TypeCreate(Oid newTypeOid,
213213 * not check for bad combinations.
214214 *
215215 * 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).
218217 */
219218if (!(internalSize > 0 ||
220219internalSize == -1 ||
@@ -223,12 +222,70 @@ TypeCreate(Oid newTypeOid,
223222(errcode (ERRCODE_INVALID_OBJECT_DEFINITION ),
224223errmsg ("invalid type internal size %d" ,
225224internalSize )));
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 ),
230271errmsg ("internal size %d is invalid for passed-by-value type" ,
231272internalSize )));
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+ }
232289
233290/* Only varlena types can be toasted */
234291if (storage != 'p' && internalSize != -1 )