Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 3cb02e3

Browse files
committed
Fix possible crash with GENERATED ALWAYS columns
In some corner cases, this could also lead to corrupted values being included in the tuple. Users who are concerned that they are affected by this should first upgrade and then perform a base backup of their database and restore onto an off-line server. They should then query each table with generated columns to ensure there are no rows where the generated expression does not match a newly calculated version of the GENERATED ALWAYS expression. If no crashes occur and no rows are returned then you're not affected. Fixes bug #16369. Reported-by: Cameron Ezell Discussion: https://postgr.es/m/16369-5845a6f1bef59884@postgresql.org Backpatch-through: 12 (where GENERATED ALWAYS columns were added.)
1 parent 737d69f commit 3cb02e3

File tree

3 files changed

+26
-0
lines changed

3 files changed

+26
-0
lines changed

src/backend/executor/nodeModifyTable.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -336,6 +336,13 @@ ExecComputeStoredGenerated(EState *estate, TupleTableSlot *slot, CmdType cmdtype
336336

337337
val = ExecEvalExpr(resultRelInfo->ri_GeneratedExprs[i], econtext, &isnull);
338338

339+
/*
340+
* We must make a copy of val as we have no guarantees about where
341+
* memory for a pass-by-reference Datum is located.
342+
*/
343+
if (!isnull)
344+
val = datumCopy(val, attr->attbyval, attr->attlen);
345+
339346
values[i] = val;
340347
nulls[i] = isnull;
341348
}

src/test/regress/expected/generated.out

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,18 @@ SELECT * FROM gtest2;
320320
1 |
321321
(1 row)
322322

323+
-- simple column reference for varlena types
324+
CREATE TABLE gtest_varlena (a varchar, b varchar GENERATED ALWAYS AS (a) STORED);
325+
INSERT INTO gtest_varlena (a) VALUES('01234567890123456789');
326+
INSERT INTO gtest_varlena (a) VALUES(NULL);
327+
SELECT * FROM gtest_varlena ORDER BY a;
328+
a | b
329+
----------------------+----------------------
330+
01234567890123456789 | 01234567890123456789
331+
|
332+
(2 rows)
333+
334+
DROP TABLE gtest_varlena;
323335
-- composite types
324336
CREATE TYPE double_int as (a int, b int);
325337
CREATE TABLE gtest4 (

src/test/regress/sql/generated.sql

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,13 @@ CREATE TABLE gtest2 (a int PRIMARY KEY, b int GENERATED ALWAYS AS (NULL) STORED)
145145
INSERT INTO gtest2 VALUES (1);
146146
SELECT * FROM gtest2;
147147

148+
-- simple column reference for varlena types
149+
CREATE TABLE gtest_varlena (a varchar, b varchar GENERATED ALWAYS AS (a) STORED);
150+
INSERT INTO gtest_varlena (a) VALUES('01234567890123456789');
151+
INSERT INTO gtest_varlena (a) VALUES(NULL);
152+
SELECT * FROM gtest_varlena ORDER BY a;
153+
DROP TABLE gtest_varlena;
154+
148155
-- composite types
149156
CREATE TYPE double_int as (a int, b int);
150157
CREATE TABLE gtest4 (

0 commit comments

Comments
 (0)