From: Justin Pryzby Date: Fri, 29 Jan 2021 21:37:46 -0600 Subject: [PATCH v21 2/7] Add default_toast_compression GUC --- src/backend/access/common/tupdesc.c | 3 +- .../access/compression/compressamapi.c | 54 +++++++++++++++++++ src/backend/bootstrap/bootstrap.c | 7 ++- src/backend/commands/tablecmds.c | 4 +- src/backend/utils/cache/syscache.c | 6 ++- src/backend/utils/misc/guc.c | 12 +++++ src/include/access/compressamapi.h | 13 ++++- 7 files changed, 92 insertions(+), 7 deletions(-) diff --git a/src/backend/access/common/tupdesc.c b/src/backend/access/common/tupdesc.c index ca26fab487..b56b689493 100644 --- a/src/backend/access/common/tupdesc.c +++ b/src/backend/access/common/tupdesc.c @@ -25,6 +25,7 @@ #include "catalog/pg_collation.h" #include "catalog/pg_type.h" #include "common/hashfn.h" +#include "commands/defrem.h" #include "miscadmin.h" #include "parser/parse_type.h" #include "utils/acl.h" @@ -668,7 +669,7 @@ TupleDescInitEntry(TupleDesc desc, att->attcollation = typeForm->typcollation; if (IsStorageCompressible(typeForm->typstorage)) - att->attcompression = DefaultCompressionOid; + att->attcompression = get_compression_am_oid(default_toast_compression, false); else att->attcompression = InvalidOid; diff --git a/src/backend/access/compression/compressamapi.c b/src/backend/access/compression/compressamapi.c index 663102c8d2..e8bfb23ec3 100644 --- a/src/backend/access/compression/compressamapi.c +++ b/src/backend/access/compression/compressamapi.c @@ -19,9 +19,12 @@ #include "access/htup_details.h" #include "access/reloptions.h" #include "access/table.h" +#include "commands/defrem.h" #include "utils/fmgroids.h" #include "utils/syscache.h" +char *default_toast_compression = DEFAULT_TOAST_COMPRESSION; // maybe needs pg_dump support ? + /* * CompressionOidToId - Convert compression Oid to built-in compression id. * @@ -59,3 +62,54 @@ CompressionIdToOid(CompressionId cmid) elog(ERROR, "Invalid compression method id %d", cmid); } } + +/* check_hook: validate new default_toast_compression */ +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 we aren't inside a transaction, or not connected to a database, we + * cannot do the catalog access necessary to verify the method. Must + * accept the value on faith. + */ + if (IsTransactionState() && MyDatabaseId != InvalidOid) + { + if (!OidIsValid(get_compression_am_oid(*newval, true))) + { + /* + * When source == PGC_S_TEST, don't throw a hard error for a + * nonexistent table access method, only a NOTICE. See comments in + * guc.h. + */ + if (source == PGC_S_TEST) + { + ereport(NOTICE, + (errcode(ERRCODE_UNDEFINED_OBJECT), + errmsg("compression access method \"%s\" does not exist", + *newval))); + } + else + { + GUC_check_errdetail("Compression access method \"%s\" does not exist.", + *newval); + return false; + } + } + } + + return true; +} diff --git a/src/backend/bootstrap/bootstrap.c b/src/backend/bootstrap/bootstrap.c index 9b451eaa71..1b885f873a 100644 --- a/src/backend/bootstrap/bootstrap.c +++ b/src/backend/bootstrap/bootstrap.c @@ -29,6 +29,7 @@ #include "catalog/pg_collation.h" #include "catalog/pg_type.h" #include "common/link-canary.h" +#include "commands/defrem.h" #include "libpq/pqsignal.h" #include "miscadmin.h" #include "nodes/makefuncs.h" @@ -732,8 +733,12 @@ DefineAttr(char *name, char *type, int attnum, int nullness) attrtypes[attnum]->attcacheoff = -1; attrtypes[attnum]->atttypmod = -1; attrtypes[attnum]->attislocal = true; + if (IsStorageCompressible(attrtypes[attnum]->attstorage)) - attrtypes[attnum]->attcompression = DefaultCompressionOid; + { + /* Cannot call get_compression_am_oid this early */ + attrtypes[attnum]->attcompression = PGLZ_COMPRESSION_AM_OID; + } else attrtypes[attnum]->attcompression = InvalidOid; diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index d7f4489c57..082db26bfa 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -11925,7 +11925,7 @@ ATExecAlterColumnType(AlteredTableInfo *tab, Relation rel, if (!IsStorageCompressible(tform->typstorage)) attTup->attcompression = InvalidOid; else if (!OidIsValid(attTup->attcompression)) - attTup->attcompression = DefaultCompressionOid; + attTup->attcompression = get_compression_am_oid(default_toast_compression, false); } else attTup->attcompression = InvalidOid; @@ -17760,7 +17760,7 @@ GetAttributeCompression(Form_pg_attribute att, char *compression) /* fallback to default compression if it's not specified */ if (compression == NULL) - return DefaultCompressionOid; + return get_compression_am_oid(default_toast_compression, false); return get_compression_am_oid(compression, false); } diff --git a/src/backend/utils/cache/syscache.c b/src/backend/utils/cache/syscache.c index e4dc4ee34e..74e42a3394 100644 --- a/src/backend/utils/cache/syscache.c +++ b/src/backend/utils/cache/syscache.c @@ -1127,8 +1127,10 @@ HeapTuple SearchSysCache1(int cacheId, Datum key1) { - Assert(cacheId >= 0 && cacheId < SysCacheSize && - PointerIsValid(SysCache[cacheId])); + Assert(cacheId >= 0); + Assert(cacheId < SysCacheSize); + // fprintf(stderr, "cache %d\n", cacheId); + Assert(PointerIsValid(SysCache[cacheId])); Assert(SysCache[cacheId]->cc_nkeys == 1); return SearchCatCache1(SysCache[cacheId], key1); diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c index eafdb1118e..70b26ea72a 100644 --- a/src/backend/utils/misc/guc.c +++ b/src/backend/utils/misc/guc.c @@ -30,6 +30,7 @@ #include #include "access/commit_ts.h" +#include "access/compressamapi.h" #include "access/gin.h" #include "access/rmgr.h" #include "access/tableam.h" @@ -3915,6 +3916,17 @@ 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, NULL + }, + { {"default_tablespace", PGC_USERSET, CLIENT_CONN_STATEMENT, gettext_noop("Sets the default tablespace to create tables and indexes in."), diff --git a/src/include/access/compressamapi.h b/src/include/access/compressamapi.h index 8226ae0596..be5b4da7b8 100644 --- a/src/include/access/compressamapi.h +++ b/src/include/access/compressamapi.h @@ -15,8 +15,12 @@ #include "postgres.h" +#include "access/xact.h" #include "catalog/pg_am_d.h" +#include "miscadmin.h" #include "nodes/nodes.h" +#include "utils/guc.h" +#include "nodes/pg_list.h" /* * Built-in compression method-id. The toast compression header will store @@ -29,8 +33,11 @@ typedef enum CompressionId LZ4_COMPRESSION_ID = 1 } CompressionId; +#define DEFAULT_TOAST_COMPRESSION "pglz" + +extern char *default_toast_compression; + /* Use default compression method if it is not specified. */ -#define DefaultCompressionOid PGLZ_COMPRESSION_AM_OID #define IsStorageCompressible(storage) ((storage) != TYPSTORAGE_PLAIN && \ (storage) != TYPSTORAGE_EXTERNAL) /* compression handler routines */ @@ -62,4 +69,8 @@ extern const CompressionAmRoutine lz4_compress_methods; extern CompressionId CompressionOidToId(Oid cmoid); extern Oid CompressionIdToOid(CompressionId cmid); +extern void assign_default_toast_compression(const char *newval, void **extra); +extern bool check_default_toast_compression(char **newval, void **extra, GucSource source); + + #endif /* COMPRESSAMAPI_H */ -- 2.17.0 --ytoMbUMiTKPMT3hY Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="v21-0003-alter-table-set-compression.patch"