From ac897c483485d3858ada23ca49650a0f2742a50f Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Sun, 21 Mar 2021 18:42:40 -0400 Subject: [PATCH] Fix assorted silliness in ATExecSetCompression(). It's not okay to scribble directly on a syscache entry. Nor to continue accessing said entry after releasing it. Also get rid of not-used local variables. Per valgrind testing. --- src/backend/commands/tablecmds.c | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index 9b2800bf5e2..877c08814e0 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -15071,9 +15071,6 @@ ATExecSetCompression(AlteredTableInfo *tab, char *compression; char typstorage; Oid cmoid; - Datum values[Natts_pg_attribute]; - bool nulls[Natts_pg_attribute]; - bool replace[Natts_pg_attribute]; ObjectAddress address; Assert(IsA(newValue, String)); @@ -15081,7 +15078,8 @@ ATExecSetCompression(AlteredTableInfo *tab, attrel = table_open(AttributeRelationId, RowExclusiveLock); - tuple = SearchSysCacheAttName(RelationGetRelid(rel), column); + /* copy the cache entry so we can scribble on it below */ + tuple = SearchSysCacheCopyAttName(RelationGetRelid(rel), column); if (!HeapTupleIsValid(tuple)) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_COLUMN), @@ -15105,32 +15103,32 @@ ATExecSetCompression(AlteredTableInfo *tab, errmsg("column data type %s does not support compression", format_type_be(atttableform->atttypid)))); - /* initialize buffers for new tuple values */ - memset(values, 0, sizeof(values)); - memset(nulls, false, sizeof(nulls)); - memset(replace, false, sizeof(replace)); - /* get the attribute compression method. */ cmoid = GetAttributeCompression(atttableform, compression); + /* update pg_attribute entry */ atttableform->attcompression = cmoid; CatalogTupleUpdate(attrel, &tuple->t_self, tuple); InvokeObjectPostAlterHook(RelationRelationId, RelationGetRelid(rel), - atttableform->attnum); + attnum); - ReleaseSysCache(tuple); - - /* apply changes to the index column as well */ + /* + * Apply the change to indexes as well (only for simple index columns, + * matching behavior of index.c ConstructTupleDescriptor()). + */ SetIndexStorageProperties(rel, attrel, attnum, cmoid, '\0', lockmode); + + heap_freetuple(tuple); + table_close(attrel, RowExclusiveLock); /* make changes visible */ CommandCounterIncrement(); ObjectAddressSubSet(address, RelationRelationId, - RelationGetRelid(rel), atttableform->attnum); + RelationGetRelid(rel), attnum); return address; }