Thread: Why the lp_len is 28 not 32?

Why the lp_len is 28 not 32?

From
"jacktby@gmail.com"
Date:
use these sqls below:
create table t(a int);
insert into t values(1);
select lp,lp_off,lp_len,t_data from heap_page_items(get_raw_page('t',0));
 lp | lp_off | lp_len |   t_data   
----+--------+--------+------------
  1 |   8160 |     28 | \x01000000
--------------------------------------------------------------------------------
jacktby@gmail.com

Re: Why the lp_len is 28 not 32?

From
Tomas Vondra
Date:
On 2/26/23 15:35, jacktby@gmail.com wrote:
> use these sqls below:
> create table t(a int);
> insert into t values(1);
> select lp,lp_off,lp_len,t_data from heap_page_items(get_raw_page('t',0));
>  lp | lp_off | lp_len |   t_data   
> ----+--------+--------+------------
>   1 |   8160 |     28 | \x01000000
> --------------------------------------------------------------------------------

Pretty sure this is because we align the data to MAXALIGN, and on x86_64
that's 8 bytes. 28 is not a multiple of 8 while 32 is.

regards

-- 
Tomas Vondra
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company



Re: Re: Why the lp_len is 28 not 32?

From
"jacktby@gmail.com"
Date:
 
Date: 2023-02-26 23:07
Subject: Re: Why the lp_len is 28 not 32?
On 2/26/23 15:35, jacktby@gmail.com wrote:
> use these sqls below:
> create table t(a int);
> insert into t values(1);
> select lp,lp_off,lp_len,t_data from heap_page_items(get_raw_page('t',0));
>  lp | lp_off | lp_len |   t_data   
> ----+--------+--------+------------
>   1 |   8160 |     28 | \x01000000
> --------------------------------------------------------------------------------
 
Pretty sure this is because we align the data to MAXALIGN, and on x86_64
that's 8 bytes. 28 is not a multiple of 8 while 32 is.
 
regards
 
--
Tomas Vondra
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company

yes, So it should be 32 bytes not 28bytes, but the sql result is 28 !!!!!! that's false!!!!
-------------------------------------------------

Re: Why the lp_len is 28 not 32?

From
Tomas Vondra
Date:
On 2/26/23 16:11, jacktby@gmail.com wrote:

> 
>     yes, So it should be 32 bytes not 28bytes, but the sql result is 28
>     !!!!!! that's false!!!!

No. The tuple is 28 bytes long, and that's what's stored in lp_len. But
we align the start of the tuple to a multiple of 8 bytes. So it's at
offset 8160 because that's the closest multiple of 8. Then there's 28
bytes of data and then 4 empty bytes.

regards

-- 
Tomas Vondra
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company



Re: Re: Why the lp_len is 28 not 32?

From
"David G. Johnston"
Date:
On Sun, Feb 26, 2023 at 8:11 AM jacktby@gmail.com <jacktby@gmail.com> wrote:
 
> ----+--------+--------+------------
>   1 |   8160 |     28 | \x01000000
> --------------------------------------------------------------------------------
 
Pretty sure this is because we align the data to MAXALIGN, and on x86_64
that's 8 bytes. 28 is not a multiple of 8 while 32 is.
 
>> yes, So it should be 32 bytes not 28bytes, but the sql result is 28 !!!!!! that's false!!!!


No, that is a definition not matching your expectation.  Are you trying to demonstrate a bug here or just observing that your intuition of this didn't work here?

The content doesn't include alignment padding.  The claim isn't that the size is "the number of bytes consumed in some place within the page" but rather the size is "the number of bytes needed to get the content required to be passed into the input function for the datatype".  Nicely, it is trivial to then align the value to figure out the consumed width.  If you just have the aligned size you would never know how many bytes you need for the data value.

David J.