From 54edcec2d44cfac01e1c2d20cc413dac57496ca9 Mon Sep 17 00:00:00 2001
From: Dilip Kumar <dilipkumar@localhost.localdomain>
Date: Wed, 24 Mar 2021 14:02:06 +0530
Subject: [PATCH v2 2/2] Fix attcompression for index expression columns

For expression columns the attcompression was not set.  So this patch
set it to the default compression method for compressible types otherwise
to the invalid compression method.
---
 src/backend/catalog/index.c                 | 11 +++++++++++
 src/test/regress/expected/compression.out   | 13 +++++++++++++
 src/test/regress/expected/compression_1.out | 14 ++++++++++++++
 src/test/regress/sql/compression.sql        |  8 ++++++++
 4 files changed, 46 insertions(+)

diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 397d70d..b5a79ce 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -30,6 +30,7 @@
 #include "access/relscan.h"
 #include "access/sysattr.h"
 #include "access/tableam.h"
+#include "access/toast_compression.h"
 #include "access/transam.h"
 #include "access/visibilitymap.h"
 #include "access/xact.h"
@@ -379,6 +380,16 @@ ConstructTupleDescriptor(Relation heapRelation,
 			to->attalign = typeTup->typalign;
 			to->atttypmod = exprTypmod(indexkey);
 
+			/*
+			 * For expression column, if attribute type storage is compressible
+			 * then set the default compression method, otherwise invalid
+			 * compression method.
+			 */
+			if (IsStorageCompressible(typeTup->typstorage))
+				to->attcompression = GetDefaultToastCompression();
+			else
+				to->attcompression = InvalidCompressionMethod;
+
 			ReleaseSysCache(tuple);
 
 			/*
diff --git a/src/test/regress/expected/compression.out b/src/test/regress/expected/compression.out
index c2f2e0e..19707fb 100644
--- a/src/test/regress/expected/compression.out
+++ b/src/test/regress/expected/compression.out
@@ -313,6 +313,19 @@ SELECT pg_column_compression(f1) FROM cmdata;
  lz4
 (2 rows)
 
+-- test expression index
+DROP TABLE cmdata2;
+CREATE TABLE cmdata2 (f1 TEXT COMPRESSION pglz, f2 TEXT COMPRESSION lz4);
+CREATE UNIQUE INDEX idx1 ON cmdata2 ((f1 || f2));
+INSERT INTO cmdata2 VALUES((SELECT array_agg(md5(g::TEXT))::TEXT FROM
+generate_series(1, 50) g), VERSION());
+\d+ idx1
+                            Index "public.idx1"
+ Column | Type | Key? | Definition | Storage  | Compression | Stats target 
+--------+------+------+------------+----------+-------------+--------------
+ expr   | text | yes  | (f1 || f2) | extended | pglz        | 
+unique, btree, for table "public.cmdata2"
+
 -- check data is ok
 SELECT length(f1) FROM cmdata;
  length 
diff --git a/src/test/regress/expected/compression_1.out b/src/test/regress/expected/compression_1.out
index 6626f8e..84b933d 100644
--- a/src/test/regress/expected/compression_1.out
+++ b/src/test/regress/expected/compression_1.out
@@ -310,6 +310,20 @@ SELECT pg_column_compression(f1) FROM cmdata;
  pglz
 (2 rows)
 
+-- test expression index
+DROP TABLE cmdata2;
+CREATE TABLE cmdata2 (f1 TEXT COMPRESSION pglz, f2 TEXT COMPRESSION lz4);
+ERROR:  unsupported LZ4 compression method
+DETAIL:  This functionality requires the server to be built with lz4 support.
+HINT:  You need to rebuild PostgreSQL using --with-lz4.
+CREATE UNIQUE INDEX idx1 ON cmdata2 ((f1 || f2));
+ERROR:  relation "cmdata2" does not exist
+INSERT INTO cmdata2 VALUES((SELECT array_agg(md5(g::TEXT))::TEXT FROM
+generate_series(1, 50) g), VERSION());
+ERROR:  relation "cmdata2" does not exist
+LINE 1: INSERT INTO cmdata2 VALUES((SELECT array_agg(md5(g::TEXT))::...
+                    ^
+\d+ idx1
 -- check data is ok
 SELECT length(f1) FROM cmdata;
  length 
diff --git a/src/test/regress/sql/compression.sql b/src/test/regress/sql/compression.sql
index 5e178be..4afd5a2 100644
--- a/src/test/regress/sql/compression.sql
+++ b/src/test/regress/sql/compression.sql
@@ -130,6 +130,14 @@ SELECT pg_column_compression(f1) FROM cmdata;
 VACUUM FULL cmdata;
 SELECT pg_column_compression(f1) FROM cmdata;
 
+-- test expression index
+DROP TABLE cmdata2;
+CREATE TABLE cmdata2 (f1 TEXT COMPRESSION pglz, f2 TEXT COMPRESSION lz4);
+CREATE UNIQUE INDEX idx1 ON cmdata2 ((f1 || f2));
+INSERT INTO cmdata2 VALUES((SELECT array_agg(md5(g::TEXT))::TEXT FROM
+generate_series(1, 50) g), VERSION());
+\d+ idx1
+
 -- check data is ok
 SELECT length(f1) FROM cmdata;
 SELECT length(f1) FROM cmdata1;
-- 
1.8.3.1

