2 -- ALTER TABLE ADD COLUMN DEFAULT test
4 SET search_path = fast_default;
5 CREATE SCHEMA fast_default;
6 CREATE TABLE m(id OID);
7 INSERT INTO m VALUES (NULL::OID);
8 CREATE FUNCTION set(tabname name) RETURNS VOID
12 SET id = (SELECT c.relfilenode
13 FROM pg_class AS c, pg_namespace AS s
14 WHERE c.relname = tabname
15 AND c.relnamespace = s.oid
16 AND s.nspname = 'fast_default');
18 $$ LANGUAGE 'plpgsql';
19 CREATE FUNCTION comp() RETURNS TEXT
23 WHEN m.id = c.relfilenode THEN 'Unchanged'
26 FROM m, pg_class AS c, pg_namespace AS s
28 AND c.relnamespace = s.oid
29 AND s.nspname = 'fast_default');
31 $$ LANGUAGE 'plpgsql';
32 CREATE FUNCTION log_rewrite() RETURNS event_trigger
39 select into this_schema relnamespace::regnamespace::text
41 where oid = pg_event_trigger_table_rewrite_oid();
42 if this_schema = 'fast_default'
44 RAISE NOTICE 'rewriting table % for reason %',
45 pg_event_trigger_table_rewrite_oid()::regclass,
46 pg_event_trigger_table_rewrite_reason();
50 CREATE TABLE has_volatile AS
51 SELECT * FROM generate_series(1,10) id;
52 CREATE EVENT TRIGGER has_volatile_rewrite
54 EXECUTE PROCEDURE log_rewrite();
55 -- only the last of these should trigger a rewrite
56 ALTER TABLE has_volatile ADD col1 int;
57 ALTER TABLE has_volatile ADD col2 int DEFAULT 1;
58 ALTER TABLE has_volatile ADD col3 timestamptz DEFAULT current_timestamp;
59 ALTER TABLE has_volatile ADD col4 int DEFAULT (random() * 10000)::int;
60 NOTICE: rewriting table has_volatile for reason 2
61 -- Test a large sample of different datatypes
62 CREATE TABLE T(pk INT NOT NULL PRIMARY KEY, c_int INT DEFAULT 1);
69 INSERT INTO T VALUES (1), (2);
70 ALTER TABLE T ADD COLUMN c_bpchar BPCHAR(5) DEFAULT 'hello',
71 ALTER COLUMN c_int SET DEFAULT 2;
72 INSERT INTO T VALUES (3), (4);
73 ALTER TABLE T ADD COLUMN c_text TEXT DEFAULT 'world',
74 ALTER COLUMN c_bpchar SET DEFAULT 'dog';
75 INSERT INTO T VALUES (5), (6);
76 ALTER TABLE T ADD COLUMN c_date DATE DEFAULT '2016-06-02',
77 ALTER COLUMN c_text SET DEFAULT 'cat';
78 INSERT INTO T VALUES (7), (8);
79 ALTER TABLE T ADD COLUMN c_timestamp TIMESTAMP DEFAULT '2016-09-01 12:00:00',
80 ADD COLUMN c_timestamp_null TIMESTAMP,
81 ALTER COLUMN c_date SET DEFAULT '2010-01-01';
82 INSERT INTO T VALUES (9), (10);
83 ALTER TABLE T ADD COLUMN c_array TEXT[]
84 DEFAULT '{"This", "is", "the", "real", "world"}',
85 ALTER COLUMN c_timestamp SET DEFAULT '1970-12-31 11:12:13',
86 ALTER COLUMN c_timestamp_null SET DEFAULT '2016-09-29 12:00:00';
87 INSERT INTO T VALUES (11), (12);
88 ALTER TABLE T ADD COLUMN c_small SMALLINT DEFAULT -5,
89 ADD COLUMN c_small_null SMALLINT,
91 SET DEFAULT '{"This", "is", "no", "fantasy"}';
92 INSERT INTO T VALUES (13), (14);
93 ALTER TABLE T ADD COLUMN c_big BIGINT DEFAULT 180000000000018,
94 ALTER COLUMN c_small SET DEFAULT 9,
95 ALTER COLUMN c_small_null SET DEFAULT 13;
96 INSERT INTO T VALUES (15), (16);
97 ALTER TABLE T ADD COLUMN c_num NUMERIC DEFAULT 1.00000000001,
98 ALTER COLUMN c_big SET DEFAULT -9999999999999999;
99 INSERT INTO T VALUES (17), (18);
100 ALTER TABLE T ADD COLUMN c_time TIME DEFAULT '12:00:00',
101 ALTER COLUMN c_num SET DEFAULT 2.000000000000002;
102 INSERT INTO T VALUES (19), (20);
103 ALTER TABLE T ADD COLUMN c_interval INTERVAL DEFAULT '1 day',
104 ALTER COLUMN c_time SET DEFAULT '23:59:59';
105 INSERT INTO T VALUES (21), (22);
106 ALTER TABLE T ADD COLUMN c_hugetext TEXT DEFAULT repeat('abcdefg',1000),
107 ALTER COLUMN c_interval SET DEFAULT '3 hours';
108 INSERT INTO T VALUES (23), (24);
109 ALTER TABLE T ALTER COLUMN c_interval DROP DEFAULT,
110 ALTER COLUMN c_hugetext SET DEFAULT repeat('poiuyt', 1000);
111 INSERT INTO T VALUES (25), (26);
112 ALTER TABLE T ALTER COLUMN c_bpchar DROP DEFAULT,
113 ALTER COLUMN c_date DROP DEFAULT,
114 ALTER COLUMN c_text DROP DEFAULT,
115 ALTER COLUMN c_timestamp DROP DEFAULT,
116 ALTER COLUMN c_array DROP DEFAULT,
117 ALTER COLUMN c_small DROP DEFAULT,
118 ALTER COLUMN c_big DROP DEFAULT,
119 ALTER COLUMN c_num DROP DEFAULT,
120 ALTER COLUMN c_time DROP DEFAULT,
121 ALTER COLUMN c_hugetext DROP DEFAULT;
122 INSERT INTO T VALUES (27), (28);
123 SELECT pk, c_int, c_bpchar, c_text, c_date, c_timestamp,
124 c_timestamp_null, c_array, c_small, c_small_null,
125 c_big, c_num, c_time, c_interval,
126 c_hugetext = repeat('abcdefg',1000) as c_hugetext_origdef,
127 c_hugetext = repeat('poiuyt', 1000) as c_hugetext_newdef
129 pk | c_int | c_bpchar | c_text | c_date | c_timestamp | c_timestamp_null | c_array | c_small | c_small_null | c_big | c_num | c_time | c_interval | c_hugetext_origdef | c_hugetext_newdef
130 ----+-------+----------+--------+------------+--------------------------+--------------------------+--------------------------+---------+--------------+-------------------+-------------------+----------+------------+--------------------+-------------------
131 1 | 1 | hello | world | 06-02-2016 | Thu Sep 01 12:00:00 2016 | | {This,is,the,real,world} | -5 | | 180000000000018 | 1.00000000001 | 12:00:00 | @ 1 day | t | f
132 2 | 1 | hello | world | 06-02-2016 | Thu Sep 01 12:00:00 2016 | | {This,is,the,real,world} | -5 | | 180000000000018 | 1.00000000001 | 12:00:00 | @ 1 day | t | f
133 3 | 2 | hello | world | 06-02-2016 | Thu Sep 01 12:00:00 2016 | | {This,is,the,real,world} | -5 | | 180000000000018 | 1.00000000001 | 12:00:00 | @ 1 day | t | f
134 4 | 2 | hello | world | 06-02-2016 | Thu Sep 01 12:00:00 2016 | | {This,is,the,real,world} | -5 | | 180000000000018 | 1.00000000001 | 12:00:00 | @ 1 day | t | f
135 5 | 2 | dog | world | 06-02-2016 | Thu Sep 01 12:00:00 2016 | | {This,is,the,real,world} | -5 | | 180000000000018 | 1.00000000001 | 12:00:00 | @ 1 day | t | f
136 6 | 2 | dog | world | 06-02-2016 | Thu Sep 01 12:00:00 2016 | | {This,is,the,real,world} | -5 | | 180000000000018 | 1.00000000001 | 12:00:00 | @ 1 day | t | f
137 7 | 2 | dog | cat | 06-02-2016 | Thu Sep 01 12:00:00 2016 | | {This,is,the,real,world} | -5 | | 180000000000018 | 1.00000000001 | 12:00:00 | @ 1 day | t | f
138 8 | 2 | dog | cat | 06-02-2016 | Thu Sep 01 12:00:00 2016 | | {This,is,the,real,world} | -5 | | 180000000000018 | 1.00000000001 | 12:00:00 | @ 1 day | t | f
139 9 | 2 | dog | cat | 01-01-2010 | Thu Sep 01 12:00:00 2016 | | {This,is,the,real,world} | -5 | | 180000000000018 | 1.00000000001 | 12:00:00 | @ 1 day | t | f
140 10 | 2 | dog | cat | 01-01-2010 | Thu Sep 01 12:00:00 2016 | | {This,is,the,real,world} | -5 | | 180000000000018 | 1.00000000001 | 12:00:00 | @ 1 day | t | f
141 11 | 2 | dog | cat | 01-01-2010 | Thu Dec 31 11:12:13 1970 | Thu Sep 29 12:00:00 2016 | {This,is,the,real,world} | -5 | | 180000000000018 | 1.00000000001 | 12:00:00 | @ 1 day | t | f
142 12 | 2 | dog | cat | 01-01-2010 | Thu Dec 31 11:12:13 1970 | Thu Sep 29 12:00:00 2016 | {This,is,the,real,world} | -5 | | 180000000000018 | 1.00000000001 | 12:00:00 | @ 1 day | t | f
143 13 | 2 | dog | cat | 01-01-2010 | Thu Dec 31 11:12:13 1970 | Thu Sep 29 12:00:00 2016 | {This,is,no,fantasy} | -5 | | 180000000000018 | 1.00000000001 | 12:00:00 | @ 1 day | t | f
144 14 | 2 | dog | cat | 01-01-2010 | Thu Dec 31 11:12:13 1970 | Thu Sep 29 12:00:00 2016 | {This,is,no,fantasy} | -5 | | 180000000000018 | 1.00000000001 | 12:00:00 | @ 1 day | t | f
145 15 | 2 | dog | cat | 01-01-2010 | Thu Dec 31 11:12:13 1970 | Thu Sep 29 12:00:00 2016 | {This,is,no,fantasy} | 9 | 13 | 180000000000018 | 1.00000000001 | 12:00:00 | @ 1 day | t | f
146 16 | 2 | dog | cat | 01-01-2010 | Thu Dec 31 11:12:13 1970 | Thu Sep 29 12:00:00 2016 | {This,is,no,fantasy} | 9 | 13 | 180000000000018 | 1.00000000001 | 12:00:00 | @ 1 day | t | f
147 17 | 2 | dog | cat | 01-01-2010 | Thu Dec 31 11:12:13 1970 | Thu Sep 29 12:00:00 2016 | {This,is,no,fantasy} | 9 | 13 | -9999999999999999 | 1.00000000001 | 12:00:00 | @ 1 day | t | f
148 18 | 2 | dog | cat | 01-01-2010 | Thu Dec 31 11:12:13 1970 | Thu Sep 29 12:00:00 2016 | {This,is,no,fantasy} | 9 | 13 | -9999999999999999 | 1.00000000001 | 12:00:00 | @ 1 day | t | f
149 19 | 2 | dog | cat | 01-01-2010 | Thu Dec 31 11:12:13 1970 | Thu Sep 29 12:00:00 2016 | {This,is,no,fantasy} | 9 | 13 | -9999999999999999 | 2.000000000000002 | 12:00:00 | @ 1 day | t | f
150 20 | 2 | dog | cat | 01-01-2010 | Thu Dec 31 11:12:13 1970 | Thu Sep 29 12:00:00 2016 | {This,is,no,fantasy} | 9 | 13 | -9999999999999999 | 2.000000000000002 | 12:00:00 | @ 1 day | t | f
151 21 | 2 | dog | cat | 01-01-2010 | Thu Dec 31 11:12:13 1970 | Thu Sep 29 12:00:00 2016 | {This,is,no,fantasy} | 9 | 13 | -9999999999999999 | 2.000000000000002 | 23:59:59 | @ 1 day | t | f
152 22 | 2 | dog | cat | 01-01-2010 | Thu Dec 31 11:12:13 1970 | Thu Sep 29 12:00:00 2016 | {This,is,no,fantasy} | 9 | 13 | -9999999999999999 | 2.000000000000002 | 23:59:59 | @ 1 day | t | f
153 23 | 2 | dog | cat | 01-01-2010 | Thu Dec 31 11:12:13 1970 | Thu Sep 29 12:00:00 2016 | {This,is,no,fantasy} | 9 | 13 | -9999999999999999 | 2.000000000000002 | 23:59:59 | @ 3 hours | t | f
154 24 | 2 | dog | cat | 01-01-2010 | Thu Dec 31 11:12:13 1970 | Thu Sep 29 12:00:00 2016 | {This,is,no,fantasy} | 9 | 13 | -9999999999999999 | 2.000000000000002 | 23:59:59 | @ 3 hours | t | f
155 25 | 2 | dog | cat | 01-01-2010 | Thu Dec 31 11:12:13 1970 | Thu Sep 29 12:00:00 2016 | {This,is,no,fantasy} | 9 | 13 | -9999999999999999 | 2.000000000000002 | 23:59:59 | | f | t
156 26 | 2 | dog | cat | 01-01-2010 | Thu Dec 31 11:12:13 1970 | Thu Sep 29 12:00:00 2016 | {This,is,no,fantasy} | 9 | 13 | -9999999999999999 | 2.000000000000002 | 23:59:59 | | f | t
157 27 | 2 | | | | | Thu Sep 29 12:00:00 2016 | | | 13 | | | | | |
158 28 | 2 | | | | | Thu Sep 29 12:00:00 2016 | | | 13 | | | | | |
168 -- Test expressions in the defaults
169 CREATE OR REPLACE FUNCTION foo(a INT) RETURNS TEXT AS $$
170 DECLARE res TEXT := '';
175 res := res || chr(ascii('a') + i);
179 END; $$ LANGUAGE PLPGSQL STABLE;
180 CREATE TABLE T(pk INT NOT NULL PRIMARY KEY, c_int INT DEFAULT LENGTH(foo(6)));
187 INSERT INTO T VALUES (1), (2);
188 ALTER TABLE T ADD COLUMN c_bpchar BPCHAR(5) DEFAULT foo(4),
189 ALTER COLUMN c_int SET DEFAULT LENGTH(foo(8));
190 INSERT INTO T VALUES (3), (4);
191 ALTER TABLE T ADD COLUMN c_text TEXT DEFAULT foo(6),
192 ALTER COLUMN c_bpchar SET DEFAULT foo(3);
193 INSERT INTO T VALUES (5), (6);
194 ALTER TABLE T ADD COLUMN c_date DATE
195 DEFAULT '2016-06-02'::DATE + LENGTH(foo(10)),
196 ALTER COLUMN c_text SET DEFAULT foo(12);
197 INSERT INTO T VALUES (7), (8);
198 ALTER TABLE T ADD COLUMN c_timestamp TIMESTAMP
199 DEFAULT '2016-09-01'::DATE + LENGTH(foo(10)),
201 SET DEFAULT '2010-01-01'::DATE - LENGTH(foo(4));
202 INSERT INTO T VALUES (9), (10);
203 ALTER TABLE T ADD COLUMN c_array TEXT[]
204 DEFAULT ('{"This", "is", "' || foo(4) ||
205 '","the", "real", "world"}')::TEXT[],
206 ALTER COLUMN c_timestamp
207 SET DEFAULT '1970-12-31'::DATE + LENGTH(foo(30));
208 INSERT INTO T VALUES (11), (12);
209 ALTER TABLE T ALTER COLUMN c_int DROP DEFAULT,
211 SET DEFAULT ('{"This", "is", "' || foo(1) ||
212 '", "fantasy"}')::text[];
213 INSERT INTO T VALUES (13), (14);
214 ALTER TABLE T ALTER COLUMN c_bpchar DROP DEFAULT,
215 ALTER COLUMN c_date DROP DEFAULT,
216 ALTER COLUMN c_text DROP DEFAULT,
217 ALTER COLUMN c_timestamp DROP DEFAULT,
218 ALTER COLUMN c_array DROP DEFAULT;
219 INSERT INTO T VALUES (15), (16);
221 pk | c_int | c_bpchar | c_text | c_date | c_timestamp | c_array
222 ----+-------+----------+--------------+------------+--------------------------+-------------------------------
223 1 | 6 | abcd | abcdef | 06-12-2016 | Sun Sep 11 00:00:00 2016 | {This,is,abcd,the,real,world}
224 2 | 6 | abcd | abcdef | 06-12-2016 | Sun Sep 11 00:00:00 2016 | {This,is,abcd,the,real,world}
225 3 | 8 | abcd | abcdef | 06-12-2016 | Sun Sep 11 00:00:00 2016 | {This,is,abcd,the,real,world}
226 4 | 8 | abcd | abcdef | 06-12-2016 | Sun Sep 11 00:00:00 2016 | {This,is,abcd,the,real,world}
227 5 | 8 | abc | abcdef | 06-12-2016 | Sun Sep 11 00:00:00 2016 | {This,is,abcd,the,real,world}
228 6 | 8 | abc | abcdef | 06-12-2016 | Sun Sep 11 00:00:00 2016 | {This,is,abcd,the,real,world}
229 7 | 8 | abc | abcdefghijkl | 06-12-2016 | Sun Sep 11 00:00:00 2016 | {This,is,abcd,the,real,world}
230 8 | 8 | abc | abcdefghijkl | 06-12-2016 | Sun Sep 11 00:00:00 2016 | {This,is,abcd,the,real,world}
231 9 | 8 | abc | abcdefghijkl | 12-28-2009 | Sun Sep 11 00:00:00 2016 | {This,is,abcd,the,real,world}
232 10 | 8 | abc | abcdefghijkl | 12-28-2009 | Sun Sep 11 00:00:00 2016 | {This,is,abcd,the,real,world}
233 11 | 8 | abc | abcdefghijkl | 12-28-2009 | Sat Jan 30 00:00:00 1971 | {This,is,abcd,the,real,world}
234 12 | 8 | abc | abcdefghijkl | 12-28-2009 | Sat Jan 30 00:00:00 1971 | {This,is,abcd,the,real,world}
235 13 | | abc | abcdefghijkl | 12-28-2009 | Sat Jan 30 00:00:00 1971 | {This,is,a,fantasy}
236 14 | | abc | abcdefghijkl | 12-28-2009 | Sat Jan 30 00:00:00 1971 | {This,is,a,fantasy}
248 DROP FUNCTION foo(INT);
249 -- Fall back to full rewrite for volatile expressions
250 CREATE TABLE T(pk INT NOT NULL PRIMARY KEY);
251 INSERT INTO T VALUES (1);
258 -- now() is stable, because it returns the transaction timestamp
259 ALTER TABLE T ADD COLUMN c1 TIMESTAMP DEFAULT now();
266 -- clock_timestamp() is volatile
267 ALTER TABLE T ADD COLUMN c2 TIMESTAMP DEFAULT clock_timestamp();
268 NOTICE: rewriting table t for reason 2
275 -- check that we notice insertion of a volatile default argument
276 CREATE FUNCTION foolme(timestamptz DEFAULT clock_timestamp())
278 IMMUTABLE AS 'select $1' LANGUAGE sql;
279 ALTER TABLE T ADD COLUMN c3 timestamptz DEFAULT foolme();
280 NOTICE: rewriting table t for reason 2
281 SELECT attname, atthasmissing, attmissingval FROM pg_attribute
282 WHERE attrelid = 't'::regclass AND attnum > 0
284 attname | atthasmissing | attmissingval
285 ---------+---------------+---------------
293 DROP FUNCTION foolme(timestamptz);
295 CREATE TABLE T (pk INT NOT NULL PRIMARY KEY);
302 INSERT INTO T SELECT * FROM generate_series(1, 10) a;
303 ALTER TABLE T ADD COLUMN c_bigint BIGINT NOT NULL DEFAULT -1;
304 INSERT INTO T SELECT b, b - 10 FROM generate_series(11, 20) a(b);
305 ALTER TABLE T ADD COLUMN c_text TEXT DEFAULT 'hello';
306 INSERT INTO T SELECT b, b - 10, (b + 10)::text FROM generate_series(21, 30) a(b);
308 SELECT c_bigint, c_text FROM T WHERE c_bigint = -1 LIMIT 1;
314 EXPLAIN (VERBOSE TRUE, COSTS FALSE)
315 SELECT c_bigint, c_text FROM T WHERE c_bigint = -1 LIMIT 1;
317 ----------------------------------------------
319 Output: c_bigint, c_text
320 -> Seq Scan on fast_default.t
321 Output: c_bigint, c_text
322 Filter: (t.c_bigint = '-1'::integer)
325 SELECT c_bigint, c_text FROM T WHERE c_text = 'hello' LIMIT 1;
331 EXPLAIN (VERBOSE TRUE, COSTS FALSE) SELECT c_bigint, c_text FROM T WHERE c_text = 'hello' LIMIT 1;
333 --------------------------------------------
335 Output: c_bigint, c_text
336 -> Seq Scan on fast_default.t
337 Output: c_bigint, c_text
338 Filter: (t.c_text = 'hello'::text)
342 SELECT COALESCE(c_bigint, pk), COALESCE(c_text, pk::text)
344 ORDER BY pk LIMIT 10;
346 ----------+----------
359 -- Aggregate function
360 SELECT SUM(c_bigint), MAX(c_text COLLATE "C" ), MIN(c_text COLLATE "C") FROM T;
367 SELECT * FROM T ORDER BY c_bigint, c_text, pk LIMIT 10;
368 pk | c_bigint | c_text
369 ----+----------+--------
382 EXPLAIN (VERBOSE TRUE, COSTS FALSE)
383 SELECT * FROM T ORDER BY c_bigint, c_text, pk LIMIT 10;
385 ----------------------------------------------
387 Output: pk, c_bigint, c_text
389 Output: pk, c_bigint, c_text
390 Sort Key: t.c_bigint, t.c_text, t.pk
391 -> Seq Scan on fast_default.t
392 Output: pk, c_bigint, c_text
396 SELECT * FROM T WHERE c_bigint > -1 ORDER BY c_bigint, c_text, pk LIMIT 10;
397 pk | c_bigint | c_text
398 ----+----------+--------
411 EXPLAIN (VERBOSE TRUE, COSTS FALSE)
412 SELECT * FROM T WHERE c_bigint > -1 ORDER BY c_bigint, c_text, pk LIMIT 10;
414 ----------------------------------------------------
416 Output: pk, c_bigint, c_text
418 Output: pk, c_bigint, c_text
419 Sort Key: t.c_bigint, t.c_text, t.pk
420 -> Seq Scan on fast_default.t
421 Output: pk, c_bigint, c_text
422 Filter: (t.c_bigint > '-1'::integer)
425 -- DELETE with RETURNING
426 DELETE FROM T WHERE pk BETWEEN 10 AND 20 RETURNING *;
427 pk | c_bigint | c_text
428 ----+----------+--------
442 EXPLAIN (VERBOSE TRUE, COSTS FALSE)
443 DELETE FROM T WHERE pk BETWEEN 10 AND 20 RETURNING *;
445 -----------------------------------------------------------
446 Delete on fast_default.t
447 Output: pk, c_bigint, c_text
448 -> Bitmap Heap Scan on fast_default.t
450 Recheck Cond: ((t.pk >= 10) AND (t.pk <= 20))
451 -> Bitmap Index Scan on t_pkey
452 Index Cond: ((t.pk >= 10) AND (t.pk <= 20))
456 UPDATE T SET c_text = '"' || c_text || '"' WHERE pk < 10;
457 SELECT * FROM T WHERE c_text LIKE '"%"' ORDER BY PK;
458 pk | c_bigint | c_text
459 ----+----------+---------
478 -- Combine with other DDL
479 CREATE TABLE T(pk INT NOT NULL PRIMARY KEY);
486 INSERT INTO T VALUES (1), (2);
487 ALTER TABLE T ADD COLUMN c_int INT NOT NULL DEFAULT -1;
488 INSERT INTO T VALUES (3), (4);
489 ALTER TABLE T ADD COLUMN c_text TEXT DEFAULT 'Hello';
490 INSERT INTO T VALUES (5), (6);
491 ALTER TABLE T ALTER COLUMN c_text SET DEFAULT 'world',
492 ALTER COLUMN c_int SET DEFAULT 1;
493 INSERT INTO T VALUES (7), (8);
494 SELECT * FROM T ORDER BY pk;
496 ----+-------+--------
508 CREATE INDEX i ON T(c_int, c_text);
509 SELECT c_text FROM T WHERE c_int = -1;
526 -- query to exercise expand_tuple function
528 SELECT 1::int AS a , 2::int AS b
529 FROM generate_series(1,20) q;
530 ALTER TABLE t1 ADD COLUMN c text;
532 stddev(cast((SELECT sum(1) FROM generate_series(1,20) x) AS float4))
533 OVER (PARTITION BY a,b,c ORDER BY b)
561 -- test that we account for missing columns without defaults correctly
562 -- in expand_tuple, and that rows are correctly expanded for triggers
563 CREATE FUNCTION test_trigger()
569 raise notice 'old tuple: %', to_json(OLD)::text;
579 -- 2 new columns, both have defaults
580 CREATE TABLE t (id serial PRIMARY KEY, a int, b int, c int);
581 INSERT INTO t (a,b,c) VALUES (1,2,3);
582 ALTER TABLE t ADD COLUMN x int NOT NULL DEFAULT 4;
583 ALTER TABLE t ADD COLUMN y int NOT NULL DEFAULT 5;
584 CREATE TRIGGER a BEFORE UPDATE ON t FOR EACH ROW EXECUTE PROCEDURE test_trigger();
586 id | a | b | c | x | y
587 ----+---+---+---+---+---
588 1 | 1 | 2 | 3 | 4 | 5
592 NOTICE: old tuple: {"id":1,"a":1,"b":2,"c":3,"x":4,"y":5}
594 id | a | b | c | x | y
595 ----+---+---+---+---+---
596 1 | 1 | 2 | 3 | 4 | 2
600 -- 2 new columns, first has default
601 CREATE TABLE t (id serial PRIMARY KEY, a int, b int, c int);
602 INSERT INTO t (a,b,c) VALUES (1,2,3);
603 ALTER TABLE t ADD COLUMN x int NOT NULL DEFAULT 4;
604 ALTER TABLE t ADD COLUMN y int;
605 CREATE TRIGGER a BEFORE UPDATE ON t FOR EACH ROW EXECUTE PROCEDURE test_trigger();
607 id | a | b | c | x | y
608 ----+---+---+---+---+---
613 NOTICE: old tuple: {"id":1,"a":1,"b":2,"c":3,"x":4,"y":null}
615 id | a | b | c | x | y
616 ----+---+---+---+---+---
617 1 | 1 | 2 | 3 | 4 | 2
621 -- 2 new columns, second has default
622 CREATE TABLE t (id serial PRIMARY KEY, a int, b int, c int);
623 INSERT INTO t (a,b,c) VALUES (1,2,3);
624 ALTER TABLE t ADD COLUMN x int;
625 ALTER TABLE t ADD COLUMN y int NOT NULL DEFAULT 5;
626 CREATE TRIGGER a BEFORE UPDATE ON t FOR EACH ROW EXECUTE PROCEDURE test_trigger();
628 id | a | b | c | x | y
629 ----+---+---+---+---+---
634 NOTICE: old tuple: {"id":1,"a":1,"b":2,"c":3,"x":null,"y":5}
636 id | a | b | c | x | y
637 ----+---+---+---+---+---
642 -- 2 new columns, neither has default
643 CREATE TABLE t (id serial PRIMARY KEY, a int, b int, c int);
644 INSERT INTO t (a,b,c) VALUES (1,2,3);
645 ALTER TABLE t ADD COLUMN x int;
646 ALTER TABLE t ADD COLUMN y int;
647 CREATE TRIGGER a BEFORE UPDATE ON t FOR EACH ROW EXECUTE PROCEDURE test_trigger();
649 id | a | b | c | x | y
650 ----+---+---+---+---+---
655 NOTICE: old tuple: {"id":1,"a":1,"b":2,"c":3,"x":null,"y":null}
657 id | a | b | c | x | y
658 ----+---+---+---+---+---
663 -- same as last 4 tests but here the last original column has a NULL value
664 -- 2 new columns, both have defaults
665 CREATE TABLE t (id serial PRIMARY KEY, a int, b int, c int);
666 INSERT INTO t (a,b,c) VALUES (1,2,NULL);
667 ALTER TABLE t ADD COLUMN x int NOT NULL DEFAULT 4;
668 ALTER TABLE t ADD COLUMN y int NOT NULL DEFAULT 5;
669 CREATE TRIGGER a BEFORE UPDATE ON t FOR EACH ROW EXECUTE PROCEDURE test_trigger();
671 id | a | b | c | x | y
672 ----+---+---+---+---+---
677 NOTICE: old tuple: {"id":1,"a":1,"b":2,"c":null,"x":4,"y":5}
679 id | a | b | c | x | y
680 ----+---+---+---+---+---
685 -- 2 new columns, first has default
686 CREATE TABLE t (id serial PRIMARY KEY, a int, b int, c int);
687 INSERT INTO t (a,b,c) VALUES (1,2,NULL);
688 ALTER TABLE t ADD COLUMN x int NOT NULL DEFAULT 4;
689 ALTER TABLE t ADD COLUMN y int;
690 CREATE TRIGGER a BEFORE UPDATE ON t FOR EACH ROW EXECUTE PROCEDURE test_trigger();
692 id | a | b | c | x | y
693 ----+---+---+---+---+---
698 NOTICE: old tuple: {"id":1,"a":1,"b":2,"c":null,"x":4,"y":null}
700 id | a | b | c | x | y
701 ----+---+---+---+---+---
706 -- 2 new columns, second has default
707 CREATE TABLE t (id serial PRIMARY KEY, a int, b int, c int);
708 INSERT INTO t (a,b,c) VALUES (1,2,NULL);
709 ALTER TABLE t ADD COLUMN x int;
710 ALTER TABLE t ADD COLUMN y int NOT NULL DEFAULT 5;
711 CREATE TRIGGER a BEFORE UPDATE ON t FOR EACH ROW EXECUTE PROCEDURE test_trigger();
713 id | a | b | c | x | y
714 ----+---+---+---+---+---
719 NOTICE: old tuple: {"id":1,"a":1,"b":2,"c":null,"x":null,"y":5}
721 id | a | b | c | x | y
722 ----+---+---+---+---+---
727 -- 2 new columns, neither has default
728 CREATE TABLE t (id serial PRIMARY KEY, a int, b int, c int);
729 INSERT INTO t (a,b,c) VALUES (1,2,NULL);
730 ALTER TABLE t ADD COLUMN x int;
731 ALTER TABLE t ADD COLUMN y int;
732 CREATE TRIGGER a BEFORE UPDATE ON t FOR EACH ROW EXECUTE PROCEDURE test_trigger();
734 id | a | b | c | x | y
735 ----+---+---+---+---+---
740 NOTICE: old tuple: {"id":1,"a":1,"b":2,"c":null,"x":null,"y":null}
742 id | a | b | c | x | y
743 ----+---+---+---+---+---
748 -- make sure expanded tuple has correct self pointer
749 -- it will be required by the RI trigger doing the cascading delete
750 CREATE TABLE leader (a int PRIMARY KEY, b int);
751 CREATE TABLE follower (a int REFERENCES leader ON DELETE CASCADE, b int);
752 INSERT INTO leader VALUES (1, 1), (2, 2);
753 ALTER TABLE leader ADD c int;
754 ALTER TABLE leader DROP c;
756 -- check that ALTER TABLE ... ALTER TYPE does the right thing
757 CREATE TABLE vtype( a integer);
758 INSERT INTO vtype VALUES (1);
759 ALTER TABLE vtype ADD COLUMN b DOUBLE PRECISION DEFAULT 0.2;
760 ALTER TABLE vtype ADD COLUMN c BOOLEAN DEFAULT true;
768 ALTER b TYPE text USING b::text,
769 ALTER c TYPE text USING c::text;
770 NOTICE: rewriting table vtype for reason 4
777 -- also check the case that doesn't rewrite the table
778 CREATE TABLE vtype2 (a int);
779 INSERT INTO vtype2 VALUES (1);
780 ALTER TABLE vtype2 ADD COLUMN b varchar(10) DEFAULT 'xxx';
781 ALTER TABLE vtype2 ALTER COLUMN b SET DEFAULT 'yyy';
782 INSERT INTO vtype2 VALUES (2);
783 ALTER TABLE vtype2 ALTER COLUMN b TYPE varchar(20) USING b::varchar(20);
784 SELECT * FROM vtype2;
791 -- Ensure that defaults are checked when evaluating whether HOT update
792 -- is possible, this was broken for a while:
793 -- https://postgr.es/m/20190202133521.ylauh3ckqa7colzj%40alap3.anarazel.de
796 INSERT INTO t DEFAULT VALUES;
797 ALTER TABLE t ADD COLUMN a int DEFAULT 1;
798 CREATE INDEX ON t(a);
799 -- set column with a default 1 to NULL, due to a bug that wasn't
800 -- noticed has heap_getattr buggily returned NULL for default columns
801 UPDATE t SET a = NULL;
802 -- verify that index and non-index scans show the same result
803 SET LOCAL enable_seqscan = true;
804 SELECT * FROM t WHERE a IS NULL;
810 SET LOCAL enable_seqscan = false;
811 SELECT * FROM t WHERE a IS NULL;
818 -- verify that a default set on a non-plain table doesn't set a missing
819 -- value on the attribute
820 CREATE FOREIGN DATA WRAPPER dummy;
821 CREATE SERVER s0 FOREIGN DATA WRAPPER dummy;
822 CREATE FOREIGN TABLE ft1 (c1 integer NOT NULL) SERVER s0;
823 ALTER FOREIGN TABLE ft1 ADD COLUMN c8 integer DEFAULT 0;
824 ALTER FOREIGN TABLE ft1 ALTER COLUMN c8 TYPE char(10);
827 WHERE attrelid = 'ft1'::regclass AND
828 (attmissingval IS NOT NULL OR atthasmissing);
835 DROP FOREIGN TABLE ft1;
837 DROP FOREIGN DATA WRAPPER dummy;
842 DROP FUNCTION test_trigger();
844 DROP FUNCTION set(name);
845 DROP FUNCTION comp();
847 DROP TABLE has_volatile;
848 DROP EVENT TRIGGER has_volatile_rewrite;
849 DROP FUNCTION log_rewrite;
850 DROP SCHEMA fast_default;
851 -- Leave a table with an active fast default in place, for pg_upgrade testing
852 set search_path = public;
853 create table has_fast_default(f1 int);
854 insert into has_fast_default values(1);
855 alter table has_fast_default add column f2 int default 42;
856 table has_fast_default;