Skip to content

Commit 0a4efdc

Browse files
committed
Don't set a fast default for anything but a plain table
The fast default code added in Release 11 omitted to check that the table a fast default was being added to was a plain table. Thus one could be added to a foreign table, which predicably blows up. Here we perform that check. In addition, on the back branches, since some of these might have escaped into the wild, if we encounter a missing value for an attribute of something other than a plain table we ignore it. Fixes bug #17056 Backpatch to release 11, Reviewed by: Andres Freund, Álvaro Herrera and Tom Lane
1 parent 981524d commit 0a4efdc

File tree

3 files changed

+42
-1
lines changed

3 files changed

+42
-1
lines changed

src/backend/catalog/heap.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2161,6 +2161,13 @@ SetAttrMissing(Oid relid, char *attname, char *value)
21612161
/* lock the table the attribute belongs to */
21622162
tablerel = table_open(relid, AccessExclusiveLock);
21632163

2164+
/* Don't do anything unless it's a plain table */
2165+
if (tablerel->rd_rel->relkind != RELKIND_RELATION)
2166+
{
2167+
table_close(tablerel, AccessExclusiveLock);
2168+
return;
2169+
}
2170+
21642171
/* Lock the attribute row and get the data */
21652172
attrrel = table_open(AttributeRelationId, RowExclusiveLock);
21662173
atttup = SearchSysCacheAttName(relid, attname);
@@ -2287,7 +2294,8 @@ StoreAttrDefault(Relation rel, AttrNumber attnum,
22872294
valuesAtt[Anum_pg_attribute_atthasdef - 1] = true;
22882295
replacesAtt[Anum_pg_attribute_atthasdef - 1] = true;
22892296

2290-
if (add_column_mode && !attgenerated)
2297+
if (rel->rd_rel->relkind == RELKIND_RELATION && add_column_mode &&
2298+
!attgenerated)
22912299
{
22922300
expr2 = expression_planner(expr2);
22932301
estate = CreateExecutorState();

src/test/regress/expected/fast_default.out

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -797,7 +797,26 @@ SELECT * FROM t WHERE a IS NULL;
797797
(1 row)
798798

799799
ROLLBACK;
800+
-- verify that a default set on a non-plain table doesn't set a missing
801+
-- value on the attribute
802+
CREATE FOREIGN DATA WRAPPER dummy;
803+
CREATE SERVER s0 FOREIGN DATA WRAPPER dummy;
804+
CREATE FOREIGN TABLE ft1 (c1 integer NOT NULL) SERVER s0;
805+
ALTER FOREIGN TABLE ft1 ADD COLUMN c8 integer DEFAULT 0;
806+
ALTER FOREIGN TABLE ft1 ALTER COLUMN c8 TYPE char(10);
807+
SELECT count(*)
808+
FROM pg_attribute
809+
WHERE attrelid = 'ft1'::regclass AND
810+
(attmissingval IS NOT NULL OR atthasmissing);
811+
count
812+
-------
813+
0
814+
(1 row)
815+
800816
-- cleanup
817+
DROP FOREIGN TABLE ft1;
818+
DROP SERVER s0;
819+
DROP FOREIGN DATA WRAPPER dummy;
801820
DROP TABLE vtype;
802821
DROP TABLE vtype2;
803822
DROP TABLE follower;

src/test/regress/sql/fast_default.sql

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -524,8 +524,22 @@ SET LOCAL enable_seqscan = false;
524524
SELECT * FROM t WHERE a IS NULL;
525525
ROLLBACK;
526526

527+
-- verify that a default set on a non-plain table doesn't set a missing
528+
-- value on the attribute
529+
CREATE FOREIGN DATA WRAPPER dummy;
530+
CREATE SERVER s0 FOREIGN DATA WRAPPER dummy;
531+
CREATE FOREIGN TABLE ft1 (c1 integer NOT NULL) SERVER s0;
532+
ALTER FOREIGN TABLE ft1 ADD COLUMN c8 integer DEFAULT 0;
533+
ALTER FOREIGN TABLE ft1 ALTER COLUMN c8 TYPE char(10);
534+
SELECT count(*)
535+
FROM pg_attribute
536+
WHERE attrelid = 'ft1'::regclass AND
537+
(attmissingval IS NOT NULL OR atthasmissing);
527538

528539
-- cleanup
540+
DROP FOREIGN TABLE ft1;
541+
DROP SERVER s0;
542+
DROP FOREIGN DATA WRAPPER dummy;
529543
DROP TABLE vtype;
530544
DROP TABLE vtype2;
531545
DROP TABLE follower;

0 commit comments

Comments
 (0)