From 454764614153696e9286f0b5726f51c69fa3d505 Mon Sep 17 00:00:00 2001
From: Shlok Kyal <shlok.kyal.oss@gmail.com>
Date: Mon, 20 May 2024 12:31:16 +0530
Subject: [PATCH v5 2/3] Support COPY command for generated columns

Currently COPY command do not copy generated column. With this commit
added support for COPY for generated column.
---
 src/backend/commands/copy.c             | 13 -------
 src/test/regress/expected/generated.out | 50 ++++++++++++++-----------
 src/test/regress/sql/generated.sql      | 20 +++++++++-
 3 files changed, 46 insertions(+), 37 deletions(-)

diff --git a/src/backend/commands/copy.c b/src/backend/commands/copy.c
index df7a4a21c9..de8f40a1af 100644
--- a/src/backend/commands/copy.c
+++ b/src/backend/commands/copy.c
@@ -847,11 +847,6 @@ ProcessCopyOptions(ParseState *pstate,
  * or NIL if there was none (in which case we want all the non-dropped
  * columns).
  *
- * We don't include generated columns in the generated full list and we don't
- * allow them to be specified explicitly.  They don't make sense for COPY
- * FROM, but we could possibly allow them for COPY TO.  But this way it's at
- * least ensured that whatever we copy out can be copied back in.
- *
  * rel can be NULL ... it's only used for error reports.
  */
 List *
@@ -869,8 +864,6 @@ CopyGetAttnums(TupleDesc tupDesc, Relation rel, List *attnamelist)
 		{
 			if (TupleDescAttr(tupDesc, i)->attisdropped)
 				continue;
-			if (TupleDescAttr(tupDesc, i)->attgenerated)
-				continue;
 			attnums = lappend_int(attnums, i + 1);
 		}
 	}
@@ -895,12 +888,6 @@ CopyGetAttnums(TupleDesc tupDesc, Relation rel, List *attnamelist)
 					continue;
 				if (namestrcmp(&(att->attname), name) == 0)
 				{
-					if (att->attgenerated)
-						ereport(ERROR,
-								(errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
-								 errmsg("column \"%s\" is a generated column",
-										name),
-								 errdetail("Generated columns cannot be used in COPY.")));
 					attnum = att->attnum;
 					break;
 				}
diff --git a/src/test/regress/expected/generated.out b/src/test/regress/expected/generated.out
index 44058db7c1..2da799104b 100644
--- a/src/test/regress/expected/generated.out
+++ b/src/test/regress/expected/generated.out
@@ -423,36 +423,40 @@ SELECT * FROM gtest3a ORDER BY a;
 TRUNCATE gtest1;
 INSERT INTO gtest1 (a) VALUES (1), (2);
 COPY gtest1 TO stdout;
-1
-2
+1	2
+2	4
 COPY gtest1 (a, b) TO stdout;
-ERROR:  column "b" is a generated column
-DETAIL:  Generated columns cannot be used in COPY.
+1	2
+2	4
 COPY gtest1 FROM stdin;
-COPY gtest1 (a, b) FROM stdin;
-ERROR:  column "b" is a generated column
-DETAIL:  Generated columns cannot be used in COPY.
+ERROR:  missing data for column "b"
+CONTEXT:  COPY gtest1, line 1: "3"
+COPY gtest1(a) FROM stdin;
+COPY gtest1 (a, b) FROM stdin DELIMITER ' ';
 SELECT * FROM gtest1 ORDER BY a;
- a | b 
----+---
- 1 | 2
- 2 | 4
- 3 | 6
- 4 | 8
-(4 rows)
+ a | b  
+---+----
+ 1 |  2
+ 2 |  4
+ 3 |  6
+ 4 |  8
+ 5 | 10
+ 6 | 12
+(6 rows)
 
 TRUNCATE gtest3;
 INSERT INTO gtest3 (a) VALUES (1), (2);
 COPY gtest3 TO stdout;
-1
-2
+1	3
+2	6
 COPY gtest3 (a, b) TO stdout;
-ERROR:  column "b" is a generated column
-DETAIL:  Generated columns cannot be used in COPY.
+1	3
+2	6
 COPY gtest3 FROM stdin;
-COPY gtest3 (a, b) FROM stdin;
-ERROR:  column "b" is a generated column
-DETAIL:  Generated columns cannot be used in COPY.
+ERROR:  missing data for column "b"
+CONTEXT:  COPY gtest3, line 1: "3"
+COPY gtest3(a) FROM stdin;
+COPY gtest3 (a, b) FROM stdin  DELIMITER ' ';
 SELECT * FROM gtest3 ORDER BY a;
  a | b  
 ---+----
@@ -460,7 +464,9 @@ SELECT * FROM gtest3 ORDER BY a;
  2 |  6
  3 |  9
  4 | 12
-(4 rows)
+ 5 | 15
+ 6 | 18
+(6 rows)
 
 -- null values
 CREATE TABLE gtest2 (a int PRIMARY KEY, b int GENERATED ALWAYS AS (NULL) STORED);
diff --git a/src/test/regress/sql/generated.sql b/src/test/regress/sql/generated.sql
index cb55d77821..b7ace62be9 100644
--- a/src/test/regress/sql/generated.sql
+++ b/src/test/regress/sql/generated.sql
@@ -197,7 +197,15 @@ COPY gtest1 FROM stdin;
 4
 \.
 
-COPY gtest1 (a, b) FROM stdin;
+COPY gtest1(a) FROM stdin;
+3
+4
+\.
+
+COPY gtest1 (a, b) FROM stdin DELIMITER ' ';
+5 1
+6 1
+\.
 
 SELECT * FROM gtest1 ORDER BY a;
 
@@ -213,7 +221,15 @@ COPY gtest3 FROM stdin;
 4
 \.
 
-COPY gtest3 (a, b) FROM stdin;
+COPY gtest3(a) FROM stdin;
+3
+4
+\.
+
+COPY gtest3 (a, b) FROM stdin  DELIMITER ' ';
+5 1
+6 1
+\.
 
 SELECT * FROM gtest3 ORDER BY a;
 
-- 
2.41.0.windows.3

