@@ -1030,17 +1030,112 @@ SELECT tableoid::regclass, * FROM gtest_parent ORDER BY 1, 2, 3;
10301030(3 rows)
10311031
10321032-- we leave these tables around for purposes of testing dump/reload/upgrade
1033- -- generated columns in partition key (not allowed)
1034- CREATE TABLE gtest_part_key (f1 date NOT NULL, f2 bigint, f3 bigint GENERATED ALWAYS AS (f2 * 2) VIRTUAL) PARTITION BY RANGE (f3);
1035- ERROR:  cannot use generated column in partition key
1036- LINE 1: ...NERATED ALWAYS AS (f2 * 2) VIRTUAL) PARTITION BY RANGE (f3);
1037-                                                                    ^
1038- DETAIL:  Column "f3" is a generated column.
1039- CREATE TABLE gtest_part_key (f1 date NOT NULL, f2 bigint, f3 bigint GENERATED ALWAYS AS (f2 * 2) VIRTUAL) PARTITION BY RANGE ((f3 * 3));
1040- ERROR:  cannot use generated column in partition key
1033+ -- tests for virtual generated columns in partition key
1034+ CREATE TABLE gtest_part_key1 (f1 date, f2 bigint, f3 bigint GENERATED ALWAYS AS (f2 * 2) VIRTUAL) PARTITION BY RANGE ((f3 * 3)); --error
1035+ ERROR:  partition key expression cannot use virtual generated column
10411036LINE 1: ...D ALWAYS AS (f2 * 2) VIRTUAL) PARTITION BY RANGE ((f3 * 3));
10421037                                                             ^
1043- DETAIL:  Column "f3" is a generated column.
1038+ HINT:  Only plain virtual generated column reference can be used in partition key
1039+ CREATE TABLE gtest_part_key1 (f1 date, f2 bigint, f3 bigint GENERATED ALWAYS AS (f2 * 2) VIRTUAL) PARTITION BY RANGE ((f3)); --ok
1040+ ALTER TABLE gtest_part_key1 ALTER COLUMN f3 SET EXPRESSION AS (f2 * 2); --error
1041+ ERROR:  cannot alter column "f3" because it is part of the partition key of relation "gtest_part_key1"
1042+ ALTER TABLE gtest_part_key1 ALTER COLUMN f2 set data type int; --error
1043+ ERROR:  cannot alter type of a column used by a generated column
1044+ DETAIL:  Column "f2" is used by generated column "f3".
1045+ ALTER TABLE gtest_part_key1 ALTER COLUMN f3 set data type int; --error
1046+ ERROR:  cannot alter column "f3" because it is part of the partition key of relation "gtest_part_key1"
1047+ LINE 1: ALTER TABLE gtest_part_key1 ALTER COLUMN f3 set data type in...
1048+                                                  ^
1049+ CREATE TABLE gtest_part_key1_0(f2 bigint, f1 date, f3 bigint GENERATED ALWAYS AS (f2 * 3) VIRTUAL);
1050+ ALTER TABLE gtest_part_key1 ATTACH PARTITION gtest_part_key1_0 FOR VALUES FROM (20) TO (30); --error
1051+ ERROR:  cannot attach table "gtest_part_key1_0" as a partition because it has with different generation expression
1052+ ALTER TABLE gtest_part_key1_0 ALTER COLUMN f3 SET EXPRESSION AS (f2 * 2);
1053+ ALTER TABLE gtest_part_key1 ATTACH PARTITION gtest_part_key1_0 FOR VALUES FROM (20) TO (30); --now ok
1054+ CREATE TABLE gtest_part_key1_1 PARTITION OF gtest_part_key1 FOR VALUES FROM (30) TO (50);
1055+ CREATE TABLE gtest_part_key1_2 PARTITION OF gtest_part_key1 FOR VALUES FROM (50) TO (100);
1056+ \d+ gtest_part_key1
1057+                          Partitioned table "generated_virtual_tests.gtest_part_key1"
1058+  Column |  Type  | Collation | Nullable |           Default            | Storage | Stats target | Description 
1059+ --------+--------+-----------+----------+------------------------------+---------+--------------+-------------
1060+  f1     | date   |           |          |                              | plain   |              | 
1061+  f2     | bigint |           |          |                              | plain   |              | 
1062+  f3     | bigint |           |          | generated always as (f2 * 2) | plain   |              | 
1063+ Partition key: RANGE (f3)
1064+ Partitions: gtest_part_key1_0 FOR VALUES FROM ('20') TO ('30'),
1065+             gtest_part_key1_1 FOR VALUES FROM ('30') TO ('50'),
1066+             gtest_part_key1_2 FOR VALUES FROM ('50') TO ('100')
1067+ 
1068+ CREATE OR REPLACE FUNCTION gtest_trigger_info() RETURNS trigger
1069+   LANGUAGE plpgsql
1070+ AS $$
1071+ BEGIN
1072+ 	RAISE INFO 'TG_WHEN: % TG_RELNAME: % trigger name: % tg_op: %', TG_WHEN, TG_relname, TG_NAME, tg_op;
1073+   IF tg_op IN ('DELETE') THEN
1074+     RAISE INFO 'old = %', OLD;
1075+     RETURN OLD;
1076+   ELSIF tg_op IN ('INSERT') THEN
1077+     RAISE INFO 'new = %', NEW;
1078+     RETURN NEW;
1079+   ELSIF tg_op IN ('UPDATE') THEN
1080+     RAISE INFO 'old = %d; new = %', OLD, NEW;
1081+     RETURN NEW;
1082+   ELSE
1083+     RETURN NEW;
1084+   END IF;
1085+ END
1086+ $$;
1087+ CREATE TRIGGER gkey1_0 BEFORE INSERT OR UPDATE ON gtest_part_key1_0
1088+ FOR EACH ROW
1089+ EXECUTE PROCEDURE gtest_trigger_info();
1090+ CREATE TRIGGER gkey1_1 BEFORE INSERT OR UPDATE ON gtest_part_key1_1
1091+ FOR EACH ROW
1092+ EXECUTE PROCEDURE gtest_trigger_info();
1093+ CREATE TRIGGER gkey1_2 BEFORE INSERT OR UPDATE ON gtest_part_key1_2
1094+ FOR EACH ROW
1095+ EXECUTE PROCEDURE gtest_trigger_info();
1096+ INSERT INTO gtest_part_key1(f2, f3) VALUES (9, default); --error
1097+ ERROR:  no partition of relation "gtest_part_key1" found for row
1098+ DETAIL:  Partition key of the failing row contains (f3) = (18).
1099+ INSERT INTO gtest_part_key1(f2, f3) VALUES (10, default) returning tableoid::regclass, *; --ok
1100+ INFO:  TG_WHEN: BEFORE TG_RELNAME: gtest_part_key1_0 trigger name: gkey1_0 tg_op: INSERT
1101+ INFO:  new = (10,,)
1102+      tableoid      | f1 | f2 | f3 
1103+ -------------------+----+----+----
1104+  gtest_part_key1_0 |    | 10 | 20
1105+ (1 row)
1106+ 
1107+ INSERT INTO gtest_part_key1_0(f2, f3) VALUES (12, default) returning tableoid::regclass, *; --ok
1108+ INFO:  TG_WHEN: BEFORE TG_RELNAME: gtest_part_key1_0 trigger name: gkey1_0 tg_op: INSERT
1109+ INFO:  new = (12,,)
1110+      tableoid      | f2 | f1 | f3 
1111+ -------------------+----+----+----
1112+  gtest_part_key1_0 | 12 |    | 24
1113+ (1 row)
1114+ 
1115+ MERGE INTO gtest_part_key1
1116+   USING (VALUES (10, 100), (12, 25), (14, 30)) AS s(sid, delta)
1117+ ON gtest_part_key1.f2 = s.sid
1118+ WHEN MATCHED AND f2 = 12 THEN UPDATE SET f2 = 20
1119+ WHEN MATCHED AND f2 = 10 THEN UPDATE SET f2 = 30
1120+ WHEN NOT MATCHED THEN INSERT(f2) VALUES (s.sid)
1121+ RETURNING merge_action(), tableoid::regclass, old.f2, old.f3, new.f2, new.f3;
1122+ INFO:  TG_WHEN: BEFORE TG_RELNAME: gtest_part_key1_0 trigger name: gkey1_0 tg_op: UPDATE
1123+ INFO:  old = (10,,)d; new = (30,,)
1124+ INFO:  TG_WHEN: BEFORE TG_RELNAME: gtest_part_key1_2 trigger name: gkey1_2 tg_op: INSERT
1125+ INFO:  new = (,30,)
1126+ INFO:  TG_WHEN: BEFORE TG_RELNAME: gtest_part_key1_0 trigger name: gkey1_0 tg_op: UPDATE
1127+ INFO:  old = (12,,)d; new = (20,,)
1128+ INFO:  TG_WHEN: BEFORE TG_RELNAME: gtest_part_key1_1 trigger name: gkey1_1 tg_op: INSERT
1129+ INFO:  new = (,20,)
1130+ INFO:  TG_WHEN: BEFORE TG_RELNAME: gtest_part_key1_0 trigger name: gkey1_0 tg_op: INSERT
1131+ INFO:  new = (14,,)
1132+  merge_action |     tableoid      | f2 | f3 | f2 | f3 
1133+ --------------+-------------------+----+----+----+----
1134+  UPDATE       | gtest_part_key1_2 | 10 | 20 | 30 | 60
1135+  UPDATE       | gtest_part_key1_1 | 12 | 24 | 20 | 40
1136+  INSERT       | gtest_part_key1_0 |    |    | 14 | 28
1137+ (3 rows)
1138+ 
10441139-- ALTER TABLE ... ADD COLUMN
10451140CREATE TABLE gtest25 (a int PRIMARY KEY);
10461141INSERT INTO gtest25 VALUES (3), (4);
0 commit comments