In PostgreSQL, what is the behavior of the bit(n) -> "char" cast? Using PostgreSQL if I cast

65::bit(8)::"char"


I get 0, if I however cast

65::bit(8)::int::"char"


I get A as I would expect.

SELECT
  v,
  v::bit(8)::"char" AS noint,
  v::bit(8)::int::"char" AS "viaInt"
FROM (VALUES (65)) AS t(v);
 v  | noint | viaInt 
----+-------+--------
 65 | 0     | A
(1 row)
That's because the cast directly to "char" without going through int first is taking the first character from the stringification of the bitfield.

SELECT 65::bit(8);
   bit    
----------
 01000001
(1 row)

SELECT '01000001'::"char", '0'::"char";
 char | char 
------+------
 0    | 0
(1 row)


If that was greater than 128, you'd have a one in that position,

SELECT 128::bit(8);
   bit    
----------
 10000000
(1 row)


Casting that to "char" would give you a 1 rather than a 0,

SELECT 128::bit(8)::"char";
 char 
------
 1
(1 row)


Keep in mind, "char" is signed, so the range is [-128,127]. For this reason you can't actually go from bit(8) to "char" without first shifting those bits. For example

SELECT 128::bit(8)::int::"char";
ERROR:  "char" out of range


See also


How exactly does the one-byte “char” type work in PostgreSQL?