Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1quNhb-000G0N-Nd for pgsql-hackers@arkaria.postgresql.org; Sun, 22 Oct 2023 01:56:27 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.94.2) (envelope-from ) id 1quNhZ-00ABde-Ho for pgsql-hackers@arkaria.postgresql.org; Sun, 22 Oct 2023 01:56:26 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1quNhZ-00ABdW-3e for pgsql-hackers@lists.postgresql.org; Sun, 22 Oct 2023 01:56:25 +0000 Received: from momjian.us ([72.94.173.45]) by magus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1quNhS-001zcs-27 for pgsql-hackers@postgresql.org; Sun, 22 Oct 2023 01:56:24 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=momjian.us; s=2023062407; h=In-Reply-To:Content-Type:MIME-Version:References:Message-ID: Subject:Cc:To:From:Date:Sender:Reply-To:Content-Transfer-Encoding:Content-ID: Content-Description; bh=cVseCTTthhfbmppPgij6jjtToW2TFXh5vMfyT4eIlH4=; b=3odUw ntRtiBPBQKBc9eg9s8xR8gwUvKOqMoF2iAfZnw2Nda30pDjrcq8Oc1u7UBxc6uabJ7HReyfzfmqNp /1I8WRe6RTr9uv8MdmZuOgUDu6vAQmYAzTOTHCuZx68q6Ut9bpcF1dpBkrFU28wrkhUYCAUhQSFaR c0ktKnAqaZ7Sc8D9rU4MvRtw28zEDWKQ/8keLeWXFObG686H/u8oxOe9QZFHhOYRvPW8j/Iq3BlQI o6ewYlm7/Suz6kZqgHZxk888JOBDBpgO5dTdTRK9cMaV0zp96E2VEuy2Zu2zGV/MCZrtxUETkG2kU dzHkuFN2hJUrnxwb3WMtbndJlo/HQ==; Received: from bruce by momjian.us with local (Exim 4.96) (envelope-from ) id 1quNhN-0028Zb-22; Sat, 21 Oct 2023 21:56:13 -0400 Date: Sat, 21 Oct 2023 21:56:13 -0400 From: Bruce Momjian To: Tom Lane Cc: Laurenz Albe , suchithjn22@gmail.com, PostgreSQL-development Subject: Re: The documentation for storage type 'plain' actually allows single byte header Message-ID: References: <167336599095.2667301.15497893107226841625@wrigleys.postgresql.org> <4977c12e127250fe9777ae57f6f5884b8f5c84ae.camel@cybertec.at> <1421365.1696027552@sss.pgh.pa.us> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk On Fri, Oct 20, 2023 at 09:48:05PM -0400, Bruce Momjian wrote: > Here is the original thread from pgsql-docs: > > https://www.postgresql.org/message-id/flat/167336599095.2667301.15497893107226841625%40wrigleys.postgresql.org > > The report is about single-byte headers being used for varlena values > with PLAIN storage. > > Here is the reproducible report: > > CREATE EXTENSION pageinspect; > CREATE TABLE test(a VARCHAR(10000) STORAGE PLAIN); > INSERT INTO test VALUES (repeat('A',10)); > > Now peek into the page with pageinspect functions > > SELECT left(encode(t_data, 'hex'), 40) FROM > heap_page_items(get_raw_page('test', 0)); > > This returned value of "1741414141414141414141". > Here the first byte 0x17 = 0001 0111 in binary. > Length + 1 is stored in the length bits (1-7). So Len = 0001011-1 = (11-1) > [base-10] = 10 [base-10] > which exactly matches the expected length. Further the data "41" repeated 10 > times also indicates character A (65 or 0x41 in ASCII) repeated 10 times. > > I researched this and thought it would be a case where we were lacking a > check before creating a single-byte header, but I couldn't find anything > missing. I think the problem is that the _source_ tupleDesc attstorage > attribute is being used to decide if we should use a short header, while > it is really the storage type of the destination that we should be > checking. Unfortunately, I don't think the destination is accessible at > the location were we are deciding about a short header. > > I am confused how to proceed. I feel we need to fully understand why > this happening before we adjust anything. Here is a backtrace --- the > short header is being created in fill_val() and the attstorage value > there is 'x'/EXTENDED. I did some more research. It turns out that the source slot/planSlot is populating its pg_attribute information via makeTargetEntry() and it has no concept of a storage type. Digging further, I found that we cannot get rid of the the use of att->attstorage != TYPSTORAGE_PLAIN in macros ATT_IS_PACKABLE and VARLENA_ATT_IS_PACKABLE macros in src/backend/access/common/heaptuple.c because there are internal uses of fill_val() that can't handle packed varlena headers. I ended up with a doc patch that adds a C comment about this odd behavior and removes doc text about PLAIN storage not using packed headers. -- Bruce Momjian https://momjian.us EDB https://enterprisedb.com Only you can decide what is important to you.