1
0
mirror of https://github.com/postgres/postgres.git synced 2026-10-23 13:29:09 +03:00

test_decoding: Don't print virtual generated columns.

Virtual generated columns are stored in tuples as null values, so
heap_getattr() in tuple_to_stringinfo() always returns null for them.
test_decoding printed such a column as null, which is
indistinguishable from a column that genuinely holds null.

This commit skips virtual generated columns in tuple_to_stringinfo(),
the only place that prints a tuple. Stored generated columns continue
to be printed, since their values do live in the heap tuple.

This is a behavior change rather than a bug fix, and it changes
test_decoding's output for tables that have virtual generated columns,
which could affect consumers that parse it. Therefore it is not
back-patched.

Author: SATYANARAYANA NARLAPURAM <satyanarlapuram@gmail.com>
Co-authored-by: Bharath Rupireddy <bharath.rupireddyforpostgres@gmail.com>
Reviewed-by: Euler Taveira <euler@eulerto.com>
Reviewed-by: Masahiko Sawada <sawada.mshk@gmail.com>
Discussion: https://postgr.es/m/CAHg+QDfTh3UbB-Ed--o2Bd=SBDJoEiG-qp3C0+ETDibF63y=dw@mail.gmail.com
This commit is contained in:
Masahiko Sawada
2026-08-18 13:55:10 -07:00
parent f7a0cca2e3
commit 755f7e2c92
3 changed files with 40 additions and 0 deletions

View File

@@ -895,6 +895,24 @@ SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'inc
data
(0 rows)
\pset format aligned
-- check that virtual generated columns are not printed
CREATE TABLE gtest1 (
a int PRIMARY KEY,
b int,
c int GENERATED ALWAYS AS (a + b) VIRTUAL,
d int GENERATED ALWAYS AS (a * 2) STORED,
e int
);
INSERT INTO gtest1 (a, b) VALUES (1, 10);
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1');
data
--------------------------------------------------------------------------------------
BEGIN
table public.gtest1: INSERT: a[integer]:1 b[integer]:10 d[integer]:2 e[integer]:null
COMMIT
(3 rows)
DROP TABLE gtest1;
SELECT pg_drop_replication_slot('regression_slot');
pg_drop_replication_slot
--------------------------

View File

@@ -467,6 +467,18 @@ SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'inc
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1');
\pset format aligned
-- check that virtual generated columns are not printed
CREATE TABLE gtest1 (
a int PRIMARY KEY,
b int,
c int GENERATED ALWAYS AS (a + b) VIRTUAL,
d int GENERATED ALWAYS AS (a * 2) STORED,
e int
);
INSERT INTO gtest1 (a, b) VALUES (1, 10);
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1');
DROP TABLE gtest1;
SELECT pg_drop_replication_slot('regression_slot');
/* check that the slot is gone */

View File

@@ -554,6 +554,16 @@ tuple_to_stringinfo(StringInfo s, TupleDesc tupdesc, HeapTuple tuple, bool skip_
if (attr->attnum < 0)
continue;
/*
* Virtual generated columns are always stored as null in the tuple,
* so don't print them at all. A printed null would not be
* distinguishable from a column that really contains a null. Stored
* generated columns are printed as usual since their values are
* actually on disk.
*/
if (attr->attgenerated == ATTRIBUTE_GENERATED_VIRTUAL)
continue;
typid = attr->atttypid;
/* get Datum from tuple */