Postgres casting to bit
vs. varbit
vs. "bit"
(with quotes)
April 5, 2023
bit
vs. varbit
vs. "bit"
(with quotes)April 5, 2023
Here’s a few things to know if you’re working with bit strings in Postgres.
bit
means bit(1)
As documented here,
bit
is an alias for bit(1)
, so it will only keep the least
significant bit.
42::bit(10) 0000101010
42::bit(1) 0
42::bit 0
43::bit(10) 0000101011
43::bit(1) 1
43::bit 1
B'101010'
You can define bit strings with the B
prefix:
B'101010' 101010
B'101010'::int 42
pg_typeof(B'101010') bit
bit
If you have a string made of only 0s and 1s, you can cast it to a bit string too! Useful for dynamically generating bit sequences.
'101010'::bit(10) 1010100000
But we instantly notice an interesting difference: when casting from an integer as we did earlier, the truncation (or padding otherwise) was right-aligned, while when casting from a string, it’s left-aligned.
12::bit(4) 1100
12::bit(2) 00
'1100'::bit(4) 1100
'1100'::bit(2) 11
B'1100'::bit(2) 11
What if you’re generating a bit string from… an actual string, but you don’t know its length in advance? You can always use a fixed length that’s larger than what you think you’ll need, but that may not be very efficient.
Instead, you can use the bit varying
type, also known as varbit
!
'101010'::bit varying 101010
'101010'::varbit 101010
pg_typeof('101010'::bit varying) bit varying
pg_typeof('101010'::varbit) bit varying
Alternatively, there’s an internal, undocumented "bit"
type
(to not be mistaken with bit
without the quotes), which will
automatically cast to a static-sized bit
, but inferring the size form
the input!
'101010'::bit 1
'101010'::varbit 101010
pg_typeof('101010'::varbit) bit varying
'101010'::"bit" 101010
pg_typeof('101010'::"bit") bit
Note: there’s probably very little situations where you’d need
"bit"
instead of varbit
, but at least now you know it exists. I
wouldn’t recommend relying on a type that’s internal to Postgres and
undocumented though!
The "bit"
magic is not transparent to \gdesc
though:
'101010'::bit 1 bit(1)
'101010'::bit(6) 101010 bit(6)
'101010'::varbit 101010 bit varying
'101010'::"bit" 101010 "bit"