From f9c8398bad190f85729c8bdece0fbd205e7b55db Mon Sep 17 00:00:00 2001
From: Justin Pryzby <pryzbyj@telsasoft.com>
Date: Fri, 19 Mar 2021 19:39:10 -0500
Subject: [PATCH 6/9] WIP: Change default_toast_compression GUC to an enum..

..since the final version of this patch doesn't require catalog access anymore
---
 src/backend/access/common/toast_compression.c | 49 +------------------
 src/backend/utils/misc/guc.c                  | 30 +++++++-----
 src/include/access/toast_compression.h        | 10 ++--
 src/test/regress/expected/compression.out     |  4 +-
 4 files changed, 28 insertions(+), 65 deletions(-)

diff --git a/src/backend/access/common/toast_compression.c b/src/backend/access/common/toast_compression.c
index a6f8b79a9e..edcd09f9e9 100644
--- a/src/backend/access/common/toast_compression.c
+++ b/src/backend/access/common/toast_compression.c
@@ -23,8 +23,8 @@
 #include "fmgr.h"
 #include "utils/builtins.h"
 
-/* Compile-time default */
-char	   *default_toast_compression = DEFAULT_TOAST_COMPRESSION;
+/* GUC */
+int	   default_toast_compression = TOAST_PGLZ_COMPRESSION_ID;
 
 /*
  * Compress a varlena using PGLZ.
@@ -266,48 +266,3 @@ toast_get_compression_id(struct varlena *attr)
 
 	return cmid;
 }
-
-/*
- * Validate a new value for the default_toast_compression GUC.
- */
-bool
-check_default_toast_compression(char **newval, void **extra, GucSource source)
-{
-	if (**newval == '\0')
-	{
-		GUC_check_errdetail("%s cannot be empty.",
-							"default_toast_compression");
-		return false;
-	}
-
-	if (strlen(*newval) >= NAMEDATALEN)
-	{
-		GUC_check_errdetail("%s is too long (maximum %d characters).",
-							"default_toast_compression", NAMEDATALEN - 1);
-		return false;
-	}
-
-	if (!CompressionMethodIsValid(CompressionNameToMethod(*newval)))
-	{
-		/*
-		 * When source == PGC_S_TEST, don't throw a hard error for a
-		 * nonexistent compression method, only a NOTICE. See comments in
-		 * guc.h.
-		 */
-		if (source == PGC_S_TEST)
-		{
-			ereport(NOTICE,
-					(errcode(ERRCODE_UNDEFINED_OBJECT),
-					 errmsg("compression method \"%s\" does not exist",
-							*newval)));
-		}
-		else
-		{
-			GUC_check_errdetail("Compression method \"%s\" does not exist.",
-								*newval);
-			return false;
-		}
-	}
-
-	return true;
-}
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index fb31c8b05c..0556f2e748 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
@@ -510,6 +510,14 @@ static struct config_enum_entry shared_memory_options[] = {
 	{NULL, 0, false}
 };
 
+static struct config_enum_entry default_toast_compression_options[] = {
+	{"pglz", TOAST_PGLZ_COMPRESSION_ID, false},
+#ifdef	USE_LZ4
+	{"lz4", TOAST_LZ4_COMPRESSION_ID, false},
+#endif
+	{NULL, 0, false}
+};
+
 /*
  * Options for enum values stored in other modules
  */
@@ -3953,17 +3961,6 @@ static struct config_string ConfigureNamesString[] =
 		check_default_table_access_method, NULL, NULL
 	},
 
-	{
-		{"default_toast_compression", PGC_USERSET, CLIENT_CONN_STATEMENT,
-			gettext_noop("Sets the default compression for new columns."),
-			NULL,
-			GUC_IS_NAME
-		},
-		&default_toast_compression,
-		DEFAULT_TOAST_COMPRESSION,
-		check_default_toast_compression, NULL, NULL
-	},
-
 	{
 		{"default_tablespace", PGC_USERSET, CLIENT_CONN_STATEMENT,
 			gettext_noop("Sets the default tablespace to create tables and indexes in."),
@@ -4605,6 +4602,17 @@ static struct config_enum ConfigureNamesEnum[] =
 		NULL, NULL, NULL
 	},
 
+	{
+		{"default_toast_compression", PGC_USERSET, CLIENT_CONN_STATEMENT,
+			gettext_noop("Sets the default compression for new columns."),
+			NULL,
+			GUC_IS_NAME
+		},
+		&default_toast_compression,
+		0, /* pglz */
+		default_toast_compression_options, NULL, NULL
+	},
+
 	{
 		{"default_transaction_isolation", PGC_USERSET, CLIENT_CONN_STATEMENT,
 			gettext_noop("Sets the transaction isolation level of each new transaction."),
diff --git a/src/include/access/toast_compression.h b/src/include/access/toast_compression.h
index 09af6e7810..88a46e264d 100644
--- a/src/include/access/toast_compression.h
+++ b/src/include/access/toast_compression.h
@@ -16,10 +16,7 @@
 #include "utils/guc.h"
 
 /* GUCs */
-extern char *default_toast_compression;
-
-/* default compression method if not specified. */
-#define DEFAULT_TOAST_COMPRESSION	"pglz"
+extern int default_toast_compression;
 
 /*
  * Built-in compression method-id.  The toast compression header will store
@@ -100,7 +97,10 @@ CompressionNameToMethod(char *compression)
 static inline char
 GetDefaultToastCompression(void)
 {
-	return CompressionNameToMethod(default_toast_compression);
+	/* See also guc.c */
+	char *const enumtoname[] = {"pglz", "lz4"};
+	Assert(default_toast_compression < lengthof(enumtoname));
+	return CompressionNameToMethod(enumtoname[default_toast_compression]);
 }
 
 /* pglz compression/decompression routines */
diff --git a/src/test/regress/expected/compression.out b/src/test/regress/expected/compression.out
index 501e0ead14..5cc76cdcd6 100644
--- a/src/test/regress/expected/compression.out
+++ b/src/test/regress/expected/compression.out
@@ -232,10 +232,10 @@ DETAIL:  pglz versus lz4
 -- test default_toast_compression GUC
 SET default_toast_compression = '';
 ERROR:  invalid value for parameter "default_toast_compression": ""
-DETAIL:  default_toast_compression cannot be empty.
+HINT:  Available values: pglz, lz4.
 SET default_toast_compression = 'I do not exist compression';
 ERROR:  invalid value for parameter "default_toast_compression": "I do not exist compression"
-DETAIL:  Compression method "I do not exist compression" does not exist.
+HINT:  Available values: pglz, lz4.
 SET default_toast_compression = 'lz4';
 DROP TABLE cmdata2;
 CREATE TABLE cmdata2 (f1 text);
-- 
2.17.0

