Можно сказать, что можно вычесть 4 из результата для типов char
и varchar
.Что делает information_schema.columns
представление под капотом, так это то, что оно вызывает функцию informatoin_schema._pg_char_max_length
(, в этом ваша разница, поскольку вы не ), тело которой:
CREATE OR REPLACE FUNCTION information_schema._pg_char_max_length(typid oid, typmod integer)
RETURNS integer
LANGUAGE sql
IMMUTABLE PARALLEL SAFE STRICT
AS $function$SELECT
CASE WHEN $2 = -1 /* default typmod */
THEN null
WHEN $1 IN (1042, 1043) /* char, varchar */
THEN $2 - 4
WHEN $1 IN (1560, 1562) /* bit, varbit */
THEN $2
ELSE null
END$function$
Тосказал, что для chars и varchars это всегда вычитает 4. Это делает ваш запрос не эквивалентным в той степени, в которой ему действительно нужно объединение с pg_type
, чтобы установить typid
столбца и обернуть значение в функции, чтобывернуть правильные значения.Это связано с тем, что в игру вступает больше вещей, чем просто.Если вы хотите упростить, вы можете сделать это без объединения (хотя это не будет пуленепробиваемым):
SELECT attname,
atttypid::regtype AS datatype,
NULLIF(information_schema._pg_char_max_length(atttypid, atttypmod), -1) AS maxlen
FROM pg_attribute
WHERE CAST(attrelid::regclass AS varchar) = 'x'
AND attnum > 0
AND NOT attisdropped
Это должно сделать это для вас.Если вы хотите продолжить расследование, обратитесь к определению вида information_schema.columns
.