From 2eb20665ee135eb269b9a5a27aa292485cd4026a Mon Sep 17 00:00:00 2001 From: wuyuechuan Date: Wed, 19 Jan 2022 17:30:39 +0800 Subject: [PATCH] create index: compressOpts should be used with compresstype compress_prealloc_chunks: must be less than BLCKSZ / chunksz --- src/common/backend/utils/cache/partcache.cpp | 46 +------------------ src/common/backend/utils/cache/relcache.cpp | 34 +++++++------- .../optimizer/commands/indexcmds.cpp | 12 +++++ .../optimizer/commands/tablecmds.cpp | 14 +----- .../storage/access/common/reloptions.cpp | 17 +++++++ src/include/access/reloptions.h | 17 +++++++ src/include/storage/page_compression.h | 16 ------- src/include/utils/rel.h | 2 +- .../expected/row_compression/normal_test.out | 6 ++- .../sql/row_compression/normal_test.sql | 4 +- 10 files changed, 76 insertions(+), 92 deletions(-) diff --git a/src/common/backend/utils/cache/partcache.cpp b/src/common/backend/utils/cache/partcache.cpp index 52520f606..42f431fee 100644 --- a/src/common/backend/utils/cache/partcache.cpp +++ b/src/common/backend/utils/cache/partcache.cpp @@ -235,48 +235,6 @@ static Partition AllocatePartitionDesc(Form_pg_partition partp) return partition; } -void SetupPageCompressForPartition(RelFileNode* node, PageCompressOpts* compress_options, const char* relationName) -{ - uint1 algorithm = compress_options->compressType; - if (algorithm == COMPRESS_TYPE_NONE) { - node->opt = 0; - } else { - if (!SUPPORT_PAGE_COMPRESSION) { - ereport(ERROR, (errmsg("unsupported page compression on this platform"))); - } - - uint1 compressLevel; - bool symbol = false; - if (compress_options->compressLevel >= 0) { - symbol = true; - compressLevel = compress_options->compressLevel; - } else { - symbol = false; - compressLevel = -compress_options->compressLevel; - } - - bool success = false; - uint1 chunkSize = ConvertChunkSize(compress_options->compressChunkSize, &success); - if (!success) { - ereport(ERROR, (errmsg("invalid compress_chunk_size %d , must be one of %d, %d, %d or %d for %s", - compress_options->compressChunkSize, BLCKSZ / 16, BLCKSZ / 8, BLCKSZ / 4, BLCKSZ / 2, - relationName))); - - } - - uint1 preallocChunks; - if (compress_options->compressPreallocChunks >= BLCKSZ / compress_options->compressChunkSize) { - preallocChunks = (uint1)(BLCKSZ / compress_options->compressChunkSize - 1); - } else { - preallocChunks = (uint1)(compress_options->compressPreallocChunks); - } - Assert(preallocChunks <= MAX_PREALLOC_CHUNKS); - node->opt = 0; - SET_COMPRESS_OPTION((*node), compress_options->compressByteConvert, compress_options->compressDiffConvert, - preallocChunks, symbol, compressLevel, algorithm, chunkSize); - } -} - StorageType PartitionGetStorageType(Oid parentOid) { HeapTuple pg_class_tuple; @@ -432,7 +390,7 @@ static void PartitionInitPhysicalAddr(Partition partition) partition->pd_node.opt = 0; if (partition->rd_options) { - SetupPageCompressForPartition(&partition->pd_node, &((StdRdOptions*)(partition->rd_options))->compress, + SetupPageCompressForRelation(&partition->pd_node, &((StdRdOptions*)(partition->rd_options))->compress, PartitionGetPartitionName(partition)); } } @@ -575,7 +533,7 @@ Partition PartitionBuildLocalPartition(const char *relname, Oid partid, Oid part /* compressed option was set by PartitionInitPhysicalAddr if part->rd_options != NULL */ if (part->rd_options == NULL && reloptions) { StdRdOptions* options = (StdRdOptions*)default_reloptions(reloptions, false, RELOPT_KIND_HEAP); - SetupPageCompressForPartition(&part->pd_node, &options->compress, PartitionGetPartitionName(part)); + SetupPageCompressForRelation(&part->pd_node, &options->compress, PartitionGetPartitionName(part)); } } diff --git a/src/common/backend/utils/cache/relcache.cpp b/src/common/backend/utils/cache/relcache.cpp index 36ef07039..2dda00a34 100644 --- a/src/common/backend/utils/cache/relcache.cpp +++ b/src/common/backend/utils/cache/relcache.cpp @@ -1300,7 +1300,6 @@ static OpClassCacheEnt* LookupOpclassInfo(Oid operatorClassOid, StrategyNumber n static void RelationCacheInitFileRemoveInDir(const char* tblspcpath); static void unlink_initfile(const char* initfilename); static void SetBackendId(Relation relation); -static void SetupPageCompressForRelation(Relation relation, PageCompressOpts *compress_options); /* * ScanPgRelation * @@ -2500,7 +2499,7 @@ static void RelationInitPhysicalAddr(Relation relation) // setup page compression options relation->rd_node.opt = 0; if (relation->rd_options && REL_SUPPORT_COMPRESSED(relation)) { - SetupPageCompressForRelation(relation, &((StdRdOptions*)(relation->rd_options))->compress); + SetupPageCompressForRelation(&relation->rd_node, &((StdRdOptions*)(relation->rd_options))->compress, RelationGetRelationName(relation)); } } @@ -4390,7 +4389,7 @@ Relation RelationBuildLocalRelation(const char* relname, Oid relnamespace, Tuple /* compressed option was set by RelationInitPhysicalAddr if rel->rd_options != NULL */ if (rel->rd_options == NULL && reloptions && SUPPORT_COMPRESSED(relkind, rel->rd_rel->relam)) { StdRdOptions *options = (StdRdOptions *) default_reloptions(reloptions, false, RELOPT_KIND_HEAP); - SetupPageCompressForRelation(rel, &options->compress); + SetupPageCompressForRelation(&rel->rd_node, &options->compress, RelationGetRelationName(rel)); } @@ -7879,14 +7878,14 @@ char RelationGetRelReplident(Relation r) return relreplident; } -/* setup page compress options for relation */ -static void SetupPageCompressForRelation(Relation relation, PageCompressOpts* compress_options) +void SetupPageCompressForRelation(RelFileNode* node, PageCompressOpts* compress_options, const char* relationName) { - relation->rd_node.opt = 0; uint1 algorithm = compress_options->compressType; - if (algorithm != COMPRESS_TYPE_NONE) { + if (algorithm == COMPRESS_TYPE_NONE) { + node->opt = 0; + } else { if (!SUPPORT_PAGE_COMPRESSION) { - elog(ERROR, "unsupported page compression on this platform"); + ereport(ERROR, (errmsg("unsupported page compression on this platform"))); } uint1 compressLevel; @@ -7902,20 +7901,21 @@ static void SetupPageCompressForRelation(Relation relation, PageCompressOpts* co bool success = false; uint1 chunkSize = ConvertChunkSize(compress_options->compressChunkSize, &success); if (!success) { - elog(ERROR, "invalid compress_chunk_size %d , must be one of %d, %d, %d or %d for %s", - compress_options->compressChunkSize, BLCKSZ / 16, BLCKSZ / 8, BLCKSZ / 4, BLCKSZ / 2, - RelationGetRelationName(relation)); + ereport(ERROR, (errmsg("invalid compress_chunk_size %d , must be one of %d, %d, %d or %d for %s", + compress_options->compressChunkSize, BLCKSZ / 16, BLCKSZ / 8, BLCKSZ / 4, BLCKSZ / 2, + relationName))); } uint1 preallocChunks; if (compress_options->compressPreallocChunks >= BLCKSZ / compress_options->compressChunkSize) { - preallocChunks = (uint1)(BLCKSZ / compress_options->compressChunkSize - 1); + ereport(ERROR, (errmsg("invalid compress_prealloc_chunks %d , must be less than %d for %s", + compress_options->compressPreallocChunks, + BLCKSZ / compress_options->compressChunkSize, relationName))); } else { preallocChunks = (uint1)(compress_options->compressPreallocChunks); } - Assert(preallocChunks <= MAX_PREALLOC_CHUNKS); - SET_COMPRESS_OPTION(relation->rd_node, compress_options->compressByteConvert, - compress_options->compressDiffConvert, preallocChunks, - symbol, compressLevel, algorithm, chunkSize); + node->opt = 0; + SET_COMPRESS_OPTION((*node), compress_options->compressByteConvert, compress_options->compressDiffConvert, + preallocChunks, symbol, compressLevel, algorithm, chunkSize); } -} +} \ No newline at end of file diff --git a/src/gausskernel/optimizer/commands/indexcmds.cpp b/src/gausskernel/optimizer/commands/indexcmds.cpp index ee1232e30..e2ff87341 100644 --- a/src/gausskernel/optimizer/commands/indexcmds.cpp +++ b/src/gausskernel/optimizer/commands/indexcmds.cpp @@ -927,6 +927,18 @@ Oid DefineIndex(Oid relationId, IndexStmt* stmt, Oid indexRelationId, bool is_al } } + TableCreateSupport indexCreateSupport{false,false,false,false,false,false}; + ListCell* cell = NULL; + foreach (cell, stmt->options) { + DefElem* defElem = (DefElem*)lfirst(cell); + SetOneOfCompressOption(defElem->defname, &indexCreateSupport); + } + + if (!indexCreateSupport.compressType && HasCompressOption(&indexCreateSupport)) { + ereport(ERROR, (errcode(ERRCODE_INVALID_OPTION), + errmsg("compress_chunk_size/compress_prealloc_chunks/compress_level/compress_byte_convert/" + "compress_diff_convert should be used with compresstype."))); + } /* * Parse AM-specific options, convert to text array form, validate. */ diff --git a/src/gausskernel/optimizer/commands/tablecmds.cpp b/src/gausskernel/optimizer/commands/tablecmds.cpp index e75f97d44..21677d683 100644 --- a/src/gausskernel/optimizer/commands/tablecmds.cpp +++ b/src/gausskernel/optimizer/commands/tablecmds.cpp @@ -1114,18 +1114,8 @@ static List* AddDefaultOptionsIfNeed(List* options, const char relkind, CreateSt ereport(ERROR, (errcode(ERRCODE_INVALID_OPTION), errmsg("It is not allowed to assign version option for non-dfs table."))); - } else if (pg_strcasecmp(def->defname, "compresstype") == 0) { - tableCreateSupport.compressType = true; - } else if (pg_strcasecmp(def->defname, "compress_chunk_size") == 0) { - tableCreateSupport.compressChunkSize = true; - } else if (pg_strcasecmp(def->defname, "compress_prealloc_chunks") == 0) { - tableCreateSupport.compressPreAllocChunks = true; - } else if (pg_strcasecmp(def->defname, "compress_level") == 0) { - tableCreateSupport.compressLevel = true; - } else if (pg_strcasecmp(def->defname, "compress_byte_convert") == 0) { - tableCreateSupport.compressByteConvert = true; - } else if (pg_strcasecmp(def->defname, "compress_diff_convert") == 0) { - tableCreateSupport.compressDiffConvert = true; + } else { + SetOneOfCompressOption(def->defname, &tableCreateSupport); } if (pg_strcasecmp(def->defname, "orientation") == 0 && pg_strcasecmp(defGetString(def), ORIENTATION_ORC) == 0) { diff --git a/src/gausskernel/storage/access/common/reloptions.cpp b/src/gausskernel/storage/access/common/reloptions.cpp index c699f4753..3a76fb517 100644 --- a/src/gausskernel/storage/access/common/reloptions.cpp +++ b/src/gausskernel/storage/access/common/reloptions.cpp @@ -2897,3 +2897,20 @@ bool is_cstore_option(char relkind, Datum reloptions) pfree_ext(std_opt); return result; } + +void SetOneOfCompressOption(const char* defname, TableCreateSupport* tableCreateSupport) +{ + if (pg_strcasecmp(defname, "compresstype") == 0) { + tableCreateSupport->compressType = true; + } else if (pg_strcasecmp(defname, "compress_chunk_size") == 0) { + tableCreateSupport->compressChunkSize = true; + } else if (pg_strcasecmp(defname, "compress_prealloc_chunks") == 0) { + tableCreateSupport->compressPreAllocChunks = true; + } else if (pg_strcasecmp(defname, "compress_level") == 0) { + tableCreateSupport->compressLevel = true; + } else if (pg_strcasecmp(defname, "compress_byte_convert") == 0) { + tableCreateSupport->compressByteConvert = true; + } else if (pg_strcasecmp(defname, "compress_diff_convert") == 0) { + tableCreateSupport->compressDiffConvert = true; + } +} diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h index c1b31e00a..13e45d9e3 100644 --- a/src/include/access/reloptions.h +++ b/src/include/access/reloptions.h @@ -130,6 +130,22 @@ typedef struct { int offset; /* offset of field in result struct */ } relopt_parse_elt; +struct TableCreateSupport { + bool compressType; + bool compressLevel; + bool compressChunkSize; + bool compressPreAllocChunks; + bool compressByteConvert; + bool compressDiffConvert; +}; + +inline bool HasCompressOption(TableCreateSupport *tableCreateSupport) +{ + return tableCreateSupport->compressLevel || tableCreateSupport->compressChunkSize || + tableCreateSupport->compressPreAllocChunks || tableCreateSupport->compressByteConvert || + tableCreateSupport->compressDiffConvert; +} + /* * The following are the table append modes currently supported. * on: mark the table on-line scaleout mode, when it is set, later data write by append mode. @@ -284,5 +300,6 @@ extern void forbid_to_set_options_for_timeseries_tbl(List* options); extern List* RemoveRelOption(List* options, const char* optName, bool* removed); void RowTblCheckCompressionOption(List *options); void RowTblCheckHashBucketOption(List* options, StdRdOptions* std_opt); +void SetOneOfCompressOption(const char *defname, TableCreateSupport *tableCreateSupport); #endif /* RELOPTIONS_H */ diff --git a/src/include/storage/page_compression.h b/src/include/storage/page_compression.h index a906eff9e..d8d4c6e26 100644 --- a/src/include/storage/page_compression.h +++ b/src/include/storage/page_compression.h @@ -113,22 +113,6 @@ typedef struct HeapPageCompressData { char data[FLEXIBLE_ARRAY_MEMBER]; /* compressed page, except for the page header */ } HeapPageCompressData; -struct TableCreateSupport { - bool compressType; - bool compressLevel; - bool compressChunkSize; - bool compressPreAllocChunks; - bool compressByteConvert; - bool compressDiffConvert; -}; - -inline bool HasCompressOption(TableCreateSupport *tableCreateSupport) -{ - return tableCreateSupport->compressLevel || tableCreateSupport->compressChunkSize || - tableCreateSupport->compressPreAllocChunks || tableCreateSupport->compressByteConvert || - tableCreateSupport->compressDiffConvert; -} - const uint4 CHUNK_SIZE_LIST[4] = {BLCKSZ / 2, BLCKSZ / 4, BLCKSZ / 8, BLCKSZ / 16}; constexpr uint4 INDEX_OF_HALF_BLCKSZ = 0; constexpr uint4 INDEX_OF_QUARTER_BLCKSZ = 1; diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h index 391e2f700..d746ff858 100644 --- a/src/include/utils/rel.h +++ b/src/include/utils/rel.h @@ -804,6 +804,6 @@ extern void RelationDecrementReferenceCount(Oid relationId); extern void GetTdeInfoFromRel(Relation rel, TdeInfo *tde_info); extern char RelationGetRelReplident(Relation r); - +extern void SetupPageCompressForRelation(RelFileNode* node, PageCompressOpts* compressOpts, const char* name); #endif /* REL_H */ diff --git a/src/test/regress/expected/row_compression/normal_test.out b/src/test/regress/expected/row_compression/normal_test.out index b94cd61a3..24a096fac 100644 --- a/src/test/regress/expected/row_compression/normal_test.out +++ b/src/test/regress/expected/row_compression/normal_test.out @@ -152,8 +152,12 @@ alter index normal_test.tbl_partition_id_idx set (compress_chunk_size=2048); ERROR: change compress_chunk_size OPTION is not supported alter index normal_test.tbl_partition_id_idx set (compress_prealloc_chunks=2); ERROR: change partition compress_prealloc_chunks OPTION is not supported +create index rolcompress_index on normal_test.tbl_pc(id) with (compress_chunk_size=4096); +ERROR: compress_chunk_size/compress_prealloc_chunks/compress_level/compress_byte_convert/compress_diff_convert should be used with compresstype. +create table rolcompress_table_001(a int) with (compresstype=2, compress_prealloc_chunks=3); +ERROR: invalid compress_prealloc_chunks 3 , must be less than 2 for rolcompress_table_001 -- support -alter table normal_test.tbl_pc set (compress_prealloc_chunks=2); +alter table normal_test.tbl_pc set (compress_prealloc_chunks=1); drop schema normal_test cascade; NOTICE: drop cascades to 3 other objects DETAIL: drop cascades to table normal_test.tbl_pc diff --git a/src/test/regress/sql/row_compression/normal_test.sql b/src/test/regress/sql/row_compression/normal_test.sql index efdcbb1c4..057bf3f95 100644 --- a/src/test/regress/sql/row_compression/normal_test.sql +++ b/src/test/regress/sql/row_compression/normal_test.sql @@ -55,7 +55,9 @@ select relname, reloptions from pg_partition where parentid in (Select relfileno alter index normal_test.tbl_partition_id_idx set (compresstype=1); alter index normal_test.tbl_partition_id_idx set (compress_chunk_size=2048); alter index normal_test.tbl_partition_id_idx set (compress_prealloc_chunks=2); +create index rolcompress_index on normal_test.tbl_pc(id) with (compress_chunk_size=4096); +create table rolcompress_table_001(a int) with (compresstype=2, compress_prealloc_chunks=3); -- support -alter table normal_test.tbl_pc set (compress_prealloc_chunks=2); +alter table normal_test.tbl_pc set (compress_prealloc_chunks=1); drop schema normal_test cascade;