Skip to content

Commit 93765bd

Browse files
committed
Fix table rewrites that include a column without a default.
In c2fe139 I made ATRewriteTable() use tuple slots. Unfortunately I did not notice that columns can be added in a rewrite that do not have a default, when another column is added/altered requiring one. Initialize columns to NULL again, and add tests. Bug: #16038 Reported-By: anonymous Author: Andres Freund Discussion: https://postgr.es/m/16038-5c974541f2bf6749@postgresql.org Backpatch: 12, where the bug was introduced in c2fe139
1 parent 50518ec commit 93765bd

File tree

3 files changed

+105
-0
lines changed

3 files changed

+105
-0
lines changed

src/backend/commands/tablecmds.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4890,6 +4890,16 @@ ATRewriteTable(AlteredTableInfo *tab, Oid OIDNewHeap, LOCKMODE lockmode)
48904890
table_slot_callbacks(oldrel));
48914891
newslot = MakeSingleTupleTableSlot(newTupDesc,
48924892
table_slot_callbacks(newrel));
4893+
4894+
/*
4895+
* Set all columns in the new slot to NULL initially, to ensure
4896+
* columns added as part of the rewrite are initialized to
4897+
* NULL. That is necessary as tab->newvals will not contain an
4898+
* expression for columns with a NULL default, e.g. when adding a
4899+
* column without a default together with a column with a default
4900+
* requiring an actual rewrite.
4901+
*/
4902+
ExecStoreAllNullTuple(newslot);
48934903
}
48944904
else
48954905
{

src/test/regress/expected/alter_table.out

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2436,6 +2436,53 @@ select * from at_view_2;
24362436
drop view at_view_2;
24372437
drop view at_view_1;
24382438
drop table at_base_table;
2439+
-- check adding a column not iself requiring a rewrite, together with
2440+
-- a column requiring a default (bug #16038)
2441+
-- ensure that rewrites aren't silently optimized away, removing the
2442+
-- value of the test
2443+
CREATE OR REPLACE FUNCTION evtrig_rewrite_log() RETURNS event_trigger
2444+
LANGUAGE plpgsql AS $$
2445+
BEGIN
2446+
RAISE WARNING 'rewriting table %',
2447+
pg_event_trigger_table_rewrite_oid()::regclass;
2448+
END;
2449+
$$;
2450+
CREATE EVENT TRIGGER evtrig_rewrite_log ON table_rewrite
2451+
EXECUTE PROCEDURE evtrig_rewrite_log();
2452+
CREATE TABLE rewrite_test(col text);
2453+
INSERT INTO rewrite_test VALUES ('something');
2454+
INSERT INTO rewrite_test VALUES (NULL);
2455+
-- empty[12] doesn't need rewrite, but notempty[12]_rewrite will force one
2456+
ALTER TABLE rewrite_test
2457+
ADD COLUMN empty1 text,
2458+
ADD COLUMN notempty1_rewrite serial;
2459+
WARNING: rewriting table rewrite_test
2460+
ALTER TABLE rewrite_test
2461+
ADD COLUMN notempty2_rewrite serial,
2462+
ADD COLUMN empty2 text;
2463+
WARNING: rewriting table rewrite_test
2464+
-- also check that fast defaults cause no problem, first without rewrite
2465+
ALTER TABLE rewrite_test
2466+
ADD COLUMN empty3 text,
2467+
ADD COLUMN notempty3_norewrite int default 42;
2468+
ALTER TABLE rewrite_test
2469+
ADD COLUMN notempty4_norewrite int default 42,
2470+
ADD COLUMN empty4 text;
2471+
-- then with rewrite
2472+
ALTER TABLE rewrite_test
2473+
ADD COLUMN empty5 text,
2474+
ADD COLUMN notempty5_norewrite int default 42,
2475+
ADD COLUMN notempty5_rewrite serial;
2476+
WARNING: rewriting table rewrite_test
2477+
ALTER TABLE rewrite_test
2478+
ADD COLUMN notempty6_rewrite serial,
2479+
ADD COLUMN empty6 text,
2480+
ADD COLUMN notempty6_norewrite int default 42;
2481+
WARNING: rewriting table rewrite_test
2482+
-- cleanup
2483+
drop event trigger evtrig_rewrite_log;
2484+
drop function evtrig_rewrite_log();
2485+
DROP TABLE rewrite_test;
24392486
--
24402487
-- lock levels
24412488
--

src/test/regress/sql/alter_table.sql

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1550,6 +1550,54 @@ drop view at_view_2;
15501550
drop view at_view_1;
15511551
drop table at_base_table;
15521552

1553+
-- check adding a column not iself requiring a rewrite, together with
1554+
-- a column requiring a default (bug #16038)
1555+
1556+
-- ensure that rewrites aren't silently optimized away, removing the
1557+
-- value of the test
1558+
CREATE OR REPLACE FUNCTION evtrig_rewrite_log() RETURNS event_trigger
1559+
LANGUAGE plpgsql AS $$
1560+
BEGIN
1561+
RAISE WARNING 'rewriting table %',
1562+
pg_event_trigger_table_rewrite_oid()::regclass;
1563+
END;
1564+
$$;
1565+
CREATE EVENT TRIGGER evtrig_rewrite_log ON table_rewrite
1566+
EXECUTE PROCEDURE evtrig_rewrite_log();
1567+
1568+
CREATE TABLE rewrite_test(col text);
1569+
INSERT INTO rewrite_test VALUES ('something');
1570+
INSERT INTO rewrite_test VALUES (NULL);
1571+
1572+
-- empty[12] doesn't need rewrite, but notempty[12]_rewrite will force one
1573+
ALTER TABLE rewrite_test
1574+
ADD COLUMN empty1 text,
1575+
ADD COLUMN notempty1_rewrite serial;
1576+
ALTER TABLE rewrite_test
1577+
ADD COLUMN notempty2_rewrite serial,
1578+
ADD COLUMN empty2 text;
1579+
-- also check that fast defaults cause no problem, first without rewrite
1580+
ALTER TABLE rewrite_test
1581+
ADD COLUMN empty3 text,
1582+
ADD COLUMN notempty3_norewrite int default 42;
1583+
ALTER TABLE rewrite_test
1584+
ADD COLUMN notempty4_norewrite int default 42,
1585+
ADD COLUMN empty4 text;
1586+
-- then with rewrite
1587+
ALTER TABLE rewrite_test
1588+
ADD COLUMN empty5 text,
1589+
ADD COLUMN notempty5_norewrite int default 42,
1590+
ADD COLUMN notempty5_rewrite serial;
1591+
ALTER TABLE rewrite_test
1592+
ADD COLUMN notempty6_rewrite serial,
1593+
ADD COLUMN empty6 text,
1594+
ADD COLUMN notempty6_norewrite int default 42;
1595+
1596+
-- cleanup
1597+
drop event trigger evtrig_rewrite_log;
1598+
drop function evtrig_rewrite_log();
1599+
DROP TABLE rewrite_test;
1600+
15531601
--
15541602
-- lock levels
15551603
--

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy