Today's test case detected alignment problems only when executing on
AIX. This change lets popular platforms detect the same problems.
Reviewed by Masahiko Sawada.
Discussion: https://postgr.es/m/
20220415072601.GG862547@rfd.leadboat.com
SELECT t.oid
FROM pg_type t JOIN pg_attribute pa ON t.oid = pa.atttypid
WHERE pa.attrelid = a.attrelid AND
- pa.attnum > 0 AND pa.attnum <= a.attnum
+ pa.attnum > 0 AND pa.attnum < a.attnum
ORDER BY pa.attnum) AS coltypes
FROM pg_attribute a JOIN pg_class c ON c.oid = attrelid
JOIN pg_namespace n ON c.relnamespace = n.oid
WHERE attalign = 'd' AND relkind = 'r' AND
attnotnull AND attlen <> -1 AND n.nspname = 'pg_catalog'
)
-SELECT relname, attname, coltypes, get_column_offset(coltypes)
+SELECT relname, attname, coltypes, get_columns_length(coltypes)
FROM check_columns
- WHERE get_column_offset(coltypes) % 8 != 0 OR
+ WHERE get_columns_length(coltypes) % 8 != 0 OR
'name'::regtype::oid = ANY(coltypes);
- relname | attname | coltypes | get_column_offset
----------+---------+----------+-------------------
+ relname | attname | coltypes | get_columns_length
+---------+---------+----------+--------------------
(0 rows)
RETURNS trigger
AS :'regresslib'
LANGUAGE C;
-CREATE FUNCTION get_column_offset (oid[])
+CREATE FUNCTION get_columns_length(oid[])
RETURNS int
AS :'regresslib'
LANGUAGE C STRICT STABLE PARALLEL SAFE;
}
/*
- * Return the column offset of the last data in the given array of
- * data types. The input data types must be fixed-length data types.
+ * Return the length of the portion of a tuple consisting of the given array
+ * of data types. The input data types must be fixed-length data types.
*/
-PG_FUNCTION_INFO_V1(get_column_offset);
+PG_FUNCTION_INFO_V1(get_columns_length);
Datum
-get_column_offset(PG_FUNCTION_ARGS)
+get_columns_length(PG_FUNCTION_ARGS)
{
ArrayType *ta = PG_GETARG_ARRAYTYPE_P(0);
Oid *type_oids;
get_typlenbyvalalign(typeoid, &typlen, &typbyval, &typalign);
/* the data type must be fixed-length */
- if (!(typbyval || (typlen > 0)))
+ if (typlen < 0)
elog(ERROR, "type %u is not fixed-length data type", typeoid);
- column_offset = att_align_nominal(column_offset, typalign);
-
- /* not include the last type size */
- if (i != (ntypes - 1))
- column_offset += typlen;
+ column_offset = att_align_nominal(column_offset + typlen, typalign);
}
PG_RETURN_INT32(column_offset);
SELECT t.oid
FROM pg_type t JOIN pg_attribute pa ON t.oid = pa.atttypid
WHERE pa.attrelid = a.attrelid AND
- pa.attnum > 0 AND pa.attnum <= a.attnum
+ pa.attnum > 0 AND pa.attnum < a.attnum
ORDER BY pa.attnum) AS coltypes
FROM pg_attribute a JOIN pg_class c ON c.oid = attrelid
JOIN pg_namespace n ON c.relnamespace = n.oid
WHERE attalign = 'd' AND relkind = 'r' AND
attnotnull AND attlen <> -1 AND n.nspname = 'pg_catalog'
)
-SELECT relname, attname, coltypes, get_column_offset(coltypes)
+SELECT relname, attname, coltypes, get_columns_length(coltypes)
FROM check_columns
- WHERE get_column_offset(coltypes) % 8 != 0 OR
+ WHERE get_columns_length(coltypes) % 8 != 0 OR
'name'::regtype::oid = ANY(coltypes);
AS :'regresslib'
LANGUAGE C;
-CREATE FUNCTION get_column_offset (oid[])
+CREATE FUNCTION get_columns_length(oid[])
RETURNS int
AS :'regresslib'
LANGUAGE C STRICT STABLE PARALLEL SAFE;