From 8f1eb264173d3dc9f76ca59caf4d8fe1671d098e Mon Sep 17 00:00:00 2001
From: Ashutosh Bapat <ashutosh.bapat@enterprisedb.com>
Date: Wed, 6 Dec 2023 15:54:01 +0530
Subject: [PATCH 05/14] Extra ATTACH PARTITION tests for identity column

Not for final commit.
---
 .../regress/expected/identity_part_extra.out  | 148 ++++++++++++++----
 src/test/regress/sql/identity_part_extra.sql  |  82 +++++++---
 2 files changed, 179 insertions(+), 51 deletions(-)

diff --git a/src/test/regress/expected/identity_part_extra.out b/src/test/regress/expected/identity_part_extra.out
index 0c8af1c658..81dfca2acc 100644
--- a/src/test/regress/expected/identity_part_extra.out
+++ b/src/test/regress/expected/identity_part_extra.out
@@ -51,8 +51,10 @@ CREATE TABLE itest_parted (f1 date NOT NULL, f2 text, f3 bigint generated always
 CREATE TABLE itest_p1 PARTITION OF itest_parted FOR VALUES FROM ('2016-07-01') TO ('2016-08-01');
 SELECT attrelid::regclass, attname, attidentity, atthasdef, attgenerated, attnotnull
     FROM pg_attribute
-    WHERE attrelid IN ('itest_parted'::regclass, 'itest_p1'::regclass)
-        AND attnum > 0;
+    WHERE attrelid IN (SELECT oid FROM pg_class WHERE relname like 'itest_p%'
+                                                    and relkind in ('r', 'p'))
+        AND attnum > 0
+    ORDER BY attrelid, attnum;
    attrelid   | attname | attidentity | atthasdef | attgenerated | attnotnull 
 --------------+---------+-------------+-----------+--------------+------------
  itest_parted | f1      |             | f         |              | t
@@ -65,7 +67,9 @@ SELECT attrelid::regclass, attname, attidentity, atthasdef, attgenerated, attnot
 
 SELECT conrelid::regclass, conname, connoinherit, conislocal, coninhcount
     FROM pg_constraint
-    WHERE conrelid in ('itest_parted'::regclass, 'itest_p1'::regclass);
+    WHERE conrelid in (SELECT oid FROM pg_class WHERE relname like 'itest_p%'
+                                                    and relkind in ('r', 'p'))
+    ORDER BY conrelid, conname;
    conrelid   |         conname          | connoinherit | conislocal | coninhcount 
 --------------+--------------------------+--------------+------------+-------------
  itest_parted | itest_parted_f1_not_null | f            | t          |           0
@@ -74,25 +78,28 @@ SELECT conrelid::regclass, conname, connoinherit, conislocal, coninhcount
  itest_p1     | itest_parted_f3_not_null | f            | f          |           1
 (4 rows)
 
-SELECT *
+SELECT classid, objid_name, objsubid, refclassid, refobjid_name, refobjsubid, deptype
     FROM v_pg_depend
-    WHERE refobjid in ('itest_parted'::regclass, 'itest_p1'::regclass)
-            OR objid in ('itest_parted'::regclass, 'itest_p1'::regclass);
-    classid    |           objid_name            | objid | objsubid |  refclassid  | refobjid_name | refobjid | refobjsubid |   deptype    
----------------+---------------------------------+-------+----------+--------------+---------------+----------+-------------+--------------
- pg_type       | itest_parted                    | 16619 |        0 | pg_class     | itest_parted  |    16617 |           0 | internal (i)
- pg_class      | itest_parted                    | 16617 |        0 | pg_namespace | 2200          |     2200 |           0 | normal (n)
- pg_class      | itest_parted                    | 16617 |        1 | pg_class     | itest_parted  |    16617 |           0 | internal (i)
- pg_constraint | public.itest_parted_f1_not_null | 16620 |        0 | pg_class     | itest_parted  |    16617 |           1 | auto (a)
- pg_constraint | public.itest_parted_f3_not_null | 16621 |        0 | pg_class     | itest_parted  |    16617 |           3 | auto (a)
- pg_class      | itest_parted_f3_seq             | 16616 |        0 | pg_class     | itest_parted  |    16617 |           3 | internal (i)
- pg_type       | itest_p1                        | 16624 |        0 | pg_class     | itest_p1      |    16622 |           0 | internal (i)
- pg_class      | itest_p1                        | 16622 |        0 | pg_namespace | 2200          |     2200 |           0 | normal (n)
- pg_class      | itest_p1                        | 16622 |        0 | pg_class     | itest_parted  |    16617 |           0 | auto (a)
- pg_constraint | public.itest_parted_f1_not_null | 16625 |        0 | pg_class     | itest_p1      |    16622 |           1 | auto (a)
- pg_constraint | public.itest_parted_f3_not_null | 16626 |        0 | pg_class     | itest_p1      |    16622 |           3 | auto (a)
- pg_class      | pg_toast.pg_toast_16622         | 16627 |        0 | pg_class     | itest_p1      |    16622 |           0 | internal (i)
-(12 rows)
+    WHERE (refobjid in (SELECT oid FROM pg_class WHERE relname like 'itest_p%'
+                                                    and relkind in ('r', 'p'))
+            OR objid in (SELECT oid FROM pg_class WHERE relname like 'itest_p%'
+                                                    and relkind in ('r', 'p')))
+            AND objid_name NOT LIKE 'pg_toast%'
+    ORDER BY classid, objid_name, objsubid, refclassid, refobjid_name, refobjsubid, deptype;
+    classid    |           objid_name            | objsubid |  refclassid  | refobjid_name | refobjsubid |   deptype    
+---------------+---------------------------------+----------+--------------+---------------+-------------+--------------
+ pg_type       | itest_p1                        |        0 | pg_class     | itest_p1      |           0 | internal (i)
+ pg_type       | itest_parted                    |        0 | pg_class     | itest_parted  |           0 | internal (i)
+ pg_class      | itest_p1                        |        0 | pg_class     | itest_parted  |           0 | auto (a)
+ pg_class      | itest_p1                        |        0 | pg_namespace | 2200          |           0 | normal (n)
+ pg_class      | itest_parted                    |        0 | pg_namespace | 2200          |           0 | normal (n)
+ pg_class      | itest_parted                    |        1 | pg_class     | itest_parted  |           0 | internal (i)
+ pg_class      | itest_parted_f3_seq             |        0 | pg_class     | itest_parted  |           3 | internal (i)
+ pg_constraint | public.itest_parted_f1_not_null |        0 | pg_class     | itest_p1      |           1 | auto (a)
+ pg_constraint | public.itest_parted_f1_not_null |        0 | pg_class     | itest_parted  |           1 | auto (a)
+ pg_constraint | public.itest_parted_f3_not_null |        0 | pg_class     | itest_p1      |           3 | auto (a)
+ pg_constraint | public.itest_parted_f3_not_null |        0 | pg_class     | itest_parted  |           3 | auto (a)
+(11 rows)
 
 INSERT into itest_parted(f1, f2) VALUES ('2016-07-2', 'from itest_parted');
 INSERT into itest_p1 (f1, f2) VALUES ('2016-07-3', 'from itest_p1');
@@ -103,26 +110,107 @@ SELECT tableoid::regclass, f1, f2, f3 FROM itest_parted;
  itest_p1 | 07-03-2016 | from itest_p1     |  2
 (2 rows)
 
+-- attached partition inherits identity and shares the sequence.
+-- existing values in the table should not be affected
+CREATE TABLE itest_p2 (f1 date NOT NULL, f2 text, f3 bigint);
+-- TODO: ideally setting an identity column should automatically spawn the NOT NULL constraint. But it doesn't do that right now.
+ALTER TABLE itest_p2 ALTER COLUMN f3 SET NOT NULL;
+INSERT INTO itest_p2 VALUES ('2016-08-2', 'before attaching', 100);
+ALTER TABLE itest_parted ATTACH PARTITION itest_p2 FOR VALUES FROM ('2016-08-01') TO ('2016-09-01');
+SELECT attrelid::regclass, attname, attidentity, atthasdef, attgenerated, attnotnull
+    FROM pg_attribute
+    WHERE attrelid IN (SELECT oid FROM pg_class WHERE relname like 'itest_p%'
+                                                    and relkind in ('r', 'p'))
+        AND attnum > 0
+    ORDER BY attrelid, attnum;
+   attrelid   | attname | attidentity | atthasdef | attgenerated | attnotnull 
+--------------+---------+-------------+-----------+--------------+------------
+ itest_parted | f1      |             | f         |              | t
+ itest_parted | f2      |             | f         |              | f
+ itest_parted | f3      | a           | f         |              | t
+ itest_p1     | f1      |             | f         |              | t
+ itest_p1     | f2      |             | f         |              | f
+ itest_p1     | f3      | a           | f         |              | t
+ itest_p2     | f1      |             | f         |              | t
+ itest_p2     | f2      |             | f         |              | f
+ itest_p2     | f3      | a           | f         |              | t
+(9 rows)
+
+SELECT conrelid::regclass, conname, connoinherit, conislocal, coninhcount
+    FROM pg_constraint
+    WHERE conrelid in (SELECT oid FROM pg_class WHERE relname like 'itest_p%'
+                                                    and relkind in ('r', 'p'))
+    ORDER BY conrelid, conname;
+   conrelid   |         conname          | connoinherit | conislocal | coninhcount 
+--------------+--------------------------+--------------+------------+-------------
+ itest_parted | itest_parted_f1_not_null | f            | t          |           0
+ itest_parted | itest_parted_f3_not_null | f            | t          |           0
+ itest_p1     | itest_parted_f1_not_null | f            | f          |           1
+ itest_p1     | itest_parted_f3_not_null | f            | f          |           1
+ itest_p2     | itest_p2_f1_not_null     | f            | f          |           1
+ itest_p2     | itest_p2_f3_not_null     | f            | f          |           1
+(6 rows)
+
+SELECT classid, objid_name, objsubid, refclassid, refobjid_name, refobjsubid, deptype
+    FROM v_pg_depend
+    WHERE (refobjid in (SELECT oid FROM pg_class WHERE relname like 'itest_p%'
+                                                    and relkind in ('r', 'p'))
+            OR objid in (SELECT oid FROM pg_class WHERE relname like 'itest_p%'
+                                                    and relkind in ('r', 'p')))
+            AND objid_name NOT LIKE 'pg_toast%'
+    ORDER BY classid, objid_name, objsubid, refclassid, refobjid_name, refobjsubid, deptype;
+    classid    |           objid_name            | objsubid |  refclassid  | refobjid_name | refobjsubid |   deptype    
+---------------+---------------------------------+----------+--------------+---------------+-------------+--------------
+ pg_type       | itest_p1                        |        0 | pg_class     | itest_p1      |           0 | internal (i)
+ pg_type       | itest_p2                        |        0 | pg_class     | itest_p2      |           0 | internal (i)
+ pg_type       | itest_parted                    |        0 | pg_class     | itest_parted  |           0 | internal (i)
+ pg_class      | itest_p1                        |        0 | pg_class     | itest_parted  |           0 | auto (a)
+ pg_class      | itest_p1                        |        0 | pg_namespace | 2200          |           0 | normal (n)
+ pg_class      | itest_p2                        |        0 | pg_class     | itest_parted  |           0 | auto (a)
+ pg_class      | itest_p2                        |        0 | pg_namespace | 2200          |           0 | normal (n)
+ pg_class      | itest_parted                    |        0 | pg_namespace | 2200          |           0 | normal (n)
+ pg_class      | itest_parted                    |        1 | pg_class     | itest_parted  |           0 | internal (i)
+ pg_class      | itest_parted_f3_seq             |        0 | pg_class     | itest_parted  |           3 | internal (i)
+ pg_constraint | public.itest_p2_f1_not_null     |        0 | pg_class     | itest_p2      |           1 | auto (a)
+ pg_constraint | public.itest_p2_f3_not_null     |        0 | pg_class     | itest_p2      |           3 | auto (a)
+ pg_constraint | public.itest_parted_f1_not_null |        0 | pg_class     | itest_p1      |           1 | auto (a)
+ pg_constraint | public.itest_parted_f1_not_null |        0 | pg_class     | itest_parted  |           1 | auto (a)
+ pg_constraint | public.itest_parted_f3_not_null |        0 | pg_class     | itest_p1      |           3 | auto (a)
+ pg_constraint | public.itest_parted_f3_not_null |        0 | pg_class     | itest_parted  |           3 | auto (a)
+(16 rows)
+
+INSERT INTO itest_p2 (f1, f2) VALUES ('2016-08-3', 'from itest_p2');
+INSERT INTO itest_parted (f1, f2) VALUES ('2016-08-4', 'from itest_parted');
+SELECT tableoid::regclass, f1, f2, f3 FROM itest_parted;
+ tableoid |     f1     |        f2         | f3  
+----------+------------+-------------------+-----
+ itest_p1 | 07-02-2016 | from itest_parted |   1
+ itest_p1 | 07-03-2016 | from itest_p1     |   2
+ itest_p2 | 08-02-2016 | before attaching  | 100
+ itest_p2 | 08-03-2016 | from itest_p2     |   3
+ itest_p2 | 08-04-2016 | from itest_parted |   4
+(5 rows)
+
 DROP TABLE itest_parted;
 -- scenarios to test
+-- adding an identity column to a partitioned table adds it to all the partitions, including the ones added after this operation - 7th Dec
+-- changing a normal column to identity column is reflected in all the partitions - 8th Dec
+-- detaching a partition removes identity property - 11th Dec
+-- attaching table with identity column is not allowed (even when the parent does not have an identity column) - 12th Dec
+-- trying to drop inherited identity of column of partition is not allowed - 13th Dec
+-- trying to change the identity properties of partition? Is that allowed? - 13th Dec
 -- changing NOT NULL attribute of inherited identity column of partition is not allowed
 -- trying to change default value of inherited identity column of partition is not allowed
 -- trying to add identity to an inherited identity column of partition is not allowed
--- trying to drop inherited identity column of partition is not allowed
--- trying to change the identity properties of partition? Is that allowed?
 -- TODO: test OVERRIDING SYSTEM VALUE OR OVERRIDING USER VALUE
--- attaching table with identity column is not allowed
--- attaching a table as partition inherits identity property
--- detaching a partition removes identity property
--- attaching a table with identity column is not allowed even when the parent table does not have an identity column
 -- dropping an identity column of parent drops it from all the partitions
 -- TODO: do we need a test for this?
--- adding an identity column to a partitioned table adds it to all the partitions, including the ones added after this operation
--- changing a normal column to identity column is reflected in all the partitions
 -- TODO: can we change an identity column to a normal column?
 -- Dump and restore tests - that would be a separate file
 -- pg_upgrade tests
--- multi-level partition test
+-- multi-level partition tests
+-- tests with other flavours of identity column
+-- tests when the identity column is partition key
 -- \d tests
 -- creating a child table with identity column is not allowed when the parent does not have it
 CREATE TABLE itest_parent (f1 date NOT NULL, f2 text, f3 bigint) PARTITION BY RANGE (f1);
diff --git a/src/test/regress/sql/identity_part_extra.sql b/src/test/regress/sql/identity_part_extra.sql
index 1ab883e5e1..7925ce6205 100644
--- a/src/test/regress/sql/identity_part_extra.sql
+++ b/src/test/regress/sql/identity_part_extra.sql
@@ -5,60 +5,100 @@ SELECT attrelid, attname, attidentity FROM pg_attribute WHERE attidentity NOT IN
 
 -- table partitions
 CREATE TABLE itest_parted (f1 date NOT NULL, f2 text, f3 bigint generated always as identity) PARTITION BY RANGE (f1);
+
 -- partition inherits identity and shares the sequence
 CREATE TABLE itest_p1 PARTITION OF itest_parted FOR VALUES FROM ('2016-07-01') TO ('2016-08-01');
 SELECT attrelid::regclass, attname, attidentity, atthasdef, attgenerated, attnotnull
     FROM pg_attribute
-    WHERE attrelid IN ('itest_parted'::regclass, 'itest_p1'::regclass)
-        AND attnum > 0;
+    WHERE attrelid IN (SELECT oid FROM pg_class WHERE relname like 'itest_p%'
+                                                    and relkind in ('r', 'p'))
+        AND attnum > 0
+    ORDER BY attrelid, attnum;
 SELECT conrelid::regclass, conname, connoinherit, conislocal, coninhcount
     FROM pg_constraint
-    WHERE conrelid in ('itest_parted'::regclass, 'itest_p1'::regclass);
-SELECT *
+    WHERE conrelid in (SELECT oid FROM pg_class WHERE relname like 'itest_p%'
+                                                    and relkind in ('r', 'p'))
+    ORDER BY conrelid, conname;
+SELECT classid, objid_name, objsubid, refclassid, refobjid_name, refobjsubid, deptype
     FROM v_pg_depend
-    WHERE refobjid in ('itest_parted'::regclass, 'itest_p1'::regclass)
-            OR objid in ('itest_parted'::regclass, 'itest_p1'::regclass);
+    WHERE (refobjid in (SELECT oid FROM pg_class WHERE relname like 'itest_p%'
+                                                    and relkind in ('r', 'p'))
+            OR objid in (SELECT oid FROM pg_class WHERE relname like 'itest_p%'
+                                                    and relkind in ('r', 'p')))
+            AND objid_name NOT LIKE 'pg_toast%'
+    ORDER BY classid, objid_name, objsubid, refclassid, refobjid_name, refobjsubid, deptype;
 INSERT into itest_parted(f1, f2) VALUES ('2016-07-2', 'from itest_parted');
 INSERT into itest_p1 (f1, f2) VALUES ('2016-07-3', 'from itest_p1');
 SELECT tableoid::regclass, f1, f2, f3 FROM itest_parted;
+
+-- attached partition inherits identity and shares the sequence.
+-- existing values in the table should not be affected
+CREATE TABLE itest_p2 (f1 date NOT NULL, f2 text, f3 bigint);
+-- TODO: ideally setting an identity column should automatically spawn the NOT NULL constraint. But it doesn't do that right now.
+ALTER TABLE itest_p2 ALTER COLUMN f3 SET NOT NULL;
+INSERT INTO itest_p2 VALUES ('2016-08-2', 'before attaching', 100);
+ALTER TABLE itest_parted ATTACH PARTITION itest_p2 FOR VALUES FROM ('2016-08-01') TO ('2016-09-01');
+SELECT attrelid::regclass, attname, attidentity, atthasdef, attgenerated, attnotnull
+    FROM pg_attribute
+    WHERE attrelid IN (SELECT oid FROM pg_class WHERE relname like 'itest_p%'
+                                                    and relkind in ('r', 'p'))
+        AND attnum > 0
+    ORDER BY attrelid, attnum;
+SELECT conrelid::regclass, conname, connoinherit, conislocal, coninhcount
+    FROM pg_constraint
+    WHERE conrelid in (SELECT oid FROM pg_class WHERE relname like 'itest_p%'
+                                                    and relkind in ('r', 'p'))
+    ORDER BY conrelid, conname;
+SELECT classid, objid_name, objsubid, refclassid, refobjid_name, refobjsubid, deptype
+    FROM v_pg_depend
+    WHERE (refobjid in (SELECT oid FROM pg_class WHERE relname like 'itest_p%'
+                                                    and relkind in ('r', 'p'))
+            OR objid in (SELECT oid FROM pg_class WHERE relname like 'itest_p%'
+                                                    and relkind in ('r', 'p')))
+            AND objid_name NOT LIKE 'pg_toast%'
+    ORDER BY classid, objid_name, objsubid, refclassid, refobjid_name, refobjsubid, deptype;
+INSERT INTO itest_p2 (f1, f2) VALUES ('2016-08-3', 'from itest_p2');
+INSERT INTO itest_parted (f1, f2) VALUES ('2016-08-4', 'from itest_parted');
+SELECT tableoid::regclass, f1, f2, f3 FROM itest_parted;
+
 DROP TABLE itest_parted;
 
 -- scenarios to test
 
--- changing NOT NULL attribute of inherited identity column of partition is not allowed
+-- adding an identity column to a partitioned table adds it to all the partitions, including the ones added after this operation - 7th Dec
 
--- trying to change default value of inherited identity column of partition is not allowed
+-- changing a normal column to identity column is reflected in all the partitions - 8th Dec
 
--- trying to add identity to an inherited identity column of partition is not allowed
+-- detaching a partition removes identity property - 11th Dec
 
--- trying to drop inherited identity column of partition is not allowed
+-- attaching table with identity column is not allowed (even when the parent does not have an identity column) - 12th Dec
 
--- trying to change the identity properties of partition? Is that allowed?
+-- trying to drop inherited identity of column of partition is not allowed - 13th Dec
+-- trying to change the identity properties of partition? Is that allowed? - 13th Dec
 
--- TODO: test OVERRIDING SYSTEM VALUE OR OVERRIDING USER VALUE
+-- changing NOT NULL attribute of inherited identity column of partition is not allowed
 
--- attaching table with identity column is not allowed
+-- trying to change default value of inherited identity column of partition is not allowed
 
--- attaching a table as partition inherits identity property
+-- trying to add identity to an inherited identity column of partition is not allowed
 
--- detaching a partition removes identity property
+-- TODO: test OVERRIDING SYSTEM VALUE OR OVERRIDING USER VALUE
 
--- attaching a table with identity column is not allowed even when the parent table does not have an identity column
 
 -- dropping an identity column of parent drops it from all the partitions
 -- TODO: do we need a test for this?
 
--- adding an identity column to a partitioned table adds it to all the partitions, including the ones added after this operation
-
--- changing a normal column to identity column is reflected in all the partitions
-
 -- TODO: can we change an identity column to a normal column?
 
 -- Dump and restore tests - that would be a separate file
 
 -- pg_upgrade tests
 
--- multi-level partition test
+-- multi-level partition tests
+
+-- tests with other flavours of identity column
+
+-- tests when the identity column is partition key
 
 -- \d tests
 
-- 
2.25.1

