Enum on-disk format

Started by Scott Baileyover 16 years ago4 messagesgeneral
Jump to latest
#1Scott Bailey
artacus@comcast.net

I'm trying to better understand the internals of Postgres, and I'm
looking at the enum type. The docs say that an enum value is stored on
disk as 4 bytes. But enum_send() returns a bytea representing the actual
text of the value and not the index of that value. So what step am I
missing here?

Also, is there a way to see the raw data for the tuple on a page? I was
using pageinspect to try to figure out what was happening on the disk.
The get_raw_page function returns the entire page and heap_page_items
will allow me to find the substring that represents a given tuple. But
the rows were much wider than I thought they would be, 28 bytes + 2 byte
spacer to store 4 bytes of data. Is there any way to see which bytes of
an item pointer actually map to columns in a table? And where can I find
more info on how Postgres stores tuples?

Scott Bailey

#2Tom Lane
tgl@sss.pgh.pa.us
In reply to: Scott Bailey (#1)
Re: Enum on-disk format

Scott Bailey <artacus@comcast.net> writes:

I'm trying to better understand the internals of Postgres, and I'm
looking at the enum type. The docs say that an enum value is stored on
disk as 4 bytes. But enum_send() returns a bytea representing the actual
text of the value and not the index of that value. So what step am I
missing here?

The wire format isn't necessarily the on-disk format. In this case
we concluded that the internal OID value wouldn't be of any use to
clients.

Also, is there a way to see the raw data for the tuple on a page?

Try contrib/pageinspect, and read
http://developer.postgresql.org/pgdocs/postgres/storage-page-layout.html

regards, tom lane

#3Scott Bailey
artacus@comcast.net
In reply to: Tom Lane (#2)
Re: Enum on-disk format

Tom Lane wrote:

Scott Bailey <artacus@comcast.net> writes:

I'm trying to better understand the internals of Postgres, and I'm
looking at the enum type. The docs say that an enum value is stored on
disk as 4 bytes. But enum_send() returns a bytea representing the actual
text of the value and not the index of that value. So what step am I
missing here?

The wire format isn't necessarily the on-disk format. In this case
we concluded that the internal OID value wouldn't be of any use to
clients.

Also, is there a way to see the raw data for the tuple on a page?

Try contrib/pageinspect, and read
http://developer.postgresql.org/pgdocs/postgres/storage-page-layout.html

regards, tom lane

Thanks Tom that did the trick. The only I/O functions I'm aware of are
send, recv, in and out. What controls converting from/to wire and
on-disk formats? And why is wire format little endian and disk big endian?

And for posterity, here's how to get to the raw tuple data.

SELECT substring(page, lp_off + t_hoff + 1, lp_len - t_hoff) AS tuple_data,
sub.*
FROM (
SELECT (heap_page_items(page)).*, page
FROM (
SELECT get_raw_page('test', 0) page
) s
) sub

#4Peter Eisentraut
peter_e@gmx.net
In reply to: Scott Bailey (#3)
Re: Enum on-disk format

On ons, 2009-11-18 at 22:33 -0800, Scott Bailey wrote:

The only I/O functions I'm aware of are
send, recv, in and out. What controls converting from/to wire and
on-disk formats?

send and recv

And why is wire format little endian and disk big endian?

The wire format is network order (which is big endian), the disk format
is whatever your CPU uses.