Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.89) (envelope-from ) id 1i5bEk-00086E-C6 for pgsql-hackers@arkaria.postgresql.org; Wed, 04 Sep 2019 19:46:38 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.89) (envelope-from ) id 1i5bEj-0005Md-5Z for pgsql-hackers@arkaria.postgresql.org; Wed, 04 Sep 2019 19:46:37 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.89) (envelope-from ) id 1i5bEi-0005MW-RZ for pgsql-hackers@lists.postgresql.org; Wed, 04 Sep 2019 19:46:36 +0000 Received: from mail-qt1-x844.google.com ([2607:f8b0:4864:20::844]) by magus.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.89) (envelope-from ) id 1i5bEf-0008D1-W2 for pgsql-hackers@postgresql.org; Wed, 04 Sep 2019 19:46:36 +0000 Received: by mail-qt1-x844.google.com with SMTP id b2so22339068qtq.5 for ; Wed, 04 Sep 2019 12:46:33 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=2ndquadrant-com.20150623.gappssmtp.com; s=20150623; h=date:from:to:cc:subject:message-id:mime-version:content-disposition :content-transfer-encoding:in-reply-to:user-agent; bh=Ryzs1qyBQSDCWWOLen4d/UXfioTqnhYwGA+QY3KHxJo=; b=Xebkty8EkvIUXm/er/NcFeuvUMda2PDEiWL1x5bPnESpgm96N0ax1hbQzQlxRETer1 cSVUiAtgUUtnczEjjhUXFL8E6cHGxn4ooqL+qw7qO0EBzwXdwrH/jitepwVsukX8I/zb SRv1buZaBka3H8dbGp3KtP8Ijp8MwzAdhokTsV6UmqggTSYBKq3k0vVU8HNGDHTbd/GN aANGy4N8yIgCmr5O3r7bnX/Cxl3r0ERJlknuk8U9HatWDA68lhBXVO4xb57IDWaI6uo0 m2xgp3QDZL8iIoax8hL3VP+C9IqDXlNPcQKaQiYoIIhv2Gax2Dbtl2ffoQXgb/hEYt7d DK7Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:mime-version :content-disposition:content-transfer-encoding:in-reply-to :user-agent; bh=Ryzs1qyBQSDCWWOLen4d/UXfioTqnhYwGA+QY3KHxJo=; b=chnrnD2/uIxYcyLjqoWSnffOTt/ywUWFFkKGybX8xiE30BXUPmiy66QGTSn0EvJ0bI 8EZ2lPsRUaMffS7XpQUSHLDOQdG+VqZmj07VCm3EtnYaj2vdemYya367LL2gmZbKp6Zn WTXsROwI8p5M8GxF/L5v/JZ+X28mz8qZ7ok09N7n+DDPJbvA47FTcn2QjI/tfrAuaa4y TXFK+jljtaWPeuR36jPnpR8505QVa5t3KZ1+qM+Duptimnjml7DjK1P4mz7o1KiLt27o YdoWA/YVTl/fPMbjj03Gq7vUfkZAMKSzR2UNRWxUitmGxgoFlkcjwzGrFmBRawkldR/E MoBg== X-Gm-Message-State: APjAAAXVc4R4+N0+vJ5xzVvXv9vEn+vjYSqDTABfJDfPankxD2iHAeVZ WjOZNGZxVKTkiwKftp+JfqE2eA== X-Google-Smtp-Source: APXvYqy9orBVKfk+4B1pxR9IAAr86JIH4LhNS8WBs4uFo3EJ1zehd2Jb2wOBCKHFCtf9YBoa4Qna8Q== X-Received: by 2002:ac8:43c2:: with SMTP id w2mr31897892qtn.295.1567626392683; Wed, 04 Sep 2019 12:46:32 -0700 (PDT) Received: from nimloth.alvh.no-ip.org ([179.56.51.113]) by smtp.gmail.com with ESMTPSA id g19sm10768753qtb.2.2019.09.04.12.46.31 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 04 Sep 2019 12:46:31 -0700 (PDT) Received: by nimloth.alvh.no-ip.org (Postfix, from userid 1000) id B7DEE123A1B; Wed, 4 Sep 2019 15:46:29 -0400 (-04) Date: Wed, 4 Sep 2019 15:46:29 -0400 From: Alvaro Herrera To: Masahiko Sawada Cc: Craig Ringer , Ashutosh Sharma , Julien Rouhaud , Peter Geoghegan , PostgreSQL Hackers , Abhijit Menon-Sen , Peter Eisentraut , Pavan Deolasee Subject: Re: [HACKERS] [PATCH] pageinspect function to decode infomasks Message-ID: <20190904194629.GA12433@alvherre.pgsql> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="sm4nu43k4a2Rpi4c" Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: User-Agent: Mutt/1.9.4 (2018-02-28) List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Precedence: bulk --sm4nu43k4a2Rpi4c Content-Type: text/plain; charset=iso-8859-1 Content-Disposition: inline Content-Transfer-Encoding: 8bit Attached v3 again, for CFbot's benefit. No changes from last time. -- Álvaro Herrera https://www.2ndQuadrant.com/ PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services --sm4nu43k4a2Rpi4c Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="v3-0001-Introduce-heap_infomask_flags-to-decode-infomask-.patch" From 018077d786f874cb314b5f61b5ef85f42c62bbe5 Mon Sep 17 00:00:00 2001 From: Masahiko Sawada Date: Fri, 23 Aug 2019 10:36:13 +0900 Subject: [PATCH v3] Introduce heap_infomask_flags to decode infomask and infomask2 --- contrib/pageinspect/Makefile | 2 +- contrib/pageinspect/expected/page.out | 97 ++++++++++++++++++++++++ contrib/pageinspect/heapfuncs.c | 104 ++++++++++++++++++++++++++ contrib/pageinspect/pageinspect--1.7--1.8.sql | 13 ++++ contrib/pageinspect/pageinspect.control | 2 +- contrib/pageinspect/sql/page.sql | 26 +++++++ doc/src/sgml/pageinspect.sgml | 33 ++++++++ 7 files changed, 275 insertions(+), 2 deletions(-) create mode 100644 contrib/pageinspect/pageinspect--1.7--1.8.sql diff --git a/contrib/pageinspect/Makefile b/contrib/pageinspect/Makefile index e5a581f..cfe0129 100644 --- a/contrib/pageinspect/Makefile +++ b/contrib/pageinspect/Makefile @@ -5,7 +5,7 @@ OBJS = rawpage.o heapfuncs.o btreefuncs.o fsmfuncs.o \ brinfuncs.o ginfuncs.o hashfuncs.o $(WIN32RES) EXTENSION = pageinspect -DATA = pageinspect--1.6--1.7.sql \ +DATA = pageinspect--1.7--1.8.sql pageinspect--1.6--1.7.sql \ pageinspect--1.5.sql pageinspect--1.5--1.6.sql \ pageinspect--1.4--1.5.sql pageinspect--1.3--1.4.sql \ pageinspect--1.2--1.3.sql pageinspect--1.1--1.2.sql \ diff --git a/contrib/pageinspect/expected/page.out b/contrib/pageinspect/expected/page.out index 3fcd9fb..3b47599 100644 --- a/contrib/pageinspect/expected/page.out +++ b/contrib/pageinspect/expected/page.out @@ -82,6 +82,103 @@ SELECT * FROM fsm_page_contents(get_raw_page('test1', 'fsm', 0)); (1 row) +-- If we freeze the only tuple on test1, the infomask should +-- always be the same in all test runs. +VACUUM FREEZE test1; +SELECT t_infomask, t_infomask2, flags +FROM heap_page_items(get_raw_page('test1', 0)), + LATERAL heap_infomask_flags(t_infomask, t_infomask2, true) m(flags); + t_infomask | t_infomask2 | flags +------------+-------------+-------------------------------------- + 2816 | 2 | {HEAP_XMAX_INVALID,HEAP_XMIN_FROZEN} +(1 row) + +SELECT t_infomask, t_infomask2, flags +FROM heap_page_items(get_raw_page('test1', 0)), + LATERAL heap_infomask_flags(t_infomask, t_infomask2, false) m(flags); + t_infomask | t_infomask2 | flags +------------+-------------+----------------------------------------------------------- + 2816 | 2 | {HEAP_XMAX_INVALID,HEAP_XMIN_COMMITTED,HEAP_XMIN_INVALID} +(1 row) + +SELECT heap_infomask_flags(2816, 0); -- show raw flags by default + heap_infomask_flags +----------------------------------------------------------- + {HEAP_XMAX_INVALID,HEAP_XMIN_COMMITTED,HEAP_XMIN_INVALID} +(1 row) + +SELECT heap_infomask_flags(2816, 0, true); + heap_infomask_flags +-------------------------------------- + {HEAP_XMAX_INVALID,HEAP_XMIN_FROZEN} +(1 row) + +SELECT heap_infomask_flags(2816, 1, true); + heap_infomask_flags +-------------------------------------- + {HEAP_XMAX_INVALID,HEAP_XMIN_FROZEN} +(1 row) + +SELECT heap_infomask_flags(2816, 1, false); + heap_infomask_flags +----------------------------------------------------------- + {HEAP_XMAX_INVALID,HEAP_XMIN_COMMITTED,HEAP_XMIN_INVALID} +(1 row) + +SELECT heap_infomask_flags(2816, x'FFFF'::integer, true); + heap_infomask_flags +----------------------------------------------------------------------------------------- + {HEAP_XMAX_INVALID,HEAP_XMIN_FROZEN,HEAP_KEYS_UPDATED,HEAP_HOT_UPDATED,HEAP_ONLY_TUPLE} +(1 row) + +SELECT heap_infomask_flags(2816, x'FFFF'::integer, false); + heap_infomask_flags +-------------------------------------------------------------------------------------------------------------- + {HEAP_XMAX_INVALID,HEAP_XMIN_COMMITTED,HEAP_XMIN_INVALID,HEAP_KEYS_UPDATED,HEAP_HOT_UPDATED,HEAP_ONLY_TUPLE} +(1 row) + +SELECT heap_infomask_flags(x'1080'::integer, 0, true); -- test for HEAP_LOCKED_UPGRADED + heap_infomask_flags +------------------------ + {HEAP_LOCKED_UPGRADED} +(1 row) + +SELECT heap_infomask_flags(x'1080'::integer, 0, false); + heap_infomask_flags +------------------------------------------ + {HEAP_XMAX_LOCK_ONLY,HEAP_XMAX_IS_MULTI} +(1 row) + +SELECT heap_infomask_flags(x'FFFF'::integer, x'FFFF'::integer, false); + heap_infomask_flags +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ + {HEAP_HASNULL,HEAP_HASVARWIDTH,HEAP_HASEXTERNAL,HEAP_HASOID_OLD,HEAP_COMBOCID,HEAP_XMAX_COMMITTED,HEAP_XMAX_INVALID,HEAP_UPDATED,HEAP_XMAX_EXCL_LOCK,HEAP_XMAX_KEYSHR_LOCK,HEAP_XMIN_COMMITTED,HEAP_XMIN_INVALID,HEAP_MOVED_IN,HEAP_MOVED_OFF,HEAP_XMAX_LOCK_ONLY,HEAP_XMAX_IS_MULTI,HEAP_KEYS_UPDATED,HEAP_HOT_UPDATED,HEAP_ONLY_TUPLE} +(1 row) + +SELECT heap_infomask_flags(x'FFFF'::integer, x'FFFF'::integer, true); + heap_infomask_flags +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + {HEAP_HASNULL,HEAP_HASVARWIDTH,HEAP_HASEXTERNAL,HEAP_HASOID_OLD,HEAP_COMBOCID,HEAP_XMAX_COMMITTED,HEAP_XMAX_INVALID,HEAP_UPDATED,HEAP_XMAX_SHR_LOCK,HEAP_XMIN_FROZEN,HEAP_MOVED,HEAP_XMAX_LOCK_ONLY,HEAP_XMAX_IS_MULTI,HEAP_KEYS_UPDATED,HEAP_HOT_UPDATED,HEAP_ONLY_TUPLE} +(1 row) + +SELECT heap_infomask_flags(0, 0, true); + heap_infomask_flags +--------------------- + {} +(1 row) + +SELECT heap_infomask_flags(0, 0, false); + heap_infomask_flags +--------------------- + {} +(1 row) + +SELECT heap_infomask_flags(-1, -1, false); + heap_infomask_flags +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ + {HEAP_HASNULL,HEAP_HASVARWIDTH,HEAP_HASEXTERNAL,HEAP_HASOID_OLD,HEAP_COMBOCID,HEAP_XMAX_COMMITTED,HEAP_XMAX_INVALID,HEAP_UPDATED,HEAP_XMAX_EXCL_LOCK,HEAP_XMAX_KEYSHR_LOCK,HEAP_XMIN_COMMITTED,HEAP_XMIN_INVALID,HEAP_MOVED_IN,HEAP_MOVED_OFF,HEAP_XMAX_LOCK_ONLY,HEAP_XMAX_IS_MULTI,HEAP_KEYS_UPDATED,HEAP_HOT_UPDATED,HEAP_ONLY_TUPLE} +(1 row) + DROP TABLE test1; -- check that using any of these functions with a partitioned table or index -- would fail diff --git a/contrib/pageinspect/heapfuncs.c b/contrib/pageinspect/heapfuncs.c index 64a6e35..0a89d47 100644 --- a/contrib/pageinspect/heapfuncs.c +++ b/contrib/pageinspect/heapfuncs.c @@ -33,6 +33,7 @@ #include "catalog/pg_am_d.h" #include "catalog/pg_type.h" #include "miscadmin.h" +#include "port/pg_bitutils.h" #include "utils/array.h" #include "utils/builtins.h" #include "utils/rel.h" @@ -494,3 +495,106 @@ tuple_data_split(PG_FUNCTION_ARGS) PG_RETURN_ARRAYTYPE_P(res); } + +/* + * Decode an infomask, per htup_details.c, into human readable + * form. For detail of masks see access/htup_details.h. + */ +PG_FUNCTION_INFO_V1(heap_infomask_flags); + +Datum +heap_infomask_flags(PG_FUNCTION_ARGS) +{ + uint16 t_infomask = PG_GETARG_INT16(0); + uint16 t_infomask2 = PG_GETARG_INT16(1); + bool decode_combined = PG_GETARG_BOOL(2); + int cnt = 0; + ArrayType *a; + int bitcnt; + Datum *d; + + bitcnt = pg_popcount32(t_infomask) + pg_popcount32(t_infomask2); + if (bitcnt == 0) + { + /* If no flags, return an empty array */ + a = construct_empty_array(TEXTOID); + PG_RETURN_POINTER(a); + } + + d = (Datum *) palloc0(sizeof(Datum) * bitcnt); + + /* decode t_infomask */ + if ((t_infomask & HEAP_HASNULL) != 0) + d[cnt++] = CStringGetTextDatum("HEAP_HASNULL"); + if ((t_infomask & HEAP_HASVARWIDTH) != 0) + d[cnt++] = CStringGetTextDatum("HEAP_HASVARWIDTH"); + if ((t_infomask & HEAP_HASEXTERNAL) != 0) + d[cnt++] = CStringGetTextDatum("HEAP_HASEXTERNAL"); + if ((t_infomask & HEAP_HASOID_OLD) != 0) + d[cnt++] = CStringGetTextDatum("HEAP_HASOID_OLD"); + if ((t_infomask & HEAP_COMBOCID) != 0) + d[cnt++] = CStringGetTextDatum("HEAP_COMBOCID"); + if ((t_infomask & HEAP_XMAX_COMMITTED) != 0) + d[cnt++] = CStringGetTextDatum("HEAP_XMAX_COMMITTED"); + if ((t_infomask & HEAP_XMAX_INVALID) != 0) + d[cnt++] = CStringGetTextDatum("HEAP_XMAX_INVALID"); + if ((t_infomask & HEAP_UPDATED) != 0) + d[cnt++] = CStringGetTextDatum("HEAP_UPDATED"); + + /* decode combined masks of t_infomaks */ + if (decode_combined && + (t_infomask & HEAP_XMAX_SHR_LOCK) != 0) + d[cnt++] = CStringGetTextDatum("HEAP_XMAX_SHR_LOCK"); + else + { + if ((t_infomask & HEAP_XMAX_EXCL_LOCK) != 0) + d[cnt++] = CStringGetTextDatum("HEAP_XMAX_EXCL_LOCK"); + if ((t_infomask & HEAP_XMAX_KEYSHR_LOCK) != 0) + d[cnt++] = CStringGetTextDatum("HEAP_XMAX_KEYSHR_LOCK"); + } + + if (decode_combined && + (t_infomask & HEAP_XMIN_FROZEN) != 0) + d[cnt++] = CStringGetTextDatum("HEAP_XMIN_FROZEN"); + else + { + if ((t_infomask & HEAP_XMIN_COMMITTED) != 0) + d[cnt++] = CStringGetTextDatum("HEAP_XMIN_COMMITTED"); + if ((t_infomask & HEAP_XMIN_INVALID) != 0) + d[cnt++] = CStringGetTextDatum("HEAP_XMIN_INVALID"); + } + + if (decode_combined && + (t_infomask & HEAP_MOVED) != 0) + d[cnt++] = CStringGetTextDatum("HEAP_MOVED"); + else + { + if ((t_infomask & HEAP_MOVED_IN) != 0) + d[cnt++] = CStringGetTextDatum("HEAP_MOVED_IN"); + if ((t_infomask & HEAP_MOVED_OFF) != 0) + d[cnt++] = CStringGetTextDatum("HEAP_MOVED_OFF"); + } + + if (decode_combined && + HEAP_LOCKED_UPGRADED(t_infomask)) + d[cnt++] = CStringGetTextDatum("HEAP_LOCKED_UPGRADED"); + else + { + if (HEAP_XMAX_IS_LOCKED_ONLY(t_infomask)) + d[cnt++] = CStringGetTextDatum("HEAP_XMAX_LOCK_ONLY"); + if ((t_infomask & HEAP_XMAX_IS_MULTI) != 0) + d[cnt++] = CStringGetTextDatum("HEAP_XMAX_IS_MULTI"); + } + + /* decode t_infomask2 */ + if ((t_infomask2 & HEAP_KEYS_UPDATED) != 0) + d[cnt++] = CStringGetTextDatum("HEAP_KEYS_UPDATED"); + if ((t_infomask2 & HEAP_HOT_UPDATED) != 0) + d[cnt++] = CStringGetTextDatum("HEAP_HOT_UPDATED"); + if ((t_infomask2 & HEAP_ONLY_TUPLE) != 0) + d[cnt++] = CStringGetTextDatum("HEAP_ONLY_TUPLE"); + + a = construct_array(d, cnt, TEXTOID, -1, false, 'i'); + + PG_RETURN_POINTER(a); +} diff --git a/contrib/pageinspect/pageinspect--1.7--1.8.sql b/contrib/pageinspect/pageinspect--1.7--1.8.sql new file mode 100644 index 0000000..aaf9399 --- /dev/null +++ b/contrib/pageinspect/pageinspect--1.7--1.8.sql @@ -0,0 +1,13 @@ +/* contrib/pageinspect/pageinspect--1.7--1.8.sql */ + +-- complain if script is sourced in psql, rather than via ALTER EXTENSION +\echo Use "ALTER EXTENSION pageinspect UPDATE TO '1.8'" to load this file. \quit + +-- decode infomask flags as human readable flag names +CREATE FUNCTION heap_infomask_flags( + infomask integer, + infomask2 integer, + decode_combined boolean DEFAULT false) +RETURNS text[] +AS 'MODULE_PATHNAME', 'heap_infomask_flags' +LANGUAGE C STRICT PARALLEL SAFE; diff --git a/contrib/pageinspect/pageinspect.control b/contrib/pageinspect/pageinspect.control index dcfc61f..f8cdf52 100644 --- a/contrib/pageinspect/pageinspect.control +++ b/contrib/pageinspect/pageinspect.control @@ -1,5 +1,5 @@ # pageinspect extension comment = 'inspect the contents of database pages at a low level' -default_version = '1.7' +default_version = '1.8' module_pathname = '$libdir/pageinspect' relocatable = true diff --git a/contrib/pageinspect/sql/page.sql b/contrib/pageinspect/sql/page.sql index 8ac9991..4ac96ef 100644 --- a/contrib/pageinspect/sql/page.sql +++ b/contrib/pageinspect/sql/page.sql @@ -31,6 +31,32 @@ SELECT tuple_data_split('test1'::regclass, t_data, t_infomask, t_infomask2, t_bi SELECT * FROM fsm_page_contents(get_raw_page('test1', 'fsm', 0)); +-- If we freeze the only tuple on test1, the infomask should +-- always be the same in all test runs. +VACUUM FREEZE test1; + +SELECT t_infomask, t_infomask2, flags +FROM heap_page_items(get_raw_page('test1', 0)), + LATERAL heap_infomask_flags(t_infomask, t_infomask2, true) m(flags); + +SELECT t_infomask, t_infomask2, flags +FROM heap_page_items(get_raw_page('test1', 0)), + LATERAL heap_infomask_flags(t_infomask, t_infomask2, false) m(flags); + +SELECT heap_infomask_flags(2816, 0); -- show raw flags by default +SELECT heap_infomask_flags(2816, 0, true); +SELECT heap_infomask_flags(2816, 1, true); +SELECT heap_infomask_flags(2816, 1, false); +SELECT heap_infomask_flags(2816, x'FFFF'::integer, true); +SELECT heap_infomask_flags(2816, x'FFFF'::integer, false); +SELECT heap_infomask_flags(x'1080'::integer, 0, true); -- test for HEAP_LOCKED_UPGRADED +SELECT heap_infomask_flags(x'1080'::integer, 0, false); +SELECT heap_infomask_flags(x'FFFF'::integer, x'FFFF'::integer, false); +SELECT heap_infomask_flags(x'FFFF'::integer, x'FFFF'::integer, true); +SELECT heap_infomask_flags(0, 0, true); +SELECT heap_infomask_flags(0, 0, false); +SELECT heap_infomask_flags(-1, -1, false); + DROP TABLE test1; -- check that using any of these functions with a partitioned table or index diff --git a/doc/src/sgml/pageinspect.sgml b/doc/src/sgml/pageinspect.sgml index 0b92025..258a0f1 100644 --- a/doc/src/sgml/pageinspect.sgml +++ b/doc/src/sgml/pageinspect.sgml @@ -180,6 +180,10 @@ test=# SELECT * FROM heap_page_items(get_raw_page('pg_class', 0)); src/include/access/htup_details.h for explanations of the fields returned. + + The heap_infomask_flags function can be used to unpack the + recognised bits of the infomasks of heap tuples. + @@ -232,6 +236,35 @@ test=# SELECT * FROM heap_page_item_attrs(get_raw_page('pg_class', 0), 'pg_class + + + + heap_infomask_flags(infomask integer, infomask2 integer, decode_combined bool) returns text[] + + heap_infomask_flags + + + + + heap_infomask_flags decodes the + t_infomask and + t_infomask2 returned by + heap_page_items into a human-readable + array of flag names. This can be used to see the tuple hint bits etc. + + + If decode_combined is set, combination flags like + HEAP_XMIN_FROZEN are output instead of raw + flags, HEAP_XMIN_COMMITTED and + HEAP_XMIN_INVALID. Default value is + false. + + + For the meaning of these flags see + src/include/access/htup_details.h + + + -- 2.10.5 --sm4nu43k4a2Rpi4c--