diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/test/regress/expected/generated_stored.out | 140 | ||||
-rw-r--r-- | src/test/regress/sql/generated_stored.sql | 59 |
2 files changed, 179 insertions, 20 deletions
diff --git a/src/test/regress/expected/generated_stored.out b/src/test/regress/expected/generated_stored.out index e28cc3919da..43db7442a67 100644 --- a/src/test/regress/expected/generated_stored.out +++ b/src/test/regress/expected/generated_stored.out @@ -122,6 +122,24 @@ SELECT * FROM gtest1 ORDER BY a; 4 | 8 (4 rows) +SELECT gtest1 FROM gtest1 ORDER BY a; -- whole-row reference + gtest1 +-------- + (1,2) + (2,4) + (3,6) + (4,8) +(4 rows) + +SELECT a, (SELECT gtest1.b) FROM gtest1 ORDER BY a; -- sublink + a | b +---+--- + 1 | 2 + 2 | 4 + 3 | 6 + 4 | 8 +(4 rows) + DELETE FROM gtest1 WHERE a >= 3; UPDATE gtest1 SET b = DEFAULT WHERE a = 1; UPDATE gtest1 SET b = 11 WHERE a = 1; -- error @@ -177,7 +195,12 @@ SELECT * FROM gtest1 ORDER BY a; 2 | 4 (2 rows) -UPDATE gtest1 SET a = 3 WHERE b = 4; +UPDATE gtest1 SET a = 3 WHERE b = 4 RETURNING old.*, new.*; + a | b | a | b +---+---+---+--- + 2 | 4 | 3 | 6 +(1 row) + SELECT * FROM gtest1 ORDER BY a; a | b ---+--- @@ -203,7 +226,14 @@ CREATE TABLE gtestm ( INSERT INTO gtestm VALUES (1, 5, 100); MERGE INTO gtestm t USING (VALUES (1, 10), (2, 20)) v(id, f1) ON t.id = v.id WHEN MATCHED THEN UPDATE SET f1 = v.f1 - WHEN NOT MATCHED THEN INSERT VALUES (v.id, v.f1, 200); + WHEN NOT MATCHED THEN INSERT VALUES (v.id, v.f1, 200) + RETURNING merge_action(), old.*, new.*; + merge_action | id | f1 | f2 | f3 | f4 | id | f1 | f2 | f3 | f4 +--------------+----+----+-----+----+-----+----+----+-----+----+----- + UPDATE | 1 | 5 | 100 | 10 | 200 | 1 | 10 | 100 | 20 | 200 + INSERT | | | | | | 2 | 20 | 200 | 40 | 400 +(2 rows) + SELECT * FROM gtestm ORDER BY id; id | f1 | f2 | f3 | f4 ----+----+-----+----+----- @@ -212,6 +242,27 @@ SELECT * FROM gtestm ORDER BY id; (2 rows) DROP TABLE gtestm; +CREATE TABLE gtestm ( + a int PRIMARY KEY, + b int GENERATED ALWAYS AS (a * 2) STORED +); +INSERT INTO gtestm (a) SELECT g FROM generate_series(1, 10) g; +MERGE INTO gtestm t USING gtestm AS s ON 2 * t.a = s.b WHEN MATCHED THEN DELETE RETURNING *; + a | b | a | b +----+----+----+---- + 1 | 2 | 1 | 2 + 2 | 4 | 2 | 4 + 3 | 6 | 3 | 6 + 4 | 8 | 4 | 8 + 5 | 10 | 5 | 10 + 6 | 12 | 6 | 12 + 7 | 14 | 7 | 14 + 8 | 16 | 8 | 16 + 9 | 18 | 9 | 18 + 10 | 20 | 10 | 20 +(10 rows) + +DROP TABLE gtestm; -- views CREATE VIEW gtest1v AS SELECT * FROM gtest1; SELECT * FROM gtest1v; @@ -319,6 +370,21 @@ Not-null constraints: "gtest1_a_not_null" NOT NULL "a" (inherited) Inherits: gtest1 +INSERT INTO gtestx (a, x) VALUES (11, 22); +SELECT * FROM gtest1; + a | b +----+----- + 3 | 6 + 4 | 8 + 11 | 242 +(3 rows) + +SELECT * FROM gtestx; + a | b | x +----+-----+---- + 11 | 242 | 22 +(1 row) + CREATE TABLE gtestxx_1 (a int NOT NULL, b int); ALTER TABLE gtestxx_1 INHERIT gtest1; -- error ERROR: column "b" in child table must be a generated column @@ -541,7 +607,7 @@ CREATE FUNCTION gf1(a int) RETURNS int AS $$ SELECT a * 3 $$ IMMUTABLE LANGUAGE REVOKE ALL ON FUNCTION gf1(int) FROM PUBLIC; CREATE TABLE gtest12 (a int PRIMARY KEY, b int, c int GENERATED ALWAYS AS (gf1(b)) STORED); INSERT INTO gtest12 VALUES (1, 10), (2, 20); -GRANT SELECT (a, c) ON gtest12 TO regress_user11; +GRANT SELECT (a, c), INSERT ON gtest12 TO regress_user11; SET ROLE regress_user11; SELECT a, b FROM gtest11; -- not allowed ERROR: permission denied for table gtest11 @@ -554,7 +620,9 @@ SELECT a, c FROM gtest11; -- allowed SELECT gf1(10); -- not allowed ERROR: permission denied for function gf1 -SELECT a, c FROM gtest12; -- allowed +INSERT INTO gtest12 VALUES (3, 30), (4, 40); -- currently not allowed because of function permissions, should arguably be allowed +ERROR: permission denied for function gf1 +SELECT a, c FROM gtest12; -- allowed (does not actually invoke the function) a | c ---+---- 1 | 30 @@ -589,6 +657,13 @@ INSERT INTO gtest20b (a) VALUES (30); ALTER TABLE gtest20b ADD CONSTRAINT chk CHECK (b < 50) NOT VALID; ALTER TABLE gtest20b VALIDATE CONSTRAINT chk; -- fails on existing row ERROR: check constraint "chk" of relation "gtest20b" is violated by some row +-- check with whole-row reference +CREATE TABLE gtest20c (a int, b int GENERATED ALWAYS AS (a * 2) STORED); +ALTER TABLE gtest20c ADD CONSTRAINT whole_row_check CHECK (gtest20c IS NOT NULL); +INSERT INTO gtest20c VALUES (1); -- ok +INSERT INTO gtest20c VALUES (NULL); -- fails +ERROR: new row for relation "gtest20c" violates check constraint "whole_row_check" +DETAIL: Failing row contains (null, null). -- not-null constraints CREATE TABLE gtest21a (a int PRIMARY KEY, b int GENERATED ALWAYS AS (nullif(a, 0)) STORED NOT NULL); INSERT INTO gtest21a (a) VALUES (1); -- ok @@ -758,6 +833,11 @@ CREATE TABLE gtest24 (a int PRIMARY KEY, b gtestdomain1 GENERATED ALWAYS AS (a * INSERT INTO gtest24 (a) VALUES (4); -- ok INSERT INTO gtest24 (a) VALUES (6); -- error ERROR: value for domain gtestdomain1 violates check constraint "gtestdomain1_check" +CREATE TYPE gtestdomain1range AS range (subtype = gtestdomain1); +CREATE TABLE gtest24r (a int PRIMARY KEY, b gtestdomain1range GENERATED ALWAYS AS (gtestdomain1range(a, a + 5)) STORED); +INSERT INTO gtest24r (a) VALUES (4); -- ok +INSERT INTO gtest24r (a) VALUES (6); -- error +ERROR: value for domain gtestdomain1 violates check constraint "gtestdomain1_check" -- typed tables (currently not supported) CREATE TYPE gtest_type AS (f1 integer, f2 text, f3 bigint); CREATE TABLE gtest28 OF gtest_type (f1 WITH OPTIONS GENERATED ALWAYS AS (f2 *2) STORED); @@ -841,6 +921,24 @@ SELECT tableoid::regclass, * FROM gtest_parent ORDER BY 1, 2, 3; gtest_child2 | 08-15-2016 | 3 | 66 (3 rows) +SELECT tableoid::regclass, * FROM gtest_child ORDER BY 1, 2, 3; + tableoid | f1 | f2 | f3 +-------------+------------+----+---- + gtest_child | 07-15-2016 | 1 | 2 + gtest_child | 07-15-2016 | 2 | 4 +(2 rows) + +SELECT tableoid::regclass, * FROM gtest_child2 ORDER BY 1, 2, 3; + tableoid | f1 | f2 | f3 +--------------+------------+----+---- + gtest_child2 | 08-15-2016 | 3 | 66 +(1 row) + +SELECT tableoid::regclass, * FROM gtest_child3 ORDER BY 1, 2, 3; + tableoid | f1 | f2 | f3 +----------+----+----+---- +(0 rows) + UPDATE gtest_parent SET f1 = f1 + 60 WHERE f2 = 1; SELECT tableoid::regclass, * FROM gtest_parent ORDER BY 1, 2, 3; tableoid | f1 | f2 | f3 @@ -1184,6 +1282,18 @@ Inherits: gtest30 ALTER TABLE gtest30_1 ALTER COLUMN b DROP EXPRESSION; -- error ERROR: cannot drop generation expression from inherited column +-- composite type dependencies +CREATE TABLE gtest31_1 (a int, b text GENERATED ALWAYS AS ('hello') STORED, c text); +CREATE TABLE gtest31_2 (x int, y gtest31_1); +ALTER TABLE gtest31_1 ALTER COLUMN b TYPE varchar; -- fails +ERROR: cannot alter table "gtest31_1" because column "gtest31_2.y" uses its row type +DROP TABLE gtest31_1, gtest31_2; +-- Check it for a partitioned table, too +CREATE TABLE gtest31_1 (a int, b text GENERATED ALWAYS AS ('hello') STORED, c text) PARTITION BY LIST (a); +CREATE TABLE gtest31_2 (x int, y gtest31_1); +ALTER TABLE gtest31_1 ALTER COLUMN b TYPE varchar; -- fails +ERROR: cannot alter table "gtest31_1" because column "gtest31_2.y" uses its row type +DROP TABLE gtest31_1, gtest31_2; -- triggers CREATE TABLE gtest26 ( a int PRIMARY KEY, @@ -1294,7 +1404,7 @@ UPDATE gtest26 SET a = 1 WHERE a = 0; NOTICE: OK DROP TRIGGER gtest11 ON gtest26; TRUNCATE gtest26; --- check that modifications of stored generated columns in triggers do +-- check that modifications of generated columns in triggers do -- not get propagated CREATE FUNCTION gtest_trigger_func4() RETURNS trigger LANGUAGE plpgsql @@ -1305,20 +1415,28 @@ BEGIN RETURN NEW; END; $$; -CREATE TRIGGER gtest12_01 BEFORE UPDATE ON gtest26 +CREATE TRIGGER gtest12_01 BEFORE INSERT OR UPDATE ON gtest26 FOR EACH ROW EXECUTE PROCEDURE gtest_trigger_func(); -CREATE TRIGGER gtest12_02 BEFORE UPDATE ON gtest26 +CREATE TRIGGER gtest12_02 BEFORE INSERT OR UPDATE ON gtest26 FOR EACH ROW EXECUTE PROCEDURE gtest_trigger_func4(); -CREATE TRIGGER gtest12_03 BEFORE UPDATE ON gtest26 +CREATE TRIGGER gtest12_03 BEFORE INSERT OR UPDATE ON gtest26 FOR EACH ROW EXECUTE PROCEDURE gtest_trigger_func(); INSERT INTO gtest26 (a) VALUES (1); -UPDATE gtest26 SET a = 11 WHERE a = 1; -INFO: gtest12_01: BEFORE: old = (1,2) +INFO: gtest12_01: BEFORE: new = (1,) +INFO: gtest12_03: BEFORE: new = (10,300) +SELECT * FROM gtest26 ORDER BY a; + a | b +----+---- + 10 | 20 +(1 row) + +UPDATE gtest26 SET a = 11 WHERE a = 10; +INFO: gtest12_01: BEFORE: old = (10,20) INFO: gtest12_01: BEFORE: new = (11,) -INFO: gtest12_03: BEFORE: old = (1,2) +INFO: gtest12_03: BEFORE: old = (10,20) INFO: gtest12_03: BEFORE: new = (10,) SELECT * FROM gtest26 ORDER BY a; a | b diff --git a/src/test/regress/sql/generated_stored.sql b/src/test/regress/sql/generated_stored.sql index ec45c93d180..6fbfcbf9615 100644 --- a/src/test/regress/sql/generated_stored.sql +++ b/src/test/regress/sql/generated_stored.sql @@ -56,6 +56,8 @@ INSERT INTO gtest1 VALUES (3, 33), (4, DEFAULT); -- error INSERT INTO gtest1 VALUES (3, DEFAULT), (4, DEFAULT); -- ok SELECT * FROM gtest1 ORDER BY a; +SELECT gtest1 FROM gtest1 ORDER BY a; -- whole-row reference +SELECT a, (SELECT gtest1.b) FROM gtest1 ORDER BY a; -- sublink DELETE FROM gtest1 WHERE a >= 3; UPDATE gtest1 SET b = DEFAULT WHERE a = 1; @@ -79,7 +81,7 @@ DROP TABLE gtestx; -- test UPDATE/DELETE quals SELECT * FROM gtest1 ORDER BY a; -UPDATE gtest1 SET a = 3 WHERE b = 4; +UPDATE gtest1 SET a = 3 WHERE b = 4 RETURNING old.*, new.*; SELECT * FROM gtest1 ORDER BY a; DELETE FROM gtest1 WHERE b = 2; SELECT * FROM gtest1 ORDER BY a; @@ -95,10 +97,19 @@ CREATE TABLE gtestm ( INSERT INTO gtestm VALUES (1, 5, 100); MERGE INTO gtestm t USING (VALUES (1, 10), (2, 20)) v(id, f1) ON t.id = v.id WHEN MATCHED THEN UPDATE SET f1 = v.f1 - WHEN NOT MATCHED THEN INSERT VALUES (v.id, v.f1, 200); + WHEN NOT MATCHED THEN INSERT VALUES (v.id, v.f1, 200) + RETURNING merge_action(), old.*, new.*; SELECT * FROM gtestm ORDER BY id; DROP TABLE gtestm; +CREATE TABLE gtestm ( + a int PRIMARY KEY, + b int GENERATED ALWAYS AS (a * 2) STORED +); +INSERT INTO gtestm (a) SELECT g FROM generate_series(1, 10) g; +MERGE INTO gtestm t USING gtestm AS s ON 2 * t.a = s.b WHEN MATCHED THEN DELETE RETURNING *; +DROP TABLE gtestm; + -- views CREATE VIEW gtest1v AS SELECT * FROM gtest1; SELECT * FROM gtest1v; @@ -140,6 +151,9 @@ CREATE TABLE gtestx (x int, b int DEFAULT 10) INHERITS (gtest1); -- error CREATE TABLE gtestx (x int, b int GENERATED ALWAYS AS IDENTITY) INHERITS (gtest1); -- error CREATE TABLE gtestx (x int, b int GENERATED ALWAYS AS (a * 22) STORED) INHERITS (gtest1); -- ok, overrides parent \d+ gtestx +INSERT INTO gtestx (a, x) VALUES (11, 22); +SELECT * FROM gtest1; +SELECT * FROM gtestx; CREATE TABLE gtestxx_1 (a int NOT NULL, b int); ALTER TABLE gtestxx_1 INHERIT gtest1; -- error @@ -274,13 +288,14 @@ REVOKE ALL ON FUNCTION gf1(int) FROM PUBLIC; CREATE TABLE gtest12 (a int PRIMARY KEY, b int, c int GENERATED ALWAYS AS (gf1(b)) STORED); INSERT INTO gtest12 VALUES (1, 10), (2, 20); -GRANT SELECT (a, c) ON gtest12 TO regress_user11; +GRANT SELECT (a, c), INSERT ON gtest12 TO regress_user11; SET ROLE regress_user11; SELECT a, b FROM gtest11; -- not allowed SELECT a, c FROM gtest11; -- allowed SELECT gf1(10); -- not allowed -SELECT a, c FROM gtest12; -- allowed +INSERT INTO gtest12 VALUES (3, 30), (4, 40); -- currently not allowed because of function permissions, should arguably be allowed +SELECT a, c FROM gtest12; -- allowed (does not actually invoke the function) RESET ROLE; DROP FUNCTION gf1(int); -- fail @@ -307,6 +322,12 @@ INSERT INTO gtest20b (a) VALUES (30); ALTER TABLE gtest20b ADD CONSTRAINT chk CHECK (b < 50) NOT VALID; ALTER TABLE gtest20b VALIDATE CONSTRAINT chk; -- fails on existing row +-- check with whole-row reference +CREATE TABLE gtest20c (a int, b int GENERATED ALWAYS AS (a * 2) STORED); +ALTER TABLE gtest20c ADD CONSTRAINT whole_row_check CHECK (gtest20c IS NOT NULL); +INSERT INTO gtest20c VALUES (1); -- ok +INSERT INTO gtest20c VALUES (NULL); -- fails + -- not-null constraints CREATE TABLE gtest21a (a int PRIMARY KEY, b int GENERATED ALWAYS AS (nullif(a, 0)) STORED NOT NULL); INSERT INTO gtest21a (a) VALUES (1); -- ok @@ -386,6 +407,10 @@ CREATE DOMAIN gtestdomain1 AS int CHECK (VALUE < 10); CREATE TABLE gtest24 (a int PRIMARY KEY, b gtestdomain1 GENERATED ALWAYS AS (a * 2) STORED); INSERT INTO gtest24 (a) VALUES (4); -- ok INSERT INTO gtest24 (a) VALUES (6); -- error +CREATE TYPE gtestdomain1range AS range (subtype = gtestdomain1); +CREATE TABLE gtest24r (a int PRIMARY KEY, b gtestdomain1range GENERATED ALWAYS AS (gtestdomain1range(a, a + 5)) STORED); +INSERT INTO gtest24r (a) VALUES (4); -- ok +INSERT INTO gtest24r (a) VALUES (6); -- error -- typed tables (currently not supported) CREATE TYPE gtest_type AS (f1 integer, f2 text, f3 bigint); @@ -431,6 +456,9 @@ INSERT INTO gtest_parent (f1, f2) VALUES ('2016-07-15', 1); INSERT INTO gtest_parent (f1, f2) VALUES ('2016-07-15', 2); INSERT INTO gtest_parent (f1, f2) VALUES ('2016-08-15', 3); SELECT tableoid::regclass, * FROM gtest_parent ORDER BY 1, 2, 3; +SELECT tableoid::regclass, * FROM gtest_child ORDER BY 1, 2, 3; +SELECT tableoid::regclass, * FROM gtest_child2 ORDER BY 1, 2, 3; +SELECT tableoid::regclass, * FROM gtest_child3 ORDER BY 1, 2, 3; UPDATE gtest_parent SET f1 = f1 + 60 WHERE f2 = 1; SELECT tableoid::regclass, * FROM gtest_parent ORDER BY 1, 2, 3; @@ -545,6 +573,18 @@ ALTER TABLE ONLY gtest30 ALTER COLUMN b DROP EXPRESSION; -- error \d gtest30_1 ALTER TABLE gtest30_1 ALTER COLUMN b DROP EXPRESSION; -- error +-- composite type dependencies +CREATE TABLE gtest31_1 (a int, b text GENERATED ALWAYS AS ('hello') STORED, c text); +CREATE TABLE gtest31_2 (x int, y gtest31_1); +ALTER TABLE gtest31_1 ALTER COLUMN b TYPE varchar; -- fails +DROP TABLE gtest31_1, gtest31_2; + +-- Check it for a partitioned table, too +CREATE TABLE gtest31_1 (a int, b text GENERATED ALWAYS AS ('hello') STORED, c text) PARTITION BY LIST (a); +CREATE TABLE gtest31_2 (x int, y gtest31_1); +ALTER TABLE gtest31_1 ALTER COLUMN b TYPE varchar; -- fails +DROP TABLE gtest31_1, gtest31_2; + -- triggers CREATE TABLE gtest26 ( a int PRIMARY KEY, @@ -630,7 +670,7 @@ UPDATE gtest26 SET a = 1 WHERE a = 0; DROP TRIGGER gtest11 ON gtest26; TRUNCATE gtest26; --- check that modifications of stored generated columns in triggers do +-- check that modifications of generated columns in triggers do -- not get propagated CREATE FUNCTION gtest_trigger_func4() RETURNS trigger LANGUAGE plpgsql @@ -642,20 +682,21 @@ BEGIN END; $$; -CREATE TRIGGER gtest12_01 BEFORE UPDATE ON gtest26 +CREATE TRIGGER gtest12_01 BEFORE INSERT OR UPDATE ON gtest26 FOR EACH ROW EXECUTE PROCEDURE gtest_trigger_func(); -CREATE TRIGGER gtest12_02 BEFORE UPDATE ON gtest26 +CREATE TRIGGER gtest12_02 BEFORE INSERT OR UPDATE ON gtest26 FOR EACH ROW EXECUTE PROCEDURE gtest_trigger_func4(); -CREATE TRIGGER gtest12_03 BEFORE UPDATE ON gtest26 +CREATE TRIGGER gtest12_03 BEFORE INSERT OR UPDATE ON gtest26 FOR EACH ROW EXECUTE PROCEDURE gtest_trigger_func(); INSERT INTO gtest26 (a) VALUES (1); -UPDATE gtest26 SET a = 11 WHERE a = 1; +SELECT * FROM gtest26 ORDER BY a; +UPDATE gtest26 SET a = 11 WHERE a = 10; SELECT * FROM gtest26 ORDER BY a; -- LIKE INCLUDING GENERATED and dropped column handling |