From a9f8a600071b4e3d89c58782b923fb8839f473e6 Mon Sep 17 00:00:00 2001 From: jeff-davis Date: Fri, 20 May 2022 08:35:00 -0700 Subject: [PATCH] Columnar: support relation options with ALTER TABLE. (#5935) Columnar: support relation options with ALTER TABLE. Use ALTER TABLE ... SET/RESET to specify relation options rather than alter_columnar_table_set() and alter_columnar_table_reset(). Not only is this more ergonomic, but it also allows better integration because it can be treated like DDL on a regular table. For instance, citus can use its own ProcessUtility_hook to distribute the new settings to the shards. DESCRIPTION: Columnar: support relation options with ALTER TABLE. --- src/backend/columnar/README.md | 25 +- src/backend/columnar/columnar_metadata.c | 150 +++++++ src/backend/columnar/columnar_tableam.c | 398 ++++++++---------- .../columnar/sql/columnar--11.0-2--11.1-1.sql | 2 + .../downgrades/columnar--11.1-1--11.0-2.sql | 2 + .../alter_columnar_table_reset/11.1-1.sql | 48 +++ .../alter_columnar_table_reset/latest.sql | 35 +- .../udfs/alter_columnar_table_set/11.1-1.sql | 48 +++ .../udfs/alter_columnar_table_set/latest.sql | 35 +- .../distributed/commands/alter_table.c | 2 +- .../distributed/commands/utility_hook.c | 44 +- .../distributed/operations/node_protocol.c | 12 +- src/backend/distributed/shared_library_init.c | 23 +- .../distributed/sql/citus--11.0-2--11.1-1.sql | 2 + .../sql/downgrades/citus--11.1-1--11.0-2.sql | 4 +- src/include/columnar/columnar.h | 1 + src/include/columnar/columnar_metadata.h | 2 + .../distributed/commands/utility_hook.h | 1 + src/include/pg_version_compat.h | 4 + src/test/regress/columnar_schedule | 1 + .../expected/columnar_citus_integration.out | 305 ++++---------- src/test/regress/expected/columnar_create.out | 7 +- src/test/regress/expected/columnar_empty.out | 21 +- .../expected/columnar_fallback_scan.out | 7 +- .../expected/columnar_first_row_number.out | 7 +- src/test/regress/expected/columnar_insert.out | 14 +- .../regress/expected/columnar_matview.out | 7 +- .../regress/expected/columnar_permissions.out | 34 ++ src/test/regress/expected/columnar_pg15.out | 60 +++ src/test/regress/expected/columnar_pg15_0.out | 6 + .../expected/columnar_tableoptions.out | 182 ++++---- src/test/regress/expected/columnar_vacuum.out | 34 +- src/test/regress/expected/columnar_zstd.out | 7 +- src/test/regress/expected/multi_extension.out | 4 +- .../multi_fix_partition_shard_index_names.out | 6 +- src/test/regress/expected/multi_multiuser.out | 11 +- src/test/regress/expected/pg12.out | 8 +- .../sql/columnar_citus_integration.sql | 112 ++--- src/test/regress/sql/columnar_create.sql | 2 +- src/test/regress/sql/columnar_empty.sql | 6 +- .../regress/sql/columnar_fallback_scan.sql | 2 +- .../regress/sql/columnar_first_row_number.sql | 2 +- src/test/regress/sql/columnar_insert.sql | 4 +- src/test/regress/sql/columnar_matview.sql | 2 +- src/test/regress/sql/columnar_permissions.sql | 14 +- src/test/regress/sql/columnar_pg15.sql | 34 ++ .../regress/sql/columnar_tableoptions.sql | 101 +++-- src/test/regress/sql/columnar_vacuum.sql | 14 +- src/test/regress/sql/columnar_zstd.sql | 2 +- src/test/regress/sql/multi_extension.sql | 4 +- src/test/regress/sql/multi_multiuser.sql | 6 +- src/test/regress/sql/pg12.sql | 8 +- 52 files changed, 1056 insertions(+), 816 deletions(-) create mode 100644 src/backend/columnar/sql/columnar--11.0-2--11.1-1.sql create mode 100644 src/backend/columnar/sql/downgrades/columnar--11.1-1--11.0-2.sql create mode 100644 src/backend/columnar/sql/udfs/alter_columnar_table_reset/11.1-1.sql create mode 100644 src/backend/columnar/sql/udfs/alter_columnar_table_set/11.1-1.sql create mode 100644 src/test/regress/expected/columnar_pg15.out create mode 100644 src/test/regress/expected/columnar_pg15_0.out create mode 100644 src/test/regress/sql/columnar_pg15.sql diff --git a/src/backend/columnar/README.md b/src/backend/columnar/README.md index 218c99df8..e8681e0f3 100644 --- a/src/backend/columnar/README.md +++ b/src/backend/columnar/README.md @@ -90,38 +90,25 @@ data. Set options using: ```sql -alter_columnar_table_set( - relid REGCLASS, - chunk_group_row_limit INT4 DEFAULT NULL, - stripe_row_limit INT4 DEFAULT NULL, - compression NAME DEFAULT NULL, - compression_level INT4) -``` - -For example: - -```sql -SELECT alter_columnar_table_set( - 'my_columnar_table', - compression => 'none', - stripe_row_limit => 10000); +ALTER TABLE my_columnar_table SET + (columnar.compression = none, columnar.stripe_row_limit = 10000); ``` The following options are available: -* **compression**: `[none|pglz|zstd|lz4|lz4hc]` - set the compression type +* **columnar.compression**: `[none|pglz|zstd|lz4|lz4hc]` - set the compression type for _newly-inserted_ data. Existing data will not be recompressed/decompressed. The default value is `zstd` (if support has been compiled in). -* **compression_level**: ```` - Sets compression level. Valid +* **columnar.compression_level**: ```` - Sets compression level. Valid settings are from 1 through 19. If the compression method does not support the level chosen, the closest level will be selected instead. -* **stripe_row_limit**: ```` - the maximum number of rows per +* **columnar.stripe_row_limit**: ```` - the maximum number of rows per stripe for _newly-inserted_ data. Existing stripes of data will not be changed and may have more rows than this maximum value. The default value is `150000`. -* **chunk_group_row_limit**: ```` - the maximum number of rows per +* **columnar.chunk_group_row_limit**: ```` - the maximum number of rows per chunk for _newly-inserted_ data. Existing chunks of data will not be changed and may have more rows than this maximum value. The default value is `10000`. diff --git a/src/backend/columnar/columnar_metadata.c b/src/backend/columnar/columnar_metadata.c index 8b9b9efc6..da6c4c326 100644 --- a/src/backend/columnar/columnar_metadata.c +++ b/src/backend/columnar/columnar_metadata.c @@ -59,6 +59,7 @@ #include "utils/rel.h" #include "utils/relfilenodemap.h" +#define COLUMNAR_RELOPTION_NAMESPACE "columnar" typedef struct { @@ -82,6 +83,7 @@ typedef enum RowNumberLookupMode FIND_GREATER } RowNumberLookupMode; +static void ParseColumnarRelOptions(List *reloptions, ColumnarOptions *options); static void InsertEmptyStripeMetadataRow(uint64 storageId, uint64 stripeId, uint32 columnCount, uint32 chunkGroupRowCount, uint64 firstRowNumber); @@ -218,6 +220,154 @@ InitColumnarOptions(Oid regclass) } +/* + * ParseColumnarRelOptions - update the given 'options' using the given list + * of DefElem. + */ +static void +ParseColumnarRelOptions(List *reloptions, ColumnarOptions *options) +{ + ListCell *lc = NULL; + + foreach(lc, reloptions) + { + DefElem *elem = castNode(DefElem, lfirst(lc)); + + if (elem->defnamespace == NULL || + strcmp(elem->defnamespace, COLUMNAR_RELOPTION_NAMESPACE) != 0) + { + ereport(ERROR, (errmsg("columnar options must have the prefix \"%s\"", + COLUMNAR_RELOPTION_NAMESPACE))); + } + + if (strcmp(elem->defname, "chunk_group_row_limit") == 0) + { + options->chunkRowCount = (elem->arg == NULL) ? + columnar_chunk_group_row_limit : defGetInt64(elem); + if (options->chunkRowCount < CHUNK_ROW_COUNT_MINIMUM || + options->chunkRowCount > CHUNK_ROW_COUNT_MAXIMUM) + { + ereport(ERROR, (errmsg("chunk group row count limit out of range"), + errhint("chunk group row count limit must be between " + UINT64_FORMAT " and " UINT64_FORMAT, + (uint64) CHUNK_ROW_COUNT_MINIMUM, + (uint64) CHUNK_ROW_COUNT_MAXIMUM))); + } + } + else if (strcmp(elem->defname, "stripe_row_limit") == 0) + { + options->stripeRowCount = (elem->arg == NULL) ? + columnar_stripe_row_limit : defGetInt64(elem); + + if (options->stripeRowCount < STRIPE_ROW_COUNT_MINIMUM || + options->stripeRowCount > STRIPE_ROW_COUNT_MAXIMUM) + { + ereport(ERROR, (errmsg("stripe row count limit out of range"), + errhint("stripe row count limit must be between " + UINT64_FORMAT " and " UINT64_FORMAT, + (uint64) STRIPE_ROW_COUNT_MINIMUM, + (uint64) STRIPE_ROW_COUNT_MAXIMUM))); + } + } + else if (strcmp(elem->defname, "compression") == 0) + { + options->compressionType = (elem->arg == NULL) ? + columnar_compression : ParseCompressionType( + defGetString(elem)); + + if (options->compressionType == COMPRESSION_TYPE_INVALID) + { + ereport(ERROR, (errmsg("unknown compression type for columnar table: %s", + quote_identifier(defGetString(elem))))); + } + } + else if (strcmp(elem->defname, "compression_level") == 0) + { + options->compressionLevel = (elem->arg == NULL) ? + columnar_compression_level : defGetInt64(elem); + + if (options->compressionLevel < COMPRESSION_LEVEL_MIN || + options->compressionLevel > COMPRESSION_LEVEL_MAX) + { + ereport(ERROR, (errmsg("compression level out of range"), + errhint("compression level must be between %d and %d", + COMPRESSION_LEVEL_MIN, + COMPRESSION_LEVEL_MAX))); + } + } + else + { + ereport(ERROR, (errmsg("unrecognized columnar storage parameter \"%s\"", + elem->defname))); + } + } +} + + +/* + * ExtractColumnarOptions - extract columnar options from inOptions, appending + * to inoutColumnarOptions. Return the remaining (non-columnar) options. + */ +List * +ExtractColumnarRelOptions(List *inOptions, List **inoutColumnarOptions) +{ + List *otherOptions = NIL; + + ListCell *lc = NULL; + foreach(lc, inOptions) + { + DefElem *elem = castNode(DefElem, lfirst(lc)); + + if (elem->defnamespace != NULL && + strcmp(elem->defnamespace, COLUMNAR_RELOPTION_NAMESPACE) == 0) + { + *inoutColumnarOptions = lappend(*inoutColumnarOptions, elem); + } + else + { + otherOptions = lappend(otherOptions, elem); + } + } + + /* validate options */ + ColumnarOptions dummy = { 0 }; + ParseColumnarRelOptions(*inoutColumnarOptions, &dummy); + + return otherOptions; +} + + +/* + * SetColumnarRelOptions - apply the list of DefElem options to the + * relation. If there are duplicates, the last one in the list takes effect. + */ +void +SetColumnarRelOptions(RangeVar *rv, List *reloptions) +{ + ColumnarOptions options = { 0 }; + + if (reloptions == NIL) + { + return; + } + + Relation rel = relation_openrv(rv, AccessShareLock); + Oid relid = RelationGetRelid(rel); + relation_close(rel, NoLock); + + /* get existing or default options */ + if (!ReadColumnarOptions(relid, &options)) + { + /* if extension doesn't exist, just return */ + return; + } + + ParseColumnarRelOptions(reloptions, &options); + + SetColumnarOptions(relid, &options); +} + + /* * SetColumnarOptions writes the passed table options as the authoritive options to the * table irregardless of the optiones already existing or not. This can be used to put a diff --git a/src/backend/columnar/columnar_tableam.c b/src/backend/columnar/columnar_tableam.c index a16210fb7..f830f3089 100644 --- a/src/backend/columnar/columnar_tableam.c +++ b/src/backend/columnar/columnar_tableam.c @@ -20,6 +20,7 @@ #include "access/xact.h" #include "catalog/catalog.h" #include "catalog/index.h" +#include "catalog/namespace.h" #include "catalog/objectaccess.h" #include "catalog/pg_am.h" #include "catalog/pg_publication.h" @@ -103,9 +104,6 @@ typedef struct IndexFetchColumnarData MemoryContext scanContext; } IndexFetchColumnarData; -/* available to other extensions using find_rendezvous_variable() */ -static ColumnarTableSetOptions_hook_type ColumnarTableSetOptions_hook = NULL; - static object_access_hook_type PrevObjectAccessHook = NULL; static ProcessUtility_hook_type PrevProcessUtilityHook = NULL; @@ -116,6 +114,8 @@ static void ColumnarTriggerCreateHook(Oid tgid); static void ColumnarTableAMObjectAccessHook(ObjectAccessType access, Oid classId, Oid objectId, int subId, void *arg); +static RangeVar * ColumnarProcessAlterTable(AlterTableStmt *alterTableStmt, + List **columnarOptions); static void ColumnarProcessUtility(PlannedStmt *pstmt, const char *queryString, #if PG_VERSION_NUM >= PG_VERSION_14 @@ -1902,11 +1902,6 @@ ColumnarSubXactCallback(SubXactEvent event, SubTransactionId mySubid, void columnar_tableam_init() { - ColumnarTableSetOptions_hook_type **ColumnarTableSetOptions_hook_ptr = - (ColumnarTableSetOptions_hook_type **) find_rendezvous_variable( - COLUMNAR_SETOPTIONS_HOOK_SYM); - *ColumnarTableSetOptions_hook_ptr = &ColumnarTableSetOptions_hook; - RegisterXactCallback(ColumnarXactCallback, NULL); RegisterSubXactCallback(ColumnarSubXactCallback, NULL); @@ -2080,6 +2075,71 @@ ColumnarTableAMObjectAccessHook(ObjectAccessType access, Oid classId, Oid object } +/* + * ColumnarProcessAlterTable - if modifying a columnar table, extract columnar + * options and return the table's RangeVar. + */ +static RangeVar * +ColumnarProcessAlterTable(AlterTableStmt *alterTableStmt, List **columnarOptions) +{ + RangeVar *columnarRangeVar = NULL; + Relation rel = relation_openrv_extended(alterTableStmt->relation, AccessShareLock, + alterTableStmt->missing_ok); + + if (rel == NULL) + { + return NULL; + } + + /* track separately in case of ALTER TABLE ... SET ACCESS METHOD */ + bool srcIsColumnar = rel->rd_tableam == GetColumnarTableAmRoutine(); + bool destIsColumnar = srcIsColumnar; + + ListCell *lc = NULL; + foreach(lc, alterTableStmt->cmds) + { + AlterTableCmd *alterTableCmd = castNode(AlterTableCmd, lfirst(lc)); + + if (alterTableCmd->subtype == AT_SetRelOptions || + alterTableCmd->subtype == AT_ResetRelOptions) + { + List *options = castNode(List, alterTableCmd->def); + + alterTableCmd->def = (Node *) ExtractColumnarRelOptions( + options, columnarOptions); + + if (destIsColumnar) + { + columnarRangeVar = alterTableStmt->relation; + } + } +#if PG_VERSION_NUM >= PG_VERSION_15 + else if (alterTableCmd->subtype == AT_SetAccessMethod) + { + if (columnarRangeVar || *columnarOptions) + { + ereport(ERROR, (errmsg( + "ALTER TABLE cannot alter the access method after altering storage parameters"), + errhint( + "Specify SET ACCESS METHOD before storage parameters, or use separate ALTER TABLE commands."))); + } + + destIsColumnar = (strcmp(alterTableCmd->name, COLUMNAR_AM_NAME) == 0); + + if (srcIsColumnar && !destIsColumnar) + { + DeleteColumnarTableOptions(RelationGetRelid(rel), true); + } + } +#endif /* PG_VERSION_15 */ + } + + relation_close(rel, NoLock); + + return columnarRangeVar; +} + + /* * Utility hook for columnar tables. */ @@ -2104,31 +2164,116 @@ ColumnarProcessUtility(PlannedStmt *pstmt, Node *parsetree = pstmt->utilityStmt; - if (IsA(parsetree, IndexStmt)) + RangeVar *columnarRangeVar = NULL; + List *columnarOptions = NIL; + + switch (nodeTag(parsetree)) { - IndexStmt *indexStmt = (IndexStmt *) parsetree; - - Relation rel = relation_openrv(indexStmt->relation, - indexStmt->concurrent ? ShareUpdateExclusiveLock : - ShareLock); - - if (rel->rd_tableam == GetColumnarTableAmRoutine()) + case T_IndexStmt: { - CheckCitusColumnarVersion(ERROR); - if (!ColumnarSupportsIndexAM(indexStmt->accessMethod)) + IndexStmt *indexStmt = (IndexStmt *) parsetree; + + Relation rel = relation_openrv(indexStmt->relation, + indexStmt->concurrent ? + ShareUpdateExclusiveLock : + ShareLock); + + if (rel->rd_tableam == GetColumnarTableAmRoutine()) { - ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("unsupported access method for the " - "index on columnar table %s", - RelationGetRelationName(rel)))); + CheckCitusColumnarVersion(ERROR); + if (!ColumnarSupportsIndexAM(indexStmt->accessMethod)) + { + ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("unsupported access method for the " + "index on columnar table %s", + RelationGetRelationName(rel)))); + } } + + RelationClose(rel); + break; } - RelationClose(rel); + case T_CreateStmt: + { + CreateStmt *createStmt = castNode(CreateStmt, parsetree); + bool no_op = false; + + if (createStmt->if_not_exists) + { + Oid existing_relid; + + /* use same check as transformCreateStmt */ + (void) RangeVarGetAndCheckCreationNamespace( + createStmt->relation, AccessShareLock, &existing_relid); + + no_op = OidIsValid(existing_relid); + } + + if (!no_op && createStmt->accessMethod != NULL && + !strcmp(createStmt->accessMethod, COLUMNAR_AM_NAME)) + { + columnarRangeVar = createStmt->relation; + createStmt->options = ExtractColumnarRelOptions(createStmt->options, + &columnarOptions); + } + break; + } + + case T_CreateTableAsStmt: + { + CreateTableAsStmt *createTableAsStmt = castNode(CreateTableAsStmt, parsetree); + IntoClause *into = createTableAsStmt->into; + bool no_op = false; + + if (createTableAsStmt->if_not_exists) + { + Oid existing_relid; + + /* use same check as transformCreateStmt */ + (void) RangeVarGetAndCheckCreationNamespace( + into->rel, AccessShareLock, &existing_relid); + + no_op = OidIsValid(existing_relid); + } + + if (!no_op && into->accessMethod != NULL && + !strcmp(into->accessMethod, COLUMNAR_AM_NAME)) + { + columnarRangeVar = into->rel; + into->options = ExtractColumnarRelOptions(into->options, + &columnarOptions); + } + break; + } + + case T_AlterTableStmt: + { + AlterTableStmt *alterTableStmt = castNode(AlterTableStmt, parsetree); + columnarRangeVar = ColumnarProcessAlterTable(alterTableStmt, + &columnarOptions); + break; + } + + default: + + /* FALL THROUGH */ + break; + } + + if (columnarOptions != NIL && columnarRangeVar == NULL) + { + ereport(ERROR, + (errmsg("columnar storage parameters specified on non-columnar table"))); } PrevProcessUtilityHook_compat(pstmt, queryString, false, context, params, queryEnv, dest, completionTag); + + if (columnarOptions != NIL) + { + SetColumnarRelOptions(columnarRangeVar, columnarOptions); + } } @@ -2325,219 +2470,36 @@ ColumnarCheckLogicalReplication(Relation rel) /* - * alter_columnar_table_set is a UDF exposed in postgres to change settings on a columnar - * table. Calling this function on a non-columnar table gives an error. + * alter_columnar_table_set() * - * sql syntax: - * pg_catalog.alter_columnar_table_set( - * table_name regclass, - * chunk_group_row_limit int DEFAULT NULL, - * stripe_row_limit int DEFAULT NULL, - * compression name DEFAULT null) + * Deprecated in 11.1-1: should issue ALTER TABLE ... SET instead. Function + * still available, but implemented in PL/pgSQL instead of C. * - * All arguments except the table name are optional. The UDF is supposed to be called - * like: - * SELECT alter_columnar_table_set('table', compression => 'pglz'); - * - * This will only update the compression of the table, keeping all other settings the - * same. Multiple settings can be changed at the same time by providing multiple - * arguments. Calling the argument with the NULL value will be interperted as not having - * provided the argument. + * C code is removed -- the symbol may still be required in some + * upgrade/downgrade paths, but it should not be called. */ PG_FUNCTION_INFO_V1(alter_columnar_table_set); Datum alter_columnar_table_set(PG_FUNCTION_ARGS) { - CheckCitusColumnarVersion(ERROR); - - Oid relationId = PG_GETARG_OID(0); - - Relation rel = table_open(relationId, AccessExclusiveLock); /* ALTER TABLE LOCK */ - if (!IsColumnarTableAmTable(relationId)) - { - ereport(ERROR, (errmsg("table %s is not a columnar table", - quote_identifier(RelationGetRelationName(rel))))); - } - - if (!pg_class_ownercheck(relationId, GetUserId())) - { - aclcheck_error(ACLCHECK_NOT_OWNER, OBJECT_TABLE, - get_rel_name(relationId)); - } - - ColumnarOptions options = { 0 }; - if (!ReadColumnarOptions(relationId, &options)) - { - ereport(ERROR, (errmsg("unable to read current options for table"))); - } - - /* chunk_group_row_limit => not null */ - if (!PG_ARGISNULL(1)) - { - options.chunkRowCount = PG_GETARG_INT32(1); - if (options.chunkRowCount < CHUNK_ROW_COUNT_MINIMUM || - options.chunkRowCount > CHUNK_ROW_COUNT_MAXIMUM) - { - ereport(ERROR, (errmsg("chunk group row count limit out of range"), - errhint("chunk group row count limit must be between " - UINT64_FORMAT " and " UINT64_FORMAT, - (uint64) CHUNK_ROW_COUNT_MINIMUM, - (uint64) CHUNK_ROW_COUNT_MAXIMUM))); - } - ereport(DEBUG1, - (errmsg("updating chunk row count to %d", options.chunkRowCount))); - } - - /* stripe_row_limit => not null */ - if (!PG_ARGISNULL(2)) - { - options.stripeRowCount = PG_GETARG_INT32(2); - if (options.stripeRowCount < STRIPE_ROW_COUNT_MINIMUM || - options.stripeRowCount > STRIPE_ROW_COUNT_MAXIMUM) - { - ereport(ERROR, (errmsg("stripe row count limit out of range"), - errhint("stripe row count limit must be between " - UINT64_FORMAT " and " UINT64_FORMAT, - (uint64) STRIPE_ROW_COUNT_MINIMUM, - (uint64) STRIPE_ROW_COUNT_MAXIMUM))); - } - ereport(DEBUG1, (errmsg( - "updating stripe row count to " UINT64_FORMAT, - options.stripeRowCount))); - } - - /* compression => not null */ - if (!PG_ARGISNULL(3)) - { - Name compressionName = PG_GETARG_NAME(3); - options.compressionType = ParseCompressionType(NameStr(*compressionName)); - if (options.compressionType == COMPRESSION_TYPE_INVALID) - { - ereport(ERROR, (errmsg("unknown compression type for columnar table: %s", - quote_identifier(NameStr(*compressionName))))); - } - ereport(DEBUG1, (errmsg("updating compression to %s", - CompressionTypeStr(options.compressionType)))); - } - - /* compression_level => not null */ - if (!PG_ARGISNULL(4)) - { - options.compressionLevel = PG_GETARG_INT32(4); - if (options.compressionLevel < COMPRESSION_LEVEL_MIN || - options.compressionLevel > COMPRESSION_LEVEL_MAX) - { - ereport(ERROR, (errmsg("compression level out of range"), - errhint("compression level must be between %d and %d", - COMPRESSION_LEVEL_MIN, - COMPRESSION_LEVEL_MAX))); - } - - ereport(DEBUG1, (errmsg("updating compression level to %d", - options.compressionLevel))); - } - - if (ColumnarTableSetOptions_hook != NULL) - { - ColumnarTableSetOptions_hook(relationId, options); - } - - SetColumnarOptions(relationId, &options); - - table_close(rel, NoLock); - - PG_RETURN_VOID(); + elog(ERROR, "alter_columnar_table_set is deprecated"); } /* - * alter_columnar_table_reset is a UDF exposed in postgres to reset the settings on a - * columnar table. Calling this function on a non-columnar table gives an error. + * alter_columnar_table_reset() * - * sql syntax: - * pg_catalog.alter_columnar_table_re - * teset( - * table_name regclass, - * chunk_group_row_limit bool DEFAULT FALSE, - * stripe_row_limit bool DEFAULT FALSE, - * compression bool DEFAULT FALSE) + * Deprecated in 11.1-1: should issue ALTER TABLE ... RESET instead. Function + * still available, but implemented in PL/pgSQL instead of C. * - * All arguments except the table name are optional. The UDF is supposed to be called - * like: - * SELECT alter_columnar_table_set('table', compression => true); - * - * All options set to true will be reset to the default system value. + * C code is removed -- the symbol may still be required in some + * upgrade/downgrade paths, but it should not be called. */ PG_FUNCTION_INFO_V1(alter_columnar_table_reset); Datum alter_columnar_table_reset(PG_FUNCTION_ARGS) { - CheckCitusColumnarVersion(ERROR); - - Oid relationId = PG_GETARG_OID(0); - - Relation rel = table_open(relationId, AccessExclusiveLock); /* ALTER TABLE LOCK */ - if (!IsColumnarTableAmTable(relationId)) - { - ereport(ERROR, (errmsg("table %s is not a columnar table", - quote_identifier(RelationGetRelationName(rel))))); - } - - if (!pg_class_ownercheck(relationId, GetUserId())) - { - aclcheck_error(ACLCHECK_NOT_OWNER, OBJECT_TABLE, - get_rel_name(relationId)); - } - - ColumnarOptions options = { 0 }; - if (!ReadColumnarOptions(relationId, &options)) - { - ereport(ERROR, (errmsg("unable to read current options for table"))); - } - - /* chunk_group_row_limit => true */ - if (!PG_ARGISNULL(1) && PG_GETARG_BOOL(1)) - { - options.chunkRowCount = columnar_chunk_group_row_limit; - ereport(DEBUG1, - (errmsg("resetting chunk row count to %d", options.chunkRowCount))); - } - - /* stripe_row_limit => true */ - if (!PG_ARGISNULL(2) && PG_GETARG_BOOL(2)) - { - options.stripeRowCount = columnar_stripe_row_limit; - ereport(DEBUG1, - (errmsg("resetting stripe row count to " UINT64_FORMAT, - options.stripeRowCount))); - } - - /* compression => true */ - if (!PG_ARGISNULL(3) && PG_GETARG_BOOL(3)) - { - options.compressionType = columnar_compression; - ereport(DEBUG1, (errmsg("resetting compression to %s", - CompressionTypeStr(options.compressionType)))); - } - - /* compression_level => true */ - if (!PG_ARGISNULL(4) && PG_GETARG_BOOL(4)) - { - options.compressionLevel = columnar_compression_level; - ereport(DEBUG1, (errmsg("reseting compression level to %d", - columnar_compression_level))); - } - - if (ColumnarTableSetOptions_hook != NULL) - { - ColumnarTableSetOptions_hook(relationId, options); - } - - SetColumnarOptions(relationId, &options); - - table_close(rel, NoLock); - - PG_RETURN_VOID(); + elog(ERROR, "alter_columnar_table_reset is deprecated"); } diff --git a/src/backend/columnar/sql/columnar--11.0-2--11.1-1.sql b/src/backend/columnar/sql/columnar--11.0-2--11.1-1.sql new file mode 100644 index 000000000..69a5dc9a7 --- /dev/null +++ b/src/backend/columnar/sql/columnar--11.0-2--11.1-1.sql @@ -0,0 +1,2 @@ +#include "udfs/alter_columnar_table_set/11.1-1.sql" +#include "udfs/alter_columnar_table_reset/11.1-1.sql" diff --git a/src/backend/columnar/sql/downgrades/columnar--11.1-1--11.0-2.sql b/src/backend/columnar/sql/downgrades/columnar--11.1-1--11.0-2.sql new file mode 100644 index 000000000..3c233c796 --- /dev/null +++ b/src/backend/columnar/sql/downgrades/columnar--11.1-1--11.0-2.sql @@ -0,0 +1,2 @@ +#include "../udfs/alter_columnar_table_set/10.0-1.sql" +#include "../udfs/alter_columnar_table_reset/10.0-1.sql" diff --git a/src/backend/columnar/sql/udfs/alter_columnar_table_reset/11.1-1.sql b/src/backend/columnar/sql/udfs/alter_columnar_table_reset/11.1-1.sql new file mode 100644 index 000000000..7c636dd6e --- /dev/null +++ b/src/backend/columnar/sql/udfs/alter_columnar_table_reset/11.1-1.sql @@ -0,0 +1,48 @@ +CREATE OR REPLACE FUNCTION pg_catalog.alter_columnar_table_reset( + table_name regclass, + chunk_group_row_limit bool DEFAULT false, + stripe_row_limit bool DEFAULT false, + compression bool DEFAULT false, + compression_level bool DEFAULT false) + RETURNS void + LANGUAGE plpgsql AS +$alter_columnar_table_reset$ +declare + noop BOOLEAN := true; + cmd TEXT := 'ALTER TABLE ' || table_name::text || ' RESET ('; +begin + if (chunk_group_row_limit) then + if (not noop) then cmd := cmd || ', '; end if; + cmd := cmd || 'columnar.chunk_group_row_limit'; + noop := false; + end if; + if (stripe_row_limit) then + if (not noop) then cmd := cmd || ', '; end if; + cmd := cmd || 'columnar.stripe_row_limit'; + noop := false; + end if; + if (compression) then + if (not noop) then cmd := cmd || ', '; end if; + cmd := cmd || 'columnar.compression'; + noop := false; + end if; + if (compression_level) then + if (not noop) then cmd := cmd || ', '; end if; + cmd := cmd || 'columnar.compression_level'; + noop := false; + end if; + cmd := cmd || ')'; + if (not noop) then + execute cmd; + end if; + return; +end; +$alter_columnar_table_reset$; + +COMMENT ON FUNCTION pg_catalog.alter_columnar_table_reset( + table_name regclass, + chunk_group_row_limit bool, + stripe_row_limit bool, + compression bool, + compression_level bool) +IS 'reset on or more options on a columnar table to the system defaults'; diff --git a/src/backend/columnar/sql/udfs/alter_columnar_table_reset/latest.sql b/src/backend/columnar/sql/udfs/alter_columnar_table_reset/latest.sql index bfee6feb4..7c636dd6e 100644 --- a/src/backend/columnar/sql/udfs/alter_columnar_table_reset/latest.sql +++ b/src/backend/columnar/sql/udfs/alter_columnar_table_reset/latest.sql @@ -5,8 +5,39 @@ CREATE OR REPLACE FUNCTION pg_catalog.alter_columnar_table_reset( compression bool DEFAULT false, compression_level bool DEFAULT false) RETURNS void - LANGUAGE C -AS 'MODULE_PATHNAME', 'alter_columnar_table_reset'; + LANGUAGE plpgsql AS +$alter_columnar_table_reset$ +declare + noop BOOLEAN := true; + cmd TEXT := 'ALTER TABLE ' || table_name::text || ' RESET ('; +begin + if (chunk_group_row_limit) then + if (not noop) then cmd := cmd || ', '; end if; + cmd := cmd || 'columnar.chunk_group_row_limit'; + noop := false; + end if; + if (stripe_row_limit) then + if (not noop) then cmd := cmd || ', '; end if; + cmd := cmd || 'columnar.stripe_row_limit'; + noop := false; + end if; + if (compression) then + if (not noop) then cmd := cmd || ', '; end if; + cmd := cmd || 'columnar.compression'; + noop := false; + end if; + if (compression_level) then + if (not noop) then cmd := cmd || ', '; end if; + cmd := cmd || 'columnar.compression_level'; + noop := false; + end if; + cmd := cmd || ')'; + if (not noop) then + execute cmd; + end if; + return; +end; +$alter_columnar_table_reset$; COMMENT ON FUNCTION pg_catalog.alter_columnar_table_reset( table_name regclass, diff --git a/src/backend/columnar/sql/udfs/alter_columnar_table_set/11.1-1.sql b/src/backend/columnar/sql/udfs/alter_columnar_table_set/11.1-1.sql new file mode 100644 index 000000000..9e9fe1be4 --- /dev/null +++ b/src/backend/columnar/sql/udfs/alter_columnar_table_set/11.1-1.sql @@ -0,0 +1,48 @@ +CREATE OR REPLACE FUNCTION pg_catalog.alter_columnar_table_set( + table_name regclass, + chunk_group_row_limit int DEFAULT NULL, + stripe_row_limit int DEFAULT NULL, + compression name DEFAULT null, + compression_level int DEFAULT NULL) + RETURNS void + LANGUAGE plpgsql AS +$alter_columnar_table_set$ +declare + noop BOOLEAN := true; + cmd TEXT := 'ALTER TABLE ' || table_name::text || ' SET ('; +begin + if (chunk_group_row_limit is not null) then + if (not noop) then cmd := cmd || ', '; end if; + cmd := cmd || 'columnar.chunk_group_row_limit=' || chunk_group_row_limit; + noop := false; + end if; + if (stripe_row_limit is not null) then + if (not noop) then cmd := cmd || ', '; end if; + cmd := cmd || 'columnar.stripe_row_limit=' || stripe_row_limit; + noop := false; + end if; + if (compression is not null) then + if (not noop) then cmd := cmd || ', '; end if; + cmd := cmd || 'columnar.compression=' || compression; + noop := false; + end if; + if (compression_level is not null) then + if (not noop) then cmd := cmd || ', '; end if; + cmd := cmd || 'columnar.compression_level=' || compression_level; + noop := false; + end if; + cmd := cmd || ')'; + if (not noop) then + execute cmd; + end if; + return; +end; +$alter_columnar_table_set$; + +COMMENT ON FUNCTION pg_catalog.alter_columnar_table_set( + table_name regclass, + chunk_group_row_limit int, + stripe_row_limit int, + compression name, + compression_level int) +IS 'set one or more options on a columnar table, when set to NULL no change is made'; diff --git a/src/backend/columnar/sql/udfs/alter_columnar_table_set/latest.sql b/src/backend/columnar/sql/udfs/alter_columnar_table_set/latest.sql index 39ddfb9dd..9e9fe1be4 100644 --- a/src/backend/columnar/sql/udfs/alter_columnar_table_set/latest.sql +++ b/src/backend/columnar/sql/udfs/alter_columnar_table_set/latest.sql @@ -5,8 +5,39 @@ CREATE OR REPLACE FUNCTION pg_catalog.alter_columnar_table_set( compression name DEFAULT null, compression_level int DEFAULT NULL) RETURNS void - LANGUAGE C -AS 'MODULE_PATHNAME', 'alter_columnar_table_set'; + LANGUAGE plpgsql AS +$alter_columnar_table_set$ +declare + noop BOOLEAN := true; + cmd TEXT := 'ALTER TABLE ' || table_name::text || ' SET ('; +begin + if (chunk_group_row_limit is not null) then + if (not noop) then cmd := cmd || ', '; end if; + cmd := cmd || 'columnar.chunk_group_row_limit=' || chunk_group_row_limit; + noop := false; + end if; + if (stripe_row_limit is not null) then + if (not noop) then cmd := cmd || ', '; end if; + cmd := cmd || 'columnar.stripe_row_limit=' || stripe_row_limit; + noop := false; + end if; + if (compression is not null) then + if (not noop) then cmd := cmd || ', '; end if; + cmd := cmd || 'columnar.compression=' || compression; + noop := false; + end if; + if (compression_level is not null) then + if (not noop) then cmd := cmd || ', '; end if; + cmd := cmd || 'columnar.compression_level=' || compression_level; + noop := false; + end if; + cmd := cmd || ')'; + if (not noop) then + execute cmd; + end if; + return; +end; +$alter_columnar_table_set$; COMMENT ON FUNCTION pg_catalog.alter_columnar_table_set( table_name regclass, diff --git a/src/backend/distributed/commands/alter_table.c b/src/backend/distributed/commands/alter_table.c index cd3abe0dc..fe3f7d0a3 100644 --- a/src/backend/distributed/commands/alter_table.c +++ b/src/backend/distributed/commands/alter_table.c @@ -711,7 +711,7 @@ ConvertTable(TableConversionState *con) char *columnarOptionsSql = GetShardedTableDDLCommandColumnar(con->hashOfName, context); - ExecuteQueryViaSPI(columnarOptionsSql, SPI_OK_SELECT); + ExecuteQueryViaSPI(columnarOptionsSql, SPI_OK_UTILITY); } con->newRelationId = get_relname_relid(con->tempName, con->schemaId); diff --git a/src/backend/distributed/commands/utility_hook.c b/src/backend/distributed/commands/utility_hook.c index 23fe4076c..e2770a32e 100644 --- a/src/backend/distributed/commands/utility_hook.c +++ b/src/backend/distributed/commands/utility_hook.c @@ -85,6 +85,7 @@ static int activeDropSchemaOrDBs = 0; static bool ConstraintDropped = false; +ProcessUtility_hook_type PrevProcessUtility = NULL; int UtilityHookLevel = 0; @@ -179,8 +180,8 @@ multi_ProcessUtility(PlannedStmt *pstmt, * that state. Since we never need to intercept transaction statements, * skip our checks and immediately fall into standard_ProcessUtility. */ - standard_ProcessUtility_compat(pstmt, queryString, false, context, - params, queryEnv, dest, completionTag); + PrevProcessUtility_compat(pstmt, queryString, false, context, + params, queryEnv, dest, completionTag); return; } @@ -198,8 +199,8 @@ multi_ProcessUtility(PlannedStmt *pstmt, * Ensure that utility commands do not behave any differently until CREATE * EXTENSION is invoked. */ - standard_ProcessUtility_compat(pstmt, queryString, false, context, - params, queryEnv, dest, completionTag); + PrevProcessUtility_compat(pstmt, queryString, false, context, + params, queryEnv, dest, completionTag); return; } @@ -230,8 +231,8 @@ multi_ProcessUtility(PlannedStmt *pstmt, PG_TRY(); { - standard_ProcessUtility_compat(pstmt, queryString, false, context, - params, queryEnv, dest, completionTag); + PrevProcessUtility_compat(pstmt, queryString, false, context, + params, queryEnv, dest, completionTag); StoredProcedureLevel -= 1; @@ -264,8 +265,8 @@ multi_ProcessUtility(PlannedStmt *pstmt, PG_TRY(); { - standard_ProcessUtility_compat(pstmt, queryString, false, context, - params, queryEnv, dest, completionTag); + PrevProcessUtility_compat(pstmt, queryString, false, context, + params, queryEnv, dest, completionTag); DoBlockLevel -= 1; } @@ -616,8 +617,8 @@ ProcessUtilityInternal(PlannedStmt *pstmt, citusCanBeUpdatedToAvailableVersion = !InstalledAndAvailableVersionsSame(); } - standard_ProcessUtility_compat(pstmt, queryString, false, context, - params, queryEnv, dest, completionTag); + PrevProcessUtility_compat(pstmt, queryString, false, context, + params, queryEnv, dest, completionTag); /* * if we are running ALTER EXTENSION citus UPDATE (to "") command, we may need @@ -1612,26 +1613,3 @@ DropSchemaOrDBInProgress(void) { return activeDropSchemaOrDBs > 0; } - - -/* - * ColumnarTableSetOptionsHook propagates columnar table options to shards, if - * necessary. - */ -void -ColumnarTableSetOptionsHook(Oid relationId, ColumnarOptions options) -{ - if (EnableDDLPropagation && IsCitusTable(relationId)) - { - /* when a columnar table is distributed update all settings on the shards */ - Oid namespaceId = get_rel_namespace(relationId); - char *schemaName = get_namespace_name(namespaceId); - char *relationName = get_rel_name(relationId); - TableDDLCommand *command = ColumnarGetCustomTableOptionsDDL(schemaName, - relationName, - options); - DDLJob *ddljob = CreateCustomDDLTaskList(relationId, command); - - ExecuteDistributedDDLJob(ddljob); - } -} diff --git a/src/backend/distributed/operations/node_protocol.c b/src/backend/distributed/operations/node_protocol.c index bd1a53ad4..ab99ac93a 100644 --- a/src/backend/distributed/operations/node_protocol.c +++ b/src/backend/distributed/operations/node_protocol.c @@ -1039,12 +1039,12 @@ CitusCreateAlterColumnarTableSet(char *qualifiedRelationName, initStringInfo(&buf); appendStringInfo(&buf, - "SELECT alter_columnar_table_set(%s, " - "chunk_group_row_limit => %d, " - "stripe_row_limit => %lu, " - "compression_level => %d, " - "compression => %s);", - quote_literal_cstr(qualifiedRelationName), + "ALTER TABLE %s SET (" + "columnar.chunk_group_row_limit = %d, " + "columnar.stripe_row_limit = %lu, " + "columnar.compression_level = %d, " + "columnar.compression = %s);", + qualifiedRelationName, options->chunkRowCount, options->stripeRowCount, options->compressionLevel, diff --git a/src/backend/distributed/shared_library_init.c b/src/backend/distributed/shared_library_init.c index 3f7656ce6..2f4da77a1 100644 --- a/src/backend/distributed/shared_library_init.c +++ b/src/backend/distributed/shared_library_init.c @@ -334,9 +334,6 @@ _PG_init(void) /* intercept planner */ planner_hook = distributed_planner; - /* register utility hook */ - ProcessUtility_hook = multi_ProcessUtility; - /* register for planner hook */ set_rel_pathlist_hook = multi_relation_restriction_hook; set_join_pathlist_hook = multi_join_restriction_hook; @@ -388,19 +385,15 @@ _PG_init(void) load_file(COLUMNAR_MODULE_NAME, false); /* - * Now, acquire symbols from columnar module. First, acquire - * the address of the set options hook, and set it so that we - * can propagate options changes. + * Register utility hook. This must be done after loading columnar, so + * that the citus hook is called first, followed by the columnar hook, + * followed by standard_ProcessUtility. That allows citus to distribute + * ALTER TABLE commands before columnar strips out the columnar-specific + * options. */ - ColumnarTableSetOptions_hook_type **ColumnarTableSetOptions_hook_ptr = - (ColumnarTableSetOptions_hook_type **) find_rendezvous_variable( - COLUMNAR_SETOPTIONS_HOOK_SYM); - - /* rendezvous variable registered during columnar initialization */ - Assert(ColumnarTableSetOptions_hook_ptr != NULL); - Assert(*ColumnarTableSetOptions_hook_ptr != NULL); - - **ColumnarTableSetOptions_hook_ptr = ColumnarTableSetOptionsHook; + PrevProcessUtility = (ProcessUtility_hook != NULL) ? + ProcessUtility_hook : standard_ProcessUtility; + ProcessUtility_hook = multi_ProcessUtility; /* * Acquire symbols for columnar functions that citus calls. diff --git a/src/backend/distributed/sql/citus--11.0-2--11.1-1.sql b/src/backend/distributed/sql/citus--11.0-2--11.1-1.sql index 374350d56..ff58922f8 100644 --- a/src/backend/distributed/sql/citus--11.0-2--11.1-1.sql +++ b/src/backend/distributed/sql/citus--11.0-2--11.1-1.sql @@ -6,3 +6,5 @@ DROP FUNCTION pg_catalog.worker_hash_partition_table(bigint, integer, text, text DROP FUNCTION pg_catalog.worker_merge_files_into_table(bigint, integer, text[], text[]); DROP FUNCTION pg_catalog.worker_range_partition_table(bigint, integer, text, text, oid, anyarray); DROP FUNCTION pg_catalog.worker_repartition_cleanup(bigint); + +#include "../../columnar/sql/columnar--11.0-2--11.1-1.sql" diff --git a/src/backend/distributed/sql/downgrades/citus--11.1-1--11.0-2.sql b/src/backend/distributed/sql/downgrades/citus--11.1-1--11.0-2.sql index d03733bc7..8703d877a 100644 --- a/src/backend/distributed/sql/downgrades/citus--11.1-1--11.0-2.sql +++ b/src/backend/distributed/sql/downgrades/citus--11.1-1--11.0-2.sql @@ -44,4 +44,6 @@ CREATE FUNCTION pg_catalog.worker_repartition_cleanup(bigint) RETURNS void LANGUAGE c STRICT -AS 'MODULE_PATHNAME', $function$worker_repartition_cleanup$function$ +AS 'MODULE_PATHNAME', $function$worker_repartition_cleanup$function$; + +#include "../../../columnar/sql/downgrades/columnar--11.1-1--11.0-2.sql" diff --git a/src/include/columnar/columnar.h b/src/include/columnar/columnar.h index 4d31a45ed..e8868808e 100644 --- a/src/include/columnar/columnar.h +++ b/src/include/columnar/columnar.h @@ -25,6 +25,7 @@ #include "columnar/columnar_compression.h" #include "columnar/columnar_metadata.h" +#define COLUMNAR_AM_NAME "columnar" #define COLUMNAR_MODULE_NAME "citus_columnar" #define COLUMNAR_SETOPTIONS_HOOK_SYM "ColumnarTableSetOptions_hook" diff --git a/src/include/columnar/columnar_metadata.h b/src/include/columnar/columnar_metadata.h index 60669a248..c17799483 100644 --- a/src/include/columnar/columnar_metadata.h +++ b/src/include/columnar/columnar_metadata.h @@ -51,5 +51,7 @@ typedef struct EmptyStripeReservation extern List * StripesForRelfilenode(RelFileNode relfilenode); extern void ColumnarStorageUpdateIfNeeded(Relation rel, bool isUpgrade); +extern List * ExtractColumnarRelOptions(List *inOptions, List **outColumnarOptions); +extern void SetColumnarRelOptions(RangeVar *rv, List *reloptions); #endif /* COLUMNAR_METADATA_H */ diff --git a/src/include/distributed/commands/utility_hook.h b/src/include/distributed/commands/utility_hook.h index 246d413d9..a057c67b6 100644 --- a/src/include/distributed/commands/utility_hook.h +++ b/src/include/distributed/commands/utility_hook.h @@ -75,6 +75,7 @@ typedef struct DDLJob List *taskList; /* worker DDL tasks to execute */ } DDLJob; +extern ProcessUtility_hook_type PrevProcessUtility; extern void multi_ProcessUtility(PlannedStmt *pstmt, const char *queryString, #if PG_VERSION_NUM >= PG_VERSION_14 diff --git a/src/include/pg_version_compat.h b/src/include/pg_version_compat.h index 2f076cf07..33cb524bd 100644 --- a/src/include/pg_version_compat.h +++ b/src/include/pg_version_compat.h @@ -77,6 +77,8 @@ RelationGetSmgr(Relation rel) standard_ProcessUtility(a, b, c, d, e, f, g, h) #define ProcessUtility_compat(a, b, c, d, e, f, g, h) \ ProcessUtility(a, b, c, d, e, f, g, h) +#define PrevProcessUtility_compat(a, b, c, d, e, f, g, h) \ + PrevProcessUtility(a, b, c, d, e, f, g, h) #define SetTuplestoreDestReceiverParams_compat(a, b, c, d, e, f) \ SetTuplestoreDestReceiverParams(a, b, c, d, e, f) #define pgproc_statusflags_compat(pgproc) ((pgproc)->statusFlags) @@ -106,6 +108,8 @@ RelationGetSmgr(Relation rel) #define standard_ProcessUtility_compat(a, b, c, d, e, f, g, h) \ standard_ProcessUtility(a, b, d, e, f, g, h) #define ProcessUtility_compat(a, b, c, d, e, f, g, h) ProcessUtility(a, b, d, e, f, g, h) +#define PrevProcessUtility_compat(a, b, c, d, e, f, g, h) \ + PrevProcessUtility(a, b, d, e, f, g, h) #define COPY_FRONTEND COPY_NEW_FE #define SetTuplestoreDestReceiverParams_compat(a, b, c, d, e, f) \ SetTuplestoreDestReceiverParams(a, b, c, d) diff --git a/src/test/regress/columnar_schedule b/src/test/regress/columnar_schedule index ca2913c55..6c888b3b8 100644 --- a/src/test/regress/columnar_schedule +++ b/src/test/regress/columnar_schedule @@ -27,6 +27,7 @@ test: columnar_clean test: columnar_types_without_comparison test: columnar_chunk_filtering test: columnar_join +test: columnar_pg15 test: columnar_trigger test: columnar_tableoptions test: columnar_recursive diff --git a/src/test/regress/expected/columnar_citus_integration.out b/src/test/regress/expected/columnar_citus_integration.out index 582945bae..b691debe5 100644 --- a/src/test/regress/expected/columnar_citus_integration.out +++ b/src/test/regress/expected/columnar_citus_integration.out @@ -1,4 +1,23 @@ -SET columnar.compression TO 'none'; +SELECT success, result FROM run_command_on_all_nodes($cmd$ + ALTER SYSTEM SET columnar.compression TO 'none' +$cmd$); + success | result +--------------------------------------------------------------------- + t | ALTER SYSTEM + t | ALTER SYSTEM + t | ALTER SYSTEM +(3 rows) + +SELECT success, result FROM run_command_on_all_nodes($cmd$ + SELECT pg_reload_conf() +$cmd$); + success | result +--------------------------------------------------------------------- + t | t + t | t + t | t +(3 rows) + CREATE SCHEMA columnar_citus_integration; SET search_path TO columnar_citus_integration; SET citus.next_shard_id TO 20090000; @@ -27,12 +46,7 @@ $cmd$); (4 rows) -- change setting -SELECT alter_columnar_table_set('table_option', compression => 'pglz'); - alter_columnar_table_set ---------------------------------------------------------------------- - -(1 row) - +ALTER TABLE table_option SET (columnar.compression = pglz); -- verify setting SELECT run_command_on_placements('table_option',$cmd$ SELECT compression FROM columnar.options WHERE regclass = '%s'::regclass; @@ -46,12 +60,7 @@ $cmd$); (4 rows) -- reset setting -SELECT alter_columnar_table_reset('table_option', compression => true); - alter_columnar_table_reset ---------------------------------------------------------------------- - -(1 row) - +ALTER TABLE table_option RESET (columnar.compression); -- verify setting SELECT run_command_on_placements('table_option',$cmd$ SELECT compression FROM columnar.options WHERE regclass = '%s'::regclass; @@ -78,12 +87,7 @@ $cmd$); (4 rows) -- change setting -SELECT alter_columnar_table_set('table_option', compression_level => 13); - alter_columnar_table_set ---------------------------------------------------------------------- - -(1 row) - +ALTER TABLE table_option SET (columnar.compression_level = 13); -- verify setting SELECT run_command_on_placements('table_option',$cmd$ SELECT compression_level FROM columnar.options WHERE regclass = '%s'::regclass; @@ -97,12 +101,7 @@ $cmd$); (4 rows) -- reset setting -SELECT alter_columnar_table_reset('table_option', compression_level => true); - alter_columnar_table_reset ---------------------------------------------------------------------- - -(1 row) - +ALTER TABLE table_option RESET (columnar.compression_level); -- verify setting SELECT run_command_on_placements('table_option',$cmd$ SELECT compression_level FROM columnar.options WHERE regclass = '%s'::regclass; @@ -129,12 +128,7 @@ $cmd$); (4 rows) -- change setting -SELECT alter_columnar_table_set('table_option', chunk_group_row_limit => 2000); - alter_columnar_table_set ---------------------------------------------------------------------- - -(1 row) - +ALTER TABLE table_option SET (columnar.chunk_group_row_limit = 2000); -- verify setting SELECT run_command_on_placements('table_option',$cmd$ SELECT chunk_group_row_limit FROM columnar.options WHERE regclass = '%s'::regclass; @@ -148,12 +142,7 @@ $cmd$); (4 rows) -- reset setting -SELECT alter_columnar_table_reset('table_option', chunk_group_row_limit => true); - alter_columnar_table_reset ---------------------------------------------------------------------- - -(1 row) - +ALTER TABLE table_option RESET (columnar.chunk_group_row_limit); -- verify setting SELECT run_command_on_placements('table_option',$cmd$ SELECT chunk_group_row_limit FROM columnar.options WHERE regclass = '%s'::regclass; @@ -180,12 +169,7 @@ $cmd$); (4 rows) -- change setting -SELECT alter_columnar_table_set('table_option', stripe_row_limit => 2000); - alter_columnar_table_set ---------------------------------------------------------------------- - -(1 row) - +ALTER TABLE table_option SET (columnar.stripe_row_limit = 2000); -- verify setting SELECT run_command_on_placements('table_option',$cmd$ SELECT stripe_row_limit FROM columnar.options WHERE regclass = '%s'::regclass; @@ -199,12 +183,7 @@ $cmd$); (4 rows) -- reset setting -SELECT alter_columnar_table_reset('table_option', stripe_row_limit => true); - alter_columnar_table_reset ---------------------------------------------------------------------- - -(1 row) - +ALTER TABLE table_option RESET (columnar.stripe_row_limit); -- verify setting SELECT run_command_on_placements('table_option',$cmd$ SELECT stripe_row_limit FROM columnar.options WHERE regclass = '%s'::regclass; @@ -219,16 +198,11 @@ $cmd$); -- verify settings are propagated when creating a table CREATE TABLE table_option_2 (a int, b text) USING columnar; -SELECT alter_columnar_table_set('table_option_2', - chunk_group_row_limit => 2000, - stripe_row_limit => 20000, - compression => 'pglz', - compression_level => 15); - alter_columnar_table_set ---------------------------------------------------------------------- - -(1 row) - +ALTER TABLE table_option_2 SET + (columnar.chunk_group_row_limit = 2000, + columnar.stripe_row_limit = 20000, + columnar.compression = pglz, + columnar.compression_level = 15); SELECT create_distributed_table('table_option_2', 'a'); create_distributed_table --------------------------------------------------------------------- @@ -298,12 +272,7 @@ $cmd$); (8 rows) -- change setting -SELECT alter_columnar_table_set('table_option', compression => 'pglz'); - alter_columnar_table_set ---------------------------------------------------------------------- - -(1 row) - +ALTER TABLE table_option SET (columnar.compression = pglz); -- verify setting SELECT run_command_on_placements('table_option',$cmd$ SELECT compression FROM columnar.options WHERE regclass = '%s'::regclass; @@ -321,12 +290,7 @@ $cmd$); (8 rows) -- reset setting -SELECT alter_columnar_table_reset('table_option', compression => true); - alter_columnar_table_reset ---------------------------------------------------------------------- - -(1 row) - +ALTER TABLE table_option RESET (columnar.compression); -- verify setting SELECT run_command_on_placements('table_option',$cmd$ SELECT compression FROM columnar.options WHERE regclass = '%s'::regclass; @@ -361,12 +325,7 @@ $cmd$); (8 rows) -- change setting -SELECT alter_columnar_table_set('table_option', compression_level => 17); - alter_columnar_table_set ---------------------------------------------------------------------- - -(1 row) - +ALTER TABLE table_option SET (columnar.compression_level = 17); -- verify setting SELECT run_command_on_placements('table_option',$cmd$ SELECT compression_level FROM columnar.options WHERE regclass = '%s'::regclass; @@ -384,12 +343,7 @@ $cmd$); (8 rows) -- reset setting -SELECT alter_columnar_table_reset('table_option', compression_level => true); - alter_columnar_table_reset ---------------------------------------------------------------------- - -(1 row) - +ALTER TABLE table_option RESET (columnar.compression_level); -- verify setting SELECT run_command_on_placements('table_option',$cmd$ SELECT compression_level FROM columnar.options WHERE regclass = '%s'::regclass; @@ -424,12 +378,7 @@ $cmd$); (8 rows) -- change setting -SELECT alter_columnar_table_set('table_option', chunk_group_row_limit => 2000); - alter_columnar_table_set ---------------------------------------------------------------------- - -(1 row) - +ALTER TABLE table_option SET (columnar.chunk_group_row_limit = 2000); -- verify setting SELECT run_command_on_placements('table_option',$cmd$ SELECT chunk_group_row_limit FROM columnar.options WHERE regclass = '%s'::regclass; @@ -447,12 +396,7 @@ $cmd$); (8 rows) -- reset setting -SELECT alter_columnar_table_reset('table_option', chunk_group_row_limit => true); - alter_columnar_table_reset ---------------------------------------------------------------------- - -(1 row) - +ALTER TABLE table_option RESET (columnar.chunk_group_row_limit); -- verify setting SELECT run_command_on_placements('table_option',$cmd$ SELECT chunk_group_row_limit FROM columnar.options WHERE regclass = '%s'::regclass; @@ -487,12 +431,7 @@ $cmd$); (8 rows) -- change setting -SELECT alter_columnar_table_set('table_option', stripe_row_limit => 2000); - alter_columnar_table_set ---------------------------------------------------------------------- - -(1 row) - +ALTER TABLE table_option SET (columnar.stripe_row_limit = 2000); -- verify setting SELECT run_command_on_placements('table_option',$cmd$ SELECT stripe_row_limit FROM columnar.options WHERE regclass = '%s'::regclass; @@ -510,12 +449,7 @@ $cmd$); (8 rows) -- reset setting -SELECT alter_columnar_table_reset('table_option', stripe_row_limit => true); - alter_columnar_table_reset ---------------------------------------------------------------------- - -(1 row) - +ALTER TABLE table_option RESET (columnar.stripe_row_limit); -- verify setting SELECT run_command_on_placements('table_option',$cmd$ SELECT stripe_row_limit FROM columnar.options WHERE regclass = '%s'::regclass; @@ -534,16 +468,11 @@ $cmd$); -- verify settings are propagated when creating a table CREATE TABLE table_option_2 (a int, b text) USING columnar; -SELECT alter_columnar_table_set('table_option_2', - chunk_group_row_limit => 2000, - stripe_row_limit => 20000, - compression => 'pglz', - compression_level => 19); - alter_columnar_table_set ---------------------------------------------------------------------- - -(1 row) - +ALTER TABLE table_option_2 SET + (columnar.chunk_group_row_limit = 2000, + columnar.stripe_row_limit = 20000, + columnar.compression = pglz, + columnar.compression_level = 19); SELECT create_distributed_table('table_option_2', 'a'); create_distributed_table --------------------------------------------------------------------- @@ -609,12 +538,7 @@ $cmd$); (2 rows) -- change setting -SELECT alter_columnar_table_set('table_option_reference', compression => 'pglz'); - alter_columnar_table_set ---------------------------------------------------------------------- - -(1 row) - +ALTER TABLE table_option_reference SET (columnar.compression = pglz); -- verify setting SELECT run_command_on_placements('table_option_reference',$cmd$ SELECT compression FROM columnar.options WHERE regclass = '%s'::regclass; @@ -626,12 +550,7 @@ $cmd$); (2 rows) -- reset setting -SELECT alter_columnar_table_reset('table_option_reference', compression => true); - alter_columnar_table_reset ---------------------------------------------------------------------- - -(1 row) - +ALTER TABLE table_option_reference RESET (columnar.compression); -- verify setting SELECT run_command_on_placements('table_option_reference',$cmd$ SELECT compression FROM columnar.options WHERE regclass = '%s'::regclass; @@ -654,12 +573,7 @@ $cmd$); (2 rows) -- change setting -SELECT alter_columnar_table_set('table_option_reference', compression_level => 11); - alter_columnar_table_set ---------------------------------------------------------------------- - -(1 row) - +ALTER TABLE table_option_reference SET (columnar.compression_level = 11); -- verify setting SELECT run_command_on_placements('table_option_reference',$cmd$ SELECT compression_level FROM columnar.options WHERE regclass = '%s'::regclass; @@ -671,12 +585,7 @@ $cmd$); (2 rows) -- reset setting -SELECT alter_columnar_table_reset('table_option_reference', compression_level => true); - alter_columnar_table_reset ---------------------------------------------------------------------- - -(1 row) - +ALTER TABLE table_option_reference RESET (columnar.compression_level); -- verify setting SELECT run_command_on_placements('table_option_reference',$cmd$ SELECT compression_level FROM columnar.options WHERE regclass = '%s'::regclass; @@ -699,12 +608,7 @@ $cmd$); (2 rows) -- change setting -SELECT alter_columnar_table_set('table_option_reference', chunk_group_row_limit => 2000); - alter_columnar_table_set ---------------------------------------------------------------------- - -(1 row) - +ALTER TABLE table_option_reference SET (columnar.chunk_group_row_limit = 2000); -- verify setting SELECT run_command_on_placements('table_option_reference',$cmd$ SELECT chunk_group_row_limit FROM columnar.options WHERE regclass = '%s'::regclass; @@ -716,12 +620,7 @@ $cmd$); (2 rows) -- reset setting -SELECT alter_columnar_table_reset('table_option_reference', chunk_group_row_limit => true); - alter_columnar_table_reset ---------------------------------------------------------------------- - -(1 row) - +ALTER TABLE table_option_reference RESET (columnar.chunk_group_row_limit); -- verify setting SELECT run_command_on_placements('table_option_reference',$cmd$ SELECT chunk_group_row_limit FROM columnar.options WHERE regclass = '%s'::regclass; @@ -744,12 +643,7 @@ $cmd$); (2 rows) -- change setting -SELECT alter_columnar_table_set('table_option_reference', stripe_row_limit => 2000); - alter_columnar_table_set ---------------------------------------------------------------------- - -(1 row) - +ALTER TABLE table_option_reference SET (columnar.stripe_row_limit = 2000); -- verify setting SELECT run_command_on_placements('table_option_reference',$cmd$ SELECT stripe_row_limit FROM columnar.options WHERE regclass = '%s'::regclass; @@ -761,12 +655,7 @@ $cmd$); (2 rows) -- reset setting -SELECT alter_columnar_table_reset('table_option_reference', stripe_row_limit => true); - alter_columnar_table_reset ---------------------------------------------------------------------- - -(1 row) - +ALTER TABLE table_option_reference RESET (columnar.stripe_row_limit); -- verify setting SELECT run_command_on_placements('table_option_reference',$cmd$ SELECT stripe_row_limit FROM columnar.options WHERE regclass = '%s'::regclass; @@ -779,16 +668,11 @@ $cmd$); -- verify settings are propagated when creating a table CREATE TABLE table_option_reference_2 (a int, b text) USING columnar; -SELECT alter_columnar_table_set('table_option_reference_2', - chunk_group_row_limit => 2000, - stripe_row_limit => 20000, - compression => 'pglz', - compression_level => 9); - alter_columnar_table_set ---------------------------------------------------------------------- - -(1 row) - +ALTER TABLE table_option_reference_2 SET + (columnar.chunk_group_row_limit = 2000, + columnar.stripe_row_limit = 20000, + columnar.compression = pglz, + columnar.compression_level = 9); SELECT create_reference_table('table_option_reference_2'); create_reference_table --------------------------------------------------------------------- @@ -855,12 +739,7 @@ $cmd$); (1 row) -- change setting -SELECT alter_columnar_table_set('table_option_citus_local', compression => 'pglz'); - alter_columnar_table_set ---------------------------------------------------------------------- - -(1 row) - +ALTER TABLE table_option_citus_local SET (columnar.compression = pglz); -- verify setting SELECT run_command_on_placements('table_option_citus_local',$cmd$ SELECT compression FROM columnar.options WHERE regclass = '%s'::regclass; @@ -871,12 +750,7 @@ $cmd$); (1 row) -- reset setting -SELECT alter_columnar_table_reset('table_option_citus_local', compression => true); - alter_columnar_table_reset ---------------------------------------------------------------------- - -(1 row) - +ALTER TABLE table_option_citus_local RESET (columnar.compression); -- verify setting SELECT run_command_on_placements('table_option_citus_local',$cmd$ SELECT compression FROM columnar.options WHERE regclass = '%s'::regclass; @@ -897,12 +771,7 @@ $cmd$); (1 row) -- change setting -SELECT alter_columnar_table_set('table_option_citus_local', compression_level => 11); - alter_columnar_table_set ---------------------------------------------------------------------- - -(1 row) - +ALTER TABLE table_option_citus_local SET (columnar.compression_level = 11); -- verify setting SELECT run_command_on_placements('table_option_citus_local',$cmd$ SELECT compression_level FROM columnar.options WHERE regclass = '%s'::regclass; @@ -913,12 +782,7 @@ $cmd$); (1 row) -- reset setting -SELECT alter_columnar_table_reset('table_option_citus_local', compression_level => true); - alter_columnar_table_reset ---------------------------------------------------------------------- - -(1 row) - +ALTER TABLE table_option_citus_local RESET (columnar.compression_level); -- verify setting SELECT run_command_on_placements('table_option_citus_local',$cmd$ SELECT compression_level FROM columnar.options WHERE regclass = '%s'::regclass; @@ -939,12 +803,7 @@ $cmd$); (1 row) -- change setting -SELECT alter_columnar_table_set('table_option_citus_local', chunk_group_row_limit => 2000); - alter_columnar_table_set ---------------------------------------------------------------------- - -(1 row) - +ALTER TABLE table_option_citus_local SET (columnar.chunk_group_row_limit = 2000); -- verify setting SELECT run_command_on_placements('table_option_citus_local',$cmd$ SELECT chunk_group_row_limit FROM columnar.options WHERE regclass = '%s'::regclass; @@ -955,12 +814,7 @@ $cmd$); (1 row) -- reset setting -SELECT alter_columnar_table_reset('table_option_citus_local', chunk_group_row_limit => true); - alter_columnar_table_reset ---------------------------------------------------------------------- - -(1 row) - +ALTER TABLE table_option_citus_local RESET (columnar.chunk_group_row_limit); -- verify setting SELECT run_command_on_placements('table_option_citus_local',$cmd$ SELECT chunk_group_row_limit FROM columnar.options WHERE regclass = '%s'::regclass; @@ -981,12 +835,7 @@ $cmd$); (1 row) -- change setting -SELECT alter_columnar_table_set('table_option_citus_local', stripe_row_limit => 2000); - alter_columnar_table_set ---------------------------------------------------------------------- - -(1 row) - +ALTER TABLE table_option_citus_local SET (columnar.stripe_row_limit = 2000); -- verify setting SELECT run_command_on_placements('table_option_citus_local',$cmd$ SELECT stripe_row_limit FROM columnar.options WHERE regclass = '%s'::regclass; @@ -997,12 +846,7 @@ $cmd$); (1 row) -- reset setting -SELECT alter_columnar_table_reset('table_option_citus_local', stripe_row_limit => true); - alter_columnar_table_reset ---------------------------------------------------------------------- - -(1 row) - +ALTER TABLE table_option_citus_local RESET (columnar.stripe_row_limit); -- verify setting SELECT run_command_on_placements('table_option_citus_local',$cmd$ SELECT stripe_row_limit FROM columnar.options WHERE regclass = '%s'::regclass; @@ -1014,16 +858,11 @@ $cmd$); -- verify settings are propagated when creating a table CREATE TABLE table_option_citus_local_2 (a int, b text) USING columnar; -SELECT alter_columnar_table_set('table_option_citus_local_2', - chunk_group_row_limit => 2000, - stripe_row_limit => 20000, - compression => 'pglz', - compression_level => 9); - alter_columnar_table_set ---------------------------------------------------------------------- - -(1 row) - +ALTER TABLE table_option_citus_local_2 SET + (columnar.chunk_group_row_limit = 2000, + columnar.stripe_row_limit = 20000, + columnar.compression = pglz, + columnar.compression_level = 9); SELECT citus_add_local_table_to_metadata('table_option_citus_local_2'); citus_add_local_table_to_metadata --------------------------------------------------------------------- diff --git a/src/test/regress/expected/columnar_create.out b/src/test/regress/expected/columnar_create.out index 9b5fdace9..ec8303b3e 100644 --- a/src/test/regress/expected/columnar_create.out +++ b/src/test/regress/expected/columnar_create.out @@ -5,12 +5,7 @@ CREATE TABLE contestant (handle TEXT, birthdate DATE, rating INT, percentile FLOAT, country CHAR(3), achievements TEXT[]) USING columnar; -SELECT alter_columnar_table_set('contestant', compression => 'none'); - alter_columnar_table_set ---------------------------------------------------------------------- - -(1 row) - +ALTER TABLE contestant SET (columnar.compression = none); CREATE INDEX contestant_idx on contestant(handle); -- Create zstd compressed table CREATE TABLE contestant_compressed (handle TEXT, birthdate DATE, rating INT, diff --git a/src/test/regress/expected/columnar_empty.out b/src/test/regress/expected/columnar_empty.out index e68645f5b..67ef1ee12 100644 --- a/src/test/regress/expected/columnar_empty.out +++ b/src/test/regress/expected/columnar_empty.out @@ -5,24 +5,9 @@ SET citus.compression to 'none'; create table t_uncompressed(a int) using columnar; create table t_compressed(a int) using columnar; -- set options -SELECT alter_columnar_table_set('t_compressed', compression => 'pglz'); - alter_columnar_table_set ---------------------------------------------------------------------- - -(1 row) - -SELECT alter_columnar_table_set('t_compressed', stripe_row_limit => 2000); - alter_columnar_table_set ---------------------------------------------------------------------- - -(1 row) - -SELECT alter_columnar_table_set('t_compressed', chunk_group_row_limit => 1000); - alter_columnar_table_set ---------------------------------------------------------------------- - -(1 row) - +ALTER TABLE t_compressed SET (columnar.compression = pglz); +ALTER TABLE t_compressed SET (columnar.stripe_row_limit = 2000); +ALTER TABLE t_compressed SET (columnar.chunk_group_row_limit = 1000); SELECT * FROM columnar.options WHERE regclass = 't_compressed'::regclass; regclass | chunk_group_row_limit | stripe_row_limit | compression_level | compression --------------------------------------------------------------------- diff --git a/src/test/regress/expected/columnar_fallback_scan.out b/src/test/regress/expected/columnar_fallback_scan.out index d386d63d4..c31db0c43 100644 --- a/src/test/regress/expected/columnar_fallback_scan.out +++ b/src/test/regress/expected/columnar_fallback_scan.out @@ -8,12 +8,7 @@ set columnar.enable_custom_scan = false; create table fallback_scan(i int) using columnar; -- large enough to test parallel_workers > 1 -select alter_columnar_table_set('fallback_scan', compression => 'none'); - alter_columnar_table_set ---------------------------------------------------------------------- - -(1 row) - +ALTER TABLE fallback_scan SET (columnar.compression = none); insert into fallback_scan select generate_series(1,150000); vacuum analyze fallback_scan; select count(*), min(i), max(i), avg(i) from fallback_scan; diff --git a/src/test/regress/expected/columnar_first_row_number.out b/src/test/regress/expected/columnar_first_row_number.out index 87c1d9508..4567140ca 100644 --- a/src/test/regress/expected/columnar_first_row_number.out +++ b/src/test/regress/expected/columnar_first_row_number.out @@ -7,12 +7,7 @@ BEGIN; INSERT INTO col_table_1 SELECT i FROM generate_series(1, 11) i; ROLLBACK; INSERT INTO col_table_1 SELECT i FROM generate_series(1, 12) i; -SELECT alter_columnar_table_set('col_table_1', stripe_row_limit => 1000); - alter_columnar_table_set ---------------------------------------------------------------------- - -(1 row) - +ALTER TABLE col_table_1 SET (columnar.stripe_row_limit = 1000); INSERT INTO col_table_1 SELECT i FROM generate_series(1, 2350) i; SELECT row_count, first_row_number FROM columnar.stripe a WHERE a.storage_id = columnar_test_helpers.columnar_relation_storageid('col_table_1'::regclass) diff --git a/src/test/regress/expected/columnar_insert.out b/src/test/regress/expected/columnar_insert.out index 2227bd839..1e3215098 100644 --- a/src/test/regress/expected/columnar_insert.out +++ b/src/test/regress/expected/columnar_insert.out @@ -171,12 +171,7 @@ DROP TABLE test_toast_columnar; -- We support writing into zero column tables, but not reading from them. -- We test that metadata makes sense so we can fix the read path in future. CREATE TABLE zero_col() USING columnar; -SELECT alter_columnar_table_set('zero_col', chunk_group_row_limit => 1000); - alter_columnar_table_set ---------------------------------------------------------------------- - -(1 row) - +ALTER TABLE zero_col SET (columnar.chunk_group_row_limit = 1000); INSERT INTO zero_col DEFAULT VALUES; INSERT INTO zero_col DEFAULT VALUES; INSERT INTO zero_col DEFAULT VALUES; @@ -231,12 +226,7 @@ ORDER BY 1,2,3,4; (5 rows) CREATE TABLE selfinsert(x int) USING columnar; -SELECT alter_columnar_table_set('selfinsert', stripe_row_limit => 1000); - alter_columnar_table_set ---------------------------------------------------------------------- - -(1 row) - +ALTER TABLE selfinsert SET (columnar.stripe_row_limit = 1000); BEGIN; INSERT INTO selfinsert SELECT generate_series(1,1010); INSERT INTO selfinsert SELECT * FROM selfinsert; diff --git a/src/test/regress/expected/columnar_matview.out b/src/test/regress/expected/columnar_matview.out index 495cb0548..8ce16f408 100644 --- a/src/test/regress/expected/columnar_matview.out +++ b/src/test/regress/expected/columnar_matview.out @@ -32,12 +32,7 @@ WHERE regclass = 't_view'::regclass; (1 row) -- show we can set options on a materialized view -SELECT alter_columnar_table_set('t_view', compression => 'pglz'); - alter_columnar_table_set ---------------------------------------------------------------------- - -(1 row) - +ALTER TABLE t_view SET (columnar.compression = pglz); SELECT * FROM columnar.options WHERE regclass = 't_view'::regclass; regclass | chunk_group_row_limit | stripe_row_limit | compression_level | compression diff --git a/src/test/regress/expected/columnar_permissions.out b/src/test/regress/expected/columnar_permissions.out index eb058c951..0bfe7aa6b 100644 --- a/src/test/regress/expected/columnar_permissions.out +++ b/src/test/regress/expected/columnar_permissions.out @@ -1,3 +1,4 @@ +create table no_access (i int) using columnar; select current_user \gset create user columnar_user; NOTICE: not propagating CREATE ROLE/USER commands to worker nodes @@ -6,8 +7,41 @@ HINT: Connect to worker nodes directly to manually create all necessary users a create table columnar_permissions(i int) using columnar; insert into columnar_permissions values(1); alter table columnar_permissions add column j int; +alter table columnar_permissions reset (columnar.compression); +alter table columnar_permissions set (columnar.compression = none); +select alter_columnar_table_reset('columnar_permissions', stripe_row_limit => true); + alter_columnar_table_reset +--------------------------------------------------------------------- + +(1 row) + +select alter_columnar_table_set('columnar_permissions', stripe_row_limit => 2222); + alter_columnar_table_set +--------------------------------------------------------------------- + +(1 row) + +select * from columnar.options where regclass = 'columnar_permissions'::regclass; + regclass | chunk_group_row_limit | stripe_row_limit | compression_level | compression +--------------------------------------------------------------------- + columnar_permissions | 10000 | 2222 | 3 | none +(1 row) + insert into columnar_permissions values(2,20); vacuum columnar_permissions; truncate columnar_permissions; drop table columnar_permissions; +-- should error +alter table no_access reset (columnar.stripe_row_limit); +ERROR: must be owner of table no_access +alter table no_access set (columnar.stripe_row_limit = 12000); +ERROR: must be owner of table no_access +select alter_columnar_table_reset('no_access', chunk_group_row_limit => true); +ERROR: must be owner of table no_access +CONTEXT: SQL statement "ALTER TABLE no_access RESET (columnar.chunk_group_row_limit)" +PL/pgSQL function alter_columnar_table_reset(regclass,boolean,boolean,boolean,boolean) line XX at EXECUTE +select alter_columnar_table_set('no_access', chunk_group_row_limit => 1111); +ERROR: must be owner of table no_access +CONTEXT: SQL statement "ALTER TABLE no_access SET (columnar.chunk_group_row_limit=1111)" +PL/pgSQL function alter_columnar_table_set(regclass,integer,integer,name,integer) line XX at EXECUTE \c - :current_user diff --git a/src/test/regress/expected/columnar_pg15.out b/src/test/regress/expected/columnar_pg15.out new file mode 100644 index 000000000..499044fde --- /dev/null +++ b/src/test/regress/expected/columnar_pg15.out @@ -0,0 +1,60 @@ +SHOW server_version \gset +SELECT substring(:'server_version', '\d+')::int >= 15 AS server_version_ge_15 +\gset +\if :server_version_ge_15 +\else +\q +\endif +CREATE TABLE alter_am(i int); +CREATE TABLE +INSERT INTO alter_am SELECT generate_series(1,1000000); +INSERT 0 1000000 +SELECT * FROM columnar.options WHERE regclass = 'alter_am'::regclass; + regclass | chunk_group_row_limit | stripe_row_limit | compression_level | compression +--------------------------------------------------------------------- +(0 rows) + +SELECT SUM(i) FROM alter_am; + sum +--------------------------------------------------------------------- + 500000500000 +(1 row) + +ALTER TABLE alter_am + SET ACCESS METHOD columnar, + SET (columnar.compression = pglz, fillfactor = 20); +ALTER TABLE +SELECT * FROM columnar.options WHERE regclass = 'alter_am'::regclass; + regclass | chunk_group_row_limit | stripe_row_limit | compression_level | compression +--------------------------------------------------------------------- + alter_am | 10000 | 150000 | 3 | pglz +(1 row) + +SELECT SUM(i) FROM alter_am; + sum +--------------------------------------------------------------------- + 500000500000 +(1 row) + +ALTER TABLE alter_am SET ACCESS METHOD heap; +ALTER TABLE +-- columnar options should be gone +SELECT * FROM columnar.options WHERE regclass = 'alter_am'::regclass; + regclass | chunk_group_row_limit | stripe_row_limit | compression_level | compression +--------------------------------------------------------------------- +(0 rows) + +SELECT SUM(i) FROM alter_am; + sum +--------------------------------------------------------------------- + 500000500000 +(1 row) + +-- error: setting columnar options must happen after converting to columnar +ALTER TABLE alter_am + SET (columnar.stripe_row_limit = 1111), + SET ACCESS METHOD columnar; +ERROR: ALTER TABLE cannot alter the access method after altering storage parameters +HINT: Specify SET ACCESS METHOD before storage parameters, or use separate ALTER TABLE commands. +DROP TABLE alter_am; +DROP TABLE diff --git a/src/test/regress/expected/columnar_pg15_0.out b/src/test/regress/expected/columnar_pg15_0.out new file mode 100644 index 000000000..a7e3fbf20 --- /dev/null +++ b/src/test/regress/expected/columnar_pg15_0.out @@ -0,0 +1,6 @@ +SHOW server_version \gset +SELECT substring(:'server_version', '\d+')::int >= 15 AS server_version_ge_15 +\gset +\if :server_version_ge_15 +\else +\q diff --git a/src/test/regress/expected/columnar_tableoptions.out b/src/test/regress/expected/columnar_tableoptions.out index 7bf650e02..2494cea8b 100644 --- a/src/test/regress/expected/columnar_tableoptions.out +++ b/src/test/regress/expected/columnar_tableoptions.out @@ -12,12 +12,7 @@ WHERE regclass = 'table_options'::regclass; (1 row) -- test changing the compression -SELECT alter_columnar_table_set('table_options', compression => 'pglz'); - alter_columnar_table_set ---------------------------------------------------------------------- - -(1 row) - +ALTER TABLE table_options SET (columnar.compression = pglz); -- show table_options settings SELECT * FROM columnar.options WHERE regclass = 'table_options'::regclass; @@ -27,12 +22,7 @@ WHERE regclass = 'table_options'::regclass; (1 row) -- test changing the compression level -SELECT alter_columnar_table_set('table_options', compression_level => 5); - alter_columnar_table_set ---------------------------------------------------------------------- - -(1 row) - +ALTER TABLE table_options SET (columnar.compression_level = 5); -- show table_options settings SELECT * FROM columnar.options WHERE regclass = 'table_options'::regclass; @@ -42,12 +32,7 @@ WHERE regclass = 'table_options'::regclass; (1 row) -- test changing the chunk_group_row_limit -SELECT alter_columnar_table_set('table_options', chunk_group_row_limit => 2000); - alter_columnar_table_set ---------------------------------------------------------------------- - -(1 row) - +ALTER TABLE table_options SET (columnar.chunk_group_row_limit = 2000); -- show table_options settings SELECT * FROM columnar.options WHERE regclass = 'table_options'::regclass; @@ -57,12 +42,7 @@ WHERE regclass = 'table_options'::regclass; (1 row) -- test changing the chunk_group_row_limit -SELECT alter_columnar_table_set('table_options', stripe_row_limit => 4000); - alter_columnar_table_set ---------------------------------------------------------------------- - -(1 row) - +ALTER TABLE table_options SET (columnar.stripe_row_limit = 4000); -- show table_options settings SELECT * FROM columnar.options WHERE regclass = 'table_options'::regclass; @@ -82,12 +62,11 @@ WHERE regclass = 'table_options'::regclass; (1 row) -- set all settings at the same time -SELECT alter_columnar_table_set('table_options', stripe_row_limit => 8000, chunk_group_row_limit => 4000, compression => 'none', compression_level => 7); - alter_columnar_table_set ---------------------------------------------------------------------- - -(1 row) - +ALTER TABLE table_options SET + (columnar.stripe_row_limit = 8000, + columnar.chunk_group_row_limit = 4000, + columnar.compression = none, + columnar.compression_level = 7); -- show table_options settings SELECT * FROM columnar.options WHERE regclass = 'table_options'::regclass; @@ -149,12 +128,7 @@ WHERE regclass = 'table_options'::regclass; table_options | 4000 | 8000 | 7 | none (1 row) -SELECT alter_columnar_table_reset('table_options', chunk_group_row_limit => true); - alter_columnar_table_reset ---------------------------------------------------------------------- - -(1 row) - +ALTER TABLE table_options RESET (columnar.chunk_group_row_limit); -- show table_options settings SELECT * FROM columnar.options WHERE regclass = 'table_options'::regclass; @@ -163,12 +137,7 @@ WHERE regclass = 'table_options'::regclass; table_options | 1000 | 8000 | 7 | none (1 row) -SELECT alter_columnar_table_reset('table_options', stripe_row_limit => true); - alter_columnar_table_reset ---------------------------------------------------------------------- - -(1 row) - +ALTER TABLE table_options RESET (columnar.stripe_row_limit); -- show table_options settings SELECT * FROM columnar.options WHERE regclass = 'table_options'::regclass; @@ -177,12 +146,7 @@ WHERE regclass = 'table_options'::regclass; table_options | 1000 | 10000 | 7 | none (1 row) -SELECT alter_columnar_table_reset('table_options', compression => true); - alter_columnar_table_reset ---------------------------------------------------------------------- - -(1 row) - +ALTER TABLE table_options RESET (columnar.compression); -- show table_options settings SELECT * FROM columnar.options WHERE regclass = 'table_options'::regclass; @@ -191,12 +155,7 @@ WHERE regclass = 'table_options'::regclass; table_options | 1000 | 10000 | 7 | pglz (1 row) -SELECT alter_columnar_table_reset('table_options', compression_level => true); - alter_columnar_table_reset ---------------------------------------------------------------------- - -(1 row) - +ALTER TABLE table_options RESET (columnar.compression_level); -- show table_options settings SELECT * FROM columnar.options WHERE regclass = 'table_options'::regclass; @@ -218,17 +177,11 @@ WHERE regclass = 'table_options'::regclass; table_options | 1000 | 10000 | 11 | pglz (1 row) -SELECT alter_columnar_table_reset( - 'table_options', - chunk_group_row_limit => true, - stripe_row_limit => true, - compression => true, - compression_level => true); - alter_columnar_table_reset ---------------------------------------------------------------------- - -(1 row) - +ALTER TABLE table_options RESET + (columnar.chunk_group_row_limit, + columnar.stripe_row_limit, + columnar.compression, + columnar.compression_level); -- show table_options settings SELECT * FROM columnar.options WHERE regclass = 'table_options'::regclass; @@ -240,37 +193,112 @@ WHERE regclass = 'table_options'::regclass; -- verify edge cases -- first start with a table that is not a columnar table CREATE TABLE not_a_columnar_table (a int); -SELECT alter_columnar_table_set('not_a_columnar_table', compression => 'pglz'); -ERROR: table not_a_columnar_table is not a columnar table -SELECT alter_columnar_table_reset('not_a_columnar_table', compression => true); -ERROR: table not_a_columnar_table is not a columnar table +ALTER TABLE not_a_columnar_table SET (columnar.compression = pglz); +ERROR: columnar storage parameters specified on non-columnar table +ALTER TABLE not_a_columnar_table RESET (columnar.compression); +ERROR: columnar storage parameters specified on non-columnar table -- verify you can't use a compression that is not known -SELECT alter_columnar_table_set('table_options', compression => 'foobar'); +ALTER TABLE table_options SET (columnar.compression = foobar); +ERROR: unknown compression type for columnar table: foobar +-- verify you can't use a columnar setting that is not known +ALTER TABLE table_options SET (columnar.foobar = 123); +ERROR: unrecognized columnar storage parameter "foobar" +ALTER TABLE table_options RESET (columnar.foobar); +ERROR: unrecognized columnar storage parameter "foobar" +-- verify that invalid options are caught early, before query executes +-- (error should be about invalid options, not division-by-zero) +CREATE TABLE fail(i) USING columnar WITH (columnar.foobar = 123) AS SELECT 1/0; +ERROR: unrecognized columnar storage parameter "foobar" +CREATE TABLE fail(i) USING columnar WITH (columnar.compression = foobar) AS SELECT 1/0; ERROR: unknown compression type for columnar table: foobar -- verify cannot set out of range compression levels -SELECT alter_columnar_table_set('table_options', compression_level => 0); +ALTER TABLE table_options SET (columnar.compression_level = 0); ERROR: compression level out of range HINT: compression level must be between 1 and 19 -SELECT alter_columnar_table_set('table_options', compression_level => 20); +ALTER TABLE table_options SET (columnar.compression_level = 20); ERROR: compression level out of range HINT: compression level must be between 1 and 19 -- verify cannot set out of range stripe_row_limit & chunk_group_row_limit options -SELECT alter_columnar_table_set('table_options', stripe_row_limit => 999); +ALTER TABLE table_options SET (columnar.stripe_row_limit = 999); ERROR: stripe row count limit out of range HINT: stripe row count limit must be between 1000 and 10000000 -SELECT alter_columnar_table_set('table_options', stripe_row_limit => 10000001); +ALTER TABLE table_options SET (columnar.stripe_row_limit = 10000001); ERROR: stripe row count limit out of range HINT: stripe row count limit must be between 1000 and 10000000 -SELECT alter_columnar_table_set('table_options', chunk_group_row_limit => 999); +ALTER TABLE table_options SET (columnar.chunk_group_row_limit = 999); ERROR: chunk group row count limit out of range HINT: chunk group row count limit must be between 1000 and 100000 -SELECT alter_columnar_table_set('table_options', chunk_group_row_limit => 100001); +ALTER TABLE table_options SET (columnar.chunk_group_row_limit = 100001); ERROR: chunk group row count limit out of range HINT: chunk group row count limit must be between 1000 and 100000 -SELECT alter_columnar_table_set('table_options', chunk_group_row_limit => 0); +ALTER TABLE table_options SET (columnar.chunk_group_row_limit = 0); ERROR: chunk group row count limit out of range HINT: chunk group row count limit must be between 1000 and 100000 INSERT INTO table_options VALUES (1); +-- multiple SET/RESET clauses +ALTER TABLE table_options + SET (columnar.compression = pglz, columnar.compression_level = 7), + SET (columnar.compression_level = 6); +SELECT * FROM columnar.options +WHERE regclass = 'table_options'::regclass; + regclass | chunk_group_row_limit | stripe_row_limit | compression_level | compression +--------------------------------------------------------------------- + table_options | 10000 | 100000 | 6 | pglz +(1 row) + +ALTER TABLE table_options + SET (columnar.compression = pglz, columnar.stripe_row_limit = 7777), + RESET (columnar.stripe_row_limit), + SET (columnar.chunk_group_row_limit = 5555); +SELECT * FROM columnar.options +WHERE regclass = 'table_options'::regclass; + regclass | chunk_group_row_limit | stripe_row_limit | compression_level | compression +--------------------------------------------------------------------- + table_options | 5555 | 100000 | 6 | pglz +(1 row) + +-- a no-op; shouldn't throw an error +ALTER TABLE IF EXISTS what SET (columnar.compression = lz4); +NOTICE: relation "what" does not exist, skipping +-- a no-op; shouldn't throw an error +CREATE TABLE IF NOT EXISTS table_options(a int) USING columnar + WITH (columnar.compression_level = 4); +NOTICE: relation "table_options" already exists, skipping +-- test old interface based on functions +SELECT alter_columnar_table_reset('table_options', compression => true); + alter_columnar_table_reset +--------------------------------------------------------------------- + +(1 row) + +SELECT * FROM columnar.options WHERE regclass = 'table_options'::regclass; + regclass | chunk_group_row_limit | stripe_row_limit | compression_level | compression +--------------------------------------------------------------------- + table_options | 5555 | 100000 | 6 | none +(1 row) + +SELECT alter_columnar_table_set('table_options', compression_level => 1); + alter_columnar_table_set +--------------------------------------------------------------------- + +(1 row) + +SELECT * FROM columnar.options WHERE regclass = 'table_options'::regclass; + regclass | chunk_group_row_limit | stripe_row_limit | compression_level | compression +--------------------------------------------------------------------- + table_options | 5555 | 100000 | 1 | none +(1 row) + +-- error: set columnar options on heap tables +CREATE TABLE heap_options(i int) ; +ALTER TABLE heap_options SET (columnar.stripe_row_limit = 12000); +ERROR: columnar storage parameters specified on non-columnar table +-- ordinarily, postgres allows bogus options for a RESET clause, +-- but if it's a heap table and someone specifies columnar options, +-- we block them +ALTER TABLE heap_options RESET (columnar.stripe_row_limit, foobar); +ERROR: columnar storage parameters specified on non-columnar table +DROP TABLE heap_options; -- verify options are removed when table is dropped DROP TABLE table_options; -- we expect no entries in çstore.options for anything not found int pg_class diff --git a/src/test/regress/expected/columnar_vacuum.out b/src/test/regress/expected/columnar_vacuum.out index 3850ce1da..d9b481bc6 100644 --- a/src/test/regress/expected/columnar_vacuum.out +++ b/src/test/regress/expected/columnar_vacuum.out @@ -62,12 +62,7 @@ select (1 row) -- test the case when all data cannot fit into a single stripe -SELECT alter_columnar_table_set('t', stripe_row_limit => 1000); - alter_columnar_table_set ---------------------------------------------------------------------- - -(1 row) - +ALTER TABLE t SET (columnar.stripe_row_limit = 1000); INSERT INTO t SELECT i, 2 * i FROM generate_series(1,2500) i; SELECT sum(a), sum(b) FROM t; sum | sum @@ -207,25 +202,15 @@ SELECT count(*) FROM t; -- add some stripes with different compression types and create some gaps, -- then vacuum to print stats BEGIN; -SELECT alter_columnar_table_set('t', - chunk_group_row_limit => 1000, - stripe_row_limit => 2000, - compression => 'pglz'); - alter_columnar_table_set ---------------------------------------------------------------------- - -(1 row) - +ALTER TABLE t SET + (columnar.chunk_group_row_limit = 1000, + columnar.stripe_row_limit = 2000, + columnar.compression = pglz); SAVEPOINT s1; INSERT INTO t SELECT i FROM generate_series(1, 1500) i; ROLLBACK TO SAVEPOINT s1; INSERT INTO t SELECT i / 5 FROM generate_series(1, 1500) i; -SELECT alter_columnar_table_set('t', compression => 'none'); - alter_columnar_table_set ---------------------------------------------------------------------- - -(1 row) - +ALTER TABLE t SET (columnar.compression = none); SAVEPOINT s2; INSERT INTO t SELECT i FROM generate_series(1, 1500) i; ROLLBACK TO SAVEPOINT s2; @@ -274,12 +259,7 @@ chunk count: 11, containing data for dropped columns: 2, none compressed: 9, pgl -- vacuum full should remove chunks for dropped columns -- note that, a chunk will be stored in non-compressed for if compression -- doesn't reduce its size. -SELECT alter_columnar_table_set('t', compression => 'pglz'); - alter_columnar_table_set ---------------------------------------------------------------------- - -(1 row) - +ALTER TABLE t SET (columnar.compression = pglz); VACUUM FULL t; VACUUM VERBOSE t; INFO: statistics for "t": diff --git a/src/test/regress/expected/columnar_zstd.out b/src/test/regress/expected/columnar_zstd.out index ab245ba76..c84d78660 100644 --- a/src/test/regress/expected/columnar_zstd.out +++ b/src/test/regress/expected/columnar_zstd.out @@ -36,12 +36,7 @@ SELECT DISTINCT * FROM test_zstd ORDER BY a, b, c LIMIT 5; VACUUM FULL test_zstd; SELECT pg_relation_size('test_zstd') AS size_comp_level_default \gset -- change compression level -SELECT alter_columnar_table_set('test_zstd', compression_level => 19); - alter_columnar_table_set ---------------------------------------------------------------------- - -(1 row) - +ALTER TABLE test_zstd SET (columnar.compression_level = 19); VACUUM FULL test_zstd; SELECT pg_relation_size('test_zstd') AS size_comp_level_19 \gset -- verify that higher compression level compressed better diff --git a/src/test/regress/expected/multi_extension.out b/src/test/regress/expected/multi_extension.out index 8f211bd97..07affead4 100644 --- a/src/test/regress/expected/multi_extension.out +++ b/src/test/regress/expected/multi_extension.out @@ -759,9 +759,9 @@ DROP TABLE columnar_table; ERROR: loaded Citus library version differs from installed extension version CREATE INDEX ON columnar_table (a); ERROR: loaded Citus library version differs from installed extension version -SELECT alter_columnar_table_set('columnar_table', compression => 'pglz'); +ALTER TABLE columnar_table SET (columnar.compression = pglz); ERROR: loaded Citus library version differs from installed extension version -SELECT alter_columnar_table_reset('columnar_table'); +ALTER TABLE columnar_table RESET (columnar.compression); ERROR: loaded Citus library version differs from installed extension version INSERT INTO columnar_table SELECT * FROM columnar_table; ERROR: loaded Citus library version differs from installed extension version diff --git a/src/test/regress/expected/multi_fix_partition_shard_index_names.out b/src/test/regress/expected/multi_fix_partition_shard_index_names.out index 91a65dc02..090ebdd4e 100644 --- a/src/test/regress/expected/multi_fix_partition_shard_index_names.out +++ b/src/test/regress/expected/multi_fix_partition_shard_index_names.out @@ -648,7 +648,7 @@ NOTICE: issuing BEGIN TRANSACTION ISOLATION LEVEL READ COMMITTED;SELECT assign_ DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx NOTICE: issuing SELECT worker_apply_shard_ddl_command (915002, 'fix_idx_names', 'CREATE TABLE fix_idx_names.p2 (dist_col integer NOT NULL, another_col integer, partition_col timestamp without time zone NOT NULL, name text) USING columnar') DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx -NOTICE: issuing SELECT alter_columnar_table_set('fix_idx_names.p2_915002', chunk_group_row_limit => 10000, stripe_row_limit => 150000, compression_level => 3, compression => 'zstd'); +NOTICE: issuing ALTER TABLE fix_idx_names.p2_915002 SET (columnar.chunk_group_row_limit = 10000, columnar.stripe_row_limit = 150000, columnar.compression_level = 3, columnar.compression = 'zstd'); DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx NOTICE: issuing SELECT worker_apply_shard_ddl_command (915002, 'fix_idx_names', 'ALTER TABLE fix_idx_names.p2 OWNER TO postgres') DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx @@ -662,9 +662,9 @@ NOTICE: issuing CREATE TABLE fix_idx_names.p2 (dist_col integer NOT NULL, anoth DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx NOTICE: issuing CREATE TABLE fix_idx_names.p2 (dist_col integer NOT NULL, another_col integer, partition_col timestamp without time zone NOT NULL, name text) USING columnar DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx -NOTICE: issuing SELECT alter_columnar_table_set('fix_idx_names.p2', chunk_group_row_limit => 10000, stripe_row_limit => 150000, compression_level => 3, compression => 'zstd'); +NOTICE: issuing ALTER TABLE fix_idx_names.p2 SET (columnar.chunk_group_row_limit = 10000, columnar.stripe_row_limit = 150000, columnar.compression_level = 3, columnar.compression = 'zstd'); DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx -NOTICE: issuing SELECT alter_columnar_table_set('fix_idx_names.p2', chunk_group_row_limit => 10000, stripe_row_limit => 150000, compression_level => 3, compression => 'zstd'); +NOTICE: issuing ALTER TABLE fix_idx_names.p2 SET (columnar.chunk_group_row_limit = 10000, columnar.stripe_row_limit = 150000, columnar.compression_level = 3, columnar.compression = 'zstd'); DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx NOTICE: issuing ALTER TABLE fix_idx_names.p2 OWNER TO postgres DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx diff --git a/src/test/regress/expected/multi_multiuser.out b/src/test/regress/expected/multi_multiuser.out index 95a99034f..a3f090087 100644 --- a/src/test/regress/expected/multi_multiuser.out +++ b/src/test/regress/expected/multi_multiuser.out @@ -240,12 +240,7 @@ SET columnar.chunk_group_row_limit = 1050; -- create columnar table CREATE TABLE columnar_table (a int) USING columnar; -- alter a columnar table that is created by that unprivileged user -SELECT alter_columnar_table_set('columnar_table', chunk_group_row_limit => 2000); - alter_columnar_table_set ---------------------------------------------------------------------- - -(1 row) - +ALTER TABLE columnar_table SET (columnar.chunk_group_row_limit = 2000); -- insert some data and read INSERT INTO columnar_table VALUES (1), (1); SELECT * FROM columnar_table; @@ -257,10 +252,10 @@ SELECT * FROM columnar_table; -- Fail to alter a columnar table that is created by a different user SET ROLE full_access; -SELECT alter_columnar_table_set('columnar_table', chunk_group_row_limit => 2000); +ALTER TABLE columnar_table SET (columnar.chunk_group_row_limit = 2000); ERROR: must be owner of table columnar_table -- Fail to reset a columnar table value created by a different user -SELECT alter_columnar_table_reset('columnar_table', chunk_group_row_limit => true); +ALTER TABLE columnar_table RESET (columnar.chunk_group_row_limit); ERROR: must be owner of table columnar_table SET ROLE read_access; -- and drop it diff --git a/src/test/regress/expected/pg12.out b/src/test/regress/expected/pg12.out index 3c2298a4e..acfa60474 100644 --- a/src/test/regress/expected/pg12.out +++ b/src/test/regress/expected/pg12.out @@ -656,12 +656,12 @@ CREATE USER read_access; NOTICE: not propagating CREATE ROLE/USER commands to worker nodes HINT: Connect to worker nodes directly to manually create all necessary users and roles. SET ROLE read_access; --- user shouldn't be able to execute alter_columnar_table_set --- or alter_columnar_table_reset for a columnar table that it +-- user shouldn't be able to execute ALTER TABLE ... SET +-- or ALTER TABLE ... RESET for a columnar table that it -- doesn't own -SELECT alter_columnar_table_set('test_pg12.superuser_columnar_table', chunk_group_row_limit => 100); +ALTER TABLE test_pg12.superuser_columnar_table SET(columnar.chunk_group_row_limit = 100); ERROR: permission denied for schema test_pg12 -SELECT alter_columnar_table_reset('test_pg12.superuser_columnar_table'); +ALTER TABLE test_pg12.superuser_columnar_table RESET (columnar.chunk_group_row_limit); ERROR: permission denied for schema test_pg12 RESET ROLE; DROP USER read_access; diff --git a/src/test/regress/sql/columnar_citus_integration.sql b/src/test/regress/sql/columnar_citus_integration.sql index 78d54ea26..caae2f27c 100644 --- a/src/test/regress/sql/columnar_citus_integration.sql +++ b/src/test/regress/sql/columnar_citus_integration.sql @@ -1,4 +1,10 @@ -SET columnar.compression TO 'none'; + +SELECT success, result FROM run_command_on_all_nodes($cmd$ + ALTER SYSTEM SET columnar.compression TO 'none' +$cmd$); +SELECT success, result FROM run_command_on_all_nodes($cmd$ + SELECT pg_reload_conf() +$cmd$); CREATE SCHEMA columnar_citus_integration; SET search_path TO columnar_citus_integration; @@ -18,13 +24,13 @@ SELECT run_command_on_placements('table_option',$cmd$ SELECT compression FROM columnar.options WHERE regclass = '%s'::regclass; $cmd$); -- change setting -SELECT alter_columnar_table_set('table_option', compression => 'pglz'); +ALTER TABLE table_option SET (columnar.compression = pglz); -- verify setting SELECT run_command_on_placements('table_option',$cmd$ SELECT compression FROM columnar.options WHERE regclass = '%s'::regclass; $cmd$); -- reset setting -SELECT alter_columnar_table_reset('table_option', compression => true); +ALTER TABLE table_option RESET (columnar.compression); -- verify setting SELECT run_command_on_placements('table_option',$cmd$ SELECT compression FROM columnar.options WHERE regclass = '%s'::regclass; @@ -36,13 +42,13 @@ SELECT run_command_on_placements('table_option',$cmd$ SELECT compression_level FROM columnar.options WHERE regclass = '%s'::regclass; $cmd$); -- change setting -SELECT alter_columnar_table_set('table_option', compression_level => 13); +ALTER TABLE table_option SET (columnar.compression_level = 13); -- verify setting SELECT run_command_on_placements('table_option',$cmd$ SELECT compression_level FROM columnar.options WHERE regclass = '%s'::regclass; $cmd$); -- reset setting -SELECT alter_columnar_table_reset('table_option', compression_level => true); +ALTER TABLE table_option RESET (columnar.compression_level); -- verify setting SELECT run_command_on_placements('table_option',$cmd$ SELECT compression_level FROM columnar.options WHERE regclass = '%s'::regclass; @@ -54,13 +60,13 @@ SELECT run_command_on_placements('table_option',$cmd$ SELECT chunk_group_row_limit FROM columnar.options WHERE regclass = '%s'::regclass; $cmd$); -- change setting -SELECT alter_columnar_table_set('table_option', chunk_group_row_limit => 2000); +ALTER TABLE table_option SET (columnar.chunk_group_row_limit = 2000); -- verify setting SELECT run_command_on_placements('table_option',$cmd$ SELECT chunk_group_row_limit FROM columnar.options WHERE regclass = '%s'::regclass; $cmd$); -- reset setting -SELECT alter_columnar_table_reset('table_option', chunk_group_row_limit => true); +ALTER TABLE table_option RESET (columnar.chunk_group_row_limit); -- verify setting SELECT run_command_on_placements('table_option',$cmd$ SELECT chunk_group_row_limit FROM columnar.options WHERE regclass = '%s'::regclass; @@ -72,13 +78,13 @@ SELECT run_command_on_placements('table_option',$cmd$ SELECT stripe_row_limit FROM columnar.options WHERE regclass = '%s'::regclass; $cmd$); -- change setting -SELECT alter_columnar_table_set('table_option', stripe_row_limit => 2000); +ALTER TABLE table_option SET (columnar.stripe_row_limit = 2000); -- verify setting SELECT run_command_on_placements('table_option',$cmd$ SELECT stripe_row_limit FROM columnar.options WHERE regclass = '%s'::regclass; $cmd$); -- reset setting -SELECT alter_columnar_table_reset('table_option', stripe_row_limit => true); +ALTER TABLE table_option RESET (columnar.stripe_row_limit); -- verify setting SELECT run_command_on_placements('table_option',$cmd$ SELECT stripe_row_limit FROM columnar.options WHERE regclass = '%s'::regclass; @@ -86,11 +92,11 @@ $cmd$); -- verify settings are propagated when creating a table CREATE TABLE table_option_2 (a int, b text) USING columnar; -SELECT alter_columnar_table_set('table_option_2', - chunk_group_row_limit => 2000, - stripe_row_limit => 20000, - compression => 'pglz', - compression_level => 15); +ALTER TABLE table_option_2 SET + (columnar.chunk_group_row_limit = 2000, + columnar.stripe_row_limit = 20000, + columnar.compression = pglz, + columnar.compression_level = 15); SELECT create_distributed_table('table_option_2', 'a'); -- verify settings on placements @@ -118,13 +124,13 @@ SELECT run_command_on_placements('table_option',$cmd$ SELECT compression FROM columnar.options WHERE regclass = '%s'::regclass; $cmd$); -- change setting -SELECT alter_columnar_table_set('table_option', compression => 'pglz'); +ALTER TABLE table_option SET (columnar.compression = pglz); -- verify setting SELECT run_command_on_placements('table_option',$cmd$ SELECT compression FROM columnar.options WHERE regclass = '%s'::regclass; $cmd$); -- reset setting -SELECT alter_columnar_table_reset('table_option', compression => true); +ALTER TABLE table_option RESET (columnar.compression); -- verify setting SELECT run_command_on_placements('table_option',$cmd$ SELECT compression FROM columnar.options WHERE regclass = '%s'::regclass; @@ -136,13 +142,13 @@ SELECT run_command_on_placements('table_option',$cmd$ SELECT compression_level FROM columnar.options WHERE regclass = '%s'::regclass; $cmd$); -- change setting -SELECT alter_columnar_table_set('table_option', compression_level => 17); +ALTER TABLE table_option SET (columnar.compression_level = 17); -- verify setting SELECT run_command_on_placements('table_option',$cmd$ SELECT compression_level FROM columnar.options WHERE regclass = '%s'::regclass; $cmd$); -- reset setting -SELECT alter_columnar_table_reset('table_option', compression_level => true); +ALTER TABLE table_option RESET (columnar.compression_level); -- verify setting SELECT run_command_on_placements('table_option',$cmd$ SELECT compression_level FROM columnar.options WHERE regclass = '%s'::regclass; @@ -154,13 +160,13 @@ SELECT run_command_on_placements('table_option',$cmd$ SELECT chunk_group_row_limit FROM columnar.options WHERE regclass = '%s'::regclass; $cmd$); -- change setting -SELECT alter_columnar_table_set('table_option', chunk_group_row_limit => 2000); +ALTER TABLE table_option SET (columnar.chunk_group_row_limit = 2000); -- verify setting SELECT run_command_on_placements('table_option',$cmd$ SELECT chunk_group_row_limit FROM columnar.options WHERE regclass = '%s'::regclass; $cmd$); -- reset setting -SELECT alter_columnar_table_reset('table_option', chunk_group_row_limit => true); +ALTER TABLE table_option RESET (columnar.chunk_group_row_limit); -- verify setting SELECT run_command_on_placements('table_option',$cmd$ SELECT chunk_group_row_limit FROM columnar.options WHERE regclass = '%s'::regclass; @@ -172,13 +178,13 @@ SELECT run_command_on_placements('table_option',$cmd$ SELECT stripe_row_limit FROM columnar.options WHERE regclass = '%s'::regclass; $cmd$); -- change setting -SELECT alter_columnar_table_set('table_option', stripe_row_limit => 2000); +ALTER TABLE table_option SET (columnar.stripe_row_limit = 2000); -- verify setting SELECT run_command_on_placements('table_option',$cmd$ SELECT stripe_row_limit FROM columnar.options WHERE regclass = '%s'::regclass; $cmd$); -- reset setting -SELECT alter_columnar_table_reset('table_option', stripe_row_limit => true); +ALTER TABLE table_option RESET (columnar.stripe_row_limit); -- verify setting SELECT run_command_on_placements('table_option',$cmd$ SELECT stripe_row_limit FROM columnar.options WHERE regclass = '%s'::regclass; @@ -186,11 +192,11 @@ $cmd$); -- verify settings are propagated when creating a table CREATE TABLE table_option_2 (a int, b text) USING columnar; -SELECT alter_columnar_table_set('table_option_2', - chunk_group_row_limit => 2000, - stripe_row_limit => 20000, - compression => 'pglz', - compression_level => 19); +ALTER TABLE table_option_2 SET + (columnar.chunk_group_row_limit = 2000, + columnar.stripe_row_limit = 20000, + columnar.compression = pglz, + columnar.compression_level = 19); SELECT create_distributed_table('table_option_2', 'a'); -- verify settings on placements @@ -215,13 +221,13 @@ SELECT run_command_on_placements('table_option_reference',$cmd$ SELECT compression FROM columnar.options WHERE regclass = '%s'::regclass; $cmd$); -- change setting -SELECT alter_columnar_table_set('table_option_reference', compression => 'pglz'); +ALTER TABLE table_option_reference SET (columnar.compression = pglz); -- verify setting SELECT run_command_on_placements('table_option_reference',$cmd$ SELECT compression FROM columnar.options WHERE regclass = '%s'::regclass; $cmd$); -- reset setting -SELECT alter_columnar_table_reset('table_option_reference', compression => true); +ALTER TABLE table_option_reference RESET (columnar.compression); -- verify setting SELECT run_command_on_placements('table_option_reference',$cmd$ SELECT compression FROM columnar.options WHERE regclass = '%s'::regclass; @@ -233,13 +239,13 @@ SELECT run_command_on_placements('table_option_reference',$cmd$ SELECT compression_level FROM columnar.options WHERE regclass = '%s'::regclass; $cmd$); -- change setting -SELECT alter_columnar_table_set('table_option_reference', compression_level => 11); +ALTER TABLE table_option_reference SET (columnar.compression_level = 11); -- verify setting SELECT run_command_on_placements('table_option_reference',$cmd$ SELECT compression_level FROM columnar.options WHERE regclass = '%s'::regclass; $cmd$); -- reset setting -SELECT alter_columnar_table_reset('table_option_reference', compression_level => true); +ALTER TABLE table_option_reference RESET (columnar.compression_level); -- verify setting SELECT run_command_on_placements('table_option_reference',$cmd$ SELECT compression_level FROM columnar.options WHERE regclass = '%s'::regclass; @@ -251,13 +257,13 @@ SELECT run_command_on_placements('table_option_reference',$cmd$ SELECT chunk_group_row_limit FROM columnar.options WHERE regclass = '%s'::regclass; $cmd$); -- change setting -SELECT alter_columnar_table_set('table_option_reference', chunk_group_row_limit => 2000); +ALTER TABLE table_option_reference SET (columnar.chunk_group_row_limit = 2000); -- verify setting SELECT run_command_on_placements('table_option_reference',$cmd$ SELECT chunk_group_row_limit FROM columnar.options WHERE regclass = '%s'::regclass; $cmd$); -- reset setting -SELECT alter_columnar_table_reset('table_option_reference', chunk_group_row_limit => true); +ALTER TABLE table_option_reference RESET (columnar.chunk_group_row_limit); -- verify setting SELECT run_command_on_placements('table_option_reference',$cmd$ SELECT chunk_group_row_limit FROM columnar.options WHERE regclass = '%s'::regclass; @@ -269,13 +275,13 @@ SELECT run_command_on_placements('table_option_reference',$cmd$ SELECT stripe_row_limit FROM columnar.options WHERE regclass = '%s'::regclass; $cmd$); -- change setting -SELECT alter_columnar_table_set('table_option_reference', stripe_row_limit => 2000); +ALTER TABLE table_option_reference SET (columnar.stripe_row_limit = 2000); -- verify setting SELECT run_command_on_placements('table_option_reference',$cmd$ SELECT stripe_row_limit FROM columnar.options WHERE regclass = '%s'::regclass; $cmd$); -- reset setting -SELECT alter_columnar_table_reset('table_option_reference', stripe_row_limit => true); +ALTER TABLE table_option_reference RESET (columnar.stripe_row_limit); -- verify setting SELECT run_command_on_placements('table_option_reference',$cmd$ SELECT stripe_row_limit FROM columnar.options WHERE regclass = '%s'::regclass; @@ -283,11 +289,11 @@ $cmd$); -- verify settings are propagated when creating a table CREATE TABLE table_option_reference_2 (a int, b text) USING columnar; -SELECT alter_columnar_table_set('table_option_reference_2', - chunk_group_row_limit => 2000, - stripe_row_limit => 20000, - compression => 'pglz', - compression_level => 9); +ALTER TABLE table_option_reference_2 SET + (columnar.chunk_group_row_limit = 2000, + columnar.stripe_row_limit = 20000, + columnar.compression = pglz, + columnar.compression_level = 9); SELECT create_reference_table('table_option_reference_2'); -- verify settings on placements @@ -315,13 +321,13 @@ SELECT run_command_on_placements('table_option_citus_local',$cmd$ SELECT compression FROM columnar.options WHERE regclass = '%s'::regclass; $cmd$); -- change setting -SELECT alter_columnar_table_set('table_option_citus_local', compression => 'pglz'); +ALTER TABLE table_option_citus_local SET (columnar.compression = pglz); -- verify setting SELECT run_command_on_placements('table_option_citus_local',$cmd$ SELECT compression FROM columnar.options WHERE regclass = '%s'::regclass; $cmd$); -- reset setting -SELECT alter_columnar_table_reset('table_option_citus_local', compression => true); +ALTER TABLE table_option_citus_local RESET (columnar.compression); -- verify setting SELECT run_command_on_placements('table_option_citus_local',$cmd$ SELECT compression FROM columnar.options WHERE regclass = '%s'::regclass; @@ -333,13 +339,13 @@ SELECT run_command_on_placements('table_option_citus_local',$cmd$ SELECT compression_level FROM columnar.options WHERE regclass = '%s'::regclass; $cmd$); -- change setting -SELECT alter_columnar_table_set('table_option_citus_local', compression_level => 11); +ALTER TABLE table_option_citus_local SET (columnar.compression_level = 11); -- verify setting SELECT run_command_on_placements('table_option_citus_local',$cmd$ SELECT compression_level FROM columnar.options WHERE regclass = '%s'::regclass; $cmd$); -- reset setting -SELECT alter_columnar_table_reset('table_option_citus_local', compression_level => true); +ALTER TABLE table_option_citus_local RESET (columnar.compression_level); -- verify setting SELECT run_command_on_placements('table_option_citus_local',$cmd$ SELECT compression_level FROM columnar.options WHERE regclass = '%s'::regclass; @@ -351,13 +357,13 @@ SELECT run_command_on_placements('table_option_citus_local',$cmd$ SELECT chunk_group_row_limit FROM columnar.options WHERE regclass = '%s'::regclass; $cmd$); -- change setting -SELECT alter_columnar_table_set('table_option_citus_local', chunk_group_row_limit => 2000); +ALTER TABLE table_option_citus_local SET (columnar.chunk_group_row_limit = 2000); -- verify setting SELECT run_command_on_placements('table_option_citus_local',$cmd$ SELECT chunk_group_row_limit FROM columnar.options WHERE regclass = '%s'::regclass; $cmd$); -- reset setting -SELECT alter_columnar_table_reset('table_option_citus_local', chunk_group_row_limit => true); +ALTER TABLE table_option_citus_local RESET (columnar.chunk_group_row_limit); -- verify setting SELECT run_command_on_placements('table_option_citus_local',$cmd$ SELECT chunk_group_row_limit FROM columnar.options WHERE regclass = '%s'::regclass; @@ -369,13 +375,13 @@ SELECT run_command_on_placements('table_option_citus_local',$cmd$ SELECT stripe_row_limit FROM columnar.options WHERE regclass = '%s'::regclass; $cmd$); -- change setting -SELECT alter_columnar_table_set('table_option_citus_local', stripe_row_limit => 2000); +ALTER TABLE table_option_citus_local SET (columnar.stripe_row_limit = 2000); -- verify setting SELECT run_command_on_placements('table_option_citus_local',$cmd$ SELECT stripe_row_limit FROM columnar.options WHERE regclass = '%s'::regclass; $cmd$); -- reset setting -SELECT alter_columnar_table_reset('table_option_citus_local', stripe_row_limit => true); +ALTER TABLE table_option_citus_local RESET (columnar.stripe_row_limit); -- verify setting SELECT run_command_on_placements('table_option_citus_local',$cmd$ SELECT stripe_row_limit FROM columnar.options WHERE regclass = '%s'::regclass; @@ -383,11 +389,11 @@ $cmd$); -- verify settings are propagated when creating a table CREATE TABLE table_option_citus_local_2 (a int, b text) USING columnar; -SELECT alter_columnar_table_set('table_option_citus_local_2', - chunk_group_row_limit => 2000, - stripe_row_limit => 20000, - compression => 'pglz', - compression_level => 9); +ALTER TABLE table_option_citus_local_2 SET + (columnar.chunk_group_row_limit = 2000, + columnar.stripe_row_limit = 20000, + columnar.compression = pglz, + columnar.compression_level = 9); SELECT citus_add_local_table_to_metadata('table_option_citus_local_2'); -- verify settings on placements diff --git a/src/test/regress/sql/columnar_create.sql b/src/test/regress/sql/columnar_create.sql index 4037dd28b..59992c0bd 100644 --- a/src/test/regress/sql/columnar_create.sql +++ b/src/test/regress/sql/columnar_create.sql @@ -7,7 +7,7 @@ CREATE TABLE contestant (handle TEXT, birthdate DATE, rating INT, percentile FLOAT, country CHAR(3), achievements TEXT[]) USING columnar; -SELECT alter_columnar_table_set('contestant', compression => 'none'); +ALTER TABLE contestant SET (columnar.compression = none); CREATE INDEX contestant_idx on contestant(handle); diff --git a/src/test/regress/sql/columnar_empty.sql b/src/test/regress/sql/columnar_empty.sql index 0f6eb1d27..545014e2e 100644 --- a/src/test/regress/sql/columnar_empty.sql +++ b/src/test/regress/sql/columnar_empty.sql @@ -7,9 +7,9 @@ create table t_uncompressed(a int) using columnar; create table t_compressed(a int) using columnar; -- set options -SELECT alter_columnar_table_set('t_compressed', compression => 'pglz'); -SELECT alter_columnar_table_set('t_compressed', stripe_row_limit => 2000); -SELECT alter_columnar_table_set('t_compressed', chunk_group_row_limit => 1000); +ALTER TABLE t_compressed SET (columnar.compression = pglz); +ALTER TABLE t_compressed SET (columnar.stripe_row_limit = 2000); +ALTER TABLE t_compressed SET (columnar.chunk_group_row_limit = 1000); SELECT * FROM columnar.options WHERE regclass = 't_compressed'::regclass; diff --git a/src/test/regress/sql/columnar_fallback_scan.sql b/src/test/regress/sql/columnar_fallback_scan.sql index 3210f0738..28e521eaf 100644 --- a/src/test/regress/sql/columnar_fallback_scan.sql +++ b/src/test/regress/sql/columnar_fallback_scan.sql @@ -10,7 +10,7 @@ set columnar.enable_custom_scan = false; create table fallback_scan(i int) using columnar; -- large enough to test parallel_workers > 1 -select alter_columnar_table_set('fallback_scan', compression => 'none'); +ALTER TABLE fallback_scan SET (columnar.compression = none); insert into fallback_scan select generate_series(1,150000); vacuum analyze fallback_scan; diff --git a/src/test/regress/sql/columnar_first_row_number.sql b/src/test/regress/sql/columnar_first_row_number.sql index b1d0e7bd4..c678f00f0 100644 --- a/src/test/regress/sql/columnar_first_row_number.sql +++ b/src/test/regress/sql/columnar_first_row_number.sql @@ -12,7 +12,7 @@ ROLLBACK; INSERT INTO col_table_1 SELECT i FROM generate_series(1, 12) i; -SELECT alter_columnar_table_set('col_table_1', stripe_row_limit => 1000); +ALTER TABLE col_table_1 SET (columnar.stripe_row_limit = 1000); INSERT INTO col_table_1 SELECT i FROM generate_series(1, 2350) i; diff --git a/src/test/regress/sql/columnar_insert.sql b/src/test/regress/sql/columnar_insert.sql index 9874109ca..9ccd125a3 100644 --- a/src/test/regress/sql/columnar_insert.sql +++ b/src/test/regress/sql/columnar_insert.sql @@ -119,7 +119,7 @@ DROP TABLE test_toast_columnar; -- We support writing into zero column tables, but not reading from them. -- We test that metadata makes sense so we can fix the read path in future. CREATE TABLE zero_col() USING columnar; -SELECT alter_columnar_table_set('zero_col', chunk_group_row_limit => 1000); +ALTER TABLE zero_col SET (columnar.chunk_group_row_limit = 1000); INSERT INTO zero_col DEFAULT VALUES; INSERT INTO zero_col DEFAULT VALUES; @@ -157,7 +157,7 @@ ORDER BY 1,2,3,4; CREATE TABLE selfinsert(x int) USING columnar; -SELECT alter_columnar_table_set('selfinsert', stripe_row_limit => 1000); +ALTER TABLE selfinsert SET (columnar.stripe_row_limit = 1000); BEGIN; INSERT INTO selfinsert SELECT generate_series(1,1010); diff --git a/src/test/regress/sql/columnar_matview.sql b/src/test/regress/sql/columnar_matview.sql index ff526d1c0..d57d81f8d 100644 --- a/src/test/regress/sql/columnar_matview.sql +++ b/src/test/regress/sql/columnar_matview.sql @@ -22,7 +22,7 @@ SELECT * FROM columnar.options WHERE regclass = 't_view'::regclass; -- show we can set options on a materialized view -SELECT alter_columnar_table_set('t_view', compression => 'pglz'); +ALTER TABLE t_view SET (columnar.compression = pglz); SELECT * FROM columnar.options WHERE regclass = 't_view'::regclass; diff --git a/src/test/regress/sql/columnar_permissions.sql b/src/test/regress/sql/columnar_permissions.sql index e131de55c..ea4470ef3 100644 --- a/src/test/regress/sql/columnar_permissions.sql +++ b/src/test/regress/sql/columnar_permissions.sql @@ -1,4 +1,6 @@ +create table no_access (i int) using columnar; + select current_user \gset create user columnar_user; @@ -8,10 +10,20 @@ create user columnar_user; create table columnar_permissions(i int) using columnar; insert into columnar_permissions values(1); alter table columnar_permissions add column j int; +alter table columnar_permissions reset (columnar.compression); +alter table columnar_permissions set (columnar.compression = none); +select alter_columnar_table_reset('columnar_permissions', stripe_row_limit => true); +select alter_columnar_table_set('columnar_permissions', stripe_row_limit => 2222); +select * from columnar.options where regclass = 'columnar_permissions'::regclass; insert into columnar_permissions values(2,20); vacuum columnar_permissions; truncate columnar_permissions; drop table columnar_permissions; -\c - :current_user +-- should error +alter table no_access reset (columnar.stripe_row_limit); +alter table no_access set (columnar.stripe_row_limit = 12000); +select alter_columnar_table_reset('no_access', chunk_group_row_limit => true); +select alter_columnar_table_set('no_access', chunk_group_row_limit => 1111); +\c - :current_user diff --git a/src/test/regress/sql/columnar_pg15.sql b/src/test/regress/sql/columnar_pg15.sql new file mode 100644 index 000000000..86117910c --- /dev/null +++ b/src/test/regress/sql/columnar_pg15.sql @@ -0,0 +1,34 @@ +SHOW server_version \gset +SELECT substring(:'server_version', '\d+')::int >= 15 AS server_version_ge_15 +\gset +\if :server_version_ge_15 +\else +\q +\endif + +CREATE TABLE alter_am(i int); + +INSERT INTO alter_am SELECT generate_series(1,1000000); + +SELECT * FROM columnar.options WHERE regclass = 'alter_am'::regclass; +SELECT SUM(i) FROM alter_am; + +ALTER TABLE alter_am + SET ACCESS METHOD columnar, + SET (columnar.compression = pglz, fillfactor = 20); + +SELECT * FROM columnar.options WHERE regclass = 'alter_am'::regclass; +SELECT SUM(i) FROM alter_am; + +ALTER TABLE alter_am SET ACCESS METHOD heap; + +-- columnar options should be gone +SELECT * FROM columnar.options WHERE regclass = 'alter_am'::regclass; +SELECT SUM(i) FROM alter_am; + +-- error: setting columnar options must happen after converting to columnar +ALTER TABLE alter_am + SET (columnar.stripe_row_limit = 1111), + SET ACCESS METHOD columnar; + +DROP TABLE alter_am; diff --git a/src/test/regress/sql/columnar_tableoptions.sql b/src/test/regress/sql/columnar_tableoptions.sql index 0033042fc..f056f5523 100644 --- a/src/test/regress/sql/columnar_tableoptions.sql +++ b/src/test/regress/sql/columnar_tableoptions.sql @@ -10,28 +10,28 @@ SELECT * FROM columnar.options WHERE regclass = 'table_options'::regclass; -- test changing the compression -SELECT alter_columnar_table_set('table_options', compression => 'pglz'); +ALTER TABLE table_options SET (columnar.compression = pglz); -- show table_options settings SELECT * FROM columnar.options WHERE regclass = 'table_options'::regclass; -- test changing the compression level -SELECT alter_columnar_table_set('table_options', compression_level => 5); +ALTER TABLE table_options SET (columnar.compression_level = 5); -- show table_options settings SELECT * FROM columnar.options WHERE regclass = 'table_options'::regclass; -- test changing the chunk_group_row_limit -SELECT alter_columnar_table_set('table_options', chunk_group_row_limit => 2000); +ALTER TABLE table_options SET (columnar.chunk_group_row_limit = 2000); -- show table_options settings SELECT * FROM columnar.options WHERE regclass = 'table_options'::regclass; -- test changing the chunk_group_row_limit -SELECT alter_columnar_table_set('table_options', stripe_row_limit => 4000); +ALTER TABLE table_options SET (columnar.stripe_row_limit = 4000); -- show table_options settings SELECT * FROM columnar.options @@ -45,7 +45,11 @@ SELECT * FROM columnar.options WHERE regclass = 'table_options'::regclass; -- set all settings at the same time -SELECT alter_columnar_table_set('table_options', stripe_row_limit => 8000, chunk_group_row_limit => 4000, compression => 'none', compression_level => 7); +ALTER TABLE table_options SET + (columnar.stripe_row_limit = 8000, + columnar.chunk_group_row_limit = 4000, + columnar.compression = none, + columnar.compression_level = 7); -- show table_options settings SELECT * FROM columnar.options @@ -85,24 +89,24 @@ SET columnar.compression_level TO 11; SELECT * FROM columnar.options WHERE regclass = 'table_options'::regclass; -SELECT alter_columnar_table_reset('table_options', chunk_group_row_limit => true); +ALTER TABLE table_options RESET (columnar.chunk_group_row_limit); -- show table_options settings SELECT * FROM columnar.options WHERE regclass = 'table_options'::regclass; -SELECT alter_columnar_table_reset('table_options', stripe_row_limit => true); +ALTER TABLE table_options RESET (columnar.stripe_row_limit); -- show table_options settings SELECT * FROM columnar.options WHERE regclass = 'table_options'::regclass; -SELECT alter_columnar_table_reset('table_options', compression => true); +ALTER TABLE table_options RESET (columnar.compression); -- show table_options settings SELECT * FROM columnar.options WHERE regclass = 'table_options'::regclass; -SELECT alter_columnar_table_reset('table_options', compression_level => true); +ALTER TABLE table_options RESET (columnar.compression_level); -- show table_options settings SELECT * FROM columnar.options @@ -118,12 +122,11 @@ SET columnar.compression_level TO 13; SELECT * FROM columnar.options WHERE regclass = 'table_options'::regclass; -SELECT alter_columnar_table_reset( - 'table_options', - chunk_group_row_limit => true, - stripe_row_limit => true, - compression => true, - compression_level => true); +ALTER TABLE table_options RESET + (columnar.chunk_group_row_limit, + columnar.stripe_row_limit, + columnar.compression, + columnar.compression_level); -- show table_options settings SELECT * FROM columnar.options @@ -132,24 +135,72 @@ WHERE regclass = 'table_options'::regclass; -- verify edge cases -- first start with a table that is not a columnar table CREATE TABLE not_a_columnar_table (a int); -SELECT alter_columnar_table_set('not_a_columnar_table', compression => 'pglz'); -SELECT alter_columnar_table_reset('not_a_columnar_table', compression => true); +ALTER TABLE not_a_columnar_table SET (columnar.compression = pglz); +ALTER TABLE not_a_columnar_table RESET (columnar.compression); -- verify you can't use a compression that is not known -SELECT alter_columnar_table_set('table_options', compression => 'foobar'); +ALTER TABLE table_options SET (columnar.compression = foobar); + +-- verify you can't use a columnar setting that is not known +ALTER TABLE table_options SET (columnar.foobar = 123); +ALTER TABLE table_options RESET (columnar.foobar); + +-- verify that invalid options are caught early, before query executes +-- (error should be about invalid options, not division-by-zero) +CREATE TABLE fail(i) USING columnar WITH (columnar.foobar = 123) AS SELECT 1/0; +CREATE TABLE fail(i) USING columnar WITH (columnar.compression = foobar) AS SELECT 1/0; -- verify cannot set out of range compression levels -SELECT alter_columnar_table_set('table_options', compression_level => 0); -SELECT alter_columnar_table_set('table_options', compression_level => 20); +ALTER TABLE table_options SET (columnar.compression_level = 0); +ALTER TABLE table_options SET (columnar.compression_level = 20); -- verify cannot set out of range stripe_row_limit & chunk_group_row_limit options -SELECT alter_columnar_table_set('table_options', stripe_row_limit => 999); -SELECT alter_columnar_table_set('table_options', stripe_row_limit => 10000001); -SELECT alter_columnar_table_set('table_options', chunk_group_row_limit => 999); -SELECT alter_columnar_table_set('table_options', chunk_group_row_limit => 100001); -SELECT alter_columnar_table_set('table_options', chunk_group_row_limit => 0); +ALTER TABLE table_options SET (columnar.stripe_row_limit = 999); +ALTER TABLE table_options SET (columnar.stripe_row_limit = 10000001); +ALTER TABLE table_options SET (columnar.chunk_group_row_limit = 999); +ALTER TABLE table_options SET (columnar.chunk_group_row_limit = 100001); +ALTER TABLE table_options SET (columnar.chunk_group_row_limit = 0); INSERT INTO table_options VALUES (1); +-- multiple SET/RESET clauses +ALTER TABLE table_options + SET (columnar.compression = pglz, columnar.compression_level = 7), + SET (columnar.compression_level = 6); + +SELECT * FROM columnar.options +WHERE regclass = 'table_options'::regclass; + +ALTER TABLE table_options + SET (columnar.compression = pglz, columnar.stripe_row_limit = 7777), + RESET (columnar.stripe_row_limit), + SET (columnar.chunk_group_row_limit = 5555); + +SELECT * FROM columnar.options +WHERE regclass = 'table_options'::regclass; + +-- a no-op; shouldn't throw an error +ALTER TABLE IF EXISTS what SET (columnar.compression = lz4); + +-- a no-op; shouldn't throw an error +CREATE TABLE IF NOT EXISTS table_options(a int) USING columnar + WITH (columnar.compression_level = 4); + +-- test old interface based on functions +SELECT alter_columnar_table_reset('table_options', compression => true); +SELECT * FROM columnar.options WHERE regclass = 'table_options'::regclass; +SELECT alter_columnar_table_set('table_options', compression_level => 1); +SELECT * FROM columnar.options WHERE regclass = 'table_options'::regclass; + +-- error: set columnar options on heap tables +CREATE TABLE heap_options(i int) USING heap; +ALTER TABLE heap_options SET (columnar.stripe_row_limit = 12000); + +-- ordinarily, postgres allows bogus options for a RESET clause, +-- but if it's a heap table and someone specifies columnar options, +-- we block them +ALTER TABLE heap_options RESET (columnar.stripe_row_limit, foobar); +DROP TABLE heap_options; + -- verify options are removed when table is dropped DROP TABLE table_options; -- we expect no entries in çstore.options for anything not found int pg_class diff --git a/src/test/regress/sql/columnar_vacuum.sql b/src/test/regress/sql/columnar_vacuum.sql index 39f1b35a5..e32f82be3 100644 --- a/src/test/regress/sql/columnar_vacuum.sql +++ b/src/test/regress/sql/columnar_vacuum.sql @@ -34,7 +34,7 @@ select from columnar_test_helpers.columnar_storage_info('t'); -- test the case when all data cannot fit into a single stripe -SELECT alter_columnar_table_set('t', stripe_row_limit => 1000); +ALTER TABLE t SET (columnar.stripe_row_limit = 1000); INSERT INTO t SELECT i, 2 * i FROM generate_series(1,2500) i; SELECT sum(a), sum(b) FROM t; @@ -91,15 +91,15 @@ SELECT count(*) FROM t; -- then vacuum to print stats BEGIN; -SELECT alter_columnar_table_set('t', - chunk_group_row_limit => 1000, - stripe_row_limit => 2000, - compression => 'pglz'); +ALTER TABLE t SET + (columnar.chunk_group_row_limit = 1000, + columnar.stripe_row_limit = 2000, + columnar.compression = pglz); SAVEPOINT s1; INSERT INTO t SELECT i FROM generate_series(1, 1500) i; ROLLBACK TO SAVEPOINT s1; INSERT INTO t SELECT i / 5 FROM generate_series(1, 1500) i; -SELECT alter_columnar_table_set('t', compression => 'none'); +ALTER TABLE t SET (columnar.compression = none); SAVEPOINT s2; INSERT INTO t SELECT i FROM generate_series(1, 1500) i; ROLLBACK TO SAVEPOINT s2; @@ -125,7 +125,7 @@ VACUUM VERBOSE t; -- vacuum full should remove chunks for dropped columns -- note that, a chunk will be stored in non-compressed for if compression -- doesn't reduce its size. -SELECT alter_columnar_table_set('t', compression => 'pglz'); +ALTER TABLE t SET (columnar.compression = pglz); VACUUM FULL t; VACUUM VERBOSE t; diff --git a/src/test/regress/sql/columnar_zstd.sql b/src/test/regress/sql/columnar_zstd.sql index ab8ed1b31..1723d418b 100644 --- a/src/test/regress/sql/columnar_zstd.sql +++ b/src/test/regress/sql/columnar_zstd.sql @@ -26,7 +26,7 @@ VACUUM FULL test_zstd; SELECT pg_relation_size('test_zstd') AS size_comp_level_default \gset -- change compression level -SELECT alter_columnar_table_set('test_zstd', compression_level => 19); +ALTER TABLE test_zstd SET (columnar.compression_level = 19); VACUUM FULL test_zstd; SELECT pg_relation_size('test_zstd') AS size_comp_level_19 \gset diff --git a/src/test/regress/sql/multi_extension.sql b/src/test/regress/sql/multi_extension.sql index abd508df4..ef642b480 100644 --- a/src/test/regress/sql/multi_extension.sql +++ b/src/test/regress/sql/multi_extension.sql @@ -315,8 +315,8 @@ VACUUM columnar_table; TRUNCATE columnar_table; DROP TABLE columnar_table; CREATE INDEX ON columnar_table (a); -SELECT alter_columnar_table_set('columnar_table', compression => 'pglz'); -SELECT alter_columnar_table_reset('columnar_table'); +ALTER TABLE columnar_table SET(columnar.compression = pglz); +ALTER TABLE columnar_table RESET (columnar.compression); INSERT INTO columnar_table SELECT * FROM columnar_table; SELECT 1 FROM columnar_table; -- columnar custom scan diff --git a/src/test/regress/sql/multi_multiuser.sql b/src/test/regress/sql/multi_multiuser.sql index 8fcb89e1e..4c2136f0c 100644 --- a/src/test/regress/sql/multi_multiuser.sql +++ b/src/test/regress/sql/multi_multiuser.sql @@ -137,15 +137,15 @@ SET columnar.chunk_group_row_limit = 1050; -- create columnar table CREATE TABLE columnar_table (a int) USING columnar; -- alter a columnar table that is created by that unprivileged user -SELECT alter_columnar_table_set('columnar_table', chunk_group_row_limit => 2000); +ALTER TABLE columnar_table SET (columnar.chunk_group_row_limit = 2000); -- insert some data and read INSERT INTO columnar_table VALUES (1), (1); SELECT * FROM columnar_table; -- Fail to alter a columnar table that is created by a different user SET ROLE full_access; -SELECT alter_columnar_table_set('columnar_table', chunk_group_row_limit => 2000); +ALTER TABLE columnar_table SET (columnar.chunk_group_row_limit = 2000); -- Fail to reset a columnar table value created by a different user -SELECT alter_columnar_table_reset('columnar_table', chunk_group_row_limit => true); +ALTER TABLE columnar_table RESET (columnar.chunk_group_row_limit); SET ROLE read_access; -- and drop it DROP TABLE columnar_table; diff --git a/src/test/regress/sql/pg12.sql b/src/test/regress/sql/pg12.sql index 2211288f4..4e369106c 100644 --- a/src/test/regress/sql/pg12.sql +++ b/src/test/regress/sql/pg12.sql @@ -388,11 +388,11 @@ CREATE TABLE superuser_columnar_table (a int) USING columnar; CREATE USER read_access; SET ROLE read_access; --- user shouldn't be able to execute alter_columnar_table_set --- or alter_columnar_table_reset for a columnar table that it +-- user shouldn't be able to execute ALTER TABLE ... SET +-- or ALTER TABLE ... RESET for a columnar table that it -- doesn't own -SELECT alter_columnar_table_set('test_pg12.superuser_columnar_table', chunk_group_row_limit => 100); -SELECT alter_columnar_table_reset('test_pg12.superuser_columnar_table'); +ALTER TABLE test_pg12.superuser_columnar_table SET(columnar.chunk_group_row_limit = 100); +ALTER TABLE test_pg12.superuser_columnar_table RESET (columnar.chunk_group_row_limit); RESET ROLE; DROP USER read_access;